feat:突然没有了。。

This commit is contained in:
shixiaohua 2024-05-30 14:32:17 +08:00
parent f76c460fd9
commit 25b2ad52a1
9 changed files with 213 additions and 38 deletions

Binary file not shown.

22
package-lock.json generated
View File

@ -18,6 +18,7 @@
"react": "^18", "react": "^18",
"react-big-calendar": "^1.12.2", "react-big-calendar": "^1.12.2",
"react-dom": "^18", "react-dom": "^18",
"sass": "^1.77.3",
"tailwindcss": "3.3.3" "tailwindcss": "3.3.3"
}, },
"devDependencies": { "devDependencies": {
@ -4092,6 +4093,11 @@
"node": ">= 4" "node": ">= 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": { "node_modules/import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz",
@ -6465,6 +6471,22 @@
"node": ">=10" "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": { "node_modules/scheduler": {
"version": "0.23.0", "version": "0.23.0",
"resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz", "resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz",

View File

@ -19,6 +19,7 @@
"react": "^18", "react": "^18",
"react-big-calendar": "^1.12.2", "react-big-calendar": "^1.12.2",
"react-dom": "^18", "react-dom": "^18",
"sass": "^1.77.3",
"tailwindcss": "3.3.3" "tailwindcss": "3.3.3"
}, },
"devDependencies": { "devDependencies": {

View File

@ -0,0 +1,6 @@
import {Event} from "react-big-calendar";
export interface TaskEvent extends Event {
id?: any;
state?:any;
priority?:any;
}

View File

@ -1,7 +1,6 @@
import {unstable_noStore as noStore} from 'next/cache'; import {unstable_noStore as noStore} from 'next/cache';
import axios, {AxiosResponse} from "axios"; import axios, {AxiosResponse} from "axios";
import {DataType, DictType, ResponseVO, ResultPage} from "@/lib/definitions"; import {DataType, DictType, ResponseVO, ResultPage} from "@/lib/definitions";
import {message} from "antd";
export async function getTaskTreeResult(requestParam:string): Promise<ResponseVO<ResultPage<DataType>>> { export async function getTaskTreeResult(requestParam:string): Promise<ResponseVO<ResultPage<DataType>>> {
noStore(); noStore();
try { try {

View File

@ -90,12 +90,12 @@ class OperationButton extends React.Component<OperationButtonProps, OperationMod
cancelText="取消" cancelText="取消"
onConfirm={() => { onConfirm={() => {
commonUpdate({ commonUpdate({
updateColoumList:[{ updateColumnList:[{
name:'state', name:'state',
code:'state', code:'state',
value:'7' value:'7'
}], }],
conditionColoumList:[{ conditionColumnList:[{
name:'id', name:'id',
code:'id', code:'id',
operateType:'=', operateType:'=',

View File

@ -1,41 +1,53 @@
'use client' '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' import {Calendar, dayjsLocalizer, Event, SlotInfo, View} from 'react-big-calendar'
// https://day.js.org/docs/zh-CN/get-set/get-set // https://day.js.org/docs/zh-CN/get-set/get-set
import dayjs, {Dayjs} from 'dayjs' import dayjs, {Dayjs} from 'dayjs'
import 'react-big-calendar/lib/css/react-big-calendar.css' 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 {useSearchParams} from "next/dist/client/components/navigation";
import {DetailModelForm} from "@/ui/task/project/DetailModelForm"; import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
import {SearchObject} from "@/lib/definitions"; import {SearchObject} from "@/lib/definitions";
import LocalContext from "@/ui/LocalContent"; 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 * https://github.com/jquense/react-big-calendar?tab=readme-ov-file
* @constructor * @constructor
*/ */
const localizer = dayjsLocalizer(dayjs) const localizer = dayjsLocalizer(dayjs)
const DragAndDropCalendar = withDragAndDrop(Calendar)
const CalShow: React.FC = () => { const CalShow: React.FC = () => {
dayjs.locale('zh-cn') dayjs.locale('zh-cn')
const [view, setView] = React.useState<View>('month'); const [view, setView] = useState<View>('month');
const [date, setDate] = React.useState<Date>(new Date()); const [date, setDate] = useState<Date>(new Date());
const clickRef = useRef<number|undefined|null>(null)
// 展示在页面的任务,默认获取当前月的信息。 // 展示在页面的任务,默认获取当前月的信息。
const [events, setEvents] = React.useState<Event[]>([]); const [events, setEvents] = useState<TaskEvent[]>([]);
const [open, setOpen] = React.useState(false); const [open, setOpen] = useState(false);
const [description, setDescription] = React.useState(''); const [description, setDescription] = useState('');
const [operationId, setOperationId] = React.useState(-1); const [operationId, setOperationId] = useState(-1);
const [itemId,setItemId] = React.useState(-1); const [itemId, setItemId] = useState(-1);
const [expectedStartTime,setExpectedStartTime] = React.useState<Dayjs>(); const [expectedStartTime, setExpectedStartTime] = useState<Dayjs>();
const [expectedEndTime,setExpectedEndTime] = React.useState<Dayjs>(); const [expectedEndTime, setExpectedEndTime] = useState<Dayjs>();
let state:string=useContext(LocalContext).taskState
let state: string = useContext(LocalContext).taskState
const handleViewChange = (newView: View) => { const handleViewChange = (newView: View) => {
setView(newView); setView(newView);
}; };
var pid = useSearchParams().get('pid'); 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) => { const handleNavigate = (newDate: Date) => {
console.log('handleNavigate', newDate) console.log('handleNavigate', newDate)
setDate(newDate); setDate(newDate);
const searchList:SearchObject[] = [] const searchList: SearchObject[] = []
if (pid != null) { if (pid != null) {
searchList.push({name: "pid", value: pid, operateType: "="}, { searchList.push({name: "pid", value: pid, operateType: "="}, {
name: 'TREE', name: 'TREE',
@ -65,6 +77,14 @@ const CalShow: React.FC = () => {
searchListE.push({name: 'expectedStartTime', value: dayjs(date).endOf('week'), operateType: "<="}) searchListE.push({name: 'expectedStartTime', value: dayjs(date).endOf('week'), operateType: "<="})
} }
loadData(searchListE); 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)]); }, [useContext(LocalContext)]);
const message = { const message = {
week: '周', week: '周',
@ -76,8 +96,8 @@ const CalShow: React.FC = () => {
today: '当下', today: '当下',
agenda: '日程' agenda: '日程'
} }
const loadData = (searchList:SearchObject[])=>{ const loadData = (searchList: SearchObject[]) => {
if (state.length > 0){ if (state.length > 0) {
searchList.push({name: 'state', value: state, operateType: "IN"}) searchList.push({name: 'state', value: state, operateType: "IN"})
} }
searchList.push({name: 'expectedEndTime', value: dayjs(date).endOf('month'), operateType: "NOT NULL"}) searchList.push({name: 'expectedEndTime', value: dayjs(date).endOf('month'), operateType: "NOT NULL"})
@ -88,20 +108,25 @@ const CalShow: React.FC = () => {
}) })
getTaskTreeResult(request).then(responseD => { getTaskTreeResult(request).then(responseD => {
if (responseD.status.success) { if (responseD.status.success) {
setEvents(responseD.data.content.map(taskState => { let result:TaskEvent[] =responseD.data.content.map<TaskEvent>(taskState => {
return { return {
start: dayjs(taskState.expectedStartTime).toDate(), start: dayjs(taskState.expectedStartTime).toDate(),
end: dayjs(taskState.expectedEndTime).toDate(), end: dayjs(taskState.expectedEndTime).toDate(),
title: taskState.name, 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) setOpen(false)
handleNavigate(expectedStartTime?expectedStartTime.toDate():date) handleNavigate(expectedStartTime ? expectedStartTime.toDate() : date)
} }
const handleSelectSlot = useCallback( const handleSelectSlot = useCallback(
({start, end}: SlotInfo) => { ({start, end}: SlotInfo) => {
@ -116,12 +141,15 @@ const CalShow: React.FC = () => {
const handleSelectEvent = useCallback( const handleSelectEvent = useCallback(
(event: Event, e: React.SyntheticEvent<HTMLElement>) => { (event: Event, e: React.SyntheticEvent<HTMLElement>) => {
// window.alert(event.title); clearClickTimeout()
console.log(event) clickRef.current = window.setTimeout(()=> {
setOperationId(OPERATION_BUTTON_TYPE.DETAIL) // window.alert(event.title);
setDescription("任务详情") console.log(event)
setItemId(event.resource) setOperationId(OPERATION_BUTTON_TYPE.DETAIL)
setOpen(true); setDescription("任务详情")
setItemId(event.resource)
setOpen(true);
},250)
}, },
[] []
) )
@ -132,24 +160,123 @@ const CalShow: React.FC = () => {
}), }),
[] []
) )
const doubleClick = (event: TaskEvent, e: React.SyntheticEvent<HTMLElement>) => {
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<TaskEvent>) => {
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 <div className="App" style={{height: '90vh'}}> return <div className="App" style={{height: '90vh'}}>
<DetailModelForm operationId={operationId} description={description} open={open} haveButton={false} itemId={itemId} {open&&<DetailModelForm operationId={operationId} description={description} open={open} haveButton={false}
reloadData={reloadData} expectedStartTime={expectedStartTime} expectedEndTime={expectedEndTime}/> itemId={itemId}
<Calendar reloadData={reloadData} expectedStartTime={expectedStartTime}
expectedEndTime={expectedEndTime}/>}
<DragAndDropCalendar
// 本地设置
localizer={localizer} localizer={localizer}
messages={message}
// 修改style
eventPropGetter={eventPropGetter}
events={events} events={events}
// 界面
view={view} view={view}
// 界面改变
onView={handleViewChange} onView={handleViewChange}
// onRangeChange={rangeChange} // onRangeChange={rangeChange}
// 时间
date={date} date={date}
// 条目信息改变
onNavigate={handleNavigate} onNavigate={handleNavigate}
messages={message}
// 点击任务 // 点击
onSelectEvent={handleSelectEvent}
// 点击空白处添加任务
onSelectSlot={handleSelectSlot}
selectable selectable
scrollToTime={scrollToTime} scrollToTime={scrollToTime}
// 双击
onDoubleClickEvent={doubleClick}
// 点击任务
onSelectEvent={handleSelectEvent}
// 点击空白处
onSelectSlot={handleSelectSlot}
// 改变时间长短
resizable
onEventResize={moveEvent}
onEventDrop={moveEvent}
/> />
</div> </div>
} }

View File

@ -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;
}

View File

@ -1,5 +1,5 @@
'use client' 'use client'
import React, {useContext, useEffect, useState} from 'react'; import React, {useContext} from 'react';
import {ConfigProvider, Table} from 'antd'; import {ConfigProvider, Table} from 'antd';
import type {TableColumnsType, TableProps} from 'antd'; import type {TableColumnsType, TableProps} from 'antd';
import {taskPriorityList, taskStateList} from "@/lib/task/project/data"; import {taskPriorityList, taskStateList} from "@/lib/task/project/data";