index.tsx 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891
  1. import { RootState } from "@/store";
  2. import {
  3. Button,
  4. Checkbox,
  5. Form,
  6. Input,
  7. Popconfirm,
  8. Radio,
  9. Select,
  10. Switch,
  11. } from "antd";
  12. import React, {
  13. useCallback,
  14. useEffect,
  15. useMemo,
  16. useRef,
  17. useState,
  18. } from "react";
  19. import { useDispatch, useSelector } from "react-redux";
  20. import TextArea from "antd/es/input/TextArea";
  21. import styles from "./index.module.scss";
  22. import { MessageFu } from "@/utils/message";
  23. import ImageLazy from "@/components/ImageLazy";
  24. import classNames from "classnames";
  25. import {
  26. PlusOutlined,
  27. CloseCircleOutlined,
  28. UploadOutlined,
  29. CloseOutlined,
  30. PlayCircleOutlined,
  31. } from "@ant-design/icons";
  32. import {
  33. getGoodsInfoByIdAPI,
  34. getGoodsSaveAPI,
  35. goodsUploadAPI,
  36. setGoodsImgBoderAPI,
  37. } from "@/store/action/B2Goods";
  38. import { baseURL } from "@/utils/http";
  39. import { FileListType, GoodsTableType } from "@/types";
  40. type Props = {
  41. id: number;
  42. closeMoalFu: () => void;
  43. addListFu: () => void;
  44. editListFu: () => void;
  45. };
  46. // 上传附件的进度条
  47. const UpAsyncLodingDom: any = document.querySelector("#UpAsyncLoding");
  48. const progressDom: any = document.querySelector("#progress");
  49. function GoodsAdd({ id, closeMoalFu, addListFu, editListFu }: Props) {
  50. const dispatch = useDispatch();
  51. // 后面添加的的知识驿站
  52. const [valueZS1, setValueZS1] = useState("");
  53. const [valueZS2, setValueZS2] = useState<any>([]);
  54. // 上传附件的信息
  55. const [fileList, setFileList] = useState({
  56. model: {} as FileListType,
  57. img: [] as FileListType[],
  58. audio: {} as FileListType,
  59. video: {} as FileListType,
  60. });
  61. // 表单的ref
  62. const FormBoxRef = useRef<any>({});
  63. // 文件的dirCode码
  64. const [dirCode, setDirCode] = useState("");
  65. const getInfoInAPIFu = useCallback(async (id: number) => {
  66. const res = await getGoodsInfoByIdAPI(id);
  67. FormBoxRef.current.setFieldsValue(res.data.entity);
  68. setCover(res.data.entity.thumb);
  69. if (res.data.entity.type) setTypeCheck(res.data.entity.type.split(","));
  70. setValueZS1(res.data.entity.tagType);
  71. if (res.data.entity.tagCountry)
  72. setValueZS2(res.data.entity.tagCountry.split(","));
  73. const data: FileListType[] = res.data.file;
  74. const obj = {
  75. model: {} as FileListType,
  76. img: [] as FileListType[],
  77. audio: {} as FileListType,
  78. video: {} as FileListType,
  79. };
  80. data.forEach((v) => {
  81. if (v.type === "img") obj.img.push(v);
  82. else obj[v.type!] = v;
  83. });
  84. setFileList(obj);
  85. setDirCode(res.data.entity.dirCode);
  86. }, []);
  87. useEffect(() => {
  88. if (id > 0) getInfoInAPIFu(id);
  89. else {
  90. setDirCode(Date.now() + "");
  91. FormBoxRef.current.setFieldsValue({
  92. topic: "不展示",
  93. display: 1,
  94. isBarrage: 0,
  95. });
  96. }
  97. }, [getInfoInAPIFu, id]);
  98. // 从仓库获取下拉列表数据
  99. const dictList = useSelector((state: RootState) => state.loginStore.dictList);
  100. // 上传封面图的ref
  101. const [coverCheck, setCoverCheck] = useState(false);
  102. const [cover, setCover] = useState("");
  103. const myInput = useRef<HTMLInputElement>(null);
  104. // 上传封面图
  105. const handeUpPhoto = useCallback(
  106. async (e: React.ChangeEvent<HTMLInputElement>) => {
  107. if (e.target.files) {
  108. // 拿到files信息
  109. const filesInfo = e.target.files[0];
  110. // 校验格式
  111. const type = ["image/jpeg", "image/png"];
  112. if (!type.includes(filesInfo.type)) {
  113. e.target.value = "";
  114. return MessageFu.warning("只支持jpg、png格式!");
  115. }
  116. // 校验大小
  117. if (filesInfo.size > 20 * 1024 * 1024) {
  118. e.target.value = "";
  119. return MessageFu.warning("最大支持20M!");
  120. }
  121. // 创建FormData对象
  122. const fd = new FormData();
  123. // 把files添加进FormData对象(‘photo’为后端需要的字段)
  124. fd.append("type", "thumb");
  125. fd.append("dirCode", dirCode);
  126. fd.append("file", filesInfo);
  127. e.target.value = "";
  128. const res: any = await goodsUploadAPI(fd);
  129. if (res.code === 0) {
  130. MessageFu.success("上传成功!");
  131. setCover(res.data.filePath);
  132. }
  133. UpAsyncLodingDom.style.opacity = 0;
  134. progressDom.style.width = "0%";
  135. }
  136. },
  137. [dirCode]
  138. );
  139. // 选中附件类型
  140. const [typeCheck, setTypeCheck] = useState<any>([]);
  141. const [typeOk, setTypeOk] = useState(false);
  142. const typeCheckArr = useMemo(() => {
  143. return [
  144. { label: "模型", value: "model" },
  145. { label: "图片", value: "img" },
  146. { label: "音频", value: "audio" },
  147. { label: "视频", value: "video" },
  148. ];
  149. }, []);
  150. // 上传附件图片的有无边框的选择
  151. const upImgDoneFu = useCallback(
  152. async (val: boolean, id: number) => {
  153. const res = await setGoodsImgBoderAPI(id, val ? 1 : 0);
  154. if (res.code === 0) {
  155. const newData = {
  156. ...fileList,
  157. img: fileList.img.map((v) => {
  158. return {
  159. ...v,
  160. isFrame: v.id === id ? val : v.isFrame,
  161. };
  162. }),
  163. };
  164. setFileList(newData);
  165. }
  166. },
  167. [fileList]
  168. );
  169. // 附件信息的校验
  170. const fileCheckFu = useMemo(() => {
  171. let flag = false;
  172. if (typeCheck.length === 0) flag = true;
  173. if (typeCheck.includes("model") && !fileList.model.id) flag = true;
  174. if (typeCheck.includes("img") && fileList.img.length === 0) flag = true;
  175. if (typeCheck.includes("audio") && !fileList.audio.id) flag = true;
  176. if (typeCheck.includes("video") && !fileList.video.id) flag = true;
  177. return flag;
  178. }, [fileList, typeCheck]);
  179. // 点击上传附件按钮
  180. const myInput2 = useRef<HTMLInputElement>(null);
  181. const [fileOneType, setFileOneType] = useState("");
  182. useEffect(() => {
  183. if (fileOneType) myInput2.current?.click();
  184. }, [fileOneType]);
  185. const upFileFu = useCallback((type: string) => {
  186. setFileOneType("");
  187. window.setTimeout(() => {
  188. setFileOneType(type);
  189. }, 100);
  190. }, []);
  191. // 上传附件的处理函数
  192. const handeUpPhoto2 = useCallback(
  193. async (e: React.ChangeEvent<HTMLInputElement>) => {
  194. if (e.target.files) {
  195. // 拿到files信息
  196. const filesInfo = e.target.files[0];
  197. let anType = ["image/jpeg", "image/png", "image/gif"];
  198. let anTit1 = "只支持png、jpg、gif和jpeg格式!";
  199. let anTit2 = "最大支持20M!";
  200. let anSize = 20 * 1024 * 1024;
  201. if (fileOneType === "audio") {
  202. anType = ["audio/mpeg"];
  203. anTit1 = "只支持mp3格式!";
  204. anTit2 = "最大支持10M!";
  205. anSize = 10 * 1024 * 1024;
  206. } else if (fileOneType === "video") {
  207. anType = ["video/mp4"];
  208. anTit1 = "只支持mp4格式!";
  209. anTit2 = "最大支持500M!";
  210. anSize = 500 * 1024 * 1024;
  211. } else if (fileOneType === "model") {
  212. anType = [""];
  213. anTit1 = "只支持4dage格式!";
  214. anTit2 = "最大支持500M!";
  215. anSize = 500 * 1024 * 1024;
  216. }
  217. // 校验格式
  218. if (fileOneType !== "model") {
  219. if (!anType.includes(filesInfo.type)) {
  220. e.target.value = "";
  221. return MessageFu.warning(anTit1);
  222. }
  223. } else {
  224. if (!filesInfo.name.includes(".4dage")) {
  225. e.target.value = "";
  226. return MessageFu.warning(anTit1);
  227. }
  228. }
  229. // 校验大小
  230. if (filesInfo.size > anSize) {
  231. e.target.value = "";
  232. return MessageFu.warning(anTit2);
  233. }
  234. // 创建FormData对象
  235. const fd = new FormData();
  236. // 把files添加进FormData对象(‘photo’为后端需要的字段)
  237. fd.append("type", fileOneType);
  238. fd.append("dirCode", dirCode);
  239. fd.append("file", filesInfo);
  240. e.target.value = "";
  241. const res: any = await goodsUploadAPI(fd);
  242. if (res.code === 0) {
  243. MessageFu.success("上传成功!");
  244. if (fileOneType === "img")
  245. setFileList({ ...fileList, img: [res.data, ...fileList.img] });
  246. else setFileList({ ...fileList, [fileOneType]: res.data });
  247. }
  248. UpAsyncLodingDom.style.opacity = 0;
  249. progressDom.style.width = "0%";
  250. }
  251. },
  252. [dirCode, fileList, fileOneType]
  253. );
  254. // 附件图片的拖动
  255. const [dragImg, setDragImg] = useState<any>(null);
  256. const handleDragOver = useCallback(
  257. (e: React.DragEvent<HTMLDivElement>, item: FileListType) => {
  258. e.dataTransfer.dropEffect = "move";
  259. },
  260. []
  261. );
  262. const handleDragEnter = useCallback(
  263. (e: React.DragEvent<HTMLDivElement>, item: FileListType) => {
  264. e.dataTransfer.effectAllowed = "move";
  265. if (item === dragImg) return;
  266. const newItems = [...fileList.img]; //拷贝一份数据进行交换操作。
  267. const src = newItems.indexOf(dragImg); //获取数组下标
  268. const dst = newItems.indexOf(item);
  269. newItems.splice(dst, 0, ...newItems.splice(src, 1)); //交换位置
  270. setFileList({ ...fileList, img: newItems });
  271. },
  272. [dragImg, fileList]
  273. );
  274. // 删除某一张图片
  275. const delImgListFu = useCallback(
  276. (id: number) => {
  277. const newItems = fileList.img.filter((v) => v.id !== id);
  278. setFileList({ ...fileList, img: newItems });
  279. },
  280. [fileList]
  281. );
  282. // 没有通过校验
  283. const onFinishFailed = useCallback(() => {
  284. setCoverCheck(true);
  285. setTypeOk(true);
  286. return MessageFu.warning("有表单不符号规则!");
  287. }, []);
  288. // 通过校验点击确定
  289. const onFinish = useCallback(
  290. async (value: GoodsTableType) => {
  291. console.log("通过校验,点击确定");
  292. setCoverCheck(true);
  293. setTypeOk(true);
  294. if (typeCheck.length === 0 || cover === "" || fileCheckFu)
  295. return MessageFu.warning("有表单不符号规则!");
  296. const fileIds = [];
  297. if (fileList.model.id && typeCheck.includes("model"))
  298. fileIds.push(fileList.model.id);
  299. if (fileList.audio.id && typeCheck.includes("audio"))
  300. fileIds.push(fileList.audio.id);
  301. if (fileList.video.id && typeCheck.includes("video"))
  302. fileIds.push(fileList.video.id);
  303. if (typeCheck.includes("img")) {
  304. fileList.img.forEach((v) => {
  305. if (v.id) fileIds.push(v.id);
  306. });
  307. }
  308. const obj = {
  309. ...value,
  310. id: id > 0 ? id : null,
  311. dirCode,
  312. fileIds: fileIds.join(","),
  313. thumb: cover,
  314. type: typeCheck.join(","),
  315. tagType: valueZS1,
  316. tagCountry: valueZS2.join(","),
  317. } as GoodsTableType;
  318. const res = await getGoodsSaveAPI(obj);
  319. if (res.code === 0) {
  320. MessageFu.success(id > 0 ? "编辑成功!" : "新增成功!");
  321. closeMoalFu();
  322. if (id > 0) editListFu();
  323. else addListFu();
  324. }
  325. },
  326. [
  327. typeCheck,
  328. cover,
  329. fileCheckFu,
  330. fileList.model.id,
  331. fileList.audio.id,
  332. fileList.video.id,
  333. fileList.img,
  334. id,
  335. dirCode,
  336. valueZS1,
  337. valueZS2,
  338. closeMoalFu,
  339. editListFu,
  340. addListFu,
  341. ]
  342. );
  343. return (
  344. <div className={styles.GoodsAdd}>
  345. <div className="main">
  346. <Form
  347. ref={FormBoxRef}
  348. name="basic"
  349. labelCol={{ span: 3 }}
  350. onFinish={onFinish}
  351. onFinishFailed={onFinishFailed}
  352. autoComplete="off"
  353. >
  354. <Form.Item
  355. label="名称"
  356. name="name"
  357. rules={[{ required: true, message: "请输入名称!" }]}
  358. getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
  359. >
  360. <Input maxLength={25} showCount placeholder="请输入内容" />
  361. </Form.Item>
  362. <Form.Item
  363. label="登记编号"
  364. name="num"
  365. getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
  366. >
  367. <Input maxLength={25} showCount placeholder="请输入内容" />
  368. </Form.Item>
  369. <Form.Item
  370. label="类别"
  371. name="dictTexture"
  372. rules={[{ required: true, message: "请选择类别!" }]}
  373. >
  374. <Select
  375. placeholder="请选择"
  376. style={{ width: 400 }}
  377. options={dictList["texture"].slice(1)}
  378. />
  379. </Form.Item>
  380. <Form.Item
  381. label="年代"
  382. name="dictAge"
  383. rules={[{ required: true, message: "请选择年代!" }]}
  384. >
  385. <Select
  386. placeholder="请选择"
  387. style={{ width: 400 }}
  388. options={dictList["age"].slice(1)}
  389. />
  390. </Form.Item>
  391. <Form.Item
  392. label="级别"
  393. name="dictLevel"
  394. rules={[{ required: true, message: "请选择级别!" }]}
  395. >
  396. <Select
  397. placeholder="请选择"
  398. style={{ width: 400 }}
  399. options={dictList["level"].slice(1)}
  400. />
  401. </Form.Item>
  402. <Form.Item
  403. label="来源"
  404. name="dictSource"
  405. rules={[{ required: true, message: "请选择来源!" }]}
  406. >
  407. <Select
  408. placeholder="请选择"
  409. style={{ width: 400 }}
  410. options={dictList["source"].slice(1)}
  411. />
  412. </Form.Item>
  413. <Form.Item
  414. label="万物墙主题"
  415. name="topic"
  416. rules={[{ required: true, message: "请选择万物墙主题!" }]}
  417. >
  418. <Select
  419. placeholder="请选择"
  420. style={{ width: 400 }}
  421. options={[
  422. { value: "战争", label: "战争" },
  423. { value: "生活", label: "生活" },
  424. { value: "不展示", label: "不展示" },
  425. ]}
  426. />
  427. </Form.Item>
  428. <Form.Item
  429. label="简介"
  430. name="description"
  431. getValueFromEvent={(e) => e.target.value.trim()}
  432. >
  433. <TextArea
  434. rows={4}
  435. placeholder="请输入内容"
  436. showCount
  437. maxLength={200}
  438. />
  439. </Form.Item>
  440. {/* -----上传封面图片 */}
  441. <div className="myformBox myformBox0">
  442. <input
  443. id="upInput"
  444. type="file"
  445. accept=".png,.jpg,.jpeg"
  446. ref={myInput}
  447. onChange={(e) => handeUpPhoto(e)}
  448. />
  449. <input
  450. id="upInput2"
  451. type="file"
  452. accept={
  453. fileOneType === "img"
  454. ? ".gif,.png,.jpg,.jpeg"
  455. : fileOneType === "audio"
  456. ? ".mp3"
  457. : fileOneType === "model"
  458. ? ".4dage"
  459. : ".mp4"
  460. }
  461. ref={myInput2}
  462. onChange={(e) => handeUpPhoto2(e)}
  463. />
  464. <div className="label">
  465. <span>*</span> 封面图:
  466. </div>
  467. <div className="fileBoxRow_r">
  468. <div
  469. hidden={cover !== ""}
  470. className="fileBoxRow_up"
  471. onClick={() => myInput.current?.click()}
  472. >
  473. <PlusOutlined />
  474. </div>
  475. <div className="fileBoxRow_r_img" hidden={cover === ""}>
  476. {cover ? (
  477. <ImageLazy width={100} height={100} src={cover} />
  478. ) : null}
  479. <Popconfirm
  480. title="删除后无法恢复,是否删除?"
  481. okText="删除"
  482. cancelText="取消"
  483. onConfirm={() => setCover("")}
  484. >
  485. <div className="clearCover">
  486. <CloseCircleOutlined />
  487. </div>
  488. </Popconfirm>
  489. </div>
  490. <div className="fileBoxRow_r_tit">
  491. 支持png、jpg和jpeg的图片格式;最大支持20M。
  492. <br />
  493. <div
  494. className={classNames(
  495. "noUpThumb",
  496. !cover && coverCheck ? "noUpThumbAc" : ""
  497. )}
  498. >
  499. 请上传封面图!
  500. </div>
  501. </div>
  502. </div>
  503. </div>
  504. {/* 选中文件类型和上传附件 */}
  505. <div className="myformBox">
  506. <div className="label">
  507. <span>*</span> 文件类型:
  508. </div>
  509. <div className="myformBoxR">
  510. <Checkbox.Group
  511. options={typeCheckArr}
  512. value={typeCheck}
  513. onChange={(e) => setTypeCheck(e)}
  514. // onChange={(e) => console.log(e)}
  515. />
  516. </div>
  517. </div>
  518. {/* -----------模型上传 */}
  519. <div
  520. className="myformBox myformBox2"
  521. hidden={!typeCheck.includes("model")}
  522. >
  523. <div className="label">
  524. <span>*</span> 模型:
  525. </div>
  526. {fileList.model.id ? (
  527. <div className="fileInfo">
  528. <a
  529. href={baseURL + fileList.model.filePath}
  530. download
  531. target="_blank"
  532. className="upSuccTxt"
  533. rel="noreferrer"
  534. >
  535. {fileList.model.fileName}
  536. </a>
  537. <Popconfirm
  538. title="删除后无法恢复,是否删除?"
  539. okText="删除"
  540. cancelText="取消"
  541. onConfirm={() => setFileList({ ...fileList, model: {} })}
  542. >
  543. <div className="clearCover">
  544. <CloseCircleOutlined />
  545. </div>
  546. </Popconfirm>
  547. </div>
  548. ) : (
  549. <>
  550. <Button
  551. onClick={() => upFileFu("model")}
  552. icon={<UploadOutlined />}
  553. >
  554. 上传
  555. </Button>
  556. <div className="fileTit">
  557. 仅支持4dage格式的模型文件,大小不能超过500M。
  558. </div>
  559. </>
  560. )}
  561. </div>
  562. {/* -----------图片上传 */}
  563. <div
  564. className="myformBox myformBox3"
  565. hidden={!typeCheck.includes("img")}
  566. >
  567. <div className="label">
  568. <span>*</span> 图片:
  569. </div>
  570. <>
  571. <div className="fileBoxRow_r">
  572. <div className="upImgBox">
  573. <div
  574. hidden={!!fileList.img.length && fileList.img.length >= 30}
  575. className="fileBoxRow_up"
  576. onClick={() => upFileFu("img")}
  577. >
  578. <PlusOutlined />
  579. </div>
  580. {fileList.img.map((v) => (
  581. <div
  582. className="fileBoxRow_r_img"
  583. key={v.id}
  584. draggable="true"
  585. onDragStart={() => setDragImg(v)}
  586. onDragOver={(e) => handleDragOver(e, v)}
  587. onDragEnter={(e) => handleDragEnter(e, v)}
  588. onDragEnd={() => setDragImg(null)}
  589. >
  590. {/* 选择有没有边框 */}
  591. <div className="upImgDoneBox">
  592. 边框:
  593. <Switch
  594. checkedChildren="有"
  595. unCheckedChildren="无"
  596. checked={v.isFrame}
  597. onChange={(val) => upImgDoneFu(val, v.id!)}
  598. />
  599. </div>
  600. {v.filePath ? (
  601. <ImageLazy
  602. noLook={dragImg ? true : false}
  603. width={100}
  604. height={100}
  605. src={v.filePath}
  606. />
  607. ) : null}
  608. <Popconfirm
  609. title="删除后无法恢复,是否删除?"
  610. okText="删除"
  611. cancelText="取消"
  612. onConfirm={() => delImgListFu(v.id!)}
  613. >
  614. <div className="clearCover">
  615. <CloseOutlined />
  616. </div>
  617. </Popconfirm>
  618. </div>
  619. ))}
  620. </div>
  621. <div className="fileTit">
  622. {fileList.img.length && fileList.img.length >= 2 ? (
  623. <>
  624. 按住鼠标可拖动图片调整顺序。
  625. <br />
  626. </>
  627. ) : null}
  628. 支持png、jpg、gif和jpeg的图片格式;最大支持20M;最多支持30张。
  629. </div>
  630. </div>
  631. </>
  632. </div>
  633. {/* -----------音频上传 */}
  634. <div
  635. className="myformBox myformBox2"
  636. hidden={!typeCheck.includes("audio")}
  637. >
  638. <div className="label">
  639. <span>*</span> 音频:
  640. </div>
  641. {fileList.audio.id ? (
  642. <div className="fileInfo">
  643. <a
  644. href={baseURL + fileList.audio.filePath}
  645. download
  646. target="_blank"
  647. className="upSuccTxt"
  648. rel="noreferrer"
  649. >
  650. {fileList.audio.fileName}
  651. </a>
  652. <Popconfirm
  653. title="删除后无法恢复,是否删除?"
  654. okText="删除"
  655. cancelText="取消"
  656. onConfirm={() => setFileList({ ...fileList, audio: {} })}
  657. >
  658. <div className="clearCover">
  659. <CloseCircleOutlined />
  660. </div>
  661. </Popconfirm>
  662. </div>
  663. ) : (
  664. <>
  665. <Button
  666. onClick={() => upFileFu("audio")}
  667. icon={<UploadOutlined />}
  668. >
  669. 上传
  670. </Button>
  671. <div className="fileTit">
  672. 仅支持MP3格式的音频文件,大小不得超过10MB。
  673. </div>
  674. </>
  675. )}
  676. </div>
  677. {/* -----------视频上传 */}
  678. <div
  679. className="myformBox myformBox2"
  680. hidden={!typeCheck.includes("video")}
  681. >
  682. <div className="label">
  683. <span>*</span> 视频:
  684. </div>
  685. {fileList.video.id ? (
  686. <div className="fileInfo">
  687. <div className="upSuccTxt">{fileList.video.fileName}</div>
  688. <div
  689. className="clearCover"
  690. hidden={!fileList.video.filePath}
  691. onClick={() =>
  692. dispatch({
  693. type: "login/lookVideo",
  694. payload: fileList.video.filePath,
  695. })
  696. }
  697. >
  698. <PlayCircleOutlined />
  699. </div>
  700. <Popconfirm
  701. title="删除后无法恢复,是否删除?"
  702. okText="删除"
  703. cancelText="取消"
  704. onConfirm={() => setFileList({ ...fileList, video: {} })}
  705. >
  706. <div className="clearCover">
  707. <CloseCircleOutlined />
  708. </div>
  709. </Popconfirm>
  710. </div>
  711. ) : (
  712. <>
  713. <Button
  714. onClick={() => upFileFu("video")}
  715. icon={<UploadOutlined />}
  716. >
  717. 上传
  718. </Button>
  719. <div className="fileTit">
  720. 仅支持MP4格式的视频文件,大小不得超过500MB。
  721. </div>
  722. </>
  723. )}
  724. </div>
  725. <div
  726. className={classNames(
  727. "noUpThumb noUpThumb2",
  728. fileCheckFu && typeOk ? "noUpThumbAc" : ""
  729. )}
  730. >
  731. 请至少选择一个文件类型,并上传对应附件!
  732. </div>
  733. <Form.Item
  734. label="展示状态"
  735. name="display"
  736. rules={[{ required: true, message: "请选择展示状态!" }]}
  737. >
  738. <Select
  739. placeholder="请选择"
  740. style={{ width: 400 }}
  741. options={[
  742. { value: 1, label: "展示" },
  743. { value: 0, label: "不展示" },
  744. ]}
  745. />
  746. </Form.Item>
  747. <Form.Item
  748. label="弹幕留言"
  749. name="isBarrage"
  750. rules={[{ required: true, message: "请选择弹幕留言!" }]}
  751. >
  752. <Select
  753. placeholder="请选择"
  754. style={{ width: 400 }}
  755. options={[
  756. { value: 1, label: "开启" },
  757. { value: 0, label: "关闭" },
  758. ]}
  759. />
  760. </Form.Item>
  761. <div className="myformBox">
  762. <div className="label">知识驿站:</div>
  763. <div className="laseFormRight">
  764. <div className="laseFormRightRow">
  765. <div className="laseFormRightLabel">类别标签:</div>
  766. <Radio.Group
  767. onChange={(e) => setValueZS1(e.target.value)}
  768. value={valueZS1}
  769. >
  770. <Radio value={"军事"}>军事</Radio>
  771. <Radio value={"历史"}>历史</Radio>
  772. <Radio value={"人物"}>人物</Radio>
  773. <Radio value={"科学"}>科学</Radio>
  774. <Radio value={"教育"}>教育</Radio>
  775. <Radio value={"经济"}>经济</Radio>
  776. </Radio.Group>
  777. </div>
  778. <div className="laseFormRightTit">
  779. 如需文物关联知识驿站,请至少标注类别标签
  780. </div>
  781. <br />
  782. <div className="laseFormRightRow">
  783. <div className="laseFormRightLabel">国家标签:</div>
  784. <Checkbox.Group
  785. value={valueZS2}
  786. onChange={(e) => setValueZS2(e)}
  787. options={[
  788. { label: "清朝", value: "清朝", disabled: !valueZS1 },
  789. { label: "美国", value: "美国", disabled: !valueZS1 },
  790. { label: "西方", value: "西方", disabled: !valueZS1 },
  791. ]}
  792. />
  793. </div>
  794. </div>
  795. </div>
  796. {/* 确定和取消按钮 */}
  797. <br />
  798. <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
  799. <Button type="primary" htmlType="submit">
  800. 提交
  801. </Button>
  802. &emsp;
  803. <Popconfirm
  804. title="放弃编辑后,信息将不会保存!"
  805. okText="放弃"
  806. cancelText="取消"
  807. onConfirm={closeMoalFu}
  808. >
  809. <Button>取消</Button>
  810. </Popconfirm>
  811. </Form.Item>
  812. </Form>
  813. </div>
  814. </div>
  815. );
  816. }
  817. const MemoGoodsAdd = React.memo(GoodsAdd);
  818. export default MemoGoodsAdd;