浏览代码

解决vue获取浏览器缓存问题。增加用户列表分配角色功能

xusl 2 年之前
父节点
当前提交
600d4fcd22
共有 42 个文件被更改,包括 1139 次插入514 次删除
  1. 0 2
      backend/src/main/java/com/jiayue/ssi/config/MybatisPlusConfig.java
  2. 118 0
      backend/src/main/java/com/jiayue/ssi/controller/IpBlacklistController.java
  3. 10 11
      backend/src/main/java/com/jiayue/ssi/controller/SysMenuController.java
  4. 26 2
      backend/src/main/java/com/jiayue/ssi/controller/SysRoleController.java
  5. 46 1
      backend/src/main/java/com/jiayue/ssi/controller/SysUserController.java
  6. 3 0
      backend/src/main/java/com/jiayue/ssi/entity/SysBlacklist.java
  7. 6 0
      backend/src/main/java/com/jiayue/ssi/entity/SysRole.java
  8. 5 0
      backend/src/main/java/com/jiayue/ssi/entity/SysUser.java
  9. 45 0
      backend/src/main/java/com/jiayue/ssi/entity/SysUserRole.java
  10. 2 1
      backend/src/main/java/com/jiayue/ssi/filter/InterfaceLimitFilter.java
  11. 65 0
      backend/src/main/java/com/jiayue/ssi/mapper/SysUserRoleMapper.java
  12. 7 0
      backend/src/main/java/com/jiayue/ssi/service/SysMenuService.java
  13. 13 0
      backend/src/main/java/com/jiayue/ssi/service/SysUserRoleService.java
  14. 8 0
      backend/src/main/java/com/jiayue/ssi/service/SysUserService.java
  15. 0 95
      backend/src/main/java/com/jiayue/ssi/service/impl/PermissionService.java
  16. 5 0
      backend/src/main/java/com/jiayue/ssi/service/impl/SysLogininforServiceImpl.java
  17. 21 17
      backend/src/main/java/com/jiayue/ssi/service/impl/SysMenuServiceImpl.java
  18. 5 0
      backend/src/main/java/com/jiayue/ssi/service/impl/SysOperLogServiceImpl.java
  19. 6 306
      backend/src/main/java/com/jiayue/ssi/service/impl/SysRoleServiceImpl.java
  20. 16 0
      backend/src/main/java/com/jiayue/ssi/service/impl/SysUserRoleServiceImpl.java
  21. 35 0
      backend/src/main/java/com/jiayue/ssi/service/impl/SysUserServiceImpl.java
  22. 4 0
      backend/src/main/java/com/jiayue/ssi/util/IPUtils.java
  23. 2 1
      backend/src/main/resources/mapper/system/SysMenuMapper.xml
  24. 1 1
      backend/src/main/resources/mapper/system/SysRoleMapper.xml
  25. 7 1
      backend/src/main/resources/mapper/system/SysRoleMenuMapper.xml
  26. 50 0
      backend/src/main/resources/mapper/system/SysUserRoleMapper.xml
  27. 二进制
      ui/public/favicon.ico
  28. 27 0
      ui/public/index.html
  29. 1 1
      ui/src/directive/permission/hasPermi.js
  30. 1 1
      ui/src/permission.js
  31. 1 1
      ui/src/store/modules/permission.js
  32. 1 1
      ui/src/utils/auth.js
  33. 9 6
      ui/src/utils/request.js
  34. 1 1
      ui/src/views/dashboard/index.vue
  35. 4 1
      ui/src/views/login/index.vue
  36. 276 0
      ui/src/views/sysManager/ipBlacklist/index.vue
  37. 75 32
      ui/src/views/sysManager/roleManager/index.vue
  38. 7 4
      ui/src/views/sysManager/sysParameter/index.vue
  39. 206 25
      ui/src/views/sysManager/userManager/index.vue
  40. 1 1
      ui/src/views/sysManager/userManager/profile/index.vue
  41. 1 1
      ui/src/views/sysManager/userManager/profile/resetPwd.vue
  42. 22 1
      ui/vue.config.js

+ 0 - 2
backend/src/main/java/com/jiayue/ssi/config/MybatisPlusConfig.java

@@ -4,11 +4,9 @@ import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
 
