# 交易订单管理 — 功能需求

## 1. 文档说明

| 项 | 说明 |
| --- | --- |
| 模块名称 | 交易订单管理（交易市场平台） |
| 目标 | 登记**供应商向承销商出售牲畜**的交易订单，完成**订单支付**后**自动生成供应商结算单**，形成「交易 → 订单支付 → 结算付款」业务闭环 |
| 依据 | 同目录 `交易订单管理-草稿.md`、原型 `Snipaste_2026-05-22_13-54-54.jpg`；关联 `../供应商结算管理/供应商结算管理-草稿.md`、原型 `Snipaste_2026-05-22_13-55-35.jpg` |
| 范围 | **仅功能与业务规则**；不含库表、接口、报文、技术栈 |

### 1.1 使用角色与入口

| 角色 | 场景 |
| --- | --- |
| 交易市场运营人员 | 录入订单、完成订单支付、查询、打印小票/凭证 |
| 财务/结算人员 | 在 **供应商结算管理** 中处理待结算单（本模块不完成结算） |
| 系统管理员 | 菜单与权限配置 |

默认进入 **交易订单列表**。

### 1.2 模块关系（业务视角）

```text
供应商管理 ──────► 选供应商；收费方式/费率（结算计费依据）
承销商管理 ──────► 选承销商
市场进栏登记 ────► 采购明细耳标候选（已进栏牲畜）
交易订单管理 ────► 主单 + 采购明细；待支付 → 已完成
       │ 完成支付（支付凭证）
       ▼
供应商结算管理 ► 自动生成结算单；待结算 → 已完成（结算凭证）
```

| 关联模块 | 本模块依赖 | 约束 |
| --- | --- | --- |
| 供应商管理 | 有效供应商 | 完成支付时须能读取收费规则 |
| 承销商管理 | 有效承销商 | — |
| 市场进栏登记 | 按供应商汇总已进栏耳标 | 无进栏耳标则无法建明细 |
| 隔离巡查登记 | 病死/病害耳标剔除（§4.2） | 与「未病死、未病害」业务一致 |
| 供应商结算管理 | 支付成功后生成一条结算单 | 一对一；不可在本模块手工建结算单 |

---

## 2. 核心业务概念

### 2.1 一条交易订单

**某供应商**向**某承销商**出售多行牲畜（每行：耳标、重量 kg、金额 元），汇总为**交易总头数**、**交易总金额**。

| 信息项 | 说明 |
| --- | --- |
| 订单编号 | 系统生成，业务唯一 |
| 采购明细 | 至少 1 行 |
| 交易总头数 | = 明细**行数** |
| 交易总金额 | = 明细**金额之和**（元，保留 2 位小数展示） |
| 订单状态 | 待支付 / 已完成 |
| 支付凭证 | 完成支付时上传的图片 |
| 订单创建时间 | 首次保存成功时写入 |
| 订单完成时间 | 完成支付成功时写入；此前为空 |

### 2.2 状态与流转

| 状态 | 含义 | 允许操作（见 §8.9） |
| --- | --- | --- |
| **待支付** | 已保存，未上传支付凭证 | 编辑、删除、完成支付、打印小票、查看 |
| **已完成** | 已支付并已生成结算单 | 查看、打印凭证 |

- 流转：**仅** 待支付 → 已完成，**不可逆**。  
- **已完成**不可改业务字段、**不可**删除、**不可**再次完成支付。

### 2.3 删除

- **待支付**：**逻辑删除**，列表不展示，数据保留。  
- **已完成**：**禁止**删除（已关联结算单）。  
- **本期无回收站**。

---

## 3. 字段与录入规则

### 3.1 订单编号

- 用户**不可录入**；新增时系统生成；修改**不可改**。  
- 规则：`YYYYMMDD` + **3 位当日序号**（`001`～`999`，左补零），如 `20260520001`。  
- 序号按**自然日**递增，仅统计**未逻辑删除**订单。  
- 保存时须唯一；冲突则拒绝并提示。

### 3.2 供应商

