init: mipu-open 对外开放项目统一管理仓库
- 添加 mipu-api 作为 git submodule (Claude Code Skill) - 迁移 API 文档源文件到 docs/ 目录统一维护 - 添加 Gitea Actions 工作流:tag推送自动打包docs并发布Release - Skill 运行时自动从 mipu-open Release 下载最新文档 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
354
docs/03-04_shopping-seat.md
Normal file
354
docs/03-04_shopping-seat.md
Normal file
@@ -0,0 +1,354 @@
|
||||
<!-- mipuyun-api-doc: shopping-seat -->
|
||||
# shopping/seat - 选座报价
|
||||
|
||||
## 用户使用场景
|
||||
|
||||
> 获取航班座位图信息,包括每个座位的位置、价格、状态(可用/已占)、以及座位特性(靠窗、靠过道、紧急出口等)
|
||||
|
||||
## 性能指标
|
||||
|
||||
> - 通过 sessionId 访问,或者 sessionId 有效,响应时间 < 10 秒
|
||||
> - 接口成功率:> 90%
|
||||
|
||||
## 请求说明
|
||||
|
||||
| **请求地址** | https://${endpoint}/shopping/seat |
|
||||
| --- | --- |
|
||||
| **请求方法** | POST |
|
||||
| **注意事项** | Header 必须带压缩请求 |
|
||||
|
||||
## 请求参数
|
||||
|
||||
### Header
|
||||
|
||||
| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON |
|
||||
| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 |
|
||||
| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key |
|
||||
| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret |
|
||||
|
||||
### 请求体
|
||||
|
||||
```json
|
||||
{
|
||||
"sessionId": "743768c1-8bdc-46ed-a586-94fdbd0ce24a",
|
||||
"journeyType": "OW",
|
||||
"origin": "OTP",
|
||||
"destination": "CAG",
|
||||
"departureDate": "20260116",
|
||||
"adults": 1,
|
||||
"children": 0,
|
||||
"infants": 0,
|
||||
"agent": "AXZ",
|
||||
"proxy": "res_mipu_bookxWdyg-it",
|
||||
"outboundFareFamily": "BASIC",
|
||||
"inboundFareFamily": "",
|
||||
"outboundSegments": [
|
||||
{
|
||||
"carrier": "XZ",
|
||||
"originAirport": "OTP",
|
||||
"destinationAirport": "FCO",
|
||||
"flightNumber": "XZ3115",
|
||||
"departureDate": "20260116"
|
||||
},
|
||||
{
|
||||
"carrier": "XZ",
|
||||
"originAirport": "FCO",
|
||||
"destinationAirport": "CAG",
|
||||
"flightNumber": "XZ2341",
|
||||
"departureDate": "20260116"
|
||||
}
|
||||
],
|
||||
"inboundSegments": []
|
||||
}
|
||||
```
|
||||
|
||||
| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| sessionId | String | 否 | 743768c1-8bdc-46ed-a586-94fdbd0ce24a | 目的是为了复用前一步的 shopping/search 或 shopping/select 的 session,提升速度 & 成功率。如带入 session,请务必保障:1. 出发到达/旅行日期/人数与前一步保持一致 |
|
||||
| journeyType | String | 是 | "OW" | 行程为单程还是往返程<br>OW:单程 OneWay<br>RT:往返 RoundTrip |
|
||||
| origin | String | 是 | "OTP" | 出发地,为 IATA 3 字码兼容城市或者机场 3 字码 |
|
||||
| destination | String | 是 | "CAG" | 到达地,为 IATA 3 字码兼容城市或者机场 3 字码 |
|
||||
| departureDate | String | 是 | 20260116 | 出发日期,格式为 `YYYYMMDD`(如 2024 年 5 月 1 日为 20240501) |
|
||||
| returnDate | String | 否 | 20240423(仅 RT 必填) | 返程日期,格式同 departureDate,仅当 journeyType=RT 时必传,OW 时可传空 |
|
||||
| adults | Integer | 是 | 1 | 成人,乘机人数量 |
|
||||
| children | Integer | 是 | 0 | 儿童,乘机人数量 |
|
||||
| infants | Integer | 是 | 0 | 婴儿,乘机人数量 |
|
||||
| agent | String | 是 | "AXZ" | Agent 代码 |
|
||||
| proxy | String | 是 | "res_mipu_bookxWdyg-it" | 本次获取航司数据采用的代理方式。如果需要指定代理国家请在代理用户后面加上国家二字码。如 myproxy-US,US 代表美国 |
|
||||
| outboundSegments | Array<FlightSegmentRequest> | 是 | 见示例 | 去程航段信息,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) |
|
||||
| inboundSegments | Array<FlightSegmentRequest> | 否 | | 返程航段信息,往返行程为必须,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) |
|
||||
| outboundFareFamily | String | 是 | "BASIC" | 去程 FareFamily 的名字 |
|
||||
| inboundFareFamily | String | 否 | | 回程 FareFamily 的名字,仅往返程有值 |
|
||||
| acceptCacheMinutes | Integer | 否 | 5 | 默认值:5<br>**如无特殊情况,本参数不建议设置或调整。**为了避免频繁请求航司设置的缓存,用户可以指定缓存时长,不填写为 5 |
|
||||
| async | Boolean | 是 | false | 是否启用 Webhook 异步模式。<br>- **false**: 同步模式,等待完整结果返回<br>- **true**: 异步模式,立即返回 202,结果通过 Webhook 回调<br><br>**异步模式说明**:<br>1. 系统会同步检查是否有新鲜缓存(acceptCacheMinutes),如有则立即返回<br>2. 无缓存时返回 202 Accepted,包含 requestId 用于追踪<br>3. 航司数据返回后,通过预先配置的 Webhook 回调通知<br><br>**注意**:使用异步模式需提前配置 `shopping_response` 类型的 Webhook |
|
||||
| callbackId | String | 否 | - | 异步模式下的业务回调标识,用于客户自行匹配业务。建议格式:`seat_{origin}_{destination}_{departureDate}_{adults}-{children}-{infants}_{flightNumber}`,最大 50 个字符 |
|
||||
|
||||
## 返回参数
|
||||
|
||||
### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"cached": false,
|
||||
"code": 0,
|
||||
"itineraries": [],
|
||||
"msg": "success",
|
||||
"seatMapList": [
|
||||
{
|
||||
"segmentIndex": 1,
|
||||
"journeyDirection": "outbound",
|
||||
"segment": {
|
||||
"flightNumber": "DM200",
|
||||
"dptAirport": "AUA",
|
||||
"arrAirport": "CUR",
|
||||
"departureTime": "202604261100",
|
||||
"arrivalTime": "202604261150"
|
||||
},
|
||||
"cabins": [
|
||||
{
|
||||
"deck": "main",
|
||||
"cabinType": "Business",
|
||||
"cabinLayout": {
|
||||
"columns": [
|
||||
{ "designator": "A", "characteristics": "W" },
|
||||
{ "designator": "C", "characteristics": "A" },
|
||||
{ "designator": "D", "characteristics": "A" },
|
||||
{ "designator": "G", "characteristics": "A" },
|
||||
{ "designator": "J", "characteristics": "W" }
|
||||
],
|
||||
"rows": { "first": 1, "last": 8 },
|
||||
"exitRowPositions": []
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"number": 1,
|
||||
"seats": [
|
||||
{
|
||||
"column": "A",
|
||||
"currency": "EUR",
|
||||
"price": 120.0,
|
||||
"seatCharacteristics": ["W", "L"],
|
||||
"seatStatus": "F"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deck": "main",
|
||||
"cabinType": "Economy",
|
||||
"cabinLayout": {
|
||||
"columns": [
|
||||
{ "designator": "A", "characteristics": "W" },
|
||||
{ "designator": "B", "characteristics": "M" },
|
||||
{ "designator": "C", "characteristics": "A" },
|
||||
{ "designator": "D", "characteristics": "A" },
|
||||
{ "designator": "E", "characteristics": "M" },
|
||||
{ "designator": "F", "characteristics": "W" }
|
||||
],
|
||||
"rows": { "first": 9, "last": 32 },
|
||||
"exitRowPositions": [
|
||||
{ "first": 16, "last": 16 },
|
||||
{ "first": 17, "last": 17 }
|
||||
]
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"number": 9,
|
||||
"seats": [
|
||||
{
|
||||
"column": "A",
|
||||
"currency": "EUR",
|
||||
"price": 21.0,
|
||||
"seatCharacteristics": ["W", "IE", "E", "L"],
|
||||
"seatStatus": "F"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"sessionId": "shopping-seat-fa149f406bcd4df9a1a318d230afc422"
|
||||
}
|
||||
```
|
||||
|
||||
### 响应字段说明
|
||||
|
||||
| 参数名称 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| code | Integer | 系统状态码:0 = 成功,非 0 为失败 |
|
||||
| msg | String | 系统消息:成功时为 null,失败时返回具体系统提示信息 |
|
||||
| cached | Boolean | 是否使用缓存数据 |
|
||||
| sessionId | String | UUID:与航司通信的 session 值,可以用于加速后续动作,如下单 |
|
||||
| itineraries | Array<Itinerary> | 航线组合列表(本接口通常为空数组) |
|
||||
| seatMapList | Array<SeatMap> | **座位图列表,按航段返回每个航段的座位信息** |
|
||||
|
||||
### 异步模式响应(async=true)
|
||||
|
||||
当 `async=true` 且无可用缓存时,系统立即返回 202 Accepted:
|
||||
|
||||
| 参数名称 | 类型 | 说明 |
|
||||
|----------|------|------|
|
||||
| code | Integer | 202(表示请求已接受,正在处理中) |
|
||||
| msg | String | "Accepted. Please wait for the webhook callback" |
|
||||
| requestId | String | 请求ID(UUID),用于追踪和关联 Webhook 回调 |
|
||||
| status | String | "PROCESSING"(处理中) |
|
||||
|
||||
完整结果将通过预先配置的 Webhook 回调返回。
|
||||
|
||||
### SeatMap(座位图)对象说明
|
||||
|
||||
seatMapList 数组中的每个元素代表一个航段的座位图,结构如下:
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| segmentIndex | Integer | 航段索引(从 1 开始),对应 outboundSegments 或 inboundSegments 中的位置 |
|
||||
| journeyDirection | String | 行程方向:`outbound`(去程)/ `inbound`(返程) |
|
||||
| segment | Object | 航段信息对象,包含航班号、出发/到达机场和时间 |
|
||||
| cabins | Array\<Cabin\> | 客舱信息列表,按舱位等级排列(如商务舱在前、经济舱在后) |
|
||||
|
||||
#### Segment(航段)对象
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| flightNumber | String | 航班号,如 "DM200" |
|
||||
| dptAirport | String | 出发机场 IATA 三字码,如 "AUA" |
|
||||
| arrAirport | String | 到达机场 IATA 三字码,如 "CUR" |
|
||||
| departureTime | String | 出发时间,格式 `YYYYMMDDHHmm`,如 "202604261100" |
|
||||
| arrivalTime | String | 到达时间,格式 `YYYYMMDDHHmm`,如 "202604261150" |
|
||||
|
||||
#### Cabin(机舱)对象
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| deck | String | 甲板类型,如 "main" 表示主甲板 |
|
||||
| cabinType | String | 客舱类型,可选值:`Economy`(经济舱)、`Business`(商务舱)、`FirstClass`(头等舱)、`PremiumEconomy`(高端经济舱) |
|
||||
| cabinLayout | Object | 机舱布局信息 |
|
||||
| rows | Array\<Row\> | 座位行列表 |
|
||||
|
||||
#### CabinLayout(机舱布局)对象
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| columns | Array<Column> | 列信息数组,描述每列的座位特性 |
|
||||
| rows | Object | 行范围,包含 `first`(起始行号)和 `last`(结束行号) |
|
||||
| exitRowPositions | Array<Object> | 紧急出口行位置数组,每个对象包含 `first` 和 `last` 行号 |
|
||||
|
||||
#### Column(列)对象
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| designator | String | 列标识符,如 "A"、"B"、"C" 等 |
|
||||
| characteristics | String | 列特性代码(见座位特性说明) |
|
||||
|
||||
#### Row(座位行)对象
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| number | Integer | 行号 |
|
||||
| seats | Array<Seat> | 该行的座位列表 |
|
||||
|
||||
#### Seat(座位)对象
|
||||
|
||||
| 字段名 | 类型 | 示值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| column | String | "A" | 列标识符(A、B、C 等) |
|
||||
| seatStatus | String | "F" | 座位状态<br>**F**:Free(可用)<br>**O**:Occupied(已占) |
|
||||
| seatCharacteristics | Array<String> | ["W", "I"] | 座位特性数组(见下文座位特性说明) |
|
||||
| price | BigDecimal | 15.0 | 座位价格(该座位选座费用) |
|
||||
| currency | String | "EUR" | 价格币种 |
|
||||
|
||||
### 座位特性说明
|
||||
|
||||
seatCharacteristics 数组中的特性代码:
|
||||
|
||||
| 代码 | 英文 | 中文说明 |
|
||||
| --- | --- | --- |
|
||||
| W | Window | 靠窗座位 |
|
||||
| A | Aisle | 靠过道座位 |
|
||||
| M | Middle | 中间座位 |
|
||||
| I | Standard | 标准座位 |
|
||||
| IE | ExitRow | 紧急出口排 |
|
||||
| E | ExtraLegroom | 额外腿部空间 |
|
||||
| L | LimitedRecline | 有限后倾 |
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 如何理解 seatMapList 的结构?
|
||||
|
||||
每个航段(Segment)都有一个独立的座位图,每个座位图可包含多个舱位(cabins)。例如:
|
||||
- 单程直飞:seatMapList 长度为 1,该航段可能包含 1 个或多个 cabins(如商务舱 + 经济舱)
|
||||
- 单程转机(2 个航段):seatMapList 长度为 2,每个航段各有独立的 cabins
|
||||
- 往返程直飞:seatMapList 长度为 2(去程 + 回程),每个航段各有独立的 cabins
|
||||
|
||||
segmentIndex 从 1 开始,与请求中的 outboundSegments/inboundSegments 数组索引对应。cabins 数组中每个 Cabin 对象代表一个舱位区域,通过 cabinType 区分舱位等级。
|
||||
|
||||
### 座位状态有哪些?
|
||||
|
||||
- **F (Free)**:座位可选,未被占用
|
||||
- **O (Occupied)**:座位已被占用,不可选择
|
||||
|
||||
### 如何识别靠窗/靠过道座位?
|
||||
|
||||
通过 seatCharacteristics 数组判断:
|
||||
- 包含 "W":靠窗座位
|
||||
- 包含 "A":靠过道座位
|
||||
- 包含 "M":中间座位(通常在 3-3 或 3-4-3 布局的中间列)
|
||||
|
||||
### 紧急出口座位如何识别?
|
||||
|
||||
包含以下特性的座位通常是紧急出口排:
|
||||
- **IE (ExitRow)**:紧急出口排
|
||||
- **E (ExtraLegroom)**:额外腿部空间
|
||||
|
||||
这些座位通常价格更高,腿部空间更大,但可能有年龄限制(如 14 岁以上)。
|
||||
|
||||
### 价格为 0 的座位是什么意思?
|
||||
|
||||
价格为 0 表示该座位免费可选,不需要额外付费。这种情况常见于:
|
||||
- 高端舱位(商务舱、头等舱)
|
||||
- 航司促销活动
|
||||
- 某些会员权益
|
||||
|
||||
## 业务案例
|
||||
|
||||
### 单人单程选座查询
|
||||
|
||||
#### 请求(Request)
|
||||
|
||||
```json
|
||||
{
|
||||
"journeyType": "OW",
|
||||
"origin": "OTP",
|
||||
"destination": "CAG",
|
||||
"departureDate": "20260116",
|
||||
"adults": 1,
|
||||
"children": 0,
|
||||
"infants": 0,
|
||||
"agent": "AXZ",
|
||||
"outboundFareFamily": "BASIC",
|
||||
"outboundSegments": [
|
||||
{
|
||||
"carrier": "XZ",
|
||||
"originAirport": "OTP",
|
||||
"destinationAirport": "CAG",
|
||||
"flightNumber": "XZ3115",
|
||||
"departureDate": "20260116"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应(Response)
|
||||
|
||||
响应包含完整的座位图,每个座位都有:
|
||||
- 位置信息(行号 + 列号)
|
||||
- 价格信息(price + currency)
|
||||
- 状态信息(seatStatus:F/O)
|
||||
- 特性信息(seatCharacteristics:靠窗/靠过道/紧急出口等)
|
||||
|
||||
在线查看完整示例:https://jsonhero.io/j/XmTLWK94Ae5X
|
||||
Reference in New Issue
Block a user