- 在ApiClient中新增submitFeedback、myFeedback、helpArticles、helpArticleDetail、 siteArticles、promotions、vipPackages、createVipOrder、vipOrders等方法 - 添加帮助文章和站点资讯的参数验证逻辑 - 更新测试文件添加新的API方法测试用例 - 在HTML页面中添加反馈、帮助和VIP服务相关页面的脚本引用 - 更新加入家谱页面为完整的申请流程界面 - 修改资讯详情页面为站点资讯展示页面 - 更新AxiosRequestUtil中认证处理逻辑 - 添加世系树渲染的HTML生成函数用于页面复用 - 更新文档中的API契约说明和页面规划
8.8 KiB
反馈与工单 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: 开放意见反馈、提交工单、我的工单和工单详情,以同一套 PC 反馈记录形成提交、列表和详情闭环。
Architecture: utils/ApiClient.js 唯一拥有 /genealogy/pc/feedback 的 GET/POST 契约;新增 UMD 模块 feedback-pages.js 负责 DTO 构造、完整 VO 规范化、列表/详情渲染和四类页面初始化。“工单”只是反馈记录的帮助中心展示名称,详情通过 URL 中由列表响应产生的 feedbackId 在我的反馈列表中精确匹配。
Tech Stack: 静态 HTML、原生 JavaScript UMD、Axios、Node node:test。
Global Constraints
- 后端
D:\WorkSpace\Java\Genealogy全程只读。 - 只调用
POST /genealogy/pc/feedback和GET /genealogy/pc/feedback。 - 请求只发送
feedbackType、feedbackContent、contactInfo;不发送feedbackTitle。 feedbackType只允许后端已确认字典值advice/bug/complaint/other;空值省略并由后端默认advice。feedbackId只能来自提交或列表响应,不提供文本输入。- 页面不展示
appUserId、handlerId、appUserPhone、原始 JSON。 - 所有提交防重复;提交成功后必须重读列表并匹配同一
feedbackId。
Task 1: ApiClient 反馈契约
Files:
- Modify:
utils/ApiClient.js - Modify:
tests/api-client-contract.test.js
Interfaces:
-
Produces:
submitFeedback(body)、myFeedback() -
Step 1: 写失败的契约测试
增加测试,使用完整请求字面量断言:
await client.submitFeedback({
feedbackType: 'bug',
feedbackContent: '页面按钮无响应',
contactInfo: '19181970173',
feedbackTitle: 'must-drop',
appUserId: 'must-drop'
});
await client.myFeedback();
assert.deepEqual(calls, [
{
method: 'POST',
url: '/genealogy/pc/feedback',
body: {
feedbackType: 'bug',
feedbackContent: '页面按钮无响应',
contactInfo: '19181970173'
}
},
{ method: 'GET', url: '/genealogy/pc/feedback' }
]);
- Step 2: 运行 RED
Run:
node --test tests/api-client-contract.test.js
Expected: FAIL,submitFeedback 或 myFeedback 不存在。
- Step 3: 最小实现
在 createClient() 返回对象中增加:
submitFeedback: function (body) {
return request('POST', '/genealogy/pc/feedback', {
body: pickDefined(body, ['feedbackType', 'feedbackContent', 'contactInfo'])
});
},
myFeedback: function () {
return request('GET', '/genealogy/pc/feedback');
}
- Step 4: 运行 GREEN
Run:
node --test tests/api-client-contract.test.js
Expected: PASS。
Task 2: 反馈 DTO、VO、列表和详情边界
Files:
- Create:
public/js/feedback-pages.js - Create:
tests/feedback-pages.test.js
Interfaces:
-
Produces:
getFeedbackId(search)buildFeedbackBody(values)validateFeedbackBody(body)normalizeFeedback(item)normalizeFeedbackList(data)findFeedbackById(data, feedbackId)buildFeedbackDetailUrl(feedbackId)renderFeedbackList(data, options)renderFeedbackDetail(item)
-
Step 1: 写失败的纯行为测试
用完整 FeedbackVo 字面量验证:
assert.deepEqual(FeedbackPages.buildFeedbackBody({
feedbackType: ' bug ',
feedbackContent: ' 页面按钮无响应 ',
contactInfo: ' 19181970173 ',
feedbackTitle: 'must-drop',
appUserId: 'must-drop'
}), {
feedbackType: 'bug',
feedbackContent: '页面按钮无响应',
contactInfo: '19181970173'
});
同时断言:
-
feedbackContent为空时报错; -
类型只允许
advice/bug/complaint/other,空值省略; -
不安全 number ID、空内容、
handleStatus非0/1/2/3、status非0/1的响应拒绝; -
数组包含一个非法元素时整批返回空数组;
-
详情只精确匹配同一字符串
feedbackId,不存在时不回退第一条; -
列表和详情转义可见文本,不出现内部用户/处理人 ID、账号手机号或原始 JSON;
-
详情 URL 使用
ticket-detail.html?feedbackId=...。 -
Step 2: 运行 RED
Run:
node --test tests/feedback-pages.test.js
Expected: FAIL,模块不存在。
- Step 3: 最小实现纯函数
normalizeFeedback() 返回且只返回:
{
feedbackId,
feedbackType,
feedbackContent,
contactInfo,
handleStatus,
handleResult,
handleTime,
status,
remark
}
状态展示固定为:
{ '0': '待处理', '1': '处理中', '2': '已处理', '3': '已关闭' }
- Step 4: 运行 GREEN
Run:
node --test tests/feedback-pages.test.js
node --check public/js/feedback-pages.js
Expected: PASS。
Task 3: 四个页面的真实反馈闭环
Files:
- Modify:
profile-feedback.html - Modify:
submit-ticket.html - Modify:
my-tickets.html - Modify:
ticket-detail.html - Modify:
public/js/feedback-pages.js - Modify:
tests/feedback-pages.test.js - Modify:
tests/pending-pages.test.js - Modify:
tests/public-static-pages.test.js - Modify:
tests/pc-scope.test.js
Interfaces:
-
Produces:
initFeedbackFormPage()、initFeedbackListPage()、initFeedbackDetailPage()、init() -
Step 1: 写失败的页面行为测试
断言四个页面:
- 不再包含
data-feature-status="pending"或pending-pages.js; - 均加载
feedback-pages.js和 ApiClient 依赖; - 两个提交页只提供
feedbackType/feedbackContent/contactInfo,不存在feedbackTitle或任意业务 ID 输入; - 列表页有
data-feedback-list和刷新按钮; - 详情页只有
data-feedback-detail,不提供回复、追问、删除或关闭操作。
断言脚本提交后调用 myFeedback(),必须按提交响应的 feedbackId 重读匹配;详情按 URL feedbackId 精确匹配。
- Step 2: 运行 RED
Run:
node --test tests/feedback-pages.test.js tests/pending-pages.test.js tests/public-static-pages.test.js tests/pc-scope.test.js
Expected: FAIL,四个页面仍为 pending。
- Step 3: 实现页面初始化
提交页:
- 构造并校验请求;
writePending锁和按钮禁用;- 调用
submitFeedback(body); - 规范化提交响应;
- 重读
myFeedback(),精确找到同一feedbackId; - 个人反馈页刷新历史列表;工单页进入
ticket-detail.html?feedbackId=...。
列表页读取 myFeedback() 并生成详情链接。详情页从 URL 读取 ID、重读列表并精确匹配;未匹配显示“反馈记录不存在或无权查看”。
- Step 4: 运行 GREEN
Run:
node --test tests/feedback-pages.test.js tests/pending-pages.test.js tests/public-static-pages.test.js tests/pc-scope.test.js
node --check public/js/feedback-pages.js
Expected: PASS。
Task 4: 导航、规划和收尾验证
Files:
- Modify:
help.html - Modify:
profile-services.html - Modify:
docs/PC接口对接规划.md - Modify:
tests/stage6-navigation.test.js - Modify:
docs/superpowers/plans/2026-07-29-feedback-tickets.md
Interfaces:
-
Consumes: Task 1–3 的真实反馈闭环。
-
Step 1: 写失败的导航测试
断言:
-
帮助中心可直接进入提交工单和我的工单;
-
服务中心可进入意见反馈;
-
所有入口不再被 pending 状态拦截;
-
不存在独立 ticket API、反馈标题或手填
feedbackId的入口。 -
Step 2: 运行 RED
Run:
node --test tests/stage6-navigation.test.js tests/public-static-pages.test.js
Expected: FAIL,帮助中心尚未开放我的工单入口或旧 pending 断言仍存在。
- Step 3: 更新入口和规划
规划记录:
-
AppFeedbackBody三个字段来源与提交时机; -
FeedbackVo可见字段、内部隐藏字段和四种处理状态; -
无独立工单 path,四个页面共用反馈记录;
-
提交后重读、详情精确匹配、401/403 和隐私边界;
-
后端没有用户侧回复、追问、关闭或删除接口,继续阻断。
-
Step 4: 聚焦和全量验证
Run:
node --test tests/feedback-pages.test.js tests/api-client-contract.test.js tests/pending-pages.test.js tests/public-static-pages.test.js tests/pc-scope.test.js tests/stage6-navigation.test.js
npm test
node --check public/js/feedback-pages.js
git -c safe.directory=D:/WorkSpace/Web/jiapu diff --check
Expected: 全部 PASS。
- Step 5: 浏览器只读验证
使用真实登录态验证四个页面、我的反馈列表、无记录详情、隐私和控制台错误。未经用户本轮明确授权,不提交真实反馈。