docs(hjc): 一站式平台对接接口文档(入向接收 + 出向推送 + 鉴权/字段映射/配置/待确认)

This commit is contained in:
2026-09-09 10:48:59 +08:00
parent ab2f615067
commit 32a3d1918c
+225
View File
@@ -0,0 +1,225 @@
# 汇吉采 ↔ 一站式代理平台 对接接口文档
> 版本:v1.0
> 适用:汇吉采标书购买平台(下称「官方网」)与一站式代理平台(下称「一站式」)之间双向数据互通。
> 相关:鉴权规则见 `docs/一站式平台推送-接口鉴权规范.md`;建表见 `src/main/resources/sql/hjc_init.sql`。
---
## 0. 概述
| 方向 | 触发时机 | 接口 | 位置 |
|---|---|---|---|
| **入向**(一站式 → 官方网) | 项目流程走到「发布中标公告」时 | `POST {官方网}/api/hjc/push/project` | 官方网接收标书/中标公告数据,按 `projectNo` upsert 落库 |
| **出向**(官方网 → 一站式) | C 端购买标书**支付成功后** / 退款时 | `POST {一站式}/api/biz/createPurchaseDetails` | 官方网把购买记录/订单信息推送到一站式落盘 |
**共享凭证**(双方约定,不通过网络传输明文密钥):
| 参数 | 值 | 说明 |
|---|---|---|
| `appKey` | `HJC_Official_Website` | 调用方标识,明文放请求头 |
| `password` | `vQ8$kR3#mW6@xP2!nF` | 签名密钥(Secret),仅参与签名,**不进报文** |
---
## 1. 鉴权规范(双向通用)
请求头携带:
| Header | 示例 | 说明 |
|---|---|---|
| `appKey` | `HJC_Official_Website` | 双方一致 |
| `timestamp` | `202604080103` | 格式 `yyyyMMddHHmm`(24 小时,北京时区,精确到分) |
| `sign` | `9f7c…(32位小写hex` | 签名值 |
**签名算法**`sign = MD5(appKey + password + timestamp)`(无分隔符,小写 32 位)。
**校验顺序**(任一步不过即拒绝,建议返回 `401`/`400`):
1. `appKey == HJC_Official_Website`
2. `timestamp` 与接收方服务器当前时间差 **≤ ±10 分钟**(防重放)
3. 用约定 `password` 重算 `MD5(appKey+password+timestamp)`,与 `sign` 不区分大小写比对
> 完整规则、示例(Python/Java)与「明文 password 头」兼容退路见 `docs/一站式平台推送-接口鉴权规范.md`。
---
## 2. 入向接口:一站式 → 官方网(接收标书/中标公告)
### 2.1 接口地址
```
POST {官方网BaseUrl}/api/hjc/push/project
```
> 官方网侧需在 SecurityConfig 放行该路径(已内置,`/api/hjc/push/project` 为公开接口,鉴权由本接口的 appKey/sign 自行校验)。
### 2.2 请求头
| Header | 值 |
|---|---|
| `appKey` | `HJC_Official_Website` |
| `timestamp` | `yyyyMMddHHmm` |
| `sign` | `MD5(appKey+password+timestamp)` |
| `tenantId` | `10626`(官方网当前固定租户,**必传**,作为落库租户) |
| `Content-Type` | `application/json` |
### 2.3 请求体字段
| 字段 | 类型 | 必填 | 说明 | 对应内部字段 |
|---|---|---|---|---|
| `projectNo` | string | ✔ | 项目编号 | `project_no`upsert 主键) |
| `projectName` | string | ✔ | 项目名称 | `project_name` |
| `tenderPrice` | number | | 标书价格/信息服务费 | `tender_price` |
| `files` | string(JSON/逗号分隔) | | 标书附件 | `tender_file` |
| `tenderOnsaleTime` | string | | 开售时间 `yyyy-MM-dd HH:mm:ss` | `onsale_time` |
| `tenderOffsaleTime` | string | | 停售时间 `yyyy-MM-dd HH:mm:ss` | `offsale_time` |
| `bulletinName` | string | | 公告标题 | `bulletin_title` |
| `customerName` | string | | 招标人 | `tenderer` |
| `supplierName` | string | | 中标公司 | `winner_supplier` |
| `bidAmount` | number | | 中标金额 | `bid_amount` |
| `content` | string | | 公告正文 | `bulletin_content` |
| `fileList` | string(JSON/逗号分隔) | | 公告附件 | `bulletin_file_list` |
| `needSellTender` | number | | 是否卖标书 0/1 | `need_sell` |
| `sellingMethod` | number | | 售卖方式 1公司财务 2公众号 3交易中心 4政采云 | `selling_method` |
### 2.4 响应
```json
{
"code": 0,
"message": "接收成功",
"data": { "id": 12, "projectNo": "ZB-2026-0001", "projectName": "xxx", "dataSource": "PUSH", "status": 1 }
}
```
- `code == 0` 成功;`code != 0` 失败(如 `message=鉴权失败` / `租户ID不能为空` / `项目编号不能为空`)。
### 2.5 落库规则(官方网侧)
-`projectNo` **upsert**:不存在则插入(`tenantId=请求头tenantId``status=1` 上架,`dataSource=PUSH``saleCount=0`);已存在则更新推送到字段。
- 兼容性:`tenderOnsaleTime`/`tenderOffsaleTime` 支持 `yyyy-MM-dd HH:mm:ss``yyyyMMddHHmmss`、ISO 带 `T` 三种格式解析;解析失败置空。
- 其余标书项目字段(分类、上下架、人工维护数据)仍可在管理后台手工调整。
---
## 3. 出向接口:官方网 → 一站式(推送购买记录/订单)
### 3.1 接口地址
```
POST {一站式BaseUrl}/api/biz/createPurchaseDetails
```
### 3.2 触发时机
- **支付成功后**(官方网 `PUT /api/hjc/order/mark-paid` 置已付)自动推送,请求状态 `status=PAID`
- **退款时**(官方网 `POST /api/hjc/order/refund` 置已退款)推送,请求状态 `status=REFUNDED`
### 3.3 请求头
| Header | 值 |
|---|---|
| `appKey` | `HJC_Official_Website` |
| `timestamp` | `yyyyMMddHHmm` |
| `sign` | `MD5(appKey+password+timestamp)` |
| `Content-Type` | `application/json` |
> `password` 不进请求头;`sign` 每次发送须按新的 `timestamp` 重新计算。
### 3.4 请求体字段
| 字段 | 类型 | 说明 |
|---|---|---|
| `idempotencyKey` | string | 幂等键,`HJC_ORD_<orderNo>` |
| `orderNo` | string | 官方网订单号(一站式去重键) |
| `projectNo` | string | 项目编号 |
| `projectName` | string | 项目名称 |
| `tenderPrice` | number | 标书单价(信息服务费) |
| `quantity` | number | 购买数量 |
| `totalAmount` | number | 订单总额 |
| `buyer.enterpriseName` | string | 购买企业名称 |
| `buyer.creditCode` | string | 企业统一社会信用代码 |
| `buyer.contactName` | string | 经办人姓名 |
| `buyer.contactPhone` | string | 经办人手机号 |
| `buyer.contactEmail` | string | 经办人邮箱 |
| `paidAt` | string | 支付时间 `yyyy-MM-dd HH:mm:ss` |
| `payMethod` | string | `WECHAT_NATIVE` / `ALIPAY` |
| `status` | string | `PAID`(已支付)/ `REFUNDED`(已退款) |
| `invoiceStatus` | string | `NONE` / `APPLIED` / `ISSUED` |
请求体示例:
```json
{
"idempotencyKey": "HJC_ORD_HJC2026080101ABCD",
"orderNo": "HJC2026080101ABCD",
"projectNo": "ZB-2026-0001",
"projectName": "xxx采购项目",
"tenderPrice": 500.00,
"quantity": 1,
"totalAmount": 500.00,
"buyer": {
"enterpriseName": "某某科技有限公司",
"creditCode": "91110XXXX",
"contactName": "张三",
"contactPhone": "13800000000",
"contactEmail": "a@b.com"
},
"paidAt": "2026-08-01 10:30:00",
"payMethod": "WECHAT_NATIVE",
"status": "PAID",
"invoiceStatus": "NONE"
}
```
### 3.5 响应约定
- 一站式按自身 `API` 返回;官方网侧把 `HTTP 2xx` 视为成功,否则记入推送日志(`hjc_order_push_log`)待重试。
- **幂等**:建议一站式以 `orderNo`/`idempotencyKey` 去重,同单重复提交返回成功、不重复插入。
### 3.6 重试策略(官方网侧)
- 失败(非 2xx / 网络异常)写入 `push_status=2``next_retry_time = now + 30min``attempt_count + 1`
- 由定时任务 `retryPendingPush()` 扫描待推送/失败记录重发;重发时 `timestamp/sign` 重新计算。
---
## 4. 字段映射总表
| 一站式字段 | 含义 | 官方网内部字段 |
|---|---|---|
| `projectNo` | 项目编号 | `hjc_bid_project.project_no` |
| `projectName` | 项目名称 | `project_name` |
| `tenderPrice` | 标书价格 | `tender_price` |
| `files` | 标书附件 | `tender_file` |
| `tenderOnsaleTime` | 开售时间 | `onsale_time` |
| `tenderOffsaleTime` | 停售时间 | `offsale_time` |
| `bulletinName` | 公告标题 | `bulletin_title` |
| `customerName` | 招标人 | `tenderer` |
| `supplierName` | 中标公司 | `winner_supplier` |
| `bidAmount` | 中标金额 | `bid_amount` |
| `content` | 公告正文 | `bulletin_content` |
| `fileList` | 公告附件 | `bulletin_file_list` |
| `needSellTender` | 是否卖标书 | `need_sell` |
| `sellingMethod` | 售卖方式 | `selling_method` |
---
## 5. 配置清单(待双方/部署方填写)
| 项 | 值 | 位置 |
|---|---|---|
| 官方网 base-url | `http://<官方网域名>/api` | 一站式侧调用方配置 |
| 一站式 base-url | `http://<一站式域名>` | `mp-java/application.yml``hjc.one-stop.base-url` |
| createPurchaseDetails 路径 | `/api/biz/createPurchaseDetails` | `hjc.one-stop.create-purchase-details-path` |
| `appKey` | `HJC_Official_Website` | 双方约定 |
| `password` | `vQ8$kR3#mW6@xP2!nF` | 双方约定 |
| 租户 ID | `10626` | 官方网请求头 `tenantId` |
---
## 6. 待确认事项
1. 出向 `sign` 拼接顺序(`appKey+password+timestamp`)与一站式既有算法是否一致;不一致请给出一站式现网签名规范。
2. `timestamp` 格式、时区、±10min 窗口是否认可。
3. `createPurchaseDetails` 字段名是否需与一站式现网入参完全一致(现按本表定义);如需调整字段名请给出一站式入参清单。
4. 入向:一站式调用官方网 `/api/hjc/push/project` 时是否也按同一套 `appKey/timestamp/sign` 鉴权(本表默认对称鉴权)。