# 安徽运八需求（以API文档为准重构）

> **重构原则**: API接口文档(网货企业端接口文档 V1.0.2) 为查询+申诉权威数据源，Showdoc文档为上报接口字段定义权威数据源。HTML原型为UI参考，原始需求文档为业务背景补充。
> **重构时间**: 2026-07-13（最后更新: 2026-07-14，根据14项确认决议）
> **原始需求**: `source_docs/requirements_raw/安徽运八需求.docx`
> **API文档（查询+申诉）**: `E:\Downloads\网货企业端接口文档（最新）.pdf` V1.0.2 (2023-04)
> **Showdoc文档（上报接口·权威字段定义）**: `output/prototype/showdoc文档.md`
> **原型**: `anhuibaba_index.html`

---

## 一、系统边界

本需求涉及两套系统的对接：

| 系统 | 职责 | 本文档覆盖 |
|:---|:---|:---|
| **运八平台（我方）** | 自动触发三阶段上报、ETC上传；查询核验结果；发起/跟踪申诉；查看上报日志 | 全量 |
| **安徽省级网络货运监测系统（省平台）** | 接收上报数据；执行核验；受理申诉并反馈 | 仅接口交互 |

API文档覆盖的是**运八平台→省平台**的查询和申诉接口。上报触发逻辑（装货完成/打款完成/开票完成自动触发）属于运八平台内部业务逻辑，API文档中未定义上报提交接口。

**上报接口（5个·Showdoc权威）** 由Showdoc文档定义，是运八平台向省平台上送数据的接口，与查询+申诉API是两个独立的接口体系：

| Showdoc上报接口 | URL | 说明 |
|:---|:---|:---|
| 上传委托合同（框架） | `/api/dataUpload/mandateContractFrame` | **前置步骤**：运单第一次上报前必须先上传框架合同 |
| 第一次上传 | `/api/dataUpload/firstUpload` | 装货完成后上报（含waybillInfo, consignorInfo, consigneeInfo, driverInfo, carInfo, goodsInfos, insuranceInformation） |
| 第二次上传 | `/api/dataUpload/secondUpload` | 打款完成后上报（含arrivalInfo, ownerStatements, carrierStatements, carrierContractInfo, ownerContractInfo, trackList） |
| 第三次上传 | `/api/dataUpload/thirdUpload` | 开票完成后上报（含invoice, oilGasInvoices） |
| ETC发票上传 | `/api/dataUpload/etcInvoiceUpload` | 税务抵扣确认后上传（含shippingNoteNumber, vehicleNumber, vehiclePlateColorCode, etcInvoices） |
| 修改第一次上报部分字段 | `/api/dataUpload/updateFirstUploadParam` | 第一次上报成功后更新变化字段 |

> **关键区分**: Showdoc的5个上报接口 + updateFirstUploadParam 是**数据上报**通道；PDF文档的9个接口是**查询+申诉**通道。两者共同构成运八平台的完整对接方案。

---

## 二、API接口清单（权威来源：接口文档 V1.0.2）

### 2.1 通用规范

| 项目 | 规范 |
|:---|:---|
| 基地址 | `http://*******/api/` |
| 协议 | HTTP POST |
| 请求格式 | JSON（除上传文件接口外） |
| 响应格式 | `{"code":200, "message":"操作成功", "data":{}}` |
| 认证 | JWT Token，调用 `/sys/login` 获取，除登录接口外均需在请求头携带 |
| 时间格式 | `yyyy-MM-dd HH:mm:ss` |
| 成功码 | `code=200` |
| 失败码 | `code=500` |

### 2.2 接口一览（共9个）

| # | 接口 | URL | 说明 |
|:---:|:---|:---|:---|
| 1 | 获取token | `POST /sys/login` | JWT认证，参数: loginName, loginPassword |
| 2 | 上传申诉附件 | `POST /appeal/uploadFile` | 文件上传，参数: file (File) |
| 3 | 提交申诉运单 | `POST /appeal/insert` | 发起申诉，参数: freightSheetNumber, complaintNumber, attachmentUrl, content, verificationAbnormalItems |
| 4 | 查询异常运单信息 | `POST /verificationSummary/page` | 分页查询，支持多维度筛选 |
| 5 | 查询申诉进度 | `POST /appeal/page` | 分页查询申诉记录及审核结果 |
| 6 | 查询运单核验详情 | `POST /verificationSummary/verificationDetail` | 单运单全部核验项明细 |
| 7 | 查询发票是否合规 | `POST /verificationSummary/cargoOwnerInvoiceInfo` | 判断托运人发票系统核验是否合规 |
| 8 | 运单里程核验查询 | `POST /verificationSummary/mileageVerificationInfo` | 批量查询运单里程核验状态 |
| 9 | 运单里程申诉 | `POST /mileageAppeal/insert` | 对里程核验结果发起申诉 |

