diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md
index edbb63e..f8cc914 100644
--- a/PROJECT_STATE.md
+++ b/PROJECT_STATE.md
@@ -4,15 +4,15 @@
| --- | --- |
| 最近更新 | 2026-07-19 |
| 当前分支 | `feature/huangting` |
-| 当前阶段 | M002 V4 入站、多卡模型、持久化基线、入站写入、查询接口、卡片确认、复核解阻、目录校验、订单详情时间线、DB 目录和 Lookup API 并行 |
-| 当前重点 | M002 V4 已完成 DB 管理目录与 Lookup API V1 后端;后续可做 V4 前端 lookup 接入、目录管理后台或真实 PMS / OPERA / OHIP 同步 |
+| 当前阶段 | M002 V4 入站、多卡模型、持久化基线、入站写入、查询接口、卡片确认、复核解阻、目录校验、订单详情时间线、DB 目录、Lookup API 和前端 lookup 接入并行 |
+| 当前重点 | M002 V4 已完成 DB 管理目录与 Lookup API V1 后端,并完成前端 V4 多卡字段 lookup 第一版接入;后续可做目录管理后台或真实 PMS / OPERA / OHIP 同步 |
## 1. 当前 Checkpoint
-- 名称:`M002-V4-CP11-db-catalog-lookup-api-v1`
-- 状态:Done,已新增 `workflow_reservation_catalog_account`、`workflow_reservation_catalog_code`,将 `QBD_TRAVEL`、`LIAN_TAI`、`HANATOUR_TD`、Room Type、Rate Code、Market、Source 固定种子导入数据库,并开放 Account / Room Type / Rate Code lookup API;已补启动阶段默认酒店目录初始化和 lookup keyword 无结果时的 wrapper 元数据修正。
+- 名称:`M002-V4-CP12-frontend-lookup-and-multicard-integration`
+- 状态:Done,前端已按 V4 任务卡 `fields[].options_source` 接入 Account / Room Type / Rate Code lookup API,替换前端硬编码目录选项;V4 多卡详情页会展示 lookup 空列表、stale、warnings、目录来源版本和 Account 派生 Market / Source,确认 / 复核仍只提交 code;订单详情页已消费 `v4_order_tasks[]` 展示 V4 订单任务时间线。
- 目标:让 V4 任务详情字段控件不再依赖前端硬编码选项,后端入站、确认、复核统一按当前酒店数据库目录做校验。
-- 边界:本轮不接真实 PMS / OPERA / OHIP 同步,不做目录管理后台,不新增 `workflow_reservation_catalog_sync_run`,不做 SuperAgent 目录机器接口,不做前端页面。
+- 边界:本轮不接真实 PMS / OPERA / OHIP 同步,不做目录管理后台,不新增 `workflow_reservation_catalog_sync_run`,不做 SuperAgent 目录机器接口,不废弃旧 V2/V3 接口。
## 2. 当前优先级
@@ -34,12 +34,12 @@
- `docs/import/` 下按日期导入的资料是输入材料,不等同于当前权威开发契约;当前开发应优先看 `docs/project/README.md` 标记为当前有效或权威契约的文档。
- 后续每完成一个 Feature 或 Checkpoint,需要更新本文件,避免项目状态继续沉淀在聊天记录里。
- M010 Rooming List Excel 生成后端 CP1 和前端 V1 已实现:前端 `/reservation/rooming-lists/new` 上传来源名单和手工字段,后端同步生成 `.xlsx` 直接下载,第一版不落库、不上传 OSS。
-- M002 V4 CP1 当前已完成入站解析和现有任务链路过渡适配;M002 V4 CP2 已完成订单任务与多卡领域模型设计;M002 V4 CP3 已完成 V4 订单任务、多卡和 S10/S99 来源通知表结构与 Repository 基线;M002 V4 CP4 已完成入站写入新模型;M002 V4 CP5 已完成前端查询接口并补齐订单详情 `v4_order_tasks[]` 时间线;M002 V4 CP6 已完成普通卡片确认和 S10/S99 来源通知 ack;M002 V4 CP7 已完成 `REVIEW_REQUIRED` 卡复核解阻和复核场景订单归属确认;M002 V4 CP8 已完成目录校验、V4 卡片 `fields[]` 字段白名单、确认写入白名单收口和嵌套业务字段目录校验;M002 V4 CP11 已完成数据库目录、初始化种子、启动补种子、Account / Room Type / Rate Code lookup API,并把 V4 入站、确认、复核目录校验切换到当前酒店数据库目录。V4 前端页面、目录管理后台、真实 PMS 同步和 SuperAgent 目录机器接口仍未完成。
+- M002 V4 CP1 当前已完成入站解析和现有任务链路过渡适配;M002 V4 CP2 已完成订单任务与多卡领域模型设计;M002 V4 CP3 已完成 V4 订单任务、多卡和 S10/S99 来源通知表结构与 Repository 基线;M002 V4 CP4 已完成入站写入新模型;M002 V4 CP5 已完成前端查询接口并补齐订单详情 `v4_order_tasks[]` 时间线;M002 V4 CP6 已完成普通卡片确认和 S10/S99 来源通知 ack;M002 V4 CP7 已完成 `REVIEW_REQUIRED` 卡复核解阻和复核场景订单归属确认;M002 V4 CP8 已完成目录校验、V4 卡片 `fields[]` 字段白名单、确认写入白名单收口和嵌套业务字段目录校验;M002 V4 CP11 已完成数据库目录、初始化种子、启动补种子、Account / Room Type / Rate Code lookup API,并把 V4 入站、确认、复核目录校验切换到当前酒店数据库目录;M002 V4 CP12 已完成前端 lookup 接入第一版和 V4 订单任务时间线消费。目录管理后台、真实 PMS 同步和 SuperAgent 目录机器接口仍未完成。
- M002 V4 CP2 已确认:V4 工作台统一列表草案为 `/api/reservation/workbench-items`,业务订单任务接口新开 `/api/reservation/order-tasks/**`,S10/S99 来源通知详情草案为 `/api/reservation/source-notifications/{notificationId}`;S10/S99 使用来源通知模型,不再挂隐藏技术订单;`FIT + BOOKING_CODE` 不建 ACTIVE 唯一约束,匹配多条进人工复核;Basic Information 必须先确认;Account / Market / Source 当前通过数据库目录读取和派生;旧 V2/V3 任务详情和草稿确认接口后续可逐步废弃。
## 5. Next Steps
-- 后续如继续做 M002 V4,可优先进入 V4 前端 lookup / 多卡页面接入 checkpoint,或进入目录管理后台、真实 PMS / OPERA / OHIP 目录同步和 `workflow_reservation_catalog_sync_run` checkpoint。
+- 后续如继续做 M002 V4,可优先进入 V4 多卡真实联调验收、目录管理后台、真实 PMS / OPERA / OHIP 目录同步和 `workflow_reservation_catalog_sync_run` checkpoint。
- 后续新增重要功能时,优先在 `docs/project/requirements/` 或未来 `docs/specs/` 中形成 Spec,再实现代码。
- M010 后续如需预览、历史记录、OSS 下载、订单 / 任务预填或客户字段目录化,再单独开前后端 checkpoint。
diff --git a/client/src/components/reservation/ReservationV4TaskCardFieldRenderer.vue b/client/src/components/reservation/ReservationV4TaskCardFieldRenderer.vue
index 91e6584..a26d785 100644
--- a/client/src/components/reservation/ReservationV4TaskCardFieldRenderer.vue
+++ b/client/src/components/reservation/ReservationV4TaskCardFieldRenderer.vue
@@ -16,6 +16,7 @@
v-if="isEditable(field) && isSelectField(field)"
class="v4-field__control"
:aria-invalid="fieldError(field) ? 'true' : 'false'"
+ :disabled="selectDisabled(field)"
:value="fieldValue(field)"
@change="updateField(field, $event)"
>
@@ -76,6 +77,12 @@
v-if="field.control_hint"
class="v4-field__hint"
>{{ field.control_hint }}
+ {{ hint.message }}