# 房型映射规则整理

> 来源：用户提供的房型映射截图。本文档先按截图规则整理，后续需用实际案例验证并补充边界情况。

## 1. 明确映射表

| 原始房型 / 描述 | Opera 房型代码 | 备注 |
| --- | --- | --- |
| `U-DBL` | `RM2` | 升级/特殊双人房/大床语义标识，按截图直接映射 |
| `U-TWN` | `RM3` | 升级/特殊双床标识，按截图直接映射 |
| `U-TRP` | `RM4` | 升级/特殊三人房标识，按截图直接映射 |
| `U-TRP=FAM (6+4)` | `RM4` | U-TRP/FAM 6+4 表达，按用户确认规则映射 |
| 普通 `DBL` / `DOUBLE` / 大床 / 双人床 | `RM2` | 普通大床 / 双人床；Rate Code 仍需按渠道和原始线索判断 |
| 普通 `TWN` / `TWIN` / 双床 | `RM3` | 普通双床；Rate Code 仍需按渠道和原始线索判断 |
| `Sup 高级房DBL` / `Sup【高级房DBL】` | `RM2` | 高级房大床 / 双人床语义；Rate Code 不得仅按 `RM2` 判断 |
| `Sup 高级房TWN` / `Sup【高级房TWN】` | `RM3` | 高级房双床语义；Rate Code 不得仅按 `RM3` 判断 |
| `TWN SUITE` | `SU6` | 套房 + 双床 |
| `DBL SUITE` | `SU1` | 套房 + 大床/双人床 |
| `FAMILY 3PAX` | `SU3` | 家庭房，3 人入住 |
| `FAMILY 4PAX` | `SU3` | 家庭房，4 人入住 |
| `ST+K:2卧1厅=1200` + `FAMILY 1` | `SU3` | 跨渠道房型表达；`FAMILY` 是房型线索，`1` 是房量，`1200` 是价格线索，不是房量 |
| `HNM` | `RM2` | 截图中直接映射为 `RM2` |
| `Q10（双床）` | `SU6` | `Q10` 需结合床型判断 |
| `Q10（大床）` | `SU1` | `Q10` 需结合床型判断 |

## 2. 归一化规则

在执行映射前，建议先对输入房型做统一清洗：

1. 去除首尾空格。
2. 将英文统一转为大写。
3. 将连续多个空格合并为一个空格。
4. 中文括号、英文括号可视为同类信息，例如 `Q10（双床）` 与 `Q10(双床)`。
5. 床型关键词建议统一识别：
   - 双床：`双床`、`TWN`、`TWIN`
   - 大床/双人床：`大床`、`DBL`、`DOUBLE`
6. 保留原始房型关键线索，例如 `Sup`、`高级房`、`U-`、`SUITE`、`Q10`、`ST+K:2卧1厅=1200`。这些线索即使映射到同一个 Opera 房型代码，也可能影响 Rate Code 判断。

## 3. 推荐匹配优先级

为了避免误判，建议按以下顺序匹配：

1. **完全匹配优先**
   - 若输入完全等于 `U-DBL`、`U-TWN`、`U-TRP`、`U-TRP=FAM (6+4)`、`Sup 高级房DBL`、`Sup 高级房TWN`、`HNM` 等明确代码，直接返回对应 Opera 房型代码。

2. **`Sup` / 高级房规则**
   - 若房型包含 `Sup` / `SUP` / `高级房` 且床型为双床 / `TWN`，映射为 `RM3`。
   - 若房型包含 `Sup` / `SUP` / `高级房` 且床型为大床 / 双人床 / `DBL`，映射为 `RM2`。
   - 必须在输出中保留 `Sup` / `高级房` 原始线索，供 Rate Code 判断使用。

3. **`Q10` 特殊规则**
   - 若房型包含 `Q10` 且床型为双床，则映射为 `SU6`。
   - 若房型包含 `Q10` 且床型为大床/双人床，则映射为 `SU1`。
   - 若只有 `Q10` 但没有床型信息，暂不自动映射，需人工确认。

4. **套房床型规则**
   - `TWN SUITE` 映射为 `SU6`。
   - `DBL SUITE` 映射为 `SU1`。
   - 如果只出现 `SUITE` 但没有 `TWN` / `DBL` / 床型信息，需人工确认。

5. **家庭房规则**
   - 若原始表达同时包含 `ST+K`、`2卧1厅`、`1200`、`FAMILY`，例如 `(【ST+K:2卧1厅=1200】FAMILY 1)`，跨 QBD / LianTai 渠道均可映射为 `SU3`。
   - 上述表达中 `FAMILY` 是房型线索，`1` 是房量，`1200` 是价格线索；需要将 `ST+K:2卧1厅=1200` 保留在 `original_room_type` / `room_type_note` / `raw_room_text` 中。
   - `FAMILY 3PAX` 映射为 `SU3`。
   - `FAMILY 4PAX` 映射为 `SU3`。
   - 可初步推断：家庭房 `FAMILY` 且入住人数为 3 或 4 时，统一映射 `SU3`。
   - 不得把所有 `FAMILY 1` 泛化为 `SU3`；只有同时出现 `ST+K`、`2卧1厅`、`1200`、`FAMILY` 时才按本规则自动映射。
   - 其他人数，例如 `FAMILY 2PAX`、`FAMILY 5PAX`，截图未覆盖，需实际案例验证。

6. **普通房床型规则**
   - 普通 `TWN` / `TWIN` / 双床映射为 `RM3`。
   - 普通 `DBL` / `DOUBLE` / 大床 / 双人床映射为 `RM2`。
   - 本规则不得覆盖更具体的 `U-`、`Sup`、`SUITE`、`Q10`、`ST+K` / `FAMILY` 规则；Rate Code 仍按渠道、原始房型关键线索和价格规则判断。

