Jelajahi Sumber

SAAS管理系统

he2802 4 tahun lalu
induk
melakukan
da36fabe13
30 mengubah file dengan 1602 tambahan dan 53 penghapusan
  1. 1 1
      pom.xml
  2. 3 0
      zhongzheng-admin/src/main/java/com/zhongzheng/core/config/SwaggerConfig.java
  3. 0 36
      zhongzheng-certificate-admin/src/main/java/com/zhongzheng/controller/TestController.java
  4. 7 0
      zhongzheng-common/src/main/java/com/zhongzheng/common/constant/Constants.java
  5. 168 0
      zhongzheng-common/src/main/java/com/zhongzheng/common/core/domain/entity/SuperSysUser.java
  6. 143 0
      zhongzheng-common/src/main/java/com/zhongzheng/common/core/domain/model/SuperLoginUser.java
  7. 5 0
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/mybatisplus/CustomTenantLineHandler.java
  8. 25 7
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/security/filter/JwtAuthenticationTokenFilter.java
  9. 98 0
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/SuperSysLoginService.java
  10. 271 0
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/SuperTokenService.java
  11. 42 0
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/UserDetailsServiceImpl.java
  12. 2 2
      zhongzheng-quartz/src/main/java/com/zhongzheng/quartz/service/impl/SysJobServiceImpl.java
  13. 39 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/system/mapper/SuperSysUserMapper.java
  14. 146 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/system/service/ISuperSysUserService.java
  15. 275 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/system/service/impl/SuperSysUserServiceImpl.java
  16. 129 0
      zhongzheng-system/src/main/resources/mapper/modules/system/SuperSysUserMapper.xml
  17. 1 1
      zhongzheng-top-admin/pom.xml
  18. 3 3
      zhongzheng-top-admin/src/main/java/com/zhongzheng/TopAdminApplication.java
  19. 2 2
      zhongzheng-top-admin/src/main/java/com/zhongzheng/TopAdminServletInitializer.java
  20. 136 0
      zhongzheng-top-admin/src/main/java/com/zhongzheng/controller/common/CaptchaController.java
  21. 105 0
      zhongzheng-top-admin/src/main/java/com/zhongzheng/controller/top/SuperSysLoginController.java
  22. 0 0
      zhongzheng-top-admin/src/main/java/com/zhongzheng/core/config/SwaggerConfig.java
  23. 0 0
      zhongzheng-top-admin/src/main/resources/META-INF/spring-devtools.properties
  24. 0 0
      zhongzheng-top-admin/src/main/resources/application-dev.yml
  25. 0 0
      zhongzheng-top-admin/src/main/resources/application-prod.yml
  26. 1 1
      zhongzheng-top-admin/src/main/resources/application.yml
  27. 0 0
      zhongzheng-top-admin/src/main/resources/banner.txt
  28. 0 0
      zhongzheng-top-admin/src/main/resources/i18n/messages.properties
  29. 0 0
      zhongzheng-top-admin/src/main/resources/logback.xml
  30. 0 0
      zhongzheng-top-admin/src/main/resources/mybatis/mybatis-config.xml

+ 1 - 1
pom.xml

@@ -217,7 +217,7 @@
         <module>zhongzheng-quartz</module>
         <module>zhongzheng-generator</module>
         <module>zhongzheng-common</module>
-        <module>zhongzheng-certificate-admin</module>
+        <module>zhongzheng-top-admin</module>
     </modules>
     <packaging>pom</packaging>
 

+ 3 - 0
zhongzheng-admin/src/main/java/com/zhongzheng/core/config/SwaggerConfig.java

@@ -141,6 +141,9 @@ public class SwaggerConfig
         // header query cookie
         parameterBuilder.name("X-Auth-Token").description("token").modelRef(new ModelRef("string")).parameterType("header").defaultValue("test").required(false);
         pars.add(parameterBuilder.build());
+        ParameterBuilder parameterBuilder1 = new ParameterBuilder();
+        parameterBuilder1.name("TenantId").description("TenantId").modelRef(new ModelRef("string")).parameterType("header").defaultValue("867735392558919680").required(false);
+        pars.add(parameterBuilder1.build());
         return pars;
     }
 

+ 0 - 36
zhongzheng-certificate-admin/src/main/java/com/zhongzheng/controller/TestController.java

@@ -1,36 +0,0 @@
-package com.zhongzheng.controller;
-
-import com.zhongzheng.common.core.controller.BaseController;
-import com.zhongzheng.common.core.domain.AjaxResult;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-
-@Api(tags ="测试模块")
-@RestController
-@RequestMapping("/v1/test")
-public class TestController extends BaseController
-{
-    private final static Map<Integer, String> users = new LinkedHashMap<Integer, String>();
-    {
-        users.put(1, "123456");
-        users.put(2, "654321");
-    }
-
-    @ApiOperation("获取用户列表")
-    @GetMapping("/list")
-    public AjaxResult userList()
-    {
-        List<String> userList = new ArrayList<String>(users.values());
-        return AjaxResult.success(userList);
-    }
-
-}

+ 7 - 0
zhongzheng-common/src/main/java/com/zhongzheng/common/constant/Constants.java

@@ -86,6 +86,11 @@ public class Constants
      */
     public static final String TOKEN_PREFIX = "Bearer ";
 
+    /**
+     * 超级管理员令牌前缀
+     */
+    public static final String SUPER_TOKEN_PREFIX = "BearerSuper ";
+
     /**
      * 微信令牌前缀
      */
@@ -98,6 +103,8 @@ public class Constants
 
     public static final String WX_LOGIN_USER_KEY = "wx_login_user_key";
 
+    public static final String SUPER_LOGIN_USER_KEY = "super_login_user_key";
+
     /**
      * 用户ID
      */

+ 168 - 0
zhongzheng-common/src/main/java/com/zhongzheng/common/core/domain/entity/SuperSysUser.java

