xusl %!s(int64=2) %!d(string=hai) anos
pai
achega
0554d448b5

+ 49 - 0
backend/src/main/java/com/jiayue/ssi/config/MyAuthenticationProvider.java

@@ -0,0 +1,49 @@
+package com.jiayue.ssi.config;
+
+import cn.hutool.crypto.SmUtil;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+import javax.annotation.Resource;
+
+/**
+* security密码对比
+*
+* @author xsl
+* @since 2023/03/13
+*/
+public class MyAuthenticationProvider extends DaoAuthenticationProvider {
+
+    @Resource
+    private PasswordEncoder passwordEncoder;
+
+    @Override
+    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
+        if (authentication.getCredentials() == null) {
+            this.logger.debug("Authentication failed: no credentials provided");
+            throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
+        } else {
+            String presentedPassword = authentication.getCredentials().toString();
+
+            String decryptPassword = null;
+            //解密登陆密码
+            try {
+                decryptPassword= SmUtil.sm3(presentedPassword).toUpperCase();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+//            if (!this.passwordEncoder.matches(decryptPassword, userDetails.getPassword())) {
+//                this.logger.debug("Authentication failed: password does not match stored value");
+//                throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
+//            }
+            if (!decryptPassword.equals(userDetails.getPassword())) {
+                this.logger.debug("Authentication failed: password does not match stored value");
+                throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
+            }
+        }
+    }
+}

+ 21 - 0
backend/src/main/java/com/jiayue/ssi/controller/SysUserController.java

@@ -89,6 +89,27 @@ public class SysUserController {
     }
 
     /**
+     * 新增用户
+     */
+    @PostMapping(value = "/resetPassword")
+    @InterfaceLimit
+    public ResponseVO resetPassword(String id) {
+        if (StringUtils.isEmpty(id)){
+            return ResponseVO.fail("重置密码失败!");
+        }
+        SysUser sysUser = new SysUser();
+        sysUser.setId(Integer.parseInt(id));
+        // 生成8位初始密码
+        String randomPwd = RandomPwd.getRandomPwd(8);
+        sysUser.setPassword(SmUtil.sm3(randomPwd).toUpperCase());
+        boolean bo = sysUserService.updateById(sysUser);
+        if (!bo){
+            return ResponseVO.fail();
+        }
+        return ResponseVO.success();
+    }
+
+    /**
      * 更新用户信息
      *
      * @param sysUser 参数

+ 47 - 0
backend/src/main/java/com/jiayue/ssi/entity/BaseEntity.java

@@ -0,0 +1,47 @@
+package com.jiayue.ssi.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+/**
+ * Entity基类
+ *
+ * @author xsl
+ */
+@Data
+public class BaseEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /** 创建者 */
+    @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;
+
+}

+ 95 - 0
backend/src/main/java/com/jiayue/ssi/util/RandomPwd.java

