- 在ApiClient中新增submitFeedback、myFeedback、helpArticles、helpArticleDetail、 siteArticles、promotions、vipPackages、createVipOrder、vipOrders等方法 - 添加帮助文章和站点资讯的参数验证逻辑 - 更新测试文件添加新的API方法测试用例 - 在HTML页面中添加反馈、帮助和VIP服务相关页面的脚本引用 - 更新加入家谱页面为完整的申请流程界面 - 修改资讯详情页面为站点资讯展示页面 - 更新AxiosRequestUtil中认证处理逻辑 - 添加世系树渲染的HTML生成函数用于页面复用 - 更新文档中的API契约说明和页面规划
7.8 KiB
VIP 套餐与订单 Implementation Plan
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: 在服务中心开放 VIP 套餐查看、响应选项创建订单和我的订单刷新闭环,不制造支付或取消能力。
Architecture: utils/ApiClient.js 唯一拥有 /genealogy/pc/vip/** 的三个接口;新增 vip-pages.js 规范化套餐、家谱选项和订单,使用响应中的字符串 ID 构造 AppVipOrderBody。profile-services.html 作为唯一 VIP 页面,只提供套餐选择、可选家谱选择、创建订单和订单刷新。
Tech Stack: 静态 HTML、原生 JavaScript UMD、Axios、Node node:test。
Global Constraints
- 后端
D:\WorkSpace\Java\Genealogy全程只读。 - 只调用
GET /genealogy/pc/vip/packages、POST /genealogy/pc/vip/orders、GET /genealogy/pc/vip/orders。 packageId只能来自套餐响应;genealogyId只能来自genealogiesMine()响应,不提供文本输入。- 页面不提供未经确认的支付方式选择;请求省略
payType,由后端默认wechat。 - 不显示立即支付、模拟支付成功、取消订单、退款或关闭订单操作。
- 创建成功后重读订单列表并精确匹配同一
orderId。 - 不展示
appUserId、用户手机号、内部原始 JSON。
Task 1: ApiClient VIP 契约
Files:
- Modify:
utils/ApiClient.js - Modify:
tests/api-client-contract.test.js
Interfaces:
-
Produces:
vipPackages()、createVipOrder(body)、vipOrders() -
Step 1: 写失败契约测试
await client.vipPackages();
await client.createVipOrder({
packageId: '2062179707935264769',
genealogyId: '2062179707935264770',
payType: 'wechat',
appUserId: 'must-drop',
payStatus: 'must-drop'
});
await client.vipOrders();
assert.deepEqual(calls.map((config) => [config.method, config.url, config.data]), [
['get', '/genealogy/pc/vip/packages', undefined],
['post', '/genealogy/pc/vip/orders', {
packageId: '2062179707935264769',
genealogyId: '2062179707935264770',
payType: 'wechat'
}],
['get', '/genealogy/pc/vip/orders', undefined]
]);
- Step 2: 运行 RED
Run: node --test tests/api-client-contract.test.js
Expected: FAIL,VIP 方法不存在。
- Step 3: 最小实现
vipPackages: function () {
return request('GET', '/genealogy/pc/vip/packages');
},
createVipOrder: function (body) {
return request('POST', '/genealogy/pc/vip/orders', {
body: pickDefined(body, ['packageId', 'genealogyId', 'payType'])
});
},
vipOrders: function () {
return request('GET', '/genealogy/pc/vip/orders');
}
- Step 4: 运行 GREEN
Run: node --test tests/api-client-contract.test.js
Expected: PASS。
Task 2: 套餐、家谱选项和订单数据边界
Files:
- Create:
public/js/vip-pages.js - Create:
tests/vip-pages.test.js
Interfaces:
-
Produces:
normalizeVipPackage(item)normalizeVipPackages(data)normalizeGenealogyOption(item)buildVipOrderBody(values)validateVipOrderBody(body)normalizeVipOrder(item)normalizeVipOrders(data)renderVipPackages(data, selectedPackageId)renderGenealogyOptions(data)renderVipOrders(data)
-
Step 1: 写失败纯行为测试
使用完整 VipPackageVo、VipOrderVo 字面量断言:
-
套餐要求稳定字符串
packageId、非空名称、packageType=vip/storage、durationUnit=permanent/day/month/year、非负价格、status=0; -
停用套餐和不安全数字长 ID 不渲染;
-
家谱选项要求稳定字符串
genealogyId和非空genealogyName; -
body 只保留
packageId/genealogyId/payType,页面默认构造不包含payType; -
必须选择有效套餐;可选家谱必须是安全字符串 ID;若显式提供
payType只允许已确认wechat; -
订单要求稳定
orderId/packageId、订单号、套餐名、非负金额、payStatus=0/1/2/3、status=0/1; -
渲染不出现用户 ID、手机号、原始 JSON,不出现支付/取消/退款按钮。
-
Step 2: 运行 RED
Run: node --test tests/vip-pages.test.js
Expected: FAIL,模块不存在。
- Step 3: 最小实现纯函数
支付状态:
{ '0': '待支付', '1': '已支付', '2': '已关闭', '3': '已退款' }
套餐类型:
{ vip: '会员套餐', storage: '存储扩容' }
套餐和订单金额保留后端字符串语义,不进行浮点运算。
- Step 4: 运行 GREEN
Run:
node --test tests/vip-pages.test.js
node --check public/js/vip-pages.js
Expected: PASS。
Task 3: 服务中心真实 VIP 闭环
Files:
- Modify:
profile-services.html - Modify:
public/js/vip-pages.js - Modify:
tests/vip-pages.test.js - Modify:
tests/pending-pages.test.js - Modify:
tests/pc-scope.test.js
Interfaces:
-
Produces:
initVipPage()、init() -
Step 1: 写失败页面行为测试
断言:
-
服务中心不再 pending,加载
vip-pages.js; -
有套餐列表、只读选中提示、可选家谱下拉、订单表单、刷新订单和订单列表;
-
不存在
packageId/genealogyId/orderId文本或数字输入; -
不存在
payType选择器以及支付、取消、退款、模拟成功按钮; -
脚本并行读取套餐、我的家谱和订单;
-
创建后重读订单并精确匹配提交响应
orderId。 -
Step 2: 运行 RED
Run:
node --test tests/vip-pages.test.js tests/pending-pages.test.js tests/pc-scope.test.js
Expected: FAIL,服务中心仍为 pending 且允许手填 ID。
- Step 3: 实现页面初始化
- 401 跳转登录,403 保留登录态;
Promise.all([vipPackages(), genealogiesMine(), vipOrders()])读取页面数据;- 点击套餐卡保存响应中的字符串
packageId; - 家谱下拉只使用
genealogiesMine()选项,空值表示不关联家谱; - 表单提交使用
writePending锁; - 创建响应必须规范化;
- 重读
vipOrders()并找到同一orderId; - 刷新订单列表并展示“订单已创建;当前 PC 暂未开放在线支付”。
- Step 4: 运行 GREEN
Run:
node --test tests/vip-pages.test.js tests/pending-pages.test.js tests/pc-scope.test.js
node --check public/js/vip-pages.js
Expected: PASS。
Task 4: 导航、规划和收尾验证
Files:
- Modify:
profile.html - Modify:
docs/PC接口对接规划.md - Modify:
tests/stage6-navigation.test.js - Modify:
docs/superpowers/plans/2026-07-29-vip-packages-orders.md
Interfaces:
-
Consumes: Task 1–3 的 VIP 套餐与订单闭环。
-
Step 1: 写失败导航测试
断言个人中心服务入口可进入 profile-services.html,服务页真实开放并且所有 VIP 业务都留在该唯一 owner 页面。
- Step 2: 运行 RED
Run: node --test tests/stage6-navigation.test.js tests/pending-pages.test.js
Expected: FAIL,服务页仍 pending 或未加载真实脚本。
- Step 3: 更新规划
记录 AppVipOrderBody、VipPackageVo、VipOrderVo 的字段来源、枚举、隐藏字段、写后重读和支付能力阻断;阶段 7 标记 VIP 批次完成。
- Step 4: 聚焦和全量验证
Run:
node --test tests/vip-pages.test.js tests/api-client-contract.test.js tests/pending-pages.test.js tests/pc-scope.test.js tests/stage6-navigation.test.js
npm test
node --check public/js/vip-pages.js
git -c safe.directory=D:/WorkSpace/Web/jiapu diff --check
Expected: 全部 PASS。
- Step 5: 浏览器只读验证
真实登录态验证套餐、家谱下拉、订单空/有数据态、无伪支付动作和控制台错误。未经用户本轮明确授权,不创建真实订单。