# 修改密码功能实现计划 > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** 为碳信网平台添加普通用户自助修改密码功能(txw-sso后端 + txw-mhzc-web前端) **Architecture:** - 后端:SSO服务新增 `POST /sso/auth/changePassword` 接口,用户通过 authenticate 验证旧密码,通过 mhzc-service 的 Feign 接口更新用户密码 - 前端:mhzc-web 新增修改密码页面(账号管理),工作台增加快捷入口,用户中心左侧菜单增加"账号管理"菜单项 **Tech Stack:** Java Spring Boot / Vue 2 / TDesign / Feign --- ## 涉及的变更文件 ### 后端(txw-sso) | 文件 | 改动 | |------|------| | `AuthService.java` | 新增 `changePassword` 接口声明 | | `AuthServiceImpl.java` | 实现 `changePassword` 逻辑 | | `AuthController.java` | 新增 `/auth/changePassword` 路由 | | `ChangePasswordReqVO.java` | 新建请求 VO | | `ChangePasswordRespVO.java` | 新建响应 VO | | `YhxxApi.java` (txw-sso-api) | 新增 Feign 方法 `updatePassword` | | `TxwMhzcYhxxbService.java` (txw-mhzc) | 新增 `updatePassword` 方法声明 | | `TxwMhzcYhxxbServiceImpl.java` (txw-mhzc) | 实现 `updatePassword` | | `TxwMhzcYhxxbMapper.xml` | 新增 updatePassword SQL | | `ISsoApi.java` | FeignClient name 常量(需确认mhzc服务名) | ### 前端(txw-mhzc-web) | 文件 | 改动 | |------|------| | `views/gzt/index.vue` | 新增修改密码快捷入口按钮 | | `views/yhzx/zhanghugl/index.vue` | 新建修改密码页面 | | `router/routes.js` | 新增 `zhanghugl` 路由 | | `views/glxtSy/config.js` | 菜单配置新增"账号管理" | | `api/sso.js` | 新建,封装 changePassword API | --- ## 后端任务拆分 ### Task 1: 后端 - 新建 ChangePasswordReqVO **文件:** `txw-sso/txw-sso-service-biz/src/main/java/com/css/txw/sso/pojo/vo/ChangePasswordReqVO.java` - [ ] **Step 1: 创建文件** ```java package com.css.txw.sso.pojo.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; @Schema(description = "修改密码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class ChangePasswordReqVO { @Schema(description = "旧密码(MD5加密)", requiredMode = Schema.RequiredMode.REQUIRED) @NotBlank(message = "旧密码不能为空") private String oldPassword; @Schema(description = "新密码(MD5加密)", requiredMode = Schema.RequiredMode.REQUIRED) @NotBlank(message = "新密码不能为空") private String newPassword; @Schema(description = "确认密码(MD5加密)", requiredMode = Schema.RequiredMode.REQUIRED) @NotBlank(message = "确认密码不能为空") private String confirmPassword; } ``` --- ### Task 2: 后端 - AuthService 新增 changePassword 接口声明 **文件:** `txw-sso/txw-sso-service-biz/src/main/java/com/css/txw/sso/service/auth/AuthService.java` 在接口末尾添加: ```java /** * 修改密码 * * @param reqVO 修改密码请求 * @return 成功返回 null */ void changePassword(ChangePasswordReqVO reqVO); ``` 引入 import: ```java import com.css.txw.sso.pojo.vo.ChangePasswordReqVO; ``` --- ### Task 3: 后端 - AuthServiceImpl 实现 changePassword **文件:** `txw-sso/txw-sso-service-biz/src/main/java/com/css/txw/sso/service/auth/impl/AuthServiceImpl.java` 在类末尾添加实现方法: ```java @Override public void changePassword(ChangePasswordReqVO reqVO) { // 1. 校验新密码与确认密码一致性 if (!reqVO.getNewPassword().equals(reqVO.getConfirmPassword())) { throw exception(AUTH_PASSWORD_CONFIRM_MISMATCH); } // 2. 密码复杂度校验(6-20位,字母+数字) if (!isValidPasswordComplexity(reqVO.getNewPassword())) { throw exception(AUTH_PASSWORD_COMPLEXITY_INVALID); } // 3. 获取当前登录用户 String userId = SecurityFrameworkUtils.getLoginUserId(); YhxxbDTO yhxx = yhxxService.getYhxx(userId); // 4. 校验新旧密码不能相同 if (reqVO.getOldPassword().equals(reqVO.getNewPassword())) { throw exception(AUTH_PASSWORD_SAME_AS_OLD); } // 5. 旧密码正确性校验 authenticate(yhxx.getDlzh(), reqVO.getOldPassword()); // 6. 更新密码 yhxxService.updatePassword(userId, reqVO.getNewPassword()); } private boolean isValidPasswordComplexity(String password) { if (password == null || password.length() < 6 || password.length() > 20) { return false; } boolean hasLetter = password.matches(".*[A-Za-z]+.*"); boolean hasDigit = password.matches(".*[0-9]+.*"); return hasLetter && hasDigit; } ``` 新增引入: ```java import com.css.txw.sso.pojo.vo.ChangePasswordReqVO; import com.css.txw.sso.util.SecurityFrameworkUtils; import static com.css.txw.sso.constants.ErrorCodeConstants.AUTH_PASSWORD_CONFIRM_MISMATCH; import static com.css.txw.sso.constants.ErrorCodeConstants.AUTH_PASSWORD_COMPLEXITY_INVALID; import static com.css.txw.sso.constants.ErrorCodeConstants.AUTH_PASSWORD_SAME_AS_OLD; ``` --- ### Task 4: 后端 - ErrorCodeConstants 新增错误码 **文件:** `txw-sso/txw-sso-service-biz/src/main/java/com/css/txw/sso/constants/ErrorCodeConstants.java` 新增三个错误码: ```java AUTH_PASSWORD_CONFIRM_MISMATCH(400, "两次输入的新密码不一致"), AUTH_PASSWORD_COMPLEXITY_INVALID(400, "密码长度6-20位,需包含字母和数字"), AUTH_PASSWORD_SAME_AS_OLD(400, "新密码不能与原密码相同"), ``` --- ### Task 5: 后端 - AuthController 新增路由 **文件:** `txw-sso/txw-sso-service-biz/src/main/java/com/css/txw/sso/controller/auth/AuthController.java` 在类末尾添加: ```java @PostMapping("/changePassword") @Operation(summary = "修改密码") public CommonResult changePassword(@RequestBody @Valid ChangePasswordReqVO reqVO) { authService.changePassword(reqVO); return success(null); } ``` 新增引入: ```java import com.css.txw.sso.pojo.vo.ChangePasswordReqVO; ``` --- ### Task 6: 后端 - YhxxService 新增 updatePassword 方法 **文件:** `txw-sso/txw-sso-service-biz/src/main/java/com/css/txw/sso/service/yhxx/YhxxService.java` 末尾新增方法声明: ```java void updatePassword(String yhUuid, String newPassword); ``` --- ### Task 7: 后端 - YhxxServiceImpl 实现 updatePassword(Feign调用mhzc) **文件:** `txw-sso/txw-sso-service-biz/src/main/java/com/css/txw/sso/service/yhxx/impl/YhxxServiceImpl.java` 首先需要确认 mhzc 服务的 Feign 接口存在。如果 YhxxApi 不支持更新密码,则需要在 txw-sso-api 中新增 Feign 方法指向 mhzc 的更新密码接口。 步骤: 1. 在 `txw-sso-api` 的 `YhxxApi.java` 中新增 `updatePassword` Feign 方法 2. 在 `txw-mhzc` 的 `TxwMhzcYhxxbService` 新增 `updatePassword` 方法 3. 在 `TxwMhzcYhxxbServiceImpl` 实现该方法 4. 在 mapper XML 中新增 update SQL 5. 在 `YhxxServiceImpl` 中调用该 Feign 接口 **YhxxApi.java (txw-sso-api) 新增:** ```java @PostMapping("/mhzc/user/updatePassword") @Operation(summary = "更新用户密码") CommonResult updatePassword(@RequestParam("yhUuid") String yhUuid, @RequestParam("dlmm") String dlmm); ``` **TxwMhzcYhxxbService.java 新增:** ```java String updatePassword(String yhUuid, String dlmm); ``` **TxwMhzcYhxxbServiceImpl.java 新增:** ```java @Override public String updatePassword(String yhUuid, String dlmm) { TxwMhzcYhxxbDO yhxxbDO = new TxwMhzcYhxxbDO(); yhxxbDO.setYhUuid(yhUuid); yhxxbDO.setDlmm(dlmm); this.updateById(yhxxbDO); return "success"; } ``` **TxwMhzcYhxxbMapper.xml 新增:** ```xml UPDATE txw_mhzc_yhxxb SET dlmm = #{dlmm} WHERE yh_uuid = #{yhUuid} ``` **YhxxServiceImpl.java 实现:** ```java @Resource private YhxxApi yhxxApi; @Override public void updatePassword(String yhUuid, String newPassword) { yhxxApi.updatePassword(yhUuid, newPassword); } ``` --- ## 前端任务拆分(txw-mhzc-web) ### Task 8: 前端 - 新建 api/sso.js **文件:** `txw-mhzc-web/src/pages/index/api/sso.js` ```js import { fetchSso } from '@/core/request'; export const changePassword = (params) => { return fetchSso({ url: '/sso/auth/changePassword', data: JSON.stringify(params), method: 'post', loading: true, }); }; ``` --- ### Task 9: 前端 - 新建修改密码页面 **文件:** `txw-mhzc-web/src/pages/index/views/yhzx/zhanghugl/index.vue` 页面元素: - 三个密码输入框(旧密码、新密码、确认密码) - 确认按钮 - 密码格式提示文字 校验逻辑: 1. 旧密码、新密码、确认密码不能为空 2. 新密码长度6-20位,需包含字母和数字(提示:密码长度6-20位,需包含字母和数字) 3. 新密码与确认密码一致性(提示:两次输入的新密码不一致) 4. 提交后调用 changePassword API 5. 成功提示"密码修改成功",可跳转回工作台 样式参考现有的登录页面,使用 TDesign 组件库。 --- ### Task 10: 前端 - 路由配置新增 zhanghugl **文件:** `txw-mhzc-web/src/pages/index/router/routes.js` 在 `yhzx` 的 children 数组中新增: ```js { path: 'zhanghugl', component: zhanghugl, name: 'zhanghugl', meta: { title: '账号管理' } } ``` 新增 zhanghugl 路由函数: ```js function zhanghugl() { return import('@/pages/index/views/yhzx/zhanghugl/index.vue'); } ``` --- ### Task 11: 前端 - 菜单配置新增"账号管理" **文件:** `txw-mhzc-web/src/pages/index/views/glxtSy/config.js` 在 `menuList` 数组中新增一项: ```js { value: 'zhanghugl', title: '账号管理', icon: 'password', } ``` --- ### Task 12: 前端 - 工作台新增修改密码快捷入口 **文件:** `txw-mhzc-web/src/pages/index/views/gzt/index.vue` 在快捷操作区域新增按钮: ```html 修改密码 ``` --- ## 任务执行顺序 建议按以下顺序执行: 1. Task 1 - 新建 ChangePasswordReqVO 2. Task 4 - 新增错误码 3. Task 6 - YhxxService 新增 updatePassword 4. Task 7 - YhxxServiceImpl + Feign + MHZC 实现 5. Task 2 - AuthService 新增 changePassword 6. Task 3 - AuthServiceImpl 实现 7. Task 5 - AuthController 新增路由 8. Task 8 - 前端 API 新建 9. Task 9 - 前端页面新建 10. Task 10 - 路由配置 11. Task 11 - 菜单配置 12. Task 12 - 工作台入口