SpringBoot+layuimini实现角色权限菜单增删改查(layui扩展组件 dtree)

角色菜单

      • 相关组件方法
      • 效果图
      • 代码实现
      • 资源菜单树组件实现
        • 权限树方法js
          • 这里我先主要实现权限树的整体实现方法,如果是直接查看使用的话可以只看这里!
        • 后端代码
          • Controlle层代码
          • Service代码及实现类代码
            • Service代码
            • ServiceImpl代码
          • resourceMapper 代码
          • roleResourceMapper代码
          • Mybatis代码
            • RoleResourceMapper.xml
            • ResourceMapper.xml
          • TreeNode.java类
          • DataGridView.java类
      • 角色信息添加及编辑页面实现
        • 添加页面和编辑页面代码HTML
          • 单选框对应的js代码
          • treeSelectData方法
          • 表格头部监听栏按钮的操作
          • 添加,修改,删除的方法
        • 添加,修改,删除的后端方法
          • Controller代码
          • Service代码
          • ServiceImpl代码
          • RoleResourceMapper
            • RoleMapper
            • RoleMapper.xml
            • RoleResourceMapper.xml
      • 前端页面完整代码

相关组件方法

消息通知组件:notify
树组件:dtree
前端框架:layuimini
layui文档地址:layui

效果图

在这里插入图片描述
在这里插入图片描述

代码实现

资源菜单树组件实现

权限树方法js
这里我先主要实现权限树的整体实现方法,如果是直接查看使用的话可以只看这里!

在这里插入图片描述

  //初始化树function initTree(roleId) {console.log(roleId);var DTree = dtree.render({elem: "#treeSelect",dataStyle: "layuiStyle",  //使用layui风格的数据格式response: {message: "msg", statusCode: 0},  //修改response中返回数据的定义dataFormat: "list",  //配置data的风格为listcheckbar: true,//复选框checkbarType: "all", // 默认就是allcheckbarData: "choose",menubar: true,//菜单栏menubarTips: {group: ["moveDown", "moveUp", "refresh", "checkAll", "unCheckAll", "searchNode"], //按钮组},skin: "zdy", // 自定义风格line: true,  // 显示树线initLevel: 1,//默认展开层级为1ficon: ["1", "-1"], // 显示非最后一级节点图标,隐藏最后一级节点图标icon: "2",//修改二级图标样式url: "/role/getAllSelectResourceDate?roleId=" + roleId});/** 搜索框方法* */$("#search_btn").unbind("click");$("#search_btn").click(function () {var value = $("#searchInput").val();if (value) {var flag = DTree.searchNode(value); // 内置方法查找节点if (!flag) {layer.msg("该名称节点不存在!刷新后重试!");}} else {DTree.menubarMethod().refreshTree(); // 内置方法刷新树}});}
