docs: add protocol payment last-period autofill design
Document confirmed rules for fq last-period due amount auto-fill and dj lump-sum deadline to due date sync in SamplePaymentPanel. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
08150167a8
commit
0efcd6a6e5
1 file changed
+93
@@ -0,0 +1,93 @@
|
||||
# 采集协议单 · 分期尾期金额与趸交应缴日自动填入
|
||||
|
||||
**日期:** 2026-10-13
|
||||
**范围:** `web-admin` 采集协议单新增/编辑弹窗(`SamplePaymentPanel`,payment_model_version ≥ 2)
|
||||
**状态:** 已确认设计,待写实现计划
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
采集协议单按样本配置缴费时:
|
||||
|
||||
1. **分期(`fq`)**:用户手填各期应缴费金额;希望前几期填完后,**最后一期自动 = 合同金额 − 前 N−1 期之和**,减少合计对不齐。
|
||||
2. **趸交(`dj`)**:填写「趸交截止时间」后,**最后一期(通常第 1 期)应缴费时间**自动填入该截止时间。
|
||||
|
||||
## 2. 已确认决策
|
||||
|
||||
| 项 | 决策 |
|
||||
|----|------|
|
||||
| 分期尾期交互 | 方案 B:自动重算;尾期仍可手改;手改后不再自动覆盖,直到前几期再变 |
|
||||
| 分改趸截止时间 | **不做**:不新增「趸交截止时间」字段,不做截止日 → 应缴日联动 |
|
||||
| 实现路径 | 方案 1:`SamplePaymentPanel` 联动 + `protocol-sample-payment.ts` 纯函数 + 单测 |
|
||||
| v1 整单缴费 | **不改** |
|
||||
| 后端 API | **不改** |
|
||||
|
||||
## 3. 行为规则
|
||||
|
||||
### 3.1 分期 · 最后一期应缴费金额
|
||||
|
||||
- **适用:** `payMode === 'fq'`,且存在 ≥ 2 个未作废应缴批次。
|
||||
- **公式:**
|
||||
`lastDue = round((contractAmount − Σ priorDueAmounts) * 100) / 100`
|
||||
用「分」为单位累加前 N−1 期,尾差落在最后一期。
|
||||
- **触发:** 用户修改**前 N−1 期**任一 `dueAmount` 时,若允许自动填入,则写入最后一期并同步 `installmentRatios`。
|
||||
- **用户覆盖:**
|
||||
- 用户直接修改最后一期 `dueAmount` → 标记该样本「尾期用户覆盖」;
|
||||
- 覆盖期间不自动改写尾期;
|
||||
- 前几期任一金额再次变化 → **清除覆盖标记**并按公式重算写入。
|
||||
- **不自动写入的情况:**
|
||||
- 最后一期已锁定(存在 `payStatus === 'yjf'` 的转账);
|
||||
- 合同金额为空 / 非有限数;
|
||||
- 前 N−1 期金额均未有效填写(无法形成有意义的补尾);
|
||||
- 当前为分改趸 `fgd`(本需求不要求对 `fgd` 做尾期自动补齐;若实现时复用同一路径,须在计划中显式写明「仅 `fq`」)。
|
||||
- **负数:** 公式结果 < 0 时写入 `0`;保存时仍由现有「各期合计 = 合同」校验拦截。
|
||||
|
||||
### 3.2 趸交 · 趸交截止时间 → 应缴费时间
|
||||
|
||||
- **适用:** `payMode === 'dj'`。
|
||||
- **行为:**
|
||||
- 截止时间有值 → 写入该样本**最后一期**未锁定批次的 `dueDate`;
|
||||
- 截止时间清空 → 同步清空该未锁定最后一期的 `dueDate`。
|
||||
- **跳过:** 最后一期已锁定(存在 `yjf` 转账)。
|
||||
- **与重建一致性:** `rebuildSchedules` 在趸交重建时已用 `lumpSumDeadline` 填 `dueDate`;须补齐「仅改截止时间、不 rebuild」路径,使行为与重建一致。
|
||||
|
||||
### 3.3 分改趸
|
||||
|
||||
- 不新增 UI 字段;不因本需求改应缴日联动。
|
||||
|
||||
## 4. 代码落点
|
||||
|
||||
### 4.1 纯函数(`web-admin/src/utils/protocol-sample-payment.ts`)
|
||||
|
||||
| 函数 | 职责 |
|
||||
|------|------|
|
||||
| `calcLastPeriodDueAmount(contractAmount, priorAmounts[])` | 返回尾期金额;无法计算时返回 `null` |
|
||||
| `shouldAutoFillLastPeriodDue({ lastManualOverride, lastLocked })` | 是否允许自动写入尾期 |
|
||||
| `applyLumpSumDeadlineToLastDueDate(schedules, deadline, isLocked)` | 返回更新后的 schedules(只改未锁定最后一期的 `dueDate`) |
|
||||
|
||||
覆盖状态由组件内存维护(如按样本 key 的 `Map` 或临时字段),**不落库**。
|
||||
|
||||
### 4.2 组件(`SamplePaymentPanel.vue`)
|
||||
|
||||
- `patchSchedule`:处理 `dueAmount` 变更时的尾期自动填入 / 覆盖标记。
|
||||
- 趸交截止时间变更:在写入 `lumpSumDeadline` 后调用 `applyLumpSumDeadlineToLastDueDate`(无需整表 rebuild)。
|
||||
|
||||
### 4.3 测试(扩展 `protocol-sample-payment.test.ts`)
|
||||
|
||||
1. 前几期填齐 → 尾期 = 合同 − 之和;尾差落在尾期。
|
||||
2. 尾期手改后前几期未变 → 不覆盖;前几期再变 → 再覆盖。
|
||||
3. 尾期锁定 → 不自动改。
|
||||
4. 趸交:填/清截止时间 → 最后一期应缴日同步/清空;锁定则跳过。
|
||||
|
||||
## 5. 非目标
|
||||
|
||||
- 分改趸截止时间 UI 与联动
|
||||
- v1 `ProtocolFormDialog` 整单缴费联动
|
||||
- 后端 schema / API 变更
|
||||
- 强制尾期只读
|
||||
|
||||
## 6. 验收要点
|
||||
|
||||
1. 新建/编辑协议单,样本缴费模式为分期:填前 N−1 期金额后,最后一期自动等于合同尾差;手改尾期后不被立刻覆盖;再改前几期则重新自动。
|
||||
2. 趸交:改「趸交截止时间」后,应缴费时间同步;清空截止时间后应缴费时间清空;已确认转账锁定的批次不被改。
|
||||
3. 分改趸界面仍无「趸交截止时间」字段,行为与改前一致。
|
||||
4. 相关纯函数单测通过。
|
||||
Reference in new issue
Block a user