68 KiB
前端提醒后端待补接口
1. 文档定位
本文记录前端页面开发时希望后端新增、补齐或稳定的接口草案。本文中的路径、入参和返参是前端视角的最小诉求,不代表后端已经承诺实现;进入开发前需要后端按当前包结构、权限、安全和业务规则二次确认。
2. 当前待补接口总览
| 优先级 | 接口 | 页面 / 场景 | 状态 |
|---|---|---|---|
| P0 | 订单列表接口 GET /api/reservation/orders |
订单列表页、首页工作台 | 已完成第一版 |
| P0 | 任务列表接口 GET /api/reservation/tasks |
任务列表菜单、订单详情任务入口 | 已完成第一版,已补来源邮件会话字段和 order_status 筛选 |
| P0 | 订单详情接口 GET /api/reservation/orders/{orderId} |
订单详情页 | 已完成第一版,已补旧 tasks[] 来源邮件会话字段和 V4 order_overview / next_v4_action / related_source_messages[] / v4_order_tasks[].cards[],前端订单详情总览页已接入 |
| P0 | 任务详情读取接口 GET /api/reservation/tasks/{taskId} |
任务详情页动态渲染 | 已完成第一版,已补来源邮件字段和 3.0 字段元数据 |
| Done | V4 订单任务详情接口 GET /api/reservation/order-tasks/{orderTaskId} |
V4 任务详情页 | 已完成第一版;页面展示顺序调整为 Basic Information、业务卡、SourceMessage Display,来源邮件正文通过 SourceMessage conversation 接口读取当前触发邮件 |
| P0 | 任务详情操作接口 | 任务详情保存、确认、OPERA、审计 | 已完成;前端可直接接入 |
| P0 | 邮件会话详情接口 GET /api/source-messages/{sourceMessageId}/conversation |
邮件会话详情页 | 已完成第一版 |
| 联调 | 演示数据 seed 接口 POST /api/system/reservation/demo-data |
本地 / test 前端页面看效果 | 已完成;仅 dev/test 受控使用 |
| 联调 | Debug EML 上传接口 POST /api/system/debug/eml-superagent-runs |
Debug 页面上传 .eml 看 SuperAgent 结果 |
已完成第一版;仅 dev/test 受控使用 |
| P1 | S10/S99 源邮件只读通知卡与旧 S000/S999 兼容 | 任务列表、任务详情来源邮件查看 | 已完成第一版:旧 S000/S999 兼容,新结构化 S10/S99 可入站并在任务列表 / 详情只读展示 |
| P1 | type-known manual review 同卡复核解阻 | 任务详情复核 | 已完成第一版:原业务任务卡复核、字段修正、订单归属确认、READY 流转 |
| P1 | 任务卡前端字段白名单元数据接口 | 字段白名单调试、版本对齐 | 未完成;若任务详情已透出完整元数据,可后置 |
| P1 | 系统管理菜单树增强接口 | 系统设置 / 菜单管理树形交互 | 已完成:完整菜单树查询、批量保存父级和排序 |
| Done | V4 目录 Lookup API | V4 Basic Information、Room Type、Rate Code 选择 | M002 V4 CP11 已实现 Account / Room Type / Rate Code 数据库目录 lookup;设计与实现说明见 ../requirements/M002-v4-real-catalog-lookup-api-design.md |
| 后置 | 普通任务切换订单接口 | 任务详情订单归属调整 | 未完成;已确认后置 |
2.1 后端当前接口完成度核对
本节按 2026-07-08 当前后端 Controller 和 result record 核对,避免重复要求后端实现已经存在的接口。
| 接口 / 能力 | 当前后端状态 | 前端是否可直接接入 | 仍需后端处理 |
|---|---|---|---|
GET /api/reservation/tasks |
已完成第一版,已补来源邮件会话字段和所属订单状态筛选 | 可以 | order_status 按任务所属订单状态过滤;不传时保持当前全部任务列表行为。 |
GET /api/reservation/orders/{orderId} |
已完成第一版,已补旧 tasks[] 来源邮件会话字段、V4 总览和 V4 v4_order_tasks[] 时间线,前端订单详情总览页已接入 |
可以 | 暂无;include_tasks=false 时旧 tasks[]、V4 v4_order_tasks[] 和 related_source_messages[] 都返回空数组,order_overview 为空快照,next_v4_action.action_type=NONE。 |
GET /api/reservation/tasks/{taskId} |
已完成第一版,已补任务顶层来源邮件字段和 fields[] 3.0 元数据 |
可以 | 当前 Controller 不接收 hotel_id;如后续多酒店隔离需要前端显式传酒店上下文,请后端补可选入参或确认按 taskId 全局唯一即可。 |
GET /api/reservation/order-tasks/{orderTaskId} |
已完成第一版;Room Information 展示模型、复核态字段白名单和 Payment 附件安全摘要待补齐 | 可以,但 Room Information 业务化展示、复核态整卡编辑和 Payment 预览需后端补模型 / 摘要后再完整联动 | V4 任务详情页展示顺序为 Basic Information、业务卡、SourceMessage Display;Trace 卡 department_code 第一版固定为 FO / HSK / FO+HSK 三个下拉值,不调用 Department lookup,不开放自由输入。Room Information 下一阶段由后端返回业务展示模型:New 展示最终值,Update 展示 change_summary[] 和合并后的最终值,Cancel 展示本地订单投影只读;Nights 后端按酒店本地日期派生,Breakfast 前端为含早勾选框,Group Booking Status 显示 TEN-Tentative / DEF-Definite / INQ-Inquiry;New Booking 最终订单投影字段 group_block_name / fit_name 可编辑,Group 默认来自 target_order.locator_value 且 locator_type=GROUP_CODE,Fit 默认来自 guest_name ?? target_order.locator_value,但 Agent 原始 target_order.locator_value 只读且不被用户编辑回写。REVIEW_REQUIRED 仍是原业务卡复核态,问题字段红字提示,按钮统一显示“确认卡片”,前端内部调用 review-resolution。Rooming List 卡第一版只做事项确认,前端展示标题、状态、目标订单信息和“确认卡片”按钮,不做名单 rows、附件预览、Excel 生成或 PMS 导入。本接口仍不直接返回邮件正文或附件 URL。来源邮件卡正文限定为当前触发该 V4 order task 的那封 SourceMessage 正文,前端用 source_message_summary.source_message_id 调用 GET /api/source-messages/{sourceMessageId}/conversation 后定位当前邮件,默认长度折叠并可展开;缺少 SOURCE_MESSAGE_ORIGINAL_READ 或会话接口失败时降级展示安全摘要。Payment 卡下一阶段建议返回 payment_attachments[] 安全摘要,供前端展示图片缩略图 / 非图片文件列表;attachment_ids[] 第一版只读,不支持前端增删、替换或重新选择附件集合;实际大图预览和下载 URL 仍走 SourceMessage conversation。 |
PUT /api/reservation/tasks/{taskId}/draft |
已完成 | 可以 | 当前 Controller 不接收 hotel_id;如写操作需要酒店上下文幂等 / 权限校验,请后端补可选入参或请求体字段。 |
POST /api/reservation/tasks/{taskId}/confirm |
已完成 | 可以 | 当前 Controller 不接收 hotel_id;如写操作需要酒店上下文幂等 / 权限校验,请后端补可选入参或请求体字段。 |
GET /api/reservation/tasks/{taskId}/audits |
已完成 | 可以 | 当前 Controller 不接收 hotel_id;如审计查询需要酒店上下文隔离,请后端补可选入参。 |
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/execute |
已完成第一版模拟操作 | 可以 | 暂无;真实 OPERA 写入另行确认。 |
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/retry |
已完成第一版模拟重试 | 可以 | 暂无;真实 OPERA 重试另行确认。 |
POST /api/reservation/tasks/{taskId}/manual-review-conversions |
已完成 | 可以 | 暂无。 |
POST /api/reservation/tasks/{taskId}/manual-review-resolutions |
已完成第一版 | 可以 | 只用于 type-known manual review;第一版 confirmed_order_id 必须等于当前任务订单,不开放普通任务任意切换订单。 |
GET /api/source-messages |
已完成安全摘要列表 | 可以 | 不能替代邮件会话全文接口。 |
GET /api/source-messages/{id} |
已完成单条安全摘要 | 可以 | 不能替代邮件会话全文接口。 |
GET /api/source-messages/{id}/original |
已完成单封原文权限读取 | 谨慎接入 | 必须带 Bearer token,需要同时拥有 SOURCE_MESSAGE_READ 和 SOURCE_MESSAGE_ORIGINAL_READ;只能读单封邮件,不能返回同一 conversation 全量邮件。 |
GET /api/reservation/orders |
已完成第一版 | 可以 | 默认查询全部订单状态;订单列表待处理展示使用 open_work_item_count;V4 普通业务已停止双写旧任务,旧 open_task_count 仅作为历史诊断计数。 |
GET /api/source-messages/{sourceMessageId}/conversation |
已完成第一版,已补 html_body_sanitized 和 html_render_mode |
可以 | 必须带 Bearer token,需要同时拥有 SOURCE_MESSAGE_READ 和 SOURCE_MESSAGE_ORIGINAL_READ;返回完整 text/html、后端清洗后的 HTML、媒体外链和关联订单 / 任务摘要;前端不传原文读取 key,页面展示优先使用 html_body_sanitized。V4 Payment 卡图片大图预览和非图片下载也复用该权限链路,只能使用当前触发 SourceMessage 且被 attachment_ids[] 引用的附件。 |
POST /api/system/reservation/demo-data |
已完成 | 仅本地 / test 联调可用 | 默认关闭,必须后端配置访问口令;不能作为生产页面接口。 |
POST /api/system/debug/eml-superagent-runs |
已完成第一版 | 仅 dev/test Debug 页面可用 | 默认关闭,必须后端配置访问口令、阿里云 OSS 和 SuperAgent Open API;Debug 服务自身只展示 SuperAgent 结果,不直接创建订单和任务;如 SuperAgent 通过正式回调 / MCP 写入业务结果,V4 smoke 必须创建 V4 order task / cards,不再创建旧 workflow_reservation_task;已能识别旧 S000/S999 和新结构化 S10/S99。 |
GET /api/source-message-conversations/{externalConversationId} |
未发现后端实现 | 不可以 | 历史讨论过的候选路径,当前不提供;前端统一使用 GET /api/source-messages/{sourceMessageId}/conversation。 |
GET /api/reservation/message-notifications |
未发现后端实现 | 不可以 | 历史候选路径,当前不提供。旧 S000/S999 和 V3 S10/S99 兼容数据通过 SOURCE_MESSAGE_ONLY 任务展示;V4 S10/S99 新数据走 V4 工作台和 /api/reservation/source-notifications/{notificationId},不要再请求本候选路径。 |
GET /api/reservation/task-card-field-whitelist |
未发现后端实现 | 不可以 | 若任务详情 fields[] 已补齐 3.0 元数据,可后置。 |
GET /api/reservation/lookups/accounts / room-types / rate-codes |
M002 V4 CP11 已实现;Rate Code Account 范围过滤待补齐 | 可以,但 Rate Code 需后端新增过滤参数后再改前端联动 | 用于 V4 任务卡下拉 / 搜索选择;Bearer token + RESERVATION_TASK_READ + 酒店访问权;Account / Room Type 支持 hotel_id、keyword、page_num、page_size,只返回 ACTIVE 目录。Rate Code 下一阶段必须新增 account_code、booking_type=GROUP/FIT 必填过滤,只返回当前 Account + GROUP/FIT 适用候选。 |
3. 任务列表 / 工作台接口字段补齐
建议路径:
GET /api/reservation/tasks
当前状态:后端已按 P0 最小诉求实现第一版,前端任务列表页可以直接接入该接口。接口已返回任务摘要、订单展示键、来源消息 ID / 主题、来源邮件会话摘要和实时可处理状态,不返回完整 AI payload、邮件正文或附件 URL。
本轮前端新增“任务列表”菜单,并且任务列表、订单详情任务队列都需要能跳转到该任务来源消息所在的完整邮件会话。因此建议在现有返回项上补齐来源邮件会话摘要字段。
默认排序:未传 order_id 时按来源消息接收时间倒序返回,保证任务列表最新消息 / 最新任务在前;传 order_id 时按同订单 queue_sequence 正序返回,保证订单队列处理顺序不被打乱。
已完成字段:
| 字段 | 说明 |
|---|---|
task_id |
任务 ID。 |
order_id |
关联订单 ID。 |
hotel_id |
酒店上下文 ID。 |
display_order_key |
前端优先展示的业务号或临时订单号。 |
temporary_order_no |
临时订单号。 |
task_type |
系统主任务类型。 |
result_type |
AI 结果类型,例如 normal_task、manual_review、source_message_review_notification。 |
ai_task_type |
SuperAgent 原始任务类型,例如 New Booking、S10、S99。 |
task_subtype |
任务 subtype。 |
route_code |
M002 V3 路由码,例如 R01_NEW_FIT_RESERVATION_NORMAL、S10、S99。 |
system_process_category |
系统处理分类,例如 BUSINESS_TASK、SOURCE_MESSAGE_NOTIFICATION。 |
task_status |
任务状态。 |
card_name |
任务卡展示名称。 |
queue_sequence |
同订单队列顺序。 |
queue_participation |
是否参与订单执行队列。 |
can_process |
当前是否可处理。 |
readonly_reason_code |
只读原因代码。 |
source_message_id |
来源 SourceMessage Inbox ID。 |
source_subject |
来源消息主题摘要。 |
created_at |
任务创建时间。 |
updated_at |
任务更新时间。 |
建议入参:
| 参数 | 必填 | 说明 |
|---|---|---|
hotel_id |
否 | 酒店 ID。单酒店阶段默认可为空,由后端按当前用户上下文或平台酒店表唯一 ACTIVE 酒店解析;显式传值时后端会校验访问权限。 |
order_id |
否 | 按订单过滤。 |
task_type |
否 | 当前旧任务列表筛选只提供 NEW_BOOKING、UPDATE_BOOKING、CANCEL_BOOKING、MANUAL_REVIEW、SOURCE_MESSAGE_ONLY;不再提供历史 INFORMATIONAL_MESSAGE 筛选项。旧 S000/S999 和 V3 S10/S99 兼容数据复用 SOURCE_MESSAGE_ONLY 只读源邮件通知卡;V4 S10/S99 新数据不进旧任务列表,走 V4 工作台和来源通知详情。 |
task_status |
否 | 任务状态过滤。 |
task_subtype |
否 | 任务卡 subtype 过滤。 |
order_status |
否 | 按任务所属订单状态过滤,支持 TEMPORARY、ACTIVE、ENDED、LOGIC_DELETED;不传时保持当前行为。 |
queue_participation |
否 | 是否参与订单执行队列。 |
keyword |
否 | Group Code、Confirmation No、临时订单号、来源消息安全摘要关键词。 |
page_num |
否 | 页码,建议从 1 开始。 |
page_size |
否 | 每页条数。 |
建议返参:
{
"items": [
{
"task_id": "10001",
"order_id": "20001",
"hotel_id": "HOTEL-TEST",
"display_order_key": "GRP-001",
"temporary_order_no": "TMP-20260708-001",
"task_type": "UPDATE_BOOKING",
"result_type": "normal_task",
"ai_task_type": "Payment Evidence",
"task_subtype": "payment_evidence",
"route_code": "R10_PAYMENT_EVIDENCE_NORMAL",
"system_process_category": "BUSINESS_TASK",
"task_status": "PENDING_CONFIRM",
"card_name": "Payment Evidence",
"queue_sequence": 2,
"queue_participation": true,
"can_process": false,
"readonly_reason_code": "PREVIOUS_TASK_NOT_FINISHED",
"source_message_id": "30001",
"source_subject": "Booking Update",
"source_sender_summary": "guest@example.com",
"source_received_at": "2026-07-08T02:58:00Z",
"external_conversation_id": "thread-20260708-001",
"conversation_message_count": 6,
"created_at": "2026-07-08T03:00:00Z",
"updated_at": "2026-07-08T03:10:00Z"
}
],
"page": {
"page_num": 1,
"page_size": 20,
"total": 1
}
}
本轮已新增字段:
| 字段 | 说明 |
|---|---|
source_sender_summary |
来源消息发件人展示值,当前不打码,用于任务列表快速判断来源。 |
source_received_at |
邮件来源接收时间,优先取 AgentBus payload received_at,用于任务列表排序和展示。 |
external_conversation_id |
来源消息所属邮件会话 ID,用于打开完整邮件会话详情。 |
conversation_message_count |
会话内邮件数量,用于提示用户该入口是整段会话,不是单封邮件。 |
result_type / ai_task_type / route_code / system_process_category |
V3 路由展示字段,用于任务卡标签、筛选和 S10/S99 只读卡判断。 |
4. 订单详情与任务时间线接口字段补齐
建议路径:
GET /api/reservation/orders/{orderId}
当前状态:后端已按 P0 最小诉求实现第一版,并在 M002 V4 CP15.1 补齐订单详情 V4 总览字段;前端订单详情总览页已接入这些字段。接口返回订单摘要、V4 当前确认快照、V4 下一步处理入口、关联来源邮件摘要、旧 V2/V3 同订单任务时间线和 V4 订单任务时间线;include_tasks=false 时旧 tasks[]、V4 v4_order_tasks[] 和 related_source_messages[] 都返回空数组,order_overview 为空快照,next_v4_action.action_type=NONE。旧任务时间线已补齐每个任务的来源邮件会话摘要。
订单详情页当前定位为“订单总览 + 当前确认快照 + V4 任务时间线 + 下一步入口”,不是 V4 任务卡处理页。同订单任务队列里的每个任务都需要自己的“查看邮件会话”入口,因为不同任务可能来自不同邮件或不同邮件会话。因此 tasks[] 中每个任务已补齐来源邮件会话字段。V4 新模型下,同一订单的多卡订单任务通过 v4_order_tasks[] 单独返回,前端点击后进入 V4 订单任务详情。
建议入参:
| 参数 | 必填 | 说明 |
|---|---|---|
orderId |
是 | 订单 ID。 |
hotel_id |
否 | 酒店 ID。单酒店阶段默认可为空,由后端解析;显式传值时后端会校验访问权限。 |
include_tasks |
否 | 是否返回任务时间线,默认 true。 |
include_source_summary |
否 | 是否返回来源消息摘要,默认 true;第一版参数保留,前端暂不要依赖它做字段裁剪。 |
建议返参:
{
"order": {
"order_id": "20001",
"hotel_id": "HOTEL-TEST",
"order_status": "ACTIVE",
"temporary_order_no": "TMP-20260708-001",
"confirmation_number": "CNF123456",
"group_code": "GRP-001",
"block_code": null,
"allotment_code": null,
"display_name": "GRP-001",
"created_at": "2026-07-08T03:00:00Z",
"updated_at": "2026-07-08T03:10:00Z"
},
"order_overview": {
"account_code": "QBD_TRAVEL",
"account_name": "Q.B.D. TRAVEL GROUP CO., LTD",
"market_code": "LEISURE",
"source_code": "TRAVEL_AGENT",
"arrival_date": "2026-07-26",
"departure_date": "2026-07-29",
"rate_code": "BAR",
"room_items": [
{
"room_type_code": "RM1",
"room_count": 2
}
],
"trace_card_status": null,
"rooming_list_card_status": null,
"payment_card_status": "REVIEW_REQUIRED",
"latest_confirmed_at": "2026-07-08T04:20:00Z"
},
"next_v4_action": {
"order_task_id": "40001",
"card_id": "41003",
"action_type": "REVIEW",
"action_status": "REVIEW_REQUIRED",
"open_order_task_count": 1
},
"related_source_messages": [
{
"source_message_id": "30002",
"hotel_id": "HOTEL-TEST",
"external_message_id": "AAMk-example",
"external_conversation_id": "thread-20260708-002",
"subject": "Booking Update",
"sender_summary": "guest@example.com",
"received_at": "2026-07-08T04:00:00Z",
"source_sent_at": null,
"conversation_message_count": 2
}
],
"tasks": [
{
"task_id": "10001",
"task_type": "NEW_BOOKING",
"result_type": "normal_task",
"ai_task_type": "New Booking",
"task_subtype": "NEW_BOOKING",
"route_code": "R01_NEW_FIT_RESERVATION_NORMAL",
"system_process_category": "BUSINESS_TASK",
"task_status": "COMPLETED",
"card_name": "New Booking",
"queue_sequence": 1,
"queue_participation": true,
"can_process": false,
"readonly_reason_code": "TASK_FINISHED",
"source_message_id": "30001",
"source_subject": "Booking Request",
"source_sender_summary": "guest@example.com",
"source_received_at": "2026-07-08T02:58:00Z",
"external_conversation_id": "thread-20260708-001",
"conversation_message_count": 6,
"created_at": "2026-07-08T03:00:00Z"
}
],
"v4_order_tasks": [
{
"order_task_id": "40001",
"order_ref": "order-1",
"order_task_status": "OPEN",
"card_counts": {
"total_count": 3,
"readonly_count": 1,
"pending_confirm_count": 1,
"review_required_count": 1,
"confirmed_count": 0
},
"cards": [
{
"card_id": "41001",
"card_type": "SOURCE_MESSAGE_DISPLAY",
"event_type": null,
"source_event_index": 0,
"card_sort_order": 10,
"card_status": "READONLY",
"review_status": null,
"confirmed_by": null,
"confirmed_at": null,
"latest_activity_at": "2026-07-08T04:00:10Z"
},
{
"card_id": "41003",
"card_type": "PAYMENT",
"event_type": "PAYMENT",
"source_event_index": 2,
"card_sort_order": 60,
"card_status": "REVIEW_REQUIRED",
"review_status": "PENDING",
"confirmed_by": null,
"confirmed_at": null,
"latest_activity_at": "2026-07-08T04:05:00Z"
}
],
"source_message_summary": {
"source_message_id": "30002",
"hotel_id": "HOTEL-TEST",
"external_message_id": "AAMk-example",
"external_conversation_id": "thread-20260708-002",
"subject": "Booking Update",
"sender_summary": "guest@example.com",
"received_at": "2026-07-08T04:00:00Z",
"source_sent_at": null,
"conversation_message_count": 2
},
"source_received_at": "2026-07-08T04:00:00Z",
"created_at": "2026-07-08T04:00:10Z",
"updated_at": "2026-07-08T04:05:00Z",
"latest_activity_at": "2026-07-08T04:05:00Z"
}
],
"warnings": []
}
本轮已新增字段:
| 字段 | 说明 |
|---|---|
source_message_id |
任务对应的来源 SourceMessage Inbox ID。 |
source_subject |
来源消息主题摘要。 |
source_sender_summary |
来源消息发件人展示值,当前不打码。 |
source_received_at |
邮件来源接收时间,优先取 AgentBus payload received_at。 |
external_conversation_id |
来源消息所属邮件会话 ID。 |
conversation_message_count |
会话内邮件数量。 |
result_type / ai_task_type / route_code / system_process_category |
V3 路由展示字段,和任务列表字段语义一致。 |
order_overview |
V4 订单详情当前确认快照,只从已确认 V4 卡片派生;未确认 AI 建议不会进入这里。 |
order_overview.account_code / account_name / market_code / source_code |
来自已确认 Basic Information 卡;为空表示 Basic Information 尚未确认或无可靠确认值。 |
order_overview.arrival_date / departure_date / rate_code / room_items[] |
来自已确认 Room Information 卡;后出现的已确认卡会覆盖前面同字段。下一阶段 Room Information 展示模型实现后,可继续从确认快照派生 nights、breakfast_included 和 Group Booking Status。 |
order_overview.trace_card_status / rooming_list_card_status / payment_card_status |
当前订单下对应业务卡最新状态,方便订单详情页展示是否还有待处理事项。 |
order_overview.latest_confirmed_at |
当前订单 V4 卡片最近确认 UTC 时间。 |
next_v4_action |
订单详情页下一步处理入口,口径与订单列表 V4 入口一致;前端点击后跳 /reservation/order-tasks/{order_task_id}。 |
next_v4_action.action_type |
CONFIRM / REVIEW / NONE。订单详情页不直接调用确认或复核接口,应进入 V4 订单任务详情页处理。 |
related_source_messages[] |
当前订单 V4 订单任务关联来源邮件安全摘要去重列表;用于订单页邮件区,不包含正文、HTML 或附件 URL。 |
v4_order_tasks[] |
V4 订单任务时间线数组。旧 tasks[] 继续保留;V4 时间线按 source_received_at、source_message_id、order_context_index、created_at、数字 ID 正序返回。 |
v4_order_tasks[].order_task_id |
V4 订单任务 ID,字符串。 |
v4_order_tasks[].order_ref |
V4 回调包内订单引用,不等同 PMS 永久订单号。 |
v4_order_tasks[].order_task_status |
V4 订单任务状态,当前为 OPEN / COMPLETED。 |
v4_order_tasks[].card_counts |
V4 任务卡数量摘要。 |
v4_order_tasks[].cards[] |
V4 订单任务下任务卡安全摘要,只返回状态、复核状态、确认人和确认时间,不返回业务 payload。 |
v4_order_tasks[].source_message_summary |
V4 来源邮件安全摘要,不包含正文、HTML、附件 URL 或 AI 原始 payload。 |
v4_order_tasks[].latest_activity_at |
V4 订单任务自身 updated_at 与其下卡片 updated_at 的最大 UTC 时间。 |
5. 订单列表接口
建议路径:
GET /api/reservation/orders
当前状态:后端已完成第一版。默认查询全部订单状态;open_task_count 排除旧任务表中 COMPLETED 和 FAILED,保留为历史诊断计数。M002 V4 CP14 已补齐 V4 继续处理入口字段;后端新增 open_work_item_count 作为订单列表统一待处理展示数量,第一版直接等于 V4 未完成订单任务数,不叠加旧任务。当前开发阶段已停止 V4 普通业务双写旧 workflow_reservation_task,开发 / 测试环境旧任务数据可清理且可重建;next_processable_task_id 仅作为历史 V2/V3 诊断兼容字段,清理后新 V4 订单不应返回旧任务入口。前端已按 next_v4_order_task_id 优先进入 V4 订单任务详情;订单列表待处理数量已改为只展示 open_work_item_count。
默认排序:按后端维护的订单最近业务活动时间倒序返回,保证最近有业务活动的订单排在前面。后端当前使用 workflow_reservation_order.latest_activity_at 作为排序字段,并在订单创建、任务创建、草稿保存、最终确认、人工复核解阻、任务状态变更等写路径维护;前端不要再基于任务时间或更新时间自行重排。
建议入参:
| 参数 | 必填 | 说明 |
|---|---|---|
hotel_id |
否 | 酒店 ID。单酒店阶段默认可为空,由后端解析;显式传值时后端会校验访问权限。 |
order_status |
否 | TEMPORARY、ACTIVE、ENDED、LOGIC_DELETED。 |
group_code |
否 | 按 Group Code 精确或模糊查询,后端决定。 |
confirmation_number |
否 | 按 Confirmation No 查询。 |
keyword |
否 | 前端搜索框统一关键词;后端匹配订单字段,也会匹配来源消息安全摘要命中的 SourceMessage ID。 |
page_num |
否 | 页码。 |
page_size |
否 | 每页条数。 |
建议返参:
{
"items": [
{
"order_id": "20001",
"hotel_id": "HOTEL-TEST",
"order_status": "ACTIVE",
"display_order_key": "GRP-001",
"temporary_order_no": null,
"confirmation_number": "CNF123456",
"group_code": "GRP-001",
"display_name": "GRP-001",
"open_task_count": 2,
"open_work_item_count": 1,
"next_processable_task_id": "10002",
"next_v4_order_task_id": "30001",
"next_v4_action_card_id": "31002",
"next_v4_action_type": "REVIEW",
"next_v4_action_status": "REVIEW_REQUIRED",
"v4_open_order_task_count": 1,
"updated_at": "2026-07-08T03:10:00Z"
}
],
"page": {
"page_num": 1,
"page_size": 20,
"total": 1
}
}
V4 继续处理字段说明:
| 字段 | 说明 |
|---|---|
open_work_item_count |
订单列表统一待处理展示数量。第一版忽略旧数据,直接等于 v4_open_order_task_count;前端展示 open count 时只使用该字段,不回退旧 open_task_count,也不要自行相加。 |
next_v4_order_task_id |
当前订单下第一条仍需用户处理的 V4 订单任务 ID;为空表示没有 V4 待处理订单任务。 |
next_v4_action_card_id |
next_v4_order_task_id 下第一张仍需确认或复核的卡片 ID。 |
next_v4_action_type |
CONFIRM / REVIEW / NONE。CONFIRM 调卡片确认接口,REVIEW 调复核解阻接口。 |
next_v4_action_status |
PENDING_CONFIRM / REVIEW_REQUIRED;NONE 时为空。 |
v4_open_order_task_count |
当前订单下未完成 V4 订单任务数,COMPLETED 不计入。 |
前端“继续处理”入口优先级:优先使用 next_v4_order_task_id 跳转 V4 订单任务详情;没有 V4 待处理且旧 next_processable_task_id 为空时展示无待处理状态。S10/S99 来源通知不创建订单,不进入订单列表字段统计。订单列表展示“待处理数量”时只使用 open_work_item_count,不使用旧 open_task_count 作为展示数量,也不在前端自行计算 open_task_count + v4_open_order_task_count;旧 open_task_count 和 v4_open_order_task_count 保留用于兼容与排查。V4 新业务主线只写 V4 模型,开发阶段不维护 V2/V3 旧任务兼容,测试数据可重建;清理旧任务数据后,新 V4 订单不应再出现旧继续处理入口。
6. 前端联调演示数据 seed 接口
建议路径:
POST /api/system/reservation/demo-data
当前状态:后端已完成第一版。该接口只用于本地 / test 联调造数,默认关闭,不是生产业务页面接口。该接口会创建旧 workflow_reservation_task 演示数据,是历史 V2/V3 页面演示入口;M002 V4 smoke 不应再使用该接口造数,避免重新制造旧任务残留。V4 smoke 应使用 SuperAgent V4 回调或专门 V4 fixture。
启用条件:
| 配置 | 说明 |
|---|---|
reservation.demo-data.enabled=true |
dev 默认开启;test 需显式启用,也可用环境变量 RESERVATION_TEST_DEMO_DATA_ENABLED=true。 |
reservation.demo-data.access-key |
配置访问口令;dev 优先使用 RESERVATION_DEV_DEMO_DATA_ACCESS_KEY,test 优先使用 RESERVATION_TEST_DEMO_DATA_ACCESS_KEY,旧通用变量 RESERVATION_DEMO_DATA_ACCESS_KEY 仅作为兼容兜底。 |
X-TH-Hotel-Demo-Data-Key |
请求头必须携带,与后端配置口令一致。 |
请求示例:
{
"run_label": "frontend-smoke"
}
返回说明:
| 字段 | 说明 |
|---|---|
demo_run_id |
本次 seed 唯一关键词,可用于任务列表 / 订单列表搜索。 |
source_messages[] |
生成的来源消息 ID、外部消息 ID 和外部会话 ID。 |
orders[] |
生成的订单 ID、订单状态和展示键。 |
tasks[] |
生成的任务 ID、任务类型、任务 subtype 和任务状态。 |
entrypoints |
可直接访问的任务列表、订单列表、订单详情、任务详情、邮件会话详情 URL。 |
第一版 seed 覆盖:队列阻塞、已完成 OPERA 模拟、OPERA 失败可重试、Fallback 人工复核、历史 Message Notification 只读任务、邮件会话完整 HTML / 附件 / 内联图片。旧 S000/S999 特殊只读任务可通过 SuperAgent 回调补充;0711 P0 新入口的 S10/S99 已纳入后端 P0 fixtures 回归测试参考。
6.1 M002 V3 当前状态和后续待补能力
本节记录 0711 P0 基线确认后,前端关心的 V3 能力状态。已完成项可以直接接入;后置项需要另开 checkpoint。
| 能力 | 页面 / 场景 | 状态 | 前端最小诉求 |
|---|---|---|---|
结构化 S10/S99 入站 |
任务列表、任务详情、Debug EML 结果展示 | 已完成第一版 | 后端接收 result_type=source_message_review_notification + route_code=S10/S99,创建只读源邮件通知卡;任务列表可见,订单列表不可见;返回 route_code、入口说明、agent_assessment、notification 和 S99 的入口 manual_review。 |
旧 S000/S999 兼容映射 |
任务列表、任务详情 | 已完成第一版 | 旧数据继续可见;前端可按 S000→S10、S999→S99 展示统一文案。 |
| 40 条 P0.1 路由元数据 | 任务列表筛选、订单任务时间线、任务详情标题、字段展示 | 已完成第一版 | 后端保存并返回 AI 原始 result_type/ai_task_type/task_subtype、route_code 和系统处理分类;前端不要只依赖系统主任务类型判断卡片。 |
| P0.1 稳定 route_code | 任务列表筛选、订单任务时间线、任务详情标题 | 已完成第一版 | route_code 保持历史稳定,不因路由总数变 40 而连续重编号;前端仍可能看到 R41_FALLBACK_BUSINESS_EVENT_REVIEW 和 R42_UNHANDLED_CURRENT_INTENT。 |
| Parent split 父事件卡型 | 任务列表、订单任务时间线、任务详情标题 | 已完成第一版 | 0712 P0.1 后,Parent split 父事件展示为 Parent Group / Cancel Allotment / cancel_allotment_control_block;route_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL 展示为普通业务卡,route_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_REVIEW 展示为同卡人工复核业务卡;linked_parent_release_after_child_split 仅作为关系字段,不作为任务 subtype 筛选项。 |
unhandled_current_intents[] 展示块 |
任务详情 | 已完成第一版 | 后端保存并在任务详情 unhandled_intents[] 返回未覆盖业务意图,只用于展示和源邮件查看,不自动建业务任务卡。 |
adapter_contract_error |
任务详情、错误提示 | 已完成第一版 | 命中 P1/P2 未闭合或路由冲突时,任务详情 adapter_contract_errors[] 返回稳定错误 code 和原始片段,不转成 Fallback。 |
| type-known manual review 同卡解阻 | 任务详情复核 | 已完成第一版 | manual_review 不再全部等同 Fallback;已知业务卡型返回原业务卡信息、review_status、review_resolution 和可编辑 pointer 字段,解阻后进入 READY。 |
| 复核场景订单归属确认 | 任务详情复核 | 已完成第一版 | 后端提供复核确认时的订单归属确认;当前第一版只能确认当前任务所属订单,后续如要选择其他订单需另行细化。 |
| P0 fixtures 回归基线 | 联调回归 | 已完成第一版 | 后端已将 0711 P0 fixtures 纳入测试参考;前端对 S10/S99、同卡复核和只读诊断块的展示应继续按本节稳定字段接入。 |
6.2 前端本轮接入状态(2026-07-11)
本轮前端已按 M002 V3 P0 完成以下接入,后端不需要重复补接口:
- 任务列表已按
result_type、route_code、system_process_category识别source_message_review_notification、adapter_contract_error、unhandled_current_intent只读诊断任务;S10/S99 和旧 S000/S999 都不展示订单入口。 - 任务详情已展示
result_type、ai_task_type、task_subtype、route_code、system_process_category、review_status、来源邮件入口、source_message_only_result、manual_review、adapter_contract_errors[]和unhandled_intents[]。 - Parent Group P0.1 前端已按
route_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL/REVIEW展示Parent Group / Cancel Allotment / cancel_allotment_control_block;review 场景继续走同卡人工复核解阻,不展示为adapter_contract_error。 - type-known
result_type=manual_review已在原业务任务卡展示复核状态和缺失字段,并调用POST /api/reservation/tasks/{taskId}/manual-review-resolutions解阻,不再创建第二张人工复核任务卡。 - 第一版解阻 UI 已改为优先使用任务详情
fields[].field_pointer,并同时提交 P0 主fields[].field_path;旧扁平legacy_field_path/legacy_field_values仅用于field_contract_version=code-v1历史任务过渡回显,不作为新前端主动提交路径。 - 前端只读规则已收口:S10/S99、适配契约异常、未处理意图、前置任务阻塞和同卡人工复核待解阻状态都不显示保存草稿、确认任务、人工转换或 OPERA 执行 / 重试入口。
- 前端 fixture 已补 V3 最小结构样例:
source_message完整对象、message_events[]的event_role、current_or_history、source_event_index、四字段case_keys、relevant_message_excerpt、attachments、file_references、context_used、extracted_fields、manual_review。
仍建议后端确认:
GET /api/reservation/tasks中旧 S000/S999 和 V3 S10/S99 兼容行是否稳定返回task_type=SOURCE_MESSAGE_ONLY。V4 S10/S99 已不应从旧任务列表返回,应通过 V4 工作台和来源通知接口展示。adapter_contract_error/unhandled_current_intent如果未来也作为独立列表行返回,请保持source_message_id可用,便于前端继续提供邮件会话入口。- 同卡人工复核解阻成功后是否一定返回
opera_operations[]。当前文档写“两条 OPERA 模拟操作”,前端实现按实际返回刷新,不假设固定数量。 - Parent Group
manual_review.reason_code=target_object_unclear场景需要任务详情稳定透出context_used.parent_identity_candidates[]。当前ReservationTaskDetailResult后端 DTO 仅透出manual_review,前端已兼容顶层context_used.parent_identity_candidates[]或manual_review.context_used.parent_identity_candidates[],但若后端不透出 candidates,页面只能显示空态提示。
前端注意:不要把访问口令写入前端仓库、浏览器环境变量或构建产物;该接口只能由本地联调人员手动调用或由受控测试脚本调用。
7. 邮件会话详情接口
建议优先路径:
GET /api/source-messages/{sourceMessageId}/conversation
历史候选路径,当前不提供:
GET /api/source-message-conversations/{externalConversationId}
当前状态:GET /api/source-messages/{sourceMessageId}/conversation 已完成第一版。前端入口从某个任务的 source_message_id 进入,后端根据该 SourceMessage 找到 external_conversation_id,再返回同一邮件会话下的全部邮件。
中文说明:
- 该接口已经完成权限收口:请求必须带
Authorization: Bearer <access_token>,当前用户必须同时拥有SOURCE_MESSAGE_READ和SOURCE_MESSAGE_ORIGINAL_READ,后端会按 SourceMessage 实际所属酒店校验访问权。 - “全部邮件”指同一个
externalConversationId下的历史邮件、当前邮件和后续回复,不是只展示任务对应的单封来源邮件。 - V4 任务详情页的
SOURCE_MESSAGE_DISPLAY卡如果展示正文,只展示当前触发该 V4 order task 的那一封 SourceMessage;前端应按入口sourceMessageId在messages[]中定位对应id,不要把整条会话全部铺在任务详情卡片里。 - V4 Payment 卡如果展示付款凭证附件,前端先用任务详情里的
payment_attachments[]安全摘要渲染 UI:图片显示缩略图,点击后通过本接口取得受控externalUrl打开大图预览;非图片统一展示文件名、类型、大小和下载按钮,不在卡片内嵌 PDF / Word / Excel 预览。 - 邮件会话详情页需要展示完整正文或清洗后的 HTML、附件、内联图片、发件人展示值、发送 / 接收时间、主题和关联订单 / 任务。
- 前端不在页面上做业务截断或隐藏;但仍只调用本项目后端接口,不直接访问邮箱、AgentBus、数据库或外部附件 URL Secret。
- 原文读取审计由后端在该业务接口内部处理,actor 使用当前登录用户稳定 ID;前端不保存或传递
X-TH-Hotel-Source-Original-Read-Key一类受控访问 key。 - 2026-07-08 后端已新增
html_body_sanitized和html_render_mode;前端页面展示邮件 HTML 时应优先使用html_body_sanitized,html_body只作为原始内容兼容字段,不建议生产直渲。 - 第一版仅处理 HTML 内容清洗;附件和内联图片 URL 来自本系统 OSS 服务,暂不做额外拦截或代理转换。
- Payment 卡预览 / 下载匹配必须使用后端返回的附件 ID /
externalMediaId,不能按文件名猜测;前端不得把externalUrl放进确认 payload、日志、错误上报、URL query 或 localStorage。
建议入参:
| 参数 | 必填 | 说明 |
|---|---|---|
sourceMessageId |
是 | 入口来源消息 ID。后端据此定位 externalConversationId。 |
当前第一版不额外接收 hotelId、includeBody、includeRelated。后端默认按 SourceMessage 自身酒店上下文查询同会话邮件,返回完整 text/html、清洗后的 HTML 和关联订单 / 任务摘要,并在内部写原文读取审计。
建议返参:
{
"conversation": {
"external_conversation_id": "thread-20260708-001",
"hotel_id": "HOTEL-TEST",
"channel": "EMAIL",
"subject": "Re: Booking Update",
"message_count": 6,
"first_received_at": "2026-07-06T01:10:00Z",
"last_received_at": "2026-07-08T03:28:00Z"
},
"messages": [
{
"id": "30001",
"external_message_id": "msg-001",
"external_conversation_id": "thread-20260708-001",
"sender_summary": "guest@example.com",
"subject": "Booking Request",
"received_at": "2026-07-06T01:10:00Z",
"source_sent_at": "2026-07-06T01:08:00Z",
"text_body": "完整邮件正文",
"html_body": "<p>完整邮件 HTML</p>",
"html_body_sanitized": "<p>完整邮件 HTML</p>",
"html_sanitize_required": true,
"html_render_mode": "SANITIZED_HTML",
"inline_images": [],
"attachments": [
{
"mediaType": "ATTACHMENT",
"fileName": "rooming-list.xlsx",
"contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"sizeBytes": 10240,
"externalUrl": "由后端决定是否返回可访问 URL",
"externalMediaId": "media-001"
}
],
"related_orders": [
{
"order_id": "20001",
"display_order_key": "GRP-001",
"order_status": "ACTIVE"
}
],
"related_tasks": [
{
"task_id": "10001",
"order_id": "20001",
"task_type": "NEW_BOOKING",
"task_subtype": "NEW_BOOKING",
"task_status": "PENDING_CONFIRM",
"card_name": "New Booking"
}
]
}
]
}
8. 任务详情接口字段元数据扩展
建议路径:
GET /api/reservation/tasks/{taskId}
当前状态:后端已有任务详情接口,前端任务详情页可以接入。该接口已返回 fields[]、草稿、确认 payload、可处理状态和 OPERA 模拟操作;本轮已透出来源邮件会话字段,以及旧 docs/import/20260708/任务卡前端展示字段表 3.0.xlsx 中 P0 需要的字段元数据。0711 P0 后续开发应迁移到 docs/import/20260711/开发交付_P0冻结基线_2026-07-11/01_Adapter_Frontend/任务卡前端字段变更说明_3.0_to_当前版_2026-07-10.xlsx 和同目录路由说明。
任务详情页面相关已完成接口:
| 接口 | 用途 | 后端状态 |
|---|---|---|
GET /api/reservation/tasks/{taskId} |
读取任务详情、字段矩阵、当前值、可处理状态、OPERA 操作摘要。 | 已完成第一版,已补本节字段。 |
PUT /api/reservation/tasks/{taskId}/draft |
保存任务卡草稿。 | 已完成。 |
POST /api/reservation/tasks/{taskId}/confirm |
最终确认任务卡字段。 | 已完成。 |
GET /api/reservation/tasks/{taskId}/audits |
查询任务审计流水。 | 已完成。 |
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/execute |
执行 OPERA 模拟操作。 | 已完成第一版模拟。 |
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/retry |
重试失败的 OPERA 模拟操作。 | 已完成第一版模拟。 |
POST /api/reservation/tasks/{taskId}/manual-review-conversions |
将 Fallback / manual_review 转换为具体任务类型。 | 已完成。 |
POST /api/reservation/tasks/{taskId}/manual-review-resolutions |
type-known manual review 在原业务任务卡上提交字段修正和订单归属确认。 | 已完成第一版。 |
已完成的 fields[] 字段:
返回口径:fields[] 是后端按当前任务生效规则过滤后的字段集合,不是完整字段矩阵。后端已经应用 visible、result_type、task_type、task_subtype 和 display_condition;未返回字段对当前任务视为不展示、不校验、不提交,前端不要自行补齐,也不要依赖固定字段数量。
| 字段 | 说明 |
|---|---|
row_number |
字段矩阵行号。 |
card_name |
任务卡名称。 |
display_area |
前端展示区域。 |
field_path |
字段路径。 |
display_name |
展示名。 |
visible |
是否展示。 |
editable |
是否可编辑。 |
input_editable |
是否输入方式编辑。 |
select_editable |
是否下拉方式编辑。 |
date_picker |
是否日期选择。 |
number_input |
是否数字输入。 |
file_display |
是否文件展示。 |
table_editable |
是否表格编辑。 |
enum_options |
枚举选项。 |
required_rule |
必填规则。 |
display_condition |
展示条件。 |
validation_rule |
校验规则。 |
write_path |
写入路径。 |
opera_write_participation |
是否参与 OPERA 写入。 |
opera_parameter_mapping |
OPERA 参数映射。 |
notes |
备注。 |
value |
当前回显值。 |
本轮已补字段:
| 位置 | 字段 | 说明 |
|---|---|---|
| 顶层 | source_subject |
任务来源消息主题摘要。 |
| 顶层 | source_sender_summary |
任务来源消息发件人展示值,当前不打码。 |
| 顶层 | source_received_at |
任务来源邮件接收时间,优先取 AgentBus payload received_at。 |
| 顶层 | external_conversation_id |
任务来源消息所属邮件会话 ID。 |
| 顶层 | conversation_message_count |
会话内邮件数量。 |
fields[] |
result_type |
3.0 字段表中的结果类型,用于前端调试和字段分组校验。 |
fields[] |
task_type |
3.0 字段表中的任务主类型。 |
fields[] |
task_subtype |
3.0 字段表中的任务 subtype / 业务动作。 |
fields[] |
default_value_source |
3.0 字段表中的默认值 / 回显来源。 |
8.1 Type-known manual review 同卡复核解阻
当前状态:后端已完成第一版。result_type=manual_review 且 system_task_type 不是 MANUAL_REVIEW 时,前端在原业务任务卡上展示复核模式,不进入 Fallback 转换页面。
任务详情增量字段:
| 字段 | 说明 |
|---|---|
review_status |
PENDING 表示等待复核,RESOLVED 表示已解阻。 |
review_resolution |
已解阻后的复核结果;未解阻时为 null。 |
manual_review |
SuperAgent 原始复核说明、缺失字段、阻塞点、建议人工动作;只读展示。 |
解阻接口:
POST /api/reservation/tasks/{taskId}/manual-review-resolutions
Content-Type: application/json
请求示例:
{
"confirmed_order_id": "20001",
"reason": "确认 PMS 房型代码后解阻。",
"field_overrides": [
{
"field_pointer": "/extracted_fields/room_items/0/pms_room_type_code",
"field_path": "extracted_fields.room_items.0.pms_room_type_code",
"value": "RM3"
}
]
}
0711 P0 房型复核说明:前端应优先提交 /extracted_fields/room_items/0/pms_room_type_code 或任务详情 fields[].field_path=extracted_fields.room_items.0.pms_room_type_code。后端仍兼容旧扁平 key / pointer,也支持只提交 field_path。如果同时提交 field_pointer 和 field_path,两者必须指向同一字段。响应里的 review_resolution.field_overrides[].field_path 使用 P0 主路径;前端只提交 field_path 时,后端会返回 P0 主 field_pointer;前端提交旧 pointer 时,field_pointer 保留前端原始值,legacy_field_path 仅用于旧页面过渡。
返回示例:
{
"task_id": "10001",
"order_id": "20001",
"task_status": "READY",
"review_status": "RESOLVED",
"review_resolution": {
"schema_version": "manual-review-resolution-v1",
"confirmed_order_id": "20001",
"resolved_at": "2026-07-11T00:00:00Z",
"field_overrides": [
{
"field_pointer": "/extracted_fields/room_items/0/pms_room_type_code",
"field_path": "extracted_fields.room_items.0.pms_room_type_code",
"legacy_field_path": "extracted_fields.pms_room_type_code",
"value": "RM3"
}
]
},
"confirmed_payload": {
"schema_version": "field_matrix-p0-room-items-v1",
"field_values": {
"extracted_fields.room_items.0.pms_room_type_code": "RM3"
},
"legacy_field_values": {
"extracted_fields.pms_room_type_code": "RM3"
},
"effective_payload": {
"extracted_fields": {
"room_items": [
{
"pms_room_type_code": "RM3"
}
]
}
}
},
"opera_operations": [
{"operation_code": "SIMULATE_PRECHECK"},
{"operation_code": "SIMULATE_WRITE"}
]
}
前端注意:
field_overrides[]必须提供field_pointer或field_path。field_pointer必须是 RFC 6901 JSON Pointer;field_path可以是 P0 主路径或旧扁平路径。两者都只能指向任务详情fields[]中当前可编辑字段;只读字段、未知字段或两者指向不一致会返回TASK_REVIEW_POINTER_INVALID。- 同一次请求不能重复提交同一字段;重复
field_pointer或重复映射到同一field_path会返回TASK_REVIEW_POINTER_DUPLICATE。 confirmed_order_id第一版必须等于当前任务order_id;普通任务任意切换订单继续后置。- type-known manual review 不能调用通用
POST /api/reservation/tasks/{taskId}/confirm;必须调用本节解阻接口,否则后端返回TASK_REVIEW_RESOLUTION_REQUIRED。 review_resolution.resolved_at是 UTCZ时间点。- 解阻成功后刷新任务详情,按钮状态以新的
task_status=READY和availability为准。 confirmed_payload.field_values按 P0 主field_path保存;legacy_field_values是旧扁平兼容回显;effective_payload是后端第一版嵌套结构,不是 OPERA 最终参数。
建议返参增量示例:
{
"task_id": "10001",
"order_id": "20001",
"source_message_id": "30001",
"source_subject": "Booking Update",
"source_sender_summary": "guest@example.com",
"source_received_at": "2026-07-08T02:58:00Z",
"external_conversation_id": "thread-20260708-001",
"conversation_message_count": 6,
"system_task_type": "NEW_BOOKING",
"task_card_type": "NEW_BOOKING",
"task_status": "PENDING_CONFIRM",
"field_contract_version": "20260711-p0",
"fields": [
{
"row_number": 2,
"card_name": "New Booking",
"result_type": "RESERVATION",
"task_type": "NEW_BOOKING",
"task_subtype": "NEW_BOOKING",
"display_area": "基础信息",
"field_path": "case_keys.group_code",
"display_name": "Group Code",
"visible": "是",
"editable": "否",
"default_value_source": "AI识别结果 / 已确认草稿回显",
"value": "GRP-001"
}
]
}
中文说明:
- 如果前端只做“按后端字段直接渲染”,现有
fields[]可以支撑第一版表单展示;本轮已经扩展ReservationTaskFieldResult,避免前端维护第二套字段矩阵。 fields[]已是当前任务生效字段集合,前端不能把导入 Excel 或历史矩阵里的其他字段自行合成到页面上;例如 Group Block 不应补出 FIT 专属 Confirmation No. 输入框。result_type、task_type、task_subtype、default_value_source当前从后端字段矩阵定义透出。- 如果后端已有更细的字段来源或适用场景元数据,可后续再扩展
field_source、applicable_scenario,不作为本轮 P0 阻塞项。 - 前端默认不需要为
GET /api/reservation/orders、GET /api/reservation/tasks、GET /api/reservation/orders/{orderId}自动拼hotel_id;如已接入酒店选择器,可以传当前选中酒店,后端会校验访问权限。当前GET /api/reservation/tasks/{taskId}以及任务写操作 Controller 不接收hotel_id;第一版先按 ID 定位,后续多酒店隔离 / 权限方案统一补齐。
9. S10/S99 源邮件只读通知与历史兼容
当前状态:后端不提供历史候选的 /api/reservation/message-notifications 列表 / 详情接口。旧 SuperAgent 入口返回 S000,source_message_id 或 S999,source_message_id 时,后端会创建 SOURCE_MESSAGE_ONLY 只读特殊任务;V3 结构化 S10/S99 兼容路径也沿用该旧任务模型。V4 route_code=S10/S99 新数据已改为独立来源通知模型,通过 V4 工作台和 /api/reservation/source-notifications/{notificationId} 展示,并通过 /api/reservation/source-notifications/{notificationId}/ack 确认已读 / 已处理。
V3 入口兼容语义:
S10:result_type=source_message_review_notification,route_code=S10,表示未匹配当前支持的业务事件。S99:result_type=source_message_review_notification,route_code=S99,表示输入不足或无法形成业务素材包。- 旧
S000前端语义映射为S10。 - 旧
S999前端语义映射为S99。
历史 INFORMATIONAL_MESSAGE 仍可通过任务列表 / 任务详情兼容展示,但新数据不要依赖它。
展示规则:
- 旧
task_type=SOURCE_MESSAGE_ONLY、task_subtype=S000/S999:按只读源邮件通知卡展示。 - V3
route_code=S10/S99兼容数据:按旧只读源邮件通知卡展示。 - V4
route_code=S10/S99新数据:按来源通知详情展示,可 ack,不通过旧任务详情处理。 - 旧
SOURCE_MESSAGE_ONLY任务列表可见,订单列表不可见;V4 来源通知在 V4 工作台可见,订单列表和订单详情不可见。 - 旧任务详情只允许查看来源邮件、会话、附件和 SuperAgent 原始返回;V4 来源通知详情只允许查看来源邮件摘要、通知信息和 ack 状态。
- 任务详情通过
source_message_only_result返回entry_result_code、entry_result_meaning、entry_result_description、entry_result_source_message_id、result_type、route_code、agent_assessment、notification、S99 的入口manual_review和raw_answer。 - 不显示编辑、人工转换、执行 OPERA 或重试 OPERA 按钮;V4 只显示 ack。
- 不参与订单任务执行顺序阻塞,也不创建隐藏技术订单。
当前不建议新增路径:
GET /api/reservation/message-notifications
GET /api/reservation/message-notifications/{taskId}
列表建议入参:
| 参数 | 必填 | 说明 |
|---|---|---|
hotel_id |
否 | 酒店 ID。单酒店阶段默认可为空,由后端解析;显式传值时后端会校验访问权限。 |
order_id |
否 | 按临时订单或真实订单过滤。 |
keyword |
否 | 邮件主题、摘要、发送人关键词。 |
page_num |
否 | 页码。 |
page_size |
否 | 每页条数。 |
详情建议返参:
{
"task_id": "10009",
"order_id": "20009",
"task_type": "SOURCE_MESSAGE_ONLY",
"task_subtype": "S000",
"task_status": "COMPLETED",
"queue_participation": false,
"readonly": true,
"visible_reason": "S000 pure information entry result",
"relevant_message_excerpt": "Noted with thanks.",
"entry_result_code": "S000",
"entry_result_description": "纯信息类邮件",
"attachments": [],
"source_message_id": "30009",
"external_conversation_id": "thread-20260708-009",
"created_at": "2026-07-08T03:00:00Z"
}
V3 S10 结构化详情当前增量:
{
"task_id": "10010",
"readonly": true,
"result_type": "source_message_review_notification",
"route_code": "S10",
"agent_assessment": {
"status": "no_booking_action_detected",
"reason_code": "no_booking_action_detected"
},
"notification": {
"notification_type": "source_message_review",
"show_source_message": true,
"requires_user_decision": true
},
"manual_review": null,
"source_message_id": "30010"
}
9.1 V3 诊断展示块
任务详情接口已新增两个只读数组:
| 字段 | 说明 |
|---|---|
adapter_contract_errors[] |
同一 SuperAgent 入站批次中未生成任务的 Adapter 契约错误。 |
unhandled_intents[] |
同一 SuperAgent 入站批次中无法映射到业务任务卡的未处理意图。 |
数组元素字段:
| 字段 | 说明 |
|---|---|
transition_id |
AI transition ID。 |
source_event_index |
AI current 事件序号。 |
array_index |
AI 返回数组顺序。 |
result_type |
AI 结果类型。 |
ai_task_type |
AI 原始任务类型。 |
task_subtype |
业务动作 subtype,可能为空。 |
route_code |
V3 路由码。 |
system_process_category |
系统处理分类。 |
adapter_error_code |
契约错误代码;未处理意图通常为空。 |
adapter_error_message |
契约错误安全摘要。 |
payload_fragment |
对前端展示安全的 AI item 片段。 |
前端注意:这两个数组不是任务队列,不提供编辑、确认、执行 OPERA 或重试入口;只用于解释为什么同一封邮件中的某些 event 没有变成业务任务。
10. 系统管理菜单树增强接口
为支持系统设置中“菜单管理”从表格交互升级为“左侧菜单树 + 右侧配置面板”,前端希望后端补两个增强接口。该能力仍属于系统管理后台 /api/admin/menus/**,不改变菜单可见性和后端接口权限的边界。
10.1 完整菜单树查询
建议路径:
GET /api/admin/menus/tree
权限要求:
| 要求 | 说明 |
|---|---|
| 登录 | 必须携带 Authorization: Bearer <access_token> |
| 权限 | 需要 SYSTEM_MENU_MANAGE |
| 审计 | 只读查询不需要写管理审计 |
查询行为:
- 返回完整菜单树,不分页。
- 默认返回全部菜单,包括
ACTIVE/DISABLED、visible=true/false。 - 按
parent_id组树,根节点parent_id=null。 - 同级按
sort_order升序,其次按menu_name或id稳定排序。 BIGINTID 继续以字符串返回。- 如果存在脏数据,例如
parent_id指向不存在菜单,应 fail-safe:该节点作为根级异常节点返回,或在响应中提供warnings[],不要导致接口 500。
建议返参:
{
"items": [
{
"id": "10001",
"parent_id": null,
"menu_code": "SYSTEM_SETTINGS",
"menu_name": "系统设置",
"menu_type": "PAGE",
"route_path": "/system",
"component_key": "system",
"icon_key": "pi pi-cog",
"permission_code": "SYSTEM_ADMIN_CONSOLE_ACCESS",
"sort_order": 900,
"visible": true,
"menu_status": "ACTIVE",
"known_route": true,
"created_at": "2026-07-16T00:00:00Z",
"updated_at": "2026-07-16T00:00:00Z",
"children": []
}
],
"warnings": []
}
10.2 批量调整菜单父级和排序
建议路径:
PUT /api/admin/menus/tree-order
权限要求:
| 要求 | 说明 |
|---|---|
| 登录 | 必须携带 Authorization: Bearer <access_token> |
| 权限 | 需要 SYSTEM_MENU_MANAGE |
| 审计 | 写操作必须写 platform_admin_audit_log |
请求体建议:
{
"items": [
{
"menu_id": "10002",
"parent_id": "10001",
"sort_order": 100
}
]
}
后端要求:
- 只允许修改
parent_id和sort_order,不允许顺带修改menu_name、route_path、permission_code、visible、menu_status。 - 使用事务保存。
- 校验
menu_id必须存在。 - 校验
parent_id为空或存在。 - 禁止把自己设为自己的父级。
- 禁止形成循环菜单树。
sort_order可为空;为空时后端按请求items[]顺序生成100、200、300... 的稳定排序号。- 成功后返回更新后的完整菜单树,方便前端立即刷新。
- 审计中记录调整前后的
parent_id/sort_order,不记录 token、secret 或敏感信息。
建议成功返参:
{
"items": [
{
"id": "10001",
"parent_id": null,
"menu_code": "SYSTEM_SETTINGS",
"menu_name": "系统设置",
"sort_order": 900,
"visible": true,
"menu_status": "ACTIVE",
"known_route": true,
"children": []
}
],
"warnings": []
}
前端接入注意:
- 前端菜单树管理页优先使用
GET /api/admin/menus/tree,不再依赖分页菜单列表拼完整树。 GET /api/admin/menus仍保留给表格分页、搜索和兼容页面使用。PUT /api/admin/menus/{menuId}仍用于单条菜单基础字段编辑。PUT /api/admin/menus/tree-order只用于批量保存树结构和排序。
11. 任务卡前端字段白名单元数据接口
是否需要该接口待确认。如果任务详情接口 fields[] 已透出 3.0 所需元数据,则第一版可以不做独立白名单接口;如果后续需要字段矩阵调试页、版本对齐页或前端预加载全部任务卡配置,再补独立接口。
建议路径:
GET /api/reservation/task-card-field-whitelist
建议入参:
| 参数 | 必填 | 说明 |
|---|---|---|
task_type |
否 | 按系统主任务类型过滤。 |
task_subtype |
否 | 按任务卡 subtype 过滤。 |
version |
否 | 字段白名单版本,例如 20260711-p0。 |
建议返参:
{
"version": "20260711-p0",
"items": [
{
"task_type": "UPDATE_BOOKING",
"task_subtype": "RATE_CHANGE",
"field_path": "rate.rate_code",
"display_name": "Rate Code",
"visible": true,
"editable": true,
"input_type": "select",
"options": []
}
]
}
12. Manual Invoice 手工开票生成接口
M009 后端 CP2 已实现,前端 V1 已接入 /reservation/invoices/new,可以在无订单 / 无任务数据时独立生成 Proforma Invoice。该接口是正式业务开票生成入口,不走 M008 调试上传 access key。
路径:
POST /api/reservation/invoices/manual-generations
入参:
{
"hotel_id": "HOTEL-TEST",
"source_type": "MANUAL",
"task_id": null,
"order_id": null,
"template_code": "PROFORMA_INVOICE_V1",
"invoice_payload": {
"document": {
"invoice_date": "2026-07-17",
"booking_date": "2026-07-12",
"due_date": "2026-07-22"
},
"recipient": {
"company_code": "LIAN_TAI",
"contact_id": "LIAN_TAI_KHUN_ANN",
"company": "LIAN TAI TRAVEL (THAILAND) CO., LTD.",
"attention": "Khun Ann",
"address": "2/86 Rajpattana Road, Rajpattana, Sapansoong, Bangkok, TH, 10240",
"telephone": "061-397-2675",
"email": "op.liantaitravel@gmail.com"
},
"booking": {
"group_name": "GRP-DEMO-0802",
"arrival_date": "2026-08-02",
"departure_date": "2026-08-05",
"room_rate_note": "includingBF",
"extra_bed_rate": 1200
},
"charges": [
{
"description": "GRP-DEMO-0802",
"room_type": "Deluxe Room",
"quantity": 2,
"rate": 3000,
"nights": 3
}
]
}
}
返参:
{
"invoice_generation_id": "2080000000000000001",
"generation_status": "SUCCEEDED",
"pdf_url": "https://oss.example.test/reservation-invoices/HOTEL-TEST/2026-07-17/.../proforma-invoice.pdf",
"pdf_object_key": "reservation-invoices/HOTEL-TEST/2026-07-17/.../proforma-invoice.pdf",
"generated_excel_object_key": "reservation-invoices/HOTEL-TEST/2026-07-17/.../proforma-invoice.xlsx",
"totals": {
"subtotal": 16822.43,
"vat": 1177.57,
"total": 18000.00,
"currency": "THB"
},
"created_at": "2026-07-17T03:30:00Z"
}
前端诉求:
- 前端已按
RESERVATION_INVOICE_GENERATE做路由权限保护;侧边栏是否展示仍取决于登录态后端返回的menus[]。 - 如需在菜单中展示,建议后端 / 管理员配置
menu_code=RESERVATION_MANUAL_INVOICE、route_path=/reservation/invoices/new、permission_code=RESERVATION_INVOICE_GENERATE。 - 该接口必须支持
source_type=MANUAL且task_id/order_id为空。 - 如果前端同时传
task_id和order_id,必须保证任务属于该订单;后端不一致时返回RESERVATION_INVOICE_CONTEXT_MISMATCH。 recipient.company_code和recipient.contact_id用于表达目录选择结果;company、attention、address、telephone、email是最终用于生成 PDF 的文本值,Manual 覆盖时也必须提交。- 后端需要重新计算金额、VAT 和合计;前端计算只做预览。
- 后端需要返回可预览 / 下载的 PDF URL。
pdf_url第一版可作为预览地址;前端会优先用浏览器fetch + Blob触发下载,避免跨域场景下<a download>失效。如果 OSS CORS 不允许浏览器读取文件,前端会退回打开 PDF 页面。后续如要求稳定下载体验,建议后端提供带Content-Disposition的受控下载代理或签名下载 URL。- 该接口应走 Bearer 登录、酒店访问权和
RESERVATION_INVOICE_GENERATE权限,不走 M008 调试上传 access key。 - 第一版最多支持 10 条
charges[];超过 10 条会返回RESERVATION_INVOICE_VALIDATION_FAILED。 - 第一版只支持
template_code=PROFORMA_INVOICE_V1,模板文件由后端受控维护。 - 第一版已写入
workflow_reservation_invoice_generation生成记录和业务审计,但暂不提供前端查询历史列表 / 详情接口。 - 错误响应中的
error_code用于前端主错误文案映射;message/details[]只作为折叠技术详情展示,不直接铺给普通用户。
13. 已确认后置接口
普通任务切换订单接口继续后置,前端暂不开发提交能力。后续如果恢复开发,建议另行确认:
POST /api/reservation/tasks/{taskId}/order-binding
待确认入参:
{
"target_order_id": "20002",
"reason": "人工确认该任务属于另一个订单"
}
待确认返参:
{
"task_id": "10001",
"previous_order_id": "20001",
"target_order_id": "20002",
"task_status": "PENDING_CONFIRM",
"audit_id": "90001"
}
14. 待确认问题
- 订单列表、任务列表当前统一使用
items + page分页结构;邮件会话详情不分页,返回同一会话全部邮件。 - 邮件会话详情接口已优先使用
GET /api/source-messages/{sourceMessageId}/conversation。 - 任务详情
fields[]已由后端直接透出 P0 需要的 3.0 元数据;独立字段白名单接口后置。 - 独立 Message Notification 页面继续后置;旧 S000/S999 和 V3 S10/S99 继续在旧任务列表和任务详情兼容展示,V4 S10/S99 走 V4 工作台和来源通知详情。
- 邮件会话全文读取的审计策略由后端内部处理;前端不保存原文读取 key。
GET /api/reservation/tasks中旧 S000/S999 和 V3 S10/S99 兼容行的task_type返回值请后端最终确认;V4 S10/S99 不应再进入旧任务列表。manual-review-resolutions成功响应中的opera_operations[]数量请后端最终确认;前端不写死两条,只按返回内容刷新展示。- 系统管理菜单树增强接口已完成:
GET /api/admin/menus/tree、PUT /api/admin/menus/tree-order。 - Manual Invoice 第一阶段的客户 / 联系人目录来源、模板初始文件、VAT 配置和生成记录是否必须落库,已在 M009 中列为开发前确认项。
- V4 真实目录与 Lookup API 第一版已在后端 CP11 落地,前端 CP12 已接入
GET /api/reservation/lookups/accounts、GET /api/reservation/lookups/room-types、GET /api/reservation/lookups/rate-codes用于 V4 字段选择控件。前端按options_source选择接口,空列表 / stale / warnings 只做非阻塞提示,确认和复核仍只提交 code;Rate Code 下一阶段已确认要按 Account +booking_type过滤,前端需等后端新增account_code、booking_type参数和适用性校验后再联动,不能自行硬编码 OWNER RATE Excel;真实 PMS 同步、目录管理后台扩展和 SuperAgent 目录机器接口仍后置。 - V4 Payment 附件预览下一阶段已确认:后端需补
payment_attachments[]安全摘要;前端图片缩略图 + 点击大图预览,非图片文件列表 + 下载;预览和下载仍走 SourceMessage conversation 原文权限链路。attachment_ids[]第一版作为 Agent 返回的只读业务事实,前端只展示并确认卡片,不做附件集合编辑。 - V4 复核态交互已确认:
REVIEW_REQUIRED不新建独立复核任务卡,仍在原业务卡内编辑当前卡fields[]白名单业务字段;问题字段红字提示;主按钮文案统一为“确认卡片”,但前端内部调用POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution。