Files
th-hotel-simple/docs/project/frontend-backend/frontend-to-backend-api-requests.md

68 KiB
Raw Blame History

前端提醒后端待补接口

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 DisplayTrace 卡 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-InquiryNew Booking 最终订单投影字段 group_block_name / fit_name 可编辑Group 默认来自 target_order.locator_valuelocator_type=GROUP_CODEFit 默认来自 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_READSOURCE_MESSAGE_ORIGINAL_READ;只能读单封邮件,不能返回同一 conversation 全量邮件。
GET /api/reservation/orders 已完成第一版 可以 默认查询全部订单状态;订单列表待处理展示使用 open_work_item_countV4 普通业务已停止双写旧任务,旧 open_task_count 仅作为历史诊断计数。
GET /api/source-messages/{sourceMessageId}/conversation 已完成第一版,已补 html_body_sanitizedhtml_render_mode 可以 必须带 Bearer token需要同时拥有 SOURCE_MESSAGE_READSOURCE_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 APIDebug 服务自身只展示 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_idkeywordpage_numpage_size,只返回 ACTIVE 目录。Rate Code 下一阶段必须新增 account_codebooking_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_taskmanual_reviewsource_message_review_notification
ai_task_type SuperAgent 原始任务类型,例如 New BookingS10S99
task_subtype 任务 subtype。
route_code M002 V3 路由码,例如 R01_NEW_FIT_RESERVATION_NORMALS10S99
system_process_category 系统处理分类,例如 BUSINESS_TASKSOURCE_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_BOOKINGUPDATE_BOOKINGCANCEL_BOOKINGMANUAL_REVIEWSOURCE_MESSAGE_ONLY;不再提供历史 INFORMATIONAL_MESSAGE 筛选项。旧 S000/S999 和 V3 S10/S99 兼容数据复用 SOURCE_MESSAGE_ONLY 只读源邮件通知卡V4 S10/S99 新数据不进旧任务列表,走 V4 工作台和来源通知详情。
task_status 任务状态过滤。
task_subtype 任务卡 subtype 过滤。
order_status 按任务所属订单状态过滤,支持 TEMPORARYACTIVEENDEDLOGIC_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 展示模型实现后,可继续从确认快照派生 nightsbreakfast_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_atsource_message_idorder_context_indexcreated_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 排除旧任务表中 COMPLETEDFAILED保留为历史诊断计数。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 TEMPORARYACTIVEENDEDLOGIC_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 / NONECONFIRM 调卡片确认接口,REVIEW 调复核解阻接口。
next_v4_action_status PENDING_CONFIRM / REVIEW_REQUIREDNONE 时为空。
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_countv4_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_KEYtest 优先使用 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_assessmentnotification 和 S99 的入口 manual_review
S000/S999 兼容映射 任务列表、任务详情 已完成第一版 旧数据继续可见;前端可按 S000→S10S999→S99 展示统一文案。
40 条 P0.1 路由元数据 任务列表筛选、订单任务时间线、任务详情标题、字段展示 已完成第一版 后端保存并返回 AI 原始 result_type/ai_task_type/task_subtyperoute_code 和系统处理分类;前端不要只依赖系统主任务类型判断卡片。
P0.1 稳定 route_code 任务列表筛选、订单任务时间线、任务详情标题 已完成第一版 route_code 保持历史稳定,不因路由总数变 40 而连续重编号;前端仍可能看到 R41_FALLBACK_BUSINESS_EVENT_REVIEWR42_UNHANDLED_CURRENT_INTENT
Parent split 父事件卡型 任务列表、订单任务时间线、任务详情标题 已完成第一版 0712 P0.1 后Parent split 父事件展示为 Parent Group / Cancel Allotment / cancel_allotment_control_blockroute_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_statusreview_resolution 和可编辑 pointer 字段,解阻后进入 READY
复核场景订单归属确认 任务详情复核 已完成第一版 后端提供复核确认时的订单归属确认;当前第一版只能确认当前任务所属订单,后续如要选择其他订单需另行细化。
P0 fixtures 回归基线 联调回归 已完成第一版 后端已将 0711 P0 fixtures 纳入测试参考;前端对 S10/S99、同卡复核和只读诊断块的展示应继续按本节稳定字段接入。

6.2 前端本轮接入状态2026-07-11

本轮前端已按 M002 V3 P0 完成以下接入,后端不需要重复补接口:

  • 任务列表已按 result_typeroute_codesystem_process_category 识别 source_message_review_notificationadapter_contract_errorunhandled_current_intent 只读诊断任务S10/S99 和旧 S000/S999 都不展示订单入口。
  • 任务详情已展示 result_typeai_task_typetask_subtyperoute_codesystem_process_categoryreview_status、来源邮件入口、source_message_only_resultmanual_reviewadapter_contract_errors[]unhandled_intents[]
  • Parent Group P0.1 前端已按 route_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL/REVIEW 展示 Parent Group / Cancel Allotment / cancel_allotment_control_blockreview 场景继续走同卡人工复核解阻,不展示为 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_rolecurrent_or_historysource_event_index、四字段 case_keysrelevant_message_excerptattachmentsfile_referencescontext_usedextracted_fieldsmanual_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_READSOURCE_MESSAGE_ORIGINAL_READ,后端会按 SourceMessage 实际所属酒店校验访问权。
  • “全部邮件”指同一个 externalConversationId 下的历史邮件、当前邮件和后续回复,不是只展示任务对应的单封来源邮件。
  • V4 任务详情页的 SOURCE_MESSAGE_DISPLAY 卡如果展示正文,只展示当前触发该 V4 order task 的那一封 SourceMessage前端应按入口 sourceMessageIdmessages[] 中定位对应 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_sanitizedhtml_render_mode;前端页面展示邮件 HTML 时应优先使用 html_body_sanitizedhtml_body 只作为原始内容兼容字段,不建议生产直渲。
  • 第一版仅处理 HTML 内容清洗;附件和内联图片 URL 来自本系统 OSS 服务,暂不做额外拦截或代理转换。
  • Payment 卡预览 / 下载匹配必须使用后端返回的附件 ID / externalMediaId,不能按文件名猜测;前端不得把 externalUrl 放进确认 payload、日志、错误上报、URL query 或 localStorage。

建议入参:

参数 必填 说明
sourceMessageId 入口来源消息 ID。后端据此定位 externalConversationId

当前第一版不额外接收 hotelIdincludeBodyincludeRelated。后端默认按 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[] 是后端按当前任务生效规则过滤后的字段集合,不是完整字段矩阵。后端已经应用 visibleresult_typetask_typetask_subtypedisplay_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_reviewsystem_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_pointerfield_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_pointerfield_pathfield_pointer 必须是 RFC 6901 JSON Pointerfield_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 是 UTC Z 时间点。
  • 解阻成功后刷新任务详情,按钮状态以新的 task_status=READYavailability 为准。
  • 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_typetask_typetask_subtypedefault_value_source 当前从后端字段矩阵定义透出。
  • 如果后端已有更细的字段来源或适用场景元数据,可后续再扩展 field_sourceapplicable_scenario,不作为本轮 P0 阻塞项。
  • 前端默认不需要为 GET /api/reservation/ordersGET /api/reservation/tasksGET /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_idS999,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 入口兼容语义:

  • S10result_type=source_message_review_notificationroute_code=S10,表示未匹配当前支持的业务事件。
  • S99result_type=source_message_review_notificationroute_code=S99,表示输入不足或无法形成业务素材包。
  • S000 前端语义映射为 S10
  • S999 前端语义映射为 S99

历史 INFORMATIONAL_MESSAGE 仍可通过任务列表 / 任务详情兼容展示,但新数据不要依赖它。

展示规则:

  • task_type=SOURCE_MESSAGE_ONLYtask_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_codeentry_result_meaningentry_result_descriptionentry_result_source_message_idresult_typeroute_codeagent_assessmentnotification、S99 的入口 manual_reviewraw_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 / DISABLEDvisible=true / false
  • parent_id 组树,根节点 parent_id=null
  • 同级按 sort_order 升序,其次按 menu_nameid 稳定排序。
  • BIGINT ID 继续以字符串返回。
  • 如果存在脏数据,例如 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_idsort_order,不允许顺带修改 menu_nameroute_pathpermission_codevisiblemenu_status
  • 使用事务保存。
  • 校验 menu_id 必须存在。
  • 校验 parent_id 为空或存在。
  • 禁止把自己设为自己的父级。
  • 禁止形成循环菜单树。
  • sort_order 可为空;为空时后端按请求 items[] 顺序生成 100200300... 的稳定排序号。
  • 成功后返回更新后的完整菜单树,方便前端立即刷新。
  • 审计中记录调整前后的 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_INVOICEroute_path=/reservation/invoices/newpermission_code=RESERVATION_INVOICE_GENERATE
  • 该接口必须支持 source_type=MANUALtask_id / order_id 为空。
  • 如果前端同时传 task_idorder_id,必须保证任务属于该订单;后端不一致时返回 RESERVATION_INVOICE_CONTEXT_MISMATCH
  • recipient.company_coderecipient.contact_id 用于表达目录选择结果;companyattentionaddresstelephoneemail 是最终用于生成 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/treePUT /api/admin/menus/tree-order
  • Manual Invoice 第一阶段的客户 / 联系人目录来源、模板初始文件、VAT 配置和生成记录是否必须落库,已在 M009 中列为开发前确认项。
  • V4 真实目录与 Lookup API 第一版已在后端 CP11 落地,前端 CP12 已接入 GET /api/reservation/lookups/accountsGET /api/reservation/lookups/room-typesGET /api/reservation/lookups/rate-codes 用于 V4 字段选择控件。前端按 options_source 选择接口,空列表 / stale / warnings 只做非阻塞提示,确认和复核仍只提交 codeRate Code 下一阶段已确认要按 Account + booking_type 过滤,前端需等后端新增 account_codebooking_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