@opentiny/vue-docs 3.24.6 → 3.26.0

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 (249) hide show
  1. package/.stylelintrc.js +2 -2
  2. package/demos/apis/button.js +15 -0
  3. package/demos/apis/calendar-view.js +3 -2
  4. package/demos/apis/chart-demo.js +1 -1
  5. package/demos/apis/chart-docs.js +1 -1
  6. package/demos/apis/chart-events.js +1 -1
  7. package/demos/apis/chart-question.js +1 -1
  8. package/demos/apis/chart.js +1 -1
  9. package/demos/apis/form.js +3 -0
  10. package/demos/apis/grid.js +76 -16
  11. package/demos/apis/modal.js +1 -1
  12. package/demos/apis/numeric.js +3 -3
  13. package/demos/apis/search.js +28 -0
  14. package/demos/apis/slider-button.js +22 -0
  15. package/demos/apis/split.js +11 -0
  16. package/demos/apis/steps.js +3 -3
  17. package/demos/apis/tabs.js +12 -0
  18. package/demos/apis/time-line.js +20 -0
  19. package/demos/mobile-first/app/button/type.vue +1 -1
  20. package/demos/mobile-first/app/button/webdoc/button.js +2 -2
  21. package/demos/mobile-first/app/slider-button/basic-usage.vue +5 -5
  22. package/demos/mobile-first/app/slider-button/webdoc/slider-button.js +1 -1
  23. package/demos/mobile-first/app/steps/advanced-steps.vue +8 -1
  24. package/demos/mobile-first/menus.js +16 -9
  25. package/demos/pc/app/action-menu/basic-usage-composition-api.vue +1 -1
  26. package/demos/pc/app/action-menu/basic-usage.vue +1 -1
  27. package/demos/pc/app/action-menu/card-mode-composition-api.vue +1 -1
  28. package/demos/pc/app/action-menu/card-mode.vue +1 -1
  29. package/demos/pc/app/action-menu/disabled-composition-api.vue +2 -2
  30. package/demos/pc/app/action-menu/disabled.vue +2 -2
  31. package/demos/pc/app/action-menu/events-composition-api.vue +1 -1
  32. package/demos/pc/app/action-menu/events.vue +1 -1
  33. package/demos/pc/app/action-menu/icon-composition-api.vue +2 -2
  34. package/demos/pc/app/action-menu/icon.vue +2 -2
  35. package/demos/pc/app/action-menu/max-show-num-composition-api.vue +1 -1
  36. package/demos/pc/app/action-menu/max-show-num.vue +1 -1
  37. package/demos/pc/app/action-menu/more-text-composition-api.vue +1 -1
  38. package/demos/pc/app/action-menu/more-text.vue +1 -1
  39. package/demos/pc/app/action-menu/popper-class-composition-api.vue +1 -1
  40. package/demos/pc/app/action-menu/popper-class.vue +1 -1
  41. package/demos/pc/app/action-menu/slot-item-composition-api.vue +1 -1
  42. package/demos/pc/app/action-menu/slot-item.vue +1 -1
  43. package/demos/pc/app/action-menu/spacing-composition-api.vue +1 -1
  44. package/demos/pc/app/action-menu/spacing.vue +1 -1
  45. package/demos/pc/app/action-menu/text-field-composition-api.vue +1 -1
  46. package/demos/pc/app/action-menu/text-field.spec.ts +1 -1
  47. package/demos/pc/app/action-menu/text-field.vue +1 -1
  48. package/demos/pc/app/amount/custom-service.spec.js +4 -4
  49. package/demos/pc/app/base-select/slot-reference.spec.ts +1 -1
  50. package/demos/pc/app/button/icon-composition-api.vue +3 -1
  51. package/demos/pc/app/button/icon.vue +3 -1
  52. package/demos/pc/app/button/webdoc/button.js +3 -2
  53. package/demos/pc/app/calendar-view/calendar-mode-composition-api.vue +7 -1
  54. package/demos/pc/app/calendar-view/calendar-mode.spec.ts +3 -0
  55. package/demos/pc/app/calendar-view/calendar-mode.vue +7 -1
  56. package/demos/pc/app/carousel/webdoc/carousel.js +0 -18
  57. package/demos/pc/app/color-picker/alpha-composition-api.vue +1 -1
  58. package/demos/pc/app/color-picker/alpha.spec.ts +2 -2
  59. package/demos/pc/app/color-picker/alpha.vue +1 -1
  60. package/demos/pc/app/color-picker/base.spec.ts +2 -2
  61. package/demos/pc/app/color-picker/default-visible.spec.ts +1 -1
  62. package/demos/pc/app/color-picker/event-composition-api.vue +2 -2
  63. package/demos/pc/app/color-picker/event.spec.ts +4 -4
  64. package/demos/pc/app/color-picker/event.vue +1 -1
  65. package/demos/pc/app/color-picker/format.spec.ts +6 -6
  66. package/demos/pc/app/color-picker/history.spec.ts +1 -7
  67. package/demos/pc/app/color-picker/predefine.spec.ts +3 -10
  68. package/demos/pc/app/color-picker/size.spec.ts +4 -4
  69. package/demos/pc/app/color-select-panel/format.spec.ts +2 -8
  70. package/demos/pc/app/color-select-panel/history.spec.ts +0 -2
  71. package/demos/pc/app/color-select-panel/predefine.spec.ts +0 -3
  72. package/demos/pc/app/container/basic-usage-composition-api.vue +10 -10
  73. package/demos/pc/app/container/basic-usage.vue +10 -10
  74. package/demos/pc/app/container/custom-with-height-composition-api.vue +8 -8
  75. package/demos/pc/app/container/custom-with-height.vue +10 -10
  76. package/demos/pc/app/date-panel/custom-week.spec.ts +2 -2
  77. package/demos/pc/app/dialog-select/nest-grid-single.spec.ts +40 -0
  78. package/demos/pc/app/dialog-select/nest-tree-multi.spec.ts +53 -0
  79. package/demos/pc/app/dialog-select/nest-tree-single.spec.ts +25 -0
  80. package/demos/pc/app/dialog-select/set-selection.spec.ts +20 -0
  81. package/demos/pc/app/file-upload/before-upload-limit-composition-api.vue +1 -1
  82. package/demos/pc/app/file-upload/before-upload-limit.spec.ts +1 -1
  83. package/demos/pc/app/file-upload/before-upload-limit.vue +1 -1
  84. package/demos/pc/app/file-upload/custom-trigger-composition-api.vue +1 -1
  85. package/demos/pc/app/file-upload/custom-trigger.spec.ts +1 -1
  86. package/demos/pc/app/file-upload/custom-trigger.vue +1 -1
  87. package/demos/pc/app/file-upload/custom-upload-tip-composition-api.vue +1 -1
  88. package/demos/pc/app/file-upload/custom-upload-tip.vue +1 -1
  89. package/demos/pc/app/file-upload/form-validation-composition-api.vue +1 -1
  90. package/demos/pc/app/file-upload/form-validation.vue +1 -1
  91. package/demos/pc/app/file-upload/image-size-composition-api.vue +1 -1
  92. package/demos/pc/app/file-upload/image-size.spec.ts +1 -1
  93. package/demos/pc/app/file-upload/image-size.vue +1 -1
  94. package/demos/pc/app/file-upload/multiple-file-composition-api.vue +1 -1
  95. package/demos/pc/app/file-upload/multiple-file.spec.ts +1 -1
  96. package/demos/pc/app/file-upload/multiple-file.vue +1 -1
  97. package/demos/pc/app/file-upload/prevent-delete-file-composition-api.vue +1 -1
  98. package/demos/pc/app/file-upload/prevent-delete-file.vue +1 -1
  99. package/demos/pc/app/file-upload/upload-request-composition-api.vue +1 -1
  100. package/demos/pc/app/file-upload/upload-request.spec.ts +2 -2
  101. package/demos/pc/app/file-upload/upload-request.vue +1 -1
  102. package/demos/pc/app/grid/base/basic-usage-composition-api.vue +1 -17
  103. package/demos/pc/app/grid/custom/column-fixed.spec.js +2 -1
  104. package/demos/pc/app/grid/custom/page-size.spec.js +1 -1
  105. package/demos/pc/app/grid/data-source/auto-load.spec.js +0 -1
  106. package/demos/pc/app/grid/data-source/request-service.spec.js +1 -1
  107. package/demos/pc/app/grid/data-source/static-data.spec.js +1 -1
  108. package/demos/pc/app/grid/dynamically-columns/dynamically-columns.spec.js +2 -1
  109. package/demos/pc/app/grid/edit/scrollbar-not-blur-composition-api.vue +119 -0
  110. package/demos/pc/app/grid/edit/scrollbar-not-blur.spec.ts +28 -0
  111. package/demos/pc/app/grid/edit/scrollbar-not-blur.vue +129 -0
  112. package/demos/pc/app/grid/editor/custom-edit.spec.js +7 -2
  113. package/demos/pc/app/grid/empty/empty-data-iscenter.spec.js +1 -1
  114. package/demos/pc/app/grid/event/toolbar-button-click-event.spec.js +1 -1
  115. package/demos/pc/app/grid/expand/expand-trigger-slot-composition-api.vue +85 -0
  116. package/demos/pc/app/grid/expand/expand-trigger-slot.spec.ts +11 -0
  117. package/demos/pc/app/grid/expand/expand-trigger-slot.vue +95 -0
  118. package/demos/pc/app/grid/expand/set-row-expansion.spec.js +4 -0
  119. package/demos/pc/app/grid/filter/custom-filter.spec.js +3 -3
  120. package/demos/pc/app/grid/filter/default-filter-composition-api.vue +6 -0
  121. package/demos/pc/app/grid/filter/default-filter.vue +6 -0
  122. package/demos/pc/app/grid/filter/default-relation.spec.js +1 -1
  123. package/demos/pc/app/grid/filter/server-filter.spec.js +1 -1
  124. package/demos/pc/app/grid/filter/simple-filter.spec.ts +5 -4
  125. package/demos/pc/app/grid/fixed/right-fixed-composition-api.vue +4 -4
  126. package/demos/pc/app/grid/fixed/right-fixed.vue +4 -4
  127. package/demos/pc/app/grid/footer/footer-summation-empty.spec.js +0 -1
  128. package/demos/pc/app/grid/large-data/full-data-loading.spec.js +10 -3
  129. package/demos/pc/app/grid/large-data/virtual-rolling.spec.js +9 -2
  130. package/demos/pc/app/grid/mouse-keyboard/keyboard-navigation.spec.js +4 -1
  131. package/demos/pc/app/grid/renderer/inner-renderer-date-composition-api.vue +4 -3
  132. package/demos/pc/app/grid/renderer/inner-renderer-date.spec.js +2 -2
  133. package/demos/pc/app/grid/renderer/inner-renderer-date.vue +3 -3
  134. package/demos/pc/app/grid/renderer/inner-renderer.spec.js +4 -0
  135. package/demos/pc/app/grid/size/max-min-grid-height.spec.js +2 -2
  136. package/demos/pc/app/grid/slot/slot-conf-composition-api.vue +141 -0
  137. package/demos/pc/app/grid/slot/slot-conf.spec.js +12 -0
  138. package/demos/pc/app/grid/slot/slot-conf.vue +151 -0
  139. package/demos/pc/app/grid/sort/combinations-sort.spec.js +2 -2
  140. package/demos/pc/app/grid/webdoc/grid-edit.js +12 -0
  141. package/demos/pc/app/grid/webdoc/grid-empty.js +1 -1
  142. package/demos/pc/app/grid/webdoc/grid-expand.js +11 -0
  143. package/demos/pc/app/grid/webdoc/grid-slot.js +9 -0
  144. package/demos/pc/app/icon/iconGroups.js +8 -2
  145. package/demos/pc/app/input/basic-usage.spec.ts +1 -1
  146. package/demos/pc/app/loading/background.spec.ts +3 -1
  147. package/demos/pc/app/loading/custom-class.spec.ts +4 -2
  148. package/demos/pc/app/loading/fullscreen.spec.ts +6 -4
  149. package/demos/pc/app/loading/loading-tip-text.spec.ts +3 -1
  150. package/demos/pc/app/loading/size.spec.ts +5 -3
  151. package/demos/pc/app/locales/custom-service-composition-api.vue +3 -3
  152. package/demos/pc/app/locales/custom-service.spec.ts +1 -1
  153. package/demos/pc/app/locales/custom-service.vue +3 -3
  154. package/demos/pc/app/modal/basic-usage.spec.ts +2 -1
  155. package/demos/pc/app/modal/message-close.spec.ts +2 -2
  156. package/demos/pc/app/modal/message-id.spec.ts +2 -2
  157. package/demos/pc/app/modal/modal-fn-slots.spec.ts +5 -7
  158. package/demos/pc/app/modal/modal-header.spec.ts +2 -1
  159. package/demos/pc/app/numeric/input-event-composition-api.vue +26 -0
  160. package/demos/pc/app/numeric/input-event.spec.ts +15 -0
  161. package/demos/pc/app/numeric/input-event.vue +34 -0
  162. package/demos/pc/app/numeric/webdoc/numeric.js +12 -0
  163. package/demos/pc/app/pager/align-composition-api.vue +10 -13
  164. package/demos/pc/app/pager/align.spec.ts +8 -3
  165. package/demos/pc/app/pager/align.vue +11 -5
  166. package/demos/pc/app/pager/page-size-composition-api.vue +2 -2
  167. package/demos/pc/app/pager/page-size.spec.ts +1 -1
  168. package/demos/pc/app/pager/page-size.vue +2 -2
  169. package/demos/pc/app/pager/pager-in-grid-composition-api.vue +0 -1
  170. package/demos/pc/app/pager/pager-in-grid.vue +0 -1
  171. package/demos/pc/app/pager/popper-append-to-body-composition-api.vue +1 -7
  172. package/demos/pc/app/pager/popper-append-to-body.vue +1 -7
  173. package/demos/pc/app/pager/popper-class-composition-api.vue +1 -7
  174. package/demos/pc/app/pager/popper-class.vue +1 -7
  175. package/demos/pc/app/popeditor/conditions.spec.ts +1 -1
  176. package/demos/pc/app/popeditor/suggest.spec.ts +1 -1
  177. package/demos/pc/app/qr-code/icon-composition-api.vue +17 -3
  178. package/demos/pc/app/qr-code/icon.spec.ts +19 -0
  179. package/demos/pc/app/qr-code/icon.vue +25 -4
  180. package/demos/pc/app/qr-code/style-composition-api.vue +2 -9
  181. package/demos/pc/app/qr-code/style.spec.ts +18 -1
  182. package/demos/pc/app/qr-code/style.vue +11 -8
  183. package/demos/pc/app/query-builder/webdoc/query-builder.js +5 -3
  184. package/demos/pc/app/search/events.spec.ts +1 -1
  185. package/demos/pc/app/search/events.vue +9 -0
  186. package/demos/pc/app/search/slot-prefix-suffix.spec.ts +1 -1
  187. package/demos/pc/app/search/webdoc/search.js +12 -4
  188. package/demos/pc/app/select/nest-grid-remote.spec.ts +3 -3
  189. package/demos/pc/app/select/nest-grid.spec.ts +1 -1
  190. package/demos/pc/app/select/nest-radio-grid-much-data.spec.ts +5 -7
  191. package/demos/pc/app/tabs/basic-usage.spec.ts +2 -2
  192. package/demos/pc/app/tabs/header-only.vue +56 -0
  193. package/demos/pc/app/tabs/size.spec.ts +2 -2
  194. package/demos/pc/app/tabs/webdoc/tabs.js +12 -0
  195. package/demos/pc/app/time-line/slot-default-composition-api.vue +81 -0
  196. package/demos/pc/app/time-line/slot-default.spec.ts +13 -0
  197. package/demos/pc/app/time-line/slot-default.vue +95 -0
  198. package/demos/pc/app/time-line/webdoc/time-line.js +12 -0
  199. package/demos/pc/menus.js +20 -10
  200. package/demos/pc/webdoc/changelog-en.md +224 -197
  201. package/demos/pc/webdoc/changelog.md +167 -387
  202. package/demos/pc/webdoc/faq.md +14 -0
  203. package/demos/saas/menus.js +2 -14
  204. package/env/.env +3 -0
  205. package/package.json +25 -24
  206. package/playground/App.vue +2 -2
  207. package/postcss.config.cjs +1 -0
  208. package/src/App.vue +26 -59
  209. package/src/components/anchor.vue +5 -1
  210. package/src/components/demo.vue +18 -7
  211. package/src/components/design-token.vue +90 -0
  212. package/src/components/float-settings.vue +4 -23
  213. package/src/components/mcp-docs.vue +4 -26
  214. package/src/components/version-tip.vue +1 -1
  215. package/src/composable/useTinyRemoter.ts +176 -0
  216. package/src/composable/utils.ts +2 -166
  217. package/src/const.ts +6 -1
  218. package/src/i18n/en.json +2 -0
  219. package/src/i18n/es.json +47 -0
  220. package/src/i18n/index.js +24 -5
  221. package/src/i18n/pt.json +47 -0
  222. package/src/i18n/zh.json +2 -0
  223. package/src/main.js +17 -13
  224. package/src/{menus.jsx → menus.js} +0 -1
  225. package/src/router.js +3 -18
  226. package/src/tools/appData.js +6 -16
  227. package/src/tools/storage.js +5 -3
  228. package/src/tools/useApiMode.js +11 -3
  229. package/src/tools/useBulletin.jsx +9 -8
  230. package/src/tools/useStyleSettings.js +8 -0
  231. package/src/tools/useTemplateMode.js +5 -1
  232. package/src/tools/utils.js +32 -1
  233. package/src/views/components-doc/cmp-config.js +13 -1
  234. package/src/views/components-doc/common.vue +42 -15
  235. package/src/views/layout/layout.vue +5 -8
  236. package/src/views/overview.vue +1 -1
  237. package/tsconfig.node.json +2 -4
  238. package/src/components/MessageCard.vue +0 -117
  239. package/src/components/tiny-robot-chat.vue +0 -128
  240. package/src/composable/DifyModelProvider.ts +0 -65
  241. package/src/composable/useTinyRobot.ts +0 -167
  242. package/src/tools/useAllTaskFinish.ts +0 -0
  243. package/src/views/comprehensive/Demo.vue +0 -212
  244. package/src/views/comprehensive/index.vue +0 -380
  245. package/src/views/comprehensive/products.json +0 -98
  246. package/src/views/comprehensive/types/index.ts +0 -37
  247. package/src/views/remoter/index.vue +0 -63
  248. package/src/views/remoter/sound.vue +0 -349
  249. /package/demos/pc/app/grid/expand/{expand-config.spec.js → expand-config.spec.ts} +0 -0
