Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-ui

This commit is contained in:
Chopper711
2023-12-11 07:58:28 +08:00
325 changed files with 238504 additions and 75 deletions

View File

@@ -1,33 +1,25 @@
import plugins from "./plugins";
import toobar from "./toolbar";
import { upLoadFile } from "@/api/common";
const localCDN = window.location.origin + "/tinymce"; //本地引入
export const initEditor = {
base_url: localCDN,
height: "400px",
language: "zh_CN",
language: "zh-Hans",
menubar: "file edit view format table", // 菜单:指定应该出现哪些菜单
toolbar: toobar, // 分组工具栏控件
plugins: plugins, // 插件(比如: advlist | link | image | preview等)
plugins:plugins, // 插件(比如: advlist | link | image | preview等)
object_resizing: false, // 是否禁用表格图片大小调整
end_container_on_empty_block: true, // enter键 分块
powerpaste_word_import: "merge", // 是否保留word粘贴样式 clean | merge
advlist_bullet_styles: "square", // 无序列表 有序列表
maxSize: "2097152", // 设置图片大小
accept: "image/jpeg, image/png", // 设置图片上传规则
images_upload_handler: async function (blobInfo, success, failure) {
const formData = new FormData();
formData.append("file", blobInfo.blob());
try {
const res = await upLoadFile(formData);
if (res.result) {
success(res.result)
} else {
failure("上传文件有误请稍后重试");
}
} catch (e) {
failure('上传出错')
}
},
paste_data_images:false,
browser_spellcheck: true, // 拼写检查
branding: false, // 去水印
elementpath: false, // 禁用编辑器底部的状态栏
statusbar: false, // 隐藏编辑器底部的状态栏
// 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";
@@ -51,7 +43,4 @@ export const initEditor = {
ul,ol{ list-style-position:inside; }
`, // 设置样式
statusbar: false, // 隐藏编辑器底部的状态栏
elementpath: false, // 禁用编辑器底部的状态栏
paste_data_images: true, // 允许粘贴图像
};

View File

@@ -0,0 +1,129 @@
<template>
<div>
<!-- 使用 fullscreen 类来控制是否全屏显示 -->
<div :class="{ fullscreen: fullscreen }" class="tinymce-container">
<!-- 使用 tinymce-textarea 类作为编辑器的文本区域 -->
<uploadImage @callback="insertImage" />
<textarea :id="tinymceId" class="tinymce-textarea" />
</div>
</div>
</template>
<script>
import { initEditor } from "@/components/editor/config";
import uploadImage from "@/components/editor/upload-image.vue";
export default {
components:{uploadImage},
name: "Tinymce",
props: {
value: {
type: String,
default: "",
},
height:{
type:String,
default:'500px'
}
},
data() {
return {
// 引入编辑器的配置
initEditor,
hasChange: false, // 标记内容是否有更改
hasInit: false, // 标记编辑器是否已初始化
tinymceId:
"tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + ""), // 生成唯一的编辑器 ID
fullscreen: false, // 标记编辑器是否处于全屏模式
toolbar: [], // 工具栏配置
content: "", // 编辑器内容
};
},
created() {
this.init();
},
watch: {
value: {
handler(val) {
if (!this.hasChange && this.hasInit) {
// 当内容有更改且编辑器已初始化时,更新编辑器的内容
this.$nextTick(() =>
window.tinymce.get(this.tinymceId).setContent(val || "")
);
}
},
deep: true,
},
},
methods: {
// 数据返回并给富文本框插入图片
insertImage(arr){
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img src="${v}" >`))
},
init() {
// 初始化编辑器
this.initTinymce();
},
initTinymce() {
const _this = this;
window.tinymce.init({
selector: `#${this.tinymceId}`,
convert_urls: false,
init_instance_callback: (editor) => {
if (_this.value) {
// 如果有初始值,则设置编辑器的内容为初始值
this.$nextTick(() => editor.setContent(_this.value));
}
_this.hasInit = true;
// 监听编辑器内容的变化
editor.on("NodeChange Change KeyUp SetContent", (event) => {
if (_this.value) {
// 内容发生更改
this.hasChange = true;
}
// 通过 input 事件将编辑器的内容传递给父组件
this.$emit("input", editor.getContent());
});
},
setup(editor) {
// 监听全屏状态变化
editor.on("FullscreenStateChanged", (e) => {
_this.fullscreen = e.state;
});
},
..._this.initEditor,
height:this.height
});
},
setContent(value) {
// 设置编辑器的内容
window.tinymce.get(this.tinymceId).setContent(value);
},
getContent() {
// 获取编辑器的内容
return window.tinymce.get(this.tinymceId).getContent();
},
destroyTinymce() {
const tinymce = window.tinymce.get(this.tinymceId);
if (tinymce) {
// 销毁编辑器实例
tinymce.destroy();
}
},
},
mounted() {
this.init();
},
activated() {
if (window.tinymce) {
this.initTinymce();
}
},
deactivated() {
this.destroyTinymce();
},
destroyed() {
this.destroyTinymce();
},
};
</script>

