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

news/2024/7/14 19:37:09/文章来源:https://blog.csdn.net/m0_46590717/article/details/139116518

角色菜单

      • 相关组件方法
      • 效果图
      • MySQL
      • 代码实现
      • 资源菜单树组件实现
        • 权限树方法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

效果图

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

MySQL

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

代码实现

资源菜单树组件实现

权限树方法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.luyixian.cn/news_show_1053177.aspx

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

相关文章

斯坦福大学ALOHA家务机器人团队发布了最新研究成果—YAY Robot语言交互式操作系统

ALOHA YAY 演示视频-智能佳 斯坦福的ALOHA家务机器人团队&#xff0c;发布了最新研究成果—Yell At Your Robot&#xff08;简称YAY&#xff09;&#xff0c;有了它&#xff0c;机器人的“翻车”动作&#xff0c;只要喊句话就能纠正了&#xff01; 标ALOHA2协作平台题 而且机器…

破解微信校验难题,Xinstall助你轻松实现Universal Link功能!

在移动互联网时代&#xff0c;App的推广和运营离不开各种技术手段的支持。其中&#xff0c;Universal Link作为连接App和网页的重要桥梁&#xff0c;被广大开发者所青睐。然而&#xff0c;很多开发者在使用Universal Link时遇到了微信校验不通过的问题&#xff0c;这不仅影响了…

数据库语法树优化

目录 一、σ、π、⋈ 1.选择σ 2.投影π 3.连接⋈ 二、 构建语法树 ① 解读sql语句 ② 写出关系代数表达式 ③ 画出语法树 三、优化语法树 四、练习 语法树优化方法 一、σ、π、⋈ 1.选择σ 选择就是在关系R中选择满足给定条件的诸元组。 通过条件SdeptIS选择出系别…

基于C#开发web网页管理系统模板流程-主界面管理员录入和编辑功能完善

前言 紧接上篇->基于C#开发web网页管理系统模板流程-登录界面和主界面_c#的网页编程-CSDN博客 已经完成了登录界面和主界面&#xff0c;本篇将完善主界面的管理员录入和编辑功能&#xff0c;事实上管理员录入和编辑的设计套路适用于所有静态表的录入和编辑 首先还是介绍一下…

Android环境下Mesa初始化流程重学习之eglInitialize

Mesa初始化流程重学习之eglInitialize 引言 说来也惭愧&#xff0c;Mesa搞了这么久了&#xff0c;每次都想深入下&#xff0c;可是每次都是浅尝辄止了。这次趁着有了一定的闲暇时间并且有了调试景嘉微显卡的机会&#xff0c;还是想重新学习下&#xff0c;深入研究下&#xff0…

【软件设计师】——5.数据库系统

目录 5.1 基本概念 5.2 三级模式两级映射 5.3 设计过程和数据模型 5.4 关系代数 5.5 完整性约束 5.6 规范化和反规范化 5.7 控制功能 5.8 SQL语言 5.9 数据库安全 5.10 数据备份 5.11 数据库故障与恢复 5.12 数据仓库、数据挖掘和大数据 5.1 基本概念 相关术语 候选…

12.可视化实现

时间过的很快,不知不觉已到第十二章。经过前面教程的讲解和实践,数据接入服务的功能已初步完成。 此章节将通过可视化的实现,对设备接入进行监控,实时监听设备的接入情况及设备的在线时长。 并且可以通过订阅按钮、取消订阅按钮、查看数据按钮,对上报数据进行实时的跟踪…

AWS容器之Amazon ECS

Amazon Elastic Container Service&#xff08;Amazon ECS&#xff09;是亚马逊提供的一种完全托管的容器编排服务&#xff0c;用于在云中运行、扩展和管理Docker容器化的应用程序。可以理解为Docker在云中对应的服务就是ECS。

OC IOS 文件解压缩预览

热很。。热很。。。。夏天的城市只有热浪没有情怀。。。 来吧&#xff0c;come on。。。 引用第三方库&#xff1a; pod SSZipArchive 开发实现&#xff1a; 一、控制器实现 头文件控制器定义&#xff1a; // // ZipRarViewController.h // // Created by carbonzhao on 2…

