tjf 8 сар өмнө
parent
commit
4ed36d478d

+ 27 - 17
ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java

@@ -19,26 +19,22 @@ import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.MessageUtils;
 import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.redis.utils.RedisUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
 import org.dromara.common.social.config.properties.SocialProperties;
 import org.dromara.common.social.utils.SocialUtils;
 import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.system.domain.app.AppletLoginForm;
 import org.dromara.system.domain.SysClient;
+import org.dromara.system.domain.app.AppletLoginForm;
 import org.dromara.system.domain.bo.SysTenantBo;
 import org.dromara.system.domain.school.bo.SysSchoolNameBo;
 import org.dromara.system.domain.school.vo.SysSchoolNameVo;
-import org.dromara.system.domain.vo.FormalParentsStudentVo;
 import org.dromara.system.domain.vo.SysRoleVo;
 import org.dromara.system.domain.vo.SysTenantVo;
 import org.dromara.system.domain.vo.SysUserVo;
-import org.dromara.system.mapper.FormalParentsStudentMapper;
 import org.dromara.system.mapper.SysUserMapper;
-import org.dromara.system.service.ISysClientService;
-import org.dromara.system.service.ISysConfigService;
-import org.dromara.system.service.ISysSocialService;
-import org.dromara.system.service.ISysTenantService;
+import org.dromara.system.service.*;
 import org.dromara.system.service.school.ISysSchoolNameService;
 import org.dromara.web.domain.vo.LoginTenantVo;
 import org.dromara.web.domain.vo.LoginVo;
