Compare commits
No commits in common. "8ca5bb4e31e1e88d4dc1768c019d032f1d9b8de6" and "fdd657a1b30b284cb995644f2e8fd2e0d3a842bc" have entirely different histories.
8ca5bb4e31
...
fdd657a1b3
|
@ -24,8 +24,7 @@
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-virtualized": "^9.22.6",
|
"react-virtualized": "^9.22.6",
|
||||||
"sass": "^1.77.3",
|
"sass": "^1.77.3",
|
||||||
"tailwindcss": "3.3.3",
|
"tailwindcss": "3.3.3"
|
||||||
"uuid": "^11.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
|
@ -34,7 +33,6 @@
|
||||||
"@types/react-big-calendar": "^1.8.9",
|
"@types/react-big-calendar": "^1.8.9",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"@types/react-virtualized": "^9.22.2",
|
"@types/react-virtualized": "^9.22.2",
|
||||||
"@types/uuid": "^10.0.0",
|
|
||||||
"@vercel/style-guide": "^5.0.1",
|
"@vercel/style-guide": "^5.0.1",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "14.2.29",
|
"eslint-config-next": "14.2.29",
|
||||||
|
@ -1672,12 +1670,6 @@
|
||||||
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/uuid": {
|
|
||||||
"version": "10.0.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@types/uuid/-/uuid-10.0.0.tgz",
|
|
||||||
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/warning": {
|
"node_modules/@types/warning": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/warning/-/warning-3.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/warning/-/warning-3.0.3.tgz",
|
||||||
|
@ -7542,18 +7534,6 @@
|
||||||
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
|
||||||
"version": "11.1.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz",
|
|
||||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
|
||||||
"funding": [
|
|
||||||
"https://github.com/sponsors/broofa",
|
|
||||||
"https://github.com/sponsors/ctavan"
|
|
||||||
],
|
|
||||||
"bin": {
|
|
||||||
"uuid": "dist/esm/bin/uuid"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/validate-npm-package-license": {
|
"node_modules/validate-npm-package-license": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||||
|
@ -8989,12 +8969,6 @@
|
||||||
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/uuid": {
|
|
||||||
"version": "10.0.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@types/uuid/-/uuid-10.0.0.tgz",
|
|
||||||
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/warning": {
|
"@types/warning": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/warning/-/warning-3.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/warning/-/warning-3.0.3.tgz",
|
||||||
|
@ -13446,11 +13420,6 @@
|
||||||
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||||
},
|
},
|
||||||
"uuid": {
|
|
||||||
"version": "11.1.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz",
|
|
||||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="
|
|
||||||
},
|
|
||||||
"validate-npm-package-license": {
|
"validate-npm-package-license": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-virtualized": "^9.22.6",
|
"react-virtualized": "^9.22.6",
|
||||||
"sass": "^1.77.3",
|
"sass": "^1.77.3",
|
||||||
"tailwindcss": "3.3.3",
|
"tailwindcss": "3.3.3"
|
||||||
"uuid": "^11.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
|
@ -35,7 +34,6 @@
|
||||||
"@types/react-big-calendar": "^1.8.9",
|
"@types/react-big-calendar": "^1.8.9",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"@types/react-virtualized": "^9.22.2",
|
"@types/react-virtualized": "^9.22.2",
|
||||||
"@types/uuid": "^10.0.0",
|
|
||||||
"@vercel/style-guide": "^5.0.1",
|
"@vercel/style-guide": "^5.0.1",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "14.2.29",
|
"eslint-config-next": "14.2.29",
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 103 KiB |
|
@ -1,14 +1,15 @@
|
||||||
'use client'
|
'use client'
|
||||||
import {ProConfigProvider} from "@ant-design/pro-components";
|
import {ProConfigProvider} from "@ant-design/pro-components";
|
||||||
import React, {lazy, Suspense} from "react";
|
import React, {lazy, Suspense} from "react";
|
||||||
|
import Page from "@/ui/login/Page";
|
||||||
import Loading from "@/app/loading";
|
import Loading from "@/app/loading";
|
||||||
import XcxLoginPage from "@/ui/login/XcxLoginPage";
|
// const Page = lazy(() => import('@/ui/login/Page'));
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<Loading/>}>
|
<Suspense fallback={<Loading/>}>
|
||||||
<ProConfigProvider dark>
|
<ProConfigProvider dark>
|
||||||
<XcxLoginPage/>
|
<Page/>
|
||||||
</ProConfigProvider>
|
</ProConfigProvider>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
.reverseScrollList {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column; /* 垂直反转 */
|
|
||||||
/*overflow-y: auto;*/
|
|
||||||
}
|
|
||||||
/* 容器样式 */
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
/* 水平居中 */
|
|
||||||
align-items: center;
|
|
||||||
/* 垂直居中 */
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
/* 线条与文本容器 */
|
|
||||||
.lineWithText {
|
|
||||||
position: relative;
|
|
||||||
width: 80%;
|
|
||||||
/* 根据需要调整宽度 */
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
/* 使用伪元素创建线条 */
|
|
||||||
.lineWithText::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
border-top: 1px solid #c8c7cc;
|
|
||||||
/* 线条颜色和粗细 */
|
|
||||||
z-index: 0;
|
|
||||||
/* 在文本下面 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 中间文本 */
|
|
||||||
.centerText {
|
|
||||||
background-color: white;
|
|
||||||
/* 背景色,确保文本清晰可见 */
|
|
||||||
padding: 0 10px;
|
|
||||||
/* 给文本一些内边距 */
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
/* 确保文本在上面 */
|
|
||||||
font-size: 16px;
|
|
||||||
/* 文本大小 */
|
|
||||||
color: #c8c7cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logTaskContent {
|
|
||||||
width: 80%;
|
|
||||||
padding: 10rpx 40rpx;
|
|
||||||
|
|
||||||
.detailLine {
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
display: inline-block;
|
|
||||||
padding: 4rpx 20rpx;
|
|
||||||
border: solid;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
border-color: #1677FF;
|
|
||||||
white-space: normal;
|
|
||||||
word-break: break-all;
|
|
||||||
word-wrap: break-word;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
.detailLineClick {
|
|
||||||
background-color: #1677FF;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,233 +0,0 @@
|
||||||
import React, {useEffect, useState} from 'react';
|
|
||||||
import {Avatar, Input, List, message} from 'antd';
|
|
||||||
import VirtualList from 'rc-virtual-list';
|
|
||||||
import {Button, Drawer} from 'antd';
|
|
||||||
import {ListDiary, SelectDiary} from "@/components/type/Diary";
|
|
||||||
import TextArea from "antd/es/input/TextArea";
|
|
||||||
import style from "@/components/DiaryOption.module.css"
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import {addTaskLogAPI} from "@/components/service/Diary";
|
|
||||||
|
|
||||||
const CONTAINER_HEIGHT = 400;
|
|
||||||
const PAGE_SIZE = 20;
|
|
||||||
|
|
||||||
const DiaryOption = (props: SelectDiary) => {
|
|
||||||
// 抽屉 start
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const showDrawer = () => {
|
|
||||||
setOpen(true);
|
|
||||||
};
|
|
||||||
const onClose = () => {
|
|
||||||
setOpen(false);
|
|
||||||
};
|
|
||||||
// 抽屉 end
|
|
||||||
|
|
||||||
// 头按钮设置 start
|
|
||||||
const [currentIndex, setCurrentIndex] = useState(1);
|
|
||||||
// 头按钮设置 end
|
|
||||||
// 数据 start
|
|
||||||
const [diaryList, setDiaryList] = useState<ListDiary[]>([]);
|
|
||||||
const [diaryReduceList, setDiaryReduceList] = useState<ListDiary[]>([])
|
|
||||||
const [page, setPage] = useState(1);
|
|
||||||
const noMore = {id: '0', keyId: 'o0',createdDate:new Date(), description: '没有更多了',taskId:props.taskId, enableFlag: 'day-separate'};
|
|
||||||
const [noMoreFlag, setNoMoreFlag] = useState(false)
|
|
||||||
const [sendValue,setSendValue] = useState<string>();
|
|
||||||
const [sendValueFlag,setSendValueFlag] =useState(false);
|
|
||||||
const handleSend = ()=>{
|
|
||||||
if(sendValueFlag){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setSendValueFlag(true);
|
|
||||||
if (!sendValue?.trim()) {
|
|
||||||
message.info("发送信息不能为空");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addTaskLogAPI({
|
|
||||||
description: sendValue!,
|
|
||||||
taskId: props.taskId,
|
|
||||||
enableFlag: '1'
|
|
||||||
}).then(res => {
|
|
||||||
setDiaryList([res.data.data, ...diaryList])
|
|
||||||
setSendValue(undefined)
|
|
||||||
}).finally(() => {
|
|
||||||
setSendValueFlag(false);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const appendData = (showMessage = true) => {
|
|
||||||
const fakeDataUrl = process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/message/diary/select`;
|
|
||||||
fetch(fakeDataUrl, {
|
|
||||||
method: 'POST', headers: {
|
|
||||||
'Content-Type': 'application/json', // 指定 JSON 格式
|
|
||||||
'Authorization': `Bearer ${localStorage.getItem('platform-security')}`,
|
|
||||||
}, body: JSON.stringify({pageNumber: page, pageSize: 100, data: {taskId: props.taskId}})
|
|
||||||
})
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((body) => {
|
|
||||||
const results = Array.isArray(body.data.content) ? body.data.content : [];
|
|
||||||
if (results.length === 0) {
|
|
||||||
diaryList.push(noMore);
|
|
||||||
setNoMoreFlag(true);
|
|
||||||
}
|
|
||||||
setDiaryList(diaryList.concat(results));
|
|
||||||
setPage(page + 1);
|
|
||||||
showMessage && message.success(`${results.length} more items loaded!`);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
appendData(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log("处理日志集合",diaryList)
|
|
||||||
const returnResult: ListDiary[] = []
|
|
||||||
diaryList.filter(taskLog => {
|
|
||||||
if (currentIndex === 0) { return true }
|
|
||||||
else if (currentIndex === 1 && taskLog.enableFlag === "1") { return true }
|
|
||||||
else if (currentIndex === 2 && taskLog.enableFlag === "0") { return true }
|
|
||||||
else return false;
|
|
||||||
}).reduce((map, taskLog) => {
|
|
||||||
if (!map.has(dayjs(taskLog.createdDate).format("YYYY-MM-DD"))) {
|
|
||||||
map.set(dayjs(taskLog.createdDate).format("YYYY-MM-DD"), []);
|
|
||||||
}
|
|
||||||
map.get(dayjs(taskLog.createdDate).format("YYYY-MM-DD"))?.push(taskLog);
|
|
||||||
return map;
|
|
||||||
}, new Map()).forEach((value, Key) => {
|
|
||||||
returnResult.push(...value)
|
|
||||||
returnResult.push({
|
|
||||||
description: dayjs(Key).isSame(dayjs(), 'date') ? "今天" : dayjs(Key).format("YYYY-MM-DD"),
|
|
||||||
id: dayjs(Key).format("YYYY-MM-DD"),
|
|
||||||
enableFlag: "day-separate",
|
|
||||||
taskId: props.taskId,
|
|
||||||
createdDate: new Date()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
setDiaryReduceList(returnResult);
|
|
||||||
}, [diaryList]);
|
|
||||||
|
|
||||||
const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {
|
|
||||||
// Refer to: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#problems_and_solutions
|
|
||||||
if (
|
|
||||||
Math.abs(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - CONTAINER_HEIGHT) <= 1 &&
|
|
||||||
!noMoreFlag
|
|
||||||
) {
|
|
||||||
appendData();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 数据 end
|
|
||||||
|
|
||||||
// 点击操作 start
|
|
||||||
const [clickTaskDiary, setClickTaskDiary] = useState<ListDiary>()
|
|
||||||
// 点击操作 end
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button type="primary" onClick={showDrawer}>
|
|
||||||
日志心得
|
|
||||||
</Button>
|
|
||||||
<Drawer
|
|
||||||
style={{boxSizing:"border-box"}}
|
|
||||||
mask={false}
|
|
||||||
title={props.taskName}
|
|
||||||
closable={{'aria-label': 'Close Button'}}
|
|
||||||
onClose={onClose}
|
|
||||||
open={open}
|
|
||||||
footer={
|
|
||||||
<div style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'stretch', // 关键:强制子项等高
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
height: 'auto', // 父容器高度由内容决定
|
|
||||||
}}>
|
|
||||||
<TextArea
|
|
||||||
rows={4}
|
|
||||||
maxLength={255}
|
|
||||||
showCount
|
|
||||||
classNames={{count: 'ant-input-data-count-inner'}}
|
|
||||||
styles={{
|
|
||||||
count: {
|
|
||||||
// color:"red",
|
|
||||||
bottom: "0px"
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
resize: 'none',
|
|
||||||
flex: 1, // 占据剩余空间
|
|
||||||
}}
|
|
||||||
value={sendValue}
|
|
||||||
onChange={(val) => setSendValue(val.target.value)}
|
|
||||||
placeholder='输入日记心得,长按日记心得有惊喜'
|
|
||||||
onKeyDown={event => {
|
|
||||||
console.log({event})
|
|
||||||
if (event.ctrlKey && event.key === 'Enter') {
|
|
||||||
handleSend();
|
|
||||||
// 阻止换行符插入
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
style={{
|
|
||||||
flexShrink: 0,
|
|
||||||
width: '2rem',
|
|
||||||
whiteSpace: 'normal',
|
|
||||||
wordWrap: 'break-word',
|
|
||||||
margin: 0,
|
|
||||||
padding: "2px",
|
|
||||||
height: 'auto'// 移除 ,依赖父容器的 alignItems: 'stretch'
|
|
||||||
}}
|
|
||||||
loading={sendValueFlag}
|
|
||||||
onClick={handleSend}
|
|
||||||
>
|
|
||||||
{sendValueFlag ? '发送中...' : '发送'}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className="displayFlexRow">
|
|
||||||
<Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(0)}
|
|
||||||
type={currentIndex == 0 ? "primary" : "default"}>全部</Button>
|
|
||||||
<Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(1)}
|
|
||||||
type={currentIndex == 1 ? "primary" : "default"}>生效</Button>
|
|
||||||
<Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(2)}
|
|
||||||
type={currentIndex == 2 ? "primary" : "default"}>失效</Button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<List>
|
|
||||||
<VirtualList
|
|
||||||
data={diaryReduceList}
|
|
||||||
height={CONTAINER_HEIGHT}
|
|
||||||
itemHeight={47}
|
|
||||||
itemKey="email"
|
|
||||||
onScroll={onScroll}
|
|
||||||
className={style.reverseScrollList}
|
|
||||||
>
|
|
||||||
{item => (
|
|
||||||
item.enableFlag === 'day-separate' ?
|
|
||||||
<div className={style.container} key={item.keyId}>
|
|
||||||
<div className={style.lineWithText}>
|
|
||||||
<text className={style.centerText}>{item.description}</text>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
: <div className={style.logTaskContent} key={item.id}>
|
|
||||||
<div
|
|
||||||
className={`${style.detailLine} ${item.id === clickTaskDiary?.id ? style.detailLineClick : ''}`}
|
|
||||||
onClick={() => setClickTaskDiary(item)}>
|
|
||||||
<text
|
|
||||||
style={{textDecoration: item.enableFlag === '0' && currentIndex === 0 ? 'line-through' : ''}}>
|
|
||||||
{item.description}
|
|
||||||
</text>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</VirtualList>
|
|
||||||
</List>
|
|
||||||
</div>
|
|
||||||
</Drawer>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default DiaryOption;
|
|
|
@ -1,9 +0,0 @@
|
||||||
import {httpReq} from "@/utils/axiosReq";
|
|
||||||
import {AddDiary, ListDiary} from "@/components/type/Diary";
|
|
||||||
import {ResponseVO} from "@/lib/definitions";
|
|
||||||
import {AxiosResponse} from "axios";
|
|
||||||
|
|
||||||
export const addTaskLogAPI= (data:AddDiary):Promise<AxiosResponse<ResponseVO<ListDiary>>> =>{
|
|
||||||
return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + "/task/message/diary",
|
|
||||||
data)
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
export type ListDiary = AddDiary & {
|
|
||||||
generateTaskId?: string,
|
|
||||||
lastModifiedDate?: Date,
|
|
||||||
id: string,
|
|
||||||
// 不能以数字开头,用户滚动定位
|
|
||||||
keyId?:string,
|
|
||||||
createdDate: Date,
|
|
||||||
deleteFlag?: number
|
|
||||||
}
|
|
||||||
export type AddDiary = {
|
|
||||||
enableFlag: string,
|
|
||||||
description: string,
|
|
||||||
taskId: string,
|
|
||||||
}
|
|
||||||
export type SelectDiary = {
|
|
||||||
taskName: string,
|
|
||||||
taskId: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
async function postJsonData(url: string, data: object) {
|
|
||||||
const response = await fetch(url, {
|
|
||||||
method: 'POST', // 或 'PUT'、'PATCH'
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json', // 指定 JSON 格式
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data), // 将对象转为 JSON 字符串
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
|
||||||
}
|
|
||||||
return response.json(); // 解析响应为 JSON
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用示例
|
|
||||||
interface User {
|
|
||||||
name: string;
|
|
||||||
age: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const user: User = { name: 'Alice', age: 25 };
|
|
||||||
postJsonData('https://api.example.com/users', user)
|
|
||||||
.then((result) => console.log('Success:', result))
|
|
||||||
.catch((error) => console.error('Error:', error));
|
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
* 复制文本到剪贴板
|
|
||||||
* // 使用示例
|
|
||||||
* copyToClipboard('要复制的文本')
|
|
||||||
* .then(() => console.log('复制成功'))
|
|
||||||
* .catch(() => console.error('复制失败'));
|
|
||||||
* @param text 要复制的文本
|
|
||||||
* @returns 返回 Promise,成功时 resolve(true),失败时 reject(false)
|
|
||||||
*/
|
|
||||||
export const copyToClipboard = (text: string): Promise<boolean> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// 方案1: 使用现代 Clipboard API
|
|
||||||
if (navigator.clipboard && window.isSecureContext) {
|
|
||||||
navigator.clipboard.writeText(text)
|
|
||||||
.then(() => resolve(true))
|
|
||||||
.catch(() => {
|
|
||||||
// 现代 API 失败时回退到传统方法
|
|
||||||
fallbackCopy(text) ? resolve(true) : reject(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 方案2: 传统 document.execCommand 方法
|
|
||||||
else {
|
|
||||||
fallbackCopy(text) ? resolve(true) : reject(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 传统复制方法兼容方案
|
|
||||||
const fallbackCopy = (text: string): boolean => {
|
|
||||||
try {
|
|
||||||
// 创建临时文本域
|
|
||||||
const textArea = document.createElement('textarea');
|
|
||||||
textArea.value = text;
|
|
||||||
|
|
||||||
// 隐藏文本域(不在视口中显示)
|
|
||||||
textArea.style.position = 'fixed';
|
|
||||||
textArea.style.top = '-9999px';
|
|
||||||
textArea.style.left = '-9999px';
|
|
||||||
textArea.style.opacity = '0';
|
|
||||||
|
|
||||||
document.body.appendChild(textArea);
|
|
||||||
|
|
||||||
// 选择并复制
|
|
||||||
textArea.select();
|
|
||||||
const successful = document.execCommand('copy');
|
|
||||||
|
|
||||||
// 清理DOM
|
|
||||||
document.body.removeChild(textArea);
|
|
||||||
|
|
||||||
return successful;
|
|
||||||
} catch (err) {
|
|
||||||
console.error('复制失败:', err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -50,7 +50,6 @@ export type DataType = TaskMessage&{
|
||||||
actualEndTime?:Date;
|
actualEndTime?:Date;
|
||||||
actualTimeRange?:(string|Dayjs|undefined)[]
|
actualTimeRange?:(string|Dayjs|undefined)[]
|
||||||
children: DataType[]|undefined;
|
children: DataType[]|undefined;
|
||||||
sortNo?:number;
|
|
||||||
}
|
}
|
||||||
export type DictType={
|
export type DictType={
|
||||||
id:number;
|
id:number;
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import {httpReq} from "@/utils/axiosReq";
|
|
||||||
|
|
||||||
export const generateQrcodeAPI = (data:{}) => {
|
|
||||||
return httpReq.post(process.env.NEXT_PUBLIC_SECURITY_REQUEST_URL + "/V2/wx/login/generate/qrcode",
|
|
||||||
data)
|
|
||||||
}
|
|
||||||
export const askLoginAPI = (data:{})=>{
|
|
||||||
return httpReq.post(process.env.NEXT_PUBLIC_SECURITY_REQUEST_URL + "/V2/wx/login/pc/ask/login",
|
|
||||||
data)
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
import {httpReq} from "@/utils/axiosReq";
|
|
||||||
import {unstable_noStore as noStore} from "next/dist/server/web/spec-extension/unstable-no-store";
|
|
||||||
|
|
||||||
export const editExpectAPI = (requestParam: {}) =>{
|
|
||||||
noStore();
|
|
||||||
return httpReq.put(
|
|
||||||
process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/task/editExpect', requestParam)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
'use client'
|
|
||||||
import {
|
|
||||||
LoginFormPage,
|
|
||||||
} from '@ant-design/pro-components';
|
|
||||||
|
|
||||||
import {message, theme, Modal, Button, Skeleton, Image, QRCode} from 'antd';
|
|
||||||
import React, {useLayoutEffect} from 'react';
|
|
||||||
import {useState} from 'react';
|
|
||||||
import {LoginObject} from "@/lib/login/definitions";
|
|
||||||
import {useRouter} from 'next/navigation'
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
import {askLoginAPI, generateQrcodeAPI} from "@/lib/login/service";
|
|
||||||
import Cookies from "js-cookie";
|
|
||||||
|
|
||||||
export default function XcxLoginPage() {
|
|
||||||
const [loaded, setLoaded] = useState(false);
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
setLoaded(true);
|
|
||||||
})
|
|
||||||
// 二维码 start
|
|
||||||
const [qrCodeShow, setQrCodeShow] = useState<boolean>(false);
|
|
||||||
const [qrCodeStatus, setQrCodeStatus] = useState<'active' | 'expired' | 'loading' | 'scanned'>();
|
|
||||||
const [qrCodeValue, setQrCodeValue] = useState<string>("-");
|
|
||||||
const generateQrcode = () => {
|
|
||||||
if (qrCodeStatus=='loading') {
|
|
||||||
message.info({content:"请耐心等待"})
|
|
||||||
}else if (qrCodeStatus=='expired') {
|
|
||||||
setQrCode()
|
|
||||||
}else if (qrCodeStatus=='active') {
|
|
||||||
|
|
||||||
}else if (qrCodeStatus=='scanned') {
|
|
||||||
|
|
||||||
}else {
|
|
||||||
setQrCode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function setQrCode(){
|
|
||||||
// 生成唯一id
|
|
||||||
setQrCodeStatus("loading")
|
|
||||||
const clientId: string = uuidv4();
|
|
||||||
generateQrcodeAPI({clientId}).then(res=>{
|
|
||||||
let qrCodeData={
|
|
||||||
clientId,serverId:res.data.data,local:"马上行计划管理"
|
|
||||||
}
|
|
||||||
setQrCodeValue(JSON.stringify(qrCodeData))
|
|
||||||
setQrCodeStatus("active")
|
|
||||||
let timeout=undefined;
|
|
||||||
// 设置定时器,每2000毫秒(2秒)执行一次myFunction
|
|
||||||
let timerId =undefined;
|
|
||||||
timerId = setInterval(askLogin,2000,timeout,timerId,qrCodeData);
|
|
||||||
// 如果需要停止定时器,可以调用 clearInterval(timerId);
|
|
||||||
// 例如:1分钟后停止定时器
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
setQrCodeStatus("expired")
|
|
||||||
clearInterval(timerId);
|
|
||||||
console.log("定时器已停止");
|
|
||||||
}, 60000);
|
|
||||||
}).catch(()=>{
|
|
||||||
setQrCodeStatus("expired")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function askLogin(timeout:any,timerId:any,qrCodeData:{}){
|
|
||||||
askLoginAPI(qrCodeData).then(res=>{
|
|
||||||
if (res.data.status.success&&res.data.data.length>0){
|
|
||||||
setQrCodeStatus("scanned")
|
|
||||||
if(timeout){
|
|
||||||
clearTimeout(timeout);
|
|
||||||
clearInterval(timerId);
|
|
||||||
}
|
|
||||||
// localStorage.removeItem("platform-security")
|
|
||||||
localStorage.setItem('platform-security', res.data.data[0].token)
|
|
||||||
// 删除名为 'platform-security' 的Cookie
|
|
||||||
// Cookies.remove('platform-security');
|
|
||||||
// 设置一个有效期为7天的Cookie
|
|
||||||
Cookies.set('platform-security', res.data.data[0].token, { expires: 7 });
|
|
||||||
router.push('/task/project')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
// 二维码 end
|
|
||||||
const {token} = theme.useToken();
|
|
||||||
const router = useRouter()
|
|
||||||
const [messageApi, contextHolder] = message.useMessage();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [captchaLoginSuccessList, setCaptchaLoginSuccessList] = useState([]);
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
backgroundColor: 'white',
|
|
||||||
height: '100vh',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{contextHolder}
|
|
||||||
{loaded ? <LoginFormPage
|
|
||||||
backgroundImageUrl="/20-1733751222585.jpg"
|
|
||||||
title="马上行计划管理"
|
|
||||||
subTitle={qrCodeShow?undefined:"使用微信扫码打开小程序"}
|
|
||||||
containerStyle={{
|
|
||||||
backgroundColor: 'rgba(0, 0, 0,0.65)',
|
|
||||||
backdropFilter: 'blur(4px)',
|
|
||||||
}}
|
|
||||||
onFinish={(formData: LoginObject) => {
|
|
||||||
// 二维码和小程序扫码来回切换
|
|
||||||
if (!qrCodeShow) {
|
|
||||||
// 生成二维码
|
|
||||||
generateQrcode()
|
|
||||||
}
|
|
||||||
setQrCodeShow(!qrCodeShow)
|
|
||||||
}}
|
|
||||||
submitter={{ searchConfig: { submitText: qrCodeShow?"在我的-PC扫码登录或者返回":"已打开微信小程序,生成登录码。",resetText: '重置2'}}}
|
|
||||||
>
|
|
||||||
<div className="displayFlexColumn" style={{margin:'20px'}}>
|
|
||||||
{
|
|
||||||
qrCodeShow?<QRCode value={qrCodeValue} size={300} status={qrCodeStatus} onRefresh={generateQrcode} />:
|
|
||||||
<Image width={300} src="/static/pc-Web.png"/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</LoginFormPage> : <Skeleton/>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
ProFormText,
|
ProFormText,
|
||||||
QueryFilter,
|
QueryFilter,
|
||||||
} from '@ant-design/pro-components';
|
} from '@ant-design/pro-components';
|
||||||
import '@/ui/task/CustomSearchForm.modules.css'
|
import '@/ui/task/CustomSearchForm.module.css'
|
||||||
import {taskStateList} from "@/lib/task/project/data";
|
import {taskStateList} from "@/lib/task/project/data";
|
||||||
const CustomSearchForm= () => {
|
const CustomSearchForm= () => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {Button, DatePicker, Select, Space} from "antd";
|
||||||
import {usePathname, useRouter} from "next/navigation";
|
import {usePathname, useRouter} from "next/navigation";
|
||||||
import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
|
import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
|
||||||
import {OPERATION_BUTTON_TYPE, taskStateList} from "@/lib/task/project/data";
|
import {OPERATION_BUTTON_TYPE, taskStateList} from "@/lib/task/project/data";
|
||||||
import style from '@/ui/task/TitleOperation.module.css'
|
import '@/ui/task/TitleOperation.modules.css'
|
||||||
import LocalContext from "@/ui/LocalContent";
|
import LocalContext from "@/ui/LocalContent";
|
||||||
import {RequestDateType} from "@/ui/task/RequestDateType";
|
import {RequestDateType} from "@/ui/task/RequestDateType";
|
||||||
import dayjs, {Dayjs} from "dayjs";
|
import dayjs, {Dayjs} from "dayjs";
|
||||||
|
@ -38,7 +38,7 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
||||||
document.title = pName;
|
document.title = pName;
|
||||||
}
|
}
|
||||||
}, [pName]);
|
}, [pName]);
|
||||||
return <div className={style.container}>
|
return <div className="container">
|
||||||
<Space style={{marginTop: 0, "height": "42px", "alignContent": "center"}}>
|
<Space style={{marginTop: 0, "height": "42px", "alignContent": "center"}}>
|
||||||
<DetailModelForm haveButton={true} open={false} operationId={OPERATION_BUTTON_TYPE.ADD}
|
<DetailModelForm haveButton={true} open={false} operationId={OPERATION_BUTTON_TYPE.ADD}
|
||||||
description='添加主线任务' reloadData={refreshData}/>
|
description='添加主线任务' reloadData={refreshData}/>
|
||||||
|
|
|
@ -13,7 +13,8 @@ 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 withDragAndDrop, {EventInteractionArgs} from "react-big-calendar/lib/addons/dragAndDrop";
|
||||||
import {TaskEvent} from "@/lib/task/calendar/data";
|
import {TaskEvent} from "@/lib/task/calendar/data";
|
||||||
import {editExpectAPI} from "@/lib/task/calendar/service";
|
import {number} from "prop-types";
|
||||||
|
import {DATE_TIME} from "@/lib/constants";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://github.com/jquense/react-big-calendar?tab=readme-ov-file
|
* https://github.com/jquense/react-big-calendar?tab=readme-ov-file
|
||||||
|
@ -25,7 +26,7 @@ const CalShow: React.FC = () => {
|
||||||
dayjs.locale('zh-cn')
|
dayjs.locale('zh-cn')
|
||||||
const [view, setView] = useState<View>('week');
|
const [view, setView] = useState<View>('week');
|
||||||
const [date, setDate] = useState<Date>(new Date());
|
const [date, setDate] = useState<Date>(new Date());
|
||||||
const clickRef = useRef<number | undefined | null>(null)
|
const clickRef = useRef<number|undefined|null>(null)
|
||||||
// 展示在页面的任务,默认获取当前月的信息。
|
// 展示在页面的任务,默认获取当前月的信息。
|
||||||
const [events, setEvents] = useState<TaskEvent[]>([]);
|
const [events, setEvents] = useState<TaskEvent[]>([]);
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
@ -34,21 +35,19 @@ const CalShow: React.FC = () => {
|
||||||
const [itemId, setItemId] = useState('-1');
|
const [itemId, setItemId] = useState('-1');
|
||||||
const [expectedStartTime, setExpectedStartTime] = useState<Dayjs>();
|
const [expectedStartTime, setExpectedStartTime] = useState<Dayjs>();
|
||||||
const [expectedEndTime, setExpectedEndTime] = useState<Dayjs>();
|
const [expectedEndTime, setExpectedEndTime] = useState<Dayjs>();
|
||||||
const [range, setRange] = useState<{ start: Date; end: Date }>({
|
const [range, setRange] = useState<{start: Date; end: Date}>({
|
||||||
start: dayjs(date).startOf('week').toDate(),
|
start: dayjs(date).startOf('week').toDate(),
|
||||||
end: dayjs(date).endOf('week').toDate()
|
end: dayjs(date).endOf('week').toDate()
|
||||||
});
|
});
|
||||||
const state = useContext(LocalContext).taskState;
|
const state=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(){
|
||||||
function clearClickTimeout() {
|
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleNavigate = (newDate: Date) => {
|
const handleNavigate = (newDate: Date) => {
|
||||||
console.log('handleNavigate', newDate)
|
console.log('handleNavigate', newDate)
|
||||||
setDate(newDate);
|
setDate(newDate);
|
||||||
|
@ -63,7 +62,7 @@ const CalShow: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("CalShow:useEffect:range", range)
|
console.log("CalShow:useEffect:range",range)
|
||||||
const searchListE = []
|
const searchListE = []
|
||||||
if (pid != null) {
|
if (pid != null) {
|
||||||
searchListE.push(
|
searchListE.push(
|
||||||
|
@ -83,7 +82,7 @@ const CalShow: React.FC = () => {
|
||||||
return () => {
|
return () => {
|
||||||
clearClickTimeout()
|
clearClickTimeout()
|
||||||
}
|
}
|
||||||
}, [useContext(LocalContext), range]);
|
}, [useContext(LocalContext),range]);
|
||||||
const message = {
|
const message = {
|
||||||
week: '周',
|
week: '周',
|
||||||
work_week: '工作周',
|
work_week: '工作周',
|
||||||
|
@ -103,27 +102,27 @@ const CalShow: React.FC = () => {
|
||||||
pageSize: 9999,
|
pageSize: 9999,
|
||||||
pageNumber: 1,
|
pageNumber: 1,
|
||||||
data: searchList,
|
data: searchList,
|
||||||
startTime: range.start,
|
startTime:range.start,
|
||||||
// startTime:dayjs(range.start).format('YYYY-MM-DD HH:mm:ss'),
|
// startTime:dayjs(range.start).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
endTime: range.end,
|
endTime:range.end,
|
||||||
// endTime:dayjs(range.end).format('YYYY-MM-DD HH:mm:ss'),
|
// endTime:dayjs(range.end).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
startColumn: "expected_start_time",
|
startColumn:"expected_start_time",
|
||||||
endColumn: "expected_end_time"
|
endColumn:"expected_end_time"
|
||||||
})
|
})
|
||||||
getTaskTreeResult(request).then(responseD => {
|
getTaskTreeResult(request).then(responseD => {
|
||||||
if (responseD.status.success) {
|
if (responseD.status.success) {
|
||||||
let result: TaskEvent[] = responseD.data.content.map<TaskEvent>(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,
|
id:taskState.id,
|
||||||
state: taskState.state,
|
state:taskState.state,
|
||||||
priority: taskState.priority
|
priority:taskState.priority
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log('responseD.data.content:', result)
|
console.log('responseD.data.content:',result)
|
||||||
setEvents([...result])
|
setEvents([...result])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -146,14 +145,14 @@ const CalShow: React.FC = () => {
|
||||||
const handleSelectEvent = useCallback(
|
const handleSelectEvent = useCallback(
|
||||||
(event: Event, e: React.SyntheticEvent<HTMLElement>) => {
|
(event: Event, e: React.SyntheticEvent<HTMLElement>) => {
|
||||||
clearClickTimeout()
|
clearClickTimeout()
|
||||||
clickRef.current = window.setTimeout(() => {
|
clickRef.current = window.setTimeout(()=> {
|
||||||
// window.alert(event.title);
|
// window.alert(event.title);
|
||||||
console.log(event)
|
console.log(event)
|
||||||
setOperationId(OPERATION_BUTTON_TYPE.DETAIL)
|
setOperationId(OPERATION_BUTTON_TYPE.DETAIL)
|
||||||
setDescription("任务详情")
|
setDescription("任务详情")
|
||||||
setItemId(event.resource)
|
setItemId(event.resource)
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
}, 250)
|
},250)
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
@ -167,7 +166,7 @@ const CalShow: React.FC = () => {
|
||||||
|
|
||||||
const doubleClick = (event: TaskEvent, e: React.SyntheticEvent<HTMLElement>) => {
|
const doubleClick = (event: TaskEvent, e: React.SyntheticEvent<HTMLElement>) => {
|
||||||
clearClickTimeout()
|
clearClickTimeout()
|
||||||
clickRef.current = window.setTimeout(() => {
|
clickRef.current = window.setTimeout(()=>{
|
||||||
// 数据落库
|
// 数据落库
|
||||||
commonUpdate({
|
commonUpdate({
|
||||||
updateColumnList: [{
|
updateColumnList: [{
|
||||||
|
@ -186,27 +185,40 @@ const CalShow: React.FC = () => {
|
||||||
const existing: TaskEvent | undefined = prev.find((ev: TaskEvent) => ev.resource === event.resource);
|
const existing: TaskEvent | undefined = prev.find((ev: TaskEvent) => ev.resource === event.resource);
|
||||||
const filtered: TaskEvent[] | undefined = prev.filter((ev: TaskEvent) => ev.resource !== event.resource);
|
const filtered: TaskEvent[] | undefined = prev.filter((ev: TaskEvent) => ev.resource !== event.resource);
|
||||||
let result: TaskEvent[] = [];
|
let result: TaskEvent[] = [];
|
||||||
if (existing !== undefined && filtered !== undefined) {
|
if (existing !== undefined&&filtered !== undefined) {
|
||||||
result = [...filtered, {...existing, state: 7}];
|
result= [...filtered, {...existing, state:7}];
|
||||||
}
|
}
|
||||||
let strings = state.split(",");
|
let strings = state.split(",");
|
||||||
console.log('result', result, strings)
|
console.log('result',result,strings)
|
||||||
return result.filter((ev: TaskEvent) => strings.indexOf(ev.state.toString()) >= 0);
|
return result.filter((ev: TaskEvent) => strings.indexOf(ev.state.toString())>=0);
|
||||||
})
|
})
|
||||||
}, 250)
|
},250)
|
||||||
}
|
}
|
||||||
|
|
||||||
const moveEvent = useCallback(
|
const moveEvent = useCallback(
|
||||||
async ({event, start, end, isAllDay: droppedOnAllDaySlot = false}: EventInteractionArgs<TaskEvent>) => {
|
({event, start, end, isAllDay: droppedOnAllDaySlot = false}: EventInteractionArgs<TaskEvent>) => {
|
||||||
console.log("onEventResize || onEventDrop :", start, end, event)
|
console.log("onEventResize || onEventDrop :",start,end)
|
||||||
const {allDay} = event
|
const {allDay} = event
|
||||||
if (!allDay && droppedOnAllDaySlot) {
|
if (!allDay && droppedOnAllDaySlot) {
|
||||||
event.allDay = true
|
event.allDay = true
|
||||||
}
|
}
|
||||||
editExpectAPI({
|
// 数据落库
|
||||||
expectedStartTime: start,
|
commonUpdate({
|
||||||
expectedEndTime: end,
|
updateColumnList: [{
|
||||||
id: event.resource
|
name: 'expectedStartTime',
|
||||||
|
code: '',
|
||||||
|
value: start.toLocaleString()
|
||||||
|
}, {
|
||||||
|
name: 'expectedEndTime',
|
||||||
|
code: '',
|
||||||
|
value: end.toLocaleString()
|
||||||
|
}],
|
||||||
|
conditionColumnList: [{
|
||||||
|
name: 'id',
|
||||||
|
code: 'id',
|
||||||
|
operateType: '=',
|
||||||
|
value: event.resource
|
||||||
|
}]
|
||||||
})
|
})
|
||||||
setEvents((prev: TaskEvent[]) => {
|
setEvents((prev: TaskEvent[]) => {
|
||||||
const existing: TaskEvent | undefined = prev.find((ev: TaskEvent) => ev.resource === event.resource);
|
const existing: TaskEvent | undefined = prev.find((ev: TaskEvent) => ev.resource === event.resource);
|
||||||
|
@ -224,49 +236,49 @@ const CalShow: React.FC = () => {
|
||||||
)
|
)
|
||||||
|
|
||||||
const eventPropGetter = useCallback(
|
const eventPropGetter = useCallback(
|
||||||
(event: TaskEvent) => ({
|
(event:TaskEvent) => ({
|
||||||
...(event.state === 7
|
...(event.state===7
|
||||||
? {className: 'completeTask'}
|
? { className: 'completeTask' }
|
||||||
: event.priority === 3 ? {className: 'importantUrgentTask'} :
|
: event.priority===3?{ className: 'importantUrgentTask' }:
|
||||||
event.priority === 2 ? {className: 'importantNotUrgentTask'} :
|
event.priority===2?{ className: 'importantNotUrgentTask' }:
|
||||||
event.priority === 1 ? {className: 'notImportantUrgentTask'} :
|
event.priority===1?{ className: 'notImportantUrgentTask' }:
|
||||||
{className: 'notImportantNotUrgentTask'}),
|
{ className: 'notImportantNotUrgentTask' }),
|
||||||
}),
|
}),
|
||||||
[setEvents]
|
[setEvents]
|
||||||
)
|
)
|
||||||
const rangeChange = (rangeLet: Date[] | { start: Date; end: Date }, current?: View | undefined) => {
|
const rangeChange = (rangeLet: Date[]|{ start: Date; end: Date },current?:View|undefined)=>{
|
||||||
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]})
|
setRange({...range,start:rangeLet[0]})
|
||||||
} else if (range.end.valueOf() < rangeLet[0].valueOf()) {
|
}else if (range.end.valueOf()<rangeLet[0].valueOf()){
|
||||||
setRange({...range, end: rangeLet[0]})
|
setRange({...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]})
|
setRange({...range,start:rangeLet[0]})
|
||||||
}
|
}
|
||||||
if (range.end.valueOf() < rangeLet[6].valueOf()) {
|
if (range.end.valueOf()<rangeLet[6].valueOf()){
|
||||||
setRange({...range, end: rangeLet[6]})
|
setRange({...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})
|
setRange({...range,start:rangeLet.start})
|
||||||
}
|
}
|
||||||
if (range.end.valueOf() < rangeLet.end.valueOf()) {
|
if (range.end.valueOf()<rangeLet.end.valueOf()){
|
||||||
setRange({...range, end: rangeLet.end})
|
setRange({...range,end:rangeLet.end})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return <div className="App" style={{height: '90vh'}}>
|
return <div className="App" style={{height: '90vh'}}>
|
||||||
{open && <DetailModelForm operationId={operationId} description={description} open={open} haveButton={false}
|
{open && <DetailModelForm operationId={operationId} description={description} open={open} haveButton={false}
|
||||||
itemId={itemId}
|
itemId={itemId} pid={pid?pid:'0'}
|
||||||
reloadData={reloadData} expectedStartTime={expectedStartTime}
|
reloadData={reloadData} expectedStartTime={expectedStartTime}
|
||||||
expectedEndTime={expectedEndTime}/>}
|
expectedEndTime={expectedEndTime}/>}
|
||||||
<DragAndDropCalendar
|
<DragAndDropCalendar
|
||||||
|
|
|
@ -9,7 +9,6 @@ import dayjs from "dayjs";
|
||||||
import {getTaskState, taskPriorityList} from "@/lib/task/project/data";
|
import {getTaskState, taskPriorityList} from "@/lib/task/project/data";
|
||||||
import 'react-virtualized/styles.css';
|
import 'react-virtualized/styles.css';
|
||||||
import RightOption from "@/ui/task/RightOption";
|
import RightOption from "@/ui/task/RightOption";
|
||||||
import {CopyOutlined} from "@ant-design/icons";
|
|
||||||
|
|
||||||
interface DroppableTableProps {
|
interface DroppableTableProps {
|
||||||
tableCode: string,
|
tableCode: string,
|
||||||
|
@ -71,7 +70,7 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => {
|
||||||
<ConfigProvider>
|
<ConfigProvider>
|
||||||
{/* 表头 */}
|
{/* 表头 */}
|
||||||
<div style={headerStyle} className='displayFlexRow'>
|
<div style={headerStyle} className='displayFlexRow'>
|
||||||
<div style={{width: '20%',paddingLeft:"1rem"}} className='displayFlexRow'>{stateName}</div>
|
<div style={{width: '20%'}} className='displayFlexRow'>{stateName}</div>
|
||||||
<div style={{width: '45%'}} className='displayFlexRow'>任务描述</div>
|
<div style={{width: '45%'}} className='displayFlexRow'>任务描述</div>
|
||||||
<div style={{width: '15%'}} className='displayFlexRow'>任务状态</div>
|
<div style={{width: '15%'}} className='displayFlexRow'>任务状态</div>
|
||||||
<div style={{width: '20%'}} className='displayFlexRow'>期望时间</div>
|
<div style={{width: '20%'}} className='displayFlexRow'>期望时间</div>
|
||||||
|
@ -90,7 +89,7 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => {
|
||||||
style={getItemStyle(snapshot.isDragging, {...provided.draggableProps.style})}
|
style={getItemStyle(snapshot.isDragging, {...provided.draggableProps.style})}
|
||||||
className="virtualized-row displayFlexRow"
|
className="virtualized-row displayFlexRow"
|
||||||
>
|
>
|
||||||
<div style={{width: '20%',paddingLeft:"1rem"}} className='displayFlexRow'>
|
<div style={{width: '20%'}} className='displayFlexRow'>
|
||||||
<Tooltip placement="topLeft" title={record.name}
|
<Tooltip placement="topLeft" title={record.name}
|
||||||
className='displayFlexRow'>
|
className='displayFlexRow'>
|
||||||
<div className='displayFlexRow'>{record.name}</div>
|
<div className='displayFlexRow'>{record.name}</div>
|
||||||
|
|
|
@ -17,38 +17,37 @@ import {
|
||||||
} from "@/lib/task/project/data";
|
} from "@/lib/task/project/data";
|
||||||
import {DataType} from "@/lib/definitions";
|
import {DataType} from "@/lib/definitions";
|
||||||
import dayjs, {Dayjs} from "dayjs";
|
import dayjs, {Dayjs} from "dayjs";
|
||||||
import DiaryOption from "@/components/DiaryOption";
|
|
||||||
|
|
||||||
export type DetailModelFormProps = {
|
export type DetailModelFormProps={
|
||||||
// 当前内容id
|
// 当前内容id
|
||||||
itemId?: string,
|
itemId?: string,
|
||||||
pid?: string,
|
pid?:string,
|
||||||
// 祖宗任务id
|
// 祖宗任务id
|
||||||
pPid?: string,
|
pPid?:string,
|
||||||
// 操作id
|
// 操作id
|
||||||
operationId: OPERATION_BUTTON_TYPE,
|
operationId: OPERATION_BUTTON_TYPE,
|
||||||
// 标题描述
|
// 标题描述
|
||||||
description: string,
|
description:string,
|
||||||
// 是否打开界面,用于非按钮操作
|
// 是否打开界面,用于非按钮操作
|
||||||
open: boolean,
|
open:boolean,
|
||||||
// 使用按钮操作
|
// 使用按钮操作
|
||||||
haveButton: boolean,
|
haveButton:boolean,
|
||||||
expectedStartTime?: Dayjs,
|
expectedStartTime?:Dayjs,
|
||||||
expectedEndTime?: Dayjs,
|
expectedEndTime?:Dayjs,
|
||||||
// 重新加载数据
|
// 重新加载数据
|
||||||
reloadData?: () => void
|
reloadData?: () => void
|
||||||
}
|
}
|
||||||
export type PidSelectTree = { label: string; value: string; pid: string; children?: PidSelectTree[] }
|
export type PidSelectTree= { label: string; value: string;pid:string; children?: PidSelectTree[] }
|
||||||
|
|
||||||
export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
console.log("DetailModelForm:props:", props)
|
console.log("DetailModelForm:props:",props)
|
||||||
const [form] = Form.useForm<DataType>();
|
const [form] = Form.useForm<DataType>();
|
||||||
const [requestTask,setRequestTask]=useState<DataType>()
|
const [pid, setPid] = useState<string>(props.pid?props.pid:'0');
|
||||||
const [editFormDisable, setEditFormDisable] = useState(props.operationId === OPERATION_BUTTON_TYPE.DETAIL)
|
const [editFormDisable, setEditFormDisable] = useState(props.operationId === OPERATION_BUTTON_TYPE.DETAIL)
|
||||||
// 团队第一层 pid必须为0
|
// 团队第一层 pid必须为0
|
||||||
const [taskType, setTaskType] = useState('0')
|
const [taskType, setTaskType] = useState('0')
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.itemId != undefined && (
|
if (props.itemId!=undefined&&(
|
||||||
props.operationId === OPERATION_BUTTON_TYPE.DETAIL || props.operationId === OPERATION_BUTTON_TYPE.UPDATE)) {
|
props.operationId === OPERATION_BUTTON_TYPE.DETAIL || props.operationId === OPERATION_BUTTON_TYPE.UPDATE)) {
|
||||||
getTask(props.itemId).then(task => {
|
getTask(props.itemId).then(task => {
|
||||||
console.log('DetailModelForm:getTask(props.itemId)', props.itemId, task);
|
console.log('DetailModelForm:getTask(props.itemId)', props.itemId, task);
|
||||||
|
@ -61,51 +60,38 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
task.data.expectedTimeRange = [task.data.expectedStartTime ? dayjs(task.data.expectedStartTime) : undefined,
|
task.data.expectedTimeRange = [task.data.expectedStartTime ? dayjs(task.data.expectedStartTime) : undefined,
|
||||||
task.data.expectedEndTime ? dayjs(task.data.expectedEndTime) : undefined];
|
task.data.expectedEndTime ? dayjs(task.data.expectedEndTime) : undefined];
|
||||||
form.setFieldsValue(task.data)
|
form.setFieldsValue(task.data)
|
||||||
if (task.data.pid=="0"){
|
console.log("form.setFieldsValue(task.data)"+JSON.stringify(task.data))
|
||||||
form.setFieldValue("pid",undefined)
|
|
||||||
}
|
|
||||||
setRequestTask(task.data)
|
|
||||||
console.log("form.setFieldsValue(task.data)" + JSON.stringify(task.data))
|
|
||||||
} else {
|
} else {
|
||||||
message.error(task.status.message);
|
message.error(task.status.message);
|
||||||
props.reloadData?.()
|
props.reloadData?.()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else if (props.operationId === OPERATION_BUTTON_TYPE.ADD || props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD) {
|
}else if(props.operationId === OPERATION_BUTTON_TYPE.ADD|| props.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD){
|
||||||
let data = {
|
let data={'expectedTimeRange':[props.expectedStartTime?props.expectedStartTime:dayjs(), props.expectedEndTime],'pid':props.pid};
|
||||||
'expectedTimeRange': [props.expectedStartTime ? props.expectedStartTime : dayjs(), props.expectedEndTime],
|
|
||||||
'pid': props.pid
|
|
||||||
};
|
|
||||||
form.setFieldsValue(data)
|
form.setFieldsValue(data)
|
||||||
}
|
}
|
||||||
}, [props])
|
}, [props])
|
||||||
|
function childReduce(child:DataType[]):PidSelectTree[]{
|
||||||
function childReduce(child: DataType[]): PidSelectTree[] {
|
const result:PidSelectTree[] = [];
|
||||||
const result: PidSelectTree[] = [];
|
child.map(data=> {
|
||||||
child.map(data => {
|
const resultData:PidSelectTree = {label:data.name,value:data.id,pid:data.pid};
|
||||||
const resultData: PidSelectTree = {label: data.name, value: data.id, pid: data.pid};
|
if (data.children){
|
||||||
if (data.children) {
|
resultData.children=childReduce(data.children);
|
||||||
resultData.children = childReduce(data.children);
|
|
||||||
}
|
}
|
||||||
result.push(resultData);
|
result.push(resultData);
|
||||||
})
|
})
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果不是添加任务需要回显
|
// 如果不是添加任务需要回显
|
||||||
// Form 当中的 initialValues
|
|
||||||
// ProComponents 底层也是封装的 antd ,所以用法也和 antd 相同。注意 initialValues 不能被 setState 动态更新,
|
|
||||||
// 所以你需要用 setFieldsValue 来更新。 initialValues 只在 form 初始化时生效且只生效一次,如果你需要异步加载,
|
|
||||||
// 推荐使用 request,或者 initialValues ? <Form/> : null
|
|
||||||
return (
|
return (
|
||||||
<ModalForm<DataType>
|
<ModalForm<DataType>
|
||||||
title={props.description}
|
title={props.description}
|
||||||
open={props.open && !props.haveButton}
|
open={props.open&&!props.haveButton}
|
||||||
trigger={props.haveButton ?
|
trigger={props.haveButton?
|
||||||
<Button type="primary">
|
<Button type="primary">
|
||||||
<PlusOutlined/>
|
<PlusOutlined />
|
||||||
{props.description}
|
{props.description}
|
||||||
</Button> : undefined
|
</Button>:undefined
|
||||||
}
|
}
|
||||||
form={form}
|
form={form}
|
||||||
autoFocusFirstInput
|
autoFocusFirstInput
|
||||||
|
@ -116,10 +102,10 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
props.reloadData?.();
|
props.reloadData?.();
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
submitter={props.itemId !== undefined && props.itemId !== '-1' ? {
|
submitter={props.itemId!==undefined&&props.itemId!=='-1'?{
|
||||||
render: (prop, defaultDoms) => {
|
render: (prop, defaultDoms) => {
|
||||||
return [
|
return [
|
||||||
editFormDisable ? <Button
|
editFormDisable?<Button
|
||||||
key="edit"
|
key="edit"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
// props.submit();
|
// props.submit();
|
||||||
|
@ -127,17 +113,16 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</Button> : undefined,
|
</Button>:undefined,
|
||||||
props.operationId === OPERATION_BUTTON_TYPE.DETAIL || props.operationId === OPERATION_BUTTON_TYPE.UPDATE ?
|
props.operationId === OPERATION_BUTTON_TYPE.DETAIL||props.operationId === OPERATION_BUTTON_TYPE.UPDATE?<Popconfirm
|
||||||
<Popconfirm
|
key ='delete'
|
||||||
key='delete'
|
|
||||||
title="删除任务"
|
title="删除任务"
|
||||||
description="确认要删除任务?"
|
description="确认要删除任务?"
|
||||||
icon={<QuestionCircleOutlined style={{color: 'red'}}/>}
|
icon={<QuestionCircleOutlined style={{color: 'red'}}/>}
|
||||||
okText="确认"
|
okText="确认"
|
||||||
cancelText="取消"
|
cancelText="取消"
|
||||||
onConfirm={() => {
|
onConfirm={() => {
|
||||||
if (props.itemId !== undefined) {
|
if (props.itemId!==undefined) {
|
||||||
deleteTask(props.itemId).then((response => {
|
deleteTask(props.itemId).then((response => {
|
||||||
console.log('response', response)
|
console.log('response', response)
|
||||||
if (response.status.success) {
|
if (response.status.success) {
|
||||||
|
@ -147,39 +132,33 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
><Button type="primary" danger>
|
||||||
<Button type="primary" danger>
|
|
||||||
删除
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
</Popconfirm> : undefined
|
</Popconfirm>:undefined
|
||||||
,
|
,
|
||||||
requestTask&&requestTask.id?<DiaryOption taskId={requestTask.id} taskName={requestTask.name}/>:undefined,
|
|
||||||
...defaultDoms
|
...defaultDoms
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
} : undefined}
|
}:undefined}
|
||||||
onFinish={async (values) => {
|
onFinish={async (values) => {
|
||||||
console.log('Received values of form: ', values,{...requestTask,...values});
|
console.log('Received values of form: ', values);
|
||||||
if (requestTask) {
|
if (values.pid===undefined){
|
||||||
const {sortNo}=requestTask;
|
values.pid='0'
|
||||||
values.sortNo=sortNo;
|
|
||||||
}
|
}
|
||||||
if (values.pid === undefined) {
|
if (values.expectedTimeRange?.[0]!=undefined) {
|
||||||
values.pid = '0'
|
values.expectedStartTime=dayjs(values.expectedTimeRange[0]).format()
|
||||||
}
|
}
|
||||||
if (values.expectedTimeRange?.[0] != undefined) {
|
if (values.expectedTimeRange?.[1]!=undefined) {
|
||||||
values.expectedStartTime = dayjs(values.expectedTimeRange[0]).format()
|
values.expectedEndTime=dayjs(values.expectedTimeRange[1]).format()
|
||||||
}
|
}
|
||||||
if (values.expectedTimeRange?.[1] != undefined) {
|
if (values.actualTimeRange?.[0]!=undefined) {
|
||||||
values.expectedEndTime = dayjs(values.expectedTimeRange[1]).format()
|
values.actualStartTime=dayjs(values.actualTimeRange[0]).toDate()
|
||||||
}
|
}
|
||||||
if (values.actualTimeRange?.[0] != undefined) {
|
if (values.actualTimeRange?.[1]!=undefined) {
|
||||||
values.actualStartTime = dayjs(values.actualTimeRange[0]).toDate()
|
values.actualEndTime=dayjs(values.actualTimeRange[1]).toDate()
|
||||||
}
|
}
|
||||||
if (values.actualTimeRange?.[1] != undefined) {
|
var result:boolean=false;
|
||||||
values.actualEndTime = dayjs(values.actualTimeRange[1]).toDate()
|
|
||||||
}
|
|
||||||
var result: boolean = false;
|
|
||||||
|
|
||||||
let state = taskStateList.find(taskState => taskState.name === values.state?.toString());
|
let state = taskStateList.find(taskState => taskState.name === values.state?.toString());
|
||||||
if (state) {
|
if (state) {
|
||||||
|
@ -190,7 +169,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
values.priority = priority.code
|
values.priority = priority.code
|
||||||
}
|
}
|
||||||
// todo 修改
|
// todo 修改
|
||||||
if (props.operationId === OPERATION_BUTTON_TYPE.UPDATE || (props.operationId === OPERATION_BUTTON_TYPE.DETAIL && !editFormDisable)) {
|
if (props.operationId === OPERATION_BUTTON_TYPE.UPDATE||(props.operationId === OPERATION_BUTTON_TYPE.DETAIL&&!editFormDisable)) {
|
||||||
await updateTask(values).then(response => {
|
await updateTask(values).then(response => {
|
||||||
console.log('response', response)
|
console.log('response', response)
|
||||||
if (response.status.success) {
|
if (response.status.success) {
|
||||||
|
@ -198,16 +177,16 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
// 树任务重新刷新
|
// 树任务重新刷新
|
||||||
// 四象限任务重新刷新
|
// 四象限任务重新刷新
|
||||||
// 如果可以直接更新列表而不请求。。。。。。
|
// 如果可以直接更新列表而不请求。。。。。。
|
||||||
console.log('props.reloadData?.()', props.reloadData)
|
console.log('props.reloadData?.()',props.reloadData)
|
||||||
props.reloadData?.()
|
props.reloadData?.()
|
||||||
result = true
|
result= true
|
||||||
} else {
|
}else {
|
||||||
message.error(response.status.message)
|
message.error(response.status.message)
|
||||||
result = false
|
result= false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
}else {
|
||||||
await addTask(values).then(response => {
|
await addTask(values).then(response => {
|
||||||
console.log('response', response)
|
console.log('response', response)
|
||||||
if (response.status.success) {
|
if (response.status.success) {
|
||||||
|
@ -215,12 +194,12 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
// 树任务重新刷新
|
// 树任务重新刷新
|
||||||
// 四象限任务重新刷新
|
// 四象限任务重新刷新
|
||||||
// 如果可以直接更新列表而不请求。。。。。。
|
// 如果可以直接更新列表而不请求。。。。。。
|
||||||
console.log('props.reloadData?.()', props.reloadData)
|
console.log('props.reloadData?.()',props.reloadData)
|
||||||
props.reloadData?.()
|
props.reloadData?.()
|
||||||
result = true
|
result= true
|
||||||
} else {
|
}else {
|
||||||
message.error(response.status.message)
|
message.error(response.status.message)
|
||||||
result = false
|
result= false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -228,9 +207,9 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
return result;
|
return result;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ProFormText width="sm" name="id" hidden={true} label="主键"/>
|
<ProFormText width="sm" name="id" hidden={true} label="主键" />
|
||||||
<ProFormText width="sm" name="code" initialValue={props.itemId} hidden={true} label="任务编码"/>
|
<ProFormText width="sm" name="code" initialValue={props.itemId} hidden={true} label="任务编码" />
|
||||||
<ProFormText width="sm" name="pPid" initialValue={props.pPid} hidden={true} label="祖宗id"/>
|
<ProFormText width="sm" name="pPid" initialValue={props.pPid} hidden={true} label="祖宗id" />
|
||||||
<ProForm.Group>
|
<ProForm.Group>
|
||||||
<ProFormSelect
|
<ProFormSelect
|
||||||
required={true}
|
required={true}
|
||||||
|
@ -239,55 +218,38 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
name="taskType"
|
name="taskType"
|
||||||
label="任务类型"
|
label="任务类型"
|
||||||
initialValue='0'
|
initialValue='0'
|
||||||
disabled={editFormDisable}
|
disabled ={editFormDisable}
|
||||||
onChange={(value: string, option) => {
|
onChange={(value:string, option)=>{
|
||||||
setTaskType(value)
|
setTaskType(value)
|
||||||
}}
|
}}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{required:true,
|
||||||
required: true,
|
message:"请输入计划类型"
|
||||||
message: "请输入计划类型"
|
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<ProFormText
|
<ProFormText
|
||||||
required={true}
|
required={true}
|
||||||
hidden={taskType != '1'}
|
hidden={taskType!='1'}
|
||||||
width="sm"
|
width="sm"
|
||||||
name="fName"
|
name="fName"
|
||||||
label="团队名称"
|
label="团队名称"
|
||||||
tooltip="最长为 10 位"
|
tooltip="最长为 10 位"
|
||||||
placeholder="请输入团队名称"
|
placeholder="请输入团队名称"
|
||||||
disabled={editFormDisable}
|
disabled ={editFormDisable}
|
||||||
/>
|
/>
|
||||||
<ProFormTreeSelect
|
<ProFormTreeSelect
|
||||||
hidden={taskType == '1'}
|
hidden={taskType=='1'}
|
||||||
width="sm"
|
width="sm"
|
||||||
request={() => {
|
request={() =>{
|
||||||
return getTaskTreeResult(JSON.stringify(
|
return getTaskTreeResult(JSON.stringify(
|
||||||
{
|
{pageSize:1000,pageNumber:1,data:[{code:'pid',value:'0',operateType:'='},{code:'state',value:'8,9',operateType:'IN'},{code:'',value:true,operateType: "TREE"}]}
|
||||||
pageSize: 1000,
|
)).then(result=> childReduce(result.data.content))
|
||||||
pageNumber: 1,
|
|
||||||
data: [{code: 'pid', value: '0', operateType: '='},
|
|
||||||
// 如果父任务完成会导致父任务不展示
|
|
||||||
// {
|
|
||||||
// code: 'state',
|
|
||||||
// value: '8,9',
|
|
||||||
// operateType: 'IN'
|
|
||||||
// },
|
|
||||||
{code: '', value: true, operateType: "TREE"}]
|
|
||||||
}
|
|
||||||
)).then(result => childReduce(result.data.content))
|
|
||||||
}}
|
}}
|
||||||
name="pid"
|
name="pid"
|
||||||
label="父级任务"
|
label="父级任务"
|
||||||
fieldProps={{
|
fieldProps={{onSelect: (e,node) => {console.log('onSelect',e,node);setPid(e)}}}
|
||||||
onSelect: (e, node) => {
|
disabled ={editFormDisable}
|
||||||
console.log('onSelect', e, node);
|
|
||||||
// setPid(e)
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
disabled={editFormDisable}
|
|
||||||
/>
|
/>
|
||||||
<ProFormText
|
<ProFormText
|
||||||
required={true}
|
required={true}
|
||||||
|
@ -296,14 +258,13 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
label="任务名称"
|
label="任务名称"
|
||||||
tooltip="最长为 10 位"
|
tooltip="最长为 10 位"
|
||||||
placeholder="请输入任务名称"
|
placeholder="请输入任务名称"
|
||||||
disabled={editFormDisable}
|
disabled ={editFormDisable}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{required:true,
|
||||||
required: true,
|
message:"请输入计划名称"
|
||||||
message: "请输入计划名称"
|
},{
|
||||||
}, {
|
max:10,
|
||||||
max: 10,
|
message:"名称长度不易超过10个字"
|
||||||
message: "名称长度不易超过10个字"
|
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
@ -314,7 +275,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
label="任务描述"
|
label="任务描述"
|
||||||
// tooltip="最长为 24 位"
|
// tooltip="最长为 24 位"
|
||||||
placeholder="请输入任务描述"
|
placeholder="请输入任务描述"
|
||||||
disabled={editFormDisable}
|
disabled ={editFormDisable}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ProForm.Group>
|
<ProForm.Group>
|
||||||
|
@ -329,11 +290,10 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
name="priority"
|
name="priority"
|
||||||
label="任务优先级"
|
label="任务优先级"
|
||||||
initialValue='3'
|
initialValue='3'
|
||||||
disabled={editFormDisable}
|
disabled ={editFormDisable}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{required:true,
|
||||||
required: true,
|
message:"请选择计划优先级"
|
||||||
message: "请选择计划优先级"
|
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
@ -348,11 +308,10 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
name="state"
|
name="state"
|
||||||
label="任务状态"
|
label="任务状态"
|
||||||
initialValue='8'
|
initialValue='8'
|
||||||
disabled={editFormDisable}
|
disabled ={editFormDisable}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{required:true,
|
||||||
required: true,
|
message:"请选择计划状态"
|
||||||
message: "请选择计划状态"
|
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
@ -363,16 +322,16 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||||
initialValue={[dayjs(), undefined]}
|
initialValue={[dayjs(), undefined]}
|
||||||
name="expectedTimeRange"
|
name="expectedTimeRange"
|
||||||
label="期望时间"
|
label="期望时间"
|
||||||
fieldProps={{allowEmpty: [true, true], showTime: true, needConfirm: true}}
|
fieldProps={{allowEmpty:[true, true],showTime:true,needConfirm:true}}
|
||||||
placeholder={['开始时间', '结束时间']}
|
placeholder={['开始时间','结束时间']}
|
||||||
disabled={editFormDisable}
|
disabled ={editFormDisable}
|
||||||
/>
|
/>
|
||||||
<ProFormDateTimeRangePicker
|
<ProFormDateTimeRangePicker
|
||||||
name="actualTimeRange"
|
name="actualTimeRange"
|
||||||
label="实际时间"
|
label="实际时间"
|
||||||
fieldProps={{allowEmpty: [true, true], showTime: true, needConfirm: true}}
|
fieldProps={ {allowEmpty:[true, true],showTime:true,needConfirm:true}}
|
||||||
placeholder={['开始时间', '结束时间']}
|
placeholder={['开始时间','结束时间']}
|
||||||
disabled={editFormDisable}
|
disabled ={editFormDisable}
|
||||||
/>
|
/>
|
||||||
</ProForm.Group>
|
</ProForm.Group>
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ httpReq.interceptors.request.use((config) => {
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
config.headers.set("source-client","web")
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
@ -38,8 +37,6 @@ httpReq.interceptors.response.use(
|
||||||
message.error('系统异常');
|
message.error('系统异常');
|
||||||
} else if (response.status >= 400 && response.status <= 500) {
|
} else if (response.status >= 400 && response.status <= 500) {
|
||||||
message.warning('无权限');
|
message.warning('无权限');
|
||||||
}else if(response.data.status.success == false){
|
|
||||||
message.error(response.data.status.message);
|
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue