From 25b2ad52a193e5a552bae4176ceee51e87b80d59 Mon Sep 17 00:00:00 2001 From: shixiaohua Date: Thu, 30 May 2024 14:32:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E7=AA=81=E7=84=B6=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E4=BA=86=E3=80=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/task-manager-server.jar | Bin 84472619 -> 84473297 bytes package-lock.json | 22 +++ package.json | 1 + src/lib/task/calendar/data.tsx | 6 + src/lib/task/project/data.tsx | 1 - src/ui/task/OperationButton.tsx | 4 +- src/ui/task/calendar/CalShow.tsx | 195 ++++++++++++++++++++----- src/ui/task/calendar/index.modules.css | 20 +++ src/ui/task/four/TreeTable.tsx | 2 +- 9 files changed, 213 insertions(+), 38 deletions(-) create mode 100644 src/lib/task/calendar/data.tsx create mode 100644 src/ui/task/calendar/index.modules.css diff --git a/docker/task-manager-server.jar b/docker/task-manager-server.jar index abed5d9671b00abeeb4dfbe3fcf7467c48897a89..164a5f6a45ecc0394a336c385d9dedd1e422d413 100644 GIT binary patch delta 22458 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

2KD;S1)b^T##QrVz)?r!NH>=ke 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 4" } }, + "node_modules/immutable": { + "version": "4.3.6", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz", @@ -6465,6 +6471,22 @@ "node": ">=10" } }, + "node_modules/sass": { + "version": "1.77.3", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.77.3.tgz", + "integrity": "sha512-WJHo+jmFp0dwRuymPmIovuxHaBntcCyja5hCB0yYY9wWrViEp4kF5Cdai98P72v6FzroPuABqu+ddLMbQWmwzA==", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz", diff --git a/package.json b/package.json index 3b21c52..14aa4e2 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "react": "^18", "react-big-calendar": "^1.12.2", "react-dom": "^18", + "sass": "^1.77.3", "tailwindcss": "3.3.3" }, "devDependencies": { diff --git a/src/lib/task/calendar/data.tsx b/src/lib/task/calendar/data.tsx new file mode 100644 index 0000000..afc84ab --- /dev/null +++ b/src/lib/task/calendar/data.tsx @@ -0,0 +1,6 @@ +import {Event} from "react-big-calendar"; +export interface TaskEvent extends Event { + id?: any; + state?:any; + priority?:any; +} diff --git a/src/lib/task/project/data.tsx b/src/lib/task/project/data.tsx index 94ac056..4be7e0d 100644 --- a/src/lib/task/project/data.tsx +++ b/src/lib/task/project/data.tsx @@ -1,7 +1,6 @@ import {unstable_noStore as noStore} from 'next/cache'; import axios, {AxiosResponse} from "axios"; import {DataType, DictType, ResponseVO, ResultPage} from "@/lib/definitions"; -import {message} from "antd"; export async function getTaskTreeResult(requestParam:string): Promise>> { noStore(); try { diff --git a/src/ui/task/OperationButton.tsx b/src/ui/task/OperationButton.tsx index 46b982e..f44c80e 100644 --- a/src/ui/task/OperationButton.tsx +++ b/src/ui/task/OperationButton.tsx @@ -90,12 +90,12 @@ class OperationButton extends React.Component { commonUpdate({ - updateColoumList:[{ + updateColumnList:[{ name:'state', code:'state', value:'7' }], - conditionColoumList:[{ + conditionColumnList:[{ name:'id', code:'id', operateType:'=', diff --git a/src/ui/task/calendar/CalShow.tsx b/src/ui/task/calendar/CalShow.tsx index 0de1a94..7331b04 100644 --- a/src/ui/task/calendar/CalShow.tsx +++ b/src/ui/task/calendar/CalShow.tsx @@ -1,41 +1,53 @@ 'use client' -import React, {useCallback, useContext, useEffect, useMemo} from "react"; +import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from "react"; import {Calendar, dayjsLocalizer, Event, SlotInfo, View} from 'react-big-calendar' // https://day.js.org/docs/zh-CN/get-set/get-set import dayjs, {Dayjs} from 'dayjs' import 'react-big-calendar/lib/css/react-big-calendar.css' -import {getTaskTreeResult, OPERATION_BUTTON_TYPE} from "@/lib/task/project/data"; +import 'react-big-calendar/lib/sass/styles.scss' +import 'react-big-calendar/lib/addons/dragAndDrop/styles.scss' +import '@/ui/task/calendar/index.modules.css' +import {commonUpdate, getTaskTreeResult, OPERATION_BUTTON_TYPE} from "@/lib/task/project/data"; import {useSearchParams} from "next/dist/client/components/navigation"; import {DetailModelForm} from "@/ui/task/project/DetailModelForm"; import {SearchObject} from "@/lib/definitions"; import LocalContext from "@/ui/LocalContent"; +import withDragAndDrop, {EventInteractionArgs} from "react-big-calendar/lib/addons/dragAndDrop"; +import {TaskEvent} from "@/lib/task/calendar/data"; +import {number} from "prop-types"; /** * https://github.com/jquense/react-big-calendar?tab=readme-ov-file * @constructor */ const localizer = dayjsLocalizer(dayjs) +const DragAndDropCalendar = withDragAndDrop(Calendar) const CalShow: React.FC = () => { dayjs.locale('zh-cn') - const [view, setView] = React.useState('month'); - const [date, setDate] = React.useState(new Date()); + const [view, setView] = useState('month'); + const [date, setDate] = useState(new Date()); + const clickRef = useRef(null) // 展示在页面的任务,默认获取当前月的信息。 - const [events, setEvents] = React.useState([]); - const [open, setOpen] = React.useState(false); - const [description, setDescription] = React.useState(''); - const [operationId, setOperationId] = React.useState(-1); - const [itemId,setItemId] = React.useState(-1); - const [expectedStartTime,setExpectedStartTime] = React.useState(); - const [expectedEndTime,setExpectedEndTime] = React.useState(); - let state:string=useContext(LocalContext).taskState + const [events, setEvents] = useState([]); + const [open, setOpen] = useState(false); + const [description, setDescription] = useState(''); + const [operationId, setOperationId] = useState(-1); + const [itemId, setItemId] = useState(-1); + const [expectedStartTime, setExpectedStartTime] = useState(); + const [expectedEndTime, setExpectedEndTime] = useState(); + + let state: string = useContext(LocalContext).taskState const handleViewChange = (newView: View) => { setView(newView); }; var pid = useSearchParams().get('pid'); + function clearClickTimeout(){ + clickRef && typeof clickRef.current=== 'number' &&!isNaN(clickRef.current) && isFinite(clickRef.current)&&window.clearTimeout(clickRef.current) + } const handleNavigate = (newDate: Date) => { console.log('handleNavigate', newDate) setDate(newDate); - const searchList:SearchObject[] = [] + const searchList: SearchObject[] = [] if (pid != null) { searchList.push({name: "pid", value: pid, operateType: "="}, { name: 'TREE', @@ -65,6 +77,14 @@ const CalShow: React.FC = () => { searchListE.push({name: 'expectedStartTime', value: dayjs(date).endOf('week'), operateType: "<="}) } loadData(searchListE); + /** + * What Is This? + * This is to prevent a memory leak, in the off chance that you + * teardown your interface prior to the timed method being called. + */ + return () => { + clearClickTimeout() + } }, [useContext(LocalContext)]); const message = { week: '周', @@ -76,8 +96,8 @@ const CalShow: React.FC = () => { today: '当下', agenda: '日程' } - const loadData = (searchList:SearchObject[])=>{ - if (state.length > 0){ + const loadData = (searchList: SearchObject[]) => { + if (state.length > 0) { searchList.push({name: 'state', value: state, operateType: "IN"}) } searchList.push({name: 'expectedEndTime', value: dayjs(date).endOf('month'), operateType: "NOT NULL"}) @@ -88,20 +108,25 @@ const CalShow: React.FC = () => { }) getTaskTreeResult(request).then(responseD => { if (responseD.status.success) { - setEvents(responseD.data.content.map(taskState => { + let result:TaskEvent[] =responseD.data.content.map(taskState => { return { start: dayjs(taskState.expectedStartTime).toDate(), end: dayjs(taskState.expectedEndTime).toDate(), title: taskState.name, - resource:taskState.id + resource: taskState.id, + id:taskState.id, + state:taskState.state, + priority:taskState.priority } - })) + }); + console.log('responseD.data.content:',result) + setEvents(result) } }) } - const reloadData = ()=>{ + const reloadData = () => { setOpen(false) - handleNavigate(expectedStartTime?expectedStartTime.toDate():date) + handleNavigate(expectedStartTime ? expectedStartTime.toDate() : date) } const handleSelectSlot = useCallback( ({start, end}: SlotInfo) => { @@ -116,12 +141,15 @@ const CalShow: React.FC = () => { const handleSelectEvent = useCallback( (event: Event, e: React.SyntheticEvent) => { - // window.alert(event.title); - console.log(event) - setOperationId(OPERATION_BUTTON_TYPE.DETAIL) - setDescription("任务详情") - setItemId(event.resource) - setOpen(true); + clearClickTimeout() + clickRef.current = window.setTimeout(()=> { + // window.alert(event.title); + console.log(event) + setOperationId(OPERATION_BUTTON_TYPE.DETAIL) + setDescription("任务详情") + setItemId(event.resource) + setOpen(true); + },250) }, [] ) @@ -132,24 +160,123 @@ const CalShow: React.FC = () => { }), [] ) + + const doubleClick = (event: TaskEvent, e: React.SyntheticEvent) => { + clearClickTimeout() + clickRef.current = window.setTimeout(()=>{ + // 数据落库 + commonUpdate({ + updateColumnList: [{ + name: '任务状态', + code: 'state', + value: 7 + }], + conditionColumnList: [{ + name: 'id', + code: 'id', + operateType: '=', + value: event.resource + }] + }) + setEvents((prev: TaskEvent[]) => { + const existing: TaskEvent | undefined = prev.find((ev: TaskEvent) => ev.resource === event.resource); + const filtered: TaskEvent[] | undefined = prev.filter((ev: TaskEvent) => ev.resource !== event.resource); + if (existing !== undefined) { + return [...filtered, {...existing, state:7}]; + } + if (filtered !== undefined) { + return [...filtered]; + } + return []; + }) + },250) + } + + const moveEvent = useCallback( + ({event, start, end, isAllDay: droppedOnAllDaySlot = false}: EventInteractionArgs) => { + const {allDay} = event + if (!allDay && droppedOnAllDaySlot) { + event.allDay = true + } + // 数据落库 + commonUpdate({ + updateColumnList: [{ + name: '期望开始时间', + code: 'expectedStartTime', + value: start + }, { + name: '期望结束时间', + code: 'expectedEndTime', + value: end + }], + conditionColumnList: [{ + name: 'id', + code: 'id', + operateType: '=', + value: event.resource + }] + }) + setEvents((prev: TaskEvent[]) => { + const existing: TaskEvent | undefined = prev.find((ev: TaskEvent) => ev.resource === event.resource); + const filtered: TaskEvent[] | undefined = prev.filter((ev: TaskEvent) => ev.resource !== event.resource); + if (start instanceof Date && end instanceof Date && existing !== undefined) { + return [...filtered, {...existing, start, end, allDay}]; + } + if (filtered !== undefined) { + return [...filtered]; + } + return []; + }) + }, + [setEvents] + ) + + const eventPropGetter = useCallback( + (event:TaskEvent) => ({ + ...(event.state===7 + ? { className: 'completeTask' } + : event.priority===3?{ className: 'importantUrgentTask' }: + event.priority===2?{ className: 'importantNotUrgentTask' }: + event.priority===1?{ className: 'notImportantUrgentTask' }: + { className: 'notImportantNotUrgentTask' }), + }), + [setEvents] + ) return