### 2.3 接口详细定义

#### 接口1: 获取token
```
POST /sys/login
请求: { "loginName": "xxx", "loginPassword": "xxx" }
响应: { "code": 200, "data": { "token": "...", "expireTime": 1681219619843, "loginName": "ceshi", "name": "测试" } }
```

#### 接口2: 上传申诉附件
```
POST /appeal/uploadFile
请求: multipart/form-data, 字段 file (File)
```

#### 接口3: 提交申诉运单
```
POST /appeal/insert
请求:
  freightSheetNumber    String  运单号           必填
  complaintNumber       String  申诉编号          必填
  attachmentUrl         String  申诉附件URL       必填
  content               String  申诉内容          必填
  verificationAbnormalItems String 核验异常项ID   必填  (逗号分隔，如"120,160")
```

#### 接口4: 查询异常运单信息
```
POST /verificationSummary/page
请求:
  pageIndex              int     页码            必填
  pageSize               int     每页条数         必填
  freightSheetNumber     String  运单号           可选
  verificationAbnormalItems String 异常项ID       可选 (多个逗号拼接)
  driverName             String  驾驶员姓名       可选
  driverIdCard           String  驾驶员身份证号   可选
  vehicleNumber          String  车牌号           可选
  appealStateId          int     申诉状态ID       可选
  verifyStateId          int     核验状态ID       可选
  beginTime ~ endTime            运单创建时间范围  可选
  beginFirstVerifyTime ~ endFirstVerifyTime  首次核验时间范围  可选
  beginLastVerifyTime ~ endLastVerifyTime    最新核验时间范围  可选
  beginInsertTime ~ endInsertTime            插入时间范围      可选

响应:
  pageRecords[]:
    freightSheetNumber       String  运单号
    appealStateId            int     申诉状态ID
    appealStateName          String  申诉状态名称
    verificationAbnormalItem String  核验异常项
    createTime               date    运单创建时间
    lastVerifyTime           date    最新核验时间
    firstVerifyTime          date    首次核验时间
    vehicleNumber            String  车牌号
    driverName               String  驾驶员姓名
    driverIdCard             String  驾驶员身份证号
    verifyStateId            int     核验状态ID
    verifyStateName          String  核验状态名称
    abnormalDetails[]:
      id        int     异常项ID
      name      String  异常项名称
      message   String  异常原因
      time      date    异常时间
      state     int     异常项处理状态 (100=未申诉, 110=申诉中)
```

#### 接口5: 查询申诉进度
```
POST /appeal/page
请求:
  pageIndex          int     页码              必填
  pageSize           int     每页条数           必填
  freightSheetNumber String  运单号             可选
  abnormalTypeId     String  核验异常项ID        可选
  auditStateId       String  审核状态ID         可选
  beginTime ~ endTime        申诉时间范围        可选
  auditBeginTime ~ auditEndTime 审核时间范围     可选
  complaintNumber    String  申诉编号           可选

响应:
  pageRecords[]:
    complaintNumber          String  申诉编号
    freightSheetNumber       String  运单号
    content                  String  申诉内容
    complainantName          String  申诉人
    auditStateId             int     审核状态ID
    auditStateName           String  审核状态名称
    auditorName              String  审核人
    auditRemark              String  审核备注
    auditTime                date    审核时间
    verificationAbnormalItem String  运单异常项
    cancelPerson             String  取消人
    cancelReason             String  取消原因
    cancelTime               date    取消时间
    revokeUserName           String  撤回人
    revokeTime               date    撤回时间
    createTime               date    创建时间
    appealAbnormalList[]:
      verificationTypeId     int     异常项ID
      verificationTypeName   String  异常项名称
```

#### 接口6: 查询运单核验详情
```
POST /verificationSummary/verificationDetail
请求:
  freightSheetNumber  String  运单号  必填
  beginInsertTime     String  插入时间-开始  可选
  endInsertTime       String  插入时间-结束  可选

响应:
  pageRecords[].details[]:
    verificationCode      int     核验项编码
    verificationName      String  核验项名称
    verificationState     String  核验状态
    verificationStateId   int     核验状态ID
    verificationTime      date    核验时间
    message               String  核验信息
```

#### 接口7: 查询发票是否合规
```
POST /verificationSummary/cargoOwnerInvoiceInfo
请求: { "freightSheetNumber": "55141359" }
响应: { "isSystemVerification": true }  // true=系统核验合规, false=人工判定合规
```

