From f457e466d555ecc7c5015e9d8f87bc500caad5ac Mon Sep 17 00:00:00 2001 From: Fleurxxx <984209872@qq.com> Date: Mon, 8 Jul 2024 23:59:20 +0800 Subject: [PATCH 01/15] fix: Fixed AI chat function --- packages/design-core/src/DesignPlugins.vue | 93 +++++++++++++++++++--- packages/plugins/robot/src/Main.vue | 36 +++++---- 2 files changed, 103 insertions(+), 26 deletions(-) diff --git a/packages/design-core/src/DesignPlugins.vue b/packages/design-core/src/DesignPlugins.vue index 2c7f1e5c5..c14294523 100644 --- a/packages/design-core/src/DesignPlugins.vue +++ b/packages/design-core/src/DesignPlugins.vue @@ -82,11 +82,25 @@ - + + + + + + + + + + + +
- +
@@ -94,24 +108,30 @@ \ No newline at end of file diff --git a/packages/plugins/robot/src/Main.vue b/packages/plugins/robot/src/Main.vue index bebf05268..e07ae9399 100644 --- a/packages/plugins/robot/src/Main.vue +++ b/packages/plugins/robot/src/Main.vue @@ -55,16 +55,16 @@ : 'chat-content-ai' ]" > - {{ item.content }} +
- 需要一个注册表单? + 需要一个注册表单? 如何将表单嵌进我的网站? - 需要一个注册表单? + 需要一个注册表单?
+ + + diff --git a/packages/plugins/robot/src/js/useDialogContent.js b/packages/plugins/robot/src/js/useDialogContent.js index a35a18859..46bb91587 100644 --- a/packages/plugins/robot/src/js/useDialogContent.js +++ b/packages/plugins/robot/src/js/useDialogContent.js @@ -1,8 +1,8 @@ -// useMarkdown.js -import MarkdownIt from 'markdown-it'; -import hljs from 'highlight.js'; -import ClipboardJS from 'clipboard'; -import 'highlight.js/styles/a11y-dark.css'; +import MarkdownIt from 'markdown-it' +import { Notify } from '@opentiny/vue' +import hljs from 'highlight.js' +import ClipboardJS from 'clipboard' +import 'highlight.js/styles/a11y-dark.css' export default function useMarkdown() { const md = new MarkdownIt({ @@ -10,46 +10,51 @@ export default function useMarkdown() { linkify: true, typographer: true, highlight: function (str, lang) { - let highlighted = str; + let highlighted = str if (lang && hljs.getLanguage(lang)) { try { highlighted = hljs.highlight(str, { language: lang, - ignoreIllegals: true, - }).value; + ignoreIllegals: true + }).value } catch (__) { - highlighted = md.utils.escapeHtml(str); + highlighted = md.utils.escapeHtml(str) } } else { - highlighted = md.utils.escapeHtml(str); + highlighted = md.utils.escapeHtml(str) } - return `
${highlighted}
`; - }, - }); + return `
${highlighted}
` + } + }) function initClipboard() { const clipboard = new ClipboardJS('.copy-btn', { text: function (trigger) { - return trigger.previousElementSibling.textContent; - }, - }); + return trigger.previousElementSibling.textContent + } + }) clipboard.on('success', function (e) { - const originalText = '复制'; - e.trigger.textContent = '已复制'; + const originalText = '复制' + e.trigger.textContent = '已复制' setTimeout(() => { - e.trigger.textContent = originalText; - }, 3000); - e.clearSelection(); - }); + e.trigger.textContent = originalText + }, 3000) + e.clearSelection() + }) - clipboard.on('error', function (e) { - console.error('无法复制文本,请尝试手动复制。'); - }); + clipboard.on('error', function () { + Notify({ + type: 'error', + message: '无法复制文本,请尝试手动复制。', + position: 'top-right', + duration: 5000 + }) + }) } return { md, - initClipboard, - }; -} \ No newline at end of file + initClipboard + } +} diff --git a/packages/plugins/robot/src/js/useSpeechRecognition.js b/packages/plugins/robot/src/js/useSpeechRecognition.js index 00e1dacd5..d3dd1bc0c 100644 --- a/packages/plugins/robot/src/js/useSpeechRecognition.js +++ b/packages/plugins/robot/src/js/useSpeechRecognition.js @@ -1,35 +1,34 @@ -import { ref } from 'vue'; +import { ref } from 'vue' export default function useSpeechRecognition() { - const recognition = webkitSpeechRecognition ? new webkitSpeechRecognition() : null; - const recognizedText = ref(''); + // eslint-disable-next-line no-undef + const recognition = webkitSpeechRecognition ? new webkitSpeechRecognition() : null + const recognizedText = ref('') if (recognition) { - recognition.continuous = true; - recognition.interimResults = true; - + recognition.continuous = true + recognition.interimResults = true recognition.onresult = (event) => { - const recognized = event.results[event.results.length - 1][0].transcript; - recognizedText.value = recognized; - }; + const recognized = event.results[event.results.length - 1][0].transcript + recognizedText.value = recognized + } } const startRecognition = () => { - console.log(recognition) if (recognition) { - recognition.start(); + recognition.start() } - }; + } const stopRecognition = () => { if (recognition) { - recognition.stop(); + recognition.stop() } - }; + } return { startRecognition, stopRecognition, - recognizedText, - }; -} \ No newline at end of file + recognizedText + } +} From bfd87cab4ce826d23dda2faaa6f24daa138a1f64 Mon Sep 17 00:00:00 2001 From: Fleurxxx <984209872@qq.com> Date: Wed, 24 Jul 2024 23:42:24 +0800 Subject: [PATCH 05/15] fix: Modify the open token dialog logic --- packages/plugins/robot/src/Main.vue | 6 +----- packages/plugins/robot/src/TokenDialog.vue | 10 ++-------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/packages/plugins/robot/src/Main.vue b/packages/plugins/robot/src/Main.vue index 6f761415d..aa4292879 100644 --- a/packages/plugins/robot/src/Main.vue +++ b/packages/plugins/robot/src/Main.vue @@ -216,7 +216,6 @@ export default { }) const tokenDialogVisible = ref(false) - let accessToken = ref(localStorage.getItem('accessToken')) const sendRequest = () => { http .post('/app-center/api/ai/chat', getSendSeesionProcess(), { timeout: 600000 }) @@ -391,11 +390,8 @@ export default { } } - watch([recognizedText, accessToken.value], (newInputContent, accessToken) => { + watch([recognizedText], (newInputContent) => { inputContent.value = newInputContent - if (!accessToken) { - tokenDialogVisible.value = true - } }) return { diff --git a/packages/plugins/robot/src/TokenDialog.vue b/packages/plugins/robot/src/TokenDialog.vue index b977993f1..1ec935a97 100644 --- a/packages/plugins/robot/src/TokenDialog.vue +++ b/packages/plugins/robot/src/TokenDialog.vue @@ -54,17 +54,11 @@ export default { keyFormVisible.value = false emit('dialog-status', false) } - function setOrUpdateLocalStorage(key, value) { - if (localStorage.getItem(key) !== null) { - localStorage.setItem(key, value) - } else { - localStorage.setItem(key, value) - } - } + const submitKeyForm = () => { keyFormRef.value.validate((valid) => { if (valid) { - setOrUpdateLocalStorage('accessToken', keyForm.value.accessToken) + localStorage.setItem('accessToken', keyForm.value.accessToken) closeKeyFormDialog() } }) From be6bbac8abd5297f522db247c41735d100280ca0 Mon Sep 17 00:00:00 2001 From: Fleurxxx <984209872@qq.com> Date: Thu, 25 Jul 2024 10:51:46 +0800 Subject: [PATCH 06/15] fix: Optimize code details --- packages/plugins/robot/package.json | 1 + packages/plugins/robot/src/ContentDialog.vue | 15 +++++++---- packages/plugins/robot/src/Main.vue | 1 - .../plugins/robot/src/js/useDialogContent.js | 6 +++-- .../robot/src/js/useSpeechRecognition.js | 27 +++++++++++++++++-- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/packages/plugins/robot/package.json b/packages/plugins/robot/package.json index 384d23899..c8c336be8 100644 --- a/packages/plugins/robot/package.json +++ b/packages/plugins/robot/package.json @@ -29,6 +29,7 @@ "@opentiny/tiny-engine-controller": "workspace:*", "@opentiny/tiny-engine-http": "workspace:*", "clipboard": "^2.0.11", + "dompurify": "^3.1.6", "highlight.js": "^11.10.0", "markdown-it": "^14.1.0", "markdown-it-highlightjs": "^4.1.0" diff --git a/packages/plugins/robot/src/ContentDialog.vue b/packages/plugins/robot/src/ContentDialog.vue index ea3050dc1..d86808a8c 100644 --- a/packages/plugins/robot/src/ContentDialog.vue +++ b/packages/plugins/robot/src/ContentDialog.vue @@ -1,22 +1,27 @@ + + +2. +2.1.任务:根据下方 Schema 配置模板,将生成 Schema 代码。 +2.2.预设 Schema 配置模板说明:模板包含了各字段的基础结构,展示了组件配置的标准格式及各项的含义。请确保生成的 Schema 代码遵循以下结构: +(1)顶层结构必须包含以下字段: state, methods, componentName, css, props, children, fileName +(2)字段解释:以下是对预定 Schema 配置模板中每个部分的详细解释: +1.state 对象: +用途:state 对象用于存储响应式数据。状态管理面板负责系统管理 state 中的响应式变量,包括添加、删除、搜索和编辑操作。 +注意事项: + 当使用 state 存储组件需要展示的数据时,必须在对象的属性中内置 type 和 value,并将 value 绑定到属性值。 + 步骤: + 1. 首先在state内部定义一个属性值: + "state": { + "tableData": [ + { + "id": "1", + "name": "GFD科技有限公司" + }, + { + "id": "2", + "name": "WWW科技有限公司" + } + ] + } + 2. 在需要展示数据的字段中引用该属性: + 错误示例: + "componentName": "TinyGrid", + "props": { + "data": "state.tableData", + "border": true + }, + 正确示例: + "componentName": "TinyGrid", + "props": { + "data": { + "type": "JSExpression", + "value": "this.state.tableData" + } + } +2.methods 对象: +用途:定义组件的方法,这些方法可以是事件处理器、工具函数或任何其他逻辑。 +例如:在模板中定义一个 handleSubmit 方法,它将在表单提交时被调用。 +3.componentName: +用途:指定根组件的名称,这是渲染的顶层组件。 +例如:"componentName": "Page" 表示根组件名为 "Page"。 +4.css: +用途:定义组件的样式,可以是内联样式或外部样式表的引用。 +例如:"css": "body { background-color: #fff; }" 将直接在组件中应用该 CSS 样式。 +5.props: +用途:定义组件的属性,这些属性可以由父组件传递给子组件。 +例如:"props": { "myProp": "someValue" } 定义了一个名为 myProp 的属性,其值为 someValue。 +6.children 数组: +用途:定义组件的子组件,这些子组件可以有自己的 componentName、props、id 和 children。 +例如:"children": [{ "componentName": "TinyForm", ... }] 定义了一个名为 "TinyForm" 的子组件。 +注意:确保数组的完整性,不要忘记结尾写"]",而不是"}". +7.fileName: +用途:定义生成的文件名,通常用于标识或保存组件的代码。 +例如:"fileName": "registration" 表示生成的文件名为 "registration"。 +8.id 属性: +用途:为组件或元素指定一个唯一的标识符,通常用于样式应用、事件处理或DOM操作。 +例如:"id": "formContainer" 为一个 div 元素定义了一个 ID 为 "formContainer"。 +9.props 对象内的属性: +用途:用于定义组件可以接受的外部属性(即参数),这些属性可以是静态的(固定值)或动态的(可变化的数据)。通过props,父组件可以控制子组件的行为或外观,而无需直接修改子组件的内部状态。 +例如:"props": { "placeholder": "请输入用户名" } 定义了一个名为 placeholder 的属性,其值为 "请输入用户名"。 +注意: +· 在书写上不要包含特殊字符,如"@"、":"等等 + 示例: + 错误写法:"props": { "@click": "resetForm" }" + 正确写法:"props": { "click": "resetForm" }" +· 按钮文本作为 props 属性:若在组件(如按钮)上添加显示文字,不应在 props 外部定义,应包含在 props 中。 + 示例: + 错误写法:{ + "componentName": "TinyButton", + "props": { + "type": "primary", + "onClick": "submitForm" + }, + "text": "提交", + "id": "33424764" + } + 正确写法:{ + "componentName": "TinyButton", + "props": { + "text": "提交", + "type": "primary", + "onClick": "submitForm" + }, + "id": "33424764" + } +提示: 模板中的每个字段是预定义的,可以根据需求进行填充或修改。例如,处理表单数据时,可在 state 中添加字段,或在 methods 中添加验证逻辑。 + +2.3.示例 Schema 配置模板: +{ + "state": { + "dataDisk": [] + }, + "methods": {}, + "componentName": "Page", + "css": "", + "props": {}, + "children": [ + { + "componentName": "div", + "props": { + "style": "" + }, + "id": "", + "children": [ + { + "componentName": "TinyForm", + "props": { + "labelWidth": "80px", + "labelPosition": "top", + "inline": false, + "label-position": "left", + "label-width": "150px", + "style": "" + }, + "id": "", + "children": [ + { + "componentName": "TinyFormItem", + "props": { + "label": "", + "style": "" + }, + "id": "", + "children": [ + { + "componentName": "TinyButtonGroup", + "props": { + "data": [], + "modelValue": "" + }, + "id": "" + } + ] + } + ] + } + ] + } + ],//必不可少,要保证代码的完整性 + "fileName": "" //顶层结构必须包含该字段 +} + +需求如下: +\`\`\``