From 9b4e1bf5cc9bab6effd5d507589678110c36052f Mon Sep 17 00:00:00 2001 From: prr <3099672575@qq.com> Date: Thu, 28 Nov 2024 14:50:43 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9Amarkdown=E5=AE=8C=E5=96=84AI?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/markdown/katex/dialog.css | 68 ++++++- frontend/public/markdown/katex/loader.svg | 1 + frontend/public/markdown/scripts/index.js | 212 ++++++++++++++++------ 3 files changed, 219 insertions(+), 62 deletions(-) create mode 100644 frontend/public/markdown/katex/loader.svg diff --git a/frontend/public/markdown/katex/dialog.css b/frontend/public/markdown/katex/dialog.css index ed51d39..cc2b356 100644 --- a/frontend/public/markdown/katex/dialog.css +++ b/frontend/public/markdown/katex/dialog.css @@ -1,18 +1,20 @@ .hide { - display: none; + display: none !important; } #aiDialog { position: absolute; - top: 10%; - left: 10%; + top: 0%; + left: 0%; width: 100%; height: 100%; + z-index: 3; } .ai-markdown-dialog { width: 40%; min-width: 150px; height: 300px; - margin: 50px auto; + float: right; + margin: 50px; padding: 10px; border-radius: 5px; background-color: #ebf9fb; @@ -24,6 +26,9 @@ height: 40px; line-height: 40px; } +.ai-content-box { + position: relative; +} .ai-dialog-content { width: 100%; height: 200px; @@ -31,9 +36,62 @@ outline: none; border-radius: 5px; border-color: rgb(203, 203, 203); + box-sizing: border-box; +} +.ai-outline-choose { + width: 100%; + height: 200px; + padding: 20px; + margin: 10px 0; + background-color: #fff; + border: 1px solid #e0dfdf; + border-radius: 5px; + box-sizing: border-box; +} +.ai-outline-choose select, +.ai-outline-choose input { + display: inline-block; + width: 80%; + height: 30px; + padding: 0 10px; + margin: 10px 0; + appearance: none; + background-color: #fff; + background-image: none; + border-radius: 4px; + border: 1px solid #ebebeb; + box-sizing: border-box; + color: #606266; + line-height: 27px; + outline: none; +} +.ai-mask { + position: absolute; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 200px; + background-color: rgba(0, 0, 0, .1); +} +#aiLoader { + width: 32px; + height: 32px; + background-image: url('./loader.svg'); + animation: rotate 2s linear infinite; +} +@keyframes rotate { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } .ai-dialog-button { - width: 50px; + min-width: 50px; border-color: rgb(181, 181, 247); border-radius: 3px; background-color: #fff; diff --git a/frontend/public/markdown/katex/loader.svg b/frontend/public/markdown/katex/loader.svg new file mode 100644 index 0000000..bb6459e --- /dev/null +++ b/frontend/public/markdown/katex/loader.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/markdown/scripts/index.js b/frontend/public/markdown/scripts/index.js index 543f55e..d580a97 100644 --- a/frontend/public/markdown/scripts/index.js +++ b/frontend/public/markdown/scripts/index.js @@ -114,13 +114,38 @@ var exportDataHook = Cherry.createMenuHook('导出', { class AiDialogClass { actionArr = { - creation_leader: "生成大纲", - creation_builder: "根据主题和提纲进行撰写", - creation_continuation: "续写", - creation_optimization: "优化", - creation_proofreading: "纠错", - creation_summarize: "总结", - creation_translation: "翻译" + creation_leader: { + title: '文章选择', + btn: ['aiCancle', 'aiOutline'] + }, + creation_builder: { + title: '大纲', + btn: ['aiAdd', 'aiReplace', 'aiCancle', 'aiArticle'] + }, + article: { + title: '文章', + btn: ['aiAdd', 'aiReplace', 'aiCancle', 'checkOutline'] + }, + creation_continuation: { + title: '续写', + btn: ['aiAdd', 'aiReplace', 'aiCancle'] + }, + creation_optimization: { + title: '优化', + btn: ['aiAdd', 'aiReplace', 'aiCancle'] + }, + creation_proofreading: { + title: '纠错', + btn: ['aiAdd', 'aiReplace', 'aiCancle'] + }, + creation_summarize: { + title: '总结', + btn: ['aiAdd', 'aiReplace', 'aiCancle'] + }, + creation_translation: { + title: '翻译', + btn: ['aiAdd', 'aiReplace', 'aiCancle'] + } } buttons = [ { @@ -148,7 +173,17 @@ class AiDialogClass { action: 'aiArticle', method: this.createAiArticle }, + { + title: '查看大纲', + action: 'checkOutline', + method: this.cheakAiContent + } ] + outline = { + title: '', + content: '', + category: '' + } constructor() { this.container = document.querySelector('#aiDialog') this.createDialog() @@ -159,18 +194,37 @@ class AiDialogClass { dialog.innerHTML = `
${this.action}
- -
- - - +
+
+
-
- - +
+
+ + +
+
+ + +
-
+
+ + + +
` @@ -182,70 +236,114 @@ class AiDialogClass { const actionType = item.getAttribute('data-type') const btn = this.buttons.find(item => item.action == actionType) if (btn && btn.method) { - btn.method(this.container) + btn.method(this.container, this) } }) }) + } + // 打开弹窗 + openDialog(action) { + this.container.classList.remove('hide') + const title = 'AI - ' + this.actionArr[action].title + this.container.querySelector('.ai-dialog-title').innerText = title + this.addButton(action) } - // 添加不同按钮 + // 根据不同选择,展示不同弹窗 addButton(action) { - let pos = 0 - action == '大纲' ? pos = 1 : pos = 0 - const btnArr = Array.from(this.container.querySelectorAll('.button-box')) - for (let i = 0; i < btnArr.length; i++) { - if (i == pos) { - btnArr[i].classList.remove('hide') - }else { - btnArr[i].classList.add('hide') + if (action == 'creation_leader') { + this.container.querySelector('.ai-outline-choose').classList.remove('hide') + this.container.querySelector('.ai-content-box').classList.add('hide') + } else { + this.container.querySelector('.ai-outline-choose').classList.add('hide') + this.container.querySelector('.ai-content-box').classList.remove('hide') + this.container.querySelector('.ai-mask').classList.remove('hide') + } + const buttonArr = Array.from(this.container.querySelectorAll('.ai-dialog-button')) + buttonArr.forEach(item => { + const actionType = item.getAttribute('data-type') + if (this.actionArr[action].btn.indexOf(actionType) !== -1) { + item.classList.remove('hide') + } else { + item.classList.add('hide') } - } + }) } - // 点击不同按钮生成不同弹窗 - showDialog(action, content) { + // 将内容放入textarea中 + putInTextarea(action, content) { // this.sendRequest(action,content) this.container.querySelector('textarea').value = content - this.addButton(action) + this.container.querySelector('.ai-mask').classList.add('hide') } // 发送请求 sendRequest(action, data) { - let title = 'ai助手' - Object.keys(this.actionArr).forEach(item => { - if (item == action) { - title = 'AI' + this.actionArr[item] - } - }) - this.container.querySelector('.ai-dialog-title').innerText = title - window.parent.postMessage({ - type: 'aiCreater', - data, - action - }, '*') - this.container.classList.remove('hide') + if (action !== 'creation_leader') { + window.parent.postMessage({ + type: 'aiCreater', + data, + action + }, '*') + } + this.openDialog(action) } // 关闭弹窗 closeDialog(dialog) { + dialog.querySelector('textarea').value = '' + this.outline = { + title: '', + content: '', + category: '' + } dialog?.classList.add('hide') } // 追加 - addAiContent(dialog) { + addAiContent(dialog, that) { const content = dialog.querySelector('textarea').value - // cherry.insert(content,false) - cherry.setMarkdown(content) - // this.closeDialog(dialog) + cherry.insert(content,false) + that.closeDialog(dialog) } // 替换 - replaceAiContent() { - console.log('替换'); - + replaceAiContent(dialog, that) { + const content = dialog.querySelector('textarea').value + cherry.setMarkdown(content) + that.closeDialog(dialog) } // 生成大纲 - createAiOutline() { - console.log('生成大纲'); - + createAiOutline(dialog, that) { + that.addButton('creation_leader') + const content = { + title: dialog.querySelector('#aiTitle').value, + category: dialog.querySelector('#aiSelect').value + } + that.outline.title = content.title + that.outline.category = content.category + if (content.title !== '' ) { + window.parent.postMessage({ + type: 'aiCreater', + data: content, + action: 'creation_leader' + }, '*') + that.openDialog('creation_builder') + } } // 生成文章 - createAiArticle() { - console.log('生成文章'); + createAiArticle(dialog, that) { + const data = { + outline: dialog.querySelector('textarea').value, + title: that.outline.title || 'AI - 文章' + } + that.outline.content = data.outline + window.parent.postMessage({ + type: 'aiCreater', + data, + action: 'creation_builder' + }, '*') + that.openDialog('article') + } + //查看大纲 + cheakAiContent(dialog, that) { + that.openDialog('creation_builder') + dialog.querySelector('textarea').value = that.outline.content + dialog.querySelector('.ai-mask').classList.add('hide') } } const aiDialog = new AiDialogClass() @@ -255,7 +353,6 @@ var aiEditMenu = Cherry.createMenuHook('AI', { noIcon: true, name: '优化', onclick: () => { - console.log(' AI优化', cherry.getMarkdown()); aiDialog.sendRequest('creation_optimization', cherry.getMarkdown()) } }, @@ -291,6 +388,7 @@ var aiEditMenu = Cherry.createMenuHook('AI', { noIcon: true, name: '大纲', onclick: () => { + // aiDialog.showDialog() aiDialog.sendRequest('creation_leader', cherry.getMarkdown()) } } @@ -581,7 +679,7 @@ const eventHandler = (e) => { cherry.setMarkdown(content); } if (eventData.type == 'aiReciver') { - aiDialog.showDialog(eventData.action, eventData.data) + aiDialog.putInTextarea(eventData.action, eventData.data) } } window.addEventListener('load', () => {