|
|
@@ -0,0 +1,295 @@
|
|
|
+import React, { useCallback, useMemo, useRef, useState } from 'react'
|
|
|
+import styles from './index.module.scss'
|
|
|
+import ImageLazy from '@/components/ImageLazy'
|
|
|
+import {
|
|
|
+ PlusOutlined,
|
|
|
+ EyeOutlined,
|
|
|
+ CloseOutlined,
|
|
|
+ DownloadOutlined,
|
|
|
+ UploadOutlined
|
|
|
+} from '@ant-design/icons'
|
|
|
+import store from '@/store'
|
|
|
+import { baseURL } from '@/utils/http'
|
|
|
+import classNames from 'classnames'
|
|
|
+import { Button } from 'antd'
|
|
|
+import { MessageFu } from '@/utils/message'
|
|
|
+import { fileDomInitialFu } from '@/utils/domShow'
|
|
|
+import { API_upFile } from '@/store/action/layout'
|
|
|
+import { forwardRef, useImperativeHandle } from 'react'
|
|
|
+import MyPopconfirm from '../MyPopconfirm'
|
|
|
+
|
|
|
+type MyTypeType = 'thumb' | 'video' | 'audio' | 'model' | 'pdf' | 'epub'
|
|
|
+
|
|
|
+// 这个组件 只处理 上传 一张图片或者 视频 音频 模型 pdf 的情况
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ fileCheck: boolean //有没有点击过确定
|
|
|
+ dirCode: string //文件的code码
|
|
|
+ myUrl: string //请求地址
|
|
|
+ format: string[] //上传格式 ["image/jpeg", "image/png"] ["video/mp4"] ,application/pdf
|
|
|
+ formatTxt: string //上传图片提示
|
|
|
+ checkTxt: string
|
|
|
+ upTxt: string
|
|
|
+ myType: MyTypeType
|
|
|
+ isLook?: boolean //是不是查看
|
|
|
+ fromData?: any
|
|
|
+ ref: any //当前自己的ref,给父组件调用
|
|
|
+ isTouXiang?: boolean //圆形头像展示
|
|
|
+}
|
|
|
+
|
|
|
+function ZupOne(
|
|
|
+ {
|
|
|
+ fileCheck,
|
|
|
+ dirCode,
|
|
|
+ myUrl,
|
|
|
+ format,
|
|
|
+ formatTxt,
|
|
|
+ checkTxt,
|
|
|
+ upTxt,
|
|
|
+ myType,
|
|
|
+ isLook = false,
|
|
|
+ fromData,
|
|
|
+ isTouXiang
|
|
|
+ }: Props,
|
|
|
+ ref: any
|
|
|
+) {
|
|
|
+ const [fileUrl, setFileUrl] = useState({
|
|
|
+ fileName: '',
|
|
|
+ filePath: '',
|
|
|
+ thumb: '' //压缩图
|
|
|
+ })
|
|
|
+
|
|
|
+ const myInput = useRef<HTMLInputElement>(null)
|
|
|
+
|
|
|
+ // 上传封面图
|
|
|
+ const handeUpPhoto = useCallback(
|
|
|
+ async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
+ if (e.target.files) {
|
|
|
+ // 拿到files信息
|
|
|
+ const filesInfo = e.target.files[0]
|
|
|
+ // console.log("-----", filesInfo.type);
|
|
|
+
|
|
|
+ // 校验格式
|
|
|
+ const type = format
|
|
|
+
|
|
|
+ if (myType === 'pdf') {
|
|
|
+ if (!filesInfo.type.includes('pdf')) {
|
|
|
+ e.target.value = ''
|
|
|
+ return MessageFu.warning(`只支持${formatTxt}格式!`)
|
|
|
+ }
|
|
|
+ } else if (myType === 'epub') {
|
|
|
+ if (!filesInfo.name.endsWith('.epub')) {
|
|
|
+ e.target.value = ''
|
|
|
+ return MessageFu.warning(`只支持${formatTxt}格式!`)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!type.includes(filesInfo.type)) {
|
|
|
+ e.target.value = ''
|
|
|
+ return MessageFu.warning(`只支持${formatTxt}格式!`)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验大小
|
|
|
+ // if (filesInfo.size > size * 1024 * 1024) {
|
|
|
+ // e.target.value = ''
|
|
|
+ // return MessageFu.warning(`最大支持${size}M!`)
|
|
|
+ // }
|
|
|
+ // 创建FormData对象
|
|
|
+ const fd = new FormData()
|
|
|
+ // 把files添加进FormData对象(‘photo’为后端需要的字段)
|
|
|
+ let myTypeRes: string = myType
|
|
|
+ if (['pdf', 'epub'].includes(myTypeRes)) myTypeRes = 'doc'
|
|
|
+ fd.append('type', myTypeRes === 'thumb' ? 'img' : myTypeRes)
|
|
|
+ fd.append('dirCode', dirCode)
|
|
|
+ fd.append('file', filesInfo)
|
|
|
+
|
|
|
+ if (fromData) {
|
|
|
+ for (const k in fromData) {
|
|
|
+ if (fromData[k]) fd.append(k, fromData[k])
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 开启压缩图片
|
|
|
+ fd.append('isCompress', 'true')
|
|
|
+
|
|
|
+ e.target.value = ''
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await API_upFile(fd, myUrl)
|
|
|
+ if (res.code === 0) {
|
|
|
+ MessageFu.success('上传成功!')
|
|
|
+ setFileUrl(res.data)
|
|
|
+ }
|
|
|
+ fileDomInitialFu()
|
|
|
+ } catch (error) {
|
|
|
+ fileDomInitialFu()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [dirCode, format, formatTxt, fromData, myType, myUrl]
|
|
|
+ )
|
|
|
+
|
|
|
+ // 让父组件调用的 回显 附件 地址
|
|
|
+ const setFileComFileFu = useCallback(
|
|
|
+ (valObj: { fileName: string; filePath: string; thumb: string }) => {
|
|
|
+ setFileUrl(valObj)
|
|
|
+ },
|
|
|
+ []
|
|
|
+ )
|
|
|
+
|
|
|
+ // 让父组件调用的返回 附件 名字和路径
|
|
|
+ const fileComFileResFu = useCallback(() => {
|
|
|
+ return fileUrl
|
|
|
+ }, [fileUrl])
|
|
|
+
|
|
|
+ // 可以让父组件调用子组件的方法
|
|
|
+ useImperativeHandle(ref, () => ({
|
|
|
+ setFileComFileFu,
|
|
|
+ fileComFileResFu
|
|
|
+ }))
|
|
|
+
|
|
|
+ const acceptRes = useMemo(() => {
|
|
|
+ let accept = '.png,.jpg,.jpeg'
|
|
|
+ if (myType === 'video') accept = '.mp4'
|
|
|
+ else if (myType === 'audio') accept = '.mp3'
|
|
|
+ else if (myType === 'model') accept = '.4dage'
|
|
|
+ else if (myType === 'pdf') accept = '.pdf'
|
|
|
+ else if (myType === 'epub') accept = '.epub'
|
|
|
+ return accept
|
|
|
+ }, [myType])
|
|
|
+
|
|
|
+ // 点击 预览(除了图片)
|
|
|
+ const lookFileNoImgFu = useCallback(
|
|
|
+ (type: MyTypeType) => {
|
|
|
+ if (type === 'pdf' || type === 'thumb') {
|
|
|
+ // 新窗口打开
|
|
|
+ window.open(baseURL + fileUrl.filePath)
|
|
|
+ } else if (type !== 'epub') {
|
|
|
+ store.dispatch({
|
|
|
+ type: 'layout/lookDom',
|
|
|
+ payload: { src: fileUrl.filePath, type }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // if (type === "pdf") {
|
|
|
+ // } else {
|
|
|
+ // }
|
|
|
+ },
|
|
|
+ [fileUrl.filePath]
|
|
|
+ )
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={styles.ZupOne}>
|
|
|
+ <input
|
|
|
+ id='upInput'
|
|
|
+ type='file'
|
|
|
+ accept={acceptRes}
|
|
|
+ ref={myInput}
|
|
|
+ onChange={e => handeUpPhoto(e)}
|
|
|
+ />
|
|
|
+ {myType === 'thumb' ? (
|
|
|
+ <div
|
|
|
+ hidden={fileUrl.filePath !== ''}
|
|
|
+ className='file_upIcon'
|
|
|
+ onClick={() => myInput.current?.click()}
|
|
|
+ >
|
|
|
+ <PlusOutlined rev={undefined} />
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <Button
|
|
|
+ hidden={fileUrl.filePath !== ''}
|
|
|
+ onClick={() => myInput.current?.click()}
|
|
|
+ icon={<UploadOutlined rev={undefined} />}
|
|
|
+ >
|
|
|
+ 上传
|
|
|
+ </Button>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {/* 为图片的情况-------------- */}
|
|
|
+ {myType === 'thumb' ? (
|
|
|
+ <div
|
|
|
+ className={classNames('file_img', isTouXiang ? 'file_imgYuan' : '')}
|
|
|
+ hidden={fileUrl.filePath === ''}
|
|
|
+ >
|
|
|
+ {fileUrl ? (
|
|
|
+ <ImageLazy
|
|
|
+ width={100}
|
|
|
+ height={100}
|
|
|
+ srcBig={fileUrl.filePath}
|
|
|
+ src={fileUrl.thumb}
|
|
|
+ noLook
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {/* 删除 */}
|
|
|
+ <div className='file_closeBox' hidden={isLook}>
|
|
|
+ <MyPopconfirm
|
|
|
+ txtK='删除'
|
|
|
+ onConfirm={() => setFileUrl({ fileName: '', filePath: '', thumb: '' })}
|
|
|
+ Dom={<CloseOutlined rev={undefined} />}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 预览 下载 */}
|
|
|
+ <div className='file_lookBox' hidden={isTouXiang}>
|
|
|
+ <EyeOutlined
|
|
|
+ onClick={() =>
|
|
|
+ store.dispatch({
|
|
|
+ type: 'layout/lookBigImg',
|
|
|
+ payload: { url: baseURL + fileUrl.filePath, show: true }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ rev={undefined}
|
|
|
+ />
|
|
|
+ <a href={baseURL + fileUrl.filePath} download target='_blank' rel='noreferrer'>
|
|
|
+ <DownloadOutlined rev={undefined} />
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ) : fileUrl.filePath ? (
|
|
|
+ <div className='fileInfo'>
|
|
|
+ <div className='upSuccTxt'>{fileUrl.fileName}</div>
|
|
|
+ {/* 视频预览 */}
|
|
|
+ <div
|
|
|
+ className='clearCover'
|
|
|
+ hidden={!fileUrl.filePath || myType === 'epub'}
|
|
|
+ onClick={() => lookFileNoImgFu(myType)}
|
|
|
+ >
|
|
|
+ <EyeOutlined rev={undefined} />
|
|
|
+ </div>
|
|
|
+ {/* 视频下载 */}
|
|
|
+ <a
|
|
|
+ href={baseURL + fileUrl.filePath}
|
|
|
+ download
|
|
|
+ target='_blank'
|
|
|
+ className='clearCover'
|
|
|
+ rel='noreferrer'
|
|
|
+ >
|
|
|
+ <DownloadOutlined rev={undefined} />
|
|
|
+ </a>
|
|
|
+ {/* 视频删除 */}
|
|
|
+
|
|
|
+ {isLook ? null : (
|
|
|
+ <MyPopconfirm
|
|
|
+ txtK='删除'
|
|
|
+ onConfirm={() => setFileUrl({ fileName: '', filePath: '', thumb: '' })}
|
|
|
+ Dom={<CloseOutlined className='clearCover' rev={undefined} />}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ <div className='fileBoxRow_r_tit' hidden={isLook}>
|
|
|
+ 格式要求:支持{formatTxt}格式。{upTxt}
|
|
|
+ <br />
|
|
|
+ <div
|
|
|
+ className={classNames('noUpThumb', !fileUrl.filePath && fileCheck ? 'noUpThumbAc' : '')}
|
|
|
+ >
|
|
|
+ {checkTxt}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+export default forwardRef(ZupOne)
|