feat:打卡日历显示
This commit is contained in:
parent
c6444b2662
commit
03626f9f58
|
@ -11,6 +11,7 @@ export default function Layout({children}: { children: React.ReactNode }) {
|
|||
expectStartTimeList.push({'name': "expectedStartTime", 'value': dayjs().subtract(7, 'day'), 'operateType': ">="});
|
||||
expectStartTimeList.push({'name': "expectedStartTime", 'value': dayjs().add(7, 'day'), 'operateType': "<"})
|
||||
const [expectedStartTime, setExpectedStartTime] = React.useState<string>(JSON.stringify(expectStartTimeList))
|
||||
const [taskTypeList,setTaskTypeList] = React.useState<string[]>(["0,1,2,3","4"])
|
||||
const [refreshDataFlag, setRefreshDataFlag] = React.useState<boolean>(true)
|
||||
|
||||
function refreshData() {
|
||||
|
@ -38,9 +39,11 @@ export default function Layout({children}: { children: React.ReactNode }) {
|
|||
<LocalContext.Provider value={{
|
||||
'taskState': taskState,
|
||||
'expectedStartTime': expectedStartTime,
|
||||
'refreshData': refreshDataFlag
|
||||
'refreshData': refreshDataFlag,
|
||||
'taskTypeList':taskTypeList
|
||||
}}>
|
||||
<TitleOperation setTaskState={setTaskState} setExpectedStartTime={setExpectedStartTime}
|
||||
setTaskTypeList={setTaskTypeList}
|
||||
refreshData={refreshData}/>
|
||||
<div style={{height:"calc(100vh - 42px)",overflow:"auto"}}>
|
||||
{children}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Button, Form} from "antd";
|
||||
import React, {useEffect} from "react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {
|
||||
ModalForm,
|
||||
ProFormDateTimeRangePicker,
|
||||
|
@ -7,43 +7,82 @@ import {
|
|||
ProFormTextArea
|
||||
} from "@ant-design/pro-components";
|
||||
import {TaskScheduleRecordForm, TaskScheduleRecordVO} from "@/components/type/TaskSchedule.d";
|
||||
import {clickRecordAPI} from "@/components/service/ScheduleTask";
|
||||
import {clickRecordAPI, getRecordById} from "@/components/service/ScheduleTask";
|
||||
import dayjs, {UnitTypeShort} from "dayjs";
|
||||
import {onceConsumerRead} from "@/utils/codeToReadName";
|
||||
import {betweenTime} from "@/utils/timeFormatUtil";
|
||||
|
||||
interface ClickRecordProps {
|
||||
taskId: string;
|
||||
openClickRecord?:boolean;
|
||||
recordId?:string;
|
||||
taskId?: string;
|
||||
taskName: string;
|
||||
onceConsume: string | undefined;
|
||||
onceConsume?: string;
|
||||
setOpenClickRecord?:(boolean: boolean) => void;
|
||||
}
|
||||
|
||||
const ClickRecord: React.FC<ClickRecordProps> = ({taskId, taskName, onceConsume}) => {
|
||||
const ClickRecord: React.FC<ClickRecordProps> = ({recordId,openClickRecord,setOpenClickRecord,taskId, taskName, onceConsume}) => {
|
||||
const [form] = Form.useForm<TaskScheduleRecordForm>();
|
||||
const [editAble, setEditAble] = useState<boolean>(true);
|
||||
useEffect(() => {
|
||||
console.log("ClickRecord:useEffect:",openClickRecord)
|
||||
if (recordId){
|
||||
setEditAble(false)
|
||||
getRecordById(recordId).then(res=>{
|
||||
if (res.data.status.success){
|
||||
form.setFieldsValue({...res.data.data,
|
||||
recordTimeRange:[res.data.data.startDate?dayjs(res.data.data.startDate).toDate():undefined,
|
||||
res.data.data.startDate?dayjs(res.data.data.recordDate).toDate():undefined]})
|
||||
}
|
||||
})
|
||||
}else {
|
||||
let data = {
|
||||
'recordTimeRange': [onceConsume ? dayjs().subtract(Number(onceConsume.split(",")[0]), onceConsume.split(",")[1] as UnitTypeShort) : dayjs(), dayjs()],
|
||||
'timeDifference': onceConsumerRead(onceConsume),
|
||||
};
|
||||
form.setFieldsValue(data)
|
||||
}, []);
|
||||
}
|
||||
}, [recordId]);
|
||||
return (
|
||||
|
||||
<ModalForm<TaskScheduleRecordForm>
|
||||
title={`${taskName}打卡`}
|
||||
layout="horizontal"
|
||||
trigger={
|
||||
trigger={(recordId?undefined:
|
||||
<Button type="primary">
|
||||
打卡记录
|
||||
</Button>}
|
||||
</Button>)}
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
maskClosable: false,
|
||||
onCancel: () => {
|
||||
setOpenClickRecord?.(false)
|
||||
},
|
||||
}}
|
||||
submitter={{
|
||||
render: (prop, defaultDoms) => {
|
||||
const result = [];
|
||||
if (recordId&&!editAble){
|
||||
result.push(<Button color="danger" key="edit"
|
||||
onClick={() => setEditAble(true)}>编辑
|
||||
</Button>)
|
||||
result.push(<Button type="primary" key="close"
|
||||
onClick={() => setOpenClickRecord?.(false)}>关闭
|
||||
</Button>)
|
||||
}else{
|
||||
result.push(defaultDoms)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}}
|
||||
open={openClickRecord}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
// destroyOnClose: true,
|
||||
onCancel: () => console.log('run'),
|
||||
}}
|
||||
readonly={!editAble}
|
||||
onFinish={async (values) => {
|
||||
if(taskId){
|
||||
values.taskId = taskId
|
||||
}
|
||||
if (values.recordTimeRange[0]) {
|
||||
values.startDate = new Date(values.recordTimeRange[0])
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ const TaskNameAndIcon = (props: {task:TaskMessage}) => {
|
|||
<use xlinkHref="#icon-dingshi"></use>
|
||||
</svg>
|
||||
}
|
||||
<text>{props.task.name}</text>
|
||||
<span>{props.task.name}</span>
|
||||
</Fragment>)
|
||||
}
|
||||
export default TaskNameAndIcon;
|
|
@ -1,7 +1,3 @@
|
|||
.localDiv{
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.icon{
|
||||
font-size: 1rem;
|
||||
font-color: orange;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import {AxiosResponse} from "axios";
|
||||
import {ResponseVO} from "@/lib/definitions";
|
||||
import {httpReq} from "@/utils/axiosReq";
|
||||
import {TaskScheduleRecordVO} from "@/components/type/TaskSchedule.d";
|
||||
import {TaskScheduleRangeVO, TaskScheduleRecordForm, TaskScheduleRecordVO} from "@/components/type/TaskSchedule.d";
|
||||
|
||||
export const generateNextTimeAPI = (cron: string): Promise<AxiosResponse<ResponseVO<string[]>>> => {
|
||||
return httpReq.get(process.env.NEXT_PUBLIC_TODO_REQUEST_URL +
|
||||
|
@ -11,3 +11,11 @@ export const clickRecordAPI = (data:TaskScheduleRecordVO)=>{
|
|||
return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL +
|
||||
`/task/schedule/click`, data)
|
||||
}
|
||||
export const getRecordById = (recordId: string): Promise<AxiosResponse<ResponseVO<TaskScheduleRecordForm>>> => {
|
||||
return httpReq.get(process.env.NEXT_PUBLIC_TODO_REQUEST_URL +
|
||||
`/task/schedule/id?id=${recordId}`)
|
||||
}
|
||||
export const editClickRecordAPI = (data:TaskScheduleRangeVO):Promise<AxiosResponse<ResponseVO<TaskScheduleRecordVO>>> =>{
|
||||
return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL +
|
||||
`/task/schedule/updateRange`,data)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
export interface TaskScheduleRecordVO{
|
||||
export interface TaskScheduleRangeVO {
|
||||
id: string,
|
||||
timeDifference:string,
|
||||
remarks:string,
|
||||
startDate: Date,
|
||||
recordDate: Date,
|
||||
}
|
||||
|
||||
export interface TaskScheduleRecordVO extends TaskScheduleRangeVO{
|
||||
timeDifference: string,
|
||||
remarks: string,
|
||||
taskId: string,
|
||||
}
|
||||
|
||||
export interface TaskScheduleRecordForm extends TaskScheduleRecordVO {
|
||||
recordTimeRange:Date[]
|
||||
recordTimeRange: (Date | undefined)[]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {Event} from "react-big-calendar";
|
||||
export interface TaskEvent extends Event {
|
||||
id?: any;
|
||||
name?:string;
|
||||
state?:any;
|
||||
taskType?:string;
|
||||
priority?:any;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import {httpReq} from "@/utils/axiosReq";
|
||||
import {unstable_noStore as noStore} from "next/dist/server/web/spec-extension/unstable-no-store";
|
||||
import {DataType, Request, ResponseVO, ResultPage} from "@/lib/definitions";
|
||||
import {TaskWebSelectVO} from "@/lib/task/project/definitions";
|
||||
import {AxiosResponse} from "axios";
|
||||
|
||||
export const editExpectAPI = (requestParam: {}) =>{
|
||||
noStore();
|
||||
|
@ -7,3 +10,13 @@ export const editExpectAPI = (requestParam: {}) =>{
|
|||
process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/task/editExpect', requestParam)
|
||||
}
|
||||
|
||||
export async function getTaskAndScheduleRecordAPI(requestParam: Request<TaskWebSelectVO>): Promise<ResponseVO<ResultPage<DataType>>> {
|
||||
noStore();
|
||||
// 使用 Axios 发送 POST 请求获取数据
|
||||
const response: AxiosResponse<ResponseVO<ResultPage<DataType>>> = await httpReq.post(
|
||||
process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/V2/task/my/schedule/record',requestParam);
|
||||
// 从响应中提取数据并返回
|
||||
console.log("response.data", response.data)
|
||||
return response.data;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import {TaskSelectVO} from "@/lib/task/drag/data";
|
|||
export async function selectTaskAPI(requestParam: Request<TaskSelectVO>):
|
||||
Promise<ResponseVO<ResultPage<DataType>>> {
|
||||
noStore();
|
||||
// 使用 Axios 发送 PUT 请求获取数据
|
||||
// 使用 Axios 发送 POST 请求获取数据
|
||||
const response: AxiosResponse<ResponseVO<ResultPage<DataType>>> = await httpReq.post(
|
||||
process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/V2/task/select', requestParam);
|
||||
// 从响应中提取数据并返回
|
||||
|
|
|
@ -5,9 +5,13 @@ export type TaskWebSelectVO ={
|
|||
description?:string,
|
||||
treeList:boolean,
|
||||
treeFilter?:boolean,
|
||||
treeOrList?:boolean,
|
||||
pid?:string,
|
||||
state?:string[],
|
||||
state?:string[]|string,
|
||||
taskTypeList?:string[],
|
||||
priority?:string[],
|
||||
expectedStartTimeStart?:Dayjs,
|
||||
expectedStartTimeEnd?:Dayjs
|
||||
expectedStartTimeEnd?:Dayjs,
|
||||
expectedStartTime?:Dayjs|Date,
|
||||
expectedEndTime?:Dayjs|Date,
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
const LocalContext = React.createContext({'taskState':'','expectedStartTime':'','refreshData':true});
|
||||
const LocalContext = React.createContext({'taskState':'','expectedStartTime':'','refreshData':true,
|
||||
'taskTypeList':[""]});
|
||||
|
||||
export default LocalContext;
|
||||
|
|
|
@ -29,7 +29,7 @@ html {
|
|||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
padding-right: 0.5em;
|
||||
/*padding-right: 0.5em;*/
|
||||
}
|
||||
.displayFlexRow{
|
||||
display: flex;
|
||||
|
|
|
@ -13,12 +13,14 @@ import Dropdown from "antd/es/dropdown/dropdown";
|
|||
|
||||
interface TitleOperationProps {
|
||||
setTaskState: (value: string) => void;
|
||||
setTaskTypeList: (value: string[]) => void;
|
||||
setExpectedStartTime: (value: string) => void;
|
||||
refreshData: () => void;
|
||||
}
|
||||
|
||||
export const TitleOperation: React.FC<TitleOperationProps> = ({
|
||||
setTaskState,
|
||||
setTaskTypeList,
|
||||
setExpectedStartTime,
|
||||
refreshData
|
||||
}: TitleOperationProps) => {
|
||||
|
@ -41,9 +43,9 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
|||
];
|
||||
|
||||
const typeList: CheckboxOptionType<string>[] = [
|
||||
{ label: '计划', value: '0,1,2,3', },
|
||||
{ label: '打卡', value: '4', },
|
||||
{ label: '事件', value: '5', },
|
||||
{label: '计划', value: '0,1,2,3'},
|
||||
{label: '打卡', value: '4'},
|
||||
// { label: '事件', value: '5', },
|
||||
];
|
||||
|
||||
// ✅ 监听 searchParams 变化
|
||||
|
@ -52,6 +54,7 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
|||
if (pName && pName != document.title) {
|
||||
document.title = pName;
|
||||
}
|
||||
setPathName(pathname)
|
||||
setPathParam(searchParams.toString());
|
||||
}, [searchParams]); // searchParams 变化时触发
|
||||
|
||||
|
@ -61,6 +64,7 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
|||
} else if (key == "2") {
|
||||
replace(pathName)
|
||||
setPathParam(undefined)
|
||||
refreshData()
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -107,9 +111,16 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
|||
}}>日历显示</Button>
|
||||
}
|
||||
{
|
||||
usePathname().startsWith("/task/calendar") &&
|
||||
(
|
||||
<Checkbox.Group options={typeList} defaultValue={['0,1,2,3','4']} />
|
||||
usePathname().startsWith("/task/calendar") && (<Fragment>
|
||||
<div style={{color: 'red'}}>*</div>
|
||||
<Checkbox.Group options={typeList} value={data.taskTypeList} onChange={(checkedValue) => {
|
||||
if (checkedValue.length == 0) {
|
||||
message.error("至少选择一个展示项")
|
||||
} else {
|
||||
setTaskTypeList(checkedValue)
|
||||
}
|
||||
}}/>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
{
|
||||
|
@ -173,7 +184,9 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
|||
{
|
||||
/*日历需要状态*/
|
||||
!usePathname().startsWith("/task/project") && <Fragment>
|
||||
<Button type={"primary"} onClick={()=>{refreshData()}}>搜索</Button>
|
||||
<Button type={"primary"} onClick={() => {
|
||||
refreshData()
|
||||
}}>搜索</Button>
|
||||
</Fragment>
|
||||
}
|
||||
</Space>
|
||||
|
|
|
@ -6,16 +6,20 @@ import 'react-big-calendar/lib/css/react-big-calendar.css'
|
|||
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 {commonUpdate, getTaskTreeResult, getTaskTreeResultAPI, 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 {Request, 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 {editExpectAPI} from "@/lib/task/calendar/service";
|
||||
import {editExpectAPI, getTaskAndScheduleRecordAPI} from "@/lib/task/calendar/service";
|
||||
import TaskNamePrefixIcon from "@/components/TaskNameAndIcon";
|
||||
import TaskNameAndIcon from "@/components/TaskNameAndIcon";
|
||||
import {TaskWebSelectVO} from "@/lib/task/project/definitions";
|
||||
import {message} from "antd";
|
||||
import ClickRecord from "@/components/ClickRecord";
|
||||
import {editClickRecordAPI} from "@/components/service/ScheduleTask";
|
||||
|
||||
/**
|
||||
* https://github.com/jquense/react-big-calendar?tab=readme-ov-file
|
||||
|
@ -31,16 +35,32 @@ const CalShow: React.FC = () => {
|
|||
// 展示在页面的任务,默认获取当前月的信息。
|
||||
const [events, setEvents] = useState<TaskEvent[]>([]);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [openClickRecord, setOpenClickRecord] = useState(false);
|
||||
const [description, setDescription] = useState('');
|
||||
const [operationId, setOperationId] = useState(-1);
|
||||
const [itemId, setItemId] = useState('-1');
|
||||
const [recordId,setRecordId] = useState();
|
||||
const [taskName, setTaskName] = useState("");
|
||||
const [expectedStartTime, setExpectedStartTime] = useState<Dayjs>();
|
||||
const [expectedEndTime, setExpectedEndTime] = useState<Dayjs>();
|
||||
const [range, setRange] = useState<{ start: Date; end: Date }>({
|
||||
start: dayjs(date).startOf('week').toDate(),
|
||||
end: dayjs(date).endOf('week').toDate()
|
||||
});
|
||||
const state = useContext(LocalContext).taskState;
|
||||
const {taskState:state,taskTypeList} = useContext(LocalContext);
|
||||
|
||||
const [searchObject,setSearchObject] =
|
||||
useState<Request<TaskWebSelectVO>>({
|
||||
pageSize: 9999,
|
||||
pageNumber: 1,
|
||||
data:{
|
||||
treeList:true,
|
||||
treeFilter:true,
|
||||
treeOrList:false,
|
||||
expectedStartTime:range.start,
|
||||
expectedEndTime:range.end
|
||||
}
|
||||
})
|
||||
|
||||
const handleViewChange = (newView: View) => {
|
||||
setView(newView);
|
||||
|
@ -60,23 +80,28 @@ const CalShow: React.FC = () => {
|
|||
{name: 'ALL-CHILD', value: "true", operateType: "ALL-CHILD"},
|
||||
{name: 'TREE-FILTER', value: "true", operateType: "TREE-FILTER"},
|
||||
);
|
||||
searchObject.data.pid=pid
|
||||
setSearchObject({...searchObject})
|
||||
}
|
||||
loadData(searchList);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("CalShow:useEffect:range", range)
|
||||
const searchListE = []
|
||||
// const searchListE = []
|
||||
if (pid != null) {
|
||||
searchListE.push(
|
||||
{name: "pid", value: pid, operateType: "="},
|
||||
{name: 'ALL-CHILD', value: "true", operateType: "ALL-CHILD"},
|
||||
{name: 'TREE-FILTER', value: "true", operateType: "TREE-FILTER"},
|
||||
);
|
||||
// searchListE.push(
|
||||
// {name: "pid", value: pid, operateType: "="},
|
||||
// {name: 'ALL-CHILD', value: "true", operateType: "ALL-CHILD"},
|
||||
// {name: 'TREE-FILTER', value: "true", operateType: "TREE-FILTER"},
|
||||
// );
|
||||
searchObject.data.pid=pid
|
||||
setSearchObject({...searchObject})
|
||||
}
|
||||
// searchListE.push({name: 'expectedStartTime', value: range.start, operateType: ">="})
|
||||
// searchListE.push({name: 'expectedStartTime', value: range.end, operateType: "<="})
|
||||
loadData(searchListE);
|
||||
// loadData(searchListE);
|
||||
loadData()
|
||||
/**
|
||||
* What Is This?
|
||||
* This is to prevent a memory leak, in the off chance that you
|
||||
|
@ -86,7 +111,7 @@ const CalShow: React.FC = () => {
|
|||
clearClickTimeout()
|
||||
}
|
||||
}, [useContext(LocalContext), range]);
|
||||
const message = {
|
||||
const calMessages = {
|
||||
week: '周',
|
||||
work_week: '工作周',
|
||||
day: '天',
|
||||
|
@ -96,39 +121,65 @@ const CalShow: React.FC = () => {
|
|||
today: '当下',
|
||||
agenda: '日程'
|
||||
}
|
||||
const loadData = (searchList: SearchObject[]) => {
|
||||
const loadData = (searchList?: SearchObject[]) => {
|
||||
if (state.length > 0) {
|
||||
searchList.push({name: 'state', value: state, operateType: "IN"})
|
||||
// searchList.push({name: 'state', value: state, operateType: "IN"})
|
||||
searchObject.data.state=state
|
||||
}
|
||||
// searchList.push({name: 'expectedEndTime', value: dayjs(date).endOf('month'), operateType: "NOT NULL"})
|
||||
let request = JSON.stringify({
|
||||
pageSize: 9999,
|
||||
pageNumber: 1,
|
||||
data: searchList,
|
||||
startTime: range.start,
|
||||
// startTime:dayjs(range.start).format('YYYY-MM-DD HH:mm:ss'),
|
||||
endTime: range.end,
|
||||
// endTime:dayjs(range.end).format('YYYY-MM-DD HH:mm:ss'),
|
||||
startColumn: "expected_start_time",
|
||||
endColumn: "expected_end_time"
|
||||
})
|
||||
getTaskTreeResult(request).then(responseD => {
|
||||
if (taskTypeList.length>0){
|
||||
searchObject.data.taskTypeList=taskTypeList
|
||||
}
|
||||
searchObject.data.expectedStartTime=range.start
|
||||
searchObject.data.expectedEndTime=range.end
|
||||
setSearchObject({...searchObject})
|
||||
getTaskAndScheduleRecordAPI(searchObject).then(responseD => {
|
||||
if (responseD.status.success) {
|
||||
let result: TaskEvent[] = responseD.data.content.map<TaskEvent>(taskState => {
|
||||
return {
|
||||
start: dayjs(taskState.expectedStartTime).toDate(),
|
||||
end: dayjs(taskState.expectedEndTime).toDate(),
|
||||
title: <TaskNameAndIcon task={taskState}/>,
|
||||
name:taskState.name,
|
||||
resource: taskState.id,
|
||||
id: taskState.id,
|
||||
state: taskState.state,
|
||||
priority: taskState.priority
|
||||
priority: taskState.priority,
|
||||
taskType:taskState.taskType
|
||||
}
|
||||
});
|
||||
console.log('responseD.data.content:', result)
|
||||
setEvents([...result])
|
||||
}
|
||||
})
|
||||
// searchList.push({name: 'expectedEndTime', value: dayjs(date).endOf('month'), operateType: "NOT NULL"})
|
||||
// let request = JSON.stringify({
|
||||
// pageSize: 9999,
|
||||
// pageNumber: 1,
|
||||
// data: searchList,
|
||||
// startTime: range.start,
|
||||
// // startTime:dayjs(range.start).format('YYYY-MM-DD HH:mm:ss'),
|
||||
// endTime: range.end,
|
||||
// // endTime:dayjs(range.end).format('YYYY-MM-DD HH:mm:ss'),
|
||||
// startColumn: "expected_start_time",
|
||||
// endColumn: "expected_end_time"
|
||||
// })
|
||||
// getTaskTreeResult(request).then(responseD => {
|
||||
// if (responseD.status.success) {
|
||||
// let result: TaskEvent[] = responseD.data.content.map<TaskEvent>(taskState => {
|
||||
// return {
|
||||
// start: dayjs(taskState.expectedStartTime).toDate(),
|
||||
// end: dayjs(taskState.expectedEndTime).toDate(),
|
||||
// title: <TaskNameAndIcon task={taskState}/>,
|
||||
// resource: taskState.id,
|
||||
// id: taskState.id,
|
||||
// state: taskState.state,
|
||||
// priority: taskState.priority
|
||||
// }
|
||||
// });
|
||||
// console.log('responseD.data.content:', result)
|
||||
// setEvents([...result])
|
||||
// }
|
||||
// })
|
||||
}
|
||||
const reloadData = () => {
|
||||
setOpen(false)
|
||||
|
@ -146,15 +197,19 @@ const CalShow: React.FC = () => {
|
|||
)
|
||||
|
||||
const handleSelectEvent = useCallback(
|
||||
(event: Event, e: React.SyntheticEvent<HTMLElement>) => {
|
||||
(event: TaskEvent, e: React.SyntheticEvent<HTMLElement>) => {
|
||||
clearClickTimeout()
|
||||
clickRef.current = window.setTimeout(() => {
|
||||
// window.alert(event.title);
|
||||
console.log("event")
|
||||
if(event.taskType=='4'){
|
||||
setTaskName(event.name||"")
|
||||
setRecordId(event.id)
|
||||
setOpenClickRecord(true);
|
||||
}else {
|
||||
setOperationId(OPERATION_BUTTON_TYPE.DETAIL)
|
||||
setDescription("任务详情")
|
||||
setItemId(event.resource)
|
||||
setOpen(true);
|
||||
}
|
||||
}, 250)
|
||||
},
|
||||
[]
|
||||
|
@ -170,6 +225,10 @@ const CalShow: React.FC = () => {
|
|||
const doubleClick = (event: TaskEvent, e: React.SyntheticEvent<HTMLElement>) => {
|
||||
clearClickTimeout()
|
||||
clickRef.current = window.setTimeout(() => {
|
||||
if (event.taskType=='4'||event.taskType=='5'){
|
||||
message.error("计划双击完成,非计划双击无效果。")
|
||||
return;
|
||||
}
|
||||
// 数据落库
|
||||
commonUpdate({
|
||||
updateColumnList: [{
|
||||
|
@ -205,11 +264,19 @@ const CalShow: React.FC = () => {
|
|||
if (!allDay && droppedOnAllDaySlot) {
|
||||
event.allDay = true
|
||||
}
|
||||
if (event.taskType=='4'){
|
||||
editClickRecordAPI({
|
||||
id:event.id,
|
||||
startDate:dayjs(start!).toDate(),
|
||||
recordDate:dayjs(end!).toDate(),
|
||||
});
|
||||
}else {
|
||||
editExpectAPI({
|
||||
expectedStartTime: start,
|
||||
expectedEndTime: end,
|
||||
id: 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);
|
||||
|
@ -275,10 +342,12 @@ const CalShow: React.FC = () => {
|
|||
reloadData={reloadData} expectedStartTime={expectedStartTime}
|
||||
closeOpen={() => setOpen(false)}
|
||||
expectedEndTime={expectedEndTime}/>}
|
||||
{openClickRecord &&
|
||||
<ClickRecord recordId={recordId} taskName={taskName} openClickRecord={openClickRecord} setOpenClickRecord={setOpenClickRecord}/>}
|
||||
<DragAndDropCalendar
|
||||
// 本地设置
|
||||
localizer={localizer}
|
||||
messages={message}
|
||||
messages={calMessages}
|
||||
// 修改style
|
||||
eventPropGetter={eventPropGetter}
|
||||
events={events}
|
||||
|
|
|
@ -9,6 +9,7 @@ import dayjs from "dayjs";
|
|||
import {getTaskState, taskPriorityList} from "@/lib/task/project/data";
|
||||
import 'react-virtualized/styles.css';
|
||||
import RightOption from "@/ui/task/RightOption";
|
||||
import TaskNameAndIcon from "@/components/TaskNameAndIcon";
|
||||
|
||||
|
||||
interface DroppableTableProps {
|
||||
|
@ -95,7 +96,7 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => {
|
|||
<div style={{width: '20%',paddingLeft:"1rem"}} className='displayFlexRow'>
|
||||
<Tooltip placement="topLeft" title={record.name}
|
||||
className='displayFlexRow'>
|
||||
<div className='displayFlexRow'>{record.name}</div>
|
||||
<div className='displayFlexRow'> <TaskNameAndIcon task={record}/></div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div style={{width: '45%', boxSizing: 'border-box', minWidth: 0}}
|
||||
|
|
|
@ -123,7 +123,7 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
|
|||
if (props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD) {
|
||||
addTask(request).then(response => {
|
||||
console.log('response', response)
|
||||
if (response.status.success) {
|
||||
if (response.data.status.success) {
|
||||
message.success("添加任务成功:" + response.data)
|
||||
props.handleCancel()
|
||||
}
|
||||
|
@ -140,11 +140,11 @@ export const DetailForm: React.FC<DetailFormProps> = (props) => {
|
|||
}
|
||||
updateTask(request).then(response => {
|
||||
console.log('response', response)
|
||||
if (response.status.success) {
|
||||
if (response.data.status.success) {
|
||||
message.success("修改任务成功:" + response.data)
|
||||
props.handleCancel()
|
||||
}else {
|
||||
message.error(response.status.message)
|
||||
message.error(response.data.status.message)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -126,18 +126,25 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
|
||||
const cascaderOnChange: CascaderProps<CascaderOption>['onChange'] =
|
||||
(value: (string | number)[], selectedOptions: CascaderOption[]) => {
|
||||
setOnceConsumeChange(value.map(toString))
|
||||
if (value.length>0){
|
||||
console.log({value})
|
||||
setOnceConsumeChange(value.map(valueMap=>valueMap.toString()))
|
||||
}else {
|
||||
setOnceConsumeChange([])
|
||||
}
|
||||
|
||||
};
|
||||
const changeValueToLabel = ()=>{
|
||||
const onceConsumeShow = ["1", "小時"];
|
||||
if (onceConsumeChange&&onceConsumeChange.length==2){
|
||||
if(onceConsumeChange[1]=='m'){
|
||||
onceConsumeChange[1]='分钟'
|
||||
onceConsumeShow[1]='分钟'
|
||||
}else if(onceConsumeChange[1]=='h'){
|
||||
onceConsumeChange[1]='小时'
|
||||
onceConsumeShow[1]='小时'
|
||||
}else if(onceConsumeChange[1]=='d'){
|
||||
onceConsumeChange[1]='天'
|
||||
onceConsumeShow[1]='天'
|
||||
}
|
||||
return onceConsumeChange;
|
||||
return onceConsumeShow;
|
||||
}else {
|
||||
return []
|
||||
}
|
||||
|
@ -384,6 +391,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
if (priority) {
|
||||
values.priority = priority.code
|
||||
}
|
||||
console.log('update:values:',{values})
|
||||
// todo 修改
|
||||
if (props.operationId === OPERATION_BUTTON_TYPE.UPDATE || (props.operationId === OPERATION_BUTTON_TYPE.DETAIL && !editFormDisable)) {
|
||||
await updateTask(values).then(response => {
|
||||
|
@ -626,7 +634,6 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
<Cascader options={options} loadData={cascaderLoadData}
|
||||
onChange={cascaderOnChange}
|
||||
defaultValue={changeValueToLabel()}
|
||||
onClick={()=>setOnceConsumeChange([])}
|
||||
clearIcon={true}
|
||||
// value={remindType.split(",")}
|
||||
/>
|
||||
|
|
Loading…
Reference in New Issue