From c01becdf470d2031737e698dc3ae6c0efb63c932 Mon Sep 17 00:00:00 2001 From: prr <3099672575@qq.com> Date: Wed, 27 Nov 2024 18:09:03 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9Amarkdown=E6=B7=BB=E5=8A=A0AI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/markdown/index.html | 3 +- frontend/public/markdown/katex/dialog.css | 43 +++++ frontend/public/markdown/scripts/index.js | 193 +++++++++++++++++++++- 3 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 frontend/public/markdown/katex/dialog.css diff --git a/frontend/public/markdown/index.html b/frontend/public/markdown/index.html index 3060763..e6bfea6 100644 --- a/frontend/public/markdown/index.html +++ b/frontend/public/markdown/index.html @@ -33,12 +33,13 @@ - +
+
diff --git a/frontend/public/markdown/katex/dialog.css b/frontend/public/markdown/katex/dialog.css new file mode 100644 index 0000000..ed51d39 --- /dev/null +++ b/frontend/public/markdown/katex/dialog.css @@ -0,0 +1,43 @@ +.hide { + display: none; +} +#aiDialog { + position: absolute; + top: 10%; + left: 10%; + width: 100%; + height: 100%; +} +.ai-markdown-dialog { + width: 40%; + min-width: 150px; + height: 300px; + margin: 50px auto; + padding: 10px; + border-radius: 5px; + background-color: #ebf9fb; + box-shadow: 0px 5px 5px #e3dfdf; + text-align: center; +} +.ai-dialog-title { + width: 100%; + height: 40px; + line-height: 40px; +} +.ai-dialog-content { + width: 100%; + height: 200px; + resize: none; + outline: none; + border-radius: 5px; + border-color: rgb(203, 203, 203); +} +.ai-dialog-button { + width: 50px; + border-color: rgb(181, 181, 247); + border-radius: 3px; + background-color: #fff; +} +.ai-dialog-button:hover { + background-color: #ceecfb; +} diff --git a/frontend/public/markdown/scripts/index.js b/frontend/public/markdown/scripts/index.js index 6452199..543f55e 100644 --- a/frontend/public/markdown/scripts/index.js +++ b/frontend/public/markdown/scripts/index.js @@ -111,6 +111,191 @@ var exportDataHook = Cherry.createMenuHook('导出', { }, ] }); + +class AiDialogClass { + actionArr = { + creation_leader: "生成大纲", + creation_builder: "根据主题和提纲进行撰写", + creation_continuation: "续写", + creation_optimization: "优化", + creation_proofreading: "纠错", + creation_summarize: "总结", + creation_translation: "翻译" + } + buttons = [ + { + title: '追加', + action: 'aiAdd', + method: this.addAiContent + }, + { + title: '替换', + action: 'aiReplace', + method: this.replaceAiContent + }, + { + title: '舍弃', + action: 'aiCancle', + method: this.closeDialog + }, + { + title: '生成大纲', + action: 'aiOutline', + method: this.createAiOutline + }, + { + title: '生成文章', + action: 'aiArticle', + method: this.createAiArticle + }, + ] + constructor() { + this.container = document.querySelector('#aiDialog') + this.createDialog() + } + // 生成弹窗的基本框架 + createDialog() { + const dialog = document.createElement('div') + dialog.innerHTML = ` +
+
${this.action}
+ +
+ + + +
+
+ + +
+
+ + +
+
` + this.container.appendChild(dialog) + // 绑定事件 + const aiOptions = Array.from(this.container.querySelectorAll('.ai-dialog-button')) + aiOptions.forEach(item => { + item.addEventListener('click', () => { + const actionType = item.getAttribute('data-type') + const btn = this.buttons.find(item => item.action == actionType) + if (btn && btn.method) { + btn.method(this.container) + } + }) + }) + } + // 添加不同按钮 + 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') + } + } + } + // 点击不同按钮生成不同弹窗 + showDialog(action, content) { + // this.sendRequest(action,content) + this.container.querySelector('textarea').value = content + this.addButton(action) + } + // 发送请求 + 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') + } + // 关闭弹窗 + closeDialog(dialog) { + dialog?.classList.add('hide') + } + // 追加 + addAiContent(dialog) { + const content = dialog.querySelector('textarea').value + // cherry.insert(content,false) + cherry.setMarkdown(content) + // this.closeDialog(dialog) + } + // 替换 + replaceAiContent() { + console.log('替换'); + + } + // 生成大纲 + createAiOutline() { + console.log('生成大纲'); + + } + // 生成文章 + createAiArticle() { + console.log('生成文章'); + } +} +const aiDialog = new AiDialogClass() +var aiEditMenu = Cherry.createMenuHook('AI', { + subMenuConfig: [ + { + noIcon: true, + name: '优化', + onclick: () => { + console.log(' AI优化', cherry.getMarkdown()); + aiDialog.sendRequest('creation_optimization', cherry.getMarkdown()) + } + }, + { + noIcon: true, + name: '纠错', + onclick: () => { + aiDialog.sendRequest('creation_proofreading', cherry.getMarkdown()) + } + }, + { + noIcon: true, + name: '续写', + onclick: () => { + aiDialog.sendRequest('creation_continuation', cherry.getMarkdown()) + } + }, + { + noIcon: true, + name: '翻译', + onclick: () => { + aiDialog.sendRequest('creation_translation', cherry.getMarkdown()) + } + }, + { + noIcon: true, + name: '总结', + onclick: () => { + aiDialog.sendRequest('creation_summarize', cherry.getMarkdown()) + } + }, + { + noIcon: true, + name: '大纲', + onclick: () => { + aiDialog.sendRequest('creation_leader', cherry.getMarkdown()) + } + } + ] +}) const saveData = () => { //console.log(markdownTitle) if (!markdownTitle || markdownTitle == "") { @@ -261,7 +446,7 @@ var basicConfig = { 'search', 'togglePreview' ], - toolbarRight: ['saveMenu', '|', 'exportDataHook', 'changeLocale', 'wordCount'], + toolbarRight: ['saveMenu', '|', 'exportDataHook', 'changeLocale', 'wordCount', 'aiEditMenu'], bubble: ['bold', 'italic', 'underline', 'strikethrough', 'sub', 'sup', 'quote', 'ruby', '|', 'size', 'color'], // array or false //sidebar: ['mobilePreview', 'copy', 'theme', 'publish'], sidebar: ['mobilePreview', 'copy', 'shortcutKey', 'theme'], @@ -276,6 +461,7 @@ var basicConfig = { saveMenu, customMenuTable, exportDataHook, + aiEditMenu }, shortcutKeySettings: { /** 是否替换已有的快捷键, true: 替换默认快捷键; false: 会追加到默认快捷键里,相同的shortcutKey会覆盖默认的 */ @@ -394,6 +580,9 @@ const eventHandler = (e) => { cherry.setMarkdown(content); } + if (eventData.type == 'aiReciver') { + aiDialog.showDialog(eventData.action, eventData.data) + } } window.addEventListener('load', () => { window.parent.postMessage({ type: 'initSuccess' }, '*') @@ -403,4 +592,4 @@ window.addEventListener('load', () => { window.addEventListener('unload', () => { window.removeEventListener('message', eventHandler) document.removeEventListener("keydown", debouncedHandleKeyDown); -}) \ No newline at end of file +})