|
|
@@ -0,0 +1,479 @@
|
|
|
+import { newsUploadAPI } from "@/store/action/A2News";
|
|
|
+import { domShowFu, progressDomFu } from "@/utils/domShow";
|
|
|
+import { MessageFu } from "@/utils/message";
|
|
|
+import { Button, DatePicker, Form, Input, Popconfirm, Select } from "antd";
|
|
|
+import TextArea from "antd/es/input/TextArea";
|
|
|
+import dayjs from "dayjs";
|
|
|
+import React, {
|
|
|
+ useCallback,
|
|
|
+ useEffect,
|
|
|
+ useMemo,
|
|
|
+ useRef,
|
|
|
+ useState,
|
|
|
+} from "react";
|
|
|
+import styles from "./index.module.scss";
|
|
|
+import {
|
|
|
+ PlusOutlined,
|
|
|
+ CloseOutlined,
|
|
|
+ PlayCircleOutlined,
|
|
|
+ CloseCircleOutlined,
|
|
|
+ UploadOutlined,
|
|
|
+} from "@ant-design/icons";
|
|
|
+import ImageLazy from "@/components/ImageLazy";
|
|
|
+import classNames from "classnames";
|
|
|
+import store from "@/store";
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ id: number;
|
|
|
+ tableType: string;
|
|
|
+ closePageFu: () => void;
|
|
|
+ editTableFu: () => void;
|
|
|
+ addTableFu: () => void;
|
|
|
+};
|
|
|
+
|
|
|
+type ImgListType = {
|
|
|
+ fileName: string;
|
|
|
+ filePath: string;
|
|
|
+ id: number;
|
|
|
+};
|
|
|
+
|
|
|
+function NewsAdd({
|
|
|
+ id,
|
|
|
+ closePageFu,
|
|
|
+ editTableFu,
|
|
|
+ addTableFu,
|
|
|
+ tableType,
|
|
|
+}: Props) {
|
|
|
+ // 设置表单初始数据(区分编辑和新增)
|
|
|
+ const FormBoxRef = useRef<any>({});
|
|
|
+
|
|
|
+ // 通过id获取详情,回显数据
|
|
|
+ const getInfoFu = useCallback((id: number) => {
|
|
|
+ // setDirCode(res.data.entity.dirCode);
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (id > 0) getInfoFu(id);
|
|
|
+ else {
|
|
|
+ setDirCode(Date.now() + "");
|
|
|
+ FormBoxRef.current.setFieldsValue({
|
|
|
+ display: 1,
|
|
|
+ // 默认新闻日期为当天
|
|
|
+ myTime:
|
|
|
+ tableType === "news"
|
|
|
+ ? dayjs(dayjs(new Date()).format("YYYY-MM-DD"), "YYYY-MM-DD")
|
|
|
+ : "",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, [getInfoFu, id, tableType]);
|
|
|
+
|
|
|
+ const myInput = useRef<HTMLInputElement>(null);
|
|
|
+
|
|
|
+ // 文件的dirCode码
|
|
|
+ const [dirCode, setDirCode] = useState("");
|
|
|
+
|
|
|
+ // 多张图片附件
|
|
|
+ const [imgList, setImgList] = useState<ImgListType[]>([]);
|
|
|
+
|
|
|
+ // 单个视频或者图片上传
|
|
|
+ const [fileOne, setFileOne] = useState<ImgListType>({
|
|
|
+ fileName: "",
|
|
|
+ filePath: "",
|
|
|
+ id: 0,
|
|
|
+ });
|
|
|
+
|
|
|
+ // 上传附件的处理函数
|
|
|
+ const handeUpPhoto = useCallback(
|
|
|
+ async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
+ if (e.target.files) {
|
|
|
+ // 拿到files信息
|
|
|
+ const filesInfo = e.target.files[0];
|
|
|
+
|
|
|
+ let anType = ["image/jpeg", "image/png"];
|
|
|
+ let anTit1 = "只支持png、jpg和jpeg格式!";
|
|
|
+ let anTit2 = "最大支持20M!";
|
|
|
+ let anSize = 20 * 1024 * 1024;
|
|
|
+
|
|
|
+ if (tableType === "video") {
|
|
|
+ anType = ["video/mp4"];
|
|
|
+ anTit1 = "只支持mp4格式!";
|
|
|
+ anTit2 = "最大支持500M!";
|
|
|
+ anSize = 500 * 1024 * 1024;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验格式
|
|
|
+ if (!anType.includes(filesInfo.type)) {
|
|
|
+ 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", tableType === "video" ? "video" : "img");
|
|
|
+ fd.append("dirCode", dirCode);
|
|
|
+ fd.append("file", filesInfo);
|
|
|
+
|
|
|
+ e.target.value = "";
|
|
|
+
|
|
|
+ const res: any = await newsUploadAPI(fd);
|
|
|
+
|
|
|
+ if (res.code === 0) {
|
|
|
+ MessageFu.success("上传成功!");
|
|
|
+ if (tableType === "news") setImgList([...imgList, res.data]);
|
|
|
+ else setFileOne(res.data);
|
|
|
+ }
|
|
|
+ domShowFu("#UpAsyncLoding", false);
|
|
|
+ progressDomFu("0%");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [dirCode, imgList, tableType]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 附件图片的拖动
|
|
|
+ const [dragImg, setDragImg] = useState<any>(null);
|
|
|
+
|
|
|
+ const handleDragOver = useCallback(
|
|
|
+ (e: React.DragEvent<HTMLDivElement>, item: ImgListType) => {
|
|
|
+ e.dataTransfer.dropEffect = "move";
|
|
|
+ },
|
|
|
+ []
|
|
|
+ );
|
|
|
+
|
|
|
+ const handleDragEnter = useCallback(
|
|
|
+ (e: React.DragEvent<HTMLDivElement>, item: ImgListType) => {
|
|
|
+ e.dataTransfer.effectAllowed = "move";
|
|
|
+ if (item === dragImg) return;
|
|
|
+ const newItems = [...imgList]; //拷贝一份数据进行交换操作。
|
|
|
+ const src = newItems.indexOf(dragImg); //获取数组下标
|
|
|
+ const dst = newItems.indexOf(item);
|
|
|
+ newItems.splice(dst, 0, ...newItems.splice(src, 1)); //交换位置
|
|
|
+ setImgList(newItems);
|
|
|
+ },
|
|
|
+ [dragImg, imgList]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 删除某一张图片
|
|
|
+ const delImgListFu = useCallback(
|
|
|
+ (id: number) => {
|
|
|
+ const newItems = imgList.filter((v) => v.id !== id);
|
|
|
+ setImgList(newItems);
|
|
|
+ },
|
|
|
+ [imgList]
|
|
|
+ );
|
|
|
+
|
|
|
+ const [typeOk, setTypeOk] = useState(false);
|
|
|
+
|
|
|
+ // 附件信息的校验
|
|
|
+ const fileCheckFu = useMemo(() => {
|
|
|
+ let flag = false;
|
|
|
+ if (tableType === "news" && imgList.length === 0) flag = true;
|
|
|
+ if (tableType !== "news" && !fileOne.filePath) flag = true;
|
|
|
+ return flag;
|
|
|
+ }, [fileOne.filePath, imgList.length, tableType]);
|
|
|
+
|
|
|
+ // 没有通过校验
|
|
|
+ const onFinishFailed = useCallback(() => {
|
|
|
+ setTypeOk(true);
|
|
|
+ // return MessageFu.warning("有表单不符号规则!");
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 通过校验点击确定
|
|
|
+ const onFinish = useCallback(
|
|
|
+ (values: any) => {
|
|
|
+ setTypeOk(true);
|
|
|
+
|
|
|
+ if (fileCheckFu) return;
|
|
|
+
|
|
|
+ const obj = {
|
|
|
+ ...values,
|
|
|
+ id: id > 0 ? id : null,
|
|
|
+ dirCode,
|
|
|
+ myTime: values.myTime ? dayjs(values.myTime).format("YYYY-MM-DD") : "",
|
|
|
+ fileIds:
|
|
|
+ tableType === "news"
|
|
|
+ ? imgList.map((v) => v.id).join(",")
|
|
|
+ : fileOne.id,
|
|
|
+ };
|
|
|
+ console.log(obj);
|
|
|
+ if (id > 0) editTableFu();
|
|
|
+ else addTableFu();
|
|
|
+ closePageFu();
|
|
|
+ },
|
|
|
+ [
|
|
|
+ addTableFu,
|
|
|
+ closePageFu,
|
|
|
+ dirCode,
|
|
|
+ editTableFu,
|
|
|
+ fileCheckFu,
|
|
|
+ fileOne.id,
|
|
|
+ id,
|
|
|
+ imgList,
|
|
|
+ tableType,
|
|
|
+ ]
|
|
|
+ );
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={styles.NewsAdd}>
|
|
|
+ <div className="pageTitle">{id > 0 ? "编辑资讯" : "新增资讯"}</div>
|
|
|
+ <div className="formBox">
|
|
|
+ <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={20} showCount placeholder="请输入内容" />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ <input
|
|
|
+ id="upInput2"
|
|
|
+ type="file"
|
|
|
+ accept={tableType === "video" ? ".mp4" : ".png,.jpg,.jpeg"}
|
|
|
+ ref={myInput}
|
|
|
+ onChange={(e) => handeUpPhoto(e)}
|
|
|
+ />
|
|
|
+
|
|
|
+ {tableType === "news" ? (
|
|
|
+ <>
|
|
|
+ <Form.Item
|
|
|
+ label="新闻日期"
|
|
|
+ name="myTime"
|
|
|
+ rules={[{ required: true, message: "请选择新闻日期!" }]}
|
|
|
+ >
|
|
|
+ <DatePicker />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item
|
|
|
+ label="正文"
|
|
|
+ name="myTxt"
|
|
|
+ rules={[{ required: true, message: "请输入正文!" }]}
|
|
|
+ // getValueFromEvent={(e) => e.target.value.trim()}
|
|
|
+ >
|
|
|
+ <TextArea
|
|
|
+ rows={8}
|
|
|
+ placeholder="请输入内容"
|
|
|
+ showCount
|
|
|
+ maxLength={1000}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ {/* 上传附件图片 */}
|
|
|
+ <div className="myformBox">
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 图片:
|
|
|
+ </div>
|
|
|
+ <>
|
|
|
+ <div className="fileBoxRow_r">
|
|
|
+ <div className="upImgBox">
|
|
|
+ <div
|
|
|
+ hidden={imgList.length >= 9}
|
|
|
+ className="fileBoxRow_up"
|
|
|
+ onClick={() => myInput.current?.click()}
|
|
|
+ >
|
|
|
+ <PlusOutlined />
|
|
|
+ </div>
|
|
|
+ {imgList.map((v) => (
|
|
|
+ <div
|
|
|
+ className="fileBoxRow_r_img"
|
|
|
+ key={v.id}
|
|
|
+ draggable="true"
|
|
|
+ onDragStart={() => setDragImg(v)}
|
|
|
+ onDragOver={(e) => handleDragOver(e, v)}
|
|
|
+ onDragEnter={(e) => handleDragEnter(e, v)}
|
|
|
+ onDragEnd={() => setDragImg(null)}
|
|
|
+ >
|
|
|
+ {v.filePath ? (
|
|
|
+ <ImageLazy
|
|
|
+ noLook={dragImg ? true : false}
|
|
|
+ width={100}
|
|
|
+ height={100}
|
|
|
+ src={v.filePath}
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() => delImgListFu(v.id)}
|
|
|
+ >
|
|
|
+ <div className="clearCover">
|
|
|
+ <CloseOutlined />
|
|
|
+ </div>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ <div className="fileTit">
|
|
|
+ {imgList.length >= 2 ? (
|
|
|
+ <>
|
|
|
+ 按住鼠标可拖动图片调整顺序。
|
|
|
+ <br />
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
+ 支持png、jpg和jpeg的图片格式;最大支持20M;最多支持9张。
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ ) : tableType === "video" ? (
|
|
|
+ // 上传视频
|
|
|
+ <>
|
|
|
+ {/* -----------视频上传 */}
|
|
|
+ <div className="myformBox myformBox2">
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 视频:
|
|
|
+ </div>
|
|
|
+ {fileOne.id ? (
|
|
|
+ <div className="fileInfo">
|
|
|
+ <div className="upSuccTxt">{fileOne.fileName}</div>
|
|
|
+ <div
|
|
|
+ className="clearCover"
|
|
|
+ hidden={!fileOne.filePath}
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: "layout/lookVideo",
|
|
|
+ payload: fileOne.filePath!,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <PlayCircleOutlined />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() =>
|
|
|
+ setFileOne({ fileName: "", filePath: "", id: 0 })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <div className="clearCover">
|
|
|
+ <CloseCircleOutlined />
|
|
|
+ </div>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <Button
|
|
|
+ onClick={() => myInput.current?.click()}
|
|
|
+ icon={<UploadOutlined />}
|
|
|
+ >
|
|
|
+ 上传
|
|
|
+ </Button>
|
|
|
+
|
|
|
+ <div className="fileTit">
|
|
|
+ 仅支持MP4格式的视频文件,大小不得超过500MB。
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ {/* 上传单张图片 */}
|
|
|
+ <div className="myformBox myformBox3">
|
|
|
+ <div className="label">
|
|
|
+ <span>*</span> 图片:
|
|
|
+ </div>
|
|
|
+ <div className="fileBoxRow_r">
|
|
|
+ <div
|
|
|
+ hidden={!!fileOne.filePath}
|
|
|
+ className="fileBoxRow_up"
|
|
|
+ onClick={() => myInput.current?.click()}
|
|
|
+ >
|
|
|
+ <PlusOutlined />
|
|
|
+ </div>
|
|
|
+ <div className="fileBoxRow_r_img" hidden={!fileOne.filePath}>
|
|
|
+ {fileOne.filePath ? (
|
|
|
+ <ImageLazy
|
|
|
+ width={100}
|
|
|
+ height={100}
|
|
|
+ src={fileOne.filePath}
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ <Popconfirm
|
|
|
+ title="删除后无法恢复,是否删除?"
|
|
|
+ okText="删除"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={() =>
|
|
|
+ setFileOne({ fileName: "", filePath: "", id: 0 })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <div className="clearCover">
|
|
|
+ <CloseCircleOutlined />
|
|
|
+ </div>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ <div className="fileBoxRow_r_tit">
|
|
|
+ 支持png、jpg和jpeg的图片格式;最大支持20M。
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <div
|
|
|
+ className={classNames(
|
|
|
+ "noUpThumb noUpThumb2",
|
|
|
+ fileCheckFu && typeOk ? "noUpThumbAc" : ""
|
|
|
+ )}
|
|
|
+ >
|
|
|
+ 请上传附件!
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Form.Item
|
|
|
+ label="展示状态"
|
|
|
+ name="display"
|
|
|
+ rules={[{ required: true, message: "请选择展示状态!" }]}
|
|
|
+ >
|
|
|
+ <Select
|
|
|
+ placeholder="请选择"
|
|
|
+ style={{ width: 400 }}
|
|
|
+ options={[
|
|
|
+ { value: 1, label: "展示" },
|
|
|
+ { value: 0, label: "不展示" },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+
|
|
|
+ {/* 确定和取消按钮 */}
|
|
|
+ <br />
|
|
|
+ <Form.Item wrapperCol={{ offset: 10, span: 16 }}>
|
|
|
+ <Button type="primary" htmlType="submit">
|
|
|
+ 提交
|
|
|
+ </Button>
|
|
|
+  
|
|
|
+ <Popconfirm
|
|
|
+ title="放弃编辑后,信息将不会保存!"
|
|
|
+ okText="放弃"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={closePageFu}
|
|
|
+ >
|
|
|
+ <Button>取消</Button>
|
|
|
+ </Popconfirm>
|
|
|
+ </Form.Item>
|
|
|
+ </Form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const MemoNewsAdd = React.memo(NewsAdd);
|
|
|
+
|
|
|
+export default MemoNewsAdd;
|