|
@@ -13,11 +13,19 @@ import {
|
|
|
} from '@ant-design/icons'
|
|
} from '@ant-design/icons'
|
|
|
import classNames from 'classnames'
|
|
import classNames from 'classnames'
|
|
|
import { baseURL } from '@/utils/http'
|
|
import { baseURL } from '@/utils/http'
|
|
|
-import { DndContext, DragEndEvent, DragOverlay, DragStartEvent, closestCenter } from '@dnd-kit/core'
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ DndContext,
|
|
|
|
|
+ DragEndEvent,
|
|
|
|
|
+ PointerSensor,
|
|
|
|
|
+ closestCenter,
|
|
|
|
|
+ useSensor,
|
|
|
|
|
+ useSensors
|
|
|
|
|
+} from '@dnd-kit/core'
|
|
|
import {
|
|
import {
|
|
|
SortableContext,
|
|
SortableContext,
|
|
|
useSortable,
|
|
useSortable,
|
|
|
verticalListSortingStrategy,
|
|
verticalListSortingStrategy,
|
|
|
|
|
+ rectSortingStrategy,
|
|
|
arrayMove
|
|
arrayMove
|
|
|
} from '@dnd-kit/sortable'
|
|
} from '@dnd-kit/sortable'
|
|
|
import { CSS } from '@dnd-kit/utilities'
|
|
import { CSS } from '@dnd-kit/utilities'
|
|
@@ -28,56 +36,47 @@ import MyPopconfirm from '../MyPopconfirm'
|
|
|
import { forwardRef, useImperativeHandle } from 'react'
|
|
import { forwardRef, useImperativeHandle } from 'react'
|
|
|
import { authFilesLookFu, FileListType } from './data'
|
|
import { authFilesLookFu, FileListType } from './data'
|
|
|
|
|
|
|
|
-// ----------------这个组件用于外面一级的附件上传
|
|
|
|
|
-
|
|
|
|
|
interface SortableFileItemProps {
|
|
interface SortableFileItemProps {
|
|
|
file: FileListType
|
|
file: FileListType
|
|
|
onDelete: (id: number) => void
|
|
onDelete: (id: number) => void
|
|
|
isLook: boolean
|
|
isLook: boolean
|
|
|
- index: number
|
|
|
|
|
- disabled?: boolean
|
|
|
|
|
- oneIsCover?: boolean
|
|
|
|
|
|
|
+ isCover?: boolean
|
|
|
}
|
|
}
|
|
|
-// 修复性能问题:移除不必要的状态和事件处理
|
|
|
|
|
|
|
+
|
|
|
const SortableFileItem = React.memo(
|
|
const SortableFileItem = React.memo(
|
|
|
- ({ file, onDelete, isLook, index, disabled, oneIsCover }: SortableFileItemProps) => {
|
|
|
|
|
|
|
+ ({ file, onDelete, isLook, isCover }: SortableFileItemProps) => {
|
|
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
|
id: file.id,
|
|
id: file.id,
|
|
|
- disabled: disabled || isLook // 修复拖动禁用问题
|
|
|
|
|
|
|
+ disabled: isLook
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- const style = {
|
|
|
|
|
|
|
+ const style: React.CSSProperties = {
|
|
|
transform: CSS.Transform.toString(transform),
|
|
transform: CSS.Transform.toString(transform),
|
|
|
transition,
|
|
transition,
|
|
|
opacity: isDragging ? 0.5 : 1
|
|
opacity: isDragging ? 0.5 : 1
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 修复按钮点击问题:阻止事件冒泡
|
|
|
|
|
|
|
+ const dragBind = isLook ? undefined : { ...attributes, ...listeners }
|
|
|
|
|
+
|
|
|
const handleButtonClick = useCallback((e: React.MouseEvent, callback: () => void) => {
|
|
const handleButtonClick = useCallback((e: React.MouseEvent, callback: () => void) => {
|
|
|
- e.stopPropagation() // 修复按钮点击无效问题:阻止事件冒泡到拖拽元素
|
|
|
|
|
|
|
+ e.stopPropagation()
|
|
|
callback()
|
|
callback()
|
|
|
}, [])
|
|
}, [])
|
|
|
|
|
|
|
|
|
|
+ const stopPointer = useCallback((e: React.PointerEvent) => {
|
|
|
|
|
+ e.stopPropagation()
|
|
|
|
|
+ }, [])
|
|
|
|
|
+
|
|
|
if (file.type === 'img') {
|
|
if (file.type === 'img') {
|
|
|
return (
|
|
return (
|
|
|
- <div
|
|
|
|
|
- ref={setNodeRef}
|
|
|
|
|
- style={style}
|
|
|
|
|
- className={classNames('ZTbox1ImgRow', isDragging ? 'dragging' : '')}
|
|
|
|
|
- >
|
|
|
|
|
- {/* 修复按钮点击无效问题:将拖拽手柄单独放置,不覆盖操作按钮 */}
|
|
|
|
|
- <div
|
|
|
|
|
- className='ZTbox1ImgRowDragHandle'
|
|
|
|
|
- {...attributes}
|
|
|
|
|
- {...listeners}
|
|
|
|
|
- style={{ cursor: isLook ? 'default' : 'grab' }}
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <div ref={setNodeRef} style={style} className='ZTbox1ImgRow'>
|
|
|
|
|
+ <div className='ZTbox1ImgRowDragHandle' {...dragBind}>
|
|
|
{file.thumb || file.filePath ? (
|
|
{file.thumb || file.filePath ? (
|
|
|
<ImageLazy noLook={true} width={100} height={100} src={file.thumb || file.filePath} />
|
|
<ImageLazy noLook={true} width={100} height={100} src={file.thumb || file.filePath} />
|
|
|
) : null}
|
|
) : null}
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- {oneIsCover && index === 0 ? <div className='ZTbox1ImgRowCover'>封面</div> : null}
|
|
|
|
|
|
|
+ {isCover ? <div className='ZTbox1ImgRowCover'>封面</div> : null}
|
|
|
|
|
|
|
|
<div className='ZTbox1ImgRowIcon'>
|
|
<div className='ZTbox1ImgRowIcon'>
|
|
|
<EyeOutlined
|
|
<EyeOutlined
|
|
@@ -99,7 +98,7 @@ const SortableFileItem = React.memo(
|
|
|
download
|
|
download
|
|
|
target='_blank'
|
|
target='_blank'
|
|
|
rel='noreferrer'
|
|
rel='noreferrer'
|
|
|
- onClick={e => e.stopPropagation()} // 修复按钮点击无效问题
|
|
|
|
|
|
|
+ onClick={e => e.stopPropagation()}
|
|
|
>
|
|
>
|
|
|
<DownloadOutlined rev={undefined} />
|
|
<DownloadOutlined rev={undefined} />
|
|
|
</a>
|
|
</a>
|
|
@@ -113,75 +112,66 @@ const SortableFileItem = React.memo(
|
|
|
<CloseOutlined
|
|
<CloseOutlined
|
|
|
className='ZTbox1ImgRowX'
|
|
className='ZTbox1ImgRowX'
|
|
|
rev={undefined}
|
|
rev={undefined}
|
|
|
- onClick={e => e.stopPropagation()} // 修复按钮点击无效问题
|
|
|
|
|
|
|
+ onClick={e => e.stopPropagation()}
|
|
|
/>
|
|
/>
|
|
|
}
|
|
}
|
|
|
/>
|
|
/>
|
|
|
)}
|
|
)}
|
|
|
</div>
|
|
</div>
|
|
|
)
|
|
)
|
|
|
- } else {
|
|
|
|
|
- return (
|
|
|
|
|
- <div
|
|
|
|
|
- ref={setNodeRef}
|
|
|
|
|
- style={style}
|
|
|
|
|
- className={classNames('Z3filesRow', isDragging ? 'dragging' : '')}
|
|
|
|
|
- >
|
|
|
|
|
- {!isLook && (
|
|
|
|
|
- <div className='dragHandle' {...attributes} {...listeners}>
|
|
|
|
|
- <MenuOutlined rev={undefined} />
|
|
|
|
|
- </div>
|
|
|
|
|
- )}
|
|
|
|
|
- <div className='Z3files1' title={file.fileName}>
|
|
|
|
|
- {file.fileName}
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div ref={setNodeRef} style={style} className='Z3filesRow' {...dragBind}>
|
|
|
|
|
+ {!isLook && (
|
|
|
|
|
+ <div className='dragHandle'>
|
|
|
|
|
+ <MenuOutlined rev={undefined} />
|
|
|
</div>
|
|
</div>
|
|
|
- <div className='Z3files2'>
|
|
|
|
|
- {authFilesLookFu(file.fileName, '') ? (
|
|
|
|
|
- <>
|
|
|
|
|
- <EyeOutlined
|
|
|
|
|
- rev={undefined}
|
|
|
|
|
- title='查看'
|
|
|
|
|
- onClick={e =>
|
|
|
|
|
- handleButtonClick(e, () => authFilesLookFu(file.fileName, file.filePath))
|
|
|
|
|
- }
|
|
|
|
|
- />
|
|
|
|
|
-  
|
|
|
|
|
- </>
|
|
|
|
|
- ) : null}
|
|
|
|
|
- <a
|
|
|
|
|
- title='下载'
|
|
|
|
|
- href={baseURL + file.filePath}
|
|
|
|
|
- download={file.fileName}
|
|
|
|
|
- target='_blank'
|
|
|
|
|
- rel='noreferrer'
|
|
|
|
|
- onClick={e => e.stopPropagation()} // 修复按钮点击无效问题
|
|
|
|
|
|
|
+ )}
|
|
|
|
|
+ <div className='Z3files1' title={file.fileName}>
|
|
|
|
|
+ {file.fileName}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className='Z3files2' onPointerDown={stopPointer}>
|
|
|
|
|
+ {authFilesLookFu(file.fileName, '') ? (
|
|
|
|
|
+ <>
|
|
|
|
|
+ <EyeOutlined
|
|
|
|
|
+ rev={undefined}
|
|
|
|
|
+ title='查看'
|
|
|
|
|
+ onClick={e =>
|
|
|
|
|
+ handleButtonClick(e, () => authFilesLookFu(file.fileName, file.filePath))
|
|
|
|
|
+ }
|
|
|
|
|
+ />
|
|
|
|
|
+  
|
|
|
|
|
+ </>
|
|
|
|
|
+ ) : null}
|
|
|
|
|
+ <a
|
|
|
|
|
+ title='下载'
|
|
|
|
|
+ href={baseURL + file.filePath}
|
|
|
|
|
+ download={file.fileName}
|
|
|
|
|
+ target='_blank'
|
|
|
|
|
+ rel='noreferrer'
|
|
|
|
|
+ onClick={e => e.stopPropagation()}
|
|
|
|
|
+ >
|
|
|
|
|
+ <DownloadOutlined rev={undefined} />
|
|
|
|
|
+ </a>
|
|
|
|
|
+  
|
|
|
|
|
+ {!isLook && (
|
|
|
|
|
+ <Popconfirm
|
|
|
|
|
+ title='删除后无法恢复,是否删除?'
|
|
|
|
|
+ okText='删除'
|
|
|
|
|
+ cancelText='取消'
|
|
|
|
|
+ onConfirm={() => onDelete(file.id)}
|
|
|
|
|
+ okButtonProps={{ loading: false }}
|
|
|
>
|
|
>
|
|
|
- <DownloadOutlined rev={undefined} />
|
|
|
|
|
- </a>
|
|
|
|
|
-  
|
|
|
|
|
- {!isLook && (
|
|
|
|
|
- <Popconfirm
|
|
|
|
|
- title='删除后无法恢复,是否删除?'
|
|
|
|
|
- okText='删除'
|
|
|
|
|
- cancelText='取消'
|
|
|
|
|
- onConfirm={() => onDelete(file.id)}
|
|
|
|
|
- okButtonProps={{ loading: false }}
|
|
|
|
|
- >
|
|
|
|
|
- <CloseOutlined
|
|
|
|
|
- rev={undefined}
|
|
|
|
|
- title='删除'
|
|
|
|
|
- onClick={e => e.stopPropagation()} // 修复按钮点击无效问题
|
|
|
|
|
- />
|
|
|
|
|
- </Popconfirm>
|
|
|
|
|
- )}
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <CloseOutlined rev={undefined} title='删除' onClick={e => e.stopPropagation()} />
|
|
|
|
|
+ </Popconfirm>
|
|
|
|
|
+ )}
|
|
|
</div>
|
|
</div>
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-// ------------------------------------------
|
|
|
|
|
type Props = {
|
|
type Props = {
|
|
|
dirCode: string
|
|
dirCode: string
|
|
|
myUrl: string
|
|
myUrl: string
|
|
@@ -197,7 +187,6 @@ type Props = {
|
|
|
ref: any
|
|
ref: any
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 修复类型检查问题:统一使用dnd-kit管理所有拖拽
|
|
|
|
|
function Z3upFilesRef(
|
|
function Z3upFilesRef(
|
|
|
{
|
|
{
|
|
|
isLook = false,
|
|
isLook = false,
|
|
@@ -216,25 +205,25 @@ function Z3upFilesRef(
|
|
|
) {
|
|
) {
|
|
|
const [list, setList] = useState<FileListType[]>([])
|
|
const [list, setList] = useState<FileListType[]>([])
|
|
|
|
|
|
|
|
- // 修复图片闪动问题:分别管理图片和非图片的排序
|
|
|
|
|
const { imageFiles, otherFiles } = useMemo(() => {
|
|
const { imageFiles, otherFiles } = useMemo(() => {
|
|
|
const arr = list || []
|
|
const arr = list || []
|
|
|
- const imgArr = arr.filter(v => v.type === 'img')
|
|
|
|
|
- const otherArr = arr.filter(v => v.type !== 'img')
|
|
|
|
|
- return { imageFiles: imgArr, otherFiles: otherArr }
|
|
|
|
|
|
|
+ return {
|
|
|
|
|
+ imageFiles: arr.filter(v => v.type === 'img'),
|
|
|
|
|
+ otherFiles: arr.filter(v => v.type !== 'img')
|
|
|
|
|
+ }
|
|
|
}, [list])
|
|
}, [list])
|
|
|
|
|
|
|
|
- const fileList = useMemo(() => {
|
|
|
|
|
- return [...imageFiles, ...otherFiles]
|
|
|
|
|
- }, [imageFiles, otherFiles])
|
|
|
|
|
-
|
|
|
|
|
- const [activeId, setActiveId] = useState<number | null>(null)
|
|
|
|
|
|
|
+ const fileList = useMemo(() => [...imageFiles, ...otherFiles], [imageFiles, otherFiles])
|
|
|
|
|
+ const imageIds = useMemo(() => imageFiles.map(f => f.id), [imageFiles])
|
|
|
|
|
+ const otherIds = useMemo(() => otherFiles.map(f => f.id), [otherFiles])
|
|
|
const myInput = useRef<HTMLInputElement>(null)
|
|
const myInput = useRef<HTMLInputElement>(null)
|
|
|
|
|
|
|
|
- // 修复性能问题:使用useMemo缓存文件ID数组
|
|
|
|
|
- const fileIds = useMemo(() => fileList.map(f => f.id), [fileList])
|
|
|
|
|
|
|
+ const sensors = useSensors(
|
|
|
|
|
+ useSensor(PointerSensor, {
|
|
|
|
|
+ activationConstraint: { distance: 5 }
|
|
|
|
|
+ })
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
- // 上传多个文件
|
|
|
|
|
const handeUpPhoto = useCallback(
|
|
const handeUpPhoto = useCallback(
|
|
|
async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
if (!e.target.files || e.target.files.length === 0) return
|
|
if (!e.target.files || e.target.files.length === 0) return
|
|
@@ -246,7 +235,6 @@ function Z3upFilesRef(
|
|
|
`最多可上传${maxCount}个文件,当前选中${files.length}个文件,还可上传${maxCount - fileList.length}个文件`
|
|
`最多可上传${maxCount}个文件,当前选中${files.length}个文件,还可上传${maxCount - fileList.length}个文件`
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- // 逐个上传文件
|
|
|
|
|
for (const file of files) {
|
|
for (const file of files) {
|
|
|
if (size && file.size > size * 1024 * 1024) {
|
|
if (size && file.size > size * 1024 * 1024) {
|
|
|
MessageFu.warning(`文件"${file.name}"超过${size}M限制!`)
|
|
MessageFu.warning(`文件"${file.name}"超过${size}M限制!`)
|
|
@@ -289,89 +277,33 @@ function Z3upFilesRef(
|
|
|
[dirCode, fileList.length, formDefId, fromData, maxCount, moduleId, myUrl, size]
|
|
[dirCode, fileList.length, formDefId, fromData, maxCount, moduleId, myUrl, size]
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- // 修复拖拽逻辑问题:统一使用dnd-kit管理拖拽
|
|
|
|
|
- const handleDragStart = useCallback((event: DragStartEvent) => {
|
|
|
|
|
- setActiveId(Number(event.active.id))
|
|
|
|
|
|
|
+ const handleDragEnd = useCallback((event: DragEndEvent) => {
|
|
|
|
|
+ const { active, over } = event
|
|
|
|
|
+ if (!over || active.id === over.id) return
|
|
|
|
|
+
|
|
|
|
|
+ setList(items => {
|
|
|
|
|
+ const sameId = (a: number | string, b: number | string) => String(a) === String(b)
|
|
|
|
|
+ const isImg = (id: typeof active.id) => items.find(item => sameId(item.id, id))?.type === 'img'
|
|
|
|
|
+ if (isImg(active.id) !== isImg(over.id)) return items
|
|
|
|
|
+
|
|
|
|
|
+ const group = items.filter(item => (isImg(active.id) ? item.type === 'img' : item.type !== 'img'))
|
|
|
|
|
+ const rest = items.filter(item => (isImg(active.id) ? item.type !== 'img' : item.type === 'img'))
|
|
|
|
|
+ const oldIndex = group.findIndex(item => sameId(item.id, active.id))
|
|
|
|
|
+ const newIndex = group.findIndex(item => sameId(item.id, over.id))
|
|
|
|
|
+ if (oldIndex < 0 || newIndex < 0) return items
|
|
|
|
|
+ const moved = arrayMove(group, oldIndex, newIndex)
|
|
|
|
|
+ return isImg(active.id) ? [...moved, ...rest] : [...rest, ...moved]
|
|
|
|
|
+ })
|
|
|
}, [])
|
|
}, [])
|
|
|
|
|
|
|
|
- // 修复拖拽交换问题:增加类型检查,只有同类型文件才能交换
|
|
|
|
|
- const handleDragEnd = useCallback(
|
|
|
|
|
- (event: DragEndEvent) => {
|
|
|
|
|
- const { active, over } = event
|
|
|
|
|
- setActiveId(null)
|
|
|
|
|
-
|
|
|
|
|
- if (over && active.id !== over.id) {
|
|
|
|
|
- const activeFile = fileList.find(item => item.id === active.id)
|
|
|
|
|
- const overFile = fileList.find(item => item.id === over.id)
|
|
|
|
|
-
|
|
|
|
|
- // 修复类型检查问题:只有同类型文件才能交换位置
|
|
|
|
|
- if (activeFile && overFile && activeFile.type === overFile.type) {
|
|
|
|
|
- setList(items => {
|
|
|
|
|
- const oldIndex = items.findIndex(item => item.id === active.id)
|
|
|
|
|
- const newIndex = items.findIndex(item => item.id === over.id)
|
|
|
|
|
- return arrayMove(items, oldIndex, newIndex)
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- [fileList]
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
- // 列表删除某一个文件
|
|
|
|
|
- const delImgListFu = useCallback(
|
|
|
|
|
- (id: number) => {
|
|
|
|
|
- setList(prev => prev.filter(v => v.id !== id))
|
|
|
|
|
- },
|
|
|
|
|
- [setList]
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
- // 获取当前拖拽的文件
|
|
|
|
|
- const activeFile = useMemo(() => {
|
|
|
|
|
- return activeId ? fileList.find(file => file.id === activeId) : null
|
|
|
|
|
- }, [activeId, fileList])
|
|
|
|
|
-
|
|
|
|
|
- // 修复拖拽覆盖层显示问题
|
|
|
|
|
- const renderDragOverlay = useCallback(() => {
|
|
|
|
|
- if (!activeFile) return null
|
|
|
|
|
-
|
|
|
|
|
- if (activeFile.type === 'img') {
|
|
|
|
|
- return (
|
|
|
|
|
- <div className={classNames('ZTbox1ImgRow', 'dragOverlay')}>
|
|
|
|
|
- {activeFile.thumb || activeFile.filePath ? (
|
|
|
|
|
- <ImageLazy
|
|
|
|
|
- noLook={true}
|
|
|
|
|
- width={100}
|
|
|
|
|
- height={100}
|
|
|
|
|
- src={activeFile.thumb || activeFile.filePath}
|
|
|
|
|
- />
|
|
|
|
|
- ) : null}
|
|
|
|
|
- <div className='ZTbox1ImgRowIcon' style={{ opacity: 0.5 }}>
|
|
|
|
|
- <EyeOutlined rev={undefined} />
|
|
|
|
|
- <DownloadOutlined rev={undefined} />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- )
|
|
|
|
|
- } else {
|
|
|
|
|
- return (
|
|
|
|
|
- <div className={classNames('Z3filesRow', 'dragOverlay')}>
|
|
|
|
|
- <div className='dragHandle'>
|
|
|
|
|
- <MenuOutlined rev={undefined} />
|
|
|
|
|
- </div>
|
|
|
|
|
- <div className='Z3files1' title={activeFile.fileName}>
|
|
|
|
|
- {activeFile.fileName}
|
|
|
|
|
- </div>
|
|
|
|
|
- <div className='Z3files2'>{/* 拖拽时隐藏操作按钮 */}</div>
|
|
|
|
|
- </div>
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- }, [activeFile])
|
|
|
|
|
|
|
+ const delImgListFu = useCallback((id: number) => {
|
|
|
|
|
+ setList(prev => prev.filter(v => v.id !== id))
|
|
|
|
|
+ }, [])
|
|
|
|
|
|
|
|
- // 设置数据
|
|
|
|
|
- const sonSetListFu = useCallback((list: FileListType[]) => {
|
|
|
|
|
- setList(list)
|
|
|
|
|
|
|
+ const sonSetListFu = useCallback((nextList: FileListType[]) => {
|
|
|
|
|
+ setList(nextList)
|
|
|
}, [])
|
|
}, [])
|
|
|
|
|
|
|
|
- // 返回数据
|
|
|
|
|
const sonResListFu = useCallback(() => {
|
|
const sonResListFu = useCallback(() => {
|
|
|
const obj = {
|
|
const obj = {
|
|
|
list: fileList || [],
|
|
list: fileList || [],
|
|
@@ -380,7 +312,6 @@ function Z3upFilesRef(
|
|
|
}
|
|
}
|
|
|
if (oneIsCover && fileList.length) {
|
|
if (oneIsCover && fileList.length) {
|
|
|
const findObj = fileList.find(v => v.type === 'img')
|
|
const findObj = fileList.find(v => v.type === 'img')
|
|
|
-
|
|
|
|
|
if (findObj) {
|
|
if (findObj) {
|
|
|
obj.thumb = findObj.thumb
|
|
obj.thumb = findObj.thumb
|
|
|
obj.thumbPc = findObj.filePath
|
|
obj.thumbPc = findObj.filePath
|
|
@@ -389,7 +320,6 @@ function Z3upFilesRef(
|
|
|
return obj
|
|
return obj
|
|
|
}, [fileList, oneIsCover])
|
|
}, [fileList, oneIsCover])
|
|
|
|
|
|
|
|
- // 可以让父组件调用子组件的方法
|
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
useImperativeHandle(ref, () => ({
|
|
|
sonSetListFu,
|
|
sonSetListFu,
|
|
|
sonResListFu
|
|
sonResListFu
|
|
@@ -420,30 +350,43 @@ function Z3upFilesRef(
|
|
|
)}
|
|
)}
|
|
|
|
|
|
|
|
<div className='Z3files'>
|
|
<div className='Z3files'>
|
|
|
- <DndContext
|
|
|
|
|
- collisionDetection={closestCenter}
|
|
|
|
|
- onDragStart={handleDragStart}
|
|
|
|
|
- onDragEnd={handleDragEnd}
|
|
|
|
|
- >
|
|
|
|
|
- <SortableContext items={fileIds} strategy={verticalListSortingStrategy}>
|
|
|
|
|
- {fileList.map((file, index) => (
|
|
|
|
|
- <SortableFileItem
|
|
|
|
|
- key={file.id}
|
|
|
|
|
- file={file}
|
|
|
|
|
- onDelete={delImgListFu}
|
|
|
|
|
- isLook={isLook}
|
|
|
|
|
- index={index}
|
|
|
|
|
- oneIsCover={oneIsCover}
|
|
|
|
|
- />
|
|
|
|
|
- ))}
|
|
|
|
|
- </SortableContext>
|
|
|
|
|
- <DragOverlay>{renderDragOverlay()}</DragOverlay>
|
|
|
|
|
|
|
+ <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
|
|
|
|
|
+ {imageFiles.length > 0 && (
|
|
|
|
|
+ <div className='ZTbox1ImgList'>
|
|
|
|
|
+ <SortableContext items={imageIds} strategy={rectSortingStrategy}>
|
|
|
|
|
+ {imageFiles.map((file, index) => (
|
|
|
|
|
+ <SortableFileItem
|
|
|
|
|
+ key={file.id}
|
|
|
|
|
+ file={file}
|
|
|
|
|
+ onDelete={delImgListFu}
|
|
|
|
|
+ isLook={isLook}
|
|
|
|
|
+ isCover={!!oneIsCover && index === 0}
|
|
|
|
|
+ />
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </SortableContext>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
|
|
+
|
|
|
|
|
+ {otherFiles.length > 0 && (
|
|
|
|
|
+ <div className='Z3filesList'>
|
|
|
|
|
+ <SortableContext items={otherIds} strategy={verticalListSortingStrategy}>
|
|
|
|
|
+ {otherFiles.map(file => (
|
|
|
|
|
+ <SortableFileItem
|
|
|
|
|
+ key={file.id}
|
|
|
|
|
+ file={file}
|
|
|
|
|
+ onDelete={delImgListFu}
|
|
|
|
|
+ isLook={isLook}
|
|
|
|
|
+ />
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </SortableContext>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
</DndContext>
|
|
</DndContext>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div className='fileTit' hidden={isLook}>
|
|
<div className='fileTit' hidden={isLook}>
|
|
|
{tips}
|
|
{tips}
|
|
|
- ;支持按住Ctrl键选择多个文件上传;按住鼠标拖动图片 / 拖动附件左侧图标 可调整顺序
|
|
|
|
|
|
|
+ ;支持按住 Ctrl 多选上传;拖动图片或附件可调整顺序
|
|
|
<div
|
|
<div
|
|
|
className={classNames(
|
|
className={classNames(
|
|
|
'noUpThumb',
|
|
'noUpThumb',
|