editor.tsx
3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import React, { useEffect, useRef, useState } from "react";
import { Editor } from "@tinymce/tinymce-react";
import tinymce from "tinymce";
import { message } from "antd";
import { cosUploadImage } from "@/app/utils/tencentCos";
import { Path } from "@/app/constant";
export function EditorComponent(props: {
htmlCode: string;
setHtmlCode: React.Dispatch<React.SetStateAction<string>>;
}) {
const editorRef = useRef<tinymce.Editor | null>(null);
const [editorValue, setEditorValue] = useState(props.htmlCode);
useEffect(() => {
setEditorValue(props.htmlCode);
}, [props.htmlCode]);
return (
<Editor
apiKey="l4kgoxhh8dtkv4thb22g4wskoq4obivan58l38asxk32an6f"
onInit={(evt: any, editor: tinymce.Editor) => {
editorRef.current = editor;
}}
initialValue={props.htmlCode}
init={{
height: "100%",
width: "100%",
menubar: false,
branding: false,
plugins: [
"advlist",
"autolink",
"lists",
"link",
"image",
"charmap",
"preview",
"anchor",
"searchreplace",
"visualblocks",
"code",
"fullscreen",
"insertdatetime",
"media",
"table",
],
toolbar:
"undo redo | blocks fontsize | saveHtml uploadImage table underline " +
"bold italic forecolor backcolor | alignleft aligncenter " +
"alignright alignjustify | bullist numlist outdent indent fullscreen preview emoticons copy cut paste",
toolbar_mode: "wrap",
content_style:
"body { font-family:Helvetica,Arial,sans-serif; font-size:14px }",
setup: (editor: tinymce.Editor) => {
editor.ui.registry.addButton("saveHtml", {
text: "保存",
icon: "save",
onAction: () => {
const content = editorRef.current?.getContent();
if (content && content !== props.htmlCode)
props.setHtmlCode(content);
},
});
editor.ui.registry.addButton("uploadImage", {
text: "上传图片",
icon: "image",
onAction: () => {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.addEventListener("change", async (e) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (!file) return;
if (!file.type.startsWith("image/")) {
message.error("请选择有效的图片文件");
return;
}
try {
const imageUrl = await cosUploadImage(file, Path.Writing);
editor.insertContent(
`<img src="https://${imageUrl}" alt="上传的图片"/>`,
);
} catch (error) {
alert(
`图片上传失败: ${
error instanceof Error ? error.message : error
}`,
);
}
});
input.click();
},
});
},
}}
/>
);
}