Files
shanxia2.0/docs/superpowers/specs/2026-10-15-mp-webview-crm-quote-design.md
T
wuzilongandCursor 88cb1a9f62 docs: add mp-webview CRM quote design spec.
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>
2026-10-15 15:35:21 +08:00

15 KiB
Raw Blame History

小程序 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 拆任务)

  1. views/m/crm/quote/* + 共享列表组件 + MpWebviewShell + mp-webview.scss
  2. 桌面报价表单增加 variant="page"(默认 dialog 不变)
  3. staticRoutes.ts 注册 /m/crm/quote*
  4. 列表/查询纯函数 + 单测(对齐产品 mp-crm-product-card 模式)
  5. workbench-menus.js + WORKBENCH_ROUTE_MAP 两项
  6. SQL:MINI_CRM_QUOTE + MINI_CRM_QUOTE_APPROVAL + 按 Web 报价菜单角色补绑
  7. 更新 docs/web-admin-mp-webview-modules.md 报价对照行
  8. 回归:对照 §10;对照接入清单五步

12. 参考

  • docs/web-admin-mp-webview-modules.md
  • docs/superpowers/specs/2026-10-15-mp-webview-crm-product-design.md
  • docs/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/*