js
复制代码
<template>
<div class="card" style="overflow: hidden; padding-bottom: 10px">
<div style="padding: 20px 20px 0 20px">
<span class="title_top"><span class="top_icon"></span>基本信息</span>
<el-divider></el-divider>
</div>
<div class="box">
<div>
<div class="box_count">
<div class="box_l">
<FlexLinePI :title="'图文标题'" :dropshow="true">
<el-input v-model.trim="ruleForm.title" maxlength="20" show-word-limit type="text" placeholder="请输入标题"
v-clear-emoij @input="e => (ruleForm.title = formateText(e))"></el-input>
</FlexLinePI>
<FlexLinePI :title="'图文摘要'" :dropshow="true"><el-input style="white-space: pre-wrap;word-break: break-all;"
v-model.trim="ruleForm.note" type="textarea" maxlength="150" show-word-limit rows="5"
placeholder="请输入正文详情" @input="e => (ruleForm.note = formateText(e))"></el-input>
</FlexLinePI>
<FlexLinePI :title="'封面图片'" :dropshow="true">
<el-upload class="avatar-uploader" :action="upload" :show-file-list="false"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" :on-progress="onprogress">
<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" style="">
( 建议上传图片尺寸100x100px,大小不超过5M )
</div>
</el-upload>
</FlexLinePI>
<FlexLinePI :title="'图文描述'" :dropshow="true" :position="false">
<div>
<quill-editor v-model="ruleForm.content" ref="quillEditor" :options="editorOption">
</quill-editor>
<div class="rich-uploader">
<!-- 图片上传组件辅助-->
<el-upload class="rich-uploader2" name="pic" action="" :show-file-list="false" accept=".jpg,.png,jpeg"
:http-request="httpRequest">
</el-upload>
<AliUpload class="rich-uploader3" :url="videoURL" @deleteVideo="deleteVideo"
@beforeupload="beforeupload" @uploadSuccess="uploadVideoSuccess" />
<!--
<el-upload class="rich-uploader3" name="pic" action="" :show-file-list="false" accept="video/*"
:http-request="httpRequestvideo">
</el-upload> -->
</div>
</div>
</FlexLinePI>
<div class="buttom">
<el-button type="primary" @click="addandedit(0)" :loading="loadingbtn">{{ loadingbtn == false ? "保存" : "记载中"
}}</el-button>
<el-button type="primary" @click="addandedit(1)" :loading="loadingbtn">
{{ loadingbtn == false ? "保存并发布" : "记载中" }}
</el-button>
<!-- <el-button type="primary" @click="look">预览</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" style="width: 180px">
<p style="-webkit-line-clamp: 1; font-size: 14px; width: 100%" class="ellipsis">
{{ ruleForm.title != "" ? ruleForm.title : "请输入标题" }}
</p>
<div style="display: flex; margin-top: 5px; height: 80px">
<div style="
flex: 1;
-webkit-line-clamp: 6;
font-size: 12px;
color: #999999;
" 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>
<!-- 图片视频上传中 -->
<el-dialog title="" :visible.sync="dialogVisiblevideo" width="160px" :close-on-click-modal="false"
:close-on-press-escape="false" :show-close="false">
<span slot="title"></span>
<div class="loadding_image" style="">
<i class="el-icon-loading" style="font-size: 50px;"></i>
<div>{{ uptext }}</div>
<div v-if="videosize != ''">此视频有 {{ videosize }} MB大小,请稍等...</div>
</div>
</el-dialog>
</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";
// 引入修改video模块并注册
import video from "@/assets/js/quillVideo.js";
import AliUpload from './component/aliUpload.vue'
Quill.register(video);
export default {
name: "AddImageText",
components: {
quillEditor,
AliUpload
// , step
},
computed: {
quill() {
const { quill } = this.$refs.quillEditor || {};
return quill;
}
},
data() {
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"], //清除字体样式
["image"], //上传图片
["video"] // 视频
];
return {
upload: upload,
uploadvideo: uploadvideo,
ruleForm: {
id: "",
title: "",
note: "",
cover: "",
content: ""
},
// 视频
progress: 0,
// 富文本
editorOption: {
placeholder: "请输入内容",
theme: "snow",
modules: {
clipboard: {
// 粘贴版,处理粘贴时候带图片
matchers: [[Node.ELEMENT_NODE, this.handleCustomMatcher]],
},
toolbar: {
container: toolbarOptions, // 工具栏
handlers: {
image: function (value) {
if (value) {
console.log(value);
// 触发input框选择图片文件
document.querySelector(".rich-uploader2 input").click();
} else {
this.quill.format("image", false);
}
},
video: function (value) {
if (value) {
console.log(value);
// 触发input框选择图片文件
document.querySelector(".rich-uploader3 input").click();
} else {
this.quill.format("video", false);
}
}
}
}
}
},
// 上传图片
urlimg: require("../../../assets/images/gift.png"),
// 当前id
updateId: "",
// 提交
loadingbtn: false,
dialogVisiblevideo: false,
uptext: "",
videosize: ""
};
},
mounted() {
this.updateId = this.$route.query.id
if (this.updateId == undefined) {
this.ruleForm = {
id: "",
title: "",
note: "",
cover: "",
content: ""
};
} else {
// 详情
this.getdetail(this.updateId);
}
// 复制图片到富文本
// let quill = this.$refs.quillEditor.quill;
// quill.root.addEventListener(
// "paste",
// (evt) => {
// if (
// evt.clipboardData &&
// evt.clipboardData.files &&
// evt.clipboardData.files.length
// ) {
// evt.preventDefault();
// [].forEach.call(evt.clipboardData.files, (file) => {
// if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
// return;
// }
// const formdata = new FormData();
// formdata.append("file", file, file.name);
// formdata.append("type", "1");
// // let length = quill.getSelection().index;
// quill.insertEmbed(1, "image", 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(1, "image", res.data.data.real_path);
// // // 调整光标到最后
// quill.setSelection(1 + 1);
// } else {
// _this.$message.warning(res.data.msg || "数据响应过慢,请稍后再试");
// }
// })
// .catch(err => {
// console.log(err);
// });
// });
// }
// },
// false
// );
},
computed: {},
methods: {
handleCustomMatcher(node, Delta) {
console.log(Delta,123)
let ops = []
Delta.ops.forEach(op => {
if (op.insert && typeof op.insert === 'string') {// 如果粘贴了图片,这里会是一个对象,所以可以这样处理
ops.push({
insert: op.insert,
})
} else {
this.$message({
message: '不允许粘贴图片,请手动上传',
type: 'warning'
})
}
})
Delta.ops = ops
return Delta
},
//
handleAvatarSuccess(res, file) {
if (res.status == 1) {
this.dialogVisiblevideo = false;
this.ruleForm.cover = res.data.real_path;
}
},
beforeAvatarUpload(file) {
let types = [
"image/jpeg",
"image/jpg",
"image/png"
];
const isImage = types.includes(file.type);
const isLtSize = file.size / 1024 / 1024 < 5;
if (!isImage) {
this.$message.warning("上传图片只能是 JPG、JPEG、PNG 格式!");
return false;
}
if (!isLtSize) {
this.$message.warning("上传图片大小不能超过 5MB!");
return false;
}
return true;
},
onprogress(event, file, fileList) {
console.log(event, file, fileList);
// this.dialogVisiblevideo = true;
},
// 详情
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);
});
},
// 步骤 2 =====================================================
httpRequest(item) {
const _this = this;
_this.uptext = "图片正在上传中...";
_this.videosize = "";
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.data.msg || "数据响应过慢,请稍后再试");
}
})
.catch(err => {
console.log(err);
});
},
// ==============================================================
// 保存编辑
addandedit(val) {
if (this.ruleForm.title == "") {
this.$message.warning("请输入图文标题");
return;
}
if (this.ruleForm.note == "") {
this.$message.warning("请输入图文摘要");
return;
}
if (this.ruleForm.cover == "") {
this.$message.warning("请上传封面图片");
return;
}
if (this.ruleForm.content == "") {
this.$message.warning("请输入图文描述");
return;
}
this.loadingbtn = true;
if (this.updateId == undefined) {
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.loadingbtn = 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.loadingbtn = false;
this.$router.push({
name: "ImageText"
});
} else {
this.$message.warning(res.msg || "数据响应过慢,请稍后再试");
}
})
.catch(err => {
console.log(err);
});
},
// 视频上传 =================
deleteVideo(val) {
console.log(val)
},
beforeupload(val) {
this.dialogVisiblevideo = val.isshow;
this.uptext = "视频上传中...";
this.videosize = Math.ceil(val.filesize / (1024 * 1024));
},
uploadVideoSuccess(val) {
this.$message.success("上传成功");
this.dialogVisiblevideo = val.isshow;
let quill = this.$refs.quillEditor.quill;
let length = quill.getSelection().index;
// 插入图片 服务器返回的图片地址
quill.insertEmbed(length, "video", val.videoURL);
// 调整光标到最后
quill.setSelection(length + 1);
},
// ======
httpRequestvideo(item) {
let chunkSize = 1024 * 1024 * 2; // 每个切片的大小(这里设置为2MB)
let totalChunks = Math.ceil(item.file.size / chunkSize); // 总切片数
let currentChunk = 1; // 当前切片索引
var start = currentChunk * chunkSize;
var end = Math.min(totalChunks, start + chunkSize);
this.dialogVisiblevideo = true;
this.videosize = Math.ceil(item.file.size / (1024 * 1024));
this.uptext = "视频上传中...";
const uploadNextChunk = () => {
const formData = new FormData();
formData.append("name", item.file.name);
formData.append("data", item.file.slice(start, end));
// 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 => {
this.dialogVisiblevideo = true;
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) {
this.dialogVisiblevideo = false;
this.$message.success(res.msg || "完成视频上传");
let length = quill.getSelection().index;
// 插入图片 服务器返回的图片地址
quill.insertEmbed(length, "video", res.data.path);
// 调整光标到最后
quill.setSelection(length + 1);
} else {
this.dialogVisiblevideo = false;
this.$message.warning(res.data.msg || "数据响应过慢,请稍后再试");
}
})
.catch(error => {
this.dialogVisiblevideo = false;
console.error("Error uploading file:", error);
});
}
}
};
</script>
<style scoped lang="less">
p {
margin: 0;
padding: 0;
}
.box {
width: 90%;
// margin: 0 auto;
margin-left: 35px;
.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: 36px;
height: 36px;
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;
}
/deep/ .el-dialog__header {
display: none;
}
/deep/ .el-dialog__body {
padding: 10px 20px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #ffffff00;
color: #ccc;
}
.loadding_image {
margin: 0 auto;
text-align: center;
width: 125px;
}
</style>