- **必填**；表单**单选**，支持名称**模糊搜索**后选定。  
- 仅能选 **供应商管理** 中有效供应商。  
- **列表筛选**：选定后**精确**匹配该供应商订单。  
- **更换供应商**：清空全部采购明细，重新加载耳标候选。

### 3.3 承销商

- **必填**；表单**单选**，支持名称**模糊搜索**后选定。  
- 仅能选 **承销商管理** 中有效承销商。  
- **列表筛选**：选定后**精确**匹配。

### 3.4 采购明细

至少 **1** 行；可增删行（保存时至少保留 1 行）。

| 字段 | 规则 |
| --- | --- |
| 耳标号 | 下拉**单选**，**必填**；须先选供应商；下拉候选见 **§4.4**；保存校验见 **§4.4 / §5 R3**；**本单内不可重复** |
| 重量 | **必填**；**> 0**；单位 **kg**；建议最多 2 位小数；库字段 `weight` |
| 金额 | **必填**；**> 0**；单位 **元**；建议最多 2 位小数；库字段 `amount` |
| 品质等级 | **只读**；库字段 `grade_code`、`grade_name`；**保存/修改订单时由服务端**根据本行重量匹配 `biz_grade_weight_config`（闭区间 `[min_weight, max_weight]`）后同时写入编码与名称；前端**无需**传、**不可**手工改 |

- 子表 `biz_trade_order_line` 冗余 **`supplier_id`**（与主表一致），由**服务端**写入，前端 Body **无需**传。
- 等级重量配置见 `sql/biz_grade_weight_config.sql`（如 A 一级 ≥140 kg、B 二级 120～139.99 kg 等）；重量落在任一档外时保存失败并提示。  
- 耳标字符规则与 **入场隔离 / 市场进栏** 一致（单段 1～32 字符等）。

### 3.5 交易总头数 / 交易总金额

| 字段 | 规则 |
| --- | --- |
| 交易总头数 | **只读联动**；= 明细行数；正整数 |
| 交易总金额 | **只读联动**；= 明细金额之和；与手工合计不一致时**以系统汇总为准** |

### 3.6 支付凭证

| 阶段 | 规则 |
| --- | --- |
| 待支付 | 无 |
| 完成支付 | **必填**；**单张**图片；`jpg` / `jpeg` / `png`；**≤ 10MB** |
| 已完成 | 列表/详情可查看；**打印凭证**须能展示 |

### 3.7 时间字段

| 字段 | 写入时机 | 规则 |
| --- | --- | --- |
| 订单创建时间 | 首次保存成功 | 系统当前时间；用户**不可改** |
| 订单完成时间 | 完成支付成功 | 系统当前时间 |

---

## 4. 采购明细耳标候选（已确认口径）

草稿要求从 **市场进栏登记** 按供应商筛选，且牲畜须**未病死、未病害**。与 **市场进栏登记**、**隔离巡查** 对齐后的规则如下。

### 4.1 集合 M：市场进栏耳标（按供应商）

1. **市场进栏登记** 中：`del_flag` 有效、**供应商** = 当前所选供应商；  
2. 汇总所有进栏记录中的耳标（子表或聚合字段，**逗号拆分、去重**）→ **M**。  

若 **M** 为空：提示「该供应商暂无进栏耳标，请先维护市场进栏登记」。

> **说明**：订单**不**使用「入场隔离已结束」耳标池；仅以**已进栏**耳标为准。

### 4.2 集合 B：病死 / 病害耳标（全表巡查）

1. **隔离巡查登记** 中：`del_flag` 有效、**病死病害数量 > 0**、耳标号非空；  
2. **不按供应商过滤**；耳标**逗号拆分、去重** → **B**。  

### 4.3 集合 C：他单已成交占用（已确认：不允许跨单重复使用）

在**其他**有效交易订单（**待支付**或**已完成**、未逻辑删除）的采购明细中已出现的耳标 → **C**。  

- **不允许**同一耳标同时出现在两笔有效订单中（含两笔待支付）。  
- **修改本单**时：本单**当前已选**耳标不计入 C（可保留、可调整）。

