|
@@ -0,0 +1,834 @@
|
|
|
+import store, { RootState } from "@/store";
|
|
|
+import {
|
|
|
+ Button,
|
|
|
+ Checkbox,
|
|
|
+ Form,
|
|
|
+ FormInstance,
|
|
|
+ Input,
|
|
|
+ Popconfirm,
|
|
|
+ Select,
|
|
|
+} from "antd";
|
|
|
+import React, {
|
|
|
+ useCallback,
|
|
|
+ useEffect,
|
|
|
+ useMemo,
|
|
|
+ useRef,
|
|
|
+ useState,
|
|
|
+} from "react";
|
|
|
+import { useSelector } from "react-redux";
|
|
|
+import TextArea from "antd/es/input/TextArea";
|
|
|
+import styles from "./index.module.scss";
|
|
|
+import { MessageFu } from "@/utils/message";
|
|
|
+import ImageLazy from "@/components/ImageLazy";
|
|
|
+import classNames from "classnames";
|
|
|
+import {
|
|
|
+ PlusOutlined,
|
|
|
+ EyeOutlined,
|
|
|
+ UploadOutlined,
|
|
|
+ CloseOutlined,
|
|
|
+ DownloadOutlined,
|
|
|
+} from "@ant-design/icons";
|
|
|
+import {
|
|
|
+ getGoodsInfoByIdAPI,
|
|
|
+ getGoodsSaveAPI,
|
|
|
+ goodsUploadAPI,
|
|
|
+} from "@/store/action/A1Goods";
|
|
|
+import { baseURL } from "@/utils/http";
|
|
|
+import { FileImgListType, FileListType, GoodsTableType } from "@/types";
|
|
|
+import { fileDomInitialFu } from "@/utils/domShow";
|
|
|
+import { ReactSortable } from "react-sortablejs";
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ id: number;
|
|
|
+ lookFlag: boolean;
|
|
|
+ closeMoalFu: () => void;
|
|
|
+ addListFu: () => void;
|
|
|
+ editListFu: () => void;
|
|
|
+};
|
|
|
+
|
|
|
+function GoodsAdd({ id, closeMoalFu, addListFu, editListFu, lookFlag }: Props) {
|
|
|
+ // 上传附件的信息
|
|
|
+ const [fileList, setFileList] = useState({
|
|
|
+ model: {} as FileListType,
|
|
|
+ audio: {} as FileListType,
|
|
|
+ video: {} as FileListType,
|
|
|
+ });
|
|
|
+
|
|
|
+ // 附件拖动的拆分数组
|
|
|
+ const [fileImgList, setFileImgList] = useState<FileImgListType>([]);
|
|
|
+
|
|
|
+ // 表单的ref
|
|
|
+ const FormBoxRef = useRef<FormInstance>(null);
|
|
|
+
|
|
|
+ // 文件的dirCode码
|
|
|
+ const [dirCode, setDirCode] = useState("");
|
|
|
+
|
|
|
+ const getInfoInAPIFu = useCallback(async (id: number) => {
|
|
|
+ const res = await getGoodsInfoByIdAPI(id);
|
|
|
+ FormBoxRef.current?.setFieldsValue(res.data.entity);
|
|
|
+ setCover(res.data.entity.thumb);
|
|
|
+
|
|
|
+ if (res.data.entity.type) setTypeCheck(res.data.entity.type.split(","));
|
|
|
+
|
|
|
+ const data: FileListType[] = res.data.file;
|
|
|
+ const obj = {
|
|
|
+ model: {} as FileListType,
|
|
|
+ audio: {} as FileListType,
|
|
|
+ video: {} as FileListType,
|
|
|
+ };
|
|
|
+
|
|
|
+ const fileImgListTemp = [] as FileImgListType;
|
|
|
+
|
|
|
+ data.forEach((v) => {
|
|
|
+ if (v.type === "img") fileImgListTemp.push(v as any);
|
|
|
+ else obj[v.type!] = v;
|
|
|
+ });
|
|
|
+ setFileImgList(fileImgListTemp);
|
|
|
+ setFileList(obj);
|
|
|
+ setDirCode(res.data.entity.dirCode);
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (id > 0) getInfoInAPIFu(id);
|
|
|
+ else {
|
|
|
+ setDirCode(Date.now() + "");
|
|
|
+ // FormBoxRef.current?.setFieldsValue({ });
|
|
|
+ }
|
|
|
+ }, [getInfoInAPIFu, id]);
|
|
|
+
|
|
|
+ // 从仓库获取下拉列表数据
|
|
|
+ const dictList = useSelector((state: RootState) => state.A0Layout.dictList);
|
|
|
+
|
|
|
+ // 上传封面图的ref
|
|
|
+ const [coverCheck, setCoverCheck] = useState(false);
|
|
|
+ const [cover, setCover] = useState("");
|
|
|
+ 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("只支持jpg、png格式!");
|
|
|
+ }
|
|
|
+ // 校验大小
|
|
|
+ if (filesInfo.size > 20 * 1024 * 1024) {
|
|
|
+ e.target.value = "";
|
|
|
+ return MessageFu.warning("最大支持20M!");
|
|
|
+ }
|
|
|
+ // 创建FormData对象
|
|
|
+ const fd = new FormData();
|
|
|
+ // 把files添加进FormData对象(‘photo’为后端需要的字段)
|
|
|
+ fd.append("type", "thumb");
|
|
|
+ fd.append("dirCode", dirCode);
|
|
|
+ fd.append("file", filesInfo);
|
|
|
+
|
|
|
+ e.target.value = "";
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await goodsUploadAPI(fd);
|
|
|
+ if (res.code === 0) {
|
|
|
+ MessageFu.success("上传成功!");
|
|
|
+ setCover(res.data.filePath);
|
|
|
+ }
|
|
|
+ fileDomInitialFu();
|
|
|
+ } catch (error) {
|
|
|
+ fileDomInitialFu();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [dirCode]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 选中附件类型
|
|
|
+ const [typeCheck, setTypeCheck] = useState<any>(["model"]);
|
|
|
+ const [typeOk, setTypeOk] = useState(false);
|
|
|
+
|
|
|
+ const typeCheckArr = useMemo(() => {
|
|
|
+ return [
|
|
|
+ { label: "模型", value: "model" },
|
|
|
+ { label: "图片", value: "img" },
|
|
|
+ { label: "音频", value: "audio" },
|
|
|
+ { label: "视频", value: "video" },
|
|
|
+ ];
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 附件信息的校验
|
|
|
+
|
|
|
+ const fileCheckFu = useMemo(() => {
|
|
|
+ let flag = false;
|
|
|
+ if (typeCheck.length === 0) flag = true;
|
|
|
+ if (typeCheck.includes("model") && !fileList.model.id) flag = true;
|
|
|
+ if (typeCheck.includes("img") && fileImgList.length === 0) flag = true;
|
|
|
+ if (typeCheck.includes("audio") && !fileList.audio.id) flag = true;
|
|
|
+ if (typeCheck.includes("video") && !fileList.video.id) flag = true;
|
|
|
+ return flag;
|
|
|
+ }, [
|
|
|
+ fileImgList.length,
|
|
|
+ fileList.audio.id,
|
|
|
+ fileList.model.id,
|
|
|
+ fileList.video.id,
|
|
|
+ typeCheck,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 点击上传附件按钮
|
|
|
+ const myInput2 = useRef<HTMLInputElement>(null);
|
|
|
+
|
|
|
+ const [fileOneType, setFileOneType] = useState("");
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (fileOneType) myInput2.current?.click();
|
|
|
+ }, [fileOneType]);
|
|
|
+
|
|
|
+ const upFileFu = useCallback((type: string) => {
|
|
|
+ setFileOneType("");
|
|
|
+ window.setTimeout(() => {
|
|
|
+ setFileOneType(type);
|
|
|
+ }, 100);
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 上传附件的处理函数
|
|
|
+ const handeUpPhoto2 = useCallback(
|
|
|
+ async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
+ if (e.target.files) {
|
|
|
+ // 拿到files信息
|
|
|
+ const filesInfo = e.target.files[0];
|
|
|
+
|
|
|
+ let anType = ["image/jpeg", "image/png", "image/gif"];
|
|
|
+ let anTit1 = "只支持png、jpg、gif和jpeg格式!";
|
|
|
+ let anTit2 = "最大支持20M!";
|
|
|
+ let anSize = 20 * 1024 * 1024;
|
|
|
+
|
|
|
+ if (fileOneType === "audio") {
|
|
|
+ anType = ["audio/mpeg"];
|
|
|
+ anTit1 = "只支持mp3格式!";
|
|
|
+ anTit2 = "最大支持10M!";
|
|
|
+ anSize = 10 * 1024 * 1024;
|
|
|
+ } else if (fileOneType === "video") {
|
|
|
+ anType = ["video/mp4"];
|
|
|
+ anTit1 = "只支持mp4格式!";
|
|
|
+ anTit2 = "最大支持500M!";
|
|
|
+ anSize = 500 * 1024 * 1024;
|
|
|
+ } else if (fileOneType === "model") {
|
|
|
+ anType = [""];
|
|
|
+ anTit1 = "只支持4dage格式!";
|
|
|
+ anTit2 = "最大支持500M!";
|
|
|
+ anSize = 500 * 1024 * 1024;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验格式
|
|
|
+ if (fileOneType !== "model") {
|
|
|
+ if (!anType.includes(filesInfo.type)) {
|
|
|
+ e.target.value = "";
|
|
|
+ return MessageFu.warning(anTit1);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!filesInfo.name.includes(".4dage")) {
|
|
|
+ e.target.value = "";
|
|
|
+ return MessageFu.warning(anTit1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验大小
|
|
|
+ if (filesInfo.size > anSize) {
|
|
|
+ e.target.value = "";
|
|
|
+ return MessageFu.warning(anTit2);
|
|
|
+ }
|
|
|
+ // 创建FormData对象
|
|
|
+ const fd = new FormData();
|
|
|
+ // 把files添加进FormData对象(‘photo’为后端需要的字段)
|
|
|
+ fd.append("type", fileOneType);
|
|
|
+ fd.append("dirCode", dirCode);
|
|
|
+ fd.append("file", filesInfo);
|
|
|
+
|
|
|
+ e.target.value = "";
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await goodsUploadAPI(fd);
|
|
|
+
|
|
|
+ if (res.code === 0) {
|
|
|
+ MessageFu.success("上传成功!");
|
|
|
+ if (fileOneType === "img")
|
|
|
+ setFileImgList([...fileImgList, res.data]);
|
|
|
+ else setFileList({ ...fileList, [fileOneType]: res.data });
|
|
|
+ }
|
|
|
+ fileDomInitialFu();
|
|
|
+ } catch (error) {
|
|
|
+ fileDomInitialFu();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [dirCode, fileImgList, fileList, fileOneType]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 附近图片列表删除某一张图片
|
|
|
+ const delImgListFu = useCallback(
|
|
|
+ (id: number) => {
|
|
|
+ const newItems = fileImgList.filter((v) => v.id !== id);
|
|
|
+ setFileImgList(newItems);
|
|
|
+ },
|
|
|
+ [fileImgList]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 没有通过校验
|
|
|
+ const onFinishFailed = useCallback(() => {
|
|
|
+ setCoverCheck(true);
|
|
|
+ setTypeOk(true);
|
|
|
+ return MessageFu.warning("有表单不符号规则!");
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 通过校验点击确定
|
|
|
+ const onFinish = useCallback(
|
|
|
+ async (value: GoodsTableType) => {
|
|
|
+ console.log("通过校验,点击确定");
|
|
|
+ setCoverCheck(true);
|
|
|
+ setTypeOk(true);
|
|
|
+ if (typeCheck.length === 0 || cover === "" || fileCheckFu)
|
|
|
+ return MessageFu.warning("有表单不符号规则!");
|
|
|
+
|
|
|
+ const fileIds = [];
|
|
|
+ if (fileList.model.id && typeCheck.includes("model"))
|
|
|
+ fileIds.push(fileList.model.id);
|
|
|
+ if (fileList.audio.id && typeCheck.includes("audio"))
|
|
|
+ fileIds.push(fileList.audio.id);
|
|
|
+ if (fileList.video.id && typeCheck.includes("video"))
|
|
|
+ fileIds.push(fileList.video.id);
|
|
|
+ if (typeCheck.includes("img")) {
|
|
|
+ fileImgList.forEach((v) => {
|
|
|
+ if (v.id) fileIds.push(v.id);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 简介的处理
|
|
|
+ const txt = value.description.replaceAll(" ", "").replaceAll("\n", "");
|
|
|
+
|
|
|
+ const obj = {
|
|
|
+ ...value,
|
|
|
+ id: id > 0 ? id : null,
|
|
|
+ dirCode,
|
|
|
+ fileIds: fileIds.join(","),
|
|
|
+ thumb: cover,
|
|
|
+ type: typeCheck.join(","),
|
|
|
+ description: txt ? value.description : "",
|
|
|
+ } as GoodsTableType;
|
|
|
+ const res = await getGoodsSaveAPI(obj);
|
|
|
+ if (res.code === 0) {
|
|
|
+ MessageFu.success(id > 0 ? "编辑成功!" : "新增成功!");
|
|
|
+ closeMoalFu();
|
|
|
+ if (id > 0) editListFu();
|
|
|
+ else addListFu();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [
|
|
|
+ typeCheck,
|
|
|
+ cover,
|
|
|
+ fileCheckFu,
|
|
|
+ fileList.model.id,
|
|
|
+ fileList.audio.id,
|
|
|
+ fileList.video.id,
|
|
|
+ id,
|
|
|
+ dirCode,
|
|
|
+ fileImgList,
|
|
|
+ closeMoalFu,
|
|
|
+ editListFu,
|
|
|
+ addListFu,
|
|
|
+ ]
|
|
|
+ );
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={styles.GoodsAdd}>
|
|
|
+ <div className="main mySorrl">
|
|
|
+ <Form
|
|
|
+ ref={FormBoxRef}
|
|
|
+ name="basic"
|
|
|
+ labelCol={{ span: 3 }}
|
|
|
+ onFinish={onFinish}
|
|
|
+ onFinishFailed={onFinishFailed}
|
|
|
+ autoComplete="off"
|
|
|
+ >
|
|
|
+ <Form.Item
|
|
|
+ label="名称"
|
|
|
+ name="name"
|
|
|
+ rules={[{ required: true, message: "请输入名称!" }]}
|
|
|
+ getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
|
|
|
+ >
|
|
|
+ <Input maxLength={25} showCount placeholder="请输入内容" />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ <Form.Item
|
|
|
+ label="登记编号"
|
|
|
+ name="num"
|
|
|
+ getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
|
|
|
+ >
|
|
|
+ <Input maxLength={25} showCount placeholder="请输入内容" />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ <Form.Item
|
|
|
+ label="类别"
|
|
|
+ name="dictTexture"
|
|
|
+ rules={[{ required: true, message: "请选择类别!" }]}
|
|
|
+ >
|
|
|
+ <Select
|
|
|
+ placeholder="请选择"
|
|
|
+ style={{ width: 400 }}
|
|
|
+ options={dictList["texture"].slice(1)}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ <Form.Item
|
|
|
+ label="年代"
|
|
|
+ name="dictAge"
|
|
|
+ rules={[{ required: true, message: "请选择年代!" }]}
|
|
|
+ >
|
|
|
+ <Select
|
|
|
+ placeholder="请选择"
|
|
|
+ style={{ width: 400 }}
|
|
|
+ options={dictList["age"].slice(1)}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ <Form.Item
|
|
|
+ label="级别"
|
|
|
+ name="dictLevel"
|
|
|
+ rules={[{ required: true, message: "请选择级别!" }]}
|
|
|
+ >
|
|
|
+ <Select
|
|
|
+ placeholder="请选择"
|
|
|
+ style={{ width: 400 }}
|
|
|
+ options={dictList["level"].slice(1)}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ <Form.Item
|
|
|
+ label="来源"
|
|
|
+ name="dictSource"
|
|
|
+ rules={[{ required: true, message: "请选择来源!" }]}
|
|
|
+ >
|
|
|
+ <Select
|
|
|
+ placeholder="请选择"
|
|
|
+ style={{ width: 400 }}
|
|
|
+ options={dictList["source"].slice(1)}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ <Form.Item
|
|
|
+ label="简介"
|
|
|
+ name="description"
|
|
|
+ // getValueFromEvent={(e) => e.target.value.trim()}
|
|
|
+ >
|
|
|
+ <TextArea
|
|
|
+ autoSize
|
|
|
+ placeholder="请输入内容"
|
|
|
+ showCount
|
|
|
+ maxLength={200}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ {/* -----上传封面图片 */}
|
|
|
+ <div className="myformBox myformBox0">
|
|
|
+ <input
|
|
|
+ id="upInput"
|
|
|
+ type="file"
|
|
|
+ accept=".png,.jpg,.jpeg"
|
|
|
+ ref={myInput}
|
|
|
+ onChange={(e) => handeUpPhoto(e)}
|
|
|
+ />
|
|
|
+ <input
|
|
|
+ id="upInput2"
|
|
|
+ type="file"
|
|
|
+ accept={
|
|
|
+ fileOneType === "img"
|
|
|
+ ? ".gif,.png,.jpg,.jpeg"
|
|
|
+ : fileOneType === "audio"
|
|
|
+ ? ".mp3"
|
|
|
+ : fileOneType === "model"
|
|
|
+ ? ".4dage"
|
|
|
+ : ".mp4"
|
|
|
+ }
|
|
|
+ ref={myInput2}
|
|
|
+ onChange={(e) => handeUpPhoto2(e)}
|
|
|
+ />
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 封面图:
|
|
|
+ </div>
|
|
|
+ <div className="fileBoxRow_r">
|
|
|
+ <div
|
|
|
+ hidden={cover !== ""}
|
|
|
+ className="fileBoxRow_up"
|
|
|
+ onClick={() => myInput.current?.click()}
|
|
|
+ >
|
|
|
+ <PlusOutlined />
|
|
|
+ </div>
|
|
|
+ <div className="fileBoxRow_r_img" hidden={cover === ""}>
|
|
|
+ {cover ? (
|
|
|
+ <ImageLazy width={100} height={100} src={cover} noLook />
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ <div className="clearCover2">
|
|
|
+ {/* 封面图预览 删除 下载 */}
|
|
|
+ <div className="clearCover2DelBox">
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => setCover("")}
|
|
|
+ >
|
|
|
+ <CloseOutlined />
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="clearCover2DLBox">
|
|
|
+ <EyeOutlined
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: "layout/lookBigImg",
|
|
|
+ payload: { url: baseURL + cover, show: true },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ />
|
|
|
+ <a
|
|
|
+ href={baseURL + cover}
|
|
|
+ download
|
|
|
+ target="_blank"
|
|
|
+ rel="noreferrer"
|
|
|
+ >
|
|
|
+ <DownloadOutlined />
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div className="fileBoxRow_r_tit">
|
|
|
+ 支持png、jpg和jpeg的图片格式;最大支持20M。
|
|
|
+ <br />
|
|
|
+ <div
|
|
|
+ className={classNames(
|
|
|
+ "noUpThumb",
|
|
|
+ !cover && coverCheck ? "noUpThumbAc" : ""
|
|
|
+ )}
|
|
|
+ >
|
|
|
+ 请上传封面图!
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 选中文件类型和上传附件 */}
|
|
|
+ <div className="myformBox">
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 文件类型:
|
|
|
+ </div>
|
|
|
+ <div className="myformBoxR">
|
|
|
+ <Checkbox.Group
|
|
|
+ options={typeCheckArr}
|
|
|
+ value={typeCheck}
|
|
|
+ onChange={(e) => setTypeCheck(e)}
|
|
|
+ // onChange={(e) => console.log(e)}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* -----------模型上传 */}
|
|
|
+ <div
|
|
|
+ className="myformBox myformBox2"
|
|
|
+ hidden={!typeCheck.includes("model")}
|
|
|
+ >
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 模型:
|
|
|
+ </div>
|
|
|
+ {fileList.model.id ? (
|
|
|
+ <div className="fileInfo">
|
|
|
+ {fileList.model.fileName}
|
|
|
+ {/* 模型预览 */}
|
|
|
+ <div
|
|
|
+ className="clearCover"
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: "layout/lookDom",
|
|
|
+ payload: { src: fileList.model.filePath!, type: "model" },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <EyeOutlined />
|
|
|
+ </div>
|
|
|
+ {/* 模型下载 */}
|
|
|
+ <a
|
|
|
+ href={baseURL + fileList.model.filePath}
|
|
|
+ download
|
|
|
+ target="_blank"
|
|
|
+ className="clearCover"
|
|
|
+ rel="noreferrer"
|
|
|
+ >
|
|
|
+ <DownloadOutlined />
|
|
|
+ </a>
|
|
|
+ {/* 模型删除 */}
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => setFileList({ ...fileList, model: {} })}
|
|
|
+ >
|
|
|
+ <div className="clearCover">
|
|
|
+ <CloseOutlined />
|
|
|
+ </div>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <Button
|
|
|
+ onClick={() => upFileFu("model")}
|
|
|
+ icon={<UploadOutlined />}
|
|
|
+ >
|
|
|
+ 上传
|
|
|
+ </Button>
|
|
|
+
|
|
|
+ <div className="fileTit">
|
|
|
+ 仅支持4dage格式的模型文件,大小不能超过500M。
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* -----------30张图片上传 */}
|
|
|
+ <div
|
|
|
+ className="myformBox myformBox3"
|
|
|
+ hidden={!typeCheck.includes("img")}
|
|
|
+ >
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 图片:
|
|
|
+ </div>
|
|
|
+ <>
|
|
|
+ <div className="fileBoxRow_r">
|
|
|
+ <div className="upImgBox">
|
|
|
+ <div
|
|
|
+ hidden={!!fileImgList.length && fileImgList.length >= 30}
|
|
|
+ className="fileBoxRow_up"
|
|
|
+ onClick={() => upFileFu("img")}
|
|
|
+ >
|
|
|
+ <PlusOutlined />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <ReactSortable
|
|
|
+ className="fileImgListBox"
|
|
|
+ list={fileImgList}
|
|
|
+ setList={setFileImgList}
|
|
|
+ >
|
|
|
+ {fileImgList.map((v, i) => (
|
|
|
+ <div className="fileBoxRow_r_img" key={v.id}>
|
|
|
+ {v.filePath ? (
|
|
|
+ <ImageLazy
|
|
|
+ noLook
|
|
|
+ width={100}
|
|
|
+ height={100}
|
|
|
+ src={v.filePath}
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => delImgListFu(v.id!)}
|
|
|
+ >
|
|
|
+ <div className="clearCover">
|
|
|
+ <CloseOutlined />
|
|
|
+ </div>
|
|
|
+ </Popconfirm>
|
|
|
+ {/* 下面的预览和下载 */}
|
|
|
+ <div className="fileImgListLDBox">
|
|
|
+ <EyeOutlined
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: "layout/lookBigImg",
|
|
|
+ payload: {
|
|
|
+ url: baseURL + v.filePath,
|
|
|
+ show: true,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ />
|
|
|
+ <a
|
|
|
+ href={baseURL + v.filePath}
|
|
|
+ download
|
|
|
+ target="_blank"
|
|
|
+ rel="noreferrer"
|
|
|
+ >
|
|
|
+ <DownloadOutlined />
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </ReactSortable>
|
|
|
+ </div>
|
|
|
+ <div className="fileTit">
|
|
|
+ {fileImgList.length && fileImgList.length >= 2 ? (
|
|
|
+ <>
|
|
|
+ 按住鼠标可拖动图片调整顺序。
|
|
|
+ <br />
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
+ 支持png、jpg、gif和jpeg的图片格式;最大支持20M;最多支持30张。
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* -----------音频上传 */}
|
|
|
+ <div
|
|
|
+ className="myformBox myformBox2"
|
|
|
+ hidden={!typeCheck.includes("audio")}
|
|
|
+ >
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 音频:
|
|
|
+ </div>
|
|
|
+ {fileList.audio.id ? (
|
|
|
+ <div className="fileInfo">
|
|
|
+ {fileList.audio.fileName}
|
|
|
+ {/* 音频预览 */}
|
|
|
+ <div
|
|
|
+ className="clearCover"
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: "layout/lookDom",
|
|
|
+ payload: { src: fileList.audio.filePath!, type: "audio" },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <EyeOutlined />
|
|
|
+ </div>
|
|
|
+ {/* 音频下载 */}
|
|
|
+ <a
|
|
|
+ href={baseURL + fileList.audio.filePath}
|
|
|
+ download
|
|
|
+ target="_blank"
|
|
|
+ className="clearCover"
|
|
|
+ rel="noreferrer"
|
|
|
+ >
|
|
|
+ <DownloadOutlined />
|
|
|
+ </a>
|
|
|
+ {/* 音频删除 */}
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => setFileList({ ...fileList, audio: {} })}
|
|
|
+ >
|
|
|
+ <div className="clearCover">
|
|
|
+ <CloseOutlined />
|
|
|
+ </div>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <Button
|
|
|
+ onClick={() => upFileFu("audio")}
|
|
|
+ icon={<UploadOutlined />}
|
|
|
+ >
|
|
|
+ 上传
|
|
|
+ </Button>
|
|
|
+
|
|
|
+ <div className="fileTit">
|
|
|
+ 仅支持MP3格式的音频文件,大小不得超过10MB。
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* -----------视频上传 */}
|
|
|
+ <div
|
|
|
+ className="myformBox myformBox2"
|
|
|
+ hidden={!typeCheck.includes("video")}
|
|
|
+ >
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 视频:
|
|
|
+ </div>
|
|
|
+ {fileList.video.id ? (
|
|
|
+ <div className="fileInfo">
|
|
|
+ <div className="upSuccTxt">{fileList.video.fileName}</div>
|
|
|
+ {/* 视频预览 */}
|
|
|
+ <div
|
|
|
+ className="clearCover"
|
|
|
+ hidden={!fileList.video.filePath}
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: "layout/lookDom",
|
|
|
+ payload: { src: fileList.video.filePath!, type: "video" },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <EyeOutlined />
|
|
|
+ </div>
|
|
|
+ {/* 视频下载 */}
|
|
|
+ <a
|
|
|
+ href={baseURL + fileList.video.filePath}
|
|
|
+ download
|
|
|
+ target="_blank"
|
|
|
+ className="clearCover"
|
|
|
+ rel="noreferrer"
|
|
|
+ >
|
|
|
+ <DownloadOutlined />
|
|
|
+ </a>
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => setFileList({ ...fileList, video: {} })}
|
|
|
+ >
|
|
|
+ <div className="clearCover">
|
|
|
+ <CloseOutlined />
|
|
|
+ </div>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <Button
|
|
|
+ onClick={() => upFileFu("video")}
|
|
|
+ icon={<UploadOutlined />}
|
|
|
+ >
|
|
|
+ 上传
|
|
|
+ </Button>
|
|
|
+
|
|
|
+ <div className="fileTit">
|
|
|
+ 仅支持MP4格式的视频文件,大小不得超过500MB。
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ className={classNames(
|
|
|
+ "noUpThumb noUpThumb2",
|
|
|
+ fileCheckFu && typeOk ? "noUpThumbAc" : ""
|
|
|
+ )}
|
|
|
+ >
|
|
|
+ 请至少选择一个文件类型,并上传对应附件!
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 确定和取消按钮 */}
|
|
|
+ <br />
|
|
|
+ <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
|
|
|
+ <Button type="primary" htmlType="submit">
|
|
|
+ 提交
|
|
|
+ </Button>
|
|
|
+  
|
|
|
+ <Popconfirm
|
|
|
+ title="放弃编辑后,信息将不会保存!"
|
|
|
+ okText="放弃"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={closeMoalFu}
|
|
|
+ >
|
|
|
+ <Button>取消</Button>
|
|
|
+ </Popconfirm>
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const MemoGoodsAdd = React.memo(GoodsAdd);
|
|
|
+
|
|
|
+export default MemoGoodsAdd;
|