@@ -0,0 +1,168 @@
+package com.zhongzheng.common.core.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.zhongzheng.common.annotation.Excel;
+import com.zhongzheng.common.annotation.Excel.ColumnType;
+import com.zhongzheng.common.annotation.Excel.Type;
+import com.zhongzheng.common.annotation.Excels;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 用户对象 super_sys_user
+ *
+ * @author hjl
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class SuperSysUser implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 用户ID */
+    @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
+    @TableId(value = "user_id",type = IdType.AUTO)
+    private Long userId;
+
+    /** 部门ID */
+    @Excel(name = "部门编号", type = Type.IMPORT)
+    private Long deptId;
+
+    /** 用户账号 */
+    @NotBlank(message = "用户账号不能为空")
+    @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
+    @Excel(name = "登录名称")
+    private String userName;
+
+    /** 用户昵称 */
+    @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
+    @Excel(name = "用户名称")
+    private String nickName;
+
+    /** 用户邮箱 */
+    @Email(message = "邮箱格式不正确")
+    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
+    @Excel(name = "用户邮箱")
+    private String email;
+
+    /** 手机号码 */
+    @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
+    @Excel(name = "手机号码")
+    private String phonenumber;
+
+    /** 用户性别 */
+    @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
+    private String sex;
+
+    /** 用户头像 */
+    private String avatar;
+
+    /** 密码 */
+    private String password;
+
+    @JsonIgnore
+    @JsonProperty
+    public String getPassword() {
+        return password;
+    }
+
+    /** 盐加密 */
+    private String salt;
+
+    /** 帐号状态(1正常 0停用) */
+    @Excel(name = "帐号状态", readConverterExp = "1=正常,0=停用")
+    private String status;
+
+    /** 删除标志(0代表存在 2代表删除) */
+    @TableLogic
+    private String delFlag;
+
+    /** 最后登录IP */
+    @Excel(name = "最后登录IP", type = Type.EXPORT)
+    private String loginIp;
+
+    /** 最后登录时间 */
+    @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
+    private Date loginDate;
+
+    /** 创建者 */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    /** 创建时间 */
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /** 更新者 */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
+
+    /** 更新时间 */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /** 备注 */
+    private String remark;
+
+    @TableField(exist = false)
+    private List<String> statusArray;
+
+    /**
+     * 请求参数
+     */
+    @TableField(exist = false)
+    private Map<String, Object> params = new HashMap<>();
+
+    /** 部门对象 */
+    @Excels({
+        @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
+        @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
+    })
+    @TableField(exist = false)
+    private SysDept dept;
+
+    /** 角色对象 */
+    @TableField(exist = false)
+    private List<SysRole> roles;
+
+    /** 角色组 */
+    @TableField(exist = false)
+    private Long[] roleIds;
+
+    /** 岗位组 */
+    @TableField(exist = false)
+    private Long[] postIds;
+
+    public SuperSysUser(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public boolean isAdmin()
+    {
+        return isAdmin(this.userId);
+    }
+
+    public static boolean isAdmin(Long userId)
+    {
+        return userId != null && 1L == userId;
+    }
+
+}

+ 143 - 0
zhongzheng-common/src/main/java/com/zhongzheng/common/core/domain/model/SuperLoginUser.java

@@ -0,0 +1,143 @@
+package com.zhongzheng.common.core.domain.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.zhongzheng.common.core.domain.entity.SuperSysUser;
+import com.zhongzheng.common.core.domain.entity.SysUser;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * 登录用户身份权限
+ *
+ * @author hjl
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class SuperLoginUser implements UserDetails
+{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户唯一标识
+     */
+    private String token;
+
+    /**
+     * 登录时间
+     */
+    private Long loginTime;
+
+    /**
+     * 过期时间
+     */
+    private Long expireTime;
+
+    /**
+     * 登录IP地址
+     */
+    private String ipaddr;
+
+    /**
+     * 登录地点
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+
+    /**
+     * 权限列表
+     */
+    private Set<String> permissions;
+
+    /**
+     * 用户信息
+     */
+    private SuperSysUser user;
+
+    public SuperLoginUser(SuperSysUser user, Set<String> permissions)
+    {
+        this.user = user;
+        this.permissions = permissions;
+    }
+
+    @JsonIgnore
+    @Override
+    public String getPassword()
+    {
+        return user.getPassword();
+    }
+
+    @Override
+    public String getUsername()
+    {
+        return user.getUserName();
+    }
+
+    /**
+     * 账户是否未过期,过期无法验证
+     */
+    @JsonIgnore
+    @Override
+    public boolean isAccountNonExpired()
+    {
+        return true;
+    }
+
+    /**
+     * 指定用户是否解锁,锁定的用户无法进行身份验证
+     *
+     * @return
+     */
+    @JsonIgnore
+    @Override
+    public boolean isAccountNonLocked()
+    {
+        return true;
+    }
+
+    /**
+     * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
+     *
+     * @return
+     */
+    @JsonIgnore
+    @Override
+    public boolean isCredentialsNonExpired()
+    {
+        return true;
+    }
+
+    /**
+     * 是否可用 ,禁用的用户不能身份验证
+     *
+     * @return
+     */
+    @JsonIgnore
+    @Override
+    public boolean isEnabled()
+    {
+        return true;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities()
+    {
+        return null;
+    }
+}

+ 5 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/mybatisplus/CustomTenantLineHandler.java

@@ -27,6 +27,11 @@ public class CustomTenantLineHandler implements TenantLineHandler {
      */
     private final static List<String> IGNORE_TABLE_NAMES = new ArrayList<String>(){{
         add("sys_tenant");
+        add("super_sys_user");
+        add("super_sys_dept");
+        add("super_sys_role");
+        add("super_sys_user_role");
+        add("tables");
     }};
 
 

+ 25 - 7
zhongzheng-framework/src/main/java/com/zhongzheng/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -1,6 +1,8 @@
 package com.zhongzheng.framework.security.filter;
 
 import cn.hutool.core.lang.Validator;
+import com.zhongzheng.common.core.domain.model.SuperLoginUser;
+import com.zhongzheng.framework.web.service.SuperTokenService;
 import com.zhongzheng.modules.user.entity.ClientLoginUser;
 import com.zhongzheng.common.core.domain.model.LoginUser;
 import com.zhongzheng.common.utils.SecurityUtils;
@@ -34,6 +36,9 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
     @Autowired
     private WxTokenService wxTokenService;
 
+    @Autowired
+    private SuperTokenService superTokenService;
+
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
             throws ServletException, IOException
@@ -49,13 +54,26 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
                 SecurityContextHolder.getContext().setAuthentication(authenticationToken);
             }
         }else{
-            LoginUser loginUser = tokenService.getLoginUser(request);
-            if (Validator.isNotNull(loginUser) && Validator.isNull(SecurityUtils.getAuthentication()))
-            {
-                tokenService.verifyToken(loginUser);
-                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
-                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+            String superToken = superTokenService.getToken(request);
+            if(StringUtils.isNoneEmpty(superToken)){
+                //超级管理员
+                SuperLoginUser super_loginUser = superTokenService.getLoginUser(request);
+                if (Validator.isNotNull(super_loginUser) && Validator.isNull(SecurityUtils.getAuthentication()))
+                {
+                    superTokenService.verifyToken(super_loginUser);
+                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(super_loginUser, null, super_loginUser.getAuthorities());
+                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+                }
+            }else{
+                LoginUser loginUser = tokenService.getLoginUser(request);
+                if (Validator.isNotNull(loginUser) && Validator.isNull(SecurityUtils.getAuthentication()))
+                {
+                    tokenService.verifyToken(loginUser);
+                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
+                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+                }
             }
         }
         chain.doFilter(request, response);

+ 98 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/SuperSysLoginService.java

@@ -0,0 +1,98 @@
+package com.zhongzheng.framework.web.service;
+
+import com.zhongzheng.common.constant.Constants;
+import com.zhongzheng.common.core.domain.model.LoginUser;
+import com.zhongzheng.common.core.domain.model.SuperLoginUser;
+import com.zhongzheng.common.core.redis.RedisCache;
+import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.exception.user.CaptchaException;
+import com.zhongzheng.common.exception.user.CaptchaExpireException;
+import com.zhongzheng.common.exception.user.UserPasswordNotMatchException;
+import com.zhongzheng.common.utils.MessageUtils;
+import com.zhongzheng.framework.manager.AsyncManager;
+import com.zhongzheng.framework.manager.factory.AsyncFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 登录校验方法
+ *
+ * @author zhongzheng
+ */
+@Component
+public class SuperSysLoginService
+{
+    @Autowired
+    private SuperTokenService tokenService;
+
+    @Resource
+    private AuthenticationManager authenticationManager;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    /**
+     * 登录验证
+     *
+     * @param username 用户名
+     * @param password 密码
+     * @param code 验证码
+     * @param uuid 唯一标识
+     * @return 结果
+     */
+    public String login(String username, String password, String code, String uuid)
+    {
+        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+        String captcha = redisCache.getCacheObject(verifyKey);
+        redisCache.deleteObject(verifyKey);
+        if (captcha == null)
+        {
+            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
+            throw new CaptchaExpireException();
+        }
+        if (!code.equalsIgnoreCase(captcha))
+        {
+            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
+            throw new CaptchaException();
+        }
+        // 用户验证
+        Authentication authentication = null;
+        try
+        {
+            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
+            String super_username = "##super##"+username;
+            authentication = authenticationManager
+                    .authenticate(new UsernamePasswordAuthenticationToken(super_username, password));
+        }
+        catch (Exception e)
+        {
+            if (e instanceof BadCredentialsException)
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+                throw new UserPasswordNotMatchException();
+            }
+            else
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
+                throw new CustomException(e.getMessage());
+            }
+        }
+    //    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+        SuperLoginUser loginUser = (SuperLoginUser) authentication.getPrincipal();
+        // 生成token
+        return tokenService.createToken(loginUser);
+    }
+
+   /* public String wx_login(String username)
+    {
+        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        // 生成token
+        return tokenService.createToken(loginUser);
+    }*/
+}

