txw/docs/superpowers/plans/2026-04-28-修改密码功能实现计划.md

10 KiB
Raw Blame History

修改密码功能实现计划

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 实现 updatePasswordFeign调用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-apiYhxxApi.java 中新增 updatePassword Feign 方法
  2. txw-mhzcTxwMhzcYhxxbService 新增 updatePassword 方法
  3. TxwMhzcYhxxbServiceImpl 实现该方法
  4. 在 mapper XML 中新增 update SQL
  5. 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

页面元素:

  • 三个密码输入框(旧密码、新密码、确认密码)
  • 确认按钮
  • 密码格式提示文字

校验逻辑:

  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 数组中新增:

{ 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>

任务执行顺序

建议按以下顺序执行:

  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 - 工作台入口