feat:1.根据路径展示2.设置主线任务

This commit is contained in:
1708-huayu 2025-08-07 19:27:37 +08:00
parent 55ffba0953
commit 09d4357719
16 changed files with 4556 additions and 105 deletions

View File

@ -107,7 +107,7 @@ const ShareOption = (props: { taskId: string }) => {
onClick={() => doDownload("/static/pc-Web.png", '微信小程序马上行计划管理.png')}></Button>
</div>
<div className="displayFlexColumn" id="myqrcode">
<div className="title">7</div>
<div className="title">1</div>
<QRCode type="svg" value={qrCodeValue} size={300} status={qrCodeStatus}
onRefresh={generateQrcode}/>
<Button onClick={downloadSvgQRCode}></Button>

View File

@ -0,0 +1,3 @@
.localDiv{
margin-bottom: 24px;
}

View File

@ -0,0 +1,169 @@
import styles from "@/components/TaskRemind.module.css";
import {CascaderProps, ConfigProvider} from 'antd';
import {Cascader} from 'antd';
import React, {useState} from "react";
interface ITaskRemind {
remindTypeList: string[],
setRemindTypeList: (taskTypeList: string[]) => void,
readonly: boolean,
}
interface Option {
value?: string | number | null;
label: React.ReactNode;
children?: Option[];
isLeaf?: boolean;
}
const optionLists: Option[] = [
{
label: "期望开始",
value: "expect_start",
isLeaf: false,
},
{
label: "期望结束",
value: "expect_end",
isLeaf: false,
},
];
const TaskRemindComponent = (props: ITaskRemind) => {
const [options, setOptions] = useState<Option[]>(optionLists);
const cascaderOnChange: CascaderProps<Option>['onChange'] = (value: (string | number)[], selectedOptions: Option[]) => {
console.log(value, selectedOptions);
};
const cascaderLoadData = (selectedOptions: Option[]) => {
const targetOption = selectedOptions[selectedOptions.length - 1];
if (targetOption.value === "expect_start" || targetOption.value === "expect_end") {
targetOption.children = [
{
label: ``,
value: 'before',
isLeaf: false,
},
{
label: ``,
value: 'after',
isLeaf: false,
},
];
} else if (targetOption.value === "before" || targetOption.value === "after") {
targetOption.children = Array.from({length: 60}, (_, i) => ({
label: i.toString().padStart(2, '0'), // 显示为 "00", "01", ..., "59"
value: i,
isLeaf: false,
}))
} else {
targetOption.children = [
{
label: "分钟",
value: "m",
isLeaf: true,
},
{
label: "小时",
value: "h",
isLeaf: false,
},
{
label: "天",
value: "d",
isLeaf: false,
}
]
}
setOptions([...options]);
}
return (<div className={styles.localDiv}>
<div style={{marginBottom: "8px"}}></div>
{/*{props.readonly ?*/}
{/* (props.remindTypeList.length == 0 ? <div>-</div> : props.remindTypeList.map(remindType => {*/}
{/* <div>remindType.split(",")</div>*/}
{/* })) :*/}
{/* (props.remindTypeList.length == 0 ? <Space wrap>*/}
{/* <Select*/}
{/* style={{width: 120}}*/}
{/* allowClear*/}
{/* // defaultValue={onceConsumeChange[0]}*/}
{/* onChange={(value) => {*/}
{/* }}*/}
{/* options={[{*/}
{/* label: "期望开始",*/}
{/* value: "expect_start",*/}
{/* }, {*/}
{/* label: "期望结束",*/}
{/* value: "expect_end",*/}
{/* }*/}
{/* ]}*/}
{/* />*/}
{/* <Select*/}
{/* style={{width: 120}}*/}
{/* allowClear*/}
{/* // defaultValue={onceConsumeChange[0]}*/}
{/* onChange={(value) => {*/}
{/* }}*/}
{/* options={[{*/}
{/* label: "前",*/}
{/* value: "before",*/}
{/* }, {*/}
{/* label: "后",*/}
{/* value: "after",*/}
{/* }*/}
{/* ]}*/}
{/* />*/}
{/* <Select*/}
{/* style={{width: 120}}*/}
{/* allowClear*/}
{/* onChange={(value) => {*/}
{/* }}*/}
{/* options={onceConsumeList}*/}
{/* />*/}
{/* <Select*/}
{/* style={{width: 120}}*/}
{/* allowClear*/}
{/* // defaultValue={onceConsumeChange[1]}*/}
{/* onChange={(value) => {*/}
{/* }}*/}
{/* options={[{label: "分钟", value: "m"}, {label: "小时", value: "h"}, {*/}
{/* label: "天",*/}
{/* value: "d"*/}
{/* }]}*/}
{/* />*/}
{/* </Space>:props.remindTypeList.map(remindType => {*/}
{/* <div>remindType.split(",")</div>*/}
{/* }))}*/}
{props.readonly ? (
props.remindTypeList.length === 0 ? (
<div>-</div>
) : (
props.remindTypeList.map((remindType, index) => (
<div key={index}>{remindType.split(",").join(", ")}</div>
))
)
) : props.remindTypeList.length === 0 ? (
<ConfigProvider
theme={{
components: {
Cascader: {
/* 这里是你的组件 token */
controlWidth:300
},
},
}}
>
<Cascader options={options} loadData={cascaderLoadData} onChange={cascaderOnChange} changeOnSelect defaultValue={["expect_start","after","1","h"]} />
</ConfigProvider>
) : (
props.remindTypeList.map((remindType, index) => (
<div key={index}>{remindType.split(",").join(", ")}</div>
))
)}
</div>)
}
export default TaskRemindComponent

View File

@ -1,13 +1,13 @@
import React, {Fragment, useEffect, useRef, useState} from "react";
import {Button, Modal, TablePaginationConfig} from "antd";
import {Button, message, Modal, TablePaginationConfig} from "antd";
import {ActionType, ProColumns, ProTable} from "@ant-design/pro-components";
import {Params} from "next/dist/shared/lib/router/utils/route-matcher";
import {TeamMemberVO} from "@/components/type/Share.d";
import type {FilterValue, SorterResult, TableCurrentDataSource} from "antd/es/table/interface";
import {listTeamMemberAPI} from "@/components/service/Share";
import {allowAddTeamAPI, listTeamMemberAPI, quitTeamAPI, removeTeamAPI} from "@/components/service/Share";
const TeamMember = (props: { taskId: string }) => {
const TeamMember = (props: { taskId: string,closeOpen?: () => void,reloadData?: () => void }) => {
const [open, setOpen] = useState(false);
const onClose = () => {
setOpen(false);
@ -18,20 +18,57 @@ const TeamMember = (props: { taskId: string }) => {
const [totalUserList, setTotalUserList] = React.useState<TeamMemberVO[]>([]);
const [totalElement, setTotalElement] = React.useState(0);
const [loading, setLoading] = React.useState(false);
const [buttonLoading, setButtonLoading] = React.useState(false);
const [currentUser, setCurrentUser] =
React.useState<{ username: string, adminFlag: boolean }>();
const [page,setPage]=React.useState({pageSize:10, pageIndex:1});
useEffect(() => {
if (open){
if (open) {
setLoading(true);
listTeamMemberAPI(props.taskId).then((res)=>{
if (res.data.status.success){
setUserList(res.data.data.splice(0,10))
listTeamMemberAPI(props.taskId).then((res) => {
if (res.data.status.success) {
setUserList(res.data.data.splice(0, 10))
setTotalUserList(res.data.data)
setTotalElement(res.data.data.length)
setTimeout(()=>{ref.current?.reload()},100)
setTimeout(() => {
ref.current?.reload()
}, 100)
}
setLoading(false)
})
}
},[open])
}, [open])
const removeTeam = (teamMember: TeamMemberVO) => {
removeTeamAPI(teamMember).then(res => {
if (res.data.status.success) {
message.success("移除成功")
setTotalUserList(res.data.data)
setUserList(res.data.data.splice((page.pageIndex - 1) * (page.pageSize), page.pageSize))
}
})
}
const quitTeam = (teamMember: TeamMemberVO) => {
quitTeamAPI(teamMember).then(res => {
if (res.data.status.success) {
message.success('退出成功,随后返回首页')
props.reloadData?.()
setOpen(!open)
props.closeOpen?.()
}
})
}
const allowAddTeam = (teamMember: TeamMemberVO) => {
allowAddTeamAPI({
userId: [teamMember.userId],
taskId: props.taskId
}).then(res=>{
message.success("添加成功")
setTotalUserList(res.data.data)
setUserList(res.data.data.splice((page.pageIndex - 1) * (page.pageSize), page.pageSize))
})
}
const columns: ProColumns<TeamMemberVO>[] = [
{
title: 'ID',
@ -50,7 +87,22 @@ const TeamMember = (props: { taskId: string }) => {
key: 'operate',
width: 120,
valueType: 'option',
render: () => [<Button key="1"></Button>],
render: (node, entity) => {
// 管理员可展示提出,普通用户自己展示退出
if (currentUser?.adminFlag && entity.userState == '1' && entity.username != currentUser.username) {
return <Button key={`${entity.id}remove`} loading={buttonLoading} danger
onClick={(event) => removeTeam(entity)}></Button>
} else if (currentUser?.adminFlag && entity.userState == '1' && entity.username != currentUser.username) {
return <Button key={`${entity.id}myself`} loading={buttonLoading} color='default'></Button>
} else if (!currentUser?.adminFlag && entity.userState == '1' && entity.username != currentUser?.username) {
return <Button key={`${entity.id}team`} loading={buttonLoading} color='default'></Button>
} else if (!currentUser?.adminFlag && entity.userState == '1' && entity.username == currentUser?.username) {
return <Button key={`${entity.id}quit`} loading={buttonLoading} danger onClick={(event) => quitTeam(entity)}>退</Button>
} else if (entity.userState == '0') {
return <Button key={`${entity.id}allow`} loading={buttonLoading} color='primary' onClick={(event) => allowAddTeam(entity)}></Button>
}
return undefined;
},
},
];
return (
@ -83,8 +135,8 @@ const TeamMember = (props: { taskId: string }) => {
// }}
/* Pagination */
pagination={{
defaultPageSize:10,
defaultCurrent:1,
defaultPageSize: page.pageSize,
defaultCurrent: page.pageIndex,
total: totalElement,
showSizeChanger: true,
showQuickJumper: true,
@ -93,7 +145,11 @@ const TeamMember = (props: { taskId: string }) => {
onChange={(pagination: TablePaginationConfig, filters: Record<string, FilterValue | null>,
sorter: SorterResult<TeamMemberVO> | SorterResult<TeamMemberVO>[], extra:
TableCurrentDataSource<TeamMemberVO>) => {
setUserList(totalUserList.splice((pagination.current??1-1)*(pagination.pageSize??10),pagination.pageSize))
setPage({
pageSize: pagination.pageSize||10,
pageIndex: pagination.current||1,
})
setUserList(totalUserList.splice((pagination.current ?? 1 - 1) * (pagination.pageSize ?? 10), pagination.pageSize))
}}
/>
</Modal>

File diff suppressed because it is too large Load Diff

View File

@ -9,4 +9,13 @@ export const addTaskPassAPI= (data:ShareVO):Promise<AxiosResponse<ResponseVO<Sha
}
export const listTeamMemberAPI = (taskId:string):Promise<AxiosResponse<ResponseVO<TeamMemberVO[]>>> =>{
return httpReq.get(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/team/member/list?taskId=${taskId}`)
}
export const removeTeamAPI = (teamMember: TeamMemberVO):Promise<AxiosResponse<ResponseVO<TeamMemberVO[]>>> =>{
return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/team/member/remove`,teamMember)
}
export const quitTeamAPI = (teamMember: TeamMemberVO):Promise<AxiosResponse<ResponseVO<TeamMemberVO[]>>> =>{
return httpReq.delete(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/team/member/quite/${teamMember.id}`)
}
export const allowAddTeamAPI = (teamAllow:any):Promise<AxiosResponse<ResponseVO<TeamMemberVO[]>>> =>{
return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/team/member/allow`,teamAllow)
}

View File

@ -1,7 +1,6 @@
import React from "react";
import {Dayjs} from "dayjs";
import {TaskStepSortVO} from "@/components/type/TaskSort.d";
import {Data} from "@dnd-kit/core";
export type Request<T>={
data:T,
@ -58,7 +57,7 @@ export type DataType = TaskMessage&{
actualTimeRange?:(string|Dayjs|undefined)[]
children: DataType[]|undefined;
sortNo?:number;
remindType?:string[]
}
export type DictType={
id:number;

View File

@ -12,7 +12,9 @@ import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
export interface OperationButtonProps {
itemId: string,
fId:string|undefined,
itemName:string,
fName:string|undefined,
priority?:string,
pid: string,
pPid: string,
@ -162,15 +164,15 @@ class OperationButton extends React.Component<OperationButtonProps, OperationMod
},
{
key: OPERATION_BUTTON_TYPE.SHOW_TREE,
label: <Link href={`/task/project?pid=${this.props.itemId}&pName=${this.props.itemName}`}></Link>,
label: <Link href={`/task/project?pid=${this.props.itemId}&pName=${this.props.itemName}${this.props.fId?('&fId='+this.props.fId+"&fName="+this.props.fName):""}`}></Link>,
},
{
key: OPERATION_BUTTON_TYPE.SHOW_FOUR,
label: <Link href={`/task/drag?pid=${this.props.itemId}&pName=${this.props.itemName}`}></Link>,
label: <Link href={`/task/drag?pid=${this.props.itemId}&pName=${this.props.itemName}${this.props.fId?('&fId='+this.props.fId+"&fName="+this.props.fName):""}`}></Link>,
},
{
key: OPERATION_BUTTON_TYPE.SHOW_CALENDAR,
label: <Link href={`/task/calendar?pid=${this.props.itemId}&pName=${this.props.itemName}`}></Link>,
label: <Link href={`/task/calendar?pid=${this.props.itemId}&pName=${this.props.itemName}${this.props.fId?('&fId='+this.props.fId+"&fName="+this.props.fName):""}`}></Link>,
}
];
return <Fragment>

View File

@ -7,8 +7,10 @@ import Link from "next/link";
import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
interface OperationButtonProps {
itemId: string,
fId:string|undefined,
taskType?:string,
itemName: string,
fName:string|undefined,
priority?:string,
pid: string,
pPid: string,
@ -89,15 +91,15 @@ const RightOption: React.FC<OperationButtonProps> = (props) => {
},
{
key: OPERATION_BUTTON_TYPE.SHOW_TREE,
label: <Link href={`/task/project?pid=${props.itemId}&pName=${props.itemName}`}></Link>,
label: <Link href={`/task/project?pid=${props.itemId}&pName=${props.itemName}${props.fId?('&fId='+props.fId+"&fName="+props.fName):""}`}></Link>,
},
{
key: OPERATION_BUTTON_TYPE.SHOW_FOUR,
label: <Link href={`/task/drag?pid=${props.itemId}&pName=${props.itemName}`}></Link>,
label: <Link href={`/task/drag?pid=${props.itemId}&pName=${props.itemName}${props.fId?('&fId='+props.fId+"&fName="+props.fName):""}`}></Link>,
},
{
key: OPERATION_BUTTON_TYPE.SHOW_CALENDAR,
label: <Link href={`/task/calendar?pid=${props.itemId}&pName=${props.itemName}`}></Link>,
label: <Link href={`/task/calendar?pid=${props.itemId}&pName=${props.itemName}${props.fId?('&fId='+props.fId+"&fName="+props.fName):""}`}></Link>,
}
];
// 获取系统样式

View File

@ -1,6 +1,6 @@
'use client'
import React, {Fragment, useContext, useEffect} from "react";
import {Button, Checkbox, CheckboxOptionType, DatePicker, Select, Space} from "antd";
import React, {Fragment, useContext, useEffect, useState} from "react";
import {Button, Checkbox, CheckboxOptionType, DatePicker, MenuProps, message, Select, Space} from "antd";
import {usePathname, useRouter} from "next/navigation";
import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
import {OPERATION_BUTTON_TYPE, taskStateList} from "@/lib/task/project/data";
@ -9,6 +9,7 @@ import LocalContext from "@/ui/LocalContent";
import {RequestDateType} from "@/ui/task/RequestDateType";
import dayjs, {Dayjs} from "dayjs";
import {useSearchParams} from "next/dist/client/components/navigation";
import Dropdown from "antd/es/dropdown/dropdown";
interface TitleOperationProps {
setTaskState: (value: string) => void;
@ -22,8 +23,14 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
refreshData
}: TitleOperationProps) => {
const {replace} = useRouter();
console.log('usePathname()', usePathname());
console.log('useSearchParams()', useSearchParams().get('pid'));
const searchParams = useSearchParams();
const pathname = usePathname();
const [pathParam, setPathParam] = useState<string | undefined>(searchParams.toString());
const [pathName, setPathName] = useState(pathname);
console.log('usePathname()', pathname);
console.log('useSearchParams()',searchParams.toString(),searchParams.get('pName'), searchParams.get('pid'));
const data = useContext(LocalContext);
const {RangePicker} = DatePicker;
const expectStartTimeParseResult: RequestDateType[] = data.expectedStartTime.length > 0 ? JSON.parse(data.expectedStartTime) : [undefined, undefined]
@ -32,17 +39,48 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
expectStartTimeParseResult[0] && expectStartTimeParseResult[0].value ? dayjs(expectStartTimeParseResult[0].value.toString()) : undefined,
expectStartTimeParseResult[1] && expectStartTimeParseResult[1].value ? dayjs(expectStartTimeParseResult[1].value.toString()) : undefined
];
const pName = useSearchParams().get("pName");
const typeList: CheckboxOptionType<string>[] = [
{ label: '计划', value: '0,1,2,3', },
{ label: '打卡', value: '4', },
{ label: '事件', value: '5', },
];
// ✅ 监听 searchParams 变化
useEffect(() => {
const pName = searchParams.get("pName");
if(pName&&pName!=document.title){
document.title = pName;
}
}, [pName]);
setPathParam(searchParams.toString());
}, [searchParams]); // searchParams 变化时触发
const onClick: MenuProps['onClick'] = ({ key }) => {
if (key == "1"){
}else if (key == "2"){
replace(pathName)
setPathParam(undefined)
}
};
const items: MenuProps['items'] = [
{
label: '退出登录',
key: '1',
},
];
const itemsPid: MenuProps['items'] = [
{
label: '退出登录',
key: '1',
},
{
label: '从顶级任务查看',
key: '2',
},
];
return <div className={style.container}>
<Space style={{marginTop: 0, "height": "42px", "alignContent": "center"}}>
<DetailModelForm haveButton={true} open={false} operationId={OPERATION_BUTTON_TYPE.ADD}
@ -50,21 +88,21 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
{
!usePathname().startsWith("/task/project") &&
<Button type="primary" onClick={() => {
replace("/task/project");
replace(`/task/project${pathParam?('?'+pathParam):""}`);
// setCurrentPath("/task/project")
}}></Button>
}
{
!usePathname().startsWith("/task/drag") &&
<Button type="primary" onClick={() => {
replace("/task/drag");
replace(`/task/drag${pathParam?('?'+pathParam):""}`);
// setCurrentPath("/task/four");
}}></Button>
}
{
!usePathname().startsWith("/task/calendar") &&
<Button type="primary" onClick={() => {
replace("/task/calendar");
replace(`/task/calendar${pathParam?('?'+pathParam):""}`);
// setCurrentPath("/task/project")
}}></Button>
}
@ -139,8 +177,10 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
</Fragment>
}
</Space>
<Dropdown menu={{ items:pathParam?itemsPid:items, onClick }}>
<svg style={{height: "32px", width: "32px", alignItems: "center"}} className="icon" aria-hidden="true">
<use xlinkHref="#icon-user__easyico"></use>
</svg>
</Dropdown>
</div>
}

View File

@ -9,7 +9,7 @@ import dayjs from "dayjs";
import {getTaskState, taskPriorityList} from "@/lib/task/project/data";
import 'react-virtualized/styles.css';
import RightOption from "@/ui/task/RightOption";
import {CopyOutlined} from "@ant-design/icons";
interface DroppableTableProps {
tableCode: string,
@ -83,6 +83,7 @@ export const DroppableTable = React.memo((props: DroppableTableProps) => {
{(provided, snapshot) => (
<RightOption refreshDate={props.refreshDate} itemId={record.id}
itemName={record.name} pid={record.pid}
fId={record.fId} fName={record.fName}
taskType={record.taskType}
pPid={record.pPid} children={<div
ref={provided.innerRef}

View File

@ -152,7 +152,9 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
columns={columns}
// rowSelection={{ ...rowSelection, checkStrictly}}
dataSource={props.resultDataTypeList.filter(resultDataType=>{
resultDataType.action= <OperationButton itemId={resultDataType.id} itemName={resultDataType.name} pid={resultDataType.pid} pPid={resultDataType.pPid} refreshDate={props.refreshDate}/>
resultDataType.action= <OperationButton itemId={resultDataType.id} itemName={resultDataType.name}
fId={resultDataType.fId} fName={resultDataType.fName}
pid={resultDataType.pid} pPid={resultDataType.pPid} refreshDate={props.refreshDate}/>
if (dataLocalContext.expectedStartTime.length === 0) {
return true;
}

View File

@ -166,7 +166,9 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
columns={columns}
// rowSelection={{ ...rowSelection, checkStrictly}}
dataSource={props.resultDataTypeList.filter(resultDataType=>{
resultDataType.action= <OperationButton itemId={resultDataType.id} itemName={resultDataType.name} priority={resultDataType.priority} pid={resultDataType.pid} pPid={resultDataType.pPid} refreshDate={props.refreshDate}/>
resultDataType.action= <OperationButton itemId={resultDataType.id} itemName={resultDataType.name}
fId={resultDataType.fId} fName={resultDataType.fName}
priority={resultDataType.priority} pid={resultDataType.pid} pPid={resultDataType.pPid} refreshDate={props.refreshDate}/>
if (dataLocalContext.expectedStartTime.length === 0) {
return true;
}

View File

@ -1,3 +1,3 @@
.localDiv{
margin-bottom: 24px;
}
}

View File

@ -26,6 +26,9 @@ import onceConsumeList from "@/components/constant/onceConsumeList.json"
import {onceConsumerRead} from "@/utils/codeToReadName";
import style from "@/ui/task/project/DetailModelForm.module.css"
import TeamMember from "@/components/TeamMember";
import {useSearchParams} from "next/dist/client/components/navigation";
import TaskRemindComponent from "@/components/TaskRemindComponent";
export type DetailModelFormProps = {
// 当前内容id
itemId?: string,
@ -49,19 +52,71 @@ export type DetailModelFormProps = {
// 重新加载数据
reloadData?: () => void
}
export type PidSelectTree = { label: string; value: string; pid: string; children?: PidSelectTree[] }
export type PidSelectTree = {
label: string;
value: string;
pid: string;
fId: string | undefined,
fName: string | undefined,
children?: PidSelectTree[]
}
export type ParentTaskVO = {
pid: string,
pName: string | undefined,
fId: string | undefined,
fName: string | undefined,
}
export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
const [form] = Form.useForm<DataType>();
const searchParams = useSearchParams();
const [requestTask, setRequestTask] = useState<DataType>()
console.log("DetailModelForm:props:", props,requestTask)
console.log("DetailModelForm:props:", props, requestTask)
const [editFormDisable, setEditFormDisable] = useState(props.operationId === OPERATION_BUTTON_TYPE.DETAIL)
// 团队第一层 pid必须为0
const [taskType, setTaskType] = useState('0')
const [spinning, setSpinning] = useState(true)
const [operationRequest, setOperationRequest] = useState(false)
const [onceConsumeChange, setOnceConsumeChange] = useState<string[]>(["1", "h"])
const [defaultPTask, setDefaultPTask] = useState<ParentTaskVO>({
pid: '0',
pName: undefined,
fId: undefined,
fName: undefined,
})
const [pTaskMap, setPTaskMap] = useState<Record<string, ParentTaskVO>>()
const [remindTypeList,setRemindTypeList] = useState<string[]>([])
function initData(){
form.resetFields()
setTaskType('0')
setOnceConsumeChange(["1", "h"])
setRequestTask(undefined);
setDefaultPTask({
pid: '0',
pName: undefined,
fId: undefined,
fName: undefined,
})
}
useEffect(() => {
if (searchParams && searchParams.get("pid")) {
setDefaultPTask({
pid: searchParams.get("pid")!,
pName: searchParams.get("pName")!,
fId: searchParams.get("fId")!,
fName: searchParams.get("fName")!,
})
} else {
setDefaultPTask({
pid: '0',
pName: undefined,
fId: undefined,
fName: undefined,
})
}
}, [searchParams]);
useEffect(() => {
if (props.itemId != undefined && (
props.operationId === OPERATION_BUTTON_TYPE.DETAIL || props.operationId === OPERATION_BUTTON_TYPE.UPDATE)) {
@ -78,19 +133,26 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
form.setFieldsValue(task.data)
if (task.data.pid == "0") {
form.setFieldValue("pid", undefined)
}else if (searchParams){
form.setFieldValue("pid", task.data.pName)
}
if (task.data.taskType) {
setTaskType(task.data.taskType)
}
setRequestTask(task.data)
setDefaultPTask({
pid: task.data.pid,
pName: task.data.pName,
fId: task.data.fId,
fName: task.data.fName,
})
if (task.data.onceConsume) {
setOnceConsumeChange(task.data.onceConsume.split(","))
}
console.log("form.setFieldsValue(task.data)" + JSON.stringify(task.data))
} else {
message.error(task.status.message);
setRequestTask(undefined)
form.resetFields()
initData()
props.reloadData?.()
}
}).finally(() => {
@ -111,13 +173,19 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
function childReduce(child: DataType[]): PidSelectTree[] {
const result: PidSelectTree[] = [];
const parentTaskMap: Record<string, ParentTaskVO> = {};
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,
fId: data.fId, fName: data.fName
};
parentTaskMap[data.id] = {pid: data.pid, pName: data.pName, fId: data.fId, fName: data.fName};
if (data.children) {
resultData.children = childReduce(data.children);
}
result.push(resultData);
})
setPTaskMap({...pTaskMap, ...parentTaskMap})
return result;
}
@ -145,8 +213,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
destroyOnClose: true,
maskClosable: false,
onCancel: () => {
setRequestTask(undefined)
form.resetFields()
initData()
props.reloadData?.();
},
}}
@ -176,8 +243,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
console.log('response', response)
if (response.status.success) {
message.success("删除任务成功:" + response.data)
setRequestTask(undefined)
form.resetFields()
initData()
props.reloadData?.()
}
}));
@ -199,7 +265,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
} else {
if (editFormDisable && taskType == '1') {
result.push(<ShareOption taskId={props.itemId!}/>)
result.push(<TeamMember taskId={props.itemId!}/> )
result.push(<TeamMember taskId={props.itemId!} closeOpen={props.closeOpen}
reloadData={props.reloadData}/>)
}
result.push(<Button type="primary" key="close"
onClick={() => props.closeOpen?.()}></Button>)
@ -236,14 +303,15 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
}
}
onFinish={async (values) => {
{/* onFinish 返回true关闭窗口范湖false不关闭窗口 */
}
console.log('Received values of form: ', values, {...requestTask, ...values});
console.log('Received values of form: ', values,defaultPTask, {...requestTask, ...values});
setOperationRequest(true)
if (requestTask) {
const {sortNo} = requestTask;
values.sortNo = sortNo;
}
values.pid = defaultPTask.pid;
values.fId = defaultPTask.fId;
values.fName = defaultPTask.fName;
if (values.pid === undefined) {
values.pid = '0'
}
@ -260,6 +328,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
values.actualEndTime = dayjs(values.actualTimeRange[1]).toDate()
}
var result: boolean = false;
values.remindType=remindTypeList;
let state = taskStateList.find(taskState => taskState.name === values.state?.toString());
if (state) {
@ -278,8 +347,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
// 树任务重新刷新
// 四象限任务重新刷新
// 如果可以直接更新列表而不请求。。。。。。
setRequestTask(undefined)
form.resetFields()
initData()
props.reloadData?.()
result = true
} else {
@ -293,15 +361,15 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
console.log('response', response)
if (response.data.status.success) {
setRequestTask(response.data.data)
message.success(`添加计划${response.data.data.name}成功`)
// 树任务重新刷新
// 四象限任务重新刷新
// 如果可以直接更新列表而不请求。。。。。。
console.log('props.reloadData?.()', props.reloadData)
result = (taskType != '1')
setRequestTask(undefined)
form.resetFields()
if(result){
initData()
}
props.reloadData?.()
} else {
message.error(response.data.status.message)
@ -310,6 +378,12 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
}
);
}
setDefaultPTask({
pid: '0',
pName: undefined,
fId: undefined,
fName: undefined,
})
setOperationRequest(false)
return result;
}}
@ -322,7 +396,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
required={true}
options={TASK_TYPE.map(task =>
(task.value == '1' && (requestTask?.id)) ? {...task, disabled: true} : task)}
// (task.value == '1' ) ? {...task, disabled: true} : task)}
// (task.value == '1' ) ? {...task, disabled: true} : task)}
width="sm"
name="taskType"
label="任务类型"
@ -353,12 +427,13 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
<ProFormTreeSelect
hidden={taskType == '1'}
width="sm"
initialValue={defaultPTask.pName}
request={() => {
return getTaskTreeResult(JSON.stringify(
{
pageSize: 1000,
pageNumber: 1,
data: [{code: 'pid', value: '0', operateType: '='},
data: [{code: 'pid', value: defaultPTask.pid, operateType: '='},
// 如果父任务完成会导致父任务不展示
// {
// code: 'state',
@ -374,8 +449,21 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
fieldProps={{
onSelect: (e, node) => {
console.log('onSelect', e, node);
// setPid(e)
setDefaultPTask(pTaskMap?.[e] || {
pid: '0',
pName: undefined,
fId: undefined,
fName: undefined,
})
},
onClear: () => {
setDefaultPTask({
pid: '0',
pName: undefined,
fId: undefined,
fName: undefined,
})
}
}}
disabled={editFormDisable}
/>
@ -406,52 +494,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
placeholder="请输入任务描述"
disabled={editFormDisable}
/>
<div className={style.localDiv}>
<Space wrap>
<text>:</text>
<Select
style={{width: 120}}
allowClear
// defaultValue={onceConsumeChange[0]}
onChange={(value) => {
}}
options={[{label: "期望开始",
value: "expect_start",},{label: "期望结束",
value: "expect_end",}
]}
/>
<Select
style={{width: 120}}
allowClear
// defaultValue={onceConsumeChange[0]}
onChange={(value) => {
}}
options={[{label: "前",
value: "before",},{label: "后",
value: "after",}
]}
/>
<Select
style={{width: 120}}
allowClear
onChange={(value) => {
}}
options={onceConsumeList}
/>
<Select
style={{width: 120}}
allowClear
// defaultValue={onceConsumeChange[1]}
onChange={(value) => {
}}
options={[{label: "分钟", value: "m"}, {label: "小时", value: "h"}, {
label: "天",
value: "d"
}]}
/>
</Space>
</div>
<TaskRemindComponent remindTypeList={remindTypeList} setRemindTypeList={(a:string[])=>setRemindTypeList(a)} readonly={editFormDisable} />
<ProForm.Group>
<ProFormSelect
request={async () =>
@ -520,7 +563,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
{taskType == "3" &&
<Fragment>
{editFormDisable ?
<div className={style.localDiv} >
<div className={style.localDiv}>
<text>:{onceConsumerRead(requestTask?.onceConsume)}</text>
</div> :
<div className={style.localDiv}>

View File

@ -156,7 +156,9 @@ const TreeTablePro: React.FC = (props:{joinId?:string}) => {
key: 'option',
title: '操作',
valueType: 'option',
render: (_, record) => <OperationButton itemId={record.id} itemName={record.name} pid={record.pid} pPid={record.pPid}
render: (_, record) => <OperationButton itemId={record.id} itemName={record.name}
fId={record.fId} fName={record.fName}
pid={record.pid} pPid={record.pPid}
priority={record.priority}
refreshDate={() => {
actionRef.current?.reload(false);