Bläddra i källkod

初始密码修改

wanglt 5 månader sedan
förälder
incheckning
0b20da78a2

+ 58 - 1
ygtx-admin/src/main/java/com/ygtx/web/controller/system/SysLoginController.java

@@ -6,8 +6,10 @@ import java.util.Set;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
+import com.ygtx.common.annotation.Anonymous;
 import com.ygtx.common.constant.Constants;
 import com.ygtx.common.core.domain.AjaxResult;
 import com.ygtx.common.core.domain.entity.SysMenu;
@@ -23,6 +25,7 @@ import com.ygtx.framework.web.service.SysPermissionService;
 import com.ygtx.framework.web.service.TokenService;
 import com.ygtx.system.service.ISysConfigService;
 import com.ygtx.system.service.ISysMenuService;
+import com.ygtx.system.service.ISysUserService;
 
 /**
  * 登录验证
@@ -46,6 +49,9 @@ public class SysLoginController
 
     @Autowired
     private ISysConfigService configService;
+    
+    @Autowired
+    private ISysUserService userService;
 
     /**
      * 登录方法
@@ -57,6 +63,24 @@ public class SysLoginController
     public AjaxResult login(@RequestBody LoginBody loginBody)
     {
         AjaxResult ajax = AjaxResult.success();
+        
+        // 检查是否为初始密码
+        String initPassword = configService.selectConfigByKey("sys.user.initPassword");
+        if (initPassword != null && initPassword.equals(loginBody.getPassword())) {
+            // 验证用户名和密码是否正确
+            try {
+                String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
+                        loginBody.getUuid());
+                // 如果能成功登录,说明是初始密码
+                ajax.put("isInitPassword", true);
+                ajax.put("message", "您使用的是初始密码,请修改密码后再登录");
+                return ajax;
+            } catch (Exception e) {
+                // 用户名或密码错误
+                ajax.put("isInitPassword", false);
+            }
+        }
+        
         // 生成令牌
         String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                 loginBody.getUuid());
@@ -64,6 +88,39 @@ public class SysLoginController
         return ajax;
     }
 
+    /**
+     * 初始密码修改
+     */
+    @Anonymous
+    @PutMapping("/initPassword")
+    public AjaxResult initPassword(@RequestBody LoginBody loginBody)
+    {
+        // 验证用户名和密码是否正确
+        try {
+            loginService.loginPreCheck(loginBody.getUsername(), loginBody.getPassword());
+
+            String initPassword = configService.selectConfigByKey("sys.user.initPassword");
+            if (initPassword.equals(loginBody.getPassword())) {
+                return AjaxResult.error("新密码不可与初始密码相同");
+            }
+            // 更新用户密码
+            SysUser user = userService.selectUserByUserName(loginBody.getUsername());
+            if (user != null) {
+                if (!SecurityUtils.matchesPassword(initPassword, user.getPassword())) {
+                    return AjaxResult.error("用户密码已被修改");
+                }
+                user.setPassword(SecurityUtils.encryptPassword(loginBody.getPassword()));
+                user.setPwdUpdateDate(new Date());
+                userService.resetUserPwd(user.getUserId(), user.getPassword());
+                return AjaxResult.success("密码修改成功");
+            } else {
+                return AjaxResult.error("用户不存在");
+            }
+        } catch (Exception e) {
+            return AjaxResult.error("密码修改失败:" + e.getMessage());
+        }
+    }
+
     /**
      * 获取用户信息
      * 
@@ -128,4 +185,4 @@ public class SysLoginController
         }
         return false;
     }
-}
+}

+ 2 - 1
ygtx-framework/src/main/java/com/ygtx/framework/config/SecurityConfig.java

@@ -114,6 +114,7 @@ public class SecurityConfig
                 requests.antMatchers("/login"
                                 , "/register"
                                 , "/captchaImage"
+                                , "/initPassword"
                                 , "/worklog/weekly/**"
                                 , "/demo/config/**"
                                 , "/demoT/config/**"
@@ -142,4 +143,4 @@ public class SecurityConfig
     {
         return new BCryptPasswordEncoder();
     }
-}
+}

+ 18 - 0
ygtx-ui/src/api/login.js

@@ -19,6 +19,24 @@ export function login(username, password, code, uuid) {
   })
 }
 
+// 初始密码修改
+export function initPassword(username, password, code, uuid) {
+  const data = {
+    username,
+    password,
+    code,
+    uuid
+  }
+  return request({
+    url: '/initPassword',
+    headers: {
+      isToken: false
+    },
+    method: 'put',
+    data: data
+  })
+}
+
 // 注册方法
 export function register(data) {
   return request({

+ 9 - 4
ygtx-ui/src/store/modules/user.js

@@ -26,9 +26,14 @@ const useUserStore = defineStore(
         const uuid = userInfo.uuid
         return new Promise((resolve, reject) => {
           login(username, password, code, uuid).then(res => {
-            setToken(res.token)
-            this.token = res.token
-            resolve()
+            if (res.isInitPassword) {
+              // 如果是初始密码,直接返回响应
+              resolve(res)
+            } else {
+              setToken(res.token)
+              this.token = res.token
+              resolve(res)
+            }
           }).catch(error => {
             reject(error)
           })
@@ -88,4 +93,4 @@ const useUserStore = defineStore(
     }
   })
 
-export default useUserStore
+export default useUserStore

+ 24 - 10
ygtx-ui/src/views/login.vue

@@ -62,6 +62,9 @@
       <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
     </div>
   </div>
+  
+  <!-- 初始密码修改弹窗 -->
+  <login-reset-pwd ref="resetPwdRef" :username="loginForm.username" :password="loginForm.password" :code="loginForm.code" :uuid="loginForm.uuid" />
 </template>
 
 <script setup>
@@ -69,6 +72,7 @@ import { getCodeImg } from "@/api/login"
 import Cookies from "js-cookie"
 import { encrypt, decrypt } from "@/utils/jsencrypt"
 import useUserStore from '@/store/modules/user'
+import LoginResetPwd from './loginResetPwd.vue'
 
 const title = import.meta.env.VITE_APP_TITLE
 const userStore = useUserStore()
@@ -97,6 +101,8 @@ const captchaEnabled = ref(true)
 // 注册开关
 const register = ref(false)
 const redirect = ref(undefined)
+// 重置密码弹窗引用
+const resetPwdRef = ref(null)
 
 watch(route, (newRoute) => {
     redirect.value = newRoute.query && newRoute.query.redirect
@@ -118,15 +124,23 @@ function handleLogin() {
         Cookies.remove("rememberMe")
       }
       // 调用action的登录方法
-      userStore.login(loginForm.value).then(() => {
-        const query = route.query
-        const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
-          if (cur !== "redirect") {
-            acc[cur] = query[cur]
-          }
-          return acc
-        }, {})
-        router.push({ path: redirect.value || "/", query: otherQueryParams })
+      userStore.login(loginForm.value).then(response => {
+        // 检查是否是初始密码
+        if (response.isInitPassword) {
+          loading.value = false
+          proxy.$modal.msgWarning(response.message)
+          // 显示修改密码弹窗,传递登录信息
+          resetPwdRef.value.show(loginForm.value)
+        } else {
+          const query = route.query
+          const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
+            if (cur !== "redirect") {
+              acc[cur] = query[cur]
+            }
+            return acc
+          }, {})
+          router.push({ path: redirect.value || "/", query: otherQueryParams })
+        }
       }).catch(() => {
         loading.value = false
         // 重新获取验证码
@@ -226,4 +240,4 @@ getCookie()
   height: 40px;
   padding-left: 12px;
 }
-</style>
+</style>

+ 123 - 0
ygtx-ui/src/views/loginResetPwd.vue

@@ -0,0 +1,123 @@
+<template>
+  <el-dialog
+    v-model="open"
+    title="修改初始密码"
+    width="500px"
+    append-to-body
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+  >
+    <el-form ref="pwdRef" :model="passwordForm" :rules="passwordRules" label-width="80px">
+      <el-form-item label="新密码" prop="newPassword">
+        <el-input
+          v-model="passwordForm.newPassword"
+          placeholder="请输入新密码"
+          type="password"
+          show-password
+        />
+      </el-form-item>
+      <el-form-item label="确认密码" prop="confirmPassword">
+        <el-input
+          v-model="passwordForm.confirmPassword"
+          placeholder="请确认新密码"
+          type="password"
+          show-password
+        />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submit" :loading="submitLoading">确 定</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue'
+import { initPassword } from "@/api/login"
+import { ElMessage } from 'element-plus'
+
+const open = ref(false)
+const pwdRef = ref(null)
+const submitLoading = ref(false)
+
+// 登录信息
+const loginInfo = reactive({
+  username: '',
+  password: '',
+  code: '',
+  uuid: ''
+})
+
+const passwordForm = reactive({
+  newPassword: '',
+  confirmPassword: ''
+})
+
+const passwordRules = reactive({
+  newPassword: [
+    { required: true, message: "新密码不能为空", trigger: "blur" },
+    { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }
+  ],
+  confirmPassword: [
+    { required: true, message: "确认密码不能为空", trigger: "blur" },
+    { validator: checkConfirmPassword, trigger: "blur" }
+  ]
+})
+
+function checkConfirmPassword(rule, value, callback) {
+  if (value !== passwordForm.newPassword) {
+    callback(new Error("两次输入的密码不一致"))
+  } else {
+    callback()
+  }
+}
+
+function show(loginData) {
+  open.value = true
+  reset()
+  // 保存登录信息
+  loginInfo.username = loginData.username
+  loginInfo.password = loginData.password
+  loginInfo.code = loginData.code
+  loginInfo.uuid = loginData.uuid
+}
+
+function hide() {
+  open.value = false
+}
+
+function reset() {
+  passwordForm.newPassword = ''
+  passwordForm.confirmPassword = ''
+  if (pwdRef.value) {
+    pwdRef.value.resetFields()
+  }
+}
+
+function submit() {
+  pwdRef.value.validate(valid => {
+    if (valid) {
+      submitLoading.value = true
+      // 使用初始密码修改接口
+      initPassword(loginInfo.username, passwordForm.newPassword, loginInfo.code, loginInfo.uuid).then(response => {
+        submitLoading.value = false
+        ElMessage.success("密码修改成功,请重新登录")
+        hide()
+        // 通知父组件密码修改成功
+        emits('passwordChanged')
+      }).catch(() => {
+        submitLoading.value = false
+      })
+    }
+  })
+}
+
+defineExpose({
+  show,
+  hide
+})
+
+const emits = defineEmits(['passwordChanged'])
+</script>