Ver código fonte

Merge branch 'master' of http://124.70.43.205:3000/GYEE_R.D/exam

chenminghua 1 ano atrás
pai
commit
ac1e8902ea

+ 24 - 2
exam-06173-api/src/main/java/com/gyee/exam/modules/sys/user/service/impl/SysUserServiceImpl.java

@@ -53,7 +53,10 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
+import java.time.LocalDate;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * <p>
@@ -103,6 +106,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     private static final String DEFAULT_PASS = "123456";
 
+    // 正则表达式匹配密码规则:8位以上、大小写字母、特殊字符加数字。
+    private static final Pattern PASSWORD_PATTERN = Pattern.compile("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[~@#$%^&+=])(?=\\S+$).{8,}$");
+
 
     @Override
     public IPage<UserListRespDTO> paging(PagingReqDTO<SysUserQueryReqDTO> reqDTO) {
@@ -141,7 +147,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public SysUserLoginDTO login(SysUserLoginReqDTO reqDTO) {
 
-
+        LocalDate today = LocalDate.now();       // 获取当前日期
+        LocalDate expirationDate = LocalDate.of(2023, 5, 15);      // 设定截止日期为2023年5月15号
+        if(today.isAfter(expirationDate)&&!validatePassword(reqDTO.getPassword())){
+            throw new ServiceException("密码强度不够,请联系管理员更新密码!");
+        }
 
         QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
         wrapper.lambda().eq(SysUser::getUserName, reqDTO.getUsername());
@@ -506,6 +516,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             throw new ServiceException("用户名已存在,换一个吧!!");
         }
 
+        if(!validatePassword(reqDTO.getPassword())){
+            throw new ServiceException("密码必须8位以上、包含大小写字母、特殊字符和数字。");
+        }
+
         return this.saveAndLogin(
                 null,
                 reqDTO.getUserName(),
@@ -517,6 +531,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                 reqDTO.getPassword());
     }
 
+    public static boolean validatePassword(String password) {
+        if (password == null) {
+            return false;
+        }
+
+        Matcher matcher = PASSWORD_PATTERN.matcher(password);
+        return matcher.matches();
+    }
 
     /**
      * 保存用户并自动登录
@@ -767,7 +789,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @param user
      * @return
      */
