123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- 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 //有没有点击过确定
- size: number //上传附件大小(M)
- 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 //是不是查看
- ref: any //当前自己的ref,给父组件调用
- // 其他后端需要的配置项
- otherArr?: { key: string; value: string }[]
- }
- function ZupOne(
- {
- fileCheck,
- size,
- dirCode,
- myUrl,
- format,
- formatTxt,
- checkTxt,
- upTxt,
- myType,
- isLook = false,
- otherArr
- }: 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)
- fd.append('dirCode', dirCode)
- fd.append('file', filesInfo)
- if (otherArr) {
- otherArr.forEach((v: any) => {
- fd.append(v.key, v.value)
- })
- }
- if (filesInfo.size > 1 * 1024 * 1024) {
- // 开启压缩图片
- 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, myType, myUrl, otherArr, size]
- )
- // 让父组件调用的 回显 附件 地址
- 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='file_img' 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'>
- <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}格式;最大支持{size}M。{upTxt}
- <br />
- <div
- className={classNames('noUpThumb', !fileUrl.filePath && fileCheck ? 'noUpThumbAc' : '')}
- >
- {checkTxt}
- </div>
- </div>
- </div>
- )
- }
- export default forwardRef(ZupOne)
|