postdischarge-ui/src/views/system/components/wangEditor.vue
2024-06-03 15:49:43 +08:00

618 lines
44 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div style="border: 1px solid #ccc;">
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" :mode="mode" />
<Editor style="height: 500px; overflow-y: hidden;" v-model="html" :defaultConfig="editorConfig" :mode="mode"
@onChange="onChange" @onCreated="onCreated" @onFocus="handleFocus" />
<el-dialog title="添加画像标签字段" :visible.sync="labelshow" width="40%" :before-close="beforeClose">
<el-cascader-panel :options="labeloptions" @change="panelchange" v-if="labelshow"
:props="{ value: 'labelFieldId', label: 'fieldName', children: 'labelFieldContentList' }"></el-cascader-panel>
<div>
<div style="margin: 20px 0;">结果预览:</div>
<el-input type="textarea" v-model="addnode.fileSpan" disabled></el-input>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="labelclick" type="primary">确定</el-button>
</div>
</el-dialog>
<el-dialog title="添加知识库字段" :visible.sync="fieldshow" width="40%" :before-close="beforeClose">
<el-cascader-panel :options="fieldoptions" @change="panelchange" v-if="fieldshow"
:props="{ value: 'labelFieldId', label: 'fieldName', children: 'labelFieldContentList' }"></el-cascader-panel>
<div>
<div style="margin: 20px 0;">结果预览:</div>
<el-input type="textarea" v-model="addnode.fileSpan" disabled></el-input>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="fieldclick" type="primary">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { DomEditor, IDomEditor, SlateElement, SlateDescendant, SlateTransforms, SlateEditor, SlateNode } from '@wangeditor/editor'
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { Boot } from '@wangeditor/editor'
import { h, VNode } from 'snabbdom'
import {
labelFieldList,
richTextPictureUrl
} from '@/api/system/wangEditor.js'
// import menuConf from "./ModalMenu";
import { getToken } from "@/utils/auth";
var that
export default ({
props: ['nodeContent'],
components: { Editor, Toolbar },
name: 'wangEditor',
data() {
return {
labeloptions: [],
fieldoptions: [],
labelshow: false,
fieldshow: false,
editor: null,
menukeys: null,
toolbarConfig: {
insertKeys: {
index: 61,
keys: ['MyButtonMenu', 'MyButtonMenutwo']
},
excludeKeys: [
'fullScreen',
'insertLink',
'codeBlock',
'todo',
'insertVideo',
'insertImage',
"emotion",
"divider",
"insertTable",
],
},
editorConfig: {
placeholder: '请输入内容...',
MENU_CONF: {
uploadImage: {
server: process.env.VUE_APP_BASE_API + '/common/richTextPictureUrl',
headers: {
Authorization: "Bearer " + getToken()
},
fieldName: "file", // 这里有个坑,如果返回的响应结果是没有上传文件,跟这里关系很大
customInsert(res, insertFn) {
if (res.code == 200) {
insertFn(res.url, null, null);
}
},
},
uploadVideo: { //上传视频配置
customUpload: this.handleUpload
},
},
},
mode: 'default', // or 'simple'
timer: '',
html: `<p></p>`,
addnode: {
fileName: '',
fileSpan: '',
fieldMark: "",
},
modify: false,
}
},
methods: {
async handleUpload(file, insertFn) {
let form = new FormData();
form.append('file', file);
let res = await this.uploadFile(form); //此方法返回上传后的id
console.log(res)
const videoUrl = URL.createObjectURL(file);
// this.content += '<video poster=\"\" controls=\"true\" width=\"auto\" height=\"auto\"><source src=\"'+ res +'\" type=\"video/mp4\"/></video>'
// 这快需要注意一下我这res返回这快应该是后端返回一个预览服务的url才能直接在富文本以及后续展示的地方展示这个视频
this.html += '<video poster=\"\" controls=\"true\" width=\"auto\" height=\"auto\"><source src=\"' + process.env.VUE_APP_BASE_API + res.fileName + '\" type=\"video/mp4\"/></video>'
// 如果没有预览服务可以让后端写一下下载接口,然后在这里直接拼,但是这个接口前缀最好使用项目中接口配置的前缀
},
async uploadFile(form) {
let res = await richTextPictureUrl(form); //此处换为自己的上传接口地址
console.log(res)
return res
},
emit() {
this.$emit("on-nodeContent", { nodeContent: this.html });
},
panelchange(item) {
if (this.labelshow) {
this.labeloptions.forEach(e => {
e.labelFieldContentList.forEach(el => {
if (el.labelFieldId == item[1]) {
this.addnode.fileSpan = el.fieldName
this.addnode.fileName = e.fieldName
this.addnode.fieldMark = el.fieldMark
}
})
})
} else if (this.fieldshow) {
this.fieldoptions.forEach(e => {
e.labelFieldContentList.forEach(el => {
if (el.labelFieldId == item[1]) {
this.addnode.fileSpan = el.fieldName
this.addnode.fileName = e.fieldName
this.addnode.fieldMark = el.fieldMark
}
})
})
}
},
labelclick() {
this.labelshow = false
setTimeout(() => {
this.editor.focus()
}, 30);
setTimeout(() => {
if (this.modify) {
this.modify = false
this.editor.deleteBackward();
}
const resume = { // JS 语法
type: 'attachment',
link: '',
fileName: this.addnode.fileName,
fileSpan: this.addnode.fileSpan,
fieldMark: this.addnode.fieldMark,
children: [{ text: '' }], // void 元素必须有一个 children ,其中只有一个空字符串,重要!!!
}
this.editor.insertNode(resume)
this.addnode = {
fileName: '',
fileSpan: '',
fieldMark: '',
}
this.editor.focus()
}, 100);
},
fieldclick() {
this.fieldshow = false
setTimeout(() => {
this.editor.focus()
}, 30);
setTimeout(() => {
if (this.modify) {
this.modify = false
this.editor.deleteBackward();
}
const resume = { // JS 语法
type: 'attachmenttwo',
link: '',
fileName: this.addnode.fileName,
fileSpan: this.addnode.fileSpan,
fieldMark: this.addnode.fieldMark,
children: [{ text: '' }], // void 元素必须有一个 children ,其中只有一个空字符串,重要!!!
}
this.editor.insertNode(resume)
this.addnode = {
fileName: '',
fieldMark: '',
fileSpan: '',
}
this.editor.focus()
}, 100);
},
onCreated(editor) {
this.editor = Object.seal(editor);
},
onChange(editor) {
// console.log("onChange", editor.getHtml()); // onChange 时获取编辑器最新内容
},
handleFocus(editor) {
// console.log("focus", editor);
},
info() {
labelFieldList('PORTRAIT_LABEL_FIELD').then(res => {
res.data.data.forEach(e => {
e.labelFieldContentList.forEach(el => {
el.labelFieldId = el.labelFieldContentId
el.fieldName = el.contentName
})
})
this.labeloptions = res.data.data
})
labelFieldList('KNOWLEDGE_FIELD').then(res => {
res.data.data.forEach(e => {
e.labelFieldContentList.forEach(el => {
el.labelFieldId = el.labelFieldContentId
el.fieldName = el.contentName
})
})
this.fieldoptions = res.data.data
})
},
beforeClose() {
this.modify = false
this.fieldshow = false
this.labelshow = false
},
},
watch: {
nodeContent(newValue, oldValue) {
console.log(newValue, oldValue)
this.html = newValue;
}
},
mounted() {
this.html = this.nodeContent
},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁编辑器
},
created() {
that = this
this.info();
}
})
class MyButtonMenu { // JS 语法
constructor(vueInstance) {
this.vueInstance = vueInstance
this.title = '添加画像标签字段'
this.iconSvg = '<svg t="1711951668796" class="icon" viewBox="0 0 1119 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4490" xmlns:xlink="http://www.w3.org/1999/xlink" width="218.5546875" height="200"><path d="M25.415082 562.922053a25.1989 25.1989 0 0 1-17.745705-43.299519L542.347456 7.392772A25.110172 25.110172 0 1 1 577.040308 43.682738L42.894601 555.9125a25.110172 25.110172 0 0 1-17.479519 7.009553z" p-id="4491"></path><path d="M1094.061411 562.922053a25.110172 25.110172 0 0 1-17.745704-7.009553L542.347456 43.682738A25.110172 25.110172 0 1 1 577.040308 7.392772l534.323165 512.229762a25.1989 25.1989 0 0 1-17.745704 43.299519zM559.738247 1023.955458a380.467906 380.467906 0 0 1-380.024264-380.112992 25.1989 25.1989 0 0 1 50.309073 0 330.070105 330.070105 0 0 0 329.715191 329.80392 25.1989 25.1989 0 1 1 0 50.309072z" p-id="4492"></path><path d="M1009.769315 799.472295H618.3878a25.1989 25.1989 0 0 1 0-50.309072h391.381515a25.1989 25.1989 0 0 1 0 50.309072z" fill="#231815" p-id="4493"></path><path d="M814.122922 996.005974a25.1989 25.1989 0 0 1-25.198901-25.198901V579.869201a25.1989 25.1989 0 1 1 50.309073 0v390.937872a25.1989 25.1989 0 0 1-25.110172 25.198901z" fill="#231815" p-id="4494"></path></svg>'
this.tag = 'button'
this.showModal = true
}
// 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
isActive(editor) {
return false;
}
// 获取菜单执行时的 value ,用不到则返回空 字符串或 false
getValue(editor) {
return "";
}
// 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
isDisabled(editor) {
return false;
}
// 点击菜单时触发的函数
exec(editor, value) {
this.vueInstance.labelshow = true
}
}
class MyButtonMenutwo { // JS 语法
constructor(vueInstance) {
this.vueInstance = vueInstance
this.title = '添加知识库字段'
this.iconSvg = '<svg t="1711422779479" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2507" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M831.6 639.6h-63.9v127.9H639.9v63.9h127.8v127.9h63.9V831.4h127.9v-63.9H831.6z" p-id="2508"></path><path d="M564.3 925.2c0-18.5-15-33.6-33.6-33.6H287.3c-86.2 0-156.4-70.2-156.4-156.4V286.9c0-86.2 70.1-156.4 156.4-156.4h448.4c86.2 0 156.4 70.2 156.4 156.4v238.8c0 18.5 15 33.6 33.6 33.6s33.6-15 33.6-33.6V286.9C959.2 163.6 859 63.3 735.7 63.3H287.3C164 63.3 63.7 163.6 63.7 286.8v448.3c0 123.2 100.3 223.5 223.6 223.5h243.4c18.6 0.1 33.6-14.9 33.6-33.4z" p-id="2509"></path></svg>'
this.tag = 'button'
this.showModal = true
}
// 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
isActive(editor) {
return false;
}
// 获取菜单执行时的 value ,用不到则返回空 字符串或 false
getValue(editor) {
return "";
}
// 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
isDisabled(editor) {
return false;
}
// 点击菜单时触发的函数
exec(editor, value) {
this.vueInstance.fieldshow = true
}
}
const menuConf = {
key: 'MyButtonMenu', // 定义 menu key :要保证唯一、不重复(重要)
factory() {
return new MyButtonMenu(that)
},
};
const menuConftwo = {
key: 'MyButtonMenutwo', // 定义 menu key :要保证唯一、不重复(重要)
factory() {
return new MyButtonMenutwo(that)
},
};
const module = { // JS 语法
menus: [menuConf, menuConftwo],
// 其他功能,下文讲解...
}
Boot.registerModule(module)
function withAttachment(editor) { // JS 语法
const { isInline, isVoid } = editor
const newEditor = editor
newEditor.isInline = elem => {
const type = DomEditor.getNodeType(elem)
if (type === 'attachment') return true // 针对 type: attachment ,设置为 inline
if (type === 'attachmenttwo') return true // 针对 type: attachment ,设置为 inline
return isInline(elem)
}
newEditor.isVoid = elem => {
const type = DomEditor.getNodeType(elem)
if (type === 'attachment') return true // 针对 type: attachment ,设置为 void
if (type === 'attachmenttwo') return true // 针对 type: attachment ,设置为 void
return isVoid(elem)
}
return newEditor // 返回 newEditor ,重要!!!
}
Boot.registerPlugin(withAttachment)
function renderAttachment(elem, children, editor) { // JS 语法
// 获取“附件”的数据,参考上文 myResume 数据结构
const { fileName = '', link = '', fileSpan = '', fieldMark = '' } = elem
// 附件 icon 图标 vnode
const iconVnode = h(
// HTML tag
'span',
// HTML 属性
{
props: {}, // HTML 属性,驼峰式写法
style: { width: '16px', height: '16px', margin: '0 0 0 6px', display: 'inline-block', transform: 'translateY(20%)', backgroundSize: '100% 100%', backgroundImage: 'url(data:image/png;base64,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)', /* 其他... */ }, // HTML style ,驼峰式写法
on: {
click() {
editor.deleteBackward();
} /* 其他... */
}
}
// img 没有子节点,所以第三个参数不用写
)
const nameiconVnode = h(
// HTML tag
'span',
// HTML 属性
{
props: {}, // HTML 属性,驼峰式写法
style: { width: '16px', height: '16px', margin: '0 0 0 6px', display: 'inline-block', transform: 'translateY(20%)', backgroundSize: '100% 100%', backgroundImage: 'url(data:image/png;base64,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)', /* 其他... */ }, // HTML style ,驼峰式写法
on: {
click() {
that.modify = true
that.labelshow = true
} /* 其他... */
}
}
// img 没有子节点,所以第三个参数不用写
)
const spanVnode = h(
// HTML tag
'span',
// HTML 属性
{
props: { contentEditable: false }, // HTML 属性,驼峰式写法
style: { color: '#22343C', background: '#E5F5F2', padding: '5px 10px' /* 其他... */ }, // style ,驼峰式写法
on: { click() { }, /* 其他... */ }
},
// img 没有子节点,所以第三个参数不用写
[fileSpan, iconVnode]
)
const nameVnode = h(
// HTML tag
'span',
// HTML 属性
{
props: { contentEditable: false }, // HTML 属性,驼峰式写法
style: { color: '#fff', background: '#009A82', padding: '5px 10px' /* 其他... */ }, // style ,驼峰式写法
on: { click() { }, /* 其他... */ }
},
// img 没有子节点,所以第三个参数不用写
[fileName, nameiconVnode]
)
// 附件元素 vnode
const attachVnode = h(
// HTML tag
'span',
// HTML 属性、样式、事件
{
props: { contentEditable: false, class: 'text' }, // HTML 属性,驼峰式写法
style: {}, // style ,驼峰式写法
on: {
click() { } /* 其他... */
}
},
// 子节点
[nameVnode, spanVnode]
)
return attachVnode
}
function renderAttachmenttwo(elem, children, editor) { // JS 语法
// 获取“附件”的数据,参考上文 myResume 数据结构
const { fileName = '', link = '', fileSpan = '', fieldMark = '' } = elem
// 附件 icon 图标 vnode
const iconVnode = h(
// HTML tag
'span',
// HTML 属性
{
props: {}, // HTML 属性,驼峰式写法
style: { width: '16px', height: '16px', margin: '0 0 0 6px', display: 'inline-block', transform: 'translateY(20%)', backgroundSize: '100% 100%', backgroundImage: 'url(data:image/png;base64,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)', /* 其他... */ }, // HTML style ,驼峰式写法
on: {
click() {
editor.deleteBackward();
} /* 其他... */
}
}
// img 没有子节点,所以第三个参数不用写
)
const nameiconVnode = h(
// HTML tag
'span',
// HTML 属性
{
props: {}, // HTML 属性,驼峰式写法
style: { width: '16px', height: '16px', margin: '0 0 0 6px', display: 'inline-block', transform: 'translateY(20%)', backgroundSize: '100% 100%', backgroundImage: 'url(data:image/png;base64,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)', /* 其他... */ }, // HTML style ,驼峰式写法
on: {
click() {
that.modify = true
that.fieldshow = true
} /* 其他... */
}
}
// img 没有子节点,所以第三个参数不用写
)
const spanVnode = h(
// HTML tag
'span',
// HTML 属性
{
props: { contentEditable: false }, // HTML 属性,驼峰式写法
style: { color: '#22343C', background: '#DAE1FB', padding: '5px 10px' /* 其他... */ }, // style ,驼峰式写法
on: { click() { }, /* 其他... */ }
},
// img 没有子节点,所以第三个参数不用写
[fileSpan, iconVnode]
)
const nameVnode = h(
// HTML tag
'span',
// HTML 属性
{
props: { contentEditable: false }, // HTML 属性,驼峰式写法
style: { color: '#fff', background: '#436AE9', padding: '5px 10px' /* 其他... */ }, // style ,驼峰式写法
on: { click() { }, /* 其他... */ }
},
// img 没有子节点,所以第三个参数不用写
[fileName, nameiconVnode]
)
// 附件元素 vnode
const attachVnode = h(
// HTML tag
'span',
// HTML 属性、样式、事件
{
props: { contentEditable: false, class: 'text' }, // HTML 属性,驼峰式写法
style: {}, // style ,驼峰式写法
on: {
click() { } /* 其他... */
}
},
// 子节点
[nameVnode, spanVnode]
)
return attachVnode
}
const renderElemConf = {
type: 'attachment', // 新元素 type ,重要!!!
renderElem: renderAttachment,
}
const renderElemConftwo = {
type: 'attachmenttwo', // 新元素 type ,重要!!!
renderElem: renderAttachmenttwo,
}
const rendermodule = { // JS 语法
// menus: [menu1Conf, menu2Conf, menu3Conf], // 菜单
// editorPlugin: withBreakAndDelete, // 插件
renderElems: [renderElemConf, renderElemConftwo/* 其他元素... */] // renderElem
// 其他功能,下文讲解...
}
Boot.registerModule(rendermodule)
function attachmentToHtml(elem, childrenHtml) { // JS 语法
// 获取附件元素的数据
const { link = '', fileName = '', fileSpan = '', fieldMark = '' } = elem
// 生成 HTML 代码
const html = `<span data-w-e-type="attachment"
data-w-e-is-void
data-w-e-is-inline
data-link="${link}"
data-fileSpan="${fileSpan}"
data-fieldMark="${fieldMark}"
data-fileName="${fileName}">
<span class="path-tag-wrap">
<span>${fileName}</span>
<span>${fileSpan}</span>
</span>
</span>`
return html
}
function attachmentToHtmltwo(elem, childrenHtml) { // JS 语法
// 获取附件元素的数据
const { link = '', fileName = '', fileSpan = '', fieldMark = '' } = elem
// 生成 HTML 代码
const html = `<span data-w-e-type="attachmenttwo"
data-w-e-is-void
data-w-e-is-inline
data-link="${link}"
data-fileSpan="${fileSpan}"
data-fieldMark="${fieldMark}"
data-fileName="${fileName}">
<span class="path-tag-wrap">
<span>${fileName}</span>
<span>${fileSpan}</span>
</span>
</span>`
return html
}
const elemToHtmlConf = {
type: 'attachment', // 新元素的 type ,重要!!!
elemToHtml: attachmentToHtml,
}
const elemToHtmlConftwo = {
type: 'attachmenttwo', // 新元素的 type ,重要!!!
elemToHtml: attachmentToHtmltwo,
}
const elemToHtmlConfmodule = { // JS 语法
elemsToHtml: [elemToHtmlConf, elemToHtmlConftwo /* 其他元素... */] // elemToHtml
}
Boot.registerModule(elemToHtmlConfmodule)
function parseAttachmentHtml(domElem, children, editor) { // JS 语法
// 从 DOM element 中获取“附件”的信息
const link = domElem.getAttribute('data-link') || ''
const fileName = domElem.getAttribute('data-fileName') || ''
const fileSpan = domElem.getAttribute('data-fileSpan') || ''
const fieldMark = domElem.getAttribute('data-fieldMark') || ''
// 生成“附件”元素(按照此前约定的数据结构)
const myResume = {
type: 'attachment',
link,
fileName,
fileSpan,
fieldMark,
children: [{ text: '' }], // void node 必须有 children ,其中有一个空字符串,重要!!!
}
return myResume
}
function parseAttachmentHtmltwo(domElem, children, editor) { // JS 语法
// 从 DOM element 中获取“附件”的信息
const link = domElem.getAttribute('data-link') || ''
const fileName = domElem.getAttribute('data-fileName') || ''
const fileSpan = domElem.getAttribute('data-fileSpan') || ''
const fieldMark = domElem.getAttribute('data-fieldMark') || ''
// 生成“附件”元素(按照此前约定的数据结构)
const myResume = {
type: 'attachmenttwo',
link,
fileName,
fileSpan,
fieldMark,
children: [{ text: '' }], // void node 必须有 children ,其中有一个空字符串,重要!!!
}
return myResume
}
const parseHtmlConf = {
selector: 'span[data-w-e-type="attachment"]', // CSS 选择器,匹配特定的 HTML 标签
parseElemHtml: parseAttachmentHtml,
}
const parseHtmlConftwo = {
selector: 'span[data-w-e-type="attachmenttwo"]', // CSS 选择器,匹配特定的 HTML 标签
parseElemHtml: parseAttachmentHtmltwo,
}
const parseHtmlConfmodule = {
parseElemsHtml: [parseHtmlConf, parseHtmlConftwo] // parseElemHtml
}
Boot.registerModule(parseHtmlConfmodule)
</script>
<style lang="scss" scoped>
::v-deep .el-textarea__inner {
color: black !important;
background-color: #fff !important;
cursor: default !important
}
.path-tag-wrap {
font-size: 18px;
line-height: 32px;
border-radius: 5px;
}
</style>
<style src="@wangeditor/editor/dist/css/style.css"></style>