更换editor,可支持拖拽式上传

This commit is contained in:
lemon橪
2022-07-05 18:04:04 +08:00
parent 8ef3510c4b
commit c7b739e546
21 changed files with 324 additions and 551 deletions

View File

@@ -38,4 +38,7 @@ body {
.ivu-tag {
cursor: pointer;
}
.tox-notifications-container{
display: none !important;
}
</style>

View File

@@ -1,4 +1,4 @@
import {commonUrl, getRequest} from '@/libs/axios';
import { commonUrl, getRequest, uploadFileRequest ,uploadFile} from "@/libs/axios";
// 通过id获取子地区
export const getChildRegion = (id) => {
@@ -10,15 +10,18 @@ export const getRegion = (params) => {
return getRequest(`${commonUrl}/common/common/region/region`, params);
};
// 获取IM接口前缀
export function getIMDetail () {
export function getIMDetail() {
return getRequest(`${commonUrl}/common/common/IM`);
}
//获取图片logo
export function getBaseSite () {
export function getBaseSite() {
return getRequest(`${commonUrl}/common/common/site`);
}
// 上传文件
export const upLoadFileMethods = (bold) => {
console.log(bold)
return uploadFileRequest(uploadFile, bold);
};

View File

@@ -318,13 +318,16 @@ export const uploadFileRequest = (url, params) => {
return service({
method: "post",
url: `${url}`,
params: params,
data: params,
headers: {
accessToken: accessToken
accessToken: accessToken,
'Content-Type': 'multipart/form-data'
}
});
};
/**
* 无需token验证的请求 避免旧token过期导致请求失败
* @param {*} url

View File

@@ -530,17 +530,30 @@
></Tree>
</FormItem>
</div>
<FormItem class="form-item-view-el" label="商品描述" prop="intro">
<editor eid="intro" v-model="baseInfoForm.intro"></editor>
<FormItem
style="width: 100%"
class="form-item-view-el"
label="商品描述"
prop="intro"
>
<editor
ref="editor"
openXss
v-model="baseInfoForm.intro"
:init="{ ...initEditor, height: '400px' }"
></editor>
</FormItem>
<FormItem
style="width: 100%"
class="form-item-view-el"
label="移动端描述"
prop="skuList"
>
<editor
eid="mobileIntro"
ref="editor"
openXss
v-model="baseInfoForm.mobileIntro"
:init="{ ...initEditor, height: '400px' }"
></editor>
</FormItem>
</div>
@@ -684,13 +697,15 @@ import * as API_GOODS from "@/api/goods";
import * as API_Shop from "@/api/shops";
import cloneObj from "@/utils/index";
import vuedraggable from "vuedraggable";
import editor from "@/views/my-components/lili/editor";
import Editor from "@tinymce/tinymce-vue";
import { initEditor } from "@/views/lili-components/editor/config";
import { uploadFile } from "@/libs/axios";
import { regular } from "@/utils";
export default {
name: "goodsOperationSec",
components: {
editor,
editor: Editor,
vuedraggable,
},
props: {
@@ -717,6 +732,7 @@ export default {
};
return {
regular,
initEditor,
total: 0,
global: 0,
accessToken: "", //令牌token
@@ -1460,7 +1476,8 @@ export default {
cost: skus[index].cost,
price: skus[index].price,
[cloneTemp[0].name]: specItem.value,
images: skus[index].images || this.baseInfoForm.goodsGalleryFiles || [],
images:
skus[index].images || this.baseInfoForm.goodsGalleryFiles || [],
};
if (specItem.value !== "") {
obj.id = skus[index].id;
@@ -1882,4 +1899,7 @@ export default {
.ivu-select .ivu-select-dropdown {
overflow: hidden !important;
}
</style>
/* .tox-notifications-container{
display: none !important;
} */
</style>

View File

@@ -0,0 +1,60 @@
import plugins from "./plugins";
import toobar from "./toolbar";
import { upLoadFileMethods } from "@/api/common";
export const initEditor = {
height: "400px",
language: "zh_CN",
menubar: "file edit insert view format table", // 菜单:指定应该出现哪些菜单
toolbar: toobar, // 分组工具栏控件
plugins: plugins, // 插件(比如: advlist | link | image | preview等)
object_resizing: false, // 是否禁用表格图片大小调整
end_container_on_empty_block: true, // enter键 分块
powerpaste_word_import: "merge", // 是否保留word粘贴样式 clean | merge
code_dialog_height: 450, // 代码框高度 、宽度
code_dialog_width: 1000,
advlist_bullet_styles: "square", // 无序列表 有序列表
maxSize: "2097152", // 设置图片大小
accept: "image/jpeg, image/png", // 设置图片上传规则
images_upload_handler: async function (blobInfo, success, failure) {
const formData = new FormData();
console.log("请求")
formData.append("file", blobInfo.blob());
try {
const res = await upLoadFileMethods(formData);
if (res.result) {
success(res.result)
} else {
failure("上传文件有误请稍后重试");
}
} catch (e) {
failure('上传出错')
}
},
// init_instance_callback: function (editor) {
// var freeTiny = document.querySelector(".tox .tox-notification--in .tox-notification .tox-notification--warning .tox .tox-notification--warning .tox-notifications-container");
// freeTiny.style.display = "none";
// },
content_style: `
* { padding:0; margin:0; }
html, body height:100%; }
img { max-width:100%; display:block;height:auto; }
a { text-decoration: none; }
iframe{ width: 100%; }
p { line-height:1.6; margin: 0px; }
table{ word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
.mce-object-iframe{ width:100%; box-sizing:border-box; margin:0; padding:0; }
ul,ol{ list-style-position:inside; }
`, // 设置样式
statusbar: false, // 隐藏编辑器底部的状态栏
elementpath: false, // 禁用编辑器底部的状态栏
paste_data_images: true, // 允许粘贴图像
};

View File

@@ -0,0 +1,4 @@
const plugins = [
'advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount'
]
export default plugins

View File

@@ -0,0 +1,2 @@
const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor ']
export default toolbar

View File

@@ -1,234 +0,0 @@
<template>
<div>
<div style="position: relative">
<div :id="eid" style="text-align: left; min-width: 1080px"></div>
<div v-if="showExpand">
<div class="e-menu e-code" @click="editHTML">
<Icon type="md-code-working" size="22" />
</div>
<div class="e-menu e-preview" @click="fullscreenModal = true">
<Icon type="ios-eye" size="24" />
</div>
<div class="e-menu e-trash" @click="clear">
<Icon type="md-trash" size="18" />
</div>
</div>
</div>
<Modal title="编辑html代码" v-model="showHTMLModal" :mask-closable="false" :width="900" :fullscreen="full">
<Input v-if="!full" v-model="dataEdit" :rows="15" type="textarea" style="max-height: 60vh; overflow: auto" />
<Input v-if="full" v-model="dataEdit" :rows="32" type="textarea" />
<div slot="footer">
<Button @click="full = !full" icon="md-expand">全屏开/</Button>
<Button @click="editHTMLOk" type="primary" icon="md-checkmark-circle-outline">确定保存</Button>
</div>
</Modal>
<Modal title="预览" v-model="fullscreenModal" fullscreen>
<div v-html="data">{{ data }}</div>
<div slot="footer">
<Button @click="fullscreenModal = false">关闭</Button>
</div>
</Modal>
</div>
</template>
<script>
import { uploadFile } from "@/libs/axios";
import E from "wangeditor";
import xss from "xss";
// 表情包配置 自定义表情可在该js文件中统一修改
import { sina } from "@/libs/emoji";
export default {
name: "editor",
props: {
eid: {
type: String,
default: "editor",
},
value: String,
base64: {
type: Boolean,
default: false,
},
showExpand: {
type: Boolean,
default: true,
},
openXss: {
type: Boolean,
default: false,
},
},
data() {
return {
editor: "", // 初始化富文本编辑器
data: this.value, // 富文本数据
dataEdit: "", // 编辑数据
showHTMLModal: false, // 显示html
full: false, // html全屏开关
fullscreenModal: false, // 显示全屏预览
};
},
methods: {
// 初始化编辑器
initEditor() {
let that = this;
this.editor = new E(`#${this.eid}`);
// 编辑内容绑定数据
this.editor.config.onchange = (html) => {
this.data = html;
this.$emit("input", this.data);
this.$emit("on-change", this.data);
};
this.editor.config.showFullScreen = false;
// z-index
this.editor.config.zIndex = 100;
if (this.base64) {
// 使用 base64 保存图片
this.editor.config.uploadImgShowBase64 = true;
} else {
// 配置上传图片服务器端地址
this.editor.config.uploadImgServer = uploadFile;
// lili如要header中传入token鉴权
this.editor.config.uploadImgHeaders = {
accessToken: that.getStore("accessToken"),
};
this.editor.config.uploadFileName = "file";
this.editor.config.uploadImgHooks = {
before: function (xhr, editor, files) {
// 图片上传之前触发
},
success: function (xhr, editor, result) {
// 图片上传并返回结果,图片插入成功之后触发
},
fail: function (xhr, editor, result) {
// 图片上传并返回结果,但图片插入错误时触发
that.$Message.error("上传图片失败");
},
error: function (xhr, editor) {
// 图片上传出错时触发
that.$Message.error("上传图片出错");
},
timeout: function (xhr, editor) {
// 图片上传超时时触发
that.$Message.error("上传图片超时");
},
// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
customInsert: function (insertImg, result, editor) {
if (result.success == true) {
let url = result.result;
insertImg(url);
that.$Message.success("上传图片成功");
} else {
that.$Message.error(result.message);
}
},
};
}
this.editor.config.customAlert = function (info) {
// info 是需要提示的内容
// that.$Message.info(info);
};
// 字体
this.editor.config.fontNames = ["微软雅黑", "宋体", "黑体", "Arial"];
// 表情面板可以有多个 tab ,因此要配置成一个数组。数组每个元素代表一个 tab 的配置
this.editor.config.emotions = [
{
// tab 的标题
title: "新浪",
// type -> 'emoji' / 'image'
type: "image",
// content -> 数组
content: sina,
},
];
if (this.value) {
if (this.openXss) {
this.editor.txt.html(xss(this.value));
} else {
this.editor.txt.html(this.value);
}
}
this.editor.create();
},
// html预览
editHTML() {
this.dataEdit = this.data;
this.showHTMLModal = true;
},
// 保存
editHTMLOk() {
this.editor.txt.html(this.dataEdit);
this.$emit("input", this.data);
this.$emit("on-change", this.data);
this.showHTMLModal = false;
},
// 清空编辑器
clear() {
this.$Modal.confirm({
title: "确认清空",
content: "确认要清空编辑器内容?清空后不能撤回",
onOk: () => {
this.data = "";
this.editor.txt.html(this.data);
this.$emit("input", this.data);
this.$emit("on-change", this.data);
},
});
},
setData(value) {
// 设置数据
if (!this.editor) {
this.initEditor();
}
if (value && value != this.data) {
this.data = value;
this.editor.txt.html(this.data);
this.$emit("input", this.data);
this.$emit("on-change", this.data);
}
},
},
watch: {
value: {
handler: function (val) {
// 赋值给富文本
this.setData(this.$options.filters.enCode(val));
},
},
},
mounted() {
this.initEditor();
},
};
</script>
<style lang="scss" scoped>
.e-menu {
z-index: 101;
position: absolute;
cursor: pointer;
color: #999;
:hover {
color: #333;
}
}
.w-e-toolbar {
// 给工具栏换行
flex-wrap: wrap;
}
.e-code {
top: 6px;
left: 976px;
}
.e-preview {
top: 6px;
left: 1014px;
}
.e-trash {
top: 4px;
left: 1047px;
}
</style>