@@ -53,7 +49,6 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -78,8 +73,6 @@ public class AuthController {
     private final ISysClientService clientService;
     private final ISysSchoolNameService sysSchoolNameService;
     private final SysUserMapper sysUserMapper;
-    private final FormalParentsStudentMapper formalParentsStudentMapper;
-
 
     /**
      * 登录方法
@@ -98,6 +91,14 @@ public class AuthController {
             log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
             return R.fail(MessageUtils.message("auth.grant.type.error"));
         }
+        //去redis中查询当前账号登录租户id = loginBody.get
+        Object tenantId = RedisUtils.getCacheObject(loginBody.getUsername() + ":login");
+        if (ObjectUtil.isEmpty(tenantId)) {
+            //如果是空,则去查询
+            SysUserVo sysUserVo = sysUserMapper.selectUserByUserName(loginBody.getUsername());
+            tenantId = sysUserVo.getTenantId();
+        }
+        loginBody.setTenantId(tenantId.toString());
         // 校验租户
         loginService.checkTenant(loginBody.getTenantId());
         // 登录
@@ -107,27 +108,36 @@ public class AuthController {
     /**
      * 微信登录方法
      *
-     * @param  form 登录信息
+     * @param form 登录信息
      * @return 结果
      */
     @SaIgnore
     @PostMapping("/weChatLogin")
-    public R<LoginVo> weChatLogin(@Validated @RequestBody AppletLoginForm form){
+    public R<LoginVo> weChatLogin(@Validated @RequestBody AppletLoginForm form) {
         LoginBody loginBody = new LoginBody();
         String clientId = "428a8310cd442757ae699df5d894f051";
         String grantType = "password";
         loginBody.setClientId(clientId);
         loginBody.setGrantType(grantType);
-        loginBody.setTenantId(form.getTenantId());
+
         SysClient client = clientService.queryByClientId(clientId);
         // 查询不到 client 或 client 内不包含 grantType
         if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
             log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
             return R.fail(MessageUtils.message("auth.grant.type.error"));
         }
+        LoginVo loginVo = IAuthStrategy.weChatLogin(form, loginBody, client);
+        //去redis中查询当前账号登录租户id = loginBody.get
+        Object tenantId = RedisUtils.getCacheObject(loginBody.getUsername() + ":login");
+        if (ObjectUtil.isEmpty(tenantId)) {
+            //如果是空,则去查询
+            SysUserVo sysUserVo = sysUserMapper.selectUserByUserName(loginBody.getUsername());
+            tenantId = sysUserVo.getTenantId();
+        }
+        loginBody.setTenantId(tenantId.toString());
         // 校验租户
         loginService.checkTenant(loginBody.getTenantId());
-        return R.ok(IAuthStrategy.weChatLogin(form,loginBody,client));
+        return R.ok(loginVo);
     }
 
 
@@ -244,12 +254,12 @@ public class AuthController {
         for (SysUserVo sysUserVo : userList) {
             boolean bl = false;
             for (SysRoleVo role : sysUserVo.getRoles()) {
-                if("parents".equals(role.getRoleKey())){
-                    bl = true ;
+                if ("parents".equals(role.getRoleKey())) {
+                    bl = true;
                     break;
                 }
             }
-            if(bl){
+            if (bl) {
                 tList.add(sysUserVo.getTenantId());
             }
 

+ 0 - 3
ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/annotation/RepeatSubmit.java

@@ -1,7 +1,6 @@
 package org.dromara.common.idempotent.annotation;
 
 import java.lang.annotation.*;
-import java.util.concurrent.TimeUnit;
 
 /**
  * 自定义注解防止表单重复提交
@@ -19,8 +18,6 @@ public @interface RepeatSubmit {
      */
     int interval() default 5000;
 
-    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
-
     /**
      * 提示消息 支持国际化 格式为 {code}
      */

+ 2 - 6
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/common/AppletController.java

@@ -4,7 +4,6 @@ package org.dromara.system.controller.common;
 import cn.dev33.satoken.annotation.SaIgnore;
 import cn.dev33.satoken.secure.BCrypt;
 import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
 import org.apache.commons.lang3.ObjectUtils;
 import org.dromara.common.core.domain.AjaxResult;
 import org.dromara.common.core.domain.R;
@@ -12,16 +11,13 @@ import org.dromara.common.idempotent.annotation.RepeatSubmit;
 import org.dromara.common.redis.utils.RedisUtils;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.system.domain.FormalTeacherClass;
-import org.dromara.system.domain.SysUser;
 import org.dromara.system.service.ISysUserService;
 import org.dromara.system.service.Task;
 import org.dromara.system.service.common.IAppletService;
 import org.dromara.system.utils.SendSmsUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-
 import java.time.Duration;
-import java.util.concurrent.TimeUnit;
 
 /**小程序公共接口
  * @Author: tjf
@@ -108,11 +104,11 @@ public class AppletController extends BaseController {
      *忘记密码发送验证短信
      */
     @SaIgnore
-    @RepeatSubmit(interval = 1,timeUnit = TimeUnit.MINUTES)
+    @RepeatSubmit(interval = 60000)
     @GetMapping("/appForgetPW/{phone}")
     public AjaxResult appForgetPW(@PathVariable String phone)
     {
-        String code = SendSmsUtils.getCode(4);
+        String code = SendSmsUtils.getCode(6);
         SendSmsUtils.sendSms(phone,"SMS_219525380","{\"code\":\"" + code + "\"}");
         String key = "SMS_CODE:"+phone;
         RedisUtils.setCacheObject(key,code, Duration.ofMinutes(5));

+ 45 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/common/RegisterCommonController.java

@@ -0,0 +1,45 @@
+package org.dromara.system.controller.common;
+
+import cn.dev33.satoken.secure.BCrypt;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.bo.SysUserBo;
+import org.dromara.system.service.ISysUserService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import static org.dromara.system.constent.Constants.ONE;
+
+/**
+ * @Author: tjf
+ * @Date: 2024/10/23 9:43
+ * @Describe:
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/register")
+public class RegisterCommonController extends BaseController {
+    private final ISysUserService userService;
+    /**
+     * 新增用户
+     */
+    @PostMapping("/common")
+    public R<Void> add(@Validated @RequestBody SysUserBo user) {
+        if (!userService.checkUserNameUnique(user)) {
+            return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
+        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
+            return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
+        }
+        else if (ONE.equals(userService.checkStrongPwd(user))) {
+            return R.fail("密码必须包含数字、大小写字母、特殊符号且大于8位");
+        }
+        user.setPassword(BCrypt.hashpw(user.getPassword()));
+        return toAjax(userService.insertUserCommon(user));
+    }
+}

+ 13 - 3
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java

@@ -3,7 +3,9 @@ package org.dromara.system.controller.system;
 import cn.dev33.satoken.secure.BCrypt;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.io.FileUtil;
+import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.model.LoginUser;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.utils.file.MimeTypeUtils;
 import org.dromara.common.log.annotation.Log;
@@ -18,7 +20,6 @@ import org.dromara.system.domain.vo.SysOssVo;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysOssService;
 import org.dromara.system.service.ISysUserService;
-import lombok.RequiredArgsConstructor;
 import org.springframework.http.MediaType;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -26,6 +27,9 @@ import org.springframework.web.multipart.MultipartFile;
 
 import java.util.Arrays;
 
+import static org.dromara.common.satoken.utils.LoginHelper.getLoginUser;
+import static org.dromara.system.constent.Constants.ONE;
+
 /**
  * 个人信息 业务处理
  *
@@ -82,16 +86,22 @@ public class SysProfileController extends BaseController {
     @Log(title = "个人信息", businessType = BusinessType.UPDATE)
     @PutMapping("/updatePwd")
     public R<Void> updatePwd(String oldPassword, String newPassword) {
+        LoginUser loginUser = getLoginUser();
         SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
         String password = user.getPassword();
+        SysUserBo sysUser = new SysUserBo();
+        sysUser.setPassword(newPassword);
+        if (ONE.equals(userService.checkStrongPwd(sysUser))) {
+            return R.fail("密码必须包含数字、大小写字母、特殊符号且大于8位");
+        }
         if (!BCrypt.checkpw(oldPassword, password)) {
             return R.fail("修改密码失败,旧密码错误");
         }
         if (BCrypt.checkpw(newPassword, password)) {
             return R.fail("新密码不能与旧密码相同");
         }
-
-        if (userService.resetUserPwd(user.getUserId(), BCrypt.hashpw(newPassword)) > 0) {
+        String passwordHashpw = BCrypt.hashpw(newPassword);
+        if (userService.resetUserPwd(user.getUserId(), passwordHashpw) > 0) {
             return R.ok();
         }
         return R.fail("修改密码异常,请联系管理员");

+ 11 - 11
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java

@@ -26,7 +26,10 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.common.web.core.BaseController;
-import org.dromara.system.domain.bo.*;
+import org.dromara.system.domain.bo.SysDeptBo;
+import org.dromara.system.domain.bo.SysPostBo;
+import org.dromara.system.domain.bo.SysRoleBo;
+import org.dromara.system.domain.bo.SysUserBo;
 import org.dromara.system.domain.vo.*;
 import org.dromara.system.listener.SysUserImportListener;
 import org.dromara.system.mapper.FormalParentsStudentMapper;
@@ -42,6 +45,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
+import static org.dromara.system.constent.Constants.ONE;
+
 /**
  * 用户信息
  *
@@ -57,14 +62,8 @@ public class SysUserController extends BaseController {
     private final ISysRoleService roleService;
     private final ISysPostService postService;
     private final ISysDeptService deptService;
-    private final ISysTenantService tenantService;
-
     private final FormalTeacherClassMapper formalTeacherClassMapper;
-
-    private final IFormalParentsStudentService formalParentsStudentService;
-
     private final FormalParentsStudentMapper formalParentsStudentMapper;
-
     private final SysMenuMapper sysMenuMapper;
 
     /**
@@ -220,10 +219,8 @@ public class SysUserController extends BaseController {
         } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
             return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
         }
-        if (TenantHelper.isEnable()) {
-            if (!tenantService.checkAccountBalance(TenantHelper.getTenantId())) {
-                return R.fail("当前租户下用户名额不足,请联系管理员");
-            }
+        else if (ONE.equals(userService.checkStrongPwd(user))) {
+            return R.fail("密码必须包含数字、大小写字母、特殊符号且大于8位");
         }
         user.setPassword(BCrypt.hashpw(user.getPassword()));
         return toAjax(userService.insertUser(user));
@@ -270,6 +267,9 @@ public class SysUserController extends BaseController {
     @Log(title = "用户管理", businessType = BusinessType.UPDATE)
     @PutMapping("/resetPwd")
     public R<Void> resetPwd(@RequestBody SysUserBo user) {
+        if (ONE.equals(userService.checkStrongPwd(user))) {
+            return R.fail("密码必须包含数字、大小写字母、特殊符号且大于8位");
+        }
         userService.checkUserAllowed(user.getUserId());
         userService.checkUserDataScope(user.getUserId());
         user.setPassword(BCrypt.hashpw(user.getPassword()));

+ 3 - 4
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java

@@ -1,7 +1,6 @@
 package org.dromara.system.domain.bo;
 
 import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.Email;
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.Size;
 import lombok.Data;
@@ -61,8 +60,8 @@ public class SysUserBo extends BaseEntity {
     /**
      * 用户邮箱
      */
-    @Email(message = "邮箱格式不正确")
-    @Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符")
+    //@Email(message = "邮箱格式不正确")
+    //@Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符")
     private String email;
 
     /**
@@ -93,7 +92,7 @@ public class SysUserBo extends BaseEntity {
     /**
      * 角色组
      */
-    @Size(min = 1, message = "用户角色不能为空")
+    //@Size(min = 1, message = "用户角色不能为空")
     private Long[] roleIds;
 
     /**

+ 13 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java

@@ -17,6 +17,12 @@ public interface ISysUserService {
 
     TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery);
 
+    /**
+     * 校验强密码
+     * @param user
+     * @return
+     */
+    public String checkStrongPwd(SysUserBo user);
     /**
      * 根据条件分页查询用户列表
      *
@@ -127,6 +133,13 @@ public interface ISysUserService {
      */
     int insertUser(SysUserBo user);
 
+    /**
+     * 通用注册用户
+     * @param user
+     * @return
+     */
+    int insertUserCommon(SysUserBo user);
+
     /**
      * 注册用户信息
      *

+ 36 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java

@@ -30,7 +30,7 @@ import org.dromara.system.domain.bo.SysUserBo;
 import org.dromara.system.domain.vo.*;
 import org.dromara.system.mapper.*;
 import org.dromara.system.service.ISysUserService;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.dromara.system.utils.PwdCheckUtil;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -39,6 +39,9 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
+import static org.dromara.system.constent.Constants.ONE;
+import static org.dromara.system.constent.Constants.TWO;
+
 /**
  * 用户 业务层处理
  *
@@ -71,6 +74,25 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
         return TableDataInfo.build(page);
     }
 
+    @Override
+    public String checkStrongPwd(SysUserBo user) {
+        String pwd = user.getPassword();
+        String result = TWO;
+        try {
+            if (!PwdCheckUtil.checkPasswordLength(pwd, "8", "16")
+                || !PwdCheckUtil.checkContainLowerCase(pwd)
+                || !PwdCheckUtil.checkContainUpperCase(pwd)
+                || !PwdCheckUtil.checkContainDigit(pwd)
+                || !PwdCheckUtil.checkContainSpecialChar(pwd)
+            ) {
+                result = ONE;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
     /**
      * 根据条件分页查询用户列表
      *
@@ -293,6 +315,19 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
         return rows;
     }
 
+    /**
+     * 通用注册用户
+     * @param user
+     * @return
+     */
+    @Override
+    public int insertUserCommon(SysUserBo user) {
+        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
+        // 新增用户信息
+        int rows = baseMapper.insert(sysUser);
+        return rows;
+    }
+
     /**
      * 注册用户信息
      *

+ 111 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/utils/PwdCheckUtil.java

@@ -0,0 +1,111 @@
+package org.dromara.system.utils;
+
+/**
+ * @Author: tjf
+ * @Date: 2022/10/10 9:24
+ * @Describe:
+ */
+public class PwdCheckUtil {
+    //定义特殊字符
+    public static String SPECIAL_CHAR = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
+
+    /**
+     * @brief   检测密码中字符长度
+     * @param[in] password            密码字符串
+     * @return  符合长度要求 返回true
+     */
+    public static boolean checkPasswordLength(String password, String minNum, String maxNum) {
+        boolean flag =false;
+        if (StringUtils.isBlank(maxNum))  {
+            minNum = StringUtils.isBlank(minNum) ? "0":minNum;
+            if (password.length() >= Integer.parseInt(minNum)) {
+                flag = true;
+            }
+        } else {
+            minNum = StringUtils.isBlank(minNum) ? "0":minNum;
+            if (password.length() >= Integer.parseInt(minNum) &&
+                    password.length() <= Integer.parseInt(maxNum)) {
+                flag = true;
+            }
+        }
+        return flag;
+    }
+
+    /**
+     * @brief   检测密码中是否包含数字
+     * @param[in] password            密码字符串
+     * @return  包含数字 返回true
+     */
+    public static boolean checkContainDigit(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (Character.isDigit(chPass[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @brief   检测密码中是否包含字母(不区分大小写)
+     * @param[in] password            密码字符串
+     * @return  包含字母 返回true
+     */
+    public static boolean checkContainCase(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (Character.isLetter(chPass[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * @brief   检测密码中是否包含小写字母
+     * @param[in] password            密码字符串
+     * @return  包含小写字母 返回true
+     */
+    public static boolean checkContainLowerCase(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (Character.isLowerCase(chPass[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * @brief   检测密码中是否包含大写字母
+     * @param[in] password            密码字符串
+     * @return  包含大写字母 返回true
+     */
+    public static boolean checkContainUpperCase(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (Character.isUpperCase(chPass[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * @brief   检测密码中是否包含特殊符号
+     * @param[in] password            密码字符串
+     * @return  包含特殊符号 返回true
+     */
+    public static boolean checkContainSpecialChar(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (SPECIAL_CHAR.indexOf(chPass[i]) != -1) {
+                return true;
+            }
+        }
+        return false;
+    }
+}