import React, { forwardRef, Ref, useContext, useEffect, useImperativeHandle, useRef, useState } from "react" import style from './index.less' import { Breadcrumb, Button, Card, Checkbox, Dropdown, Empty, message, Modal, Pagination, Popconfirm, Radio, Spin, Typography } from "antd" import { DispatchCloudNew } from "." import { deleteBatchApi, delMaterialApi, getFolderListApi, getMaterialListApi } from "@/services/adqV3/cloudNew" import { useAjax } from "@/Hook/useAjax" import { useSize } from "ahooks" import './global.less' import { useModel } from "umi" import { CheckboxValueType } from "antd/lib/checkbox/Group" import MoveFile from "./moveFile" import { ItemType } from "antd/lib/menu/hooks/useItems" import UploadFile from "./uploadFile" import UpdateCreate from "./updateCreate" import { formatSecondsToTime, getVideoImgUrl } from "@/utils/utils" import { ExclamationCircleOutlined } from "@ant-design/icons" import UpdateFile from "./updateFile" import Details from "./details" import useFileDrop from "@/Hook/useFileDrop" import UploadsTable from "./uploadsTable" const { Text } = Typography; interface Props { /** 新增文件夹 */ onAddFolder?: () => void onUpdateFolder?: (data: any) => void onDelFolder?: (id: number, name: string) => void } interface MaterialRef { folderRefresh: () => void search: (value: { searchType: "file" | "folder"; keyword?: string; }) => void } /** * 素材列表 * @returns */ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props, ref1: Ref) => { /********************************/ const { initialState } = useModel('@@initialState'); const { breadcrumdData, setSelectedKeys, setBreadcrumdData, setMaterialParams, materialParams, selectedKeys, treeData, folderCreateBy, findParentKeys, loadedKeys, handleUpdateFolder, batchFolderVisible, setBatchFolderVisible, handleType, setHandleType } = useContext(DispatchCloudNew)!; const ref = useRef(null); const size = useSize(ref); const [folderList, setFolderList] = useState<{ id: number, folderName: string, createBy: number, description?: string }[]>([]) const [rowNum, setRowNum] = useState(0) const [checkedFolderList, setCheckedFolderList] = useState([]) const [checkFolderAll, setCheckFolderAll] = useState(false); const [indeterminateFolder, setIndeterminateFolder] = useState(false); const [moveVisible, setMoveVisible] = useState(false) const [moveType, setMoveType] = useState<'folder' | 'file'>('folder') const [batchType, setBatchType] = useState<'folder' | 'file'>() const [checkedList, setCheckedList] = useState([]) const [uploadVisible, setUploadVisible] = useState(false) const [updateOwnerData, setUpdateOwnerData] = useState<{ visible?: boolean, folderId: number }>({ folderId: 0 }) const [updateFileData, setUpdateFileData] = useState<{ visible?: boolean, initialValues: any }>({ visible: false, initialValues: {} }) const [detailsData, setDetailsData] = useState<{ visible?: boolean, data: any }>({ visible: false, data: {} }) const getFolderList = useAjax((params) => getFolderListApi(params)) const delMaterial = useAjax((params) => delMaterialApi(params)) const deleteBatch = useAjax((params) => deleteBatchApi(params)) const getMaterialList = useAjax((params) => getMaterialListApi(params)) /********************************/ useImperativeHandle(ref1, () => ({ // 刷新文件夹 folderRefresh() { getFolder() }, search(value) { setHandleType('file') setMaterialParams(data => ({ ...data, ...value, pageNum: 1 })) } })); // 根据内容宽度计算列数 useEffect(() => { if (size?.width) { let rowNum = Math.floor((size?.width - 26) / 200) setRowNum(rowNum || 1) } }, [size?.width]) useEffect(() => { cancelSelect() if (isShowFolder()) { // 文件夹 getFolder() } else { // 文件 getFile() } }, [selectedKeys, handleType, materialParams]) /** 获取下级文件夹 */ const getFolder = () => { let parentId: number | undefined; if (selectedKeys?.length) { const parentIdArr = (selectedKeys[0] as string).split('-') const parentIdArrLength = parentIdArr.length parentId = Number(parentIdArr[parentIdArrLength - 1]) } getFolderList.run({ parentId }).then(res => { setFolderList(() => res || []) }) } // 搜索素材 const getFile = () => { let parentId: number | undefined; if (selectedKeys?.length) { const parentIdArr = (selectedKeys[0] as string).split('-') const parentIdArrLength = parentIdArr.length parentId = Number(parentIdArr[parentIdArrLength - 1]) } let params = JSON.parse(JSON.stringify(materialParams)) if (params?.width || params?.height) { params.sizeQueries = [{ width: params?.width, height: params?.height, relation: '=' }] delete params?.width delete params?.height } else { delete params?.sizeQueries } getMaterialList.run({ ...params, folderId: parentId }) } // 文件夹选择 const onCheckboxChange = (checkedValues: CheckboxValueType[]) => { let data: any[] = [] if (batchType === 'folder') { data = folderList } else { data = getMaterialList?.data?.records || [] } setCheckedFolderList(checkedValues) setIndeterminateFolder(!!checkedValues.length && checkedValues.length < data.length); setCheckFolderAll(checkedValues.length === data.length); }; // 取消选择 const cancelSelect = () => { setCheckFolderAll(false) setCheckedFolderList([]) setIndeterminateFolder(false) setCheckedList([]) } // 是否管理员 const isAdmin = () => { return ['999'].includes(initialState?.currentUser?.powerLevel?.toString() || '') } // 是否有权限 const isPermission = (createBy: any) => { return initialState?.currentUser?.userId?.toString() === createBy.toString() } // 文件夹更多 const getItems = (item: any) => { let data: ItemType[] = [] if (isPermission(item.createBy)) { data.push({ label: '编辑', style: { fontSize: 12 }, key: 'edit', onClick: () => onUpdateFolder?.(item) }) if (!!selectedKeys?.[0]) { data.push({ label: '移动', style: { fontSize: 12 }, key: 'move', onClick: () => { setCheckedList([item.id]) setMoveType('folder') setMoveVisible(true) } }) } else if (isAdmin()) { data.push({ label: '修改文件夹所属人', style: { fontSize: 12 }, key: 'createBy', onClick: () => { setUpdateOwnerData({ visible: true, folderId: item.id }) } }) } data.push({ label: 删除, key: 'del', onClick: () => onDelFolder?.(item.id, item?.folderName) }) } else { if (isAdmin() && !selectedKeys?.[0]) { data.push({ label: '修改文件夹所属人', style: { fontSize: 12 }, key: 'createBy', onClick: () => { setUpdateOwnerData({ visible: true, folderId: item.id }) } }) } } return data } // 删除素材 const delFile = (id: number, name: string) => { Modal.confirm({ title: {`删除素材“${name}”`}, icon: , content: '是否确定删除该素材', okText: '确认', cancelText: '取消', className: 'modalResetCss', onOk: () => { return new Promise((resolve: (value: unknown) => void) => { delMaterial.run(id).then(res => { if (res) { message.success('删除成功'); getMaterialList.refresh() resolve('') } }) }) } }); } // 操作素材 更多 const getItemsFile = (item: any) => { let data: ItemType[] = [] if (isPermission(item.createBy)) { data.push({ label:
{ e.stopPropagation() e.preventDefault() setUpdateFileData({ visible: true, initialValues: item }) }}>编辑
, style: { fontSize: 12 }, key: 'edit' }) if (!!selectedKeys?.[0]) { data.push({ label:
{ e.stopPropagation() e.preventDefault() setCheckedList([item.id]) setMoveType('file') setMoveVisible(true) }}>移动
, style: { fontSize: 12 }, key: 'move' }) } data.push({ label:
{ e.stopPropagation() e.preventDefault() delFile(item.id, item?.materialName) }}>删除
, key: 'del' }) } return data } // 是否展示文件夹 const isShowFolder = () => { return handleType === 'folder' } // 获取拖拽的文件 const [fileList, setFileList] = useState() const [uploadsVisible, setUploadsVisible] = useState(false) const { isDragOver, dropAreaProps } = useFileDrop((fileList) => { console.log('fileList--->', fileList) setFileList(fileList) setUploadsVisible(true) }); return
{ setHandleType(e.target.checked ? 'folder' : 'file') setMaterialParams({ pageNum: 1, pageSize: 30 }) setBatchFolderVisible(false) cancelSelect() }} checked={handleType === 'folder'} >是否操作文件夹 {handleType === 'folder' && } {(!selectedKeys?.[0] && handleType === 'folder') && <> } {handleType === 'folder' ? <> {!!selectedKeys?.[0] && } : <> }
{batchFolderVisible ?
{ setCheckedFolderList( e.target.checked ? batchType === 'folder' ? folderList.map(item => item.id) : getMaterialList?.data?.records?.filter((item: { createBy: any }) => isPermission(item.createBy)).map((item: { id: any }) => item.id) : [] ) setIndeterminateFolder(false) setCheckFolderAll(e.target.checked) }} disabled={batchType === 'folder' ? folderList?.length ? false : true : !getMaterialList?.data?.records?.some((item: { createBy: any }) => isPermission(item.createBy))} indeterminate={indeterminateFolder} checked={checkFolderAll} >全选 已选{checkedFolderList?.length || 0}个{batchType === 'file' ? '素材' : '文件夹'}
{batchType === 'file' && { const hide = message.loading('正在删除...', 0, () => {}); deleteBatch.run(checkedFolderList).then(res => { hide() if (res) { getMaterialList.refresh() message.success('删除成功') } }).catch(() => hide()) }} > }
: (materialParams?.materialName || materialParams?.materialType || (materialParams?.designerIds && materialParams?.designerIds?.length > 0) || materialParams?.width || materialParams?.height) ?
搜索「素材」 {materialParams?.materialName && 关键词【{materialParams.materialName}】} {(materialParams?.designerIds && materialParams?.designerIds?.length > 0) && 设计师ID【{materialParams.designerIds.join(',')}】} {materialParams?.materialType && 素材类型【{materialParams.materialType === 'video' ? '视频' : '图片'}】} {materialParams?.width && 素材宽【{materialParams.width}】} {materialParams?.height && 素材高【{materialParams.height}】}
:
{breadcrumdData.map((item, index) => {breadcrumdData.length !== index + 1 ? { setBreadcrumdData(data => data.splice(0, index + 1)) setSelectedKeys(item.currentKey === '0' ? [] : [item.currentKey]) }} >{item.label} : item.label} )}
}
{isDragOver &&
拖动文件到这里
} {(isShowFolder() && folderList.length > 0) || (!isShowFolder() && getMaterialList?.data?.records?.length > 0) ?
{isShowFolder() ? folderList.map((item) =>
{batchFolderVisible &&
}
} onDoubleClick={() => { if (!batchFolderVisible) { let newExpandedKeys = '0-' + item.id if (selectedKeys?.[0]) { newExpandedKeys = selectedKeys[0] + '-' + item.id } findParentKeys(newExpandedKeys, treeData) setSelectedKeys([newExpandedKeys]) // 判断是否加载了下级文件 加载了 就不更新 if (!loadedKeys.includes(newExpandedKeys)) handleUpdateFolder(newExpandedKeys) } }} >
{item?.folderName}
{isPermission(item.createBy) || (!selectedKeys?.[0] && isAdmin()) ? e.preventDefault()} style={{ fontSize: 11 }}>更多 : 无权限操作}
) : getMaterialList?.data?.records.map((item: any) =>
{batchFolderVisible &&
{ e.stopPropagation(); }}>
} {item.materialType === 'video' &&
}
{item.width}*{item.height}
{item.materialType === 'video' &&
{formatSecondsToTime(Math.floor(item.videoDuration))}
}
} onClick={() => { setDetailsData({ visible: true, data: item }) }} >
{item?.materialName}
详情
)}
:
}
{handleType === 'file' &&
{ setMaterialParams({ ...materialParams, pageNum: page, pageSize }) }} />
} {/* 移动文件 素材 */} {moveVisible && { setMoveVisible(false) cancelSelect() }} onChange={(selectedKey: string) => { getFolder() setMoveVisible(false) if (moveType === 'folder') { handleUpdateFolder(selectedKeys[0] as string) if (loadedKeys.includes(selectedKey)) { handleUpdateFolder(selectedKey) } } else { getMaterialList.refresh() } cancelSelect() setBatchFolderVisible(false) }} />} {/* 上传文件 */} {uploadVisible && { setUploadVisible(false) getMaterialList.refresh() }} onClose={() => { setUploadVisible(false) }} />} {/* 修改所属人 */} {updateOwnerData.visible && { setUpdateOwnerData({ visible: false, folderId: 0 }) }} onChange={() => { getFolder() setUpdateOwnerData({ visible: false, folderId: 0 }) }} />} {/* 修改素材 */} {updateFileData?.visible && { setUpdateFileData({ visible: false, initialValues: {} }) }} onChange={() => { getMaterialList.refresh() setUpdateFileData({ visible: false, initialValues: {} }) }} />} {/* 素材详情 */} {detailsData?.visible &&
{ setDetailsData({ visible: false, data: {} }) }} onChange={() => { getMaterialList.refresh() }} />} {/* 拖动上传 */} {uploadsVisible && { setUploadsVisible(false) setFileList(undefined) }} onChange={() => { setUploadsVisible(false) setFileList(undefined) getMaterialList.refresh() }} />} }) export default React.memo(Material)