From 55e5468d473596495f8c7e23ac8786439668b4fd Mon Sep 17 00:00:00 2001 From: 1708-huayu <57060237+1708-huayu@users.noreply.github.com> Date: Mon, 7 Jul 2025 18:46:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=8F=B3=E9=94=AE=EF=BC=8C=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=88=97=E8=A1=A8=E5=AF=BC=E8=87=B4=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E8=A2=AB=E9=98=BB=E6=8C=A1,=E4=BD=BF=E7=94=A8enum?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/task/drag/layout.tsx | 28 +++-- src/lib/task/drag/data.tsx | 2 + src/lib/task/drag/service.tsx | 2 +- src/lib/task/project/data.tsx | 5 +- src/ui/task/RightOption.tsx | 136 ++++++++++++++++++++++++ src/ui/task/drag/DroppableTable.tsx | 117 ++++++++------------ src/ui/task/drag/index.modules.css | 1 - src/ui/task/project/DetailModelForm.tsx | 2 +- 8 files changed, 210 insertions(+), 83 deletions(-) create mode 100644 src/ui/task/RightOption.tsx diff --git a/src/app/task/drag/layout.tsx b/src/app/task/drag/layout.tsx index bfad5e6..22e2f2b 100644 --- a/src/app/task/drag/layout.tsx +++ b/src/app/task/drag/layout.tsx @@ -2,27 +2,40 @@ * A layout is UI that is shared between multiple routes. On navigation, layouts preserve state, remain interactive, and do not re-render. */ 'use client' -import React, {useEffect, useState} from 'react'; +import React, {useContext, useEffect, useState} from 'react'; 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 LocalContext from "@/ui/LocalContent"; +import {useSearchParams} from "next/dist/client/components/navigation"; export default function Layout({children}: { children: React.ReactNode }) { const [allTaskList, setAllTaskList] = useState([]); + + const data = useContext(LocalContext); + console.log('data',data); + let pid = useSearchParams().get('pid'); + useEffect(() => { addData() - }, []) + }, [data]) - async function addData() { + function addData() { const requestParam: Request = { pageSize: 1000, pageNumber: 1, - data: {state: '9'} + data: {state: data.taskState} } - const res = await selectTaskAPI(requestParam) - setAllTaskList(res.data.content) + if (data.expectedStartTime.length>0){ + const parse = JSON.parse(data.expectedStartTime); + requestParam.data.expectedStartTimeStart=parse[0].value; + requestParam.data.expectedStartTimeEnd=parse[1].value; + } + selectTaskAPI(requestParam).then(res=>{ + setAllTaskList(res.data.content) + }) } // 处理拖拽结束事件 @@ -51,6 +64,5 @@ export default function Layout({children}: { children: React.ReactNode }) { {/* 不紧急不重要 */} task.priority == '0')}/> - ) - ; + ); } diff --git a/src/lib/task/drag/data.tsx b/src/lib/task/drag/data.tsx index c8ab15a..d099004 100644 --- a/src/lib/task/drag/data.tsx +++ b/src/lib/task/drag/data.tsx @@ -3,4 +3,6 @@ export type TaskSelectVO = { state?: string; priority?: string; allOverdueTasks?:boolean; + expectedStartTimeStart?:string; + expectedStartTimeEnd?:string; } \ No newline at end of file diff --git a/src/lib/task/drag/service.tsx b/src/lib/task/drag/service.tsx index ad5969b..00f606e 100644 --- a/src/lib/task/drag/service.tsx +++ b/src/lib/task/drag/service.tsx @@ -9,7 +9,7 @@ export async function selectTaskAPI(requestParam: Request): noStore(); // 使用 Axios 发送 PUT 请求获取数据 const response: AxiosResponse>> = await httpReq.post( - process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/task/select', requestParam); + process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/V2/task/select', requestParam); // 从响应中提取数据并返回 return response.data; } \ No newline at end of file diff --git a/src/lib/task/project/data.tsx b/src/lib/task/project/data.tsx index 3b85a48..6e3f29d 100644 --- a/src/lib/task/project/data.tsx +++ b/src/lib/task/project/data.tsx @@ -116,7 +116,7 @@ export const taskPriorityList: DictType[] = [ code: '1', name: '不重要紧急', order: 2, - color: '#fafafa' + color: '#1677ff' }, { id: 0, code: '0', @@ -216,5 +216,6 @@ export enum OPERATION_BUTTON_TYPE { SHOW_FOUR, SHOW_CALENDAR, ADD, - UPDATE_PRIORITY + UPDATE_PRIORITY, + INIT } diff --git a/src/ui/task/RightOption.tsx b/src/ui/task/RightOption.tsx new file mode 100644 index 0000000..178eb4a --- /dev/null +++ b/src/ui/task/RightOption.tsx @@ -0,0 +1,136 @@ +import React, {Fragment, useState} from 'react'; +import {Form, MenuProps, message, Popconfirm} from 'antd'; +import { Dropdown, theme } from 'antd'; +import {commonUpdate, deleteTask, OPERATION_BUTTON_TYPE} from "@/lib/task/project/data"; +import {QuestionCircleOutlined} from "@ant-design/icons"; +import Link from "next/link"; +import {DetailModelForm} from "@/ui/task/project/DetailModelForm"; +interface OperationButtonProps { + itemId: string, + priority?:string, + pid: string, + pPid: string, + operationId?: OPERATION_BUTTON_TYPE, + refreshDate?: () => void, + children: React.ReactNode +} +const RightOption: React.FC = (props) => { + const [operateState, setOperateState] = useState({ + operationId:OPERATION_BUTTON_TYPE.INIT,openModal:false}); + const items: MenuProps['items'] = [ + { + key: OPERATION_BUTTON_TYPE.DETAIL, + label: { + setOperateState({openModal: true, operationId: OPERATION_BUTTON_TYPE.DETAIL}) + }}>任务详情, + }, + { + key: OPERATION_BUTTON_TYPE.ADD_CHILD, + label: { + setOperateState({openModal: true, operationId: OPERATION_BUTTON_TYPE.ADD_CHILD}) + }}>添加支线任务, + }, + { + key: OPERATION_BUTTON_TYPE.UPDATE, + label: { + setOperateState({openModal: true, operationId: OPERATION_BUTTON_TYPE.UPDATE}) + }}>修改任务, + }, + { + key: OPERATION_BUTTON_TYPE.DELETE, + label: } + okText="确认" + cancelText="取消" + onConfirm={() => { + deleteTask(props.itemId).then((response => { + console.log('response', response) + if (response.status.success) { + message.success("删除任务成功:" + response.data) + props.refreshDate?.() + } + })); + }} + >删除任务, + }, + { + key: OPERATION_BUTTON_TYPE.COMPLETE, + label: { + commonUpdate({ + updateColumnList:[{ + name:'state', + code:'state', + value:'7' + }], + conditionColumnList:[{ + name:'id', + code:'id', + operateType:'=', + value:props.itemId + }] + }).then((response => { + console.log('response', response) + if (response.status.success) { + message.success("完成任务成功") + props.refreshDate?.() + } + })); + }} + >完成任务, + }, + { + key: OPERATION_BUTTON_TYPE.SHOW_TREE, + label: 树任务显示子任务, + }, + { + key: OPERATION_BUTTON_TYPE.SHOW_FOUR, + label: 四象限显示子任务, + }, + { + key: OPERATION_BUTTON_TYPE.SHOW_CALENDAR, + label: 日历显示子任务, + } + ]; + // 获取系统样式 + const { + token: { colorBgLayout, colorTextTertiary }, + } = theme.useToken(); + + const handleCancel = () => { + setOperateState({...operateState, openModal: false}) + if (operateState.operationId !== OPERATION_BUTTON_TYPE.DETAIL) { + props.refreshDate?.() + } + } + const onClick: MenuProps['onClick'] = ({key}) => { + console.log(key) + }; + + return ( + + + {props.children} + + {operateState.openModal&&} + + ); +}; + +export default RightOption; \ No newline at end of file diff --git a/src/ui/task/drag/DroppableTable.tsx b/src/ui/task/drag/DroppableTable.tsx index 657d70b..1003edc 100644 --- a/src/ui/task/drag/DroppableTable.tsx +++ b/src/ui/task/drag/DroppableTable.tsx @@ -7,9 +7,8 @@ import {DataType} from "@/lib/definitions"; import './index.modules.css' import dayjs from "dayjs"; import {getTaskState, taskPriorityList} from "@/lib/task/project/data"; -import {List as VirtualizedList, AutoSizer} from "react-virtualized"; import 'react-virtualized/styles.css'; -import OperationButton from "@/ui/task/OperationButton"; +import RightOption from "@/ui/task/RightOption"; interface DroppableTableProps { tableCode: string, @@ -35,13 +34,14 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => { const getItemStyle = React.useCallback((isDragging: boolean, draggableStyle: any): CSSProperties => ({ userSelect: "none", background: isDragging ? "lightgreen" : "white", - position: 'relative', // 确保 zIndex 生效 - zIndex: isDragging ? 2147483647 : 'auto', // 使用 'auto' 代替 0 可能更好 + position: 'relative', + zIndex: isDragging ? 2147483647 : 'auto', ...draggableStyle, borderBottom: '1px solid #f0f0f0', boxSizing: 'border-box', - // verticalAlign: 'middle', - // textAlign: 'center', + verticalAlign: 'middle', + textAlign: 'center', + borderColor:taskPriorityList.find((item) => item.code === props.tableCode)?.color }), []); const getListStyle = React.useCallback((isDraggingOver: boolean) => ({ @@ -50,55 +50,10 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => { width: '50vw' }), []); - const rowRenderer = React.useCallback(({index, key, style}: { - index: number; - key: string; - style: React.CSSProperties - }) => { - const record = props.taskList[index]; - if (!record) return null; - - return ( - - {(provided, snapshot) => ( -
-
- -
{record.name}
-
-
-
- -
{record.description}
-
-
-
{getTaskState(record.state) ? getTaskState(record.state).name : ""}
-
-
起: {record.expectedStartTime ? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") : ""}
-
止: {record.expectedStartTime ? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") : ""}
-
-
- -
-
- )} -
- ); - }, [props.taskList, getItemStyle]); - const headerStyle = React.useMemo(() => ({ backgroundColor: taskPriorityList.find((item) => item.code === props.tableCode)?.color, height: '55px', - borderBottom: '1px solid #f0f0f0', + // borderBottom: '1px solid #f0f0f0', fontWeight: 'bold' }), [props.tableCode]); @@ -109,32 +64,54 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => { ref={provided.innerRef} {...provided.droppableProps} style={getListStyle(snapshot.isDraggingOver)} - className="droppable-table" + className="droppable-table scrollHidden" > {/* 表头 */}
-
{stateName}
-
任务描述
+
{stateName}
+
任务描述
任务状态
期望时间
-
操作
{/* 虚拟列表主体 */} -
- - {({height, width}) => ( - - )} - +
+ {props.taskList.map((record, index) => { + return + {(provided, snapshot) => ( + +
+ +
{record.name}
+
+
+
+ +
{record.description}
+
+
+
{getTaskState(record.state) ? getTaskState(record.state).name : ""}
+
+
起: {record.expectedStartTime ? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") : ""}
+
止: {record.expectedEndTime ? dayjs(record.expectedEndTime).format("YYYY-MM-DD HH:mm") : ""}
+
+
}> + + + )} + + })}
{provided.placeholder} diff --git a/src/ui/task/drag/index.modules.css b/src/ui/task/drag/index.modules.css index eee2bb2..9066b5d 100644 --- a/src/ui/task/drag/index.modules.css +++ b/src/ui/task/drag/index.modules.css @@ -2,7 +2,6 @@ box-sizing: border-box; border: 1px solid #f0f0f0; border-radius: 4px; - overflow: hidden; } .virtualized-row { diff --git a/src/ui/task/project/DetailModelForm.tsx b/src/ui/task/project/DetailModelForm.tsx index 275bc7f..1f085ce 100644 --- a/src/ui/task/project/DetailModelForm.tsx +++ b/src/ui/task/project/DetailModelForm.tsx @@ -25,7 +25,7 @@ export type DetailModelFormProps={ // 祖宗任务id pPid?:string, // 操作id - operationId: number, + operationId: OPERATION_BUTTON_TYPE, // 标题描述 description:string, // 是否打开界面,用于非按钮操作