feat:添加复制功能及农历
This commit is contained in:
parent
2cc85e67dc
commit
34b85a177c
|
@ -16,6 +16,7 @@
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
|
"lunar-calendar": "^0.1.4",
|
||||||
"next": "14.2.29",
|
"next": "14.2.29",
|
||||||
"postcss": "8.4.31",
|
"postcss": "8.4.31",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
|
@ -4840,6 +4841,14 @@
|
||||||
"node": "14 || >=16.14"
|
"node": "14 || >=16.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lunar-calendar": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/lunar-calendar/-/lunar-calendar-0.1.4.tgz",
|
||||||
|
"integrity": "sha512-5r87vbg5yg56z/jkf3A+Ur+ZggUTiJw1VATT9P7RELQgWcTNhfJ+OLkNYroSna6r65bMqyaAgapo9vRN40L75A==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/luxon": {
|
"node_modules/luxon": {
|
||||||
"version": "3.4.4",
|
"version": "3.4.4",
|
||||||
"resolved": "https://registry.npmmirror.com/luxon/-/luxon-3.4.4.tgz",
|
"resolved": "https://registry.npmmirror.com/luxon/-/luxon-3.4.4.tgz",
|
||||||
|
@ -11500,6 +11509,11 @@
|
||||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.2.0.tgz",
|
||||||
"integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="
|
"integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="
|
||||||
},
|
},
|
||||||
|
"lunar-calendar": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/lunar-calendar/-/lunar-calendar-0.1.4.tgz",
|
||||||
|
"integrity": "sha512-5r87vbg5yg56z/jkf3A+Ur+ZggUTiJw1VATT9P7RELQgWcTNhfJ+OLkNYroSna6r65bMqyaAgapo9vRN40L75A=="
|
||||||
|
},
|
||||||
"luxon": {
|
"luxon": {
|
||||||
"version": "3.4.4",
|
"version": "3.4.4",
|
||||||
"resolved": "https://registry.npmmirror.com/luxon/-/luxon-3.4.4.tgz",
|
"resolved": "https://registry.npmmirror.com/luxon/-/luxon-3.4.4.tgz",
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
|
"lunar-calendar": "^0.1.4",
|
||||||
"next": "14.2.29",
|
"next": "14.2.29",
|
||||||
"postcss": "8.4.31",
|
"postcss": "8.4.31",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default function Layout({children}: { children: React.ReactNode }) {
|
||||||
const [spinning,setSpinning]=useState(false);
|
const [spinning,setSpinning]=useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
selectData()
|
selectData()
|
||||||
}, [data])
|
}, [data,pid])
|
||||||
|
|
||||||
function selectData() {
|
function selectData() {
|
||||||
setSpinning(true)
|
setSpinning(true)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {Button, Form, message, Popconfirm} from "antd";
|
import {Button, Form, message, Popconfirm} from "antd";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useRef, useState} from "react";
|
||||||
import {
|
import {
|
||||||
ModalForm,
|
ModalForm,
|
||||||
ProFormDateTimeRangePicker,
|
ProFormDateTimeRangePicker,
|
||||||
|
@ -17,7 +17,6 @@ import dayjs, {UnitTypeShort} from "dayjs";
|
||||||
import {onceConsumerRead} from "@/utils/codeToReadName";
|
import {onceConsumerRead} from "@/utils/codeToReadName";
|
||||||
import {betweenTime} from "@/utils/timeFormatUtil";
|
import {betweenTime} from "@/utils/timeFormatUtil";
|
||||||
import {QuestionCircleOutlined} from "@ant-design/icons";
|
import {QuestionCircleOutlined} from "@ant-design/icons";
|
||||||
import {deleteTask} from "@/lib/task/project/data";
|
|
||||||
|
|
||||||
interface ClickRecordProps {
|
interface ClickRecordProps {
|
||||||
openClickRecord?: boolean;
|
openClickRecord?: boolean;
|
||||||
|
@ -67,6 +66,7 @@ const ClickRecord: React.FC<ClickRecordProps> = ({
|
||||||
form.setFieldsValue(data)
|
form.setFieldsValue(data)
|
||||||
}
|
}
|
||||||
}, [recordId]);
|
}, [recordId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<ModalForm<TaskScheduleRecordForm>
|
<ModalForm<TaskScheduleRecordForm>
|
||||||
|
@ -139,8 +139,11 @@ const ClickRecord: React.FC<ClickRecordProps> = ({
|
||||||
} else {
|
} else {
|
||||||
await clickRecordAPI(values);
|
await clickRecordAPI(values);
|
||||||
}
|
}
|
||||||
|
console.log("before reloadData")
|
||||||
|
reloadData?.();
|
||||||
|
console.log("after reloadData")
|
||||||
|
// 然后在onFinish中使用
|
||||||
setOpenClickRecord?.(false)
|
setOpenClickRecord?.(false)
|
||||||
reloadData?.()
|
|
||||||
return true
|
return true
|
||||||
}catch (e){
|
}catch (e){
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
import {TaskMessage} from "@/lib/definitions";
|
import {TaskMessage} from "@/lib/definitions";
|
||||||
import React, {Fragment} from "react";
|
import React, {Fragment} from "react";
|
||||||
import {SmileOutlined} from "@ant-design/icons";
|
import {CopyOutlined, SmileOutlined} from "@ant-design/icons";
|
||||||
|
import {copyToClipboard} from "@/lib/copyToClipboard";
|
||||||
|
|
||||||
const TaskNameAndIcon = (props: {task:TaskMessage}) => {
|
const TaskNameAndIcon = (props: { task: TaskMessage }) => {
|
||||||
return (<Fragment>
|
return (<Fragment>
|
||||||
|
<CopyOutlined onClick={(e) => {
|
||||||
|
e.preventDefault(); // 阻止默认行为(如果有)
|
||||||
|
e.stopPropagation(); // 阻止事件冒泡
|
||||||
|
copyToClipboard(props.task.name)
|
||||||
|
}}/>
|
||||||
{props.task.fId &&
|
{props.task.fId &&
|
||||||
<svg className="icon" aria-hidden="true">
|
<svg className="icon" aria-hidden="true">
|
||||||
<use xlinkHref="#icon-tuandui"></use>
|
<use xlinkHref="#icon-tuandui"></use>
|
||||||
|
@ -19,7 +25,7 @@ const TaskNameAndIcon = (props: {task:TaskMessage}) => {
|
||||||
<use xlinkHref="#icon-dingshi"></use>
|
<use xlinkHref="#icon-dingshi"></use>
|
||||||
</svg>
|
</svg>
|
||||||
}
|
}
|
||||||
{props.task.taskType == '4' && <SmileOutlined className="icon"/>
|
{props.task.taskType == '4' && <SmileOutlined className="icon"/>
|
||||||
}
|
}
|
||||||
<span>{props.task.name}</span>
|
<span>{props.task.name}</span>
|
||||||
</Fragment>)
|
</Fragment>)
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
declare module 'lunar-calendar' {
|
||||||
|
export interface LunarDate {
|
||||||
|
lunarYear: number;
|
||||||
|
lunarMonth: number;
|
||||||
|
lunarDay: number;
|
||||||
|
zodiac: string;
|
||||||
|
ganZhiYear: string;
|
||||||
|
ganZhiMonth: string;
|
||||||
|
ganZhiDay: string;
|
||||||
|
lunarMonthName: string;
|
||||||
|
lunarDayName: string;
|
||||||
|
solarTerm: string;
|
||||||
|
// 其他农历字段...
|
||||||
|
}
|
||||||
|
|
||||||
|
export function solarToLunar(
|
||||||
|
year: number,
|
||||||
|
month: number,
|
||||||
|
day: number
|
||||||
|
): LunarDate;
|
||||||
|
|
||||||
|
// 其他可能的方法...
|
||||||
|
}
|
|
@ -74,7 +74,7 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
||||||
} else if (key == "2") {
|
} else if (key == "2") {
|
||||||
replace(pathName)
|
replace(pathName)
|
||||||
setPathParam(undefined)
|
setPathParam(undefined)
|
||||||
refreshData()
|
// refreshData()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
'use client'
|
'use client'
|
||||||
import React, {Fragment, useCallback, useContext, useEffect, useMemo, useRef, useState} from "react";
|
import React, {Fragment, useCallback, useContext, useEffect, useMemo, useRef, useState} from "react";
|
||||||
import {Calendar, dateFnsLocalizer, dayjsLocalizer, Event, SlotInfo, View} from 'react-big-calendar'
|
import {
|
||||||
|
Calendar,
|
||||||
|
Culture,
|
||||||
|
dateFnsLocalizer,
|
||||||
|
DateLocalizer,
|
||||||
|
dayjsLocalizer,
|
||||||
|
Event,
|
||||||
|
SlotInfo,
|
||||||
|
View
|
||||||
|
} from 'react-big-calendar'
|
||||||
import dayjs, {Dayjs} from 'dayjs'
|
import dayjs, {Dayjs} from 'dayjs'
|
||||||
import 'dayjs/locale/zh-cn';
|
import 'dayjs/locale/zh-cn';
|
||||||
import 'react-big-calendar/lib/css/react-big-calendar.css'
|
import 'react-big-calendar/lib/css/react-big-calendar.css'
|
||||||
|
@ -20,8 +29,9 @@ import {TaskWebSelectVO} from "@/lib/task/project/definitions";
|
||||||
import {message, Modal, Spin} from "antd";
|
import {message, Modal, Spin} from "antd";
|
||||||
import ClickRecord from "@/components/ClickRecord";
|
import ClickRecord from "@/components/ClickRecord";
|
||||||
import {editClickRecordRangeAPI} from "@/components/service/ScheduleTask";
|
import {editClickRecordRangeAPI} from "@/components/service/ScheduleTask";
|
||||||
import {ExclamationCircleFilled, LoadingOutlined} from "@ant-design/icons";
|
import {CopyOutlined, ExclamationCircleFilled, LoadingOutlined} from "@ant-design/icons";
|
||||||
|
import {copyToClipboard} from "@/lib/copyToClipboard";
|
||||||
|
import {solarToLunar} from "lunar-calendar";
|
||||||
const {confirm} = Modal;
|
const {confirm} = Modal;
|
||||||
/**
|
/**
|
||||||
* https://github.com/jquense/react-big-calendar?tab=readme-ov-file
|
* https://github.com/jquense/react-big-calendar?tab=readme-ov-file
|
||||||
|
@ -64,7 +74,16 @@ const CalShow: React.FC = () => {
|
||||||
expectedEndTime: range.end
|
expectedEndTime: range.end
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const dateFormat = (date: Date, culture?: Culture, localizer?: DateLocalizer) => {
|
||||||
|
const solarDate = new Date(date);
|
||||||
|
const lunarDate = solarToLunar(
|
||||||
|
solarDate.getFullYear(),
|
||||||
|
solarDate.getMonth() + 1,
|
||||||
|
solarDate.getDate()
|
||||||
|
);
|
||||||
|
console.log({lunarDate})
|
||||||
|
return `${solarDate.getDate()}/农历:${lunarDate.lunarMonthName}-${lunarDate.lunarDayName}`;
|
||||||
|
};
|
||||||
const handleViewChange = (newView: View) => {
|
const handleViewChange = (newView: View) => {
|
||||||
setView(newView);
|
setView(newView);
|
||||||
};
|
};
|
||||||
|
@ -75,19 +94,23 @@ const CalShow: React.FC = () => {
|
||||||
clickRef && typeof clickRef.current === 'number' && !isNaN(clickRef.current) && isFinite(clickRef.current) && window.clearTimeout(clickRef.current)
|
clickRef && typeof clickRef.current === 'number' && !isNaN(clickRef.current) && isFinite(clickRef.current) && window.clearTimeout(clickRef.current)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会触发范围变化
|
||||||
|
* @param newDate
|
||||||
|
*/
|
||||||
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: 'ALL-CHILD', value: "true", operateType: "ALL-CHILD"},
|
// {name: 'ALL-CHILD', value: "true", operateType: "ALL-CHILD"},
|
||||||
{name: 'TREE-FILTER', value: "true", operateType: "TREE-FILTER"},
|
// {name: 'TREE-FILTER', value: "true", operateType: "TREE-FILTER"},
|
||||||
);
|
// );
|
||||||
searchObject.data.pid = pid
|
// searchObject.data.pid = pid
|
||||||
setSearchObject({...searchObject})
|
// setSearchObject({...searchObject})
|
||||||
}
|
// }
|
||||||
loadData(searchList);
|
// loadData();
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -102,6 +125,10 @@ const CalShow: React.FC = () => {
|
||||||
// );
|
// );
|
||||||
searchObject.data.pid = pid
|
searchObject.data.pid = pid
|
||||||
setSearchObject({...searchObject})
|
setSearchObject({...searchObject})
|
||||||
|
} else {
|
||||||
|
const {pid, ...search} = searchObject.data
|
||||||
|
searchObject.data = search
|
||||||
|
setSearchObject({...searchObject})
|
||||||
}
|
}
|
||||||
// searchListE.push({name: 'expectedStartTime', value: range.start, operateType: ">="})
|
// searchListE.push({name: 'expectedStartTime', value: range.start, operateType: ">="})
|
||||||
// searchListE.push({name: 'expectedStartTime', value: range.end, operateType: "<="})
|
// searchListE.push({name: 'expectedStartTime', value: range.end, operateType: "<="})
|
||||||
|
@ -115,7 +142,7 @@ const CalShow: React.FC = () => {
|
||||||
return () => {
|
return () => {
|
||||||
clearClickTimeout()
|
clearClickTimeout()
|
||||||
}
|
}
|
||||||
}, [state, taskTypeList, refreshData, range]);
|
}, [state, taskTypeList, refreshData, range, pid]);
|
||||||
const calMessages = {
|
const calMessages = {
|
||||||
week: '周',
|
week: '周',
|
||||||
work_week: '工作周',
|
work_week: '工作周',
|
||||||
|
@ -135,6 +162,7 @@ const CalShow: React.FC = () => {
|
||||||
noEventsInRange: '暂无计划',
|
noEventsInRange: '暂无计划',
|
||||||
}
|
}
|
||||||
const loadData = (searchList?: SearchObject[]) => {
|
const loadData = (searchList?: SearchObject[]) => {
|
||||||
|
console.log("loadData")
|
||||||
setSpinning(true)
|
setSpinning(true)
|
||||||
searchObject.data.state = state
|
searchObject.data.state = state
|
||||||
searchObject.data.taskTypeList = taskTypeList
|
searchObject.data.taskTypeList = taskTypeList
|
||||||
|
@ -148,7 +176,12 @@ const CalShow: React.FC = () => {
|
||||||
start: dayjs(taskState.expectedStartTime).toDate(),
|
start: dayjs(taskState.expectedStartTime).toDate(),
|
||||||
end: dayjs(taskState.expectedEndTime).toDate(),
|
end: dayjs(taskState.expectedEndTime).toDate(),
|
||||||
title: <Fragment><TaskNameAndIcon task={taskState}/>
|
title: <Fragment><TaskNameAndIcon task={taskState}/>
|
||||||
<div>{taskState.description}</div>
|
<div>
|
||||||
|
{taskState.description && <CopyOutlined onClick={(e) => {
|
||||||
|
e.preventDefault(); // 阻止默认行为(如果有)
|
||||||
|
e.stopPropagation(); // 阻止事件冒泡
|
||||||
|
copyToClipboard(taskState.description)
|
||||||
|
}}/>} {taskState.description}</div>
|
||||||
</Fragment>,
|
</Fragment>,
|
||||||
// style: {
|
// style: {
|
||||||
// backgroundColor: 'green',
|
// backgroundColor: 'green',
|
||||||
|
@ -198,9 +231,13 @@ const CalShow: React.FC = () => {
|
||||||
// }
|
// }
|
||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* from表单使用,打卡记录新建使用
|
||||||
|
*/
|
||||||
const reloadData = () => {
|
const reloadData = () => {
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
handleNavigate(date)
|
loadData();
|
||||||
|
// handleNavigate(date)
|
||||||
}
|
}
|
||||||
const handleSelectSlot = useCallback(
|
const handleSelectSlot = useCallback(
|
||||||
({start, end}: SlotInfo) => {
|
({start, end}: SlotInfo) => {
|
||||||
|
@ -246,7 +283,7 @@ const CalShow: React.FC = () => {
|
||||||
message.error("计划双击完成,非计划双击无效果。")
|
message.error("计划双击完成,非计划双击无效果。")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.state=='7'){
|
if (event.state == '7') {
|
||||||
message.error("任务已经完成")
|
message.error("任务已经完成")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -276,7 +313,7 @@ const CalShow: React.FC = () => {
|
||||||
if (existing !== undefined && filtered !== undefined) {
|
if (existing !== undefined && filtered !== undefined) {
|
||||||
result = [...filtered, {...existing, state: "7"}];
|
result = [...filtered, {...existing, state: "7"}];
|
||||||
}
|
}
|
||||||
let strings = state==""?[]:state.split(",");
|
let strings = state == "" ? [] : state.split(",");
|
||||||
console.log('result', result, strings)
|
console.log('result', result, strings)
|
||||||
return result.filter((ev: TaskEvent) => !ev.state || strings.length == 0 || strings.indexOf(ev.state.toString()) >= 0);
|
return result.filter((ev: TaskEvent) => !ev.state || strings.length == 0 || strings.indexOf(ev.state.toString()) >= 0);
|
||||||
})
|
})
|
||||||
|
@ -340,36 +377,31 @@ const CalShow: React.FC = () => {
|
||||||
console.log("rangeChange:", rangeLet, (current ? current : view))
|
console.log("rangeChange:", rangeLet, (current ? current : view))
|
||||||
// view 为天的时候类型为数组,index:0为当天
|
// view 为天的时候类型为数组,index:0为当天
|
||||||
if ((current ? current : view) === "day" && Array.isArray(rangeLet)) {
|
if ((current ? current : view) === "day" && Array.isArray(rangeLet)) {
|
||||||
if (range.start.valueOf() > rangeLet[0].valueOf()) {
|
// if (range.start.valueOf() > rangeLet[0].valueOf()) {
|
||||||
// setRange({...range, start: rangeLet[0]})
|
range.start = rangeLet[0];
|
||||||
range.start=rangeLet[0];
|
// }
|
||||||
} else if (range.end.valueOf() < rangeLet[0].valueOf()) {
|
// if (range.end.valueOf() < rangeLet[0].valueOf()) {
|
||||||
// setRange({...range, end: rangeLet[0]})
|
range.end = dayjs(rangeLet[0]).add(1,'d').toDate()
|
||||||
range.end=rangeLet[0]
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 为周的时候类型为数组,周一到周日七天
|
// 为周的时候类型为数组,周一到周日七天
|
||||||
if ((current ? current : view) === "week" && Array.isArray(rangeLet)) {
|
if ((current ? current : view) === "week" && Array.isArray(rangeLet)) {
|
||||||
if (range.start.valueOf() > rangeLet[0].valueOf()) {
|
// if (range.start.valueOf() > rangeLet[0].valueOf()) {
|
||||||
// setRange({...range, start: rangeLet[0]})
|
range.start = rangeLet[0];
|
||||||
range.start=rangeLet[0];
|
// }
|
||||||
}
|
// if (range.end.valueOf() < rangeLet[6].valueOf()) {
|
||||||
if (range.end.valueOf() < rangeLet[6].valueOf()) {
|
range.end = dayjs(rangeLet[6]).add(1,'d').toDate()
|
||||||
// setRange({...range, end: rangeLet[6]})
|
// }
|
||||||
range.end=rangeLet[6]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 为月的时候类型为对象
|
// 为月的时候类型为对象
|
||||||
if ((current ? current : view) === "month" && rangeLet && !Array.isArray(rangeLet)) {
|
if ((current ? current : view) === "month" && rangeLet && !Array.isArray(rangeLet)) {
|
||||||
if (range.start.valueOf() > rangeLet.start.valueOf()) {
|
// if (range.start.valueOf() > rangeLet.start.valueOf()) {
|
||||||
// setRange({...range, start: rangeLet.start})
|
range.start = rangeLet.start
|
||||||
range.start = rangeLet.start
|
// }
|
||||||
}
|
// if (range.end.valueOf() < rangeLet.end.valueOf()) {
|
||||||
if (range.end.valueOf() < rangeLet.end.valueOf()) {
|
range.end = dayjs(rangeLet.end).add(1,'d').toDate()
|
||||||
// setRange({...range, end: rangeLet.end})
|
|
||||||
range.end = rangeLet.end
|
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
setRange({...range})
|
setRange({...range})
|
||||||
}
|
}
|
||||||
|
@ -388,9 +420,24 @@ const CalShow: React.FC = () => {
|
||||||
reloadData={loadData}/>}
|
reloadData={loadData}/>}
|
||||||
<Spin spinning={spinning} indicator={<LoadingOutlined style={{fontSize: 48}} spin/>} fullscreen/>
|
<Spin spinning={spinning} indicator={<LoadingOutlined style={{fontSize: 48}} spin/>} fullscreen/>
|
||||||
<DragAndDropCalendar
|
<DragAndDropCalendar
|
||||||
|
|
||||||
// 本地设置
|
// 本地设置
|
||||||
localizer={localizer}
|
localizer={localizer}
|
||||||
messages={calMessages}
|
messages={calMessages}
|
||||||
|
formats={{
|
||||||
|
dayFormat: dateFormat,
|
||||||
|
dateFormat: dateFormat,
|
||||||
|
monthHeaderFormat: (date) => {
|
||||||
|
const solarDate = new Date(date);
|
||||||
|
const lunarDate = solarToLunar(
|
||||||
|
solarDate.getFullYear(),
|
||||||
|
solarDate.getMonth() + 1,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
return `${solarDate.getFullYear()}年${solarDate.getMonth() + 1}月 (农历${lunarDate.lunarMonthName})`;
|
||||||
|
},
|
||||||
|
dayHeaderFormat: dateFormat
|
||||||
|
}}
|
||||||
// 修改style
|
// 修改style
|
||||||
eventPropGetter={eventPropGetter}
|
eventPropGetter={eventPropGetter}
|
||||||
events={events}
|
events={events}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import {getTaskState, taskPriorityList, taskStateList} from "@/lib/task/project/
|
||||||
import 'react-virtualized/styles.css';
|
import 'react-virtualized/styles.css';
|
||||||
import RightOption from "@/ui/task/RightOption";
|
import RightOption from "@/ui/task/RightOption";
|
||||||
import TaskNameAndIcon from "@/components/TaskNameAndIcon";
|
import TaskNameAndIcon from "@/components/TaskNameAndIcon";
|
||||||
|
import {copyToClipboard} from "@/lib/copyToClipboard";
|
||||||
|
import {CopyOutlined} from "@ant-design/icons";
|
||||||
|
|
||||||
|
|
||||||
interface DroppableTableProps {
|
interface DroppableTableProps {
|
||||||
|
@ -99,9 +101,13 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => {
|
||||||
<div className='displayFlexRow'> <TaskNameAndIcon task={record}/></div>
|
<div className='displayFlexRow'> <TaskNameAndIcon task={record}/></div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div style={{width: '45%', boxSizing: 'border-box', minWidth: 0}}
|
<div style={{width: '45%', boxSizing: 'border-box', minWidth: 0,display: 'flex',justifyContent:"start"}}
|
||||||
className='displayFlexRow'>
|
>
|
||||||
<Tooltip placement="topLeft" title={record.description}>
|
<Tooltip placement="topLeft" title={record.description} className="displayFlexRow">
|
||||||
|
{record.description && <CopyOutlined onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
copyToClipboard(record.description)
|
||||||
|
}}/>}
|
||||||
<div className='displayFlexRow text-ellipsis'>{record.description}</div>
|
<div className='displayFlexRow text-ellipsis'>{record.description}</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -481,8 +481,6 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
await addTask(values).then(response => {
|
await addTask(values).then(response => {
|
||||||
console.log('response', response)
|
console.log('response', response)
|
||||||
if (response.data.status.success) {
|
if (response.data.status.success) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use client'
|
'use client'
|
||||||
import {
|
import {
|
||||||
CheckSquareFilled,
|
CheckSquareFilled, CopyOutlined,
|
||||||
QuestionCircleOutlined
|
QuestionCircleOutlined
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import type {ActionType, FormInstance, ProColumns, ProFormInstance} from '@ant-design/pro-components';
|
import type {ActionType, FormInstance, ProColumns, ProFormInstance} from '@ant-design/pro-components';
|
||||||
|
@ -21,6 +21,7 @@ import '@/ui/task/project/TreeTablePro.modules.css'
|
||||||
import {useSearchParams} from "next/navigation";
|
import {useSearchParams} from "next/navigation";
|
||||||
import {TaskWebSelectVO} from "@/lib/task/project/definitions";
|
import {TaskWebSelectVO} from "@/lib/task/project/definitions";
|
||||||
import TaskNameAndIcon from "@/components/TaskNameAndIcon";
|
import TaskNameAndIcon from "@/components/TaskNameAndIcon";
|
||||||
|
import {copyToClipboard} from "@/lib/copyToClipboard";
|
||||||
|
|
||||||
const TreeTablePro: React.FC = (props: { joinId?: string }) => {
|
const TreeTablePro: React.FC = (props: { joinId?: string }) => {
|
||||||
// 刷新表格
|
// 刷新表格
|
||||||
|
@ -64,9 +65,15 @@ const TreeTablePro: React.FC = (props: { joinId?: string }) => {
|
||||||
title: '任务描述',
|
title: '任务描述',
|
||||||
dataIndex: 'description',
|
dataIndex: 'description',
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return <Tooltip placement="topLeft" title={record.description}>
|
return <Fragment>
|
||||||
<div className='text-ellipsis'>{record.description}</div>
|
|
||||||
</Tooltip>
|
<Tooltip placement="topLeft" title={record.description}>
|
||||||
|
<div className='text-ellipsis'>{record.description && <CopyOutlined onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
copyToClipboard(record.description)
|
||||||
|
}}/>}{record.description}</div>
|
||||||
|
</Tooltip>
|
||||||
|
</Fragment>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -246,16 +253,16 @@ const TreeTablePro: React.FC = (props: { joinId?: string }) => {
|
||||||
name: params.name,
|
name: params.name,
|
||||||
description: params.description,
|
description: params.description,
|
||||||
}
|
}
|
||||||
// 列表展示
|
// 列表展示
|
||||||
if (!switchChecked) {
|
if (!switchChecked) {
|
||||||
search.treeOrList=false;
|
search.treeOrList = false;
|
||||||
search.treeList=true;
|
search.treeList = true;
|
||||||
search.treeFilter=true;
|
search.treeFilter = true;
|
||||||
}else {
|
} else {
|
||||||
// 树展示
|
// 树展示
|
||||||
search.treeOrList=true;
|
search.treeOrList = true;
|
||||||
search.treeList=true;
|
search.treeList = true;
|
||||||
search.treeFilter=filterChecked;
|
search.treeFilter = filterChecked;
|
||||||
}
|
}
|
||||||
if (params.state) {
|
if (params.state) {
|
||||||
search.state = params.state.join(',');
|
search.state = params.state.join(',');
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import axios, {CancelTokenSource} from "axios";
|
import axios, {AxiosInterceptorOptions, CancelTokenSource} from "axios";
|
||||||
import {message} from "antd";
|
import {message} from "antd";
|
||||||
import {refreshTokenAPI} from "@/lib/login/service";
|
import {refreshTokenAPI} from "@/lib/login/service";
|
||||||
|
|
||||||
|
@ -19,11 +19,14 @@ const cancelTokenSource: CancelTokenSource = axios.CancelToken.source();
|
||||||
httpReq.defaults.headers.common['Accept'] = 'application/json';
|
httpReq.defaults.headers.common['Accept'] = 'application/json';
|
||||||
// 请求前处理
|
// 请求前处理
|
||||||
httpReq.interceptors.request.use((config) => {
|
httpReq.interceptors.request.use((config) => {
|
||||||
|
console.log("config.url", config.url)
|
||||||
// 从本地存储中获取 token
|
// 从本地存储中获取 token
|
||||||
const token = localStorage.getItem('platform-security');
|
const token = localStorage.getItem('platform-security');
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
reduceToken(token)
|
if (config.url && config.url.indexOf("refreshToken") == -1) {
|
||||||
|
reduceToken(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
config.headers.set("source-client", "web")
|
config.headers.set("source-client", "web")
|
||||||
return config;
|
return config;
|
||||||
|
@ -32,6 +35,9 @@ httpReq.interceptors.request.use((config) => {
|
||||||
console.info("interceptors错误提示.request" + error)
|
console.info("interceptors错误提示.request" + error)
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
})
|
})
|
||||||
|
httpReq.interceptors.response.use((onFulfilled) => {
|
||||||
|
return onFulfilled;
|
||||||
|
})
|
||||||
|
|
||||||
function reduceToken(token: string) {
|
function reduceToken(token: string) {
|
||||||
if (!token || token.split('.').length !== 3) {
|
if (!token || token.split('.').length !== 3) {
|
||||||
|
@ -62,10 +68,10 @@ function reduceToken(token: string) {
|
||||||
console.log("updateToken:decodedToken:", decodedToken);
|
console.log("updateToken:decodedToken:", decodedToken);
|
||||||
const endTime = decodedToken.exp;
|
const endTime = decodedToken.exp;
|
||||||
console.log('距离过期' + (((endTime as number) - (Date.now() / 1000)) / 60 / 60 + '小时'))
|
console.log('距离过期' + (((endTime as number) - (Date.now() / 1000)) / 60 / 60 + '小时'))
|
||||||
if (((endTime as number) - (Date.now() / 1000)) / 60 / 60 / 24 < 3) {
|
if (((endTime as number) - (Date.now() / 1000)) / 60 / 60 < 3) {
|
||||||
// 小于3小时更新toke3小时或12小时不动过期、内不动
|
// 小于3小时更新toke3小时或12小时不动过期、内不动
|
||||||
refreshTokenAPI().then(res=>{
|
refreshTokenAPI().then(res => {
|
||||||
if (res.data.status.success){
|
if (res.data.status.success) {
|
||||||
localStorage.setItem('platform-security', res.data.data)
|
localStorage.setItem('platform-security', res.data.data)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue