123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- import SvgIcon from '@/components/SvgIcon'
- import { iFile, iOSSData } from '@/types/file'
- import { apiGetFileList, apiSaveFileInfo, getSignature } from '@/utils/common/api'
- import consts from '@/utils/consts'
- import { dayjsFormat } from '@/utils/util'
- import { InboxOutlined } from '@ant-design/icons'
- import { message, Modal, Table, Upload } from 'antd'
- import { ColumnsType } from 'antd/lib/table'
- import { UploadChangeParam } from 'antd/lib/upload'
- import { UploadFile } from 'antd/lib/upload/interface'
- import React, { useEffect, useState } from 'react'
- import { ZhCloseButton } from '../Button'
- const { Dragger } = Upload
- interface iFileModalProps {
- dataId: string
- visible: boolean
- dataType: number
- onCancel: () => void
- showUpload?: boolean
- }
- interface iFileModalState {
- id: string
- filename: string
- filepath: string
- accountName: string
- createTime: string
- }
- export default function FileModal(props: iFileModalProps) {
- const { dataId = "", visible = false, onCancel, dataType = 1, showUpload = false } = props
- const [ files, setFiles ] = useState<Array<iFileModalState>>([])
- const [ total, setTotal ] = useState<number>(0)
- const [ OSSData, setOssData ] = useState<iOSSData>({
- dir: '',
- expire: '',
- host: '',
- accessId: '',
- policy: '',
- signature: ''
- })
- useEffect(() => {
- if (props.visible) {
- initOssData()
- initData()
- }
- }, [ visible ])
- const initData = async(pageNo: number = 1, pageSize: number = consts.PAGE_SIZE) => {
- // const { current: pageNo = 1, pageSize = consts.PAGESIZE } = pagination || {}
- const { code = -1, data = [], total = 0 } = await apiGetFileList(dataType, dataId, pageNo, pageSize)
- if (code === consts.RET_CODE.SUCCESS) {
- setFiles(data)
- setTotal(total)
- }
- }
- // 上传文件改变时的状态
- const onChange = async (info: UploadChangeParam) => {
- const { status } = info.file
- if (status !== 'uploading') {
- // console.log(info.file, info.fileList)
- }
- if (status === 'done') {
- // message.success(`${info.file.name} 上传成功!`)
- const newFileList: iFile[] = [
- {
- createTime: new Date(),
- filepath: info.file.url,
- filename: info.file.name
- }
- ]
- const { code = -1 } = await apiSaveFileInfo(newFileList, consts.DATA_TYPE.RETURN, dataId)
- if (code === consts.RET_CODE.SUCCESS) {
- initData()
- }
- } else if (status === 'error') {
- message.error(`${info.file.name} 上传失败!`)
- }
- }
- // 初始化、获取签名
- const initOssData = async () => {
- try {
- const { code = -1, data = {} } = await getSignature()
- if (code === consts.RET_CODE.SUCCESS) {
- setOssData({ ...OSSData, ...data })
- } else {
- message.error("获取签名失败,请联系管理员!")
- }
- } catch (error) {
- message.error(error)
- }
- }
- // 额外参数、oss签名
- const getExtraData = (file: UploadFile) => {
- return {
- key: file.url,
- OSSAccessKeyId: OSSData.accessId,
- policy: OSSData.policy,
- Signature: OSSData.signature
- }
- }
- const transformFile = (file: any) => {
- file.url = OSSData.dir + file.name
- return file
- }
- // 上传前的回调
- const beforeUpload = (file: any) => {
- const { UPLOAD_LIMIT } = consts
- const isLt30M = file.size / 1024 / 1024 < UPLOAD_LIMIT
- if (!isLt30M) {
- message.error("上传附件大小限制在30MB!")
- return false
- }
- const expire = parseInt(OSSData.expire) * 1000
- if (expire < Date.now()) {
- initOssData()
- return false
- }
- return true
- }
- // 移除文件
- const onRemove = (file: any) => {
- }
- const columns: ColumnsType<iFileModalState> = [
- {
- title: "文件名",
- dataIndex: "filepath",
- width: 287,
- onCell: () => {
- return {
- style: {
- maxWidth: 287,
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow:'ellipsis',
- cursor:'pointer'
- }
- }
- },
- // eslint-disable-next-line react/display-name
- render: (path: string, record: iFileModalState) => <a href={consts.OSS_PATH.REVIEW + path} target="_blank" rel="noopener noreferrer">{record.filename}</a>
- },
- {
- title: "上传人",
- dataIndex: "accountName"
- },
- {
- title: "上传时间",
- dataIndex: "createTime",
- // eslint-disable-next-line react/display-name
- render: text => <span>{dayjsFormat(text, "YYYY-MM-DD")}</span>
- },
- {
- title: "操作",
- align: "center",
- // eslint-disable-next-line react/display-name
- render: (_, record) => <a href={consts.OSS_PATH.DOWNLOAD + record.filepath} download><SvgIcon type="xxh-download"></SvgIcon></a>
- }
- ]
- return (
- <Modal
- title="附件"
- getContainer={false}
- visible={visible}
- onCancel={onCancel}
- footer={<ZhCloseButton onClick={() => onCancel()} size="small">关闭</ZhCloseButton>}
- >
- {
- showUpload ?
- <div className="pi-mg-bottom-10">
- <Dragger
- name="file"
- action={OSSData.host}
- multiple={true}
- onChange={onChange}
- beforeUpload={beforeUpload}
- data={getExtraData}
- transformFile={transformFile}
- showUploadList={false}
- // accept={consts.UPLOAD_WHITE}
- onRemove={onRemove}
- >
- <p className="ant-upload-drag-icon">
- <InboxOutlined />
- </p>
- <p className="ant-upload-text">把文件拖入指定区域,完成上传,同样支持点击上传。</p>
- <p className="ant-upload-hint">
- 支持单文件/多文件上传。附件大小最大为30MB!
- </p>
- </Dragger>
- </div>
- : ''
- }
- <Table
- dataSource={files}
- columns={columns}
- rowKey={record => record.id}
- bordered
- pagination={{
- hideOnSinglePage: true,
- size: "small",
- pageSize: consts.PAGE_SIZE,
- onChange: (page, pageSize) => initData(page, pageSize),
- total
- }}
- // onChange={(pagination) => initData(pagination)}
- ></Table>
- </Modal>
- )
- }
|