手搓顺序表(C语言)

目录 SeqList.h SeqList.c 头插尾插复用任意位置插入 头删尾删复用任意位置删除 SLtest.c 测试示例 顺序表优劣分析 SeqList.h //SeqList.h#pragma once#include <stdio.h> #include <assert.h> #include <stdlib.h> #define IN_CY 3typedef int S…

系统管理、磁盘分区

系统管理 业务层面&#xff1a;为了满足一定的需求所做的特定操作。 硬盘是什么&#xff0c;硬盘的作用&#xff1a; **硬盘&#xff1a;**计算机的存储设备&#xff0c;机械硬盘是由一个或者多个磁性的盘组成&#xff0c;可以在盘片上进行数据的读写。 连接方式&#xff1a…

开源VS闭源:谁将引领AI大模型的新时代?

一、引言 随着人工智能技术的飞速发展&#xff0c;AI大模型已成为推动这一浪潮的核心动力。在AI大模型的发展过程中&#xff0c;开源与闭源两种不同的发展路径一直备受关注。本文将深入探讨这两种路径的优劣势&#xff0c;分析它们对AI大模型发展的影响&#xff0c;并预测谁将…

深入了解 CSS 预处理器 Sass

今天我们来深入探讨一下 CSS 预处理器 Sass。我们将学习什么是 Sass,如何使用它,以及它是如何工作的。 什么是 Sass? Sass 是 syntactically awesome style sheets 的缩写,是一种 CSS 预处理器。它是 CSS 的扩展,为基础 CSS 增加了更多的功能和优雅。普通的 CSS 代码很容…

从git上拉取项目进行操作

1.Git的概念 Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速的处理从很小到非常大的项目版本管理。它实现多人协作的机制是利用clone命令将项目从远程库拉取到本地库&#xff0c;做完相应的操作后再利用push命令从本地库将项目提交至远程库。 2.Git的工作流程…

惯性测量单元M-G370系列广泛用于工业系统各个领域

爱普生现已推出型号为M-G370系列的高稳定性、高精度及极小尺寸封装的惯性测量单元(IMU)&#xff0c;可广泛应用于工业系统的各个领域。 为了节省PCB的面积和产品空间&#xff0c;M-G370系列性测量单元设计精巧&#xff0c;且具有6个自由度:三轴角速率和三轴线性加速度&…

七大获取免费https证书的方式

想要实现https访问最简单有效的的方法就是安装SSL证书。只要证书正常安装上以后&#xff0c;浏览器就不会出现网站不安全提示或者访问被拦截的情况。下面我来教大家怎么去获取免费的SSL证书&#xff0c;又如何安装证书实现https访问。 一、选择免费SSL证书提供商 有多家机构提…

揭秘:如何使用Python统计女友生日还剩几天?

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;为何需要统计生日天数&#xff1f; 二、需求分析与准备 1. 用户输入格…

失落的方舟台服账号怎么注册 失落的方舟台服注册收不到验证码

《失落的方舟》&#xff08;Lost Ark&#xff09;是由韩国Smilegate公司研发的一款大型多人在线角色扮演游戏&#xff08;MMORPG&#xff09;。该游戏以其精美的画面、丰富的剧情、动作类游戏的战斗手感以及广阔的开放世界而著称&#xff0c;自发布以来便吸引了全球众多游戏玩家…

黑马python-面向对象程序设计

1.定义类 class 类名&#xff1a; 代码 ….. 注意&#xff1a;类名要满足标识符命名规则&#xff0c;同时遵循大驼峰命名习惯 2.self&#xff1a; self指调用该函数的对象 3.创建对象 对象名类&#xff08;&#xff09; 4.添加获取对象属性 对象名.属性名值 5._init_()方法&…

享受当下,还是留待未来?一项fMRI与眼动追踪技术的联合研究

摘要 时间贴现(temporal discount)是指个体对奖励的估计会随着时间流逝而下降的心理现象。具体而言&#xff0c;当获得奖励的时间以日期(日期条件&#xff1b;例如&#xff0c;2023年6月8日)而不是延迟(延迟条件&#xff1b;例如&#xff0c;30天)呈现时&#xff0c;贴现率较低…