diff --git a/plugins/mipu-api/skills/mipu-api/.gitignore b/plugins/mipu-api/skills/mipu-api/.gitignore new file mode 100644 index 0000000..37db6ca --- /dev/null +++ b/plugins/mipu-api/skills/mipu-api/.gitignore @@ -0,0 +1,2 @@ +# docs are downloaded at runtime from mipu-open releases +docs/ diff --git a/plugins/mipu-api/skills/mipu-api/.version b/plugins/mipu-api/skills/mipu-api/.version new file mode 100644 index 0000000..0ec25f7 --- /dev/null +++ b/plugins/mipu-api/skills/mipu-api/.version @@ -0,0 +1 @@ +v1.0.0 diff --git a/plugins/mipu-api/skills/mipu-api/SKILL.md b/plugins/mipu-api/skills/mipu-api/SKILL.md index 9813f96..3fb335f 100644 --- a/plugins/mipu-api/skills/mipu-api/SKILL.md +++ b/plugins/mipu-api/skills/mipu-api/SKILL.md @@ -1,11 +1,29 @@ --- name: mipu-api description: 米普云航司API文档助手,帮助开发者查询API接口、生成集成代码、排查错误码。当用户询问API用法、请求格式、响应结构、错误处理或需要生成调用代码时使用。 -allowed-tools: "Read,Grep,Glob" +allowed-tools: "Read,Grep,Glob,Bash" --- # 米普云航司接口转换器 - API 文档助手 +## 0. 文档自动更新 + +每次响应用户请求前,**必须先执行文档更新检查**: + +1. 使用 `Glob` 查找 skill 目录:搜索 `**/skills/mipu-api/update.sh` 获取脚本绝对路径 +2. 使用 `Bash` 执行更新脚本: + ```bash + bash + ``` +3. 脚本会自动: + - 对比本地 `.version` 与 Gitea 远程最新 Release 版本 + - 版本一致 → 静默退出,无输出 + - 版本不同 → 下载 `docs.tar.gz` 解压到 `docs/`,输出更新信息 + - 网络异常 → 静默退出,不影响后续使用 +4. 更新完成后继续用本地 `docs/` 回答问题 + +**重要**:如果 update.sh 执行超过 5 秒或报错,直接跳过,使用现有本地文档即可。 + ## 1. 角色 你是米普云(MipuYun)航司接口转换器的 API 文档专家。你可以: @@ -16,7 +34,7 @@ allowed-tools: "Read,Grep,Glob" ## 2. 文档检索策略 -文档位于 `.claude/skills/mipu-api/docs/` 目录,按编号前缀分类: +文档位于 skill 目录下的 `docs/` 目录,按编号前缀分类: | 前缀 | 类别 | 内容 | |------|------|------| @@ -28,6 +46,7 @@ allowed-tools: "Read,Grep,Glob" | 09-01~09-04 | 设备管理 | device list/bind/unbind/task | | 10-xx | 系统规范 | 错误码 | | 11-xx | 邮箱/代理 | 域名管理、邮件搜索、Proxy 约定 | +| 12-xx | 代理高级 | BrightData Proxy Advanced | **检索方法**: - 问具体端点 → `Read` 读取对应文件(如问行李报价 → 读 `03-03_shopping-baggage.md`) @@ -89,7 +108,7 @@ Base URL: `https://${endpoint}/` ## 7. 行为规则 -1. **只读**:绝不修改任何文件 +1. **只读**:绝不修改任何文件(update.sh 自动更新除外) 2. **引用来源**:回答时标注引用的文档文件名 3. **不确定时询问**:agent code、proxy 配置等不明确的参数,主动询问客户 4. **中文优先**:面向中文开发者,正文使用中文,代码和技术术语保留英文 diff --git a/plugins/mipu-api/skills/mipu-api/docs/02-01_cache-search.md b/plugins/mipu-api/skills/mipu-api/docs/02-01_cache-search.md deleted file mode 100644 index e4d71d8..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/02-01_cache-search.md +++ /dev/null @@ -1,144 +0,0 @@ - -# cache/search - 查询航司缓存数据 - -# 缓存票价搜索(cache/search)API 说明文档 - -## 用户使用场景 - -> 用户希望以低成本,高性能的模式获取航司的价格数据,该数据源为我司缓存库内容,非实时提取航司数据。 - -## 错误场景(不应该使用本接口的场景) - -> 本接口不会与航司产生任何交互,无法保障在响应时刻价格/库存与航司完全一致。 - -## 性能指标 - -> - 航司路线&旅行日期覆盖率:按航司提供,平均值为180天内>90%。 -> - 价格准确率(验价变价率):<85% - -## 请求说明 - -| **请求地址** | https://${endpoint}/cache/search | -| --- | --- | -| **请求方法** | 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 -{ - "journeyType": "OW", - "origin": "MIL", - "destination": "CAG", - "departureDate": "20251118", - "adults": 1, - "children": 0, - "infants": 0, - "agent": "u2web" -} -``` - -| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** | -| --- | --- | --- | --- | --- | -| journeyType | String | 是 | "OW" | 行程为单程还是往返程OW:单程OneWayRT:往返RoundTrip | -| origin | String | 是 | "CJJ" | 出发地,为IATA 3字码兼容城市或者机场3字码 | -| originAirport | String | 否 | | | -| destination | String | 是 | "SHA" | 到达地,为IATA3字码兼容城市或者机场3字码 | -| destinationAirport | String | 否 | | | -| departureDate | String | 是 | 20240326 | 出发日期,格式为 `YYYYMMDD`(如 2024 年 5 月 1 日为 20240501) | -| returnDate | String | 否 | 20240423(仅 RT 必填) | 返程日期,格式同 departureDate,仅当 journeyType=RT 时必传,OW 时可传空 | -| adults | Integer | 是 | 2 | 成人,乘机人数量 | -| children | Integer | 是 | 1 | 儿童,乘机人数量 | -| infants | Integer | 是 | 0 | 婴儿,乘机人数量 | -| agent | String | 是 | "F9-web" | 你自行定义的F9执行器编码(Agent Code) | -| proxy | String | 是 | | 本次获取航司数据采用的代理方式。如果需要指定代理国家请在代理用户后面加上国家二字码。如myproxy-USUS代表美国 | -| acceptCacheMinutes | Integer | 否 | 5 | 默认值:5**如无特殊情况,本参数不建议设置或调整。**为了避免频繁请求航司设置的缓存,用户可以指定缓存时长,不填写为5。 | - -## 返回参数 - -探索一个返回参数json,https://jsonhero.io/j/XmTLWK94Ae5X - -| 参数名称 | 类型 | 示例值 | 说明 | -| --- | --- | --- | --- | -| itineraries | Array | - | 航线组合列表,包含不同航班拼接的行程方案 | -| code | Integer | 0 | 系统状态码:0 = 成功,非 0 为失败 | -| msg | String | null | 系统消息:成功时为 null,失败时返回具体系统提示信息 | -| sessionId | String | 66d807b0-abbc-4b57-aeff-bbf4fc29fb75 | UUID: 与航司通信的session值,可以用于加速后续动作,如继续获取包裹,选座,下单。 | - -# 常见问题 - -## origin/originAirport的区别是什么? - -origin:出发地,建议传入IATA规定的城市码,必填 - -originAirport:出发机场,非必填 - -由于各个数据源对于城市码/机场码的需求场景不一致,服务端做了兼容处理。 - -一般情况只需要传入Origin(城市码),我们会自动将Origin翻译为机场码,并对航司进行轮询获取所有数据。 - -部分特殊情况,如只需要搜索单个机场码,或者直接搜索城市码,不希望服务端转换为机场码,请将需要搜索的三字码直接放入OriginAirport。 - -**举例:** - -入参:origin: LON。 - -不传入originAirport, 服务端发送给航司originAirport: LCY, LGW, LHR, LTN, SEN, STN - -传入originAirport: LCY, 服务端实际发送给航司originAirport: LCY - -传入originAirport: LON, 服务端实际发送给航司 originAirport: LON - -**destination/destinationAirport逻辑同origin/originAirport** - -## - -# 业务案例 - -## 单人单程搜索 - -### 请求(Request) - -```objective-c - -``` - -### 请求(Response) - ---- - -## 转机行程搜索 - -### 请求(Request) - -```json -{ - "journeyType": "OW", - "origin": "BOM", - "destination": "CNX", - "departureDate": "20251118", - "adults": 1, - "children": 0, - "infants": 0 -} -``` - -### 响应(Response) - -在线查看:https://jsonhero.io/j/J0LMhczR0bJM/editor - diff --git a/plugins/mipu-api/skills/mipu-api/docs/03-01_shopping-search.md b/plugins/mipu-api/skills/mipu-api/docs/03-01_shopping-search.md deleted file mode 100644 index 106a308..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/03-01_shopping-search.md +++ /dev/null @@ -1,192 +0,0 @@ - -# shopping/search - 运价报价 - -## 概述 - -航班搜索(Flight Search)API 用于驱动 Agent 去数据源(航司)获取对应数据。 - -### 用户使用场景 - -本接口一般用于: -- 查询单家航司报价 -- 建立航司数据本地缓存 - -### 错误场景(不建议使用) - -本接口不适合以下场景: - -- **秒级搜索响应**:本接口为实时调用接口,响应时间依赖数据源(航司),一般响应时间在10秒左右。如需秒级搜索响应,请参考缓存搜索接口(cache/search)。 -- **验价**:验价请使用 shopping/select(8秒内响应,成功率98%)。 - -### 性能指标 - -| 指标 | 说明 | -|------|------| -| 响应速度 | 依赖数据源(航司)响应,根据大数据统计90%的请求在10秒内 | -| 成功率 | >90% | - -## 请求说明 - -| 项目 | 值 | -|------|-----| -| **请求地址** | `https://${endpoint}/shopping/search` | -| **请求方法** | 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 -{ - "journeyType": "OW", - "origin": "MIL", - "destination": "CAG", - "departureDate": "20251118", - "adults": 1, - "children": 0, - "infants": 0, - "agent": "u2web", - "proxy": "myproxy-us" -} -``` - -| 参数名称 | 类型 | 是否必选 | 示例值(默认值) | 说明 | -|----------|------|----------|-----------------|------| -| journeyType | String | 是 | "OW" | 行程类型:OW=单程(OneWay),RT=往返(RoundTrip) | -| origin | String | 是 | "CJJ" | 出发地,为IATA 3字码兼容城市或者机场3字码 | -| originAirport | String | 否 | - | 出发机场 | -| destination | String | 是 | "SHA" | 到达地,为IATA 3字码兼容城市或者机场3字码 | -| destinationAirport | String | 否 | - | 到达机场 | -| departureDate | String | 是 | 20240326 | 出发日期,格式为 `YYYYMMDD`(如2024年5月1日为20240501) | -| returnDate | String | 否 | 20240423 | 返程日期,格式同 departureDate,仅当 journeyType=RT 时必传 | -| adults | Integer | 是 | 2 | 成人乘机人数量 | -| children | Integer | 是 | 1 | 儿童乘机人数量 | -| infants | Integer | 是 | 0 | 婴儿乘机人数量 | -| agent | String | 是 | "F9-web" | 你自行定义的执行器编码(Agent Code) | -| proxy | String | 是 | - | 本次获取航司数据采用的代理方式。如需指定代理国家请在代理用户后面加上国家二字码,如 myproxy-US 代表美国 | -| currency | String | 否 | - | 航司所支持的货币类型,如航司不支持对应货币,接口会进行报错 | -| acceptCacheMinutes | Integer | 否 | 5 | 默认值:5。**如无特殊情况,本参数不建议设置或调整。**为了避免频繁请求航司设置的缓存,用户可以指定缓存时长,不填写为5分钟 | -| async | Boolean | 是 | false | 是否启用 Webhook 异步模式。
- **false**: 同步模式,等待完整结果返回
- **true**: 异步模式,立即返回 202,结果通过 Webhook 回调

**异步模式说明**:
1. 系统会同步检查是否有新鲜缓存(acceptCacheMinutes),如有则立即返回
2. 无缓存时返回 202 Accepted,包含 requestId 用于追踪
3. 航司数据返回后,通过预先配置的 Webhook 回调通知

**注意**:使用异步模式需提前配置 `shopping_response` 类型的 Webhook | -| callbackId | String | 否 | - | 异步模式下的业务回调标识,用于客户自行匹配业务。建议格式:`search_{origin}_{destination}_{departureDate}_{adults}-{children}-{infants}`,最大 50 个字符 | - -## 返回参数 - -在线查看返回参数示例:https://jsonhero.io/j/XmTLWK94Ae5X - -| 参数名称 | 类型 | 示例值 | 说明 | -|----------|------|--------|------| -| itineraries | Array\ | - | 航线组合列表,包含不同航班拼接的行程方案。详见 [Itinerary 实体定义](08-01_itinerary.md) | -| code | Integer | 0 | 系统状态码:0=成功,非0为失败 | -| msg | String | null | 系统消息:成功时为 null,失败时返回具体系统提示信息 | -| sessionId | String | 66d807b0-abbc-4b57-aeff-bbf4fc29fb75 | UUID:与航司通信的 session 值,可以用于加速后续动作,如继续获取包裹、选座、下单 | - -### 异步模式响应(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 回调返回。 - -## 常见问题 - -### origin/originAirport 的区别是什么? - -**origin**:出发地,建议传入 IATA 规定的城市码,必填 - -**originAirport**:出发机场,非必填 - -由于各个数据源对于城市码/机场码的需求场景不一致,服务端做了兼容处理。 - -一般情况只需要传入 Origin(城市码),我们会自动将 Origin 翻译为机场码,并对航司进行轮询获取所有数据。 - -部分特殊情况,如只需要搜索单个机场码,或者直接搜索城市码不希望服务端转换为机场码,请将需要搜索的三字码直接放入 originAirport。 - -**举例:** - -- 入参:`origin: LON` - - 不传入 originAirport,服务端发送给航司:`originAirport: LCY, LGW, LHR, LTN, SEN, STN` - - 传入 originAirport: LCY,服务端实际发送给航司:`originAirport: LCY` - - 传入 originAirport: LON,服务端实际发送给航司:`originAirport: LON` - -**destination/destinationAirport 逻辑同 origin/originAirport** - -### 这个接口会使用缓存吗? - -默认情况本接口会读取一个 5 分钟短效缓存,如果你在 5 分钟重复请求同一个路线,那么第二次会直接返回缓存数据。 - -你也可以通过 `acceptCacheMinutes` 自己控制缓存时效。 - -## 响应实体介绍 - -### 响应示例 - -```json -{ - "code": 0, - "msg": null, - "sessionId": "66d807b0-abbc-4b57-aeff-bbf4fc29fb75", - "itineraries": [ - { - "outboundSegments": [ - { - "index": 1, - "carrier": "VJ", - "flightNumber": "VJ884", - "operatingCarrier": "", - "operatingFlightnumber": "", - "originAirport": "BOM", - "destinationAirport": "SGN", - "departureTime": "202510270040", - "arrivalTime": "202510270705", - "departureTerminal": "", - "arrivalTerminal": "", - "stopCities": "", - "duration": 295, - "aircraftCode": "330", - "codeShare": false - } - ], - "inboundSegments": [], - "fares": [ - { - "fareBasis": "", - "rtnFareBasis": "", - "fareFamily": "Lion Economy", - "rtnFareFamily": "", - "currency": "USD", - "adultFare": 100.00, - "adultTax": 50.00, - "bookingCode": "Y", - "availableSeats": 7, - "flightPolicy": { - "airlineCode": "SL", - "fareFamilyType": "Lion Economy", - "freeAncillaryList": [ - { "categoryCode": "CabinBaggageOverheadLocker", "segmentIndex": 1, "paxType": "ADT", "piece": 1, "weight": 7, "size": "" }, - { "categoryCode": "StandardCheckedBaggage", "segmentIndex": 1, "paxType": "ADT", "piece": 1, "weight": 20 } - ] - } - } - ] - } - ] -} -``` - -> **提示**:`itineraries` 数组中的每个元素是一个完整的行程方案,详见 [Itinerary 实体定义](08-01_itinerary.md) diff --git a/plugins/mipu-api/skills/mipu-api/docs/03-02_shopping-select.md b/plugins/mipu-api/skills/mipu-api/docs/03-02_shopping-select.md deleted file mode 100644 index 0f5f81b..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/03-02_shopping-select.md +++ /dev/null @@ -1,206 +0,0 @@ - -# shopping/select - 验价/确定航班 - -# 确定航班(shopping/select)API 说明文档 - -## 用户使用场景 - -> 本接口目的是: -> 验价:可满足8秒内响应,>95%成功率。 -> 进一步获取免费行李/退改规则信息(对于无法再shopping/search获取的航司场景) - -## 错误场景(不应该使用本接口的场景) - -> 如航司在点选行程后占位,本接口需谨慎使用,防止航司侧异常。 - -## 性能指标 - -> - 响应速度:95%的请求<8秒。 -> - 请求频率QPS:根据你的商务合同确定 -> - 接口成功率:>95% - -## 请求说明 - -| **请求地址** | https://${endpoint}/shopping/select | -| --- | --- | -| **请求方法** | 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": "66d807b0-abbc-4b57-aeff-bbf4fc29fb75", - "journeyType": "OW", - "origin": "MIL", - "destination": "CAG", - "departureDate": "20251118", - "adults": 1, - "children": 0, - "infants": 0, - "agent": "u2web", - "proxy": "myproxy-us", - "outboundFareFamily": "promo", - "inboundFareFamily": "", - "outboundSegments": [ - { - "carrier": "SL", - "originAirport": "PHS", - "destinationAirport": "DMK", - "flightNumber": "SL557", - "departureDate": "20251119" - } - ], - "inboundSegments": [ - ] -} -``` - -| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** | -| --- | --- | --- | --- | --- | -| sessionId | String | 否 | 66d807b0-abbc-4b57-aeff-bbf4fc29fb75 | 目的是为了复用前一步的shopping/search的session,提升速度&成功率。如带入session,请务必保障:1. 出发到达/旅行日期/人数与前一步保持一致。 | -| journeyType | String | 是 | "OW" | 行程为单程还是往返程OW:单程OneWayRT:往返RoundTrip | -| origin | String | 是 | "CJJ" | 出发地,为IATA 3字码兼容城市或者机场3字码 | -| destination | String | 是 | "SHA" | 到达地,为IATA3字码兼容城市或者机场3字码 | -| departureDate | String | 是 | 20240326 | 出发日期,格式为 `YYYYMMDD`(如 2024 年 5 月 1 日为 20240501) | -| returnDate | String | 否 | 20240423(仅 RT 必填) | 返程日期,格式同 departureDate,仅当 journeyType=RT 时必传,OW 时可传空 | -| adults | Integer | 是 | 2 | 成人,乘机人数量 | -| children | Integer | 是 | 1 | 儿童,乘机人数量 | -| infants | Integer | 是 | 0 | 婴儿,乘机人数量 | -| outboundSegments | Array | 是 | | 去程航段信息,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) | -| inboundSegments | Array | 否 | | 返程航段信息往返行程为必须,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) | -| outboundFareFamily | String | 是 | | 去程FareFamily的名字 | -| inboundFareFamily | String | 否 | | 回程FareFamily的名字仅往返程有值 | -| agent | String | 是 | "u2web" | 你自行定义的执行器编码(Agent Code) | -| proxy | String | 是 | | 本次获取航司数据采用的代理方式。如果需要指定代理国家请在代理用户后面加上国家二字码。如myproxy-USUS代表美国 | -| acceptCacheMinutes | Integer | 否 | 5 | 默认值:5**如无特殊情况,本参数不建议设置或调整。**为了避免频繁请求航司设置的缓存,用户可以指定缓存时长,不填写为5。 | -| async | Boolean | 是 | false | 是否启用 Webhook 异步模式。
- **false**: 同步模式,等待完整结果返回
- **true**: 异步模式,立即返回 202,结果通过 Webhook 回调

**异步模式说明**:
1. 系统会同步检查是否有新鲜缓存(acceptCacheMinutes),如有则立即返回
2. 无缓存时返回 202 Accepted,包含 requestId 用于追踪
3. 航司数据返回后,通过预先配置的 Webhook 回调通知

