39 lines
4.9 KiB
Markdown
39 lines
4.9 KiB
Markdown
|
|
# 支付密码开发与验证记录
|
|||
|
|
|
|||
|
|
操作时间:2026-09-08
|
|||
|
|
操作类型:扩展、修复
|
|||
|
|
影响模块:用户设置、钱包密码、各业务端共用验证码与支付密码校验。
|
|||
|
|
|
|||
|
|
## 操作前后
|
|||
|
|
|
|||
|
|
设置中的支付密码原为未开放入口。现接通`/settings/payment-password`,读取当前钱包的`payment_password_set`,区分首次设置、旧密码修改、验证码找回;状态缺失进入错误重试,不能推断为未设置。密码限定六位数字、二次确认、请求中禁止重复提交,错误保留表单,仅收到`changed=true`才提示成功。
|
|||
|
|
|
|||
|
|
后端更新增加旧散列条件,防止并发覆盖;密码散列不进入SQL日志。输错计数与十五分钟锁定改为Redis原子脚本,五次失败后拒绝正确密码;缓存不可用也拒绝验证。验证码绑定客户端、手机号及用途,并在同一原子操作中校验和消费,防止并发重复使用。成功重置后清除本人锁定;若清锁失败,响应独立返回`lock_cleared=false`,页面明确区分密码已更新与锁仍可能生效。
|
|||
|
|
|
|||
|
|
## 短信限制
|
|||
|
|
|
|||
|
|
仓库仅有Mock验证码写入Redis,没有真实短信供应商。用户确认不知道现成配置路径;不重复索要密钥,也未擅自接入付费服务。接口保留原字段并新增`delivery_mode=mock`、`delivery_status=not_sent`及`retry_after`,关闭Mock时返回2410“短信验证服务尚未配置”。支付密码和注册页面不再把请求建立描述为短信已发送。首次设置与找回已通过隔离Mock联调,但真实手机收码仍未完成,不能计为生产可用短信流程。
|
|||
|
|
|
|||
|
|
## 代码与接口
|
|||
|
|
|
|||
|
|
- `apps/user_app/lib/ui/features/settings/payment_password_page.dart`:新增页面;`_load`状态读取、`_sendCode`用途及冷却、`_save`明确响应确认。
|
|||
|
|
- `apps/user_app/lib/data/repositories/client_repository.dart`:`wallet`、`requestPaymentPasswordCode`、`setPaymentPassword`增加会话保护,验证码手机号来自当前资料;不会接受页面传入钱包归属。
|
|||
|
|
- `apps/user_app/lib/domain/models/client_models.dart`:可空密码状态及验证码请求结果模型,保持旧构造调用兼容。
|
|||
|
|
- `apps/user_app/lib/app/router.dart`、`ui/features/settings/settings_page.dart`:受保护路由及设置入口;`register_page.dart`修正Mock提示。
|
|||
|
|
- `backend/api/internal/logic/common/client_wallet.go`:`SetPaymentPassword`严格数字、锁感知验证、条件更新及清锁结果;原接口字段兼容。
|
|||
|
|
- `backend/api/internal/logic/common/payment_password_guard.go`:抽出原共用校验并增加原子计数。
|
|||
|
|
- `backend/api/internal/logic/common/client_auth.go`:短信未配置拒绝、交付元数据及验证码原子消费。
|
|||
|
|
- 新增`payment_password_test.go`、`payment_password_remote_test.go`、`verification_availability_test.go`;Flutter新增`test/data/payment_password_test.dart`与`test/ui/payment_password_page_test.dart`。视觉工具增加`31-payment`,沿用明确测试数据,不从真实账户生成密码截图。
|
|||
|
|
|
|||
|
|
## 验证与风险
|
|||
|
|
|
|||
|
|
Flutter analyze及全量117项测试通过;页面8组320/360/390/430宽度、1.0/1.3文本缩放检查通过,已查看320放大截图无溢出。后端全量go test、go vet、API构建通过;新增短信不可用拒绝测试通过。
|
|||
|
|
|
|||
|
|
Web使用`--pwa-strategy=none`构建成功,Android调试包构建成功。浏览器加载新包后,支付密码深链跳转登录并在登录后回到原页面,读取真实已设置状态;空表单出现三处六位数字提示,找回模式正确切换为手机验证码,控制台无error/warn。未在真实用户钱包提交改密或发送验证码,成功变更由上述独立远程回滚测试覆盖。API进程39900监听12426,健康检查200;18571继续提供新Web产物。Android构建仍有既有插件Kotlin迁移提示,本轮未升级依赖,真机键盘及输入尚待验证。
|
|||
|
|
|
|||
|
|
显式开启`HEQI_REMOTE_PAYMENT_PASSWORD_TEST=1`的远程测试通过:独立临时用户与零余额钱包、首次设置、旧密码修改、验证码重置、错误格式、用途不匹配、16并发验证码仅一次成功、8并发错误密码触发五次锁定、重置解锁。数据库整体回滚后确认账户和钱包均不存在,仅清理本轮独立Redis键。没有修改真实账户支付密码、余额、数据库结构或远程缓存配置。
|
|||
|
|
|
|||
|
|
原子校验为共用逻辑,会影响所有调用支付密码或验证码的业务端,因此运行后端全量回归。Redis故障时相关验证不可用属于预期拒绝行为。网络中断后密码更新结果仍可能不确定,现有接口没有操作号查询;页面不把未知结果表述为密码未变更。
|
|||
|
|
|
|||
|
|
该子页没有独立一比一原稿,不把通用表单截图算作图31全量视觉验收。图31及全量App仍未完成严格1:1与全部功能验收,当前计数仍为16张部分实现、42张未完成对应完整页面、0张严格验收通过。
|