@blueking/chat-x 0.0.51 → 0.0.52-dev.2

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.
Files changed (199) hide show
  1. package/README.md +15 -8
  2. package/dist/ag-ui/types/contents.d.ts +2 -0
  3. package/dist/ag-ui/types/messages.d.ts +6 -1
  4. package/dist/common/constants.d.ts +2 -0
  5. package/dist/components/ai-buttons/add-menu-btn/add-menu-btn.vue.d.ts +24 -0
  6. package/dist/components/chat-content/collapsible-content/collapsible-content.vue.d.ts +28 -0
  7. package/dist/components/chat-content/file-content/upload-file-item.vue.d.ts +5 -2
  8. package/dist/components/chat-content/file-content/upload-image-item.vue.d.ts +1 -0
  9. package/dist/components/chat-content/flow-agent-content/use-flow-node-actions.d.ts +1 -1
  10. package/dist/components/chat-input/ai-slash-input/ai-slash-input.vue.d.ts +21 -10
  11. package/dist/components/chat-input/ai-slash-input/command.d.ts +6 -3
  12. package/dist/components/chat-input/ai-slash-input/constants.d.ts +2 -0
  13. package/dist/components/chat-input/ai-slash-input/use-menu-trigger.d.ts +17 -0
  14. package/dist/components/chat-input/build-default-placeholder.d.ts +9 -3
  15. package/dist/components/chat-input/chat-input.vue.d.ts +30 -18
  16. package/dist/components/chat-input/input-menu/constants.d.ts +60 -0
  17. package/dist/components/chat-input/input-menu/index.d.ts +4 -0
  18. package/dist/components/chat-input/input-menu/input-menu-option.vue.d.ts +14 -0
  19. package/dist/components/chat-input/input-menu/input-menu-panel.vue.d.ts +17 -0
  20. package/dist/components/chat-input/input-menu/use-input-menu.d.ts +22 -0
  21. package/dist/components/chat-input/model-selector/types.d.ts +3 -2
  22. package/dist/components/chat-message/message-container/message-container.vue.d.ts +1 -1
  23. package/dist/components/chat-message/user-message/user-message.vue.d.ts +1 -1
  24. package/dist/components/mention/create-mention-tippy.d.ts +27 -0
  25. package/dist/components/mention/index.d.ts +4 -0
  26. 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
  27. 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
  28. 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
  29. package/dist/components/resource-icon/index.d.ts +1 -0
  30. package/dist/components/resource-icon/resource-icon.vue.d.ts +11 -0
  31. package/dist/composables/index.d.ts +1 -0
  32. package/dist/composables/use-artifact-preview.d.ts +5 -2
  33. package/dist/composables/use-common.d.ts +0 -9
  34. package/dist/composables/use-global-config.d.ts +4 -0
  35. package/dist/composables/use-input-mention.d.ts +13 -0
  36. package/dist/composables/use-message-group.d.ts +1011 -72
  37. package/dist/icons/index.d.ts +1 -0
  38. package/dist/icons/input.d.ts +21 -0
  39. package/dist/icons/menu-item.d.ts +22 -0
  40. package/dist/index.css +1 -1
  41. package/dist/index.js +5116 -4595
  42. package/dist/index.js.map +1 -1
  43. package/dist/lang/lang.d.ts +13 -3
  44. package/dist/mcp/generated/docs/activity-message.md +3 -3
  45. package/dist/mcp/generated/docs/add-menu-btn.md +91 -0
  46. package/dist/mcp/generated/docs/ai-selection.md +1 -1
  47. package/dist/mcp/generated/docs/ai-slash-input.md +72 -26
  48. package/dist/mcp/generated/docs/assistant-message.md +7 -1
  49. package/dist/mcp/generated/docs/chat-container.md +45 -6
  50. package/dist/mcp/generated/docs/chat-input.md +327 -483
  51. package/dist/mcp/generated/docs/collapsible-content.md +78 -0
  52. package/dist/mcp/generated/docs/constants.md +36 -3
  53. package/dist/mcp/generated/docs/execution-summary.md +1 -23
  54. package/dist/mcp/generated/docs/file-artifact-panel.md +24 -5
  55. package/dist/mcp/generated/docs/file-content.md +4 -0
  56. package/dist/mcp/generated/docs/file-upload-btn.md +15 -12
  57. package/dist/mcp/generated/docs/flow-agent-content.md +10 -12
  58. package/dist/mcp/generated/docs/input-menu-panel.md +166 -0
  59. package/dist/mcp/generated/docs/mention-tag.md +83 -0
  60. package/dist/mcp/generated/docs/mention-text.md +86 -0
  61. package/dist/mcp/generated/docs/message-container.md +1 -1
  62. package/dist/mcp/generated/docs/message-render.md +1 -1
  63. package/dist/mcp/generated/docs/message-tools.md +15 -4
  64. package/dist/mcp/generated/docs/messages.md +3 -0
  65. package/dist/mcp/generated/docs/model-selector.md +4 -2
  66. package/dist/mcp/generated/docs/overflow-tips.md +3 -3
  67. package/dist/mcp/generated/docs/resource-icon.md +102 -0
  68. package/dist/mcp/generated/docs/text-content.md +7 -3
  69. package/dist/mcp/generated/docs/theme.md +27 -35
  70. package/dist/mcp/generated/docs/use-artifact-preview.md +7 -3
  71. package/dist/mcp/generated/docs/use-command-selection.md +1 -1
  72. package/dist/mcp/generated/docs/use-container-scroll.md +2 -1
  73. package/dist/mcp/generated/docs/use-flow-node-actions.md +8 -15
  74. package/dist/mcp/generated/docs/use-global-config.md +11 -4
  75. package/dist/mcp/generated/docs/use-input-mention.md +119 -0
  76. package/dist/mcp/generated/docs/use-menu-keydown.md +15 -16
  77. package/dist/mcp/generated/docs/use-message-group.md +3 -6
  78. package/dist/mcp/generated/docs/user-message.md +39 -17
  79. package/dist/mcp/generated/index.json +233 -81
  80. package/dist/types/editor.d.ts +0 -29
  81. package/dist/types/index.d.ts +1 -0
  82. package/dist/types/input-menu.d.ts +46 -0
  83. package/dist/utils/artifact-tags.d.ts +36 -0
  84. package/dist/utils/collect-message-artifacts.d.ts +14 -0
  85. package/dist/utils/file.d.ts +3 -3
  86. package/dist/utils/index.d.ts +2 -1
  87. package/dist/utils/upload-file.d.ts +6 -1
  88. package/package.json +4 -3
  89. package/skills/blueking-chat-x/SKILL.md +143 -0
  90. package/skills/blueking-chat-x/references/_index.md +153 -0
  91. package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
  92. package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
  93. package/skills/blueking-chat-x/references/components/add-menu-btn.md +88 -0
  94. package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
  95. package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
  96. package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
  97. package/skills/blueking-chat-x/references/components/ai-slash-input.md +102 -0
  98. package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
  99. package/skills/blueking-chat-x/references/components/assistant-message.md +504 -0
  100. package/skills/blueking-chat-x/references/components/chat-container.md +912 -0
  101. package/skills/blueking-chat-x/references/components/chat-input.md +614 -0
  102. package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
  103. package/skills/blueking-chat-x/references/components/code-content.md +211 -0
  104. package/skills/blueking-chat-x/references/components/collapsible-content.md +76 -0
  105. package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
  106. package/skills/blueking-chat-x/references/components/content-render.md +233 -0
  107. package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
  108. package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
  109. package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
  110. package/skills/blueking-chat-x/references/components/execution-summary.md +150 -0
  111. package/skills/blueking-chat-x/references/components/file-artifact-panel.md +307 -0
  112. package/skills/blueking-chat-x/references/components/file-content.md +340 -0
  113. package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
  114. package/skills/blueking-chat-x/references/components/file-upload-btn.md +162 -0
  115. package/skills/blueking-chat-x/references/components/flow-agent-content.md +266 -0
  116. package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
  117. package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
  118. package/skills/blueking-chat-x/references/components/image-content.md +182 -0
  119. package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
  120. package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
  121. package/skills/blueking-chat-x/references/components/info-message.md +144 -0
  122. package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
  123. package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
  124. package/skills/blueking-chat-x/references/components/input-menu-panel.md +162 -0
  125. package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
  126. package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
  127. package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
  128. package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
  129. package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
  130. package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
  131. package/skills/blueking-chat-x/references/components/mention-tag.md +79 -0
  132. package/skills/blueking-chat-x/references/components/mention-text.md +83 -0
  133. package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
  134. package/skills/blueking-chat-x/references/components/message-container.md +645 -0
  135. package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
  136. package/skills/blueking-chat-x/references/components/message-render.md +327 -0
  137. package/skills/blueking-chat-x/references/components/message-time.md +177 -0
  138. package/skills/blueking-chat-x/references/components/message-tools.md +427 -0
  139. package/skills/blueking-chat-x/references/components/model-selector.md +157 -0
  140. package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
  141. package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
  142. package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
  143. package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
  144. package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
  145. package/skills/blueking-chat-x/references/components/resource-icon.md +98 -0
  146. package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
  147. package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
  148. package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
  149. package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
  150. package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
  151. package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
  152. package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
  153. package/skills/blueking-chat-x/references/components/text-content.md +80 -0
  154. package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
  155. package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
  156. package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
  157. package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
  158. package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
  159. package/skills/blueking-chat-x/references/components/user-message.md +444 -0
  160. package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
  161. package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
  162. package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
  163. package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
  164. package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
  165. package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
  166. package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +235 -0
  167. package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
  168. package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
  169. package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
  170. package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
  171. package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +164 -0
  172. package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
  173. package/skills/blueking-chat-x/references/composables/use-global-config.md +155 -0
  174. package/skills/blueking-chat-x/references/composables/use-input-mention.md +115 -0
  175. package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +161 -0
  176. package/skills/blueking-chat-x/references/composables/use-message-group.md +244 -0
  177. package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
  178. package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
  179. package/skills/blueking-chat-x/references/directives/index.md +61 -0
  180. package/skills/blueking-chat-x/references/directives/overflow-tips.md +205 -0
  181. package/skills/blueking-chat-x/references/icons/index.md +185 -0
  182. package/skills/blueking-chat-x/references/plugins/index.md +56 -0
  183. package/skills/blueking-chat-x/references/plugins/markdown-container.md +55 -0
  184. package/skills/blueking-chat-x/references/plugins/markdown-latex.md +205 -0
  185. package/skills/blueking-chat-x/references/plugins/markdown-mermaid.md +247 -0
  186. package/skills/blueking-chat-x/references/theme/theme.md +423 -0
  187. package/skills/blueking-chat-x/references/types/constants.md +340 -0
  188. package/skills/blueking-chat-x/references/types/index.md +120 -0
  189. package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
  190. package/skills/blueking-chat-x/references/types/messages.md +556 -0
  191. package/skills/blueking-chat-x/references/types/schema.md +91 -0
  192. package/skills/blueking-chat-x/references/utils/index.md +196 -0
  193. package/skills/blueking-chat-x/scripts/generate-references.mjs +536 -0
  194. package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +0 -28
  195. package/dist/components/chat-input/ai-slash-editor/theme.d.ts +0 -24
  196. package/dist/mcp/generated/docs/ai-prompt-list.md +0 -45
  197. package/dist/mcp/generated/docs/ai-skill-list.md +0 -75
  198. package/dist/mcp/generated/docs/ai-slash-editor.md +0 -43
  199. package/dist/mcp/generated/docs/ai-slash-menu.md +0 -42