@@ -1,65 +0,0 @@
1
- import type { ChatCompletionRequest } from '@opentiny/tiny-robot-kit'
2
- import type { AIModelConfig } from '@opentiny/tiny-robot-kit'
3
- import type { ChatCompletionResponse } from '@opentiny/tiny-robot-kit'
4
- import type { StreamHandler } from '@opentiny/tiny-robot-kit'
5
- import { BaseModelProvider } from '@opentiny/tiny-robot-kit'
6
- import { globalConversation, handleSSEStream } from './utils.js'
7
- import type { Ref } from 'vue'
8
-
9
- /**
10
- * 对接AIClient的自定义 Dify 大模型服务
11
- *
12
- * const client = new AIClient({
13
- * provider: 'custom',
14
- * providerImplementation: new CustomModelProvider( config )
15
- * });
16
- */
17
- export class DifyModelProvider extends BaseModelProvider {
18
- _messages: Ref<ChatCompletionRequest['messages']> = []
19
-
20
- constructor(config: AIModelConfig) {
21
- super(config)
22
- }
23
- /** 同步请示不需要实现 */
24
- chat(request: ChatCompletionRequest): Promise<ChatCompletionResponse> {
25
- throw new Error('Method not implemented.')
26
- }
27
-
28
- /** 异步流式请求 */
29
- async chatStream(request: ChatCompletionRequest, handler: StreamHandler): Promise<void> {
30
- const { signal } = request
31
- this.validateRequest(request)
32
-
33
- try {
34
- // 验证请求的messages属性,必须是数组,且每个消息必须有role\content属性
35
- const lastMessage = request.messages[request.messages.length - 1].content
36
- // 模拟异步流式响应
37
- const response = await fetch(`${this.config.apiUrl}/chat-messages`, {
38
- method: 'POST',
39
- headers: {
40
- 'Content-Type': 'application/json',
41
- 'Authorization': `Bearer ${this.config.apiKey}`,
42
- 'Accept': 'text/event-stream'
43
- },
44
- body: JSON.stringify({
45
- query: lastMessage,
46
- user: 'user',
47
- response_mode: 'streaming',
48
- inputs: {
49
- sessionId: globalConversation.sessionId
50
- },
51
- conversation_id: globalConversation.id
52
- })
53
- })
54
-
55
- await handleSSEStream(response, handler, this._messages, signal)
56
- } catch (error) {
57
- if (signal && signal.aborted) {
58
- console.warn('Request was aborted:', error)
59
- } else {
60
- console.error('Error in chatStream:', error)
61
- // handler.onError(handleRequestError(error))
62
- }
63
- }
64
- }
65
- }
@@ -1,167 +0,0 @@
1
- import type { AIModelConfig } from '@opentiny/tiny-robot-kit'
2
- import { AIClient, useConversation } from '@opentiny/tiny-robot-kit'
3
- import { IconAi, IconUser } from '@opentiny/tiny-robot-svgs'
4
- import { h, nextTick, onMounted, ref, watch } from 'vue'
5
- import { DifyModelProvider } from './DifyModelProvider.js'
6
- import type { SuggestionItem } from '@opentiny/tiny-robot'
7
-
8
- const difyConfig: AIModelConfig = {
9
- provider: 'custom',
10
- apiUrl: 'https://api.dify.ai/v1',
11
- apiKey: 'app-H0VJI4LqZ4KskdcA5a07pjXf'
12
- }
13
- export function useTinyRobot() {
14
- const difyModelProvider = new DifyModelProvider(difyConfig)
15
- const client = new AIClient({
16
- providerImplementation: difyModelProvider,
17
- ...difyConfig
18
- })
19
-
20
- const fullscreen = ref(false)
21
- const show = ref(true)
22
-
23
- const aiAvatar = h(IconAi, { style: { fontSize: '32px' } })
24
- const userAvatar = h(IconUser, { style: { fontSize: '32px' } })
25
- const welcomeIcon = h(IconAi, { style: { fontSize: '48px' } })
26
-
27
- const promptItems = [
28
- {
29
- label: '识别网页的内容',
30
- description: '公司人员表中员工最多和最少的公司,帮我统计一下!',
31
- icon: h('span', { style: { fontSize: '18px' } }, '💡')
32
- },
33
- {
34
- label: '智能操作网页',
35
- description: '请帮我选中公司人员表中员工最多的公司',
36
- icon: h('span', { style: { fontSize: '18px' } }, '🕹')
37
- }
38
- ]
39
- const handlePromptItemClick = (ev, item) => {
40
- sendMessage(item.description)
41
- }
42
-
43
- const { messageManager } = useConversation({ client })
44
- const { messages, messageState, inputMessage, sendMessage, abortRequest } = messageManager
45
- difyModelProvider._messages = messages
46
-
47
- const roles = {
48
- assistant: {
49
- type: 'markdown',
50
- placement: 'start',
51
- avatar: aiAvatar,
52
- maxWidth: '80%'
53
- },
54
- user: {
55
- placement: 'end',
56
- avatar: userAvatar,
57
- maxWidth: '80%'
58
- }
59
- }
60
-
61
- // 建议按钮组,设置对话的模板
62
- const suggestionPillItems = [
63
- {
64
- id: '1',
65
- text: '公司人员表',
66
- icon: h('span', { style: { fontSize: '18px' } }, '🏢')
67
- }
68
- ]
69
-
70
- function handleSuggestionPillItemClick(item: SuggestionItem) {
71
- let templateText = `请对 [目标组件] ,执行 [操作]`
72
- let currentInitialValue = { 目标组件: item.text, 操作: '' }
73
-
74
- if (senderRef.value) {
75
- senderRef.value.setTemplate(templateText, currentInitialValue)
76
- }
77
- }
78
-
79
- const senderRef = ref(null)
80
- const currentTemplate = ref('')
81
- const suggestionOpen = ref(false)
82
-
83
- // 清除当前指令
84
- const clearTemplate = () => {
85
- // 清空指令相关状态
86
- currentTemplate.value = ''
87
-
88
- // 确保重新聚焦到输入框
89
- nextTick(() => {
90
- senderRef.value?.focus()
91
- })
92
- }
93
-
94
- // 发送消息
95
- const handleSendMessage = () => {
96
- sendMessage(inputMessage.value)
97
-
98
- clearTemplate()
99
- }
100
-
101
- const handleMessageKeydown = (event, triggerFn, suggestionKeyDown) => {
102
- // 如果指令面板已打开,交给 suggestion 组件处理键盘事件
103
- if (suggestionOpen.value) {
104
- suggestionKeyDown(event)
105
- return
106
- }
107
-
108
- // 如果按下斜杠键并且不在指令编辑模式,触发指令面板
109
- if (event.key === '/' && !currentTemplate.value) {
110
- triggerFn({
111
- text: '',
112
- position: 0
113
- })
114
- }
115
-
116
- // ESC 键清除当前指令
117
- if (event.key === 'Escape' && currentTemplate.value) {
118
- event.preventDefault()
119
- clearTemplate()
120
- }
121
- }
122
-
123
- watch(
124
- () => inputMessage.value,
125
- (value) => {
126
- // 如果指令面板已打开,并且指令为空,关闭指令面板
127
- if (suggestionOpen.value && value === '') {
128
- suggestionOpen.value = false
129
- }
130
- }
131
- )
132
-
133
- // 页面加载完成后自动聚焦输入框
134
- onMounted(() => {
135
- setTimeout(() => {
136
- senderRef.value?.focus()
137
- }, 500)
138
- })
139
-
140
- return {
141
- client,
142
- fullscreen,
143
- show,
144
- aiAvatar,
145
- userAvatar,
146
- welcomeIcon,
147
- promptItems,
148
-
149
- messageManager,
150
- messages,
151
- messageState,
152
- inputMessage,
153
- sendMessage,
154
- abortRequest,
155
- roles,
156
- handlePromptItemClick,
157
-
158
- senderRef,
159
- currentTemplate,
160
- suggestionOpen,
161
- clearTemplate,
162
- handleSendMessage,
163
- handleMessageKeydown,
164
- suggestionPillItems,
165
- handleSuggestionPillItemClick
166
- }
167
- }
File without changes
@@ -1,212 +0,0 @@
1
- <template>
2
- <div class="products-page">
3
- <div class="page-header">
4
- <h3>商品管理</h3>
5
- </div>
6
- <div class="page-content">
7
- <div class="button-box">
8
- <tiny-button type="info" @click="addProductToEdit"> 添加商品 </tiny-button>
9
- <tiny-button type="danger" @click="removeProduct"> 删除商品 </tiny-button>
10
- <tiny-button type="success" @click="saveProduct"> 保存 </tiny-button>
11
- </div>
12
- <tiny-grid
13
- auto-resize
14
- ref="gridRef"
15
- :data="products"
16
- :height="500"
17
- :edit-config="{ trigger: 'click', mode: 'cell', showStatus: true }"
18
- :tiny_mcp_config="{
19
- server,
20
- business: {
21
- id: 'product-list',
22
- description: '商品列表'
23
- }
24
- }"
25
- >
26
- <tiny-grid-column type="index" width="50" />
27
- <tiny-grid-column type="selection" width="50" />
28
- <tiny-grid-column title="商品图片" width="100">
29
- <template #default="{ row }">
30
- <img :src="row.image" class="product-image" />
31
- </template>
32
- </tiny-grid-column>
33
-
34
- <tiny-grid-column field="name" title="商品名称" :editor="{ component: 'input' }" />
35
- <tiny-grid-column
36
- field="price"
37
- :editor="{
38
- component: 'input',
39
- attrs: { type: 'number' }
40
- }"
41
- title="价格"
42
- >
43
- <template #default="{ row }"> ¥{{ row.price }} </template>
44
- </tiny-grid-column>
45
- <tiny-grid-column
46
- field="stock"
47
- :editor="{
48
- component: 'input',
49
- attrs: { type: 'number' }
50
- }"
51
- title="库存"
52
- />
53
- <tiny-grid-column
54
- field="category"
55
- :editor="{
56
- component: 'select',
57
- options: [
58
- { label: '手机', value: 'phones' },
59
- { label: '笔记本', value: 'laptops' },
60
- { label: '平板', value: 'tablets' }
61
- ]
62
- }"
63
- title="分类"
64
- >
65
- <template #default="{ row }">
66
- {{ categoryLabels[row.category] }}
67
- </template>
68
- </tiny-grid-column>
69
- <tiny-grid-column
70
- field="status"
71
- :editor="{
72
- component: 'select',
73
- options: [
74
- { label: '上架', value: 'on' },
75
- { label: '下架', value: 'off' }
76
- ]
77
- }"
78
- title="状态"
79
- >
80
- <template #default="{ row }">
81
- <tiny-tag :type="row.status === 'on' ? 'success' : 'warning'">
82
- {{ row.status === 'on' ? '上架' : '下架' }}
83
- </tiny-tag>
84
- </template>
85
- </tiny-grid-column>
86
- </tiny-grid>
87
- </div>
88
- </div>
89
- </template>
90
-
91
- <script setup lang="ts">
92
- import { ref } from 'vue'
93
- import productsData from './products.json'
94
- import { $local } from '../../composable/utils'
95
- import { useNextServer } from '@opentiny/next-vue'
96
- import { TinyGrid, TinyGridColumn, TinyButton, TinyTag, TinyModal } from '@opentiny/vue'
97
-
98
- if (!$local.products) {
99
- $local.products = productsData
100
- }
101
-
102
- const products = ref($local.products)
103
- const gridRef = ref(null)
104
-
105
- const categoryLabels: Record<string, string> = {
106
- phones: '手机',
107
- laptops: '笔记本',
108
- tablets: '平板'
109
- }
110
-
111
- // 新增商品到编辑弹窗
112
- const addProductToEdit = async () => {
113
- gridRef?.value?.insert({
114
- image: 'https://agent.icjs.ink/images/huawei-pura.jpg',
115
- price: 10000,
116
- stock: 100,
117
- category: 'phones',
118
- status: 'on'
119
- })
120
- }
121
-
122
- const removeProduct = () => {
123
- const selectedRows = gridRef?.value?.getSelectRecords()
124
- if (selectedRows.length === 0) {
125
- TinyModal.confirm({
126
- message: '请选择要删除的商品',
127
- title: '删除商品',
128
- status: 'warning'
129
- })
130
- return
131
- }
132
- if (selectedRows.length > 0) {
133
- gridRef?.value?.removeSelecteds()
134
- }
135
- }
136
-
137
- const saveProduct = () => {
138
- setTimeout(() => {
139
- const data = gridRef?.value?.getTableData()
140
- $local.products = data.tableData
141
- TinyModal.message({
142
- message: '保存成功',
143
- status: 'success'
144
- })
145
- }, 1000)
146
- }
147
-
148
- const { server } = useNextServer({
149
- serverInfo: { name: 'commodity-config', version: '1.0.0' }
150
- })
151
- </script>
152
-
153
- <style scoped lang="less">
154
- .products-page {
155
- .page-header {
156
- display: flex;
157
- justify-content: space-between;
158
- align-items: center;
159
- margin-bottom: 20px;
160
- padding: 16px 20px;
161
- background-color: #ffffff;
162
- border-radius: 8px;
163
- position: relative;
164
- border: 1px solid #edf2f7;
165
-
166
- &::before {
167
- content: '';
168
- position: absolute;
169
- top: 50%;
170
- left: 0;
171
- width: 4px;
172
- height: 24px;
173
- background: #1677ff;
174
- border-radius: 2px;
175
- transform: translateY(-50%);
176
- }
177
-
178
- h3 {
179
- margin: 0;
180
- font-size: 20px;
181
- font-weight: 600;
182
- color: #1f2937;
183
- position: relative;
184
- padding-left: 20px;
185
- letter-spacing: 0.3px;
186
- }
187
- }
188
- }
189
-
190
- .button-box {
191
- display: flex;
192
- gap: 16px;
193
- margin-bottom: 20px;
194
- justify-content: flex-end;
195
- }
196
- .loading-state {
197
- padding: 20px;
198
- }
199
-
200
- .product-image {
201
- display: block;
202
- width: 40px;
203
- height: 40px;
204
- border-radius: 4px;
205
- }
206
- .page-content {
207
- padding: 20px;
208
- background: #fff;
209
- border-radius: 8px;
210
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
211
- }
212
- </style>