Compare commits

...

5 Commits

Author SHA1 Message Date
1708-huayu e1a40a8980 feat:协作计划按钮处理 2025-07-25 18:53:01 +08:00
1708-huayu 354fb92d28 feat:创建计划描述处理 2025-07-24 18:55:10 +08:00
1708-huayu 24c01d4dc8 feat:窗口变动后日志高度自动更新 2025-07-24 18:40:43 +08:00
1708-huayu a2aced4c85 feat:日志高度设置 2025-07-23 18:39:39 +08:00
1708-huayu db19c5e12c feat:日志修改 2025-07-22 18:47:00 +08:00
7 changed files with 384 additions and 125 deletions

View File

@ -1,8 +1,3 @@
.reverseScrollList {
display: flex;
flex-direction: column; /* 垂直反转 */
/*overflow-y: auto;*/
}
/* 容器样式 */ /* 容器样式 */
.container { .container {
display: flex; display: flex;
@ -55,7 +50,7 @@
display: inline-block; display: inline-block;
padding: 4rpx 20rpx; padding: 4rpx 20rpx;
border: solid; border: solid;
border-radius: 20rpx; border-radius: 0.5rem;
border-color: #1677FF; border-color: #1677FF;
white-space: normal; white-space: normal;
word-break: break-all; word-break: break-all;

View File

@ -1,15 +1,17 @@
import React, {useEffect, useState} from 'react'; import React, {Fragment, useEffect, useRef, useState} from 'react';
import {Avatar, Input, List, message} from 'antd'; import {Dropdown, List, MenuProps, message, Popconfirm} from 'antd';
import VirtualList from 'rc-virtual-list'; import VirtualList from 'rc-virtual-list';
import {Button, Drawer} from 'antd'; import {Button, Drawer} from 'antd';
import {ListDiary, SelectDiary} from "@/components/type/Diary"; import {ListDiary, SelectDiary} from "@/components/type/Diary";
import TextArea from "antd/es/input/TextArea"; import TextArea from "antd/es/input/TextArea";
import style from "@/components/DiaryOption.module.css" import style from "@/components/DiaryOption.module.css"
import dayjs from "dayjs"; import dayjs from "dayjs";
import {addTaskLogAPI} from "@/components/service/Diary"; import {addTaskLogAPI, deleteTaskLogByIdAPI, editEnableFlagAPI} from "@/components/service/Diary";
import {ListRef} from "rc-virtual-list/lib/List";
const CONTAINER_HEIGHT = 400; import {copyToClipboard} from "@/lib/copyToClipboard";
const PAGE_SIZE = 20; import {useWindowSize} from "@/hooks/useWindowSize";
import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
import {OPERATION_BUTTON_TYPE} from "@/lib/task/project/data";
const DiaryOption = (props: SelectDiary) => { const DiaryOption = (props: SelectDiary) => {
// 抽屉 start // 抽屉 start
@ -21,6 +23,40 @@ const DiaryOption = (props: SelectDiary) => {
setOpen(false); setOpen(false);
}; };
// 抽屉 end // 抽屉 end
const [shouldScroll, setShouldScroll] = React.useState(true);
// 设置高度 start
const { height } = useWindowSize();
const [containerHeight, setContainerHeight] = useState(400);
useEffect(() => {
setDiaryList([])
}, []);
useEffect(() => {
if (!open) return;
// 使用 setTimeout 确保 Drawer 内容已渲染
const timer = setTimeout(() => {
const innerDiv = document.querySelector('.ant-drawer-body');
const titleButtonHeight = document.querySelector('.titleButton');
// clientHeight可视高度包括 padding但不包括 border、margin 和滚动条)
// offsetHeight总高度包括 padding、border 和滚动条,但不包括 margin
// scrollHeight内容总高度包括不可见部分
if (innerDiv && titleButtonHeight) {
console.log(innerDiv.clientHeight)
setContainerHeight(innerDiv.clientHeight - titleButtonHeight.clientHeight)
}
}, 100);
return () => clearTimeout(timer);
// console.log({contentRef})
// const observer = new ResizeObserver((entries) => {
// const entry = entries[0];
// setContentHeight(entry.contentRect.height);
// });
//
// observer.observe(contentRef.current);
//
// return () => observer.disconnect();
}, [open,height]);
// 设置高度 end
// 头按钮设置 start // 头按钮设置 start
const [currentIndex, setCurrentIndex] = useState(1); const [currentIndex, setCurrentIndex] = useState(1);
@ -29,12 +65,19 @@ const DiaryOption = (props: SelectDiary) => {
const [diaryList, setDiaryList] = useState<ListDiary[]>([]); const [diaryList, setDiaryList] = useState<ListDiary[]>([]);
const [diaryReduceList, setDiaryReduceList] = useState<ListDiary[]>([]) const [diaryReduceList, setDiaryReduceList] = useState<ListDiary[]>([])
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const noMore = {id: '0', keyId: 'o0',createdDate:new Date(), description: '没有更多了',taskId:props.taskId, enableFlag: 'day-separate'}; const noMore = {
id: '0',
keyId: 'o0',
createdDate: new Date(),
description: '没有更多了',
taskId: props.taskId,
enableFlag: 'day-separate'
};
const [noMoreFlag, setNoMoreFlag] = useState(false) const [noMoreFlag, setNoMoreFlag] = useState(false)
const [sendValue,setSendValue] = useState<string>(); const [sendValue, setSendValue] = useState<string>();
const [sendValueFlag,setSendValueFlag] =useState(false); const [sendValueFlag, setSendValueFlag] = useState(false);
const handleSend = ()=>{ const handleSend = () => {
if(sendValueFlag){ if (sendValueFlag) {
return return
} }
setSendValueFlag(true); setSendValueFlag(true);
@ -49,12 +92,16 @@ const DiaryOption = (props: SelectDiary) => {
}).then(res => { }).then(res => {
setDiaryList([res.data.data, ...diaryList]) setDiaryList([res.data.data, ...diaryList])
setSendValue(undefined) setSendValue(undefined)
setShouldScroll(true);
}).finally(() => { }).finally(() => {
setSendValueFlag(false); setSendValueFlag(false);
}) })
} }
const appendData = (showMessage = true) => { const appendData = (showMessage = true) => {
if (!open){
return
}
const fakeDataUrl = process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/message/diary/select`; const fakeDataUrl = process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/message/diary/select`;
fetch(fakeDataUrl, { fetch(fakeDataUrl, {
method: 'POST', headers: { method: 'POST', headers: {
@ -72,21 +119,29 @@ const DiaryOption = (props: SelectDiary) => {
setDiaryList(diaryList.concat(results)); setDiaryList(diaryList.concat(results));
setPage(page + 1); setPage(page + 1);
showMessage && message.success(`${results.length} more items loaded!`); showMessage && message.success(`${results.length} more items loaded!`);
if (!showMessage) {
if (listRef && listRef.current && typeof listRef.current.scrollTo == 'function') {
listRef.current.scrollTo({top: 9999999});
}
}
}); });
}; };
useEffect(() => { useEffect(() => {
appendData(false); appendData(false);
}, []); }, [open]);
useEffect(() => { useEffect(() => {
console.log("处理日志集合",diaryList) console.log("处理日志集合", diaryList)
const returnResult: ListDiary[] = [] const returnResult: ListDiary[] = []
diaryList.filter(taskLog => { diaryList.filter(taskLog => {
if (currentIndex === 0) { return true } if (currentIndex === 0) {
else if (currentIndex === 1 && taskLog.enableFlag === "1") { return true } return true
else if (currentIndex === 2 && taskLog.enableFlag === "0") { return true } } else if (currentIndex === 1 && taskLog.enableFlag === "1") {
else return false; return true
} else if (currentIndex === 2 && taskLog.enableFlag === "0") {
return true
} else return false;
}).reduce((map, taskLog) => { }).reduce((map, taskLog) => {
if (!map.has(dayjs(taskLog.createdDate).format("YYYY-MM-DD"))) { if (!map.has(dayjs(taskLog.createdDate).format("YYYY-MM-DD"))) {
map.set(dayjs(taskLog.createdDate).format("YYYY-MM-DD"), []); map.set(dayjs(taskLog.createdDate).format("YYYY-MM-DD"), []);
@ -103,32 +158,150 @@ const DiaryOption = (props: SelectDiary) => {
createdDate: new Date() createdDate: new Date()
}) })
}) })
setDiaryReduceList(returnResult); setDiaryReduceList(returnResult.reverse());
}, [diaryList]); }, [diaryList, currentIndex]);
const listRef = useRef<ListRef>(null);
const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => { const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {
// Refer to: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#problems_and_solutions // Refer to: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#problems_and_solutions
if ( // if (
Math.abs(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - CONTAINER_HEIGHT) <= 1 && // Math.abs(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - containerHeight) <= 1 &&
!noMoreFlag // !noMoreFlag
) { // ) {
// appendData();
// }
if (e.currentTarget.scrollTop === 0 && !noMoreFlag) {
appendData(); appendData();
setShouldScroll(false);
} }
}; };
// 数据 end // 数据 end
// 滚动处理 start
// 条件滚动
useEffect(() => {
console.log({shouldScroll}, {listRef})
if (shouldScroll && listRef.current) {
listRef.current.scrollTo({
top: 99999,
});
}
}, [diaryList, shouldScroll, open]);
// 滚动处理 end
// 点击操作 start // 点击操作 start
const [clickTaskDiary, setClickTaskDiary] = useState<ListDiary>() const [clickTaskDiary, setClickTaskDiary] = useState<ListDiary>()
const onClickTAskDiary = (item: ListDiary, operate: string) => {
if (clickTaskDiary == item && operate == 'L') {
setClickTaskDiary(undefined)
} else {
setClickTaskDiary(item)
}
}
// 删除操作
const [popConfirmOpen, setPopConfirmOpen] = useState(false);
const [popConfirmLoading, setPopConfirmLoading] = useState(false);
const popConfirmOk = () => {
setPopConfirmLoading(true)
if (clickTaskDiary){
deleteTaskLogByIdAPI(clickTaskDiary.id).then(res=>{
if (res.data.status.success){
setDiaryList(diaryList.filter(taskLog => taskLog.id != clickTaskDiary.id))
message.info("删除成功")
setPopConfirmLoading(false)
setPopConfirmOpen(false)
}else {
message.error(res.data.status.message)
}
})
}
}
const handleCancel = () =>{
setPopConfirmOpen(false)
}
const editEnableFlag = (enableFlag:string) => {
if (clickTaskDiary){
editEnableFlagAPI(clickTaskDiary.id,enableFlag).then(res=>{
if (res.data.status.success){
setDiaryList(diaryList.map(taskLog => {
if(taskLog.id == clickTaskDiary.id){
taskLog.enableFlag = enableFlag;
}
return taskLog;
}))
message.info("设置成功")
}else {
message.error(res.data.status.message)
}
})
}
}
const [addTaskOpen,setAddTaskOpen] = useState(false)
const commonItems: MenuProps['items'] = [
{
label: '复制',
key: '1',
onClick: () => {
copyToClipboard(clickTaskDiary!.description)
}
},
{
label: '创建计划',
key: '3',
onClick:()=>{
// 打开添加任务窗口
setAddTaskOpen(true)
}
},
{
label: '删除',
key: '4',
onClick: () => {
setPopConfirmOpen(true)
}
},
{
label: '取消',
key: '5',
onClick:()=>{
setClickTaskDiary(undefined)
}
},
]
const items: MenuProps['items'] = [
];
items.push(...commonItems)
items.splice(1,0,{
label: '失效',
key: '2',
onClick:()=>{
editEnableFlag("0")
},
})
const itemsEnable: MenuProps['items'] = [
];
itemsEnable.push(...commonItems)
itemsEnable.splice(1,0,{
label: '生效',
key: '2',
onClick:()=>{
editEnableFlag("1")
},
})
// 点击操作 end // 点击操作 end
return ( return (
<> <Fragment>
<Button type="primary" onClick={showDrawer}> <Button type="primary" onClick={showDrawer}>
</Button> </Button>
<Drawer <Drawer
style={{boxSizing:"border-box"}} style={{boxSizing: "border-box"}}
styles={{
body: {padding: "0 24px"}
}}
mask={false} mask={false}
title={props.taskName} title={props.taskName}
closable={{'aria-label': 'Close Button'}} closable={{'aria-label': 'Close Button'}}
@ -187,7 +360,8 @@ const DiaryOption = (props: SelectDiary) => {
</div> </div>
} }
> >
<div className="displayFlexRow"> <div className="displayFlexRow titleButton"
style={{position: "sticky", top: "0", background: "white", zIndex: "100"}}>
<Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(0)} <Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(0)}
type={currentIndex == 0 ? "primary" : "default"}></Button> type={currentIndex == 0 ? "primary" : "default"}></Button>
<Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(1)} <Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(1)}
@ -195,39 +369,64 @@ const DiaryOption = (props: SelectDiary) => {
<Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(2)} <Button style={{flexGrow: 1}} onClick={() => setCurrentIndex(2)}
type={currentIndex == 2 ? "primary" : "default"}></Button> type={currentIndex == 2 ? "primary" : "default"}></Button>
</div> </div>
<div> <List>
<List> <VirtualList
<VirtualList data={diaryReduceList}
data={diaryReduceList} height={containerHeight}
height={CONTAINER_HEIGHT} // itemHeight={47}
itemHeight={47} itemKey="id"
itemKey="email" onScroll={onScroll}
onScroll={onScroll} // style={{height: "auto"}}
className={style.reverseScrollList} ref={listRef}
> >
{item => ( {item => (
item.enableFlag === 'day-separate' ? item.enableFlag === 'day-separate' ?
<div className={style.container} key={item.keyId}> <div className={style.container} key={item.keyId}>
<div className={style.lineWithText}> <div className={style.lineWithText}>
<text className={style.centerText}>{item.description}</text> <text className={style.centerText}>{item.description}</text>
</div>
</div> </div>
: <div className={style.logTaskContent} key={item.id}> </div>
<div : <div className={style.logTaskContent} key={item.id}>
className={`${style.detailLine} ${item.id === clickTaskDiary?.id ? style.detailLineClick : ''}`} <Dropdown menu={{items: (item.enableFlag == "1" ? items : itemsEnable)}}
onClick={() => setClickTaskDiary(item)}> trigger={['contextMenu']}>
<text <Popconfirm
style={{textDecoration: item.enableFlag === '0' && currentIndex === 0 ? 'line-through' : ''}}> title="警告"
{item.description} description={`确认要删除日志:${item.description.length > 5 ? item.description.substring(0, 5) + '...' : item.description}?`}
</text> open={popConfirmOpen&&clickTaskDiary?.id==item.id}
</div> onConfirm={popConfirmOk}
</div> okButtonProps={{loading: popConfirmLoading}}
)} onCancel={handleCancel}
</VirtualList> okText="Yes"
</List> cancelText="No"
</div> >
<div
className={`${style.detailLine} ${item.id === clickTaskDiary?.id ? style.detailLineClick : ''}`}
onClick={() => onClickTAskDiary(item, "L")}
onContextMenu={() => onClickTAskDiary(item, "R")}>
<text
style={{
textDecoration: item.enableFlag === '0' && currentIndex === 0 ? 'line-through' : '',
whiteSpace: 'pre-line'
}}>
{item.description}
</text>
</div>
</Popconfirm>
</Dropdown>
</div>
)}
</VirtualList>
</List>
</Drawer> </Drawer>
</> {addTaskOpen&&<DetailModelForm pid={props.taskId}
operationId={OPERATION_BUTTON_TYPE.ADD_CHILD}
description={"新增计划"}
open={addTaskOpen}
haveButton={false}
reloadData={()=>setAddTaskOpen(false)}
taskContent={clickTaskDiary?.description}
/>}
</Fragment>
); );
}; };
export default DiaryOption; export default DiaryOption;