- - } +
} diff --git a/src/ui/task/calendar/index.modules.css b/src/ui/task/calendar/index.modules.css new file mode 100644 index 0000000..b4a4847 --- /dev/null +++ b/src/ui/task/calendar/index.modules.css @@ -0,0 +1,20 @@ +.completeTask{ + background-color: deepskyblue !important; + color: black !important; +} +.importantUrgentTask{ + background-color: red !important; + color: black !important; +} +.notImportantUrgentTask{ + background-color: gray !important; + color: black !important; +} +.importantNotUrgentTask{ + background-color: yellow !important; + color: black !important; +} +.notImportantNotUrgentTask{ + background-color: green !important; + color: black !important; +} diff --git a/src/ui/task/four/TreeTable.tsx b/src/ui/task/four/TreeTable.tsx index c8ed907..4c2cca4 100644 --- a/src/ui/task/four/TreeTable.tsx +++ b/src/ui/task/four/TreeTable.tsx @@ -1,5 +1,5 @@ 'use client' -import React, {useContext, useEffect, useState} from 'react'; +import React, {useContext} from 'react'; import {ConfigProvider, Table} from 'antd'; import type {TableColumnsType, TableProps} from 'antd'; import {taskPriorityList, taskStateList} from "@/lib/task/project/data";