@blueking/chat-x 0.0.51-beta.5 → 0.0.52-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -8
- package/dist/ag-ui/types/contents.d.ts +2 -0
- package/dist/ag-ui/types/messages.d.ts +6 -1
- package/dist/common/constants.d.ts +2 -0
- package/dist/components/ai-buttons/add-menu-btn/add-menu-btn.vue.d.ts +24 -0
- package/dist/components/chat-content/collapsible-content/collapsible-content.vue.d.ts +28 -0
- package/dist/components/chat-content/file-content/upload-file-item.vue.d.ts +5 -2
- package/dist/components/chat-content/file-content/upload-image-item.vue.d.ts +1 -0
- package/dist/components/chat-content/flow-agent-content/use-flow-node-actions.d.ts +1 -1
- package/dist/components/chat-input/ai-slash-input/ai-slash-input.vue.d.ts +21 -10
- package/dist/components/chat-input/ai-slash-input/command.d.ts +6 -3
- package/dist/components/chat-input/ai-slash-input/constants.d.ts +2 -0
- package/dist/components/chat-input/ai-slash-input/use-menu-trigger.d.ts +17 -0
- package/dist/components/chat-input/build-default-placeholder.d.ts +9 -3
- package/dist/components/chat-input/chat-input.vue.d.ts +30 -18
- package/dist/components/chat-input/input-menu/constants.d.ts +60 -0
- package/dist/components/chat-input/input-menu/index.d.ts +4 -0
- package/dist/components/chat-input/input-menu/input-menu-option.vue.d.ts +14 -0
- package/dist/components/chat-input/input-menu/input-menu-panel.vue.d.ts +17 -0
- package/dist/components/chat-input/input-menu/use-input-menu.d.ts +22 -0
- package/dist/components/chat-input/model-selector/types.d.ts +3 -2
- package/dist/components/chat-message/message-container/message-container.vue.d.ts +1 -1
- package/dist/components/chat-message/user-message/user-message.vue.d.ts +1 -1
- package/dist/components/mention/create-mention-tippy.d.ts +27 -0
- package/dist/components/mention/index.d.ts +4 -0
- package/dist/components/{chat-input/ai-slash-input/ai-prompt-list/ai-prompt-list.vue.d.ts → mention/mention-popover.vue.d.ts} +3 -2
- package/dist/components/{chat-input/ai-slash-input/ai-skill-list/ai-skill-list.vue.d.ts → mention/mention-tag.vue.d.ts} +7 -3
- package/dist/components/{chat-input/ai-slash-input/ai-slash-menu/ai-slash-menu.vue.d.ts → mention/mention-text.vue.d.ts} +3 -3
- package/dist/components/resource-icon/index.d.ts +1 -0
- package/dist/components/resource-icon/resource-icon.vue.d.ts +11 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/use-artifact-preview.d.ts +5 -2
- package/dist/composables/use-common.d.ts +0 -9
- package/dist/composables/use-global-config.d.ts +4 -0
- package/dist/composables/use-input-mention.d.ts +13 -0
- package/dist/composables/use-message-group.d.ts +1011 -72
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/input.d.ts +21 -0
- package/dist/icons/menu-item.d.ts +22 -0
- package/dist/index.css +1 -1
- package/dist/index.js +4953 -4429
- package/dist/index.js.map +1 -1
- package/dist/lang/lang.d.ts +13 -3
- package/dist/mcp/generated/docs/activity-message.md +3 -3
- package/dist/mcp/generated/docs/add-menu-btn.md +91 -0
- package/dist/mcp/generated/docs/ai-slash-input.md +72 -26
- package/dist/mcp/generated/docs/assistant-message.md +7 -1
- package/dist/mcp/generated/docs/chat-container.md +45 -6
- package/dist/mcp/generated/docs/chat-input.md +327 -483
- package/dist/mcp/generated/docs/collapsible-content.md +78 -0
- package/dist/mcp/generated/docs/constants.md +36 -3
- package/dist/mcp/generated/docs/execution-summary.md +1 -23
- package/dist/mcp/generated/docs/file-artifact-panel.md +24 -5
- package/dist/mcp/generated/docs/file-content.md +4 -0
- package/dist/mcp/generated/docs/file-upload-btn.md +15 -12
- package/dist/mcp/generated/docs/flow-agent-content.md +10 -12
- package/dist/mcp/generated/docs/input-menu-panel.md +166 -0
- package/dist/mcp/generated/docs/mention-tag.md +83 -0
- package/dist/mcp/generated/docs/mention-text.md +86 -0
- package/dist/mcp/generated/docs/message-container.md +1 -1
- package/dist/mcp/generated/docs/message-render.md +1 -1
- package/dist/mcp/generated/docs/message-tools.md +15 -4
- package/dist/mcp/generated/docs/messages.md +3 -0
- package/dist/mcp/generated/docs/model-selector.md +4 -2
- package/dist/mcp/generated/docs/overflow-tips.md +3 -3
- package/dist/mcp/generated/docs/resource-icon.md +102 -0
- package/dist/mcp/generated/docs/text-content.md +7 -3
- package/dist/mcp/generated/docs/theme.md +27 -35
- package/dist/mcp/generated/docs/use-artifact-preview.md +7 -3
- package/dist/mcp/generated/docs/use-command-selection.md +1 -1
- package/dist/mcp/generated/docs/use-container-scroll.md +2 -1
- package/dist/mcp/generated/docs/use-flow-node-actions.md +8 -15
- package/dist/mcp/generated/docs/use-global-config.md +11 -4
- package/dist/mcp/generated/docs/use-input-mention.md +119 -0
- package/dist/mcp/generated/docs/use-menu-keydown.md +15 -16
- package/dist/mcp/generated/docs/use-message-group.md +3 -6
- package/dist/mcp/generated/docs/user-message.md +39 -17
- package/dist/mcp/generated/index.json +233 -81
- package/dist/types/editor.d.ts +0 -29
- package/dist/types/index.d.ts +1 -0
- package/dist/types/input-menu.d.ts +46 -0
- package/dist/utils/artifact-tags.d.ts +36 -0
- package/dist/utils/collect-message-artifacts.d.ts +14 -0
- package/dist/utils/file.d.ts +3 -3
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/upload-file.d.ts +6 -1
- package/package.json +3 -2
- package/skills/blueking-chat-x/SKILL.md +143 -0
- package/skills/blueking-chat-x/references/_index.md +153 -0
- package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
- package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
- package/skills/blueking-chat-x/references/components/add-menu-btn.md +88 -0
- package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
- package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
- package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
- package/skills/blueking-chat-x/references/components/ai-slash-input.md +102 -0
- package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
- package/skills/blueking-chat-x/references/components/assistant-message.md +504 -0
- package/skills/blueking-chat-x/references/components/chat-container.md +912 -0
- package/skills/blueking-chat-x/references/components/chat-input.md +614 -0
- package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
- package/skills/blueking-chat-x/references/components/code-content.md +211 -0
- package/skills/blueking-chat-x/references/components/collapsible-content.md +76 -0
- package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
- package/skills/blueking-chat-x/references/components/content-render.md +233 -0
- package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
- package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
- package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
- package/skills/blueking-chat-x/references/components/execution-summary.md +150 -0
- package/skills/blueking-chat-x/references/components/file-artifact-panel.md +307 -0
- package/skills/blueking-chat-x/references/components/file-content.md +340 -0
- package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
- package/skills/blueking-chat-x/references/components/file-upload-btn.md +162 -0
- package/skills/blueking-chat-x/references/components/flow-agent-content.md +266 -0
- package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
- package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
- package/skills/blueking-chat-x/references/components/image-content.md +182 -0
- package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
- package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
- package/skills/blueking-chat-x/references/components/info-message.md +144 -0
- package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
- package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
- package/skills/blueking-chat-x/references/components/input-menu-panel.md +162 -0
- package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
- package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
- package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
- package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
- package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
- package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
- package/skills/blueking-chat-x/references/components/mention-tag.md +79 -0
- package/skills/blueking-chat-x/references/components/mention-text.md +83 -0
- package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
- package/skills/blueking-chat-x/references/components/message-container.md +645 -0
- package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
- package/skills/blueking-chat-x/references/components/message-render.md +327 -0
- package/skills/blueking-chat-x/references/components/message-time.md +177 -0
- package/skills/blueking-chat-x/references/components/message-tools.md +427 -0
- package/skills/blueking-chat-x/references/components/model-selector.md +157 -0
- package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
- package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
- package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
- package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
- package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
- package/skills/blueking-chat-x/references/components/resource-icon.md +98 -0
- package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
- package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
- package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
- package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
- package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
- package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
- package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
- package/skills/blueking-chat-x/references/components/text-content.md +80 -0
- package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
- package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
- package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
- package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
- package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
- package/skills/blueking-chat-x/references/components/user-message.md +444 -0
- package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
- package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
- package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
- package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
- package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
- package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
- package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +235 -0
- package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
- package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
- package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
- package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
- package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +164 -0
- package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
- package/skills/blueking-chat-x/references/composables/use-global-config.md +155 -0
- package/skills/blueking-chat-x/references/composables/use-input-mention.md +115 -0
- package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +161 -0
- package/skills/blueking-chat-x/references/composables/use-message-group.md +244 -0
- package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
- package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
- package/skills/blueking-chat-x/references/directives/index.md +61 -0
- package/skills/blueking-chat-x/references/directives/overflow-tips.md +205 -0
- package/skills/blueking-chat-x/references/icons/index.md +185 -0
- package/skills/blueking-chat-x/references/plugins/index.md +56 -0
- package/skills/blueking-chat-x/references/plugins/markdown-container.md +55 -0
- package/skills/blueking-chat-x/references/plugins/markdown-latex.md +205 -0
- package/skills/blueking-chat-x/references/plugins/markdown-mermaid.md +247 -0
- package/skills/blueking-chat-x/references/theme/theme.md +423 -0
- package/skills/blueking-chat-x/references/types/constants.md +340 -0
- package/skills/blueking-chat-x/references/types/index.md +120 -0
- package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
- package/skills/blueking-chat-x/references/types/messages.md +556 -0
- package/skills/blueking-chat-x/references/types/schema.md +91 -0
- package/skills/blueking-chat-x/references/utils/index.md +196 -0
- package/skills/blueking-chat-x/scripts/generate-references.mjs +536 -0
- package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +0 -28
- package/dist/components/chat-input/ai-slash-editor/theme.d.ts +0 -24
- package/dist/mcp/generated/docs/ai-prompt-list.md +0 -45
- package/dist/mcp/generated/docs/ai-skill-list.md +0 -75
- package/dist/mcp/generated/docs/ai-slash-editor.md +0 -43
- package/dist/mcp/generated/docs/ai-slash-menu.md +0 -42
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# ImageContent 图片内容
|
|
2
|
+
|
|
3
|
+
> 能力域:媒体文件 | 导入:`import { ImageContent } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
渲染 Markdown 图片 token。 源码位置:src/components/markdown-token/image-content/image-content.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:markdown-content(解析图片 token 后挂载本组件)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ImageContent 图片渲染
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/markdown-token/image-content/image-content.vue`
|
|
15
|
+
- **能力域**:媒体文件
|
|
16
|
+
- **能力说明**:渲染 Markdown 图片 token。
|
|
17
|
+
|
|
18
|
+
> **能力域**:媒体文件
|
|
19
|
+
|
|
20
|
+
Markdown Token 层的图片渲染基础组件,被 `MarkdownContent` 在解析到图片 token 时自动调用,通常无需手动引入。
|
|
21
|
+
|
|
22
|
+
核心能力:**流式 URL 防闪烁**(debounce 稳定判断 + throttle 预加载)、**全局缓存**(模块级 `Set` 跨实例共享)、**三态渲染**(加载中 / 成功 / 失败)。
|
|
23
|
+
|
|
24
|
+
## 组件结构
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
span.ai-md-image-wrapper(inline-block,vertical-align: middle)
|
|
28
|
+
├── [showLoading] span.md-image-loading(inline-flex,gap: 6px,padding: 4px 8px,bg: #f5f7fa)
|
|
29
|
+
│ ├── bkui-vue Loading(spin,mini,primary)
|
|
30
|
+
│ └── "图片加载中..."
|
|
31
|
+
├── [showError] span.md-image-error(同上,color: #ea3636,bg: #fee)
|
|
32
|
+
│ ├── span.md-image-error-icon → ⚠️(font-size: 14px)
|
|
33
|
+
│ └── span.md-image-error-text → alt || "图片加载失败"
|
|
34
|
+
└── [else] img.md-image(max-width: 100%,height: auto,loading="lazy")
|
|
35
|
+
:src="src" :alt="alt"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> **错误文本**:优先显示 `alt`,未传 `alt` 时才显示 "图片加载失败"。
|
|
39
|
+
|
|
40
|
+
## 状态机
|
|
41
|
+
|
|
42
|
+
组件内部维护三个 `shallowRef`:`isLoading`、`hasError`、`isUrlStable`,以及两个 computed 控制显示:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
showLoading 为 true 的条件(按优先级):
|
|
46
|
+
1. isCached(全局缓存命中)→ false,直接显示图片
|
|
47
|
+
2. !isValidUrl → true(URL 无效或正在输入中)
|
|
48
|
+
3. isLoading → true(正在预加载)
|
|
49
|
+
4. !isUrlStable && hasError → true(URL 仍在变化,忽略旧错误)
|
|
50
|
+
|
|
51
|
+
showError 为 true 的条件(需全部满足):
|
|
52
|
+
isUrlStable && hasError && !isLoading
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### URL 有效性(isValidUrl)
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
src 被判定为无效的情况(显示 Loading):
|
|
59
|
+
· 空字符串 / '#' / '#)'
|
|
60
|
+
· 以 '#' 或 '#)' 结尾(Markdown 语法补全占位符)
|
|
61
|
+
· 无协议且不是相对路径/带图片扩展名的路径
|
|
62
|
+
· https?:// 开头但域名中无 '.' 且不是 localhost
|
|
63
|
+
|
|
64
|
+
合法 URL 格式:
|
|
65
|
+
· https?://、// → 协议 URL(域名需含 '.' 或为 localhost)
|
|
66
|
+
· data:、blob: → Data URL / Blob URL
|
|
67
|
+
· /path 或 ./path → 绝对/相对路径
|
|
68
|
+
· image.png、a.jpg?v=1 → 带图片扩展名的文件名
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 流式防抖与节流
|
|
72
|
+
|
|
73
|
+
| 机制 | 参数 | 作用 |
|
|
74
|
+
| --------------------------- | ------------------------- | ---------------------------------------------------------------- |
|
|
75
|
+
| `markUrlStable`(debounce) | 500ms | URL 停止变化 500ms 后置 `isUrlStable = true`,此后才允许显示错误 |
|
|
76
|
+
| `preloadImage`(throttle) | 100ms,leading + trailing | 限制 `new Image()` 预加载频率,流式输入时不会每个字符都发请求 |
|
|
77
|
+
|
|
78
|
+
### 全局缓存
|
|
79
|
+
|
|
80
|
+
`loadedImageCache` 是**模块级 `Set<string>`**,所有 `ImageContent` 实例共享:
|
|
81
|
+
|
|
82
|
+
- 图片加载成功后 → `loadedImageCache.add(url)`
|
|
83
|
+
- 组件初始化时若命中缓存 → `isLoading = false`,`isUrlStable = true`,跳过所有预加载逻辑,直接渲染 `<img>`
|
|
84
|
+
- 页面刷新后缓存清空(仅内存缓存)
|
|
85
|
+
|
|
86
|
+
## 基础用法
|
|
87
|
+
|
|
88
|
+
```vue
|
|
89
|
+
<template>
|
|
90
|
+
<ImageContent
|
|
91
|
+
src="https://picsum.photos/seed/demo/400/200"
|
|
92
|
+
alt="示例图片"
|
|
93
|
+
/>
|
|
94
|
+
</template>
|
|
95
|
+
|
|
96
|
+
<script setup lang="ts">
|
|
97
|
+
import { ImageContent } from '@blueking/chat-x';
|
|
98
|
+
</script>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 加载失败
|
|
102
|
+
|
|
103
|
+
URL 稳定后(500ms 无变化)加载失败,显示 `⚠️ + alt文本`(无 alt 时显示"图片加载失败"):
|
|
104
|
+
|
|
105
|
+
## Data URL
|
|
106
|
+
|
|
107
|
+
支持 Base64 / SVG Data URL,不经过 `isValidUrl` 的网络检测,直接进入预加载:
|
|
108
|
+
|
|
109
|
+
```vue
|
|
110
|
+
<template>
|
|
111
|
+
<ImageContent
|
|
112
|
+
src="data:image/svg+xml,..."
|
|
113
|
+
alt="内联 SVG"
|
|
114
|
+
/>
|
|
115
|
+
</template>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 流式输入防闪烁
|
|
119
|
+
|
|
120
|
+
流式 Markdown 渲染时 URL 逐字符拼接,组件通过 debounce + throttle 避免频繁请求和闪烁:
|
|
121
|
+
|
|
122
|
+
```vue
|
|
123
|
+
<template>
|
|
124
|
+
<button
|
|
125
|
+
@click="simulateStreaming"
|
|
126
|
+
:disabled="isStreaming"
|
|
127
|
+
>
|
|
128
|
+
{{ isStreaming ? '输入中...' : '模拟流式输入' }}
|
|
129
|
+
</button>
|
|
130
|
+
<ImageContent
|
|
131
|
+
:src="streamingUrl"
|
|
132
|
+
alt="流式图片"
|
|
133
|
+
/>
|
|
134
|
+
</template>
|
|
135
|
+
|
|
136
|
+
<script setup lang="ts">
|
|
137
|
+
import { ref } from 'vue';
|
|
138
|
+
import { ImageContent } from '@blueking/chat-x';
|
|
139
|
+
|
|
140
|
+
const streamingUrl = ref('');
|
|
141
|
+
const isStreaming = ref(false);
|
|
142
|
+
|
|
143
|
+
const simulateStreaming = async () => {
|
|
144
|
+
const url = 'https://picsum.photos/seed/chat-x-stream/400/200';
|
|
145
|
+
streamingUrl.value = '';
|
|
146
|
+
isStreaming.value = true;
|
|
147
|
+
for (let i = 0; i <= url.length; i++) {
|
|
148
|
+
await new Promise(r => setTimeout(r, 60));
|
|
149
|
+
streamingUrl.value = url.slice(0, i);
|
|
150
|
+
}
|
|
151
|
+
isStreaming.value = false;
|
|
152
|
+
};
|
|
153
|
+
</script>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**流式过程中的状态变化**:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
URL = '' → isValidUrl=false → showLoading=true(Loading)
|
|
160
|
+
URL = 'https://' → isValidUrl=false → showLoading=true(域名不完整)
|
|
161
|
+
URL = 'https://p…' → isValidUrl=false → showLoading=true(域名无 '.')
|
|
162
|
+
URL = 完整 URL → isValidUrl=true → throttle 触发 preloadImage
|
|
163
|
+
debounce 500ms → isUrlStable=true
|
|
164
|
+
onload → cache → showLoading=false → 显示图片
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## API
|
|
168
|
+
|
|
169
|
+
### Props
|
|
170
|
+
|
|
171
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
172
|
+
| ------ | -------- | ---- | ---------------------------------------------------------------------------- |
|
|
173
|
+
| src | `string` | ✓ | 图片 URL,支持 https / http / // / data: / blob: / 相对路径 / 带扩展名文件名 |
|
|
174
|
+
| alt | `string` | — | 替代文本;加载失败时优先显示此文本,未传时显示"图片加载失败" |
|
|
175
|
+
|
|
176
|
+
## 使用场景
|
|
177
|
+
|
|
178
|
+
`ImageContent` 由 `MarkdownContent` 在渲染 `image` token 时自动调用,通常不需要手动引入。如需在 Markdown 以外的场景渲染带流式防抖保护的图片,可单独使用。
|
|
179
|
+
|
|
180
|
+
## 关联组件
|
|
181
|
+
|
|
182
|
+
- [MarkdownContent](/components/rendering/markdown-content) — 图片 token 渲染入口
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# ImagePreviewGroup 图片预览组
|
|
2
|
+
|
|
3
|
+
> 能力域:媒体文件 | 导入:`import { ImagePreviewGroup } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
通过 provide/inject 管理同组图片预览。 源码位置:src/components/image-preview/image-preview-group.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:ai-image(子级注册并参与多图预览集合)、image-preview(内置实例承载多图切换与工具栏)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ImagePreviewGroup 图片预览组
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/image-preview/image-preview-group.vue`
|
|
15
|
+
- **能力域**:媒体文件
|
|
16
|
+
- **能力说明**:通过 provide/inject 管理同组图片预览。
|
|
17
|
+
|
|
18
|
+
> **能力域**:媒体文件
|
|
19
|
+
|
|
20
|
+
多图预览管理容器。通过 `provide/inject` + `Map<symbol>` 模式管理子级 `AiImage` 的注册与预览状态,点击任意子图片时自动收集所有已注册图片并打开多图预览。
|
|
21
|
+
|
|
22
|
+
## 组件结构
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
.ai-image-preview-group
|
|
26
|
+
├── <slot />(放置多个 AiImage)
|
|
27
|
+
└── ImagePreview(内置,按需显示)
|
|
28
|
+
v-model:visible="previewVisible"
|
|
29
|
+
v-model:current="activeIndex"
|
|
30
|
+
:images="previewImages"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 工作原理
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
┌─ ImagePreviewGroup ──────────────────────────────────────┐
|
|
37
|
+
│ provide(IMAGE_PREVIEW_GROUP_KEY, { register, unregister, preview }) │
|
|
38
|
+
│ │
|
|
39
|
+
│ ┌─ AiImage ─┐ ┌─ AiImage ─┐ ┌─ AiImage ─┐ │
|
|
40
|
+
│ │ uid: sym1 │ │ uid: sym2 │ │ uid: sym3 │ │
|
|
41
|
+
│ │ onMounted → register(sym, getItem) │
|
|
42
|
+
│ │ onClick → groupContext.preview(sym) │
|
|
43
|
+
│ │ onUnmount → unregister(sym) │
|
|
44
|
+
│ └────────────┘ └────────────┘ └────────────┘ │
|
|
45
|
+
│ │
|
|
46
|
+
│ preview(uid) → 收集所有 registry 中的 ImageItem → │
|
|
47
|
+
│ 设置 activeIndex → 打开 ImagePreview │
|
|
48
|
+
└───────────────────────────────────────────────────────────────────────┘
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 基础用法
|
|
52
|
+
|
|
53
|
+
```vue
|
|
54
|
+
<template>
|
|
55
|
+
<ImagePreviewGroup>
|
|
56
|
+
<AiImage
|
|
57
|
+
v-for="(src, i) in images"
|
|
58
|
+
:key="i"
|
|
59
|
+
:src="src"
|
|
60
|
+
:width="160"
|
|
61
|
+
:height="120"
|
|
62
|
+
/>
|
|
63
|
+
</ImagePreviewGroup>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<script setup lang="ts">
|
|
67
|
+
import { AiImage, ImagePreviewGroup } from '@blueking/chat-x';
|
|
68
|
+
|
|
69
|
+
const images = [
|
|
70
|
+
'https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=400&h=300&fit=crop',
|
|
71
|
+
'https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=400&h=300&fit=crop',
|
|
72
|
+
'https://images.unsplash.com/photo-1447752875215-b2761acb3c5d?w=400&h=300&fit=crop',
|
|
73
|
+
];
|
|
74
|
+
</script>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 带图片信息
|
|
78
|
+
|
|
79
|
+
配合 `showInfo` 和 `AiImage` 的 `previewProps`,在预览工具栏显示图片尺寸信息:
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<template>
|
|
83
|
+
<ImagePreviewGroup :show-info="true">
|
|
84
|
+
<AiImage
|
|
85
|
+
v-for="(img, i) in images"
|
|
86
|
+
:key="i"
|
|
87
|
+
:src="img.src"
|
|
88
|
+
:preview-props="img.previewProps"
|
|
89
|
+
:width="160"
|
|
90
|
+
:height="120"
|
|
91
|
+
/>
|
|
92
|
+
</ImagePreviewGroup>
|
|
93
|
+
</template>
|
|
94
|
+
|
|
95
|
+
<script setup lang="ts">
|
|
96
|
+
import { AiImage, ImagePreviewGroup, type ImagePreviewConfig } from '@blueking/chat-x';
|
|
97
|
+
|
|
98
|
+
const images = [
|
|
99
|
+
{
|
|
100
|
+
src: '...缩略图地址...',
|
|
101
|
+
previewProps: {
|
|
102
|
+
src: '...高清原图地址...',
|
|
103
|
+
name: '湖泊风景.jpg',
|
|
104
|
+
width: 1920,
|
|
105
|
+
resolution: '1920×1080',
|
|
106
|
+
} as ImagePreviewConfig,
|
|
107
|
+
},
|
|
108
|
+
// ...更多图片
|
|
109
|
+
];
|
|
110
|
+
</script>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 自定义下载
|
|
114
|
+
|
|
115
|
+
通过 `onDownload` 统一控制所有子图片的下载行为:
|
|
116
|
+
|
|
117
|
+
```vue
|
|
118
|
+
<template>
|
|
119
|
+
<ImagePreviewGroup :on-download="handleDownload">
|
|
120
|
+
<AiImage
|
|
121
|
+
v-for="(src, i) in images"
|
|
122
|
+
:key="i"
|
|
123
|
+
:src="src"
|
|
124
|
+
:width="160"
|
|
125
|
+
:height="120"
|
|
126
|
+
/>
|
|
127
|
+
</ImagePreviewGroup>
|
|
128
|
+
</template>
|
|
129
|
+
|
|
130
|
+
<script setup lang="ts">
|
|
131
|
+
import { AiImage, ImagePreviewGroup } from '@blueking/chat-x';
|
|
132
|
+
|
|
133
|
+
const handleDownload = (url: string) => {
|
|
134
|
+
window.open(`/api/download?url=${encodeURIComponent(url)}`);
|
|
135
|
+
};
|
|
136
|
+
</script>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## API
|
|
140
|
+
|
|
141
|
+
### Props
|
|
142
|
+
|
|
143
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
144
|
+
| ------------ | ----------------------- | ------- | --------------------------------------------- |
|
|
145
|
+
| maskClosable | `boolean` | `true` | 点击遮罩层是否关闭预览 |
|
|
146
|
+
| showInfo | `boolean` | `false` | 预览工具栏是否显示图片尺寸信息 |
|
|
147
|
+
| onDownload | `(url: string) => void` | — | 自定义下载回调;不传时使用默认 `<a>` 标签下载 |
|
|
148
|
+
|
|
149
|
+
### Slots
|
|
150
|
+
|
|
151
|
+
| 插槽名 | 说明 |
|
|
152
|
+
| ------- | ----------------------------------------------- |
|
|
153
|
+
| default | 放置子级 `AiImage` 组件 |
|
|
154
|
+
| extra | 预览工具栏的额外操作区域(透传给 ImagePreview) |
|
|
155
|
+
|
|
156
|
+
## 类型定义
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
interface ImagePreviewGroupContext {
|
|
160
|
+
register: (uid: symbol, getItem: () => ImageItem) => void;
|
|
161
|
+
unregister: (uid: symbol) => void;
|
|
162
|
+
preview: (uid: symbol) => void;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const IMAGE_PREVIEW_GROUP_KEY: InjectionKey<ImagePreviewGroupContext>;
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## 与 AiImage 的协作关系
|
|
169
|
+
|
|
170
|
+
| AiImage 场景 | 行为 |
|
|
171
|
+
| ------------- | ---------------------------------------------------------------------------------------- |
|
|
172
|
+
| 未在 Group 内 | `inject` 返回 `null`,AiImage 内部自行渲染 `ImagePreview`(独立模式) |
|
|
173
|
+
| 在 Group 内 | `inject` 获取 Group 上下文;`onMounted` 注册自身;点击时调用 `groupContext.preview(uid)` |
|
|
174
|
+
|
|
175
|
+
## 使用场景
|
|
176
|
+
|
|
177
|
+
- AI 对话中一条消息包含多张图片,需要统一预览
|
|
178
|
+
- 图片画廊场景
|
|
179
|
+
- 任何需要"点击缩略图 → 多图预览切换"的场景
|
|
180
|
+
|
|
181
|
+
## 关联组件
|
|
182
|
+
|
|
183
|
+
- [AiImage](/components/medias/ai-image) — 子级缩略图与注册
|
|
184
|
+
- [ImagePreview](/components/medias/image-preview) — 内置全屏预览
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# ImagePreview 图片预览
|
|
2
|
+
|
|
3
|
+
> 能力域:媒体文件 | 导入:`import { ImagePreview } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
图片全屏预览容器,支持缩放、旋转、下载工具栏。 源码位置:src/components/image-preview/image-preview.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:ai-image(独立模式下由 AiImage 打开预览)、image-preview-group(组内容器内持有一个实例做多图切换)、file-content(文件列表点击缩略图触发预览)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ImagePreview 图片预览
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/image-preview/image-preview.vue`
|
|
15
|
+
- **能力域**:媒体文件
|
|
16
|
+
- **能力说明**:图片全屏预览容器,支持缩放、旋转、下载工具栏。
|
|
17
|
+
|
|
18
|
+
> **能力域**:媒体文件
|
|
19
|
+
|
|
20
|
+
全屏图片预览组件,通过 `Teleport` 渲染到 `body`,支持缩放、旋转、拖拽、下载、键盘导航等功能。`images` 支持传入 URL 字符串、`ImageItem` 对象或 `File` 对象,File 对象会自动通过 `URL.createObjectURL` 生成预览并在关闭/卸载时回收。通常不直接使用,而是配合 `AiImage`、`ImagePreviewGroup` 或 `FileContent` 自动触发。
|
|
21
|
+
|
|
22
|
+
## 组件结构
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Teleport(to="body")
|
|
26
|
+
└── .ai-image-preview(fixed,z-index: 10000,background: rgba(0,0,0,0.6))
|
|
27
|
+
├── .ai-image-preview-close(右上角关闭按钮)
|
|
28
|
+
├── .ai-image-preview-arrow-left(左切换箭头,多图时显示)
|
|
29
|
+
├── .ai-image-preview-arrow-right(右切换箭头,多图时显示)
|
|
30
|
+
├── .ai-image-preview-body(图片主体区域,支持拖拽/滚轮缩放)
|
|
31
|
+
│ ├── <img>(currentStatus !== 'error' 时)
|
|
32
|
+
│ ├── .ai-image-preview-error(加载失败时)
|
|
33
|
+
│ └── .ai-image-preview-loading(加载中,支持模糊缩略图)
|
|
34
|
+
└── PreviewToolbar(底部工具栏)
|
|
35
|
+
├── 页码(多图时: 1/3)
|
|
36
|
+
├── 缩小 / 放大 / 旋转 / 重置 / 下载
|
|
37
|
+
├── slot#extra(额外操作区域)
|
|
38
|
+
└── 图片信息(showInfo 时显示宽度/分辨率)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 内部子组件
|
|
42
|
+
|
|
43
|
+
### PreviewToolbar
|
|
44
|
+
|
|
45
|
+
底部圆角工具栏,包含以下按钮:
|
|
46
|
+
|
|
47
|
+
| 按钮 | 功能 | tooltip |
|
|
48
|
+
| ---- | ------------------------------ | ------- |
|
|
49
|
+
| 缩小 | 按 15% 步进缩小(最小 0.1 倍) | 缩小 |
|
|
50
|
+
| 放大 | 按 15% 步进放大(最大 10 倍) | 放大 |
|
|
51
|
+
| 旋转 | 顺时针旋转 90° | 旋转 |
|
|
52
|
+
| 重置 | 重置缩放/旋转/位移 | 重置 |
|
|
53
|
+
| 下载 | 触发下载 | 下载 |
|
|
54
|
+
|
|
55
|
+
多图模式下还显示页码(如 "1 / 3")和分隔线。
|
|
56
|
+
|
|
57
|
+
### useImageTransform
|
|
58
|
+
|
|
59
|
+
图片变换 Composable,管理缩放/旋转/平移状态:
|
|
60
|
+
|
|
61
|
+
- `scale`:缩放比例(0.1 ~ 10,步进 15%)
|
|
62
|
+
- `rotate`:旋转角度(每次 +90°,累加不取模)
|
|
63
|
+
- `translateX / translateY`:拖拽偏移量
|
|
64
|
+
- 支持鼠标滚轮缩放和拖拽平移
|
|
65
|
+
- `resetTransform` 重置时跳过过渡动画(`skipTransition`),避免视觉闪烁
|
|
66
|
+
|
|
67
|
+
### usePreviewKeyboard
|
|
68
|
+
|
|
69
|
+
键盘导航 Composable:
|
|
70
|
+
|
|
71
|
+
| 按键 | 功能 |
|
|
72
|
+
| ----- | ------------------ |
|
|
73
|
+
| `Esc` | 关闭预览 |
|
|
74
|
+
| `←` | 上一张(多图模式) |
|
|
75
|
+
| `→` | 下一张(多图模式) |
|
|
76
|
+
|
|
77
|
+
预览打开时自动锁定 `body` 滚动(`overflow: hidden`),关闭时恢复。
|
|
78
|
+
|
|
79
|
+
## 基础用法(单图)
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<template>
|
|
83
|
+
<button @click="visible = true">预览图片</button>
|
|
84
|
+
<ImagePreview
|
|
85
|
+
v-model:visible="visible"
|
|
86
|
+
:images="images"
|
|
87
|
+
/>
|
|
88
|
+
</template>
|
|
89
|
+
|
|
90
|
+
<script setup lang="ts">
|
|
91
|
+
import { ref } from 'vue';
|
|
92
|
+
import { ImagePreview } from '@blueking/chat-x';
|
|
93
|
+
|
|
94
|
+
const visible = ref(false);
|
|
95
|
+
const images = ['https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=1920'];
|
|
96
|
+
</script>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 多图预览
|
|
100
|
+
|
|
101
|
+
传入多张图片时,左右箭头和页码自动显示,支持循环切换:
|
|
102
|
+
|
|
103
|
+
```vue
|
|
104
|
+
<template>
|
|
105
|
+
<button @click="visibleMulti = true">预览多张图片</button>
|
|
106
|
+
<ImagePreview
|
|
107
|
+
v-model:visible="visibleMulti"
|
|
108
|
+
v-model:current="currentIndex"
|
|
109
|
+
:images="images"
|
|
110
|
+
:show-info="true"
|
|
111
|
+
/>
|
|
112
|
+
</template>
|
|
113
|
+
|
|
114
|
+
<script setup lang="ts">
|
|
115
|
+
import { ref } from 'vue';
|
|
116
|
+
import { ImagePreview, type ImageItem } from '@blueking/chat-x';
|
|
117
|
+
|
|
118
|
+
const visibleMulti = ref(false);
|
|
119
|
+
const currentIndex = ref(0);
|
|
120
|
+
const images: ImageItem[] = [
|
|
121
|
+
{ url: '...', name: '湖泊风景.jpg', width: 1920, resolution: '1920×1080' },
|
|
122
|
+
{ url: '...', name: '山谷日出.jpg', width: 1920, resolution: '1920×1280' },
|
|
123
|
+
{ url: '...', name: '森林小径.jpg', width: 1920, resolution: '1920×1280' },
|
|
124
|
+
];
|
|
125
|
+
</script>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## File 对象预览
|
|
129
|
+
|
|
130
|
+
`images` 数组中可直接传入 `File` 对象,组件会自动通过 `URL.createObjectURL` 生成预览 URL,并在预览关闭或组件卸载时自动调用 `URL.revokeObjectURL` 释放内存:
|
|
131
|
+
|
|
132
|
+
```vue
|
|
133
|
+
<template>
|
|
134
|
+
<button @click="visibleFile = true">预览 File 对象</button>
|
|
135
|
+
<ImagePreview
|
|
136
|
+
v-model:visible="visibleFile"
|
|
137
|
+
:images="fileImages"
|
|
138
|
+
/>
|
|
139
|
+
</template>
|
|
140
|
+
|
|
141
|
+
<script setup lang="ts">
|
|
142
|
+
import { ref } from 'vue';
|
|
143
|
+
import { ImagePreview } from '@blueking/chat-x';
|
|
144
|
+
|
|
145
|
+
const visibleFile = ref(false);
|
|
146
|
+
const fileImages = [
|
|
147
|
+
new File(['png-data'], 'screenshot.png', { type: 'image/png' }),
|
|
148
|
+
new File(['jpg-data'], 'photo.jpg', { type: 'image/jpeg' }),
|
|
149
|
+
];
|
|
150
|
+
</script>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
> **ObjectURL 生命周期管理**:组件内部维护 `objectUrls` 数组,在以下时机自动回收:
|
|
154
|
+
>
|
|
155
|
+
> - `normalizedImages` 计算属性重算时(会先 `revokeObjectUrls`,再按当前 `images` 与 `visible` 生成新列表)
|
|
156
|
+
> - **`visible` 为 `false` 时**:计算属性直接清空并 `revokeObjectURL`,避免仅依赖 `props.images` 时 computed 仍缓存**已失效**的 blob URL,导致关闭预览后再次打开加载失败
|
|
157
|
+
> - 组件 `onBeforeUnmount` 时
|
|
158
|
+
|
|
159
|
+
## API
|
|
160
|
+
|
|
161
|
+
### Props
|
|
162
|
+
|
|
163
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
164
|
+
| ------------ | --------------------------------- | ------- | ----------------------------------------------------------- |
|
|
165
|
+
| images | `(File \| ImageItem \| string)[]` | `[]` | 图片列表;字符串自动转为 `{ url }`,File 自动转为 ObjectURL |
|
|
166
|
+
| maskClosable | `boolean` | `true` | 点击遮罩层是否关闭预览 |
|
|
167
|
+
| showInfo | `boolean` | `false` | 工具栏是否显示图片尺寸信息(width / resolution) |
|
|
168
|
+
| onDownload | `(url: string) => void` | — | 自定义下载回调;不传时使用默认 `<a>` 标签下载 |
|
|
169
|
+
|
|
170
|
+
### v-model
|
|
171
|
+
|
|
172
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
173
|
+
| ------- | --------- | ---- | ----------------------- |
|
|
174
|
+
| visible | `boolean` | ✅ | 控制预览弹窗的显示/隐藏 |
|
|
175
|
+
| current | `number` | — | 当前展示的图片索引 |
|
|
176
|
+
|
|
177
|
+
### Slots
|
|
178
|
+
|
|
179
|
+
| 插槽名 | 说明 |
|
|
180
|
+
| ------ | -------------------------------------- |
|
|
181
|
+
| extra | 工具栏额外操作区域,渲染在下载按钮右侧 |
|
|
182
|
+
|
|
183
|
+
## 类型定义
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
interface ImageItem {
|
|
187
|
+
url: string;
|
|
188
|
+
thumbnailUrl?: string;
|
|
189
|
+
name?: string;
|
|
190
|
+
file?: File;
|
|
191
|
+
width?: number;
|
|
192
|
+
height?: number;
|
|
193
|
+
resolution?: string;
|
|
194
|
+
downloadUrl?: string;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
type ImageLoadingStatus = 'loading' | 'loaded' | 'error';
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 交互说明
|
|
201
|
+
|
|
202
|
+
| 操作 | 效果 |
|
|
203
|
+
| ------------- | --------------------------------------- |
|
|
204
|
+
| 滚轮向上 | 放大图片(15% 步进) |
|
|
205
|
+
| 滚轮向下 | 缩小图片(15% 步进) |
|
|
206
|
+
| 鼠标左键拖拽 | 平移图片 |
|
|
207
|
+
| 点击遮罩 | 关闭预览(`maskClosable` 为 `true` 时) |
|
|
208
|
+
| 点击关闭按钮 | 关闭预览 |
|
|
209
|
+
| 左/右箭头按钮 | 切换上/下一张(多图,循环切换) |
|
|
210
|
+
| `Esc` 键 | 关闭预览 |
|
|
211
|
+
| `←` / `→` 键 | 切换上/下一张(多图) |
|
|
212
|
+
|
|
213
|
+
## 使用场景
|
|
214
|
+
|
|
215
|
+
- 单张或多张图片的全屏预览
|
|
216
|
+
- AI 对话中点击图片放大查看(由 `AiImage` 自动触发)
|
|
217
|
+
- 文件列表中点击图片缩略图预览(由 `FileContent` 内部集成)
|
|
218
|
+
- 用户消息中点击附件图片预览(由 `UserMessage` → `FileContent` 自动触发)
|
|
219
|
+
- 需要旋转/缩放/下载操作的图片查看
|
|
220
|
+
- 传入 `File` 对象直接预览(无需手动管理 ObjectURL)
|
|
221
|
+
|
|
222
|
+
## 关联组件
|
|
223
|
+
|
|
224
|
+
- [AiImage](/components/medias/ai-image) — 独立模式触发预览
|
|
225
|
+
- [ImagePreviewGroup](/components/medias/image-preview-group) — 多图预览容器
|
|
226
|
+
- [FileContent](/components/medias/file-content) — 附件列表点击预览
|