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