View File

@@ -1,4 +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'
'advlist', 'anchor', 'autolink', 'autosave', 'code', 'codesample', 'directionality', 'emoticons', 'fullscreen', 'image', 'importcss', 'insertdatetime', 'link', 'lists', 'media', 'nonbreaking', 'pagebreak', 'preview', 'save', 'searchreplace', 'table', 'template', 'visualblocks', 'visualchars', 'wordcount'
]
export default plugins

View File

@@ -0,0 +1,213 @@
<template>
<div class="wrapper">
<Button @click="handleClickUploadImage">上传图片</Button>
<Modal v-model="show" width="850" @on-ok="callback" title="上传图片">
<div class="import-oss" @click="importOSS">
从资源库中导入
</div>
<div style="display: flex; flex-wrap: wrap">
<vuedraggable
:animation="200"
:list="images"
>
<div
v-for="(item, __index) in images"
:key="__index"
class="upload-list"
>
<template>
<img alt="image" :src="item.url"/>
<div class="upload-list-cover">
<div>
<Icon
size="30"
type="md-search"
@click.native="$previewImage(item.url)"
></Icon>
<Icon
size="30"
type="md-trash"
@click.native="handleRemoveGoodsPicture(__index)"
></Icon>
</div>
</div>
</template>
</div>
</vuedraggable>
<div class="upload-box">
<Upload
ref="upload"
:action="uploadFileUrl"
:format="['jpg', 'jpeg', 'png']"
:headers="{ ...accessToken }"
:max-size="10240"
:on-exceeded-size="handleMaxSize"
:on-format-error="handleFormatError"
:on-success="handleSuccessGoodsPicture"
:show-upload-list="false"
multiple
type="drag"
>
<div style="width: 148px; height: 148px; line-height: 148px">
<Icon size="20" type="md-add"></Icon>
</div>
</Upload>
</div>
</div>
</Modal>
<Modal width="1000" v-model="showOssManager" @on-ok="confirmUrls">
<OssManage ref="ossManage" @selected="handleCallback" />
</Modal>
</div>
</template>
<script>
import vuedraggable from "vuedraggable";
import { uploadFile } from "@/libs/axios";
import OssManage from "@/views/sys/oss-manage/ossManage.vue";
export default {
name: "upload-image",
components: {
OssManage,
vuedraggable,
},
data() {
return {
show: false, // 是否显示弹窗
uploadFileUrl: uploadFile, // 上传地址
accessToken:"",
showOssManager:false, // 是否显示oss管理弹窗
images:[],
selectedImage:[]
}
},
mounted() {
this.accessToken = {
accessToken: this.getStore("accessToken"),
};
},
methods: {
confirmUrl(){
},
handleClickUploadImage(){
this.show = true
},
// 回调给父级
callback() {
// 先给数据做一下处理 然后将数据传给父级
const formatImages = this.images.map((item) => item.url);
this.$emit('callback',formatImages)
},
// 移除商品图片
handleRemoveGoodsPicture(__index) {
this.images.splice(__index, 1);
},
// 图片大小不正确
handleMaxSize(file) {
this.$Notice.warning({
title: "超过文件大小限制",
desc: "图片大小不能超过10MB",
});
},
// 图片格式不正确
handleFormatError(file) {
this.$Notice.warning({
title: "文件格式不正确",
desc: "文件 " + file.name + " 的格式不正确",
});
},
// sku图片上传成功
handleSuccessGoodsPicture(res, file) {
if (file.response) {
file.url = file.response.result;
this.images.push(file);
}
},
confirmUrls(){
this.selectedImage.length ? this.selectedImage.forEach(element => {
this.images.push({ url: element.url })
}):''
this.showOssManager = false
},
handleCallback(val){
this.selectedImage = val
},
// 从资源库中导入图片
importOSS(){
this.showOssManager = true
this.$refs.ossManage.selectImage = true;
}
}
}
</script>
<style scoped lang="scss">
.import-oss{
margin-bottom: 10px;
text-align: right;
color: $theme_color;
cursor: pointer;
}
.wrapper{
margin: 10px 0;
}
.upload-list {
width: 150px;
height: 150px;
text-align: center;
border: 1px solid transparent;
border-radius: 4px;
display: inline-block;
background: #fff;
position: relative;
margin-right: 4px;
vertical-align: bottom;
}
.upload-box{
margin: 10px 0;
}
.upload-list img {
width: 100%;
height: 100%;
}
.upload-list-cover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
justify-content: space-between;
align-items: center;
flex-direction: column;
}
.upload-list:hover .upload-list-cover {
display: flex;
}
.upload-list-cover div {
margin-top: 50px;
width: 100%;
>i {
width: 50%;
margin-top: 8px;
color: #fff;
font-size: 20px;
cursor: pointer;
}
}
</style>