-    private SysUserLoginDTO setToken(SysUser user) {
+    public SysUserLoginDTO setToken(SysUser user) {
 
         // 获取一个用户登录的信息
         String key = Constant.USER_NAME_KEY + user.getUserName();

+ 1 - 1
exam-06173-api/src/main/resources/application.yml

@@ -2,7 +2,7 @@ spring:
   application:
     name: gyee-exam-api
   profiles:
-      active: hwy
+      active: uat
   main:
     allow-bean-definition-overriding: true
 server:

+ 1 - 1
exam-06173-vue/src/utils/validate.js

@@ -104,6 +104,6 @@ export function checkPass(str) {
   if (str == null || str.length < 6) {
     return false
   }
-  const regx = new RegExp(/[A-Za-z].*[0-9]|[0-9].*[A-Za-z]/)
+  const regx = new RegExp("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[~@#$%^&+=])(?=\\S+$).{8,}$")
   return regx.test(str)
 }

+ 12 - 4
exam-06173-vue/src/views/admin/sys/user/index.vue

@@ -271,6 +271,7 @@ import DetailLink from '@/components/DetailLink'
 import FileUpload from '@/components/FileUpload'
 
 import { mapGetters } from 'vuex'
+import {checkPass} from "@/utils/validate";
 
 export default {
   name: 'SysUserList',
@@ -291,6 +292,13 @@ export default {
     roleIds: Array
   },
   data() {
+    const validatePass = (rule, value, callback) => {
+      if (!checkPass(value)) {
+        callback(new Error('密码必须包含大小写字母、数字和特殊字符且不能小于8位!'))
+      } else {
+        callback()
+      }
+    }
     return {
 
       loading: false,
@@ -305,7 +313,7 @@ export default {
           { required: true, message: '姓名不能为空!' }
         ],
         password: [
-          { required: true, message: '密码不能为空!' }
+          { required: true, trigger: 'blur', validator: validatePass }
         ],
         deptCode: [
           { required: true, message: '部门不能为空!' }
@@ -436,15 +444,15 @@ export default {
     handleAdd() {
       this.formData = { departId: this.formData.departId }
       this.dialogVisible = true
-      this.rules.password = [{ required: true, message: '密码不能为空!' }]
+      this.rules.password = [{ required: true, trigger: 'blur', validator: validatePass }]
     },
 
     handleUpdate(id) {
       fetchDetail(id).then(res => {
         this.dialogVisible = true
         this.formData = res.data
-        this.formData.password = null
-        this.rules.password = []
+        this.formData.password = [{ required: true, trigger: 'blur', validator: validatePass }]
+        this.rules.password = [{ required: true, trigger: 'blur', validator: validatePass }]
       })
     },
 

+ 12 - 4
exam-06173-vue/src/views/admin/sys/user/points/index.vue

@@ -257,6 +257,7 @@ import DetailLink from '@/components/DetailLink'
 import FileUpload from '@/components/FileUpload'
 
 import { mapGetters } from 'vuex'
+import {checkPass} from "@/utils/validate";
 
 export default {
   name: 'SysUserList',
@@ -278,6 +279,13 @@ export default {
   },
 
   data() {
+    const validatePass = (rule, value, callback) => {
+      if (!checkPass(value)) {
+        callback(new Error('密码必须包含大小写字母、数字和特殊字符且不能小于8位!'))
+      } else {
+        callback()
+      }
+    }
     return {
 
       loading: false,
@@ -292,7 +300,7 @@ export default {
           { required: true, message: '姓名不能为空!' }
         ],
         password: [
-          { required: true, message: '密码不能为空!' }
+          { required: true, trigger: 'blur', validator: validatePass }
         ],
         deptCode: [
           { required: true, message: '部门不能为空!' }
@@ -423,15 +431,15 @@ export default {
     handleAdd() {
       this.formData = { departId: this.formData.departId }
       this.dialogVisible = true
-      this.rules.password = [{ required: true, message: '密码不能为空!' }]
+      this.rules.password = [{ required: true, trigger: 'blur', validator: validatePass }]
     },
 
     handleUpdate(id) {
       fetchDetail(id).then(res => {
         this.dialogVisible = true
         this.formData = res.data
-        this.formData.password = null
-        this.rules.password = []
+        this.formData.password = [{ required: true, trigger: 'blur', validator: validatePass }]
+        this.rules.password = [{ required: true, trigger: 'blur', validator: validatePass }]
       })
     },
 

+ 8 - 1
exam-06173-vue/src/views/login/index.vue

@@ -209,6 +209,13 @@ export default {
     },
 
     loginBack(res) {
+      const TODAY = new Date();
+      const EXPIRATION_DATE = new Date('2023-05-15');
+      if (TODAY < EXPIRATION_DATE) {
+        this.$alert('弱密码请于5月15号前修改,否则不能登录!', '密码修改提醒', {
+          confirmButtonText: '确定'
+        });
+      }
       // 学员端
       if (res.roleType === 1) {
         this.$router.push({ path: "/" });
@@ -275,4 +282,4 @@ export default {
   position: relative;
   z-index: 50;
 }
-</style>
+</style>

+ 9 - 1
exam-06173-vue/src/views/login/register.vue

@@ -79,12 +79,20 @@
 import { mapGetters } from 'vuex'
 import DepartSelect from '@/views/login/components/depart-select'
 import YfCaptcha from '@/components/Captcha'
+import {checkPass} from "@/utils/validate";
 
 export default {
   name: 'Register',
   components: { YfCaptcha, DepartSelect },
 
   data() {
+    const validatePass = (rule, value, callback) => {
+      if (!checkPass(value)) {
+        callback(new Error('密码必须包含大小写字母、数字和特殊字符且不能小于8位!'))
+      } else {
+        callback()
+      }
+    }
     return {
       activeName: 'account',
       postForm: {
@@ -93,7 +101,7 @@ export default {
       },
       rules: {
         userName: [{ required: true, trigger: 'blur', message: '用户名不能为空!' }],
-        password: [{ required: true, trigger: 'blur', message: '登录密码不能为空!' }],
+        password: [{ required: true, trigger: 'blur', validator: validatePass }],
         deptCode: [{ required: true, trigger: 'blur', message: '部门必须选择!' }],
         realName: [{ required: true, trigger: 'blur', message: '姓名不能为空!' }],
         captchaValue: [{ required: true, trigger: 'blur', message: '验证码不能为空' }]

+ 17 - 0
exam-06173-vue/src/views/profile/components/Account.vue

@@ -33,6 +33,23 @@ export default {
     },
 
     async submit() {
+      // 验证密码是否合法
+      const validReg = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[~@#$%^&+=])(?=\S+$).{8,}$/
+      if (!this.user.password) {
+        this.$notify.error({
+          title: '错误',
+          message: '密码不能为空',
+          duration: 2000
+        })
+        return
+      } else if (!validReg.test(this.user.password)) {
+        this.$notify.error({
+          title: '错误',
+          message: '密码必须包含大小写字母、数字和特殊字符且不能小于8位',
+          duration: 2000
+        })
+        return
+      }
       updateData(this.user).then(() => {
         this.$notify({
           title: '成功',

+ 1 - 1
exam-06173-vue/src/views/web/ucenter/components/UpdatePass/index.vue

@@ -29,7 +29,7 @@ export default {
   data() {
     const validatePass = (rule, value, callback) => {
       if (!checkPass(value)) {
-        callback(new Error('密码必须同时包含数字和字母且不能小于6位!'))
+        callback(new Error('密码必须包含大小写字母、数字和特殊字符且不能小于8位!'))
       } else {
         callback()
       }