- 将包名从 @fishdingding/bim-engine-sdk 改为 iflow-engine - 将构建输出文件从 bim-engine-sdk.*.js 改为 iflow-engine.*.js - 将全局变量从 LyzBimEngineSDK 改为 IflowEngine - 将第三方引擎SDK从本地引入改为npm包引入 (iflow-engine-base) - 移除本地 src/engine_base 目录,移至回收站 - 更新所有文档和demo中的引用
25 KiB
Dialog 组件详细文档
本文档详细描述 Dialog 组件的实现细节,包括 API、UI 结构、逻辑流程等,供 AI 根据文档重现组件。
1. 组件概述
1.1 基本信息
- 组件名称:
BimDialog - 文件路径:
src/components/dialog/index.ts - 类型定义:
src/components/dialog/index.type.ts - 样式文件:
src/components/dialog/index.css - 实现接口:
IBimComponent - 用途: 提供可拖拽、可缩放的通用弹窗组件,支持自定义内容和样式
1.2 在 SDK 中的位置
- Dialog 组件是独立的 UI 组件
- 必须通过
DialogManager使用,不允许直接使用 DialogManager位于src/managers/dialog-manager.ts
2. 组件类 API 文档
2.1 构造函数
constructor(options: DialogOptions)
参数:
options:DialogOptions- 弹窗配置选项(详见类型定义)
默认配置:
{
title: 'Dialog',
width: 300,
height: 'auto',
position: 'center',
draggable: true,
resizable: false,
minWidth: 200,
minHeight: 100
}
行为:
- 合并用户配置和默认配置
- 创建 DOM 结构
- 自动调用
init()方法
2.2 公共方法
init(): void
初始化组件功能(实现 IBimComponent 接口)
功能:
- 将弹窗元素添加到容器
- 初始化位置
- 如果
draggable为 true,初始化拖拽功能 - 如果
resizable为 true,初始化缩放功能 - 订阅主题和语言变更
- 调用
onOpen回调
调用时机: 构造函数中自动调用,也可手动调用
setTheme(theme: ThemeConfig): void
设置主题(实现 IBimComponent 接口)
参数:
theme:ThemeConfig- 全局主题配置
功能:
- 将主题颜色映射到 CSS 变量
- 如果用户未自定义颜色,使用主题颜色
- 如果用户已自定义颜色,保持用户自定义
CSS 变量映射:
--bim-dialog-bg←theme.panelBackground(如果未自定义backgroundColor)--bim-dialog-header-bg←theme.componentHover(如果未自定义headerBackgroundColor)--bim-dialog-title-color←theme.textPrimary(如果未自定义titleColor)--bim-dialog-text-color←theme.textPrimary(如果未自定义textColor)--bim-dialog-border-color←theme.border(如果未自定义borderColor)
setLocales(): void
设置语言(实现 IBimComponent 接口)
功能:
- 更新标题文本(如果标题是翻译键)
- 使用
t()函数获取翻译后的文本
行为:
- 查找
.bim-dialog-title元素 - 如果
options.title存在,使用t(options.title)更新文本
setContent(content: HTMLElement | string): void
动态设置弹窗内容
参数:
content:HTMLElement | string- 内容元素或 HTML 字符串
功能:
- 清空当前内容
- 设置新内容(支持 HTML 字符串或 DOM 元素)
fitHeight(recenter: boolean = false): void
根据内容自动调整弹窗高度
使用场景:
- 弹窗内容存在“展开/收起”等高度变化的交互(例如测量面板展开后需要增高弹窗,避免遮挡底部操作按钮)
参数:
recenter: 是否根据options.position重新计算定位(默认false)
行为:
- 先将高度设置为
auto,获取自然高度 - 再将高度夹紧到
[minHeight, containerHeight]范围内 - 默认不重置用户拖拽后的
left/top,仅做边界夹紧;若recenter=true则按position重新定位
close(): void
关闭弹窗并销毁
功能:
- 清理
requestAnimationFrame(如果存在) - 取消主题和语言订阅
- 从 DOM 中移除元素
- 标记为已销毁
- 调用
onClose回调
destroy(): void
销毁组件(实现 IBimComponent 接口)
功能:
- 调用
close()方法
2.3 私有方法(供理解实现细节)
createDom(): HTMLElement
创建弹窗的 DOM 结构
返回: 创建的弹窗根元素
DOM 结构:
<div class="bim-dialog" [id="..."]>
<div class="bim-dialog-header" [class="draggable"]>
<span class="bim-dialog-title">标题文本</span>
<span class="bim-dialog-close">×</span>
</div>
<div class="bim-dialog-content">
<!-- 用户内容 -->
</div>
[<div class="bim-dialog-resize-handle"></div>] <!-- 如果 resizable -->
</div>
关键实现:
- 创建根元素,应用 CSS 变量和尺寸
- 创建标题栏,包含标题和关闭按钮
- 创建内容区域,支持 HTML 字符串或 DOM 元素
- 如果
resizable为 true,创建缩放手柄 - 事件拦截: 绑定所有鼠标/触摸事件,使用
stopPropagation()阻止冒泡,防止传递给 3D 引擎
事件拦截列表:
['click', 'dblclick', 'contextmenu', 'wheel',
'mousedown', 'mouseup', 'mousemove',
'touchstart', 'touchend', 'touchmove',
'pointerdown', 'pointerup', 'pointermove',
'pointerenter', 'pointerleave', 'pointerover', 'pointerout']
initPosition(): void
初始化弹窗位置
功能:
- 根据
position选项计算弹窗位置 - 支持预设位置(如 'center', 'top-left' 等)或坐标对象
{ x, y } - 确保弹窗不超出容器边界
位置计算逻辑:
center:left = (containerWidth - dialogWidth) / 2,top = (containerHeight - dialogHeight) / 2top-left:left = 0,top = 0top-center:left = (containerWidth - dialogWidth) / 2,top = 0top-right:left = containerWidth - dialogWidth,top = 0left-center:left = 0,top = (containerHeight - dialogHeight) / 2right-center:left = containerWidth - dialogWidth,top = (containerHeight - dialogHeight) / 2bottom-left:left = 0,top = containerHeight - dialogHeightbottom-center:left = (containerWidth - dialogWidth) / 2,top = containerHeight - dialogHeightbottom-right:left = containerWidth - dialogWidth,top = containerHeight - dialogHeight{ x, y }: 直接使用坐标值
边界限制:
left = Math.max(0, Math.min(left, containerWidth - dialogWidth));
top = Math.max(0, Math.min(top, containerHeight - dialogHeight));
initDrag(): void
初始化拖拽功能
功能:
- 在标题栏上绑定
mousedown事件 - 实现拖拽移动功能
- 使用
requestAnimationFrame优化性能 - 使用
capture: true确保事件在捕获阶段处理
拖拽流程:
mousedown: 记录起始位置和弹窗当前位置,缓存容器和弹窗尺寸mousemove: 计算偏移量,更新弹窗位置,限制在容器边界内mouseup: 清理事件监听和动画帧
性能优化:
- 使用
requestAnimationFrame节流更新 - 缓存容器和弹窗尺寸,减少 reflow
- 使用
capture: true确保事件处理
initResize(): void
初始化缩放功能
功能:
- 在缩放手柄上绑定
mousedown事件 - 实现右下角拖拽缩放功能
- 使用
requestAnimationFrame优化性能 - 限制最小尺寸
缩放流程:
mousedown: 记录起始位置和弹窗当前尺寸mousemove: 计算偏移量,更新弹窗尺寸,限制最小尺寸mouseup: 清理事件监听和动画帧
尺寸限制:
newWidth = Math.max(minWidth || 100, startWidth + deltaX);
newHeight = Math.max(minHeight || 50, startHeight + deltaY);
3. 分化组件说明
3.1 BimInfoDialog
文件路径: src/components/dialog/bimInfoDialog/index.ts
继承关系: BimInfoDialog extends BimDialog
特殊功能:
- 预定义了信息展示的内容结构
- 包含标题、信息列表和操作按钮
- 使用固定的配置(宽度 320px,可缩放,可拖拽)
实现方式:
- 在构造函数中创建内容 DOM
- 调用父类构造函数,传入预定义的配置
- 不需要重写其他方法,直接继承父类功能
内容结构:
<div class="bim-info-dialog-content">
<h3>Model Information</h3>
<ul>
<li><strong>Name:</strong> Sample Project</li>
<li><strong>Version:</strong> 1.0.0</li>
<li><strong>Date:</strong> 当前日期</li>
<li><strong>Status:</strong> <span style="color: green;">Active</span></li>
</ul>
<button>Update Status</button>
</div>
与父类的差异:
- 固定了内容结构
- 固定了部分配置选项
- 其他功能完全继承自
BimDialog
4. Manager API 文档
4.1 DialogManager 类
文件路径: src/managers/dialog-manager.ts
继承关系: DialogManager extends BimComponent
4.2 构造函数
constructor(engine: BimEngine, container: HTMLElement)
参数:
engine:BimEngine- 引擎实例container:HTMLElement- 弹窗挂载的目标容器
行为:
- 保存容器引用
- 监听
ui:open-dialog事件 - 如果事件 payload.id 是 'info',自动打开信息弹窗
4.3 公共方法
create(options: Omit<DialogOptions, 'container'>): BimDialog
创建一个通用弹窗
参数:
options:Omit<DialogOptions, 'container'>- 弹窗配置(不需要传 container)
返回: BimDialog 实例
功能:
- 自动使用 Manager 绑定的容器
- 创建
BimDialog实例 - 应用当前主题
- 将弹窗添加到活跃列表
- 在
onClose回调中自动从列表移除
使用示例:
const dialog = engine.dialog.create({
title: '测试弹窗',
content: '这是内容',
width: 400,
height: 300
});
showInfoDialog(): void
显示二次封装的模型信息弹窗
功能:
- 创建
BimInfoDialog实例 - 直接显示信息弹窗
注意: 此方法创建的弹窗不会自动加入管理列表(遗留逻辑)
updateTheme(theme: ThemeConfig): void
响应全局主题变更
参数:
theme:ThemeConfig- 全局主题配置
功能:
- 遍历所有活跃弹窗
- 调用每个弹窗的
setTheme()方法
destroy(): void
销毁管理器
功能:
- 销毁所有活跃弹窗
- 清空活跃列表
5. UI 详细描述
5.1 DOM 结构
完整 HTML 结构:
<div class="bim-dialog" id="[可选ID]" style="[CSS变量和尺寸]">
<!-- 标题栏 -->
<div class="bim-dialog-header [draggable]">
<span class="bim-dialog-title">标题文本</span>
<span class="bim-dialog-close">×</span>
</div>
<!-- 内容区域 -->
<div class="bim-dialog-content">
<!-- 用户内容(HTML字符串或DOM元素) -->
</div>
<!-- 缩放手柄(如果 resizable) -->
<div class="bim-dialog-resize-handle"></div>
</div>
5.2 CSS 类名和样式
.bim-dialog (根元素)
position: absolute- 绝对定位background-color: var(--bim-dialog-bg)- 背景色(CSS 变量)border: 1px solid var(--bim-dialog-border-color)- 边框border-radius: 6px- 圆角box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3)- 阴影display: flex+flex-direction: column- 垂直布局z-index: 10001- 层级(确保在 3D 引擎之上)min-width: 200px- 最小宽度min-height: 100px- 最小高度pointer-events: auto- 确保可接收事件
.bim-dialog-header (标题栏)
height: 32px- 固定高度background-color: var(--bim-dialog-header-bg)- 背景色display: flex+align-items: center+justify-content: space-between- 水平布局padding: 0 10px- 内边距cursor: default- 默认光标user-select: none- 禁止选中border-bottom: 1px solid var(--bim-dialog-border-color)- 底边框
.bim-dialog-header.draggable (可拖拽标题栏)
cursor: move- 移动光标
.bim-dialog-title (标题文本)
font-size: 14px- 字体大小font-weight: 500- 字体粗细white-space: nowrap- 不换行overflow: hidden- 隐藏溢出text-overflow: ellipsis- 文本省略color: var(--bim-dialog-title-color)- 文字颜色
.bim-dialog-close (关闭按钮)
cursor: pointer- 指针光标font-size: 18px- 字体大小color: #999- 默认颜色line-height: 1- 行高margin-left: 8px- 左边距
.bim-dialog-close:hover (关闭按钮悬停)
color: #fff- 悬停颜色
.bim-dialog-content (内容区域)
flex: 1- 占据剩余空间padding: 10px- 内边距overflow: auto- 内容溢出时滚动font-size: 14px- 字体大小color: var(--bim-dialog-text-color)- 文字颜色
.bim-dialog-resize-handle (缩放手柄)
position: absolute- 绝对定位width: 10px+height: 10px- 尺寸bottom: 0+right: 0- 右下角位置cursor: se-resize- 缩放光标z-index: 10- 层级
.bim-dialog-resize-handle::after (缩放装饰)
- 使用伪元素创建右下角斜线装饰
border-right+border-bottom- 创建斜线效果
5.3 CSS 变量
定义位置: :root 或元素内联样式
变量列表:
--bim-dialog-bg: 窗体背景颜色(默认rgba(17, 17, 17, 0.95))--bim-dialog-header-bg: 标题栏背景颜色(默认#2a2a2a)--bim-dialog-title-color: 标题文字颜色(默认#fff)--bim-dialog-text-color: 内容文字颜色(默认#ccc)--bim-dialog-border-color: 边框颜色(默认#444)
5.4 交互行为
拖拽
- 触发区域: 标题栏(
.bim-dialog-header) - 触发条件:
draggable: true - 行为:
- 鼠标按下标题栏时开始拖拽
- 鼠标移动时弹窗跟随移动
- 鼠标释放时结束拖拽
- 弹窗位置限制在容器边界内
缩放
- 触发区域: 缩放手柄(
.bim-dialog-resize-handle) - 触发条件:
resizable: true - 行为:
- 鼠标按下缩放手柄时开始缩放
- 鼠标移动时弹窗尺寸跟随变化
- 鼠标释放时结束缩放
- 尺寸限制在最小尺寸以上
关闭
- 触发方式:
- 点击关闭按钮(
.bim-dialog-close) - 调用
close()方法
- 点击关闭按钮(
- 行为: 弹窗从 DOM 移除,调用
onClose回调
5.5 响应式行为
- 弹窗位置会根据容器尺寸自动调整,确保不超出边界
- 内容区域支持滚动(
overflow: auto) - 标题文本过长时显示省略号(
text-overflow: ellipsis)
6. 逻辑流程详细描述
6.1 初始化流程
-
构造函数调用:
- 合并配置选项(用户配置 + 默认配置)
- 调用
createDom()创建 DOM 结构 - 保存 header 和 contentArea 引用
- 自动调用
init()
-
init() 方法执行:
- 检查是否已初始化,如果是则返回
- 将弹窗元素添加到容器
- 调用
initPosition()计算并设置位置 - 如果
draggable为 true,调用initDrag() - 如果
resizable为 true,调用initResize() - 标记为已初始化
- 调用
onOpen回调(如果存在) - 订阅主题变更:
themeManager.subscribe() - 订阅语言变更:
localeManager.subscribe()
6.2 生命周期
创建阶段
- 构造函数 →
createDom()→init()
运行阶段
- 响应主题变更:
setTheme()被调用 - 响应语言变更:
setLocales()被调用 - 用户交互:拖拽、缩放、关闭
销毁阶段
close()或destroy()被调用- 清理
requestAnimationFrame - 取消主题和语言订阅
- 从 DOM 移除元素
- 调用
onClose回调
6.3 事件处理流程
拖拽事件流程
- 用户在标题栏按下鼠标 →
mousedown事件 - 记录起始位置和弹窗当前位置
- 缓存容器和弹窗尺寸
- 在 document 上绑定
mousemove和mouseup(捕获阶段) - 鼠标移动时 →
mousemove事件- 计算偏移量
- 使用
requestAnimationFrame更新位置 - 限制在容器边界内
- 鼠标释放时 →
mouseup事件- 清理事件监听
- 清理动画帧
缩放事件流程
- 用户在缩放手柄按下鼠标 →
mousedown事件 - 记录起始位置和弹窗当前尺寸
- 在 document 上绑定
mousemove和mouseup(捕获阶段) - 鼠标移动时 →
mousemove事件- 计算偏移量
- 使用
requestAnimationFrame更新尺寸 - 限制在最小尺寸以上
- 鼠标释放时 →
mouseup事件- 清理事件监听
- 清理动画帧
事件拦截流程
- 弹窗根元素上绑定所有鼠标/触摸事件
- 使用
stopPropagation()阻止事件冒泡 - 防止事件传递给 3D 引擎
- 使用
passive: false允许阻止默认行为
6.4 状态管理
内部状态
_isInitialized: 是否已初始化_isDestroyed: 是否已销毁rafId:requestAnimationFrame的 ID(用于节流)
订阅管理
unsubscribeTheme: 主题订阅取消函数unsubscribeLocale: 语言订阅取消函数
6.5 与其他组件的交互
- 与 DialogManager: 通过 Manager 创建和管理
- 与 ThemeManager: 订阅主题变更
- 与 LocaleManager: 订阅语言变更
- 与 3D 引擎: 通过事件拦截防止交互冲突
7. 国际化支持
7.1 使用的翻译键
options.title: 弹窗标题(如果提供,会通过t()函数翻译)
7.2 语言变更处理
- 组件订阅
localeManager.subscribe() - 语言变更时,
setLocales()方法被调用 - 更新标题文本:
titleEl.textContent = t(this.options.title)
7.3 实现细节
public setLocales(): void {
if (this.options.title) {
const titleEl = this.header.querySelector('.bim-dialog-title');
if (titleEl) {
titleEl.textContent = t(this.options.title);
}
}
}
8. 主题支持
8.1 使用的主题变量
theme.panelBackground→--bim-dialog-bgtheme.componentHover→--bim-dialog-header-bgtheme.textPrimary→--bim-dialog-title-color和--bim-dialog-text-colortheme.border→--bim-dialog-border-color
8.2 主题变更处理
- 组件订阅
themeManager.subscribe() - 主题变更时,
setTheme()方法被调用 - 如果用户未自定义颜色,使用主题颜色
- 如果用户已自定义颜色,保持用户自定义
8.3 实现细节
public setTheme(theme: ThemeConfig) {
const style = this.element.style;
if (!this.options.backgroundColor)
style.setProperty('--bim-dialog-bg', theme.panelBackground);
if (!this.options.headerBackgroundColor)
style.setProperty('--bim-dialog-header-bg', theme.componentHover);
// ... 其他颜色映射
}
9. 使用示例
9.1 基本使用(通过 Manager)
import { BimEngine } from 'iflow-engine';
const engine = new BimEngine('container');
// 创建简单弹窗
const dialog = engine.dialog.create({
title: 'dialog.testTitle', // 使用翻译键
content: '这是内容',
width: 400,
height: 300
});
// 创建可缩放弹窗
const resizableDialog = engine.dialog.create({
title: '可缩放弹窗',
content: '<div>内容</div>',
width: 500,
height: 400,
resizable: true,
draggable: true
});
// 创建自定义位置弹窗
const positionedDialog = engine.dialog.create({
title: '自定义位置',
content: '内容',
position: { x: 100, y: 100 },
width: 300,
height: 200
});
9.2 高级使用
// 创建带自定义样式的弹窗
const styledDialog = engine.dialog.create({
title: '自定义样式',
content: '<div>内容</div>',
backgroundColor: 'rgba(100, 0, 0, 0.95)',
headerBackgroundColor: '#cc0000',
titleColor: '#ffffff',
textColor: '#ffcccc',
borderColor: '#ff6666',
width: 300,
height: 200
});
// 创建带回调的弹窗
const callbackDialog = engine.dialog.create({
title: '带回调',
content: '内容',
onOpen: () => {
console.log('弹窗已打开');
},
onClose: () => {
console.log('弹窗已关闭');
}
});
// 动态更新内容
const dynamicDialog = engine.dialog.create({
title: '动态内容',
content: '初始内容'
});
// 稍后更新内容
dynamicDialog.setContent('<div>新内容</div>');
9.3 使用信息弹窗
// 通过 Manager 显示信息弹窗
engine.dialog.showInfoDialog();
// 通过事件总线打开(如果配置了监听)
engine.emit('ui:open-dialog', { id: 'info' });
10. 实现细节(供 AI 重现)
10.1 关键算法
位置计算算法
// 计算居中位置
function calculateCenterPosition(containerWidth, containerHeight, dialogWidth, dialogHeight) {
return {
left: (containerWidth - dialogWidth) / 2,
top: (containerHeight - dialogHeight) / 2
};
}
// 边界限制算法
function clampPosition(left, top, containerWidth, containerHeight, dialogWidth, dialogHeight) {
return {
left: Math.max(0, Math.min(left, containerWidth - dialogWidth)),
top: Math.max(0, Math.min(top, containerHeight - dialogHeight))
};
}
拖拽算法
// 拖拽位置更新
function updateDragPosition(startX, startY, currentX, currentY, startLeft, startTop) {
const deltaX = currentX - startX;
const deltaY = currentY - startY;
return {
left: startLeft + deltaX,
top: startTop + deltaY
};
}
缩放算法
// 缩放尺寸更新
function updateResizeSize(startX, startY, currentX, currentY, startWidth, startHeight, minWidth, minHeight) {
const deltaX = currentX - startX;
const deltaY = currentY - startY;
return {
width: Math.max(minWidth, startWidth + deltaX),
height: Math.max(minHeight, startHeight + deltaY)
};
}
10.2 性能优化点
-
requestAnimationFrame 节流:
- 拖拽和缩放使用
requestAnimationFrame节流更新 - 避免频繁的 DOM 操作
- 拖拽和缩放使用
-
尺寸缓存:
- 拖拽开始时缓存容器和弹窗尺寸
- 减少
getBoundingClientRect()调用
-
事件捕获:
- 使用
capture: true确保事件在捕获阶段处理 - 即使内部元素阻止冒泡,也能捕获事件
- 使用
-
CSS 变量:
- 使用 CSS 变量应用主题
- 主题变更时无需重新渲染 DOM
10.3 注意事项和边界情况
-
容器尺寸为 0:
- 位置计算时可能出现除零或负数
- 使用
Math.max()确保位置不为负
-
弹窗尺寸大于容器:
- 位置计算时确保弹窗不超出容器
- 使用边界限制算法
-
快速连续操作:
- 使用
rafId防止多个动画帧同时执行 - 确保动画帧正确清理
- 使用
-
事件清理:
- 组件销毁时必须清理所有事件监听
- 必须取消主题和语言订阅
-
事件拦截:
- 必须拦截所有鼠标/触摸事件
- 防止事件传递给 3D 引擎
-
翻译键处理:
- 标题可能是翻译键或普通文本
- 只有翻译键才需要通过
t()函数处理
11. 类型定义
11.1 DialogOptions
interface DialogOptions extends DialogColors {
container: HTMLElement; // 弹窗挂载的父容器(必需)
title?: string; // 弹窗标题(可选,支持翻译键)
content?: HTMLElement | string; // 弹窗内容(可选)
width?: number | string; // 宽度(可选,默认 300)
height?: number | string; // 高度(可选,默认 'auto')
position?: DialogPosition; // 位置(可选,默认 'center')
draggable?: boolean; // 是否可拖拽(可选,默认 true)
resizable?: boolean; // 是否可缩放(可选,默认 false)
minWidth?: number; // 最小宽度(可选,默认 200)
minHeight?: number; // 最小高度(可选,默认 100)
onClose?: () => void; // 关闭回调(可选)
onOpen?: () => void; // 打开回调(可选)
id?: string; // 弹窗 ID(可选)
}
11.2 DialogPosition
type DialogPosition =
| 'center'
| 'top-left' | 'top-center' | 'top-right'
| 'left-center' | 'right-center'
| 'bottom-left' | 'bottom-center' | 'bottom-right'
| { x: number; y: number };
11.3 DialogColors
interface DialogColors {
backgroundColor?: string; // 窗体背景颜色
headerBackgroundColor?: string; // 标题栏背景颜色
titleColor?: string; // 标题文字颜色
textColor?: string; // 内容文字颜色
borderColor?: string; // 边框颜色
}
12. 文件清单
12.1 相关文件
src/components/dialog/index.ts- 主组件类src/components/dialog/index.type.ts- 类型定义src/components/dialog/index.css- 样式文件src/components/dialog/bimInfoDialog/index.ts- 信息弹窗(分化组件)src/components/dialog/bimInfoDialog/index.css- 信息弹窗样式src/managers/dialog-manager.ts- 管理器类
12.2 依赖文件
src/types/component.ts- IBimComponent 接口src/themes/types.ts- ThemeConfig 类型src/services/theme.ts- ThemeManagersrc/services/locale.ts- LocaleManager
13. 更新记录
| 日期 | 修改内容 | 修改人 |
|---|---|---|
| 2024-XX-XX | 初始创建 | AI Assistant |
重要提醒: 本文档必须与组件代码保持同步。任何组件修改都必须更新本文档!