<template>
<div class="card" style="overflow: hidden; padding-bottom: 10px">
<div class="box">
<div>
<div class="box_count">
<div class="box_l">
<FlexLinePI :title="'图文标题'" :dropshow="true">
<el-input
v-model="ruleForm.title"
maxlength="50"
type="text"
placeholder="请输入标题"
>el-input>
FlexLinePI>
<FlexLinePI :title="'图文摘要'" :dropshow="true"
><el-input
v-model="ruleForm.note"
type="textarea"
maxlength="200"
show-word-limit
rows="5"
placeholder="请输入正文详情"
>el-input>
FlexLinePI>
<FlexLinePI :title="'封面图片'" :dropshow="true">
<el-upload
class="avatar-uploader"
:action="upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img
v-if="ruleForm.cover"
:src="ruleForm.cover"
class="avatar"
/>
<i v-else class="el-icon-plus avatar-uploader-icon">i>
<div slot="tip" class="el-upload__tip">
建议上传图片尺寸800*800px,大小不超过5M
div>
el-upload>
FlexLinePI>
<FlexLinePI :title="''" :dropshow="false">
<div>
<div class="rich-uploader">
<el-upload
class="rich-uploader2"
name="pic"
action=""
:show-file-list="false"
:http-request="httpRequest"
>
el-upload>
<el-upload
class="rich-uploader3"
name="pic"
action=""
:show-file-list="false"
:http-request="httpRequestvideo"
>
el-upload>
div>
<quill-editor
v-model="ruleForm.content"
ref="quillEditor"
:options="editorOption"
>
quill-editor>
div>
FlexLinePI>
<div class="buttom">
<el-button type="primary" @click="addandedit(0)">保存el-button>
<el-button type="primary" @click="addandedit(1)"
>保存并发布el-button
>
div>
div>
<div
class="box_r"
:style="{
'background-image': `url(${require('../../../assets/images/phone.png')}`,
}"
>
<div class="box_r_informationurl">
<div class="box_r_inImg">
<img
src="../../../assets/images/authorlogo.png"
alt=""
srcset=""
style="width: 100%; height: 100%"
/>
div>
<div class="box_r_inlanguage">
<p
style="-webkit-line-clamp: 1; font-size: 18px"
class="ellipsis"
>
{{ ruleForm.title != "" ? ruleForm.title : "请输入标题" }}
p>
<div style="display: flex; margin-top: 5px; height: 90px">
<div style="flex: 1; -webkit-line-clamp: 5" class="ellipsis">
{{ ruleForm.note != "" ? ruleForm.note : "请输入正文详情" }}
div>
<div class="box_r_inlanguageimg">
<img
:src="ruleForm.cover != '' ? ruleForm.cover : urlimg"
alt=""
srcset=""
style="width: 100%; height: 100%"
/>
div>
div>
div>
div>
div>
div>
div>
div>
div>
template>
<script>
import step from "@/components/EchartsChart/nextstep.vue";
import { upload, uploadvideo } from "@/api/common.js";
import { quillEditor, Quill } from "vue-quill-editor";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import axios from "axios";
import {
detailGraphic,
addGraphic,
updateGraphic,
} from "@/api/material/index.js";
import video from "@/assets/js/quillVideo.js";
Quill.register(video);
export default {
name: "AddImageText",
components: { quillEditor, step },
computed: {
quill() {
const { quill } = this.$refs.quillEditor || {}
return quill;
},
},
data() {
const toolbarOptions = [
["bold", "italic", "underline", "strike"],
["blockquote", "code-block"],
[{ header: 1 }, { header: 2 }],
[{ list: "ordered" }, { list: "bullet" }],
[{ script: "sub" }, { script: "super" }],
[{ indent: "-1" }, { indent: "+1" }],
[{ direction: "rtl" }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }],
[{ font: [] }],
[{ align: [] }],
["clean"],
["image"],
["video"],
];
return {
upload: upload,
uploadvideo: uploadvideo,
ruleForm: {
id: "",
title: "",
note: "",
cover: "",
content: "",
},
progress: 0,
editorOption: {
placeholder: "请输入内容",
theme: "snow",
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
image: function (value) {
if (value) {
console.log(value);
document.querySelector(".rich-uploader2 input").click();
} else {
this.quill.format("image", false);
}
},
video: function (value) {
if (value) {
console.log(value);
document.querySelector(".rich-uploader3 input").click();
} else {
this.quill.format("video", false);
}
},
},
},
},
},
urlimg: require("../../../assets/images/gift.png"),
updateId: sessionStorage.getItem("updateId")
? sessionStorage.getItem("updateId")
: "",
};
},
mounted() {
if (this.updateId == "" || this.updateId == null) {
this.ruleForm = {
id: "",
title: "",
note: "",
cover: "",
content: "",
};
} else {
this.getdetail(this.updateId);
}
},
computed: {},
methods: {
handleAvatarSuccess(res, file) {
if (res.status == 1) {
this.ruleForm.cover = res.data.real_path;
}
},
beforeAvatarUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 5MB!");
}
return isLt2M;
},
getdetail(id) {
detailGraphic({
id: id,
})
.then((res) => {
if (res.status == 1) {
this.ruleForm = {
id: res.data.id,
title: res.data.title,
note: res.data.note,
cover: res.data.cover,
content: res.data.content,
};
} else {
this.$message.warning(res.msg || "数据响应过慢,请稍后再试");
}
})
.catch((err) => {
console.log(err);
});
},
httpRequest(item) {
let quill = this.$refs.quillEditor.quill;
let formdata = new FormData();
formdata.append("file", item.file, item.file.name);
formdata.append("type", "1");
let length = quill.getSelection().index;
quill.insertEmbed(length, "image", item.file);
axios
.post(upload, formdata, {
header: { "Content-Type": "multipart/form-data" },
})
.then((res) => {
if (res.data.status == 1) {
let length = quill.getSelection().index;
quill.insertEmbed(length, "image", res.data.data.real_path);
quill.setSelection(length + 1);
} else {
this.$message.warning(res.msg || "数据响应过慢,请稍后再试");
}
})
.catch((err) => {
console.log(err);
});
},
addandedit(val) {
if (this.updateId == "" || this.updateId == null) {
let tmpParams = {
id: "",
title: this.ruleForm.title,
note: this.ruleForm.note,
cover: this.ruleForm.cover,
content: this.ruleForm.content,
is_publish: val,
};
this.sever(tmpParams);
} else {
let tmpParams = {
id: this.updateId,
title: this.ruleForm.title,
note: this.ruleForm.note,
cover: this.ruleForm.cover,
content: this.ruleForm.content,
is_publish: val,
};
this.edit(tmpParams);
}
},
sever(val) {
addGraphic(val)
.then((res) => {
if (res.status == 1) {
this.dialogVisible = false;
this.$router.push({
name: "ImageText",
});
} else {
this.$message.warning(res.msg || "数据响应过慢,请稍后再试");
}
})
.catch((err) => {
console.log(err);
});
},
edit(val) {
updateGraphic(val)
.then((res) => {
if (res.status == 1) {
this.dialogVisible = false;
this.$router.push({
name: "ImageText",
});
} else {
this.$message.warning(res.msg || "数据响应过慢,请稍后再试");
}
})
.catch((err) => {
console.log(err);
});
},
httpRequestvideo(item) {
let chunkSize = 1024 * 1024 * 5;
let totalChunks = Math.ceil(item.file.size / chunkSize);
let currentChunk = 1;
const uploadNextChunk = () => {
const formData = new FormData();
formData.append("name", item.file.name);
formData.append("data", item.file);
formData.append("total", totalChunks);
formData.append("index", currentChunk);
formData.append("filename", item.file.name);
axios
.post(uploadvideo + "?act=upload", formData, {
headers: { "Content-Type": "multipart/form-data" },
onUploadProgress: (progressEvent) => {
this.progress = Math.round(
(currentChunk * 100 +
progressEvent.loaded / progressEvent.total) /
totalChunks
);
},
})
.then((res) => {
currentChunk++;
if (currentChunk < totalChunks + 1) {
uploadNextChunk();
} else {
this.progress = 0;
let date = {
name: item.file.name,
data: item.file,
total: totalChunks,
index: currentChunk,
filename: item.file.name,
};
this.uploadok(date);
}
})
.catch((error) => {
console.error("Error uploading file:", error);
});
};
uploadNextChunk();
},
uploadok(val) {
let quill = this.$refs.quillEditor.quill;
let formdata = new FormData();
formdata.append("name", val.name);
formdata.append("data", val.data);
formdata.append("total", val.total);
formdata.append("index", val.index);
formdata.append("filename", val.filename);
axios
.post(uploadvideo + "?act=join", formdata, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((res) => {
if (res.data.status == 1) {
let length = quill.getSelection().index;
quill.insertEmbed(length, "video", res.data.path);
quill.setSelection(length + 1);
} else {
this.$message.warning(res.msg || "数据响应过慢,请稍后再试");
}
})
.catch((error) => {
console.error("Error uploading file:", error);
});
},
},
};
script>
<style scoped lang='less'>
p {
margin: 0;
padding: 0;
}
.box {
width: 90%;
margin: 0 auto;
padding: 10px 0;
.box_count {
display: flex;
// justify-content: center;
.box_l {
width: 50%;
}
.box_r {
width: 320px;
height: 580px;
margin: 10px 10px 10px 100px;
background-size: 100% 100%;
// box-shadow: 0 0 10px 0 #ccc;
border-radius: 25px;
position: relative;
.box_r_informationurl {
width: 100%;
margin-top: 60px;
display: flex;
padding: 30px;
.box_r_inImg {
width: 50px;
height: 50px;
margin-left: 10px;
}
.box_r_inlanguage {
flex: 1;
margin: 0 10px;
background: #ffffff;
padding: 10px;
border-radius: 5px;
.box_r_inlanguageimg {
width: 50px;
height: 50px;
}
}
}
}
}
.buttom {
display: flex;
justify-content: center;
margin: 10px 0;
}
}
/deep/ .ql-container {
height: 600px;
}
/deep/ .avatar {
border-radius: 0;
}
style>
// 文件主要是使视频video替换ifrom标签的文档进行使用
import { Quill } from "vue-quill-editor";
// 源码中是import直接倒入,这里要用Quill.import引入
const BlockEmbed = Quill.import("blots/block/embed");
const Link = Quill.import("formats/link");
const ATTRIBUTES = ["height", "width"];
class Video extends BlockEmbed {
static create(value) {
const node = super.create(value);
// 添加video标签所需的属性
node.setAttribute("controls", "controls");
node.setAttribute("type", "video/mp4");
node.setAttribute("src", this.sanitize(value));
return node;
}
static formats(domNode) {
return ATTRIBUTES.reduce((formats, attribute) => {
if (domNode.hasAttribute(attribute)) {
formats[attribute] = domNode.getAttribute(attribute);
}
return formats;
}, {});
}
static sanitize(url) {
return Link.sanitize(url);
}
static value(domNode) {
return domNode.getAttribute("src");
}
format(name, value) {
if (ATTRIBUTES.indexOf(name) > -1) {
if (value) {
this.domNode.setAttribute(name, value);
} else {
this.domNode.removeAttribute(name);
}
} else {
super.format(name, value);
}
}
html() {
const { video } = this.value();
return `${video}`;
}
}
Video.blotName = "video"; // 这里不用改,楼主不用iframe,直接替换掉原来,如果需要也可以保留原来的,这里用个新的blot
Video.className = "ql-video";
Video.tagName = "video"; // 用video标签替换iframe
export default Video;