# AI 讲房集成指南

本文档面向**接入众趣 zqsdk 的开发者**，说明如何在自己的项目中实现「AI 讲房」功能。按步骤完成能力判断、事件监听、方法调用与 UI 搭建即可完成集成。

---

## 一、功能简介与前置条件

### 1.1 什么是 AI 讲房

AI 讲房是众趣 SDK 的「新版讲房」能力：按预设段落（小区内部、周边配套、户型解析、房源信息）自动播放讲解，并同步当前段落与进度。你的项目需要：

- 在合适的时机判断**当前模型是否支持讲房**；
- **监听 SDK 事件**以更新进度与播放状态；
- **调用 SDK 方法**实现开始、暂停、切换段落；
- 提供**讲房入口、控制条、进度展示**等 UI（样式可完全自定义）。

### 1.2 展示示例

![讲房入口](../../screenshot/introduce/讲房入口按钮.png)
![小区内部](../../screenshot/introduce/小区内部.png)
![周边配套](../../screenshot/introduce/周边配套.png)
![户型解析](../../screenshot/introduce/户型解析.png)

### 1.3 前置条件

- 已接入众趣 zqsdk，并在 `zqsdk.init` 的 `complete` 回调中拿到 `window.housePlay`（或等价实例）。
- 模型存在讲房数据；支持讲房的模型会在初始化时提供 `vr_speak_data`。
  AI讲房接口对接流程见: [AI讲房业务对接文档]('https://opendev.3dnest.cn/doc/open/business-integration/ai-house-narration/')
- 本项目采用的baidu地图进行的示例组件开发， 如果需要正常使用，需要您设置环境变量`VITE_APP_BAIDU_MAP_AK`到.env中

#### 1.4 申请百度ak
百度地图ak, 用于本demo项目中地图相关信息的展示。百度地图应用申请地址：https://lbsyun.baidu.com/）
创建应用，应用类型请选择【浏览器端】
![创建应用](../../screenshot/baidu-map/百度地图-创建应用.png)

ak在此处复制
![百度地图ak](../../screenshot/baidu-map/百度地图-ak.png)

## 二、集成步骤概览

| 步骤 | 内容 |
|------|------|
| 1 | 在 `init_UI` 中根据 `vr_speak_data` 判断是否支持讲房，并初始化你的「讲房可用」状态与段落列表 |
| 2 | 在 housePlay 上注册讲房相关事件，将进度、段落索引、暂停/结束同步到你的状态 |
| 3 | 在用户操作时调用 `startLecture` / `pauseLecture` / `goToLectureByName` |
| 4 | 实现讲房入口、控制条、进度条、讲房时的遮罩等 UI |
| 5 | 监听 `connect_ui_operation`，在讲房过程中显隐地图、小区图、周边配套等 |

以下按步骤展开。

---

## 三、第一步：判断模型是否支持讲房

**时机**：在 `housePlay.on('init_UI', ...)` 回调中执行。

**做法**：从 `housePlay.model.settings.vr_speak_data` 判断是否存在且为非空对象。若是，则当前模型支持讲房。

```javascript
housePlay.on('init_UI', function(model) {
  // model 即 housePlay.model，可从 model.settings 读取配置
  let settings = model.settings || {};
  let vrSpeakData = settings.vr_speak_data;
  let hasLecture = vrSpeakData && typeof vrSpeakData === 'object' && Object.keys(vrSpeakData).length > 0;

  if (hasLecture) {
    // 在你的应用里：显示「AI 讲房」入口，并初始化讲房段落列表（见下）
    yourApp.setLectureAvailable(true);
    yourApp.initLectureSegmentList(vrSpeakData);  // 可选：用 vrSpeakData 解析自定义段落，或使用固定 4 段
  }
});
```

**段落列表建议**：SDK 按「场景名」切换，固定为以下 4 段（顺序可自定），你只需维护「展示名 + 传给 SDK 的名称」的映射：

| 展示名（可自定义） | 传给 SDK 的名称（必须一致） |
|-------------------|----------------------------|
| 小区内部          | `uptown_inside`            |
| 周边配套          | `uptown_outside`           |
| 户型解析          | `house_parse`              |
| 房源信息          | `house_info`               |

列表末尾可加一项「退出讲房」，仅用于关闭面板并暂停，不传 SDK。

---

## 四、第二步：准备讲房状态与段落数据

建议在你自己项目中维护至少以下状态（名称可自定）：

| 状态 | 含义 | 建议更新方式 |
|------|------|----------------|
| 讲房是否可用 | 当前模型是否有讲房数据 | 仅在 `init_UI` 中根据 `vr_speak_data` 设置 |
| 讲房面板是否显示 | 是否打开讲房控制条/浮层 | 用户点击入口时设为 true，点击退出时设为 false |
| 是否正在播放 | 与 SDK 实际播放状态一致 | **仅由 SDK 事件回调更新**，避免与 SDK 不同步 |
| 当前段落索引 | 0~3 对应四段，或你的列表 index | 由 `lectureUpdate` 第一参数或用户点击段落时更新 |
| 当前段落进度 | 0–100，用于进度条 | 由 `lectureUpdate` 第二参数更新 |

段落数据结构示例（便于你渲染列表并调用 `goToLectureByName`）：

```javascript
const defaultSegments = [
  { name: '小区内部', lectureName: 'uptown_inside' },
  { name: '周边配套', lectureName: 'uptown_outside' },
  { name: '户型解析', lectureName: 'house_parse' },
  { name: '房源信息', lectureName: 'house_info' }
];
// 可再 push 一项 { name: '退出讲房', lectureName: null } 用于关闭面板
```

---

## 五、第三步：注册 SDK 事件并同步到你的状态

在 housePlay 可用后（例如在 `zqsdk.init` 的 `complete` 里 `housePlay.start()` 之后），注册以下讲房事件，并**仅在这些回调中**更新「是否正在播放」「当前段落索引」「当前段落进度」。

```javascript
// 讲房进度更新：第一参数为当前段落 index 或 playStyle，第二参数为当前段落内进度百分比
housePlay.on('lectureUpdate', function(playStyleOrIndex, percent) {
  yourApp.setLectureProgress(typeof percent === 'number' ? percent : 0);
  if (typeof playStyleOrIndex === 'number' && playStyleOrIndex >= 0) {
    yourApp.setCurrentSegmentIndex(playStyleOrIndex);
  }
});

// 讲房场景切换：playStyle 为新段落名称（如 'uptown_outside'）
housePlay.on('lectureNextPlayStyle', function(playStyle) {
  yourApp.setCurrentSegmentByPlayStyle(playStyle);
  yourApp.setLectureProgress(0);  // 切换段落时重置进度
});

// 讲房暂停
housePlay.on('lecturePause', function() {
  yourApp.setLecturePlaying(false);
});

// 讲房结束
housePlay.on('lectureEnd', function() {
  yourApp.setLecturePlaying(false);
  yourApp.hideLecturePanel();  // 可选：自动关闭面板
});
```

注意：**不要**在用户点击「播放」时仅本地把「是否正在播放」设为 true 而不调 SDK；应先调 SDK，再由上述事件回写状态，以保证与 SDK 一致。

---

## 六、第四步：在用户操作时调用 SDK 方法

SDK 提供三个与讲房相关的方法（均在 `housePlay` 上调用）：

| 方法 | 说明 | 调用时机建议 |
|------|------|--------------|
| `housePlay.startLecture()` | 开始或继续讲房 | 用户点击「开始讲房」或控制条上的「播放」 |
| `housePlay.pauseLecture()` | 暂停讲房 | 用户点击「暂停」或「退出讲房」 |
| `housePlay.goToLectureByName(name)` | 跳转到指定段落 | 在**开始/继续播放前**先跳段，再调用 `startLecture()` |

**推荐交互逻辑**：

- **用户点击「AI 讲房」入口**：显示讲房面板 → 将本地「当前选中段」设为 0（或保持上次）→ 调用 `housePlay.startLecture()`（若希望从第一段开始，可先 `goToLectureByName('uptown_inside')` 再 `startLecture()`）。
- **用户点击控制条「播放」**：若当前有选中段落且非「退出」，先 `goToLectureByName(当前段的 lectureName)`，再 `startLecture()`；否则仅 `startLecture()`。
- **用户点击「暂停」**：仅调用 `pauseLecture()`；播放状态由事件 `lecturePause`/`lectureEnd` 回写。
- **用户点击某一段落**：  
  - 若当前为**暂停**：只更新你本地的「当前选中段」和进度条置 0，**不调 SDK**。  
  - 若当前为**播放**：先 `goToLectureByName(该段 lectureName)`，再 `startLecture()`。
