import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import styles from './index.module.scss' import { Button, Checkbox, Input, Modal } from 'antd' import { forwardRef, useImperativeHandle } from 'react' import { baseURL } from '@/utils/http' import { PlusOutlined, CloseCircleOutlined, UploadOutlined, CloseOutlined, DownloadOutlined, EyeOutlined } from '@ant-design/icons' import { MessageFu } from '@/utils/message' import { API_upFile } from '@/store/action/layout' import { fileDomInitialFu } from '@/utils/domShow' import store from '@/store' import ImageLazy from '../ImageLazy' import classNames from 'classnames' import MyPopconfirm from '../MyPopconfirm' // import { A2_APIchangeImgName } from "@/store/action/A2exhibition"; export type FileListType = { fileName: string thumb?: string filePath: string id: number type: 'model' | 'img' | 'audio' | 'video' imgName: string } type Props = { ref: any //当前自己的ref,给父组件调用 selecFlag: string //筛选的字符串 模型/图片/音频/视频 fileCheck: boolean //有没有点击过确定 dirCode: string //文件的code码 myUrl: string //请求地址 isLook?: boolean //是不是查看 modelSize?: number //模型文件大小限制 imgSize?: number //图片大小限制 imgLength?: number //图片数量限制 audioSize?: number //音频大小限制 videoSize?: number //视频大小限制 videoTit?: string //视频上传的提示语 isTypeShow?: boolean //默认就选中(只有一个类型的时候) isUpName?: boolean //是否能修改图片名字 lastImgTxt?: string //加载最后面的上传提示 oneIsCover?: boolean //是否将第一张作为封面 } function ZupTypes( { selecFlag, fileCheck, dirCode, myUrl, isLook = false, modelSize = 500, imgSize = 5, imgLength = 9, audioSize = 10, videoSize = 500, videoTit = '', isTypeShow = false, isUpName = false, lastImgTxt = '', oneIsCover = false }: Props, ref: any ) { // 筛选 const [typeCheck, setTypeCheck] = useState([]) // 筛选数组 const typeCheckArr = useMemo(() => { const arr = [ { label: '模型', value: 'model' }, { label: '图片', value: 'img' }, { label: '音频', value: 'audio' }, { label: '视频', value: 'video' } ] const arrRes = arr.filter(v => selecFlag.includes(v.label)) if (arrRes.length <= 1 && isTypeShow) { setTypeCheck([arrRes[0].value]) // 默认就选中(只有一个类型的时候) } return arrRes }, [isTypeShow, selecFlag]) // 上传附件的信息 const [fileList, setFileList] = useState({ model: {} as FileListType, img: [] as FileListType[], audio: {} as FileListType, video: {} as FileListType }) // 附件信息的校验,不满足返回 true 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') && fileList.img.length === 0) flag = true if (typeCheck.includes('audio') && !fileList.audio.id) flag = true if (typeCheck.includes('video') && !fileList.video.id) flag = true return flag }, [fileList, typeCheck]) // 点击上传附件按钮 const myInput = useRef(null) const [fileOneType, setFileOneType] = useState('') useEffect(() => { if (fileOneType) myInput.current?.click() }, [fileOneType]) const upFileFu = useCallback((type: string) => { setFileOneType('') window.setTimeout(() => { setFileOneType(type) }, 100) }, []) // 上传附件的处理函数 const handeUpPhoto2 = useCallback( async (e: React.ChangeEvent) => { if (e.target.files) { // 拿到files信息 const filesInfo = e.target.files[0] let anType = ['image/jpeg', 'image/png'] let anTit1 = '只支持png、jpg格式!' let anTit2 = `最大支持${imgSize}M!` let anSize = imgSize * 1024 * 1024 if (fileOneType === 'audio') { anType = ['audio/mpeg'] anTit1 = '只支持mp3格式!' anTit2 = `最大支持${audioSize}M!` anSize = audioSize * 1024 * 1024 } else if (fileOneType === 'video') { anType = ['video/mp4'] anTit1 = '只支持mp4格式!' anTit2 = `最大支持${videoSize}M!` anSize = videoSize * 1024 * 1024 } else if (fileOneType === 'model') { anType = [''] anTit1 = '只支持4dage格式!' anTit2 = `最大支持${modelSize}M!` anSize = modelSize * 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('isDb', 'true') //初始图片 fileName为:未命名 if (isUpName) { fd.append('isDefaultName', 'false') } fd.append('file', filesInfo) if (fileOneType === 'img' && filesInfo.size > 1 * 1024 * 1024) { // 开启压缩图片 fd.append('isCompress', 'true') } e.target.value = '' const res = await API_upFile(fd, myUrl) try { if (res.code === 0) { MessageFu.success('上传成功!') if (fileOneType === 'img') setFileList({ ...fileList, img: [...fileList.img, { ...res.data, imgName: '未命名' }] }) else setFileList({ ...fileList, [fileOneType]: res.data }) } fileDomInitialFu() } catch (error) { fileDomInitialFu() } } }, [audioSize, dirCode, fileList, fileOneType, imgSize, isUpName, modelSize, myUrl, videoSize] ) // 附件图片的拖动 const [dragImg, setDragImg] = useState(null) const handleDragOver = useCallback( (e: React.DragEvent, item: FileListType) => { if (isLook) return e.dataTransfer.dropEffect = 'move' }, [isLook] ) const handleDragEnter = useCallback( (e: React.DragEvent, item: FileListType) => { if (isLook) return e.dataTransfer.effectAllowed = 'move' if (item === dragImg) return const newItems = [...fileList.img] //拷贝一份数据进行交换操作。 const src = newItems.indexOf(dragImg) //获取数组下标 const dst = newItems.indexOf(item) newItems.splice(dst, 0, ...newItems.splice(src, 1)) //交换位置 setFileList({ ...fileList, img: newItems }) }, [dragImg, fileList, isLook] ) // 删除某一张图片 const delImgListFu = useCallback( (id: number) => { const newItems = fileList.img.filter(v => v.id !== id) setFileList({ ...fileList, img: newItems }) }, [fileList] ) // 模型 音频 视频 的 dom const resOneDivDom = useCallback( (type: 'model' | 'audio' | 'video') => { const dom = ( ) return dom }, [audioSize, fileList, modelSize, typeCheck, upFileFu, videoSize, videoTit] ) // ------------让父组件调用的 回显 const setFileComFileFu = useCallback((info: any) => { if (info.type) setTypeCheck(info.type.split(',')) if (info.fileList && info.fileList.length) { const data: FileListType[] = info.fileList const obj = { model: {} as FileListType, img: [] as FileListType[], audio: {} as FileListType, video: {} as FileListType } data.forEach(v => { if (v.type === 'img') { obj.img.push({ ...v, imgName: v.fileName }) } else obj[v.type!] = v }) setFileList(obj) } }, []) // --------------让父组件调用的返回 附件 信息 const fileComFileResFu = useCallback(() => { let coverUrl = '' 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')) { fileList.img.forEach((v, i) => { if (v.id) { fileIds.push(v.id) if (oneIsCover && i === 0) { // 返回 第一张图的url 作为封面 coverUrl = v.thumb || v.filePath } } }) } return { sonType: typeCheck, sonFileIds: fileIds, sonIsOk: fileCheckFu, coverUrl } }, [ fileCheckFu, fileList.audio.id, fileList.img, fileList.model.id, fileList.video.id, oneIsCover, typeCheck ]) // 可以让父组件调用子组件的方法 useImperativeHandle(ref, () => ({ setFileComFileFu, fileComFileResFu })) // 修改图片名称 const [isNameChange, setIsNameChange] = useState({ id: 0, oldName: '', newName: '' }) // 关闭弹窗 const isNameChangeXFu = useCallback(() => { setIsNameChange({ id: 0, oldName: '', newName: '' }) }, []) // 点击图片名字-出来弹窗 const isNameChangeFu = useCallback( (item: FileListType) => { if (isLook) return setIsNameChange({ id: item.id, oldName: item.imgName, newName: '' }) }, [isLook] ) // 修改完这点击 确定修改 const isNameChangeOkFu = useCallback(async () => { // if (!isNameChange.newName) return MessageFu.warning("图片名不能为空!"); // const res = await A2_APIchangeImgName({ // id: isNameChange.id, // fileName: isNameChange.newName, // }); // if (res.code === 0) { // MessageFu.success("修改图片名成功!"); // setFileList({ // ...fileList, // img: fileList.img.map((v) => ({ // ...v, // imgName: v.id === isNameChange.id ? isNameChange.newName : v.imgName, // })), // }); // isNameChangeXFu(); // } }, []) // return (
handeUpPhoto2(e)} /> {/* -----------模型 */} {resOneDivDom('model')} {/* -----------图片 */} {/* -----------音频 */} {resOneDivDom('audio')} {/* -----------视频 */} {resOneDivDom('video')} {/* 最后的提示 */}
请最少上传一张图片!
{/* 点击修改名字出来的弹窗 */} {isNameChange.id ? (
当前名: {isNameChange.oldName}

修改为: { setIsNameChange({ ...isNameChange, newName: e.target.value.replace(/\s+/g, '') }) }} />
) : null}
) } export default forwardRef(ZupTypes)