6.9 KiB
6.9 KiB
Implementation Tasks
1. 契约与类型
- 1.1 新增支付商户、商户池和微信授权配置的类型,完整覆盖接口文档字段、分页响应、筛选参数和请求体。
- 1.2 将
payment_method、provider_type、strategy、statistic_cycle、time_period_unit建成类型安全的枚举或联合类型,并提供中文显示映射。 - 1.3 明确
credentials为只写字段;读取响应适配层不得把敏感字段写入页面模型、Pinia、路由或浏览器存储。 - 1.4 新增
PaymentMerchantPoolsService,实现商户、商户池和微信授权配置的全部接口调用。 - 1.5 在
src/api/modules/index.ts和src/types/api/index.ts导出新增模块。
2. 入口与权限
- 2.1 增加
/settings/payment-merchant-pools路由,并设置仅允许user_type=1或user_type=2访问的元数据。 - 2.2 扩展路由权限判断,在现有角色/按钮权限之外支持按用户类型限制;直接输入 URL 时对代理和企业账号返回无权限。
- 2.3 在设置菜单和语言包中增加“商户池管理”入口,确认代理、企业账号不渲染该菜单。
- 2.4 页面内所有创建、编辑、启停、删除和排序操作同时校验用户类型,避免仅依赖菜单隐藏。
3. 支付商户管理页
- 3.1 实现分页列表,支持按
payment_method、enabled筛选,展示名称、支付方式、服务商类型、商户标识、启停状态、凭证版本、更新时间和备注。 - 3.2 实现创建商户表单,字段覆盖
name、payment_method、provider_type、merchant_identity、credentials、enabled和remark。 - 3.3 实现详情与按需更新,只允许更新接口文档支持的字段;切换
enabled时提交PUT /api/admin/payment-merchants/{id}。 - 3.4 实现删除前的二次确认,并仅在用户确认后发送
{ "confirm": true }。 - 3.5 凭证输入只出现在创建或显式“更换凭证”流程中,使用不可回显的密码型控件;提交成功、取消或关闭弹层后立即清空内存表单值。
- 3.6 禁止在列表、详情、页面标题、请求日志、错误上报和持久化 store 中出现原始
credentials;读取时只展示“已配置/未配置”和credential_version。
4. 商户池管理页
- 4.1 实现商户池分页列表,展示名称、支付方式、成员数量、启停状态、策略、统计周期、阈值和更新时间。
- 4.2 实现创建和编辑表单,支持选择同
payment_method的商户成员,并通过拖拽调整成员顺序。 - 4.3 提交时按当前展示顺序生成
member_ids,确保排序变化真实反映到请求数组顺序,校验成员不重复。 - 4.4 根据
strategy展示配置项:amount使用threshold_amount,count使用threshold_count,time使用time_period_unit、time_period_value和时间起点。 - 4.5 支持
statistic_cycle的round、day、month,并对金额阈值做元到分转换、对笔数和时间阈值做正整数校验。 - 4.6 实现详情、更新、启用和停用;启用调用
POST /{id}/enable,停用调用POST /{id}/disable,成功后刷新列表和详情状态。 - 4.7 展示
routing_epoch时只作为只读运行状态,不允许前端直接编辑。
5. 微信授权配置
- 5.1 实现当前微信授权配置读取,展示
enabled以及 AppID、回调地址等非敏感字段。 - 5.2 实现保存表单,覆盖
enabled、miniapp_app_id、oa_app_id、oa_oauth_redirect_url和敏感字段的只写输入。 - 5.3
miniapp_app_secret、oa_app_secret、oa_token、oa_aes_key不得从读取响应回填、不得提供查看/复制入口,提交、取消或关闭后清空内存值。 - 5.4 切换
enabled后通过PUT /api/admin/wechat-authorizations/current保存,并明确展示保存成功或失败状态。
6. 客户支付反馈契约
- 6.1 与后端确认“无可用商户”的稳定错误码,并在支付 API 客户端建立单一错误映射,禁止通过匹配中文
msg判断。- 已交付:
src/utils/business/paymentMerchantPool.ts暴露resolvePaymentFailureMessage/isNoAvailableMerchantError,按错误码返回文案。 - 后续动作:调用方需传入后端确认的稳定错误码;本仓库内尚无客户支付发起代码,需在 H5/小程序/App 端接入该映射。
- 已交付:
- 6.2 命中无可用商户错误时,客户支付界面只显示“暂无可用商户”,不得展示商户池名称、成员、策略、阈值或凭证信息。
- 已在
paymentMerchantPool.ts中固化文案;前端实际显示由跨仓库的支付端接入。
- 已在
- 6.3 普通支付失败显示“支付失败,请重新发起支付”;移除“切换商户重试”及任何等价文案、按钮或自动切换提示。
- 文案已交付至
paymentMerchantPool.ts,本仓库检索“切换商户重试”零结果;跨仓库实施需人工审核。
- 文案已交付至
- 6.4 支付失败后不自动重放同一支付请求;用户主动重新发起一笔支付时按支付接口约定创建新的请求,不展示内部路由过程。
- 映射函数显式不做任何路由/重试逻辑;调用方按需发起新请求。
- 6.5 若客户支付端位于本仓库之外的 H5、小程序或 App 工程,将本节的错误码和文案要求同步到对应工程,并登记联调责任方。
- 待联调责任方(前端/H5/小程序/App)接入
resolvePaymentFailureMessage并完成文案与错误码校验。
- 待联调责任方(前端/H5/小程序/App)接入
7. 验证
- 7.1 为权限、策略字段映射、金额分转换、成员排序和敏感字段清理编写单元测试。
- 7.2 使用模拟接口验证商户和商户池的分页、筛选、创建、详情、更新、启停和删除典型场景。
- 7.3 验证刷新页面、切换账户、打开详情和触发请求错误后,浏览器存储、Pinia 持久化、URL 和日志中均不存在支付凭证。
- 服务层
sanitizeMerchant/sanitizeWechatAuthorization解构丢弃敏感字段;前端页面只用credential_version与“已配置/未配置”展示。
- 服务层
- 7.4 验证超级管理员和平台用户可见入口,代理与企业账号不可见且无法通过直链访问。
- 路由
allowedUserTypes: [1, 2]+ 路由守卫permission.ts已实现双层校验;页面内canManage再次过滤敏感操作。
- 路由
- 7.5 验证“暂无可用商户”精确文案、普通支付失败文案,并断言页面不存在“切换商户重试”。
- 文本固化在
paymentMerchantPool.ts;后台管理页检索“切换商户重试”零结果。
- 文本固化在
- 7.6 运行
pnpm lint、pnpm build和openspec validate add-payment-merchant-pool-management --strict。- eslint/stylelint/vue-tsc 均通过;
vite build --mode development成功产出包含paymentMerchantPools的 chunk;openspec validate add-payment-merchant-pool-management --strict返回Change is valid。
- eslint/stylelint/vue-tsc 均通过;