- **用户点击「退出讲房」**：调用 `pauseLecture()`，并关闭讲房面板、重置本地展示状态。

这样可避免「暂停时误触 SDK」导致状态错乱。

---

## 七、第五步：实现讲房 UI

UI 完全由你自定义，只需满足功能对应关系即可。

### 7.1 建议具备的 UI 元素

1. **讲房入口**  
   - 显示条件：SDK 已就绪且当前模型 `vr_speak_data` 存在（即「讲房可用」为 true），且讲房面板未打开。  
   - 点击：打开讲房面板，并调用 `startLecture()`（必要时先 `goToLectureByName` 再 `startLecture`）。

2. **讲房控制条/浮层**  
   - 显示条件：讲房面板已打开。  
   - 内容建议：  
     - 播放/暂停按钮 → 对应 `startLecture` / `pauseLecture`，且播放时若需从当前段开始则先 `goToLectureByName`；  
     - 段落列表（4 段 + 可选「退出讲房」）→ 点击段落时按「第四步」逻辑处理；  
     - 当前段进度条 → 绑定「当前段落进度」状态（0–100）。

3. **讲房播放时的画布遮罩（推荐）**  
   - 当「讲房面板已打开且正在播放」时，在 3D/全景画布上盖一层透明遮罩（`pointer-events: auto`），避免用户误触旋转/漫游；讲房控制条置于遮罩之上并可点击。这样体验更稳定。

4. **讲房模式下的其他 UI**  
   - 可根据需要隐藏底部栏、右侧面板、导览入口等，仅保留讲房相关控件，避免与讲房控制条重叠。

### 7.2 可选：顶部房源标题

若你有房源名称，可在讲房面板打开时在顶部居中展示，提升识别度；数据来源由你业务决定（如从 `vr_speak_data.settings` 或房源接口获取）。

---

## 八、第六步：讲房过程中显示地图、小区图、周边配套

讲房播放到某些段落时，SDK 会通过事件 **`connect_ui_operation`** 下发「要显示/隐藏的 UI」，用于在讲房过程中自动弹出或关闭地图、小区图、房源详情等。

### 8.1 监听方式

```javascript
housePlay.on('connect_ui_operation', function(action) {
  if (!action || action.type !== 'UI_OPERATION' || !action.data) return;
  if (action.data.type !== 'UI') return;

  let target = action.data.target;   // 要控制的 UI 目标
  let show = action.data.action;     // true 显示，false 隐藏（或其他数据）

  switch (target) {
    case 'houseInfo':   // 房源详情（可包含地图、小区图、房源信息等）
      yourApp.toggleHouseInfoPanel(show);
      break;
    case 'bigMap':      // 大地图
      yourApp.toggleBigMap(show);
      break;
    case 'imgSwiper':   // 小区图片轮播
      yourApp.toggleCommunityImageSwiper(show);
      break;
    case 'bigHangpai':  // 大航拍
      yourApp.toggleBigHangpaiPanel(show);
      break;
    case 'mapSearchItemIndex':  // 周边配套 POI 数据
      yourApp.setMapSearchData(show);
      break;
    // 其他 target 按需处理
  }
});
```

### 8.2 数据来源

讲房所需的地图、小区图等数据通常来自模型配置。可在 `init_UI` 或房源数据加载时，将 `housePlay.model.settings.vr_speak_data.settings` 中与 UI 相关的字段（如 `communityImages`、`address`、`panoramaLink` 等）合并到你自己的房源/详情数据中，再在收到 `connect_ui_operation` 时根据 `target` 显示对应组件。

### 8.3 周边配套 POI 数据（mapSearchItemIndex）

当讲房进入「周边配套」段落时，SDK 会通过 `connect_ui_operation` 下发 `mapSearchItemIndex` 数据，包含当前分类的 POI（兴趣点）列表，用于在地图上展示周边学校、地铁、公交、购物中心、医院、公园、菜市场等配套设施。

#### 8.3.1 数据结构

