123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- import { MessageFu } from "@/utils/message";
- import { Button, Form, Input, Popconfirm, Radio } from "antd";
- import React, { useCallback, useEffect, useRef, useState } from "react";
- import { PlusOutlined, CloseOutlined } from "@ant-design/icons";
- import classNames from "classnames";
- import styles from "./index.module.scss";
- import ImageLazy from "@/components/ImageLazy";
- import { ImgListType, WallSaveAPIType } from "@/types";
- import WallLook from "../WallLook";
- import {
- getWallDetailAPI,
- goodsUploadAPI,
- setWallSave,
- } from "@/store/action/B3Wall";
- type Props = {
- id: number;
- closeMoalFu: (txt:string) => void;
- };
- // 上传附件的进度条
- const UpAsyncLodingDom: any = document.querySelector("#UpAsyncLoding");
- const progressDom: any = document.querySelector("#progress");
- function WallAdd({ id, closeMoalFu }: Props) {
- const getInfoFu = useCallback(async (id: number) => {
- const res = await getWallDetailAPI(id);
- FormBoxRef.current.setFieldsValue({ name: res.data.entity.name });
- setImgNum(res.data.entity.type);
- const imgListRes = res.data.file;
- setImgList(imgListRes);
- imgListRef.current = imgListRes;
- }, []);
- useEffect(() => {
- if (id > 0) getInfoFu(id);
- }, [getInfoFu, id]);
- // 表单的ref
- const FormBoxRef = useRef<any>({});
- // 上传封面图的ref
- const myInput = useRef<HTMLInputElement>(null);
- // 版式的选择
- const [imgNum, setImgNum] = useState<1 | 2 | 4 | 6 | 8>(1);
- // 上传图片的校验
- const [imgCheck, setImgCheck] = useState(false);
- // 上传图片的全部数据(最多8张来进行切割)
- const imgListRef = useRef<ImgListType[]>([]);
- // 在页面展示的图片
- const [imgList, setImgList] = useState<ImgListType[]>([]);
- // 版式的选择改变,切割数组
- useEffect(() => {
- if (imgListRef.current.length) {
- const newData = imgListRef.current.slice(0, imgNum);
- setImgList(newData);
- }
- }, [imgNum]);
- // ---------附件图片的拖动
- 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);
- imgListRef.current = imgListRef.current.filter((v) => v.id !== id);
- },
- [imgList]
- );
- // 没有通过校验
- const onFinishFailed = useCallback(() => {
- setImgCheck(true);
- }, []);
- // 上传封面图
- 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 > 30 * 1024 * 1024) {
- e.target.value = "";
- return MessageFu.warning("最大支持30M!");
- }
- // 创建FormData对象
- const fd = new FormData();
- // 把files添加进FormData对象(‘photo’为后端需要的字段)
- fd.append("type", "img");
- fd.append("file", filesInfo);
- e.target.value = "";
- const res: any = await goodsUploadAPI(fd);
- if (res.code === 0) {
- MessageFu.success("上传成功!");
- setImgList([res.data, ...imgList]);
- imgListRef.current.unshift(res.data);
- }
- UpAsyncLodingDom.style.opacity = 0;
- progressDom.style.width = "0%";
- }
- },
- [imgList]
- );
- // 通过校验点击确定
- const onFinish = useCallback(
- async (value: { name: string }) => {
- console.log("通过校验,点击确定");
- setImgCheck(true);
- if (imgList.length < imgNum) return;
- const obj: WallSaveAPIType = {
- id: id > 0 ? id : null,
- fileIds: imgList.map((v) => v.id).join(","),
- name: value.name,
- type: imgNum,
- };
- const res = await setWallSave(obj);
- if (res.code === 0) {
- MessageFu.success(id > 0 ? "编辑成功!" : "新增成功!");
- closeMoalFu(id>0?'编辑':'新增');
- }
- },
- [closeMoalFu, id, imgList, imgNum]
- );
- // 点击预览效果
- const [lookImg, setLookImg] = useState(false);
- return (
- <div className={styles.WallAdd}>
- <div className="main">
- <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>
- <div className="myformBox">
- <div className="label">
- <span>*</span> 版式:
- </div>
- <div className="myformBoxR">
- <Radio.Group
- onChange={(e) => setImgNum(e.target.value)}
- value={imgNum}
- >
- <Radio value={1}>1</Radio>
- <Radio value={2}>2</Radio>
- <Radio value={4}>4</Radio>
- <Radio value={6}>6</Radio>
- <Radio value={8}>8</Radio>
- </Radio.Group>
- </div>
- </div>
- {/* 图片上传 */}
- <div className="myformBox myformBox0">
- <input
- id="upInput"
- type="file"
- accept=".png,.jpg,.jpeg"
- ref={myInput}
- onChange={(e) => handeUpPhoto(e)}
- />
- <div className="label"></div>
- <div className="myformBoxR">
- <div className="fileBoxRow_r">
- <div className="upImgBox">
- <div
- hidden={imgList.length >= imgNum}
- 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 && imgList.length >= 2 ? (
- <>
- 按住鼠标可拖动图片调整顺序。
- <br />
- </>
- ) : null}
- 建议尺寸:{12960 / imgNum}*1920
- <br />
- 支持png、jpg和jpeg的图片格式;最大支持30M。
- </div>
- </div>
- </div>
- </div>
- {/* 校验提示 */}
- <div
- className={classNames(
- "noUpThumb",
- imgList.length < imgNum && imgCheck ? "noUpThumbAc" : ""
- )}
- >
- 请上传 {imgNum} 张图片!
- </div>
- {/* 确定和取消按钮 */}
- <br />
- <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
- <Button type="primary" htmlType="submit">
- 提交
- </Button>
-  
- <Button disabled={!imgList.length} onClick={() => setLookImg(true)}>
- 预览效果
- </Button>
-  
- <Popconfirm
- title="放弃编辑后,信息将不会保存!"
- okText="放弃"
- cancelText="取消"
- onConfirm={()=>closeMoalFu('取消')}
- >
- <Button>取消</Button>
- </Popconfirm>
- </Form.Item>
- </Form>
- </div>
- {/* 点击预览效果出来的页面 */}
- {lookImg ? (
- <WallLook imgList={imgList} closeMoalFu={() => setLookImg(false)} />
- ) : null}
- </div>
- );
- }
- const MemoWallAdd = React.memo(WallAdd);
- export default MemoWallAdd;
|