#### 接口8: 运单里程核验查询
```
POST /verificationSummary/mileageVerificationInfo
请求: { "freightSheetNumberList": ["22222222", "111111"] }
响应: [
  { "verificationStateId": 110, "freightSheetNumber": "22222222", "mileage": 350.263 },
  { "verificationStateId": null, "freightSheetNumber": "4658151", "mileage": null }
]
// 注: 运单未上报里程时 verificationStateId 和 mileage 为 null
```

#### 接口9: 运单里程申诉
```
POST /mileageAppeal/insert
请求:
  freightSheetNumber  String  运单号    必填
  content             String  申诉内容  必填
  complaintNumber     String  申诉编号  必填
  mileage             String  里程数    必填
```

---

## 三、数据字典（权威来源：接口文档 §4.1~§4.5）

### 3.1 异常项ID对照表（§4.1）— 共17项

| Code | 名称 | 说明 |
|:---:|:---|:---|
| 100 | 委托合同 | 托运人与承运人签订的委托运输合同核验 |
| 120 | 承运合同 | 承运人以自身名义签订的运输合同核验 |
| 130 | 实时定位 | 车辆实时定位数据核验 |
| 140 | 运单时间逻辑 | 运单各时间节点的逻辑合理性核验（如装货时间<卸货时间） |
| 150 | 车辆资质 | 车辆道路运输经营许可证有效性核验 |
| 160 | 道路运输证 | 车辆道路运输证有效期核验 |
| 170 | 驾驶证 | 驾驶员驾驶证有效性核验 |
| 180 | 从业资格证 | 驾驶员从业资格证有效期核验 |
| 190 | 车辆重复 | 同一车辆在同一时段是否存在多运单 |
| 200 | 司机重复 | 同一司机在同一时段是否存在多运单 |
| 210 | 车辆轨迹 | GPS轨迹真实性、与运单路线匹配度核验 |
| 220 | 运费收款 | 运单是否在运费收款方名下 |
| 230 | 公司统一收款 | 是否通过公司账户统一收款 |
| 240 | 集中支付 | 是否通过网络货运平台集中支付 |
| 250 | 资金流水 | 资金流水单号唯一性、金额匹配核验 |
| 260 | 发票信息 | 托运人发票信息核验（第三次上报相关） |
| 270 | 非通行车辆可开票 | 非通行车辆是否允许开具通行费发票 |

### 3.2 运单核验状态（§4.2）

| Code | 名称 | 说明 |
|:---:|:---|:---|
| 100 | 未核验 | 运单尚未被省平台核验 |
| 110 | 核验通过 | 全部核验项通过 |
| 120 | 全部异常 | 存在核验不通过的异常项 |

### 3.3 运单部分核验状态（§4.3）

| Code | 名称 | 说明 |
|:---:|:---|:---|
| 100 | 未核验 | 尚未核验 |
| 110 | 部分核验 | 部分核验项已通过，仍有待核验项 |
| 120 | 全部核验 | 全部核验项已出结果 |

### 3.4 运单申诉状态（§4.4）— 权威枚举

| Code | 名称 | 说明 |
|:---:|:---|:---|
| **100** | **未申诉** | 尚未发起申诉 |
| **110** | **审核通过** | 省平台审核通过 |
| **120** | **审核不通过** | 省平台审核驳回 |
| **130** | **已取消** | 省平台侧操作，我方只读（申诉由省平台取消，非我方可操作状态） |

> **已取消(130)说明**: 状态130=已取消是**省平台侧直接操作**产生的状态，我方系统不提供"取消申诉"功能。运八平台只能查询到此状态，不能主动将申诉状态设为130。我方申诉状态流转不包含取消操作。

### 3.5 附件状态（§4.5）

| Code | 名称 | 说明 |
|:---:|:---|:---|
| 100 | 未处理 | 申诉附件尚未被省平台处理 |
| 110 | 处理通过 | 附件核验通过 |
| 120 | 处理异常 | 附件核验异常 |

---

## 四、功能模块（综合API文档+原型+原始需求）

### 4.1 上报运单看板

**入口**: 侧边栏 → 上报运单看板

**统计卡片**（原型定义）:
- 异常运单数、待申诉数、申诉中数、已处理数

**查询条件**（综合原型+接口4请求参数）:

| 筛选项 | 类型 | 可选值 |
|:---|:---|:---|
| 运单号/托运单号/货源单号 | 文本输入 | 模糊搜索 |
| 上报阶段 | 下拉 | 全部 / 第一次上报 / 第二次上报 / 第三次上报 |
| 核验状态 | 下拉 | 全部 / 异常 / 通过 |
| 申诉状态 | 下拉 | 全部 / 未申诉(100) / 审核通过(110) / 审核不通过(120) / 已取消(130·省平台只读) |

**列表字段**（原型为准，15列含勾选）:
货源单号 / 运单号 / 托运单号 / 车牌号 / 司机姓名 / 上报阶段 / 托运方名称 / 核验状态 / 申诉状态 / 异常项 / 货物名称 / 合同金额 / 最新核验时间 / 操作

**操作按钮**:
- 异常运单: [申诉] [详情]
- 申诉中运单: [进度] [详情]
- 正常运单: [详情]

**标签颜色**（原型CSS定义）:
- 蓝色 `.tag-blue`: 上传中、申诉中
- 绿色 `.tag-green`: 已上传、通过、已完成、申诉通过、对公账户
- 红色 `.tag-red`: 上传失败、异常、申诉驳回
- 橙色 `.tag-orange`: 异常项标签、待上报
- 灰色 `.tag-gray`: 未申诉
- 紫色 `.tag-purple`: (预留)

### 4.2 委托合同上传（前置步骤·Showdoc权威）

**来源**: Showdoc接口 `POST /api/dataUpload/mandateContractFrame`

**时机**: 在进行运单的第一次上报前，需先将委托合同（框架）通过此接口上传至省平台。

**说明**:
- 委托合同（框架）和委托合同**二选一**上报
- 文件信息可暂时不传，在修改委托合同时再补充合同文件
- 后续合同有新增或修改，再调用上传或修改接口即可
- 目前省平台不支持单独查询合同，可在运单第一次上报后，在运单信息中查看合同

**核心字段**:
| 参数 | 必选 | 说明 |
|:---|:---|:---|
| contract_number | 是 | 合同编号 |
| expire_time | 是 | 合同有效期截止时间 yyyy-MM-dd |
| unified_social_credit_identifier | 可选 | 单托运企业统一社会信用代码 |
| owner_enterprise_name | 可选 | 单托运企业名称 |
| enterpriseList | 可选 | 多托运企业列表（与单托运企业互斥，都传值默认取单） |
| uploadFileInfo | 否 | 文件信息（name / url / dataList三选一） |

### 4.3 第一次上报（装货完成）

**触发条件**: 运单装货完成 AND 货源税源地=安徽

**上报数据子对象**（以接口文档字段定义为准）:

| 子对象 | 必选/可选 | 核心字段（Showdoc权威定义） |
|:---|:---|:---|
| waybillInfo（建单信息） | 必选 | originalDocumentNumber, shippingNoteNumber, documentCreateTime(yyyyMMddHHmmss), carrier, unifiedSocialCreditIdentifier, permitNumber, businessTypeCode, goodsArrangementTypeCode, orderReceivingTime(yyyyMMddHHmmss), departureTime(yyyyMMddHHmmss), commercialContractNumber, contractNumber(可选), mileage(可选·3位小数) |
| consignorInfo（托运人信息） | 必选 | consignor, consignorId, frameContractNumber(可选), placeOfLoading, loadingLongitude(6位小数), loadingLatitude(6位小数), loadingCountrySubdivisionCode |
| consigneeInfo（收货方信息·6字段） | 必选 | consignee, consigneeId, goodsReceiptPlace, unLoadingLongitude(6位小数), unLoadingLatitude(6位小数), unLoadingNationSubdivisionCode |
| driverInfo（司机信息·15字段） | 必选 | driverName, telephone, drivingIdNumber, drivingLicense, vehicleClass, issuingOrganizations, validPeriodFrom(yyyyMMdd), validPeriodTo(yyyyMMdd), qualificationCertificate, provinceCode, qualificationCertificateFrom(可选), qualificationCertificateTo(可选), taxRegistrationCertificate(可选), registerDate(yyyyMMdd), anchoredUrl(可选·文件列表) |
| carInfo（车辆信息·20字段） | 必选 | vehicleNumber, vehiclePlateColorCode, vehicleType, LicensePlateTypeCode, owner, ownerId(可选), useCharacter, vin, issuingOrganizations, registerDate(yyyyMMdd), issueDate(yyyyMMdd), vehicleEnergyType, vehicleTonnage(Double), grossMass(Double), roadTransportCertificateNumber, trailerVehiclePlateNumber(可选), vehicleLicenseNumber(可选), roadTransportSocialCreditFrom(可选·yyyyMMdd), roadTransportSocialCreditTo(可选·yyyyMMdd), anchoredUrl(可选·文件列表) |
| goodsInfos（货物信息） | 必选，可多条 | descriptionOfGoods, cargoTypeClassificationCode, quantity(Double), unit |
| insuranceInformation（保险信息） | 可选 | policyNumber, insuranceCompany |