@@ -0,0 +1,95 @@
+package com.jiayue.ssi.util;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 随机生成复杂密码
+ *
+ * @author xsl
+ * @since 2023/03/13
+ */
+public class RandomPwd {
+
+    private static final String lowStr = "abcdefghijklmnopqrstuvwxyz";
+    private static final String specialStr = "~!@#$%^&*()_+/-=[]{};:'<>?.";
+    private static final String numStr = "0123456789";
+
+    // 随机获取字符串字符
+    private static char getRandomChar(String str) {
+        SecureRandom random = new SecureRandom();
+        return str.charAt(random.nextInt(str.length()));
+    }
+
+    // 随机获取小写字符
+    private static char getLowChar() {
+        return getRandomChar(lowStr);
+    }
+
+    // 随机获取大写字符
+    private static char getUpperChar() {
+        return Character.toUpperCase(getLowChar());
+    }
+
+    // 随机获取数字字符
+    private static char getNumChar() {
+        return getRandomChar(numStr);
+    }
+
+    // 随机获取特殊字符
+    private static char getSpecialChar() {
+        return getRandomChar(specialStr);
+    }
+
+    //指定调用字符函数
+    private static char getRandomChar(int funNum) {
+        switch (funNum) {
+            case 0:
+                return getLowChar();
+            case 1:
+                return getUpperChar();
+            case 2:
+                return getNumChar();
+            default:
+                return getSpecialChar();
+        }
+    }
+
+    // 指定长度,随机生成复杂密码
+    public static String getRandomPwd(int num) {
+        if (num > 20 || num < 8) {
+            System.out.println("长度不满足要求");
+            return "";
+        }
+        List<Character> list = new ArrayList<>(num);
+        list.add(getLowChar());
+        list.add(getUpperChar());
+        list.add(getNumChar());
+        list.add(getSpecialChar());
+
+        for (int i = 4; i < num; i++) {
+            SecureRandom random = new SecureRandom();
+            int funNum = random.nextInt(4);
+            list.add(getRandomChar(funNum));
+        }
+
+        Collections.shuffle(list);   // 打乱排序
+        StringBuilder stringBuilder = new StringBuilder(list.size());
+        for (Character c : list) {
+            stringBuilder.append(c);
+        }
+
+        return stringBuilder.toString();
+    }
+
+    // 测试函数入口
+    public static void main(String[] args) {
+        for (int i = 0; i < 10; i++) {
+            int num = 8;
+            System.out.println(getRandomPwd(num));
+        }
+    }
+
+}

+ 134 - 0
ui/src/api/system/user.js