后端代码
Controlle层代码
  /** 权限配置菜单查询* @getAllSelectRoleDate* */@PostMapping("/getAllSelectResourceDate")public DataGridView listResource(Integer roleId) {// System.out.println("前端接受的权限id"+roleId);return roleService.listResource(roleId);}
Service代码及实现类代码
Service代码
 /** 查询所有菜单* */DataGridView listResource(Integer roleId);
ServiceImpl代码
 /** 查询所有菜单信息* */@Overridepublic DataGridView listResource(Integer roleId) {// 从数据库中获取所有的资源List<ResourceEntity> resourceList = resourceMapper.selectAllResource();//根据权限id查询资源,修改更新权限的时候使用List<RoleResourceEntity> roleResourceEntities = roleResourceMapper.selectRoleResourceByRoleId(roleId);// 遍历所有资源List<TreeNode> data = new ArrayList<>();// 判断是否是提提添加还是修改操作if (roleId == 0 || roleResourceEntities.isEmpty()) {for (ResourceEntity resource : resourceList) {// 资源IDInteger id = resource.getResourceId();// 资源IDInteger pid = resource.getParentId();// 资源名称String title = resource.getTitle();// 默认展开状态为falseBoolean spread = false;// 默认选中状态为falseString checkArr="0";// 封装数据data.add(new TreeNode(id, pid, title, spread,checkArr));}} else {for (ResourceEntity resource : resourceList) {// 遍历角色对应的资源列表// 默认选中状态为false 这里实现的是dtree的选中状态 0:未选中 1:选中String checkArr = "0";for (RoleResourceEntity roleResource : roleResourceEntities) {// 如果资源ID相同if (roleResource.getResourceId().equals(resource.getResourceId())) {// 将资源的选中状态设置为truecheckArr = "1";}}// 封装数据// 资源IDInteger id = resource.getResourceId();// 父级IDInteger pid = resource.getParentId();// 资源名称String title = resource.getTitle();// 默认不展开,如果数据不为空则展开Boolean spread = true;// 将数据封装到TreeNode中data.add(new TreeNode(id, pid, title, spread, checkArr));}}// 返回数据return new DataGridView(data);}
resourceMapper 代码
 /** 查询所有资源* */List<ResourceEntity> selectAllResource();
roleResourceMapper代码
    /** 根据角色ID查询角色资源* */List<RoleResourceEntity> selectRoleResourceByRoleId(Integer roleId);
Mybatis代码
RoleResourceMapper.xml
 <select id="selectRoleResourceByRoleId" resultType="com.example.erp_project.entity.RoleResourceEntity">select *from sys_role_resourcewhere roleId = #{roleId}</select>
ResourceMapper.xml
  <!--查询所有资源--><select id="selectAllResource" resultType="com.example.erp_project.entity.ResourceEntity">select *from sys_resourceorder by sort asc</select>
TreeNode.java类
package com.example.erp_project.util;import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.ArrayList;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TreeNode {//自己的资源idprivate Integer id;@JsonProperty("parentId") //返回的json的名称 parentId ,为了确定层级关系//父级idprivate Integer pid;//名称private String title;//是否展开private Boolean spread;//子节点private List<TreeNode> children = new ArrayList<TreeNode>();/*** 0为不选中  1为选中*/private String checkArr="0";/** 前端数据接收的数据项* */public TreeNode(Integer id, Integer pid, String title, Boolean spread, String checkArr) {this.id = id;this.pid = pid;this.title = title;this.spread = spread;this.checkArr = checkArr;}}
DataGridView.java类
package com.example.erp_project.util;import lombok.Data;/*** @author Lolo don‘t feel*/
@Data
public class DataGridView {//状态码private Integer code = 0;//总数private String msg = "";//分页数据private Long count = 0L;//这里是dtree中部门的数据private Object data;public DataGridView(Long count, Object data) {this.count = count;this.data = data;}public DataGridView(Object data) {this.data = data;}}

角色信息添加及编辑页面实现

添加页面和编辑页面代码HTML

这里主要查看的是分配权限中的 lay-filter="role-status"属性
在这里插入图片描述

<!-- 添加和修改的弹出层开始 --><div style="display: none;padding: 20px" id="saveOrUpdateDiv"><form class="layui-form" lay-filter="role-form" id="role-form"><!--隐藏数据id值,用于数据更新使用--><input type="hidden" name="roleId" id="roleId"><div class="layui-form-item"><label class="layui-form-label">角色名称:</label><div class="layui-input-block"><input type="text" name="roleName" id="roleName" lay-verify="required"placeholder="请填写角色名称"autocomplete="off"class="layui-input" lay-affix="clear"></div></div><div class="layui-form-item"><label class="layui-form-label">角色描述:</label><div class="layui-input-block"><textarea name="remark" placeholder="请输入内容" class="layui-textarea"lay-affix="clear"></textarea></div></div><div class="layui-form-item"><label class="layui-form-label">角色状态:</label><div class="layui-input-block"><input type="radio" name="state" value="1" title="正常" checked><input type="radio" name="state" value="0" title="停用"></div></div><input type="hidden" name="r" id="r"><div class="layui-form-item"><label class="layui-form-label">分配权限:</label><div class="layui-input-block"><input type="radio" name="roleState" value="1" title="分配" lay-filter="role-status"><input type="radio" name="roleState" value="0" title="暂不分配"lay-filter="role-status" ></div></div></form></div><!-- 添加和修改的弹出层结束 -->
单选框对应的js代码
    /** 权限分配菜单* */form.on('radio(role-status)', function (data) {var elem = data.elem; // 获得 radio 原始 DOM 对象var checked = elem.checked; // 获得 radio 选中状态var value = elem.value; // 获得 radio 值var othis = data.othis; // 获得 radio 元素被替换后的 jQuery 对象//获取页面输入框的值,如果为空则赋值为0,否则赋值为输入框的值//将value赋值给隐藏域$("#r").val(value);//将value赋值给隐藏域,这里注意用于角色信息编辑页面,否则会报错,报的错误就是:Cannot read property 'checked' of nullvar roleId = $("#roleId").val();if (!roleId) {roleId = 0;}//如果选中的是分配权限,然后调用 treeSelectData(roleId,1);方法加载菜单资源if (value==="1"){treeSelectData(roleId,1);//这里传递的roleId是0 查询的就是全部资源未选择,而编辑页面传递的就是选中数据的roleId}});
treeSelectData方法

效果图
在这里插入图片描述

HTML代码

   <!--分配权限的弹出层开始--><div style="display: none;padding: 20px" id="roleDiv"><div style="padding: 15px"><div class="layui-btn-container"><button type="button" class="layui-btn layui-btn-xs data-orange-btn"dtree-id="treeSelect" dtree-menu="checkAll"><i class="fa fa-check-square-o"></i> 全选</button><button type="button" class="layui-btn layui-btn-xs data-black-btn"dtree-id="treeSelect" dtree-menu="unCheckAll"><i class="fa fa-remove"></i> 取消全选</button><button class="layui-btn data-light-btn layui-btn-xs" dtree-id="treeSelect" dtree-menu="moveDown"><iclass="fa fa-expand"></i> 展开</button><button class="layui-btn data-grey-btn layui-btn-xs" dtree-id="treeSelect" dtree-menu="moveUp"><iclass="fa fa-compress"></i> 折叠</button></div><div class="layui-input-inline" style="width: 130px"><input type="text" class="layui-input" id="searchInput" placeholder="输入查询节点内容..."lay-affix="clear"style="height: 28px;font-size: 13px"></div><button class="layui-btn data-other-btn layui-btn-xs " id="search_btn"><i class="fa fa-search"></i> 搜索</button><button class="layui-btn data-other-btn layui-btn-xs " dtree-id="treeSelect" dtree-menu="refresh"><iclass="fa fa-refresh"></i> 刷新</button><div class="layui-form-item" style="padding: 15px"><ul id="treeSelect" class="dtree" data-id="0"></ul></div></div></div><!--分配权限的弹出层结束-->

添加和编辑页面下图中的代码课一不用查看
在这里插入图片描述

 /** 权限树弹出层方法* 这里传递两个参数一个是根据roleId(用于获取数据将权限进行分配),* 一个是根据status(用于判断是添加和修改页面,还是权限直接分配页面)。* */function treeSelectData(roleId,status) {layer.open({type: 1,title: '权限分配',content: $("#roleDiv"),area: ['360px', '520px'],closeBtn: false,btnAlign: 'c',//样式skin: 'class-layer-orange',btn: ['<i class="fa fa-check"></i> 确认分配', '<i class="fa fa-times "></i> 关闭'],success: function () {initTree(roleId);//弹出树组件根据角色id去查询对应的资源菜单},yes: function (index) {var params = dtree.getCheckbarNodesParam("treeSelect"); // 获取选中值if (params.length == 0) {//判断是否选中节点notify.info("至少选择一个节点!" ,"vcenter", "shadow", false,1000);return false;}//判断是添加和修改页面,还是权限直接分配页面,如果为1则表示是在角色信息,添加,修改页面的操作。if (status == 1){notify.loading('正在分配权限...', "vcenter", "shadow", false);setTimeout(function () {notify.destroyAll();//关闭loading加载notify.success('分配成功!', "vcenter", "shadow", false,1000);//设置提示框,"提示信息","位置", "样式", "是否显示关闭按钮", "显示时间"//关闭当前页面layer.closeLast('page');},1000)}else {/** 页面分配权限,及角色信息页面的权限分配* */// 将选中的节点转换为字符串var mStr = params.map(node => node.nodeId).join(",");notify.loading('正在分配权限...', "vcenter", "shadow", false);setTimeout(function () {notify.destroyAll();//关闭loading加载//传递数据到后端$.ajax({url: '/role/updateRoleResource',type: 'POST',data: {roleId: roleId, resourceIds: mStr},success: function (data) {if (data.code === 0) {notify.success(data.msg, "vcenter", "shadow", false,1000);} else if (data.code === 1){notify.warning(data.msg, "vcenter", "shadow", false,1000);} else {notify.error(data.msg, "vcenter", "shadow", false,1000);}}}) .done(function () {setTimeout(function () {notify.destroyAll();layer.closeAll();table.reload('roleTableId');//重载表格}, 1000);});},2000)}}, btn2: function () {if (status == 1){//清空 radio 值form.val("role-form", {"roleState": ""});notify.info("已取消操作!", "vcenter", "shadow", false,1000);layer.close();}else {notify.info("已取消操作!", "vcenter", "shadow", false,1000);layer.closeAll();}}});}
表格头部监听栏按钮的操作

在这里插入图片描述

 /** 头部操作栏监听* */table.on('toolbar(roleTableFilter)', function (obj) {switch (obj.event) {case 'add':layer.open({type: 1,title: '新增角色',content: $("#saveOrUpdateDiv"),area: ['660px', '450px'],closeBtn: false,//样式skin: 'class-layer-sea',btn: ['<i class="fa fa-check"></i> 新增', '<i class="fa fa-mail-reply-all "></i> 取消'],success: function (layero, index) {//清空表单数据$("#role-form")[0].reset();},yes: function (index) {var str = $("#r").val();submitForm('/role/insertRoleInfo', 'GET', index,'正在新增角色信息...',str)}, btn2: function () {layer.close();}});break;case 'edit':var id = 'roleTableId'; //获取表格idvar checkStatus = table.checkStatus(id) //获取选中行数据var data = checkStatus.data[0]; //获取选中行数据if (checkStatus.data.length == 0) { //判断notify.info('请选择要修改的角色信息', "vcenter", "shadow", false,1500);return false;}if (checkStatus.data.length > 1) {//判断notify.warning('只能选择一条数据进行修改', "vcenter", "shadow", false,1500);return false;}if (data.roleName==="超级管理员"){notify.warning('超级管理员不能进行修改', "vcenter", "shadow", false,1500);return false;}//调用数据修改方法updateFormInfo(data);break;case 'delete':var id = 'roleTableId';//获取表格idvar checkStatus = table.checkStatus(id)//获取选中行数据var data = checkStatus.data; // 获取选中的数据console.log(data);if (data.length == 0) {notify.info('请选择要删除的角色信息', "vcenter", "shadow", false,1500);return false;}if (data[0].roleName=="超级管理员"){notify.warning('超级管理员不能进行删除', "vcenter", "shadow", false,1500);return false;}deleteFormInfo(data);break;};});
添加,修改,删除的方法
  /** 方法整合调用* *//** 表单提交,这里设置五个参数:url, type, index,mes,str* */function submitForm(url, type, index,mes,str) {//获取表单数据var roleName = $("input[name='roleName']").val();var remark = $("textarea[name='remark']").val();var status = $("input[name='state']:checked").val();var roleState = $("input[name='roleState']:checked").val();console.log(status);console.log(roleState);//验证表单数据if (roleName === '') {notify.info('请填写角色名称', "vcenter", "shadow", false,1000);return false;}if (remark === '') {notify.info('请填写角色描述', "vcenter", "shadow", false,1000);return false;}if (status == null) {notify.info('请选择角色状态', "vcenter", "shadow", false,1000);return false;}if (roleState == null) {notify.info('请选择是否分配权限', "vcenter", "shadow", false,1000);return false;}// 判断是否分配权限,如果等于1才获取选中的节点,否则不获取if (str==='1'){//根据是否分配权限判断,如果等于1才获取选中的节点,否则不获取if (roleState === '1'){// 获取选中的节点var param = dtree.getCheckbarNodesParam("treeSelect");// 将选中的节点转换为字符串var mStr = param.map(node => node.nodeId).join(",");}}// 提交表单数据notify.loading(mes, "vcenter", "shadow", false);// 延迟执行,避免loading层显示过快setTimeout(function () {notify.destroyAll();$.ajax({url: url,type: type,data: {roleName: roleName,   // 角色名称remark: remark,       // 角色描述status: status,       //  角色状态:1:启用,0:禁用roleState: roleState, //角色状态:1:启用,0:禁用resource: mStr        // 将选中的节点转换为字符串},success: function (data) {if (data.code === 0) {notify.success(data.msg, "vcenter", "shadow", false);} else if (data.code === 1) {notify.warning(data.msg, "vcenter", "shadow", false);} else {notify.error(data.msg, "vcenter", "shadow", false);}}}).done(function () {setTimeout(function () {notify.destroyAll();layer.closeAll(index);parent.location.reload();}, 500);});}, 2000);}/** 修改数据方法* */function updateFormInfo(data) {layer.open({type: 1,title: '修改角色信息',content: $("#saveOrUpdateDiv"),area: ['660px', '450px'],closeBtn: false,//样式skin: 'class-layer-yellow',btn: ['<i class="fa fa-check"></i> 保存', '<i class="fa fa-mail-reply-all "></i> 取消'],success: function (layero, index) {//清空表单数据form.val("role-form", data);}, yes: function (index) {var str = $("input[name='r']").val();console.log(str);//调用方法提交表单submitForm('/role/updateRoleInfo?roleId=' + data.roleId, 'POST', index,'正在更新角色信息...',str)}, btn2: function () {layer.close();}})}/** 删除数据方法* */function deleteFormInfo(data) {layer.confirm('确定删除该数据么', function (index) {//执行删除操作notify.loading('正在删除数据信息...', "vcenter", "shadow", false);setTimeout(function () {//关闭loading加载notify.destroyAll();$.ajax({url: '/role/deleteRoleInfo',type: 'DELETE',data: JSON.stringify({ids: data}),contentType: "application/json",success: function (data) {if (data.code === 0) {notify.success(data.msg, "vcenter", "shadow", false);} else {notify.error(data.msg, "vcenter", "shadow", false);}}}).done(function () {setTimeout(function () {notify.destroyAll();layer.closeAll(index);parent.location.reload();//重载页面}, 500);});}, 2000)});}
添加,修改,删除的后端方法
Controller代码
/** 数据添加* @insertRoleInfo* */@GetMapping("/insertRoleInfo")// 定义一个方法,用于插入角色信息public ResultUtil insertRoleInfo(String roleName, String remark, Integer status,Integer roleState, String resource) {// 从请求参数中获取要删除的ID列表System.out.println(resource);try {// 判断传入的参数是否为空if (roleName != null && remark != null && status != null && roleState != null) {// 调用roleService的getRoleInfo方法,根据角色名查询角色信息RoleEntity roleEntity = roleService.getRoleInfo(roleName);// 如果查询到的角色信息不为空,说明角色名已存在if (roleEntity == null) {// 创建一个新的RoleEntity对象,并设置相关属性RoleEntity role = new RoleEntity();role.setRoleName(roleName);role.setRemark(remark);role.setStatus(status);role.setRoleState(roleState);role.setCreateTime(new Date());// 调用roleService的saveAndUpdateRoleInfo方法添加角色信息,并返回添加结果roleService.saveAndUpdateRoleInfo(role, resource);return ResultUtil.ok(0, "角色信息新增成功");}return ResultUtil.warning(1, "角色名称重复!请更换!");}return ResultUtil.warning(1, "表单提交信息错误");} catch (Exception e) {e.fillInStackTrace();return ResultUtil.error("角色信息新增失败");}}/** 数据更新* @updateRoleInfo* */@PostMapping("/updateRoleInfo")public ResultUtil updateRoleInfo(Integer roleId, String roleName, String remark,Integer status, Integer roleState, String resource) {//System.out.println("权限id" + roleId + "是否分配" + roleState);//System.out.println("菜单" + resource);//System.out.println(status+""+roleState);try {// 调用roleService的getRoleInfo方法,根据角色名查询角色信息RoleEntity roleEntity = roleService.getRoleInfo(roleName);// 如果查询到的角色信息不为空,说明角色名已存在if (roleEntity != null && !roleEntity.getRoleId().equals(roleId)) {return ResultUtil.warning(1, "角色名称重复!请更换!");}// 创建一个新的RoleEntity对象,并设置相关属性RoleEntity role = new RoleEntity();// 设置角色名称role.setRoleName(roleName);// 设置角色备注role.setRemark(remark);// 设置角色状态role.setStatus(status);// 设置权限状态role.setRoleState(roleState);// 设置更新时间role.setUpdateTime(new Date());// 设置角色IDrole.setRoleId(roleId);// 调用roleService的saveAndUpdateRoleInfo方法更新角色信息,并返回更新结果roleService.saveAndUpdateRoleInfo(role, resource);//返回成功信息return ResultUtil.ok(0, "角色信息更新成功");} catch (Exception e) {e.fillInStackTrace();return ResultUtil.error("角色信息更新失败");}}/** 数据删除操作* @deleteRoleInfo* */@DeleteMapping("/deleteRoleInfo")public ResultUtil deleteRoleInfo(@RequestBody Map<String, Object> params) {try {// 从请求参数中获取要删除的ID列表List<Integer> ids = (List<Integer>) params.get("ids");System.out.println("删除的数据id值" + ids);//批量查询角色信息List<RoleEntity> roleEntities = roleService.selectRoleInfo(ids);// 判断角色信息列表是否为空if (roleEntities.size() > 0) {// 遍历角色信息列表,删除角色与资源的关联关系for (RoleEntity roleEntity : roleEntities) {// 删除角色与资源的关联关系roleResourceService.deleteRoleResource(roleEntity.getRoleId());}}// 根据标识符列表查询要删除的数据roleService.deleteRoleInfo(ids);// 返回成功消息return ResultUtil.ok(0, "数据删除成功");} catch (Exception e) {e.printStackTrace();// 返回失败消息return ResultUtil.error("数据删除失败");}}
Service代码
/** 数据插入* @return* */void saveAndUpdateRoleInfo(RoleEntity role, String resource);/** 数据删除* */void deleteRoleInfo(List<Integer> ids);/** 查询所有菜单* */DataGridView listResource(Integer roleId);/** 根据名称查询角色* */RoleEntity getRoleInfo(String roleName);
ServiceImpl代码
   /** 数据添加和修改操作* */@Overridepublic void saveAndUpdateRoleInfo(RoleEntity role, String resource) {//System.out.println("role = " + resource);// 判断是否为添加操作if (role.getRoleId() == null){// 添加操作roleMapper.insertRoleInfo(role);// 获取添加的角色信息,根据当前角色名称获取角色信息RoleEntity roleEntity = roleMapper.getRoleInfo(role.getRoleName());//System.out.println("roleEntity = " + roleEntity);// 判断是否添加成功if (roleEntity != null) {// 如果资源字符串不为空且长度不为0if (resource != null && resource.length() != 0){// 将资源字符串按逗号分割String[] split = resource.split(",");for (String s : split) {// 创建角色资源实体对象RoleResourceEntity roleResourceEntity = new RoleResourceEntity();// 设置角色IDroleResourceEntity.setRoleId(roleEntity.getRoleId());// 设置资源IDroleResourceEntity.setResourceId(Integer.parseInt(s));// 插入角色资源信息roleResourceMapper.insertRoleResource(roleResourceEntity);}}}}else if (role.getRoleId() != null){// 修改操作roleMapper.updateRoleInfo(role);// 删除角色资源信息roleResourceMapper.deleteRoleResource(role.getRoleId());// 判断是否为空if (resource != null && resource.length() != 0){// 将资源字符串按逗号分割String[] split = resource.split(",");for (String s : split) {// 创建角色资源实体对象RoleResourceEntity roleResourceEntity = new RoleResourceEntity();// 设置角色IDroleResourceEntity.setRoleId(role.getRoleId());// 设置资源IDroleResourceEntity.setResourceId(Integer.parseInt(s));// 插入角色资源信息roleResourceMapper.insertRoleResource(roleResourceEntity);}}}}/** 数据删除操作* */@Overridepublic void deleteRoleInfo(List<Integer> ids) {roleMapper.deleteRoleInfo(ids);}/** 根据角色名称查询角色信息* */@Overridepublic RoleEntity getRoleInfo(String roleName) {return roleMapper.getRoleInfo(roleName);}
RoleResourceMapper
/** 添加角色资源* */void insertRoleResource(RoleResourceEntity roleResourceEntity);/** 根据角色ID删除角色资源* */void deleteRoleResource(Integer roleId);
RoleMapper
   /** 数据插入操作* @return* */void insertRoleInfo(RoleEntity role);/** 数据更新操作* @return* */void updateRoleInfo(RoleEntity role);/** 数据删除操作* @return* */void deleteRoleInfo(List<Integer> ids);/** 根据角色名查询角色信息* */RoleEntity getRoleInfo(String roleName);
RoleMapper.xml
 <!--数据添加操作insertRoleInfo--><insert id="insertRoleInfo">insert into sys_role(role_name,remark,status,create_time,role_state)values(#{roleName},#{remark},#{status},#{createTime},#{roleState})</insert><!--数据更新操作--><update id="updateRoleInfo" parameterType="RoleEntity">update sys_role<set><if test="roleName != null and roleName != ''">role_name = #{roleName},</if><if test="remark != null and remark != ''">remark = #{remark},</if><if test="status != null">status = #{status},</if><if test="updateTime != null">update_time = #{updateTime},</if><if test="roleState != null">role_state = #{roleState},</if></set>where roleId = #{roleId}</update><!--数据批量删除操作--><delete id="deleteRoleInfo"  parameterType="java.util.List">delete from sys_role where roleId in<foreach collection="list" item="r" separator="," open="(" close=")">#{r.roleId}</foreach></delete>
RoleResourceMapper.xml
 <!--添加角色资源--><insert id="insertRoleResource" parameterType="com.example.erp_project.entity.RoleResourceEntity">insert into sys_role_resource(roleId,resourceId)values(#{roleId},#{resourceId})</insert><!--根据id删除角色资源--><delete id="deleteRoleResource" parameterType="int">delete from sys_role_resourcewhere roleId = #{roleId}</delete><!--根据roleId查询数据--><select id="selectByRoleId" resultType="com.example.erp_project.entity.RoleResourceEntity">select *from sys_role_resourcewhere roleId = #{roleId}</select>

前端页面完整代码

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>角色信息管理</title><meta name="renderer" content="webkit"><link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{../static/favicon.ico}"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><link rel="stylesheet" th:href="@{../layui/css/layui.css}" media="all"><link rel="stylesheet" th:href="@{../css/public.css}" media="all"><!--    图标样式文件--><link rel="stylesheet" th:href="@{../lib/font-awesome-4.7.0/css/font-awesome.min.css}" media="all"><!--引入自定义的样式文件--><link rel="stylesheet" th:href="@{../css/custom/custom.css}" media="all"><!--第三方树组件--><link rel="stylesheet" th:href="@{../dist/dtree/font/dtreefont.css}" media="all"><link rel="stylesheet" th:href="@{../dist/dtree/dtree.css}" media="all">
</head>
<body>
<div class="layuimini-container"><div class="layuimini-main"><!-- 搜索表单信息--><fieldset class="table-search-fieldset"><legend>搜索信息</legend><div style="margin: 10px 10px 10px 10px"><form class="layui-form layui-form-pane"><div class="layui-form-item"><div class="layui-inline"><label class="layui-form-label">角色名称</label><div class="layui-input-inline"><input type="text" name="name" autocomplete="off" class="layui-input"lay-affix="clear"></div></div><div class="layui-inline"><label class="layui-form-label">角色状态</label><div class="layui-input-inline" style="width: 100px"><select name="status" lay-filter="aihao"><option value="">所有</option><option value="1">正常</option><option value="0">停用</option></select></div></div><div class="layui-inline"><label class="layui-form-label">权限状态</label><div class="layui-input-inline" style="width: 100px"><select name="roleState" lay-filter="aihao"><option value="">所有</option><option value="1">已分配</option><option value="0">未分配</option></select></div></div><div class="layui-inline"><label class="layui-form-label">创建日期</label><div class="layui-inline" id="laydate-rangeLinked"><div class="layui-input-inline" style="width: 100px"><input type="text" autocomplete="off" id="start-date" name="start"class="layui-input" placeholder="创建日期" readonly></div><div class="layui-form-mid">-</div><div class="layui-input-inline" style="width: 100px"><input type="text" autocomplete="off" id="end-date" name="end" class="layui-input"placeholder="结束日期" readonly></div></div></div><div class="layui-inline"><button type="submit" class="layui-btn layui-bg-green layui-btn-radius layui-btn-sm"lay-submitlay-filter="search-btn"><i class="fa fa-search"></i> 搜 索</button><button type="button" class="layui-btn layui-bg-orange layui-btn-radius layui-btn-sm"lay-on="reset-btn"><i class="fa fa-refresh"></i> 重置</button></div></div></form></div></fieldset><!--        表头表单--><script type="text/html" id="toolbar"><div class="layui-btn-container"><button class="layui-btn data-add-btn layui-btn-sm " lay-event="add"><iclass="fa fa-plus"></i> 新增</button><button class="layui-btn data-edit-btn layui-btn-sm " lay-event="edit"><iclass="fa fa-pencil-square-o"></i> 编辑</button><button class="layui-btn layui-btn-sm data-del-btn" lay-event="delete"><iclass="fa fa-times"></i> 删除</button></div></script><!--        表格--><table class="layui-hide" id="roleTableId" lay-filter="roleTableFilter"></table><!--        表格后的操作栏--><script type="text/html" id="TableBar"><!--如果权限状态为1、则显示编辑权限,编辑,删除按钮,如果为0,则显示分配权限,编辑,删除按钮-->{{#if(d.roleState=='1'&&d.roleName!="超级管理员"){}}<a class="layui-btn layui-btn-xs data-other-btn" lay-event="ed-role"><iclass="fa fa-pencil-square-o"></i> 权限</a><a class="layui-btn layui-btn-xs data-edit-btn" lay-event="edit"><iclass="fa fa-pencil-square-o"></i> 信息</a><a class="layui-btn layui-btn-xs data-del-btn" lay-event="delete"><iclass="fa fa-times"></i> 删除</a>{{#}else if(d.roleState=='0'&&d.roleName!="超级管理员"){}}<a class="layui-btn layui-btn-xs data-orange-btn" lay-event="add-role"><iclass="fa fa-sitemap"></i> 分配权限</a><a class="layui-btn layui-btn-xs data-edit-btn" lay-event="edit"><iclass="fa fa-pencil-square-o"></i> 信息</a><a class="layui-btn layui-btn-xs data-del-btn" lay-event="delete"><iclass="fa fa-times"></i> 删除</a>{{#}}}</script><!-- 添加和修改的弹出层开始 --><div style="display: none;padding: 20px" id="saveOrUpdateDiv"><form class="layui-form" lay-filter="role-form" id="role-form"><!--隐藏数据id值,用于数据更新使用--><input type="hidden" name="roleId" id="roleId"><div class="layui-form-item"><label class="layui-form-label">角色名称:</label><div class="layui-input-block"><input type="text" name="roleName" id="roleName" lay-verify="required"placeholder="请填写角色名称"autocomplete="off"class="layui-input" lay-affix="clear"></div></div><div class="layui-form-item"><label class="layui-form-label">角色描述:</label><div class="layui-input-block"><textarea name="remark" placeholder="请输入内容" class="layui-textarea"lay-affix="clear"></textarea></div></div><div class="layui-form-item"><label class="layui-form-label">角色状态:</label><div class="layui-input-block"><input type="radio" name="state" value="1" title="正常" checked><input type="radio" name="state" value="0" title="停用"></div></div><input type="hidden" name="r" id="r"><div class="layui-form-item"><label class="layui-form-label">分配权限:</label><div class="layui-input-block"><input type="radio" name="roleState" value="1" title="分配" lay-filter="role-status"><input type="radio" name="roleState" value="0" title="暂不分配"lay-filter="role-status" ></div></div></form></div><!-- 添加和修改的弹出层结束 --><!--分配权限的弹出层开始--><div style="display: none;padding: 20px" id="roleDiv"><div style="padding: 15px"><div class="layui-btn-container"><button type="button" class="layui-btn layui-btn-xs data-orange-btn"dtree-id="treeSelect" dtree-menu="checkAll"><i class="fa fa-check-square-o"></i> 全选</button><button type="button" class="layui-btn layui-btn-xs data-black-btn"dtree-id="treeSelect" dtree-menu="unCheckAll"><i class="fa fa-remove"></i> 取消全选</button><button class="layui-btn data-light-btn layui-btn-xs" dtree-id="treeSelect" dtree-menu="moveDown"><iclass="fa fa-expand"></i> 展开</button><button class="layui-btn data-grey-btn layui-btn-xs" dtree-id="treeSelect" dtree-menu="moveUp"><iclass="fa fa-compress"></i> 折叠</button></div><div class="layui-input-inline" style="width: 130px"><input type="text" class="layui-input" id="searchInput" placeholder="输入查询节点内容..."lay-affix="clear"style="height: 28px;font-size: 13px"></div><button class="layui-btn data-other-btn layui-btn-xs " id="search_btn"><i class="fa fa-search"></i> 搜索</button><button class="layui-btn data-other-btn layui-btn-xs " dtree-id="treeSelect" dtree-menu="refresh"><iclass="fa fa-refresh"></i> 刷新</button><div class="layui-form-item" style="padding: 15px"><ul id="treeSelect" class="dtree" data-id="0"></ul></div></div></div><!--分配权限的弹出层结束--></div>
</div>
<script th:src="@{../layui/layui.js}" charset="utf-8"></script>
<!--引用第三方插件(消息通知插件)-->
<script th:src="@{../dist/notify/notify.js}"></script>
<!--第三方树组件-->
<script th:src="@{../dist/dtree/dtree.js}"></script>
<script type="text/html" id="templet-switch"><!-- 这里的 checked 的状态值判断仅作为演示 -->{{# if(d.roleName != "超级管理员") {}}<input type="checkbox" name="status" value="{{= d.roleId }}" title="启用|停用" lay-skin="switch"style="background-color: #c2bddc"lay-filter="templet-status" {{=d.status== 1 ? "checked" : "" }}>{{# }}}
</script><script th:inline="none">layui.use(['form', 'table', 'notify','dtree'], function () {var $ = layui.jquery,form = layui.form,table = layui.table;var notify = layui.notify;var util = layui.util;var laydate = layui.laydate;var tree = layui.tree;var dtree = layui.dtree;/** 权限分配菜单* */form.on('radio(role-status)', function (data) {var elem = data.elem; // 获得 radio 原始 DOM 对象var checked = elem.checked; // 获得 radio 选中状态var value = elem.value; // 获得 radio 值var othis = data.othis; // 获得 radio 元素被替换后的 jQuery 对象//获取页面输入框的值,如果为空则赋值为0,否则赋值为输入框的值//将value赋值给隐藏域$("#r").val(value);//将value赋值给隐藏域,这里注意用于角色信息编辑页面,否则会报错,报的错误就是:Cannot read property 'checked' of nullvar roleId = $("#roleId").val();//获取隐藏域的值,如果为空则赋值为0,否则赋值为隐藏域的值if (!roleId) {roleId = 0;}//如果选中的是分配权限,然后调用 treeSelectData(roleId,1);方法加载菜单资源if (value==="1"){treeSelectData(roleId,1);//这里传递的roleId是0 查询的就是全部资源未选择,而编辑页面传递的就是选中数据的roleId}});/** 搜索栏日期选择* 日期范围 - 左右面板联动选择模式* */laydate.render({elem: '#laydate-rangeLinked',range: ['#start-date', '#end-date'],rangeLinked: true, // 开启日期范围选择时的区间联动标注模式 ---  2.8+ 新增theme: '#e5e5f6'});/** 点击重置按钮,重新加载当前页面* */util.on('lay-on', {"reset-btn": function () {//搜索页面重载表格数据//重载当前页面window.location.reload();},});/** 数据表渲染* */table.render({elem: '#roleTableId',url: '/role/getAllSelectRoleDate',toolbar: '#toolbar',defaultToolbar: false,cols: [[{type: "checkbox", width: 50},{field: 'roleName', title: '角色名称', align: "center"},{field: 'roleState', title: '权限状态', align: "center", templet: function (d) {if (d.roleName==="超级管理员"){return '<span class="layui-btn layui-btn-xs layui-btn-radius" style="color: #e64e81">不允许修改</span>';}else {if (d.roleState == 1) {return '<span class="layui-btn layui-btn-xs layui-btn-radius" ' +'style="background-color: #0a84b2;"  lay-event="eroa">已分配</span>';} else {return '<span class="layui-btn layui-btn-xs layui-btn-radius" ' +'style="background-color: #e5dbd7;" lay-event="area">未分配</span>';}}}},{field: 'remark', title: '角色描述', align: "center"},{field: 'status', title: '角色状态', align: "center", templet: '#templet-switch'},{field: 'createTime', title: '创建时间', align: "center"},{title: '操作', Width: 180, toolbar: '#TableBar', align: "center"}]],limits: [10, 15, 20, 25, 50, 100],limit: 10,page: true,text: {none: '抱歉!暂无相关数据'},loading: true,skin: 'grid'});/** 监听搜索操作* */form.on('submit(search-btn)', function (data) {//获取搜索栏中的数据var result = data.field;//执行搜索重载table.reload('roleTableId', {page: {curr: 1}, where: {roleName: result.name,status: result.status,startDate: result.start,endDate: result.end,roleState: result.roleState}}, 'data');return false;});/** 头部操作栏监听* */table.on('toolbar(roleTableFilter)', function (obj) {switch (obj.event) {case 'add':layer.open({type: 1,title: '新增角色',content: $("#saveOrUpdateDiv"),area: ['660px', '450px'],closeBtn: false,//样式skin: 'class-layer-sea',btn: ['<i class="fa fa-check"></i> 新增', '<i class="fa fa-mail-reply-all "></i> 取消'],success: function (layero, index) {//清空表单数据$("#role-form")[0].reset();},yes: function (index) {var str = $("#r").val();submitForm('/role/insertRoleInfo', 'GET', index,'正在新增角色信息...',str)}, btn2: function () {layer.close();}});break;case 'edit':var id = 'roleTableId'; //获取表格idvar checkStatus = table.checkStatus(id) //获取选中行数据var data = checkStatus.data[0]; //获取选中行数据if (checkStatus.data.length == 0) { //判断notify.info('请选择要修改的角色信息', "vcenter", "shadow", false,1500);return false;}if (checkStatus.data.length > 1) {//判断notify.warning('只能选择一条数据进行修改', "vcenter", "shadow", false,1500);return false;}if (data.roleName==="超级管理员"){notify.warning('超级管理员不能进行修改', "vcenter", "shadow", false,1500);return false;}//调用数据修改方法updateFormInfo(data);break;case 'delete':var id = 'roleTableId';//获取表格idvar checkStatus = table.checkStatus(id)//获取选中行数据var data = checkStatus.data; // 获取选中的数据console.log(data);if (data.length == 0) {notify.info('请选择要删除的角色信息', "vcenter", "shadow", false,1500);return false;}if (data[0].roleName=="超级管理员"){notify.warning('超级管理员不能进行删除', "vcenter", "shadow", false,1500);return false;}deleteFormInfo(data);break;};});/** 表格状态监听栏** */table.on('tool(roleTableFilter)', function (obj) {//编辑需要将数据赋值到页面var data = obj.data;//定义数组来存放obj.data,进行删除操作var dataArr = [];//数组赋值dataArr.push(obj.data);//数据编辑操作if (obj.event === 'edit') {updateFormInfo(data);return false;} else if (obj.event === 'delete') {deleteFormInfo(dataArr);} else if (obj.event === 'eroa') {layer.confirm('该角色已经分配权限,是否编辑权限?', function (index) {treeSelectData(data.roleId,0);})} else if (obj.event === 'area') {layer.confirm('该角色还未分配权限,立即分配权限?', function (index) {treeSelectData(data.roleId,0);})} else if (obj.event === 'add-role') {treeSelectData(data.roleId,0);} else if (obj.event === 'ed-role') {treeSelectData(data.roleId,0);}});/** 开关状态* */form.on('switch(templet-status)', function (obj) {var id = this.value;var name = this.name;var status = obj.elem.checked ? 1 : 0;$.ajax({url: '/role/updateRoleStatus',type: 'POST',data: {roleId: id,status: status},success: function (result) {if (result.code ===0) {// notify.success(result.msg, "vcenter", "shadow", false, 1500); // 成功提示layer.tips(result.msg, obj.othis);// 成功提示} else {// notify.warning(result.msg, "vcenter", "shadow", false, 1500);// 警告提示layer.tips(result.msg, obj.othis);// 警告提示}}});});/** 方法整合调用* *//** 表单提交,这里设置五个参数:url, type, index,mes,str* */function submitForm(url, type, index,mes,str) {//获取表单数据var roleName = $("input[name='roleName']").val();var remark = $("textarea[name='remark']").val();var status = $("input[name='state']:checked").val();var roleState = $("input[name='roleState']:checked").val();console.log(status);console.log(roleState);//验证表单数据if (roleName === '') {notify.info('请填写角色名称', "vcenter", "shadow", false,1000);return false;}if (remark === '') {notify.info('请填写角色描述', "vcenter", "shadow", false,1000);return false;}if (status == null) {notify.info('请选择角色状态', "vcenter", "shadow", false,1000);return false;}if (roleState == null) {notify.info('请选择是否分配权限', "vcenter", "shadow", false,1000);return false;}// 判断是否分配权限,如果等于1才获取选中的节点,否则不获取if (str==='1'){//根据是否分配权限判断,如果等于1才获取选中的节点,否则不获取if (roleState === '1'){// 获取选中的节点var param = dtree.getCheckbarNodesParam("treeSelect");// 将选中的节点转换为字符串var mStr = param.map(node => node.nodeId).join(",");}}// 提交表单数据notify.loading(mes, "vcenter", "shadow", false);// 延迟执行,避免loading层显示过快setTimeout(function () {notify.destroyAll();$.ajax({url: url,type: type,data: {roleName: roleName,   // 角色名称remark: remark,       // 角色描述status: status,       //  角色状态:1:启用,0:禁用roleState: roleState, //角色状态:1:启用,0:禁用resource: mStr        // 将选中的节点转换为字符串},success: function (data) {if (data.code === 0) {notify.success(data.msg, "vcenter", "shadow", false);} else if (data.code === 1) {notify.warning(data.msg, "vcenter", "shadow", false);} else {notify.error(data.msg, "vcenter", "shadow", false);}}}).done(function () {setTimeout(function () {notify.destroyAll();layer.closeAll(index);parent.location.reload();}, 500);});}, 2000);}/** 修改数据方法* */function updateFormInfo(data) {layer.open({type: 1,title: '修改角色信息',content: $("#saveOrUpdateDiv"),area: ['660px', '450px'],closeBtn: false,//样式skin: 'class-layer-yellow',btn: ['<i class="fa fa-check"></i> 保存', '<i class="fa fa-mail-reply-all "></i> 取消'],success: function (layero, index) {//清空表单数据form.val("role-form", data);}, yes: function (index) {var str = $("input[name='r']").val();console.log(str);//调用方法提交表单submitForm('/role/updateRoleInfo?roleId=' + data.roleId, 'POST', index,'正在更新角色信息...',str)}, btn2: function () {layer.close();}})}/** 删除数据方法* */function deleteFormInfo(data) {layer.confirm('确定删除该数据么', function (index) {//执行删除操作notify.loading('正在删除数据信息...', "vcenter", "shadow", false);setTimeout(function () {//关闭loading加载notify.destroyAll();$.ajax({url: '/role/deleteRoleInfo',type: 'DELETE',data: JSON.stringify({ids: data}),contentType: "application/json",success: function (data) {if (data.code === 0) {notify.success(data.msg, "vcenter", "shadow", false);} else {notify.error(data.msg, "vcenter", "shadow", false);}}}).done(function () {setTimeout(function () {notify.destroyAll();layer.closeAll(index);parent.location.reload();//重载页面}, 500);});}, 2000)});}/** 权限树生成* *///初始化树function initTree(roleId) {console.log(roleId);var DTree = dtree.render({elem: "#treeSelect",dataStyle: "layuiStyle",  //使用layui风格的数据格式response: {message: "msg", statusCode: 0},  //修改response中返回数据的定义dataFormat: "list",  //配置data的风格为listcheckbar: true,//复选框checkbarType: "all", // 默认就是allcheckbarData: "choose",menubar: true,//菜单栏menubarTips: {group: ["moveDown", "moveUp", "refresh", "checkAll", "unCheckAll", "searchNode"], //按钮组},skin: "zdy", // 自定义风格line: true,  // 显示树线initLevel: 1,//默认展开层级为1ficon: ["1", "-1"], // 显示非最后一级节点图标,隐藏最后一级节点图标icon: "2",//修改二级图标样式url: "/role/getAllSelectResourceDate?roleId=" + roleId});/** 搜索框方法* */$("#search_btn").unbind("click");$("#search_btn").click(function () {var value = $("#searchInput").val();if (value) {var flag = DTree.searchNode(value); // 内置方法查找节点if (!flag) {layer.msg("该名称节点不存在!刷新后重试!");}} else {DTree.menubarMethod().refreshTree(); // 内置方法刷新树}});}/** 权限树弹出层方法* 这里传递两个参数一个是根据roleId(用于获取数据将权限进行分配),* 一个是根据status(用于判断是添加和修改页面,还是权限直接分配页面)。* */function treeSelectData(roleId,status) {layer.open({type: 1,title: '权限分配',content: $("#roleDiv"),area: ['360px', '520px'],closeBtn: false,btnAlign: 'c',//样式skin: 'class-layer-orange',btn: ['<i class="fa fa-check"></i> 确认分配', '<i class="fa fa-times "></i> 关闭'],success: function () {initTree(roleId);},yes: function (index) {var params = dtree.getCheckbarNodesParam("treeSelect"); // 获取选中值if (params.length == 0) {//判断是否选中节点notify.info("至少选择一个节点!" ,"vcenter", "shadow", false,1000);return false;}//判断是添加和修改页面,还是权限直接分配页面,如果为1则表示是在角色信息,添加,修改页面的操作。if (status == 1){notify.loading('正在分配权限...', "vcenter", "shadow", false);setTimeout(function () {notify.destroyAll();//关闭loading加载notify.success('分配成功!', "vcenter", "shadow", false,1000);//设置提示框,"提示信息","位置", "样式", "是否显示关闭按钮", "显示时间"//关闭当前页面layer.closeLast('page');},1000)}else {/** 页面分配权限,及角色信息页面的权限分配* */// 将选中的节点转换为字符串var mStr = params.map(node => node.nodeId).join(",");notify.loading('正在分配权限...', "vcenter", "shadow", false);setTimeout(function () {notify.destroyAll();//关闭loading加载//传递数据到后端$.ajax({url: '/role/updateRoleResource',type: 'POST',data: {roleId: roleId, resourceIds: mStr},success: function (data) {if (data.code === 0) {notify.success(data.msg, "vcenter", "shadow", false,1000);} else if (data.code === 1){notify.warning(data.msg, "vcenter", "shadow", false,1000);} else {notify.error(data.msg, "vcenter", "shadow", false,1000);}}}) .done(function () {setTimeout(function () {notify.destroyAll();layer.closeAll();table.reload('roleTableId');//重载表格}, 1000);});},2000)}}, btn2: function () {if (status == 1){//清空 radio 值form.val("role-form", {"roleState": ""});notify.info("已取消操作!", "vcenter", "shadow", false,1000);layer.close();}else {notify.info("已取消操作!", "vcenter", "shadow", false,1000);layer.closeAll();}}});}})
</script></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/839310.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始傅里叶变换

从零开始傅里叶变换 1 Overview2 傅里叶级数2.1 基向量2.2 三角函数系表示 f ( t ) f(t) f(t)2.2.1 三角函数系的正交性2.2.2 三角函数系的系数 2.3 复指数函数系表示 f ( t ) f(t) f(t)2.3.1 复指数函数系的系数2.3.2 复指数函数系的正交性 2.4 傅里叶级数总结 3 傅里叶变换…

如何将手机中的音乐转移到 SD 卡上?轻松传输音乐

概括 如何将音乐从手机转移到 SD 卡&#xff1f;我们的智能手机可以充当个人点唱机&#xff0c;因此有效管理我们的音乐库变得至关重要。无论您是存储空间不足还是只是想整理您的音乐收藏&#xff0c;将音乐从手机传输到 SD 卡都是一个实用的解决方案。 在本指南中&#xff0…

二叉树的递归实现及例题

目录 遍历方式 示例 原理 前序遍历示例 二叉树的节点个数 原理 层序遍历 原理 这样做的目的是 判断完全二叉树 例题 ​编辑 思路 代码 遍历方式 二叉树的遍历方式可分为&#xff1a; 前序遍历&#xff1a;先访问根&#xff0c;访问左子树&#xff0c;在访问右子…

浏览器的下载行为基本原理

浏览器解析 在使用浏览器访问某些资源时&#xff0c;有些资源是直接下载有些资源是直接打开。例如前端的html&#xff0c;xml&#xff0c;css&#xff0c;图片等资源都是直接打开&#xff0c;而txt&#xff0c;excel等文件是直接下载。那么如何控制访问一个资源时是下载文件还…

App Inventor 2 如何接入ChatGPT:国内访问OpenAI的最佳方式

如何接入OpenAI 由于国内无法访问OpenAI&#xff0c;KX上网可选大陆及香港&#xff08;被屏蔽&#xff09;以外才行。因此对于大多数人来说&#xff0c;想体验或使用ChatGPT就不太便利&#xff0c;不过App Inventor 2 为我们提供了相对便利的一种方式&#xff0c;即“试验性质…

C# run Node.js

C# run nodejs Inter-Process Communication&#xff0c;IPC Process类 启动Node.js进程&#xff0c;通过标准输入输出与其进行通信。 // n.js// 监听来自标准输入的消息 process.stdin.on(data, function (data) {// 收到消息后&#xff0c;在控制台输出并回复消息console.l…

连锁服装门店补货一般怎样的流程

连锁服装门店的补货流程通常包括以下四个关键步骤&#xff1a; 分析销售数据和库存情况 首先&#xff0c;连锁服装门店需要定期分析销售数据和库存情况。通过销售数据可以了解各款商品的销售情况、热销款式和滞销款式等信息。同时&#xff0c;需要检查每个门店的库存情况&…

06Django项目--用户管理系统--新增

对应视频链接点击直达 06Django项目--用户管理系统--新增 对应视频链接点击直达模块构思a&#xff0c;用户信息的构成&#xff08;表结构设计&#xff09;b&#xff0c;models里面的设计 用户新增页面设计a&#xff0c;先在模版里面选一个新增的样式b&#xff0c;然后删除该页面…

win32-鼠标消息、键盘消息、计时器消息、菜单资源

承接前文&#xff1a; win32窗口编程windows 开发基础win32-注册窗口类、创建窗口win32-显示窗口、消息循环、消息队列 本文目录 键盘消息键盘消息的分类WM_CHAR 字符消息 鼠标消息鼠标消息附带信息 定时器消息 WM_TIMER创建销毁定时器 菜单资源资源相关菜单资源使用命令消息的…

网络原理3

运营商路由器&#xff0c;也可以把它当做一个NAT设备它就会对中间经过的数据包&#xff0c;进行网络地址转换当内网设备经过运营商路由器访问外网的时候就会把IP数据包中的源ip&#xff0c;替换成它自己的ip. 我的电脑要发送一个数据给cctalk服务器此时&#xff0c;我的电脑上就…

论文精读--InstructGPT

模型效果取决于数据效果&#xff0c;但在精细度上控制不够&#xff0c;只是大力出奇迹&#xff0c;这样有很大的问题&#xff1a; &#xff08;1&#xff09;数据量太多或者没有这方面的数据&#xff0c;模型学不会怎么办 &#xff08;2&#xff09;安全性问题&#xff0c;模…

大模型的实践应用24-LLaMA-Factory微调通义千问qwen1.5-1.8B模型的实例

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用24-LLaMA-Factory微调通义千问qwen1.5-1.8B模型的实例, LLaMA-Factory是一个专门用于大语言模型微调的框架,它支持多种微调方法,如LoRA、QLoRA等,并提供了丰富的数据集和预训练模型,便于用户进行模型微调。通义千问…

【Java】全套云HIS(医院信息管理系统)可对接医保 采用云端SaaS模式部署

【Java】全套云HIS&#xff08;医院信息管理系统&#xff09;可对接医保 采用云端SaaS模式部署 SaaS 模式的云 HIS 更适用于基层医疗机构&#xff0c;而传统的 HIS 已经在大中型医疗机构大规模应用。过去&#xff0c;国内的大中型医疗机构投入了大量的资金来进行信息化系统建设…

基于python实现搜索的目标站点内容监测系统

基于python实现搜索的目标站点内容监测系统 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 登录页面 后台的登录一般是为了管理员的管理方便进行一个用户权限的验证。也是为管理员提供的唯…

mysqldump提示Using a password on the command line interface can be insecured的解决办法

mysql数据库备份一句话执行命令 mysqldump --all-databases -h127.0.0.1 -uroot -p123456 > allbackupfile.sql 提示如下提示 [rootyfvyy5b2on3knb8q opt]# mysqldump --all-databases -h127.0.0.1 > allbackupfile.sql mysqldump: Couldnt execute SELECT COLUMN_NA…

Stable Diffusion vs Midjunery的区别和选择

现在网上最多的关于AI绘画的工具莫过于stable diffusion&#xff08;sd&#xff09;和midjunery&#xff08;mj&#xff09;了&#xff0c;最近尝试了一番&#xff0c;稍作总结吧算是。我们对于工具的使用通常考虑的无非就是好不好用&#xff0c;效果如何&#xff0c;当然还有费…

linux查看硬盘信息

1、查看挂接的分区状态 [rootMaster ~]# fdisk -l |grep Disk 2、查看硬盘和分区分布 [rootMaster ~]# lsblk 3、查看硬盘和分区的详细信息 [rootMaster ~]# fdisk -l 4、查看挂接的分区状态 [rootMaster ~]# swapon -s 5、查看硬盘使用情况 [rootMaster ~]# df -hT 6、硬…

A股翻车现场

英伟达业绩炸裂&#xff0c;但今天A股这边不仅没喝着汤&#xff0c;还再度上演大型翻车现场&#xff0c;人家不仅股价大涨7个点还站上1000美元大关&#xff0c; 而咱A股里的英伟达&#xff0c;AI&#xff0c;TMT相关概念股&#xff0c;包括工业&#xff08;富联&#xff09;&am…

92.网络游戏逆向分析与漏洞攻防-游戏技能系统分析-利用哈希表实现快速读取文本内容

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

Kafka-ACK机制(ack应答原理、冥等性、事务)

Kafka-ACK机制 Kafka中的ACK&#xff08;Acknowledgement&#xff09;机制是用于保证消息可靠传递的关键组件之一。在生产者发送消息到Kafka集群时&#xff0c;ACK机制决定了何时认为消息已经成功发送。这个机制非常重要&#xff0c;因为它影响了生产者对消息发送的信心以及消费…