Files
shanxia2.0/docs/superpowers/specs/2026-08-01-quote-approver-setting-design.md
T
2026-08-01 17:29:37 +08:00

150 lines
6.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.
# 报价单审批人设置(租户级默认审批人)
**日期:** 2026-08-01
**状态:** 已实现
**选定方案:** A — 租户级「报价单审批人设置」页 + 提交审批弹窗预填
**相关 Demo:** `docs/fresh-mint-quote-approver-setting-demo.html`
**现状入口:** `web-admin` 报价单管理 `#/crm/quote`(提交审批弹窗每次手选审批人)
## 1. 目标
1. 管理员在独立设置页配置**租户级默认审批人**(支持多人、有序)。
2. 业务员点击「提交审批」时,弹窗**自动预填**默认审批人,减少重复选择。
3. 预填后仍可修改;未配置时行为与现网一致(审批人必填、须手选)。
## 2. 非目标(首版不做)
- 默认备注模板
- 「记住上次选的人」客户端缓存
- 按部门 / 金额分岔审批人
- 接入通用工作流引擎(OpenSpec `workflow-conventions` 目标能力,另项推进)
- 改变现有 `submitQuote` 审批链路语义(顺序审批、状态流转等保持不变)
## 3. 已确认决策
| 项 | 决策 |
|----|------|
| 配置粒度 | 租户级一份配置 |
| 提交时可改预填审批人 | 可以 |
| 谁维护设置 | 仅拥有「报价单审批人设置」菜单权限的角色 |
| 未配置时 | 与现在一样:审批人必填,弹窗为空,须手选 |
| 默认备注 | 首版不做 |
## 4. 数据模型
### 4.1 表 `crm_quote_approver_setting`
新建表,遵守 database-conventions 公共字段顺序:`id` → 业务字段 → 公共字段。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | VARCHAR(64) | UUID 主键 |
| `approver_ids` | VARCHAR(1000) | 有序审批人用户 ID,逗号分隔(与现提交 `approverIds` 语义一致) |
| `status` | CHAR(1) | `0` 启用 / `1` 停用;停用等同未配置 |
| `tenant_no` | … | 租户 |
| `order_num` / `remark` / `create_*` / `update_*` / `del_flag` | … | 公共字段 |
约定:
- 同一 `tenant_no` 下有效(`del_flag=0`)记录**至多一条**:`GET` 取该条;`PUT` 无则 insert、有则 update(upsert),禁止同租户插入第二条有效记录。
- SQL 变更同步维护 `docs/sql/`(及必要的 migrate 脚本)。
- 不做默认备注字段;备注仍只在提交弹窗手填。
### 4.2 模型与 CRUD
- SQLAlchemy:`backend/app/models/crm_models.py` 新增 `CrmQuoteApproverSetting`
- CRUD:`backend/app/crud/crm/quote_approver_setting.py`(或同级模块)
- `get_setting(db, tenant_no)` → dict | None
- `save_setting(db, tenant_no, approver_ids, status, user_info)` → upsert
保存时校验:审批人 ID 须为当前租户下存在且可用的用户;无效 ID 拒绝保存并提示。
## 5. API
挂在现有 CRM 路由体系(与 `crm_quote_routes` 同前缀风格),建议:
| 方法 | 路径(示意) | 说明 |
|------|----------------|------|
| POST | `/api/web/.../crm/quote-approver-setting/get` | 返回当前租户配置;无记录返回 `{ approverIds: [], status: '0' }`(空列表不预填;默认启用避免设置页首次落到停用) |
| POST | `/api/web/.../crm/quote-approver-setting/save` | Body:`{ approverIds: string[], status: '0'\|'1' }`;有则更新、无则创建 |
约束:
- 读写均按当前用户 `tenant_no` 过滤/写入,**不信任**客户端覆盖租户。
- GET:登录且具备报价单相关业务权限即可读(用于提交预填);不要求具备设置页菜单。
- PUT:须具备「报价单审批人设置」菜单权限(与项目现有角色-菜单校验方式对齐)。
- **不改**现有 `submitQuote` 入参:仍由前端提交最终 `approverIds`。
## 6. 前端
### 6.1 设置页
- 路由建议:`#/crm/quote-approver-setting`
- 源码建议:`web-admin/src/views/crm/quote/approver-setting/index.vue`(表单配置页,非列表 CRUD)
- 字段:默认审批人(多选、有序)、启用状态
- UI:Fresh Mint;`label-position="top"`;面板主标题走 `panelTitleBarTextRules`(「报价单审批人设置」)
- 菜单:CRM 报价相关下新增菜单项;图标仅一级菜单;权限挂在角色-菜单上
- API 模块:`web-admin/src/api/crm/quote/` 增补 get/save setting
### 6.2 提交审批弹窗预填
改造所有会打开「提交审批」并选择审批人的入口,至少包括:
- `web-admin/src/views/crm/quote/index.vue`
- `web-admin/src/views/crm/quote/components/QuoteFormPanel.vue`
- 若 `ApproverSelector.vue` 仍被使用,一并预填
行为:
1. 打开弹窗 → 拉用户列表 + 拉设置。
2. 若存在**启用**配置且过滤无效用户后仍有 ID → 预填 `approverIds`;可选轻提示「已按审批人设置预填,可修改」。
3. 否则不预填、不提示,校验与现网一致(审批人必填)。
4. 拉设置失败:不阻断打开弹窗,视为未配置。
5. 备注字段:不预填。
### 6.3 界面模式
- 设置页:接近「单对象配置表单」;对照 `docs/web-admin-ui-pattern-index.md` 选型时优先表单配置类模式(实现计划中写明 P 编号)。
- 提交弹窗:沿用现有 `dialog-form-layout` + `form-grid-2`,不新开交互范式。
## 7. 数据流
```
管理员 → 设置页 PUT → crm_quote_approver_setting
业务员 → 打开提交弹窗 → GET setting → 预填 approverIds(可改)
业务员 → 确定 → 现有 submitQuote({ id, approverIds, remark })
后端 → create_approval_records(现有逻辑)
```
## 8. 边界情况
| 场景 | 行为 |
|------|------|
| 设置中含已停用/已删用户 | 保存时校验失败;预填时过滤无效 ID,过滤后为空则当未配置 |
| `status=停用` | 不预填 |
| 清空审批人并保存 | 允许;之后不预填 |
| 多人顺序 | 与现网一致:按选择顺序依次审批 |
| 租户隔离 | 全部按 `tenant_no` |
## 9. 验收标准
1. 管理员保存启用的默认审批人后,业务员打开提交弹窗可见预填且顺序正确。
2. 业务员修改预填审批人后可成功提交,审批记录与所选一致。
3. 未配置或停用时,提交行为与改造前一致。
4. 无设置菜单权限的用户无法打开/保存设置页;有报价权限的用户仍可正常提交审批。
5. 跨租户不可读到他租配置。
## 10. 实现触点(清单)
| 层 | 触点 |
|----|------|
| SQL | `docs/sql/` + migrate;新表 `crm_quote_approver_setting` |
| Backend | model、CRUD、CRM route 注册、权限 |
| Frontend | 设置页、API、菜单/路由、提交弹窗预填 |
| Docs | 本设计;可选更新 UI pattern 索引条目 |
## 11. 测试建议
- 后端:get 空/有配置;put upsert;停用不返回为「可预填」;非法用户 ID 拒绝;租户隔离。
- 前端手工:设置保存 → 列表提交预填 → 改人提交 → 清空设置后恢复手选;无菜单权限用户不可进设置页。