Explorar el Código

调整secrity登录

ezhizao hace 1 año
padre
commit
2f6f59a018

+ 1 - 1
src/main/java/cn/ezhizao/common/utils/SecurityUtils.java

@@ -35,7 +35,7 @@ public class SecurityUtils
     {
         try
         {
-            return getLoginUser().getTenantId();
+            return getLoginUser().getSupplierId();
         }
         catch (Exception e)
         {

+ 76 - 0
src/main/java/cn/ezhizao/framework/security/LoginBody.java

@@ -0,0 +1,76 @@
+package cn.ezhizao.framework.security;
+
+/**
+ * 用户登录对象
+ *
+ * @author ruoyi
+ */
+public class LoginBody {
+    /**
+     * 用户名
+     */
+    private String username;
+
+
+    /**
+     * 用户密码
+     */
+    private String password;
+
+    /**
+     * 租户 id
+     */
+    private String tenantId;
+
+
+    /**
+     * 验证码
+     */
+    private String code;
+
+    /**
+     * 唯一标识
+     */
+    private String uuid;
+
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(String tenantId) {
+        this.tenantId = tenantId;
+    }
+}

+ 18 - 82
src/main/java/cn/ezhizao/framework/security/LoginUser.java

@@ -1,7 +1,8 @@
 package cn.ezhizao.framework.security;
 
-import cn.ezhizao.project.system.domain.SysUser;
+import cn.ezhizao.project.business.domain.BizSupplierUser;
 import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.Getter;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.userdetails.UserDetails;
 
@@ -13,6 +14,7 @@ import java.util.Set;
  *
  * @author ruoyi
  */
+@Getter
 public class LoginUser implements UserDetails {
     private static final long serialVersionUID = 1L;
 
@@ -22,14 +24,11 @@ public class LoginUser implements UserDetails {
     private Long userId;
 
     /**
-     * 租户 Id
+     * 供应商 Id
      */
-    private Long tenantId = 0L;
+    private Long supplierId = 0L;
 
-    /**
-     * 部门ID
-     */
-    private Long deptId;
+    private String supplierName;
 
     /**
      * 用户唯一标识
@@ -74,35 +73,7 @@ public class LoginUser implements UserDetails {
     /**
      * 用户信息
      */
-    private SysUser user;
-
-    public Long getTenantId() {
-        return tenantId;
-    }
-
-    public void setTenantId(Long tenantId) {
-        this.tenantId = tenantId;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public Long getDeptId() {
-        return deptId;
-    }
-
-    public void setDeptId(Long deptId) {
-        this.deptId = deptId;
-    }
-
-    public String getToken() {
-        return token;
-    }
+    private BizSupplierUser user;
 
     public void setToken(String token) {
         this.token = token;
@@ -111,22 +82,22 @@ public class LoginUser implements UserDetails {
     public LoginUser() {
     }
 
-    public LoginUser(SysUser user, Set<String> permissions) {
+    public LoginUser(BizSupplierUser user, Set<String> permissions) {
         this.user = user;
         this.permissions = permissions;
     }
 
-    public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions) {
+    public LoginUser(Long userId, BizSupplierUser user, Set<String> permissions) {
+        this.supplierId = user.getSupplierId();
         this.userId = userId;
-        this.deptId = deptId;
         this.user = user;
         this.permissions = permissions;
     }
 
-    public LoginUser(Long tenantId, Long userId, Long deptId, SysUser user, Set<String> permissions) {
-        this.tenantId = tenantId;
+    public LoginUser(Long supplierId, String supplierName, Long userId, BizSupplierUser user, Set<String> permissions) {
+        this.supplierId = supplierId;
+        this.supplierName = supplierName;
         this.userId = userId;
-        this.deptId = deptId;
         this.user = user;
         this.permissions = permissions;
     }
@@ -139,7 +110,7 @@ public class LoginUser implements UserDetails {
 
     @Override
     public String getUsername() {
-        return user.getUserName();
+        return user.getUsername();
     }
 
     /**
@@ -153,8 +124,7 @@ public class LoginUser implements UserDetails {
 
     /**
      * 指定用户是否解锁,锁定的用户无法进行身份验证
-     *
-     * @return
+     * @return 布尔值
      */
     @JSONField(serialize = false)
     @Override
@@ -164,8 +134,7 @@ public class LoginUser implements UserDetails {
 
     /**
      * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
-     *
-     * @return
+     * @return 布尔值
      */
     @JSONField(serialize = false)
     @Override
@@ -175,8 +144,7 @@ public class LoginUser implements UserDetails {
 
     /**
      * 是否可用 ,禁用的用户不能身份验证
-     *
-     * @return
+     * @return 布尔值
      */
     @JSONField(serialize = false)
     @Override
@@ -184,67 +152,35 @@ public class LoginUser implements UserDetails {
         return true;
     }
 
-    public Long getLoginTime() {
-        return loginTime;
-    }
-
     public void setLoginTime(Long loginTime) {
         this.loginTime = loginTime;
     }
 
-    public String getIpaddr() {
-        return ipaddr;
-    }
-
     public void setIpaddr(String ipaddr) {
         this.ipaddr = ipaddr;
     }
 
-    public String getLoginLocation() {
-        return loginLocation;
-    }
-
     public void setLoginLocation(String loginLocation) {
         this.loginLocation = loginLocation;
     }
 
-    public String getBrowser() {
-        return browser;
-    }
-
     public void setBrowser(String browser) {
         this.browser = browser;
     }
 
-    public String getOs() {
-        return os;
-    }
-
     public void setOs(String os) {
         this.os = os;
     }
 
-    public Long getExpireTime() {
-        return expireTime;
-    }
-
     public void setExpireTime(Long expireTime) {
         this.expireTime = expireTime;
     }
 
-    public Set<String> getPermissions() {
-        return permissions;
-    }
-
     public void setPermissions(Set<String> permissions) {
         this.permissions = permissions;
     }
 
-    public SysUser getUser() {
-        return user;
-    }
-
-    public void setUser(SysUser user) {
+    public void setUser(BizSupplierUser user) {
         this.user = user;
     }
 

+ 50 - 0
src/main/java/cn/ezhizao/framework/security/RegisterBody.java

@@ -0,0 +1,50 @@
+package cn.ezhizao.framework.security;
+
+/**
+ * 用户注册对象
+ *
+ * @author ruoyi
+ */
+public class RegisterBody extends LoginBody
+{
+    /**
+        统一社会 信用编码
+    */
+    private String creditCode;
+
+    /**
+     *  注册角色 1 发单方 2 供应商
+     */
+    public String role;
+
+    /**
+     *  注册手机号
+     */
+    public String phoneNumber;
+
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+
+    public String getCreditCode() {
+        return creditCode;
+    }
+
+    public void setCreditCode(String creditCode) {
+        this.creditCode = creditCode;
+    }
+
+    public String getRole() {
+        return role;
+    }
+
+    public void setRole(String role) {
+        this.role = role;
+    }
+
+}

+ 7 - 3
src/main/java/cn/ezhizao/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -23,14 +23,18 @@ import java.io.IOException;
  * @author ruoyi
  */
 @Component
-public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
+public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
+{
     @Resource
     private TokenService tokenService;
 
     @Override
-    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+            throws ServletException, IOException
+    {
         LoginUser loginUser = tokenService.getLoginUser(request);
-        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
+        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
+        {
             tokenService.verifyToken(loginUser);
             UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
             authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

+ 48 - 30
src/main/java/cn/ezhizao/framework/security/service/PermissionService.java

@@ -16,15 +16,12 @@ import java.util.Set;
  * @author ruoyi
  */
 @Service("ss")
-public class PermissionService {
-    /**
-     * 所有权限标识
-     */
+public class PermissionService
+{
+    /** 所有权限标识 */
     private static final String ALL_PERMISSION = "*:*:*";
 
-    /**
-     * 管理员角色权限标识
-     */
+    /** 管理员角色权限标识 */
     private static final String SUPER_ADMIN = "admin";
 
     private static final String ROLE_DELIMETER = ",";
@@ -37,12 +34,15 @@ public class PermissionService {
      * @param permission 权限字符串
      * @return 用户是否具备某权限
      */
-    public boolean hasPermi(String permission) {
-        if (StringUtils.isEmpty(permission)) {
+    public boolean hasPermi(String permission)
+    {
+        if (StringUtils.isEmpty(permission))
+        {
             return false;
         }
         LoginUser loginUser = SecurityUtils.getLoginUser();
-        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) {
+        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
+        {
             return false;
         }
         PermissionContextHolder.setContext(permission);
@@ -55,8 +55,9 @@ public class PermissionService {
      * @param permission 权限字符串
      * @return 用户是否不具备某权限
      */
-    public boolean lacksPermi(String permission) {
-        return !hasPermi(permission);
+    public boolean lacksPermi(String permission)
+    {
+        return hasPermi(permission) != true;
     }
 
     /**
@@ -65,18 +66,23 @@ public class PermissionService {
      * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
      * @return 用户是否具有以下任意一个权限
      */
-    public boolean hasAnyPermi(String permissions) {
-        if (StringUtils.isEmpty(permissions)) {
+    public boolean hasAnyPermi(String permissions)
+    {
+        if (StringUtils.isEmpty(permissions))
+        {
             return false;
         }
         LoginUser loginUser = SecurityUtils.getLoginUser();
-        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) {
+        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)) {
+        for (String permission : permissions.split(PERMISSION_DELIMETER))
+        {
+            if (permission != null && hasPermissions(authorities, permission))
+            {
                 return true;
             }
         }
@@ -89,17 +95,22 @@ public class PermissionService {
      * @param role 角色字符串
      * @return 用户是否具备某角色
      */
-    public boolean hasRole(String role) {
-        if (StringUtils.isEmpty(role)) {
+    public boolean hasRole(String role)
+    {
+        if (StringUtils.isEmpty(role))
+        {
             return false;
         }
         LoginUser loginUser = SecurityUtils.getLoginUser();
-        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) {
+        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
+        {
             return false;
         }
-        for (SysRole sysRole : loginUser.getUser().getRoles()) {
+        for (SysRole sysRole : loginUser.getUser().getRoles())
+        {
             String roleKey = sysRole.getRoleKey();
-            if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) {
+            if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
+            {
                 return true;
             }
         }
@@ -112,7 +123,8 @@ public class PermissionService {
      * @param role 角色名称
      * @return 用户是否不具备某角色
      */
-    public boolean lacksRole(String role) {
+    public boolean lacksRole(String role)
+    {
         return hasRole(role) != true;
     }
 
@@ -122,16 +134,21 @@ public class PermissionService {
      * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
      * @return 用户是否具有以下任意一个角色
      */
-    public boolean hasAnyRoles(String roles) {
-        if (StringUtils.isEmpty(roles)) {
+    public boolean hasAnyRoles(String roles)
+    {
+        if (StringUtils.isEmpty(roles))
+        {
             return false;
         }
         LoginUser loginUser = SecurityUtils.getLoginUser();
-        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) {
+        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
+        {
             return false;
         }
-        for (String role : roles.split(ROLE_DELIMETER)) {
-            if (hasRole(role)) {
+        for (String role : roles.split(ROLE_DELIMETER))
+        {
+            if (hasRole(role))
+            {
                 return true;
             }
         }
@@ -142,10 +159,11 @@ public class PermissionService {
      * 判断是否包含权限
      *
      * @param permissions 权限列表
-     * @param permission  权限字符串
+     * @param permission 权限字符串
      * @return 用户是否具备某权限
      */
-    private boolean hasPermissions(Set<String> permissions, String permission) {
+    private boolean hasPermissions(Set<String> permissions, String permission)
+    {
         return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
     }
 }

+ 102 - 0
src/main/java/cn/ezhizao/framework/security/service/SysLoginService.java

@@ -0,0 +1,102 @@
+package cn.ezhizao.framework.security.service;
+
+import cn.ezhizao.common.constant.CacheConstants;
+import cn.ezhizao.common.constant.Constants;
+import cn.ezhizao.common.exception.ServiceException;
+import cn.ezhizao.common.exception.user.CaptchaException;
+import cn.ezhizao.common.exception.user.CaptchaExpireException;
+import cn.ezhizao.common.exception.user.UserPasswordNotMatchException;
+import cn.ezhizao.common.utils.DateUtils;
+import cn.ezhizao.common.utils.MessageUtils;
+import cn.ezhizao.common.utils.ServletUtils;
+import cn.ezhizao.common.utils.StringUtils;
+import cn.ezhizao.common.utils.ip.IpUtils;
+import cn.ezhizao.common.utils.uuid.SnowflakeIdWorker;
+import cn.ezhizao.framework.manager.AsyncManager;
+import cn.ezhizao.framework.manager.factory.AsyncFactory;
+import cn.ezhizao.framework.redis.RedisCache;
+import cn.ezhizao.framework.security.LoginUser;
+import cn.ezhizao.framework.security.context.AuthenticationContextHolder;
+import cn.ezhizao.project.system.domain.SysUser;
+import cn.ezhizao.project.system.service.ISysDeptService;
+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 java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 登录校验方法
+ *
+ * @author ruoyi
+ */
+@Component
+public class SysLoginService {
+    @Resource
+    private TokenService tokenService;
+
+    @Resource
+    private AuthenticationManager authenticationManager;
+
+    @Resource
+    private RedisCache redisCache;
+
+    /**
+     * 登录验证
+     *
+     * @param username 用户名
+     * @param password 密码
+     * @return 结果
+     */
+    public Map<String, Object> login(String username, String password) {
+        // 用户验证
+        Authentication authentication;
+        try {
+            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
+            AuthenticationContextHolder.setContext(authenticationToken);
+            // 该方法会去调用 UserDetailsServiceImpl.loadUserByUsername
+            authentication = authenticationManager.authenticate(authenticationToken);
+        } 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 ServiceException(e.getMessage());
+            }
+        } finally {
+            AuthenticationContextHolder.clearContext();
+        }
+        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        Map<String, Object> result = new HashMap<>(3);
+        // 生成token
+        result.put(Constants.TOKEN, tokenService.createToken(loginUser));
+        return result;
+    }
+
+    /**
+     * 校验验证码
+     *
+     * @param username 用户名
+     * @param code     验证码
+     * @param uuid     唯一标识
+     */
+    public void validateCaptcha(String username, String code, String uuid) {
+        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(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();
+        }
+    }
+}

+ 10 - 21
src/main/java/cn/ezhizao/framework/security/service/SysPasswordService.java

@@ -24,8 +24,7 @@ import java.util.concurrent.TimeUnit;
  * @author ruoyi
  */
 @Component
-public class SysPasswordService
-{
+public class SysPasswordService {
     @Resource
     private RedisCache redisCache;
 
@@ -41,54 +40,44 @@ public class SysPasswordService
      * @param username 用户名
      * @return 缓存键key
      */
-    private String getCacheKey(String username)
-    {
+    private String getCacheKey(String username) {
         return CacheConstants.PWD_ERR_CNT_KEY + username;
     }
 
-    public void validate(SysUser user)
-    {
+    public void validate(SysUser user) {
         Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
         String username = usernamePasswordAuthenticationToken.getName();
         String password = usernamePasswordAuthenticationToken.getCredentials().toString();
 
         Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
 
-        if (retryCount == null)
-        {
+        if (retryCount == null) {
             retryCount = 0;
         }
 
-        if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
-        {
+        if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) {
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
                     MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
             throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
         }
 
-        if (!matches(user, password))
-        {
+        if (!matches(user, password)) {
             retryCount = retryCount + 1;
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
                     MessageUtils.message("user.password.retry.limit.count", retryCount)));
             redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
             throw new UserPasswordNotMatchException();
-        }
-        else
-        {
+        } else {
             clearLoginRecordCache(username);
         }
     }
 
-    public boolean matches(SysUser user, String rawPassword)
-    {
+    public boolean matches(SysUser user, String rawPassword) {
         return SecurityUtils.matchesPassword(rawPassword, user.getPassword());
     }
 
-    public void clearLoginRecordCache(String loginName)
-    {
-        if (redisCache.hasKey(getCacheKey(loginName)))
-        {
+    public void clearLoginRecordCache(String loginName) {
+        if (redisCache.hasKey(getCacheKey(loginName))) {
             redisCache.deleteObject(getCacheKey(loginName));
         }
     }

+ 30 - 0
src/main/java/cn/ezhizao/framework/security/service/SysPermissionService.java

@@ -0,0 +1,30 @@
+package cn.ezhizao.framework.security.service;
+
+import cn.ezhizao.project.business.domain.BizSupplierUser;
+import org.springframework.stereotype.Component;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * 用户权限处理
+ *
+ * @author ruoyi
+ */
+@Component
+public class SysPermissionService {
+    /**
+     * 获取菜单数据权限
+     *
+     * @param user 用户信息
+     * @return 菜单权限信息
+     */
+    public Set<String> getMenuPermission(BizSupplierUser user) {
+        Set<String> perms = new HashSet<String>();
+        // 管理员拥有所有权限
+        if ("1".equals(user.getIsAdmin()))
+            perms.add("*:*:*");
+
+        return perms;
+    }
+}

+ 144 - 0
src/main/java/cn/ezhizao/framework/security/service/SysRegisterService.java

@@ -0,0 +1,144 @@
+package cn.ezhizao.framework.security.service;
+
+import cn.ezhizao.common.constant.CacheConstants;
+import cn.ezhizao.common.constant.Constants;
+import cn.ezhizao.common.constant.UserConstants;
+import cn.ezhizao.common.exception.user.CaptchaException;
+import cn.ezhizao.common.exception.user.CaptchaExpireException;
+import cn.ezhizao.common.utils.MessageUtils;
+import cn.ezhizao.common.utils.SecurityUtils;
+import cn.ezhizao.common.utils.StringUtils;
+import cn.ezhizao.framework.manager.AsyncManager;
+import cn.ezhizao.framework.manager.factory.AsyncFactory;
+import cn.ezhizao.framework.redis.RedisCache;
+import cn.ezhizao.framework.security.RegisterBody;
+import cn.ezhizao.project.system.domain.SysUser;
+import cn.ezhizao.project.system.domain.SysUserRole;
+import cn.ezhizao.project.system.mapper.SysUserRoleMapper;
+import cn.ezhizao.project.system.service.ISysConfigService;
+import cn.ezhizao.project.system.service.ISysUserService;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 注册校验方法
+ *
+ * @author ruoyi
+ */
+@Component
+public class SysRegisterService
+{
+    @Resource
+    private ISysUserService userService;
+
+    @Resource
+    private ISysConfigService configService;
+    @Resource
+    private RedisCache redisCache;
+
+    @Resource
+    SysUserRoleMapper userRoleMapper;
+
+
+    /**
+     * 注册
+     */
+    public String register(RegisterBody registerBody)
+    {
+        String  msg = "",
+                username = registerBody.getUsername(),
+                password = registerBody.getPassword(),
+                deptCode = registerBody.getCreditCode(),
+                phoneNumber = registerBody.getPhoneNumber(),
+                code = registerBody.getCode();
+        Long roleId = Long.parseLong(registerBody.getRole());
+        // 验证码开关
+        boolean captchaEnabled = configService.selectCaptchaEnabled();
+        if (captchaEnabled) {
+            validateCaptcha(phoneNumber, code);
+        }
+        SysUser sysUser = new SysUser();
+        sysUser.setUserName(username);
+        sysUser.setPhoneNumber(phoneNumber);
+        sysUser.setUserType("01");
+
+            if (StringUtils.isEmpty(username)) {
+                msg = "用户名不能为空";
+            } else if (StringUtils.isEmpty(password)) {
+                msg = "用户密码不能为空";
+            } else if (username.length() < UserConstants.USERNAME_MIN_LENGTH
+                    || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
+                msg = "账户长度必须在2到20个字符之间";
+            } else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
+                    || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
+                msg = "密码长度必须在5到20个字符之间";
+            } else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser))) {
+                msg = "注册账号已存在";
+            }else if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(sysUser))) {
+                msg = "注册手机号已存在";
+            } else {
+                sysUser.setNickName(username);
+                sysUser.setPassword(SecurityUtils.encryptPassword(password));
+
+                SysUserRole sysUserRoleAdmin = new SysUserRole();
+                sysUserRoleAdmin.setUserId(sysUser.getUserId());
+                sysUserRoleAdmin.setRoleId(roleId);
+                List<SysUserRole> sysUserRoles = new ArrayList<>();
+                sysUserRoles.add(sysUserRoleAdmin);
+                userRoleMapper.batchUserRole(sysUserRoles);
+
+                boolean regFlag = userService.registerUser(sysUser);
+
+                if (!regFlag) {
+                    msg = "注册失败,请联系系统管理人员";
+                } else {
+                    redisCache.deleteObject(phoneNumber);
+                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success")));
+                }
+            }
+        return msg;
+    }
+
+    /**
+     * 校验验证码
+     *
+     * @param username 用户名
+     * @param code 验证码
+     * @param uuid 唯一标识
+     * @return 结果
+     */
+    public void validateCaptcha(String username, String code, String uuid)
+    {
+        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
+        String captcha = redisCache.getCacheObject(verifyKey);
+        redisCache.deleteObject(verifyKey);
+        if (captcha == null)
+        {
+            throw new CaptchaExpireException();
+        }
+        if (!code.equalsIgnoreCase(captcha))
+        {
+            throw new CaptchaException();
+        }
+    }
+
+    /**
+     * 校验短信验证码
+     * @param key
+     */
+    public void validateCaptcha(String key,String value)
+    {
+        String verifyCode = redisCache.getCacheObject(key);
+        if (verifyCode == null)
+        {
+            throw new CaptchaExpireException();
+        }
+        if (!value.equalsIgnoreCase(verifyCode))
+        {
+            throw new CaptchaException();
+        }
+    }
+}

+ 3 - 10
src/main/java/cn/ezhizao/framework/security/service/TokenService.java

@@ -30,21 +30,15 @@ import java.util.concurrent.TimeUnit;
 @Component
 public class TokenService
 {
-    /**
-     * 令牌自定义标识
-     */
+    // 令牌自定义标识
     @Value("${token.header}")
     private String header;
 
-    /**
-     * 令牌秘钥
-     */
+    // 令牌秘钥
     @Value("${token.secret}")
     private String secret;
 
-    /**
-     * 令牌有效期(默认30分钟)
-     */
+    // 令牌有效期(默认30分钟)
     @Value("${token.expireTime}")
     private int expireTime;
 
@@ -78,7 +72,6 @@ public class TokenService
             }
             catch (Exception e)
             {
-                return null;
             }
         }
         return null;

+ 34 - 5
src/main/java/cn/ezhizao/framework/security/service/UserDetailsServiceImpl.java

@@ -1,20 +1,49 @@
 package cn.ezhizao.framework.security.service;
 
+import cn.ezhizao.framework.security.LoginUser;
+import cn.ezhizao.project.business.domain.BizSupplierUser;
+import cn.ezhizao.project.business.service.IBizSupplierUserService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * 用户验证处理
  *
  * @author ruoyi
  */
 @Service
-public class UserDetailsServiceImpl implements UserDetailsService
-{
+public class UserDetailsServiceImpl implements UserDetailsService {
+    private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
+
+    @Resource
+    private IBizSupplierUserService userService;
+
+    @Resource
+    private SysPasswordService passwordService;
+
+    @Resource
+    private SysPermissionService permissionService;
+
+    @Resource
+    HttpServletRequest request;
+
     @Override
-    public UserDetails loadUserByUsername(String userName)
-    {
-        return null;
+    public UserDetails loadUserByUsername(String userName) {
+        final String supplierId = request.getHeader("supplierId");
+        BizSupplierUser user = userService.selectUserByUserNameAndSupplierId(userName, supplierId);
+
+        return createLoginUser(user);
+
+    }
+
+    public UserDetails createLoginUser(BizSupplierUser user) {
+        return new LoginUser(user.getId(), user, permissionService.getMenuPermission(user));
     }
 }

+ 47 - 0
src/main/java/cn/ezhizao/project/business/domain/BizSupplierUser.java

@@ -0,0 +1,47 @@
+package cn.ezhizao.project.business.domain;
+
+import cn.ezhizao.framework.web.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 外协商的用户表
+ *
+ * @author ezhizao
+ * date    2024-04-29
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "biz_supplier_user")
+public class BizSupplierUser extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "租户(厂别)id")
+    private Long tenantId;
+
+    @ApiModelProperty(value = "外协商id")
+    private Long supplierId;
+
+    @ApiModelProperty(value = "公司编码")
+    private String supplierCode;
+
+    @ApiModelProperty(value = "公司名")
+    private String supplierName;
+
+    @ApiModelProperty(value = "用户名")
+    private String username;
+
+    @ApiModelProperty(value = "密码")
+    private String password;
+
+    @ApiModelProperty(value = "姓名")
+    private String name;
+
+    @ApiModelProperty(value = "是否管理员(0:否,1:是)")
+    private String isAdmin;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+}

+ 16 - 0
src/main/java/cn/ezhizao/project/business/mapper/BizSupplierUserMapper.java

@@ -0,0 +1,16 @@
+package cn.ezhizao.project.business.mapper;
+
+import cn.ezhizao.project.business.domain.BizSupplierUser;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 外协单主
+带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子Mapper接口
+ *
+ * @author ezhizao
+ * @date 2024-04-26
+ */
+public interface BizSupplierUserMapper extends BaseMapper<BizSupplierUser>
+{
+
+}

+ 24 - 0
src/main/java/cn/ezhizao/project/business/service/IBizSupplierUserService.java

@@ -0,0 +1,24 @@
+package cn.ezhizao.project.business.service;
+
+import cn.ezhizao.project.business.domain.BizSupplierUser;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * 用户 业务层
+ *
+ * @author ruoyi
+ */
+public interface IBizSupplierUserService extends IService<BizSupplierUser>
+{
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @param supplierId 租户id
+     * @return 用户对象信息
+     */
+    BizSupplierUser selectUserByUserNameAndSupplierId(String userName, String supplierId);
+
+}

+ 33 - 0
src/main/java/cn/ezhizao/project/business/service/impl/BizSupplierUserServiceImpl.java

@@ -0,0 +1,33 @@
+package cn.ezhizao.project.business.service.impl;
+
+import cn.ezhizao.project.business.domain.BizSupplierUser;
+import cn.ezhizao.project.business.mapper.BizSupplierUserMapper;
+import cn.ezhizao.project.business.service.IBizSupplierUserService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * 用户 业务层处理
+ *
+ * @author ruoyi
+ */
+@Service
+public class BizSupplierUserServiceImpl extends ServiceImpl<BizSupplierUserMapper, BizSupplierUser> implements IBizSupplierUserService {
+    private static final Logger log = LoggerFactory.getLogger(BizSupplierUserServiceImpl.class);
+
+    @Resource
+    private BizSupplierUserMapper userMapper;
+
+    @Override
+    public BizSupplierUser selectUserByUserNameAndSupplierId(String username, String supplierId) {
+        QueryWrapper<BizSupplierUser> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("username", username).eq("supplier_id", supplierId);
+
+        return userMapper.selectOne(queryWrapper);
+    }
+}

+ 1 - 1
src/main/resources/application-dev.yml

@@ -7,7 +7,7 @@ spring:
         # 端口,默认为6379
         port: 7379
         # 数据库索引
-        database: 0
+        database: 9
         # 密码
         password: ezhizao.cn123456
         # 连接超时时间