123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- import React, { useCallback, useMemo, useRef, useState } from "react";
- import styles from "./index.module.scss";
- import ImageLazy from "@/components/ImageLazy";
- import {
- PlusOutlined,
- EyeOutlined,
- CloseOutlined,
- DownloadOutlined,
- UploadOutlined,
- } from "@ant-design/icons";
- import store from "@/store";
- import { baseURL } from "@/utils/http";
- import classNames from "classnames";
- import { Button } from "antd";
- import { MessageFu } from "@/utils/message";
- import { fileDomInitialFu } from "@/utils/domShow";
- import { API_upFile } from "@/store/action/layout";
- import { forwardRef, useImperativeHandle } from "react";
- import MyPopconfirm from "../MyPopconfirm";
- type MyTypeType = "thumb" | "video" | "audio" | "model" | "pdf";
- // 这个组件 只处理 上传 一张图片或者 视频 音频 模型 pdf 的情况
- type Props = {
- fileCheck: boolean; //有没有点击过确定
- size: number; //上传附件大小(M)
- dirCode: string; //文件的code码
- myUrl: string; //请求地址
- format: string[]; //上传格式 ["image/jpeg", "image/png"] ["video/mp4"] ,application/pdf
- formatTxt: string; //上传图片提示
- checkTxt: string;
- upTxt: string;
- myType: MyTypeType;
- isLook?: boolean; //是不是查看
- fromData?: any;
- ref: any; //当前自己的ref,给父组件调用
- };
- function ZupOne(
- {
- fileCheck,
- size,
- dirCode,
- myUrl,
- format,
- formatTxt,
- checkTxt,
- upTxt,
- myType,
- isLook = false,
- 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];
- // console.log("-----", filesInfo.type);
- // 校验格式
- const type = format;
- if (myType === "pdf") {
- if (!filesInfo.type.includes("pdf")) {
- e.target.value = "";
- return MessageFu.warning(`只支持${formatTxt}格式!`);
- }
- } else {
- 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’为后端需要的字段)
- let myTypeRes: string = myType;
- if (["pdf"].includes(myTypeRes)) myTypeRes = "doc";
- fd.append("type", myTypeRes);
- 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";
- else if (myType === "pdf") accept = ".pdf";
- return accept;
- }, [myType]);
- // 点击 预览(除了图片)
- const lookFileNoImgFu = useCallback(
- (type: MyTypeType) => {
- if (type === "pdf" || type === "thumb") {
- // 新窗口打开
- window.open(baseURL + fileUrl.filePath);
- } else {
- store.dispatch({
- type: "layout/lookDom",
- payload: { src: fileUrl.filePath, type },
- });
- }
- // if (type === "pdf") {
- // } else {
- // }
- },
- [fileUrl.filePath]
- );
- return (
- <div className={styles.ZupOne}>
- <input
- id="upInput"
- type="file"
- accept={acceptRes}
- ref={myInput}
- onChange={(e) => handeUpPhoto(e)}
- />
- {myType === "thumb" ? (
- <div
- hidden={fileUrl.filePath !== ""}
- className="file_upIcon"
- onClick={() => myInput.current?.click()}
- >
- <PlusOutlined rev={undefined} />
- </div>
- ) : (
- <Button
- hidden={fileUrl.filePath !== ""}
- onClick={() => myInput.current?.click()}
- icon={<UploadOutlined rev={undefined} />}
- >
- 上传
- </Button>
- )}
- {/* 为图片的情况-------------- */}
- {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}>
- <MyPopconfirm
- txtK="删除"
- onConfirm={() => setFileUrl({ fileName: "", filePath: "" })}
- Dom={<CloseOutlined rev={undefined} />}
- />
- </div>
- {/* 预览 下载 */}
- <div className="file_lookBox">
- <EyeOutlined
- onClick={() =>
- store.dispatch({
- type: "layout/lookBigImg",
- payload: { url: baseURL + fileUrl.filePath, show: true },
- })
- }
- rev={undefined}
- />
- <a
- href={baseURL + fileUrl.filePath}
- 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={() => lookFileNoImgFu(myType)}
- >
- <EyeOutlined rev={undefined} />
- </div>
- {/* 视频下载 */}
- <a
- href={baseURL + fileUrl.filePath}
- download
- target="_blank"
- className="clearCover"
- rel="noreferrer"
- >
- <DownloadOutlined rev={undefined} />
- </a>
- {/* 视频删除 */}
- <MyPopconfirm
- txtK="删除"
- onConfirm={() => setFileUrl({ fileName: "", filePath: "" })}
- Dom={<CloseOutlined className="clearCover" rev={undefined} />}
- />
- </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);
|