View File

@@ -111,12 +111,12 @@
/>
</FormItem>
<FormItem class="form-item-view-el" label="文章内容" prop="content">
<editor
ref="editor"
openXss
v-model="form.content"
:init="{ ...initEditor,height:'800px' }"
></editor>
<tinymec
ref="editor"
openXss
v-model="form.content"
v-if="modalVisible"
></tinymec>
</FormItem>
<FormItem label="是否展示" prop="openStatus">
<i-switch size="large" v-model="form.openStatus">
@@ -146,12 +146,10 @@ import {
seeArticle,
updateArticleStatus,
} from "@/api/pages";
import Editor from "@tinymce/tinymce-vue";
import { initEditor } from "@/components/editor/config";
import tinymec from "@/components/editor/index.vue";
export default {
components: {
editor: Editor,
tinymec: tinymec,
},
props: {
selected: {
@@ -161,7 +159,6 @@ export default {
},
data() {
return {
initEditor: initEditor,
selectedIndex: 99999, // 已选下标
loading: true, // 表单加载状态
modalType: 0, // 添加或编辑标识

View File

@@ -17,12 +17,12 @@
</FormItem>
<FormItem class="form-item-view-el" label="文章内容" prop="content">
<editor
ref="editor"
openXss
v-model="form.article.content"
:init="{ ...initEditor,height:'800px' }"
></editor>
<editor
ref="editor"
openXss
v-model="form.article.content"
v-if="modalVisible"
></editor>
</FormItem>
</Form>
<div slot="footer">
@@ -40,12 +40,12 @@ import {
updatePrivacy,
getPrivacy,
} from "@/api/pages";
import Editor from "@tinymce/tinymce-vue";
import { initEditor } from "@/components/editor/config";
import tinymec from "@/components/editor/index.vue";
export default {
name: "privacy",
components: {
editor: Editor,
editor: tinymec,
},
props: {
selected: {
@@ -55,7 +55,6 @@ export default {
},
data() {
return {
initEditor,
loading: false, // 表单加载状态
modalVisible: false, // 添加或编辑显示
treeDataDefault: [],

View File

@@ -1144,6 +1144,7 @@ export default {
size += item.fileSize * 1.0;
});
this.totalSize = ((size * 1.0) / (1024 * 1024)).toFixed(2) + " MB";
this.$emit("selected", e)
},
},
mounted() {