update 视频排序调整

This commit is contained in:
LittleBoy 2024-12-23 23:20:21 +08:00 committed by Coding
parent 1beabc7376
commit 9c90ffda26
6 changed files with 73 additions and 56 deletions

View File

@ -6,7 +6,7 @@ import {Checkbox, Popconfirm} from "antd";
import {CheckCircleFilled, MenuOutlined, MinusCircleFilled, LoadingOutlined} from "@ant-design/icons"; import {CheckCircleFilled, MenuOutlined, MinusCircleFilled, LoadingOutlined} from "@ant-design/icons";
import ImageCover from '@/assets/images/cover.png' import ImageCover from '@/assets/images/cover.png'
import {IconEdit, IconPlay, IconPlaying} from "@/components/icons"; import {IconDelete, IconEdit, IconPlay, IconPlaying} from "@/components/icons";
import {VideoStatus} from "@/service/api/video.ts"; import {VideoStatus} from "@/service/api/video.ts";
import {formatTime} from "@/util/strings.ts"; import {formatTime} from "@/util/strings.ts";
@ -52,8 +52,16 @@ export const VideoListItem = (
onClick={onItemClick} onClick={onItemClick}
> >
<div className={`list-row ${generating ? 'disabled' : ''} ${active?'playing':''}`}> <div className={`list-row ${generating ? 'disabled' : ''} ${active?'playing':''}`}>
<div className="col number">{index}</div> <div
<div className="col cover"> className="col number"
{... (sortable && !generating?listeners:{})}
{... (sortable && !generating?attributes:{})}
>{index}</div>
<div
className="col cover"
{... (sortable && !generating?listeners:{})}
{... (sortable && !generating?attributes:{})}
>
<div className="relative"> <div className="relative">
<img className="w-[100px] h-[56px] object-cover" src={video.cover || ImageCover}/> <img className="w-[100px] h-[56px] object-cover" src={video.cover || ImageCover}/>
{generating && {generating &&
@ -70,17 +78,25 @@ export const VideoListItem = (
</div>} </div>}
</div> </div>
</div> </div>
<div className="col title"> <div
className="col title"
{... (sortable && !generating?listeners:{})}
{... (sortable && !generating?attributes:{})}
>
<div className="line-clamp-2"> <div className="line-clamp-2">
{video.title || video.video_title} {video.title || video.video_title}
</div> </div>
</div> </div>
<div className="col generated-time">{video.publish_time ? formatTime(video.publish_time) : ''}</div> <div
className="col generated-time"
{... (sortable && !generating?listeners:{})}
{... (sortable && !generating?attributes:{})}
>{video.publish_time ? formatTime(video.publish_time) : ''}</div>
<div className="col operation"> <div className="col operation">
{sortable && !generating && (!active ? {/*{sortable && !generating && (!active ?*/}
<button className="hover:text-blue-500 cursor-move" {...attributes} {...listeners}> {/* <button className="hover:text-blue-500 cursor-move">*/}
<MenuOutlined/> {/* <MenuOutlined/>*/}
</button> : <button disabled className="cursor-not-allowed"><MenuOutlined/></button>)} {/* </button> : <button disabled className="cursor-not-allowed"><MenuOutlined/></button>)}*/}
{editable && !generating && <> {editable && !generating && <>
{onEdit && {onEdit &&
@ -91,13 +107,6 @@ export const VideoListItem = (
}} style={{fontSize: '1.1em'}}> }} style={{fontSize: '1.1em'}}>
<IconEdit/> <IconEdit/>
</button>} </button>}
<Checkbox checked={state.checked} onChange={() => {
if (onCheckedChange) {
onCheckedChange(!state.checked)
} else {
setState({checked: !state.checked})
}
}} />
{onRemove && <Popconfirm {onRemove && <Popconfirm
title={<div style={{minWidth: 150}}><span>?</span></div>} title={<div style={{minWidth: 150}}><span>?</span></div>}
@ -105,8 +114,15 @@ export const VideoListItem = (
okText="删除" okText="删除"
cancelText="取消" cancelText="取消"
> >
<button className="hover:text-blue-500"><MinusCircleFilled/></button> <button className="hover:text-blue-500"><IconDelete/></button>
</Popconfirm>} </Popconfirm>}
<Checkbox checked={state.checked} onChange={() => {
if (onCheckedChange) {
onCheckedChange(!state.checked)
} else {
setState({checked: !state.checked})
}
}} />
</>} </>}
</div> </div>
</div> </div>

View File

@ -145,7 +145,7 @@ export default function LiveIndex() {
}) })
}, },
onCancel: () => { onCancel: () => {
showToast('退出并清除移动视频位置操作', 'info'); showToast('退出并恢复之前的直播队列', 'info');
loadList() loadList()
setEditable(false) setEditable(false)
} }

View File