### 4.4 下拉与保存可选集（实现口径）

| 场景 | 集合 / 规则 |
| --- | --- |
| **加载下拉** `GET /supplierEarTags` | 仅查 **`biz_market_entry_ear_tag`**：`supplier_id` = 当前供应商，`distinct ear_tag` 升序；**不**剔 B、**不**剔 C；可展示他单待支付已占用的耳标 |
| **保存校验（R3）** | 每行耳标 ∈ **（M − B）− C**；M 为 **§4.1**（有效进栏主表关联子表）；编辑时 C **排除本单** `order_id` |
| **完成支付成功后** | 按本单每行 **`supplier_id` + `ear_tag`** 删除 `biz_market_entry_ear_tag` 对应记录，释放进栏耳标池（与下拉数据源一致） |

> 下拉宽松、保存严格：用户可能选到保存时被 R3 拒绝的耳标（如病死 B、他单占用 C），须提示 §11 示例文案。

### 4.5 联动

| 时机 | 行为 |
| --- | --- |
| 选供应商 | 重载 `/supplierEarTags`（§4.4 下拉口径） |
| 换供应商 | 清空明细 |
| 增删行 | 更新头数、金额 |
| 保存 | 执行 §5 |

---

## 5. 保存规则（R1～R8）

**待支付**订单新增/修改点「确定」时全部满足：

| 编号 | 规则 |
| --- | --- |
| **R1** | 供应商、承销商、至少 1 行明细均已填 |
| **R2** | 供应商、承销商在各自主数据中仍有效 |
| **R3** | 每行耳标 ∈ §4.4 **保存校验**集合 **（M − B）− C**；重量、金额 > 0；服务端按重量写入 `grade_code`、`grade_name`（§3.4） |
| **R4** | 本单耳标不重复 |
| **R5** | 交易总头数 = 明细行数 |
| **R6** | 交易总金额 = 明细金额之和（按 2 位小数汇总） |
| **R7** | **已完成**订单不可保存修改 |
| **R8** | 订单编号唯一（系统生成冲突时拒绝） |

---

## 6. 完成支付

### 6.1 入口

仅 **待支付** 显示「完成支付」→ 弹窗 **「完成订单支付」**。

### 6.2 弹窗

- **支付凭证**：必填，§3.6。  
- **确定** / **取消**（取消不改变订单）。

### 6.3 确定后（须同一业务事务，全部成功或全部回滚）

| 序号 | 动作 |
| --- | --- |
| 1 | 订单状态 → **已完成** |
| 2 | 写入 **订单完成时间** |
| 3 | 保存 **支付凭证** |
| 4 | **生成一条**供应商结算单（§7） |
| 5 | 按明细 **`supplier_id` + `ear_tag`** 删除 **`biz_market_entry_ear_tag`** 中对应行（§4.4） |

任一步失败：订单保持 **待支付**，提示原因；**不得**出现「已完成但无结算单」或「已完成但未释放进栏耳标」等半成品状态（同一事务回滚）。

### 6.4 重试与幂等（已确认）

| 情况 | 处理 |
| --- | --- |
| 用户再次点击「完成支付」且仍为待支付 | **允许**重试上传凭证 |
| 订单已完成 | **不显示**完成支付 |
| 订单已完成且结算单已存在 | **不得**再次生成结算单 |

### 6.5 前置校验（完成支付时）

除支付凭证外，须满足：

- 供应商仍有效，且已配置 **收费方式**（否则无法计算结算金额）；  
- 订单仍为 **待支付**；  
- 采购明细、头数、金额仍满足 R3～R6（防止长时间挂单后数据失真）。

---

## 7. 与供应商结算管理的衔接

### 7.1 生成时机与数量

- **唯一触发**：本模块 **完成支付** 成功。  
- **一对一**：一笔订单 → **一条**结算单；不可在订单界面手工新建。  
- 结算单**不可**由用户选择「关联多订单」。

### 7.2 带入结算单的信息

