Files
sgxt_web/src/components/ypModel/index.vue
2025-09-24 18:10:41 +08:00

185 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog v-model="modelValue" center width="1000px" :destroy-on-close="true" title="报告模板" @close="close" :close-on-click-modal="false">
<div class="cntBox">
<!-- 工具栏 -->
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
<!-- 编辑器 -->
<Editor :style="`height: ${props.heightNumber}px; overflow-y: hidden`" v-model="textContent" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" @onChange="handChange" />
</div>
<template #footer>
<el-button type="primary" @click="SaveReport">保存</el-button>
<!-- <el-button type="primary" @click="downloadWithStyles">历史报告</el-button> -->
<el-button type="primary" @click="downloadWithStyles">下载</el-button>
<el-button type="primary" @click="close">取消</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { compressImage } from "@/utils/tools.js";
import "@wangeditor/editor/dist/css/style.css";
import { qcckPost } from "@/api/qcckApi.js";
import { ElMessage } from "element-plus";
import { saveAs } from 'file-saver';
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { ref, shallowRef, onBeforeUnmount, defineEmits, defineProps, watch } from "vue";
const props = defineProps({
modelValue:{
type:Boolean,
default:false
},
// 编辑器内容
textContent: {
type: String,
default: ""
},
placeholder: {
type: String,
default: "请输入内容。。。。"
},
heightNumber: {
type: Number,
default: 448
}
});
const editorRef = shallowRef();
const mode = "default";
//工具配置
const toolbarConfig = {
excludeKeys: ["blockquote", "codeBlock"] //清除不必要的工具,引用和代码块
// 注意wangEditor默认包含了对齐相关的按钮包括两端对齐
// 如果需要自定义工具栏,可以使用以下配置
// toolbarKeys: [
// // 其他工具栏按钮
// 'justifyJustify', // 两端对齐按钮
// ]
};
// 为了确保编辑器内容默认应用两端对齐,我们在编辑器创建时设置全局样式
const emits = defineEmits(["update:textContent", "changeFn","update:modelValue","SaveReport"]);
//编辑器配置
const editorConfig = {
withCredentials: true, //允许跨域
placeholder: props.placeholder, //提示语
MENU_CONF: {
uploadImage: {
// 自定义上传图片
async customUpload(file, insertFn) {
let fileBlob = await compressImage(file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
if (fileData.size > 2 * 1024 * 1024) {
ElMessage({ message: "图片超过2MB", type: "success" });
} else {
await uploadFn(fileData, insertFn);
}
}
},
uploadVideo: {
// 自定义上传视频
async customUpload(file, insertFn) {
await uploadFn(file, insertFn);
}
}
}
};
// 初始化完成后设置默认的两端对齐样式
const setDefaultJustifyStyle = () => {
const editor = editorRef.value;
if (editor) {
// 获取编辑区域元素
const editableEle = editor.getEditableContainer();
if (editableEle) {
editableEle.style.textAlign = 'justify';
// 添加中文两端对齐的处理样式
editableEle.style.textJustify = 'inter-character';
}
}
};
// 监听编辑器创建完成事件,设置两端对齐样式
watch(editorRef, (newVal) => {
if (newVal) {
setDefaultJustifyStyle();
}
});
const uploadFn = (file, insertFn) => {
let param = new FormData();
param.append("file", file);
qcckPost(param, "/mosty-base/minio/image/upload").then((res) => {
insertFn(res);
});
};
//编辑器创建成功
const handleCreated = (editor) => {
editorRef.value = editor;
};
//内容发生变化
const handChange = (editor) => {
// 判断是否是一个空段落,是空就传空文本
if (editor.isEmpty()) {
emits("changeFn", editor.getText());
} else {
emits("changeFn", editor.getHtml());
}
};
const close = () => {
emits("update:modelValue", false)
}
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor) editor.destroy();
});
// 带样式的下载方法
const downloadWithStyles = () => {
const wordDocument = `
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>富文本导出</title>
<style>
/* 应用两端对齐样式 */
body {
text-align: justify;
text-justify: inter-character; /* 中文文本两端对齐 */
font-family: "Microsoft YaHei", Arial, sans-serif;
}
p {
text-align: justify;
text-justify: inter-character;
}
</style>
</head>
<body>
${props.textContent}
</body>
</html>
`;
const blob = new Blob([wordDocument], {
type: 'application/msword'
});
saveAs(blob, 'styled-document.doc');
};
const SaveReport = () => {
console.log(props.textContent);
emits("SaveReport",props.textContent)
}
</script>
<style lang="scss" scoped>
.cntBox{
// height: 60vh;
padding: 8px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
border: 1px dashed #e9e9e9;
}
</style>