```javascript
// action.data 结构
{
  type: 'UI',
  target: 'mapSearchItemIndex',
  action: {
    name: '学校',  // 分类名称：学校 | 地铁 | 公交 | 购物中心 | 医院 | 公园 | 菜市场
    poi: [
      {
        name: 'XX小学',           // POI 名称
        title: 'XX小学',          // POI 标题（可能与 name 相同）
        lng: 116.404,             // 经度
        lat: 39.915,              // 纬度
        location: { lng, lat },   // 坐标（部分版本使用此字段）
        distance: 500,            // 距离房源的距离（米）
        address: 'XX路XX号'       // 地址（可选）
      },
      // ... 更多 POI
    ]
  }
}
```

**注意**：SDK 下发的分类名称可能是具体类型（如 "初中"、"小学"），需要映射到标准分类（如 "学校"）。

#### 8.3.2 分类名称映射

SDK 可能下发的分类名称与标准分类的映射关系：

| SDK 下发名称 | 标准分类 |
|-------------|---------|
| 幼儿园、小学、初中、高中、大学 | 学校 |
| 地铁、地铁站 | 地铁 |
| 公交、公交站 | 公交 |
| 购物、商场、超市 | 购物中心 |
| 医院、诊所、卫生院 | 医院 |
| 公园、绿地、广场 | 公园 |
| 菜市场、菜场、农贸市场、生鲜 | 菜市场 |

```javascript
// 分类名称映射函数示例
function normalizeMapSearchCategory(name) {
  const schoolTypes = ['幼儿园', '小学', '初中', '高中', '大学', '学校'];
  if (schoolTypes.includes(name)) return '学校';
  if (name.includes('地铁')) return '地铁';
  if (name.includes('公交')) return '公交';
  if (name.includes('购物') || name.includes('商场') || name.includes('超市')) return '购物中心';
  if (name.includes('医院') || name.includes('诊所')) return '医院';
  if (name.includes('公园') || name.includes('绿地')) return '公园';
  if (name.includes('菜市场') || name.includes('农贸')) return '菜市场';
  return name;  // 已是标准分类则直接返回
}
```

#### 8.3.3 监听与处理

```javascript
housePlay.on('connect_ui_operation', function(action) {
  if (!action || action.type !== 'UI_OPERATION' || !action.data) return;
  if (action.data.type !== 'UI') return;

  let target = action.data.target;
  let data = action.data.action;

  switch (target) {
    // ... 其他 target 处理

    case 'mapSearchItemIndex':
      // 周边配套 POI 数据
      if (data && typeof data === 'object' && data.name && data.poi) {
        let rawCategoryName = data.name;
        let normalizedCategory = normalizeMapSearchCategory(rawCategoryName);
        
        yourApp.setMapSearchData({
          rawName: rawCategoryName,           // 原始名称（用于显示）
          normalizedName: normalizedCategory, // 标准分类（用于索引）
          poi: data.poi.map(function(item) {
            return {
              name: item.name || item.title,
              lng: item.lng || (item.location && item.location.lng),
              lat: item.lat || (item.location && item.location.lat),
              distance: item.distance || 0,
              address: item.address || ''
            };
          }).sort(function(a, b) {
            return (a.distance || 0) - (b.distance || 0);  // 按距离排序
          })
        });
      }
      break;
  }
});
```

#### 8.3.4 状态管理建议

建议在你的应用中维护以下周边配套相关状态：

| 状态 | 含义 | 说明 |
|------|------|------|
| `mapSearchCurrentIndex` | 当前分类索引 | 0-6 对应：学校、地铁、公交、购物中心、医院、公园、菜市场 |
| `mapSearchCurrentName` | 当前分类名称 | 如 "学校"、"地铁" 等 |
| `mapSearchCurrentPoi` | 当前分类的 POI 列表 | 数组，包含 name、lng、lat、distance 等 |
| `mapSearchCategoriesData` | 所有分类的 POI 缓存 | 对象，key 为标准分类名，value 为 POI 数组 |

```javascript
// 分类常量
const MAP_SEARCH_CATEGORIES = ['学校', '地铁', '公交', '购物中心', '医院', '公园', '菜市场'];

// 设置 POI 数据
function setMapSearchData(data) {
  let rawCategoryName = data.rawName;
  let normalizedCategory = data.normalizedName;
  let poiList = data.poi;

  // 使用标准分类名缓存数据
  mapSearchCategoriesData[normalizedCategory] = poiList;

  // 更新当前分类（显示原始名称便于用户理解）
  mapSearchCurrentName = rawCategoryName;
  mapSearchCurrentPoi = poiList;
  mapSearchCurrentIndex = MAP_SEARCH_CATEGORIES.indexOf(normalizedCategory);
}

// 切换分类（用户手动切换时）
function switchMapSearchCategory(index) {
  let categoryName = MAP_SEARCH_CATEGORIES[index];
  let cachedData = mapSearchCategoriesData[categoryName];

  mapSearchCurrentIndex = index;
  mapSearchCurrentName = categoryName;
  mapSearchCurrentPoi = cachedData || [];
}
```

