This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nezha-nezha-fronted/nezha-fronted/src/components/chart/richTextEditor.vue

172 lines
4.8 KiB
Vue

<template>
<div style="position: relative" class="rich-text-editor" :class="{'rich-text-editor-error':tooLong}">
<div :id="id" class="editor-core" ref="editor" style="height:350px;"></div>
<div class="text-too-long" v-if="tooLong">{{$t('validate.tooLong')}}</div>
<el-upload
action=""
:auto-upload="false"
accept=".jpg,.png"
:on-change="uploadChange"
style="display: none"
ref="upload"
>
</el-upload>
</div>
</template>
<script>
import 'quill/dist/quill.snow.css'
import Quill from 'quill'
export default {
name: 'richTextEditor',
props: {
editData: String
},
data () {
return {
id: 'editor-' + this.guid(),
quill: null,
options: {
theme: 'snow',
modules: {
toolbar: [
[{ header: [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline', 'strike'],
['link', 'code-block'],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ color: [] }, { background: [] }],
[{ align: [] }],
['image'] // 上传图片
]
}
},
maxLength: 0, // 记录最大长度
tooLong: false
}
},
created () {
},
methods: {
initEditor: function () {
const $self = this
if (!this.quill) {
this.quill = new Quill(this.$refs.editor, this.options)
// 覆盖默认上传图片
const toolbar = this.quill.getModule('toolbar')
toolbar.addHandler('image', (value) => {
if (value) {
this.$refs.upload.$children[0].$refs.input.click()
} else {
this.quill.format('image', false)
}
})
this.quill.on('selection-change', function (range, oldRange, source) {
const tooltip = $self.$el.querySelector('.ql-tooltip')
if (tooltip) {
const left = tooltip.style.left
if (left && /\-\d+\.?\d+?px/.test(left)) {
tooltip.style.left = '10px'
}
}
})
this.quill.on('text-change', function (delta, oldDelta, source) {
const length = $self.getHtml().length
if (length > 60000) {
$self.quill.deleteText($self.maxLength - 1, $self.quill.getText().length - 1, 'api')
$self.tooLong = true
} else {
$self.maxLength = $self.quill.getText().length
$self.tooLong = false
}
$self.$emit('textChange', $self.quill.root.innerHTML)
})
this.$nextTick(() => {
this.$emit('after-init')
// this.$emit('textChange')
})
}
},
getHtml: function () {
const html = `<div class="editor-core ql-container ql-snow"><div class="ql-editor">${this.quill.root.innerHTML}</div></div>`
return html
},
getContent: function () {
if (this.tooLong) {
return false
} else {
return this.getHtml()
}
},
guid () {
function S4 () {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
}
return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4())
},
// 上传图片
async uploadChange (file) {
// 图片小于4M
const isLt4M = (file.size / 1024 / 1024) < 4
if (isLt4M) {
console.log(this.$axios.defaults.baseURL + 'file/download/')
const form = new FormData()
form.append('file', file.raw)
const res = await this.$post('/file/upload', form, { 'Content-Type': 'multipart/form-data' })
if (res.code === 200) {
// 获取光标所在位置
const currentIndex = this.quill.getSelection().index
// 插入图片
const uploadUrl = this.$axios.defaults.baseURL + 'file/download/'
this.quill.insertEmbed(currentIndex, 'image', `${uploadUrl}${res.data.uuid}`)
// 调整光标到最后
this.quill.setSelection(currentIndex + 1)
} else {
this.$message.error(res.msg)
}
} else {
this.$message.error(this.$t('tip.imgSize'))
}
}
},
mounted () {
this.initEditor()
if (this.editData) {
this.quill.clipboard.dangerouslyPasteHTML(null, this.editData, 'api')
}
},
beforeDestroy () {
this.quill.off('selection-change')
this.quill.off('text-change')
}
}
</script>
<style>
.rich-text-editor .ql-editor{
overflow: auto !important;
}
.text-too-long{
color: #F56C6C;
font-size: 12px;
line-height: 1;
padding-top: 4px;
position: absolute;
top: 100%;
left: 0;
}
.rich-text-editor-error {
border: 1px solid #F56C6C;
}
.rich-text-editor-error .ql-container.ql-snow {
border: unset !important
}
.rich-text-editor-error .ql-toolbar.ql-snow{
border-top: unset !important;
border-left: unset !important;
border-right: unset !important;
}
</style>