material.tsx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. import React, { forwardRef, Ref, useContext, useEffect, useImperativeHandle, useRef, useState } from "react"
  2. import style from './index.less'
  3. import { Breadcrumb, Button, Card, Checkbox, Dropdown, Empty, message, Modal, Pagination, Popconfirm, Radio, Spin, Typography } from "antd"
  4. import { DispatchCloudNew } from "."
  5. import { deleteBatchApi, delMaterialApi, getFolderListApi, getMaterialListApi } from "@/services/adqV3/cloudNew"
  6. import { useAjax } from "@/Hook/useAjax"
  7. import { useSize } from "ahooks"
  8. import './global.less'
  9. import { useModel } from "umi"
  10. import { CheckboxValueType } from "antd/lib/checkbox/Group"
  11. import MoveFile from "./moveFile"
  12. import { ItemType } from "antd/lib/menu/hooks/useItems"
  13. import UploadFile from "./uploadFile"
  14. import UpdateCreate from "./updateCreate"
  15. import { formatSecondsToTime, getVideoImgUrl } from "@/utils/utils"
  16. import { ExclamationCircleOutlined } from "@ant-design/icons"
  17. import UpdateFile from "./updateFile"
  18. import Details from "./details"
  19. import useFileDrop from "@/Hook/useFileDrop"
  20. import UploadsTable from "./uploadsTable"
  21. const { Text } = Typography;
  22. interface Props {
  23. /** 新增文件夹 */
  24. onAddFolder?: () => void
  25. onUpdateFolder?: (data: any) => void
  26. onDelFolder?: (id: number, name: string) => void
  27. }
  28. interface MaterialRef {
  29. folderRefresh: () => void
  30. search: (value: {
  31. searchType: "file" | "folder";
  32. keyword?: string;
  33. }) => void
  34. }
  35. /**
  36. * 素材列表
  37. * @returns
  38. */
  39. const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props, ref1: Ref<MaterialRef>) => {
  40. /********************************/
  41. const { initialState } = useModel('@@initialState');
  42. const { breadcrumdData, setSelectedKeys, setBreadcrumdData, setMaterialParams, materialParams, selectedKeys, treeData, folderCreateBy, findParentKeys, loadedKeys, handleUpdateFolder, batchFolderVisible, setBatchFolderVisible, handleType, setHandleType } = useContext(DispatchCloudNew)!;
  43. const ref = useRef<HTMLDivElement>(null);
  44. const size = useSize(ref);
  45. const [folderList, setFolderList] = useState<{ id: number, folderName: string, createBy: number, description?: string }[]>([])
  46. const [rowNum, setRowNum] = useState<number>(0)
  47. const [checkedFolderList, setCheckedFolderList] = useState<CheckboxValueType[]>([])
  48. const [checkFolderAll, setCheckFolderAll] = useState<boolean>(false);
  49. const [indeterminateFolder, setIndeterminateFolder] = useState<boolean>(false);
  50. const [moveVisible, setMoveVisible] = useState<boolean>(false)
  51. const [moveType, setMoveType] = useState<'folder' | 'file'>('folder')
  52. const [batchType, setBatchType] = useState<'folder' | 'file'>()
  53. const [checkedList, setCheckedList] = useState<CheckboxValueType[]>([])
  54. const [uploadVisible, setUploadVisible] = useState<boolean>(false)
  55. const [updateOwnerData, setUpdateOwnerData] = useState<{ visible?: boolean, folderId: number }>({ folderId: 0 })
  56. const [updateFileData, setUpdateFileData] = useState<{ visible?: boolean, initialValues: any }>({ visible: false, initialValues: {} })
  57. const [detailsData, setDetailsData] = useState<{ visible?: boolean, data: any }>({ visible: false, data: {} })
  58. const getFolderList = useAjax((params) => getFolderListApi(params))
  59. const delMaterial = useAjax((params) => delMaterialApi(params))
  60. const deleteBatch = useAjax((params) => deleteBatchApi(params))
  61. const getMaterialList = useAjax((params) => getMaterialListApi(params))
  62. /********************************/
  63. useImperativeHandle(ref1, () => ({
  64. // 刷新文件夹
  65. folderRefresh() {
  66. getFolder()
  67. },
  68. search(value) {
  69. setHandleType('file')
  70. setMaterialParams(data => ({ ...data, ...value, pageNum: 1 }))
  71. }
  72. }));
  73. // 根据内容宽度计算列数
  74. useEffect(() => {
  75. if (size?.width) {
  76. let rowNum = Math.floor((size?.width - 26) / 200)
  77. setRowNum(rowNum || 1)
  78. }
  79. }, [size?.width])
  80. useEffect(() => {
  81. cancelSelect()
  82. if (isShowFolder()) {
  83. // 文件夹
  84. getFolder()
  85. } else {
  86. // 文件
  87. getFile()
  88. }
  89. }, [selectedKeys, handleType, materialParams])
  90. /** 获取下级文件夹 */
  91. const getFolder = () => {
  92. let parentId: number | undefined;
  93. if (selectedKeys?.length) {
  94. const parentIdArr = (selectedKeys[0] as string).split('-')
  95. const parentIdArrLength = parentIdArr.length
  96. parentId = Number(parentIdArr[parentIdArrLength - 1])
  97. }
  98. getFolderList.run({ parentId }).then(res => {
  99. setFolderList(() => res || [])
  100. })
  101. }
  102. // 搜索素材
  103. const getFile = () => {
  104. let parentId: number | undefined;
  105. if (selectedKeys?.length) {
  106. const parentIdArr = (selectedKeys[0] as string).split('-')
  107. const parentIdArrLength = parentIdArr.length
  108. parentId = Number(parentIdArr[parentIdArrLength - 1])
  109. }
  110. let params = JSON.parse(JSON.stringify(materialParams))
  111. if (params?.width || params?.height) {
  112. params.sizeQueries = [{ width: params?.width, height: params?.height, relation: '=' }]
  113. delete params?.width
  114. delete params?.height
  115. } else {
  116. delete params?.sizeQueries
  117. }
  118. getMaterialList.run({ ...params, folderId: parentId })
  119. }
  120. // 文件夹选择
  121. const onCheckboxChange = (checkedValues: CheckboxValueType[]) => {
  122. let data: any[] = []
  123. if (batchType === 'folder') {
  124. data = folderList
  125. } else {
  126. data = getMaterialList?.data?.records || []
  127. }
  128. setCheckedFolderList(checkedValues)
  129. setIndeterminateFolder(!!checkedValues.length && checkedValues.length < data.length);
  130. setCheckFolderAll(checkedValues.length === data.length);
  131. };
  132. // 取消选择
  133. const cancelSelect = () => {
  134. setCheckFolderAll(false)
  135. setCheckedFolderList([])
  136. setIndeterminateFolder(false)
  137. setCheckedList([])
  138. }
  139. // 是否管理员
  140. const isAdmin = () => {
  141. return ['999'].includes(initialState?.currentUser?.powerLevel?.toString() || '')
  142. }
  143. // 是否有权限
  144. const isPermission = (createBy: any) => {
  145. return initialState?.currentUser?.userId?.toString() === createBy.toString()
  146. }
  147. // 文件夹更多
  148. const getItems = (item: any) => {
  149. let data: ItemType[] = []
  150. if (isPermission(item.createBy)) {
  151. data.push({ label: '编辑', style: { fontSize: 12 }, key: 'edit', onClick: () => onUpdateFolder?.(item) })
  152. if (!!selectedKeys?.[0]) {
  153. data.push({
  154. label: '移动', style: { fontSize: 12 }, key: 'move', onClick: () => {
  155. setCheckedList([item.id])
  156. setMoveType('folder')
  157. setMoveVisible(true)
  158. }
  159. })
  160. } else if (isAdmin()) {
  161. data.push({
  162. label: '修改文件夹所属人', style: { fontSize: 12 }, key: 'createBy', onClick: () => {
  163. setUpdateOwnerData({ visible: true, folderId: item.id })
  164. }
  165. })
  166. }
  167. data.push({ label: <span style={{ color: 'red', fontSize: 12 }}>删除</span>, key: 'del', onClick: () => onDelFolder?.(item.id, item?.folderName) })
  168. } else {
  169. if (isAdmin() && !selectedKeys?.[0]) {
  170. data.push({
  171. label: '修改文件夹所属人', style: { fontSize: 12 }, key: 'createBy', onClick: () => {
  172. setUpdateOwnerData({ visible: true, folderId: item.id })
  173. }
  174. })
  175. }
  176. }
  177. return data
  178. }
  179. // 删除素材
  180. const delFile = (id: number, name: string) => {
  181. Modal.confirm({
  182. title: <strong>{`删除素材“${name}”`}</strong>,
  183. icon: <ExclamationCircleOutlined />,
  184. content: '是否确定删除该素材',
  185. okText: '确认',
  186. cancelText: '取消',
  187. className: 'modalResetCss',
  188. onOk: () => {
  189. return new Promise((resolve: (value: unknown) => void) => {
  190. delMaterial.run(id).then(res => {
  191. if (res) {
  192. message.success('删除成功');
  193. getMaterialList.refresh()
  194. resolve('')
  195. }
  196. })
  197. })
  198. }
  199. });
  200. }
  201. // 操作素材 更多
  202. const getItemsFile = (item: any) => {
  203. let data: ItemType[] = []
  204. if (isPermission(item.createBy)) {
  205. data.push({
  206. label: <div onClick={(e) => {
  207. e.stopPropagation()
  208. e.preventDefault()
  209. setUpdateFileData({ visible: true, initialValues: item })
  210. }}>编辑</div>, style: { fontSize: 12 }, key: 'edit'
  211. })
  212. if (!!selectedKeys?.[0]) {
  213. data.push({
  214. label: <div onClick={(e) => {
  215. e.stopPropagation()
  216. e.preventDefault()
  217. setCheckedList([item.id])
  218. setMoveType('file')
  219. setMoveVisible(true)
  220. }}>移动</div>, style: { fontSize: 12 }, key: 'move'
  221. })
  222. }
  223. data.push({
  224. label: <div style={{ color: 'red', fontSize: 12 }} onClick={(e) => {
  225. e.stopPropagation()
  226. e.preventDefault()
  227. delFile(item.id, item?.materialName)
  228. }}>删除</div>, key: 'del'
  229. })
  230. }
  231. return data
  232. }
  233. // 是否展示文件夹
  234. const isShowFolder = () => {
  235. return handleType === 'folder'
  236. }
  237. // 获取拖拽的文件
  238. const [fileList, setFileList] = useState<FileList>()
  239. const [uploadsVisible, setUploadsVisible] = useState<boolean>(false)
  240. const { isDragOver, dropAreaProps } = useFileDrop((fileList) => {
  241. console.log('fileList--->', fileList)
  242. setFileList(fileList)
  243. setUploadsVisible(true)
  244. });
  245. return <div className={style.material}>
  246. <div className={style.operates}>
  247. <div className={style.left_bts}>
  248. <Checkbox
  249. onChange={(e) => {
  250. setHandleType(e.target.checked ? 'folder' : 'file')
  251. setMaterialParams({ pageNum: 1, pageSize: 30 })
  252. setBatchFolderVisible(false)
  253. cancelSelect()
  254. }}
  255. checked={handleType === 'folder'}
  256. ><span style={{ fontSize: 12 }}>是否操作文件夹</span></Checkbox>
  257. {handleType === 'folder' && <Button onClick={() => onAddFolder?.()} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>新建文件夹</Button>}
  258. {(!selectedKeys?.[0] && handleType === 'folder') && <>
  259. <Button type="primary" disabled={folderCreateBy ? !isPermission(folderCreateBy) : false} onClick={() => setUploadVisible(true)}>上传素材</Button>
  260. </>}
  261. {handleType === 'folder' ? <>
  262. {!!selectedKeys?.[0] && <Button onClick={() => { setBatchFolderVisible(true); setBatchType('folder') }} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>批量操作文件夹</Button>}
  263. </> : <>
  264. <Button type="primary" disabled={folderCreateBy ? !isPermission(folderCreateBy) : false} onClick={() => setUploadVisible(true)}>上传素材</Button>
  265. <Button onClick={() => { setBatchFolderVisible(true); setBatchType('file') }} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>批量操作素材</Button>
  266. </>}
  267. </div>
  268. <div className={style.left_bts}>
  269. <Button type="link" loading={getMaterialList.loading} onClick={() => {
  270. getMaterialList.refresh()
  271. }}>刷新</Button>
  272. </div>
  273. </div>
  274. {batchFolderVisible ? <div className={style.operates}>
  275. <div className={style.left_bts}>
  276. <Checkbox
  277. onChange={(e) => {
  278. setCheckedFolderList(
  279. e.target.checked ? batchType === 'folder' ?
  280. folderList.map(item => item.id) :
  281. getMaterialList?.data?.records?.filter((item: { createBy: any }) => isPermission(item.createBy)).map((item: { id: any }) => item.id) :
  282. []
  283. )
  284. setIndeterminateFolder(false)
  285. setCheckFolderAll(e.target.checked)
  286. }}
  287. disabled={batchType === 'folder' ? folderList?.length ? false : true : !getMaterialList?.data?.records?.some((item: { createBy: any }) => isPermission(item.createBy))}
  288. indeterminate={indeterminateFolder}
  289. checked={checkFolderAll}
  290. >全选</Checkbox>
  291. <span style={{ color: '#1890FF' }}>已选{checkedFolderList?.length || 0}个{batchType === 'file' ? '素材' : '文件夹'}</span>
  292. </div>
  293. <div className={style.left_bts}>
  294. <Button disabled={checkedFolderList?.length === 0} onClick={() => {
  295. setCheckedList(checkedFolderList)
  296. setMoveVisible(true)
  297. setMoveType(batchType as any)
  298. }}>{batchType === 'folder' ? '移动文件夹' : '移动素材'}</Button>
  299. {batchType === 'file' && <Popconfirm
  300. title="确定删除?"
  301. onConfirm={() => {
  302. const hide = message.loading('正在删除...', 0, () => {});
  303. deleteBatch.run(checkedFolderList).then(res => {
  304. hide()
  305. if (res) {
  306. getMaterialList.refresh()
  307. message.success('删除成功')
  308. }
  309. }).catch(() => hide())
  310. }}
  311. >
  312. <Button danger disabled={checkedFolderList?.length === 0} loading={deleteBatch.loading}>删除</Button>
  313. </Popconfirm>}
  314. <Button type="primary" onClick={() => {
  315. setBatchFolderVisible(false)
  316. }}>完成</Button>
  317. </div>
  318. </div> : (materialParams?.materialName || materialParams?.materialType || (materialParams?.designerIds && materialParams?.designerIds?.length > 0) || materialParams?.width || materialParams?.height) ? <div className={style.operates}>
  319. <span>搜索「素材」
  320. {materialParams?.materialName && <span style={{ fontSize: 12 }}>关键词【{materialParams.materialName}】</span>}
  321. {(materialParams?.designerIds && materialParams?.designerIds?.length > 0) && <span style={{ fontSize: 12 }}>设计师ID【{materialParams.designerIds.join(',')}】</span>}
  322. {materialParams?.materialType && <span style={{ fontSize: 12 }}>素材类型【{materialParams.materialType === 'video' ? '视频' : '图片'}】</span>}
  323. {materialParams?.width && <span style={{ fontSize: 12 }}>素材宽【{materialParams.width}】</span>}
  324. {materialParams?.height && <span style={{ fontSize: 12 }}>素材高【{materialParams.height}】</span>}
  325. </span>
  326. </div> : <div className={style.operates}>
  327. <Breadcrumb>
  328. {breadcrumdData.map((item, index) => <Breadcrumb.Item key={item.key}>
  329. {breadcrumdData.length !== index + 1 ? <a
  330. style={{ color: '#1890ff' }}
  331. onClick={() => {
  332. setBreadcrumdData(data => data.splice(0, index + 1))
  333. setSelectedKeys(item.currentKey === '0' ? [] : [item.currentKey])
  334. }}
  335. >{item.label}</a> : item.label}
  336. </Breadcrumb.Item>)}
  337. </Breadcrumb>
  338. </div>}
  339. <div className={`${style.content} content_global`}>
  340. <Spin spinning={getFolderList.loading || getMaterialList.loading}>
  341. <div className={style.content_scroll} ref={ref} {...dropAreaProps}>
  342. {isDragOver && <div className={`${style.placeholder} ${isDragOver ? style.dragOver : ''}`}><span>拖动文件到这里</span></div>}
  343. {(isShowFolder() && folderList.length > 0) || (!isShowFolder() && getMaterialList?.data?.records?.length > 0) ? <Checkbox.Group value={checkedFolderList} style={{ width: '100%' }} onChange={onCheckboxChange}>
  344. <div className={style.content_scroll_div}>
  345. {isShowFolder() ? folderList.map((item) => <div key={item.id} className={style.content_row} style={{ width: rowNum ? (1 / rowNum * 100) + '%' : 200 }}>
  346. <Card
  347. hoverable
  348. bodyStyle={{ padding: 0 }}
  349. className={`${style.content_col}`}
  350. cover={<div className={style.content_cover} style={{ height: 120 }}>
  351. {batchFolderVisible && <div className={style.checkbox}><Checkbox value={item.id} disabled={!isPermission(item.createBy)} /></div>}
  352. <img src={require('../../../../../public/file.png')} height={'100%'} alt="" />
  353. </div>}
  354. onDoubleClick={() => {
  355. if (!batchFolderVisible) {
  356. let newExpandedKeys = '0-' + item.id
  357. if (selectedKeys?.[0]) {
  358. newExpandedKeys = selectedKeys[0] + '-' + item.id
  359. }
  360. findParentKeys(newExpandedKeys, treeData)
  361. setSelectedKeys([newExpandedKeys])
  362. // 判断是否加载了下级文件 加载了 就不更新
  363. if (!loadedKeys.includes(newExpandedKeys))
  364. handleUpdateFolder(newExpandedKeys)
  365. }
  366. }}
  367. >
  368. <div className={style.body}>
  369. <Text ellipsis>{item?.folderName}</Text>
  370. </div>
  371. <div className={style.actions}>
  372. <div style={{ height: 22 }}></div>
  373. {isPermission(item.createBy) || (!selectedKeys?.[0] && isAdmin()) ? <Dropdown menu={{
  374. items: getItems(item)
  375. }}>
  376. <a onClick={e => e.preventDefault()} style={{ fontSize: 11 }}>更多</a>
  377. </Dropdown> : <a style={{ fontSize: 11 }}>无权限操作</a>}
  378. </div>
  379. </Card>
  380. </div>) : getMaterialList?.data?.records.map((item: any) => <div key={item.id} className={style.content_row} style={{ width: rowNum ? (1 / rowNum * 100) + '%' : 200 }}>
  381. <Card
  382. hoverable
  383. bodyStyle={{ padding: 0 }}
  384. className={`${style.content_col}`}
  385. cover={<div style={{ height: 120, padding: 0 }} className={style.content_cover}>
  386. {batchFolderVisible && <div className={style.checkbox} onClick={(e) => { e.stopPropagation(); }}><Checkbox value={item.id} disabled={!isPermission(item.createBy)} /></div>}
  387. {item.materialType === 'video' && <div className={style.playr}>
  388. <img src={require('../../../../../public/image/play.png')} alt="" />
  389. </div>}
  390. <div className={style.file_info}>
  391. <div>{item.width}*{item.height}</div>
  392. {item.materialType === 'video' && <div>{formatSecondsToTime(Math.floor(item.videoDuration))}</div>}
  393. </div>
  394. <img src={item.materialType === 'image' ? item.ossUrl : getVideoImgUrl(item.ossUrl)} className={style.coverImg} alt="" />
  395. </div>}
  396. onClick={() => { setDetailsData({ visible: true, data: item }) }}
  397. >
  398. <div className={style.body}>
  399. <div className={style.title}><Text ellipsis>{item?.materialName}</Text></div>
  400. <a className={style.detailBt}>详情</a>
  401. </div>
  402. <div className={style.actions}>
  403. <div style={{ height: 22 }}></div>
  404. {isPermission(item.createBy) ? <Dropdown
  405. menu={{
  406. items: getItemsFile(item)
  407. }}
  408. >
  409. <a onClick={e => { e.preventDefault(); e.stopPropagation() }} style={{ fontSize: 11 }}>更多</a>
  410. </Dropdown> : <a style={{ fontSize: 11 }}>无权限操作</a>}
  411. </div>
  412. </Card>
  413. </div>)}
  414. </div>
  415. </Checkbox.Group> : <div style={{ height: '100%', width: '100%', alignContent: 'center' }}><Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /></div>}
  416. </div>
  417. </Spin>
  418. </div>
  419. {handleType === 'file' && <div className={style.fotter}>
  420. <Pagination
  421. size="small"
  422. total={getMaterialList?.data?.totalRow || 0}
  423. showSizeChanger
  424. showQuickJumper
  425. pageSize={getMaterialList?.data?.pageSize || 30}
  426. current={getMaterialList?.data?.pageNumber || 1}
  427. onChange={(page: number, pageSize: number) => {
  428. setMaterialParams({ ...materialParams, pageNum: page, pageSize })
  429. }}
  430. />
  431. </div>}
  432. {/* 移动文件 素材 */}
  433. {moveVisible && <MoveFile
  434. moveType={moveType}
  435. checkedList={checkedList}
  436. userId={initialState?.currentUser?.userId?.toString() || ''}
  437. visible={moveVisible}
  438. onClose={() => {
  439. setMoveVisible(false)
  440. cancelSelect()
  441. }}
  442. onChange={(selectedKey: string) => {
  443. getFolder()
  444. setMoveVisible(false)
  445. if (moveType === 'folder') {
  446. handleUpdateFolder(selectedKeys[0] as string)
  447. if (loadedKeys.includes(selectedKey)) {
  448. handleUpdateFolder(selectedKey)
  449. }
  450. } else {
  451. getMaterialList.refresh()
  452. }
  453. cancelSelect()
  454. setBatchFolderVisible(false)
  455. }}
  456. />}
  457. {/* 上传文件 */}
  458. {uploadVisible && <UploadFile
  459. folderId={breadcrumdData[breadcrumdData.length - 1].key}
  460. userId={(initialState?.currentUser?.userId || 0) as number}
  461. visible={uploadVisible}
  462. onChange={() => {
  463. setUploadVisible(false)
  464. getMaterialList.refresh()
  465. }}
  466. onClose={() => {
  467. setUploadVisible(false)
  468. }}
  469. />}
  470. {/* 修改所属人 */}
  471. {updateOwnerData.visible && <UpdateCreate
  472. {...updateOwnerData}
  473. onClose={() => {
  474. setUpdateOwnerData({ visible: false, folderId: 0 })
  475. }}
  476. onChange={() => {
  477. getFolder()
  478. setUpdateOwnerData({ visible: false, folderId: 0 })
  479. }}
  480. />}
  481. {/* 修改素材 */}
  482. {updateFileData?.visible && <UpdateFile
  483. {...updateFileData}
  484. onClose={() => {
  485. setUpdateFileData({ visible: false, initialValues: {} })
  486. }}
  487. onChange={() => {
  488. getMaterialList.refresh()
  489. setUpdateFileData({ visible: false, initialValues: {} })
  490. }}
  491. />}
  492. {/* 素材详情 */}
  493. {detailsData?.visible && <Details
  494. {...detailsData}
  495. onClose={() => {
  496. setDetailsData({ visible: false, data: {} })
  497. }}
  498. onChange={() => {
  499. getMaterialList.refresh()
  500. }}
  501. />}
  502. {/* 拖动上传 */}
  503. {uploadsVisible && <UploadsTable
  504. folderId={breadcrumdData[breadcrumdData.length - 1].key}
  505. userId={(initialState?.currentUser?.userId || 0) as number}
  506. visible={uploadsVisible}
  507. fileList={fileList}
  508. isPermission={!!(folderCreateBy && isPermission(folderCreateBy))}
  509. onClose={() => {
  510. setUploadsVisible(false)
  511. setFileList(undefined)
  512. }}
  513. onChange={() => {
  514. setUploadsVisible(false)
  515. setFileList(undefined)
  516. getMaterialList.refresh()
  517. }}
  518. />}
  519. </div>
  520. })
  521. export default React.memo(Material)