215 lines
9.9 KiB
Markdown
215 lines
9.9 KiB
Markdown
# 采集协议单 · 缴费默认定价与明细规则设计
|
||
|
||
**日期**:2026-07-06
|
||
**范围**:`web-admin` 采集协议单新增/编辑(`ProtocolFormDialog.vue`)、标准信息导入、后端缴费保存校验
|
||
**前置 spec**:[2026-06-04-protocol-pay-mode-switch-design.md](./2026-06-04-protocol-pay-mode-switch-design.md)、[2026-06-10-protocol-installment-config-design.md](./2026-06-10-protocol-installment-config-design.md)
|
||
**状态**:已实现
|
||
|
||
---
|
||
|
||
## 1. 背景与目标
|
||
|
||
业务方给出「样本数 × 缴费模式」下的**默认合同金额、默认期数、默认各期金额**。这些数值仅作录入辅助;用户可自由修改合同金额、分期期数、各期金额;趸交也可拆成多条缴费明细(如预付款 + 尾款)。
|
||
|
||
当前实现与目标的主要差距:
|
||
|
||
| 维度 | 现状 | 目标 |
|
||
|------|------|------|
|
||
| 合同金额来源 | 非作废样本 `price` 之和 | 按定价表填**默认**,用户可改;样本数变化**不**自动改金额 |
|
||
| 分期默认金额 | 均分或历史 50/10/10… | 固定模板(6,480 / 3,880…) |
|
||
| 分期默认期数 | 一律 6 期 | 1 样本 6 期;2 样本分期/混合 5 期 |
|
||
| 缴费模式 | `dj` / `fq` | 增加双样本 **趸交+分期** `djfq` |
|
||
| 趸交明细条数 | 后端禁止多条 `dfj` | 允许多条,合计 = 合同金额 |
|
||
| 默认填充时机 | 切分期、改样本价等会联动 | **方案 B**:仅新建或**首次**选缴费模式时填默认 |
|
||
|
||
---
|
||
|
||
## 2. 决策记录
|
||
|
||
| 议题 | 决定 |
|
||
|------|------|
|
||
| 默认值性质 | 仅初始填充,**不锁定**;用户可改合同金额、期数、各期金额 |
|
||
| 样本数变化 | **不**自动改合同金额、期数、明细(方案 B) |
|
||
| 缴费模式变化 | **首次**从空/未选切到某模式时填该模式默认;已选过且用户已编辑后,再次切换仍走既有「模式切换」确认流(见 §6) |
|
||
| 单样本分期默认合同额 | **25,880**(6,480 + 3,880×5) |
|
||
| 趸交默认合同额 | 优惠价:1 样本 **22,880**;2 样本 **37,880** |
|
||
| 双样本「趸交+分期」 | 新模式 `djfq`,默认 **41,000**,5 期:22,880、6,480、3,880、3,880、3,880 |
|
||
| 双样本纯分期 | 默认 **44,000**,5 期:12,960、7,760、7,760、7,760、7,760 |
|
||
| 趸交多条明细 | 允许;`Σ dueAmount(全部明细)= contractAmount`;保存时不再限制「仅 1 条 dfj」 |
|
||
| 样本 `price` 字段 | 仍维护样本单价;与合同默认**解耦**;导入/保存时可提示样本价合计与合同额不一致,**不阻断** |
|
||
| 定价表存放 | 前端 `protocol-payment-presets.ts`(常量);后端镜像校验逻辑不依赖默认表,只校验合计与条数 |
|
||
|
||
---
|
||
|
||
## 3. 默认定价表
|
||
|
||
有效样本数 = 当前协议单内 `sampleStatus !== 'yzf'` 的样本条数,取值 **1** 或 **2**(与现网一致,不支持 0 样本保存缴费)。
|
||
|
||
| 样本数 | `pay_mode` | 默认合同金额 | 默认期数 | 默认各期金额(元) |
|
||
|--------|------------|-------------|----------|-------------------|
|
||
| 1 | `dj` | 22,880 | — | 单条明细 `dueAmount = 22,880`(用户可拆多条) |
|
||
| 1 | `fq` | 25,880 | 6 | 6,480、3,880、3,880、3,880、3,880、3,880 |
|
||
| 2 | `dj` | 37,880 | — | 单条明细 `dueAmount = 37,880`(用户可拆多条) |
|
||
| 2 | `djfq` | 41,000 | 5 | 22,880、6,480、3,880、3,880、3,880 |
|
||
| 2 | `fq` | 44,000 | 5 | 12,960、7,760、7,760、7,760、7,760 |
|
||
|
||
**标签**:`djfq` 展示为「趸交+分期」;字典 `status-tag-registry` / 后端摘要增加 `djfq` → `趸交+分期`。
|
||
|
||
**双样本时缴费模式选项**:`dj`、`djfq`、`fq`(隐藏或禁用 `djfq` 当样本数 ≠ 2)。
|
||
|
||
---
|
||
|
||
## 4. 默认填充时机(方案 B)
|
||
|
||
### 4.1 会填充默认的场景
|
||
|
||
1. **新建协议单**,用户**第一次**选择缴费模式(`pay_mode` 从初始 `dj` 切到 `fq` / `djfq`,或新建后首次进入缴费 Tab 且明细为空时的初始化,与产品确认以「首次 `onPayModeChange` 且该模式从未应用过」为准)。
|
||
2. **新建协议单**,打开时若默认 `pay_mode=dj` 且 `paymentDetails` 为空:按 **当前样本数** 填趸交默认(合同额 + 1 条明细)。若此时样本数仍为 0,待用户添加第 1 个样本后**不**自动重填(方案 B);用户选模式或手动点「套用默认」时再填。
|
||
|
||
> **实现建议**:维护 `paymentDefaultsApplied: Record<PayMode, boolean>`(或 `lastAppliedPresetKey: string | null`)。某 `pay_mode` 第一次生效时调用 `applyPaymentPreset(sampleCount, payMode)`,并标记已应用。
|
||
|
||
### 4.2 不会自动改金额的场景
|
||
|
||
- 增删样本、样本作废/恢复
|
||
- 修改样本 `price`
|
||
- 修改合同金额后回头改样本
|
||
|
||
用户自行改合同额、期数、明细;仅触发**合计校验**与既有「分期参数变更 / 模式切换」确认流。
|
||
|
||
### 4.3 可选辅助(P1,非本期必须)
|
||
|
||
缴费主表旁「恢复默认」按钮:按当前样本数 + 当前 `pay_mode` 重新套用 §3 定价表,**需二次确认**。
|
||
|
||
---
|
||
|
||
## 5. 缴费明细与校验
|
||
|
||
### 5.1 趸交 `dj`
|
||
|
||
- 明细 **≥ 1** 条;用户可通过「添加明细」增加(含预付款场景)。
|
||
- `canAddPaymentDetail`:改为在 `dj` 下**始终允许**添加(或:待缴条数无硬上限,仅校验合计)。
|
||
- 保存校验:
|
||
- `Σ dueAmount(全部明细)` 与 `contractAmount` 差额 ≤ 0.01;
|
||
- 允许多条 `dfj`;
|
||
- 若存在 `yjf`:`Σ yjf.dueAmount + Σ dfj.dueAmount` 仍须等于 `contractAmount`(与现 `remaining` 逻辑一致,但允许多条 `dfj` 分摊剩余)。
|
||
|
||
### 5.2 分期 `fq` 与混合 `djfq`
|
||
|
||
- 明细条数 **=** `installment_count`(与现 `fq` 一致)。
|
||
- `installment_ratios` 存**各期金额(元)**,非百分比(与现网一致)。
|
||
- `Σ 各期 dueAmount = contractAmount`。
|
||
- `djfq` 在数据层按分期处理:每期有 `installmentNo`、应缴日;第 1 期金额语义为「趸交部分」,不做单独子表。
|
||
|
||
### 5.3 与标准信息导入
|
||
|
||
- 导入解析到的 `contractAmount`、多笔 `transfer` **覆盖**默认填充(与 [2026-07-02-protocol-standard-import-design.md](./2026-07-02-protocol-standard-import-design.md) 一致)。
|
||
- 导入后标记 `paymentDefaultsApplied` 全部为已应用,避免再自动覆盖。
|
||
|
||
---
|
||
|
||
## 6. 缴费模式切换(在 2026-06-04 上的修订)
|
||
|
||
既有切换规则(已缴锁定、确认流)**保留**。下列条目**修订**原 spec:
|
||
|
||
| 原规则 | 新规则 |
|
||
|--------|--------|
|
||
| 趸交仅 1 条有效明细 | 趸交可多条;切换生成时仍可合并为 1 条**默认**,用户随后可拆 |
|
||
| `pay_mode` 仅 `dj`/`fq` | 增加 `djfq`;`djfq` ↔ `fq` 按分期规则;`djfq` → `dj` 同 `fq` → `dj` |
|
||
| 切换后分期金额均分 | 切换后若走「重建明细」,使用 §3 对应默认各期金额(非均分) |
|
||
|
||
**双样本 → 单样本**(或反向):不自动改合同/明细(方案 B);若当前 `pay_mode=djfq` 且样本数变为 1,**阻断保存**并提示「请切换缴费模式」,或自动要求用户改模式(推荐:**保存前校验**样本数与 `djfq` 一致)。
|
||
|
||
---
|
||
|
||
## 7. 数据模型
|
||
|
||
### 7.1 `biz_protocol_payment.pay_mode`
|
||
|
||
| 值 | 含义 |
|
||
|----|------|
|
||
| `dj` | 趸交 |
|
||
| `fq` | 分期 |
|
||
| `djfq` | 趸交+分期(仅双样本) |
|
||
|
||
字段长度 `varchar(8)` 足够。无需新列;`installment_count` / `installment_ratios` 在 `djfq` 与 `fq` 用法相同。
|
||
|
||
### 7.2 迁移
|
||
|
||
- 字典项(若缴费模式走 dict):增加 `djfq`。
|
||
- 历史数据无 `djfq`,只读展示兼容即可。
|
||
|
||
---
|
||
|
||
## 8. UI
|
||
|
||
### 8.1 缴费模式
|
||
|
||
```text
|
||
[ 趸交 ] [ 分期 ] // 1 样本
|
||
[ 趸交 ] [ 趸交+分期 ] [ 分期 ] // 2 样本
|
||
```
|
||
|
||
### 8.2 分期金额区
|
||
|
||
- `fq` / `djfq`:展示期数、间隔、开始时间、各期金额输入格;默认期数/金额来自 §3。
|
||
- 合计行:`合计 xxx / 合同 xxx`(已有)。
|
||
|
||
### 8.3 样本价格
|
||
|
||
- 样本 Tab 的「价格」保留;**移除** `syncContractAmount()` 在样本价变更时对 `contractAmount` 的自动写入(方案 B)。
|
||
- 可选弱提示:样本价合计 ≠ 合同金额时展示 `form-tip`(不阻断保存)。
|
||
|
||
---
|
||
|
||
## 9. 后端改动摘要
|
||
|
||
| 文件 | 改动 |
|
||
|------|------|
|
||
| `protocol_pay_mode_switch.py` | `dj`:删除「仅 1 条 dfj」;改为明细总额校验;支持 `djfq` 走 `fq` 分支 |
|
||
| `collection_protocol.py` | 读写 `pay_mode=djfq`;列表/详情标签 |
|
||
| `qc_work_order_fee_summary.py` 等 | `djfq` 标签与分期展示 |
|
||
|
||
---
|
||
|
||
## 10. 前端改动摘要
|
||
|
||
| 文件 | 改动 |
|
||
|------|------|
|
||
| `protocol-payment-presets.ts` | **新建**,§3 定价表 + `applyPaymentPreset()` |
|
||
| `protocol-payment-installment.ts` | 默认金额生成改为调用 preset(均分仅作无 preset 时的兜底) |
|
||
| `protocol-pay-mode-switch.ts` | `dj` 多明细;`PayMode` 含 `djfq` |
|
||
| `ProtocolFormDialog.vue` | 模式 UI、首次填充、去掉样本价→合同额联动 |
|
||
| `ProtocolViewDialog.vue` | `djfq` 展示 |
|
||
| `status-tag-registry.ts` | `djfq` |
|
||
| `protocol-standard-import-parse.ts` | 识别「趸交+分期」文案 → `djfq`(P1) |
|
||
|
||
---
|
||
|
||
## 11. 测试要点
|
||
|
||
- [ ] 新建 1 样本,首次选 `fq` → 合同 25,880,6 期金额正确
|
||
- [ ] 新建 2 样本,首次选 `djfq` → 41,000,5 期正确
|
||
- [ ] 改样本数 1→2,合同/明细**不变**
|
||
- [ ] 趸交添加 2 条明细,合计 = 合同额,保存成功
|
||
- [ ] 趸交 2 条 `dfj` 预付款场景,保存成功
|
||
- [ ] 修改各期金额后合计 ≠ 合同额,前后端均拦截
|
||
- [ ] 模式切换 + 已缴锁定,仍符合 2026-06-04
|
||
- [ ] 2 样本 `djfq` 删至 1 样本,保存提示改模式
|
||
- [ ] 标准导入多笔转账 + 趸交,保存成功
|
||
|
||
---
|
||
|
||
## 12. 范围外
|
||
|
||
- 定价表后台可配置化(本期写死常量)
|
||
- 3 个及以上样本
|
||
- 按样本绑定不同缴费模式(每样本独立主表)
|
||
|
||
---
|
||
|
||
## 13. 修订记录
|
||
|
||
| 日期 | 说明 |
|
||
|------|------|
|
||
| 2026-07-06 | 初稿:默认定价表、方案 B、djfq、趸交多明细 |
|