feat:突然没有了。。
This commit is contained in:
parent
f76c460fd9
commit
25b2ad52a1
Binary file not shown.
|
@ -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",
|
||||||
|
|
|
@ -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": {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
import {Event} from "react-big-calendar";
|
||||||
|
export interface TaskEvent extends Event {
|
||||||
|
id?: any;
|
||||||
|
state?:any;
|
||||||
|
priority?:any;
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
|
@ -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:'=',
|
||||||
|
|
|
@ -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>
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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";
|
||||||
|
|
Loading…
Reference in New Issue