@@ -0,0 +1,134 @@
+import request from '@/utils/request'
+
+// 查询用户列表
+export function listUser(query) {
+  return request({
+    url: '/sysUserController/getAll',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询用户详细
+export function getUser(userId) {
+  return request({
+    url: '/system/user/' + parseStrEmpty(userId),
+    method: 'get'
+  })
+}
+
+// 新增用户
+export function addUser(data) {
+  return request({
+    url: '/system/user',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改用户
+export function updateUser(data) {
+  return request({
+    url: '/system/user',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除用户
+export function delUser(userId) {
+  return request({
+    url: '/system/user/' + userId,
+    method: 'delete'
+  })
+}
+
+// 用户密码重置
+export function resetUserPwd(userId, password) {
+  const data = {
+    userId,
+    password
+  }
+  return request({
+    url: '/system/user/resetPwd',
+    method: 'put',
+    data: data
+  })
+}
+
+// 用户状态修改
+export function changeUserStatus(userId, status) {
+  const data = {
+    userId,
+    status
+  }
+  return request({
+    url: '/system/user/changeStatus',
+    method: 'put',
+    data: data
+  })
+}
+
+// 查询用户个人信息
+export function getUserProfile() {
+  return request({
+    url: '/system/user/profile',
+    method: 'get'
+  })
+}
+
+// 修改用户个人信息
+export function updateUserProfile(data) {
+  return request({
+    url: '/system/user/profile',
+    method: 'put',
+    data: data
+  })
+}
+
+// 用户密码重置
+export function updateUserPwd(oldPassword, newPassword) {
+  const data = {
+    oldPassword,
+    newPassword
+  }
+  return request({
+    url: '/system/user/profile/updatePwd',
+    method: 'put',
+    params: data
+  })
+}
+
+// 用户头像上传
+export function uploadAvatar(data) {
+  return request({
+    url: '/system/user/profile/avatar',
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询授权角色
+export function getAuthRole(userId) {
+  return request({
+    url: '/system/user/authRole/' + userId,
+    method: 'get'
+  })
+}
+
+// 保存授权角色
+export function updateAuthRole(data) {
+  return request({
+    url: '/system/user/authRole',
+    method: 'put',
+    params: data
+  })
+}
+
+// 查询部门下拉树结构
+export function deptTreeSelect() {
+  return request({
+    url: '/system/user/deptTree',
+    method: 'get'
+  })
+}

+ 58 - 45
ui/src/views/sysManager/userManager/index.vue

@@ -101,7 +101,7 @@
                               type="text"
                               icon="el-icon-edit"
                               @click="handleResetPwd(scope.row)"
-                            >重置密码</el-button>
+                            >重置密码并且发送邮箱</el-button>
                             <el-button
                               size="mini"
                               type="text"
@@ -333,7 +333,7 @@ export default {
     // 表单重置
     reset() {
       this.form = {
-        userId: undefined,
+        id: undefined,
         username: undefined,
         nickname: undefined,
         phonenumber: undefined,
@@ -354,46 +354,9 @@ export default {
     /** 新增按钮操作 */
     handleAdd() {
       this.reset();
-        // this.postOptions = response.posts;
-        // this.roleOptions = response.roles;
         this.open = true;
         this.title = "添加用户";
         this.form.password = this.initPassword;
-
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      const userId = row.userId || this.ids;
-      getUser(userId).then(response => {
-        this.form = response.data;
-        this.postOptions = response.posts;
-        this.roleOptions = response.roles;
-        this.$set(this.form, "postIds", response.postIds);
-        this.$set(this.form, "roleIds", response.roleIds);
-        this.open = true;
-        this.title = "修改用户";
-        this.form.password = "";
-      });
-    },
-    /** 重置密码按钮操作 */
-    handleResetPwd(row) {
-      this.$prompt('请输入"' + row.userName + '"的新密码', "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        closeOnClickModal: false,
-        inputPattern: /^.{5,20}$/,
-        inputErrorMessage: "用户密码长度必须介于 5 和 20 之间"
-      }).then(({ value }) => {
-          resetUserPwd(row.userId, value).then(response => {
-            this.$modal.msgSuccess("修改成功,新密码是:" + value);
-          });
-        }).catch(() => {});
-    },
-    /** 分配角色操作 */
-    handleAuthRole: function(row) {
-      const userId = row.userId;
-      this.$router.push("/system/user-auth/role/" + userId);
     },
     /** 提交按钮 */
     submitForm: function() {
@@ -407,12 +370,12 @@ export default {
               this.getList();
             });
           } else {
-            const param = {
-              username: this.form.username,
-              nickname: this.form.nickname,
-              phonenumber: this.form.phonenumber,
-              mailbox: this.form.mailbox
-            }
+            // const param = {
+            //   username: this.form.username,
+            //   nickname: this.form.nickname,
+            //   phonenumber: this.form.phonenumber,
+            //   mailbox: this.form.mailbox
+            // }
             this.$axios.post('/sysUserController', this.form).then((res) => {
               this.$message.success('新增成功')
               this.open = false;
@@ -427,6 +390,56 @@ export default {
         }
       });
     },
+    /** 重置密码按钮操作 */
+    handleResetPwd(row) {
+      this.$confirm('重置密码并发送到邮箱'+row.mailbox, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        const param = {
+            id: row.id
+        }
+        this.$axios.post('/sysUserController/resetPassword', param).then((res) => {
+          if (res.code==0){
+            this.$message({
+              type: 'success',
+              message: '重置并发送成功!'
+            });
+          }
+          else{
+            this.$message({
+              type: 'error',
+              message: '重置失败!'
+            });
+          }
+        }).catch((error) => {
+          console.log(error)
+          this.loading = false
+        })
+      }).catch(() => {
+      });
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const userId = row.userId || this.ids;
+      getUser(userId).then(response => {
+        this.form = response.data;
+        this.postOptions = response.posts;
+        this.roleOptions = response.roles;
+        this.$set(this.form, "postIds", response.postIds);
+        this.$set(this.form, "roleIds", response.roleIds);
+        this.open = true;
+        this.title = "修改用户";
+        this.form.password = "";
+      });
+    },
+    /** 分配角色操作 */
+    handleAuthRole: function(row) {
+      const userId = row.userId;
+      this.$router.push("/system/user-auth/role/" + userId);
+    },
     /** 删除按钮操作 */
     handleDelete(row) {
       const userIds = row.userId || this.ids;