**注意**:使用异步模式需提前配置 `shopping_response` 类型的 Webhook | -| callbackId | String | 否 | - | 异步模式下的业务回调标识,用于客户自行匹配业务。建议格式:`select_{origin}_{destination}_{departureDate}_{adults}-{children}-{infants}_{flightNumber}`,最大 50 个字符 | - -## 返回参数 - -探索一个返回参数json(同shopping/search),https://jsonhero.io/j/XmTLWK94Ae5X - -| 参数名称 | 类型 | 示例值 | 说明 | -| --- | --- | --- | --- | -| itineraries | Array | - | 航线组合列表,包含不同航班拼接的行程方案 | -| baggageList | | | | -| | | | | -| code | Integer | 0 | 系统状态码:0 = 成功,非 0 为失败 | -| msg | String | null | 系统消息:成功时为 null,失败时返回具体系统提示信息 | -| sessionId | String | 66d807b0-abbc-4b57-aeff-bbf4fc29fb75 | UUID: 与航司通信的session值,可以用于加速后续动作,如继续获取包裹,选座,下单。 | - -### 异步模式响应(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 回调返回。 - -## 响应实体介绍 - -### 响应示例 - -```json -{ - "code": 0, - "msg": null, - "sessionId": "66d807b0-abbc-4b57-aeff-bbf4fc29fb75", - "itineraries": [ - { - "outboundSegments": [ - { - "index": 1, - "carrier": "SL", - "flightNumber": "SL557", - "operatingCarrier": "", - "operatingFlightnumber": "", - "originAirport": "PHS", - "destinationAirport": "DMK", - "departureTime": "202511190800", - "arrivalTime": "202511191130", - "departureTerminal": "", - "arrivalTerminal": "", - "stopCities": "", - "duration": 210, - "aircraftCode": "320", - "codeShare": false - } - ], - "inboundSegments": [], - "fares": [ - { - "fareBasis": "", - "rtnFareBasis": "", - "fareFamily": "promo", - "rtnFareFamily": "", - "currency": "USD", - "adultFare": 80.00, - "adultTax": 30.00, - "bookingCode": "Y", - "availableSeats": 9, - "flightPolicy": { - "airlineCode": "SL", - "fareFamilyType": "promo", - "freeAncillaryList": [ - { "categoryCode": "CabinBaggageOverheadLocker", "segmentIndex": 1, "paxType": "ADT", "piece": 1, "weight": 7, "size": "" }, - { "categoryCode": "StandardCheckedBaggage", "segmentIndex": 1, "paxType": "ADT", "piece": 0, "weight": 0 } - ] - } - } - ] - } - ], - "baggageList": [] -} -``` - -> **提示**:`itineraries` 数组中的每个元素是一个完整的行程方案,详见 [Itinerary 实体定义](08-01_itinerary.md) - -# 常见问题 - -## 航司不稳定的时候,如何保障成功率>95% - -我们支持多个通过proxy入参实现并发请求。 - -**案例1:竖线分隔,随机挑选** - -proxy= myproxy-us|myproxy-uk - -行为:随机从myproxy-us中挑选一个 - -**案例2:加号分隔** - -proxy= myproxy-us+myproxy-uk - -行为:启动两个进程对数据源(航司)做并发访问,确保成功率。 - -**案例3:组合** - -proxy= myproxy1-us|myproxy2-au+myproxy1-uk|myproxy2-de - -行为:随机挑选myproxy1|myproxy2的代理,并启动两个进程对数据源做并发访问。 - -## 如果航司侧响应大于8秒,这个请求会被抛弃吗? - -不会,为了兼容异常场景,该接口我们最大等待航司响应的时长为15秒。 - diff --git a/plugins/mipu-api/skills/mipu-api/docs/03-03_shopping-baggage.md b/plugins/mipu-api/skills/mipu-api/docs/03-03_shopping-baggage.md deleted file mode 100644 index c05e337..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/03-03_shopping-baggage.md +++ /dev/null @@ -1,264 +0,0 @@ - -# shopping/baggage - 行李报价 - -## 用户使用场景 - -> 获取行程可支持的收费行李规格,以及各个规格的行李价格 - -## 性能指标 - -> - 通过sessionId访问,或者sessionId有效,响应时间<8秒。 - -## 请求说明 - -| **请求地址** | https://${endpoint}/shopping/baggage | -| --- | --- | -| **请求方法** | 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": "66d807b0-abbc-4b57-aeff-bbf4fc29fb75", - "journeyType": "OW", - "origin": "MIL", - "destination": "CAG", - "departureDate": "20251118", - "adults": 1, - "children": 0, - "infants": 0, - "agent": "u2web", - "proxy": "myproxy-us", - "outboundFareFamily": "promo", - "inboundFareFamily": "", - "outboundSegments": [ - { - "carrier": "SL", - "originAirport": "PHS", - "destinationAirport": "DMK", - "flightNumber": "SL557", - "departureDate": "20251119" - } - ], - "inboundSegments": [ - ] -} -``` - -> **注意**:本接口的请求参数与 [shopping/select](03-02_shopping-select.md) 完全一致,详细的参数说明请参考 shopping/select 文档。 - -| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** | -| --- | --- | --- | --- | --- | -| sessionId | String | 否 | 66d807b0-abbc-4b57-aeff-bbf4fc29fb75 | 目的是为了复用前一步的shopping/search的session,提升速度&成功率。如带入session,请务必保障:1. 出发到达/旅行日期/人数与前一步保持一致。 | -| journeyType | String | 是 | "OW" | 行程为单程还是往返程OW:单程OneWayRT:往返RoundTrip | -| origin | String | 是 | "CJJ" | 出发地,为IATA 3字码兼容城市或者机场3字码 | -| destination | String | 是 | "SHA" | 到达地,为IATA3字码兼容城市或者机场3字码 | -| departureDate | String | 是 | 20240326 | 出发日期,格式为 `YYYYMMDD`(如 2024 年 5 月 1 日为 20240501) | -| returnDate | String | 否 | 20240423(仅 RT 必填) | 返程日期,格式同 departureDate,仅当 journeyType=RT 时必传,OW 时可传空 | -| adults | Integer | 是 | 2 | 成人,乘机人数量 | -| children | Integer | 是 | 1 | 儿童,乘机人数量 | -| infants | Integer | 是 | 0 | 婴儿,乘机人数量 | -| outboundSegments | Array | 是 | | 去程航段信息,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) | -| inboundSegments | Array | 否 | | 返程航段信息往返行程为必须,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) | -| outboundFareFamily | String | 是 | | 去程FareFamily的名字 | -| inboundFareFamily | String | 否 | | 回程FareFamily的名字仅往返程有值 | -| agent | String | 是 | "u2web" | 你自行定义的执行器编码(Agent Code) | -| proxy | String | 是 | | 本次获取航司数据采用的代理方式。如果需要指定代理国家请在代理用户后面加上国家二字码。如myproxy-USUS代表美国 | -| acceptCacheMinutes | Integer | 否 | 5 | 默认值:5**如无特殊情况,本参数不建议设置或调整。**为了避免频繁请求航司设置的缓存,用户可以指定缓存时长,不填写为5。 | -| async | Boolean | 是 | false | 是否启用 Webhook 异步模式。
- **false**: 同步模式,等待完整结果返回
- **true**: 异步模式,立即返回 202,结果通过 Webhook 回调

**异步模式说明**:
1. 系统会同步检查是否有新鲜缓存(acceptCacheMinutes),如有则立即返回
2. 无缓存时返回 202 Accepted,包含 requestId 用于追踪
3. 航司数据返回后,通过预先配置的 Webhook 回调通知

**注意**:使用异步模式需提前配置 `shopping_response` 类型的 Webhook | -| callbackId | String | 否 | - | 异步模式下的业务回调标识,用于客户自行匹配业务。建议格式:`baggage_{origin}_{destination}_{departureDate}_{adults}-{children}-{infants}_{flightNumber}`,最大 50 个字符 | - -> **参数一致性说明**:本接口的所有请求参数(Header 和 请求体)与 [shopping/select](03-02_shopping-select.md) 完全相同。如果您已经熟悉 shopping/select 接口,可以直接使用相同的参数格式调用本接口。 - -## 返回参数 - -| 参数名称 | 类型 | 示例值 | 说明 | -| --- | --- | --- | --- | -| code | Integer | 0 | 系统状态码:0 = 成功,非 0 为失败 | -| msg | String | null | 系统消息:成功时为 null,失败时返回具体系统提示信息 | -| sessionId | String | 66d807b0-abbc-4b57-aeff-bbf4fc29fb75 | UUID: 与航司通信的session值,可以用于加速后续动作,如继续获取包裹,选座,下单。 | -| itineraries | Array\ | - | 航线组合列表。由于在本接口已确定路线和FareFamily,数组长度 ≤ 1 | -| ancillaries | Array\<[AncillaryGroup](#ancillarygroup)\> | {json实体} | 辅营产品分组列表(新结构,三级嵌套) | -| ancillaryList | Array | {json实体} | *(兼容旧结构)* 当 `ancillaries` 为空时可能存在,建议优先使用 `ancillaries` | - -### 异步模式响应(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 回调返回。 - ---- - -## 响应实体介绍 - -响应采用三级嵌套结构:**AncillaryGroup** → **AncillaryCategory** → **BaggageOption** - -``` -ancillaries (Array) - └─ AncillaryGroup ← 按航程方向 + 运价家族分组 - └─ categoryList (Array) - └─ AncillaryCategory ← 按行李类别分组 - └─ categoryDetail (Array) - └─ BaggageOption ← 具体行李选项及价格 -``` - -### AncillaryGroup(最外层) - -| 字段名 | 类型 | 说明 | -|--------|------|------| -| currency | String | 售价币种(ISO 4217),如 `CAD`、`EUR`、`USD` | -| fareFamilyType | String | 运价家族类型,如 `BASIC`、`SMART`、`PROMO` | -| journeyDirection | String | 航程方向:`outbound`(去程)/ `inbound`(回程) | -| categoryList | Array\<[AncillaryCategory](#ancillarycategory)\> | 辅营类别列表 | - -### AncillaryCategory(中间层) - -| 字段名 | 类型 | 说明 | -|--------|------|------| -| categoryCode | String | 类别代码,见 [categoryCode 说明](#categorycode-说明) | -| maxPieces | String | 该类别最多可购买件数 | -| pricingMode | String | 定价模式,见 [pricingMode 说明](#pricingmode-说明) | -| categoryDetail | Array\<[BaggageOption](#baggageoption)\> | 选项列表 | - -### BaggageOption(最内层) - -| 字段名 | 类型 | 说明 | -|--------|------|------| -| pieceNo | Integer | 第 N 件。STEP 模式下为序号(1, 2, 3...),FLAT/TIERED 模式下为 1 | -| weight | BigDecimal | 行李额重量(KG) | -| size | String | 尺寸限制,如 `"55x40x23cm"` | -| price | BigDecimal | 该选项/该件价格 | -| maxPieces | Integer | 该选项可购买数量 | - ---- - -### 响应示例 - -#### 示例1:FLAT + STEP 混合 - -```json -{ - "code": 0, - "msg": null, - "sessionId": "NYW34327-f212fbacdd054dda8a509e846e300ebf", - "itineraries": [], - "ancillaries": [ - { - "currency": "CAD", - "fareFamilyType": "BASIC", - "journeyDirection": "outbound", - "categoryList": [ - { - "categoryCode": "CabinBaggageOverheadLocker", - "maxPieces": "1", - "pricingMode": "FLAT", - "categoryDetail": [ - { "pieceNo": 1, "weight": 10, "size": "55x40x23cm", "price": 39.00, "maxPieces": 1 }, - { "pieceNo": 1, "weight": 23, "size": "55x40x23cm", "price": 64.00, "maxPieces": 1 } - ] - }, - { - "categoryCode": "StandardCheckedBaggage", - "maxPieces": "5", - "pricingMode": "STEP", - "categoryDetail": [ - { "pieceNo": 1, "weight": 10, "size": "", "price": 39.00, "maxPieces": 1 }, - { "pieceNo": 1, "weight": 23, "size": "", "price": 64.00, "maxPieces": 1 }, - { "pieceNo": 2, "weight": 23, "size": "", "price": 64.00, "maxPieces": 1 }, - { "pieceNo": 3, "weight": 23, "size": "", "price": 99.00, "maxPieces": 1 } - ] - } - ] - }, - { - "currency": "CAD", - "fareFamilyType": "BASIC", - "journeyDirection": "inbound", - "categoryList": [ - { - "categoryCode": "CabinBaggageOverheadLocker", - "maxPieces": "1", - "pricingMode": "FLAT", - "categoryDetail": [ - { "pieceNo": 1, "weight": 10, "size": "55x40x23cm", "price": 35.00, "maxPieces": 1 } - ] - } - ] - } - ] -} -``` - -#### 示例2:TIERED 模式(按重量档位) - -```json -{ - "code": 0, - "msg": null, - "sessionId": "...", - "ancillaries": [ - { - "currency": "CNY", - "fareFamilyType": "ECONOMY", - "journeyDirection": "outbound", - "categoryList": [ - { - "categoryCode": "StandardCheckedBaggage", - "maxPieces": "1", - "pricingMode": "TIERED", - "categoryDetail": [ - { "pieceNo": 1, "weight": 20, "size": "", "price": 300.00, "maxPieces": 1 }, - { "pieceNo": 1, "weight": 25, "size": "", "price": 500.00, "maxPieces": 1 }, - { "pieceNo": 1, "weight": 30, "size": "", "price": 800.00, "maxPieces": 1 } - ] - } - ] - } - ] -} -``` - ---- - -### categoryCode 说明 - -| categoryCode | 说明 | -|--------------|------| -| CabinBaggageOverheadLocker | 手提行李(头顶行李架) | -| CabinBaggageUnderSeat | 手提行李(座椅下) | -| StandardCheckedBaggage | 托运行李 | - -### pricingMode 说明 - -| pricingMode | 说明 | 渲染建议 | -|-------------|------|----------| -| FLAT | 固定单价,每件独立产品 | 卡片网格展示,每个选项一张卡片 | -| STEP | 逐件定价,第 N 件对应不同价格 | 表格展示,按 pieceNo 分组,同 pieceNo 行用背景色合并 | -| TIERED | 按总重量档位选择,不计件 | 单选列表展示,互斥选项 | - -> **提示**: -> - `ancillaries` 数组按 `journeyDirection`(outbound/inbound)和 `fareFamilyType` 分组 -> - 优先使用 `ancillaries`(新三级结构),`ancillaryList` 为兼容旧结构 -> - 同一 `pricingMode` 内,`categoryDetail` 按 `pieceNo` 升序排列 -> - STEP 模式下,相同 `pieceNo` 可能有多个重量/价格选项(如第 1 件可选 10kg 或 23kg) diff --git a/plugins/mipu-api/skills/mipu-api/docs/03-04_shopping-seat.md b/plugins/mipu-api/skills/mipu-api/docs/03-04_shopping-seat.md deleted file mode 100644 index 6e9b2bf..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/03-04_shopping-seat.md +++ /dev/null @@ -1,354 +0,0 @@ - -# 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" | 行程为单程还是往返程
OW:单程 OneWay
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](07-01_flight-segment-request.md) | -| inboundSegments | Array | 否 | | 返程航段信息,往返行程为必须,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) | -| outboundFareFamily | String | 是 | "BASIC" | 去程 FareFamily 的名字 | -| inboundFareFamily | String | 否 | | 回程 FareFamily 的名字,仅往返程有值 | -| acceptCacheMinutes | Integer | 否 | 5 | 默认值:5
**如无特殊情况,本参数不建议设置或调整。**为了避免频繁请求航司设置的缓存,用户可以指定缓存时长,不填写为 5 | -| async | Boolean | 是 | false | 是否启用 Webhook 异步模式。
- **false**: 同步模式,等待完整结果返回
- **true**: 异步模式,立即返回 202,结果通过 Webhook 回调

**异步模式说明**:
1. 系统会同步检查是否有新鲜缓存(acceptCacheMinutes),如有则立即返回
2. 无缓存时返回 202 Accepted,包含 requestId 用于追踪
3. 航司数据返回后,通过预先配置的 Webhook 回调通知