**业务规则**:
- 仅安徽税源地(省份代码=34，非28)运单触发
- 上报成功后自动调用"修改第一次上报部分字段"接口更新变化字段
- 失败自动重试最多3次，全部失败后站内信通知运营
- 第一次上报是后续上报的前置条件（后端校验）

**列表页**（原型为准，14列+勾选）:
货源单号 / 运单号 / 托运单号 / 车牌号 / 司机姓名 / 托运方名称 / 业务类型 / 货物名称 / 装货地址 / 卸货地址 / 运输里程 / 合同编号 / 上报状态 / 操作

**上报状态**（内部系统状态，非API枚举）:
- 上传中（蓝色）
- 已上传（绿色）
- 上传失败（红色）— 显示"手动上传"按钮
- 异常（橙色）

### 4.4 第二次上报（打款完成）

**触发条件**: 财务打款完成 AND 第一次上报已完成

**核验项**: 省平台自动核验，共17项（见§3.1）。每项独立产生核验结果，核验异常项可通过申诉机制逐项申诉。

**上报数据子对象**（Showdoc权威·第二次上传结构完全不同）:
| 子对象 | 必选/可选 | 核心字段 |
|:---|:---|:---|
| arrivalInfo（运抵信息） | 必选 | shippingNoteNumber, startTicketFileUrl(文件列表), arrivalTime(yyyyMMddHHmmss), arrivalTicketFileUrl(文件列表), waybillFreightAmount(Double·3位小数·承运运费), totalMonetaryAmount(Double·3位小数·委托运费) |
| ownerStatements（货主流水） | 必选 | documentNumber, carrier, actualCarrierId, paymentMeansCode, paymentName, paymentAccount, paymentBankName(选填), recipient, receiptAccount, receiptBankName(选填), sequenceCode, monetaryAmount(Double·3位小数), appointmentTime(yyyyMMdd), payTime(yyyyMMddHHmmss) |
| carrierStatements（承运人流水） | 必选 | documentNumber, carrier, actualCarrierId, paymentMeansCode, paymentName, paymentAccount, paymentBankName, recipient, receiptIdCard, receiptAccount, receiptBankName, sequenceCode, monetaryAmount(String·3位小数), appointmentTime(yyyyMMdd), payTime(yyyyMMddHHmmss), oilCardAmount(选填·3位小数), replaceAgreementFiles(可选·代收协议文件) |
| carrierContractInfo（承运合同） | 必选 | contractBusinessName, contractNumber, partyAName, partyAId, partyBName, partyBId, contractedCarryingCapacity(Double·3位小数), unit, contractAmount(Double·3位小数), agreedBusinessCompletionTime(yyyyMMdd), promisePayTime(yyyyMMdd), partyBReceiptName, partyBAccount, bankName(否), placeOfLoading, goodsReceiptPlace, descriptionOfGoods, vehicleNumber, contractSigningTime(yyyyMMddHHmmss), contractUrl(文件列表) |
| ownerContractInfo（委托合同） | 可选 | 18字段（委托合同与框架合同二选一上报） |
| trackList（车辆轨迹） | 必选，2~2000点 | locationMethod(BD/LBS/WECHAT/APP), locationTime(yyyyMMddHHmmss), locationAddress, longitude(6位小数), latitude(6位小数), trackType(LOADING/UNLOADING/NORMAL·可选) |

**列表页**（原型为准，17列+勾选）:
货源单号 / 运单号 / 托运单号 / 车牌号 / 司机姓名 / 托运方名称 / 承运运费 / 总金额 / 付款方式 / 付款时间 / 收款人 / 收款账号 / 收款账号类型 / 核验状态 / 异常项 / 上报状态 / 操作

**收款账号类型标签**: 个人账户=蓝色, 对公账户=绿色

### 4.5 第三次上报（开票完成）

**触发条件**: 发票开具完成 AND 第二次上报已完成

**前置条件**: 第二次上报必须完成（后端校验）

**API关联接口**: 
- `POST /verificationSummary/cargoOwnerInvoiceInfo` — 查询托运人发票系统核验是否合规
- 响应: `isSystemVerification`: true=系统核验合规, false=人工判定合规

**列表页**（原型为准，15列+勾选）:
货源单号 / 运单号 / 托运单号 / 发票号码 / 发票金额 / 税率 / 销售方名称 / 受票方名称 / 开票日期 / 油气票张数 / 核验状态 / 异常原因 / 上报状态 / 操作