@@ -0,0 +1,233 @@
1
+ # UserFeedback 用户反馈
2
+
3
+ > 能力域:工具与反馈 | 导入:`import { MessageUserFeedback } from '@blueking/chat-x'` | since 1.0.0
4
+
5
+ 用户反馈弹层,提交踩/反馈原因。 源码位置:src/components/message-tools/user-feedback/user-feedback.vue。
6
+
7
+ **关联**:message-tools(点赞/踩操作触发并收集反馈)
8
+
9
+ ---
10
+
11
+ # MessageUserFeedback 用户反馈
12
+ ## 源码事实
13
+
14
+ - **源码位置**:`src/components/message-tools/user-feedback/user-feedback.vue`
15
+ - **能力域**:工具与反馈
16
+ - **能力说明**:用户反馈弹层,提交踩/反馈原因。
17
+
18
+ > **能力域**:工具与反馈
19
+
20
+ AI 消息点赞/踩后收集用户具体反馈原因的弹出面板。支持多选预设原因标签、补充文字说明(textarea)、异步加载原因列表(骨架屏)。
21
+
22
+ > **通常不需要直接使用。** `MessageTools` 在用户点击 `like`/`unlike` 工具按钮时,会通过内置 Tippy 弹出层自动呈现本组件,并驱动 `loading` 和 `reasonList`。
23
+
24
+ ## 组件结构
25
+
26
+ ```
27
+ .ai-user-feedback(width: 400px,padding: 16px,gap: 16px)
28
+ ├── .ai-feedback-title(font-size: 16px,color: #313238)
29
+ │ props.title
30
+
31
+ ├── .ai-feedback-reason-list(flex-wrap,gap: 4px)
32
+ │ loading=true → 8 × .reason-item.ai-skeleton-element(每项 width: 70px)
33
+ │ loading=false → v-for reasonList → .reason-item
34
+ │ is-active(已选):color #1768ef,bg #e1ecff
35
+ │ :hover :同上(与 is-active 共享样式)
36
+
37
+ ├── .ai-feedback-other
38
+ │ bkui-vue Input(type=textarea,rows=3,placeholder="说出您的想法")
39
+ │ → v-model 绑定内部 shallowRef otherReason
40
+
41
+ └── .ai-feedback-footer(justify-content: flex-end,gap: 8px)
42
+ Button primary "提交"(width: 64px,disabled:selectedReasons 空且 otherReason 空)
43
+ Button default "取消"(width: 64px)
44
+ ```
45
+
46
+ ## 基础用法
47
+
48
+ ```vue
49
+ <template>
50
+ <MessageUserFeedback
51
+ title="什么原因让你满意?"
52
+ :reason-list="reasonList"
53
+ @submit="handleSubmit"
54
+ @cancel="handleCancel"
55
+ />
56
+ </template>
57
+
58
+ <script setup lang="ts">
59
+ import { MessageUserFeedback } from '@blueking/chat-x';
60
+
61
+ const reasonList = ['回答准确', '信息全面', '表达清晰', '解决了问题', '示例恰当'];
62
+
63
+ const handleSubmit = (selectedReasons: string[], otherReason: string) => {
64
+ // selectedReasons: 当前已勾选的原因(提交后组件不自动清空)
65
+ // otherReason: textarea 中的补充说明(可为空字符串)
66
+ console.log('已选原因:', selectedReasons, '补充说明:', otherReason);
67
+ };
68
+
69
+ const handleCancel = () => {
70
+ // cancel 触发前组件已清空 selectedReasons 和 otherReason
71
+ console.log('用户取消了反馈');
72
+ };
73
+ </script>
74
+ ```
75
+
76
+ **满意反馈**
77
+
78
+ **不满意反馈**
79
+
80
+ ## 加载状态
81
+
82
+ 原因列表通常需要异步获取,将 `loading` 设为 `true` 时渲染 **8 个**骨架屏占位块(固定数量,与 `reasonList` 无关),数据就绪后切换为 `false`:
83
+
84
+ ```vue
85
+ <template>
86
+ <MessageUserFeedback
87
+ title="什么原因让你满意?"
88
+ :reason-list="reasonList"
89
+ :loading="isLoading"
90
+ @submit="handleSubmit"
91
+ @cancel="handleCancel"
92
+ />
93
+ </template>
94
+
95
+ <script setup lang="ts">
96
+ import { ref } from 'vue';
97
+ import { MessageUserFeedback } from '@blueking/chat-x';
98
+
99
+ const isLoading = ref(true);
100
+ const reasonList = ref<string[]>([]);
101
+
102
+ async function fetchReasons() {
103
+ isLoading.value = true;
104
+ try {
105
+ reasonList.value = await fetchFeedbackReasons();
106
+ } finally {
107
+ isLoading.value = false;
108
+ }
109
+ }
110
+ </script>
111
+ ```
112
+
113
+ **骨架屏效果**
114
+
115
+ ## 交互说明
116
+
117
+ | 操作 | 行为说明 |
118
+ | ------------ | ------------------------------------------------------------------------------------------------------------- |
119
+ | 点击原因标签 | **多选**,高亮(`is-active`);再次点击取消选中;hover 效果与选中态相同 |
120
+ | 填写补充说明 | 可选;不选任何标签时,仅有补充说明文本也可解锁提交按钮 |
121
+ | 点击提交 | `selectedReasons.length === 0 && otherReason === ''` 时禁用;点击后触发 `submit` 事件,**组件不自动清空状态** |
122
+ | 点击取消 | 先将 `selectedReasons` 和 `otherReason` 清空(两者均重置),再触发 `cancel` 事件 |
123
+
124
+ > **提交与取消的状态差异**:点击"提交"后内部 `selectedReasons` / `otherReason` **不重置**,由父组件决定后续行为(如关闭弹层);点击"取消"则**立即重置**两者,再触发事件。
125
+
126
+ ## 与 MessageTools 配合使用
127
+
128
+ `MessageUserFeedback` 在实际场景中由 `MessageTools` 驱动,整体流程:
129
+
130
+ ```
131
+ 用户点击 like / unlike
132
+
133
+ MessageTools 内部:loading=true,弹出反馈面板(骨架屏)
134
+
135
+ 调用 onAction(tool) → 返回 string[](支持 async)
136
+
137
+ loading=false,展示原因标签列表
138
+
139
+ 用户选择原因 → 点击提交
140
+
141
+ 触发 onAgentFeedback(tool, messages, reasonList, otherReason)
142
+ ```
143
+
144
+ ```vue
145
+ <template>
146
+ <MessageContainer
147
+ :messages="messages"
148
+ :on-agent-action="handleAgentAction"
149
+ :on-agent-feedback="handleFeedback"
150
+ />
151
+ </template>
152
+
153
+ <script setup lang="ts">
154
+ import { MessageContainer, type IToolBtn, type Message } from '@blueking/chat-x';
155
+
156
+ const messages: Message[] = [
157
+ /* ... */
158
+ ];
159
+
160
+ // 点击 like/unlike 时调用,返回原因列表(支持异步)
161
+ const handleAgentAction = async (tool: IToolBtn): Promise<string[]> => {
162
+ if (tool.id === 'like') {
163
+ return ['回答准确', '信息全面', '表达清晰', '解决了问题'];
164
+ }
165
+ if (tool.id === 'unlike') {
166
+ return ['信息错误', '回答不相关', '解释不清楚', '没有解决问题'];
167
+ }
168
+ return [];
169
+ };
170
+
171
+ // 用户提交反馈后触发
172
+ const handleFeedback = (tool: IToolBtn, messages: Message[], reasonList: string[], otherReason: string) => {
173
+ console.log(`${tool.id} 反馈:`, { reasonList, otherReason });
174
+ // 上报到后端
175
+ };
176
+ </script>
177
+ ```
178
+
179
+ 若需在自定义位置独立使用,可配合 `vue-tippy`:
180
+
181
+ ```vue
182
+ <template>
183
+ <Tippy
184
+ :arrow="false"
185
+ interactive
186
+ trigger="click"
187
+ theme="ai-chat-box-light light"
188
+ :offset="[0, 6]"
189
+ :append-to="() => document.body"
190
+ >
191
+ <button>👍 点赞</button>
192
+ <template #content>
193
+ <MessageUserFeedback
194
+ title="什么原因让你满意?"
195
+ :reason-list="reasonList"
196
+ :loading="isLoading"
197
+ @submit="handleSubmit"
198
+ @cancel="handleCancel"
199
+ />
200
+ </template>
201
+ </Tippy>
202
+ </template>
203
+ ```
204
+
205
+ ## API
206
+
207
+ ### Props
208
+
209
+ | 属性名 | 类型 | 必填 | 默认值 | 说明 |
210
+ | ---------- | ---------- | ---- | ------- | ------------------------------------------------------ |
211
+ | title | `string` | ✓ | — | 面板标题文本 |
212
+ | reasonList | `string[]` | ✓ | — | 预设原因标签列表;`loading=true` 时列表不渲染 |
213
+ | loading | `boolean` | — | `false` | `true` 时显示 8 个骨架屏占位块,隐藏 `reasonList` 内容 |
214
+
215
+ ### Events
216
+
217
+ | 事件名 | 参数签名 | 触发时机 |
218
+ | ------ | --------------------------------------------- | ----------------------------------------------------------- |
219
+ | submit | `(reasonList: string[], otherReason: string)` | 点击提交按钮时(至少一项原因或补充说明不为空) |
220
+ | cancel | — | 点击取消按钮时(内部已重置 selectedReasons 和 otherReason) |
221
+
222
+ ### 内部状态
223
+
224
+ 以下为组件内部 `shallowRef` 状态,不暴露为 props/emits:
225
+
226
+ | 状态名 | 类型 | 说明 |
227
+ | --------------- | ---------- | ------------------------------------------- |
228
+ | selectedReasons | `string[]` | 当前已选原因列表;取消时重置,提交时不重置 |
229
+ | otherReason | `string` | textarea 补充说明;取消时重置,提交时不重置 |
230
+
231
+ ## 关联组件
232
+
233
+ - [MessageTools](/components/feedback/message-tools) — 点赞/踩入口与反馈联动
@@ -0,0 +1,444 @@
1
+ # UserMessage 用户消息
2
+
3
+ > 能力域:消息系统 | 未从包入口导出:内部组件(入口的同名导出是 TS 类型,不是组件) | since 0.0.20
4
+
5
+ 渲染用户消息:纯文本(非 Markdown)、键值引用、二进制附件与编辑态 ChatInput / ShortcutRender; 正文经 CollapsibleContent 限高 200px,property.docSchema 含标签时改用 MentionText 还原资源标签; 工具栏含 copy / edit / delete。源码位置:src/components/chat-message/user-message/user-message.vue。
6
+
7
+ **关联**:mention-text(文档含标签时用它还原已选资源)、collapsible-content(正文超过 200px 时折叠)、message-render(由 MessageRender 在 role 为 user 时创建)、message-tools(消息工具栏交互与状态由 MessageTools 体系承载)、message-time(createdAt 经工具栏 prepend 插槽展示)、message-container(嵌入列表时由 MessageContainer 管理分组与多选)、chat-input(编辑态普通消息使用 ChatInput)
8
+
9
+ ---
10
+
11
+ # UserMessage 用户消息
12
+
13
+ ## 源码事实
14
+
15
+ - **源码位置**:`src/components/chat-message/user-message/user-message.vue`
16
+ - **能力域**:消息系统
17
+ - **能力说明**:渲染用户消息:纯文本、键值引用、文件附件与编辑态输入(**不**渲染 Markdown)。
18
+
19
+ > **导出说明**:`UserMessage` **未**从 `@blueking/chat-x` 包入口导出(入口同名是 TS interface)。消费方请用 `MessageRender` / `MessageContainer`。下文 `UserMessageComp` 为文档站内部相对路径示例。
20
+
21
+ 用户消息展示组件,右对齐。支持纯文本、多媒体(图片/文件)、文本引用、结构化引用、快捷指令,以及内联编辑。
22
+
23
+ ## 组件结构
24
+
25
+ **正常模式**
26
+
27
+ ```
28
+ .ai-user-message(align-items: flex-end,gap: 6px,font-size: 12px)
29
+ ├── CiteContent(v-if:cite 为字符串)
30
+ │ 紧凑条带(高 28px,灰色 #f5f7fa),引用图标 + 单行截断文本
31
+
32
+ ├── [Binary 图片区] v-if binaryImageFiles.length
33
+ │ .ai-user-message-binary-files → FileContent(readonly=true,图片统一渲染,支持点击预览)
34
+
35
+ ├── [Binary 非图片文件区] v-for binaryNonImageFiles
36
+ │ .ai-user-message-binary-files → FileContent(readonly=true,每个文件独立渲染)
37
+
38
+ ├── .ai-user-message-content(气泡:bg #e1ecff,padding 8×12,border-radius 4px)
39
+ │ └── CollapsibleContent(maxHeight = CONST_USER_MESSAGE_MAX_HEIGHT,200px)
40
+ │ v-if: cite 为数组 → KeyValueContent(title + key/value 列表)
41
+ │ v-else-if: 文档含标签 → MentionText(还原 @ 选中的资源)
42
+ │ v-else-if: content → TextContent × N(textParts 中每个文本片段一个实例)
43
+
44
+ └── MessageTools(.ai-user-message-tools)
45
+ v-if: messageToolsStatus !== 'hidden'
46
+ visibility: hidden(默认)→ visible(:hover 时)
47
+ tools: [copy, edit, delete],updateTools: []
48
+ #prepend slot → MessageTime(createdAt,工具图标左侧)
49
+ ```
50
+
51
+ > **时间随工具栏显隐**:时间位于工具栏内,与工具按钮共用 `visibility` 控制,因此同样在悬停消息时才可见。
52
+
53
+ **编辑模式**(点击 `edit` 按钮后 `isEdit=true`)
54
+
55
+ ```
56
+ .ai-user-message
57
+ ├── CiteContent(同上,不受编辑模式影响)
58
+
59
+ ├── ShortcutRender(v-if: shortcut 有值)
60
+ │ @close → isEdit=false
61
+ │ @submit(formModel) → onShortcutConfirm(formModel) + isEdit=false
62
+
63
+ └── ChatInput(v-else,带自定义 #send-icon slot)
64
+ v-model: editContent(有富文本文档时用文档回填,否则取 textParts[0])
65
+ defaultUploadFiles: binaryFiles
66
+ menuSources: injectGlobalConfig().menuSources
67
+ #send-icon slot → .user-edit-footer
68
+ Button "取消" → isEdit=false
69
+ Button primary "发送" → chatInputRef.triggerSendMessage() + isEdit=false
70
+ ```
71
+
72
+ ## 资源标签回显与正文折叠
73
+
74
+ **标签回显**:`property.docSchema` 是发送时输入框的富文本文档。**只有文档里真的含标签节点时**才走 [MentionText](/components/rendering/mention-text) 结构化渲染,纯文本文档仍走 `TextContent`——历史消息与第三方消息的表现因此保持不变。`content` 始终是纯文本,后端契约不变。
75
+
76
+ **附件标签不重复展示**:`ChatInput` 发送时会把待发送附件补成 `artifact` 标签写进文档,本组件在渲染与编辑回填前会剥掉 `value` 命中当前附件的那些标签(`outputId` 与 `id` 都参与匹配,历史消息经 chat-helper 转换后只剩 `id`),同一文件只由 `FileContent` 卡片承载。整行标签被剥掉后不留空行,用户手输的空行照常保留;`@` 选中的其它资源、以及没有附件承载的 `artifact` 标签都照常回显。
77
+
78
+ 编辑态同样以 `docSchema` 回填,否则改完这条消息已选资源会退化成纯文本;因此业务侧在 `onInputConfirm` 里要把新的 `docSchema` 一起写回。
79
+
80
+ **正文折叠**:正文外层套 [CollapsibleContent](/components/rendering/collapsible-content),超过 `CONST_USER_MESSAGE_MAX_HEIGHT`(200px)时折叠并展示「显示更多 / 收起」。
81
+
82
+ **编辑态自动聚焦**:点击 `edit` 后编辑态输入框才开始渲染,组件在 `nextTick` 后调用 `focus()`,光标落到已有内容末尾。
83
+
84
+ ## 基础用法
85
+
86
+ `content` 为字符串时,通过 `TextContent` 以**纯文本**插值渲染(`{{ content }}`),**不**走 Markdown。
87
+
88
+ ```vue
89
+ <template>
90
+ <MessageRender
91
+ :message="message"
92
+ :on-action="handleAction"
93
+ />
94
+ </template>
95
+
96
+ <script setup lang="ts">
97
+ import { MessageRender, MessageRole, MessageStatus, type IToolBtn } from '@blueking/chat-x';
98
+
99
+ const message = {
100
+ id: '1',
101
+ messageId: '1',
102
+ role: MessageRole.User,
103
+ content: '你好,请帮我分析以下这段 Python 代码的性能瓶颈。',
104
+ status: MessageStatus.Complete,
105
+ };
106
+
107
+ const handleAction = async (tool: IToolBtn) => {
108
+ // copy / edit 有内置行为;delete 需业务侧处理
109
+ console.log('工具操作:', tool.id);
110
+ };
111
+ </script>
112
+ ```
113
+
114
+ > **工具栏**:悬停时显示「复制」「编辑」「删除」(CSS `visibility`,始终占位)。
115
+
116
+ ## 多媒体消息
117
+
118
+ `content` 为数组时,同时支持文本(`type: 'text'`)和二进制文件(`type: 'binary'`)。组件将 `binary` 项按图片和非图片分为两组:
119
+
120
+ - **图片文件**(`binaryImageFiles`):判断 `url` 存在或 `mimeType` / `file.type` 以 `image/` 开头的文件,统一放入一个 `FileContent`(`readonly=true`)中渲染,支持点击缩略图全屏预览
121
+ - **非图片文件**(`binaryNonImageFiles`):每个文件单独渲染在 `FileContent`(`readonly=true`)中
122
+
123
+ `text` 项经 `textParts` 计算属性统一为 `string[]`,按顺序各渲染一个 `TextContent`。
124
+
125
+ ```vue
126
+ <script setup lang="ts">
127
+ import { MessageRender, MessageContentType, MessageRole, MessageStatus } from '@blueking/chat-x';
128
+
129
+ const message = {
130
+ id: '1',
131
+ messageId: '1',
132
+ role: MessageRole.User,
133
+ status: MessageStatus.Complete,
134
+ content: [
135
+ {
136
+ type: MessageContentType.Binary,
137
+ url: 'https://example.com/screenshot.png',
138
+ mimeType: 'image/png',
139
+ filename: 'screenshot.png',
140
+ },
141
+ {
142
+ type: MessageContentType.Text,
143
+ text: '请帮我分析这张架构图,指出其中的问题。',
144
+ },
145
+ ],
146
+ };
147
+ </script>
148
+ ```
149
+
150
+ ## 带引用的消息
151
+
152
+ 通过 `property.extra.cite` 传入引用内容,支持两种格式,渲染位置不同:
153
+
154
+ | `cite` 类型 | 渲染组件 | 渲染位置 |
155
+ | ------------------------- | ------------------------------------------------ | ---------------- |
156
+ | `string` | `CiteContent`(紧凑条带,高 28px,文本单行截断) | 气泡**外部上方** |
157
+ | `{ title?, data[] }` 对象 | `KeyValueContent`(键值对列表) | 气泡**内部** |
158
+
159
+ ### 文本引用
160
+
161
+ `cite` 为字符串时,在气泡上方显示一个带引用图标的灰色条带(`#f5f7fa`),文本过长时截断。
162
+
163
+ ```vue
164
+ <script setup lang="ts">
165
+ // 消费方将 property 挂在 message 上,经 MessageRender 透传
166
+ const message = {
167
+ role: 'user',
168
+ content: '这段代码每次循环都发起请求,应该如何优化?',
169
+ property: {
170
+ extra: {
171
+ cite: '// 原始代码\nfor (let i = 0; i < arr.length; i++) {\n fetch(`/api/${arr[i]}`)\n}',
172
+ },
173
+ },
174
+ };
175
+ </script>
176
+ ```
177
+
178
+ ### 结构化引用(键值对)
179
+
180
+ `cite` 为对象 `{ title?, data: { key, value }[] }` 时,引用内容渲染在气泡**内部**(`KeyValueContent` 组件):
181
+
182
+ ```vue
183
+ <script setup lang="ts">
184
+ const message = {
185
+ role: 'user',
186
+ content: '请帮我分析这份报表的数据趋势。',
187
+ property: {
188
+ extra: {
189
+ cite: {
190
+ title: '销售数据分析',
191
+ type: 'structured',
192
+ data: [
193
+ { key: '报表名称', value: '2024 年 Q4 销售报表' },
194
+ { key: '时间范围', value: '2024年10月 - 12月' },
195
+ { key: '数据量', value: '12,580 条' },
196
+ ],
197
+ },
198
+ },
199
+ },
200
+ };
201
+ </script>
202
+ ```
203
+
204
+ ## 快捷指令消息
205
+
206
+ 当消息来自快捷指令时,`property.extra.shortcut` 中携带快捷指令对象。在**编辑模式**下,组件渲染 `ShortcutRender` 代替普通 `ChatInput`。
207
+
208
+ `shortcut` computed 支持两条来源路径:
209
+
210
+ ```
211
+ 1. property.extra.shortcut 有值 → 直接使用
212
+ 2. property.extra.cite 为对象 + property.extra.context 有值
213
+ → 从 cite.data 和 context 动态构建 ShortcutComponent[] 数组
214
+ ```
215
+
216
+ ```vue
217
+ <script setup lang="ts">
218
+ const message = {
219
+ role: 'user',
220
+ content: '请帮我翻译这段文字',
221
+ property: {
222
+ extra: {
223
+ shortcut: {
224
+ id: 'translate',
225
+ name: '翻译',
226
+ components: [
227
+ {
228
+ type: 'select',
229
+ key: 'targetLang',
230
+ name: '目标语言',
231
+ default: 'en',
232
+ options: [
233
+ { label: '英文', value: 'en' },
234
+ { label: '中文', value: 'zh' },
235
+ ],
236
+ },
237
+ {
238
+ type: 'textarea',
239
+ key: 'content',
240
+ name: '翻译内容',
241
+ fillBack: true,
242
+ default: '请帮我翻译这段文字',
243
+ },
244
+ ],
245
+ formModel: { targetLang: 'en', content: '请帮我翻译这段文字' },
246
+ },
247
+ },
248
+ },
249
+ };
250
+ </script>
251
+ ```
252
+
253
+ ## 消息编辑
254
+
255
+ 点击「编辑」按钮后进入编辑模式,根据消息类型呈现不同界面:
256
+
257
+ | 消息类型 | 编辑界面 | 确认回调 |
258
+ | -------------------------------------------- | ----------------------------------------------------- | ------------------- |
259
+ | 普通文本 / 含文件消息 | `ChatInput`(自定义 `#send-icon`,含"取消/发送"按钮) | `onInputConfirm` |
260
+ | 含 `property.extra.shortcut` 或 cite+context | `ShortcutRender` | `onShortcutConfirm` |
261
+
262
+ **`editContent` 的初始化逻辑**(仅文本部分,二进制文件通过 `defaultUploadFiles` 恢复):
263
+
264
+ ```
265
+ 文档含标签 → editContent = property.docSchema(保留已选资源)
266
+ 否则 textParts 有值 → editContent = textParts[0](取第一个文本片段)
267
+ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
268
+ 进入编辑态后 → nextTick 后自动 focus,光标落在内容末尾
269
+ ```
270
+
271
+ `textParts` 由 `content` 统一计算:`string` 转为单元素数组,`InputContent[]` 则过滤出 `type: 'text'` 且非空的项并映射为 `string[]`。
272
+
273
+ ```vue
274
+ <template>
275
+ <MessageRender
276
+ :message="message"
277
+ :on-action="handleAction"
278
+ :on-input-confirm="handleInputConfirm"
279
+ :on-shortcut-confirm="handleShortcutConfirm"
280
+ />
281
+ </template>
282
+
283
+ <script setup lang="ts">
284
+ import {
285
+ MessageRender,
286
+ MessageRole,
287
+ MessageStatus,
288
+ type IToolBtn,
289
+ type TagSchema,
290
+ type UserMessage,
291
+ } from '@blueking/chat-x';
292
+
293
+ const message = {
294
+ id: '1',
295
+ messageId: '1',
296
+ role: MessageRole.User,
297
+ content: '请帮我优化这段代码',
298
+ status: MessageStatus.Complete,
299
+ };
300
+
301
+ const handleAction = async (tool: IToolBtn) => {
302
+ // edit → 组件内切编辑态;copy → 组件内复制
303
+ // delete → 无内置行为,业务侧处理(如删除会话消息)
304
+ console.log('工具:', tool.id);
305
+ };
306
+
307
+ const handleInputConfirm = async (content: UserMessage['content'], docSchema: TagSchema) => {
308
+ console.log('编辑后内容:', content, docSchema);
309
+ };
310
+
311
+ const handleShortcutConfirm = async (formModel: Record<string, unknown>) => {
312
+ console.log('快捷指令表单:', formModel);
313
+ };
314
+ </script>
315
+ ```
316
+
317
+ ## 工具按钮
318
+
319
+ 工具栏使用 CSS `visibility` 控制可见性(非 `display`),始终占位,hover 时显示:
320
+
321
+ **内置工具列表(`CONST_USER_MESSAGE_TOOLS`)**
322
+
323
+ | 工具 ID | 名称 | 内置行为 |
324
+ | -------- | ---- | -------------------------------------------- |
325
+ | `copy` | 复制 | 字符串直接复制;数组 `JSON.stringify` 后复制 |
326
+ | `edit` | 编辑 | 切换 `isEdit=true`,进入编辑模式并自动聚焦 |
327
+ | `delete` | 删除 | 无内置行为,需通过 `onAction` 外部处理 |
328
+
329
+ > `cite`(引用)已从内置列表移除,后续不再支持;需要类似能力时通过 `messageTools` 自行追加按钮并在 `onAction` 中处理。
330
+
331
+ 可通过 `messageTools` 按 id 覆盖/追加,`{ id: 'edit', hidden: true }` 可隐藏内置项。
332
+
333
+ ```vue
334
+ <!-- 经 MessageRender 控制工具栏状态 -->
335
+ <MessageRender
336
+ :message="message"
337
+ message-tools-status="hidden"
338
+ />
339
+ <MessageRender
340
+ :message="message"
341
+ message-tools-status="disabled"
342
+ />
343
+ ```
344
+
345
+ ## 全局配置透传
346
+
347
+ 编辑态 `ChatInput` 的上传能力与菜单数据源都来自 `injectGlobalConfig()`——`supportUpload` 与 `menuSources`(通常由 `ChatContainer` 注册)。自定义 `#message` 插槽时须把同一配置链路保留,否则编辑态会与主输入区不一致(菜单为空、无法上传)。
348
+
349
+ ```vue
350
+ <template>
351
+ <ChatContainer
352
+ :messages="messages"
353
+ :support-upload="true"
354
+ :on-agent-action="handleAgentAction"
355
+ :on-user-action="handleUserAction"
356
+ >
357
+ <template #message="{ message, messageToolsStatus, onInterruptResume }">
358
+ <MessageRender
359
+ :message="message"
360
+ :message-tools-status="messageToolsStatus"
361
+ :on-action="handleUserAction"
362
+ :on-input-confirm="(content, docSchema) => handleUserInputConfirm(message, content, docSchema)"
363
+ :on-shortcut-confirm="formModel => handleUserShortcutConfirm(message, formModel)"
364
+ :on-interrupt-resume="onInterruptResume"
365
+ />
366
+ </template>
367
+ </ChatContainer>
368
+ </template>
369
+ ```
370
+
371
+ ## API
372
+
373
+ ### Props
374
+
375
+ | 属性名 | 类型 | 说明 |
376
+ | ------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- |
377
+ | content | `string \| InputContent[]` | 消息内容,字符串或含 text/binary 的数组 |
378
+ | createdAt | `number \| string` | 消息创建时间,经 `MessageTools` 的 `#prepend` 插槽交给 `MessageTime` 渲染在工具图标左侧;无值时不展示 |
379
+ | property | `{ docSchema?: TagSchema; extra?: MessageExtra; artifacts?: AIFileInfo[] }` | 附加属性;本组件消费 `docSchema` 与 `extra.cite` / `extra.shortcut` / `extra.context` |
380
+ | messageTools | `IToolBtn[]` | 自定义用户消息工具组;按 id 与 `CONST_USER_MESSAGE_TOOLS` 合并,`{ id, hidden: true }` 可隐藏 |
381
+ | messageToolsStatus | `MessageToolsStatus` | 工具按钮状态,`disabled` 禁用、`hidden` 从 DOM 移除 |
382
+ | onAction | `MessageToolsProps['onAction']` | 工具回调;`copy`/`edit` 有内置行为,`delete` 需外部处理 |
383
+ | onInputConfirm | `(content: UserMessage['content'], docSchema: TagSchema) => Promise<void>` | 普通消息编辑确认回调 |
384
+ | onShortcutConfirm | `(formModel: Record<string, unknown>) => Promise<void>` | 快捷指令消息编辑确认回调 |
385
+ | tippyOptions | `Partial<Omit<TippyOptions, 'getReferenceClientRect' \| 'triggerTarget'>>` | 自定义工具栏 Tippy 配置,透传给内部 `MessageTools` |
386
+
387
+ ### Events / Slots / Expose
388
+
389
+ 无。
390
+
391
+ ### 全局配置依赖
392
+
393
+ 编辑态 `ChatInput` 通过 `injectGlobalConfig()` 读取 `supportUpload` 与 `menuSources`(缺省为空数组,即编辑态无菜单)。祖先需已 `useGlobalConfig()`(通常由 `ChatContainer` 注册)。
394
+
395
+ ## 类型定义
396
+
397
+ ```typescript
398
+ // 文本内容项
399
+ interface TextInputContent {
400
+ type: 'text';
401
+ text: string;
402
+ }
403
+
404
+ // 二进制内容项(图片、文件)
405
+ interface BinaryContent {
406
+ type: 'binary';
407
+ url?: string;
408
+ mimeType?: string;
409
+ filename?: string;
410
+ }
411
+
412
+ type InputContent = TextInputContent | BinaryContent;
413
+
414
+ // property.extra(与源码 BaseMessage.property.extra 对齐)
415
+ type MessageExtra = {
416
+ // 文本引用 或 结构化引用(互斥 union,不是两个同名字段)
417
+ cite?:
418
+ | string
419
+ | {
420
+ title: string;
421
+ type: 'structured';
422
+ data: Array<{ key: string; value: string }>;
423
+ };
424
+ command?: string;
425
+ pause?: boolean;
426
+ shortcut?: Partial<Shortcut>;
427
+ context?: Array<{
428
+ __key: string;
429
+ __label: string;
430
+ __value: string;
431
+ fillBack?: boolean;
432
+ context_type?: string;
433
+ }>;
434
+ };
435
+ ```
436
+
437
+ ## 关联组件
438
+
439
+ - [MessageRender](/components/message/message-render) — user 角色由其实例化
440
+ - [MentionText](/components/rendering/mention-text) — 含标签文档的回显
441
+ - [CollapsibleContent](/components/rendering/collapsible-content) — 正文 200px 折叠
442
+ - [MessageTools](/components/feedback/message-tools) — 工具栏交互
443
+ - [MessageTime](/components/feedback/message-time) — 工具栏左侧的消息时间
444
+ - [MessageContainer](/components/setup/message-container) — 列表与多选容器