文件
hyb-oa/issues/2026-04-08_r58-invoice-inline-print.csv
T

7.1 KiB

1IDTitleDescriptionAcceptanceTest_MethodToolsDev_StatusReview1_StatusRegression_StatusFilesDependenciesNotes
2A1R58 执行合同建档与范围冻结创建并校验 R58 报销详情页内嵌发票绑定与单据打印执行合同 CSV,冻结范围仅包含发票候选查询、报销详情读模型增强、详情页内嵌绑定/解绑/上传和打印页。issues/2026-04-08_r58-invoice-inline-print.csv 12 列完整、Dependencies 为 JSON 数组字符串、Test_Method 可复现;范围仅覆盖 A1-A6,不混入 Prisma 迁移、bind/unbind/upload 核心逻辑改写或服务端 PDF 方案。命令:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-04-08_r58-invoice-inline-print.csv。检查:1) 对照 AGENTS.md 与 issues/README.md 校验字段完整;2) A2-A6 依赖链正确;3) Notes 写明无迁移和回滚方式。manualDONEDONEDONEissues/2026-04-08_r58-invoice-inline-print.csv[]回滚路径:删除本次 CSV 不影响业务。
3A2发票可绑定查询与报销详情读模型增强新增 /api/invoice-pool/bindable 候选查询,并增强 GET /api/reimbursements/:id 返回打印页与内嵌绑定所需字段。/api/invoice-pool/bindable 按 reimbursementId 校验所有权和 draft/rejected 状态,支持 search 与 limit;GET /api/reimbursements/:id 返回 department、createdAt、submittedAt、扩展 invoices[] 与 approvalHistory[],且不改变现有 pendingWorkflow/workflowProgress 语义。命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && npx prisma validate && node --check src/routes/invoicePool/read.js && node --check src/routes/reimbursements.js && npm test -- tests/unit/routes/invoicePool.bindable.test.js。业务:1) owner/submitter 可查自己单据候选发票;2) 非 draft/rejected 报销不可查询;3) 详情返回发票扩展字段、submittedAt 与 approvalHistory 正确。manualDONEDONEDONEserver/src/routes/invoicePool/read.js|server/src/routes/reimbursements.js|server/tests/unit/routes/invoicePool.bindable.test.js["A1"]回滚路径:删除 bindable 路由与报销详情新增字段映射,恢复原详情响应。
4A3报销详情页内嵌发票绑定/解绑与快速上传改造 ReimbursementDetailPage 的关联票据区,在 draft/rejected 状态内直接完成候选查询、绑定、解绑和上传后 OCR 等待。详情页在满足权限与状态时显示添加发票入口;弹窗支持搜索候选发票、多选绑定、可选 linkedItemId;已绑定发票展示号/日期/卖方/金额/原始文件名并可解绑;上传成功后轮询到 available 自动进入候选列表。命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd client && npm run typecheck && npm run build。业务:1) draft/rejected 可打开绑定弹窗;2) 可绑定到报销单或具体明细;3) 解绑后详情刷新;4) 上传新发票后提示 OCR 中,识别成功自动出现在候选列表。manualDONEDONEDONEclient/src/pages/ReimbursementDetailPage.tsx|client/src/api/invoicePool.ts|client/src/api/reimbursements.ts["A1","A2"]回滚路径:恢复详情页只读票据展示,移除内嵌绑定弹窗与上传轮询逻辑。
5A4报销单打印视图、路由与入口新增 A4 打印页,复用报销详情数据渲染 A4 布局,并在详情页提供打印 / PDF 入口。/reimbursements/:reimbursementId/print 仅能查看报销详情的用户可访问;页面展示基本信息、明细、发票、审批记录、关联信息和二维码;工具栏仅屏幕可见,点击打印只触发 window.print;引入 qrcode.react 作为唯一新增前端依赖。命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd client && npm install qrcode.react && npm run typecheck && npm run build。业务:1) 详情页可进入打印页;2) 打印页能渲染审批记录和二维码;3) 浏览器打印预览布局符合 A4,工具栏不出现在打印稿。manualDONEDONEDONEclient/src/pages/ReimbursementPrintPage.tsx|client/src/pages/ReimbursementDetailPage.tsx|client/src/router/index.tsx|client/src/router/lazy/ReimbursementPrintPage.ts|client/src/router/lazy/index.ts|client/package.json|client/package-lock.json["A1","A2"]回滚路径:移除打印页、路由、入口和 qrcode.react 依赖。
6A5Reviewer 复核权限与数据暴露边界对发票候选查询、详情页内嵌绑定、打印视图和新增依赖做实现后 review,自检权限、敏感字段和客户端打印行为。review 覆盖 bindable 所有权/状态校验、linkedItemId 可空、上传 owner 使用 detail.ownerId 时的代理权限边界、打印页仅消费详情白名单字段、window.print 无服务端副作用以及 qrcode.react 依赖合理性。检查:1) 阅读 server/src/routes/invoicePool/read.js、server/src/routes/reimbursements.js、client/src/pages/ReimbursementDetailPage.tsx、client/src/pages/ReimbursementPrintPage.tsx;2) 确认没有新增 Prisma 迁移、没有修改 bind/unbind/upload 核心逻辑;3) 记录 review 结论并回填 CSV。manualDONEDONEDONEserver/src/routes/invoicePool/read.js|server/src/routes/reimbursements.js|client/src/pages/ReimbursementDetailPage.tsx|client/src/pages/ReimbursementPrintPage.tsx|client/package.json["A2","A3","A4"]回滚路径:若 review 发现权限或数据泄露风险,停止提交并回退对应改动。
7A6QA、回归、部署验证与提交收口执行 post-check、手工 smoke、CSV 三列状态回填并完成提交。后端语法/单测、前端 typecheck/build 全通过;手工验证详情页内绑定已有发票、上传新发票等待 OCR、打印页预览与打印动作;CSV 三列状态按实测回填;完成 git commit。命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && npx prisma validate && node --check src/routes/invoicePool.js && node --check src/routes/invoicePool/read.js && node --check src/routes/reimbursements.js && npm test -- tests/unit/routes/invoicePool.bindable.test.js && cd ../client && npm install qrcode.react && npm run typecheck && npm run build。部署后:bash deploy/trialrun/deploy.sh,并手工 smoke 详情页内绑定、上传 OCR、打印页 window.print。manualDONEDONEDONEissues/2026-04-08_r58-invoice-inline-print.csv|server/src/routes/invoicePool.js|server/src/routes/invoicePool/read.js|server/src/routes/reimbursements.js|server/tests/unit/routes/invoicePool.bindable.test.js|client/src/api/invoicePool.ts|client/src/api/reimbursements.ts|client/src/pages/ReimbursementDetailPage.tsx|client/src/pages/ReimbursementPrintPage.tsx|client/src/router/index.tsx|client/src/router/lazy/ReimbursementPrintPage.ts|client/src/router/lazy/index.ts|client/package.json|client/package-lock.json["A2","A3","A4","A5"]回滚路径:若 QA 或部署 smoke 失败,暂停提交并回退对应代码;本轮无 Prisma 迁移,无需远端 migrate status。已完成本地 post-check 与 bash deploy/trialrun/deploy.sh;live smoke 因缺少 LIVE_SMOKE_* 凭据被脚本自动跳过。