| 结算单展示项 | 来源 |
| --- | --- |
| 关联订单编号 | 本订单编号 |
| 供应商 | 本订单供应商 |
| 交易总头数 | 本订单 |
| 交易总金额（元） | 本订单 |
| 结算创建时间 | 生成时刻 |

结算单编号、结算状态、服务费、实际应付、结算凭证等按 **§7.3～§7.4** 及结算模块自身规则处理。

### 7.3 结算单编号

- 系统自动生成：`JSD` + `YYYYMMDD` + 3 位当日序号（`001`～`999`）。  
- 与订单编号**独立**；通过 **关联订单编号** 关联。

### 7.4 服务费与实际应付（生成时计算并固化）

读取**生成结算单时刻**该供应商在 **供应商管理** 中的收费配置，计算后**写入结算单并不再随主数据变更自动重算**（快照）。

| 收费方式 | 服务费金额（元） |
| --- | --- |
| **按户计费** | **0** |
| **按头计费** | 交易总头数 × **收费标准**（元/头） |
| **按额计费** | 交易总金额 ×（**交易费率** + **管理费率**）÷ 100 |

**实际应付结算金额（元）** = 交易总金额 − 服务费金额。

**金额精度（已确认）**：

- 服务费、实际应付均保留 **2 位小数**；  
- 按 **四舍五入** 至分；  
- 按额计费时：先求（交易费率 + 管理费率）之和（%），再乘以交易总金额。

### 7.5 结算单初始状态

- **结算状态**：**待结算**。  
- **结算凭证**、**结算完成时间**：空。  
- 后续在 **供应商结算管理** 中「完成结算」、上传结算凭证。

### 7.6 订单与结算状态对照

```text
订单：  （无）─保存─► 待支付 ──完成支付──► 已完成
结算：  （无）          （无）  ──生成──► 待结算 ──完成结算──► 已完成
```

- 订单 **待支付**：无结算单。  
- 订单 **已完成**：必有 **待结算** 或 **已完成** 的结算单。  
- 结算完成后，订单状态**仍为**已完成（不回退）。

---

## 8. 功能清单

### 8.1 新增

入口：列表「新增」。确定后：生成编号、**待支付**、订单创建时间。取消不保存。

### 8.2 列表查询

| 筛选项 | 匹配方式 |
| --- | --- |
| 订单编号 | **模糊** |
| 供应商 | 下拉选定后 **精确**（支持输入模糊搜索后选定） |
| 承销商 | 同上 **精确** |
| 组合 | 条件 **同时** 生效 |

- 仅未逻辑删除记录；默认按 **订单创建时间** 降序；默认每页 **20** 条。  
- 工具栏：搜索、重置、新增。

**列表列**：订单编号、订单创建时间、供应商、承销商、采购明细（入口）、交易总头数（头）、交易总金额（元）、订单状态、支付凭证、订单完成时间、操作。

**采购明细列**：点击打开 **采购明细表** 弹窗（只读展示该单全部行：耳标、重量、金额、品质等级名称）；列表行内可摘要展示（如首耳标+「等 N 头」）。

### 8.3 修改

- **仅待支付**；**全部业务字段**可改（含明细）；编号、创建时间不可改。  
- 规则同 §4、§5。

### 8.4 查看

全字段只读；明细完整；支付凭证可查看；含审计信息（与项目惯例一致）。

### 8.5 删除

- **仅待支付**；二次确认（宜含编号、供应商、金额或头数）；逻辑删除。

### 8.6 打印

| 功能 | 范围 | 内容 |
| --- | --- | --- |
| **打印小票** | **仅待支付** | 编号、双方、明细、头数、金额、创建时间；**不含**支付凭证、完成时间 |
| **打印凭证** | **仅已完成** | 含 §3 交易信息 + **订单完成时间** + **支付凭证** + 订单状态 |

> 待支付**不提供**「打印凭证」；已完成**不提供**「打印小票」。

### 8.7 按状态操作矩阵

| 状态 | 操作 |
| --- | --- |
| 待支付 | 打印小票、完成支付、查看、编辑、删除 |
| 已完成 | 打印凭证、查看 |

无权限不显示按钮。

