Files
baiyue-firstleg/docs/phase1-local-api.md
T
2026-07-31 13:52:35 +08:00

272 lines
10 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.
# 一期本地联调 API 文档
## 1. 通用约定
统一基地址:`http://127.0.0.1:9000`;局域网前端使用 `http://192.168.110.149:9000`。除登录、注册、刷新和 Swagger 外,接口均携带:
```http
Authorization: Bearer <accessToken>
Content-Type: application/json
```
普通成功响应:
```json
{
"code": "0",
"message": "success",
"data": {},
"requestId": null,
"traceId": null,
"timestamp": "2026-07-30T12:00:00"
}
```
分页数据:
```json
{"records": [], "page": 1, "size": 20, "total": 0, "pages": 0}
```
常用业务错误码:`A0400` 参数错误、`A0401` 未登录、`A0403` 无权限、`A0404` 不存在、`A0409` 冲突、`A0422` 业务校验失败、`A0429` 请求过多、`B0001` 业务失败、`S0500` 服务异常、`S0503` 服务不可用。
## 2. 认证接口
| 方法 | 路径 | 登录要求 | 说明 |
|---|---|---|---|
| POST | `/api/auth/register` | 匿名 | 注册商户及租户 |
| POST | `/api/auth/login` | 匿名 | 平台、商户统一登录 |
| POST | `/api/auth/refresh` | 匿名 | 刷新令牌 |
| POST | `/api/auth/logout` | Access Token | 注销刷新令牌 |
注册请求:
```json
{
"username": "merchant_demo",
"password": "ChangeMe123!",
"displayName": "张三",
"companyName": "深圳示例贸易有限公司",
"legalPerson": "张三",
"legalPhone": "13800138000",
"contactEmail": "demo@example.com",
"countryCode": "CN",
"address": "广东省深圳市南山区测试路1号"
}
```
用户名为 4 至 64 位字母、数字或下划线,密码为 8 至 72 位。注册响应 `data`:`accountId,tenantId,membershipId,tenantStatus,nextStep`。
登录请求:
```json
{"username":"merchant_admin","password":"ChangeMe123!"}
```
登录/刷新响应 `data`:`tokenType,accessToken,expiresIn,refreshToken,refreshExpiresIn`。刷新和退出请求均为:
```json
{"refreshToken":"<refreshToken>"}
```
## 3. IAM 商户端
| 方法 | 路径 | 请求/响应 |
|---|---|---|
| GET | `/api/merchant/v1/iam/tenant/profile` | 返回当前 JWT 租户资料 |
| PUT | `/api/merchant/v1/iam/tenant/profile` | 更新当前租户资料 |
| GET | `/api/merchant/v1/iam/tenant/qualifications` | 返回当前租户资质列表 |
IAM 的商户资质接口只读。旧的 `POST /api/merchant/v1/iam/tenant/qualifications` 已移除,上传必须使用 File 服务的 multipart 接口,避免数据库出现没有真实文件支撑的 URL。
个人资料与修改密码:
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | `/api/merchant/v1/iam/profile` | 查询当前登录成员资料 |
| PUT | `/api/merchant/v1/iam/profile` | 编辑姓名、电话和邮箱 |
| PUT | `/api/auth/password` | 校验旧密码并修改本人密码,成功后撤销全部旧会话 |
成员与角色:
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET/POST | `/api/merchant/v1/iam/members` | 成员列表、创建成员和认证账号 |
| GET/PUT | `/api/merchant/v1/iam/members/{membershipId}` | 成员详情、编辑资料和角色 |
| PUT | `/api/merchant/v1/iam/members/{membershipId}/status` | 启用或停用普通成员 |
| PUT | `/api/merchant/v1/iam/members/{membershipId}/password` | 管理员重置成员密码 |
| GET/POST | `/api/merchant/v1/iam/roles` | 角色列表、新建角色 |
| GET/PUT/DELETE | `/api/merchant/v1/iam/roles/{roleId}` | 角色详情、编辑、删除 |
| PUT | `/api/merchant/v1/iam/roles/{roleId}/status` | 启用或停用自定义角色 |
| GET | `/api/merchant/v1/iam/permissions` | 查询去重后的权限资源 |
| PUT | `/api/merchant/v1/iam/roles/permissions` | 全量保存角色权限 |
| GET | `/api/merchant/v1/iam/members/{membershipId}/roles` | 查询成员当前角色 |
| PUT | `/api/merchant/v1/iam/members/roles` | 全量保存或清空成员角色 |
成员列表和详情均返回 `displayName,phone,email,roleIds`;角色列表和详情均返回 `permissionIds`。企业所有者和系统角色受保护,已分配成员的自定义角色不能删除。
资料更新请求:
```json
{
"tenantName": "深圳示例贸易有限公司",
"legalName": "深圳示例贸易有限公司",
"contactName": "李四",
"contactPhone": "13900139000",
"contactEmail": "service@example.com"
}
```
资料响应字段:`id,tenantCode,tenantName,status,legalName,unifiedSocialCreditCode,contactName,contactPhone,contactEmail`。
## 4. IAM 平台审核
| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
| GET | `/api/platform/v1/iam/reviews` | 平台身份 | 待审核记录 |
| GET | `/api/platform/v1/iam/tenants/{tenantId}/qualifications` | `platform:customer:review` | 指定租户资质 |
| POST | `/api/platform/v1/iam/reviews/{id}/approve` | `platform:customer:approve` | 审核通过 |
| POST | `/api/platform/v1/iam/reviews/{id}/reject` | `platform:customer:reject` | 审核驳回 |
审核请求:
```json
{"comment":"资料完整,审核通过"}
```
审核通过后租户状态为 `ACTIVE`、资质为 `APPROVED`;驳回后租户和资质为 `REJECTED`。
## 5. 资质文件
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | `/api/merchant/v1/files/qualifications` | 上传当前租户营业执照 |
| GET | `/api/merchant/v1/files/qualifications/{fileName}` | 商户下载自己的资质 |
| GET | `/api/platform/v1/files/qualifications/{tenantId}/{fileName}` | 平台查看指定租户资质 |
历史 `/phase1-seed/...` 路径不符合 File 服务契约,不能直接改成不存在的 UUID。处理步骤见 `docs/企业资质文件迁移说明.md`。
上传采用 `multipart/form-data`:`file` 必填,`certificateNo` 可选。只接受文件内容真实为 JPG/PNG 的图片,最大 5MB。上传成功 `data`:
```json
{
"qualificationId": 1,
"reviewId": 1,
"tenantStatus": "PENDING",
"documentUrl": "/api/merchant/v1/files/qualifications/文件名.png"
}
```
下载接口直接返回图片二进制,不使用统一 JSON 包装。
## 6. 商户头程订单
基路径:`/api/merchant/v1/orders/first-leg`。
| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
| POST | `/api/merchant/v1/orders/first-leg` | `merchant:order:create` | 创建草稿,`data` 为订单 ID |
| PUT | `/api/merchant/v1/orders/first-leg/{id}` | `merchant:order:edit` | 编辑草稿 |
| GET | `/api/merchant/v1/orders/first-leg` | 商户身份 | 分页查询自己的订单 |
| GET | `/api/merchant/v1/orders/first-leg/{id}` | 商户身份 | 查询自己的订单详情 |
| POST | `/api/merchant/v1/orders/first-leg/{id}/submit` | `merchant:order:submit` | 提交订单 |
列表参数:`keyword,status,customerId,destinationWarehouseId,createdFrom,createdTo,page,size`;`page` 从 1 开始,`size` 为 1 至 200。
创建/编辑请求示例:
```json
{
"customerId": 10001,
"customerName": "深圳示例贸易有限公司",
"transportMode": "SEA",
"tradeTerm": "FOB",
"destinationCountryCode": "US",
"destinationWarehouseId": 1001,
"destinationWarehouseName": "ONT8",
"expectedShipDate": "2026-08-15",
"customerRemark": "提货前联系",
"pickupMethod": "PICKUP",
"receivingWarehouseId": 2001,
"receivingWarehouseName": "深圳收货仓",
"channelCode": "SEA-US-FBA",
"channelName": "美国海运渠道",
"taxMode": "BUY_DECLARATION",
"containerMode": "LCL",
"customsInspection": false,
"destinationType": "FBA",
"amazonWarehouseCode": "ONT8",
"shipmentId": "FBA20260730001",
"referenceId": "REF20260730001",
"sender": {
"companyName": "深圳示例贸易有限公司",
"contactName": "张三",
"phone": "13800138000",
"email": "sender@example.com",
"countryCode": "CN",
"province": "广东",
"city": "深圳",
"district": "南山",
"addressLine": "测试路1号",
"postalCode": "518000"
},
"receiver": {
"companyName": "Amazon",
"contactName": "ONT8",
"phone": "1234567890",
"email": "ont8@example.com",
"countryCode": "US",
"province": "CA",
"city": "Moreno Valley",
"district": "Riverside",
"addressLine": "24300 Nandina Ave",
"postalCode": "92551"
},
"cargoes": [{
"cargoName": "蓝牙音箱",
"hsCode": "8518210000",
"packageType": "CARTON",
"packageCount": 2,
"grossWeightKg": 20.5,
"volumeCbm": 0.2,
"declaredValue": 200,
"currency": "USD",
"dangerousGoods": false,
"totalQuantity": 20,
"netWeightKg": 18
}]
}
```
枚举约束:`transportMode=SEA|AIR|RAIL|TRUCK`;`pickupMethod=SELF_EXPRESS|PICKUP|SELF_TRUCK`;`taxMode=BUY_DECLARATION|TAX_REFUND`;`containerMode=FULL_CONTAINER|LCL`;`destinationType=FBA|OVERSEAS|PRIVATE`。
订单详情 `data` 包含 `order,cargoes,parties,internalNotes,statusHistory`。商户详情的 `internalNotes` 固定为空;平台内部备注不得向商户展示。企业必须为 `ACTIVE` 且至少有一项 `APPROVED` 资质,才能创建和提交订单。
## 7. 一期相关查询接口
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | `/api/merchant/v1/warehouses?page=1&size=20` | 商户仓库列表 |
| GET | `/api/merchant/v1/warehouses/{warehouseId}` | 启用仓库详情、地址、能力和收货截单时间 |
| GET | `/api/merchant/v1/partners/candidates` | 当前租户启用往来单位候选 |
| GET | `/api/merchant/v1/partners/{partnerId}` | 当前租户启用往来单位详情 |
| GET | `/api/platform/v1/warehouse-admin?tenantId={tenantId}&page=1&size=20` | 平台仓储列表 |
| GET | `/api/platform/v1/iam/status` | IAM 网关路由状态 |
| GET | `/api/platform/v1/orders/status` | Order 网关路由状态 |
| GET | `/api/platform/v1/first-leg/status` | Firstleg 网关路由状态 |
| GET | `/api/platform/v1/warehouses/status` | Warehouse 网关路由状态 |
| GET | `/api/platform/v1/files/status` | File 网关路由状态 |
| GET | `/api/platform/v1/print/status` | Print 网关路由状态 |
往来单位由 `warehouse-service` 承载,表为 `baiyue_warehouse.wh_partner`,不是独立服务或独立数据库。仓库和往来单位查询强制执行租户隔离和停用过滤。
平台履约可通过 `PUT /api/platform/v1/orders/first-leg/{orderId}/express?tenantId={tenantId}` 写入 `expressCompany,expressTrackingNo`;商户端只能在订单详情读取,不能维护快递公司或调用平台写接口。
## 8. Swagger 分组
入口:`http://127.0.0.1:9000/swagger-ui.html`。当前可用分组:Auth 平台、IAM 平台/商户、Order 平台/商户、Firstleg 平台、Warehouse 平台/商户、File 平台/商户、Print 平台。
## 9. 一期明确不纳入
订单平台审核、受理、履约、完成、取消;尾程业务;跨区域事件通知;测试/生产部署,均不属于本地一期前端联调验收范围。