index.tsx 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. import useCopy from "@/Hook/useCopy"
  2. import React, { useCallback, useEffect, useState } from "react"
  3. import { Carousel, Image, message, Pagination, Popconfirm, Spin } from 'antd'
  4. import style from './index.less'
  5. import FileModal from './components/fileModal'
  6. import { useModel } from "umi"
  7. import ImgModal from "./components/imgModal"
  8. import TreeBox from "./components/tree"
  9. import SortModal from "./components/fileModal/sortModal"
  10. import { EyeOutlined } from "@ant-design/icons"
  11. import ImgsModal from "./components/imgsModal"
  12. import MoveTo from "./components/moveTo"
  13. import VideoNews from "@/pages/launchSystemNew/components/newsModal/videoNews"
  14. import { getVideoImgUrl } from "@/utils/utils"
  15. import useFileDrop from "@/Hook/useFileDrop"
  16. import { RcFile } from "antd/lib/upload"
  17. import UploadsTable from "./components/uploadsTable"
  18. import Migrate from "./components/Migrate"
  19. interface News {
  20. id: number,
  21. sysMediaId: number,
  22. sortIndex: number,
  23. title: string,
  24. thumbUrl: string,
  25. author: string,
  26. digest: string,
  27. showCoverPic: boolean,
  28. content: string,//内容只在调取详情时获取
  29. contentSourceUrl: string,//文章地址
  30. needOpenComment: boolean,
  31. onlyFansCanComment: boolean
  32. }
  33. interface Item {
  34. id: number,
  35. folder: boolean,//是否是文件夹
  36. mediaType: 'VIDEO' | 'IMG' | 'PAGE',//类型
  37. number: string,//编号
  38. title: string,//名称
  39. url: string,//链接
  40. belongType: string,//所属类型
  41. createTime: string,//创建时间
  42. description: string,//k图文描述
  43. news?: News[]//图文内容
  44. knewsThumbUrl: string, // 图片链接
  45. knewsThumbId: number,//本地图片ID
  46. knewsThumbInfo: any,//k客服详情
  47. videoTitle: string,//视频标题
  48. width: number, // 宽
  49. height: number, // 高
  50. pageSpecsList?: any[],
  51. }
  52. interface Props {
  53. isAll?: boolean,//是否允许全选默认开启
  54. height?: any,//当使用为弹窗组件时设置高度以免太高
  55. noFile?: boolean,//是否禁止选择文件夹
  56. setPage?: (type: 0 | 1 | 2 | 3, data?: any) => void, // 0 创建 1 查看 2 复制
  57. isBack?: boolean, // 是否需要回填
  58. }
  59. function FlieBox(props: Props) {
  60. const { isAll = true, height, noFile = false, setPage, isBack = false } = props
  61. const { state, set, dels, list, get, onFile, allFile, delPupOn, delPupOff, changeClickFile, editFile, fileClick, treeClick, pathClick, getList, edit_media_folder, get_folder_tree } = useModel(isAll ? 'useLaunchAdq.useBdMedia' : 'useLaunchAdq.useBdMediaPup')
  62. const { fileVisible, belongUser, selectFile, selectItem, delPupId, xy, rightClickPup, path, publicPath, parentId, imgVisrible, imgsVisrible, mediaType, sortVisible, num } = state
  63. const { copy } = useCopy()
  64. const fileImg = require('../../../public/file.png')
  65. const [moveId, setMoveId] = useState<any>('')//移动的素材ID
  66. const [treeEl, item, folderId, setActionId, setHoverId] = TreeBox({ data: get_folder_tree.data, belongUser })
  67. const [listData, setListData] = useState<any>({})
  68. const [showImg, setShowImg] = useState(-1)
  69. /********************************/
  70. let moveSelected = document.getElementById("moveSelected"); // 选区
  71. let fileContent = document.getElementById("file_content"); // 内容区
  72. const [startPoint, setStartPoint] = useState({ x: 0, y: 0, flag: false }); // 记录鼠标开始按下坐标 flag 是否开启拖拽
  73. const [isSelect, setIsSelect] = useState<boolean>(false) // 记录是否框选过素材
  74. const [sourceList, setSourceList] = useState<any>({})
  75. const [moveShow, setMoveShow] = useState<boolean>(false)
  76. const [migrateSc, setMigrateSc] = useState<boolean>(false)
  77. /********************************/
  78. // 处理数据
  79. useEffect(() => {
  80. let newList: any = {}
  81. listData?.records?.forEach((item: { id: number }) => {
  82. newList[item.id] = JSON.parse(JSON.stringify(item))
  83. })
  84. setSourceList(newList)
  85. }, [listData?.records])
  86. // 获取数据
  87. useEffect(() => {
  88. setListData(list?.data)
  89. }, [list, mediaType])
  90. /**复制编号 */
  91. const copyId = useCallback((e: React.MouseEvent<HTMLSpanElement, MouseEvent>, value: string) => {
  92. e.stopPropagation()//阻止冒泡传递到文件夹被点击事件
  93. copy(value)
  94. }, [])
  95. /**全局右键菜单 */
  96. const Menu = useCallback((props: { isItem?: boolean }) => {
  97. if (props.isItem && isAll) {
  98. return <ul style={{ top: xy?.y, left: xy?.x }} className={style.menu} >
  99. {(isAll || num === 100) && <li onClick={() => allFile('xz')}>全选</li>}
  100. {(isAll || num === 100) && listData?.records && listData?.records?.some((item: { id: number }) => selectFile?.includes(item.id)) && <li onClick={() => allFile('qx')} style={{ color: 'red' }}>取消选择</li>}
  101. {(isAll && selectItem?.length > 0 && ['IMG', 'VIDEO'].includes(mediaType || '') && selectItem.every((item: any) => !item.folder)) && <li onClick={() => { setMigrateSc(true) }} style={{ color: 'red' }}>迁移素材</li>}
  102. {mediaType === 'PAGE' && !rightClickPup.folder ? <>
  103. {/* <li onClick={() => { setPage && setPage(1, rightClickPup.id) }}>查看</li> */}
  104. <li onClick={() => { setPage && setPage(2, rightClickPup.id) }}>复制</li>
  105. <li onClick={() => { setPage && setPage(3, rightClickPup.id) }}>批量复制</li>
  106. </> : <>
  107. <li onClick={() => { editFile() }}>编辑</li>
  108. </>}
  109. {mediaType !== 'PAGE' && !rightClickPup.folder && <li onClick={() => { copy(rightClickPup?.url) }}>复制链接</li>}
  110. <li onClick={() => { set({ actionItem: rightClickPup, sortVisible: true }) }}>编辑排序</li>
  111. <li onClick={() => { set({ fileVisible: true }) }}>新建文件夹</li>
  112. <li onClick={() => { set({ imgVisrible: true }) }}>新建素材</li>
  113. {isAll && selectFile && selectFile?.length > 0 && <li onClick={() => { setMoveShow(true) }}>移动至</li>}
  114. <li onClick={(e) => { delPupOn(rightClickPup.id); onFile(e, rightClickPup, isAll, true) }} style={{ color: 'red' }}>删除</li>
  115. {isAll && selectFile && selectFile?.length > 0 && <li onClick={dels} style={{ color: 'red' }}>删除选中文件</li>}
  116. </ul>
  117. }
  118. return <ul style={{ top: xy?.y, left: xy?.x }} className={style.menu}>
  119. {(isAll || num === 100) && <li onClick={() => allFile('xz')}>全选</li>}
  120. {(isAll || num === 100) && listData?.records && listData?.records?.some((item: { id: number }) => selectFile?.includes(item.id)) && <li onClick={() => allFile('qx')} style={{ color: 'red' }}>取消选择</li>}
  121. {(isAll && selectItem?.length > 0 && ['IMG', 'VIDEO'].includes(mediaType || '') && selectItem.every((item: any) => !item.folder)) && <li onClick={() => { setMigrateSc(true) }} style={{ color: 'red' }}>迁移素材</li>}
  122. {//防止K图文无限嵌套创建判断
  123. (isAll !== false) && <li onClick={() => { set({ fileVisible: true }) }}>新建文件夹</li> //: <li>此处无法新建操作</li>
  124. }
  125. {mediaType === 'PAGE' ? isAll ? <li onClick={() => { setPage && setPage(0) }}>新建素材</li> : <li>此处无法新建操作</li> : <li onClick={() => { set({ imgVisrible: true }) }}>新建素材</li>}
  126. {mediaType === 'IMG' && <li onClick={() => { set({ imgsVisrible: true }) }}>批量新建素材</li>}
  127. {isAll && selectFile && selectFile?.length > 0 && <li onClick={dels} style={{ color: 'red' }}>删除选中文件</li>}
  128. </ul>
  129. }, [xy, rightClickPup, allFile, mediaType])
  130. /**鼠标右键 */
  131. const rightMenu = useCallback((e: any, isItem?: any) => {
  132. e.stopPropagation()
  133. e.preventDefault()
  134. let x = e.clientX;
  135. let y = e.clientY;
  136. set({ xy: { x, y } })
  137. if (isItem) {
  138. set({ rightClickPup: isItem })
  139. } else {
  140. set({ rightClickPup: { id: 'all' } })
  141. }
  142. return false;
  143. }, [])
  144. /**左键点击页面隐藏菜单 */
  145. useEffect(() => {
  146. function fnc(e: any) {
  147. set({ rightClickPup: { id: '' } })
  148. }
  149. document.addEventListener('click', fnc)
  150. return () => {
  151. document.removeEventListener('click', fnc)
  152. }
  153. }, [])
  154. // /**切换个人|公共|父目录ID变化清空选中的文件*/
  155. useEffect(() => {
  156. if (!isBack) {
  157. set({ selectFile: [], selectItem: [] })
  158. }
  159. if (belongUser == '1' && path) {//处理切换个人|公共时保留路径层级的请求
  160. set({ parentId: path[path?.length - 1]?.id || null })
  161. }
  162. if (belongUser == '0' && publicPath) {
  163. set({ parentId: publicPath[publicPath?.length - 1]?.id || null })
  164. }
  165. }, [belongUser, parentId, path?.length, publicPath?.length])
  166. /**卸载组件处理 */
  167. useEffect(() => {
  168. return () => {
  169. set({ parentId: null })
  170. }
  171. }, [])
  172. /**获取目录树*/
  173. useEffect(() => {
  174. get_folder_tree.run({ belongUser, mediaType })
  175. }, [isAll, mediaType, belongUser])
  176. // 点击目录树进入对应目录
  177. useEffect(() => {
  178. if (item) {
  179. let { icon, children, ...arg } = item
  180. treeClick(arg)
  181. }
  182. }, [item])
  183. // 拖动事件配置
  184. const moveConfig = useCallback((item: any) => {
  185. return {
  186. draggable: true,
  187. onDragStart: (ev: any) => {
  188. let img = document.createElement('img')
  189. img.src = fileImg;
  190. ev.dataTransfer.setDragImage(img, 0, 0)
  191. console.log('item---->', item)
  192. setMoveId(item.id)
  193. },
  194. onDragEnd: (e: any) => {
  195. if (folderId !== '' && moveId !== '') {
  196. edit_media_folder.run({ sysMediaId: moveId, folderId, mediaType }).then(res => {
  197. message.success('操作成功')
  198. list.refresh()
  199. })
  200. }
  201. setActionId('')
  202. setHoverId('')
  203. setMoveId('')
  204. },
  205. }
  206. }, [folderId, moveId, mediaType])
  207. /** 判断2个元素是否重合 */
  208. const elementsOverlap = (el1: HTMLElement, el2: HTMLElement) => {
  209. const domRect1 = el1.getBoundingClientRect();
  210. const domRect2 = el2.getBoundingClientRect();
  211. return !(
  212. domRect1.top > domRect2.bottom ||
  213. domRect1.right < domRect2.left ||
  214. domRect1.bottom < domRect2.top ||
  215. domRect1.left > domRect2.right
  216. );
  217. }
  218. /**记录鼠标down event */
  219. const onMouseDown = ({ target: { dataset }, pageX, pageY }: any) => {
  220. const { type } = dataset
  221. if (isBack && num !== 100) return
  222. if (moveSelected && type === 'right-boxzones') {
  223. moveSelected.style.top = pageY + 'px';
  224. moveSelected.style.left = pageX + 'px';
  225. setStartPoint({ x: pageX, y: pageY, flag: true })
  226. }
  227. }
  228. /**记录鼠标抬起事件 */
  229. const onMouseUp = () => {
  230. if (startPoint.flag && moveSelected) {
  231. setStartPoint({ x: 0, y: 0, flag: false })
  232. moveSelected.style.width = '0px';
  233. moveSelected.style.height = '0px';
  234. moveSelected.style.top = '0px';
  235. moveSelected.style.left = '0px';
  236. moveSelected.style.bottom = '0px';
  237. moveSelected.style.right = '0px';
  238. }
  239. }
  240. /** 鼠标移动事件 */
  241. const onMouseMove = ({ pageX, pageY }: any) => {
  242. const { x, y, flag } = startPoint
  243. if (flag) {
  244. if (moveSelected) {
  245. if (pageX < x) { //表示左移
  246. moveSelected.style.left = pageX + 'px';
  247. moveSelected.style.width = (x - pageX) + 'px'; //向左移动的距离作为选区的宽
  248. } else {
  249. moveSelected.style.width = (pageX - x) + 'px';
  250. }
  251. if (pageY < y) { //向上移动
  252. moveSelected.style.top = pageY + 'px';
  253. moveSelected.style.height = (y - pageY) + 'px';
  254. } else {
  255. moveSelected.style.height = (pageY - y) + 'px';
  256. }
  257. //通过得到的left和top加上元素自身的宽高来计算选区的right和bottom
  258. moveSelected.style.bottom = Number(moveSelected.style.top.split('px')[0]) + Number(moveSelected.style.height.split('px')[0]) + 'px';
  259. moveSelected.style.right = Number(moveSelected.style.left.split('px')[0]) + Number(moveSelected.style.width.split('px')[0]) + 'px';
  260. if (fileContent && fileContent?.children?.length > 0) {
  261. //找出选中的区域并激活
  262. let checkboxs: any = fileContent?.children
  263. for (let i = 0; i < checkboxs?.length; i++) {
  264. let id = checkboxs[i]?.getAttribute('data-id')
  265. if (elementsOverlap(moveSelected, checkboxs[i]) && id) {
  266. id = Number(id)
  267. let state = selectFile?.some((i) => i === id)
  268. if (!state) {//新增
  269. setIsSelect(true)
  270. set({ selectFile: [...selectFile as number[], id] })
  271. if (isBack) {
  272. set({ selectItem: [...selectItem, sourceList[id]] })
  273. }
  274. }
  275. }
  276. }
  277. }
  278. }
  279. }
  280. }
  281. /** 鼠标离开可拖动区域事件 */
  282. const onMouseLeave = () => {
  283. if (startPoint.flag && moveSelected) {
  284. setStartPoint({ x: 0, y: 0, flag: false })
  285. moveSelected.style.width = '0px';
  286. moveSelected.style.height = '0px';
  287. moveSelected.style.top = '0px';
  288. moveSelected.style.left = '0px';
  289. }
  290. }
  291. // 获取拖拽的文件
  292. const [fileList, setFileList] = useState<FileList>()
  293. const [uploadVisible, setUploadVisible] = useState<boolean>(false)
  294. const { isDragOver, dropAreaProps } = useFileDrop((fileList) => {
  295. if (!moveId) {
  296. setFileList(fileList)
  297. setUploadVisible(true)
  298. }
  299. });
  300. return <div style={{ display: 'flex', flexFlow: 'row', width: '100%', padding: get_folder_tree?.data?.length ? 0 : '0 16px 0' }}>
  301. {get_folder_tree?.data?.length > 0 && <div style={{ flexShrink: 0 }}>
  302. {treeEl}
  303. </div>}
  304. <div
  305. style={{ flex: 1, padding: '10px 0px 0px' }}
  306. data-type="right-boxzones"
  307. onMouseDown={onMouseDown}
  308. onMouseUp={onMouseUp}
  309. onMouseLeave={onMouseLeave}
  310. onMouseMove={onMouseMove}
  311. onDoubleClick={() => {
  312. if (isSelect) {
  313. set({ selectItem: [] }); set({ selectFile: [] })
  314. }
  315. }}
  316. >
  317. <div
  318. className={style.files}
  319. data-type="right-boxzones"
  320. onContextMenu={rightMenu}
  321. style={height ? { height } : {}}
  322. {...(mediaType !== 'PAGE' ? dropAreaProps : {})}
  323. >
  324. {mediaType !== 'PAGE' && isDragOver && !moveId && <div className={`${style.placeholder} ${isDragOver ? style.dragOver : ''}`}><span>拖动文件到这里</span></div>}
  325. {/* 层级路径 */}
  326. <div className={style.path} >
  327. {//存在渲染个人本地路径不存在执行公共本地
  328. belongUser == '1' && path?.map((item: { title: string }, index: number) => {
  329. return <span key={index} onClick={() => { pathClick({ ...item, index }) }} >
  330. <span className={path?.length !== index + 1 ? style.path_color : ''}>{item?.title}</span>
  331. {path?.length !== index + 1 && <span className={style.rt} >{'>'}</span>}
  332. </span>
  333. })
  334. }
  335. {belongUser == '0' && publicPath?.map((item: { title: string }, index: number) => {
  336. return <span key={index} onClick={() => { pathClick({ ...item, index }) }} >
  337. <span className={publicPath?.length !== index + 1 ? style.path_color : ''}>{item?.title}</span>
  338. {publicPath?.length !== index + 1 && <span className={style.rt} >{'>'}</span>}
  339. </span>
  340. })}
  341. </div>
  342. {/* 内容 */}
  343. <Spin spinning={list.loading} style={{ width: '100%' }}>
  344. <div className={style.file_content} data-type="right-boxzones" id="file_content">
  345. {listData?.records?.map((item: Item, index: number) => {
  346. if (item.folder) {
  347. {/* 文件夹模板 */ }
  348. return <Popconfirm
  349. title="确定要删除吗?"
  350. onConfirm={() => { dels(item) }}
  351. okText="是"
  352. cancelText="否"
  353. onCancel={delPupOff}
  354. open={delPupId === item.id}
  355. key={item.id}
  356. >
  357. <Spin tip='正在请求素材详情,请耐心等待...' spinning={get?.loading}>
  358. <div
  359. className={`${style.flex_box} ${selectFile?.some((id: number) => id === item.id) ? style.action : ''}`}
  360. onContextMenu={(e) => { rightMenu(e, item) }}
  361. onClick={(e) => {
  362. e.stopPropagation()
  363. e.preventDefault()
  364. changeClickFile(e, item, isAll, noFile)
  365. }}
  366. onDragStart={(e: any) => {
  367. e.preventDefault()
  368. }}
  369. >
  370. <img src={fileImg}
  371. className={style.flex_box_img}
  372. onClick={(e: any) => { e.stopPropagation(); fileClick(item) }}
  373. onDragOver={(ev) => {
  374. ev.preventDefault()
  375. }}
  376. onDrop={() => {
  377. if (item.id !== folderId) {
  378. setActionId(item.id)
  379. }
  380. }}
  381. />
  382. <span className={style.flex_box_name} >{item?.title}</span>
  383. <span className={style.flex_box_id} onClick={(e) => { copyId(e, item?.number) }} >{item?.number}</span>
  384. </div>
  385. </Spin>
  386. </Popconfirm>
  387. } else {
  388. {/* 图片模板 ,视频模板,音频模板*/ }
  389. let topPageElements: any
  390. let topName: string = ""
  391. if (mediaType === 'PAGE' && item?.pageSpecsList) {
  392. topPageElements = item?.pageSpecsList[0]?.pageElementsSpecList[0]
  393. }
  394. let El = null
  395. if (mediaType === 'IMG') {
  396. El = <Image
  397. rootClassName={style.imgData}
  398. src={item.url}
  399. onClick={(e) => {
  400. e.stopPropagation()
  401. let className = (e.target as any).className
  402. if (className === 'ant-image-mask-info') {
  403. setShowImg(index)
  404. } else {
  405. changeClickFile(e, item, isAll, noFile)
  406. }
  407. }}
  408. preview={{
  409. visible: showImg === index,
  410. maskClassName: style.maskClass,
  411. onVisibleChange: (value) => {
  412. if (!value) {
  413. setShowImg(-1)
  414. }
  415. }
  416. }}
  417. />
  418. } else if (mediaType === 'VIDEO') {
  419. El = <VideoNews src={item.url} />
  420. } else if (mediaType === 'PAGE') {
  421. switch (topPageElements?.elementType) {
  422. case 'TOP_IMAGE':
  423. topName = "顶部图片"
  424. El = <Image
  425. src={topPageElements?.topImageSpec?.imageUrl}
  426. preview={{ visible: false, maskClassName: style.maskClass }}
  427. onClick={(e) => {
  428. e.stopPropagation()
  429. let className = (e.target as any).className
  430. if (className === 'ant-image-mask-info') {
  431. setPage && setPage(1, item.id)
  432. } else {
  433. changeClickFile(e, item, isAll, noFile)
  434. }
  435. }}
  436. />
  437. break
  438. case 'TOP_SLIDER':
  439. topName = "顶部轮播图"
  440. El = <>
  441. <Carousel autoplay style={{ width: 150, textAlign: 'center' }}>
  442. {topPageElements?.topSliderSpec?.imageUrlList?.map((url: string, index: number) => <div key={index}>
  443. <Image
  444. preview={{ visible: false, maskClassName: style.maskClass }}
  445. src={url}
  446. onClick={(e) => {
  447. e.stopPropagation()
  448. let className = (e.target as any).className
  449. if (className === 'ant-image-mask-info') {
  450. setPage && setPage(1, item.id)
  451. } else {
  452. changeClickFile(e, item, isAll, noFile)
  453. }
  454. }} />
  455. </div>)}
  456. </Carousel>
  457. </>
  458. break
  459. case 'TOP_VIDEO':
  460. topName = "顶部视频"
  461. El = <Image
  462. src={getVideoImgUrl(topPageElements?.topVideoSpec?.videoUrl)}
  463. preview={{ visible: false, maskClassName: style.maskClass }}
  464. onClick={(e) => {
  465. e.stopPropagation()
  466. let className = (e.target as any).className
  467. if (className === 'ant-image-mask-info') {
  468. setPage && setPage(1, item.id)
  469. } else {
  470. changeClickFile(e, item, isAll, noFile)
  471. }
  472. }}
  473. />
  474. break
  475. }
  476. }
  477. return <Popconfirm
  478. title="确定要删除吗?"
  479. onConfirm={() => { dels(item.id) }}
  480. okText="是"
  481. cancelText="否"
  482. onCancel={delPupOff}
  483. open={delPupId === item.id}
  484. key={item.id}
  485. >
  486. <Spin tip='正在请求素材详情,请耐心等待...' spinning={get?.loading} data-id={item.id}>
  487. <div
  488. className={`${style.image_box} ${!isBack ? (selectFile?.some((id: number) => id === item.id) ? style.action : '') : (selectItem?.some((item1: { url: string }) => item1.url === item.url) ? style.action : '')}`}
  489. onContextMenu={(e) => { rightMenu(e, item) }}
  490. onClick={(e) => { changeClickFile(e, item, isAll) }}
  491. {...moveConfig(item)}
  492. >
  493. <span className={`${style.select}`} onClick={(e) => { changeClickFile(e, item, isAll) }}>
  494. <span role="img" aria-label="check" style={{ color: '#fff' }}><svg viewBox="64 64 896 896" focusable="false" data-icon="check" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 00-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"></path></svg></span>
  495. </span>
  496. {El}
  497. <span className={style.flex_box_name} onClick={(e) => { copyId(e, item?.videoTitle || item?.title) }}>{item?.videoTitle || item?.title}</span>
  498. {mediaType === 'PAGE' ? <span>{topName}</span> : <span>{item?.width}*{item.height}</span>}
  499. </div>
  500. </Spin>
  501. </Popconfirm>
  502. }
  503. })}
  504. </div>
  505. </Spin>
  506. {/* 鼠标右键菜单 */}
  507. {rightClickPup.id ? rightClickPup.id === 'all' ? <Menu /> : <Menu isItem /> : null}
  508. {/* 新建文件弹窗 */}
  509. {fileVisible && <FileModal isAll={isAll} />}
  510. {/* 编辑排序 */}
  511. {sortVisible && <SortModal isAll={isAll} />}
  512. {/* 新建非图文 */}
  513. {imgVisrible && <ImgModal isAll={isAll} />}
  514. {imgsVisrible && <ImgsModal isAll={isAll} />}
  515. {/* 移动至 */}
  516. {moveShow && <MoveTo visible={moveShow} onClose={() => setMoveShow(false)} isAll={isAll} catalogueData={get_folder_tree.data} />}
  517. </div>
  518. <div className={style.pagination}>
  519. {/* 分页 */}
  520. {listData?.records?.length > 0 && <Pagination
  521. showSizeChanger
  522. onChange={(page: number, pageSize?: number) => {
  523. getList({ pageSize, pageNum: page })
  524. }}
  525. onShowSizeChange={(current: number, size: number) => {
  526. getList({ pageSize: size, pageNum: current })
  527. }}
  528. pageSizeOptions={['10', '20', '30', '50', '100']}
  529. current={listData?.current}
  530. defaultPageSize={30}
  531. total={listData?.total}
  532. />}
  533. </div>
  534. <div className={style.moveSelected} id='moveSelected' />
  535. </div>
  536. {uploadVisible && <UploadsTable
  537. parentId={parentId}
  538. belongUser={belongUser}
  539. mediaType={mediaType}
  540. visible={uploadVisible}
  541. fileList={fileList}
  542. onClose={() => {
  543. setUploadVisible(false)
  544. setFileList(undefined)
  545. }}
  546. onChange={() => {
  547. setUploadVisible(false)
  548. setFileList(undefined)
  549. list.refresh()
  550. }}
  551. />}
  552. {/* 迁移素材 */}
  553. {migrateSc && <Migrate
  554. visible={migrateSc}
  555. mediaType={mediaType as any}
  556. selectSc={selectItem}
  557. onClose={() => {
  558. setMigrateSc(false)
  559. }}
  560. />}
  561. </div>
  562. }
  563. export default React.memo(FlieBox)