### 8.8 本期不做

部分支付/退款、拆单、批量导入导出、订单侧完成结算、改已完成订单、物理删除、承销商结算。

---

## 9. 业务流程图

### 9.1 订单主流程

```mermaid
flowchart TD
    L[订单列表] --> N[新增/编辑]
    N --> V{R1-R8?}
    V -->|否| N
    V -->|是| P[待支付]
    P --> E[编辑/删除/打小票]
    P --> Pay[完成支付+凭证]
    Pay --> OK{成功?}
    OK -->|否| P
    OK -->|是| D[已完成+生成结算单]
    D --> L
```

### 9.2 与结算衔接

```mermaid
sequenceDiagram
    participant O as 交易订单
    participant S as 供应商结算
    O->>O: 完成支付
    O->>S: 生成结算单(待结算,费用快照)
    S->>S: 完成结算(结算凭证)
```

### 9.3 耳标候选

```mermaid
flowchart LR
    M[进栏耳标 M] --> X[M-B]
    X --> Y[减他单 C]
    Y --> Z[下拉/保存校验]
```

---

## 10. 权限（业务层）

查询列表、查看详情、新增、修改、删除、完成支付、打印（小票/凭证）— 实施配置，本文不列编码。

---

## 11. 提示语（示例）

| 情况 | 示例 |
| --- | --- |
| 缺供应商/承销商/明细 | 请选择供应商 / 承销商 / 请至少添加一行采购明细 |
| 请先选供应商 | 请先选择供应商 |
| 无进栏耳标 | 该供应商暂无进栏耳标，请先维护市场进栏登记 |
| 耳标重复 | 存在重复耳标：{耳标号} |
| 耳标不可用 | 耳标 {耳标号} 不可选或已被其他订单占用 |
| 已完成不可改删 | 已完成订单不可修改 / 不可删除 |
| 支付凭证 | 请上传支付凭证 / 文件格式或大小不符合要求 |
| 完成支付失败 | 完成支付失败：{原因} |
| 供应商收费未配置 | 供应商收费方式未配置，无法生成结算单 |
| 编号冲突 | 订单编号生成冲突，请重试 |

---

## 12. 关联需求分析（供应商结算管理）

依据 `../供应商结算管理/供应商结算管理功能需求.md`（及草稿、原型），明确两模块分工与一致性。

### 12.1 职责边界

| 能力 | 交易订单管理 | 供应商结算管理 |
| --- | --- | --- |
| 交易与采购明细 | ✓ | — |
| 订单支付凭证 | ✓ | — |
| 触发创建结算单 | ✓（自动） | 被动接收 |
| 服务费/实际应付计算 | 生成时计算并**快照** | 展示、打印 |
| 结算凭证与结算完成 | — | ✓ |
| 按结算单号/订单号查询 | — | ✓ |

### 12.2 关键字段对照

| 概念 | 订单 | 结算 | 一致性 |
| --- | --- | --- | --- |
| 编号 | 日期+3位 | JSD+日期+3位 | 独立；用关联订单编号串联 |
| 交易总头数 | 头 | 头 | 生成时一致 |
| 交易总金额 | 元 | 元 | 生成时一致 |
| 服务费 | — | 元 | §7.4 |
| 实际应付 | — | 元 | 总金额−服务费 |
| 支付凭证 vs 结算凭证 | 订单支付 | 结算付款 | **两阶段、两种凭证** |

### 12.3 结算模块功能摘要（便于联调）

完整规则见 **`../供应商结算管理/供应商结算管理功能需求.md`**。摘要如下：

| 项 | 规则 |
| --- | --- |
| 列表筛选 | 结算单编号模糊；关联订单编号模糊 |
| 列表列 | 结算单编号、结算创建时间、关联订单编号、供应商、交易总头数、交易总金额、服务费、实际应付、结算状态、结算凭证、结算完成时间 |
| 待结算操作 | 完成结算、查看 |
| 已完成操作 | 打印凭证、查看 |
| 完成结算 | 弹窗上传结算凭证（规则同订单支付凭证 §3.6）；确定后状态已完成、写入结算完成时间 |
| 流程终点 | **完成结算**为平台业务链终点；结算模块内无后续必办 |
| 跨模块导航 | **不提供**从结算列表/详情跳转至订单详情；关联订单编号仅展示与筛选 |

