| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- import React, {
- useCallback,
- useEffect,
- useMemo,
- useRef,
- useState,
- } from "react";
- import styles from "./index.module.scss";
- // 引入编辑器组件
- // 安装---npm install braft-editor --save --force
- // npm install braft-utils --save --force
- import { ContentUtils } from "braft-utils";
- import BraftEditor from "braft-editor";
- // 引入编辑器样式
- import "braft-editor/dist/index.css";
- import classNames from "classnames";
- import { MessageFu } from "@/utils/message";
- import { fileDomInitialFu } from "@/utils/domShow";
- import { baseURL } from "@/utils/http";
- import { forwardRef, useImperativeHandle } from "react";
- import { API_upFile } from "@/store/action/layout";
- type Props = {
- check: boolean; //表单校验,为fasle表示不校验
- dirCode: string; //文件的code码
- isLook: boolean; //是否是查看进来
- ref: any; //当前自己的ref,给父组件调用
- myUrl: string; //上传的api地址
- full?: boolean;
- };
- function ZRichText({ check, dirCode, isLook, myUrl, full }: Props, ref: any) {
- // 添加 上传 图片的dom
- useEffect(() => {
- if (!isLook) {
- setTimeout(() => {
- const dom = document.querySelector(".bf-controlbar")!;
- const div = document.createElement("div");
- div.className = "upImgBox";
- // div.title = "上传图片";
- div.innerHTML = "上传图片";
- div.onclick = async () => {
- myInput.current?.click();
- };
- dom.appendChild(div);
- }, 200);
- // 监听 富文本 的 class 变化,在全屏的时候会 富文本会添加上 fullscreen 的类
- // 修复顶部样式冲突问题
- const editorDom = document.querySelector(
- ".bf-container"
- ) as HTMLDivElement;
- const observer = new MutationObserver(() => {
- // console.log("change");
- const dom = document.querySelector(".layoutRightTop") as HTMLDivElement;
- if (editorDom.className.includes("fullscreen")) dom.style.zIndex = "-1";
- else dom.style.zIndex = "100";
- });
- observer.observe(editorDom, {
- attributes: true,
- });
- // 销毁监听
- return () => {
- observer.disconnect();
- };
- }
- }, [isLook]);
- // 编辑器文本
- const [editorValue, setEditorValue] = useState(
- // 初始内容
- BraftEditor.createEditorState("")
- );
- // 判断 富文本是否为空
- const isTxtFlag = useMemo(() => {
- const txt: string = editorValue.toHTML();
- if (
- txt.replaceAll("<p>", "").replaceAll("</p>", "").replaceAll(" ", "") ===
- ""
- ) {
- return true;
- } else return false;
- }, [editorValue]);
- const myInput = useRef<HTMLInputElement>(null);
- // 上传图片
- const handeUpPhoto = useCallback(
- async (e: React.ChangeEvent<HTMLInputElement>) => {
- if (e.target.files) {
- // 拿到files信息
- const filesInfo = e.target.files[0];
- // 校验格式
- const type = ["image/jpeg", "image/png"];
- if (!type.includes(filesInfo.type)) {
- e.target.value = "";
- return MessageFu.warning("只支持png、jpg和jpeg格式!");
- }
- // 校验大小
- if (filesInfo.size > 5 * 1024 * 1024) {
- e.target.value = "";
- return MessageFu.warning("最大支持5M!");
- }
- // 创建FormData对象
- const fd = new FormData();
- // 把files添加进FormData对象(‘photo’为后端需要的字段)
- fd.append("type", "img");
- fd.append("dirCode", dirCode);
- fd.append("file", filesInfo);
- e.target.value = "";
- try {
- const res = await API_upFile(fd, myUrl);
- if (res.code === 0) {
- MessageFu.success("上传成功!");
- // 在光标位置插入图片
- const newTxt = ContentUtils.insertMedias(editorValue, [
- {
- type: "IMAGE",
- url: baseURL + res.data.filePath,
- },
- ]);
- setEditorValue(newTxt);
- }
- fileDomInitialFu();
- } catch (error) {
- fileDomInitialFu();
- }
- }
- },
- [dirCode, editorValue, myUrl]
- );
- // 让父组件调用的 回显 富文本
- const ritxtShowFu = useCallback((val: string) => {
- setEditorValue(BraftEditor.createEditorState(val));
- }, []);
- // 让父组件调用的返回 富文本信息 和 表单校验
- const fatherBtnOkFu = useCallback(() => {
- return { val: editorValue.toHTML(), flag: isTxtFlag };
- }, [editorValue, isTxtFlag]);
- // 可以让父组件调用子组件的方法
- useImperativeHandle(ref, () => ({
- ritxtShowFu,
- fatherBtnOkFu,
- }));
- return (
- <div
- className={styles.ZRichText}
- style={{ width: full ? "100%" : "", height: full ? "100%" : "" }}
- >
- <input
- id="upInput"
- type="file"
- accept=".png,.jpg,.jpeg"
- ref={myInput}
- onChange={(e) => handeUpPhoto(e)}
- />
- <div className="txtBox" style={{ height: full ? "100%" : "" }}>
- <BraftEditor
- readOnly={isLook}
- placeholder="请输入内容"
- value={editorValue}
- onChange={(e) => setEditorValue(e)}
- imageControls={["remove"]}
- />
- </div>
- <div
- className={classNames(
- "noUpThumb",
- check && isTxtFlag ? "noUpThumbAc" : ""
- )}
- >
- 请输入正文!
- </div>
- </div>
- );
- }
- // const MemoZRichText = React.memo(ZRichText);
- export default forwardRef(ZRichText);
|