<richText details="标记" :value="ruleForm.data" @getInputValue="getInputValue" />
// 监听并且给输入框复制
getInputValue(val, key) {
switch (key) {
case '标记':
this.ruleForm.data= val
break
}
}
const toolbarOptions = [
[],
['blockquote', 'code-block'],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ script: 'sub' }, { script: 'super' }],
[{ indent: '-1' }, { indent: '+1' }],
[{ direction: 'rtl' }],
[{ 'color': [] }, { 'background': [] }],
['link'],
['upload']
]
export default toolbarOptions
<template>
<div style="width:100%">
<div class="avatar">
<el-upload id="quill-upload" ref="annexUpload" action="上传的路径" name="content" :limit="1" list-type="picture" :on-exceed="handleExceed" :on-error="handleError" :file-list="uploadList" :with-credentials="true" :auto-upload="true" />
</div>
<quill-editor ref="myQuillEditor" v-model="content" v-viewer :options="editorOption" @change="onEditorChange($event)" @focus="onEditorClick($event)" />
<el-dialog
title="附件上传"
:visible.sync="dialogVisible"
width="28%"
:modal="false"
:before-close="handleClose"
>
<div class="demo">
<el-upload
ref="upload"
class="upload-demo"
action="/api/security_audit_tools/hole_planet_file"
:on-change="handleProgress"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
:auto-upload="false"
:on-success="handleSuccess"
:on-error="handleFileError"
:before-upload="beforeAvatarUpload"
:on-exceed="handleExceed1"
multiple
drag
:limit="5"
>
<i class="el-icon-upload" />
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div slot="tip" class="el-upload__tip">一次只能上传5个文件,且每个文件不超过50Mb</div>
</el-upload>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleClose">取 消</el-button>
<el-button type="primary" :disabled="uploadAble" @click="insertData">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor, Quill } from 'vue-quill-editor'
import toolbarOptions from './toolbarOptions'
import { uploadFileBug, uploadPicTask } from '@/api/codecheck/bugPlanet/index'
var Link = Quill.import('formats/link')
class FileBlot extends Link { // 继承Link Blot
static create(value) {
let node
if (value && !value.href) { // 适应原本的Link Blot
node = super.create(value)
} else { // 自定义Link Blot
node = super.create(value.href)
// node.setAttribute('download', value.innerText); // 左键点击即下载
node.innerText = value.innerText
node.download = value.innerText
}
return node
}
}
FileBlot.blotName = 'link'
FileBlot.tagName = 'A'
Quill.register(FileBlot)
export default {
components: { quillEditor },
props: {
details: {
type: String,
default: ''
},
value: {
type: String,
default: ''
},
goto: {
type: Number,
default: 0
},
tabIndex: {
type: Number,
default: 0
}
},
data() {
return {
once: false,
timing: null,
uploadAble: false,
sucList: [],
fileList: [],
fileExe: [],
dialogVisible: false,
content: '',
editorOption: {
placeholder: '',
theme: 'snow',
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
image: function(value) {
if (value) {
document.querySelector('.quill-upload input').click()
} else {
this.quill.format('image', false)
}
},
upload: (value) => {
if (value) {
this.dialogVisible = true
// document.querySelector('#quill-upload1 input').click()
}
}
}
}
}
},
uploadList: []
}
},
watch: {
value(curVal) {
if (curVal) {
this.content = curVal
}
// if (!this.once) {
// this.$nextTick(() => {
// this.$refs.myQuillEditor.quill.blur()
// window.scrollTo(0, 0)
// this.once = true
// })
// }
},
goto() {
setTimeout(() => {
const quill = this.$refs.myQuillEditor.quill
quill.setSelection(this.content.length + 1)
}, 100)
},
fileList: {
handler() {
let isOk = true
this.fileList.forEach(item => {
if (item.size / 1024 / 1024 < 50 && item.status !== 'success') {
isOk = false
}
})
isOk ? this.uploadAble = false : this.uploadAble = true
},
deep: true
}
},
mounted() {
this.initPic()
if (this.value) {
this.content = this.value
setTimeout(() => {
const quill = this.$refs.myQuillEditor.quill
quill.setSelection(this.content.length + 1)
}, 100)
}
},
methods: {
insertData() {
const quill = this.$refs.myQuillEditor.quill
let length = quill.getSelection(true).index
this.$refs.myQuillEditor.quill.focus()
this.sucList.forEach((item, i) => {
if (i === 0) {
const title = `\n 上传人:${item.uploader},上传时间:${item.uploadTime} \n`
quill.insertEmbed(length, title)
length += title.length
quill.insertEmbed(length, 'link', { href: item.url, innerText: item.name, download: item.name }, 'api')
length += item.name.length
} else {
const title = `\n`
quill.insertEmbed(length, title)
length += title.length
quill.insertEmbed(length, 'link', { href: item.url, innerText: item.name, download: item.name }, 'api')
length += item.name.length
}
// quill.setSelection(length + 1)
})
this.sucList = []
this.fileList = []
this.dialogVisible = false
},
// 文件上传限制
handleExceed1(files, fileList) {
this.$message.warning(`当前限制一次性上传最多 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
},
handleProgress(file, fileList) {
this.fileList = fileList
if (file.status === 'ready') {
const isLt2M = file.size / 1024 / 1024 < 50
if (!isLt2M) {
if (this.timing) {
clearTimeout(this.timing)
}
this.timing = setTimeout(() => {
this.$message.error(`上传附件大小不能超过 50MB!`)
}, 1 * 500)
this.fileExe.push(file.name)
let index = -1
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].name === file.name) {
index = i
}
}
this.$nextTick(function() {
const style = document.getElementsByClassName('el-upload-list__item-name')
style[index].style.color = 'red'
})
} else {
const params = new FormData()
params.append('file', file.raw)
file.status = 'uploading'
file.percentage = 0
const onUploadProgress = (progressEvent) => {
const percent = (progressEvent.loaded / progressEvent.total) * (89 + Math.round(Math.random() * 10)) || 0
file.percentage = percent
}
uploadFileBug({
data: params
}, onUploadProgress).then((res) => {
if (res.code === '0') {
file.status = 'success'
this.sucList.push({ url: process.env.VUE_APP_BASE_API + '/api/security_audit_tools/hole_planet_file' + res.data.url, name: res.data.name, uploadTime: res.data.uploadTime, uploader: res.data.uploader })
} else {
file.status = 'ready'
}
})
}
}
},
beforeAvatarUpload(file) {
},
handleSuccess(response, file, fileList) {
if (response.code === '0') {
this.sucList.push({ url: process.env.VUE_APP_BASE_API + '/api/security_audit_tools/hole_planet_file' + response.data.url, name: response.data.name, uploadTime: response.data.uploadTime, uploader: response.data.uploader })
}
},
handleFileError(err, file, fileList) {
this.$message.error(`文件上传失败,请尝试重新上传,文件失败原因为: ${err}`)
},
submitUpload() {
this.$refs.upload.headers['token'] = localStorage.getItem('panlong_userToken')
this.$refs.upload.submit()
},
handleRemove(file, fileList) {
for (let i = 0; i < this.fileList.length; i++) {
if (this.fileList[i].name === file.name) {
this.fileList.splice(i, 1)
}
}
for (let i = 0; i < this.sucList.length; i++) {
if (this.sucList[i].name === file.name) {
this.sucList.splice(i, 1)
}
}
for (let i = 0; i < this.fileExe.length; i++) {
if (this.fileExe[i] === file.name) {
this.fileExe.splice(i, 1)
}
}
if (this.fileExe.length === 0) {
this.uploadAble = false
}
},
handlePreview(file) {
// console.log(file)
},
handleClose() {
this.dialogVisible = false
},
// 监听点击超链接显示弹窗
onEditorClick(event) {
const e = document.querySelectorAll('.ql-tooltip,.ql-flip')
if (e && e[this.tabIndex]) {
if (e[this.tabIndex].style.left.indexOf('-') === 0) {
e[this.tabIndex].style.left = 0
}
if (e[this.tabIndex].style.top.indexOf('-') === 0) {
e[this.tabIndex].style.top = 0
}
}
},
// 监听富文本改变
onEditorChange(e) {
this.$emit('getInputValue', e.html, this.details)
},
// 文件上传限制
handleExceed(files, fileList) {
this.$message.warning(`当前限制一次性上传最多 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
},
// 文件上传失败提示
handleError(err, file, fileList) {
this.$message.error(`文件上传失败,请尝试重新上传,文件失败原因为: ${err}`)
},
initPic() {
const quill = this.$refs.myQuillEditor.quill
this.$forceUpdate()
quill.root.addEventListener(
'paste',
(evt) => {
if (evt.clipboardData && evt.clipboardData.files && evt.clipboardData.files.length) {
evt.preventDefault()
;[].forEach.call(evt.clipboardData.files, (file) => {
if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
return
}
var formData = new FormData()
formData.append('uploadFile', file)
uploadPicTask({
data: formData
}).then((res) => {
var range = quill.getSelection()
if (range) {
const quill = this.$refs.myQuillEditor.quill
const length = quill.getSelection().index
quill.insertEmbed(length, 'image', '/api/security_audit_tools/hole_planet_file/image/' + res.data)
quill.setSelection(length + 1)
// eslint-disable-next-line no-unused-vars
let fileType = null
if (file.raw && file.raw.type) {
fileType = file.raw.type
} else {
fileType = file.type
}
this.uploadList = []
this.$refs.myQuillEditor.quill.setSelection(range.index + 1)
}
})
})
}
},
false
)
}
}
}
</script>
<style lang="scss" scoped>
.avatar {
display: none;
}
::v-deep .el-dialog__header{
padding: 20px 20px 10px;
}
.demo{
.upload-demo{
border: 1px solid #eee;
min-height: 200px;
padding: 10px;
}
}
::v-deep .el-dialog__footer{
display: flex;
justify-content: center;
}
::v-deep .ql-container {
/* overflow-y: auto; */
height: 300px !important;
line-height: 25px;
// padding-bottom: 25px;
}
::v-deep .el-upload--text{
width: 100%;
}
::v-deep .el-upload-dragger {
background-color: #fff;
border: 1px dashed #d9d9d9;
border-radius: 6px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 180px;
text-align: center;
position: relative;
overflow: hidden;
}
</style>