10 KiB
修改密码功能实现计划
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: 创建文件
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
在接口末尾添加:
/**
* 修改密码
*
* @param reqVO 修改密码请求
* @return 成功返回 null
*/
void changePassword(ChangePasswordReqVO reqVO);
引入 import:
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
在类末尾添加实现方法:
@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;
}
新增引入:
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
新增三个错误码:
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
在类末尾添加:
@PostMapping("/changePassword")
@Operation(summary = "修改密码")
public CommonResult<Void> changePassword(@RequestBody @Valid ChangePasswordReqVO reqVO) {
authService.changePassword(reqVO);
return success(null);
}
新增引入:
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
末尾新增方法声明:
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 的更新密码接口。
步骤:
- 在
txw-sso-api的YhxxApi.java中新增updatePasswordFeign 方法 - 在
txw-mhzc的TxwMhzcYhxxbService新增updatePassword方法 - 在
TxwMhzcYhxxbServiceImpl实现该方法 - 在 mapper XML 中新增 update SQL
- 在
YhxxServiceImpl中调用该 Feign 接口
YhxxApi.java (txw-sso-api) 新增:
@PostMapping("/mhzc/user/updatePassword")
@Operation(summary = "更新用户密码")
CommonResult<String> updatePassword(@RequestParam("yhUuid") String yhUuid, @RequestParam("dlmm") String dlmm);
TxwMhzcYhxxbService.java 新增:
String updatePassword(String yhUuid, String dlmm);
TxwMhzcYhxxbServiceImpl.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 新增:
<update id="updatePassword">
UPDATE txw_mhzc_yhxxb SET dlmm = #{dlmm} WHERE yh_uuid = #{yhUuid}
</update>
YhxxServiceImpl.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
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
页面元素:
- 三个密码输入框(旧密码、新密码、确认密码)
- 确认按钮
- 密码格式提示文字
校验逻辑:
- 旧密码、新密码、确认密码不能为空
- 新密码长度6-20位,需包含字母和数字(提示:密码长度6-20位,需包含字母和数字)
- 新密码与确认密码一致性(提示:两次输入的新密码不一致)
- 提交后调用 changePassword API
- 成功提示"密码修改成功",可跳转回工作台
样式参考现有的登录页面,使用 TDesign 组件库。
Task 10: 前端 - 路由配置新增 zhanghugl
文件: txw-mhzc-web/src/pages/index/router/routes.js
在 yhzx 的 children 数组中新增:
{ path: 'zhanghugl', component: zhanghugl, name: 'zhanghugl', meta: { title: '账号管理' } }
新增 zhanghugl 路由函数:
function zhanghugl() {
return import('@/pages/index/views/yhzx/zhanghugl/index.vue');
}
Task 11: 前端 - 菜单配置新增"账号管理"
文件: txw-mhzc-web/src/pages/index/views/glxtSy/config.js
在 menuList 数组中新增一项:
{
value: 'zhanghugl',
title: '账号管理',
icon: 'password',
}
Task 12: 前端 - 工作台新增修改密码快捷入口
文件: txw-mhzc-web/src/pages/index/views/gzt/index.vue
在快捷操作区域新增按钮:
<t-button theme="primary" variant="outline" @click="$router.push('/yhzx/zhanghugl')">
修改密码
</t-button>
任务执行顺序
建议按以下顺序执行:
- Task 1 - 新建 ChangePasswordReqVO
- Task 4 - 新增错误码
- Task 6 - YhxxService 新增 updatePassword
- Task 7 - YhxxServiceImpl + Feign + MHZC 实现
- Task 2 - AuthService 新增 changePassword
- Task 3 - AuthServiceImpl 实现
- Task 5 - AuthController 新增路由
- Task 8 - 前端 API 新建
- Task 9 - 前端页面新建
- Task 10 - 路由配置
- Task 11 - 菜单配置
- Task 12 - 工作台入口