diff --git a/yudao-ui-admin/package.json b/yudao-ui-admin/package.json index c92e3d233..c16997fc0 100644 --- a/yudao-ui-admin/package.json +++ b/yudao-ui-admin/package.json @@ -65,6 +65,7 @@ "vue-count-to": "1.0.13", "vue-cropper": "0.5.8", "vue-meta": "^2.4.0", + "vue-quill-editor": "^3.0.6", "vue-router": "3.4.9", "vue-video-player": "^5.0.2", "vuedraggable": "2.24.3", diff --git a/yudao-ui-admin/src/views/mp/components/wx-editor/WxEditor.vue b/yudao-ui-admin/src/views/mp/components/wx-editor/WxEditor.vue new file mode 100644 index 000000000..c2e8d669c --- /dev/null +++ b/yudao-ui-admin/src/views/mp/components/wx-editor/WxEditor.vue @@ -0,0 +1,219 @@ +<!-- + - Copyright (C) 2018-2019 + - All rights reserved, Designed By www.joolun.com +--> +<template> + <div id="wxEditor"> + <div v-loading="quillUpdateImg" element-loading-text="请稍等,图片上传中"> + <!-- 图片上传组件辅助--> + <el-upload class="avatar-uploader" name="file" :action="serverUrl" :headers="header" + :show-file-list="false" :data="uploadData" + :on-success="uploadSuccess" :on-error="uploadError" :before-upload="beforeUpload"> + </el-upload> + <quill-editor class="editor" v-model="content" ref="myQuillEditor" :options="editorOption" + @change="onEditorChange($event)"> + </quill-editor> + </div> + </div> +</template> + +<script> +// 工具栏配置 +const toolbarOptions = [ + ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线 + ["blockquote", "code-block"], // 引用 代码块 + [{ header: 1 }, { header: 2 }], // 1、2 级标题 + [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表 + [{ script: "sub" }, { script: "super" }], // 上标/下标 + [{ indent: "-1" }, { indent: "+1" }], // 缩进 + // [{'direction': 'rtl'}], // 文本方向 + [{ size: ["small", false, "large", "huge"] }], // 字体大小 + [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题 + [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色 + [{ font: [] }], // 字体种类 + [{ align: [] }], // 对齐方式 + ["clean"], // 清除文本格式 + ["link", "image", "video"] // 链接、图片、视频 +] + +import { quillEditor } from "vue-quill-editor" +import "quill/dist/quill.core.css" +import "quill/dist/quill.snow.css" +import "quill/dist/quill.bubble.css" +import { getAccessToken } from "@/utils/auth"; + +export default { + props: { + uploadData: { + type: Object + }, + /*编辑器的内容*/ + value: { + type: String + }, + /*图片大小*/ + maxSize: { + type: Number, + default: 4000 // kb + } + }, + name: 'wxEditor', + components: { + quillEditor + }, + data() { + return { + editorType: '1', + content: this.value.replace(/data-src/g, "src"), + + quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示 + editorOption: { + theme: "snow", // or 'bubble' + placeholder: "请输入文章内容", + modules: { + toolbar: { + container: toolbarOptions, + // container: "#toolbar", + handlers: { + image: function(value) { + if (value) { + // 触发input框选择图片文件 + document.querySelector(".avatar-uploader input").click(); + } else { + this.quill.format("image", false); + } + }, + link: function(value) { + if (value) { + const href = prompt('注意!只支持公众号图文链接'); + this.quill.format("link", href); + } else { + this.quill.format("link", false); + } + }, + } + } + } + }, + serverUrl: process.env.VUE_APP_BASE_API +'/wxmaterial/newsImgUpload', // 这里写你要上传的图片服务器地址 + headers: { Authorization: "Bearer " + getAccessToken() }, // 设置上传的请求头部 + } + }, + methods: { + onEditorChange(editor) { + //内容改变事件 + this.$emit("input", this.content) + }, + + // 富文本图片上传前 + beforeUpload() { + // 显示loading动画 + this.quillUpdateImg = true + }, + + uploadSuccess(res, file) { + // res为图片服务器返回的数据 + // 获取富文本组件实例 + let quill = this.$refs.myQuillEditor.quill + // 如果上传成功 + if(res.link){ + // 获取光标所在位置 + let length = quill.getSelection().index; + // 插入图片 res.info为服务器返回的图片地址 + quill.insertEmbed(length, 'image', res.link) + // 调整光标到最后 + quill.setSelection(length + 1) + } else { + this.$message.error('图片插入失败') + } + // loading动画消失 + this.quillUpdateImg = false; + }, + // 富文本图片上传失败 + uploadError() { + // loading动画消失 + this.quillUpdateImg = false; + this.$message.error("图片插入失败"); + } + } +} +</script> + +<style> +.editor { + line-height: normal !important; + height: 500px; +} +.ql-snow .ql-tooltip[data-mode=link]::before { + content: "请输入链接地址:"; +} +.ql-snow .ql-tooltip.ql-editing a.ql-action::after { + border-right: 0; + content: '保存'; + padding-right: 0; +} + +.ql-snow .ql-tooltip[data-mode=video]::before { + content: "请输入视频地址:"; +} + +.ql-snow .ql-picker.ql-size .ql-picker-label::before, +.ql-snow .ql-picker.ql-size .ql-picker-item::before { + content: '14px'; +} +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before, +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before { + content: '10px'; +} +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before, +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before { + content: '18px'; +} +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before, +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { + content: '32px'; +} + +.ql-snow .ql-picker.ql-header .ql-picker-label::before, +.ql-snow .ql-picker.ql-header .ql-picker-item::before { + content: '文本'; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { + content: '标题1'; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { + content: '标题2'; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { + content: '标题3'; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { + content: '标题4'; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { + content: '标题5'; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { + content: '标题6'; +} + +.ql-snow .ql-picker.ql-font .ql-picker-label::before, +.ql-snow .ql-picker.ql-font .ql-picker-item::before { + content: '标准字体'; +} +.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before, +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before { + content: '衬线字体'; +} +.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before, +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before { + content: '等宽字体'; +} +</style> + diff --git a/yudao-ui-admin/src/views/mp/draft/index.vue b/yudao-ui-admin/src/views/mp/draft/index.vue index 52ea208eb..72162934f 100644 --- a/yudao-ui-admin/src/views/mp/draft/index.vue +++ b/yudao-ui-admin/src/views/mp/draft/index.vue @@ -117,7 +117,7 @@ SOFTWARE. <div class="right" v-loading="addMaterialLoading" v-if="articlesAdd.length > 0"> <!--富文本编辑器组件--> <el-row> - <WxEditor v-model="articlesAdd[isActiveAddNews].content" :uploadData="uploadData" + <wx-editor v-model="articlesAdd[isActiveAddNews].content" :uploadData="uploadData" v-if="hackResetEditor"/> </el-row> <br><br><br><br> @@ -162,17 +162,17 @@ SOFTWARE. <script> // import { getPage as getPage1 } from '@/api/wxmp/wxmaterial' -// import WxEditor from '@/components/Editor/WxEditor.vue' +import WxEditor from '@/views/mp/components/wx-editor/WxEditor.vue'; import WxNews from '@/views/mp/components/wx-news/main.vue'; import WxMaterialSelect from '@/views/mp/components/wx-material-select/main.vue' import { getAccessToken } from '@/utils/auth' -import {createDraft, getDraftPage} from "@/api/mp/draft"; -import {getSimpleAccounts} from "@/api/mp/account"; +import { createDraft, getDraftPage } from "@/api/mp/draft"; +import { getSimpleAccounts } from "@/api/mp/account"; export default { name: 'mpDraft', components: { - // WxEditor, + WxEditor, WxNews, WxMaterialSelect }, @@ -234,7 +234,7 @@ export default { this.setAccountId(this.accounts[0].id); } // 加载数据 - // this.getList(); + // this.getList(); // TODO 芋艿:开发完,放出来 }) }, methods: { diff --git a/yudao-ui-admin/yarn.lock b/yudao-ui-admin/yarn.lock index bd8e20a3b..671350613 100644 --- a/yudao-ui-admin/yarn.lock +++ b/yudao-ui-admin/yarn.lock @@ -8410,7 +8410,7 @@ "extend" "^3.0.2" "fast-diff" "1.1.2" -"quill@1.3.7": +"quill@^1.3.4", "quill@1.3.7": "integrity" "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==" "resolved" "https://registry.npmmirror.com/quill/-/quill-1.3.7.tgz" "version" "1.3.7" @@ -10479,6 +10479,14 @@ dependencies: "deepmerge" "^4.2.2" +"vue-quill-editor@^3.0.6": + "integrity" "sha512-g20oSZNWg8Hbu41Kinjd55e235qVWPLfg4NvsLW6d+DhgBTFbEuMpcWlUdrD6qT3+Noim6DRu18VLM9lVShXOQ==" + "resolved" "https://registry.npmmirror.com/vue-quill-editor/-/vue-quill-editor-3.0.6.tgz" + "version" "3.0.6" + dependencies: + "object-assign" "^4.1.1" + "quill" "^1.3.4" + "vue-router@3.4.9": "integrity" "sha512-CGAKWN44RqXW06oC+u4mPgHLQQi2t6vLD/JbGRDAXm0YpMv0bgpKuU5bBd7AvMgfTz9kXVRIWKHqRwGEb8xFkA==" "resolved" "https://registry.npmmirror.com/vue-router/-/vue-router-3.4.9.tgz"