View File

@ -7,3 +7,9 @@ export const addTaskLogAPI= (data:AddDiary):Promise<AxiosResponse<ResponseVO<Lis
return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + "/task/message/diary", return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + "/task/message/diary",
data) data)
} }
export const deleteTaskLogByIdAPI = (id:string) => {
return httpReq.delete( process.env.NEXT_PUBLIC_TODO_REQUEST_URL+`/task/message/diary?id=${id}`);
}
export const editEnableFlagAPI = (id:string,enableFlag:string) => {
return httpReq.put( process.env.NEXT_PUBLIC_TODO_REQUEST_URL+`/task/message/diary/enable?id=${id}&enableFlag=${enableFlag}`);
}

View File

@ -0,0 +1,21 @@
import { useState, useEffect } from 'react';
export function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowSize;
}

View File

@ -1,7 +1,7 @@
import {unstable_noStore as noStore} from 'next/cache'; import {unstable_noStore as noStore} from 'next/cache';
import {AxiosResponse} from "axios"; import {AxiosResponse} from "axios";
import {httpReq} from "@/utils/axiosReq"; import {httpReq} from "@/utils/axiosReq";
import {DataType, DictType, Request, ResponseVO, ResultPage} from "@/lib/definitions"; import {DataType, DictType, Request, ResponseVO, ResultPage, TaskMessage} from "@/lib/definitions";
import {TaskWebSelectVO} from "@/lib/task/project/definitions"; import {TaskWebSelectVO} from "@/lib/task/project/definitions";
export async function getTaskTreeResult(requestParam: string): Promise<ResponseVO<ResultPage<DataType>>> { export async function getTaskTreeResult(requestParam: string): Promise<ResponseVO<ResultPage<DataType>>> {
@ -52,12 +52,20 @@ export async function getTask(id: string): Promise<ResponseVO<DataType>> {
return response.data; return response.data;
} }
export async function addTask(task: DataType): Promise<ResponseVO<string>> { export function addTask(task: DataType): Promise<AxiosResponse<ResponseVO<TaskMessage>>> {
noStore(); noStore();
// 使用 Axios 发送 POST 请求添加数据 // 使用 Axios 发送 POST 请求添加数据
const response: AxiosResponse<ResponseVO<string>> = await httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/task', task); switch(task.taskType){
// 从响应中提取数据并返回 // 常规任务
return response.data; case '0':return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/V2/task', task);
// 团队任务
case '1':return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/V2/task', task);
// 顺序
case '2':return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/task/step/sort', task);
// 周期
case '3':return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + '/task/schedule', task);
default:throw new Error("创建任务必选任务类型");
}
} }
export async function updateTask(task: DataType): Promise<ResponseVO<string>> { export async function updateTask(task: DataType): Promise<ResponseVO<string>> {

View File

@ -268,6 +268,7 @@ const CalShow: React.FC = () => {
{open && <DetailModelForm operationId={operationId} description={description} open={open} haveButton={false} {open && <DetailModelForm operationId={operationId} description={description} open={open} haveButton={false}
itemId={itemId} itemId={itemId}
reloadData={reloadData} expectedStartTime={expectedStartTime} reloadData={reloadData} expectedStartTime={expectedStartTime}
closeOpen={()=>setOpen(false)}
expectedEndTime={expectedEndTime}/>} expectedEndTime={expectedEndTime}/>}
<DragAndDropCalendar <DragAndDropCalendar
// 本地设置 // 本地设置

View File

@ -2,7 +2,7 @@ import {PlusOutlined, QuestionCircleOutlined} from '@ant-design/icons';
import { import {
ModalForm, ModalForm,
ProForm, ProForm,
ProFormDateRangePicker, ProFormDateTimeRangePicker, ProFormDateTimeRangePicker,
ProFormSelect, ProFormSelect,
ProFormText, ProFormTextArea, ProFormTreeSelect, ProFormText, ProFormTextArea, ProFormTreeSelect,
} from '@ant-design/pro-components'; } from '@ant-design/pro-components';
@ -29,10 +29,13 @@ export type DetailModelFormProps = {
operationId: OPERATION_BUTTON_TYPE, operationId: OPERATION_BUTTON_TYPE,
// 标题描述 // 标题描述
description: string, description: string,
// 任务内容描述
taskContent?: string,
// 是否打开界面,用于非按钮操作 // 是否打开界面,用于非按钮操作
open: boolean, open: boolean,
// 使用按钮操作 // 使用按钮操作
haveButton: boolean, haveButton: boolean,
closeOpen?: () => void,
expectedStartTime?: Dayjs, expectedStartTime?: Dayjs,
expectedEndTime?: Dayjs, expectedEndTime?: Dayjs,
// 重新加载数据 // 重新加载数据
@ -43,7 +46,7 @@ export type PidSelectTree = { label: string; value: string; pid: string; childre
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 [requestTask, setRequestTask] = useState<DataType>()
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')
@ -61,8 +64,8 @@ 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"){ if (task.data.pid == "0") {
form.setFieldValue("pid",undefined) form.setFieldValue("pid", undefined)
} }
setRequestTask(task.data) setRequestTask(task.data)
console.log("form.setFieldsValue(task.data)" + JSON.stringify(task.data)) console.log("form.setFieldsValue(task.data)" + JSON.stringify(task.data))
@ -74,7 +77,9 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
} 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], 'expectedTimeRange': [props.expectedStartTime ? props.expectedStartTime : dayjs(), props.expectedEndTime],
'pid': props.pid 'pid': props.pid,
'description': props.taskContent,
'name': props.taskContent && props.taskContent?.length > 10 ? props.taskContent.substring(0, 10) : props.taskContent,
}; };
form.setFieldsValue(data) form.setFieldsValue(data)
} }
@ -112,22 +117,21 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
modalProps={{ modalProps={{
destroyOnClose: true, destroyOnClose: true,
onCancel: () => { onCancel: () => {
console.log('run');
props.reloadData?.(); props.reloadData?.();
}, },
}} }}
readonly={editFormDisable}
submitter={props.itemId !== undefined && props.itemId !== '-1' ? { submitter={props.itemId !== undefined && props.itemId !== '-1' ? {
render: (prop, defaultDoms) => { render: (prop, defaultDoms) => {
return [ console.log("submitter render: ", {prop})
let result = [
editFormDisable ? <Button editFormDisable ? <Button
key="edit" key="edit"
onClick={() => { onClick={() => {
// props.submit(); // props.submit();
setEditFormDisable(false) setEditFormDisable(false)
}} }}
> ></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'
@ -148,21 +152,50 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
} }
}} }}
> >
<Button type="primary" danger> <Button type="primary" key="delete" danger>
</Button> </Button>
</Popconfirm> : undefined </Popconfirm> : undefined,
, requestTask && requestTask.id ?
requestTask&&requestTask.id?<DiaryOption taskId={requestTask.id} taskName={requestTask.name}/>:undefined, <DiaryOption key="diary" taskId={requestTask.id} taskName={requestTask.name}/> : undefined,
...defaultDoms ]
];
// 非新增或者编辑状态不展示
if (!editFormDisable) {
result.push(...defaultDoms)
} else {
result.push(<Button type="primary" key="join"
onClick={() => props.closeOpen?.()}></Button>)
result.push(<Button type="primary" key="close"
onClick={() => props.closeOpen?.()}></Button>)
}
return result;
}, },
} : undefined} } : {
render: (prop, defaultDoms) => {
console.log("submitter render: ", {prop}, {props},{taskType},{defaultDoms})
// if ( prop.searchConfig) {
// if (taskType == '1') {
// prop.searchConfig.submitText = "创建团队"
// }else {
// prop.searchConfig.submitText = "确认"
// }
// }
// return defaultDoms;
const result = defaultDoms.filter(defaultButton=>defaultButton.key=='rest');
result.push(<Button type="primary" key="create-team" onClick={() => form.submit()}>{taskType=='1'?"创建团队":"确认"}
</Button>)
return result;
}
}
}
onFinish={async (values) => { onFinish={async (values) => {
console.log('Received values of form: ', values,{...requestTask,...values}); {/* onFinish 返回true关闭窗口范湖false不关闭窗口 */
}
console.log('Received values of form: ', values, {...requestTask, ...values});
if (requestTask) { if (requestTask) {
const {sortNo}=requestTask; const {sortNo} = requestTask;
values.sortNo=sortNo; values.sortNo = sortNo;
} }
if (values.pid === undefined) { if (values.pid === undefined) {
values.pid = '0' values.pid = '0'
@ -210,16 +243,16 @@ 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.status.success) { if (response.data.status.success) {
message.success("添加任务成功:" + response.data) message.success(`添加计划${response.data.data.name}成功`)
// 树任务重新刷新 // 树任务重新刷新
// 四象限任务重新刷新 // 四象限任务重新刷新
// 如果可以直接更新列表而不请求。。。。。。 // 如果可以直接更新列表而不请求。。。。。。
console.log('props.reloadData?.()', props.reloadData) console.log('props.reloadData?.()', props.reloadData)
result = (taskType!='1')
props.reloadData?.() props.reloadData?.()
result = true
} else { } else {
message.error(response.status.message) message.error(response.data.status.message)
result = false result = false
} }
} }
@ -238,7 +271,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
width="sm" width="sm"
name="taskType" name="taskType"
label="任务类型" label="任务类型"
initialValue='0' initialValue={taskType}
disabled={editFormDisable} disabled={editFormDisable}
onChange={(value: string, option) => { onChange={(value: string, option) => {
setTaskType(value) setTaskType(value)
@ -269,12 +302,12 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
pageSize: 1000, pageSize: 1000,
pageNumber: 1, pageNumber: 1,
data: [{code: 'pid', value: '0', operateType: '='}, data: [{code: 'pid', value: '0', operateType: '='},
// 如果父任务完成会导致父任务不展示 // 如果父任务完成会导致父任务不展示
// { // {
// code: 'state', // code: 'state',
// value: '8,9', // value: '8,9',
// operateType: 'IN' // operateType: 'IN'
// }, // },
{code: '', value: true, operateType: "TREE"}] {code: '', value: true, operateType: "TREE"}]
} }
)).then(result => childReduce(result.data.content)) )).then(result => childReduce(result.data.content))
@ -309,52 +342,48 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
/> />
</ProForm.Group> </ProForm.Group>
<ProFormTextArea <ProFormTextArea
// width="md" width="xl"
name="description" name="description"
label="任务描述" label="任务描述"
// tooltip="最长为 24 位" tooltip="最长255个字"
placeholder="请输入任务描述" placeholder="请输入任务描述"
disabled={editFormDisable} disabled={editFormDisable}
/> />
<ProForm.Group> <ProForm.Group>
<ProFormSelect <ProFormSelect
request={async () => taskPriorityList.map(taskState => { request={async () =>
return { taskPriorityList.map
'label': taskState.name, (
'value': taskState.code taskState => {
} return {'label': taskState.name, 'value': taskState.code}
})} }
)
}
width="sm" width="sm"
name="priority" name="priority"
label="任务优先级" label="任务优先级"
initialValue='3' initialValue='3'
disabled={editFormDisable} disabled={editFormDisable}
rules={[ rules={[{required: true, message: "请选择计划优先级"}]}
{
required: true,
message: "请选择计划优先级"
}
]}
/> />
<ProFormSelect <ProFormSelect
width="sm" width="sm"
options={taskStateList.map(taskState => { options={taskStateList.map(taskState => {
return { return {'label': taskState.name, 'value': taskState.code}
'label': taskState.name,
'value': taskState.code
}
})} })}
name="state" name="state"
label="任务状态" label="任务状态"
initialValue='8' initialValue='8'
disabled={editFormDisable} disabled={editFormDisable}
rules={[ rules={
{ [
required: true, {
message: "请选择计划状态" required: true,
} message: "请选择计划状态"
]} }
]
}
/> />
</ProForm.Group> </ProForm.Group>
@ -378,4 +407,4 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
</ModalForm> </ModalForm>
); );
}; };