import useCopy from "@/Hook/useCopy" import React, { useCallback, useEffect, useState } from "react" import { Carousel, Image, message, Pagination, Popconfirm, Spin } from 'antd' import style from './index.less' import FileModal from './components/fileModal' import { useModel } from "umi" import ImgModal from "./components/imgModal" import TreeBox from "./components/tree" import SortModal from "./components/fileModal/sortModal" import { EyeOutlined } from "@ant-design/icons" import ImgsModal from "./components/imgsModal" import MoveTo from "./components/moveTo" import VideoNews from "@/pages/launchSystemNew/components/newsModal/videoNews" import { getVideoImgUrl } from "@/utils/utils" import useFileDrop from "@/Hook/useFileDrop" import { RcFile } from "antd/lib/upload" import UploadsTable from "./components/uploadsTable" import Migrate from "./components/Migrate" interface News { id: number, sysMediaId: number, sortIndex: number, title: string, thumbUrl: string, author: string, digest: string, showCoverPic: boolean, content: string,//内容只在调取详情时获取 contentSourceUrl: string,//文章地址 needOpenComment: boolean, onlyFansCanComment: boolean } interface Item { id: number, folder: boolean,//是否是文件夹 mediaType: 'VIDEO' | 'IMG' | 'PAGE',//类型 number: string,//编号 title: string,//名称 url: string,//链接 belongType: string,//所属类型 createTime: string,//创建时间 description: string,//k图文描述 news?: News[]//图文内容 knewsThumbUrl: string, // 图片链接 knewsThumbId: number,//本地图片ID knewsThumbInfo: any,//k客服详情 videoTitle: string,//视频标题 width: number, // 宽 height: number, // 高 pageSpecsList?: any[], } interface Props { isAll?: boolean,//是否允许全选默认开启 height?: any,//当使用为弹窗组件时设置高度以免太高 noFile?: boolean,//是否禁止选择文件夹 setPage?: (type: 0 | 1 | 2 | 3, data?: any) => void, // 0 创建 1 查看 2 复制 isBack?: boolean, // 是否需要回填 } function FlieBox(props: Props) { const { isAll = true, height, noFile = false, setPage, isBack = false } = props 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') const { fileVisible, belongUser, selectFile, selectItem, delPupId, xy, rightClickPup, path, publicPath, parentId, imgVisrible, imgsVisrible, mediaType, sortVisible, num } = state const { copy } = useCopy() const fileImg = require('../../../public/file.png') const [moveId, setMoveId] = useState('')//移动的素材ID const [treeEl, item, folderId, setActionId, setHoverId] = TreeBox({ data: get_folder_tree.data, belongUser }) const [listData, setListData] = useState({}) const [showImg, setShowImg] = useState(-1) /********************************/ let moveSelected = document.getElementById("moveSelected"); // 选区 let fileContent = document.getElementById("file_content"); // 内容区 const [startPoint, setStartPoint] = useState({ x: 0, y: 0, flag: false }); // 记录鼠标开始按下坐标 flag 是否开启拖拽 const [isSelect, setIsSelect] = useState(false) // 记录是否框选过素材 const [sourceList, setSourceList] = useState({}) const [moveShow, setMoveShow] = useState(false) const [migrateSc, setMigrateSc] = useState(false) /********************************/ // 处理数据 useEffect(() => { let newList: any = {} listData?.records?.forEach((item: { id: number }) => { newList[item.id] = JSON.parse(JSON.stringify(item)) }) setSourceList(newList) }, [listData?.records]) // 获取数据 useEffect(() => { setListData(list?.data) }, [list, mediaType]) /**复制编号 */ const copyId = useCallback((e: React.MouseEvent, value: string) => { e.stopPropagation()//阻止冒泡传递到文件夹被点击事件 copy(value) }, []) /**全局右键菜单 */ const Menu = useCallback((props: { isItem?: boolean }) => { if (props.isItem && isAll) { return
    {(isAll || num === 100) &&
  • allFile('xz')}>全选
  • } {(isAll || num === 100) && listData?.records && listData?.records?.some((item: { id: number }) => selectFile?.includes(item.id)) &&
  • allFile('qx')} style={{ color: 'red' }}>取消选择
  • } {(isAll && selectItem?.length > 0 && ['IMG', 'VIDEO'].includes(mediaType || '') && selectItem.every((item: any) => !item.folder)) &&
  • { setMigrateSc(true) }} style={{ color: 'red' }}>迁移素材
  • } {mediaType === 'PAGE' && !rightClickPup.folder ? <> {/*
  • { setPage && setPage(1, rightClickPup.id) }}>查看
  • */}
  • { setPage && setPage(2, rightClickPup.id) }}>复制
  • { setPage && setPage(3, rightClickPup.id) }}>批量复制
  • : <>
  • { editFile() }}>编辑
  • } {mediaType !== 'PAGE' && !rightClickPup.folder &&
  • { copy(rightClickPup?.url) }}>复制链接
  • }
  • { set({ actionItem: rightClickPup, sortVisible: true }) }}>编辑排序
  • { set({ fileVisible: true }) }}>新建文件夹
  • { set({ imgVisrible: true }) }}>新建素材
  • {isAll && selectFile && selectFile?.length > 0 &&
  • { setMoveShow(true) }}>移动至
  • }
  • { delPupOn(rightClickPup.id); onFile(e, rightClickPup, isAll, true) }} style={{ color: 'red' }}>删除
  • {isAll && selectFile && selectFile?.length > 0 &&
  • 删除选中文件
  • }
} return
    {(isAll || num === 100) &&
  • allFile('xz')}>全选
  • } {(isAll || num === 100) && listData?.records && listData?.records?.some((item: { id: number }) => selectFile?.includes(item.id)) &&
  • allFile('qx')} style={{ color: 'red' }}>取消选择
  • } {(isAll && selectItem?.length > 0 && ['IMG', 'VIDEO'].includes(mediaType || '') && selectItem.every((item: any) => !item.folder)) &&
  • { setMigrateSc(true) }} style={{ color: 'red' }}>迁移素材
  • } {//防止K图文无限嵌套创建判断 (isAll !== false) &&
  • { set({ fileVisible: true }) }}>新建文件夹
  • //:
  • 此处无法新建操作
  • } {mediaType === 'PAGE' ? isAll ?
  • { setPage && setPage(0) }}>新建素材
  • :
  • 此处无法新建操作
  • :
  • { set({ imgVisrible: true }) }}>新建素材
  • } {mediaType === 'IMG' &&
  • { set({ imgsVisrible: true }) }}>批量新建素材
  • } {isAll && selectFile && selectFile?.length > 0 &&
  • 删除选中文件
  • }
}, [xy, rightClickPup, allFile, mediaType]) /**鼠标右键 */ const rightMenu = useCallback((e: any, isItem?: any) => { e.stopPropagation() e.preventDefault() let x = e.clientX; let y = e.clientY; set({ xy: { x, y } }) if (isItem) { set({ rightClickPup: isItem }) } else { set({ rightClickPup: { id: 'all' } }) } return false; }, []) /**左键点击页面隐藏菜单 */ useEffect(() => { function fnc(e: any) { set({ rightClickPup: { id: '' } }) } document.addEventListener('click', fnc) return () => { document.removeEventListener('click', fnc) } }, []) // /**切换个人|公共|父目录ID变化清空选中的文件*/ useEffect(() => { if (!isBack) { set({ selectFile: [], selectItem: [] }) } if (belongUser == '1' && path) {//处理切换个人|公共时保留路径层级的请求 set({ parentId: path[path?.length - 1]?.id || null }) } if (belongUser == '0' && publicPath) { set({ parentId: publicPath[publicPath?.length - 1]?.id || null }) } }, [belongUser, parentId, path?.length, publicPath?.length]) /**卸载组件处理 */ useEffect(() => { return () => { set({ parentId: null }) } }, []) /**获取目录树*/ useEffect(() => { get_folder_tree.run({ belongUser, mediaType }) }, [isAll, mediaType, belongUser]) // 点击目录树进入对应目录 useEffect(() => { if (item) { let { icon, children, ...arg } = item treeClick(arg) } }, [item]) // 拖动事件配置 const moveConfig = useCallback((item: any) => { return { draggable: true, onDragStart: (ev: any) => { let img = document.createElement('img') img.src = fileImg; ev.dataTransfer.setDragImage(img, 0, 0) console.log('item---->', item) setMoveId(item.id) }, onDragEnd: (e: any) => { if (folderId !== '' && moveId !== '') { edit_media_folder.run({ sysMediaId: moveId, folderId, mediaType }).then(res => { message.success('操作成功') list.refresh() }) } setActionId('') setHoverId('') setMoveId('') }, } }, [folderId, moveId, mediaType]) /** 判断2个元素是否重合 */ const elementsOverlap = (el1: HTMLElement, el2: HTMLElement) => { const domRect1 = el1.getBoundingClientRect(); const domRect2 = el2.getBoundingClientRect(); return !( domRect1.top > domRect2.bottom || domRect1.right < domRect2.left || domRect1.bottom < domRect2.top || domRect1.left > domRect2.right ); } /**记录鼠标down event */ const onMouseDown = ({ target: { dataset }, pageX, pageY }: any) => { const { type } = dataset if (isBack && num !== 100) return if (moveSelected && type === 'right-boxzones') { moveSelected.style.top = pageY + 'px'; moveSelected.style.left = pageX + 'px'; setStartPoint({ x: pageX, y: pageY, flag: true }) } } /**记录鼠标抬起事件 */ const onMouseUp = () => { if (startPoint.flag && moveSelected) { setStartPoint({ x: 0, y: 0, flag: false }) moveSelected.style.width = '0px'; moveSelected.style.height = '0px'; moveSelected.style.top = '0px'; moveSelected.style.left = '0px'; moveSelected.style.bottom = '0px'; moveSelected.style.right = '0px'; } } /** 鼠标移动事件 */ const onMouseMove = ({ pageX, pageY }: any) => { const { x, y, flag } = startPoint if (flag) { if (moveSelected) { if (pageX < x) { //表示左移 moveSelected.style.left = pageX + 'px'; moveSelected.style.width = (x - pageX) + 'px'; //向左移动的距离作为选区的宽 } else { moveSelected.style.width = (pageX - x) + 'px'; } if (pageY < y) { //向上移动 moveSelected.style.top = pageY + 'px'; moveSelected.style.height = (y - pageY) + 'px'; } else { moveSelected.style.height = (pageY - y) + 'px'; } //通过得到的left和top加上元素自身的宽高来计算选区的right和bottom moveSelected.style.bottom = Number(moveSelected.style.top.split('px')[0]) + Number(moveSelected.style.height.split('px')[0]) + 'px'; moveSelected.style.right = Number(moveSelected.style.left.split('px')[0]) + Number(moveSelected.style.width.split('px')[0]) + 'px'; if (fileContent && fileContent?.children?.length > 0) { //找出选中的区域并激活 let checkboxs: any = fileContent?.children for (let i = 0; i < checkboxs?.length; i++) { let id = checkboxs[i]?.getAttribute('data-id') if (elementsOverlap(moveSelected, checkboxs[i]) && id) { id = Number(id) let state = selectFile?.some((i) => i === id) if (!state) {//新增 setIsSelect(true) set({ selectFile: [...selectFile as number[], id] }) if (isBack) { set({ selectItem: [...selectItem, sourceList[id]] }) } } } } } } } } /** 鼠标离开可拖动区域事件 */ const onMouseLeave = () => { if (startPoint.flag && moveSelected) { setStartPoint({ x: 0, y: 0, flag: false }) moveSelected.style.width = '0px'; moveSelected.style.height = '0px'; moveSelected.style.top = '0px'; moveSelected.style.left = '0px'; } } // 获取拖拽的文件 const [fileList, setFileList] = useState() const [uploadVisible, setUploadVisible] = useState(false) const { isDragOver, dropAreaProps } = useFileDrop((fileList) => { if (!moveId) { setFileList(fileList) setUploadVisible(true) } }); return
{get_folder_tree?.data?.length > 0 &&
{treeEl}
}
{ if (isSelect) { set({ selectItem: [] }); set({ selectFile: [] }) } }} >
{mediaType !== 'PAGE' && isDragOver && !moveId &&
拖动文件到这里
} {/* 层级路径 */}
{//存在渲染个人本地路径不存在执行公共本地 belongUser == '1' && path?.map((item: { title: string }, index: number) => { return { pathClick({ ...item, index }) }} > {item?.title} {path?.length !== index + 1 && {'>'}} }) } {belongUser == '0' && publicPath?.map((item: { title: string }, index: number) => { return { pathClick({ ...item, index }) }} > {item?.title} {publicPath?.length !== index + 1 && {'>'}} })}
{/* 内容 */}
{listData?.records?.map((item: Item, index: number) => { if (item.folder) { {/* 文件夹模板 */ } return { dels(item) }} okText="是" cancelText="否" onCancel={delPupOff} open={delPupId === item.id} key={item.id} >
id === item.id) ? style.action : ''}`} onContextMenu={(e) => { rightMenu(e, item) }} onClick={(e) => { e.stopPropagation() e.preventDefault() changeClickFile(e, item, isAll, noFile) }} onDragStart={(e: any) => { e.preventDefault() }} > { e.stopPropagation(); fileClick(item) }} onDragOver={(ev) => { ev.preventDefault() }} onDrop={() => { if (item.id !== folderId) { setActionId(item.id) } }} /> {item?.title} { copyId(e, item?.number) }} >{item?.number}
} else { {/* 图片模板 ,视频模板,音频模板*/ } let topPageElements: any let topName: string = "" if (mediaType === 'PAGE' && item?.pageSpecsList) { topPageElements = item?.pageSpecsList[0]?.pageElementsSpecList[0] } let El = null if (mediaType === 'IMG') { El = { e.stopPropagation() let className = (e.target as any).className if (className === 'ant-image-mask-info') { setShowImg(index) } else { changeClickFile(e, item, isAll, noFile) } }} preview={{ visible: showImg === index, maskClassName: style.maskClass, onVisibleChange: (value) => { if (!value) { setShowImg(-1) } } }} /> } else if (mediaType === 'VIDEO') { El = } else if (mediaType === 'PAGE') { switch (topPageElements?.elementType) { case 'TOP_IMAGE': topName = "顶部图片" El = { e.stopPropagation() let className = (e.target as any).className if (className === 'ant-image-mask-info') { setPage && setPage(1, item.id) } else { changeClickFile(e, item, isAll, noFile) } }} /> break case 'TOP_SLIDER': topName = "顶部轮播图" El = <> {topPageElements?.topSliderSpec?.imageUrlList?.map((url: string, index: number) =>
{ e.stopPropagation() let className = (e.target as any).className if (className === 'ant-image-mask-info') { setPage && setPage(1, item.id) } else { changeClickFile(e, item, isAll, noFile) } }} />
)}
break case 'TOP_VIDEO': topName = "顶部视频" El = { e.stopPropagation() let className = (e.target as any).className if (className === 'ant-image-mask-info') { setPage && setPage(1, item.id) } else { changeClickFile(e, item, isAll, noFile) } }} /> break } } return { dels(item.id) }} okText="是" cancelText="否" onCancel={delPupOff} open={delPupId === item.id} key={item.id} >
id === item.id) ? style.action : '') : (selectItem?.some((item1: { url: string }) => item1.url === item.url) ? style.action : '')}`} onContextMenu={(e) => { rightMenu(e, item) }} onClick={(e) => { changeClickFile(e, item, isAll) }} {...moveConfig(item)} > { changeClickFile(e, item, isAll) }}> {El} { copyId(e, item?.videoTitle || item?.title) }}>{item?.videoTitle || item?.title} {mediaType === 'PAGE' ? {topName} : {item?.width}*{item.height}}
} })}
{/* 鼠标右键菜单 */} {rightClickPup.id ? rightClickPup.id === 'all' ? : : null} {/* 新建文件弹窗 */} {fileVisible && } {/* 编辑排序 */} {sortVisible && } {/* 新建非图文 */} {imgVisrible && } {imgsVisrible && } {/* 移动至 */} {moveShow && setMoveShow(false)} isAll={isAll} catalogueData={get_folder_tree.data} />}
{/* 分页 */} {listData?.records?.length > 0 && { getList({ pageSize, pageNum: page }) }} onShowSizeChange={(current: number, size: number) => { getList({ pageSize: size, pageNum: current }) }} pageSizeOptions={['10', '20', '30', '50', '100']} current={listData?.current} defaultPageSize={30} total={listData?.total} />}
{uploadVisible && { setUploadVisible(false) setFileList(undefined) }} onChange={() => { setUploadVisible(false) setFileList(undefined) list.refresh() }} />} {/* 迁移素材 */} {migrateSc && { setMigrateSc(false) }} />}
} export default React.memo(FlieBox)