Files
qipai/docs/devlogs/2026-06-25-M08-B-保洁端.md
T
2026-06-27 15:44:32 +08:00

89 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M08-B 保洁端
## 本次工程增量
- 新增 `2026062525_m08b_cleaner_tasks` 迁移,建立 `qipai_cleaning_tasks``qipai_cleaning_task_events`,覆盖 WAITING、CLAIMED、STARTED、SUBMITTED、COMPLETED、REJECTED、EXEMPT、SETTLED、CANCELLED 状态和事件追踪。
- 权限补齐 `cleaning.task.write``cleaning.statistics.read``CLEANER`、门店管理员、租户管理员和平台管理员可获得保洁任务读写与统计能力。
- 新增 `CleaningTaskRepository``/app-api/cleaning/*` 路由:任务大厅、我的任务、接单、开始、提交验收和个人统计均要求登录态与保洁权限。
- 生产 `server.ts` 注入真实保洁仓储,迁移 runner 纳入 M08-B 数据库迁移。
- 小程序新增 `pages/cleaner/tasks`,调用真实 app-api 展示任务大厅、我的任务、待结算统计,并支持接单、开始和提交照片 URL 验收。
- `scripts/check-miniapp-m08-a.mjs` 扩展为同时检查 M08-A 顾客端与 M08-B 保洁端页面注册和真实接口调用。
## 2026-06-26 增量
- `/app-api/cleaning/tasks/:taskId/photos` 接入受控图片上传:保洁员必须登录且拥有当前任务,任务状态必须为 `STARTED``REJECTED`,上传后复用 `MediaStorage` 压缩为 WebP 并返回固定 `https://api.txyundm.cn/uploads/...` URL。
- `/app-api/cleaning/tasks/:taskId/submit` 改为必须提交至少一张照片;`REJECTED` 任务允许再次提交,提交后清空驳回原因并记录事件。
- 新增 `/app-api/cleaning/tasks/:taskId/rework`,保洁员可将本人 `REJECTED` 任务重新转为 `STARTED`,清空旧照片和驳回原因,进入补做流程。
- `OrderStateRepository` 在订单状态进入 `FINISHED` 时通过同一事务调用 `CleaningTaskRepository.createForFinishedOrder`,按 `order_id` 唯一键幂等创建 `WAITING` 保洁任务并写入 `AUTO_CREATE` 事件。
- 小程序保洁端将手工照片 URL 文本框改为相机/相册选择图片,上传成功后再提交验收;驳回任务显示原因并提供“重做”入口。
- 修复 `marketing-benefit-service.test.mjs` 中固定订单时间导致 2026-06-26 后自然过期的问题,改为相对未来时间,避免测试随日期漂移失效。
## 2026-06-26 继续增量
- 新增管理侧保洁任务查询 `/admin-api/cleaning/tasks`,按管理员门店范围和状态筛选任务。
- 新增管理侧指派 `/admin-api/cleaning/tasks/:taskId/assign`,指派前校验被指派用户为有效 `CLEANER` 且拥有任务门店范围。
- 新增管理侧验收 `/admin-api/cleaning/tasks/:taskId/complete`,将 `SUBMITTED` 任务转为 `COMPLETED` 并记录事件。
- 新增管理侧驳回 `/admin-api/cleaning/tasks/:taskId/reject`,写入驳回原因并允许保洁端进入补做链路。
- 新增 `/admin-api/cleaning/settlement-candidates`,返回 `COMPLETED` 且未结算的任务,作为后续结算单生成前置。
## 2026-06-26 结算增量
- 新增 `2026062626_m08b_cleaning_settlements` 迁移,建立保洁结算单主表和明细表,任务明细唯一进入一个结算单。
- 新增 `cleaning.settlement.read``cleaning.settlement.write` 权限,保洁员可读本人结算相关能力,门店/租户/平台管理员可生成和确认结算。
- 新增 `GET /admin-api/cleaning/settlements``POST /admin-api/cleaning/settlements``POST /admin-api/cleaning/settlements/:id/confirm`,支持从已完成未结算任务生成 `DRAFT` 结算单并确认到 `CONFIRMED`
- 结算生成会锁定当前候选任务,写入结算明细,固化任务奖励金额,并把任务转为 `SETTLED`,避免同一任务重复结算。
- 新增 `POST /admin-api/cleaning/reclaim-timeouts`,可按分钟阈值和数量限制回收超时停留在 `CLAIMED`/`STARTED` 的任务,恢复到任务大厅。
## 2026-06-26 多人协作增量
- 新增 `2026062627_m08b_cleaning_collaboration` 迁移,建立 `qipai_cleaning_task_members`,支持 `LEAD` 负责人和 `ASSIST` 协作者、成员分账金额、移除和成员维度结算时间。
- 调整 `qipai_cleaning_settlement_items`,新增 `cleaner_user_id`,唯一键从“任务唯一”升级为“任务 + 保洁员唯一”,允许同一协作任务按成员分别进入不同保洁员结算单。
- `CleaningTaskRepository` 在接单、指派和验收时自动维护负责人成员;重新指派会撤掉旧未结算负责人,避免同一任务出现多个有效 `LEAD`
- 新增管理侧成员接口:查看成员、添加/更新协作者、移除未结算协作者。协作者必须拥有 `CLEANER` 角色和任务门店范围,协作者分账总额不能超过任务奖励。
- `GET /app-api/cleaning/tasks/mine``GET /app-api/cleaning/stats` 扩展为负责人/协作者视角;待结算金额按成员分账金额统计。
- 结算生成改为按成员 `reward_cents` 生成明细,单个成员结算后只标记该成员 `settled_at`;所有有效成员均结清后任务才整体转为 `SETTLED`
## 2026-06-27 发放闭环增量
- 新增 `2026062728_m08b_cleaning_payouts` 迁移,为 `qipai_cleaning_settlements` 增加 `paid_by``payout_channel``payout_reference``payout_error`,记录保洁结算发放操作人、渠道、外部流水号和失败原因。
- 新增 `POST /admin-api/cleaning/settlements/:settlementId/paid`,仅允许管理员将 `CONFIRMED` 结算单标记为 `PAID`,写入发放渠道、流水号、发放人和 `paid_at`,并清空旧失败原因。
- 新增 `POST /admin-api/cleaning/settlements/:settlementId/payout-failure`,仅允许对 `CONFIRMED` 结算单记录发放失败原因,保留 `CONFIRMED` 状态,支持修复外部付款后重试。
- 结算单查询返回新增发放字段,管理端后续可以直接展示发放状态、渠道流水和失败原因。
## 验收结果
- `npm run build``backend/`):PASS。
- `node scripts/check-miniapp-m08-a.mjs`PASS。
- `node tests/cleaning-route.test.mjs`PASS。
- `node tests/migration-contract.test.mjs`PASS。
- `node tests/migration-runner.test.mjs`PASS。
- `npm test``backend/`):PASS。
- 2026-06-26 追加验证:
- `node tests/cleaning-route.test.mjs`PASS,覆盖 `rework` 和照片上传路由。
- `npm test -- --runInBand``backend/`):PASS。
- `node scripts/check-miniapp-m08-a.mjs`PASS。
- 继续增量后 `npm test -- --runInBand``backend/`):PASS,覆盖管理侧指派、验收、驳回和待结算候选路由。
- 结算增量后 `npm test -- --runInBand``backend/`):PASS,覆盖结算迁移、结算单路由和超时回收路由。
- 结算增量后 `node scripts/check-miniapp-m08-a.mjs`PASS。
- 多人协作增量后 `npm run build``backend/`):PASS。
- 多人协作增量后 `node tests/migration-contract.test.mjs`PASS。
- 多人协作增量后 `node tests/migration-runner.test.mjs`PASS。
- 多人协作增量后 `node tests/cleaning-route.test.mjs`:PASS,覆盖成员查看、添加和移除路由。
- 发放闭环增量后 `npm run build``backend/`):PASS。
- 发放闭环增量后 `node tests/migration-contract.test.mjs`PASS。
- 发放闭环增量后 `node tests/migration-runner.test.mjs`PASS。
- 发放闭环增量后 `node tests/cleaning-route.test.mjs`:PASS,覆盖结算发放成功和发放失败记录路由。
## 状态
M08-B 保持 `PARTIAL`。当前已完成保洁端任务大厅、我的任务、接单、开始、照片上传、提交验收、驳回补做、订单结束自动建任务、统计、管理员任务查询、指派、验收、驳回、超时回收、多人协作分账、待结算候选、正式结算单生成、确认、发放成功标记和发放失败记录基础工程闭环;真实微信零钱/企业付款适配器接入和后台/小程序管理界面仍待继续。M08-A 的真机合法域名、真实微信支付和实物开门验证按外部条件阻塞保留,不阻断 M08-B 工程推进。
## 提交
- 工程提交:`03496d7`
- 远端校验:待本轮 push 后执行 `HEAD == origin/main`