|
@@ -1,17 +1,23 @@
|
|
|
import React, { forwardRef, Ref, useContext, useEffect, useImperativeHandle, useRef, useState } from "react"
|
|
|
import style from './index.less'
|
|
|
-import { Breadcrumb, Button, Card, Dropdown, Pagination, Spin, Typography } from "antd"
|
|
|
+import { Breadcrumb, Button, Card, Checkbox, Dropdown, Pagination, Radio, Spin, Typography } from "antd"
|
|
|
import { DispatchCloudNew } from "."
|
|
|
import { getFolderListApi } from "@/services/adqV3/cloudNew"
|
|
|
import { useAjax } from "@/Hook/useAjax"
|
|
|
import { useSize } from "ahooks"
|
|
|
-const { Text, Title } = Typography;
|
|
|
+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"
|
|
|
+const { Text } = Typography;
|
|
|
|
|
|
interface Props {
|
|
|
/** 新增文件夹 */
|
|
|
onAddFolder?: () => void
|
|
|
onUpdateFolder?: (data: any) => void
|
|
|
- onDelFolder?: (id: number) => void
|
|
|
+ onDelFolder?: (id: number, name: string) => void
|
|
|
}
|
|
|
|
|
|
interface MaterialRef {
|
|
@@ -24,11 +30,19 @@ interface MaterialRef {
|
|
|
const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props, ref1: Ref<MaterialRef>) => {
|
|
|
|
|
|
/********************************/
|
|
|
- const { breadcrumdData, setExpandedKeys, setBreadcrumdData, expandedKeys } = useContext(DispatchCloudNew)!;
|
|
|
+ const { initialState } = useModel('@@initialState');
|
|
|
+ const { breadcrumdData, setSelectedKeys, setBreadcrumdData, selectedKeys, treeData, folderCreateBy, findParentKeys, loadedKeys, handleUpdateFolder, batchFolderVisible, setBatchFolderVisible, handleType, setHandleType } = useContext(DispatchCloudNew)!;
|
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
|
const size = useSize(ref);
|
|
|
- const [folderList, setFolderList] = useState<{ id: number, folderName: string, description?: string }[]>([])
|
|
|
+ const [folderList, setFolderList] = useState<{ id: number, folderName: string, createBy: number, description?: string }[]>([])
|
|
|
const [rowNum, setRowNum] = useState<number>(0)
|
|
|
+ const [checkedFolderList, setCheckedFolderList] = useState<CheckboxValueType[]>([])
|
|
|
+ const [checkFolderAll, setCheckFolderAll] = useState<boolean>(false);
|
|
|
+ const [indeterminateFolder, setIndeterminateFolder] = useState<boolean>(false);
|
|
|
+ const [moveVisible, setMoveVisible] = useState<boolean>(false)
|
|
|
+ const [moveType, setMoveType] = useState<'folder' | 'file'>('folder')
|
|
|
+ const [checkedList, setCheckedList] = useState<CheckboxValueType[]>([])
|
|
|
+ const [uploadVisible, setUploadVisible] = useState<boolean>(false)
|
|
|
|
|
|
const getFolderList = useAjax((params) => getFolderListApi(params))
|
|
|
/********************************/
|
|
@@ -43,88 +57,228 @@ const Material = forwardRef(({ onAddFolder, onUpdateFolder, onDelFolder }: Props
|
|
|
// 根据内容宽度计算列数
|
|
|
useEffect(() => {
|
|
|
if (size?.width) {
|
|
|
- let rowNum = Math.floor((size?.width - 26) / 240)
|
|
|
+ let rowNum = Math.floor((size?.width - 26) / 200)
|
|
|
setRowNum(rowNum || 1)
|
|
|
}
|
|
|
}, [size?.width])
|
|
|
|
|
|
useEffect(() => {
|
|
|
- getFolder()
|
|
|
- }, [expandedKeys])
|
|
|
+ if (isShowFolder()) {
|
|
|
+ // 文件夹
|
|
|
+ getFolder()
|
|
|
+ } else {
|
|
|
+ // 文件
|
|
|
+ }
|
|
|
+ }, [selectedKeys, handleType])
|
|
|
|
|
|
/** 获取下级文件夹 */
|
|
|
const getFolder = () => {
|
|
|
- if (expandedKeys?.length) {
|
|
|
- const parentIdArr = (expandedKeys[0] as string).split('-')
|
|
|
+ let parentId: number | undefined;
|
|
|
+ if (selectedKeys?.length) {
|
|
|
+ const parentIdArr = (selectedKeys[0] as string).split('-')
|
|
|
const parentIdArrLength = parentIdArr.length
|
|
|
- const parentId = Number(parentIdArr[parentIdArrLength - 1])
|
|
|
- getFolderList.run({ parentId }).then(res => {
|
|
|
- setFolderList(res || [])
|
|
|
- })
|
|
|
+ parentId = Number(parentIdArr[parentIdArrLength - 1])
|
|
|
+ }
|
|
|
+ getFolderList.run({ parentId }).then(res => {
|
|
|
+ setFolderList(() => res || [])
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 文件夹选择
|
|
|
+ const onCheckboxChange = (checkedValues: CheckboxValueType[]) => {
|
|
|
+ setCheckedFolderList(checkedValues)
|
|
|
+ setIndeterminateFolder(!!checkedValues.length && checkedValues.length < folderList.length);
|
|
|
+ setCheckFolderAll(checkedValues.length === folderList.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: () => {
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ data.push({ label: <span style={{ color: 'red', fontSize: 12 }}>删除</span>, key: 'del', onClick: () => onDelFolder?.(item.id, item?.folderName) })
|
|
|
} else {
|
|
|
- setFolderList([])
|
|
|
+ if (isAdmin() && !selectedKeys?.[0]) {
|
|
|
+ data.push({
|
|
|
+ label: '修改文件夹所属人', style: { fontSize: 12 }, key: 'createBy', onClick: () => {
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
+ return data
|
|
|
+ }
|
|
|
+
|
|
|
+ // 是否展示文件夹
|
|
|
+ const isShowFolder = () => {
|
|
|
+ return !selectedKeys?.[0] || handleType === 'folder'
|
|
|
}
|
|
|
|
|
|
return <div className={style.material}>
|
|
|
<div className={style.operates}>
|
|
|
<div className={style.left_bts}>
|
|
|
- <Button type="primary">上传素材</Button>
|
|
|
- <Button onClick={() => onAddFolder?.()}>新建文件夹</Button>
|
|
|
+ {!!selectedKeys?.[0] && <Checkbox
|
|
|
+ onChange={(e) => {
|
|
|
+ setHandleType(e.target.checked ? 'folder' : 'file')
|
|
|
+ }}
|
|
|
+ checked={handleType === 'folder'}
|
|
|
+ ><span style={{ fontSize: 12 }}>是否操作文件夹</span></Checkbox>}
|
|
|
+ {(!selectedKeys?.[0] || handleType === 'folder') && <Button onClick={() => onAddFolder?.()} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>新建文件夹</Button>}
|
|
|
+ {handleType === 'folder' ? <>
|
|
|
+ {!!selectedKeys?.[0] && <Button onClick={() => setBatchFolderVisible(true)} disabled={folderCreateBy ? !isPermission(folderCreateBy) : false}>批量操作文件夹</Button>}
|
|
|
+ </> : <>
|
|
|
+ {!!selectedKeys?.[0] && <Button type="primary" disabled={folderCreateBy ? !isPermission(folderCreateBy) : false} onClick={() => setUploadVisible(true)}>上传素材</Button>}
|
|
|
+ </>}
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div className={style.operates}>
|
|
|
+ {batchFolderVisible ? <div className={style.operates}>
|
|
|
+ <div className={style.left_bts}>
|
|
|
+ <Checkbox onChange={(e) => {
|
|
|
+ setCheckedFolderList(e.target.checked ? folderList.map(item => item.id) : [])
|
|
|
+ setIndeterminateFolder(false)
|
|
|
+ setCheckFolderAll(e.target.checked)
|
|
|
+ }} indeterminate={indeterminateFolder} checked={checkFolderAll}>全选</Checkbox>
|
|
|
+ <span style={{ color: '#1890FF' }}>已选{checkedFolderList?.length || 0}个文件夹</span>
|
|
|
+ </div>
|
|
|
+ <div className={style.left_bts}>
|
|
|
+ <Button disabled={checkedFolderList?.length === 0} onClick={() => {
|
|
|
+ setCheckedList(checkedFolderList)
|
|
|
+ setMoveVisible(true)
|
|
|
+ setMoveType('folder')
|
|
|
+ }}>移动文件夹</Button>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ setBatchFolderVisible(false)
|
|
|
+ }}>完成</Button>
|
|
|
+ </div>
|
|
|
+ </div> : <div className={style.operates}>
|
|
|
<Breadcrumb>
|
|
|
{breadcrumdData.map((item, index) => <Breadcrumb.Item key={item.key}>
|
|
|
{breadcrumdData.length !== index + 1 ? <a
|
|
|
style={{ color: '#1890ff' }}
|
|
|
onClick={() => {
|
|
|
setBreadcrumdData(data => data.splice(0, index + 1))
|
|
|
- setExpandedKeys([item.currentKey])
|
|
|
+ setSelectedKeys(item.currentKey === '0' ? [] : [item.currentKey])
|
|
|
}}
|
|
|
>{item.label}</a> : item.label}
|
|
|
</Breadcrumb.Item>)}
|
|
|
</Breadcrumb>
|
|
|
- </div>
|
|
|
- <div className={style.content}>
|
|
|
+ </div>}
|
|
|
+ <div className={`${style.content} content_global`}>
|
|
|
<Spin spinning={getFolderList.loading}>
|
|
|
<div className={style.content_scroll} ref={ref}>
|
|
|
- <div>
|
|
|
- {folderList.map((item, index) => <div key={index} className={style.content_row} style={{ width: rowNum ? (1 / rowNum * 100) + '%' : 240 }}>
|
|
|
- <Card
|
|
|
- hoverable
|
|
|
- bodyStyle={{ padding: 0 }}
|
|
|
- className={`${style.content_col}`}
|
|
|
- cover={<div style={{ height: 150 }} className={style.content_cover}>
|
|
|
- <img src={require('../../../../../public/file.png')} height={'100%'} alt="" />
|
|
|
- </div>}
|
|
|
- >
|
|
|
- <div className={style.body}>
|
|
|
- <Text ellipsis>{item?.folderName}</Text>
|
|
|
- </div>
|
|
|
- <div className={style.actions}>
|
|
|
- <div></div>
|
|
|
- <Dropdown menu={{
|
|
|
- items: [
|
|
|
- { label: '编辑', key: 'edit', onClick: () => onUpdateFolder?.(item) },
|
|
|
- { label: <span style={{ color: 'red' }}>删除</span>, key: 'del', onClick: () => onDelFolder?.(item.id) }
|
|
|
- ]
|
|
|
- }}>
|
|
|
- <a onClick={e => e.preventDefault()} style={{ fontSize: 12 }}>
|
|
|
- 更多
|
|
|
- </a>
|
|
|
- </Dropdown>
|
|
|
- </div>
|
|
|
- </Card>
|
|
|
- </div>)}
|
|
|
-
|
|
|
- </div>
|
|
|
+ <Checkbox.Group value={checkedFolderList} style={{ width: '100%' }} onChange={onCheckboxChange}>
|
|
|
+ <div className={style.content_scroll_div}>
|
|
|
+ {isShowFolder() ? folderList.map((item, index) => <div key={index} className={style.content_row} style={{ width: rowNum ? (1 / rowNum * 100) + '%' : 200 }}>
|
|
|
+ <Card
|
|
|
+ hoverable
|
|
|
+ bodyStyle={{ padding: 0 }}
|
|
|
+ className={`${style.content_col}`}
|
|
|
+ cover={<div style={{ height: 120 }} className={style.content_cover}>
|
|
|
+ {batchFolderVisible && <div className={style.checkbox}><Checkbox value={item.id} /></div>}
|
|
|
+ <img src={require('../../../../../public/file.png')} height={'100%'} alt="" />
|
|
|
+ </div>}
|
|
|
+ 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)
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <div className={style.body}>
|
|
|
+ <Text ellipsis>{item?.folderName}</Text>
|
|
|
+ </div>
|
|
|
+ <div className={style.actions}>
|
|
|
+ <div style={{ height: 22 }}></div>
|
|
|
+ {isPermission(item.createBy) || (!selectedKeys?.[0] && isAdmin()) ? <Dropdown menu={{
|
|
|
+ items: getItems(item)
|
|
|
+ }}>
|
|
|
+ <a onClick={e => e.preventDefault()} style={{ fontSize: 11 }}>更多</a>
|
|
|
+ </Dropdown> : <a style={{ fontSize: 11 }}>无权限操作</a>}
|
|
|
+ </div>
|
|
|
+ </Card>
|
|
|
+ </div>) : <>
|
|
|
+ 素材
|
|
|
+ </>}
|
|
|
+ </div>
|
|
|
+ </Checkbox.Group>
|
|
|
</div>
|
|
|
</Spin>
|
|
|
</div>
|
|
|
- <div className={style.fotter}>
|
|
|
+ {handleType === 'file' && <div className={style.fotter}>
|
|
|
<Pagination size="small" total={50} showSizeChanger showQuickJumper />
|
|
|
- </div>
|
|
|
+ </div>}
|
|
|
+
|
|
|
+ {/* 移动文件 */}
|
|
|
+ {moveVisible && <MoveFile
|
|
|
+ moveType={moveType}
|
|
|
+ checkedList={checkedList}
|
|
|
+ userId={initialState?.currentUser?.userId?.toString() || ''}
|
|
|
+ visible={moveVisible}
|
|
|
+ onClose={() => {
|
|
|
+ setMoveVisible(false)
|
|
|
+ cancelSelect()
|
|
|
+ }}
|
|
|
+ onChange={(selectedKey: string) => {
|
|
|
+ getFolder()
|
|
|
+ setMoveVisible(false)
|
|
|
+ cancelSelect()
|
|
|
+ handleUpdateFolder(selectedKeys[0] as string)
|
|
|
+ if (loadedKeys.includes(selectedKey)) {
|
|
|
+ handleUpdateFolder(selectedKey)
|
|
|
+ }
|
|
|
+ setBatchFolderVisible(false)
|
|
|
+ }}
|
|
|
+ />}
|
|
|
+
|
|
|
+ {/* 上传文件 */}
|
|
|
+ {uploadVisible && <UploadFile
|
|
|
+ visible={uploadVisible}
|
|
|
+ onChange={() => {
|
|
|
+
|
|
|
+ }}
|
|
|
+ onClose={() => {
|
|
|
+ setUploadVisible(false)
|
|
|
+ }}
|
|
|
+ />}
|
|
|
</div>
|
|
|
})
|
|
|
|