147 lines
4.4 KiB
Vue
147 lines
4.4 KiB
Vue
<template>
|
|
<div>
|
|
<HugerteEditor ref="editorRef" :init="init" v-model="modelValue" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from "vue";
|
|
import HugerteEditor from "@/components/hugerte-editor/index";
|
|
import { uploadTempFile } from "@/service/email";
|
|
const editorRef = ref<any>(null);
|
|
const modelValue = defineModel();
|
|
const props = defineProps({
|
|
height: {
|
|
type: Number,
|
|
default: 600
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: "请输入内容..."
|
|
}
|
|
});
|
|
const emit = defineEmits(["upload-image"]);
|
|
|
|
function getPlainText() {
|
|
const editor = editorRef.value?.getEditor?.();
|
|
return editor?.getContent({ format: "text" }) ?? "";
|
|
}
|
|
|
|
function getHtml() {
|
|
const editor = editorRef.value?.getEditor?.();
|
|
return editor?.getContent() ?? "";
|
|
}
|
|
function clear() {
|
|
const editor = editorRef.value?.getEditor?.();
|
|
if (editor) {
|
|
editor.setContent(""); // 清空内容
|
|
}
|
|
}
|
|
|
|
defineExpose({
|
|
getHtml,
|
|
getPlainText,
|
|
clear
|
|
});
|
|
|
|
const init = {
|
|
language: "zh_CN",
|
|
height: props.height,
|
|
placeholder: props.placeholder,
|
|
menubar: false,
|
|
statusbar: false,
|
|
plugins: "accordion advlist anchor formatpainter fullscreen image link lists preview table searchreplace ",
|
|
font_size_formats: "12px 14px 16px 18px 20px 22px 24px 26px 28px 30px 32px",
|
|
font_family_formats:
|
|
"PingFang SC;微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,;sans-serif",
|
|
toolbar:
|
|
"undo redo formatpainter removeformat | " +
|
|
"blocks fontfamily fontsize | " +
|
|
"bold italic underline strikethrough superscript subscript | forecolor backcolor |hr blockquote | " +
|
|
"align lineheight | bullist numlist indent outdent table|" +
|
|
"link customImage| searchreplace preview fullscreen print",
|
|
formats: {
|
|
blockquote: {
|
|
block: "blockquote",
|
|
styles: {
|
|
"border-left": "2px solid #ccc",
|
|
margin: "1em 0",
|
|
"padding-left": "1em"
|
|
}
|
|
}
|
|
},
|
|
body_class: "my-editor-body",
|
|
toolbar_mode: "wrap",
|
|
setup: function (editor: any) {
|
|
function applyTableInlineStyles() {
|
|
const body = editor.getBody();
|
|
if (!body) return;
|
|
|
|
body.querySelectorAll("table").forEach((table: HTMLTableElement) => {
|
|
table.style.width = "100%";
|
|
table.style.borderCollapse = "collapse";
|
|
table.style.border = "1px solid #ccc";
|
|
});
|
|
|
|
body.querySelectorAll("th").forEach((th: HTMLTableElement) => {
|
|
th.style.border = "1px solid #ccc";
|
|
th.style.padding = "8px";
|
|
th.style.backgroundColor = "#f2f2f2";
|
|
th.style.textAlign = "left";
|
|
});
|
|
|
|
body.querySelectorAll("td").forEach((td: HTMLTableElement) => {
|
|
td.style.border = "1px solid #ccc";
|
|
td.style.padding = "8px";
|
|
td.style.wordBreak = "break-word"; // 更合理
|
|
td.style.whiteSpace = "normal";
|
|
});
|
|
}
|
|
|
|
// 只在执行“插入表格”命令时添加样式
|
|
editor.on("ExecCommand", (e: any) => {
|
|
if (e.command === "mceInsertTable") {
|
|
// 延迟一下让表格插入完毕
|
|
setTimeout(() => {
|
|
applyTableInlineStyles();
|
|
}, 0);
|
|
}
|
|
});
|
|
|
|
editor.ui.registry.addButton("customImage", {
|
|
icon: "image",
|
|
tooltip: "上传图片",
|
|
onAction: () => {
|
|
const input = document.createElement("input");
|
|
input.type = "file";
|
|
input.accept = "image/*";
|
|
input.click();
|
|
|
|
input.onchange = async () => {
|
|
const files = input.files;
|
|
if (!files || files.length === 0) return;
|
|
|
|
const file = files[0];
|
|
|
|
try {
|
|
const res = await uploadTempFile(file);
|
|
|
|
emit("upload-image", res.data);
|
|
|
|
editor.insertContent(`<img src="${res.data.fileUrl}" />`);
|
|
} catch (err) {
|
|
console.error("图片上传失败", err);
|
|
}
|
|
};
|
|
}
|
|
});
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.preview-iframe {
|
|
background-color: white;
|
|
}
|
|
</style>
|