Capture agreed scope for migrating quote manage/approve into mini program H5, aligned with the product webview pattern. Co-authored-by: Cursor <cursoragent@cursor.com>
15 KiB
小程序 WebView · CRM 报价单 — 设计文档
日期: 2026-10-15
状态: 待实现
方案: 复用运输计划 / CRM 产品 WebView 模板;在web-admin新增/#/m/crm/quote*;工作台开放「报价单管理」「报价单审批」
权威接入清单:docs/web-admin-mp-webview-modules.md
样式参考:/#/m/pl/plan*、/#/m/crm/product*(三墙 Token,mp-webview.scss)
前置:docs/superpowers/specs/2026-10-15-mp-webview-crm-product-design.md(CRM 根菜单与产品入口已落地)
1. 目标
在微信小程序「CRM管理」下提供与 Web 端 报价单管理、报价单审批 同等的管理闭环能力,以 WebView 加载 H5 落地:
- 业务改动优先只发
web-admin静态资源 - 不复制鉴权、不新建第二个
web-view壳页 - 移动端视觉对齐运输计划 / 产品管理 H5,不套桌面 Fresh Mint
Web 对照
| 能力 | 桌面 | 权限 |
|---|---|---|
| 报价单管理 | src/views/crm/quote/index.vue(QuoteListPage mode=manage) |
crm:quote:list |
| 报价单审批 | src/views/crm/quote/approval/index.vue(mode=approve) |
crm:quote:approve |
| 表单/详情组件 | quote/form、detail、components/* |
— |
2. 已确认决策
| # | 项 | 决策 |
|---|---|---|
| D1 | 接入方式 | 方案 1:嵌套 H5(同产品管理),不写原生 pages/crm/quote* |
| D2 | 管理能力 | 列表 / 详情 / 新增编辑 / 删除 + 提交审批 + 复制新增 + 作废 + 版本历史(只读) |
| D3 | 明确不做 | 分享、转合同、富文本「生成报价单」、PDF、导出;列头 facet / 列显隐 / 底部统计条 / 日期快捷条;批量提交 / 批量审批;工作台「审批人设置」 |
| D4 | 双入口 | 管理 /#/m/crm/quote;审批 /#/m/crm/quote/approval;管理页不做审批操作,审批页不改单 |
| D5 | 粒度 | 仅单条提交审批、单条通过/驳回 |
| D6 | 表单字段 | 全字段对齐 Web(主表 + 明细行);variant="page" 复用校验与提交;布局移动端化 |
| D7 | 提交审批 | 选审批人(多选、有序)+ 备注;可预填桌面 getQuoteApproverSetting;不挂移动端审批人设置菜单 |
| D8 | 列表 | 管理 Tab:全部 / 待审批 / 已审批;审批 Tab:待审批(默认)/ 已审批;顶部 keyword(主题 / 客户 / 单号) |
| D9 | H5 落点 | web-admin /#/m/crm/quote*,复用现有 /web/crm/quote*(及审批人设置 get) |
| D10 | 视觉 | 三墙绿 #0a9f6d / #087f57(mp-webview.scss);不用管理端 #10b981 作主色 |
| D11 | 菜单 | MINI_CRM_ROOT 下挂「报价单管理」「报价单审批」;工作台两项 + WORKBENCH_ROUTE_MAP |
| D12 | 角色绑定 | 有 Web crm:quote:list 的角色补绑管理入口;有 Web crm:quote:approve 的角色补绑审批入口;均补绑移动端根与 MINI_CRM_ROOT(幂等) |
| D13 | 双权限 | 入口 mini:crm:quote:list / mini:crm:quote:approve;业务 API 仍校验现有 Web crm:quote:* |
3. 非目标
- 不把桌面
QuoteListPage的el-table/ 多选工具栏 / 导出 / 生成报价单对话框原样塞进 WebView - 不改报价后端业务规则、租户隔离与数据权限语义
- 本期不开放 CRM 其它未约定叶子(线索/客户/合同等)
- 不新建独立
mobile-h5工程,不新增第二个mp-webview页面 - 不输出独立 HTML Demo(样式直接对齐现网
/m/pl/plan、/m/crm/product) - 不做分享链接、转合同、富文本/PDF、Excel 导出、审批人设置 H5
4. 架构
小程序工作台「CRM管理」→「报价单管理」
→ pages/common/mp-webview?path=/m/crm/quote
小程序工作台「CRM管理」→「报价单审批」
→ pages/common/mp-webview?path=/m/crm/quote/approval
1) POST /api/web/auth/mp-webview-ticket (小程序 Bearer)
2) web-view src = {WEB_ORIGIN}/?mpTicket=…#/m/crm/quote…?mpTicket=…
3) H5:MpWebviewShell → POST /api/web/auth/mp-webview-exchange
4) 之后与桌面同账号调用现有 CRM 报价 API
┌─────────────┐ ticket ┌────────────────────────┐ JWT ┌────────────┐
│ miniprogram│ ──────────────► │ web-admin /#/m/crm/… │ ───────────► │ FastAPI │
│ mp-webview │ ◄────────────── │ MpWebviewShell │ ◄─────────── │ 既有报价 │
└─────────────┘ 401→reLaunch └────────────────────────┘ 租户/权限 └────────────┘
边界
| 单元 | 职责 | 依赖 |
|---|---|---|
pages/common/mp-webview |
取票、拼 URL、承载 <web-view>(已有,不改协议) |
小程序 token、WEB_ORIGIN |
MpWebviewShell |
无侧栏、安全区、401 桥接(已有) | 换票、wx.miniProgram |
/#/m/crm/quote* |
报价移动端 UI | 现有 api/crm/quote、审批人设置 get |
| 工作台 | 入口可见性与跳转 | workbench-menus.js + WORKBENCH_ROUTE_MAP + menu-codes |
| 菜单 SQL | 两个叶子 + 按 Web 权角色补绑 | sys_menu / sys_role_menu;复用已有 MINI_CRM_ROOT |
5. H5 路由与页面
5.1 静态路由
在 web-admin/src/router/routes/staticRoutes.ts(catch-all 之前)增加,且:
meta: { isHideTab: true, isMpWebview: true }
| 路径 | 文件(建议) | 用途 |
|---|---|---|
/m/crm/quote |
views/m/crm/quote/index.vue |
管理列表(mode=manage) |
/m/crm/quote/approval |
views/m/crm/quote/approval.vue |
审批列表(mode=approve;可复用列表组件) |
/m/crm/quote/new |
views/m/crm/quote/form.vue |
新增;复制新增可用 ?copyFrom=<id> |
/m/crm/quote/:id |
views/m/crm/quote/detail.vue |
详情(管理/审批共用;按入口与权限显隐底栏) |
/m/crm/quote/:id/edit |
views/m/crm/quote/form.vue |
编辑 |
/m/crm/quote/:id/versions |
views/m/crm/quote/versions.vue |
版本历史(只读) |
路由顺序注意:/approval、/new 须写在 /:id 之前。
列表与审批列表宜抽共享组件(如 MpQuoteList.vue),用 mode 区分 Tab 默认值、Speed Dial、跳转 query(如 ?from=approval)以便详情底栏判定入口。
5.2 管理列表 /m/crm/quote
- Header:返回工作台 + 标题「报价单管理」+ 搜索框(
keyword:报价主题 / 客户名称 / 单号,与现有 list API 一致) - Tab:全部 / 待审批 / 已审批(映射桌面
all/submitted/accepted;「全部」仍带桌面同款excludeStatus=invalid等查询语义) - 卡片流:报价单号、主题、客户、报价类型 Tag、金额、状态 Tag、报价日期;点击进详情
- Speed Dial:主「新增报价单」→
/m/crm/quote/new - 不做:多选、导出、facet、列显隐、底部统计条、日期快捷条
5.3 审批列表 /m/crm/quote/approval
- Header:返回工作台 + 标题「报价单审批」+ 同上搜索
- Tab:待审批(默认)/ 已审批
- 卡片:同管理列表字段;无新增 Speed Dial
- 点击进同一详情路由;通过 query 或 session 标记来自审批入口
5.4 详情 /m/crm/quote/:id
- 全字段只读(主表 + 产品明细 + 审批流);布局对齐产品详情(
mp-wv-section/ kv) - 状态可编辑性、再编辑确认文案复用
quoteStatus.ts(isQuoteEditableStatus/getQuoteReeditConfirmMessage)
管理入口底栏(对齐桌面管理语义,且不含 D3 排除项):
| 状态 / 条件 | 可用操作 |
|---|---|
| 草稿 | 提交审批、编辑、删除(若桌面有创建人等规则则同规则)、作废、复制新增、版本历史 |
可编辑非草稿(submitted / accepted / rejected 等,见 QUOTE_EDITABLE_STATUSES) |
编辑(含确认)、作废、复制新增、版本历史 |
| 已作废 | 复制新增、版本历史 |
| 任意(管理) | 不出现:生成报价单、分享、转合同、审批通过/驳回 |
审批入口底栏:
| 条件 | 可用操作 |
|---|---|
| 待我审批 | 通过 / 驳回(驳回必填意见,对齐桌面) |
| 其它 | 返回;可只读查看审批流 |
| 任意(审批) | 不出现:编辑、提交审批、删除、作废、复制新增 |
提交审批:Bottom Sheet — 审批人多选有序 + 备注;预填 getQuoteApproverSetting;调用 submitQuote(单条)。
5.5 表单 /new、/:id/edit
- 挂载桌面
QuoteFormDialog/QuoteFormPanel的variant="page"(或等价全屏复用) - 主表与明细行可写字段与 Web 全对齐;视觉须移动端化,禁止桌面多列栅格原样塞手机
- 复制新增:与桌面
openCopy同源(详情预填后addQuote) - 编辑保存后回草稿等业务规则不变
5.6 版本历史 /:id/versions
- 只读列表,调用
queryVersions - 本期只读;不在该页发起编辑或生成新版本商务动作(若桌面「新版本」与复制新增不同,移动端以复制新增满足「再开一单」,版本页仅历史查阅)
6. 小程序工作台
6.1 workbench-menus.js
- CRM 模块:
visible: true(已有) - 保留「产品管理」;新增:
| name | enabled | code | perms |
|---|---|---|---|
| 报价单管理 | true |
crm-quote-webview |
mini:crm:quote:list |
| 报价单审批 | true |
crm-quote-approval-webview |
mini:crm:quote:approve |
- 模块
desc可更新为含「报价」的简述 - 其它未约定 CRM 叶子本期仍不开放
6.2 config/api.js · WORKBENCH_ROUTE_MAP
'crm-quote-webview' → PAGE_PATHS.mpWebview + '?path=' + encodeURIComponent('/m/crm/quote')
'crm-quote-approval-webview' → PAGE_PATHS.mpWebview + '?path=' + encodeURIComponent('/m/crm/quote/approval')
禁止为报价再建第二个 web-view 页。
7. 菜单与权限(SQL)
7.1 菜单树
挂在「移动端」根 id = '1';复用已有 MINI_CRM_ROOT:
移动端 (1)
└─ CRM管理 (MINI_CRM_ROOT)
├─ 产品管理 (MINI_CRM_PRODUCT) mini:crm:product:list (已有)
├─ 报价单管理 (MINI_CRM_QUOTE) mini:crm:quote:list
└─ 报价单审批 (MINI_CRM_QUOTE_APPROVAL) mini:crm:quote:approve
| id | menu_name | parent_id | perms |
|---|---|---|---|
MINI_CRM_QUOTE |
报价单管理 | MINI_CRM_ROOT |
mini:crm:quote:list |
MINI_CRM_QUOTE_APPROVAL |
报价单审批 | MINI_CRM_ROOT |
mini:crm:quote:approve |
脚本路径建议:docs/sql/migrations/2026-10-15-mini-crm-quote-webview-menus.sql(INSERT … WHERE NOT EXISTS 幂等)。
MINI_CRM_ROOT 若不存在则一并插入(与产品脚本同构,防测试库未跑产品迁移)。
7.2 角色自动补绑
Web 源菜单
| Web menu id | perms | 补绑移动端 |
|---|---|---|
CRM3000000000000000000000000010 |
crm:quote:list |
1、MINI_CRM_ROOT、MINI_CRM_QUOTE |
CRM3000000000000000000000000016 |
crm:quote:approve |
1、MINI_CRM_ROOT、MINI_CRM_QUOTE_APPROVAL |
全部 NOT EXISTS 防重。超管 menu-codes 为 all: true 不依赖补绑也能见入口,仍须写入菜单定义。
7.3 双权限说明
| 层 | 校验 |
|---|---|
| 工作台显示「报价单管理」 | mini:crm:quote:list ∈ menu-codes |
| 工作台显示「报价单审批」 | mini:crm:quote:approve ∈ menu-codes |
| 管理侧 list/CRUD/提交/作废/版本/复制 | 现有 Web crm:quote:*(与桌面同) |
| 审批通过/驳回 | 现有 Web crm:quote:approve 及接口侧规则 |
仅有移动入口、无 Web 权 → H5 内接口失败 / 「无权限」。
仅有 Web 权、未跑补绑 SQL → 工作台看不到入口。
8. 数据流与 API
不新建业务 API。 复用 @/api/crm/quote(及审批人设置 get):
| 能力 | 既有能力 |
|---|---|
| 列表 | listQuote(Tab → status / excludeStatus;keyword) |
| 详情 | getQuote + 明细 / 审批流(与桌面详情一致) |
| 增改 | addQuote / updateQuote(含产品明细) |
| 删除 | delQuote |
| 复制新增 | 与桌面 openCopy 同源(预填后 addQuote) |
| 提交审批 | getQuoteApproverSetting 预填 + submitQuote(单条) |
| 作废 | invalidQuote |
| 版本历史 | queryVersions |
| 审批 | listApproval + approveQuote(单条) |
本期不调用:generatePdf / saveTemplate / getTemplate、generateShare、toContract、exportQuote、统计与分享日志 API、saveQuoteApproverSetting。
租户隔离、数据权限、默认排序与桌面同账号一致。
9. 错误处理与发版
| 场景 | 行为 |
|---|---|
无对应 mini:crm:quote:* |
工作台不显示该入口 |
| H5 业务 403/无权限 | 页内「无权限」 |
| 401 | 通知小程序回登录 / 工作台,不进 /#/auth/login |
| ticket 二次 exchange | 失败提示从工作台重进 |
发版
- H5 UI/业务:发
web-admin即可(业务域名已配时) - 工作台两项 / route map:需发带变更的 小程序 包
- 菜单与角色:在目标库执行迁移 SQL(含测试库)
10. 测试要点
- ticket 换票后管理/审批列表与桌面同账号一致(同租户;Tab 与 keyword 语义对齐)
- 管理:新增草稿 → 提交审批(选手 + 备注,可预填默认人)→ 详情可见审批流
- 审批:待审详情单条通过 / 驳回;管理页无审批按钮;审批页无编辑 / 作废 / 提交
- 复制新增、作废、版本历史只读;编辑再保存触发与桌面一致的回草稿确认
- 全字段表单(含明细行)保存与回显
- 401 回小程序,不到桌面登录页
- 有对应 Web 权且跑过 SQL 的角色可见对应入口;未补绑则无入口
- 移动端 不出现:分享、转合同、生成报价单/PDF、导出、批量、审批人设置
- 桌面
/#/crm/quote*默认行为不受影响(仅表单组件增加可选variant,默认仍为 dialog)
11. 实现清单(供后续 plan 拆任务)
views/m/crm/quote/*+ 共享列表组件 +MpWebviewShell+mp-webview.scss- 桌面报价表单增加
variant="page"(默认dialog不变) staticRoutes.ts注册/m/crm/quote*- 列表/查询纯函数 + 单测(对齐产品
mp-crm-product-card模式) workbench-menus.js+WORKBENCH_ROUTE_MAP两项- SQL:
MINI_CRM_QUOTE+MINI_CRM_QUOTE_APPROVAL+ 按 Web 报价菜单角色补绑 - 更新
docs/web-admin-mp-webview-modules.md报价对照行 - 回归:对照 §10;对照接入清单五步
12. 参考
docs/web-admin-mp-webview-modules.mddocs/superpowers/specs/2026-10-15-mp-webview-crm-product-design.mddocs/superpowers/specs/2026-09-14-mp-webview-transport-plan-design.md- Web 管理:
web-admin/src/views/crm/quote/index.vue、approval/index.vue、QuoteListPage.vue - Web 表单/详情:
components/QuoteFormPanel.vue、QuoteFormDialog.vue、QuoteDetailDialog.vue - 状态工具:
web-admin/src/views/crm/quote/quoteStatus.ts - API:
web-admin/src/api/crm/quote/ - 产品 H5:
web-admin/src/views/m/crm/product/* - 运输计划 H5:
web-admin/src/views/m/pl/plan/*