#### 8.3.5 地图 UI 实现建议

周边配套地图建议包含以下 UI 元素：

1. **地图主体**
   - 显示房源位置（中心标记点）
   - 显示当前分类的 POI 标记
   - POI 数据更新时自动显示第一个 POI 的步行路径

2. **分类切换栏**（底部或顶部）
   - 7 个分类按钮：学校、地铁、公交、购物中心、医院、公园、菜市场
   - 高亮当前分类
   - 点击切换分类，更新地图上的 POI 标记

3. **POI 列表侧边栏**（可选）
   - 显示当前分类的 POI 列表
   - 每项显示名称和距离
   - 点击可定位到该 POI 并显示步行路径

4. **步行路径**
   - POI 数据更新时，自动显示第一个 POI 的步行路线
   - 点击 POI 时，切换显示该 POI 的步行路线
   - 使用百度地图 `WalkingRoute` API 实现

```javascript
// 百度地图步行路径示例
let walkingRoute = new BMap.WalkingRoute(map, {
  renderOptions: { map: map, autoViewport: false }
});

// 显示步行路径
function showWalkingRoute(poi) {
  walkingRoute.clearResults();
  let start = new BMap.Point(houseLng, houseLat);  // 房源坐标
  let end = new BMap.Point(poi.lng, poi.lat);       // POI 坐标
  walkingRoute.search(start, end);
}

// POI 数据更新时自动显示第一个 POI 的路径
function renderPoiMarkers(poiList) {
  // ... 渲染 POI 标记 ...
  
  // 自动显示第一个 POI 的步行路径
  if (poiList.length > 0) {
    showWalkingRoute(poiList[0]);
  }
}
```

---

## 九、API 速查表

### 9.1 方法（housePlay）

| 方法 | 说明 |
|------|------|
| `housePlay.startLecture()` | 开始/继续讲房 |
| `housePlay.pauseLecture()` | 暂停讲房 |
| `housePlay.goToLectureByName(name)` | 跳转到指定段落；`name` 取值：`uptown_inside` \| `uptown_outside` \| `house_parse` \| `house_info` |

### 9.2 事件（housePlay.on）

| 事件 | 回调参数 | 说明 |
|------|----------|------|
| `lectureUpdate` | `(playStyleOrIndex, percent)` | 进度更新；第一参数为段落 index 或 playStyle 字符串，第二参数为 0–100 百分比 |
| `lectureNextPlayStyle` | `(playStyle)` | 场景切换；`playStyle` 为新段落名称（如 `uptown_outside`） |
| `lecturePause` | 无 | 讲房暂停 |
| `lectureEnd` | 无 | 讲房结束 |
| `lecture` | `(state)` | 旧版；`state === 'stop'` 表示停止 |
| `connect_ui_operation` | `(action)` | 讲房过程中显隐 UI；`action.data.target` 与 `action.data.action` 见下表 |

### 9.3 connect_ui_operation target 速查

| target | action 类型 | 说明 |
|--------|-------------|------|
| `houseInfo` | `boolean` | 房源详情面板显隐 |
| `bigMap` | `boolean` | 大地图显隐 |
| `imgSwiper` | `boolean` | 小区图片轮播显隐 |
| `bigHangpai` | `boolean` | 大航拍面板显隐 |
| `houseInfoSwiper` | `boolean` | 房源信息轮播自动播放 |
| `initHouseInfoSwiper` | `number` | 房源信息轮播初始索引 |
| `mapSearchItemIndex` | `{ name, poi[] }` | 周边配套 POI 数据（见 8.3 节） |

### 9.4 判断讲房是否可用

- 在 `init_UI` 中读取：`housePlay.model.settings.vr_speak_data`，存在且为非空对象即表示支持讲房。

---

## 十、常见问题与注意事项

