|
@@ -7,9 +7,15 @@
|
|
|
<el-checkbox v-model="form.islink">是否使用外链</el-checkbox>
|
|
|
</el-form-item>
|
|
|
<div v-if="form.islink==1">
|
|
|
+ <el-form-item label="导航池名称:" prop="category_name">
|
|
|
+ <el-cascader :key="parentKey" v-model="form.cat_arr_id" placeholder="请选择要绑定的父级导航" :props="parentData" filterable clearable></el-cascader>
|
|
|
+ </el-form-item>
|
|
|
<el-form-item label="外链地址:" prop="linkurl">
|
|
|
<el-input v-model="form.linkurl" autocomplete="off"></el-input>
|
|
|
</el-form-item>
|
|
|
+ <el-form-item label="作者:" prop="author">
|
|
|
+ <el-input v-model="form.author" autocomplete="off"></el-input>
|
|
|
+ </el-form-item>
|
|
|
</div>
|
|
|
<div v-if="form.islink==0">
|
|
|
<el-form-item label="导航池名称:" prop="category_name">
|
|
@@ -32,15 +38,20 @@
|
|
|
<el-form-item label="资讯描述:" prop="introduce">
|
|
|
<el-input type="textarea" v-model="form.introduce"></el-input>
|
|
|
</el-form-item>
|
|
|
- <div class="QuillTitle"><span>* </span>资讯内容:</div>
|
|
|
+ <div class="QuillTitle">
|
|
|
+ <span>* </span>资讯内容:
|
|
|
+ <el-button @click="toggleSourceMode">
|
|
|
+ {{ showHtml ? '切换到编辑模式' : '切换到源码模式' }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
<el-form-item label="" prop="content">
|
|
|
<div class="editor-container">
|
|
|
- <quill-editor
|
|
|
- ref="quillEditor"
|
|
|
- v-model="form.content"
|
|
|
- :options="editorOptions"
|
|
|
- class="my-quill-editor"
|
|
|
- />
|
|
|
+ <div v-if="showHtml">
|
|
|
+ <textarea v-model="editorHtml" style="width: 100%; height: 400px;"></textarea>
|
|
|
+ </div>
|
|
|
+ <div v-else>
|
|
|
+ <quill-editor ref="quillEditor" v-model="form.content" :options="editorOptions" class="my-quill-editor"/>
|
|
|
+ </div>
|
|
|
<!-- 多图上传隐藏的input -->
|
|
|
<input type="file" ref="multiFileInput" @change="handleMultipleFiles" multiple hidden accept="image/jpeg, image/png" />
|
|
|
</div>
|
|
@@ -82,20 +93,18 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-// 引入 Quill 和相关插件
|
|
|
-import Quill from 'quill';
|
|
|
-import VueQuillEditor from 'vue-quill-editor';
|
|
|
-import 'quill/dist/quill.core.css';
|
|
|
+import { quillEditor } from 'vue-quill-editor';
|
|
|
import 'quill/dist/quill.snow.css';
|
|
|
-import 'quill/dist/quill.bubble.css';
|
|
|
-import ImageUploader from 'quill-image-uploader';
|
|
|
+import ImageResize from 'quill-image-resize-module';
|
|
|
+import Quill from 'quill'; // 引入 Quill
|
|
|
+import Delta from 'quill-delta'; // 引入 Delta,用于手动修改文档
|
|
|
|
|
|
-// 注册插件
|
|
|
-Quill.register('modules/imageUploader', ImageUploader);
|
|
|
+// 注册 Image Resize 模块
|
|
|
+Quill.register('modules/imageResize', ImageResize);
|
|
|
|
|
|
export default {
|
|
|
components: {
|
|
|
- QuillEditor: VueQuillEditor.quillEditor // 注册 QuillEditor 组件
|
|
|
+ quillEditor
|
|
|
},
|
|
|
data() {
|
|
|
//0.全局操作 start ------------------------------------------------------------>
|
|
@@ -118,8 +127,9 @@ export default {
|
|
|
//0.全局操作 end ------------------------------------------------------------>
|
|
|
return {
|
|
|
//1.表单项 start ------------------------------------------------------------>
|
|
|
- editStatus:false,//当前页面是编辑还是添加
|
|
|
- editId:"",//如果是编辑 添加资讯id
|
|
|
+ editStatus:false,
|
|
|
+
|
|
|
+ //提交表单
|
|
|
form: {
|
|
|
//1.1使用了外链
|
|
|
title: '',//资讯标题
|
|
@@ -164,29 +174,44 @@ export default {
|
|
|
fromurl:[{required:true,trigger:'blur',validator:validateEmpty}]
|
|
|
},
|
|
|
//1.3富文本编辑器配置
|
|
|
+ showHtml: false, //用于保存源码内容
|
|
|
+ editorHtml: '',
|
|
|
editorOptions: {
|
|
|
placeholder: '请输入内容...',
|
|
|
- theme: 'snow',
|
|
|
+ theme: 'snow', // 主题样式
|
|
|
modules: {
|
|
|
toolbar: {
|
|
|
container: [
|
|
|
- [{ 'font': [] }],
|
|
|
- [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
|
|
|
- [{ 'size': ['small', false, 'large', 'huge'] }],
|
|
|
- ['bold', 'italic', 'underline', 'strike'],
|
|
|
- [{ 'color': [] }, { 'background': [] }],
|
|
|
- [{ 'script': 'sub' }, { 'script': 'super' }],
|
|
|
- [{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
|
|
- [{ 'indent': '-1' }, { 'indent': '+1' }],
|
|
|
- [{ 'align': [] }],
|
|
|
- ['link', 'image'], // 确保image按钮存在
|
|
|
- ['clean']
|
|
|
+ [{ 'font': [] }], // 字体
|
|
|
+ [{ 'header': [1, 2, 3, 4, 5, 6, false] }], // 标题
|
|
|
+ [{ 'size': ['small', false, 'large', 'huge'] }], // 字体大小
|
|
|
+ ['bold', 'italic', 'underline', 'strike'], // 加粗、斜体、下划线、删除线
|
|
|
+ [{ 'color': [] }, { 'background': [] }], // 文字颜色、背景颜色
|
|
|
+ [{ 'script': 'sub' }, { 'script': 'super' }], // 上标、下标
|
|
|
+ [{ 'list': 'ordered'}, { 'list': 'bullet' }], // 列表
|
|
|
+ [{ 'indent': '-1'}, { 'indent': '+1' }], // 缩进
|
|
|
+ [{ 'align': [] }], // 对齐方式
|
|
|
+ ['blockquote', 'code-block'], // 引用、代码块
|
|
|
+ ['link', 'image', 'video'], // 链接、图片、视频
|
|
|
+ ['clean'],
|
|
|
+ [{ 'html': true }] // 添加自定义按钮的占位符
|
|
|
],
|
|
|
handlers: {
|
|
|
image: () => {
|
|
|
this.handleImageClick();
|
|
|
+ },
|
|
|
+ showHtml: function() {
|
|
|
+ this.$emit('toggleSourceMode');
|
|
|
}
|
|
|
}
|
|
|
+ },
|
|
|
+ imageResize: {
|
|
|
+ displayStyles: {
|
|
|
+ backgroundColor: 'black',
|
|
|
+ border: 'none',
|
|
|
+ color: 'white'
|
|
|
+ },
|
|
|
+ modules: ['Resize', 'DisplaySize', 'Toolbar'] // 启用不同的调整方式
|
|
|
}
|
|
|
}
|
|
|
},
|
|
@@ -257,49 +282,7 @@ export default {
|
|
|
// 阻止默认的上传行为
|
|
|
return false;
|
|
|
},
|
|
|
- //1.2 编辑器上传图片
|
|
|
- handleImageClick() {
|
|
|
- this.$refs.multiFileInput.click(); // 打开文件选择框
|
|
|
- },
|
|
|
- handleMultipleFiles(event) {
|
|
|
- const files = event.target.files;
|
|
|
- if (files.length) {
|
|
|
- this.uploadMultipleImages(files); // 处理多图片上传
|
|
|
- }
|
|
|
- },
|
|
|
- uploadMultipleImages(files) {
|
|
|
- const uploadPromises = [];
|
|
|
- for (let i = 0; i < files.length; i++) {
|
|
|
- uploadPromises.push(this.uploadImage(files[i]));
|
|
|
- }
|
|
|
-
|
|
|
- Promise.all(uploadPromises).then(urls => {
|
|
|
- const quillEditor = this.$refs.quillEditor.quill;
|
|
|
- urls.forEach(url => {
|
|
|
- const range = quillEditor.getSelection();
|
|
|
- quillEditor.insertEmbed(range.index, 'image', url); // 在编辑器中插入图片
|
|
|
- });
|
|
|
- }).catch(error => {
|
|
|
- this.$message.error('图片上传失败,请重试!');
|
|
|
- });
|
|
|
- },
|
|
|
- uploadImage(file) {
|
|
|
- const formData = new FormData();
|
|
|
- formData.append('file', file);
|
|
|
- return this.$store.dispatch('pool/uploadFile', formData)
|
|
|
- .then(res => {
|
|
|
- if (res && res.data && res.data.imgUrl) {
|
|
|
- return res.data.imgUrl;
|
|
|
- } else {
|
|
|
- throw new Error('图片上传失败');
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(error => {
|
|
|
- this.$message.error('图片上传失败,请重试!');
|
|
|
- throw error;
|
|
|
- });
|
|
|
- },
|
|
|
- //1.3 提交表单
|
|
|
+ //1.2 提交表单
|
|
|
addToServe(){
|
|
|
//提交之前先判断是否为外链
|
|
|
//如果使用了外链,清理掉除了外链以外的内容
|
|
@@ -328,17 +311,17 @@ export default {
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
- //1.4 清理表单
|
|
|
+ //1.3 清理表单
|
|
|
cleatForm(type){
|
|
|
if(type==1){
|
|
|
//使用了外链,进行部分表单清理
|
|
|
- this.form.cat_arr_id = "";
|
|
|
+ //this.form.cat_arr_id = "";
|
|
|
this.form.level = "";
|
|
|
this.form.imgurl = "";
|
|
|
this.form.keyword = "";
|
|
|
this.form.introduce = "";
|
|
|
this.form.content = "";
|
|
|
- this.form.author = "";
|
|
|
+ //this.form.author = "";
|
|
|
this.form.hits = "";
|
|
|
this.form.is_original = "";
|
|
|
this.form.copyfrom = "";
|
|
@@ -463,8 +446,115 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
//跳转操作 end ------------------------------------------------------------>
|
|
|
+
|
|
|
+ //4.富文本编辑器 start ------------------------------------------------------------>
|
|
|
+ //4.1 编辑器点击上传图片
|
|
|
+ handleImageClick() {
|
|
|
+ this.$refs.multiFileInput.click(); // 打开文件选择框
|
|
|
+ },
|
|
|
+ handleMultipleFiles(event) {
|
|
|
+ const files = event.target.files;
|
|
|
+ if (files.length) {
|
|
|
+ this.uploadMultipleImages(files); // 处理多图片上传
|
|
|
+ }
|
|
|
+ },
|
|
|
+ uploadMultipleImages(files) {
|
|
|
+ const uploadPromises = [];
|
|
|
+ for (let i = 0; i < files.length; i++) {
|
|
|
+ uploadPromises.push(this.uploadImage(files[i]));
|
|
|
+ }
|
|
|
+
|
|
|
+ Promise.all(uploadPromises).then(urls => {
|
|
|
+ const quillEditor = this.$refs.quillEditor.quill;
|
|
|
+ urls.forEach(url => {
|
|
|
+ const range = quillEditor.getSelection();
|
|
|
+ quillEditor.insertEmbed(range.index, 'image', url); // 在编辑器中插入图片
|
|
|
+ });
|
|
|
+ }).catch(error => {
|
|
|
+ this.$message.error('图片上传失败,请重试!');
|
|
|
+ });
|
|
|
+ },
|
|
|
+ uploadImage(file) {
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('file', file);
|
|
|
+ return this.$store.dispatch('pool/uploadFile', formData)
|
|
|
+ .then(res => {
|
|
|
+ if (res && res.data && res.data.imgUrl) {
|
|
|
+ return res.data.imgUrl;
|
|
|
+ } else {
|
|
|
+ throw new Error('图片上传失败');
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ this.$message.error('图片上传失败,请重试!');
|
|
|
+ throw error;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ //4.2 图片粘贴上传
|
|
|
+ // 处理从网页粘贴的图片 URL
|
|
|
+ handleImageFromWeb(imageUrl) {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ console.log('开始下载图片:', imageUrl);
|
|
|
+
|
|
|
+ this.fetchImageAsBlob(imageUrl).then((blob) => {
|
|
|
+ console.log('图片已下载为 Blob:', blob);
|
|
|
+
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('file', blob, 'image.jpg');
|
|
|
+
|
|
|
+ this.$store.dispatch('pool/uploadFile', formData).then((res) => {
|
|
|
+ if (res && res.data && res.data.imgUrl) {
|
|
|
+ console.log('图片上传成功:', res.data.imgUrl);
|
|
|
+ resolve(res.data.imgUrl);
|
|
|
+ } else {
|
|
|
+ console.log('图片上传失败,保留原 URL:', imageUrl);
|
|
|
+ resolve(imageUrl);
|
|
|
+ }
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('图片上传时出现错误:', error);
|
|
|
+ resolve(imageUrl);
|
|
|
+ });
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('图片下载失败:', error);
|
|
|
+ resolve(imageUrl);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ fetchImageAsBlob(url) {
|
|
|
+ return fetch(url)
|
|
|
+ .then(response => {
|
|
|
+ if (!response.ok) {
|
|
|
+ throw new Error('Failed to fetch image');
|
|
|
+ }
|
|
|
+ return response.blob();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //编辑源码
|
|
|
+ toggleSourceMode() {
|
|
|
+ if (!this.showHtml) {
|
|
|
+ // 切换到源码模式,将编辑器内容同步到 textarea 中
|
|
|
+ this.editorHtml = this.$refs.quillEditor.quill.root.innerHTML;
|
|
|
+ this.showHtml = true; // 显示 textarea
|
|
|
+ } else {
|
|
|
+ // 切换回富文本模式,将 textarea 内容同步回编辑器
|
|
|
+ this.showHtml = false; // 显示 Quill 编辑器
|
|
|
+
|
|
|
+ // Quill 编辑器可能被销毁,所以使用 $nextTick 确保 DOM 渲染完成后再操作编辑器
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.quillEditor) {
|
|
|
+ this.$refs.quillEditor.quill.root.innerHTML = this.editorHtml;
|
|
|
+ } else {
|
|
|
+ console.error('Quill 编辑器实例未找到');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //富文本编辑器 end ------------------------------------------------------------>
|
|
|
+
|
|
|
},
|
|
|
mounted(){
|
|
|
+ //1.判断是新建还是回显
|
|
|
if(this.$route.query.id!=undefined){
|
|
|
this.editId = this.$route.query.id;
|
|
|
this.editStatus = true;
|
|
@@ -474,7 +564,43 @@ export default {
|
|
|
this.editStatus = false;
|
|
|
console.log("添加新闻!")
|
|
|
}
|
|
|
- }
|
|
|
+
|
|
|
+ //复制内容到富文本 start ------------------------------------------------------------>
|
|
|
+ this.$nextTick(() => {
|
|
|
+ const quillEditor = this.$refs.quillEditor.quill;
|
|
|
+
|
|
|
+ if (quillEditor) {
|
|
|
+ console.log('Quill 编辑器已初始化');
|
|
|
+
|
|
|
+ // 在粘贴事件触发时,记录所有 img 的 src
|
|
|
+ quillEditor.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
|
|
|
+ if (node.tagName === 'IMG') {
|
|
|
+ const imageUrl = node.getAttribute('src');
|
|
|
+ console.log('检测到粘贴的图片 URL:', imageUrl);
|
|
|
+
|
|
|
+ if (imageUrl && !imageUrl.startsWith('data:') && !imageUrl.startsWith('file://')) {
|
|
|
+ // 先处理图片上传
|
|
|
+ this.handleImageFromWeb(imageUrl).then((uploadedImageUrl) => {
|
|
|
+ // 查找编辑器中所有 img 标签并替换 src
|
|
|
+ const imgs = quillEditor.root.querySelectorAll('img');
|
|
|
+ imgs.forEach((img) => {
|
|
|
+ if (img.getAttribute('src') === imageUrl) {
|
|
|
+ img.setAttribute('src', uploadedImageUrl); // 替换 src
|
|
|
+ console.log('图片 src 已替换为:', uploadedImageUrl);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return delta; // 返回原始 delta
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ console.error('Quill 初始化失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+ //复制富文本 end ------------------------------------------------------------>
|
|
|
+ },
|
|
|
};
|
|
|
</script>
|
|
|
|
|
@@ -558,4 +684,8 @@ export default {
|
|
|
height: 150px;
|
|
|
display: block;
|
|
|
}
|
|
|
+
|
|
|
+ .my-quill-editor {
|
|
|
+ height: 320px;
|
|
|
+ }
|
|
|
</style>
|