From 4b32486a5f102e81f553fea2de94f55d5f647400 Mon Sep 17 00:00:00 2001 From: 1708-huayu <57060237+1708-huayu@users.noreply.github.com> Date: Thu, 10 Jul 2025 19:03:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=9B=9B=E8=B1=A1=E9=99=90=E6=8B=96?= =?UTF-8?q?=E6=8B=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/task/drag/layout.tsx | 93 +++++++++++++++++++++---- src/app/task/layout.tsx | 2 +- src/lib/definitions.ts | 1 + src/lib/task/drag/data.tsx | 3 + src/lib/task/drag/service.tsx | 10 +++ src/ui/task/TitleOperation.tsx | 2 +- src/ui/task/drag/DroppableTable.tsx | 7 +- src/ui/task/project/DetailModelForm.tsx | 23 ++++++ src/utils/axiosReq.ts | 2 +- 9 files changed, 123 insertions(+), 20 deletions(-) diff --git a/src/app/task/drag/layout.tsx b/src/app/task/drag/layout.tsx index 425ab0b..b275076 100644 --- a/src/app/task/drag/layout.tsx +++ b/src/app/task/drag/layout.tsx @@ -7,26 +7,35 @@ import {DragDropContext, DropResult} from 'react-beautiful-dnd'; import {DroppableTable} from "@/ui/task/drag/DroppableTable"; import {DataType, Request} from "@/lib/definitions"; import {TaskSelectVO} from "@/lib/task/drag/data"; -import {selectTaskAPI} from "@/lib/task/drag/service"; +import {moveItem, selectTaskAPI} from "@/lib/task/drag/service"; import LocalContext from "@/ui/LocalContent"; import {useSearchParams} from "next/dist/client/components/navigation"; export default function Layout({children}: { children: React.ReactNode }) { const [allTaskList, setAllTaskList] = useState([]); + // 3 + const [importUrgent, setImportUrgent] = useState([]); + // 2 + const [notImportUrgent, setNotImportUrgent] = useState([]); + // 1 + const [importNotUrgent, setImportNotUrgent] = useState([]); + // 0 + const [notImportNotUrgent, setNotImportNotUrgent] = useState([]); const data = useContext(LocalContext); console.log('data',data); let pid = useSearchParams().get('pid'); useEffect(() => { - addData() + selectData() }, [data]) - function addData() { + function selectData() { const requestParam: Request = { pageSize: 1000, pageNumber: 1, - data: {state: data.taskState,pid:pid} + data: {state: data.taskState,pid:pid,treeList:true,treeOrList:false,treeFilter:true}, + sortList:[{property:"sort_no",direction:"ASC"}] } if (data.expectedStartTime.length>0){ const parse = JSON.parse(data.expectedStartTime); @@ -35,34 +44,88 @@ export default function Layout({children}: { children: React.ReactNode }) { } selectTaskAPI(requestParam).then(res=>{ setAllTaskList(res.data.content) + setImportUrgent(res.data.content.filter(task => task.priority == '3')) + setNotImportUrgent(res.data.content.filter(task => task.priority == '2')) + setImportNotUrgent(res.data.content.filter(task => task.priority == '1')) + setNotImportNotUrgent(res.data.content.filter(task => task.priority == '0')) }) } + const filterByIndex = (list:DataType[],filterIndex:number)=>{ + return list.filter((item,index)=>index!=filterIndex) + } + + const addItemByIndex = (list:DataType[],addIndex:number,item:DataType)=>{ + console.log("list.splice(addIndex,0,item)",list,addIndex,item) + list.splice(addIndex,0,item) + return list; + } + // 处理拖拽结束事件 - const onDragEnd = (result: DropResult) => { - console.log('拖拽结束') + const onDragEnd = async (result: DropResult) => { + console.log('拖拽结束',{result}) const {source, destination} = result; - console.log('Source Droppable ID:', source.droppableId); - console.log('Destination Droppable ID:', destination?.droppableId); - if (!destination || !['table1', 'table2'].includes(destination.droppableId)) return; // 如果拖拽到无效区域,直接返回 if (!destination) return; // 如果拖拽到同一个表格的同一个位置,直接返回 - if (source.droppableId === destination.droppableId && source.index === destination.index) { - return; + if (destination==source) return; + + let sourceList =allTaskList.filter(task => task.priority == source.droppableId) + let currentId = sourceList[source.index].id; + + let destinationList=allTaskList.filter(task => task.priority == destination.droppableId); + let preId; + let nextId; + if(destination.droppableId==source.droppableId){ + // 从后往前 + if (source.index>destination.index){ + if (destination.index!=0){ + preId=destinationList[destination.index-1].id + } + nextId=destinationList[destination.index].id + }else { + preId=destinationList[destination.index].id + if (destination.index!=destinationList.length-1){ + nextId=destinationList[destination.index+1].id + } + } + }else { + if (destination.index!=0){ + preId=destinationList[destination.index-1].id + } + if (destination.index!=destinationList.length){ + nextId=destinationList[destination.index].id + } + // 移除 + if (source.droppableId=="3"){setImportUrgent(filterByIndex(importUrgent,source.index))} + if (source.droppableId=="2"){setNotImportUrgent(filterByIndex(notImportUrgent,source.index))} + if (source.droppableId=="1"){setImportNotUrgent(filterByIndex(importNotUrgent,source.index))} + if (source.droppableId=="0"){setNotImportNotUrgent(filterByIndex(notImportNotUrgent,source.index))} + // 加入 + if (destination.droppableId=="3"){setImportUrgent(addItemByIndex(importUrgent,destination.index,sourceList[source.index]))} + if (destination.droppableId=="2"){setNotImportUrgent(addItemByIndex(notImportUrgent,destination.index,sourceList[source.index]))} + if (destination.droppableId=="1"){setImportNotUrgent(addItemByIndex(importNotUrgent,destination.index,sourceList[source.index]))} + if (destination.droppableId=="0"){setNotImportNotUrgent(addItemByIndex(notImportNotUrgent,destination.index,sourceList[source.index]))} } + try{ + await moveItem({priority:destination.droppableId,currentId,preId,nextId}) + selectData() + }catch (e){ + console.log(e) + } + }; return (
{/* 紧急重要 */} - task.priority == '3')}/> + {/* 不紧急重要 */} - task.priority == '2')}/> + {/* 紧急不重要 */} - task.priority == '1')}/> + {/* 不紧急不重要 */} - task.priority == '0')}/> +
); } diff --git a/src/app/task/layout.tsx b/src/app/task/layout.tsx index 82394b0..e39c42d 100644 --- a/src/app/task/layout.tsx +++ b/src/app/task/layout.tsx @@ -6,7 +6,7 @@ import dayjs from "dayjs"; import {ConfigProvider} from "antd"; export default function Layout({children}: { children: React.ReactNode }) { - const [taskState, setTaskState] = React.useState('8,9') + const [taskState, setTaskState] = React.useState('8,9,10') let expectStartTimeList = []; expectStartTimeList.push({'name': "expectedStartTime", 'value': dayjs().subtract(7, 'day'), 'operateType': ">="}); expectStartTimeList.push({'name': "expectedStartTime", 'value': dayjs().add(7, 'day'), 'operateType': "<"}) diff --git a/src/lib/definitions.ts b/src/lib/definitions.ts index 562c502..0b14ee4 100644 --- a/src/lib/definitions.ts +++ b/src/lib/definitions.ts @@ -5,6 +5,7 @@ export type Request={ data:T, pageSize:number, pageNumber:number, + sortList?:{direction:string,property:string}[] } type Status={ success:boolean; diff --git a/src/lib/task/drag/data.tsx b/src/lib/task/drag/data.tsx index 637fdb2..fd21f36 100644 --- a/src/lib/task/drag/data.tsx +++ b/src/lib/task/drag/data.tsx @@ -2,6 +2,9 @@ export type TaskSelectVO = { pid?:string|undefined|null; name?: string; state?: string; + treeList?:boolean; + treeOrList?:boolean; + treeFilter?:boolean; priority?: string; allOverdueTasks?:boolean; expectedStartTimeStart?:string; diff --git a/src/lib/task/drag/service.tsx b/src/lib/task/drag/service.tsx index 00f606e..4a6266a 100644 --- a/src/lib/task/drag/service.tsx +++ b/src/lib/task/drag/service.tsx @@ -12,4 +12,14 @@ export async function selectTaskAPI(requestParam: Request): process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/V2/task/select', requestParam); // 从响应中提取数据并返回 return response.data; +} + +export async function moveItem(requestParam:{}): + Promise> { + noStore(); + // 使用 Axios 发送 PUT 请求获取数据 + const response: AxiosResponse> = await httpReq.post( + process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/task/moveItem', requestParam); + // 从响应中提取数据并返回 + return response.data; } \ No newline at end of file diff --git a/src/ui/task/TitleOperation.tsx b/src/ui/task/TitleOperation.tsx index 1fb773f..e1e53a1 100644 --- a/src/ui/task/TitleOperation.tsx +++ b/src/ui/task/TitleOperation.tsx @@ -124,7 +124,7 @@ export const TitleOperation: React.FC = ({ { /*日历需要状态*/ !usePathname().startsWith("/task/project") && - + } diff --git a/src/ui/task/drag/DroppableTable.tsx b/src/ui/task/drag/DroppableTable.tsx index 5f1b917..8b3ea9d 100644 --- a/src/ui/task/drag/DroppableTable.tsx +++ b/src/ui/task/drag/DroppableTable.tsx @@ -12,7 +12,8 @@ import RightOption from "@/ui/task/RightOption"; interface DroppableTableProps { tableCode: string, - taskList: DataType[] + taskList: DataType[], + refreshDate?: () => void, } export const DroppableTable = React.memo((props: DroppableTableProps) => { @@ -79,7 +80,9 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => { {props.taskList.map((record, index) => { return {(provided, snapshot) => ( - = (props) => { onChange={(value:string, option)=>{ setTaskType(value) }} + rules={[ + {required:true, + message:"请输入计划类型" + } + ]} /> = (props) => { tooltip="最长为 10 位" placeholder="请输入任务名称" disabled ={editFormDisable} + rules={[ + {required:true, + message:"请输入计划名称" + },{ + max:10, + message:"名称长度不易超过10个字" + } + ]} /> = (props) => { label="任务优先级" initialValue='3' disabled ={editFormDisable} + rules={[ + {required:true, + message:"请选择计划优先级" + } + ]} /> = (props) => { label="任务状态" initialValue='8' disabled ={editFormDisable} + rules={[ + {required:true, + message:"请选择计划状态" + } + ]} /> diff --git a/src/utils/axiosReq.ts b/src/utils/axiosReq.ts index aaa23a5..7cb5b9d 100644 --- a/src/utils/axiosReq.ts +++ b/src/utils/axiosReq.ts @@ -8,7 +8,7 @@ export const httpReq = axios.create({ validateStatus: function (status) { return status >= 200 && status < 300; // default }, - timeout: 2000, + timeout: 10000, timeoutErrorMessage: "网络连接超时", withCredentials: false, })