Files
xin-procurement-weapp/mini-order-bill-api.md
T
2026-08-14 20:21:50 +08:00

428 lines
15 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.
# 小程序订单与账单接口文档
> 适用端:微信小程序(h5 仓库,Taro)
> 覆盖接口:订单列表 / 订单详情、账单列表 / 账单详情
> 更新日期:2026-08-14
## 通用约定
| 项 | 说明 |
|---|---|
| 根地址 | `BASE_URL`(见 `src/utils/request.ts`,如 `http://localhost:8000/index.php` |
| 认证 | 请求头 `Authorization: Bearer {token}`,token 来自登录接口,本地存储 key `auth_token` |
| 响应包络 | `{ success: boolean, data: T, msg?: string, showType?: number }` |
| 分页结构 | `{ data: T[], total: number, pageSize: number, current: number }`(账单列表在此结构上附加 `summary` |
| 失败处理 | `success=false``msg` 为中文错误信息(含参数校验失败);HTTP 401 表示登录过期,需重新登录 |
| 金额字段 | 一律为**字符串**(decimal 序列化,如 `"140.00"`),直接展示即可;参与计算需自行转 number |
| 门店隔离 | 两个列表均强制按当前用户绑定门店过滤,无需也不能传门店参数 |
## 状态枚举
**订单状态(status**
| 值 | 名称 | 说明 |
|---|---|---|
| 0 | 待接单 | 下单成功待后台接单,**仅此状态可取消** |
| 1 | 已接单 | 后台已接单,等待归集生成采购单 |
| 2 | 采购中 | 已归集进采购单 |
| 3 | 配送中 | |
| 4 | 已完成 | |
| 9 | 已取消 | |
**账单支付进度(pay_state**——由后端推导,覆盖原始支付状态(status)的展示口径
| 值 | 名称 | 推导条件 | 说明 |
|---|---|---|---|
| 0 | 待支付 | status=0 且 payment_id=0 | `can_pay=true`,可发起合并付款 |
| 1 | 审核中 | status=0 且 payment_id>0 | 已提交合并付款凭证,待后台审核;**审核拒绝后自动回到待支付** |
| 2 | 已支付 | status=1 | 线上审核通过或后台线下收款登记 |
---
## GET /mini/order
门店历史订单列表,按订货日期倒序(同日期按 ID 倒序)分页。行数据附带**商品预览**(前 3 条明细),完整明细请调订单详情。
- **权限**:需登录且已绑定正常门店
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| status | number | 否 | 订单状态(见枚举表),不传=全部 |
| start_date | string | 否 | 订货日期起,`Y-m-d`;可配合 `/mini/order/summary` 返回的 `period_label` 下钻 |
| end_date | string | 否 | 订货日期止,`Y-m-d`,不得早于 start_date |
| page | number | 否 | 页码,默认 1 |
| pageSize | number | 否 | 每页数量,默认 10**最大 50** |
### 响应示例
```json
{
"success": true,
"msg": "ok",
"data": {
"data": [
{
"id": 1024,
"order_no": "SO202608140001",
"order_date": "2026-08-14",
"status": 0,
"status_name": "待接单",
"can_cancel": true,
"total_quantity": 8,
"total_weight": "0.000",
"total_amount": "44.00",
"remark": "下午送到",
"purchase_id": 0,
"bill_id": 0,
"created_at": "2026-08-14 09:30:00",
"item_count": 4,
"items": [
{ "product_name": "白菜", "quantity": 2, "unit": "件" },
{ "product_name": "土豆", "quantity": 2, "unit": "件" },
{ "product_name": "番茄", "quantity": 2, "unit": "件" }
]
}
],
"total": 36,
"pageSize": 10,
"current": 1
}
}
```
### 字段说明(列表行)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | number | 订单 ID |
| order_no | string | 订单编号(SO 前缀) |
| order_date | string | 订货日期 `Y-m-d` |
| status | number | 订单状态(见枚举表) |
| **status_name** | string | 状态中文名,**直接展示,前端不要再硬编码映射** |
| **can_cancel** | boolean | 是否可取消(=待接单);取消按钮据此渲染 |
| total_quantity | number | 订货总数量(件/包数) |
| total_weight | string | 总称重(斤,手动录入参考值,常为 0) |
| total_amount | string | 订单金额 |
| remark | string | 订单备注,可能为空字符串 |
| purchase_id | number | 关联采购单 ID0=未归集 |
| bill_id | number | 关联账单 ID0=未出账(>0 可跳账单详情) |
| created_at | string | 下单时间 `Y-m-d H:i:s` |
| **item_count** | number | 明细种数(如「共 4 种」) |
| **items** | array | 商品预览,**仅前 3 条**(`product_name` / `quantity` / `unit`),完整明细走详情接口 |
---
## GET /mini/order/{id}
订单详情(校验本店归属),返回订单全部字段 + 完整明细(`items` 数组,含下单时商品快照)。
- **权限**:需登录且已绑定正常门店;非本店订单返回 `success=false`「订单不存在」
### 响应示例
```json
{
"success": true,
"msg": "ok",
"data": {
"id": 1024,
"order_no": "SO202608140001",
"store_id": 3,
"order_date": "2026-08-14",
"total_quantity": 8,
"total_weight": "0.000",
"total_amount": "44.00",
"status": 0,
"remark": "下午送到",
"purchase_id": 0,
"bill_id": 0,
"created_at": "2026-08-14 09:30:00",
"items": [
{
"id": 501,
"order_id": 1024,
"product_id": 11,
"product_name": "白菜",
"product_spec": "约30斤/件",
"unit": "件",
"price": "5.50",
"quantity": 2,
"weight": "0.000",
"amount": "11.00",
"remark": ""
}
]
}
}
```
### 字段说明
订单本体字段同列表行(无 `status_name` / `can_cancel` / 预览字段,状态展示沿用列表行数据或自行映射);`items` 为完整明细:
| 字段 | 类型 | 说明 |
|---|---|---|
| product_name / product_spec / unit | string | 下单时商品快照(品名/规格包规/单位),商品档案后续变更不影响 |
| price | string | 下单时门店等级实际价快照 |
| quantity | number | 订货量(件/包数) |
| weight | string | 称重(斤,参考值) |
| amount | string | 明细金额 = price × quantity |
---
## GET /mini/bill
门店账单列表(采购单完成后由后台按门店生成,门店端只读),按账单日期倒序分页。响应在分页结构上**附加 `summary` 待支付汇总**(仅按门店口径统计,不受筛选参数影响),供页面头部与合并付款入口展示。
- **权限**:需登录且已绑定正常门店
### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| status | number | 否 | 原始支付状态:0 未支付(含审核中)/ 1 已支付,不传=全部 |
| payable | number | 否 | 传 `1` = 仅可发起付款的账单(未支付且未在审核中),**合并付款选择页专用** |
| start_date | string | 否 | 账单日期起,`Y-m-d` |
| end_date | string | 否 | 账单日期止,`Y-m-d`,不得早于 start_date |
| page | number | 否 | 页码,默认 1 |
| pageSize | number | 否 | 每页数量,默认 10**最大 50** |
### 响应示例
```json
{
"success": true,
"msg": "ok",
"data": {
"data": [
{
"id": 88,
"bill_no": "ZD202608140001",
"bill_date": "2026-08-14",
"purchase_id": 31,
"purchase": { "id": 31, "purchase_no": "PO202608130001", "purchase_date": "2026-08-13" },
"product_amount": "100.00",
"delivery_fee": "10.00",
"box_num": 2,
"tray_num": 1,
"box_price": "5.00",
"tray_price": "20.00",
"added_amount": "30.00",
"total_amount": "140.00",
"status": 0,
"status_name": "未支付",
"pay_state": 0,
"pay_state_name": "待支付",
"can_pay": true,
"payment_id": 0,
"settlement_date": "2026-08-17",
"paid_at": null,
"pay_remark": "",
"remark": "",
"created_at": "2026-08-14 03:17:01"
}
],
"total": 12,
"pageSize": 10,
"current": 1,
"summary": { "unpaid_count": 3, "unpaid_amount": "420.50" }
}
}
```
### 字段说明(列表行)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | number | 账单 ID |
| bill_no | string | 账单编号(ZD 前缀) |
| bill_date | string | 账单日期(出账日)`Y-m-d` |
| purchase_id | number | 关联采购单 ID |
| purchase | object \| null | 关联采购单 `{ id, purchase_no, purchase_date }` |
| product_amount | string | 商品金额(订单汇总快照,不可修改) |
| delivery_fee | string | 配送费 |
| box_num / tray_num | number | 周转筐 / 周转托盘数量 |
| box_price / tray_price | string | 筐 / 托盘单价(出账时快照) |
| added_amount | string | 附加金额 = box_num×box_price + tray_num×tray_price |
| total_amount | string | **账单总金额 = 商品金额 + 配送费 + 附加金额** |
| status | number | 原始支付状态:0 未支付 / 1 已支付(展示用 pay_state 系列字段) |
| status_name | string | 支付状态中文名 |
| **pay_state** | number | 支付进度:0 待支付 / 1 审核中 / 2 已支付(见枚举表) |
| **pay_state_name** | string | 支付进度中文名,**列表状态标签直接用它** |
| **can_pay** | boolean | 是否可勾选发起合并付款(=待支付) |
| payment_id | number | 关联支付记录 ID,0=未发起付款;审核中时可跳支付记录详情查看进度 |
| **settlement_date** | string | 应结算日期 = 账单日期 + 门店回款周期天数 |
| paid_at | string \| null | 付款时间(已支付时非空) |
| pay_remark | string | 付款备注(如「微信支付(支付单号 ZF…)」、线下收款说明) |
| remark | string | 账单备注 |
| created_at | string | 出账时间 |
### summary 字段
| 字段 | 类型 | 说明 |
|---|---|---|
| unpaid_count | number | 待支付账单笔数(**含审核中**) |
| unpaid_amount | string | 待支付金额合计(含审核中) |
---
## GET /mini/bill/{id}
账单详情(校验本店归属):账单信息(字段同列表行)+ 合并后的商品明细 + 关联订单。
- **权限**:需登录且已绑定正常门店;非本店账单返回 `success=false`「账单不存在」
### 响应示例
```json
{
"success": true,
"msg": "ok",
"data": {
"bill": { "id": 88, "bill_no": "ZD202608140001", "...": "(字段同列表行)" },
"items": [
{
"product_id": 11,
"product_name": "白菜",
"product_spec": "约30斤/件",
"unit": "件",
"price": "5.50",
"quantity": 20,
"weight": "0.000",
"amount": "110.00"
}
],
"orders": [
{
"id": 1024,
"order_no": "SO202608130001",
"order_date": "2026-08-13",
"total_quantity": 8,
"total_weight": "0.000",
"total_amount": "44.00",
"status": 4
}
]
}
}
```
### 字段说明
- **bill**:与列表行完全一致(含 `pay_state_name` / `can_pay` / `settlement_date` 等派生字段)
- **items**:按商品聚合的合并明细(跨本账单全部订单),`price` 为加权平均口径(Σ金额÷Σ数量,保证 单价×数量=金额);`quantity` 为合计数量(number)、`amount` 为合计金额
- **orders**:本账单关联的门店订单(单价明细可继续下钻 `GET /mini/order/{id}`),`status` 为订单状态枚举
---
## 前端接入示例
`src/types/order.ts` 关键类型(列表行替换为接口返回,**删除本地 `ORDER_STATUS_MAP` 硬编码**):
```ts
/** 订单列表行(状态名/可取消/商品预览均由后端给出) */
export interface OrderListItem {
id: number
order_no: string
order_date: string
status: number
status_name: string
can_cancel: boolean
total_quantity: number
total_weight: string
total_amount: string
remark: string
purchase_id: number
bill_id: number
created_at: string
item_count: number
items: Array<{ product_name: string; quantity: number; unit: string }>
}
```
`src/services/bill.ts`**替代旧 `statement.ts`——旧 `/mini/statement` 已下线**):
```ts
import { get } from '@/utils/request'
import type { PaginatedData } from '@/types/api'
/** 账单(列表行与详情的 bill 字段一致) */
export interface Bill {
id: number
bill_no: string
bill_date: string
purchase_id: number
purchase: { id: number; purchase_no: string; purchase_date: string } | null
product_amount: string
delivery_fee: string
box_num: number
tray_num: number
box_price: string
tray_price: string
added_amount: string
total_amount: string
status: 0 | 1
status_name: string
/** 支付进度:0 待支付 / 1 审核中 / 2 已支付 */
pay_state: 0 | 1 | 2
pay_state_name: string
can_pay: boolean
payment_id: number
settlement_date: string
paid_at: string | null
pay_remark: string
remark: string
created_at: string
}
export interface BillSummary {
unpaid_count: number
unpaid_amount: string
}
export interface BillDetail {
bill: Bill
items: Array<{
product_id: number; product_name: string; product_spec: string
unit: string; price: string; quantity: number; weight: string; amount: string
}>
orders: Array<{
id: number; order_no: string; order_date: string
total_quantity: number; total_weight: string; total_amount: string; status: number
}>
}
/** 账单列表:GET /mini/billpayable=1 为合并付款选择页口径) */
export function getBillListApi(
params: { status?: number; payable?: 1; start_date?: string; end_date?: string; page?: number; pageSize?: number } = {},
) {
return get<PaginatedData<Bill> & { summary: BillSummary }>('/mini/bill', { data: params })
}
/** 账单详情:GET /mini/bill/{id} */
export function getBillDetailApi(id: number) {
return get<BillDetail>(`/mini/bill/${id}`)
}
```
订单列表行商品预览渲染建议:
```tsx
<Text className='order-item__preview'>
{order.items.map(i => `${i.product_name}×${i.quantity}`).join('、')}
{order.item_count > 3 ? ` 等${order.item_count}种` : ''}
</Text>
```
## 注意事项
1. **状态文案一律用接口返回的 `status_name` / `pay_state_name`**:订单状态为 6 态(0/1/2/3/4/9),h5 现有 `ORDER_STATUS_MAP` 是旧 5 态(缺采购中/配送中),继续硬编码会显示异常。
2. **账单状态标签用 `pay_state_name` 而非 `status`**`status=0` 同时覆盖「待支付」与「审核中」两种展示;`payable=1` 筛选与 `can_pay` 同口径(待支付),合并付款页直接用它。
3. **审核拒绝后账单自动回到待支付**payment_id 归零),列表刷新即可重新勾选付款,无需额外处理。
4. `summary` 统计的是**全部门店口径**(含审核中),与列表筛选参数无关;筛选「已支付」时 summary 仍返回待支付汇总。
5. 订单列表 `items` 仅为前 3 条预览(`item_count` 为总种数),完整明细必须调详情接口;两个详情接口均校验门店归属,跨店访问返回「不存在」。
6. `settlement_date` 由门店回款周期实时计算(门店改周期后历史账单随之变化),如需固化口径请后续提需求加快照列。
7. 参数校验失败与业务失败一样返回 `success=false` + 中文 `msg`(HTTP 200),无需特殊分支处理。