+ 271 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/SuperTokenService.java

@@ -0,0 +1,271 @@
+package com.zhongzheng.framework.web.service;
+
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import com.zhongzheng.common.constant.Constants;
+import com.zhongzheng.common.core.domain.model.LoginUser;
+import com.zhongzheng.common.core.domain.model.SuperLoginUser;
+import com.zhongzheng.common.core.redis.RedisCache;
+import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.exception.user.UserPasswordNotMatchException;
+import com.zhongzheng.common.utils.MessageUtils;
+import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.common.utils.ip.AddressUtils;
+import com.zhongzheng.common.utils.ip.IpUtils;
+import com.zhongzheng.framework.manager.AsyncManager;
+import com.zhongzheng.framework.manager.factory.AsyncFactory;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * token验证处理
+ *
+ * @author zhongzheng
+ */
+@Component
+public class SuperTokenService
+{
+    // 令牌自定义标识
+    @Value("${token.header}")
+    private String header;
+
+    // 令牌秘钥
+    @Value("${token.secret}")
+    private String secret;
+
+    // 令牌有效期(默认30分钟)
+    @Value("${token.expireTime}")
+    private int expireTime;
+
+    protected static final long MILLIS_SECOND = 1000;
+
+    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
+
+    private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Resource
+    private AuthenticationManager authenticationManager;
+
+    /**
+     * 获取用户身份信息
+     *
+     * @return 用户信息
+     */
+    public SuperLoginUser getLoginUser(HttpServletRequest request)
+    {
+
+        //测试用户
+        String test_token = request.getHeader("X-Auth-Token");
+        if("test".equals(test_token)){
+            return getTestUser();
+        }
+        // 获取请求携带的令牌
+        String token = getToken(request);
+        if (Validator.isNotEmpty(token))
+        {
+            Claims claims = parseToken(token);
+            // 解析对应的权限以及用户信息
+            String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
+            String userKey = getTokenKey(uuid);
+            SuperLoginUser user = redisCache.getCacheObject(userKey);
+            return user;
+        }
+
+        return null;
+    }
+
+    private SuperLoginUser getTestUser(){
+        Authentication authentication = null;
+        try
+        {
+            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
+            authentication = authenticationManager
+                    .authenticate(new UsernamePasswordAuthenticationToken("##super##admin", "admin123"));
+        }
+        catch (Exception e)
+        {
+            if (e instanceof BadCredentialsException)
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor("admin", Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+                throw new UserPasswordNotMatchException();
+            }
+            else
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor("admin", Constants.LOGIN_FAIL, e.getMessage()));
+                throw new CustomException(e.getMessage());
+            }
+        }
+        SuperLoginUser loginUser = (SuperLoginUser) authentication.getPrincipal();
+        loginUser.setExpireTime(System.currentTimeMillis()+200);
+        return loginUser;
+    }
+
+    /**
+     * 设置用户身份信息
+     */
+    public void setLoginUser(SuperLoginUser loginUser)
+    {
+        if (Validator.isNotNull(loginUser) && Validator.isNotEmpty(loginUser.getToken()))
+        {
+            refreshToken(loginUser);
+        }
+    }
+
+    /**
+     * 删除用户身份信息
+     */
+    public void delLoginUser(String token)
+    {
+        if (Validator.isNotEmpty(token))
+        {
+            String userKey = getTokenKey(token);
+            redisCache.deleteObject(userKey);
+        }
+    }
+
+    /**
+     * 创建令牌
+     *
+     * @param loginUser 用户信息
+     * @return 令牌
+     */
+    public String createToken(SuperLoginUser loginUser)
+    {
+        String token = IdUtil.fastUUID();
+        loginUser.setToken(token);
+        setUserAgent(loginUser);
+        refreshToken(loginUser);
+
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(Constants.LOGIN_USER_KEY, token);
+        return createToken(claims);
+    }
+
+    /**
+     * 验证令牌有效期,相差不足20分钟,自动刷新缓存
+     *
+     * @param loginUser
+     * @return 令牌
+     */
+    public void verifyToken(SuperLoginUser loginUser)
+    {
+        long expireTime = loginUser.getExpireTime();
+        long currentTime = System.currentTimeMillis();
+        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
+        {
+            refreshToken(loginUser);
+        }
+    }
+
+    /**
+     * 刷新令牌有效期
+     *
+     * @param loginUser 登录信息
+     */
+    public void refreshToken(SuperLoginUser loginUser)
+    {
+        loginUser.setLoginTime(System.currentTimeMillis());
+        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
+        // 根据uuid将loginUser缓存
+        String userKey = getTokenKey(loginUser.getToken());
+        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
+    }
+
+    /**
+     * 设置用户代理信息
+     *
+     * @param loginUser 登录信息
+     */
+    public void setUserAgent(SuperLoginUser loginUser)
+    {
+        UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
+        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
+        loginUser.setIpaddr(ip);
+        loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
+        loginUser.setBrowser(userAgent.getBrowser().getName());
+        loginUser.setOs(userAgent.getOs().getName());
+    }
+
+    /**
+     * 从数据声明生成令牌
+     *
+     * @param claims 数据声明
+     * @return 令牌
+     */
+    private String createToken(Map<String, Object> claims)
+    {
+        String token = Jwts.builder()
+                .setClaims(claims)
+                .signWith(SignatureAlgorithm.HS512, secret).compact();
+        return token;
+    }
+
+    /**
+     * 从令牌中获取数据声明
+     *
+     * @param token 令牌
+     * @return 数据声明
+     */
+    private Claims parseToken(String token)
+    {
+        return Jwts.parser()
+                .setSigningKey(secret)
+                .parseClaimsJws(token)
+                .getBody();
+    }
+
+    /**
+     * 从令牌中获取用户名
+     *
+     * @param token 令牌
+     * @return 用户名
+     */
+    public String getUsernameFromToken(String token)
+    {
+        Claims claims = parseToken(token);
+        return claims.getSubject();
+    }
+
+    /**
+     * 获取请求token
+     *
+     * @param request
+     * @return token
+     */
+    public String getToken(HttpServletRequest request)
+    {
+        String token = request.getHeader(header);
+        if (Validator.isNotEmpty(token) && token.startsWith(Constants.SUPER_TOKEN_PREFIX))
+        {
+            token = token.replace(Constants.SUPER_TOKEN_PREFIX, "");
+            return token;
+        }else{
+            return null;
+        }
+
+    }
+
+    private String getTokenKey(String uuid)
+    {
+        return Constants.LOGIN_TOKEN_KEY + uuid;
+    }
+}