### 12.4 端到端业务链

```text
市场进栏(耳标子表) → 交易订单(待支付) → 完成支付(删子表耳标+结算单) → 结算单(待结算) → 完成结算 → 闭环
```

### 12.5 异常场景（两模块协同）

| 场景 | 处理原则 |
| --- | --- |
| 完成支付时供应商已删或收费未配 | **拒绝**完成支付 |
| 支付成功但结算生成失败 | 订单保持待支付（§6.3）；用户可重试 |
| 订单待支付被删 | 无结算单；耳标占用释放 |
| 订单已完成 | 不可删；结算单待结算/已完成均不回写订单状态 |
| 结算单已完成 | 订单仍已完成；**不可**作废订单 |
| 进栏登记删除某耳标 | 待支付订单保存时 R3 可能失败；已完成订单保留历史明细 |
| 完成支付成功 | 从 `biz_market_entry_ear_tag` 删除本单耳标；下拉池不再展示 |

### 12.6 对市场进栏登记的依赖

- 交易成交对象必须是 **已进栏** 耳标（§4.1，**保存校验**）。  
- 下拉展示来自进栏耳标**子表**（§4.4），与保存可选集口径不同。  
- 病死耳标通过 §4.2 与巡查模块联动，**保存时**剔除（下拉仍可能展示，由 R3 拦截）。  
- 运营顺序建议：进栏 → 建单 → 支付 → 结算。

---

## 13. 非功能建议

| 项 | 建议 |
| --- | --- |
| 权限 | 操作分权 |
| 审计 | 增删改、完成支付留痕 |
| 校验 | 保存、完成支付须**服务端**执行 R1～R8 与 §6.5 |
| 事务 | 完成支付与生成结算单原子性 |
| 易用性 | 删除、完成支付二次确认 |

---

## 14. 已确认业务决策（评审纪要）

| 序号 | 决策 |
| --- | --- |
| 1 | 耳标候选来自 **市场进栏登记**，不使用入场隔离池 |
| 2 | 剔除 **全表**巡查病死/病害耳标（§4.2） |
| 3 | **禁止**同一耳标出现在多笔有效订单（§4.3） |
| 4 | 结算费用以生成结算单时 **快照** 为准 |
| 5 | 金额 **2 位小数、四舍五入** |
| 6 | 完成支付失败可重试；已成功不得重复生成结算单 |
| 7 | 打印：待支付仅小票；已完成仅凭证 |
| 8 | **下拉耳标**：仅 `biz_market_entry_ear_tag` 按 `supplier_id`；**保存**仍 **(M−B)−C** |
| 9 | **完成支付**后删除进栏子表已成交耳标（`supplier_id` + `ear_tag`） |
| 10 | 采购明细子表冗余 `supplier_id`，与主表一致 |

---

## 15. 草稿对照

| 草稿条目 | 章节 |
| --- | --- |
| 交易订单 1～7 | §3、§4、§5、§8 |
| 交易订单 5、13～14 | §6、§7、§8.7 |
| 交易订单 8～12 | §8.3～§8.6 |
| 结算 2～11 | §7、§12 |
| 技术栈、异常报文格式 | 不纳入 |

---

## 16. 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初稿：订单与结算衔接、耳标与状态 |
| 1.1 | 优化：拍板耳标/费用/快照/重试/打印边界；§4 与进栏/巡查对齐；§12 关联分析；§14 决策纪要；对齐草稿列表精确筛选 |
| 1.2 | 对齐实现：§4.4 拆「下拉子表 / 保存 M−B−C / 支付后删进栏耳标」；§3.4 子表 `supplier_id`；§6.3 步骤 5；§14 决策 8～10 |
| 1.3 | 对齐结算需求 v1.1：§12.3 补充「完成结算为流程终点、不跳转订单」 |