### 4.6 ETC发票上传

**触发条件**: ETC发票税务抵扣成功后，由运营人员在运八系统**手动确认抵扣完成**，确认后系统触发ETC发票上传（非自动触发）

**列表页**（原型为准，10列+勾选）:
货源单号 / 运单号 / 托运单号 / ETC发票号 / 交易金额 / 入口收费站 / 出口收费站 / 交易时间 / 上传状态 / 操作

**详情弹窗字段**（原型为准）:
- 运单信息: 运单号、货源单号、托运单号、车牌号、司机姓名、托运方名称、收货方名称
- ETC发票信息: ETC发票号码、ETC发票代码、交易金额、税率(3%)、发票金额(不含税)、税额、入口收费站、出口收费站、交易时间、发票状态

### 4.7 异常申诉功能

**关联API接口**: 
- `POST /appeal/uploadFile` — 上传申诉附件
- `POST /appeal/insert` — 提交申诉
- `POST /appeal/page` — 查询申诉进度
- `POST /mileageAppeal/insert` — 里程申诉（独立接口）

**申诉流程**（闭环）:
```
异常运单查询(接口4) → 发起申诉(接口3) → 省平台复核 → 
查询申诉进度(接口5) → 审核通过(110) | 审核不通过(120) → 
重新申诉(接口3) [审核不通过时]
```

**申诉状态流转**（以API §4.4为准，我方可控流转）:
```
未申诉(100) → 提交申诉 → 未申诉(100) [申诉中·abnormalDetails.state=110]
未申诉(100) → 省平台审核通过 → 审核通过(110) [终态]
未申诉(100) → 省平台审核驳回 → 审核不通过(120) → 重新申诉 → 未申诉(100) [新申诉单]
```

> **已取消(130)**: 此状态由省平台侧操作产生（如省平台管理员取消申诉），我方系统不提供触发入口，仅被动查询和展示。因此不纳入我方申诉状态流转中。

**列表页**（原型为准，14列+勾选）:
运单号 / 托运单号 / 车牌号 / 司机姓名 / 托运方名称 / 上报阶段 / 核验状态 / 异常项 / 申诉状态 / 申诉时间 / 申诉人 / 省平台反馈结果 / 省平台反馈时间 / 操作

**详情弹窗分组**（原型为准）:
- 申诉信息: 申诉单号、上报阶段、异常项、申诉原因、申诉状态、申诉时间、申诉人、申诉附件
- 运单信息: 运单号、托运单号、车牌号、司机姓名、托运方名称
- 异常信息: 核验状态、异常原因、异常时间
- 省平台反馈信息: 反馈状态、反馈时间、反馈结果、反馈意见
- 处理记录（时间线）: 操作人、操作时间、操作类型、操作内容

### 4.8 上报日志

**查询条件**（原型为准）:
- 运单号/托运单号/货源单号: 模糊搜索
- 上报阶段: 全部 / 第一次上报 / 第二次上报 / 第三次上报 / ETC上传
- 上报结果: 全部 / 成功 / 失败
- 时间范围: 开始时间 ~ 结束时间

**列表字段**（原型为准，11列）:
序号 / 货源单号 / 运单号 / 托运单号 / 上报阶段 / 上报结果 / 接口URL / HTTP状态码 / 响应时间 / 上报时间 / 操作

**日志详情弹窗**: 展示完整请求报文（URL/Method/Headers/Body）和响应报文（StatusCode/Headers/Body），JSON格式化展示，支持一键复制。

---

## 五、状态枚举汇总（以API文档为权威）

### 5.1 申诉状态（API §4.4 权威）

| Code | 名称 | 原始需求对应 | 我方可操作 | 说明 |
|:---:|:---|:---|:---:|:---|
| 100 | 未申诉 | 未申诉 + 申诉中 | 是 | 含已提交但省平台尚未审核的情况（申诉中通过 abnormalDetails[].state=110 标识） |
| 110 | 审核通过 | 申诉通过 | 否（终态） | 省平台审核通过 |
| 120 | 审核不通过 | 申诉驳回 | 否（可重新申诉） | 省平台审核驳回，可重新发起申诉 |
| 130 | 已取消 | （无） | **否·省平台只读** | 省平台侧操作取消，我方仅查询展示 |

### 5.2 核验状态（API §4.2 权威）

| Code | 名称 | 说明 |
|:---:|:---|:---|
| 100 | 未核验 | 运单尚未核验 |
| 110 | 核验通过 | 全部17项核验通过 |
| 120 | 全部异常 | 存在核验异常项 |