**注意**:使用异步模式需提前配置 `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 | 航线组合列表(本接口通常为空数组) | -| seatMapList | Array | **座位图列表,按航段返回每个航段的座位信息** | - -### 异步模式响应(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\ | 客舱信息列表,按舱位等级排列(如商务舱在前、经济舱在后) | - -#### 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\ | 座位行列表 | - -#### CabinLayout(机舱布局)对象 - -| 字段名 | 类型 | 说明 | -| --- | --- | --- | -| columns | Array | 列信息数组,描述每列的座位特性 | -| rows | Object | 行范围,包含 `first`(起始行号)和 `last`(结束行号) | -| exitRowPositions | Array | 紧急出口行位置数组,每个对象包含 `first` 和 `last` 行号 | - -#### Column(列)对象 - -| 字段名 | 类型 | 说明 | -| --- | --- | --- | -| designator | String | 列标识符,如 "A"、"B"、"C" 等 | -| characteristics | String | 列特性代码(见座位特性说明) | - -#### Row(座位行)对象 - -| 字段名 | 类型 | 说明 | -| --- | --- | --- | -| number | Integer | 行号 | -| seats | Array | 该行的座位列表 | - -#### Seat(座位)对象 - -| 字段名 | 类型 | 示值 | 说明 | -| --- | --- | --- | --- | -| column | String | "A" | 列标识符(A、B、C 等) | -| seatStatus | String | "F" | 座位状态
**F**:Free(可用)
**O**:Occupied(已占) | -| seatCharacteristics | Array | ["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 diff --git a/plugins/mipu-api/skills/mipu-api/docs/03-05_async-query.md b/plugins/mipu-api/skills/mipu-api/docs/03-05_async-query.md deleted file mode 100644 index a194881..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/03-05_async-query.md +++ /dev/null @@ -1,187 +0,0 @@ - -# async/query - 异步查询 - -# 异步查询(async/query)API 说明文档 - -## 用户使用场景 - -> 本接口目的是: -> 当异步调用API返回code:202时,通过本接口查询异步请求的结果。 - -## 使用时机 - -> 当异步调用API返回 `code: 202` 时,表示请求已接收并正在后台处理。 -> 此时响应中会包含 `requestId`,使用本接口查询处理结果。 - -## 性能指标 - -> - 响应速度:毫秒级(直接从缓存读取) -> - 请求频率QPS:无限制 -> - 数据保留时间:24小时 - -## 请求说明 - -| **请求地址** | https://${endpoint}/async/query/{requestId} | -| --- | --- | -| **请求方法** | GET | -| **注意事项** | Header 必须带认证信息。 | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### 路径参数 - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| requestId | String | 是 | abc123-def456 | 异步请求返回的 requestId | - -## 响应说明 - -### 有结果(请求已处理完成) - -当异步请求已处理完成,**直接返回原始响应数据**(不包裹在统一响应结构中)。 - -**判断方式**:响应体中直接包含业务数据字段(如 `itineraries`、`bookingId` 等),无 `code` 字段包裹。 - -**示例 - 有结果(搜索)**: - -```json -{ - "itineraries": [ - { - "itineraryId": "xxx", - "outbound": { - "segments": [...] - }, - "price": { - "total": 1200.00 - } - } - ], - "sessionId": "session-xxx" -} -``` - -**示例 - 有结果(预订)**: - -```json -{ - "bookingId": "BK123456", - "status": "HOLD", - "expiryTime": "2025-01-20T12:00:00Z" -} -``` - -### 无结果(请求未找到或已过期) - -当异步请求不存在或已过期时,返回 404 错误。 - -**判断方式**:响应体中 `code: 404` - -**示例 - 无结果**: - -```json -{ - "code": 404, - "msg": "Not found" -} -``` - -**可能原因**: -1. `requestId` 不存在 -2. 请求已过期(超过 24 小时) -3. 请求属于其他租户(clientCode 不匹配) - -### 请求仍在处理中 - -当异步请求仍在处理中时,会返回处理中的状态。 - -**示例 - 处理中**: - -```json -{ - "code": 202, - "msg": "Processing", - "requestId": "abc123-def456" -} -``` - -## 完整示例 - -### 请求示例 - -```bash -curl -X GET "https://api.example.com/async/query/abc123-def456" \ - -H "client-key: your-client-key" \ - -H "client-secret: your-client-secret" -``` - -### 响应示例(有结果) - -```json -{ - "itineraries": [ - { - "itineraryId": "itinerary-001", - "outbound": { - "segments": [ - { - "carrier": "CA", - "flightNumber": "CA123", - "origin": "PEK", - "destination": "SHA", - "departureTime": "2025-01-20T08:00:00", - "arrivalTime": "2025-01-20T10:00:00" - } - ] - }, - "price": { - "currency": "CNY", - "total": 1200.00 - } - } - ], - "sessionId": "session-xxx" -} -``` - -### 响应示例(无结果) - -```json -{ - "code": 404, - "msg": "Not found" -} -``` - -## 常见问题 - -### Q: 如何获取 requestId? - -A: 当异步调用API返回 `code: 202` 时,响应中会包含 `requestId` 字段。 - -```json -{ - "code": 202, - "msg": "Async request accepted", - "requestId": "abc123-def456" -} -``` - -### Q: 结果会保留多久? - -A: 异步请求的结果会保留 24 小时,超时后自动删除。 - -### Q: 可以查询其他租户的请求吗? - -A: 不可以。接口会根据认证信息中的 clientCode 进行租户隔离,只能查询本租户的请求。 - -### Q: 建议的轮询策略是什么? - -A: 建议每隔 2-5 秒查询一次,最多查询 10 次。如果 10 次后仍未获取结果,可能是航司响应较慢,建议稍后重试。 diff --git a/plugins/mipu-api/skills/mipu-api/docs/04-01_booking-hold.md b/plugins/mipu-api/skills/mipu-api/docs/04-01_booking-hold.md deleted file mode 100644 index 0e6f3a1..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/04-01_booking-hold.md +++ /dev/null @@ -1,163 +0,0 @@ - -# booking/hold - 下单 - -# 下单(booking/hold) API 说明文档 - -## 使用场景 - -> 1. 用户在航班验价通过后,确认预订意向,提交乘客与联系人信息以生成正式订单 - -## 错误场景(不应该使用本接口的场景) - -> 1. 未通过验价接口(checkRoute)获取有效 offerId 时(此场景需先调用验价接口,确保价格与航线有效性) -> 1. 验价接口返回的 offerId 已过期(通常与支付截止时间关联,过期后需重新验价获取新 offerId) -> 1. 乘客信息、证件信息未完整填写或格式错误时(应先校验信息合法性,避免接口调用失败) - -## 性能指标 - -> - 响应速度:98% 的请求响应速度 < 15000ms(因需实时对接航司数据,响应速度明显慢于搜索接口) - -## 请求说明 - -| **请求地址** | https://${endpoint}/booking/hold | -| --- | --- | -| **请求方法** | POST | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝。 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境secret | - -### - -### 请求体 - -```json -{ - "orderId": "abbc4b57fb75", - "journeyType": "OW", - "origin": "MIL", - "destination": "CAG", - "departureDate": "20251118", - "adults": 1, - "children": 0, - "infants": 0, - "agent": "u2web", - "proxy": "myproxy-us", - "outboundFareFamily": "promo", - "inboundFareFamily": "", - "maximumFareThreshold": 15009.69, - "currency": "THB", - "outboundSegments": [ - { - "carrier": "SL", - "originAirport": "PHS", - "destinationAirport": "DMK", - "flightNumber": "SL557", - "departureDate": "20251119" - } - ], - "inboundSegments": [ - ], - "passengers": [ - { - "firstName": "first", - "lastName": "last", - "passengerType": "ADT", - "dateOfBirth": "19970616", - "gender": "M", - "documentNumber": "E12343214", - "documentType": "PP", - "documentIssuePlace": "CN", - "documentExpirationDate": "20260731", - "nationality": "CN", - "mobile": "0086-18923726222", - "frequentFlyerNumber": "", - "frequentFlyerCarrier": "" - } - ], - "contactInfo": { - "firstName": "san", - "lastName": "zhang", - "address": "dfdsaqqq", - "phoneCountryCode": "0086", - "phone": "18912345678", - "email": "san.zhang@gmail.com", - "postCode": "310006", - "city": "hangzhou", - "province": "zejiang", - "country": "CN" - } -} -``` - -#### 参数详情 - -| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** | -| --- | --- | --- | --- | --- | -| orderId | String | 是 | abbc4b57fb75 | 你系统内的订单号,返回的有效报价唯一标识,用于关联待下单的航线与价格 | -| journeyType | String | 是 | "OW" | 行程为单程还是往返程OW:单程OneWayRT:往返RoundTrip | -| origin | String | 是 | "CJJ" | 出发地,为IATA 3字码兼容城市或者机场3字码 | -| destination | String | 是 | "SHA" | 到达地,为IATA3字码兼容城市或者机场3字码 | -| departureDate | String | 是 | 20240326 | 出发日期,格式为 `YYYYMMDD`(如 2024 年 5 月 1 日为 20240501) | -| returnDate | String | 否 | 20240423(仅 RT 必填) | 返程日期,格式同 departureDate,仅当 journeyType=RT 时必传,OW 时可传空 | -| adults | Integer | 是 | 2 | 成人,乘机人数量 | -| children | Integer | 是 | 1 | 儿童,乘机人数量 | -| infants | Integer | 是 | 0 | 婴儿,乘机人数量 | -| outboundSegments | Array | 是 | | 去程航段信息,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) | -| inboundSegments | Array | 否 | | 返程航段信息往返行程为必须,详见 [FlightSegmentRequest](07-01_flight-segment-request.md) | -| outboundFareFamily | String | 是 | | 去程FareFamily的名字 | -| inboundFareFamily | String | 否 | | 回程FareFamily的名字仅往返程有值 | -| maximumFareThreshold | Number | **是** | 15009.69 | 最高票价阈值,超过此价格的报价将不会被接受(用于限制订单金额) | -| currency | String | **是** | "THB" | 出票币种代码,遵循ISO 4217标准,如:USD、CNY、THB、EUR等。
**注意**:必须为出票币种,系统不会进行任何汇率转换 | -| proxy | String | 是 | | 本次获取航司数据采用的代理方式。如果需要指定代理国家请在代理用户后面加上国家二字码。如myproxy-US,US代表美国 | -| passengers | Array | 是 | 请查看实体定义([Passenger](07-02_passenger.md)) | 乘客信息列表,支持 1-9 名乘客(具体数量受航司限制),每个数组元素为单个乘客详情 | -| contactInfo | Object | 是 | 请查看实体定义([ContactInfo](07-03_contact-info.md)) | 联系人信息,用于接收订单通知、行程单等 | - -## - -## 返回参数 - -探索一个响应实体:https://jsonhero.io/j/pPOhukgKMcln/editor - -| **参数名称** | **类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| code | Integer | 0 | 系统状态码:0 = 成功,非 0 = 失败 | -| msg | String | null | 系统消息:成功时为 null,失败时返回具体错误提示(如 “证件有效期不足”“航司订单创建超时”) | -| pnr | String | 000000 | 仅同步模式会响应PNR信息注意对于不支持Hold的航司,我们也会实施与航司进行交互,并将动作完成在支付前一步,这种情况也可以返回000000 | -| pnrExpiryTime | String | YYYYMMDDHHMMSS20251225121212 | hold到的PNR有效期,此处时间为UTC 0时区格式。 | -| status | String | | * 异步模式,且进行中为进行中,失败,成功 * 同步模式,为完成,失败,成功 | -| orderId | String | | 入参给的orderId | -| feeItems | Array | 参考Feeitems实体 | 从航司处获取的报价细项拆分[feeItems 实体定义](08-06_fee-items.md) | - -## 实体定义说明 - -本接口涉及的实体对象定义如下: - -### 请求参数实体 - -| 实体名称 | 说明 | 链接 | -| --- | --- | --- | -| FlightSegmentRequest | 航段请求对象,用于描述单段航班的核心信息 | [查看详情](07-01_flight-segment-request.md) | -| Passenger | 乘客信息对象,包括身份信息、证件信息、常旅客信息等 | [查看详情](07-02_passenger.md) | -| ContactInfo | 联系人信息对象,用于接收订单通知、行程单等 | [查看详情](07-03_contact-info.md) | - -### 返回参数实体 - -| 实体名称 | 说明 | 链接 | -| --- | --- | --- | -| Itinerary | 行程组合信息,包含去程和返程航段列表 | [查看详情](08-01_itinerary.md) | -| FlightFare | 票价信息对象,描述不同乘客类型的费用构成 | [查看详情](08-02_flight-fare.md) | -| SegmentElement | 航段响应对象,描述单段航班的详细信息 | [查看详情](08-03_segment-element.md) | -| FreeBaggage (freeAncillaryList) | 免费行李额元素,描述每个航段每种乘客类型的免费行李配额 | [查看详情](08-04_flight-policy.md) | -| RefundRule (refundRules) | 退改规则对象,描述航班的退改签政策(预留字段,暂未提供) | [查看详情](08-04_flight-policy.md) | -| FlightPolicy | 航班政策对象,包含行李、退改等政策信息 | [查看详情](08-04_flight-policy.md) | -| AncillaryProduct | 附加产品对象,描述付费行李等附加服务 | [查看详情](08-05_ancillary-product.md) | -| feeItems | 费用明细对象,拆分航班预订的各类费用 | [查看详情](08-06_fee-items.md) | - diff --git a/plugins/mipu-api/skills/mipu-api/docs/04-02_booking-payment.md b/plugins/mipu-api/skills/mipu-api/docs/04-02_booking-payment.md deleted file mode 100644 index 0735dc4..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/04-02_booking-payment.md +++ /dev/null @@ -1,302 +0,0 @@ - -# booking/payment - 支付 - -# 更新支付信息(booking/payment) API 说明文档 - -## 使用场景 - -> 1. 客户完成 booking/hold 下单后,需要更新订单的支付信息(如支付方式、信用卡信息等) -> 2. 用于在支付流程中记录或更新支付相关信息 -> 3. 使用 Apple Pay 支付时,可指定设备标签来选择执行任务的设备 - -## 错误场景(不应该使用本接口的场景) - -> 1. 未完成 booking/hold 下单,订单不存在时 -> 2. orderId 为空或未提供时 -> 3. 订单不属于当前客户(clientCode 不匹配)时 - -## 性能指标 - -> - 响应速度:98% 的请求响应速度 < 2000ms -> - 接口成功率:> 99% - -## 请求说明 - -| **请求地址** | https://${endpoint}/booking/payment | -| --- | --- | -| **请求方法** | POST | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝。 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### - -### 请求体 - -```json -{ - "orderId": "abbc4b57fb75", - "proxy": "myproxy-us", - "paymentMethod": "CREDIT_CARD", - "retryCount": 0, - "creditCard": { - "number": "4111111111111111", - "CVV": "123", - "expiryMonth": "12", - "expiryYear": "25", - "lastName": "Doe", - "firstName": "John", - "country": "US" - } -} -``` - -#### 参数详情 - -| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** | -| --- | --- | --- | --- | --- | -| orderId | String | **是** | abbc4b57fb75 | 客户的订单号,必须是通过 booking/hold 创建的订单 | -| proxy | String | 是 | | 本次获取航司数据采用的代理方式。如果需要指定代理国家请在代理用户后面加上国家二字码。如myproxy-US,US代表美国 | -| paymentMethod | String | 否 | "CREDIT_CARD" | 支付方式代码:
**BALANCE**:余额支付
**CREDIT_CARD**:信用卡
**APPLE_PAY**:Apple Pay(支持设备标签) | -| retryCount | Integer | 否 | 0 | 支付重试次数,默认为 0(不重试) | -| creditCard | Object | 条件必填 | | 信用卡信息对象,当 paymentMethod 为 CREDIT_CARD 时必填 | -| ├─ number | String | **条件必填** | "4111111111111111" | 信用卡号(13-19 位数字) | -| ├─ CVV | String | **条件必填** | "123" | CVV 安全码(3-4 位数字) | -| ├─ expiryMonth | String | **条件必填** | "12" | 有效期月份(1-2 位数字) | -| ├─ expiryYear | String | **条件必填** | "25" | 有效期年份(2 或 4 位数字) | -| ├─ lastName | String | **条件必填** | "Doe" | 持卡人姓 | -| ├─ firstName | String | **条件必填** | "John" | 持卡人名 | -| ├─ country | String | **条件必填** | "US" | 持卡人国家(二字码) | -| ├─ province | String | 否 | | 持卡人省份/州 | -| ├─ city | String | 否 | | 持卡人城市 | -| ├─ postCode | String | 否 | | 持卡人邮编 | -| ├─ address | String | 否 | | 持卡人地址 | -| ├─ phone | String | 否 | | 持卡人电话(实体卡时使用) | -| ├─ email | String | 否 | | 持卡人邮箱(实体卡时使用) | -| ├─ maximumPaymentAmount | BigDecimal | 否 | | 最大支付金额 | -| └─ reusable | Boolean | 否 | false | 是否为多次卡(默认单次卡) | -| deviceTag | String | 否 | "EUR" | 设备标签,仅当 paymentMethod 为 APPLE_PAY 时可选,用于指定执行任务的设备 | - -### 设备标签说明 (deviceTag) - -- **适用场景**:仅当 `paymentMethod` 为 `APPLE_PAY` 时有效 -- **作用**:指定执行任务的设备标签,系统会优先分配有对应标签的设备 -- **可选性**:留空则自动分配设备 -- **示例**: - ```json - { - "orderId": "abbc4b57fb75", - "paymentMethod": "APPLE_PAY", - "deviceTag": "EUR" - } - ``` - -## 返回参数 - -### 成功响应 - -```json -{ - "code": 0, - "msg": "Payment info updated successfully", - "orderId": "abbc4b57fb75" -} -``` - -### 失败响应 - -#### 缺少 orderId -```json -{ - "code": 400, - "msg": "orderId is required" -} -``` - -#### 订单不存在 -```json -{ - "code": 404, - "msg": "Booking not found", - "orderId": "abbc4b57fb75" -} -``` - -#### 更新失败 -```json -{ - "code": 500, - "msg": "Failed to update payment info", - "orderId": "abbc4b57fb75" -} -``` - -### 响应字段说明 - -| **参数名称** | **类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| code | Integer | 0 | 系统状态码
**0**:成功
**400**:缺少必填参数(orderId)
**404**:订单不存在或不属于当前客户
**500**:更新支付信息失败 | -| msg | String | "Payment info updated successfully" | 系统消息:成功时返回成功提示,失败时返回具体错误信息 | -| orderId | String | "abbc4b57fb75" | 客户的订单号,与请求中的 orderId 一致 | - -## 业务流程 - -### 支付信息更新流程 - -``` -1. 客户完成航班搜索(shopping/search) - ↓ -2. 客户选择航班并验价(shopping/select) - ↓ -3. 客户提交订单(booking/hold)→ 获取 orderId - ↓ -4. 客户选择支付方式,调用支付接口(booking/payment) - ↓ -5. 支付完成 -``` - -## 常见问题 - -### 为什么 orderId 是必填的? - -orderId 是订单的唯一标识符,系统需要通过它来: -1. 定位到具体的订单 -2. 验证订单是否属于当前客户(通过 clientCode) -3. 确保只有合法的订单才能更新支付信息 - -### paymentMethod 支持哪些支付方式? - -系统支持三种支付方式:**BALANCE**(余额支付)、**CREDIT_CARD**(信用卡)、**APPLE_PAY**(Apple Pay,支持设备标签)。详见上方参数表格中的 paymentMethod 说明。 - -### Apple Pay 中的 deviceTag 是什么? - -`deviceTag` 是设备标签,用于指定执行 Apple Pay 支付任务的设备: -- 仅在 `paymentMethod` 为 `APPLE_PAY` 时有效 -- 可以指定有特定标签的设备执行任务 -- 留空则系统自动分配可用设备 -- 示例:`"deviceTag": "EUR"` 表示优先使用欧洲地区的设备 - -### 信用卡信息安全吗? - -本接口仅用于记录支付信息到系统中。实际的支付处理通常由第三方支付网关完成,建议: -1. 在前端不要存储真实的完整信用卡号 -2. 使用 PCI DSS 合规的支付网关处理实际支付 -3. 仅存储支付网关返回的支付令牌(token) - -### 如果订单不存在会怎样? - -接口会返回 `code: 404` 和 `msg: "Booking not found"`。这种情况通常由以下原因造成: -1. orderId 错误或不存在 -2. 订单属于其他客户(clientCode 不匹配) -3. 订单已过期或被删除 - -## 业务案例 - -### 更新信用卡支付信息 - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75", - "paymentMethod": "CREDIT_CARD", - "creditCard": { - "number": "4111111111111111", - "CVV": "123", - "expiryMonth": "12", - "expiryYear": "25", - "lastName": "Doe", - "firstName": "John", - "country": "US" - } -} -``` - -#### 响应(Response) - -```json -{ - "code": 0, - "msg": "Payment info updated successfully", - "orderId": "abbc4b57fb75" -} -``` - -### 使用 Apple Pay 并指定设备标签 - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75", - "paymentMethod": "APPLE_PAY", - "deviceTag": "EUR" -} -``` - -#### 响应(Response) - -```json -{ - "code": 0, - "msg": "Payment info updated successfully", - "orderId": "abbc4b57fb75" -} -``` - -### 缺少 orderId 的错误请求 - -#### 请求(Request) - -```json -{ - "paymentMethod": "CREDIT_CARD" -} -``` - -#### 响应(Response) - -```json -{ - "code": 400, - "msg": "orderId is required" -} -``` - -### 订单不存在的错误请求 - -#### 请求(Request) - -```json -{ - "orderId": "nonexistent-order-id", - "paymentMethod": "CREDIT_CARD" -} -``` - -#### 响应(Response) - -```json -{ - "code": 404, - "msg": "Booking not found", - "orderId": "nonexistent-order-id" -} -``` - -## 错误码说明 - -| 错误码 | 说明 | 处理建议 | -| --- | --- | --- | -| 0 | 成功 | 支付信息已成功更新 | -| 400 | 请求参数错误 | 检查是否提供了必填的 orderId | -| 404 | 订单不存在 | 确认订单 ID 是否正确,且订单属于当前客户 | -| 500 | 服务器内部错误 | 系统处理异常,请稍后重试或联系技术支持 | diff --git a/plugins/mipu-api/skills/mipu-api/docs/04-03_booking-query.md b/plugins/mipu-api/skills/mipu-api/docs/04-03_booking-query.md deleted file mode 100644 index 2833dde..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/04-03_booking-query.md +++ /dev/null @@ -1,424 +0,0 @@ - -# booking/query - 订单查询 - -# 订单查询(booking/query) API 说明文档 - -## 使用场景 - -> 1. 查询订单的详细信息和当前状态 -> 2. 在支付完成后查询订单确认状态 -> 3. 在客服系统中查询订单详情 -> 4. 获取订单的完整行程、乘客和费用信息 - -## 错误场景(不应该使用本接口的场景) - -> 1. 查询不存在的订单 ID -> 2. 查询不属于当前客户的订单(clientCode 不匹配) - -## 性能指标 - -> - 响应速度:98% 的请求响应速度 < 500ms -> - 接口成功率:> 99.5% - -## 请求说明 - -| **请求地址** | https://${endpoint}/booking/query | -| --- | --- | -| **请求方法** | POST | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### - -### 请求体 - -```json -{ - "orderId": "abbc4b57fb75" -} -``` - -#### 参数详情 - -| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** | -| --- | --- | --- | --- | --- | -| orderId | String | **是** | abbc4b57fb75 | 客户的订单号,用于查询订单详情 | - -## 返回参数 - -### 成功响应 - -```json -{ - "orderId": "abbc4b57fb75", - "requestId": "req-12345", - "agentCode": "u2web", - "status": "CONFIRMED", - "payStatus": "PAID", - "origin": "MIL", - "destination": "CAG", - "journeyType": "OW", - "pnr": "ABC123", - "pnrExpiryTime": "2025-12-25T12:00:00Z", - "feeItems": { - "baseFare": 100.00, - "taxes": 50.50, - "total": 150.50, - "currency": "EUR" - }, - "passengers": [ - { - "lastName": "Rossi", - "firstName": "Mario", - "passengerType": "ADT", - "adult": true, - "child": false, - "infant": false, - "dateOfBirth": "1980-01-15", - "gender": "M", - "documentType": "PASSPORT", - "documentNumber": "AA1234567", - "ancillaries": [] - } - ], - "segments": [ - { - "airline": "AZ", - "flightNo": "AZ1234", - "dptAirport": "MIL", - "arrAirport": "CAG", - "dptTime": "2025-11-18T10:30:00Z", - "arrTime": "2025-11-18T12:15:00Z", - "equipment": "A320" - } - ], - "credential": null, - "promoCode": "SAVE10", - "createTime": "2024-11-15T10:00:00Z", - "updateTime": "2024-11-15T10:30:00Z", - "retryCount": 3, - "retriedCount": 0 -} -``` - -## 错误码说明 - -本接口可能返回以下错误码: - -| **错误码** | **错误名称** | **说明** | **处理建议** | -| --- | --- | --- | --- | -| 42005 | BOOKING_NOT_FOUND | 订单不存在 | 请检查 orderId 是否正确,或订单是否属于当前客户 | -| 41003 | PRICE_CHANGED | 票价高于预期 | 航司侧价格已变动,请检查响应中的 feeItems 获取最新价格,引导用户确认是否继续 | - -### 失败响应 - -#### 订单不存在 (42005) - -```json -{ - "code": 42005, - "msg": "Booking not found" -} -``` - -#### 票价变动 (41003) - -```json -{ - "code": 41003, - "msg": "Price changed. Please check the latest price in feeItems.", - "data": { - "orderId": "abbc4b57fb75", - "feeItems": { - "baseFare": 110.00, - "taxes": 52.50, - "total": 162.50, - "currency": "EUR" - } - } -} -``` - -### 响应字段说明 - -#### 基本字段 - -| **参数名称** | **类型** | **说明** | -| --- | --- | --- | -| orderId | String | 客户的订单号 | -| requestId | String | 请求 ID | -| agentCode | String | 代理商代码 | -| status | String | 订单状态(见下方状态说明) | -| payStatus | String | 支付状态(见下方支付状态说明) | -| origin | String | 出发地 IATA 3 字码 | -| destination | String | 到达地 IATA 3 字码 | -| journeyType | String | 行程类型
**OW**:单程
**RT**:往返 | - -#### PNR 相关 - -| **参数名称** | **类型** | **说明** | -| --- | --- | --- | -| pnr | String | 航司 PNR 码(订座记录编号) | -| pnrExpiryTime | String | PNR 有效期,ISO 8601 格式(UTC 0 时区) | - -#### 费用信息 - -| **参数名称** | **类型** | **说明** | -| --- | --- | --- | -| feeItems | Map | 费用明细(原始 JSON 对象)
详见:[feeItems 实体定义](/api-doc?doc=entity-fee-items) | - -#### 乘客和航班 - -| **参数名称** | **类型** | **说明** | -| --- | --- | --- | -| passengers | Array\ | 乘客信息列表(见 BookingPassenger 定义) | -| segments | Array\ | 航班段列表(见 BookingSegment 定义) | - -#### 其他信息 - -| **参数名称** | **类型** | **说明** | -| --- | --- | --- | -| credential | Object | 订单凭据信息 | -| promoCode | String | 促销码 | -| createTime | DateTime | 订单创建时间,ISO 8601 格式 | -| updateTime | DateTime | 订单最后更新时间,ISO 8601 格式 | -| retryCount | Integer | 可重试的次数 | -| retriedCount | Integer | 已经重试的次数 | - -## 状态说明 - -### 订单状态 (status) - -| **状态** | **说明** | -| --- | --- | -| PENDING | 订单处理中,等待航司确认 | -| CONFIRMED | 订单已确认,PNR 已生成 | -| CANCELLED | 订单已取消 | -| FAILED | 订单失败 | - -### 支付状态 (payStatus) - -| **状态** | **说明** | -| --- | --- | -| UNPAID | 未支付 | -| PENDING | 支付处理中 | -| PAID | 已支付 | -| REFUNDED | 已退款 | -| FAILED | 支付失败 | - -## 数据来源说明 - -本接口返回的数据优先从 `responseJson` 字段解析,如果 `responseJson` 为空或解析失败(code 不是 0 且 feeItems/passengers/segments 均为空),则从 `holdResponse` 字段回退获取。 - -## 业务流程 - -### 订单查询场景 - -``` -1. 客户下单(booking/hold)→ 获取 orderId - ↓ -2. 客户选择支付方式并支付(booking/payment) - ↓ -3. 查询订单状态(booking/query)→ 确认订单状态 - ↓ -4. 如需要,可以取消订单(booking/cancel) -``` - -## 常见问题 - -### 如果订单不存在会返回什么? - -接口会返回错误响应,code 为 40401,msg 为 "Booking not found"。这种情况通常由以下原因造成: -1. orderId 错误或不存在 -2. 订单属于其他客户(clientCode 不匹配) -3. 订单已过期或被删除 - -### status 和 payStatus 有什么区别? - -- **status**:订单的整体状态(PENDING/CONFIRMED/CANCELLED/FAILED) -- **payStatus**:订单的支付状态(UNPAID/PENDING/PAID/REFUNDED/FAILED) - -### feeItems 返回什么结构? - -`feeItems` 是一个原始的 Map 对象,直接从航司响应的 JSON 中解析。 - -详细的字段说明请参考:[feeItems 实体定义](/api-doc?doc=entity-fee-items) - -### passengers 和 segments 的详细定义是什么? - -#### BookingPassenger(乘客信息) - -| **参数名称** | **类型** | **说明** | -| --- | --- | --- | -| lastName | String | 乘客姓 | -| firstName | String | 乘客名 | -| passengerType | String | 乘客类型(ADT/CHD/INF) | -| adult | Boolean | 是否为成人 | -| child | Boolean | 是否为儿童 | -| infant | Boolean | 是否为婴儿 | -| dateOfBirth | String | 出生日期 | -| gender | String | 性别(M/F) | -| documentType | String | 证件类型(如 PASSPORT) | -| documentNumber | String | 证件号码 | -| ancillaries | Array | 附加服务列表 | - -#### BookingSegment(航班段信息) - -| **参数名称** | **类型** | **说明** | -| --- | --- | --- | -| airline | String | 航司代码(IATA 2 字码) | -| flightNo | String | 航班号(如 AZ1234) | -| dptAirport | String | 出发机场 IATA 3 字码 | -| arrAirport | String | 到达机场 IATA 3 字码 | -| dptTime | String | 出发时间,ISO 8601 格式 | -| arrTime | String | 到达时间,ISO 8601 格式 | -| equipment | String | 机型(如 A320、B737) | - -### 什么时候会从 holdResponse 回退数据? - -当 `responseJson` 满足以下任一条件时,会从 `holdResponse` 回退 feeItems/passengers/segments: -1. `responseJson` 为空 -2. `responseJson` 解析失败 -3. `code` 不是 0 且 feeItems/passengers/segments 均为空 - -这确保了即使订单最终状态失败,也能获取到 hold 阶段的数据。 - -### 遇到票价变动错误 (PRICE_CHANGED) 怎么办? - -当接口返回错误码 41003 (PRICE_CHANGED) 时,表示航司侧票价高于预期。这种情况通常发生在: - -1. 下单后到支付前,航司调整了票价 -2. 库存紧张导致票价上涨 -3. 促销活动价格已过期 - -**处理流程:** - -``` -1. 接收到 41003 错误响应 - ↓ -2. 从响应的 data.feeItems 中获取最新价格 - ↓ -3. 向用户展示价格变动信息 - ↓ -4. 询问用户是否继续 - ↓ -5a. 用户同意 → 重新调用 booking/hold 使用新价格 - ↓ -5b. 用户拒绝 → 取消订单流程 -``` - -**关键点:** - -- 错误响应中的 `feeItems` 包含最新的价格明细 -- 需要用户明确确认后才能继续交易 - -## 业务案例 - -### 查询已确认的订单 - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75" -} -``` - -#### 响应(Response) - -```json -{ - "orderId": "abbc4b57fb75", - "agentCode": "u2web", - "status": "CONFIRMED", - "payStatus": "PAID", - "origin": "MIL", - "destination": "CAG", - "journeyType": "OW", - "pnr": "ABC123", - "passengers": [ - { - "lastName": "Rossi", - "firstName": "Mario", - "passengerType": "ADT" - } - ], - "segments": [ - { - "airline": "AZ", - "flightNo": "AZ1234", - "dptAirport": "MIL", - "arrAirport": "CAG", - "dptTime": "2025-11-18T10:30:00Z", - "arrTime": "2025-11-18T12:15:00Z" - } - ], - "createTime": "2024-11-15T10:00:00Z", - "updateTime": "2024-11-15T10:30:00Z" -} -``` - -### 查询往返程订单 - -#### 请求(Request) - -```json -{ - "orderId": "rt-order-12345" -} -``` - -#### 响应(Response) - -```json -{ - "orderId": "rt-order-12345", - "journeyType": "RT", - "origin": "MIL", - "destination": "CAG", - "status": "CONFIRMED", - "payStatus": "PAID", - "pnr": "XYZ789", - "passengers": [ - { - "lastName": "Rossi", - "firstName": "Mario", - "passengerType": "ADT" - }, - { - "lastName": "Bianchi", - "firstName": "Luca", - "passengerType": "ADT" - } - ], - "segments": [ - { - "airline": "AZ", - "flightNo": "AZ1234", - "dptAirport": "MIL", - "arrAirport": "CAG", - "dptTime": "2025-11-18T10:30:00Z", - "arrTime": "2025-11-18T12:15:00Z" - }, - { - "airline": "AZ", - "flightNo": "AZ5678", - "dptAirport": "CAG", - "arrAirport": "MIL", - "dptTime": "2025-11-25T14:00:00Z", - "arrTime": "2025-11-25T15:45:00Z" - } - ], - "createTime": "2024-11-15T10:00:00Z", - "updateTime": "2024-11-15T10:30:00Z" -} -``` diff --git a/plugins/mipu-api/skills/mipu-api/docs/04-04_booking-cancel.md b/plugins/mipu-api/skills/mipu-api/docs/04-04_booking-cancel.md deleted file mode 100644 index c4d71bb..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/04-04_booking-cancel.md +++ /dev/null @@ -1,343 +0,0 @@ - -# booking/cancel - 取消订单 - -# 取消订单(booking/cancel) API 说明文档 - -## 使用场景 - -> 1. 客户主动取消未支付的订单 -> 2. 客户因行程变更取消已确认的订单(需符合退改规则) -> 3. 系统自动取消过期未支付的订单 -> 4. 客服代客取消订单 - -## 错误场景(不应该使用本接口的场景) - -> 1. 订单已不可取消(如已起飞航班) -> 1. 订单不属于当前客户(clientCode 不匹配) -> 1. 重复取消已取消的订单 - -## 性能指标 - -> - 响应速度:98% 的请求响应速度 < 2000ms -> - 接口成功率:> 95% - -## 请求说明 - -| **请求地址** | https://${endpoint}/booking/cancel | -| --- | --- | -| **请求方法** | POST | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝。 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### - -### 请求体 - -```json -{ - "orderId": "abbc4b57fb75", - "cancelReason": "Customer request - flight change" -} -``` - -#### 参数详情 - -| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** | -| --- | --- | --- | --- | --- | -| orderId | String | **是** | abbc4b57fb75 | 客户的订单号,用于取消订单 | -| cancelReason | String | **是** | "Customer request" | 取消原因,用于记录和审计
**客户主动取消**:Customer request
**行程变更**:Flight change
**重复订单**:Duplicate booking
**支付超时**:Payment timeout
**其他**:Other reason | - -## 返回参数 - -### 成功响应 - -```json -{ - "code": 0, - "msg": "Booking cancelled successfully", - "historyId": 789 -} -``` - -### 失败响应 - -#### 订单不存在 -```json -{ - "code": 1, - "msg": "Failed to cancel booking" -} -``` - -### 响应字段说明 - -| **参数名称** | **类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| code | Integer | 0 | 系统状态码
**0**:取消成功
**1**:取消失败 | -| msg | String | "Booking cancelled successfully" | 系统消息:成功或失败的详细信息 | -| historyId | Long | 789 | 历史记录 ID,用于追踪取消操作记录 | - -## 业务流程 - -### 订单取消流程 - -``` -1. 客户下单(booking/hold)→ 获取 orderId - ↓ -2. 订单状态变化 - ├─ 未支付超时 → 系统自动取消 - ├─ 客户主动取消 → 调用取消接口 - └─ 行程变更取消 → 调用取消接口 - ↓ -3. 调用取消接口(booking/cancel)→ 提供取消原因 - ↓ -4a. 成功:code=0,订单状态更新为 CANCELLED - ↓ -4b. 失败:code=1,返回错误信息 -``` - -### 取消后状态变化 - -``` -取消前: -- 状态:PENDING / CONFIRMED -- PNR:已生成(如已确认) - -取消后: -- 状态:CANCELLED -- PNR:被航司释放 -- 历史记录:保存取消操作记录 -``` - -## 常见问题 - -### 取消订单后可以恢复吗? - -通常**不可以**。订单一旦取消: -1. PNR 被释放,座位被释放回库存 -2. 如果需要恢复,需要重新下单 -3. 某些航司可能支持恢复,但需要联系客服处理 - -### 哪些订单可以取消? - -可以取消的订单: -1. **状态为 PENDING**:处理中的订单 -2. **状态为 CONFIRMED**:已确认但未起飞的订单 -3. **符合退改规则**:在退改规则允许的时间范围内 - -不可取消的订单: -1. **已起飞**:航班已经起飞 -2. **已取消**:订单已经被取消过 -3. **已使用**:乘客已办理登机 - -### cancelReason 有什么用? - -cancelReason 用于: -1. **审计追踪**:记录取消原因,便于后续分析 -2. **统计分析**:统计取消原因分布,优化产品 -3. **客服支持**:客服可以查看取消原因 -4. **退款处理**:根据取消原因判断是否退款及退款金额 - -### 取消成功后如何退款? - -取消成功后: -1. 系统会自动触发退款流程 -2. 退款金额根据**退改规则**和**取消时间**决定 -3. 退款通常需要 3-7 个工作日到账 -4. 可以通过 **booking/query** 查询退款状态 - -### 重复取消会怎样? - -如果订单已经是 CANCELLED 状态: -1. 再次调用取消接口会返回失败(code=1) -2. 不会重复处理退款 -3. 建议取消前先通过 **booking/query** 查询订单状态 - -## 业务案例 - -### 客户主动取消订单 - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75", - "cancelReason": "Customer request - flight change" -} -``` - -#### 响应(Response) - -```json -{ - "code": 0, - "msg": "Booking cancelled successfully", - "historyId": 789 -} -``` - -### 行程变更取消订单 - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75", - "cancelReason": "Itinerary change - customer requested new dates" -} -``` - -#### 响应(Response) - -```json -{ - "code": 0, - "msg": "Booking cancelled successfully", - "historyId": 790 -} -``` - -### 重复订单取消 - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75", - "cancelReason": "Duplicate booking - same itinerary booked twice" -} -``` - -#### 响应(Response) - -```json -{ - "code": 0, - "msg": "Booking cancelled successfully", - "historyId": 791 -} -``` - -### 取消不存在的订单 - -#### 请求(Request) - -```json -{ - "orderId": "nonexistent-order-id", - "cancelReason": "Test cancellation" -} -``` - -#### 响应(Response) - -```json -{ - "code": 1, - "msg": "Failed to cancel booking" -} -``` - -## 取消原因建议 - -### 标准取消原因 - -| 场景 | 建议的 cancelReason | 说明 | -| --- | --- | --- | -| 客户主动取消 | "Customer request" | 客户主动要求取消 | -| 行程变更 | "Flight change" | 客户需要更改行程 | -| 重复预订 | "Duplicate booking" | 同一航班重复预订 | -| 支付超时 | "Payment timeout" | 支付时间超过限制 | -| 价格问题 | "Price issue" | 客户认为价格不合理 | -| 个人原因 | "Personal reason" | 客户个人原因 | -| 系统错误 | "System error" | 系统导致的错误 | -| 其他原因 | "Other reason" | 其他未列出的原因 | - -### 详细取消原因 - -建议在标准原因后添加详细说明: - -```json -{ - "orderId": "abbc4b57fb75", - "cancelReason": "Customer request - found better price elsewhere" -} -``` - -## 取消最佳实践 - -### 1. 取消前先查询状态 - -```javascript -// 1. 先查询订单状态 -const order = await bookingQuery({ orderId: "xxx" }); - -// 2. 确认订单可以取消后再取消 -if (order.status === "CONFIRMED" || order.status === "PENDING") { - const result = await bookingCancel({ - orderId: "xxx", - cancelReason: "Customer request" - }); - - if (result.code === 0) { - console.log("取消成功"); - } -} -``` - -### 2. 记录取消原因 - -始终提供清晰、准确的取消原因: -```json -{ - "cancelReason": "Customer request - passenger name change needed" -} -``` - -而不是: -```json -{ - "cancelReason": "Cancel" -} -``` - -### 3. 处理取消失败 - -```javascript -const result = await bookingCancel({ - orderId: "xxx", - cancelReason: "Customer request" -}); - -if (result.code !== 0) { - // 记录错误日志 - console.error("取消失败:", result.msg); - - // 联系客服处理 - await contactSupport({ - orderId: "xxx", - issue: "Cancel failed", - message: result.msg - }); -} -``` - -## 错误处理 - -### 常见错误及处理方式 - -| 错误场景 | code | msg | 处理建议 | -| --- | --- | --- | --- | -| 订单不存在 | 1 | "Failed to cancel booking" | 确认 orderId 是否正确 | -| 订单已取消 | 1 | "Failed to cancel booking" | 先查询订单状态 | -| 订单不可取消 | 1 | "Failed to cancel booking" | 检查退改规则和航班状态 | -| 系统错误 | 1 | "Failed to cancel booking" | 稍后重试或联系技术支持 | diff --git a/plugins/mipu-api/skills/mipu-api/docs/04-05_booking-retry.md b/plugins/mipu-api/skills/mipu-api/docs/04-05_booking-retry.md deleted file mode 100644 index e934164..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/04-05_booking-retry.md +++ /dev/null @@ -1,342 +0,0 @@ - -# booking/retry - 订单重试 - -# 订单重试(booking/retry) API 说明文档 - -## 使用场景 - -> 1. 当订单创建失败时,可以通过本接口重试订单 -> 2. 用于自动或手动恢复失败的订单 -> 3. 支持指定重试次数,避免无限重试 - -## 错误场景(不应该使用本接口的场景) - -> 1. 订单已成功时(status=CONFIRMED)不需要重试 -> 1. 订单已取消时不能重试 -> 1. 重试次数已达上限时继续重试 - -## 性能指标 - -> - 响应速度:98% 的请求响应速度 < 3000ms(包含重试处理时间) -> - 接口成功率:> 95% - -## 请求说明 - -| **请求地址** | https://${endpoint}/booking/retry | -| --- | --- | -| **请求方法** | POST | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝。 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### - -### 请求体 - -```json -{ - "orderId": "abbc4b57fb75", - "retryCount": 1 -} -``` - -#### 参数详情 - -| **参数名称** | **类型** | **是否必选** | **示例值(默认值)** | **说明** | -| --- | --- | --- | --- | --- | -| orderId | String | **是** | abbc4b57fb75 | 客户的订单号,用于重试失败的订单 | -| retryCount | Integer | 否 | 1 | 重试次数,用于追踪当前是第几次重试
**不提供**:系统将自动重试
**提供**:使用指定的重试次数 | - -## 返回参数 - -### 成功响应 - -```json -{ - "id": 12345, - "orderId": "abbc4b57fb75", - "journeyType": "OW", - "origin": "MIL", - "destination": "CAG", - "departureDate": "20251118", - "returnDate": null, - "adults": 1, - "children": 0, - "infants": 0, - "status": "PENDING", - "pnr": null, - "pnrExpiryTime": null, - "agent": "u2web", - "outboundFareFamily": "promo", - "inboundFareFamily": null, - "totalPrice": 150.50, - "currency": "EUR", - "createTime": "20241115100000", - "updateTime": "20241115101500", - "passengers": [ - { - "firstName": "first", - "lastName": "last", - "passengerType": "ADT" - } - ], - "contactInfo": { - "firstName": "san", - "lastName": "zhang", - "email": "san.zhang@gmail.com", - "phone": "0086-18912345678" - } -} -``` - -### 失败响应 - -#### 订单不存在 -```json -null -``` - -### 响应字段说明 - -| **参数名称** | **类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| id | Long | 12345 | 系统内部订单 ID(仅用于调试) | -| orderId | String | "abbc4b57fb75" | 客户的订单号 | -| journeyType | String | "OW" | 行程类型
**OW**:单程
**RT**:往返 | -| origin | String | "MIL" | 出发地 IATA 3 字码 | -| destination | String | "CAG" | 到达地 IATA 3 字码 | -| departureDate | String | "20251118" | 出发日期,格式 YYYYMMDD | -| returnDate | String/null | null | 返程日期,格式 YYYYMMDD(仅往返程有值) | -| adults | Integer | 1 | 成人数量 | -| children | Integer | 0 | 儿童数量 | -| infants | Integer | 0 | 婴儿数量 | -| status | String | "PENDING" | 订单状态
**PENDING**:处理中(重试中)
**CONFIRMED**:已确认
**FAILED**:失败 | -| pnr | String/null | null | 航司 PNR 码(订座记录编号),重试中可能为空 | -| pnrExpiryTime | String/null | null | PNR 有效期,格式 YYYYMMDDHHmmss(UTC 0 时区) | -| agent | String | "u2web" | Agent 代码 | -| outboundFareFamily | String | "promo" | 去程票价族 | -| inboundFareFamily | String/null | null | 回程票价族(仅往返程有值) | -| totalPrice | BigDecimal | 150.50 | 订单总价 | -| currency | String | "EUR" | 币种代码 | -| createTime | String | "20241115100000" | 订单创建时间,格式 YYYYMMDDHHmmss | -| updateTime | String | "20241115101500" | 订单最后更新时间,格式 YYYYMMDDHHmmss | -| passengers | Array | | 乘客信息列表 | -| contactInfo | Object | | 联系人信息 | - -## 业务流程 - -### 订单重试流程 - -``` -1. 客户下单(booking/hold)→ 订单创建失败 - ↓ -2. 系统或客户检测到失败状态 - ↓ -3. 调用重试接口(booking/retry)→ 指定 retryCount - ↓ -4. 系统重新处理订单 - ↓ -5a. 成功:status=CONFIRMED,返回订单详情 - ↓ -5b. 失败:status=FAILED,可以再次重试 -``` - -### 自动重试策略 - -建议的自动重试策略: - -``` -第 1 次重试(retryCount=1):立即重试 -第 2 次重试(retryCount=2):等待 30 秒 -第 3 次重试(retryCount=3):等待 60 秒 -第 4 次重试(retryCount=4):等待 120 秒 -超过 4 次:停止重试,联系客服 -``` - -## 常见问题 - -### 什么时候应该使用重试接口? - -当订单状态为 **FAILED** 时,可以考虑使用重试接口: -1. 航司系统临时不可用 -2. 网络超时 -3. 航司返回临时错误 - -### retryCount 的作用是什么? - -retryCount 用于: -1. **追踪重试次数**:记录当前是第几次重试 -2. **防止无限重试**:可以设置最大重试次数上限 -3. **系统监控**:用于监控重试频率和成功率 - -### 如果订单不存在会返回什么? - -接口会返回 `null`。这种情况通常由以下原因造成: -1. orderId 错误或不存在 -2. 订单属于其他客户(clientCode 不匹配) - -### 重试后订单状态仍然是 FAILED 怎么办? - -如果多次重试后仍然失败: -1. 检查错误信息和日志 -2. 确认订单参数是否正确 -3. 检查航司系统是否正常 -4. 联系技术支持 - -### 可以重试已确认的订单吗? - -不建议。如果订单状态已经是 **CONFIRMED**,重试没有意义。建议先调用 **booking/query** 查询订单状态,确认订单确实失败后再重试。 - -## 业务案例 - -### 第 1 次重试失败的订单 - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75", - "retryCount": 1 -} -``` - -#### 响应(Response) - -```json -{ - "id": 12345, - "orderId": "abbc4b57fb75", - "journeyType": "OW", - "origin": "MIL", - "destination": "CAG", - "departureDate": "20251118", - "adults": 1, - "status": "PENDING", - "pnr": null, - "totalPrice": 150.50, - "currency": "EUR", - "createTime": "20241115100000", - "updateTime": "20241115101500" -} -``` - -### 第 2 次重试(等待后) - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75", - "retryCount": 2 -} -``` - -#### 响应(Response) - -```json -{ - "id": 12345, - "orderId": "abbc4b57fb75", - "status": "CONFIRMED", - "pnr": "ABC123", - "pnrExpiryTime": "20251225120000", - "updateTime": "20241115102000" -} -``` - -### 重试不存在的订单 - -#### 请求(Request) - -```json -{ - "orderId": "nonexistent-order-id", - "retryCount": 1 -} -``` - -#### 响应(Response) - -```json -null -``` - -### 不指定 retryCount 的重试 - -#### 请求(Request) - -```json -{ - "orderId": "abbc4b57fb75" -} -``` - -#### 响应(Response) - -```json -{ - "orderId": "abbc4b57fb75", - "status": "PENDING", - "updateTime": "20241115103000" -} -``` - -**说明**:不提供 retryCount 时,系统将自动管理重试次数。 - -## 重试最佳实践 - -### 1. 指数退避策略 - -```json -{ - "retryCount": 1, - "waitTime": 0 -} -``` -→ 失败后立即重试 - -```json -{ - "retryCount": 2, - "waitTime": 30 -} -``` -→ 失败后等待 30 秒 - -```json -{ - "retryCount": 3, - "waitTime": 60 -} -``` -→ 失败后等待 60 秒 - -### 2. 最大重试次数限制 - -建议设置最大重试次数为 **3-5 次**,超过后: -- 停止自动重试 -- 通知客服介入 -- 记录错误日志 - -### 3. 重试前先查询状态 - -```javascript -// 1. 先查询订单状态 -const order = await bookingQuery({ orderId: "xxx" }); - -// 2. 确认订单失败后再重试 -if (order.status === "FAILED") { - await bookingRetry({ - orderId: "xxx", - retryCount: 1 - }); -} -``` diff --git a/plugins/mipu-api/skills/mipu-api/docs/07-01_flight-segment-request.md b/plugins/mipu-api/skills/mipu-api/docs/07-01_flight-segment-request.md deleted file mode 100644 index 2640742..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/07-01_flight-segment-request.md +++ /dev/null @@ -1,23 +0,0 @@ - -# FlightSegmentRequest - -# FlightSegmentRequest对象定义 - -Segment 对象用于描述单段航班的核心信息(告知我们定位到具体的行程),定义如下: - -| **字段名** | **数据类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| carrier | String | "VJ" | 承运航司 IATA 二字码(如 VJ = 越南航空),**与 flightNumber 前缀的航司码一致**(示例中 flightNumber="VJ884",carrier="VJ" 符合规则) | -| flightNumber | String | "VJ884" | 航班号,格式为 "航司二字码 + 数字": | -| originAirport | String | "BOM" / "SGN" | 出发机场 IATA 三字码(如 BOM = 孟买贾特拉帕蒂・希瓦吉国际机场,SGN = 胡志明市新山一国际机场) | -| destinationAirport | String | "SGN" / "SYD" | 到达机场 IATA 三字码(如 SYD = 悉尼金斯福德・史密斯机场) | -| stopCities | String | "CDG/MAD" | 经停地城市三字码,多个城市用 `/` 分隔(可选字段,用于支持包含经停点的航班查询) | -| departureDate | String | "20251027" | 起飞日期日期,固定格式 `YYYYMMDD`(20251027表示 2025 年 10 月 27 日) | - -# 备注 - -1. **请求体内的旅行时间是departureDate,不同于响应体的departureTime**:原因是航司会出现出发时间的调整,为了保障成功率,请求只需要告知日期即可。 -1. 本实体兼容FlightSegmentResponse, 你可以把shopping/search中获得实体直接引用。 -1. 如入参为departureTime,我们会抛弃时间,只采用日期。 -1. **stopCities 为可选字段**,仅在航班包含经停点时需要填写。格式为多个城市三字码用 `/` 分隔,例如 "CDG/MAD" 表示经停巴黎和马德里。 - diff --git a/plugins/mipu-api/skills/mipu-api/docs/07-02_passenger.md b/plugins/mipu-api/skills/mipu-api/docs/07-02_passenger.md deleted file mode 100644 index 8bfe2de..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/07-02_passenger.md +++ /dev/null @@ -1,24 +0,0 @@ - -# Passenger - -# Passenger 实体定义 - -Passenger 实体用于描述航班预订中单个乘客的核心信息,包括身份信息、证件信息、常旅客信息及附加服务选择,是订单创建、值机办理等流程的关键数据依据。 - -| **字段名** | **数据类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| firstName | String | San | 乘客名,需与证件名完全一致,国际航司不可填入中文 | -| lastName | String | Zhang | 乘客姓,需与证件姓完全一致,国际航司不可填入中文 | -| passengerType | String | "ADT"、"CHD"、"INF" | 乘客类型,固定枚举值,用于区分票价规则与服务权益:- "ADT" = 成人(Adult,通常指 12 周岁及以上乘客)- "CHD" = 儿童(Child,通常指 2-11 周岁乘客,需单独购票,部分航司可享折扣)- "INF" = 婴儿(Infant,通常指 2 周岁以下乘客,需与成人乘客绑定预订,票价规则特殊) | -| dateOfBirth | String | "20251017" | 乘客出生日期,固定格式为 **YYYYMMDD**(如 "20180520" 表示 2018 年 5 月 20 日) | -| gender | String | "M"、"F" | 乘客性别,固定枚举值:- "M" = 男(Male)- "F" = 女(Female) | -| documentNumber | String | "E12345678" | 证件号码,需与证件类型(documentType)匹配 | -| documentType | String | "PP"、"ID" | 证件类型,固定枚举值,需与航司支持的证件类型一致:- "PP" = 护照(Passport),国际航班必填- "ID" = 身份证(Identity Card) | -| documentIssuePlace | String | "CN"、"US" | 证件签发国家 / 地区代码,遵循 **ISO 3166-1 alpha-2** 标准(2 位字母编码):- "CN" = 中国内地- "US" = 美国 | -| documentExpirationDate | String | "20281030" | 证件有效期截止日期,固定格式为 **YYYYMMDD**(如 "20301231" 表示 2030 年 12 月 31 日),需满足 “有效期截止日期> 航班返程日期”(单程航班需满足 “> 出发日期”),否则会导致预订失败 | -| nationality | String | "CN"、"US" | 乘客国籍代码,遵循 **ISO 3166-1 alpha-2** 标准,与乘客护照 / 身份证上的国籍信息一致,用于航司核验出入境资格,不可为空 | -| mobile | String | 0086-13200112233 | 乘客手机号码注意格式采用xxxx-xxxxxxxxxxx前面4位为国家码。 | -| frequentFlyerCarrier | String | "CA"、"MU" | 常旅客所属航司代码,遵循 IATA 二字码标准,需与 ffpCardNo 对应的航司一致:- "CA" = 中国国际航空- "MU" = 中国东方航空无会员卡时填写 null,非必选 | -| frequentFlyerNumber | String | "CA1234567890" | 常旅客卡号(Frequent Flyer Program Card Number),即乘客在某航司的会员卡编号(如国航 “凤凰知音” 卡号 "CA1234567890"),无会员卡时填写 null,非必选 | -| ancillaries | Array | Ancillary | 复用shopping/baggage中的行李响应字段,详见 [Ancillary 实体定义](07-04_ancillary.md) | - diff --git a/plugins/mipu-api/skills/mipu-api/docs/07-03_contact-info.md b/plugins/mipu-api/skills/mipu-api/docs/07-03_contact-info.md deleted file mode 100644 index 9175a62..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/07-03_contact-info.md +++ /dev/null @@ -1,37 +0,0 @@ - -# ContanctInfo - -# ContactInfo 实体定义 - -Contact 实体用于描述航班订单的联系人信息,是航司与用户沟通的核心渠道,用于发送订单确认通知、电子行程单、航班变动提醒等关键信息。 - -```objective-c - "contactInfo": { - "firstName": "san", - "lastName": "zhang", - "address": "dfdsaqqq", - "phoneCountryCode": "0086", - "phone": "18912345678", - "email": "san.zhang@gmail.com", - "postCode": "310006", - "city": "hangzhou", - "province": "zejiang", - "country": "CN" - -``` - - - -| **字段名** | **数据类型** | 是否必选 | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| firstName | String | 是 | San | 乘客名,需与证件名完全一致,国际航司不可填入中文 | -| lastName | String | 是 | Zhang | 乘客姓,需与证件姓完全一致,国际航司不可填入中文 | -| address | String | 否 | No. 88 Jianguo Road, Chaoyang District, Beijing | 联系人详细地址,用英语(字母)填写。是否必选取决于航司是否需要这个信息。 | -| phoneCountryCode | String | 是 | 0086 | 国家码 | -| phone | String | 是 | 18912345678 | 联系电话号码 | -| postcode | String | 否 | "100022" | 联系人地址对应的邮编(邮政编码)是否必选取决于航司是否需要这个信息。 | -| email | String | 是 | "name@emaildomain.com" | 联系人邮箱地址,需符合标准邮箱格式(如 "用户名 @域名"),用于接收电子行程单(ETicket)、订单确认邮件、航班变动通知,是订单关键凭证的主要发送渠道,不可为空且需确保邮箱可正常接收邮件 | -| city | String | 否 | hangzhou | 联系地址城市 | -| province | String | 否 | zhejiang | 联系地址省/州 | -| country | String | 否 | CN | 联系地址国家码 | - diff --git a/plugins/mipu-api/skills/mipu-api/docs/07-04_ancillary.md b/plugins/mipu-api/skills/mipu-api/docs/07-04_ancillary.md deleted file mode 100644 index c13513e..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/07-04_ancillary.md +++ /dev/null @@ -1,174 +0,0 @@ - -# Ancillary - -# Ancillary 实体定义 - -## 重要约定 - -| **字段名** | **数据类型** | **示例值** | **说明** | -|------------------| --- | --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| journeyDirection | String | outbound | **行程方向**:- outbound: 去程- inbound: 回程
**用途**:区分往返行程的去程和回程方向 | -| categoryCode | String | StandardCheckedBaggage | 值举例:
- 托运行李:StandardCheckedBaggage
- 随身行李:CabinBaggageOverheadLocker
- 选座产品:Seat | -| productCode | String | SCI_BAG_20KG | 值举例:
- 托运行李:SCI_BAG_20KG
- 随身行李:CBOL_BAG_15KG
- 选座产品:SEAT_16A | -| price | Number | 21.22 | 预计采购价格,选填 | -| currency | String | USD | 预计采购价对应的货币,选填 | -| baggage | Object | {"piece":0,"weight":20,"size":"","allWeight":true} | 行李附加信息:仅当行李类产品时非空,描述行李的重量、件数等属性 | -| ├─ piece | Integer | 1 | 行李最多件数:1:最多限一件2:最多限两件 | -| ├─ weight | Integer | 20 | 行李总重量限制:单位为公斤(KG),允许的行李总总量。20表示为:20KG | -| ├─ size | String | "" | 行李尺寸限制:格式为 "长*宽*高"(如 "56*36***23cm"),空字符串表示无特殊尺寸限制(需遵循航司通用规则) | -| seat | Object | {"segmentIndex":1,"row":"12","column":"A"} | 座位附加信息:仅当`categoryCode=Seat`(座位类产品)时非空,描述座位的位置信息 | -| ├─ segmentIndex | Integer | 1 | **航段序号**:从 1 开始,在整个行程中连续编号
• 单程(OW):去程从 1 开始
• 往返(RT):去程从 1 开始,**回程 = 去程航段数 + 1**
**示例**:
- 单程直飞:segmentIndex=1
- 单程2段转机:segmentIndex=1, 2
- 往返直飞:去程 segmentIndex=1,回程 segmentIndex=2
- 往返2段转机:去程 segmentIndex=1,2,回程 segmentIndex=3,4 | -| ├─ row | String | "12" | 座位行号:标识座位所在的行(如 "12" 表示第12排) | -| ├─ column | String | "A" | 座位列号:标识座位所在的列(如 "A"、"B"、"C" 等) | - -# 二、行李与选座的行程处理规则 - -## 1. segmentIndex 的计算规则 - -**重要**:seat 对象中的 `segmentIndex` 在整个行程中**连续编号**,不是每个方向重新从 1 开始。 - -**计算规则:** -- **单程(OW)**:去程从 1 开始连续编号 - - 直飞:segmentIndex = 1 - - 2段转机:segmentIndex = 1, 2 - - 3段转机:segmentIndex = 1, 2, 3 - -- **往返(RT)**:去程从 1 开始,回程紧接去程的编号 - - 往返直飞:去程 segmentIndex = 1,回程 segmentIndex = 2 - - 去程2段+回程1段:去程 segmentIndex = 1, 2,回程 segmentIndex = 3 - - 去程2段+回程2段:去程 segmentIndex = 1, 2,回程 segmentIndex = 3, 4 - -**计算公式:** -- 去程第 N 段:segmentIndex = N -- 回程第 M 段:segmentIndex = 去程航段数 + M - -## 2. 往返行程的区分 - -往返行程通过 `journeyDirection` 字段来区分: -- **outbound**:去程 -- **inbound**:回程 - -对于选座产品(`categoryCode=Seat`),每个座位通过 `segmentIndex` 标识其对应的航段。 - -## 3. 行李产品的特殊规则 - -### 转机行程的行李规格要求 - -在单向的转机行程中(即同一个 `journeyDirection` 下有多个航段),行李规格(重量、件数)**必须保持一致**。 - -### 规则说明 - -- 如果去程有3个航段(BOM→SGN→SYD→MEL),整个去程购买的行李规格必须相同 -- 例如:不能第1段购买20KG,第2段购买25KG -- 必须所有航段都购买20KG,或都购买25KG - -### 为什么需要相同规格? - -- 转机时行李会自动转运到下一航段,不需要重新托运 -- 航司系统要求整个行程使用相同的行李规格,以确保行李正常转运 - -### 往返行程的行李 - -- 去程和回程(不同的 `journeyDirection`)可以购买不同规格的行李 -- 例如:去程购买20KG,回程购买25KG是允许的 - -## 4. 选座产品的特殊规则 - -### 每个航段独立选座 - -与行李不同,选座是**每个航段独立进行的**。 - -### 规则说明 - -- 每个航段都需要单独选择座位(通过 seat 对象中的 segmentIndex 区分) -- 即使是转机行程,不同航段可以选择不同的座位 -- 例如:第1段选 12A,第2段选 15F - -### 为什么需要独立选座? - -- 每个航段的航班座位图不同 -- 机型、座位布局可能不同 -- 乘客可能希望在不同航段选择不同位置(如去程靠窗,回程靠过道) - -### 选座对象中的字段 - -- `segmentIndex`:标识选座对应的航段(seat 专用字段) -- `row`:座位行号(如 "12") -- `column`:座位列号(如 "A"、"F") - -**示例 - 转机行程选座:** - -往返直飞(去程1段+回程1段): -```json -// 去程座位 -{ - "categoryCode": "Seat", - "productCode": "SEAT_12A", - "journeyDirection": "outbound", - "seat": { - "segmentIndex": 1, - "row": "12", - "column": "A" - } -} -// 回程座位 -{ - "categoryCode": "Seat", - "productCode": "SEAT_8F", - "journeyDirection": "inbound", - "seat": { - "segmentIndex": 2, - "row": "8", - "column": "F" - } -} -``` - -往返转机(去程2段+回程2段): -```json -// 去程第1段座位 -{ - "categoryCode": "Seat", - "productCode": "SEAT_12A", - "journeyDirection": "outbound", - "seat": { - "segmentIndex": 1, - "row": "12", - "column": "A" - } -} -// 去程第2段座位 -{ - "categoryCode": "Seat", - "productCode": "SEAT_15F", - "journeyDirection": "outbound", - "seat": { - "segmentIndex": 2, - "row": "15", - "column": "F" - } -} -// 回程第1段座位(segmentIndex = 去程航段数 + 1 = 3) -{ - "categoryCode": "Seat", - "productCode": "SEAT_8A", - "journeyDirection": "inbound", - "seat": { - "segmentIndex": 3, - "row": "8", - "column": "A" - } -} -// 回程第2段座位(segmentIndex = 去程航段数 + 2 = 4) -{ - "categoryCode": "Seat", - "productCode": "SEAT_10F", - "journeyDirection": "inbound", - "seat": { - "segmentIndex": 4, - "row": "10", - "column": "F" - } -} -``` - diff --git a/plugins/mipu-api/skills/mipu-api/docs/08-01_itinerary.md b/plugins/mipu-api/skills/mipu-api/docs/08-01_itinerary.md deleted file mode 100644 index 9a26839..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/08-01_itinerary.md +++ /dev/null @@ -1,76 +0,0 @@ - -# Itinerary - 行程实体对象 - -Itinerary 实体(行程组合信息,与实际响应字段一致) - -| **参数名称** | **类型** | **说明** | -| --- | --- | --- | -| outboundSegments | Array<[SegmentElement](08-03_segment-element.md)> | 去程航段列表:单程(OW)和往返(RT)场景均返回,按行程顺序排列 | -| inboundSegments | Array<[SegmentElement](08-03_segment-element.md)> | 返程航段列表:仅往返(RT)场景返回,字段含义同 outboundSegments;单程(OW)场景为空数组 | -| fares | Array<[FlightFare](08-02_flight-fare.md)> | 该行程下的可选票价方案列表,每个方案包含去程/回程的票价、税费、座位数、舱位类型及航班政策信息 | - -## 实体轮廓 - -```json -{ - "outboundSegments": [ - { - "index": 1, - "carrier": "VJ", - "flightNumber": "VJ884", - "operatingCarrier": "", - "operatingFlightnumber": "", - "originAirport": "BOM", - "destinationAirport": "SGN", - "departureTime": "202510270040", - "arrivalTime": "202510270705", - "departureTerminal": "", - "arrivalTerminal": "", - "stopCities": "", - "duration": 295, - "aircraftCode": "330", - "codeShare": false - } - ], - "inboundSegments": [ - { - // 同 outboundSegments 结构 - } - ], - "fares": [ - { - "fareBasis": "", - "rtnFareBasis": "", - "fareFamily": "Lion Economy", - "rtnFareFamily": "Lion Promo", - "currency": "USD", - "bookingCode": "Y,Y", - "rtnBookingCode": "Y,Y", - "availableSeats": 7, - "rtnAvailableSeats": 2, - "flightPolicy": { - "airlineCode": "SL", - "fareFamilyType": "Lion Economy", - "description": "", - "freeAncillaryList": [ - { - "categoryCode": "CabinBaggageOverheadLocker", - "segmentIndex": 1, - "paxType": "ADT", - "piece": 1, - "weight": 7, - "size": "" - } - ], - "refundRules": [], // 预留字段,暂未提供 - "changeRules": [] // 预留字段,暂未提供 - }, - "rtnFlightPolicy": { - // 同 flightPolicy 结构 - } - } - ] -} -``` - -> `RuleElement` 结构详见 [FlightPolicy](08-04_flight-policy.md) diff --git a/plugins/mipu-api/skills/mipu-api/docs/08-02_flight-fare.md b/plugins/mipu-api/skills/mipu-api/docs/08-02_flight-fare.md deleted file mode 100644 index f7c456d..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/08-02_flight-fare.md +++ /dev/null @@ -1,32 +0,0 @@ - -# FlightFare - -FlightFare 实体用于描述不同乘客类型(成人 / 儿童 / 婴儿)的费用构成,拆分基础票价与税费等明细项,同时包含去程和返程的价格、政策信息,字段与实际响应完全对应。 - -> **说明**:带 `rtn` 前缀的字段为回程字段,仅往返程有值。 - -| **参数名称** | **类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| fareBasis | String | | 去 fareBasis 信息(如有) | -| rtnFareBasis | String | | 回程 fareBasis 信息(如有) | -| fareFamily | String | "Lion Economy" | 去程票价舱/产品类型名称 | -| rtnFareFamily | String | "Lion Promo" | 回程票价舱/产品类型名称 | -| currency | String | "USD" | 币种编码,遵循 ISO 4217 标准(如 USD = 美元,CNY = 人民币) | -| adultFare | BigDecimal | 6115.00 | 去程成人票价(不含税) | -| rtnAdultFare | BigDecimal | 6100.00 | 回程成人票价(不含税) | -| adultTax | BigDecimal | 13714.00 | 去程成人税费 | -| rtnAdultTax | BigDecimal | 8540.00 | 回程成人税费 | -| childFare | BigDecimal | 0.00 | 去程儿童票价(不含税),儿童定义为 2-12 周岁 | -| rtnChildFare | BigDecimal | 0.00 | 回程儿童票价(不含税) | -| childTax | BigDecimal | 0.00 | 去程儿童税费 | -| rtnChildTax | BigDecimal | 0.00 | 回程儿童税费 | -| infantFare | BigDecimal | 0.00 | 去程婴儿票价(不含税),婴儿定义为 0-2 周岁(无独立座位) | -| rtnInfantFare | BigDecimal | 0.00 | 回程婴儿票价(不含税) | -| infantTax | BigDecimal | 0.00 | 去程婴儿税费 | -| rtnInfantTax | BigDecimal | 0.00 | 回程婴儿税费 | -| bookingCode | String | "Y,Y" | 去程舱位代码(如 Y、B、M、W 等),廉航领域不一定存在,可通过系统设置-参数设置-默认舱位编码指定默认值。
**格式说明**:
- 单程直飞:单个代码,如 `"Y"`
- 单程转机:逗号分隔多段,如 `"B,Y"` 表示第一段 B 舱,第二段 Y 舱 | -| rtnBookingCode | String | "Y,Y" | 回程舱位代码(如 Y、B、M、W 等),廉航领域不一定存在。
**格式说明**:同 bookingCode,单段为单个代码,多段用逗号分隔 | -| availableSeats | int | 7 | 去程剩余座位数 | -| rtnAvailableSeats | int | 2 | 回程剩余座位数 | -| flightPolicy | [FlightPolicy](08-04_flight-policy.md) | | 去程航班政策(包含去程免费行李额、退改规则等) | -| rtnFlightPolicy | [FlightPolicy](08-04_flight-policy.md) | | 回程航班政策(包含回程免费行李额、退改规则等) | diff --git a/plugins/mipu-api/skills/mipu-api/docs/08-03_segment-element.md b/plugins/mipu-api/skills/mipu-api/docs/08-03_segment-element.md deleted file mode 100644 index c6b67e4..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/08-03_segment-element.md +++ /dev/null @@ -1,30 +0,0 @@ - -# FlightSegmentResponse - -# FlightSegment 对象定义 - -Segment 对象用于描述单段航班的核心信息(如在搜索结果中的去程航段 `outboundSegments`、返程航段 `inboundSegments`),具体定义如下: - -| **字段名** | **数据类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| index | Integer | 1 / 2 | 航段序号,按行程顺序递增(一般用于转机行程,第一段去程为 1,第二段去程为 2),非空且唯一 | -| carrier | String | "VJ" | 承运航司 IATA 二字码(如 VJ = 越南航空),**与 flightNumber 前缀的航司码一致**(示例中 flightNumber="VJ884",carrier="VJ" 符合规则) | -| flightNumber | String | "VJ884" | 航班号,格式为 “航司二字码 + 数字”: | -| operatingFlightnumber | String | "" | 实际承运航班号:- 代码共享航班时,填写实际承运航司的航班号- 非代码共享航班时,空字符串或与 flightNumber 一致(示例中为非代码共享,故为空) | -| operatingCarrier | String | "" | 实际承运航司 IATA 二字码:- 代码共享航班(codeShare=true)时,需填写实际承运航司(如 carrier="CA",operatingCarrier="MU")- 非代码共享航班(codeShare=false)时,空字符串或与 carrier 一致(示例中为非代码共享,故为空) | -| originAirport | String | "BOM" / "SGN" | 出发机场 IATA 三字码(如 BOM = 孟买贾特拉帕蒂・希瓦吉国际机场,SGN = 胡志明市新山一国际机场) | -| departureTime | String | "202510270040" | 起飞日期时间,固定格式 `YYYYMMDDHHMM`(202510270040 表示 2025 年 10 月 27 日 00:40) | -| destinationAirport | String | "SGN" / "SYD" | 到达机场 IATA 三字码(如 SYD = 悉尼金斯福德・史密斯机场) | -| arrivalTime | String | "202510270705" | 到达日期时间,格式同 depTime(202510280805 表示 2025 年 10 月 28 日 08:05) | -| stopCities | String | "" | 经停地,空字符串表示直飞 | -| duration | int | 295 / 515 | 飞行时长,单位为分钟(295 分钟 = 4 小时 55 分钟,515 分钟 = 8 小时 35 分钟) | -| codeShare | boolean | false | 代码共享标识:- true = 代码共享航班(由其他航司实际承运)- false = 非代码共享航班(由 carrier 航司直接承运) | -| cabin | String | "" | 舱位等级代码(如 "Y"= 经济舱、"C"= 公务舱),空字符串表示未明确具体舱位代码 | -| aircraftCode | String | "330" | 机型编码(如 "330"= 空客 A330,"738"= 波音 737-800),用于标识执飞客机型号 | -| departureTerminal | String | "T1" | 起飞机场航站楼(如 "T2"=2 号航站楼),空字符串表示未明确航站楼信息(需以机场实时通知为准) | -| arrivalTerminal | String | "T1" | 到达机场航站楼,规则同 departureTerminal | - -# 特殊业务规则备注 - -1. **航班号前 0 规则**:响应体内的航班号会按照航司接口中获取数据原样返回,请注意处理是否带0的情况。 - diff --git a/plugins/mipu-api/skills/mipu-api/docs/08-04_flight-policy.md b/plugins/mipu-api/skills/mipu-api/docs/08-04_flight-policy.md deleted file mode 100644 index 1b354ae..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/08-04_flight-policy.md +++ /dev/null @@ -1,43 +0,0 @@ - -# FlightPolicy - -# FlightPolicy 实体定义(基于实际响应) - -该实体用于描述航班的附加产品信息(如免费行李额、退改规则等),字段与最新响应数据完全对齐。 - -> **注意**:去程和回程的免费行李额分别存储在 `FlightFare.flightPolicy` 和 `FlightFare.rtnFlightPolicy` 中,因此 `freeBaggageList` 不再包含 `journeyDirection` 字段来区分方向。 - -| **字段名** | **数据类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| airlineCode | String | "SL" | 航司代码 | -| fareFamilyType | String | "Lion Economy" | 舱位/子舱位类型名称 | -| description | String | | 政策描述 | -| freeAncillaryList | List\ | | 免费行李额列表(详见下方说明) | -| refundRules | List\ | | 退票规则列表(预留字段,暂未提供) | -| changeRules | List\ | | 改签规则列表(预留字段,暂未提供) | - -## freeAncillaryList(FreeAncillary) - -免费行李额元素,描述每个航段、每种乘客类型的免费行李配额。 - -| **字段名** | **数据类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| categoryCode | String | "StandardCheckedBaggage" | 辅营类型代码:`StandardCheckedBaggage` = 托运行李,`CabinBaggageUnderSeat` = 客舱行李(座椅下),`CabinBaggageOverheadLocker` = 客舱行李(行李架) | -| segmentIndex | Integer | 1 | 航段序号,从 1 开始 | -| paxType | String | "ADT" | 乘客类型:`ADT` = 成人,`CHD` = 儿童,`INF` = 婴儿 | -| piece | Integer | 1 | 行李件数(PC) | -| weight | Integer | 20 | 行李重量(KG) | -| size | String | | 行李尺寸 | - -**示例:** - -```json -{ - "freeAncillaryList": [ - { "categoryCode": "CabinBaggageOverheadLocker", "segmentIndex": 1, "paxType": "ADT", "piece": 1, "weight": 7 }, - { "categoryCode": "StandardCheckedBaggage", "segmentIndex": 1, "paxType": "ADT", "piece": 1, "weight": 20 }, - { "categoryCode": "CabinBaggageOverheadLocker", "segmentIndex": 2, "paxType": "ADT", "piece": 1, "weight": 7 }, - { "categoryCode": "StandardCheckedBaggage", "segmentIndex": 2, "paxType": "ADT", "piece": 1, "weight": 20 } - ] -} -``` \ No newline at end of file diff --git a/plugins/mipu-api/skills/mipu-api/docs/08-05_ancillary-product.md b/plugins/mipu-api/skills/mipu-api/docs/08-05_ancillary-product.md deleted file mode 100644 index 7ad66ac..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/08-05_ancillary-product.md +++ /dev/null @@ -1,121 +0,0 @@ - -# AncillaryProduct(辅营产品) - -## 数据结构总览 - -辅营产品采用三级嵌套结构: - -``` -AncillaryGroup(分组层) - └─ AncillaryCategory(类别层) - └─ BaggageOption(选项层) -``` - ---- - -## AncillaryGroup(分组层) - -按 **航程方向 + 运价家族** 分组的最外层容器。 - -| 字段名 | 类型 | 示例值 | 说明 | -|--------|------|--------|------| -| currency | String | "CAD" | 售价币种(ISO 4217) | -| fareFamilyType | String | "BASIC" | 运价家族类型,如 `BASIC`、`SMART`、`PROMO` | -| journeyDirection | String | "outbound" | 航程方向:`outbound`(去程)/ `inbound`(回程) | -| categoryList | Array\ | - | 辅营类别列表 | - ---- - -## AncillaryCategory(类别层) - -按行李类别分组,携带定价模式和购买限制。 - -| 字段名 | 类型 | 示例值 | 说明 | -|--------|------|--------|------| -| categoryCode | String | "StandardCheckedBaggage" | 类别代码,见下方 categoryCode 说明 | -| maxPieces | String | "5" | 该类别最多可购买件数 | -| pricingMode | String | "STEP" | 定价模式:`FLAT` / `STEP` / `TIERED`,见下方说明 | -| categoryDetail | Array\ | - | 该类别下的选项列表 | - -### categoryCode 说明 - -| categoryCode | 说明 | -|--------------|------| -| CabinBaggageOverheadLocker | 手提行李(头顶行李架) | -| CabinBaggageUnderSeat | 手提行李(座椅下) | -| StandardCheckedBaggage | 托运行李 | - -### pricingMode 说明 - -| pricingMode | 说明 | -|-------------|------| -| FLAT | 固定单价,每件为独立产品,pieceNo 固定为 1 | -| STEP | 逐件定价,pieceNo 表示第 N 件,同 pieceNo 可有多个重量选项 | -| TIERED | 按总重量档位选择,不计件,pieceNo 固定为 1 | - ---- - -## BaggageOption(选项层) - -具体的行李规格和价格。 - -| 字段名 | 类型 | 示例值 | 说明 | -|--------|------|--------|------| -| pieceNo | Integer | 1 | 第 N 件。STEP 模式下为序号(1, 2, 3...),FLAT/TIERED 模式下为 1 | -| weight | BigDecimal | 23 | 行李额重量(KG) | -| size | String | "55x40x23cm" | 尺寸限制,空字符串表示无特殊限制 | -| price | BigDecimal | 64.00 | 该选项/该件价格 | -| maxPieces | Integer | 1 | 该选项可购买数量 | - ---- - -## 响应示例 - -### STEP 模式示例 - -```json -{ - "currency": "CAD", - "fareFamilyType": "BASIC", - "journeyDirection": "outbound", - "categoryList": [ - { - "categoryCode": "StandardCheckedBaggage", - "maxPieces": "5", - "pricingMode": "STEP", - "categoryDetail": [ - { "pieceNo": 1, "weight": 10, "size": "", "price": 39.00, "maxPieces": 1 }, - { "pieceNo": 1, "weight": 23, "size": "", "price": 64.00, "maxPieces": 1 }, - { "pieceNo": 2, "weight": 23, "size": "", "price": 64.00, "maxPieces": 1 }, - { "pieceNo": 3, "weight": 23, "size": "", "price": 99.00, "maxPieces": 1 } - ] - } - ] -} -``` - -> **STEP 模式解读**:第 1 件可选 10kg($39)或 23kg($64),第 2 件 23kg($64),第 3 件 23kg($99)。 - -### TIERED 模式示例 - -```json -{ - "currency": "CNY", - "fareFamilyType": "ECONOMY", - "journeyDirection": "outbound", - "categoryList": [ - { - "categoryCode": "StandardCheckedBaggage", - "maxPieces": "1", - "pricingMode": "TIERED", - "categoryDetail": [ - { "pieceNo": 1, "weight": 20, "size": "", "price": 300.00, "maxPieces": 1 }, - { "pieceNo": 1, "weight": 25, "size": "", "price": 500.00, "maxPieces": 1 }, - { "pieceNo": 1, "weight": 30, "size": "", "price": 800.00, "maxPieces": 1 } - ] - } - ] -} -``` - -> **TIERED 模式解读**:按重量档位互斥选择,20kg(¥300)、25kg(¥500)或 30kg(¥800),只能选一个。 diff --git a/plugins/mipu-api/skills/mipu-api/docs/08-06_fee-items.md b/plugins/mipu-api/skills/mipu-api/docs/08-06_fee-items.md deleted file mode 100644 index 479ab77..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/08-06_fee-items.md +++ /dev/null @@ -1,230 +0,0 @@ - -# feeItems 实体定义 - -该实体用于拆分航班预订费用,字段与最新响应数据完全对齐,同时补充业务含义说明: - -### **字段结构** - -```plaintext -feeItems -├── amount (总金额) -├── currency (货币代码) -├── fare (票价) -│ ├── amount (票价总金额) -│ ├── name (费用名称) -│ ├── remark (费用备注) -│ └── passengers (按乘机人拆分) -│ └── 每个乘客的票价明细 -├── tax (税费) -│ ├── amount (税费总金额) -│ ├── name (费用名称) -│ ├── remark (费用备注) -│ ├── passengers (按乘机人拆分) -│ │ └── 每个乘客的税费明细 -│ │ └── fees (税费细项) -│ │ └── 每个税费的明细 -│ └── fees (税费总细项) -│ └── 每个税费的明细 -├── cabinBaggage (手提行李) -│ ├── amount (手提行李总金额) -│ ├── name (费用名称) -│ ├── remark (费用备注) -│ └── passengers (按乘机人拆分) -│ └── 每个乘客的手提行李费用明细 -├── checkedBaggage (托运行李) -│ ├── amount (托运行李总金额) -│ ├── name (费用名称) -│ ├── remark (费用备注) -│ └── passengers (按乘机人拆分) -│ └── 每个乘客的托运行李费用明细 -├── seat (座位) -│ ├── amount (座位总金额) -│ ├── name (费用名称) -│ ├── remark (费用备注) -│ └── passengers (按乘机人拆分) -│ └── 每个乘客的座位费用明细 -├── payment (支付手续费) -│ ├── amount (支付手续费总金额) -│ ├── name (费用名称) -│ └── remark (费用备注) -└── other (其他额外费用) - ├── amount (其他额外费用总金额) - ├── name (费用名称) - -``` - -| 字段名 | 数据类型 | 示例值 | 说明 | -| --- | --- | --- | --- | -| totalPrice | Decimal | "850.00" | 总金额:航班预订的全部费用合计,单位与 currency 一致 | -| currency | String | "CNY" | 货币代码:标识费用的货币类型(如 CNY 为人民币、USD 为美元) | -| ticketPrice | Object | {"amount":"200.00","name":"票价",...} | 票价对象:包含票价总金额、费用名称、备注及可选的乘机人拆分明细(PassengerFee 数组) | -| tax | Object | {"amount":"250.00","name":"税",...} | 税费对象:包含税费总金额、费用名称、备注,可选乘机人拆分明细(PassengerFee 数组)和税费细项(FeeDetail 数组) | -| cabinBaggage | Object | {"amount":"50.00","name":"手提行李",...} | 手提行李费用对象:包含总金额、费用名称、备注及可选的乘机人拆分明细(PassengerFee 数组),可选字段 | -| checkedBaggage | Object | {"amount":"150.00","name":"托运行李",...} | 托运行李费用对象:包含总金额、费用名称、备注及可选的乘机人拆分明细(PassengerFee 数组),可选字段 | -| seat | Object | {"amount":"100.00","name":"座位",...} | 座位费用对象:包含总金额、费用名称、备注及可选的乘机人拆分明细(PassengerFee 数组),可选字段 | -| payment | Object | {"amount":"50.00","name":"支付手续费",...} | 支付手续费对象:包含总金额、费用名称、备注,无乘机人拆分,可选字段 | -| other | Object | {"amount":"0.00","name":"其他费用",...} | 其他额外费用对象:包含总金额、费用名称、备注,无乘机人拆分,可选字段 | - -## 嵌套实体定义 - -### PassengerFee(乘机人费用明细) - -| 字段名 | 数据类型 | 示例值 | 说明 | -| --- | --- | --- | --- | -| amount | Decimal | "100.00" | 乘机人对应费用金额:单个乘客在该费用类型下的应付金额 | -| name | String | "willow/yang" | 乘机人姓名:对应乘客的姓名标识 | -| remark | String | "成人票价" | 备注:说明该乘客费用的相关信息(如乘客类型、费用用途) | -| fees | Array[FeeDetail] | [{"amount":"100.00","name":"机场税",...}] | 税费细项数组:仅税费对象的乘机人明细中可选,包含该乘客的具体税费拆分,可选字段 | - -### FeeDetail(费用细项明细) - -| 字段名 | 数据类型 | 示例值 | 说明 | -| --- | --- | --- | --- | -| amount | Decimal | "170.00" | 细项金额:单个费用细项的总金额或乘机人对应金额 | -| name | String | "机场税" | 细项名称:描述费用细项的类型(如机场税、燃油附加费) | -| remark | String | "机场税" | 备注:补充说明费用细项的相关信息,与名称语义一致 | -| code | String | - | 费用细项编码:唯一标识该费用细项类型,可选字段 | - -### **响应示例** - -```json -{ - "success": true, - "feeItems": { - "totalPrice": "850.00", - "currency": "CNY", - "ticketPrice": { - "amount": "200.00", - "name": "票价", - "remark": "票价", - "passengers": [ - { - "amount": "100.00", - "name": "willow/yang", - "remark": "成人票价" - }, - { - "amount": "100.00", - "name": "jasen/yang", - "remark": "成人票价" - } - ] - }, - "tax": { - "amount": "250.00", - "name": "税", - "remark": "税费", - "passengers": [ - { - "amount": "150.00", - "name": "willow/yang", - "remark": "成人税价", - "fees": [ - { - "amount": "100.00", - "name": "机场税", - "remark": "机场税" - }, - { - "amount": "50.00", - "name": "燃油附加费", - "remark": "燃油附加费" - } - ] - }, - { - "amount": "100.00", - "name": "jasen/yang", - "remark": "成人税价", - "fees": [ - { - "amount": "70.00", - "name": "机场税", - "remark": "机场税" - }, - { - "amount": "30.00", - "name": "燃油附加费", - "remark": "燃油附加费" - } - ] - } - ], - "fees": [ - { - "amount": "170.00", - "name": "机场税", - "remark": "机场税" - }, - { - "amount": "80.00", - "name": "燃油附加费", - "remark": "燃油附加费" - } - ] - }, - "cabinBaggage": { - "amount": "50.00", - "name": "手提行李", - "remark": "手提行李费", - "passengers": [ - { - "amount": "25.00", - "name": "willow/yang", - "remark": "手提行李费" - }, - { - "amount": "25.00", - "name": "jasen/yang", - "remark": "手提行李费" - } - ] - }, - "checkedBaggage": { - "amount": "150.00", - "name": "托运行李", - "remark": "托运行李费", - "passengers": [ - { - "amount": "75.00", - "name": "willow/yang", - "remark": "托运行李费" - }, - { - "amount": "75.00", - "name": "jasen/yang", - "remark": "托运行李费" - } - ] - }, - "seat": { - "amount": "100.00", - "name": "座位", - "remark": "选座费", - "passengers": [ - { - "amount": "50.00", - "name": "willow/yang", - "remark": "选座费" - }, - { - "amount": "50.00", - "name": "jasen/yang", - "remark": "选座费" - } - ] - }, - "payment": { - "amount": "50.00", - "name": "支付手续费", - "remark": "支付手续费" - }, - "other": { - "amount": "0.00", - "name": "其他费用", - "remark": "其他费用" - } - } -} -``` - diff --git a/plugins/mipu-api/skills/mipu-api/docs/09-01_device-list.md b/plugins/mipu-api/skills/mipu-api/docs/09-01_device-list.md deleted file mode 100644 index e10f707..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/09-01_device-list.md +++ /dev/null @@ -1,141 +0,0 @@ - -# device/list - 设备列表 - -## 概述 - -设备列表API用于查询当前客户的所有设备信息,包括设备状态、绑定的VCC卡、任务状态等。 - -### 用户使用场景 - -本接口用于: -- 查看所有可用设备及其在线状态 -- 检查设备的VCC卡绑定情况 -- 查看设备的任务处理状态 - -## 请求说明 - -| 项目 | 值 | -|------|-----| -| **请求地址** | `https://${endpoint}/device/list` | -| **请求方法** | GET | -| **注意事项** | 无需请求体,从Header中获取clientCode | - -### Header 参数 - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -## 返回参数 - -成功时返回设备信息列表: - -```json -[ - { - "deviceId": "device-001", - "status": "ONLINE", - "vccCardNumber": "424242******4242", - "bindingVccCardNumber": "555555******5555", - "lastHeartbeatTime": 1704140800000, - "taskStatus": "PROCESSING", - "processingTask": { - "taskId": "task-123", - "taskType": "BIND_VCC", - "status": "PROCESSING", - "createTime": "2025-01-15T10:30:00Z", - "updateTime": "2025-01-15T10:35:00Z", - "deviceId": "device-001" - }, - "pendingTasks": [] - }, - { - "deviceId": "device-002", - "status": "OFFLINE", - "vccCardNumber": "378222******2222", - "bindingVccCardNumber": null, - "lastHeartbeatTime": 1704130000000, - "taskStatus": "IDLE", - "processingTask": null, - "pendingTasks": [ - { - "taskId": "task-124", - "taskType": "UNBIND_VCC", - "status": "PENDING", - "createTime": "2025-01-15T11:00:00Z", - "updateTime": "2025-01-15T11:00:00Z", - "deviceId": "device-002" - } - ] - } -] -``` - -| 参数名称 | 类型 | 说明 | -|----------|------|------| -| deviceId | String | 设备编号 | -| status | String | 设备状态:ONLINE=在线,OFFLINE=离线 | -| vccCardNumber | String | 当前绑定的VCC卡号(脱敏显示) | -| bindingVccCardNumber | String | 正在绑定的VCC卡号(脱敏显示,绑定任务进行中时存在) | -| lastHeartbeatTime | Long | 最后心跳时间(时间戳毫秒) | -| taskStatus | String | 任务状态:IDLE=空闲,PROCESSING=处理中,PENDING=有等待任务 | -| processingTask | Object | 正在执行的任务信息 | -| pendingTasks | Array | 等待队列中的任务列表 | - -### TaskInfo 任务信息 - -| 参数名称 | 类型 | 说明 | -|----------|------|------| -| taskId | String | 任务ID | -| taskType | String | 任务类型:BIND_VCC=绑定VCC卡,UNBIND_VCC=解绑VCC卡,PAYMENT=支付 | -| status | String | 任务状态:PENDING=等待中,PROCESSING=处理中,COMPLETED=已完成,FAILED=失败 | -| createTime | String | 创建时间(ISO 8601格式) | -| updateTime | String | 更新时间(ISO 8601格式) | -| deviceId | String | 设备ID | - -## 业务案例 - -### 查询所有设备状态 - -### 请求 - -```bash -curl -X GET "https://${endpoint}/device/list" \ - -H "client-key: your_key" \ - -H "client-secret: your_secret" -``` - -### 响应 - -```json -[ - { - "deviceId": "device-001", - "status": "ONLINE", - "vccCardNumber": "424242******4242", - "bindingVccCardNumber": null, - "lastHeartbeatTime": 1704140800000, - "taskStatus": "IDLE", - "processingTask": null, - "pendingTasks": [] - } -] -``` - -## 常见问题 - -### 设备状态ONLINE和OFFLINE的区别是什么? - -- **ONLINE**:设备在线,可以接收和处理任务 -- **OFFLINE**:设备离线,无法处理任务 - -### taskStatus有几种状态? - -- **IDLE**:设备空闲,没有正在处理的任务 -- **PROCESSING**:设备正在执行任务 -- **PENDING**:设备有待处理的任务队列 - -### VCC卡号为什么要脱敏显示? - -为了保护支付安全,VCC卡号只显示前6位和后4位,中间用*替换。 diff --git a/plugins/mipu-api/skills/mipu-api/docs/09-02_device-bind.md b/plugins/mipu-api/skills/mipu-api/docs/09-02_device-bind.md deleted file mode 100644 index 4b97346..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/09-02_device-bind.md +++ /dev/null @@ -1,143 +0,0 @@ - -# device/bind - VCC卡绑定 - -## 概述 - -VCC卡绑定API用于向设备提交VCC卡绑定请求。绑定过程是异步的,提交后会返回任务ID,可以通过任务查询接口查询绑定进度。 - -### 用户使用场景 - -本接口用于: -- 为在线设备绑定新的VCC卡 -- 替换设备当前绑定的VCC卡 - -## 请求说明 - -| 项目 | 值 | -|------|-----| -| **请求地址** | `https://${endpoint}/device/bind` | -| **请求方法** | POST | -| **注意事项** | 绑定过程是异步的,需要轮询任务状态 | - -### Header 参数 - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### 请求体参数 - -```json -{ - "deviceId": "device-001", - "creditCard": { - "cardNumber": "4242424242424242", - "cvv": "123", - "expiryDate": "12/25" - } -} -``` - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| deviceId | String | 是 | "device-001" | 设备编号 | -| creditCard | Object | 是 | - | 信用卡信息 | -| creditCard.cardNumber | String | 是 | "4242424242424242" | 卡号 | -| creditCard.cvv | String | 是 | "123" | CVV码 | -| creditCard.expiryDate | String | 是 | "12/25" | 有效期,格式:MM/YY | - -## 返回参数 - -成功时返回任务信息: - -```json -{ - "success": true, - "message": "VCC卡绑定任务已提交", - "taskId": "task-bind-123456" -} -``` - -| 参数名称 | 类型 | 说明 | -|----------|------|------| -| success | Boolean | 是否成功提交 | -| message | String | 结果消息 | -| taskId | String | 任务ID,用于查询任务状态 | - -失败时返回: - -```json -{ - "success": false, - "message": "设备离线,无法执行绑定任务", - "taskId": null -} -``` - -## 业务案例 - -### 绑定VCC卡 - -### 请求 - -```bash -curl -X POST "https://${endpoint}/device/bind" \ - -H "Content-Type: application/json" \ - -H "client-key: your_key" \ - -H "client-secret: your_secret" \ - -d '{ - "deviceId": "device-001", - "creditCard": { - "cardNumber": "4242424242424242", - "cvv": "123", - "expiryDate": "12/25" - } - }' -``` - -### 响应 - -```json -{ - "success": true, - "message": "VCC卡绑定任务已提交", - "taskId": "task-bind-123456" -} -``` - -### 查询绑定任务进度 - -使用返回的taskId查询任务状态: - -```bash -curl -X GET "https://${endpoint}/device/task/task-bind-123456" \ - -H "client-key: your_key" \ - -H "client-secret: your_secret" -``` - -## 常见问题 - -### 绑定是同步还是异步的? - -绑定是**异步操作**。提交绑定请求后会立即返回任务ID,需要通过任务查询接口轮询任务状态。 - -### 绑定失败的可能原因? - -- 设备离线(status=OFFLINE) -- 设备正在执行其他任务(taskStatus=PROCESSING) -- 信用卡信息格式错误 -- 信用卡已过期 - -### 如何判断绑定是否完成? - -通过任务查询接口检查任务状态: -- **PENDING**:任务在队列中等待 -- **PROCESSING**:正在绑定中 -- **COMPLETED**:绑定完成 -- **FAILED**:绑定失败 - -### 绑定完成后如何验证? - -再次调用设备列表接口,查看设备的 `vccCardNumber` 字段是否已更新为新卡号。 diff --git a/plugins/mipu-api/skills/mipu-api/docs/09-03_device-unbind.md b/plugins/mipu-api/skills/mipu-api/docs/09-03_device-unbind.md deleted file mode 100644 index 775c587..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/09-03_device-unbind.md +++ /dev/null @@ -1,128 +0,0 @@ - -# device/unbind - VCC卡解绑 - -## 概述 - -VCC卡解绑API用于向设备提交VCC卡解绑请求。解绑过程是异步的,提交后会返回任务ID,可以通过任务查询接口查询解绑进度。 - -### 用户使用场景 - -本接口用于: -- 移除设备当前绑定的VCC卡 -- 更换VCC卡前先解绑旧卡 - -## 请求说明 - -| 项目 | 值 | -|------|-----| -| **请求地址** | `https://${endpoint}/device/unbind` | -| **请求方法** | POST | -| **注意事项** | 解绑过程是异步的,需要轮询任务状态 | - -### Header 参数 - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### 请求体参数 - -```json -{ - "deviceId": "device-001" -} -``` - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| deviceId | String | 是 | "device-001" | 设备编号 | - -## 返回参数 - -成功时返回任务信息: - -```json -{ - "success": true, - "message": "VCC卡解绑任务已提交", - "taskId": "task-unbind-123456" -} -``` - -| 参数名称 | 类型 | 说明 | -|----------|------|------| -| success | Boolean | 是否成功提交 | -| message | String | 结果消息 | -| taskId | String | 任务ID,用于查询任务状态 | - -失败时返回: - -```json -{ - "success": false, - "message": "设备没有绑定的VCC卡", - "taskId": null -} -``` - -## 业务案例 - -### 解绑VCC卡 - -### 请求 - -```bash -curl -X POST "https://${endpoint}/device/unbind" \ - -H "Content-Type: application/json" \ - -H "client-key: your_key" \ - -H "client-secret: your_secret" \ - -d '{ - "deviceId": "device-001" - }' -``` - -### 响应 - -```json -{ - "success": true, - "message": "VCC卡解绑任务已提交", - "taskId": "task-unbind-123456" -} -``` - -### 查询解绑任务进度 - -使用返回的taskId查询任务状态: - -```bash -curl -X GET "https://${endpoint}/device/task/task-unbind-123456" \ - -H "client-key: your_key" \ - -H "client-secret: your_secret" -``` - -## 常见问题 - -### 解绑是同步还是异步的? - -解绑是**异步操作**。提交解绑请求后会立即返回任务ID,需要通过任务查询接口轮询任务状态。 - -### 解绑失败的可能原因? - -- 设备离线(status=OFFLINE) -- 设备正在执行其他任务(taskStatus=PROCESSING) -- 设备没有绑定的VCC卡(vccCardNumber为空) - -### 如何判断解绑是否完成? - -通过任务查询接口检查任务状态: -- **PENDING**:任务在队列中等待 -- **PROCESSING**:正在解绑中 -- **COMPLETED**:解绑完成 -- **FAILED**:解绑失败 - -### 解绑完成后如何验证? - -再次调用设备列表接口,查看设备的 `vccCardNumber` 字段是否已为空。 diff --git a/plugins/mipu-api/skills/mipu-api/docs/09-04_device-task.md b/plugins/mipu-api/skills/mipu-api/docs/09-04_device-task.md deleted file mode 100644 index 9b3e821..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/09-04_device-task.md +++ /dev/null @@ -1,165 +0,0 @@ - -# device/task/{taskId} - 查询任务 - -## 概述 - -任务查询API用于查询设备任务的执行状态和详情。通过绑定/解绑接口获取的任务ID,可以使用本接口查询任务进度。 - -### 用户使用场景 - -本接口用于: -- 查询VCC卡绑定任务的状态 -- 查询VCC卡解绑任务的状态 -- 查询支付任务的状态 -- 获取任务的详细信息和设备状态 - -## 请求说明 - -| 项目 | 值 | -|------|-----| -| **请求地址** | `https://${endpoint}/device/task/{taskId}` | -| **请求方法** | GET | -| **注意事项** | taskId从绑定/解绑接口返回中获取 | - -### Header 参数 - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### URL 参数 - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| taskId | String | 是 | "task-bind-123456" | 任务ID,从绑定/解绑接口返回 | - -## 返回参数 - -成功时返回任务详情: - -```json -{ - "deviceId": "device-001", - "deviceStatus": "ONLINE", - "task": { - "taskId": "task-bind-123456", - "taskType": "BIND_VCC", - "status": "PROCESSING", - "createTime": "2025-01-15T10:30:00Z", - "updateTime": "2025-01-15T10:35:00Z", - "deviceId": "device-001", - "orderId": null, - "creditCard": { - "cardNumber": "424242******4242", - "cvv": "***", - "expiryDate": "12/25" - }, - "orderDetail": null - } -} -``` - -| 参数名称 | 类型 | 说明 | -|----------|------|------| -| deviceId | String | 执行任务的设备ID | -| deviceStatus | String | 设备状态:ONLINE=在线,OFFLINE=离线 | -| task | Object | 任务详细信息 | - -### Task 任务信息 - -| 参数名称 | 类型 | 说明 | -|----------|------|------| -| taskId | String | 任务ID | -| taskType | String | 任务类型:BIND_VCC=绑定VCC卡,UNBIND_VCC=解绑VCC卡,PAYMENT=支付 | -| status | String | 任务状态:PENDING=等待中,PROCESSING=处理中,COMPLETED=已完成,FAILED=失败 | -| createTime | String | 创建时间(ISO 8601格式) | -| updateTime | String | 更新时间(ISO 8601格式) | -| deviceId | String | 设备ID | -| orderId | String | 订单ID(仅PAYMENT类型任务) | -| creditCard | Object | 信用卡信息(仅BIND_VCC类型任务,脱敏显示) | -| orderDetail | String | 订单详情(仅PAYMENT类型任务) | - -## 业务案例 - -### 查询绑定任务状态 - -### 请求 - -```bash -curl -X GET "https://${endpoint}/device/task/task-bind-123456" \ - -H "client-key: your_key" \ - -H "client-secret: your_secret" -``` - -### 响应 - 任务处理中 - -```json -{ - "deviceId": "device-001", - "deviceStatus": "ONLINE", - "task": { - "taskId": "task-bind-123456", - "taskType": "BIND_VCC", - "status": "PROCESSING", - "createTime": "2025-01-15T10:30:00Z", - "updateTime": "2025-01-15T10:35:00Z", - "deviceId": "device-001", - "creditCard": { - "cardNumber": "424242******4242", - "cvv": "***", - "expiryDate": "12/25" - } - } -} -``` - -### 响应 - 任务完成 - -```json -{ - "deviceId": "device-001", - "deviceStatus": "ONLINE", - "task": { - "taskId": "task-bind-123456", - "taskType": "BIND_VCC", - "status": "COMPLETED", - "createTime": "2025-01-15T10:30:00Z", - "updateTime": "2025-01-15T10:36:00Z", - "deviceId": "device-001" - } -} -``` - -### 响应 - 任务不存在 - -```json -{ - "deviceId": null, - "deviceStatus": null, - "task": null -} -``` - -## 常见问题 - -### 任务状态有哪几种? - -- **PENDING**:任务在队列中等待执行 -- **PROCESSING**:任务正在执行中 -- **COMPLETED**:任务执行完成 -- **FAILED**:任务执行失败 - -### 任务查询不到是什么原因? - -- 任务ID错误 -- 任务已完成且已被清理(根据系统配置,任务可能会在完成后一段时间被清理) -- 任务ID来自其他客户 - -### 为什么要轮询查询任务状态? - -因为绑定/解绑操作是异步的,设备需要时间完成操作。建议间隔3-5秒轮询一次,直到任务状态变为 COMPLETED 或 FAILED。 - -### 信用卡信息为什么要脱敏? - -为了保护支付安全,任务详情中的信用卡信息只显示脱敏后的卡号和掩码CVV。 diff --git a/plugins/mipu-api/skills/mipu-api/docs/10_error-codes.md b/plugins/mipu-api/skills/mipu-api/docs/10_error-codes.md deleted file mode 100644 index 9b62819..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/10_error-codes.md +++ /dev/null @@ -1,62 +0,0 @@ - -# 错误码说明 - -## 完整错误码列表 - -| 错误码 | 枚举名称 | 消息 | 可重试 | 说明 | -|--------|----------|------|--------|------| -| 100 | - | 鉴权失败 | false | 请检查 client-key, client-secret 信息是否正确 | -| 102 | - | 超过限流 | true | 请求频率超过限制,请稍后重试 | -| 103 | - | Proxy error | true | 代理服务器失败,请检查代理服务器 URL 是否正确,或者代理 IP 用量是否足够。如果使用平台代理且刚刚修改过命名,请等待 5 分钟平台缓存同步再试 | -| 104 | - | Agent not exist or agent is disabled | false | 检查 agent code 是否正确,agent 是否被停用。如果刚刚创建运行器(agent),请等待 5 分钟平台缓存同步再试 | -| 40013 | AGENT_MISSED_CREDENTIAL | Agent credential not configured | false | Agent 凭证未配置,请检查 Agent 的认证信息是否正确配置 | -| 42010 | PRICE_CHANGED | Fare price has changed, please check latest price from feeitem | false | 价格变动,请检查响应中的 feeItems 获取最新价格 | -| 41007 | FLIGHT_NOT_AVAILABLE | Flight not available | true | 航班不存在/已售罄 | -| 42011 | INSUFFICIENT_SEATS | Insufficient seats | true | 剩余座位不足 | -| 42000 | ORDER_ID_REQUIRED | Order ID is required | false | 缺少订单 ID | -| 42001 | ORDER_ID_DUPLICATE | Order ID already exists | false | 订单 ID 重复 | -| 42002 | PASSENGER_MISMATCH | Passenger information mismatch | false | 乘客信息不匹配 | -| 42003 | BOOKING_FAILED | Failed to create booking | true | 预订失败 | -| 42004 | HOLD_EXECUTION_FAILED | Hold execution failed | true | Hold 执行失败 | -| 42005 | BOOKING_NOT_FOUND | Booking not found | false | 预订未找到 | -| 42006 | DUPLICATE_PASSENGER_NAME | Duplicate passenger name in booking | false | 乘客姓名重复 | -| 42007 | DUPLICATE_BOOKING | Duplicate booking detected | false | 重复预订 | -| 42008 | INVALID_PASSENGER_INFO | Invalid passenger information | false | 乘客信息错误 | -| 42009 | DOCUMENT_ISSUE | Document validation failed | false | 证件问题 | -| 42012 | SEAT_NOT_AVAILABLE | Selected seat is not available | false | 所选座位不可用 | -| 49000 | SYSTEM_ERROR | Internal system error | true | 系统内部错误 | -| 49003 | QUOTA_EXCEEDED | Daily quota exceeded. Please upgrade your plan or try again tomorrow. | false | 日配额已超限,请升级套餐或明天再试 | - -## PRICE_CHANGED (42010) 详细说明 - -**触发场景:** - -当航司侧票价高于预期时,接口会返回错误码 42010。 - -**响应结构:** - -```json -{ - "code": 42010, - "msg": "Fare price has changed, please check latest price from feeitem", - "timestamp": "2024-11-15T10:30:00Z", - "data": { - "orderId": "abbc4b57fb75", - "feeItems": { - "baseFare": 110.00, - "taxes": 52.50, - "total": 162.50, - "currency": "EUR" - } - } -} -``` - -**处理流程:** - -1. 接收到 42010 错误响应 -2. 从响应的 `data.feeItems` 中获取最新价格 -3. 向用户展示价格变动信息 -4. 询问用户是否接受新价格 -5. 如用户同意,重新调用接口 -6. 如用户拒绝,取消订单流程 diff --git a/plugins/mipu-api/skills/mipu-api/docs/11-01_mailbox-domain-list.md b/plugins/mipu-api/skills/mipu-api/docs/11-01_mailbox-domain-list.md deleted file mode 100644 index ef1309a..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/11-01_mailbox-domain-list.md +++ /dev/null @@ -1,90 +0,0 @@ - -# mailbox/domain/list - 域名列表 - -## 概述 - -查询当前客户已绑定的所有邮箱域名列表。 - -### 使用场景 - -- 查看当前客户已绑定的所有邮箱域名列表 -- 管理员需要了解企业邮箱的域名配置情况 - -## 请求说明 - -| 项目 | 值 | -|------|-----| -| **请求地址** | `https://${endpoint}/mailbox/domain/list` | -| **请求方法** | POST | -| **注意事项** | 无需请求体,系统自动从请求上下文中提取 clientCode | - -### Header 参数 - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -## 返回参数 - -返回 `MailboxDomain` 对象数组: - -| 参数名称 | 类型 | 示例值 | 说明 | -|----------|------|--------|------| -| domainId | Long | 123 | 域名配置主键 | -| domainName | String | example.com | 域名全称 | -| status | Integer | 1 | 状态:0-待审核,1-已启用,2-已禁用,3-已删除 | -| statusText | String | 已启用 | 状态文本描述 | -| verifyStatus | Integer | 2 | 验证状态:0-未验证,1-验证中,2-验证通过,3-验证失败 | -| verifyStatusText | String | 验证通过 | 验证状态文本 | -| verifyToken | String | a1b2c3d4 | DNS验证令牌 | -| verifyHost | String | _mailbox-verify-a1b2c3d4 | DNS验证主机名 | -| verifyTime | String | 2025-01-01T10:00:00Z | 验证通过时间(ISO 8601格式) | -| createTime | String | 2025-01-01T10:00:00Z | 创建时间(ISO 8601格式) | -| updateTime | String | 2025-01-02T10:00:00Z | 更新时间(ISO 8601格式) | -| remark | String | 备注信息 | 备注 | - -## 返回示例 - -```json -[ - { - "domainId": 123, - "domainName": "example.com", - "status": 1, - "statusText": "已启用", - "verifyStatus": 2, - "verifyStatusText": "验证通过", - "verifyToken": "a1b2c3d4", - "verifyHost": "_mailbox-verify-a1b2c3d4", - "verifyTime": "2025-01-01T10:00:00Z", - "createTime": "2025-01-01T10:00:00Z", - "updateTime": "2025-01-02T10:00:00Z", - "remark": "主域名" - }, - { - "domainId": 124, - "domainName": "company.com", - "status": 0, - "statusText": "待审核", - "verifyStatus": 0, - "verifyStatusText": "未验证", - "verifyToken": "e5f6g7h8", - "verifyHost": "_mailbox-verify-e5f6g7h8", - "verifyTime": null, - "createTime": "2025-01-03T10:00:00Z", - "updateTime": "2025-01-03T10:00:00Z", - "remark": "备用域名" - } -] -``` - -## 错误码说明 - -| 错误码 | 说明 | -|--------|------| -| 401 | 认证失败,client-key 或 client-secret 无效 | -| 403 | 权限不足,无权访问该客户的域名列表 | -| 500 | 服务器内部错误 | diff --git a/plugins/mipu-api/skills/mipu-api/docs/11-02_mailbox-domain-apply.md b/plugins/mipu-api/skills/mipu-api/docs/11-02_mailbox-domain-apply.md deleted file mode 100644 index 3281d91..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/11-02_mailbox-domain-apply.md +++ /dev/null @@ -1,90 +0,0 @@ - -# mailbox/domain/apply - 申请绑定域名 - -# 申请绑定域名(mailbox/domain/apply) API 说明文档 - -## 使用场景 - -> 1. 企业客户需要为自己的邮箱系统绑定自定义域名 -> 1. 配置企业邮箱后,员工可以使用 @company.com 格式的邮箱地址 - -## 错误场景(不应该使用本接口的场景) - -> 1. 域名已被其他客户绑定 -> 1. 域名格式不正确(如包含非法字符) -> 1. 客户已达到域名绑定数量上限 - -## 性能指标 - -> - 响应速度:98% 的请求响应速度 < 1000ms - -## 请求说明 - -| **请求地址** | https://${endpoint}/mailbox/domain/apply | -| --- | --- | -| **请求方法** | POST | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境secret | - -### 请求体 - -```json -{ - "domainName": "example.com" -} -``` - -#### 参数详情 - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| domainName | String | 是 | example.com | 要绑定的域名名称,必须是有效的域名格式 | - -## 返回参数 - -| **参数名称** | **类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| domainId | Long | 123 | 域名唯一标识 | -| domainName | String | example.com | 域名名称 | -| status | String | PENDING | 域名状态:PENDING=待DNS验证 | -| dnsVerified | Boolean | false | DNS验证状态,新申请的域名需要验证 | -| createTime | String | 2025-01-02T10:00:00Z | 域名创建时间(ISO 8601格式) | - -## 返回示例 - -```json -{ - "domainId": 123, - "domainName": "example.com", - "status": "PENDING", - "dnsVerified": false, - "createTime": "2025-01-02T10:00:00Z" -} -``` - -## 后续步骤 - -申请域名绑定后,需要完成DNS验证才能激活邮箱服务: - -1. 在域名DNS管理中添加相应的MX记录 -2. 调用 `mailbox/domain/verify` 接口验证DNS配置 -3. 验证通过后,域名状态将变为 ACTIVE - -## 错误码说明 - -| **错误码** | **说明** | -| --- | --- | -| 400 | 请求参数错误,域名格式不正确 | -| 401 | 认证失败,client-key 或 client-secret 无效 | -| 409 | 域名已被其他客户绑定 | -| 429 | 已达到域名绑定数量上限 | -| 500 | 服务器内部错误 | diff --git a/plugins/mipu-api/skills/mipu-api/docs/11-03_mailbox-domain-detail.md b/plugins/mipu-api/skills/mipu-api/docs/11-03_mailbox-domain-detail.md deleted file mode 100644 index ac1feff..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/11-03_mailbox-domain-detail.md +++ /dev/null @@ -1,87 +0,0 @@ - -# mailbox/domain/detail - 域名详情 - -# 查询域名详情(mailbox/domain/detail) API 说明文档 - -## 使用场景 - -> 1. 查看指定域名的详细配置信息 -> 1. 管理员需要了解域名的DNS配置和验证状态 - -## 错误场景(不应该使用本接口的场景) - -> 1. 查询的域名ID不存在 -> 1. 查询的域名不属于当前客户(权限不足) - -## 性能指标 - -> - 响应速度:98% 的请求响应速度 < 500ms - -## 请求说明 - -| **请求地址** | https://${endpoint}/mailbox/domain/detail | -| --- | --- | -| **请求方法** | POST | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境secret | - -### 请求体 - -```json -{ - "domainId": 123 -} -``` - -#### 参数详情 - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| domainId | Long | 是 | 123 | 域名ID | - -## 返回参数 - -| **参数名称** | **类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| domainId | Long | 123 | 域名唯一标识 | -| domainName | String | example.com | 域名名称 | -| status | String | ACTIVE | 域名状态 | -| dnsVerified | Boolean | true | DNS验证状态 | -| createTime | String | 2025-01-01T10:00:00Z | 域名创建时间 | -| updateTime | String | 2025-01-02T10:00:00Z | 域名更新时间 | -| mxRecord | String | mail.example.com | MX记录(如已配置) | -| txtRecord | String | v=spf1 include:... | SPF记录(如已配置) | - -## 返回示例 - -```json -{ - "domainId": 123, - "domainName": "example.com", - "status": "ACTIVE", - "dnsVerified": true, - "createTime": "2025-01-01T10:00:00Z", - "updateTime": "2025-01-02T10:00:00Z", - "mxRecord": "mail.example.com", - "txtRecord": "v=spf1 include:_spf.example.com ~all" -} -``` - -## 错误码说明 - -| **错误码** | **说明** | -| --- | --- | -| 400 | 请求参数错误,domainId 格式不正确 | -| 401 | 认证失败,client-key 或 client-secret 无效 | -| 403 | 权限不足,无权访问该域名信息 | -| 404 | 域名不存在 | -| 500 | 服务器内部错误 | diff --git a/plugins/mipu-api/skills/mipu-api/docs/11-04_mailbox-domain-delete.md b/plugins/mipu-api/skills/mipu-api/docs/11-04_mailbox-domain-delete.md deleted file mode 100644 index 90acea3..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/11-04_mailbox-domain-delete.md +++ /dev/null @@ -1,95 +0,0 @@ - -# mailbox/domain/delete - 删除域名 - -# 删除域名(mailbox/domain/delete) API 说明文档 - -## 使用场景 - -> 1. 企业不再需要使用某个域名作为邮箱域名 -> 1. 域名配置错误,需要删除后重新申请 - -## 错误场景(不应该使用本接口的场景) - -> 1. 域名下仍有活跃的邮箱账户(需要先删除邮箱账户) -> 1. 域名不属于当前客户(权限不足) -> 1. 域名ID不存在 - -## 性能指标 - -> - 响应速度:98% 的请求响应速度 < 1000ms - -## 请求说明 - -| **请求地址** | https://${endpoint}/mailbox/domain/delete | -| --- | --- | -| **请求方法** | POST | - -## 请求参数 - -### Header - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境secret | - -### 请求体 - -```json -{ - "domainId": 123 -} -``` - -#### 参数详情 - -| **参数名称** | **类型** | **是否必选** | **示例值** | **说明** | -| --- | --- | --- | --- | --- | -| domainId | Long | 是 | 123 | 要删除的域名ID | - -## 返回参数 - -| **参数名称** | **类型** | **示例值** | **说明** | -| --- | --- | --- | --- | -| code | Integer | 0 | 状态码:0=成功,1=失败 | -| msg | String | Domain deleted successfully | 操作结果消息 | -| domainId | Long | 123 | 被删除的域名ID | - -## 返回示例 - -成功响应: -```json -{ - "code": 0, - "msg": "Domain deleted successfully", - "domainId": 123 -} -``` - -失败响应: -```json -{ - "code": 1, - "msg": "Failed to delete domain", - "domainId": 123 -} -``` - -## 注意事项 - -> - 删除域名是不可逆操作,请谨慎操作 -> - 删除前请确保该域名下没有关联的邮箱账户 -> - 删除后,该域名的所有邮箱服务将停止 - -## 错误码说明 - -| **错误码** | **说明** | -| --- | --- | -| 400 | 请求参数错误,domainId 格式不正确 | -| 401 | 认证失败,client-key 或 client-secret 无效 | -| 403 | 权限不足,无权删除该域名 | -| 404 | 域名不存在 | -| 409 | 域名下仍有活跃的邮箱账户,无法删除 | -| 500 | 服务器内部错误 | diff --git a/plugins/mipu-api/skills/mipu-api/docs/11-06_mailbox-mail-search.md b/plugins/mipu-api/skills/mipu-api/docs/11-06_mailbox-mail-search.md deleted file mode 100644 index e125903..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/11-06_mailbox-mail-search.md +++ /dev/null @@ -1,400 +0,0 @@ - -# mailbox/mail/search - 搜索邮件 - -## 概述 - -根据关键词、邮件类型等条件搜索邮件,返回分页结果。 - -### 使用场景 - -- 用户需要在邮箱中查找特定邮件 -- 根据关键词、邮件类型等条件筛选邮件 -- 分页浏览邮件列表 - -## 请求说明 - -| 项目 | 值 | -|------|-----| -| **请求地址** | `https://${endpoint}/mailbox/mail/search` | -| **请求方法** | POST | - -### Header 参数 - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON | -| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 | -| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key | -| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret | - -### 请求体参数 - -| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 | -|----------|------|----------|--------|------| -| keyword | String | 否 | 机票 | 搜索关键词,支持邮件主题、发件人等 | -| mailType | Integer | 否 | 1 | 邮件类型:1-收件,2-发件 | -| domainName | String | 否 | example.com | 域名过滤 | -| hasAttachment | Boolean | 否 | true | 是否有附件 | -| readStatus | Integer | 否 | 0 | 阅读状态:0-未读,1-已读 | -| startTime | String | 否 | 2025-01-01T00:00:00Z | 起始时间(ISO 8601格式,**必须使用UTC时区**,以`Z`结尾) | -| endTime | String | 否 | 2025-01-31T23:59:59Z | 结束时间(ISO 8601格式,**必须使用UTC时区**,以`Z`结尾) | -| airlineCode | String | 否 | CA | 航空代码(如:CA-国航、MU-东航、CZ-南航等) | -| pageIndex | Integer | 是 | 1 | 页码,从1开始 | -| pageSize | Integer | 是 | 20 | 每页数量,建议10-50,最大100 | -| orderBy | String | 否 | sendTime | 排序字段,支持:`sendTime`(发送时间)、`receiveTime`(接收时间)、`subject`(主题) | -| orderDirection | String | 否 | DESC | 排序方向:`ASC`=升序,`DESC`=降序 | - -#### 请求体示例 - -```json -{ - "keyword": "机票", - "mailType": 1, - "airlineCode": "CA", - "pageIndex": 1, - "pageSize": 20, - "orderBy": "sendTime", - "orderDirection": "DESC" -} -``` - -## 返回参数 - -返回分页结果 `PageResult`: - -| 参数名称 | 类型 | 示例值 | 说明 | -|----------|------|--------|------| -| pageIndex | Integer | 1 | 当前页码 | -| pageSize | Integer | 20 | 每页数量 | -| total | Long | 150 | 总记录数 | -| records | Array\ | - | 邮件列表 | - -> **注意**: -> - 请求和响应统一使用 `pageIndex` -> - 总页数 `totalPages` 字段已移除,前端需自行计算:`totalPages = Math.ceil(total / pageSize)` - -### MailInfo 对象字段 - -| 参数名称 | 类型 | 示例值 | 说明 | -|----------|------|--------|------| -| mailId | String | MSG_001 | 邮件ID | -| subject | String | 机票预订确认 | 邮件主题 | -| fromAddress | String | airline@example.com | 发件人地址 | -| toAddresses | String\[\] | ["user@example.com"] | 收件人列表 | -| ccAddresses | String\[\] | ["cc@example.com"] | 抄送列表 | -| mailType | Integer | 1 | 邮件类型:1-收件,2-发件 | -| mailTypeText | String | 收件 | 类型文本 | -| hasAttachment | Boolean | true | 是否有附件 | -| attachmentCount | Integer | 2 | 附件数量 | -| mailSize | Long | 1024000 | 邮件大小(字节) | -| mailSizeText | String | 1.0 MB | 人性化大小 | -| readStatus | Integer | 0 | 阅读状态:0-未读,1-已读 | -| receiveTime | String | 2025-01-02T10:00:00Z | 接收时间 | -| sendTime | String | 2025-01-02T10:00:00Z | 发送时间 | -| emlDownloadUrl | String | https://... | 原始EML文件下载地址(临时链接,1小时有效期) | - -## 返回示例 - -```json -{ - "pageIndex": 1, - "pageSize": 20, - "total": 150, - "records": [ - { - "mailId": "MSG_001", - "subject": "机票预订确认", - "fromAddress": "airline@example.com", - "toAddresses": ["user@example.com"], - "ccAddresses": ["cc@example.com"], - "mailType": 1, - "mailTypeText": "收件", - "hasAttachment": true, - "attachmentCount": 2, - "mailSize": 1024000, - "mailSizeText": "1.0 MB", - "readStatus": 0, - "receiveTime": "2025-01-02T10:00:00Z", - "sendTime": "2025-01-02T10:00:00Z", - "emlDownloadUrl": "https://cdn.example.com/download/eml/MSG_001?token=xxx" - }, - { - "mailId": "MSG_002", - "subject": "航班变更通知", - "fromAddress": "airline@example.com", - "toAddresses": ["user@example.com"], - "ccAddresses": [], - "mailType": 1, - "mailTypeText": "收件", - "hasAttachment": false, - "attachmentCount": 0, - "mailSize": 51200, - "mailSizeText": "50.0 KB", - "readStatus": 1, - "receiveTime": "2025-01-02T09:00:00Z", - "sendTime": "2025-01-02T09:00:00Z", - "emlDownloadUrl": "https://cdn.example.com/download/eml/MSG_002?token=yyy" - } - ] -} -``` - -## 时区说明 - -### UTC 时区要求 - -本接口要求所有时间参数**必须使用 UTC 时区**(协调世界时)。 - -**什么是 UTC?** -- UTC(Coordinated Universal Time)是世界标准时间,不受夏令时影响 -- UTC 是全球统一的时间基准,与地理位置无关 -- 北京时间 = UTC + 8小时,纽约时间 = UTC - 5小时(东部标准时间) - -**为什么使用 UTC?** -1. **避免时区混淆**:不同地区的服务器和客户端使用不同时区会导致时间解释错误 -2. **跨时区一致**:确保全球用户查询结果一致 -3. **简化逻辑**:无需处理复杂的时区转换和夏令时问题 - -**时间格式要求:** -``` -ISO 8601 格式:2025-01-15T00:00:00Z - ^^^^^^^^^^^ ^^^^^^^ ^ ^ - 日期 时间 时区标识(UTC) -``` - -### 时间转换示例 - -| 本地时间 | UTC 时间(需要发送) | 说明 | -|----------|---------------------|------| -| 2025-01-15 00:00:00 (北京) | 2025-01-14T16:00:00Z | 北京时间 UTC+8,减8小时 | -| 2025-01-15 00:00:00 (纽约) | 2025-01-15T05:00:00Z | 纽约时间 UTC-5,加5小时 | -| 2025-01-15 00:00:00 (伦敦) | 2025-01-15T00:00:00Z | 伦敦时间 UTC+0(冬季) | -| 2025-01-15 00:00:00 (东京) | 2025-01-14T15:00:00Z | 东京时间 UTC+9,减9小时 | - -> **重要**:发送时间前,请务必将本地时间转换为 UTC 时间! - -### 代码示例 - -#### Java 示例 - -```java -import java.time.*; -import java.time.format.DateTimeFormatter; -import okhttp3.*; -import com.google.gson.Gson; - -public class MailSearchExample { - - private static final String API_ENDPOINT = "https://api.example.com/mailbox/mail/search"; - private static final String CLIENT_KEY = "your-client-key"; - private static final String CLIENT_SECRET = "your-client-secret"; - - public static void main(String[] args) { - // 方式1: 使用当前时间(自动转换为UTC) - ZonedDateTime nowUtc = ZonedDateTime.now(ZoneOffset.UTC); - ZonedDateTime oneDayAgoUtc = nowUtc.minusDays(1); - - // 方式2: 从本地时间转换到UTC - ZonedDateTime localTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai")); - ZonedDateTime utcTime = localTime.withZoneSameInstant(ZoneOffset.UTC); - - // 方式3: 指定特定时间(例如:北京时间2025-01-15 00:00:00) - ZonedDateTime beijingTime = ZonedDateTime.of( - 2025, 1, 15, 0, 0, 0, 0, - ZoneId.of("Asia/Shanghai") - ); - ZonedDateTime startTimeUtc = beijingTime.withZoneSameInstant(ZoneOffset.UTC); - ZonedDateTime endTimeUtc = beijingTime.plusDays(1).minusSeconds(1) - .withZoneSameInstant(ZoneOffset.UTC); - - // 格式化为ISO 8601格式(带Z后缀) - DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT; - String startTime = startTimeUtc.format(formatter); // 2025-01-14T16:00:00Z - String endTime = endTimeUtc.format(formatter); // 2025-01-15T15:59:59Z - - // 构建请求体 - MailSearchRequest request = new MailSearchRequest(); - request.setKeyword("机票"); - request.setMailType(1); - request.setStartTime(startTime); - request.setEndTime(endTime); - request.setPageIndex(1); - request.setPageSize(20); - - // 设置排序(按发送时间降序) - request.setOrderBy("sendTime"); - request.setOrderDirection("DESC"); - - // 发送请求 - sendRequest(request); - } - - static class MailSearchRequest { - private String keyword; - private Integer mailType; - private String startTime; - private String endTime; - private Integer pageIndex; - private Integer pageSize; - private String orderBy; - private String orderDirection; - - // getters and setters... - } - - private static void sendRequest(MailSearchRequest request) throws Exception { - Gson gson = new Gson(); - String json = gson.toJson(request); - - OkHttpClient client = new OkHttpClient(); - RequestBody body = RequestBody.create( - json, - MediaType.parse("application/json; charset=utf-8") - ); - - Request httpRequest = new Request.Builder() - .url(API_ENDPOINT) - .post(body) - .addHeader("Content-Type", "application/json") - .addHeader("Accept-Encoding", "gzip, deflate, br") - .addHeader("client-key", CLIENT_KEY) - .addHeader("client-secret", CLIENT_SECRET) - .build(); - - try (Response response = client.newCall(httpRequest).execute()) { - System.out.println(response.body().string()); - } - } -} -``` - -#### Python 示例 - -```python -import requests -from datetime import datetime, timezone, timedelta -from zoneinfo import ZoneInfo # Python 3.9+ -import json - -API_ENDPOINT = "https://api.example.com/mailbox/mail/search" -CLIENT_KEY = "your-client-key" -CLIENT_SECRET = "your-client-secret" - -def search_mails(): - # 方式1: 使用当前UTC时间 - now_utc = datetime.now(timezone.utc) - one_day_ago_utc = now_utc - timedelta(days=1) - - # 方式2: 从本地时间转换到UTC(例如:北京时间) - beijing_tz = ZoneInfo("Asia/Shanghai") - local_time = datetime(2025, 1, 15, 0, 0, 0, tzinfo=beijing_tz) - start_time_utc = local_time.astimezone(timezone.utc) - end_time_utc = (local_time + timedelta(days=1) - timedelta(seconds=1)).astimezone(timezone.utc) - - # 方式3: 直接创建UTC时间 - start_time_utc = datetime(2025, 1, 14, 16, 0, 0, tzinfo=timezone.utc) - end_time_utc = datetime(2025, 1, 15, 15, 59, 59, tzinfo=timezone.utc) - - # 格式化为ISO 8601格式(带Z后缀) - start_time = start_time_utc.isoformat() - end_time = end_time_utc.isoformat() - # 结果: "2025-01-14T16:00:00+00:00" 或 "2025-01-14T16:00:00Z" - - # 确保以Z结尾(某些库可能使用+00:00) - if not start_time.endswith('Z'): - start_time = start_time.replace('+00:00', 'Z').replace('+00:00:00', 'Z') - if not end_time.endswith('Z'): - end_time = end_time.replace('+00:00', 'Z').replace('+00:00:00', 'Z') - - # 构建请求体 - payload = { - "keyword": "机票", - "mailType": 1, - "startTime": start_time, # "2025-01-14T16:00:00Z" - "endTime": end_time, # "2025-01-15T15:59:59Z" - "pageIndex": 1, - "pageSize": 20, - "orderBy": "sendTime", - "orderDirection": "DESC" - } - - # 发送请求 - headers = { - "Content-Type": "application/json", - "Accept-Encoding": "gzip, deflate, br", - "client-key": CLIENT_KEY, - "client-secret": CLIENT_SECRET - } - - response = requests.post( - API_ENDPOINT, - data=json.dumps(payload), - headers=headers - ) - - print(f"Status Code: {response.status_code}") - print(f"Response: {response.json()}") - - return response.json() - -# 常用时区转换工具函数 -def convert_to_utc(local_time_str, local_timezone="Asia/Shanghai"): - """ - 将本地时间字符串转换为UTC时间字符串 - - Args: - local_time_str: 本地时间,如 "2025-01-15 00:00:00" - local_timezone: 本地时区,默认 "Asia/Shanghai" - - Returns: - UTC时间字符串,如 "2025-01-14T16:00:00Z" - """ - local_tz = ZoneInfo(local_timezone) - local_dt = datetime.strptime(local_time_str, "%Y-%m-%d %H:%M:%S") - local_dt = local_dt.replace(tzinfo=local_tz) - utc_dt = local_dt.astimezone(timezone.utc) - return utc_dt.isoformat().replace('+00:00', 'Z') - -# 使用示例 -if __name__ == "__main__": - # 北京时间 2025-01-15 00:00:00 转换为 UTC - utc_time = convert_to_utc("2025-01-15 00:00:00", "Asia/Shanghai") - print(f"UTC Time: {utc_time}") # 输出: 2025-01-14T16:00:00Z - - search_mails() -``` - -#### cURL 示例 - -```bash -curl -X POST "https://api.example.com/mailbox/mail/search" \ - -H "Content-Type: application/json" \ - -H "Accept-Encoding: gzip, deflate, br" \ - -H "client-key: your-client-key" \ - -H "client-secret: your-client-secret" \ - -d '{ - "keyword": "机票", - "mailType": 1, - "startTime": "2025-01-14T16:00:00Z", - "endTime": "2025-01-15T15:59:59Z", - "pageIndex": 1, - "pageSize": 20, - "orderBy": "sendTime", - "orderDirection": "DESC" - }' -``` - -## 搜索技巧 - -- 支持模糊匹配,关键词可以匹配邮件主题和发件人 -- mailType 为可选参数,不传则搜索所有类型邮件 -- 建议 pageSize 设置为 20-50 以获得最佳性能 -- **时间参数必须使用 UTC 时区**,发送前请确保时间已正确转换 - -## 错误码说明 - -| 错误码 | 说明 | -|--------|------| -| 400 | 请求参数错误,pageIndex、pageSize、orderBy 或 orderDirection 不合法 | -| 401 | 认证失败,client-key 或 client-secret 无效 | -| 500 | 服务器内部错误 | diff --git a/plugins/mipu-api/skills/mipu-api/docs/11_proxy-conventions.md b/plugins/mipu-api/skills/mipu-api/docs/11_proxy-conventions.md deleted file mode 100644 index 36e92bd..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/11_proxy-conventions.md +++ /dev/null @@ -1,55 +0,0 @@ - -# Proxy约定说明 - -用户可在luban系统(my.mipuyun.com)管理我们提供的高质量住宅代理。 - -为了更有效的使用代理,对于Proxy字段的发送提供以下约定 - ---- - -## 1. 指定代理地区/国家 - -在proxy名后拼接 `-国家码(地区码)`,myproxy是代理命名,举例如下: - -| 地区(国家) | 码 | Proxy命名举例 | -|-----------|---|--------------| -| 美国 | us | myproxy-us | -| 法国 | fr | myproxy-fr | -| 英国 | uk | myproxy-uk | -| **欧洲** | **eu** | **myproxy-eu** | - ---- - -## 2. 利用多个代理提升agent质量 - -为提升agent对接的质量,支持在proxy字段输入多个代理,并提供串行和并发来满足各种场景 - -### 拼接符号介绍 - -| 符号 | 说明 | -|------|------| -| **竖线 \|** | 多个代理随机选择 | -| **逗号 ,** | 多个代理串行选择,希望提升成功率,但可以接受响应速度略慢的场景 | -| **加号 +** | 多个代理并发执行,应用于有较高成功率&较低响应速度的场景 | - -### 代理使用示例 - -| 代理举例 | 适合场景 | 效果 | -|----------|---------|------| -| myproxy-us | 所有场景 | 指定US地区进行agent执行 | -| myproxy-us\|myproxy-uk | 所有场景 | 从US, UK两个地区随机选择一个进行agent执行 | -| myproxy-us\|myproxy-uk,myproxy-us\|myproxy-eu | **shopping/search** | 仅对shpping/search生效,可接受较大的响应时长等待,第一轮采用myproxy-us\|myproxy-uk进行对接。如果成功,立即返回结束业务。如果失败,采用myproxy-us\|myproxy-eu启动第二轮对接。 | -| myproxy-us + myproxy-uk | **shopping/select**
**shopping/baggage**
**shopping/seat** | 采用多线程并发模式,线程a采用myproxy-us,线程b采用myproxy-uk, 同时向航司发起业务请求。 | -| myproxy-us\|myproxy-eu + myproxy-uk\|myproxy-uk | **shopping/select**
**shopping/baggage**
**shopping/seat** | 采用多线程并发模式,线程a采用myproxy-us\|myproxy-eu,线程b采用myproxy-uk\|myproxy-uk, 同时向航司发起业务请求。 | - ---- - -## 3. 异常处理 - -### 如果将符号用在了不支持的场景怎么办? - -系统会最大限度接受异常的代理串输入,但会选择最保守的执行方式,我们会采集最小的代理信息进行执行。 - -**示例**: -- 并发场景(select/baggage/seat)收到逗号:`myproxy-us,myproxy-uk` -- 那么执行层会变成:`myproxy-us` diff --git a/plugins/mipu-api/skills/mipu-api/docs/12_brightdata-proxy-advanced.md b/plugins/mipu-api/skills/mipu-api/docs/12_brightdata-proxy-advanced.md deleted file mode 100644 index 989bbdd..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/12_brightdata-proxy-advanced.md +++ /dev/null @@ -1,157 +0,0 @@ - -# BrightData 代理串高级用法 - -# 📄 BrightData 代理 URL 使用指南 - -**适用于:BrightData Residential / Datacenter / Mobile Proxies** - ---- - -## 🔗 1. 代理 URL 格式解析 - -示例 URL: - -```plaintext -http://brd-customer-hl_333c2-zone-myproxy-country-us-session-11111vy0c -``` - -### ✅ 结构拆解: - -| **部分** | **说明** | -| --- | --- | -| brd-customer-hl_665225c2 | 客户 ID(固定,由 BrightData 分配) | -| zone=myproxy | 代理子账号名称 | -| country=us | 目标国家代码(ISO 3166-1 alpha-2,如 us, gb, jp) | -| session=11111vy0c | 会话 ID(用于控制 IP 是否复用) | -| proxypassword | 代理子账号密码 | -| brd.superproxy.io:22225 | BrightData 全球统一代理网关 | - -> 💡 **关键参数均通过用户名(username)中的字段传递**,这是 BrightData 的特殊设计。 - ---- - -## 🌍 2. 如何指定国家(Country) - -只需修改 `country=xx` 部分即可。 - -### 示例: - -```plaintext -# 美国 IP -...-country-us-... - -# 英国 IP -...-country-gb-... - -# 日本 IP -...-country-jp-... - -# 德国 IP - -``` - -> ✅ 支持所有 BrightData 覆盖的国家([完整国家列表](https%3A%2F%2Fbrightdata.com%2Fcountries)) -> ⚠️ 如果指定的国家无可用 IP,请求可能失败或返回默认地区 IP(取决于 Zone 设置) - ---- - -## 🔁 3. 如何更换 IP(获取新 IP) - -BrightData 使用 `**session**`** 参数控制 IP 复用**: - -- **相同 **`**session**`** 值 → 复用同一个出口 IP**(通常维持 5 分钟以上) -- **不同 **`**session**`** 值 → 获取全新 IP** -### ✅ 方法:修改 `session` 字段 - -#### 示例: - -```plaintext -# Session A: 固定 IP #1 -...-session-abc123@... - -# Session B: 固定 IP #2(与 abc123 不同) - -``` - -> 🔑 **只要 **`**session**`** 值不同,就会分配新 IP**(即使其他参数相同) - -### 💡 编程建议: - -在代码中动态生成随机 session ID 来每次获取新 IP: - -``` -import random -import string - -def generate_session_id(length=10): - return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length)) - -session = generate_session_id() - -``` - ---- - -## 🔒 4. 如何保持 IP 不变(固定 IP) - -只需 **在多次请求中使用相同的 **`**session**`** 值**。 - -### ✅ 规则: - -- 同一个 `session` 在 **5 分钟内有效** -- 在此期间,所有使用该 session 的请求将通过 **同一个出口 IP** -- 超过 5 分钟无活动,IP 可能被回收 -### 示例(固定美国 IP): - -```plaintext -http://brd-customer-hl_665225c2-zone-myproxy-country-us-session-my_fixed_ip_001:xxxxy0c@brd.superproxy.io:22225/ -``` - -> 🕒 建议:如果需要长时间固定 IP,每 5~8 分钟发一次心跳请求以保持会话活跃。 - ---- - -## 🛠️ 5. 完整使用示例(Python requests) - -``` -import requests - -# 固定美国 IP(session = "my_session_1") -proxy_url = "http://brd-customer-hl_665225c2-zone-myproxy-country-us-session-my_session_1:xxxxy0c@brd.superproxy.io:22225/" - -proxies = { - "http": proxy_url, - "https": proxy_url -} - -try: - resp = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10) - print(resp.json()) # 显示出口 IP -except Exception as e: - -``` - ---- - -## ⚙️ 6. 其他高级参数(可选) - -你还可以在 username 中添加更多参数(用 `-` 连接): - -[电子表格] - -> 📌 完整参数文档:[BrightData Proxy Parameters](https%3A%2F%2Fdocs.brightdata.com%2Fapi-reference%2Fproxy%2Fgeolocation-targeting%23city-targeting) - ---- - -## ❗ 注意事项 - -1. **密码(**`**proxypassword**`**)是敏感信息**,切勿泄露或提交到 Git。 -1. **不要硬编码 session** 用于大规模爬虫,避免 IP 被目标网站封禁。 ---- - -## ✅ 总结:核心操作速查 - -[电子表格] - ---- - diff --git a/plugins/mipu-api/skills/mipu-api/docs/README.md b/plugins/mipu-api/skills/mipu-api/docs/README.md deleted file mode 100644 index e487f1d..0000000 --- a/plugins/mipu-api/skills/mipu-api/docs/README.md +++ /dev/null @@ -1,29 +0,0 @@ - -# 米普云 - 航司接口转换器API文档 - -## 什么是航司接口转换器 - -航司接口转换器是一种中间服务工具,用于将不同航空公司的预订、出票、查询等系统接口进行标准化和适配。由于各航司的系统架构、数据格式、认证方式各不相同,直接对接成本高、开发周期长。航司接口转换器通过统一的接入层,帮助第三方平台(如OTA、旅行社、企业差旅系统等)快速、高效地与多个航司系统对接。 - -该转换器的核心功能包括: - -- **协议转换**:将不同航司的私有API或B2B协议转换为通用标准 -- **数据映射**:将航司返回的原始数据结构转换为易于理解和处理的统一格式 -- **身份代理**:通过Agent机制,自动完成登录、鉴权、会话维持等操作 -- **稳定性保障**:提供重试机制、错误处理、日志记录等功能,提升对接稳定性 - -## 如何使用航司接口转换器 - -### 1. 选择需要转换的航司&渠道 - -访问 https://my.mipuyun.com,登录后选择:航司列表菜单,在你需要转换的航司上面选择对应的渠道,一般渠道有 Web(官网)/B2B/API。 - -### 2. 创建Agent - -### 3. 在线测试 - -创建好 Agent 后,可在控制台中选择该 Agent 并点击"运行"按钮,立即发起一次测试请求。 - -### 4. 通过API与我们对接 - -当测试成功后,你可以调用我们的开放 API 接口,实现全流程自动化。 diff --git a/plugins/mipu-api/skills/mipu-api/update.sh b/plugins/mipu-api/skills/mipu-api/update.sh new file mode 100755 index 0000000..5eb49c6 --- /dev/null +++ b/plugins/mipu-api/skills/mipu-api/update.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Mipu API docs auto-updater +# Checks latest release from mipu-open repo and updates local docs. +# Safe to run in any environment — fails silently on network errors. + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +DOCS_DIR="$SCRIPT_DIR/docs" +VERSION_FILE="$SCRIPT_DIR/.version" +API_URL="https://git.addhh.com/api/v1/repos/willow/mipu-open/releases/latest" + +# Get current version +CURRENT="" +if [ -f "$VERSION_FILE" ]; then + CURRENT=$(cat "$VERSION_FILE" | tr -d '[:space:]') +fi + +# Fetch latest release info (timeout 3s, fail silently) +RELEASE=$(curl -sf --connect-timeout 3 --max-time 5 "$API_URL" 2>/dev/null) || exit 0 + +# Parse remote version +REMOTE=$(echo "$RELEASE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tag_name',''))" 2>/dev/null) || exit 0 + +# Skip if same version or empty +[ -z "$REMOTE" ] && exit 0 +[ "$REMOTE" = "$CURRENT" ] && exit 0 + +# Find docs.tar.gz download URL +ASSET_URL=$(echo "$RELEASE" | python3 -c " +import sys,json +r=json.load(sys.stdin) +for a in r.get('assets',[]): + if a['name']=='docs.tar.gz': + print(a['browser_download_url']) + break +" 2>/dev/null) || exit 0 + +[ -z "$ASSET_URL" ] && exit 0 + +# Download +TMP=$(mktemp /tmp/mipu-docs.XXXXXX.tar.gz) +curl -sfL --connect-timeout 5 --max-time 30 "$ASSET_URL" -o "$TMP" 2>/dev/null || { rm -f "$TMP"; exit 0; } + +# Replace docs directory +rm -rf "$DOCS_DIR" +mkdir -p "$SCRIPT_DIR" +tar -xzf "$TMP" -C "$SCRIPT_DIR" +rm -f "$TMP" + +# Write new version +echo "$REMOTE" > "$VERSION_FILE" + +echo "Mipu API docs updated: ${CURRENT:-none} → ${REMOTE}"