-import com.jiayue.ssi.mapper.SysBlacklistMapper;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import javax.annotation.Resource;
 
 
 /**

+ 118 - 0
backend/src/main/java/com/jiayue/ssi/controller/IpBlacklistController.java

@@ -0,0 +1,118 @@
+package com.jiayue.ssi.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jiayue.ssi.annotation.AgainVerify;
+import com.jiayue.ssi.annotation.OperateLog;
+import com.jiayue.ssi.backenum.AuditType;
+import com.jiayue.ssi.backenum.BusinessType;
+import com.jiayue.ssi.constant.CacheConstants;
+import com.jiayue.ssi.entity.SysBlacklist;
+import com.jiayue.ssi.service.SysBlacklistService;
+import com.jiayue.ssi.util.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * ip黑名单接口
+ *
+ * @author xsl
+ * @since 2023/03/13
+ */
+@RestController
+@RequestMapping("/ipBlacklistController")
+@Slf4j
+public class IpBlacklistController {
+    @Autowired
+    SysBlacklistService sysBlacklistService;
+
+    /**
+     * 获取ip列表分页信息
+     *
+     * @return 用户信息
+     */
+    @GetMapping(value = "/getAll")
+    @PreAuthorize("@ss.hasPermi('system:ipblacklist:list')")
+    public ResponseVO getAll(Integer currentPage, Integer pageSize, String ip) {
+        try {
+            QueryWrapper<SysBlacklist> wrapper = new QueryWrapper<>();
+            if (StringUtils.isNotEmpty(ip)){
+                if (!IPUtils.isIP(ip)) {
+                    return ResponseVO.fail("查询条件ip不合法!");
+                }
+                wrapper.eq("ip", ip);
+            }
+            Page<SysBlacklist> result = sysBlacklistService.page(new Page<>(currentPage, pageSize), wrapper);
+            return ResponseVO.success(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("获取ip列表异常");
+            return ResponseVO.error(null);
+        }
+    }
+
+    /**
+     * 新增ip
+     */
+    @PostMapping(value = "/addIp")
+    @OperateLog(title = "黑名单管理", businessType = BusinessType.INSERT, auditType = AuditType.SYS)
+    @PreAuthorize("@ss.hasPermi('system:ipblacklist:add')")
+    public ResponseVO addIp(String ip) {
+        if (!IPUtils.isIP(ip)) {
+            return ResponseVO.fail("ip不合法,不能添加!");
+        }
+        SysBlacklist sysBlacklist = new SysBlacklist();
+        sysBlacklist.setIp(ip);
+        sysBlacklist.setIpTime(new Date());
+        sysBlacklist.setAddBy(SecurityContextUtil.getSysUser().getUsername());
+        try {
+            boolean bo = sysBlacklistService.save(sysBlacklist);
+            if (bo) {
+                return ResponseVO.success("添加ip成功");
+            } else {
+                log.error("添加ip失败");
+                return ResponseVO.fail("添加ip失败");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("添加ip异常");
+            return ResponseVO.error(e);
+        }
+    }
+
+    /**
+     * 删除用户信息
+     */
+    @PostMapping(value = "/delIp")
+    @OperateLog(title = "黑名单管理", businessType = BusinessType.DELETE, auditType = AuditType.SYS)
+    @PreAuthorize("@ss.hasPermi('system:ipblacklist:remove')")
+    public ResponseVO delIp(String id) {
+        if (StringUtils.isEmpty(id)) {
+            return ResponseVO.fail("id不能为空!");
+        }
+        // id获取ip信息
+        SysBlacklist sysBlacklist = sysBlacklistService.getById(id);
+        if (sysBlacklist == null) {
+            return ResponseVO.fail("不能执行删除ip操作!");
+        }
+        try {
+            boolean bo = sysBlacklistService.removeById(Integer.parseInt(id));
+            if (bo) {
+                CacheConstants.blacklistMap.remove(sysBlacklist.getIp());
+                return ResponseVO.success("删除ip成功");
+            } else {
+                log.error("删除用户信息失败");
+                return ResponseVO.fail("删除ip失败");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("删除ip异常");
+            return ResponseVO.error(e);
+        }
+    }
+}

+ 10 - 11
backend/src/main/java/com/jiayue/ssi/controller/SysMenuController.java

@@ -42,7 +42,7 @@ public class SysMenuController {
     @PreAuthorize("@ss.hasPermi('system:menu:list')")
     public ResponseVO list(SysMenu menu) {
         try {
-            if (StringUtils.isNotEmpty(menu.getMenuName())){
+            if (StringUtils.isNotEmpty(menu.getMenuName())) {
                 if (menu.getMenuName().length() > 50) {
                     return ResponseVO.fail("菜单名长度不能超过50个字符!");
                 }
@@ -60,7 +60,7 @@ public class SysMenuController {
      * 新增菜单
      */
     @PostMapping
-    @OperateLog(title = "菜单管理", businessType = BusinessType.INSERT,auditType = AuditType.SYS)
+    @OperateLog(title = "菜单管理", businessType = BusinessType.INSERT, auditType = AuditType.SYS)
     @PreAuthorize("@ss.hasPermi('system:menu:add')")
     public ResponseVO add(@RequestBody SysMenu menu) {
         if (RyStringUtils.isEmpty(menu.getMenuName())) {
@@ -68,7 +68,7 @@ public class SysMenuController {
         } else if (menu.getMenuName().length() > 50) {
             return ResponseVO.fail("菜单名长度不能超过50个字符!");
         }
-        if (!"F".equals(menu.getMenuType())){
+        if (!"F".equals(menu.getMenuType())) {
             if (RyStringUtils.isEmpty(menu.getPath())) {
                 return ResponseVO.fail("路由地址不能为空!");
             } else if (menu.getPath().length() > 200) {
@@ -125,7 +125,7 @@ public class SysMenuController {
      * @return 执行结果
      */
     @PutMapping
-    @OperateLog(title = "菜单管理", businessType = BusinessType.UPDATE,auditType = AuditType.SYS)
+    @OperateLog(title = "菜单管理", businessType = BusinessType.UPDATE, auditType = AuditType.SYS)
     @PreAuthorize("@ss.hasPermi('system:menu:edit')")
     public ResponseVO update(@RequestBody SysMenu menu) {
         if (menu.getMenuId() == null) {
@@ -136,7 +136,7 @@ public class SysMenuController {
         } else if (menu.getMenuName().length() > 50) {
             return ResponseVO.fail("菜单名长度不能超过50个字符!");
         }
-        if (!"F".equals(menu.getMenuType())){
+        if (!"F".equals(menu.getMenuType())) {
             if (RyStringUtils.isEmpty(menu.getPath())) {
                 return ResponseVO.fail("路由地址不能为空!");
             } else if (menu.getPath().length() > 200) {
@@ -208,7 +208,7 @@ public class SysMenuController {
      * 删除菜单信息
      */
     @DeleteMapping
-    @OperateLog(title = "菜单管理", businessType = BusinessType.DELETE,auditType = AuditType.SYS)
+    @OperateLog(title = "菜单管理", businessType = BusinessType.DELETE, auditType = AuditType.SYS)
     @PreAuthorize("@ss.hasPermi('system:menu:remove')")
     public ResponseVO delete(String menuId) {
         if (org.apache.commons.lang3.StringUtils.isEmpty(menuId)) {
@@ -217,11 +217,10 @@ public class SysMenuController {
         if (sysMenuService.hasChildByMenuId(Long.parseLong(menuId))) {
             return ResponseVO.fail("存在子菜单,不允许删除");
         }
-        //////////////// 角色创建后再补这个逻辑
-        // if (sysMenuService.checkMenuExistRole(menuId))
-        // {
-        // return ResponseVO.fail("菜单已分配,不允许删除");
-        // }
+
+        if (sysMenuService.checkMenuExistRole(Long.parseLong(menuId))) {
+            return ResponseVO.fail("菜单已分配,不允许删除");
+        }
         try {
             int bo = sysMenuService.deleteMenuById(Long.parseLong(menuId));
             if (bo == 1) {

+ 26 - 2
backend/src/main/java/com/jiayue/ssi/controller/SysRoleController.java

@@ -23,6 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 
 /**
  * 角色接口
@@ -55,7 +57,6 @@ public class SysRoleController {
      *
      * @return 参数信息
      */
-    //    @PreAuthorize("@ss.hasPermi('system:role:list')")
     @GetMapping(value = "/getAll")
     @PreAuthorize("@ss.hasPermi('system:role:list')")
     public ResponseVO getAll(Integer currentPage, Integer pageSize, String roleName, String status, String roleKey) {
@@ -84,7 +85,7 @@ public class SysRoleController {
             return ResponseVO.success(result);
         } catch (Exception e) {
             e.printStackTrace();
-            log.error("获取参数异常");
+            log.error("获取角色列表异常");
             return ResponseVO.error(null);
         }
     }
@@ -224,4 +225,27 @@ public class SysRoleController {
             return ResponseVO.error(e);
         }
     }
+    /**
+     * 获取分配角色信息
+     *
+     * @return
+     */
+    @GetMapping(value = "/getRoleByType")
+    @PreAuthorize("@ss.hasPermi('system:user:role')")
+    public ResponseVO getRoleByType(String usertype) {
+        try {
+            if (StringUtils.isEmpty(usertype)) {
+               return ResponseVO.fail("用户类型为空不能获取角色列表!");
+            }
+            QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
+            wrapper.eq("role_type", usertype);
+            wrapper.eq("status", "0");
+            List<SysRole> result = roleService.list(wrapper);
+            return ResponseVO.success(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("获取分配角色列表异常");
+            return ResponseVO.error(null);
+        }
+    }
 }

+ 46 - 1
backend/src/main/java/com/jiayue/ssi/controller/SysUserController.java

@@ -12,6 +12,8 @@ import com.jiayue.ssi.backenum.BusinessType;
 import com.jiayue.ssi.config.SendMailUtil;
 import com.jiayue.ssi.constant.SecretKeyConstants;
 import com.jiayue.ssi.entity.SysUser;
+import com.jiayue.ssi.entity.SysUserRole;
+import com.jiayue.ssi.service.SysUserRoleService;
 import com.jiayue.ssi.service.SysUserService;
 import com.jiayue.ssi.service.impl.SysPermissionService;
 import com.jiayue.ssi.util.*;
@@ -38,7 +40,9 @@ public class SysUserController {
     @Autowired
     SendMailUtil sendMailUtil;
     @Autowired
-    private SysPermissionService sysPermissionService;
+    SysPermissionService sysPermissionService;
+    @Autowired
+    SysUserRoleService sysUserRoleService;
 
     /**
      * 获取用户分页信息
@@ -398,4 +402,45 @@ public class SysUserController {
             return ResponseVO.error(e);
         }
     }
+    /**
+     * 用户授权角色
+     */
+    @PostMapping("/authRole")
+    @PreAuthorize("@ss.hasPermi('system:user:role')")
+    @OperateLog(title = "用户管理", businessType = BusinessType.GRANT, auditType = AuditType.SYS)
+    public ResponseVO authRole(Long userId, Long roleId) {
+        if (userId==null) {
+            return ResponseVO.fail("用户id不能为空!");
+        }
+        try {
+            sysUserService.insertUserAuth(userId, roleId);
+            return ResponseVO.success("分配角色成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("分配角色异常");
+            return ResponseVO.error(e);
+        }
+    }
+
+    /**
+     * 根据用户ID获取角色
+     * @param userId
+     * @return
+     */
+    @GetMapping("/getUserRole")
+    public ResponseVO getUserRole(Long userId) {
+        if (userId==null) {
+            return ResponseVO.fail("用户id不能为空!");
+        }
+        try {
+            QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
+            wrapper.eq("user_id", userId);
+            SysUserRole sysUserRole = sysUserRoleService.getOne(wrapper);
+            return ResponseVO.success(sysUserRole);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("分配角色异常");
+            return ResponseVO.error(e);
+        }
+    }
 }

+ 3 - 0
backend/src/main/java/com/jiayue/ssi/entity/SysBlacklist.java

@@ -2,6 +2,7 @@ package com.jiayue.ssi.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 
@@ -23,4 +24,6 @@ public class SysBlacklist {
     /** ip锁定时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date ipTime;
+    /** 添加者 */
+    private String addBy;
 }

+ 6 - 0
backend/src/main/java/com/jiayue/ssi/entity/SysRole.java

@@ -47,6 +47,12 @@ public class SysRole extends BaseEntity {
     /** 角色状态(0正常 1停用) */
     private String status;
 
+    /** 角色类型(0管理 1业务) */
+    private String roleType;
+
+    /** 是否内置角色(0是 1否) */
+    private String builtIn;
+
     /** 菜单组 */
     @TableField(exist = false)
     private Long[] menuIds;

+ 5 - 0
backend/src/main/java/com/jiayue/ssi/entity/SysUser.java

@@ -66,6 +66,11 @@ public class SysUser extends BaseEntity implements UserDetails {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date loginDate;
 
+    /**
+     * 用户类型(0管理员、1普通用户)
+     */
+    private String usertype;
+
     @Override
     public boolean isEnabled() {
         return true;

+ 45 - 0
backend/src/main/java/com/jiayue/ssi/entity/SysUserRole.java

@@ -0,0 +1,45 @@
+package com.jiayue.ssi.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 用户和角色关联 sys_user_role
+ *
+ * @author ruoyi
+ */
+public class SysUserRole extends BaseEntity {
+    /** 用户ID */
+    private Long userId;
+
+    /** 角色ID */
+    private Long roleId;
+
+    public Long getUserId()
+    {
+        return userId;
+    }
+
+    public void setUserId(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public Long getRoleId()
+    {
+        return roleId;
+    }
+
+    public void setRoleId(Long roleId)
+    {
+        this.roleId = roleId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("userId", getUserId())
+            .append("roleId", getRoleId())
+            .toString();
+    }
+}

+ 2 - 1
backend/src/main/java/com/jiayue/ssi/filter/InterfaceLimitFilter.java

@@ -46,12 +46,13 @@ public class InterfaceLimitFilter extends OncePerRequestFilter {
             return;
         }
         else{
-            if (!InterfaceLimitUtil.checkInterface(request, 1000, 10)) {
+            if (!InterfaceLimitUtil.checkInterface(request, 1000, 1)) {
                 log.info("接口拦截:{} 请求超过限制频率【{}次/{}ms】,IP为{}", request.getRequestURI(), 10,1000, remoteIp);
                 // 锁定ip黑名单
                 SysBlacklist sysBlacklist = new SysBlacklist();
                 sysBlacklist.setIp(remoteIp);
                 sysBlacklist.setIpTime(new Date());
+                sysBlacklist.setAddBy("SYSTEM");
                 SpringUtils.getBean(SysBlacklistService.class).save(sysBlacklist);
                 // 将锁定ip加入缓存
                 CacheConstants.blacklistMap.put(remoteIp,sysBlacklist.getId());

+ 65 - 0
backend/src/main/java/com/jiayue/ssi/mapper/SysUserRoleMapper.java

@@ -0,0 +1,65 @@
+package com.jiayue.ssi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.ssi.entity.SysUserRole;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 用户与角色关联表 数据层
+ *
+ * @author ruoyi
+ */
+@Mapper
+public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
+    /**
+     * 通过用户ID删除用户和角色关联
+     *
+     * @param userId 用户ID
+     * @return 结果
+     */
+    public int deleteUserRoleByUserId(Long userId);
+
+    /**
+     * 批量删除用户和角色关联
+     *
+     * @param ids 需要删除的数据ID
+     * @return 结果
+     */
+    public int deleteUserRole(Long[] ids);
+
+    /**
+     * 通过角色ID查询角色使用数量
+     *
+     * @param roleId 角色ID
+     * @return 结果
+     */
+    public int countUserRoleByRoleId(Long roleId);
+
+    /**
+     * 批量新增用户角色信息
+     *
+     * @param userRoleList 用户角色列表
+     * @return 结果
+     */
+    public int batchUserRole(List<SysUserRole> userRoleList);
+
+    /**
+     * 删除用户和角色关联信息
+     *
+     * @param userRole 用户和角色关联信息
+     * @return 结果
+     */
+    public int deleteUserRoleInfo(SysUserRole userRole);
+
+    /**
+     * 批量取消授权用户角色
+     *
+     * @param roleId 角色ID
+     * @param userIds 需要删除的用户数据ID
+     * @return 结果
+     */
+    public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds);
+}

+ 7 - 0
backend/src/main/java/com/jiayue/ssi/service/SysMenuService.java

@@ -113,4 +113,11 @@ public interface SysMenuService  extends IService<SysMenu> {
      * @return 权限列表
      */
     Set<String> selectMenuPermsByUserId(Long userId);
+    /**
+     * 查询菜单是否存在角色
+     *
+     * @param menuId 菜单ID
+     * @return 结果 true 存在 false 不存在
+     */
+    boolean checkMenuExistRole(Long menuId);
 }

+ 13 - 0
backend/src/main/java/com/jiayue/ssi/service/SysUserRoleService.java

@@ -0,0 +1,13 @@
+package com.jiayue.ssi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.ssi.entity.SysUserRole;
+
+/**
+* 用户角色联合接口
+* @author xsl
+* @date 2023/2/16
+*/
+public interface SysUserRoleService extends IService<SysUserRole> {
+
+}

+ 8 - 0
backend/src/main/java/com/jiayue/ssi/service/SysUserService.java

@@ -1,6 +1,7 @@
 package com.jiayue.ssi.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.ssi.entity.SysRole;
 import com.jiayue.ssi.entity.SysUser;
 import java.util.List;
 
@@ -64,4 +65,11 @@ public interface SysUserService extends IService<SysUser> {
      * @return
      */
     boolean relockUserById(Integer id);
+    /**
+     * 用户授权角色
+     *
+     * @param userId 用户ID
+     * @param roleId 角色组
+     */
+    int insertUserAuth(Long userId, Long roleId);
 }

+ 0 - 95
backend/src/main/java/com/jiayue/ssi/service/impl/PermissionService.java

@@ -60,101 +60,6 @@ public class PermissionService
         return hasPermi(permission) != true;
     }
 
-//    /**
-//     * 验证用户是否具有以下任意一个权限
-//     *
-//     * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
-//     * @return 用户是否具有以下任意一个权限
-//     */
-//    public boolean hasAnyPermi(String permissions)
-//    {
-//        if (StringUtils.isEmpty(permissions))
-//        {
-//            return false;
-//        }
-//        LoginUser loginUser = SecurityUtils.getLoginUser();
-//        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
-//        {
-//            return false;
-//        }
-//        PermissionContextHolder.setContext(permissions);
-//        Set<String> authorities = loginUser.getPermissions();
-//        for (String permission : permissions.split(PERMISSION_DELIMETER))
-//        {
-//            if (permission != null && hasPermissions(authorities, permission))
-//            {
-//                return true;
-//            }
-//        }
-//        return false;
-//    }
-
-//    /**
-//     * 判断用户是否拥有某个角色
-//     *
-//     * @param role 角色字符串
-//     * @return 用户是否具备某角色
-//     */
-//    public boolean hasRole(String role)
-//    {
-//        if (StringUtils.isEmpty(role))
-//        {
-//            return false;
-//        }
-//        LoginUser loginUser = SecurityUtils.getLoginUser();
-//        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
-//        {
-//            return false;
-//        }
-//        for (SysRole sysRole : loginUser.getUser().getRoles())
-//        {
-//            String roleKey = sysRole.getRoleKey();
-//            if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
-//            {
-//                return true;
-//            }
-//        }
-//        return false;
-//    }
-
-//    /**
-//     * 验证用户是否不具备某角色,与 isRole逻辑相反。
-//     *
-//     * @param role 角色名称
-//     * @return 用户是否不具备某角色
-//     */
-//    public boolean lacksRole(String role)
-//    {
-//        return hasRole(role) != true;
-//    }
-
-//    /**
-//     * 验证用户是否具有以下任意一个角色
-//     *
-//     * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
-//     * @return 用户是否具有以下任意一个角色
-//     */
-//    public boolean hasAnyRoles(String roles)
-//    {
-//        if (StringUtils.isEmpty(roles))
-//        {
-//            return false;
-//        }
-//        LoginUser loginUser = SecurityUtils.getLoginUser();
-//        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
-//        {
-//            return false;
-//        }
-//        for (String role : roles.split(ROLE_DELIMETER))
-//        {
-//            if (hasRole(role))
-//            {
-//                return true;
-//            }
-//        }
-//        return false;
-//    }
-
     /**
      * 判断是否包含权限
      *

+ 5 - 0
backend/src/main/java/com/jiayue/ssi/service/impl/SysLogininforServiceImpl.java

@@ -12,6 +12,8 @@ import com.jiayue.ssi.service.SysLogininforService;
 import com.jiayue.ssi.service.SysMenuService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
 *
@@ -30,6 +32,7 @@ public class SysLogininforServiceImpl  extends ServiceImpl<SysLogininforMapper,
      * @param logininfor 访问日志对象
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public void insertLogininfor(SysLogininfor logininfor) {
         logininforMapper.insertLogininfor(logininfor);
     }
@@ -39,6 +42,7 @@ public class SysLogininforServiceImpl  extends ServiceImpl<SysLogininforMapper,
      * @return
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean removeLoginInfoById(Long infoId) {
         LambdaUpdateWrapper<SysLogininfor> updateWrapper = new UpdateWrapper<SysLogininfor>().lambda();
         updateWrapper.eq(SysLogininfor::getInfoId, infoId).set(SysLogininfor::getDelFlag, 1);
@@ -52,6 +56,7 @@ public class SysLogininforServiceImpl  extends ServiceImpl<SysLogininforMapper,
      * 清空系统登录日志
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean cleanLogininfor() {
         LambdaUpdateWrapper<SysLogininfor> updateWrapper = new UpdateWrapper<SysLogininfor>().lambda();
         updateWrapper.eq(SysLogininfor::getDelFlag,0).set(SysLogininfor::getDelFlag, 1);

+ 21 - 17
backend/src/main/java/com/jiayue/ssi/service/impl/SysMenuServiceImpl.java

@@ -13,11 +13,14 @@ import com.jiayue.ssi.entity.vo.MetaVo;
 import com.jiayue.ssi.entity.vo.RouterVo;
 import com.jiayue.ssi.mapper.SysMenuMapper;
 import com.jiayue.ssi.mapper.SysRoleMapper;
+import com.jiayue.ssi.mapper.SysRoleMenuMapper;
 import com.jiayue.ssi.service.SysMenuService;
 import com.jiayue.ssi.util.SecurityContextUtil;
 import com.jiayue.ssi.util.RyStringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 菜单服务类
@@ -32,6 +35,8 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
     SysMenuMapper menuMapper;
     @Autowired
     SysRoleMapper roleMapper;
+    @Autowired
+    SysRoleMenuMapper roleMenuMapper;
 
 
     /**
@@ -120,11 +125,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
     @Override
     public List<SysMenu> selectMenuTreeByUserId(Long userId) {
         List<SysMenu> menus = null;
-//        if (userId == 1) {
-//            menus = menuMapper.selectMenuTreeAll();
-//        } else {
-            menus = menuMapper.selectMenuTreeByUserId(userId);
-//        }
+        menus = menuMapper.selectMenuTreeByUserId(userId);
         return getChildPerms(menus, 0);
     }
 
@@ -297,6 +298,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
      * @return 结果
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public int insertMenu(SysMenu menu) {
         return menuMapper.insertMenu(menu);
     }
@@ -308,6 +310,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
      * @return 结果
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public int updateMenu(SysMenu menu) {
         menu.setUpdateBy(SecurityContextUtil.getSysUser().getCreateBy());
         return menuMapper.updateMenu(menu);
@@ -335,18 +338,6 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
         int result = menuMapper.hasChildByMenuId(menuId);
         return result > 0;
     }
-    // /**
-    // * 查询菜单使用数量
-    // *
-    // * @param menuId 菜单ID
-    // * @return 结果
-    // */
-    // @Override
-    // public boolean checkMenuExistRole(Long menuId)
-    // {
-    // int result = roleMenuMapper.checkMenuExistRole(menuId);
-    // return result > 0;
-    // }
 
     /**
      * 删除菜单管理信息
@@ -355,6 +346,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
      * @return 结果
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public int deleteMenuById(Long menuId) {
         return menuMapper.deleteMenuById(SecurityContextUtil.getSysUser().getUsername(),menuId);
     }
@@ -442,4 +434,16 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
         }
         return permsSet;
     }
+    /**
+     * 查询菜单使用数量
+     *
+     * @param menuId 菜单ID
+     * @return 结果
+     */
+    @Override
+    public boolean checkMenuExistRole(Long menuId)
+    {
+        int result = roleMenuMapper.checkMenuExistRole(menuId);
+        return result > 0;
+    }
 }

+ 5 - 0
backend/src/main/java/com/jiayue/ssi/service/impl/SysOperLogServiceImpl.java

@@ -8,6 +8,8 @@ import com.jiayue.ssi.mapper.SysOperLogMapper;
 import com.jiayue.ssi.service.SysOperLogService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 操作日志 服务层处理
@@ -25,6 +27,7 @@ public class SysOperLogServiceImpl  extends ServiceImpl<SysOperLogMapper, SysOpe
      * @param operLog 操作日志对象
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public void insertOperlog(SysOperLog operLog)
     {
         operLogMapper.insertOperlog(operLog);
@@ -35,6 +38,7 @@ public class SysOperLogServiceImpl  extends ServiceImpl<SysOperLogMapper, SysOpe
      * @return
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean removeOperlogById(Long operId) {
         LambdaUpdateWrapper<SysOperLog> updateWrapper = new UpdateWrapper<SysOperLog>().lambda();
         updateWrapper.eq(SysOperLog::getOperId, operId).set(SysOperLog::getDelFlag, 1);
@@ -48,6 +52,7 @@ public class SysOperLogServiceImpl  extends ServiceImpl<SysOperLogMapper, SysOpe
      * 清空操作日志
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean cleanOperLog() {
         LambdaUpdateWrapper<SysOperLog> updateWrapper = new UpdateWrapper<SysOperLog>().lambda();
         updateWrapper.eq(SysOperLog::getDelFlag,0).set(SysOperLog::getDelFlag, 1);

+ 6 - 306
backend/src/main/java/com/jiayue/ssi/service/impl/SysRoleServiceImpl.java

@@ -16,6 +16,7 @@ import com.jiayue.ssi.util.RyStringUtils;
 import com.jiayue.ssi.util.SecurityContextUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
@@ -43,7 +44,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
      * @return 结果
      */
     @Override
-    @Transactional
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public int insertRole(SysRole role) {
         // 新增角色信息
         roleMapper.insertRole(role);
@@ -56,6 +57,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
      *
      * @param role 角色对象
      */
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public int insertRoleMenu(SysRole role) {
         int rows = 1;
         // 新增用户与角色管理
@@ -75,102 +77,6 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
         return rows;
     }
 
-
-//    @Autowired
-//    SysRoleMapper sysRoleMapper;
-
-//    @Autowired
-//    private SysRoleMenuMapper roleMenuMapper;
-//
-//    @Autowired
-//    private SysUserRoleMapper userRoleMapper;
-//
-//    @Autowired
-//    private SysRoleDeptMapper roleDeptMapper;
-
-    /**
-     * 根据条件分页查询角色数据
-     *
-     * @param role 角色信息
-     * @return 角色数据集合信息
-     */
-//    @Override
-//    @DataScope(deptAlias = "d")
-//    public List<SysRole> selectRoleList(SysRole role)
-//    {
-//        return roleMapper.selectRoleList(role);
-//    }
-//
-//    /**
-//     * 根据用户ID查询角色
-//     *
-//     * @param userId 用户ID
-//     * @return 角色列表
-//     */
-//    @Override
-//    public List<SysRole> selectRolesByUserId(Long userId)
-//    {
-//        List<SysRole> userRoles = roleMapper.selectRolePermissionByUserId(userId);
-//        List<SysRole> roles = selectRoleAll();
-//        for (SysRole role : roles)
-//        {
-//            for (SysRole userRole : userRoles)
-//            {
-//                if (role.getRoleId().longValue() == userRole.getRoleId().longValue())
-//                {
-//                    role.setFlag(true);
-//                    break;
-//                }
-//            }
-//        }
-//        return roles;
-//    }
-//
-//    /**
-//     * 根据用户ID查询权限
-//     *
-//     * @param userId 用户ID
-//     * @return 权限列表
-//     */
-//    @Override
-//    public Set<String> selectRolePermissionByUserId(Long userId)
-//    {
-//        List<SysRole> perms = roleMapper.selectRolePermissionByUserId(userId);
-//        Set<String> permsSet = new HashSet<>();
-//        for (SysRole perm : perms)
-//        {
-//            if (StringUtils.isNotNull(perm))
-//            {
-//                permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
-//            }
-//        }
-//        return permsSet;
-//    }
-//
-//    /**
-//     * 查询所有角色
-//     *
-//     * @return 角色列表
-//     */
-//    @Override
-//    public List<SysRole> selectRoleAll()
-//    {
-//        return SpringUtils.getAopProxy(this).selectRoleList(new SysRole());
-//    }
-//
-//    /**
-//     * 根据用户ID获取角色选择框列表
-//     *
-//     * @param userId 用户ID
-//     * @return 选中角色ID列表
-//     */
-//    @Override
-//    public List<Long> selectRoleListByUserId(Long userId)
-//    {
-//        return roleMapper.selectRoleListByUserId(userId);
-//    }
-//
-
     /**
      * 通过角色ID查询角色
      *
@@ -189,7 +95,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
      * @return 结果
      */
     @Override
-    @Transactional
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public int updateRole(SysRole role) {
         // 修改角色信息
         this.updateById(role);
@@ -215,7 +121,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
         }
         return UserConstants.UNIQUE;
     }
-//
+
     /**
      * 校验角色权限是否唯一
      *
@@ -257,163 +163,6 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
         SysRole sysRole = roleMapper.selectOne(queryWrapper);
         return sysRole;
     }
-//
-//    /**
-//     * 校验角色是否允许操作
-//     *
-//     * @param role 角色信息
-//     */
-//    @Override
-//    public void checkRoleAllowed(SysRole role)
-//    {
-//        if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin())
-//        {
-//            throw new ServiceException("不允许操作超级管理员角色");
-//        }
-//    }
-//
-//    /**
-//     * 校验角色是否有数据权限
-//     *
-//     * @param roleId 角色id
-//     */
-//    @Override
-//    public void checkRoleDataScope(Long roleId)
-//    {
-//        if (!SysUser.isAdmin(SecurityUtils.getUserId()))
-//        {
-//            SysRole role = new SysRole();
-//            role.setRoleId(roleId);
-//            List<SysRole> roles = SpringUtils.getAopProxy(this).selectRoleList(role);
-//            if (StringUtils.isEmpty(roles))
-//            {
-//                throw new ServiceException("没有权限访问角色数据!");
-//            }
-//        }
-//    }
-//
-//    /**
-//     * 通过角色ID查询角色使用数量
-//     *
-//     * @param roleId 角色ID
-//     * @return 结果
-//     */
-//    @Override
-//    public int countUserRoleByRoleId(Long roleId)
-//    {
-//        return userRoleMapper.countUserRoleByRoleId(roleId);
-//    }
-//
-//    /**
-//     * 新增保存角色信息
-//     *
-//     * @param role 角色信息
-//     * @return 结果
-//     */
-//    @Override
-//    @Transactional
-//    public int insertRole(SysRole role)
-//    {
-//        // 新增角色信息
-//        roleMapper.insertRole(role);
-//        return insertRoleMenu(role);
-//    }
-//
-//    /**
-//     * 修改保存角色信息
-//     *
-//     * @param role 角色信息
-//     * @return 结果
-//     */
-//    @Override
-//    @Transactional
-//    public int updateRole(SysRole role)
-//    {
-//        // 修改角色信息
-//        roleMapper.updateRole(role);
-//        // 删除角色与菜单关联
-//        roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId());
-//        return insertRoleMenu(role);
-//    }
-//
-//    /**
-//     * 修改角色状态
-//     *
-//     * @param role 角色信息
-//     * @return 结果
-//     */
-//    @Override
-//    public int updateRoleStatus(SysRole role)
-//    {
-//        return roleMapper.updateRole(role);
-//    }
-//
-//    /**
-//     * 修改数据权限信息
-//     *
-//     * @param role 角色信息
-//     * @return 结果
-//     */
-//    @Override
-//    @Transactional
-//    public int authDataScope(SysRole role)
-//    {
-//        // 修改角色信息
-//        roleMapper.updateRole(role);
-//        // 删除角色与部门关联
-//        roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId());
-//        // 新增角色和部门信息(数据权限)
-//        return insertRoleDept(role);
-//    }
-//
-//    /**
-//     * 新增角色菜单信息
-//     *
-//     * @param role 角色对象
-//     */
-//    public int insertRoleMenu(SysRole role)
-//    {
-//        int rows = 1;
-//        // 新增用户与角色管理
-//        List<SysRoleMenu> list = new ArrayList<SysRoleMenu>();
-//        for (Long menuId : role.getMenuIds())
-//        {
-//            SysRoleMenu rm = new SysRoleMenu();
-//            rm.setRoleId(role.getRoleId());
-//            rm.setMenuId(menuId);
-//            list.add(rm);
-//        }
-//        if (list.size() > 0)
-//        {
-//            rows = roleMenuMapper.batchRoleMenu(list);
-//        }
-//        return rows;
-//    }
-//
-//    /**
-//     * 新增角色部门信息(数据权限)
-//     *
-//     * @param role 角色对象
-//     */
-//    public int insertRoleDept(SysRole role)
-//    {
-//        int rows = 1;
-//        // 新增角色与部门(数据权限)管理
-//        List<SysRoleDept> list = new ArrayList<SysRoleDept>();
-//        for (Long deptId : role.getDeptIds())
-//        {
-//            SysRoleDept rd = new SysRoleDept();
-//            rd.setRoleId(role.getRoleId());
-//            rd.setDeptId(deptId);
-//            list.add(rd);
-//        }
-//        if (list.size() > 0)
-//        {
-//            rows = roleDeptMapper.batchRoleDept(list);
-//        }
-//        return rows;
-//    }
-//
 
     /**
      * 通过角色ID删除角色
@@ -422,60 +171,11 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
      * @return 结果
      */
     @Override
-    @Transactional
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public int deleteRoleById(Long roleId) {
         String username = SecurityContextUtil.getSysUser().getUsername();
         // 删除角色与菜单关联
         roleMenuMapper.deleteRoleMenuByRoleId(username, roleId);
         return roleMapper.deleteRoleById(username, roleId);
     }
-
-
-//
-//    /**
-//     * 取消授权用户角色
-//     *
-//     * @param userRole 用户和角色关联信息
-//     * @return 结果
-//     */
-//    @Override
-//    public int deleteAuthUser(SysUserRole userRole)
-//    {
-//        return userRoleMapper.deleteUserRoleInfo(userRole);
-//    }
-//
-//    /**
-//     * 批量取消授权用户角色
-//     *
-//     * @param roleId 角色ID
-//     * @param userIds 需要取消授权的用户数据ID
-//     * @return 结果
-//     */
-//    @Override
-//    public int deleteAuthUsers(Long roleId, Long[] userIds)
-//    {
-//        return userRoleMapper.deleteUserRoleInfos(roleId, userIds);
-//    }
-//
-//    /**
-//     * 批量选择授权用户角色
-//     *
-//     * @param roleId 角色ID
-//     * @param userIds 需要授权的用户数据ID
-//     * @return 结果
-//     */
-//    @Override
-//    public int insertAuthUsers(Long roleId, Long[] userIds)
-//    {
-//        // 新增用户与角色管理
-//        List<SysUserRole> list = new ArrayList<SysUserRole>();
-//        for (Long userId : userIds)
-//        {
-//            SysUserRole ur = new SysUserRole();
-//            ur.setUserId(userId);
-//            ur.setRoleId(roleId);
-//            list.add(ur);
-//        }
-//        return userRoleMapper.batchUserRole(list);
-//    }
 }

+ 16 - 0
backend/src/main/java/com/jiayue/ssi/service/impl/SysUserRoleServiceImpl.java

@@ -0,0 +1,16 @@
+package com.jiayue.ssi.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.ssi.entity.SysUserRole;
+import com.jiayue.ssi.mapper.SysUserRoleMapper;
+import com.jiayue.ssi.service.SysUserRoleService;
+import org.springframework.stereotype.Service;
+
+/**
+* 用户管理服务类
+* @author xsl
+* @date 2023/2/16
+*/
+@Service
+public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService {
+}

+ 35 - 0
backend/src/main/java/com/jiayue/ssi/service/impl/SysUserServiceImpl.java

@@ -4,13 +4,19 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.ssi.entity.SysRole;
 import com.jiayue.ssi.entity.SysUser;
+import com.jiayue.ssi.entity.SysUserRole;
 import com.jiayue.ssi.mapper.SysUserMapper;
+import com.jiayue.ssi.mapper.SysUserRoleMapper;
 import com.jiayue.ssi.service.SysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -22,6 +28,9 @@ import java.util.List;
 public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
     @Autowired
     SysUserMapper sysUserMapper;
+    @Autowired
+    SysUserRoleMapper sysUserRoleMapper;
+
     /**
      * 获取所有用户
      * @return List<SysUser>
@@ -36,6 +45,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @return boolean
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean saveUser(SysUser sysUser){
        return this.save(sysUser);
     }
@@ -45,6 +55,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @return boolean
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean updateUser(SysUser sysUser){
         return this.updateById(sysUser);
     }
@@ -54,6 +65,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @return
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean deleteUser(String id){
         return this.removeById(id);
     }
@@ -87,6 +99,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @return
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean removeUserById(Integer id) {
         LambdaUpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<SysUser>().lambda();
         updateWrapper.eq(SysUser::getId, id).set(SysUser::getDelFlag, 1);
@@ -103,6 +116,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @return
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean resetPassword(Integer id,String initPassword) {
         LambdaUpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<SysUser>().lambda();
         updateWrapper.eq(SysUser::getId, id).set(SysUser::getLastUpdatePwdTime, null).set(SysUser::getPassword,initPassword);
@@ -118,6 +132,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @return
      */
     @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean relockUserById(Integer id) {
         LambdaUpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<SysUser>().lambda();
         updateWrapper.eq(SysUser::getId, id).set(SysUser::getStatus, 0);
@@ -127,4 +142,24 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
         return false;
     }
+    /**
+     * 用户授权角色
+     *
+     * @param userId 用户ID
+     * @param roleId 角色ID
+     */
+    @Override
+    @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
+    public int insertUserAuth(Long userId, Long roleId) {
+        int returnVal = 0;
+        sysUserRoleMapper.deleteUserRoleByUserId(userId);
+        if (roleId!=null){
+            // 新增用户与角色管理
+            SysUserRole ur = new SysUserRole();
+            ur.setUserId(userId);
+            ur.setRoleId(roleId);
+            returnVal = sysUserRoleMapper.insert(ur);
+        }
+        return returnVal;
+    }
 }

+ 4 - 0
backend/src/main/java/com/jiayue/ssi/util/IPUtils.java

@@ -323,4 +323,8 @@ public class IPUtils {
         }
         return false;
     }
+
+    public static void main(String[] args) {
+        System.out.println(isIP("192.168.5.132"));
+    }
 }

+ 2 - 1
backend/src/main/resources/mapper/system/SysMenuMapper.xml

@@ -91,9 +91,10 @@
 		from sys_menu m
             left join sys_role_menu rm on m.menu_id = rm.menu_id
         where m.del_flag=0
+              and rm.del_flag=0
               and rm.role_id = #{roleId}
             <if test="menuCheckStrictly">
-              and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.menu_id = rm.menu_id and rm.role_id = #{roleId})
+              and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.menu_id = rm.menu_id and rm.role_id = #{roleId} and m.del_flag=0 and rm.del_flag=0)
             </if>
 		order by m.parent_id, m.order_num
 	</select>

+ 1 - 1
backend/src/main/resources/mapper/system/SysRoleMapper.xml

@@ -75,7 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
 	<select id="selectRoleById" parameterType="Long" resultMap="SysRoleResult">
 		<include refid="selectRoleVo"/>
-		where r.role_id = #{roleId}
+		where r.role_id = #{roleId} and r.del_flag = '0'
 	</select>
 
 	<select id="selectRolesByUserName" parameterType="String" resultMap="SysRoleResult">

+ 7 - 1
backend/src/main/resources/mapper/system/SysRoleMenuMapper.xml

@@ -7,10 +7,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	<resultMap type="SysRoleMenu" id="SysRoleMenuResult">
 		<result property="roleId"     column="role_id"      />
 		<result property="menuId"     column="menu_id"      />
+		<result property="delFlag"            column="del_flag"              />
+		<result property="createBy"           column="create_by"             />
+		<result property="createTime"         column="create_time"           />
+		<result property="updateBy"           column="update_by"             />
+		<result property="updateTime"         column="update_time"           />
+		<result property="remark"             column="remark"                />
 	</resultMap>
 
 	<select id="checkMenuExistRole" resultType="Integer">
-	    select count(1) from sys_role_menu where menu_id = #{menuId}
+	    select count(1) from sys_role_menu where menu_id = #{menuId} and del_flag=0
 	</select>
 
 	<delete id="deleteRoleMenuByRoleId">

+ 50 - 0
backend/src/main/resources/mapper/system/SysUserRoleMapper.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jiayue.ssi.mapper.SysUserRoleMapper">
+
+	<resultMap type="SysUserRole" id="SysUserRoleResult">
+		<result property="userId"     column="user_id"      />
+		<result property="roleId"     column="role_id"      />
+		<result property="delFlag"            column="del_flag"              />
+		<result property="createBy"           column="create_by"             />
+		<result property="createTime"         column="create_time"           />
+		<result property="updateBy"           column="update_by"             />
+		<result property="updateTime"         column="update_time"           />
+		<result property="remark"             column="remark"                />
+	</resultMap>
+
+	<delete id="deleteUserRoleByUserId" parameterType="Long">
+		update sys_user_role set del_flag=1 where user_id=#{userId}
+	</delete>
+
+	<select id="countUserRoleByRoleId" resultType="Integer">
+	    select count(1) from sys_user_role where role_id=#{roleId}
+	</select>
+
+	<delete id="deleteUserRole" parameterType="Long">
+ 		delete from sys_user_role where user_id in
+ 		<foreach collection="array" item="userId" open="(" separator="," close=")">
+ 			#{userId}
+        </foreach>
+ 	</delete>
+
+	<insert id="batchUserRole">
+		insert into sys_user_role(user_id, role_id) values
+		<foreach item="item" index="index" collection="list" separator=",">
+			(#{item.userId},#{item.roleId})
+		</foreach>
+	</insert>
+
+	<delete id="deleteUserRoleInfo" parameterType="SysUserRole">
+		delete from sys_user_role where user_id=#{userId} and role_id=#{roleId}
+	</delete>
+
+	<delete id="deleteUserRoleInfos">
+	    delete from sys_user_role where role_id=#{roleId} and user_id in
+ 	    <foreach collection="userIds" item="userId" open="(" separator="," close=")">
+ 	        #{userId}
+            </foreach>
+	</delete>
+</mapper>

二进制
ui/public/favicon.ico


+ 27 - 0
ui/public/index.html

@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= webpackConfig.name %></title>
+    <meta http-equiv="expires" content="0" />
+<!--    <meta http-equiv="pragram" content="no-cache">-->
+    <META HTTP-EQUIV="Pragma"CONTENT="no-cache">
+    <META HTTP-EQUIV="Cache-Control"CONTENT="no-cache">
+    <META HTTP-EQUIV="Expires"CONTENT="0">
+
+<!--    <meta http-equiv="Expires" content="0">-->
+<!--    <meta http-equiv="Pragma" content="no-cache">-->
+<!--    <meta http-equiv="Cache-control" content="no-cache">-->
+<!--    <meta http-equiv="Cache" content="no-cache">-->
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 1 - 1
ui/src/directive/permission/hasPermi.js

@@ -12,7 +12,7 @@ export default {
     const all_permission = "*:*:*";
     // const permissions = store.getters && store.getters.permissions
     // 用户信息解密
-    let decryptUserInfo = userinfoDecrypt(sessionStorage.getItem('userinfo'))
+    let decryptUserInfo = userinfoDecrypt(sessionStorage.getItem('active'))
     const permissions = JSON.parse(decryptUserInfo).permissions
     if (value && value instanceof Array && value.length > 0) {
       const permissionFlag = value

+ 1 - 1
ui/src/permission.js

@@ -40,7 +40,7 @@ router.beforeEach(async (to, from, next) => {
       if (to.path !=='/dashboard' && to.path !=='/user/profile'){
         // 用户信息解密
         // let decryptUserInfo = userinfoDecrypt(store.getters.userinfo)
-        let decryptUserInfo = userinfoDecrypt(sessionStorage.getItem('userinfo'))
+        let decryptUserInfo = userinfoDecrypt(sessionStorage.getItem('active'))
         let user = JSON.parse(decryptUserInfo).sysUser
         if (user.lastUpdatePwdTime==null){
           Message({

+ 1 - 1
ui/src/store/modules/permission.js

@@ -42,7 +42,7 @@ const permission = {
           const sidebarRoutes = filterAsyncRouter(sdata)
           const rewriteRoutes = filterAsyncRouter(rdata, false, true)
           const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
-          rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
+          // rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
           // router.addRoutes(asyncRoutes);
           commit('SET_ROUTES', rewriteRoutes)
           commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))

+ 1 - 1
ui/src/utils/auth.js

@@ -14,7 +14,7 @@ export function setToken(token) {
 
 export function removeToken() {
   sessionStorage.removeItem('token')
-  sessionStorage.removeItem('userinfo')
+  sessionStorage.removeItem('active')
   store.dispatch('tagsView/delAllCachedViews')
   store.dispatch('tagsView/delAllVisitedViews')
 }

+ 9 - 6
ui/src/utils/request.js

@@ -7,6 +7,7 @@ import {removeToken} from "@/utils/auth";
 import router, {resetRouter} from "@/router";
 import {doEncrypt, doDecryptStr,doSign,doVerifySignature,userinfoEncrypt,userinfoDecrypt} from '@/utils/smutil'
 const service = axios.create({
+  headers: {'Cache-Control': 'no-cache'},
   baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
   // withCredentials: true, // send cookies when cross-domain requests
   timeout: 1000 * 60 * 10 // request timeout
@@ -53,11 +54,12 @@ service.interceptors.request.use(
     }
 
     if (sessionStorage.getItem("token")!=="undefined" && sessionStorage.getItem("token")!==undefined && sessionStorage.getItem("token")!=null) { // 判断是否存在token,如果存在的话,则每个http header都加上token
-      let tokenStr = doEncrypt(sessionStorage.getItem("token"))
-      config.headers['Authorization'] = tokenStr
-      config.headers['TokenSign'] = doSign(sessionStorage.getItem("token"))
-      console.log('Authorization='+tokenStr)
-      console.log('TokenSign='+config.headers['TokenSign'])
+      let tokenStr = sessionStorage.getItem("token")
+
+      config.headers['Authorization'] = tokenStr.split("&")[0]
+      config.headers['TokenSign'] = tokenStr.split("&")[1]
+      // console.log('Authorization='+tokenStr)
+      // console.log('TokenSign='+config.headers['TokenSign'])
     }
     return config
   },
@@ -94,6 +96,7 @@ service.interceptors.response.use(
     let data = JSON.parse(decData)
     // if the custom code is not 20000, it is judged as an error.
     //console.log(res.code)
+
     if (data.code > 1) {
       // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
       if (data.code === 50008 || data.code === 50012 || data.code === 50014) {
@@ -108,7 +111,7 @@ service.interceptors.response.use(
           })
         })
       }
-      return Promise.reject(new Error(data.message || 'Error'))
+      return Promise.reject(new Error(data.data))
     } else {
       return data
     }

+ 1 - 1
ui/src/views/dashboard/index.vue

@@ -29,7 +29,7 @@ export default {
         // 用户信息+菜单权限加密存储
         let encryptUserInfo = userinfoEncrypt(JSON.stringify(res.data))
         // this.$store.dispatch('user/changeSetting',encryptUserInfo)
-        sessionStorage.setItem('userinfo',encryptUserInfo)
+        sessionStorage.setItem('active',encryptUserInfo)
         var user = res.data.sysUser
         if (user.lastUpdatePwdTime==null){
             this.$message({

+ 4 - 1
ui/src/views/login/index.vue

@@ -82,6 +82,7 @@
 <script>
 
 import store from "@/store";
+import {doEncrypt, doSign} from "@/utils/smutil";
 
 export default {
   name: 'Login',
@@ -255,7 +256,9 @@ export default {
             mailbox: this.loginForm.mailbox
           }
           this.$axios.post('/user/login', param).then((res) => {
-            sessionStorage.setItem('token', res.data)
+            let tokenStr = doEncrypt(res.data)
+            let sign = doSign(res.data)
+            sessionStorage.setItem('token', tokenStr+'&'+sign)
             // 清空路由菜单
             store.commit('SET_R', [])
             this.$router.push('/')

+ 276 - 0
ui/src/views/sysManager/ipBlacklist/index.vue

@@ -0,0 +1,276 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="24">
+      <!--用户数据-->
+      <el-col :span="24" :xs="24">
+        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
+          <el-form-item label="IP地址" prop="ip">
+            <el-input
+              maxlength="15"
+              v-model="queryParams.ip"
+              placeholder="请输入IP地址"
+              clearable
+              style="width: 240px"
+              @keyup.enter.native="handleQuery"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button
+              type="primary"
+              plain
+              icon="el-icon-plus"
+              size="mini"
+              @click="handleAdd"
+              v-hasPermi="['system:ipblacklist:add']"
+            >新增
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button
+              type="danger"
+              plain
+              icon="el-icon-delete"
+              size="mini"
+              @click="handleDelete"
+              v-hasPermi="['system:ipblacklist:remove']"
+            >删除
+            </el-button>
+          </el-col>
+        </el-row>
+        <div style="padding-top: 10px">
+          <vxe-table
+            ref="xTable"
+            align="center"
+            :loading="loading"
+            class="mytable-style"
+            auto-resize
+            border
+            resizable
+            export-config
+            highlight-current-row
+            show-overflow
+            max-height="700"
+            :data="userList"
+            :radio-config="{trigger: 'row'}"
+          >
+            <vxe-column type="radio" width="60"/>
+            <vxe-table-column field="ip" title="IP地址"/>
+            <vxe-table-column field="ipTime" title="锁定时间"/>
+            <vxe-table-column field="addBy" title="添加人"/>
+          </vxe-table>
+          <vxe-pager
+            v-show="showTable"
+            perfect
+            :current-page.sync="currentPage"
+            :page-size.sync="pageSize"
+            :total="total"
+            :page-sizes="[10,50,100]"
+            :layouts="['PrevJump', 'PrevPage','JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']"
+            @page-change="handlePageChange"
+          >
+          </vxe-pager>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { debounce } from 'lodash'
+export default {
+  name: "ipBlacklist",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      showTable: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      currentPage: 1,
+      pageSize: 10,
+      // 总条数
+      total: 0,
+      // 用户表格数据
+      userList: null,
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 默认密码
+      initPassword: undefined,
+      // 角色选项
+      roleOptions: [],
+      // 表单参数
+      form: {},
+      // 查询参数
+      queryParams: {
+        ip: undefined
+      }
+    };
+  },
+  watch: {},
+  created() {
+    this.getList()
+  },
+  methods: {
+    handlePageChange({currentPage, pageSize}) {
+      this.currentPage = currentPage
+      this.pageSize = pageSize
+      this.getList()
+    },
+    /** 查询用户列表 */
+    getList(){
+      this.loading = true;
+      var searchParams = {
+        currentPage: this.currentPage,
+        pageSize: this.pageSize,
+        ip: this.queryParams.ip
+      }
+      this.$axios.get('/ipBlacklistController/getAll',
+        {params: searchParams}).then((res) => {
+
+        if (res.code == 0) {
+          this.userList = res.data.records
+          this.total = res.data.total
+          if (res.data.records == '') {
+            this.showTable = false
+          } else {
+            this.showTable = true
+          }
+        } else {
+          // 输出后端返回信息
+          this.$message({
+            type: 'error',
+            message: res.data
+          });
+        }
+        this.loading = false
+      }).catch((error) => {
+        this.loading = false
+        this.$message.error(error)
+      })
+    },
+    /** 搜索按钮操作 */
+    handleQuery:debounce(function(){
+      // 验证查询条件ip是否合理
+      if (this.queryParams.ip!=undefined && this.queryParams.ip!=''){
+        var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
+        if (!reg.test(this.queryParams.ip)){
+          this.$message({
+            type: 'warning',
+            message: '请输入正确ip地址!'
+          });
+          return
+        }
+      }
+      this.getList();
+    },1000),
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+    },
+    /** 添加按钮操作 */
+    handleAdd(){
+      const ipReg = new RegExp(/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/)
+      this.$prompt('请输入黑名单IP','黑名单操作',{
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        inputValidator:(val)=>{
+          if (!ipReg.test(val)){
+            return false;
+          }
+        },
+        inputErrorMessage: 'IP格式不正确'
+      }).then(async({value})=>{
+        this.doAdd(value)
+      }).catch((e)=>{})
+    },
+    /** 删除按钮操作 */
+    handleDelete(){
+      const _selectData = this.$refs.xTable.getRadioRecord(true)
+      if (_selectData == null) {
+        this.$message({
+          type: 'warning',
+          message: '请选择记录!'
+        });
+        return
+      }
+      this.$confirm('是否删除此IP?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.doDelete(_selectData)
+      }).catch(() => {
+      });
+    },
+    /**
+     * 添加提交
+     */
+    doAdd:debounce(function(ip){
+      const param = {
+        ip:ip
+      }
+      this.$axios.post('/ipBlacklistController/addIp', param).then((res) => {
+        if (res.code == 0) {
+          this.$message({
+            type: 'success',
+            message: '添加成功!'
+          });
+          this.getList();
+        } else {
+          this.$message({
+            type: 'error',
+            message: res.data
+          });
+        }
+      }).catch((error) => {
+        this.$message({
+          type: 'error',
+          message: '添加失败!'
+        });
+        this.loading = false
+      })
+    },1000),
+    /**
+     * 删除提交
+     */
+    doDelete:debounce(function(_selectData){
+      const param = {
+        id: _selectData.id
+      }
+      this.$axios.post('/ipBlacklistController/delIp', param).then((res) => {
+        if (res.code == 0) {
+          this.$message({
+            type: 'success',
+            message: '删除成功!'
+          });
+          this.getList();
+        } else {
+          this.$message({
+            type: 'error',
+            message: res.data
+          });
+        }
+      }).catch((error) => {
+        this.$message({
+          type: 'error',
+          message: '删除失败!'
+        });
+        console.log(error)
+        this.loading = false
+      })
+    },1000)
+  }
+};
+</script>

+ 75 - 32
ui/src/views/sysManager/roleManager/index.vue

@@ -11,11 +11,11 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="权限字符" prop="roleKey">
+      <el-form-item label="字符标识" prop="roleKey">
         <el-input
           maxlength="50"
           v-model="queryParams.roleKey"
-          placeholder="请输入权限字符"
+          placeholder="请输入字符标识"
           clearable
           style="width: 240px"
           @keyup.enter.native="handleQuery"
@@ -96,11 +96,10 @@
         <vxe-column type="radio" width="60"/>
         <vxe-table-column field="roleId" title="角色编号"/>
         <vxe-table-column field="roleName" title="角色名称"/>
-        <vxe-table-column field="roleKey" title="权限字符"/>
+        <vxe-table-column field="roleType" title="类型" :formatter="typeFormat"/>
+        <vxe-table-column field="roleKey" title="字符标识"/>
         <vxe-table-column field="roleSort" title="显示顺序"/>
         <vxe-table-column field="status" title="状态" :formatter="statusFormat"/>
-        <vxe-table-column title="操作" width="320">
-        </vxe-table-column>
       </vxe-table>
       <vxe-pager
         v-show="showTable"
@@ -118,19 +117,29 @@
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="100px">
         <el-form-item label="角色名称" prop="roleName">
-          <el-input v-model="form.roleName" maxlength="15" placeholder="请输入角色名称"/>
+          <el-input v-model="form.roleName" maxlength="15" placeholder="请输入角色名称" :disabled="edit"/>
         </el-form-item>
-        <el-form-item prop="roleKey">
-          <span slot="label">
-            <el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-            权限字符
-          </span>
-          <el-input v-model="form.roleKey" maxlength="50" placeholder="请输入权限字符"/>
+        <el-form-item label="字符标识" prop="roleKey">
+          <el-input v-model="form.roleKey" maxlength="50" placeholder="请输入字符标识" :disabled="edit"/>
         </el-form-item>
         <el-form-item label="角色顺序" prop="roleSort">
-          <el-input-number v-model="form.roleSort" controls-position="right" :min="0"/>
+          <el-input-number v-model="form.roleSort" controls-position="right" :min="0" :disabled="edit"/>
+        </el-form-item>
+        <el-form-item label="类型">
+          <el-select
+            v-model="form.status"
+            placeholder="请选择角色类型"
+            clearable
+            style="width: 240px"
+            :disabled="edit"
+          >
+            <el-option
+              v-for="item in typeOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
         </el-form-item>
         <el-form-item label="状态">
           <el-select
@@ -138,6 +147,7 @@
             placeholder="请选择用户状态"
             clearable
             style="width: 240px"
+            :disabled="edit"
           >
             <el-option
               v-for="item in statusOptions"
@@ -164,7 +174,7 @@
           ></el-tree>
         </el-form-item>
         <el-form-item label="备注">
-          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :disabled="edit"></el-input>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -228,10 +238,15 @@ export default {
   dicts: ['sys_normal_disable'],
   data() {
     return {
+      typeOptions: [
+        {value: '0', label: '管理员'},
+        {value: '1', label: '业务员'}
+      ],
       statusOptions: [
         {value: '0', label: '正常'},
         {value: '1', label: '停用'}
       ],
+      edit:false,
       showTable: true,
       // 遮罩层
       loading: true,
@@ -318,8 +333,20 @@ export default {
     this.getList();
   },
   methods: {
+    // 列表状态格式化
+    typeFormat({cellValue}) {
+      let belongTo = '未知的类型'
+      for (let i = 0; i < this.typeOptions.length; i++) {
+        if (cellValue == "0") {
+          belongTo = "管理员"
+        } else if (cellValue == "1") {
+          belongTo = "业务员"
+        }
+      }
+      return belongTo
+    },
     /** 查询角色列表 */
-    getList: debounce(function () {
+    getList(){
       this.loading = true;
       var searchParams = {
         currentPage: this.currentPage,
@@ -341,7 +368,7 @@ export default {
       }).catch((error) => {
         // this.$message.error('获取数据出错' + error)
       })
-    }, 500),
+    },
     handlePageChange({currentPage, pageSize}) {
       this.currentPage = currentPage
       this.pageSize = pageSize
@@ -376,15 +403,6 @@ export default {
       checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
       return checkedKeys;
     },
-    // 所有部门节点数据
-    getDeptAllCheckedKeys() {
-      // 目前被选中的部门节点
-      let checkedKeys = this.$refs.dept.getCheckedKeys();
-      // 半选中的部门节点
-      let halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys();
-      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
-      return checkedKeys;
-    },
     /** 根据角色ID查询菜单树结构 */
     getRoleMenuTreeselect(roleId) {
       var param = {
@@ -425,6 +443,7 @@ export default {
       if (this.$refs.menu != undefined) {
         this.$refs.menu.setCheckedKeys([]);
       }
+      this.edit = false,
       this.menuExpand = false,
         this.menuNodeAll = false,
         this.deptExpand = true,
@@ -444,10 +463,10 @@ export default {
       this.resetForm("form");
     },
     /** 搜索按钮操作 */
-    handleQuery() {
+    handleQuery:debounce(function(){
       this.queryParams.pageNum = 1;
       this.getList();
-    },
+    },1000),
     /** 重置按钮操作 */
     resetQuery() {
       this.dateRange = [];
@@ -505,6 +524,7 @@ export default {
       this.getMenuTreeselect();
       this.open = true;
       this.title = "添加角色";
+      this.edit=false;
     }, 500),
     /** 修改按钮操作 */
     handleUpdate:debounce(function () {
@@ -517,6 +537,11 @@ export default {
         });
         return
       }
+
+      if (_selectData.roleKey=='system' || _selectData.roleKey=='audit'){
+        this.edit=true;
+      }
+
       const roleId = _selectData.roleId
       // const roleMenu = this.getRoleMenuTreeselect(roleId);
         var param = {
@@ -539,7 +564,7 @@ export default {
           })
         })
         this.title = "修改角色";
-    }, 500),
+    }, 1000),
     /** 选择角色权限范围触发 */
     dataScopeSelectChange(value) {
       if (value !== '2') {
@@ -555,6 +580,16 @@ export default {
     submitForm: debounce(function () {
       this.$refs["form"].validate(valid => {
         if (valid) {
+          if (this.form.roleKey.trim()=='system' || this.form.roleKey.trim()=='audit'){
+            if (this.form.builtIn!='0'){
+              // 不是内置用户则拦截
+              this.$message({
+                type: 'warning',
+                message: '字符标识不能是system或audit!'
+              });
+              return
+            }
+          }
           if (this.form.roleId != undefined) {
             this.form.menuIds = this.getMenuAllCheckedKeys();
             // 更新操作
@@ -594,7 +629,7 @@ export default {
           }
         }
       });
-    }, 500),
+    }, 1000),
     /** 提交按钮(数据权限) */
     submitDataScope: function () {
       if (this.form.roleId != undefined) {
@@ -616,6 +651,15 @@ export default {
         });
         return
       }
+
+      if (_selectData.roleKey=='system' || _selectData.roleKey=='audit'){
+        this.$message({
+          type: 'warning',
+          message: '内置角色不能删除!'
+        });
+        return
+      }
+
       this.$confirm('是否确认删除角色?', '提示', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
@@ -629,7 +673,6 @@ export default {
      * 删除提交
      */
     doDelete:debounce(function(_selectData){
-      console.log(_selectData)
       const param = {
         roleId: _selectData.roleId
       }

+ 7 - 4
ui/src/views/sysManager/sysParameter/index.vue

@@ -21,9 +21,8 @@
         style="width: 300px;margin: 0px;padding: 0px;"
         size="mini"
         prefix-icon="el-icon-search"
-        @keyup.enter.native="handleQuery"
       />
-      <el-button type="primary" icon="el-icon-search" size="mini" @click="getList">搜索</el-button>
+      <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
       <div style="padding-top: 10px">
         <vxe-table
           ref="xTable"
@@ -160,7 +159,11 @@ export default {
       }
       return true
     },
-    getList:debounce(function(){
+    /** 搜索按钮操作 */
+    handleQuery:debounce(function(){
+      this.getList()
+    },1000),
+    getList(){
       this.loading = true;
       var searchParams = {
         currentPage: this.currentPage,
@@ -181,7 +184,7 @@ export default {
       }).catch((error) => {
         // this.$message.error('获取数据出错' + error)
       })
-    },1000),
+    },
     handlePageChange({ currentPage, pageSize }) {
       this.currentPage = currentPage
       this.pageSize = pageSize

+ 206 - 25
ui/src/views/sysManager/userManager/index.vue

@@ -109,11 +109,12 @@
             <vxe-column type="radio" width="60"/>
             <vxe-table-column field="username" title="用户账号"/>
             <vxe-table-column field="nickname" title="用户姓名"/>
-            <vxe-table-column field="mailbox" title="邮箱"/>
+            <vxe-table-column field="mailbox" title="用户邮箱"/>
             <vxe-table-column field="phonenumber" title="手机号码"/>
-            <vxe-table-column field="status" title="状态" :formatter="statusFormat"/>
+            <vxe-table-column field="status" title="用户状态" :formatter="statusFormat"/>
+            <vxe-table-column field="usertype" title="用户类型" :formatter="typeFormat"/>
             <vxe-table-column title="操作" width="320">
-              <template slot-scope="scope" v-if="scope.row.userId !== 1">
+              <template slot-scope="scope" v-if="scope.row.id !== 1">
                 <el-button
                   size="mini"
                   type="text"
@@ -127,6 +128,7 @@
                   type="text"
                   icon="el-icon-delete"
                   @click="handleAuthRole(scope.row)"
+                  v-hasPermi="['system:user:role']"
                 >分配角色
                 </el-button>
               </template>
@@ -165,7 +167,7 @@
         </el-row>
         <el-row>
           <el-col :span="12">
-            <el-form-item label="邮箱" prop="mailbox">
+            <el-form-item label="用户邮箱" prop="mailbox">
               <el-input style="width: 220px" v-model="form.mailbox" placeholder="请输入邮箱" maxlength="50"/>
             </el-form-item>
           </el-col>
@@ -177,7 +179,7 @@
         </el-row>
         <el-row>
           <el-col :span="12">
-            <el-form-item label="状态">
+            <el-form-item label="用户状态">
               <el-select style="width: 220px" v-model="form.status" placeholder="请选择状态">
                 <el-option
                   v-for="item in statusOptions"
@@ -189,14 +191,13 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="角色">
-              <el-select style="width: 220px" v-model="form.roleIds" multiple placeholder="请选择角色">
+            <el-form-item label="用户类型">
+              <el-select style="width: 220px" v-model="form.usertype" placeholder="请选择类型">
                 <el-option
-                  v-for="item in roleOptions"
-                  :key="item.roleId"
-                  :label="item.roleName"
-                  :value="item.roleId"
-                  :disabled="item.status == 1"
+                  v-for="item in typeOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
                 ></el-option>
               </el-select>
             </el-form-item>
@@ -208,6 +209,48 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+
+    <!-- 分配角色对话框 -->
+    <el-dialog :title="jstitle" :visible.sync="jsopen" width="650px" append-to-body>
+      <el-form width="630px" label-width="80px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="用户账号">
+              <el-input style="width: 220px" v-model="jsusername"
+                        maxlength="20" :disabled="true"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="用户姓名">
+              <el-input style="width: 220px" v-model="jsnickname" maxlength="30" :disabled="true"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div style="padding-top: 10px">
+        <vxe-table
+          ref="xTable"
+          align="center"
+          :loading="loading"
+          class="mytable-style"
+          auto-resize
+          border
+          resizable
+          export-config
+          highlight-current-row
+          show-overflow
+          max-height="700"
+          :data="roleList"
+        >
+          <vxe-column type="selection" :reserve-selection="true" width="60"/>
+          <vxe-table-column field="roleName" title="角色名称"/>
+        </vxe-table>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="jssubmitForm">确 定</el-button>
+        <el-button @click="jscancel">取 消</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -217,11 +260,21 @@ export default {
   name: "User",
   data() {
     return {
+      // 角色表格数据
+      jsuserid:'',
+      roleList: [],
+      jsusername:'',
+      jsnickname:'',
+      jsusertype:'',
       statusOptions: [
         {value: '0', label: '正常'},
         {value: '1', label: '锁定'},
         {value: '2', label: '注销'}
       ],
+      typeOptions: [
+        {value: '0', label: '管理员'},
+        {value: '1', label: '普通用户'}
+      ],
       // 遮罩层
       loading: true,
       showTable: true,
@@ -239,8 +292,12 @@ export default {
       userList: null,
       // 弹出层标题
       title: "",
+      // 角色分配弹出层标题
+      jstitle: "",
       // 是否显示弹出层
       open: false,
+      // 角色是否显示弹出层
+      jsopen: false,
       // 默认密码
       initPassword: undefined,
       // 角色选项
@@ -299,8 +356,20 @@ export default {
       }
       return belongTo
     },
+    // 列表状态格式化
+    typeFormat({cellValue}) {
+      let belongTo = '未知的类型'
+      for (let i = 0; i < this.typeOptions.length; i++) {
+        if (cellValue == "0") {
+          belongTo = "管理员"
+        } else if (cellValue == "1") {
+          belongTo = "普通用户"
+        }
+      }
+      return belongTo
+    },
     /** 查询用户列表 */
-    getList:debounce(function(){
+    getList(){
       this.loading = true;
       var searchParams = {
         currentPage: this.currentPage,
@@ -323,7 +392,7 @@ export default {
       }).catch((error) => {
         // this.$message.error(error)
       })
-    },0),
+    },
     // 用户状态修改
     handleStatusChange(row) {
       let text = row.status === "0" ? "启用" : "停用";
@@ -340,6 +409,10 @@ export default {
       this.open = false;
       this.reset();
     },
+    // 角色取消按钮
+    jscancel() {
+      this.jsopen = false;
+    },
     // 表单重置
     reset() {
       this.edit = false;
@@ -350,14 +423,15 @@ export default {
         phonenumber: undefined,
         mailbox: undefined,
         status: "0",
+        usertype: "0",
         remark: undefined
       };
       this.resetForm("form");
     },
     /** 搜索按钮操作 */
-    handleQuery() {
-      this.getList();
-    },
+    handleQuery:debounce(function(){
+      this.getList()
+    },1000),
     /** 重置按钮操作 */
     resetQuery() {
       this.resetForm("queryForm");
@@ -449,7 +523,7 @@ export default {
         })
       }).catch(() => {
       });
-    },1000),
+    },500),
     /** 删除按钮操作 */
     handleDelete(){
       const _selectData = this.$refs.userTable.getRadioRecord(true)
@@ -460,6 +534,13 @@ export default {
         });
         return
       }
+      if (_selectData.id==1) {
+        this.$message({
+          type: 'warning',
+          message: '内置系统管理员不能删除!'
+        });
+        return
+      }
       this.$prompt('请输入密码','鉴别操作',{
         confirmButtonText: '确定',
         cancelButtonText: '取消',
@@ -472,7 +553,7 @@ export default {
         inputErrorMessage: '不能为空,最多可录入20个字符'
       }).then(async({value})=>{
         this.doDelete(_selectData,value)
-      })
+      }).catch((e)=>{})
     },
     /**
      * 删除提交
@@ -503,7 +584,7 @@ export default {
         console.log(error)
         this.loading = false
       })
-    },1000),
+    },500),
     /** 修改按钮操作 */
     handleUpdate() {
       this.reset();
@@ -575,12 +656,112 @@ export default {
         this.loading = false
       })
     },1000),
-
+    getUserRole(userid){
+      const a = this.$axios
+      return new Promise(function(resolve, reject) {
+        var userRoleParams = {
+          userId: userid
+        }
+        a.get('/sysUserController/getUserRole',
+          {params: userRoleParams}).then(res => {
+            // 返回userRole对象
+          resolve(res.data)
+        })
+      }).catch((error) => {
+        console.error('获取用户角色出错' + error)
+      })
+    },
+    getRoleByType(usertype){
+      // 根据用户类型获取角色列表
+      const a = this.$axios
+      let _this = this
+      return new Promise(function(resolve, reject) {
+        var searchParams = {
+          usertype: usertype
+        }
+        a.get('/sysRoleController/getRoleByType',
+          {params: searchParams}).then(res => {
+          if (res.code == 0) {
+            // 返回角色列表
+            _this.roleList = res.data
+            resolve(res.data)
+          } else {
+            // 输出后端返回信息
+            this.$message({
+              type: 'error',
+              message: res.data
+            });
+          }
+        })
+      }).catch((error) => {
+        this.$message.error(error)
+      })
+    },
     /** 分配角色操作 */
-    handleAuthRole: function (row) {
-      const userId = row.userId;
-      this.$router.push("/system/user-auth/role/" + userId);
-    }
+    handleAuthRole:debounce(function(row){
+      this.jsuserid = row.id
+      this.jsusername = row.username
+      this.jsnickname = row.nickname
+      this.jsopen = true;
+      this.title = "分配角色";
+
+      Promise.all([this.getRoleByType(row.usertype),this.getUserRole(this.jsuserid)]).then((res) => {
+        if (res[1]!='' && res[1]!=undefined){
+          const roleTable = this.$refs.xTable.getTableData()
+          for (var i=0;i<roleTable.tableData.length;i++){
+            if (res[1].roleId==roleTable.tableData[i].roleId){
+              // 将原有的角色勾选上
+              this.$refs.xTable.setCheckboxRow(roleTable.tableData[i], true)
+            }
+          }
+        }
+      }).catch(e=>{
+        console.log(e)
+        this.$message.error("获取分配角色异常:"+e)
+      })
+    },1000),
+    /** 角色分配提交按钮 */
+    jssubmitForm:debounce(function(){
+      const _selectData = this.$refs.xTable.getCheckboxRecords(true)
+      if (_selectData.length>1){
+        this.$message({
+          type: 'warning',
+          message: '每个用户只能分配一个角色!'
+        });
+        return
+      }
+      let roleid = '';
+      if (_selectData.length==1){
+        roleid = _selectData[0].roleId
+      }
+
+      // 提交后台角色分配
+      const param = {
+        userId: this.jsuserid,
+        roleId:  roleid
+      }
+      this.$axios.post('/sysUserController/authRole', param).then((res) => {
+        if (res.code == 0) {
+          this.$message({
+            type: 'success',
+            message: '角色分配成功!'
+          });
+          this.jscancel()
+        } else {
+          this.$message({
+            type: 'error',
+            message: res.data
+          });
+        }
+      }).catch((error) => {
+        this.$message({
+          type: 'error',
+          message: '角色分配失败!'
+        });
+        console.log(error)
+        this.loading = false
+      })
+    },1000)
   }
 };
 </script>

+ 1 - 1
ui/src/views/sysManager/userManager/profile/index.vue

@@ -54,7 +54,7 @@ export default {
   },
   created() {
     // 用户信息解密
-    let decryptUserInfo = userinfoDecrypt(sessionStorage.getItem('userinfo'))
+    let decryptUserInfo = userinfoDecrypt(sessionStorage.getItem('active'))
     this.user = JSON.parse(decryptUserInfo).sysUser
   },
   methods: {

+ 1 - 1
ui/src/views/sysManager/userManager/profile/resetPwd.vue

@@ -116,7 +116,7 @@ export default {
             return
           }
           // 用户信息解密
-          let decryptUserInfo = userinfoDecrypt(sessionStorage.getItem('userinfo'))
+          let decryptUserInfo = userinfoDecrypt(sessionStorage.getItem('active'))
           this.user = JSON.parse(decryptUserInfo).sysUser
           const param = {
             id: this.user.id,

+ 22 - 1
ui/vue.config.js

@@ -15,6 +15,7 @@ const name = defaultSettings.title || 'vue Admin Template' // page title
 // port = 9528 npm run dev OR npm run dev --port = 9528
 const port = process.env.port || process.env.npm_config_port || 9527 // dev port
 
+const Version = new Date().getTime()
 // All configuration item explanations can be find in https://cli.vuejs.org/config/
 module.exports = {
   /**
@@ -33,7 +34,7 @@ module.exports = {
   pages: {
     index: {
       entry: './src/main.js',
-      template: './src/index.html',
+      template: './public/index.html',
       filename: 'index.html'
     }
   },
@@ -66,6 +67,12 @@ module.exports = {
       alias: {
         '@': resolve('src')
       }
+    },
+    output: { // 输出重构  打包编译后的 文件名称  【模块名称.版本号.时间戳】
+      // filename: utils.assetsPath('js/[name].[chunkhash].'+Version+'js'),
+      // chunkFilename: utils.assetsPath('js/[id].[chunkhash].'+Version+'js')
+      filename: 'static/js/[name].${Version}.js',         // js打包文件,添加时间戳
+      chunkFilename: 'static/js/[name].${Version}.js'
     }
   },
   chainWebpack(config) {
@@ -99,6 +106,20 @@ module.exports = {
         return options
       })
       .end()
+// img的文件名修改   // img打包文件,添加时间戳
+    config.module
+      .rule('images')
+      .use('url-loader')
+      .tap(options => {
+        options.name = `static/img/[name].${Version}.[ext]`
+        options.fallback = {
+          loader: 'file-loader',
+          options: {
+            name: `static/img/[name].${Version}.[ext]`
+          }
+        }
+        return options
+      })
 
     config
       // https://webpack.js.org/configuration/devtool/#development