### 5.3 异常项处理状态（API §4.1 子字段）

| Code | 名称 | 说明 |
|:---:|:---|:---|
| 100 | 未申诉 | 该异常项尚未发起申诉 |
| 110 | 申诉中 | 该异常项已提交申诉，待审核 |

### 5.4 上报状态（内部系统状态，非API枚举）

| 状态 | 标签颜色 | 说明 |
|:---|:---|:---|
| 上传中 | 蓝色 | 数据正在上报中 |
| 已上传 | 绿色 | 上报成功 |
| 上传失败 | 红色 | 上报超时或错误，显示"手动上传"按钮 |
| 异常 | 橙色 | 数据校验不通过 |

---

## 六、与原始需求的关键差异

| # | 项目 | 原始需求 | API/Showdoc（权威） | 影响 |
|:---:|:---|:---|:---|:---|
| 1 | 核验项数量 | 7类 | **17项** (API §4.1) | 测试覆盖需从14条扩展到34条 |
| 2 | 申诉状态 | 未申诉/申诉中/通过/驳回 | **未申诉(100)/审核通过(110)/审核不通过(120)/已取消(130·省平台只读)** | 申诉状态枚举全部更新，130不纳入我方流转 |
| 3 | 申诉"进行中" | 独立状态"申诉中" | 归属于"未申诉(100)"，由abnormalDetails[].state=110标识 | 状态机变更 |
| 4 | 已取消状态 | 无 | **130=已取消·省平台操作·我方只读** | 不提供"取消申诉"按钮，仅查询展示 |
| 5 | 里程申诉 | 无 | **独立接口** `/mileageAppeal/insert` | 新增功能模块 |
| 6 | 发票合规查询 | 无 | **独立接口** `/verificationSummary/cargoOwnerInvoiceInfo` | 新增功能点 |
| 7 | 核验状态 | 通过/异常（二元） | 未核验(100)/通过(110)/全部异常(120) | 新增"未核验"初始状态 |
| 8 | 附件状态 | 无 | 未处理(100)/处理通过(110)/处理异常(120) | 新增枚举 |
| 9 | 委托合同上传 | 无 | Showdoc **mandateContractFrame** 接口 | 新增前置步骤：第一次上报前必须先上传框架合同 |
| 10 | ETC触发方式 | 税务抵扣完成（自动） | **人工手动确认抵扣完成后触发** | 需要运营人员在运八系统手动确认 |
| 11 | 金额精度 | 2位小数 | **第二次上报金额3位小数**（Showdoc） | 金额存储和校验精度变更 |
| 12 | 时间格式 | `yyyy-MM-dd HH:mm:ss` | **上报接口用 `yyyyMMddHHmmss`（14位）**（Showdoc） | 上报数据格式化逻辑变更 |
| 13 | ETC invoiceAmount | 总金额 | **不含税金额**（Showdoc） | ETC发票金额语义变更 |

---

## 七、上报接口文档参考（Showdoc · 权威字段定义）

### 7.0 Showdoc通用规范

| 项目 | 规范 |
|:---|:---|
| 认证方式 | MD5签名Token（请求体JSON字符串+密钥 → MD5加密），非JWT |
| 请求格式 | `{"partnerId":"xxx", "appId":"xxx", "workerId":"001", "args":{...}}` |
| 成功码 | `code=200` |
| 失败码 | `code=500` |
| 时间戳 | 13位毫秒时间戳 |

> ⚠️ **关键差异**: Showdoc上报接口使用MD5签名Token，而查询+申诉API（PDF文档）使用JWT Token。两套认证体系独立。

### 7.1 字段精度关键差异（Showdoc vs 原始需求）

以下是从Showdoc文档中发现的与原始需求/原型不一致的关键字段定义：

