Files
shanxia2.0/docs/superpowers/specs/2026-10-15-mp-webview-crm-contract-design.md
T
2026-10-15 17:36:54 +08:00

226 lines
9.7 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.
# 小程序 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/*`