## 4. 当前可提炼的业务规则

### 4.1 普通房 / 升级房 / 高级房代码

`U-` 开头的房型按具体后缀映射；`Sup` / 高级房按床型映射。注意：映射到同一个 Opera 房型代码，不代表 Rate Code 相同。

| 规则 | Opera 房型代码 |
| --- | --- |
| 普通 `DBL` / `DOUBLE` / 大床 / 双人床 | `RM2` |
| 普通 `TWN` / `TWIN` / 双床 | `RM3` |
| `U-DBL` | `RM2` |
| `U-TWN` | `RM3` |
| `U-TRP` | `RM4` |
| `U-TRP=FAM (6+4)` | `RM4` |
| `Sup 高级房DBL` / `Sup【高级房DBL】` | `RM2` |
| `Sup 高级房TWN` / `Sup【高级房TWN】` | `RM3` |

Rate Code 判断必须保留原始房型关键线索：

| 原始关键线索 | Opera 房型代码 | Rate Code 影响 |
| --- | --- | --- |
| 普通 `DBL` / `TWN` | `RM2` / `RM3` | 按渠道普通房规则判断；不带 `U` 时按无 `UP` Rate Code |
| `U-DBL` / `U-TWN` | `RM2` / `RM3` | 通常按 `U-` 规则判断 |
| `Sup 高级房DBL` / `Sup 高级房TWN` | `RM2` / `RM3` | 通常按 `Sup` / 高级房规则判断 |

不得只把 `U-TWN` 与 `Sup 高级房TWN` 都归一成 `RM3` 后再判断 Rate Code；也不得只把 `U-DBL` 与 `Sup 高级房DBL` 都归一成 `RM2` 后再判断 Rate Code。

### 4.2 套房按床型区分

| 床型 | Opera 房型代码 |
| --- | --- |
| 大床 / 双人床 / `DBL` | `SU1` |
| 双床 / `TWN` | `SU6` |

适用样例：

| 输入 | 输出 |
| --- | --- |
| `DBL SUITE` | `SU1` |
| `TWN SUITE` | `SU6` |
| `Q10（大床）` | `SU1` |
| `Q10（双床）` | `SU6` |

### 4.3 家庭房统一到 `SU3`

目前截图覆盖：

| 输入 | 输出 |
| --- | --- |
| `FAMILY 3PAX` | `SU3` |
| `FAMILY 4PAX` | `SU3` |
| `ST+K:2卧1厅=1200` + `FAMILY 1` | `SU3` |

`ST+K:2卧1厅=1200` + `FAMILY 1` 是跨 QBD / LianTai 渠道可识别的房型表达：`FAMILY` 是房型线索，`1` 进入 `room_quantity = 1`，`1200` 是价格线索，不计入房量。解析时必须保留原始表达，供 Rate Code 按渠道判断使用。

待验证推断：只要是家庭房且人数为 3 或 4，均映射为 `SU3`。`FAMILY 1` 不在该泛化范围内，除非同时命中 `ST+K`、`2卧1厅`、`1200`、`FAMILY`。

## 5. 待实际案例验证的问题

1. `HNM -> RM2` 的业务含义需要确认，例如是否代表 honeymoon / 蜜月房，或只是某个渠道房型代码。
2. `U-DBL` 映射 `RM2`，但 `DBL SUITE` 映射 `SU1`，说明 `DBL` 本身不能单独决定房型，必须结合是否为 `SUITE` 或 `U-` 前缀判断。
3. `TWN` 在不同语境下映射不同：
   - `U-TWN -> RM3`
   - `TWN SUITE -> SU6`
   - `Q10（双床）-> SU6`
4. `Q10` 必须结合床型判断，不能只根据 `Q10` 单独映射。
5. 家庭房是否所有人数都映射 `SU3` 暂未确认，目前只能确定 `3PAX`、`4PAX`，以及同时包含 `ST+K`、`2卧1厅`、`1200`、`FAMILY` 的 `FAMILY 1` 表达。
6. `RM2` / `RM3` 只能作为 Opera 房型代码，不能反推 Rate Code。Rate Code 必须结合原始房型关键线索，例如 `Sup` / `高级房` 或 `U-`。

## 6. 建议校验输出格式

后续验证实际案例时，建议每条案例按以下格式记录：

| 原始输入 | 归一化后 | 命中规则 | 期望 Opera 代码 | 实际 Opera 代码 | 结论 |
| --- | --- | --- | --- | --- | --- |
| 示例：`Q10（双床）` | `Q10 双床` | `Q10 + 双床` | `SU6` | 待填 | 待验证 |

## 7. 简化版伪代码

```text
normalize(room_type)

if exact_match in explicit_mapping:
    return explicit_mapping[exact_match]

if contains "SUP" or contains "高级房":
    if contains twin_bed_keyword:
        return "RM3" with original_room_type_marker="SUP"
    if contains double_bed_keyword:
        return "RM2" with original_room_type_marker="SUP"
    return "NEED_CONFIRMATION"

if contains "Q10":
    if contains twin_bed_keyword:
        return "SU6"
    if contains double_bed_keyword:
        return "SU1"
    return "NEED_CONFIRMATION"

if contains "SUITE":
    if contains twin_bed_keyword:
        return "SU6"
    if contains double_bed_keyword:
        return "SU1"
    return "NEED_CONFIRMATION"

if contains "ST+K" and contains "2卧1厅" and contains "1200" and contains "FAMILY":
    return "SU3" with room_quantity_from_family_suffix and raw_room_type_note="ST+K:2卧1厅=1200"

if contains "FAMILY":
    if contains "3PAX" or contains "4PAX":
        return "SU3"
    return "NEED_CONFIRMATION"

return "UNMAPPED"
```
