|
@@ -0,0 +1,247 @@
|
|
|
+import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
|
+import styles from "./index.module.scss";
|
|
|
+import ImageLazy from "@/components/ImageLazy";
|
|
|
+import {
|
|
|
+ PlusOutlined,
|
|
|
+ EyeOutlined,
|
|
|
+ CloseOutlined,
|
|
|
+ DownloadOutlined,
|
|
|
+} from "@ant-design/icons";
|
|
|
+import store from "@/store";
|
|
|
+import { baseURL } from "@/utils/http";
|
|
|
+import classNames from "classnames";
|
|
|
+import { Popconfirm } from "antd";
|
|
|
+import { MessageFu } from "@/utils/message";
|
|
|
+import { fileDomInitialFu } from "@/utils/domShow";
|
|
|
+import { API_upFile } from "@/store/action/layout";
|
|
|
+import { forwardRef, useImperativeHandle } from "react";
|
|
|
+
|
|
|
+// 这个组件 只处理 上传 一张图片或者 视频 音频 模型 的情况
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ isLook: boolean; //是不是查看
|
|
|
+ fileCheck: boolean; //有没有点击过确定
|
|
|
+ size: number; //上传附件大小(M)
|
|
|
+ dirCode: string; //文件的code码
|
|
|
+ myUrl: string; //请求地址
|
|
|
+ format: string[]; //上传格式
|
|
|
+ formatTxt: string; //上传图片提示
|
|
|
+ checkTxt: string;
|
|
|
+ upTxt: string;
|
|
|
+ myType: "thumb" | "video" | "audio" | "model";
|
|
|
+ fromData?: any;
|
|
|
+ ref: any; //当前自己的ref,给父组件调用
|
|
|
+};
|
|
|
+
|
|
|
+function ZupOne(
|
|
|
+ {
|
|
|
+ isLook,
|
|
|
+ fileCheck,
|
|
|
+ size,
|
|
|
+ dirCode,
|
|
|
+ myUrl,
|
|
|
+ format,
|
|
|
+ formatTxt,
|
|
|
+ checkTxt,
|
|
|
+ upTxt,
|
|
|
+ myType,
|
|
|
+ fromData,
|
|
|
+ }: Props,
|
|
|
+ ref: any
|
|
|
+) {
|
|
|
+ const [fileUrl, setFileUrl] = useState({
|
|
|
+ fileName: "",
|
|
|
+ filePath: "",
|
|
|
+ });
|
|
|
+
|
|
|
+ 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 = format;
|
|
|
+ if (!type.includes(filesInfo.type)) {
|
|
|
+ e.target.value = "";
|
|
|
+ return MessageFu.warning(`只支持${formatTxt}格式!`);
|
|
|
+ }
|
|
|
+ // 校验大小
|
|
|
+ if (filesInfo.size > size * 1024 * 1024) {
|
|
|
+ e.target.value = "";
|
|
|
+ return MessageFu.warning(`最大支持${size}M!`);
|
|
|
+ }
|
|
|
+ // 创建FormData对象
|
|
|
+ const fd = new FormData();
|
|
|
+ // 把files添加进FormData对象(‘photo’为后端需要的字段)
|
|
|
+ fd.append("type", myType);
|
|
|
+ fd.append("dirCode", dirCode);
|
|
|
+ fd.append("file", filesInfo);
|
|
|
+
|
|
|
+ if (fromData) {
|
|
|
+ for (const k in fromData) {
|
|
|
+ if (fromData[k]) fd.append(k, fromData[k]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ e.target.value = "";
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await API_upFile(fd, myUrl);
|
|
|
+ if (res.code === 0) {
|
|
|
+ MessageFu.success("上传成功!");
|
|
|
+ setFileUrl(res.data);
|
|
|
+ }
|
|
|
+ fileDomInitialFu();
|
|
|
+ } catch (error) {
|
|
|
+ fileDomInitialFu();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [dirCode, format, formatTxt, fromData, myType, myUrl, size]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 让父组件调用的 回显 附件 地址
|
|
|
+ const setFileComFileFu = useCallback(
|
|
|
+ (valObj: { fileName: string; filePath: string }) => {
|
|
|
+ setFileUrl(valObj);
|
|
|
+ },
|
|
|
+ []
|
|
|
+ );
|
|
|
+
|
|
|
+ // 让父组件调用的返回 附件 名字和路径
|
|
|
+ const fileComFileResFu = useCallback(() => {
|
|
|
+ return fileUrl;
|
|
|
+ }, [fileUrl]);
|
|
|
+
|
|
|
+ // 可以让父组件调用子组件的方法
|
|
|
+ useImperativeHandle(ref, () => ({
|
|
|
+ setFileComFileFu,
|
|
|
+ fileComFileResFu,
|
|
|
+ }));
|
|
|
+
|
|
|
+ const acceptRes = useMemo(() => {
|
|
|
+ let accept = ".png,.jpg,.jpeg";
|
|
|
+ if (myType === "video") accept = ".mp4";
|
|
|
+ else if (myType === "audio") accept = ".mp3";
|
|
|
+ else if (myType === "model") accept = ".4dage";
|
|
|
+ return accept;
|
|
|
+ }, [myType]);
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={styles.ZupOne}>
|
|
|
+ <input
|
|
|
+ id="upInput"
|
|
|
+ type="file"
|
|
|
+ accept={acceptRes}
|
|
|
+ ref={myInput}
|
|
|
+ onChange={(e) => handeUpPhoto(e)}
|
|
|
+ />
|
|
|
+
|
|
|
+ <div
|
|
|
+ hidden={fileUrl.filePath !== ""}
|
|
|
+ className="file_upIcon"
|
|
|
+ onClick={() => myInput.current?.click()}
|
|
|
+ >
|
|
|
+ <PlusOutlined rev={undefined} />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 为图片的情况-------------- */}
|
|
|
+ {myType === "thumb" ? (
|
|
|
+ <div className="file_img" hidden={fileUrl.filePath === ""}>
|
|
|
+ {fileUrl ? (
|
|
|
+ <ImageLazy width={100} height={100} src={fileUrl.filePath} noLook />
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {/* 删除 */}
|
|
|
+ <div className="file_closeBox" hidden={isLook}>
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => setFileUrl({ fileName: "", filePath: "" })}
|
|
|
+ >
|
|
|
+ <CloseOutlined rev={undefined} />
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 预览 下载 */}
|
|
|
+ <div className="file_lookBox">
|
|
|
+ <EyeOutlined
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: "layout/lookBigImg",
|
|
|
+ payload: { url: baseURL + fileUrl, show: true },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ rev={undefined}
|
|
|
+ />
|
|
|
+ <a
|
|
|
+ href={baseURL + fileUrl}
|
|
|
+ download
|
|
|
+ target="_blank"
|
|
|
+ rel="noreferrer"
|
|
|
+ >
|
|
|
+ <DownloadOutlined rev={undefined} />
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ) : fileUrl.filePath ? (
|
|
|
+ <div className="fileInfo">
|
|
|
+ <div className="upSuccTxt">{fileUrl.fileName}</div>
|
|
|
+ {/* 视频预览 */}
|
|
|
+ <div
|
|
|
+ className="clearCover"
|
|
|
+ hidden={!fileUrl.filePath}
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: "layout/lookDom",
|
|
|
+ payload: { src: fileUrl.filePath, type: myType },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <EyeOutlined rev={undefined} />
|
|
|
+ </div>
|
|
|
+ {/* 视频下载 */}
|
|
|
+ <a
|
|
|
+ href={baseURL + fileUrl.filePath}
|
|
|
+ download
|
|
|
+ target="_blank"
|
|
|
+ className="clearCover"
|
|
|
+ rel="noreferrer"
|
|
|
+ >
|
|
|
+ <DownloadOutlined rev={undefined} />
|
|
|
+ </a>
|
|
|
+ {/* 视频删除 */}
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => setFileUrl({ fileName: "", filePath: "" })}
|
|
|
+ >
|
|
|
+ <div className="clearCover" hidden={isLook}>
|
|
|
+ <CloseOutlined rev={undefined} />
|
|
|
+ </div>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ <div className="fileBoxRow_r_tit" hidden={isLook}>
|
|
|
+ 支持{formatTxt}的图片格式;最大支持{size}M。{upTxt}
|
|
|
+ <br />
|
|
|
+ <div
|
|
|
+ className={classNames(
|
|
|
+ "noUpThumb",
|
|
|
+ !fileUrl.filePath && fileCheck ? "noUpThumbAc" : ""
|
|
|
+ )}
|
|
|
+ >
|
|
|
+ {checkTxt}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+export default forwardRef(ZupOne);
|