@ -107,7 +107,7 @@ export default function NewEdit() {
{data?.list?.map((item, i) => { {data?.list?.map((item, i) => {
const checked = selectedRowKeys.includes(item.id) const checked = selectedRowKeys.includes(item.id)
return <div key={i} className={clsx("row flex", {checked})}> return <div key={i} className={clsx("row flex", {checked})}>
<div className="col title"> <div className="col title cursor-pointer" onClick={() => setEditId(item.id)}>
<div> <div>
<div className="text-base">{item.title}</div> <div className="text-base">{item.title}</div>
<div <div
@ -128,7 +128,7 @@ export default function NewEdit() {
className="text-sm">{formatTime(item.publish_time, 'YYYY-MM-DD HH:mm')}</div> className="text-sm">{formatTime(item.publish_time, 'YYYY-MM-DD HH:mm')}</div>
</div> </div>
<div className="col operations"> <div className="col operations">
<span className="icon-btn" onClick={() => setEditId(item.id)}><IconEdit/></span> {/*<span className="icon-btn"><IconEdit/></span>*/}
<Popconfirm title={'确认删除此新闻吗?'} description={'删除后需从新闻素材中重新选择'} onConfirm={()=>{ <Popconfirm title={'确认删除此新闻吗?'} description={'删除后需从新闻素材中重新选择'} onConfirm={()=>{
handleDelete(item.id) handleDelete(item.id)
}}> }}>

View File

@ -82,7 +82,6 @@ export default function NewsIndex() {
{activeNews && <Modal {activeNews && <Modal
rootClassName={'news-detail-modal'} rootClassName={'news-detail-modal'}
closeIcon={null} open={true} width={1000} closeIcon={null} open={true} width={1000}
maskClosable={false}
footer={null} onCancel={() => setActiveNews(undefined)} footer={null} onCancel={() => setActiveNews(undefined)}
> >
<div className="news-detail pl-16 pr-1 flex pb-5"> <div className="news-detail pl-16 pr-1 flex pb-5">

View File

@ -65,12 +65,13 @@ export default function VideoIndex() {
checkedAll: !state.checkedAll checkedAll: !state.checkedAll
}) })
} }
const handleModifySort = () => { const handleModifySort = (items:VideoInfo[]) => {
setVideoData((items) => { // .then(() => {
modifyOrder(items.map(s => s.id)).catch(() => { // showToast('调整视频顺序成功!','success')
showToast('调整视频顺序失败,请重试!') // })
}).finally(loadList) modifyOrder(items.map(s => s.id)).catch(()=>{
return items; loadList();
showToast('调整视频顺序失败,请重试!','warning')
}) })
} }
// //
@ -94,8 +95,6 @@ export default function VideoIndex() {
} }
},[videoData,scrollerRef]) },[videoData,scrollerRef])
return (<div className="container py-10 page-live"> return (<div className="container py-10 page-live">
{contextHolder} {contextHolder}
<div className="flex"> <div className="flex">
@ -148,16 +147,18 @@ export default function VideoIndex() {
setVideoData((items) => { setVideoData((items) => {
oldIndex = items.findIndex(s => s.id == active.id); oldIndex = items.findIndex(s => s.id == active.id);
newIndex = items.findIndex(s => s.id == over.id); newIndex = items.findIndex(s => s.id == over.id);
return arrayMove(items, oldIndex, newIndex); const newSorts = arrayMove(items, oldIndex, newIndex);
handleModifySort(newSorts)
return newSorts;
}); });
modal.confirm({ // modal.confirm({
title: '提示', // title: '提示',
content: '是否要移动到指定位置', // content: '是否要移动到指定位置',
onOk: handleModifySort, // onOk: handleModifySort,
onCancel: () => { // onCancel: () => {
setVideoData(originArr); // setVideoData(originArr);
} // }
}) // })
} }
}}> }}>
<SortableContext items={videoData}> <SortableContext items={videoData}>
@ -179,6 +180,7 @@ export default function VideoIndex() {
}) })
}} }}
onItemClick={ () => playVideo(v, index)} onItemClick={ () => playVideo(v, index)}
onRemove={()=>{}}
onEdit={v.status == VideoStatus.Generating ? undefined : () => { onEdit={v.status == VideoStatus.Generating ? undefined : () => {
setEditId(v.article_id) setEditId(v.article_id)
}} }}
@ -195,21 +197,21 @@ export default function VideoIndex() {
</div> </div>
<div className="page-action"> <div className="page-action">
<ButtonToTop visible={state.showToTop} onClick={()=>scrollerRef.current?.scrollToPosition(0)}/> <ButtonToTop visible={state.showToTop} onClick={()=>scrollerRef.current?.scrollToPosition(0)}/>
<ButtonBatch {checkedIdArray.length > 0 && <ButtonBatch
onProcess={deleteByIds} onProcess={deleteByIds}
selected={checkedIdArray} selected={checkedIdArray}
emptyMessage={`请选择要删除的新闻视频`} emptyMessage={`请选择要删除的新闻视频`}
title={`已选择${checkedIdArray.length}条,确定要全部删除吗?`} title={`已选择${checkedIdArray.length}条,确定要全部删除吗?`}
className='bg-gray-300 hover:bg-gray-400 text-white' className='bg-gray-300 hover:bg-gray-400 text-white'
confirmMessage={`删除后需从新闻素材中`} confirmMessage={`删除后需从新闻素材中`}
onSuccess={() => { onSuccess={() => {
showToast('删除成功!', 'success') showToast('删除成功!', 'success')
loadList() loadList()
}} }}
> >
<span className="text"></span> <span className="text"></span>
<IconDelete /> <IconDelete />
</ButtonBatch> </ButtonBatch>}
<ButtonPush2Room ids={checkedIdArray} list={videoData} onSuccess={loadList}/> <ButtonPush2Room ids={checkedIdArray} list={videoData} onSuccess={loadList}/>
</div> </div>
</div> </div>

View File

@ -20,12 +20,12 @@ const NavigationUserContainer = () => {
const {logout, user} = useAuth() const {logout, user} = useAuth()
const navigate = useNavigate() const navigate = useNavigate()
const items: MenuProps['items'] = [ const items: MenuProps['items'] = [
{ // {
key: 'profile', // key: 'profile',
label: <div onClick={() => { // label: <div onClick={() => {
navigate('/history') // navigate('/history')
}}></div>, // }}>视频库</div>,
}, // },
{ {
key: 'logout', key: 'logout',
label: <div onClick={() => { label: <div onClick={() => {