+ 42 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/UserDetailsServiceImpl.java

@@ -1,10 +1,13 @@
 package com.zhongzheng.framework.web.service;
 
 import cn.hutool.core.lang.Validator;
+import com.zhongzheng.common.core.domain.entity.SuperSysUser;
 import com.zhongzheng.common.core.domain.entity.SysUser;
 import com.zhongzheng.common.core.domain.model.LoginUser;
+import com.zhongzheng.common.core.domain.model.SuperLoginUser;
 import com.zhongzheng.common.enums.UserStatus;
 import com.zhongzheng.common.exception.BaseException;
+import com.zhongzheng.modules.system.service.ISuperSysUserService;
 import com.zhongzheng.modules.system.service.ISysUserService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -14,6 +17,9 @@ import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.stereotype.Service;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * 用户验证处理
  *
@@ -30,9 +36,37 @@ public class UserDetailsServiceImpl implements UserDetailsService
     @Autowired
     private SysPermissionService permissionService;
 
+    @Autowired
+    private ISuperSysUserService superUserService;
+
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
     {
+        if (username.startsWith("##super##")) {
+            //超级管理系统用户
+            String super_username =username.replace("##super##","");
+            System.out.println("这是超级管理员用户名:"+super_username);
+            SuperSysUser super_user = superUserService.selectUserByUserName(super_username);
+            System.out.println(super_user+"密码AA");
+            System.out.println(super_user.getPassword()+"密码");
+            if (Validator.isNull(super_user))
+            {
+                log.info("登录用户:{} 不存在.", username);
+                throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
+            }
+            else if (UserStatus.DELETED.getCode().equals(super_user.getDelFlag()))
+            {
+                log.info("登录用户:{} 已被删除.", username);
+                throw new BaseException("对不起,您的账号:" + username + " 已被删除");
+            }
+            else if (UserStatus.DISABLE.getCode().equals(super_user.getStatus()))
+            {
+                log.info("登录用户:{} 已被停用.", username);
+                throw new BaseException("对不起,您的账号:" + username + " 已停用");
+            }
+            return createSuperLoginUser(super_user);
+        }
+        //普通系统用户
         SysUser user = userService.selectUserByUserName(username);
         if (Validator.isNull(user))
         {
@@ -57,4 +91,12 @@ public class UserDetailsServiceImpl implements UserDetailsService
     {
         return new LoginUser(user, permissionService.getMenuPermission(user));
     }
+
+    public UserDetails createSuperLoginUser(SuperSysUser user)
+    {
+        Set<String> perms = new HashSet<String>();
+        //拥有所有权限
+        perms.add("*:*:*");
+        return new SuperLoginUser(user, perms);
+    }
 }

+ 2 - 2
zhongzheng-quartz/src/main/java/com/zhongzheng/quartz/service/impl/SysJobServiceImpl.java

@@ -36,11 +36,11 @@ public class SysJobServiceImpl extends ServiceImpl<SysJobMapper, SysJob> impleme
      */
     @PostConstruct
     public void init() throws SchedulerException, TaskException {
-        scheduler.clear();
+       /* scheduler.clear();
         List<SysJob> jobList = list();
         for (SysJob job : jobList) {
             ScheduleUtils.createScheduleJob(scheduler, job);
-        }
+        }*/
     }
 
     /**

+ 39 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/system/mapper/SuperSysUserMapper.java

@@ -0,0 +1,39 @@
+package com.zhongzheng.modules.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.common.core.domain.entity.SuperSysUser;
+import com.zhongzheng.common.core.domain.entity.SysUser;
+
+import java.util.List;
+
+/**
+ * 用户表 数据层
+ *
+ * @author zhongzheng
+ */
+public interface SuperSysUserMapper extends BaseMapper<SuperSysUser> {
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param sysUser 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SuperSysUser> selectUserList(SuperSysUser sysUser);
+
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    public SuperSysUser selectUserByUserName(String userName);
+
+    /**
+     * 通过用户ID查询用户
+     *
+     * @param userId 用户ID
+     * @return 用户对象信息
+     */
+    public SuperSysUser selectUserById(Long userId);
+
+}

+ 146 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/system/service/ISuperSysUserService.java

@@ -0,0 +1,146 @@
+package com.zhongzheng.modules.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.common.core.domain.entity.SuperSysUser;
+import com.zhongzheng.common.core.domain.entity.SysUser;
+
+import java.util.List;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface ISuperSysUserService extends IService<SuperSysUser> {
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SuperSysUser> selectUserList(SuperSysUser user);
+
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    public SuperSysUser selectUserByUserName(String userName);
+
+    /**
+     * 通过用户ID查询用户
+     *
+     * @param userId 用户ID
+     * @return 用户对象信息
+     */
+    public SuperSysUser selectUserById(Long userId);
+
+    /**
+     * 根据用户ID查询用户所属角色组
+     *
+     * @param userName 用户名
+     * @return 结果
+     */
+    public String selectUserRoleGroup(String userName);
+
+    /**
+     * 根据用户ID查询用户所属岗位组
+     *
+     * @param userName 用户名
+     * @return 结果
+     */
+    public String selectUserPostGroup(String userName);
+
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param userName 用户名称
+     * @return 结果
+     */
+    public String checkUserNameUnique(String userName);
+
+    /**
+     * 校验手机号码是否唯一
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public String checkPhoneUnique(SuperSysUser user);
+
+    /**
+     * 校验email是否唯一
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public String checkEmailUnique(SuperSysUser user);
+
+    /**
+     * 校验用户是否允许操作
+     *
+     * @param user 用户信息
+     */
+    public void checkUserAllowed(SuperSysUser user);
+
+    /**
+     * 新增用户信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public int insertUser(SuperSysUser user);
+
+    /**
+     * 修改用户信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public int updateUser(SuperSysUser user);
+
+    /**
+     * 修改用户状态
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public int updateUserStatus(SuperSysUser user);
+
+    /**
+     * 修改用户基本信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public int updateUserProfile(SuperSysUser user);
+
+    /**
+     * 修改用户头像
+     *
+     * @param userName 用户名
+     * @param avatar   头像地址
+     * @return 结果
+     */
+    public boolean updateUserAvatar(String userName, String avatar);
+
+    /**
+     * 重置用户密码
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public int resetPwd(SuperSysUser user);
+
+    /**
+     * 重置用户密码
+     *
+     * @param userName 用户名
+     * @param password 密码
+     * @return 结果
+     */
+    public int resetUserPwd(String userName, String password);
+
+
+
+}

+ 275 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/system/service/impl/SuperSysUserServiceImpl.java

@@ -0,0 +1,275 @@
+package com.zhongzheng.modules.system.service.impl;
+
+import cn.hutool.core.lang.Validator;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.common.annotation.DataScope;
+import com.zhongzheng.common.constant.UserConstants;
+import com.zhongzheng.common.core.domain.entity.SuperSysUser;
+import com.zhongzheng.common.core.domain.entity.SysRole;
+import com.zhongzheng.common.core.domain.entity.SysUser;
+import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.utils.SecurityUtils;
+import com.zhongzheng.modules.system.domain.SysPost;
+import com.zhongzheng.modules.system.domain.SysUserPost;
+import com.zhongzheng.modules.system.domain.SysUserRole;
+import com.zhongzheng.modules.system.mapper.*;
+import com.zhongzheng.modules.system.service.ISuperSysUserService;
+import com.zhongzheng.modules.system.service.ISysConfigService;
+import com.zhongzheng.modules.system.service.ISysUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 用户 业务层处理
+ *
+ * @author zhongzheng
+ */
+@Slf4j
+@Service
+public class SuperSysUserServiceImpl extends ServiceImpl<SuperSysUserMapper, SuperSysUser> implements ISuperSysUserService {
+
+    @Autowired
+    private SysRoleMapper roleMapper;
+
+    @Autowired
+    private SysPostMapper postMapper;
+
+
+
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    @Override
+    @DataScope(deptAlias = "d", userAlias = "u")
+    public List<SuperSysUser> selectUserList(SuperSysUser user) {
+        return baseMapper.selectUserList(user);
+    }
+
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    @Override
+    public SuperSysUser selectUserByUserName(String userName) {
+        return baseMapper.selectUserByUserName(userName);
+    }
+
+    /**
+     * 通过用户ID查询用户
+     *
+     * @param userId 用户ID
+     * @return 用户对象信息
+     */
+    @Override
+    public SuperSysUser selectUserById(Long userId) {
+        return baseMapper.selectUserById(userId);
+    }
+
+    /**
+     * 查询用户所属角色组
+     *
+     * @param userName 用户名
+     * @return 结果
+     */
+    @Override
+    public String selectUserRoleGroup(String userName) {
+        List<SysRole> list = roleMapper.selectRolesByUserName(userName);
+        StringBuffer idsStr = new StringBuffer();
+        for (SysRole role : list) {
+            idsStr.append(role.getRoleName()).append(",");
+        }
+        if (Validator.isNotEmpty(idsStr.toString())) {
+            return idsStr.substring(0, idsStr.length() - 1);
+        }
+        return idsStr.toString();
+    }
+
+    /**
+     * 查询用户所属岗位组
+     *
+     * @param userName 用户名
+     * @return 结果
+     */
+    @Override
+    public String selectUserPostGroup(String userName) {
+        List<SysPost> list = postMapper.selectPostsByUserName(userName);
+        StringBuffer idsStr = new StringBuffer();
+        for (SysPost post : list) {
+            idsStr.append(post.getPostName()).append(",");
+        }
+        if (Validator.isNotEmpty(idsStr.toString())) {
+            return idsStr.substring(0, idsStr.length() - 1);
+        }
+        return idsStr.toString();
+    }
+
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param userName 用户名称
+     * @return 结果
+     */
+    @Override
+    public String checkUserNameUnique(String userName) {
+        int count = count(new LambdaQueryWrapper<SuperSysUser>().eq(SuperSysUser::getUserName, userName).last("limit 1"));
+        if (count > 0) {
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param user 用户信息
+     * @return
+     */
+    @Override
+    public String checkPhoneUnique(SuperSysUser user) {
+        Long userId = Validator.isNull(user.getUserId()) ? -1L : user.getUserId();
+        SuperSysUser info = getOne(new LambdaQueryWrapper<SuperSysUser>()
+                .select(SuperSysUser::getUserId, SuperSysUser::getPhonenumber)
+                .eq(SuperSysUser::getPhonenumber, user.getPhonenumber()).last("limit 1"));
+        if (Validator.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+
+    /**
+     * 校验email是否唯一
+     *
+     * @param user 用户信息
+     * @return
+     */
+    @Override
+    public String checkEmailUnique(SuperSysUser user) {
+        Long userId = Validator.isNull(user.getUserId()) ? -1L : user.getUserId();
+        SuperSysUser info = getOne(new LambdaQueryWrapper<SuperSysUser>()
+                .select(SuperSysUser::getUserId, SuperSysUser::getEmail)
+                .eq(SuperSysUser::getEmail, user.getEmail()).last("limit 1"));
+        if (Validator.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+
+    /**
+     * 校验用户是否允许操作
+     *
+     * @param user 用户信息
+     */
+    @Override
+    public void checkUserAllowed(SuperSysUser user) {
+        if (Validator.isNotNull(user.getUserId()) && user.isAdmin()) {
+            throw new CustomException("不允许操作超级管理员用户");
+        }
+    }
+
+    /**
+     * 新增保存用户信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public int insertUser(SuperSysUser user) {
+        // 新增用户信息
+        int rows = baseMapper.insert(user);
+
+        return rows;
+    }
+
+    /**
+     * 修改保存用户信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public int updateUser(SuperSysUser user) {
+
+        return baseMapper.updateById(user);
+    }
+
+    /**
+     * 修改用户状态
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    public int updateUserStatus(SuperSysUser user) {
+        return baseMapper.updateById(user);
+    }
+
+    /**
+     * 修改用户基本信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    public int updateUserProfile(SuperSysUser user) {
+        return baseMapper.updateById(user);
+    }
+
+    /**
+     * 修改用户头像
+     *
+     * @param userName 用户名
+     * @param avatar   头像地址
+     * @return 结果
+     */
+    @Override
+    public boolean updateUserAvatar(String userName, String avatar) {
+        return baseMapper.update(null,
+                new LambdaUpdateWrapper<SuperSysUser>()
+                        .set(SuperSysUser::getAvatar,avatar)
+                        .eq(SuperSysUser::getUserName,userName)) > 0;
+    }
+
+    /**
+     * 重置用户密码
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    public int resetPwd(SuperSysUser user) {
+        return baseMapper.updateById(user);
+    }
+
+    /**
+     * 重置用户密码
+     *
+     * @param userName 用户名
+     * @param password 密码
+     * @return 结果
+     */
+    @Override
+    public int resetUserPwd(String userName, String password) {
+        return baseMapper.update(null,
+                new LambdaUpdateWrapper<SuperSysUser>()
+                        .set(SuperSysUser::getPassword,password)
+                        .eq(SuperSysUser::getUserName,userName));
+    }
+
+
+
+}

+ 129 - 0
zhongzheng-system/src/main/resources/mapper/modules/system/SuperSysUserMapper.xml

@@ -0,0 +1,129 @@
+<?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.zhongzheng.modules.system.mapper.SuperSysUserMapper">
+
+    <resultMap type="SuperSysUser" id="SuperSysUserResult">
+        <id property="userId" column="user_id"/>
+        <result property="deptId" column="dept_id"/>
+        <result property="userName" column="user_name"/>
+        <result property="nickName" column="nick_name"/>
+        <result property="email" column="email"/>
+        <result property="phonenumber" column="phonenumber"/>
+        <result property="sex" column="sex"/>
+        <result property="avatar" column="avatar"/>
+        <result property="password" column="password"/>
+        <result property="status" column="status"/>
+        <result property="delFlag" column="del_flag"/>
+        <result property="loginIp" column="login_ip"/>
+        <result property="loginDate" column="login_date"/>
+        <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"/>
+        <association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult"/>
+        <collection property="roles" javaType="java.util.List" resultMap="RoleResult"/>
+    </resultMap>
+
+    <resultMap id="deptResult" type="SysDept">
+        <id property="deptId" column="dept_id"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="deptName" column="dept_name"/>
+        <result property="orderNum" column="order_num"/>
+        <result property="leader" column="leader"/>
+        <result property="status" column="dept_status"/>
+    </resultMap>
+
+    <resultMap id="RoleResult" type="SysRole">
+        <id property="roleId" column="role_id"/>
+        <result property="roleName" column="role_name"/>
+        <result property="roleKey" column="role_key"/>
+        <result property="roleSort" column="role_sort"/>
+        <result property="dataScope" column="data_scope"/>
+        <result property="status" column="role_status"/>
+    </resultMap>
+
+    <sql id="selectUserVo">
+        select u.user_id,
+               u.dept_id,
+               u.user_name,
+               u.nick_name,
+               u.email,
+               u.avatar,
+               u.phonenumber,
+               u.password,
+               u.sex,
+               u.status,
+               u.del_flag,
+               u.login_ip,
+               u.login_date,
+               u.create_by,
+               u.create_time,
+               u.remark,
+               d.dept_id,
+               d.parent_id,
+               d.dept_name,
+               d.order_num,
+               d.leader,
+               d.status as dept_status,
+               r.role_id,
+               r.role_name,
+               r.role_key,
+               r.role_sort,
+               r.data_scope,
+               r.status as role_status
+        from super_sys_user u
+                 left join super_sys_dept d on u.dept_id = d.dept_id
+                 left join super_sys_user_role ur on u.user_id = ur.user_id
+                 left join super_sys_role r on r.role_id = ur.role_id
+    </sql>
+
+    <select id="selectUserList" parameterType="SuperSysUser" resultMap="SuperSysUserResult">
+        select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex,
+        u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from
+        sys_user u
+        left join sys_dept d on u.dept_id = d.dept_id
+        where u.del_flag = '0'
+        <if test="userName != null and userName != ''">
+            AND u.user_name like concat('%', #{userName}, '%')
+        </if>
+        <if test="status != null and status != ''">
+            AND u.status = #{status}
+        </if>
+        <if test="phonenumber != null and phonenumber != ''">
+            AND u.phonenumber like concat('%', #{phonenumber}, '%')
+        </if>
+        <if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
+            AND date_format(u.create_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
+        </if>
+        <if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
+            AND date_format(u.create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
+        </if>
+        <if test="deptId != null and deptId != 0">
+            AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId},
+            ancestors) ))
+        </if>
+        <if test="statusArray != null and statusArray.size()!=0 ">
+            AND u.status in
+            <foreach collection="statusArray" item="item" index="index" open="(" close=")" separator=",">
+                #{item}
+            </foreach>
+        </if>
+        <!-- 数据范围过滤 -->
+        ${params.dataScope}
+    </select>
+
+    <select id="selectUserByUserName" parameterType="String" resultMap="SuperSysUserResult">
+        <include refid="selectUserVo"/>
+        where u.user_name = #{userName}
+    </select>
+
+    <select id="selectUserById" parameterType="Long" resultMap="SuperSysUserResult">
+        <include refid="selectUserVo"/>
+        where u.user_id = #{userId}
+    </select>
+
+
+</mapper>

+ 1 - 1
zhongzheng-certificate-admin/pom.xml → zhongzheng-top-admin/pom.xml

@@ -9,7 +9,7 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>jar</packaging>
-    <artifactId>zhongzheng-certificate-admin</artifactId>
+    <artifactId>zhongzheng-top-admin</artifactId>
 
     <dependencies>
         <!-- spring-boot-devtools -->

+ 3 - 3
zhongzheng-certificate-admin/src/main/java/com/zhongzheng/CertificateAdminApplication.java → zhongzheng-top-admin/src/main/java/com/zhongzheng/TopAdminApplication.java

@@ -6,13 +6,13 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 
 
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
-public class CertificateAdminApplication {
+public class TopAdminApplication {
 
     public static void main(String[] args)
     {
         System.setProperty("spring.devtools.restart.enabled", "false");
-        SpringApplication.run(CertificateAdminApplication.class, args);
-        System.out.println("(♥◠‿◠)ノ゙  证书Admin启动成功   ლ(´ڡ`ლ)゙");
+        SpringApplication.run(TopAdminApplication.class, args);
+        System.out.println("(♥◠‿◠)ノ゙  超级Admin启动成功   ლ(´ڡ`ლ)゙");
     }
 
 }

+ 2 - 2
zhongzheng-certificate-admin/src/main/java/com/zhongzheng/CertificateAdminServletInitializer.java → zhongzheng-top-admin/src/main/java/com/zhongzheng/TopAdminServletInitializer.java

@@ -8,11 +8,11 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
  *
  * @author zhongzheng
  */
-public class CertificateAdminServletInitializer extends SpringBootServletInitializer
+public class TopAdminServletInitializer extends SpringBootServletInitializer
 {
     @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
     {
-        return application.sources(CertificateAdminApplication.class);
+        return application.sources(TopAdminApplication.class);
     }
 }

+ 136 - 0
zhongzheng-top-admin/src/main/java/com/zhongzheng/controller/common/CaptchaController.java

@@ -0,0 +1,136 @@
+package com.zhongzheng.controller.common;
+
+import cn.hutool.captcha.AbstractCaptcha;
+import cn.hutool.captcha.CircleCaptcha;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.captcha.ShearCaptcha;
+import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.captcha.generator.MathGenerator;
+import cn.hutool.captcha.generator.RandomGenerator;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
+import com.github.xiaoymin.knife4j.annotations.DynamicResponseParameters;
+import com.zhongzheng.common.constant.Constants;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.common.core.redis.RedisCache;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 验证码操作处理
+ *
+ * @author hjl
+ */
+@Api(tags ="系统操作管理")
+@RestController
+public class CaptchaController {
+
+	// 圆圈干扰验证码
+	@Resource(name = "CircleCaptcha")
+	private CircleCaptcha circleCaptcha;
+	// 线段干扰的验证码
+	@Resource(name = "LineCaptcha")
+	private LineCaptcha lineCaptcha;
+	// 扭曲干扰验证码
+	@Resource(name = "ShearCaptcha")
+	private ShearCaptcha shearCaptcha;
+
+	@Autowired
+	private RedisCache redisCache;
+
+	// 验证码类型
+	@Value("${captcha.captchaType}")
+	private String captchaType;
+	// 验证码类别
+	@Value("${captcha.captchaCategory}")
+	private String captchaCategory;
+	// 数字验证码位数
+	@Value("${captcha.captchaNumberLength}")
+	private int numberLength;
+	// 字符验证码长度
+	@Value("${captcha.captchaCharLength}")
+	private int charLength;
+
+	/**
+	 * 生成验证码
+	 */
+	@ApiOperation("获取验证码")
+	@DynamicResponseParameters(name = "CodeMapModel",properties = {
+			@DynamicParameter(name = "uuid",value = "验证码uuid"),
+			@DynamicParameter(name = "img",value = "验证码图片base64"),
+	})
+	@GetMapping("/captchaImage")
+	public AjaxResult getCode() {
+		// 保存验证码信息
+		String uuid = IdUtil.simpleUUID();
+		String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+		String code = null;
+		// 生成验证码
+		CodeGenerator codeGenerator;
+		AbstractCaptcha captcha;
+		switch (captchaType) {
+			case "math":
+				codeGenerator = new MathGenerator(numberLength);
+				break;
+			case "char":
+				codeGenerator = new RandomGenerator(charLength);
+				break;
+			default:
+				throw new IllegalArgumentException("验证码类型异常");
+		}
+		switch (captchaCategory) {
+			case "line":
+				captcha = lineCaptcha;
+				break;
+			case "circle":
+				captcha = circleCaptcha;
+				break;
+			case "shear":
+				captcha = shearCaptcha;
+				break;
+			default:
+				throw new IllegalArgumentException("验证码类别异常");
+		}
+		captcha.setGenerator(codeGenerator);
+		captcha.createCode();
+		if ("math".equals(captchaType)) {
+			code = getCodeResult(captcha.getCode());
+		} else if ("char".equals(captchaType)) {
+			code = captcha.getCode();
+		}
+		redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
+		Map<String,Object> map = new HashMap();
+		map.put("uuid", uuid);
+		map.put("img", captcha.getImageBase64());
+		return AjaxResult.success(map);
+	}
+
+	private String getCodeResult(String capStr) {
+		int a = Convert.toInt(StrUtil.sub(capStr, 0, numberLength).trim());
+		char operator = capStr.charAt(numberLength);
+		int b = Convert.toInt(StrUtil.sub(capStr, numberLength + 1, numberLength + 1 + numberLength).trim());
+		switch (operator) {
+			case '*':
+				return a * b + "";
+			case '+':
+				return a + b + "";
+			case '-':
+				return a - b + "";
+			default:
+				return "";
+		}
+	}
+
+}

+ 105 - 0
zhongzheng-top-admin/src/main/java/com/zhongzheng/controller/top/SuperSysLoginController.java

@@ -0,0 +1,105 @@
+package com.zhongzheng.controller.top;
+
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import com.zhongzheng.common.constant.Constants;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.common.core.domain.entity.SuperSysUser;
+import com.zhongzheng.common.core.domain.entity.SysMenu;
+import com.zhongzheng.common.core.domain.entity.SysUser;
+import com.zhongzheng.common.core.domain.model.LoginBody;
+import com.zhongzheng.common.core.domain.model.LoginUser;
+import com.zhongzheng.common.core.domain.model.SuperLoginUser;
+import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.framework.web.service.SuperSysLoginService;
+import com.zhongzheng.framework.web.service.SuperTokenService;
+import com.zhongzheng.framework.web.service.SysPermissionService;
+import com.zhongzheng.framework.web.service.TokenService;
+import com.zhongzheng.modules.system.service.ISysMenuService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * 登录验证
+ *
+ * @author zhongzheng
+ */
+@Api(tags ="登录用户操作管理")
+@ApiSupport(order = 2)
+@RestController
+public class SuperSysLoginController
+{
+    @Autowired
+    private SuperSysLoginService loginService;
+
+    @Autowired
+    private ISysMenuService menuService;
+
+    @Autowired
+    private SysPermissionService permissionService;
+
+    @Autowired
+    private SuperTokenService tokenService;
+
+    /**
+     * 登录方法
+     *
+     * @param loginBody 登录信息
+     * @return 结果
+     */
+    @ApiOperation("登录")
+    @PostMapping("/login")
+    public AjaxResult login(@RequestBody LoginBody loginBody)
+    {
+        System.out.println(123);
+        AjaxResult ajax = AjaxResult.success();
+        // 生成令牌
+        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
+                loginBody.getUuid());
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+    /**
+     * 获取用户信息
+     *
+     * @return 用户信息
+     */
+    @ApiOperation("登录用户信息")
+    @GetMapping("getInfo")
+    public AjaxResult getInfo()
+    {
+        SuperLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        SuperSysUser user = loginUser.getUser();
+        // 角色集合
+        Set<String> roles = new HashSet<String>();
+        roles.add("admin");
+        // 权限集合
+        Set<String> permissions = new HashSet<String>();
+        permissions.add("*:*:*");
+        Map<String,Object> map = new HashMap<>();
+        map.put("user", user);
+        map.put("roles", roles);
+        map.put("permissions", permissions);
+        return AjaxResult.success(map);
+    }
+
+    /**
+     * 获取路由信息
+     *
+     * @return 路由信息
+     */
+    @ApiOperation("路由菜单信息")
+    @GetMapping("getRouters")
+    public AjaxResult getRouters()
+    {
+        SuperLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        // 用户信息
+        SuperSysUser user = loginUser.getUser();
+        List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId());
+        return AjaxResult.success(menuService.buildMenus(menus));
+    }
+}

+ 0 - 0
zhongzheng-certificate-admin/src/main/java/com/zhongzheng/core/config/SwaggerConfig.java → zhongzheng-top-admin/src/main/java/com/zhongzheng/core/config/SwaggerConfig.java


+ 0 - 0
zhongzheng-certificate-admin/src/main/resources/META-INF/spring-devtools.properties → zhongzheng-top-admin/src/main/resources/META-INF/spring-devtools.properties


+ 0 - 0
zhongzheng-certificate-admin/src/main/resources/application-dev.yml → zhongzheng-top-admin/src/main/resources/application-dev.yml


+ 0 - 0
zhongzheng-certificate-admin/src/main/resources/application-prod.yml → zhongzheng-top-admin/src/main/resources/application-prod.yml


+ 1 - 1
zhongzheng-certificate-admin/src/main/resources/application.yml → zhongzheng-top-admin/src/main/resources/application.yml

@@ -1,7 +1,7 @@
 # 项目相关配置
 zhongzheng:
   # 名称
-  name: zhongzheng-certificate-admin
+  name: zhongzheng-top-admin
   # 版本
   version: 3.4.0
   # 版权年份

+ 0 - 0
zhongzheng-certificate-admin/src/main/resources/banner.txt → zhongzheng-top-admin/src/main/resources/banner.txt


+ 0 - 0
zhongzheng-certificate-admin/src/main/resources/i18n/messages.properties → zhongzheng-top-admin/src/main/resources/i18n/messages.properties


+ 0 - 0
zhongzheng-certificate-admin/src/main/resources/logback.xml → zhongzheng-top-admin/src/main/resources/logback.xml


+ 0 - 0
zhongzheng-certificate-admin/src/main/resources/mybatis/mybatis-config.xml → zhongzheng-top-admin/src/main/resources/mybatis/mybatis-config.xml