ソースを参照

docs: add mp-webview CRM contract design spec.

Capture agreed scope for migrating contract manage/approve into mini program H5 (no price letter this round).

Co-authored-by: Cursor <cursoragent@cursor.com>
wuzilong 2 週間 前
親
コミット
b8e919cc5e

+ 225 - 0
docs/superpowers/specs/2026-10-15-mp-webview-crm-contract-design.md

@@ -0,0 +1,225 @@
+# 小程序 WebView · CRM 合同 — 设计文档
+
+> **日期**: 2026-10-15  
+> **状态**: 待实现  
+> **方案**: 复用运输计划 / CRM 产品·报价 WebView 模板;在 `web-admin` 新增 `/#/m/crm/contract*`;工作台开放「合同管理」「合同审批」  
+> **权威接入清单**: `docs/web-admin-mp-webview-modules.md`  
+> **样式参考**: `/#/m/pl/plan*`、`/#/m/crm/product*`、`/#/m/crm/quote*`(三墙 Token,`mp-webview.scss`)  
+> **前置**: 报价 WebView 已落地;`MINI_CRM_ROOT` 已存在
+
+## 1. 目标
+
+在微信小程序「CRM管理」下提供与 Web 端 **合同管理**、**合同审批** 同等的管理闭环能力,以 **WebView 加载 H5** 落地:
+
+- 业务改动优先只发 `web-admin` 静态资源
+- 不复制鉴权、不新建第二个 `web-view` 壳页
+- 移动端视觉对齐运输计划 / 产品 / 报价 H5,不套桌面 Fresh Mint
+
+**Web 对照**
+
+| 能力 | 桌面 | 权限 |
+|------|------|------|
+| 合同管理 | `src/views/crm/contract/index.vue`(`ContractListPage mode=manage`) | `crm:contract:list` |
+| 合同审批 | `src/views/crm/contract/approval/index.vue`(`mode=approve`) | `crm:contract:approve` |
+| 表单/详情 | `components/ContractFormDialog`、`ContractDetailDialog` 等 | — |
+
+**本期不做调价函**(`crm/price-letter`)。
+
+## 2. 已确认决策
+
+| # | 项 | 决策 |
+|---|-----|------|
+| D1 | 接入方式 | **方案 1:嵌套 H5**,不写原生 `pages/crm/contract*` |
+| D2 | 管理能力 | 列表 / 详情 / 新增编辑 / 删除 + **提交审批** + **合同复制** + **作废** + **作废恢复** + **上传扫描件** |
+| D3 | 明确不做 | 调价函;执行管理;续签;打印;导出 PDF / Excel;列 facet / 列显隐 / 日期快捷 / 统计条;工作台「合同审批人设置」 |
+| D4 | 双入口 | 管理 `/#/m/crm/contract`;审批 `/#/m/crm/contract/approval`;管理页不做审批操作,审批页不改单 |
+| D5 | 粒度 | **支持单条与批量**提交审批、通过/驳回 |
+| D6 | 表单字段 | **全字段对齐 Web**;`variant="page"` 复用校验与提交;布局移动端化 |
+| D7 | 提交审批 | 选审批人(多选、有序)+ 备注;可预填桌面 `getContractApproverSetting`;不挂移动端审批人设置菜单 |
+| D8 | 列表 | 管理 Tab:全部 / 待审批 / 已审批;审批 Tab:待审批(默认)/ 已审批;顶部 `keyword` |
+| D9 | H5 落点 | `web-admin` `/#/m/crm/contract*`,复用现有合同 API |
+| D10 | 视觉 | 三墙绿 `#0a9f6d` / `#087f57`(`mp-webview.scss`) |
+| D11 | 菜单 | `MINI_CRM_ROOT` 下挂「合同管理」「合同审批」;工作台两项 + `WORKBENCH_ROUTE_MAP` |
+| D12 | 角色绑定 | 有 Web `crm:contract:list` → 补绑管理入口;有 `crm:contract:approve` → 补绑审批入口;均补绑移动端根与 `MINI_CRM_ROOT` |
+| D13 | 双权限 | 入口 `mini:crm:contract:list` / `mini:crm:contract:approve`;业务 API 仍校验 Web `crm:contract:*` |
+
+## 3. 非目标
+
+- 不做调价函管理及相关 API / 菜单
+- 不把桌面 `ContractListPage` 的导出 / 打印 / 执行 / 续签原样塞进 WebView
+- 不改合同后端业务规则、租户隔离与数据权限语义
+- 不新建独立 `mobile-h5`、不新增第二个 `mp-webview`、不输出独立 HTML Demo
+
+## 4. 架构
+
+```text
+工作台「合同管理」→ pages/common/mp-webview?path=/m/crm/contract
+工作台「合同审批」→ pages/common/mp-webview?path=/m/crm/contract/approval
+       1) POST /api/web/auth/mp-webview-ticket
+       2) web-view src = {WEB_ORIGIN}/?mpTicket=…#/m/crm/contract…?mpTicket=…
+       3) H5:MpWebviewShell → POST /api/web/auth/mp-webview-exchange
+       4) 之后与桌面同账号调用现有 CRM 合同 API
+```
+
+| 单元 | 职责 |
+|------|------|
+| `pages/common/mp-webview` | 已有壳,不改协议 |
+| `MpWebviewShell` | 已有 |
+| `/#/m/crm/contract*` | 新建移动端 UI |
+| 工作台 + SQL | 两叶子 + 角色补绑 |
+
+## 5. H5 路由与页面
+
+### 5.1 静态路由
+
+在 `staticRoutes.ts` catch-all 之前,`meta: { isHideTab: true, isMpWebview: true }`:
+
+| 路径 | 文件(建议) | 用途 |
+|------|--------------|------|
+| `/m/crm/contract` | `views/m/crm/contract/index.vue` | 管理列表 |
+| `/m/crm/contract/approval` | `views/m/crm/contract/approval.vue` | 审批列表 |
+| `/m/crm/contract/new` | `form.vue` | 新增;复制 `?copyFrom=` |
+| `/m/crm/contract/:id/edit` | `form.vue` | 编辑 |
+| `/m/crm/contract/:id` | `detail.vue` | 详情 |
+
+顺序:`/approval`、`/new`、`/:id/edit` 须在 `/:id` 之前。
+
+列表宜抽共享组件 `MpContractList.vue`(`mode=manage|approve`)。
+
+### 5.2 查询语义
+
+| mode | view | 请求要点 |
+|------|------|----------|
+| manage | `all` | `excludeStatus=invalid` |
+| manage | `approving`(UI「待审批」) | `status=approving`;不传 pending/approved 用户过滤 |
+| manage | `approved`(UI「已审批」) | `status=approved`;不传 approvedByUserId |
+| approve | `submitted`(待审批) | `pendingApprovalUserId=当前用户`(与桌面审批 Tab 一致) |
+| approve | `approved`(已审批) | `approvedByUserId=当前用户` |
+
+分页字段对齐 `ContractQuery`(实现时打开 types 核对 `pageNum`/`page`)。
+
+### 5.3 管理列表
+
+- Header:回工作台 +「合同管理」+ keyword(主题/客户/单号,与 list API 一致)
+- Tab + 卡片流;**多选**;Speed Dial「新增合同」
+- 批量栏:提交审批(仅草稿)、作废等(按桌面可操作集合过滤,跳过提示)
+- 不做:导出、打印、facet、日期快捷、执行/续签
+
+### 5.4 审批列表
+
+- 标题「合同审批」;Tab 待审批(默认)/ 已审批
+- 多选 + 批量通过/驳回;无新增 Speed Dial
+
+### 5.5 详情
+
+- 只读全字段(主表 + 明细 + 审批流 + 扫描件展示)
+- **管理底栏**:按状态 — 提交审批 / 编辑 / 删除(`canDeleteByCreator`)/ 作废 / 作废恢复 / 复制 / 上传扫描件;**不出现**执行、续签、打印、审批通过驳回
+- **审批底栏**:待我审 → 通过 / 驳回;**不出现**改单类按钮
+- 提交 Sheet:审批人多选有序 + 备注;预填默认审批人
+
+### 5.6 表单
+
+- `ContractFormDialog`(或 Panel)`variant="page"`,全字段;单列/卡片化;禁止桌面多列原样塞手机
+
+### 5.7 批量
+
+- 列表选择模式;底栏「已选 N」+ 主操作
+- 批量提交:共用一组审批人+备注;仅草稿;跳过非草稿并提示
+- 批量审批:仅当前用户 pending 节点;驳回意见必填;跳过无权/非待审并提示
+
+## 6. 小程序工作台
+
+### 6.1 `workbench-menus.js`
+
+| name | code | perms |
+|------|------|-------|
+| 合同管理 | `crm-contract-webview` | `mini:crm:contract:list` |
+| 合同审批 | `crm-contract-approval-webview` | `mini:crm:contract:approve` |
+
+不挂调价函。模块 `desc` 可含「合同」。
+
+### 6.2 `WORKBENCH_ROUTE_MAP`
+
+```text
+'crm-contract-webview' → mp-webview?path=/m/crm/contract
+'crm-contract-approval-webview' → mp-webview?path=/m/crm/contract/approval
+```
+
+## 7. 菜单与权限(SQL)
+
+### 7.1 菜单树
+
+```text
+MINI_CRM_ROOT
+├─ …产品 / 报价…
+├─ MINI_CRM_CONTRACT            mini:crm:contract:list
+└─ MINI_CRM_CONTRACT_APPROVAL   mini:crm:contract:approve
+```
+
+脚本:`docs/sql/migrations/2026-10-15-mini-crm-contract-webview-menus.sql`(幂等;`MINI_CRM_ROOT` 不存在则插入)。
+
+### 7.2 角色补绑
+
+| Web menu id | perms | 补绑 |
+|-------------|-------|------|
+| `CRM3000000000000000000000000020` | `crm:contract:list` | `1`、`MINI_CRM_ROOT`、`MINI_CRM_CONTRACT` |
+| `CRM3000000000000000000000000021` | `crm:contract:approve` | `1`、`MINI_CRM_ROOT`、`MINI_CRM_CONTRACT_APPROVAL` |
+
+### 7.3 双权限
+
+入口看 `mini:crm:contract:*`;H5 内业务看 Web `crm:contract:*`。
+
+## 8. 数据流与 API
+
+**不新建业务 API。** 复用:
+
+| 能力 | API |
+|------|-----|
+| 列表 | `listContract` |
+| 详情 | `getContract` + `listContractApproval` |
+| 增改删 | `addContract` / `updateContract` / `delContract` |
+| 复制 | 预填后 `addContract` |
+| 提交 | `submitApproval` / `batchSubmitApproval` + `getContractApproverSetting` |
+| 审批 | `approvePass` / `approveReject`(或桌面同源封装;批量逐条) |
+| 作废/恢复 | `invalidContract` / `restoreContract` |
+| 扫描件 | `uploadFile` / `uploadAttachments` |
+
+**不调用**:`exportContract`、模板/打印、`startExecute`/`finishContract`/`renewContract`、统计、`saveContractApproverSetting`、调价函 API。
+
+## 9. 错误处理与发版
+
+| 场景 | 行为 |
+|------|------|
+| 无对应 `mini:crm:contract:*` | 工作台不显示该入口 |
+| H5 403 | 页内「无权限」 |
+| 401 | 回小程序,不进 `/#/auth/login` |
+| ticket 二次 exchange 失败 | 提示从工作台重进 |
+
+发版:H5→web-admin;工作台→小程序包;菜单→目标库执行 SQL。
+
+## 10. 测试要点
+
+- 换票后管理/审批列表与桌面同账号一致
+- Tab、keyword、多选批量提交/审批;跳过提示正确
+- 详情单条:提交、复制、作废/恢复、上传扫描件;管理无审批、审批无改单
+- 全字段表单保存回显
+- 无打印/PDF/导出/执行/续签/调价函入口
+- 桌面 `/#/crm/contract*` 默认行为不变
+
+## 11. 实现清单(供 plan 拆任务)
+
+1. 列表查询纯函数 + 单测  
+2. 菜单 SQL + 角色补绑  
+3. 静态路由 + 路径常量 + 空壳  
+4. 共享列表(含多选批量)  
+5. 详情 + 提交/审批 Sheet + 作废/恢复/上传  
+6. 表单 `variant="page"` + form 壳  
+7. 工作台两项 + route map  
+8. 更新 `docs/web-admin-mp-webview-modules.md` + 回归  
+
+## 12. 参考
+
+- `docs/superpowers/specs/2026-10-15-mp-webview-crm-quote-design.md`
+- `docs/web-admin-mp-webview-modules.md`
+- Web:`web-admin/src/views/crm/contract/*`、`src/api/crm/contract/*`
+- 报价 H5:`web-admin/src/views/m/crm/quote/*`