| # | 字段相关 | 原始需求/原型假设 | Showdoc权威定义 |
|:---:|:---|:---|:---|
| 1 | **金额精度** | 保留2位小数 | **第二次上报金额保留3位小数**（arrivalInfo.waybillFreightAmount、totalMonetaryAmount、carrierStatements.monetaryAmount、ownerStatements.monetaryAmount、carrierContractInfo.contractAmount、contractedCarryingCapacity等均保留3位小数，如整数以.000填充） |
| 2 | **时间格式** | `yyyy-MM-dd HH:mm:ss` | **上报接口时间格式为 `yyyyMMddHHmmss`（14位）**（如documentCreateTime、orderReceivingTime、departureTime），日期字段用 `yyyyMMdd`（8位） |
| 3 | **第一次上报字段数** | consigneeInfo=5字段、driverInfo=13字段、carInfo=19字段 | Showdoc: consigneeInfo=6字段（含unLoadingNationSubdivisionCode）、driverInfo=15字段（含registerDate、anchoredUrl）、carInfo=20字段（含anchoredUrl）、goodsInfos.quantity=Double |
| 4 | **第二次上报结构** | 追加资金流水+轨迹 | Showdoc定义完全不同：arrivalInfo(含startTicketFileUrl+arrivalTicketFileUrl)+ownerStatements+carrierStatements+carrierContractInfo+ownerContractInfo(可选)+trackList；carrierStatements含oilCardAmount和replaceAgreementFiles |
| 5 | **第三次上报** | 发票17字段 | Showdoc: invoice明确17字段+invoiceUrl文件；oilGasInvoices选填 |
| 6 | **ETC发票** | invoiceAmount=发票总金额 | **invoiceAmount = 不含税金额**（not总金额!）；17个etcInvoices字段；税率格式x.x%（如3%） |
| 7 | **委托合同上传** | 未提及 | Showdoc有 `mandateContractFrame` 接口 — 之前完全遗漏！委托合同（框架）和委托合同二选一上报 |

### 7.2 Showdoc FAQ 关键摘录

以下FAQ影响功能设计和测试用例设计：

| 主题 | FAQ要点 |
|:---|:---|
| **运单不可取消/删除** | 服务平台不支持取消或删除运单，上传后不允许修改任何信息。建议企业在运单信息确认后再上传。 |
| **承运人流水核验时效** | 除承运人流水核验需等待次日银行提供数据后开始核验，其余核验项会在一至两小时内核验完成。 |
| **发票红冲流程** | 货主发票开具后需红冲：在服务平台企业端将货主发票作废，再将重新开具的发票通过第三次上传接口上传。 |
| **税率统一3%** | 承运人流水中的税率统一传3%，税额按3%计算。 |
| **油卡金额** | 在上传承运人流水时据实填写油卡金额（oilCardAmount），如一条运单存在多条承运人流水，可在任一承运人流水中填写。 |
| **委托合同（框架）上传时机** | 在进行运单第一次上报前需将框架合同通过接口上传至服务平台，后续合同有新增或修改再调用上传/修改接口。 |
| **轨迹点数** | 企业上传的轨迹点数需在2-2000之间。地址字段若无，传"-"。 |
| **核验结果查看** | 两种方式：①服务平台企业端查询；②对接服务平台异常查询接口实现在企业自有系统内查询、处理。 |
| **合规运单开票** | 运单必须上传至服务平台且核验通过后才允许开具货主发票；第二次上传完成后即可查看核验结果。 |

---

## 八、待确认项（14项 → 已确认14项 ✅）

> **更新 2026-07-14**: 以下14项已全部通过用户确认决议。方框标记为确认结果。

### 阻塞级（已确认）
1. ✅ **核验项展示**: API 17项核验全部展示，每项可独立申诉。analysis文档已明确。
2. ✅ **上报接口字段定义**: Showdoc文档为权威数据源。Showdoc定义5个上报接口 + updateFirstUploadParam，与PDF的9个查询+申诉接口分离。

### 重要级（已确认）
3. ✅ **申诉状态"已取消(130)"**: 省平台侧操作，我方只读，不提供"取消申诉"按钮。运单不可取消/删除。
4. ✅ **原型UI状态映射**: "待省平台反馈"和"反馈处理中"为UI层面的展示状态，对应API 未申诉(100)·申诉中。
5. ✅ **第三次上报列表字段**: 以原型15列为准。
6. ✅ **里程申诉与通用申诉**: 独立接口 `/mileageAppeal/insert`，与 `/appeal/insert` 分离。
7. ✅ **发票合规查询**: 独立接口 `/cargoOwnerInvoiceInfo`，独立于申诉流程。

### 参考级（已确认）
8. ✅ **自动重试间隔**: 当前方案5s/15s/30s合理可用。
9. ✅ **ETC税额**: 税率固定3%，税额按3%计算。
10. ✅ **申诉超时告警**: 7个工作日阈值可用。
11. ✅ **省份代码**: 安徽=34，与API文档一致。
12. ✅ **第二次上报详情弹窗缺失轨迹**: 确认为原原型Bug，增强版原型已包含轨迹表格。
13. ✅ **原型详情弹窗字段**: 以接口Showdoc定义为准。
14. ✅ **ETC触发条件**: ETC发票税务抵扣成功后，由运营人员在运八系统**手动确认抵扣完成**，确认后系统触发ETC发票上传（非自动触发）。
