- pipeline.py: ETC 开票信息写入 base_etc_invoice + 推送记录写入 tms_order_etc_push, 随 receipt 阶段执行; 每单发票条数可配 (etc_invoice.count), 发票号/金额/进出站/时间自动变化, 金额合计受运费×50%约束; order_code/order_no 取步骤 03 的 orderCode, push_order_no 追加 -1, dry-run 仅预览不写库 - config.yaml: 新增 etc_invoice 配置节 + 刷新登录 token - README.md: 阶段 E 流程图、接口表 Step 22/23 及取值说明
11 KiB
yun8 运输流程完整自动化
将 yun8.postman_collection.json 中 "运输流程" 全部 18 个接口 + SQL 写入实现为 Python 流水线。
流程概览
┌─────────────────────────────────────────────────────────────────┐
│ 阶段 A: 司机端 (Step 01-05) │
│ 查询货源 → 接单 → 查询待运输单 → 装货 → 卸货 │
│ 变量: mainOrderCode → code / vehicleCode / orderCode │
├─────────────────────────────────────────────────────────────────┤
│ 阶段 B: 运费核算 (Step 06-09) │
│ 查询运单 → 运单详情 → 核算试算 → 核算提交 │
│ 变量: 30+ 核算字段 + ticketImageUrls │
├─────────────────────────────────────────────────────────────────┤
│ 阶段 C: 审核 & 付款 (Step 10-14) │
│ 查询审核 → 审核通过 → 油卡充值 → 司机打款 → 货主打款 │
├─────────────────────────────────────────────────────────────────┤
│ 阶段 D: 回单文件 + SQL (Step 15-18) │
│ 运单上传(payNo) → 打款记录 → 文件名前缀 → INSERT → 上报运单 │
├─────────────────────────────────────────────────────────────────┤
│ 阶段 E: ETC 开票 SQL (Step 22-24) │
│ 写入 base_etc_invoice (多条) → 写入 tms_order_etc_push │
│ → 更新 tms_order_detail 开票状态 │
└─────────────────────────────────────────────────────────────────┘
上下游变量传递
| 步骤 | 产出变量 | 消费步骤 |
|---|---|---|
| 01 查询货源 | mainOrderCode, residueNumber |
02, 09 |
| 03 查询待运输单 | code, vehicleCode, orderCode |
04-18 |
| 06 运费核算 | 30+ 字段 (branchCode, oilFee, ...) | 09, 12 |
| 07 运单详情 | deliveryCashFee, driverActualFreight, ... |
09, 13 |
| 08 核算试算 | ticketImageUrls |
09 |
| 15 运单上传 | payNo (sendMsg 正则提取) |
SQL |
| 16 打款记录 | 所有 code |
17 |
| 17 文件名前缀 | filePrefix |
SQL |
安装
cd yun8_sync
pip install -r requirements.txt
配置
编辑 config.yaml:
Token(二选一)
auth:
driver_token: "Bearer xxx" # 写在配置文件
admin_token: "Bearer yyy"
或命令行传入 --auth-driver / --auth-admin(命令行优先)。
重量模式
driver_params:
weight_mode: "fixed" # fixed=固定值 / random=每次随机 1.0~10.0
per_weight: "10" # fixed 模式:接单单位重量
weight: "10" # fixed 模式:装货/卸货重量
- fixed: 使用配置的固定值
- random: 每次循环随机生成 1.0~10.0 小数(一位小数),
per_weight和weight自动保持一致
核算/付款参数
accounting:
branch_code: "49adb23841asw3118yunnanchenggang"
business_type_code: "1003999"
payee_code: "16d0c260f7e34967b36113c770e03486"
shipment_phone: "15198908093"
shipment_party_code: "ce8b73b38cf6450d84740cf23aa4ed52"
settlement_type: "2"
payment:
pay_types: "3,4,5,9,10,11"
pay_platform: "3"
sms_code: "1234"
phone: "13888888888"
pay_type: "arpa_2"
注:
branchCode/businessTypeCode/payeeCode/shipmentPhone/shipmentPartyCode会优先从 step06 返回值中读取,配置仅作兜底。
数据库
database:
host: "36.137.133.24"
port: 3306
user: "root"
password: "Rgxi3!kD9jjXpgzx"
database: "ntocc"
charset: "utf8mb4"
SQL 模板
sql:
file_name_template: "{file_prefix}_1_signed.pdf"
template: |
INSERT INTO `ntocc`.`base_gd_mft_file` (...) VALUES (...)
占位符 {file_prefix} 和 {pay_no} 由流水线自动填充。
使用
命令行参数
| 参数 | 说明 | 默认值 |
|---|---|---|
--config |
配置文件路径 | ./config.yaml |
--auth-driver |
司机端 Bearer Token | 读取 config |
--auth-admin |
管理端 Bearer Token | 读取 config |
--stage |
运行阶段: all / driver / accounting / payment / receipt |
all |
--dry-run |
仅预览 SQL,不写库 | False |
--repeat |
循环执行次数 | 1 |
--delay |
每次循环间隔秒数 | 0 |
分阶段运行
# 完整流程(18步)
python main.py --auth-driver "Bearer xxx" --auth-admin "Bearer yyy"
# 仅跑司机端 (Step 01-05)
python main.py --stage driver --auth-driver "Bearer xxx" --auth-admin "Bearer yyy"
# 仅跑运费核算 (Step 06-09)
python main.py --stage accounting --auth-driver "Bearer xxx" --auth-admin "Bearer yyy"
# 仅跑审核付款 (Step 10-14)
python main.py --stage payment --auth-driver "Bearer xxx" --auth-admin "Bearer yyy"
# 仅跑回单+SQL+上报 (Step 15-18)
python main.py --stage receipt --auth-driver "Bearer xxx" --auth-admin "Bearer yyy"
独立运行
payment或receipt阶段时,会自动从 admin 端补全前置数据(code/orderCode),无需手动指定。
循环执行
# 完整流程循环 10 次,每次间隔 5 秒
python main.py --repeat 10 --delay 5
# 仅 receipt 阶段循环 100 次
python main.py --stage receipt --repeat 100 --delay 2
# 配合 random 重量模式,每次自动换新重量
python main.py --repeat 50 --delay 3
每次循环独立创建 Pipeline,变量上下文重置。某次失败不中断后续循环,Ctrl+C 随时停止。
预览模式
# 不写数据库,仅打印 SQL
python main.py --dry-run
# 循环预览
python main.py --repeat 5 --dry-run
Token 从配置文件读取(无需命令行)
在 config.yaml 中填写 auth.driver_token 和 auth.admin_token,然后:
python main.py --repeat 100
故障处理
| 现象 | 处理方式 |
|---|---|
| WAF 拦截 (SQL注入误判) | 已内置:直连服务器 + 手工 query string 编码 |
| "运单正被处理中" | 已内置:自动重试 5 次,间隔递增 5~13s |
| "货运单不存在" | Token 过期或运单状态不对,检查 admin token |
| 独立阶段提示 code 为空 | 已内置:自动从 admin 端补全 |
| GBK 编码报错 | 已修复:全部输出使用纯 ASCII 字符 |
项目结构
yun8_sync/
├── config.yaml # 配置文件 (API / Auth / 重量 / 核算 / 付款 / DB / SQL)
├── client.py # HTTP 客户端 (18 个接口 + Pre/Post 脚本逻辑)
├── pipeline.py # 流程编排 (Postman 变量上下文 + 步骤串联 + 重试)
├── db.py # 数据库操作 (INSERT)
├── main.py # CLI 入口 (分阶段 + 循环 + dry-run)
├── requirements.txt # Python 依赖
└── README.md # 本文件
接口对照表
| Step | 名称 | 方法 | 路径 | Auth |
|---|---|---|---|---|
| 01 | 查询货源 | GET | /ntocc-tms-api/order/orderHallList |
Driver |
| 02 | 接单 | POST | /ntocc-tms-api/orderDetail/receive |
Driver |
| 03 | 查询待运输单 | GET | /ntocc-tms-api/orderDetail |
Driver |
| 04 | 装货 | PUT | /ntocc-tms-api/orderDetail/fill |
Driver |
| 05 | 卸货 | PUT | /ntocc-tms-api/orderDetail/uploadTicketImage |
Driver |
| 06 | 运费核算查询运单 | GET | /ntocc-tms-api/orderDetail/orderDetailHandlePageList |
Admin |
| 07 | 查询运单详情 | POST | /ntocc-tms-api/orderDetail/getOrderDetailExpensesParamList |
Admin |
| 08 | 核算试算 | PUT | /ntocc-tms-api/orderDetail/calculateOrderDetail |
Admin |
| 09 | 核算提交 | PUT | /ntocc-tms-api/orderDetail/orderHandleEditSubmitHandle |
Admin |
| 10 | 查询运单审核 | GET | /ntocc-basic-api/dytBusiness/orderDetail |
Admin |
| 11 | 核算审核通过 | POST | /ntocc-tms-api/orderDetail/auditOrderDetail |
Admin |
| 12 | 单油卡充值 | POST | /ntocc-tms-api/finance/singleOil |
Admin |
| 13 | 垫资-财务打款 | POST | /ntocc-tms-api/arpaTransfer/payToDriver |
Admin |
| 14 | 垫资-货主打款 | POST | /ntocc-tms-api/orderDetail/applicationForPayment |
Admin |
| 15 | 查询运单上传 | GET | /ntocc-basic-api/dytBusiness/orderDetail?status=5 |
Admin |
| 16 | 查询打款记录 | GET | /ntocc-tms-api/remitDefinite |
Admin |
| 17 | 查询文件名前缀 | GET | /ntocc-tms-api/centralizedPayment/downLoadElectronicReceipt |
Admin |
| 18 | 上报运单 | POST | /ntocc-basic-api/dytBusiness/reportOrderDetail |
Admin |
| — | SQL INSERT | — | ntocc.base_gd_mft_file |
— |
| 22 | ETC 开票信息写入 | SQL INSERT | — | ntocc.base_etc_invoice |
| 23 | ETC 推送记录写入 | SQL INSERT | — | ntocc.tms_order_etc_push |
| 24 | 运单 ETC 开票状态更新 | SQL UPDATE | — | ntocc.tms_order_detail |
步骤 22 每个运单插入
etc_invoice.count条发票(config.yaml 配置,默认 3),每条的发票号码(随机 20 位数字)、金额(随机分配,所有发票合计 ≤ 运费×50%,运费优先取driverActualFreight、缺失时取shipmentActualFreight,超限或运费未知则跳过发票写入)、进站/出站(按广东→河北路段链取相邻两站)、时间(交易时间在运单窗口内逐条推进)各不相同;税额、开票方、发票类型、URL 等其余字段用固定值。 步骤 22/23 的order_code/order_no取步骤 03 的orderCode,push_order_no为其后追加-1,order_detail_code取步骤 03 的code,两个表的code按现有数据规则(32 位十六进制)自动生成,随 receipt 阶段执行(--dry-run仅预览不写库)。 步骤 23 的推送记录固定写入invoice_pull_status=2、start_status=1、end_status=1、start_result='成功'、end_result='成功';步骤 24 将步骤 03orderCode对应运单的etc_invoice_status置为 3。