From 8e7c814fab227e159299ad0a9c05ecb6b9bdc0a8 Mon Sep 17 00:00:00 2001 From: prr <3099672575@qq.com> Date: Wed, 20 Nov 2024 18:07:12 +0800 Subject: [PATCH] =?UTF-8?q?add:word=E6=B7=BB=E5=8A=A0AI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/stores/model.ts | 2 + packages/word/index.html | 3 + packages/word/src/assets/images/ai-edit.svg | 1 + .../word/src/editor/core/command/Command.ts | 2 + .../src/editor/core/command/CommandAdapt.ts | 15 ++ .../src/editor/core/worker/works/catalog.ts | 4 +- .../src/editor/dataset/constant/Element.ts | 3 +- .../word/src/editor/dataset/enum/Element.ts | 1 + packages/word/src/main.ts | 11 + .../word/src/plugins/floatingToolbar/index.ts | 201 ++++++++++++++---- .../plugins/floatingToolbar/style/index.scss | 18 +- packages/word/src/style.css | 4 + 12 files changed, 216 insertions(+), 49 deletions(-) create mode 100644 packages/word/src/assets/images/ai-edit.svg diff --git a/frontend/src/stores/model.ts b/frontend/src/stores/model.ts index a3d1896..db8292e 100644 --- a/frontend/src/stores/model.ts +++ b/frontend/src/stores/model.ts @@ -153,6 +153,8 @@ export const useModelStore = defineStore('modelStore', () => { return modelList.filter((d: any) => d.action == action) } async function addDownList(data: any) { + console.log(data); + //modelList.value.unshift(data) // const has = modelList.value.find((d: any) => d.model == data.model) // //console.log(has) diff --git a/packages/word/index.html b/packages/word/index.html index 4c139df..f821ec6 100644 --- a/packages/word/index.html +++ b/packages/word/index.html @@ -334,6 +334,9 @@ + diff --git a/packages/word/src/assets/images/ai-edit.svg b/packages/word/src/assets/images/ai-edit.svg new file mode 100644 index 0000000..d3e202b --- /dev/null +++ b/packages/word/src/assets/images/ai-edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/word/src/editor/core/command/Command.ts b/packages/word/src/editor/core/command/Command.ts index e5e53f2..d401400 100644 --- a/packages/word/src/editor/core/command/Command.ts +++ b/packages/word/src/editor/core/command/Command.ts @@ -28,6 +28,7 @@ export class Command { public executeStrikeout: CommandAdapt['strikeout'] public executeSuperscript: CommandAdapt['superscript'] public executeSubscript: CommandAdapt['subscript'] + public executeAiEdit: CommandAdapt['aiEdit'] public executeColor: CommandAdapt['color'] public executeHighlight: CommandAdapt['highlight'] public executeTitle: CommandAdapt['title'] @@ -152,6 +153,7 @@ export class Command { this.executeStrikeout = adapt.strikeout.bind(adapt) this.executeSuperscript = adapt.superscript.bind(adapt) this.executeSubscript = adapt.subscript.bind(adapt) + this.executeAiEdit = adapt.aiEdit.bind(adapt) this.executeColor = adapt.color.bind(adapt) this.executeHighlight = adapt.highlight.bind(adapt) // 标题、对齐方式、列表 diff --git a/packages/word/src/editor/core/command/CommandAdapt.ts b/packages/word/src/editor/core/command/CommandAdapt.ts index c6f8530..ac1a379 100644 --- a/packages/word/src/editor/core/command/CommandAdapt.ts +++ b/packages/word/src/editor/core/command/CommandAdapt.ts @@ -475,6 +475,7 @@ export class CommandAdapt { const isDisabled = this.draw.isReadonly() || this.draw.isDisabled() if (isDisabled) return const selection = this.range.getSelectionElementList() + if (selection?.length) { const noBoldIndex = selection.findIndex(s => !s.bold) selection.forEach(el => { @@ -633,6 +634,20 @@ export class CommandAdapt { this.draw.render({ isSetCursor: false }) } + public aiEdit(operate: string | null) { + console.log('ai edit:', operate) + const isDisabled = this.draw.isReadonly() || this.draw.isDisabled() + if (isDisabled) return + const selection = this.range.getSelectionElementList() + if (!selection) return + let content = '' + selection.forEach(el => { + content += el.value + }) + //console.log('操作内容:', content); + return content + } + public color(payload: string | null) { const isDisabled = this.draw.isReadonly() || this.draw.isDisabled() if (isDisabled) return diff --git a/packages/word/src/editor/core/worker/works/catalog.ts b/packages/word/src/editor/core/worker/works/catalog.ts index ddd7933..3cb1394 100644 --- a/packages/word/src/editor/core/worker/works/catalog.ts +++ b/packages/word/src/editor/core/worker/works/catalog.ts @@ -18,6 +18,7 @@ enum ElementType { SUPERSCRIPT = 'superscript', SUBSCRIPT = 'subscript', SEPARATOR = 'separator', + AIEDIT = 'aiEdit', PAGE_BREAK = 'pageBreak', CONTROL = 'control', CHECKBOX = 'checkbox', @@ -54,7 +55,8 @@ const TEXTLIKE_ELEMENT_TYPE: ElementType[] = [ ElementType.SUBSCRIPT, ElementType.SUPERSCRIPT, ElementType.CONTROL, - ElementType.DATE + ElementType.DATE, + ElementType.AIEDIT ] const ZERO = '\u200B' diff --git a/packages/word/src/editor/dataset/constant/Element.ts b/packages/word/src/editor/dataset/constant/Element.ts index 1db6e52..5d611be 100644 --- a/packages/word/src/editor/dataset/constant/Element.ts +++ b/packages/word/src/editor/dataset/constant/Element.ts @@ -131,7 +131,8 @@ export const TEXTLIKE_ELEMENT_TYPE: ElementType[] = [ ElementType.SUBSCRIPT, ElementType.SUPERSCRIPT, ElementType.CONTROL, - ElementType.DATE + ElementType.DATE, + ElementType.AIEDIT ] export const IMAGE_ELEMENT_TYPE: ElementType[] = [ diff --git a/packages/word/src/editor/dataset/enum/Element.ts b/packages/word/src/editor/dataset/enum/Element.ts index 23a5dc6..4644de6 100644 --- a/packages/word/src/editor/dataset/enum/Element.ts +++ b/packages/word/src/editor/dataset/enum/Element.ts @@ -6,6 +6,7 @@ export enum ElementType { SUPERSCRIPT = 'superscript', SUBSCRIPT = 'subscript', SEPARATOR = 'separator', + AIEDIT = 'aiEdit', PAGE_BREAK = 'pageBreak', CONTROL = 'control', CHECKBOX = 'checkbox', diff --git a/packages/word/src/main.ts b/packages/word/src/main.ts index 5d304a0..9ab3e00 100644 --- a/packages/word/src/main.ts +++ b/packages/word/src/main.ts @@ -237,6 +237,14 @@ window.onload = function () { instance.command.executeSubscript() } + //ai + const aiEditDom = document.querySelector('.menu-item__ai-edit')! + aiEditDom.title = `ai帮助` + aiEditDom.onclick = function () { + console.log('ai-edit') + instance.command.executeAiEdit('') + } + const colorControlDom = document.querySelector('#color')! colorControlDom.oninput = function () { instance.command.executeColor(colorControlDom.value) @@ -1540,6 +1548,9 @@ window.onload = function () { // 8. 内部事件监听 instance.listener.rangeStyleChange = function (payload) { // 控件类型 + payload.type === ElementType.AIEDIT + ? aiEditDom.classList.add('active') + : aiEditDom.classList.remove('active') payload.type === ElementType.SUBSCRIPT ? subscriptDom.classList.add('active') : subscriptDom.classList.remove('active') diff --git a/packages/word/src/plugins/floatingToolbar/index.ts b/packages/word/src/plugins/floatingToolbar/index.ts index 06d1d6f..bc91afd 100644 --- a/packages/word/src/plugins/floatingToolbar/index.ts +++ b/packages/word/src/plugins/floatingToolbar/index.ts @@ -6,7 +6,6 @@ import { ToolbarType } from './enum' import { IToolbarRegister } from './interface' import { PLUGIN_PREFIX } from './constant' import { Svgs } from './icons/Svgs' - function createPickerToolbar( container: HTMLDivElement, toolbarType: ToolbarType, @@ -63,55 +62,54 @@ function createPickerToolbar( } export const defaultAiPanelMenus = [ { - prompt: `{content}\n请帮我优化一下这段内容,并直接返回优化后的结果。\n注意:你应该先判断一下这句话是中文还是英文,如果是中文,请给我返回中文的内容,如果是英文,请给我返回英文内容,只需要返回内容即可,不需要告知我是中文还是英文。`, icon: Svgs.optimize, - title: '改进写作' + // title: '改进写作', + title: '优化', + key: 'creation_optimization' }, { - prompt: `{content}\n请帮我检查一下这段内容,是否有拼写错误或者语法上的错误。\n注意:你应该先判断一下这句话是中文还是英文,如果是中文,请给我返回中文的内容,如果是英文,请给我返回英文内容,只需要返回内容即可,不需要告知我是中文还是英文。`, icon: Svgs.checkGrammar, - title: '检查拼写和语法' - }, - { - prompt: `{content}\n这句话的内容较长,帮我简化一下这个内容,并直接返回简化后的内容结果。\n注意:你应该先判断一下这句话是中文还是英文,如果是中文,请给我返回中文的内容,如果是英文,请给我返回英文内容,只需要返回内容即可,不需要告知我是中文还是英文。`, - icon: Svgs.simplification, - title: '简化内容' + // title: '检查拼写和语法' + title: '纠错', + key: 'creation_proofreading' }, + // { + // icon: Svgs.simplification, + // title: '简化内容' + // }, { - prompt: `{content}\n这句话的内容较简短,帮我简单的优化和丰富一下内容,并直接返回优化后的结果。注意:优化的内容不能超过原来内容的 2 倍。\n注意:你应该先判断一下这句话是中文还是英文,如果是中文,请给我返回中文的内容,如果是英文,请给我返回英文内容,只需要返回内容即可,不需要告知我是中文还是英文。`, icon: Svgs.richContent, - title: '丰富内容' + // title: '丰富内容' + title: '续写', + key: 'creation_continuation' }, '
', { - prompt: `{content}\n请帮我翻译以上内容,在翻译之前,想先判断一下这个内容是不是中文,如果是中文,则翻译问英文,如果是其他语言,则需要翻译为中文,注意,你只需要返回翻译的结果,不需要对此进行任何解释,不需要除了翻译结果以外的其他任何内容。`, icon: Svgs.translation, - title: '翻译' + title: '翻译', + key: 'creation_translation' }, { - prompt: `{content}\n请帮我总结以上内容,并直接返回总结的结果\n注意:你应该先判断一下这句话是中文还是英文,如果是中文,请给我返回中文的内容,如果是英文,请给我返回英文内容,只需要返回内容即可,不需要告知我是中文还是英文。`, icon: Svgs.summary, - title: '总结' + title: '总结', + key: 'creation_summarize' } ] // 创建ai选择栏 function createAIToolbar( container: HTMLDivElement, toolbarType: ToolbarType, - changed: (color: string) => void + editor: Editor ) { const toolbarItem = document.createElement('div') toolbarItem.classList.add(`${PLUGIN_PREFIX}-picker-ai`) toolbarItem.classList.add(`${PLUGIN_PREFIX}-${toolbarType}`) - const chooseBox = document.createElement('div') - chooseBox.classList.add('ce-picker-container') - toolbarItem.append(chooseBox) const aiBubbleMenuItems = defaultAiPanelMenus toolbarItem.innerHTML = ` - -
+ +
-