1. **务必在事件回调中更新「是否正在播放」**  
   不要只在点击播放时本地设为 true；否则 SDK 暂停或出错时，你的 UI 会与真实状态不一致。应以 `lecturePause`、`lectureEnd` 为准。

2. **暂停时切换段落不要调 SDK**  
   用户暂停后点击其他段落，只更新你本地的「当前选中段」和进度条；等用户再次点击「播放」时再 `goToLectureByName` + `startLecture`，避免多余调用。

3. **先 goToLectureByName 再 startLecture**  
   若希望「从指定段开始播放」，请先调用 `goToLectureByName(lectureName)`，再调用 `startLecture()`。

4. **方法是否存在**  
   部分环境或旧版 SDK 可能未暴露 `startLecture` / `pauseLecture` / `goToLectureByName`，调用前可用 `housePlay.startLecture != null` 等方式做兼容。

5. **与导览的关系**  
   讲房与导览相互独立；同一模型可同时有导览和讲房，分别用 `heroLocations` 和 `vr_speak_data` 判断即可。

6. **周边配套分类名称映射**  
   SDK 下发的分类名称可能是具体类型（如 "初中"），需要映射到标准分类（如 "学校"）后再进行索引和缓存，确保分类切换栏正确高亮。

7. **周边配套路径自动显示**  
   当 POI 数据更新时，建议自动显示第一个 POI 的步行路径，提升用户体验。

---

## 十一、本仓库实现参考

若需参考本仓库的完整实现（Vue 3 + Pinia + TypeScript），可参阅：

### 11.1 核心文件

| 文件 | 说明 |
|------|------|
| `src/stores/introduce.ts` | 讲房状态管理（段落、进度、POI、面板显隐等） |
| `src/stores/vr.ts` | SDK 事件监听与分发（`lectureUpdate`、`connect_ui_operation` 等） |
| `src/types/lecture.ts` | 讲房相关类型定义（`MapSearchPoiItem`、`MapSearchData`、`normalizeMapSearchCategory` 等） |

### 11.2 UI 组件

| 文件 | 说明 |
|------|------|
| `src/modules/pc/introduce/NestIntroduceBtn.vue` | 讲房入口按钮 |
| `src/modules/pc/introduce/NestIntroducePanel.vue` | 讲房控制面板（段落列表、进度条、播放/暂停） |
| `src/modules/pc/introduce/NestIntroduceOverlay.vue` | 讲房播放遮罩 |
| `src/modules/pc/introduce/NestIntroduceActionPanel.vue` | 讲房弹出 UI 容器 |

### 11.3 讲房弹出面板

| 文件 | 说明 |
|------|------|
| `src/modules/pc/introduce/NestLectureBigMap.vue` | 讲房大地图（含周边配套 POI） |
| `src/modules/pc/introduce/NestLectureImgSwiper.vue` | 讲房图片轮播 |
| `src/modules/pc/introduce/NestLectureBigHangpai.vue` | 讲房航拍面板 |
| `src/modules/pc/introduce/NestLectureHouseInfo.vue` | 讲房房源信息 |

### 11.4 公共组件

| 文件 | 说明 |
|------|------|
| `src/components/common/pc/NestModalMap.vue` | 通用地图组件（支持 POI 标记、分类切换、步行路径） |
| `src/components/common/pc/NestModalImgSwiper.vue` | 通用图片轮播组件 |
| `src/components/common/pc/NestHouseInfo.vue` | 通用房源信息组件 |

### 11.5 布局入口

| 文件 | 说明 |
|------|------|
| `src/layouts/pc/PcHouseLayout.vue` | PC 端布局（讲房组件挂载点） |

## 十二、 离线数据包目录位置与资源替换

众趣推送的离线数据包中，会存在AI讲房相关资源内容，如讲房音频等资源。资源目录放置在 {{model_id}}/audio/目录下。

替换目录：
#### 模型版本目录
1. settings.txt （单个文件）
2. settings_local.txt （单个文件）

#### 模型id目录
1. audio （整个目录）


#### 截图示意
{{模型id}}/audio目录
![AI讲房音频文件在离线数据包位置](../../screenshot/introduce/AI讲房资源替换目录.png)

{{模型版本}}/setting.txt 和 setting_local.txt
![AI讲房离线数据包setting替换示意](../../screenshot/introduce/AI讲房离线数据包setting替换示意.png)
