From 75f00a6472776008aeb4b680b85bddb2d74766dc Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Fri, 16 Oct 2026 17:38:14 +0800 Subject: [PATCH] docs: add plan for hiding collector staff UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Break down protocol/donation hide, presign rename to 市场专员, and silent collectorUserId write rules into TDD tasks. Co-authored-by: Cursor --- .../2026-10-16-hide-collector-staff-ui.md | 415 ++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 docs/superpowers/plans/2026-10-16-hide-collector-staff-ui.md diff --git a/docs/superpowers/plans/2026-10-16-hide-collector-staff-ui.md b/docs/superpowers/plans/2026-10-16-hide-collector-staff-ui.md new file mode 100644 index 00000000..52f59d02 --- /dev/null +++ b/docs/superpowers/plans/2026-10-16-hide-collector-staff-ui.md @@ -0,0 +1,415 @@ +# 隐藏「采集专员」可见 UI(预签改名)— 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:** 协议单/科研捐赠/缴费确认时间线等隐藏用户可见「采集专员」;预签全链路文案改为「市场专员」;`collectorUserId` 静默保留(新建默认当前用户,编辑不清空)。 + +**Architecture:** 纯前端展示层改动。移动协议表单对 `collectorUserId` 使用已有 `hidden: true` 模式(不渲染但仍进表单状态与 payload);Web 去掉选择器 DOM,保留 `formData.collectorUserId` 回填与提交。预签只改可见 label/title/提示语,字段名不变。后端与转正式映射不动。 + +**Tech Stack:** Vue 3 + Element Plus(web-admin);Vue 3 + Vant(mobile-oa-h5);`node:test`(mobile-oa-h5) + +**Spec:** `docs/superpowers/specs/2026-10-16-hide-collector-staff-ui-design.md` + +--- + +## File map + +| 文件 | 职责 | +|------|------| +| `mobile-oa-h5/src/market/modules/protocol.js` | 协议/捐赠详情去掉采集专员行;表单字段 `hidden: true` | +| `mobile-oa-h5/src/market/list-presenter.js` | 协议列表卡去掉采集专员字段 | +| `mobile-oa-h5/src/market/modules/presign.js` | 预签详情 label → 市场专员 | +| `mobile-oa-h5/src/market/presign/presign-list-model.js` | 预签列表/详情字段 label → 市场专员 | +| `mobile-oa-h5/src/views/market/presign/PresignOrderForm.vue` | 表单 label / 选择器 title → 市场专员 | +| `mobile-oa-h5/src/market/*.test.js` 等 | 同步断言 | +| `web-admin/.../protocol/ProtocolFormDialog.vue` | 去掉采集专员表单项;保留静默写入 | +| `web-admin/.../protocol/ProtocolViewDialog.vue` | 详情去掉采集专员 | +| `web-admin/.../protocol/index.vue` | 列表去掉采集专员列 | +| `web-admin/.../research-donation/list/*` | 捐赠表单/列表/详情同上 | +| `web-admin/.../clinical-payment-confirm-timeline/index.vue` | 去掉采集专员展示 | +| `web-admin/.../presign-order/PresignOrderFormDialog.vue` | label → 市场专员 | +| `web-admin/.../presign-order/index.vue` | 转正式确认文案改写 | + +--- + +### Task 1: mobile-oa-h5 — 协议表单/详情隐藏采集专员(TDD) + +**Files:** +- Modify: `mobile-oa-h5/src/market/module-contracts.test.js` +- Modify: `mobile-oa-h5/src/market/mobile-parity-ui.test.js`(若有「采集专员」可见断言) +- Modify: `mobile-oa-h5/src/market/modules/protocol.js` +- Modify: `mobile-oa-h5/src/market/list-presenter.test.js` + +- [ ] **Step 1: 改测试 — 表单字段 hidden;详情/列表不再含「采集专员」** + +在 `module-contracts.test.js` 把人员 optionKey 测试改为: + +```js +test('protocol personnel fields use isolated hydrated option collections', () => { + const fields = getMarketModule('protocol').formSections.flatMap((section) => section.fields) + const collector = fields.find((field) => field.key === 'collectorUserId') + assert.equal(collector.optionKey, 'collectorStaff') + assert.equal(collector.hidden, true) + assert.equal(fields.find((field) => field.key === 'salesUserId').optionKey, 'salesStaff') + assert.equal(fields.find((field) => field.key === 'regionManagerUserId').optionKey, 'managerStaff') +}) +``` + +在 `list-presenter.test.js`:删除或改写 `field.label === '采集专员'` 的断言(列表卡不应再有该 label)。 + +在 `module-contracts.test.js` / 详情相关测试:若断言详情含「采集专员」,改为 assert 找不到该 label。 + +- [ ] **Step 2: 跑测试确认失败** + +```bash +cd mobile-oa-h5 && node --test \ + src/market/module-contracts.test.js \ + src/market/list-presenter.test.js +``` + +Expected: FAIL(`hidden` 未定义或仍存在「采集专员」字段) + +- [ ] **Step 3: 实现 — protocol 模块** + +`modules/protocol.js`: + +1. 详情 `fields` 中删除: + `{ label: '采集专员', value: person(...) }` +2. 表单改为: + `{ key: 'collectorUserId', label: '采集专员', type: 'select', optionKey: 'collectorStaff', hidden: true }` + +`list-presenter.js`:删除 +`field('采集专员', personName(...))` 这一行。 + +**勿改** `protocol-form-defaults.js` 的默认当前用户逻辑。 + +- [ ] **Step 4: 再跑测试** + +```bash +cd mobile-oa-h5 && node --test \ + src/market/module-contracts.test.js \ + src/market/list-presenter.test.js \ + src/market/protocol-form-defaults.test.js +``` + +Expected: PASS(含新建默认 `collectorUserId` 仍为当前用户) + +- [ ] **Step 5: Commit** + +```bash +git add mobile-oa-h5/src/market/modules/protocol.js \ + mobile-oa-h5/src/market/list-presenter.js \ + mobile-oa-h5/src/market/module-contracts.test.js \ + mobile-oa-h5/src/market/list-presenter.test.js \ + mobile-oa-h5/src/market/mobile-parity-ui.test.js +git commit -m "$(cat <<'EOF' +fix(mobile-oa-h5): hide collector staff on protocol UI + +Keep collectorUserId in form state as a hidden field with create defaults. +EOF +)" +``` + +--- + +### Task 2: mobile-oa-h5 — 预签文案改为「市场专员」(TDD) + +**Files:** +- Modify: `mobile-oa-h5/src/market/presign/presign-list-model.test.js` +- Modify: `mobile-oa-h5/src/market/module-contracts.test.js`(若有预签「采集专员」断言) +- Modify: `mobile-oa-h5/src/market/presign/presign-list-model.js` +- Modify: `mobile-oa-h5/src/market/modules/presign.js` +- Modify: `mobile-oa-h5/src/views/market/presign/PresignOrderForm.vue` +- Modify: `mobile-oa-h5/src/market/mobile-parity-ui.test.js`(预签相关文案) + +- [ ] **Step 1: 改测试期望 label 为「市场专员」** + +`presign-list-model.test.js` 示例: + +```js +{ key: 'collectorUserName', label: '市场专员', value: '采集员甲' }, +``` + +`module-contracts.test.js` 中预签详情若有: +`field.label === '采集专员'` → `'市场专员'`。 + +- [ ] **Step 2: 跑测确认失败** + +```bash +cd mobile-oa-h5 && node --test \ + src/market/presign/presign-list-model.test.js \ + src/market/module-contracts.test.js +``` + +Expected: FAIL(实际仍是「采集专员」) + +- [ ] **Step 3: 实现改名** + +1. `presign-list-model.js`:`label: '采集专员'` → `label: '市场专员'` +2. `modules/presign.js`:详情 `{ label: '采集专员', ...}` → `{ label: '市场专员', ...}` +3. `PresignOrderForm.vue`: + - `` → `` + - `title="选择采集专员"` → `title="选择市场专员"` +4. **不要**把 `form.collectorUserId` / `v-model` 改成 `salesUserId` + +- [ ] **Step 4: 再跑测试** + +```bash +cd mobile-oa-h5 && node --test \ + src/market/presign/presign-list-model.test.js \ + src/market/module-contracts.test.js \ + src/market/presign/presign-form-view.test.js \ + src/market/mobile-parity-ui.test.js +``` + +Expected: PASS + +- [ ] **Step 5: Commit** + +```bash +git add mobile-oa-h5/src/market/presign \ + mobile-oa-h5/src/market/modules/presign.js \ + mobile-oa-h5/src/views/market/presign/PresignOrderForm.vue \ + mobile-oa-h5/src/market/module-contracts.test.js \ + mobile-oa-h5/src/market/mobile-parity-ui.test.js +git commit -m "$(cat <<'EOF' +fix(mobile-oa-h5): rename presign collector label to 市场专员 + +Keep collectorUserId for convert-to-protocol mapping. +EOF +)" +``` + +--- + +### Task 3: web-admin — 采集协议单隐藏采集专员 + +**Files:** +- Modify: `web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue` +- Modify: `web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue` +- Modify: `web-admin/src/views/cell-storage/protocol/index.vue` + +- [ ] **Step 1: 表单 — 删除「采集专员」`el-form-item` 模板块** + +在 `ProtocolFormDialog.vue` 删除约: + +```vue + + ... + +``` + +**必须保留:** + +- `formData.collectorUserId` +- 新建时 `collectorUserId.value = uid` / `formData.collectorUserId = uid` +- 编辑回填 `formData.collectorUserId = String(prot.collectorUserId || ...)` +- 提交 `collectorUserId: formData.collectorUserId || ''`(编辑路径依赖已回填的非空值) + +可删除仅服务于该选择器的 `remoteSearchCollectorUsers` / `onCollectorUserChange` 及模板用的 `collectorUserId` ref(若删除 ref,确保提交只读 `formData.collectorUserId`)。若一时不好拆,允许保留死代码,但模板不得再渲染选择器。 + +- [ ] **Step 2: 列表 — 删除采集专员列** + +`protocol/index.vue` 删除: + +```vue + +``` + +- [ ] **Step 3: 详情 — 删除采集专员 data-item** + +`ProtocolViewDialog.vue` 删除: + +```vue +
采集专员
{{ collectorDisplay }}
+``` + +`collectorDisplay` computed 若无其它引用可删;仅被该处使用则一并清理。 + +- [ ] **Step 4: 手工检查清单(本任务)** + +- 新增协议:Network 请求体含非空 `collectorUserId`(当前用户) +- 编辑已有协议:保存后 `collectorUserId` 与打开前一致(不为空串清空) + +- [ ] **Step 5: Commit** + +```bash +git add web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue \ + web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue \ + web-admin/src/views/cell-storage/protocol/index.vue +git commit -m "$(cat <<'EOF' +fix(web-admin): hide collector staff on collection protocol UI + +Retain silent collectorUserId defaults and edit hydration. +EOF +)" +``` + +--- + +### Task 4: web-admin — 科研捐赠隐藏采集专员 + +**Files:** +- Modify: `web-admin/src/views/research-donation/list/DonationFormDialog.vue` +- Modify: `web-admin/src/views/research-donation/list/DonationViewDialog.vue` +- Modify: `web-admin/src/views/research-donation/list/index.vue` + +- [ ] **Step 1: 与 Task 3 同模式** + +- 表单:去掉「采集专员」`el-form-item`;保留 `formData.collectorUserId` 默认当前用户与编辑回填;提交继续带该字段(`DonationFormDialog` 现为 `collectorUserId: formData.collectorUserId || undefined` — 编辑时必须已回填,避免 `undefined` 漏传导致后端未更新;新建靠默认 uid) +- 列表:删 `label="采集专员"` 列 +- 详情:删「采集专员」data-item + +- [ ] **Step 2: Commit** + +```bash +git add web-admin/src/views/research-donation/list/ +git commit -m "$(cat <<'EOF' +fix(web-admin): hide collector staff on research donation UI +EOF +)" +``` + +--- + +### Task 5: web-admin — 缴费确认时间线 + 全仓可见文案扫尾 + +**Files:** +- Modify: `web-admin/src/components/business/clinical-payment-confirm-timeline/index.vue` +- 按需修改其它生产代码中用户可见「采集专员」(**排除**预签、Demo HTML、docs) + +- [ ] **Step 1: 时间线去掉采集专员** + +删除: + +```vue +
采集专员
+
{{ dash(detail?.collectorUserName) }}
+``` + +- [ ] **Step 2: 扫尾 grep** + +```bash +rg '采集专员' web-admin/src mobile-oa-h5/src --glob '!**/demo*' -n +``` + +Expected 残留仅允许: + +- 预签相关文件中已改为「市场专员」后不应再有「采集专员」用户文案 +- 代码注释(可选清理) +- 若发现其它生产 UI 文案,一并隐藏 + +- [ ] **Step 3: Commit** + +```bash +git add web-admin/src/components/business/clinical-payment-confirm-timeline/index.vue +# 加上 Step 2 扫到的其它生产文件 +git commit -m "$(cat <<'EOF' +fix(web-admin): remove collector staff from payment confirm timeline +EOF +)" +``` + +--- + +### Task 6: web-admin — 预签改名为「市场专员」 + +**Files:** +- Modify: `web-admin/src/views/cell-storage/presign-order/PresignOrderFormDialog.vue` +- Modify: `web-admin/src/views/cell-storage/presign-order/index.vue` + +- [ ] **Step 1: 表单 label** + +```vue + + +``` + +placeholder 若写「请选择采集专员」一并改为「请选择市场专员」。 + +- [ ] **Step 2: 转正式确认文案** + +`index.vue` 现文案: + +```text +确认转为正式采集协议单?将带入采集专员/市场专员/地区经理;... +``` + +改为避免「采集专员」用户文案,例如: + +```text +确认转为正式采集协议单?将带入市场专员(同步为正式单采集专员与市场专员)/地区经理;意向金通过预签订单关联在正式单中展示(与预签同一数据,不自动写入样本缴费)。 +``` + +或更短: + +```text +确认转为正式采集协议单?将按预签「市场专员」与地区经理带入正式单人员;意向金通过预签订单关联在正式单中展示(与预签同一数据,不自动写入样本缴费)。 +``` + +- [ ] **Step 3: 确认列表/详情无「采集专员」列**(当前 `presign-order/index.vue` 无该列则跳过) + +- [ ] **Step 4: Commit** + +```bash +git add web-admin/src/views/cell-storage/presign-order/ +git commit -m "$(cat <<'EOF' +fix(web-admin): rename presign collector label to 市场专员 +EOF +)" +``` + +--- + +### Task 7: 验收与图谱 + +- [ ] **Step 1: 自动化** + +```bash +cd mobile-oa-h5 && node --test src/market/**/*.test.js src/market/presign/**/*.test.js +``` + +Expected: PASS(或仅与本次无关的既有失败;本改动相关文件必须绿) + +- [ ] **Step 2: 手动冒烟** + +1. Web 新增协议 / 捐赠:请求含 `collectorUserId` = 当前用户;界面无「采集专员」 +2. Web 编辑协议:保存后该字段不变 +3. Web/移动预签:界面为「市场专员」,提交仍是 `collectorUserId`;转正式人员映射与改前一致 +4. 缴费确认时间线无「采集专员」 + +- [ ] **Step 3: 更新 graphify(若改了 web-admin / 有前端结构变动)** + +```bash +./scripts/update-graph.sh frontend +``` + +- [ ] **Step 4: 最终 grep** + +```bash +rg '采集专员' web-admin/src mobile-oa-h5/src -n +``` + +用户可见生产文案应为 0(注释除外);预签应为「市场专员」。 + +--- + +## Spec coverage checklist + +| Spec 要求 | Task | +|-----------|------| +| 协议单隐藏表单/列表/详情 | 1, 3 | +| 科研捐赠隐藏 | 1(移动详情同源), 4 | +| 时间线等外围隐藏 | 5 | +| 预签改名「市场专员」、字段仍 collectorUserId | 2, 6 | +| 新建默认当前用户 | 1(不改 defaults)、3/4 保留初始化 | +| 编辑不清空 | 3/4 保留回填+提交 | +| 不改后端/转正式映射 | 全任务不碰 backend | +| 测试更新 | 1, 2, 7 |