feat:添加新增

This commit is contained in:
shixiaohua 2024-04-24 13:54:59 +08:00
parent a55e567899
commit 2b7bb13c83
13 changed files with 228 additions and 187 deletions

View File

@ -209,21 +209,21 @@ export const taskStateList: DictType[] = [
code: '7', code: '7',
name: '完成', name: '完成',
order: 7, order: 7,
color: 'red' color: 'GREEN'
}, },
{ {
id: 8, id: 8,
code: '8', code: '8',
name: '新建', name: '新建',
order: 8, order: 8,
color: 'red' color: 'RED'
}, },
{ {
id: 9, id: 9,
code: '9', code: '9',
name: '进行中', name: '进行中',
order: 9, order: 9,
color: 'red' color: 'YELLOW'
} }
] ]
export enum OPERATION_BUTTON_TYPE { export enum OPERATION_BUTTON_TYPE {

View File

@ -1,6 +1,6 @@
'use client' 'use client'
import SideNav from '@/app/ui/dashboard/sidenav'; import SideNav from '@/app/ui/dashboard/sidenav';
import TreeTable from "@/app/ui/task/project/TreeTable"; import TreeTable from "@/app/ui/task/four/TreeTable";
import '@/app/ui/task/four/index.modules.css' import '@/app/ui/task/four/index.modules.css'
import {useContext, useEffect} from "react"; import {useContext, useEffect} from "react";
import LocalContext from "@/app/ui/LocalContent"; import LocalContext from "@/app/ui/LocalContent";

View File

@ -1,7 +1,7 @@
'use client' 'use client'
import React from "react"; import React from "react";
import {TitleOperation} from "@/app/ui/task/TitleOperation"; import {TitleOperation} from "@/app/ui/task/TitleOperation";
import LocalContext from "../ui/LocalContent"; import LocalContext from "@/app/ui/LocalContent";
import dayjs from "dayjs"; import dayjs from "dayjs";
export default function Layout({children}: { children: React.ReactNode }) { export default function Layout({children}: { children: React.ReactNode }) {

View File

@ -1,12 +0,0 @@
import TreeTable from "@/app/ui/task/project/TreeTable";
import TreeTablePro from "@/app/ui/task/project/TreeTablePro";
const Page: React.FC = () => {
return (
<>
<TreeTable/>
</>
);
};
export default Page;

View File

@ -1,4 +1,4 @@
import TreeTable from "@/app/ui/task/project/TreeTable"; import TreeTable from "@/app/ui/task/four/TreeTable";
import TreeTablePro from "@/app/ui/task/project/TreeTablePro"; import TreeTablePro from "@/app/ui/task/project/TreeTablePro";
const Page: React.FC = () => { const Page: React.FC = () => {

View File

@ -1,10 +1,6 @@
'use client' 'use client'
import {Button, Col, Form, Input, Row, Select, Space, theme} from "antd"; import {Button, Col, Form, Input, Row, Select, Space, theme} from "antd";
import React, {useState} from "react"; import React, {useState} from "react";
import {DownOutlined} from "@ant-design/icons";
import {OperationButtonProps} from "@/app/ui/task/project/OperationButton";
import {Span} from "next/dist/server/lib/trace/tracer";
import CustomSearchForm from "@/app/ui/task/CustomSearchForm";
const AdvancedSearchForm = () => { const AdvancedSearchForm = () => {
const { token } = theme.useToken(); const { token } = theme.useToken();

View File

@ -1,7 +1,7 @@
import React, {Fragment} from "react"; import React, {Fragment} from "react";
import {Button, Dropdown, MenuProps, message, Modal, Popconfirm, Space} from "antd"; import {Button, Dropdown, MenuProps, message, Modal, Popconfirm, Space} from "antd";
import {DownOutlined, QuestionCircleOutlined} from "@ant-design/icons"; import {DownOutlined, QuestionCircleOutlined} from "@ant-design/icons";
import {DetailForm} from "@/app/ui/task/project/DetailForm"; import {DetailForm} from "@/app/ui/task/four/DetailForm";
import {deleteTask, OPERATION_BUTTON_TYPE} from "@/app/lib/task/project/data"; import {deleteTask, OPERATION_BUTTON_TYPE} from "@/app/lib/task/project/data";
import Link from "next/link"; import Link from "next/link";

View File

@ -3,89 +3,80 @@ import {Button, DatePicker, Flex, Select, Space} from "antd";
import {usePathname, useRouter} from "next/navigation"; import {usePathname, useRouter} from "next/navigation";
import {DetailModelForm} from "@/app/ui/task/project/DetailModelForm"; import {DetailModelForm} from "@/app/ui/task/project/DetailModelForm";
import {OPERATION_BUTTON_TYPE, taskStateList} from "@/app/lib/task/project/data"; import {OPERATION_BUTTON_TYPE, taskStateList} from "@/app/lib/task/project/data";
import './TitleOperation.modules.css' import '@/app/ui/task/TitleOperation.modules.css'
import dayjs from "dayjs"; import dayjs from "dayjs";
interface TitleOperationProps { interface TitleOperationProps {
setTaskState: (value: string) => void; setTaskState: (value: string) => void;
setExpectedStartTime:(value:string)=>void; setExpectedStartTime: (value: string) => void;
} }
export const TitleOperation: React.FC<TitleOperationProps> = ({setTaskState,setExpectedStartTime}: TitleOperationProps) => { export const TitleOperation: React.FC<TitleOperationProps> = ({
setTaskState,
setExpectedStartTime
}: TitleOperationProps) => {
const {replace} = useRouter(); const {replace} = useRouter();
const [currentPath, setCurrentPath] = React.useState(usePathname()); const [currentPath, setCurrentPath] = React.useState(usePathname());
const {RangePicker} = DatePicker; const {RangePicker} = DatePicker;
return <Space style={{marginTop:0}}> return <Space style={{marginTop: 0}}>
<DetailModelForm operationId={OPERATION_BUTTON_TYPE.ADD} description='添加主线任务'/> <DetailModelForm operationId={OPERATION_BUTTON_TYPE.ADD} description='添加主线任务'/>
{currentPath.startsWith("/task/project") ? {currentPath.startsWith("/task/project") ?
<> <>
<Button type="primary" onClick={() => { <Button type="primary" onClick={() => {
replace("/task/four"); replace("/task/four");
setCurrentPath("/task/four"); setCurrentPath("/task/four");
}}></Button> }}></Button>
<Button type="primary" onClick={() => { </> : <>
replace("/task/list"); <Button type="primary" onClick={() => {
setCurrentPath("/task/list"); replace("/task/project");
}}></Button> setCurrentPath("/task/project")
</> : }}></Button>
currentPath.startsWith("/task/list") ? <span style={{whiteSpace: 'nowrap'}}>:</span>
<> <Select
<Button type="primary" onClick={() => { mode="multiple"
replace("/task/project"); allowClear
setCurrentPath("/task/project") style={{minWidth: '100px'}}
}}></Button> placeholder="任务状态"
<Button type="primary" onClick={() => { defaultValue={['8', '9']}
replace("/task/four"); onChange={(value) => {
setCurrentPath("/task/four"); console.log('onChange')
}}></Button> setTaskState(value.join(','))
</> : <> }}
<Button type="primary" onClick={() => { options={taskStateList.map(item => {
replace("/task/project"); return {label: item.name, value: item.code}
setCurrentPath("/task/project"); })}
}}></Button>
<Button type="primary" onClick={() => {
replace("/task/list");
setCurrentPath("/task/list");
}}></Button>
</>
}
{/*<AdvancedSearchForm/>*/}
<span style={{whiteSpace: 'nowrap'}}>:</span>
<Select
mode="multiple"
allowClear
style={{minWidth: '100px'}}
placeholder="任务状态"
defaultValue={['8', '9']}
onChange={(value) => {
console.log('onChange')
setTaskState(value.join(','))
}}
options={taskStateList.map(item => {
return {label: item.name, value: item.code}
})}
/>
<span style={{whiteSpace: 'nowrap'}}>:</span>
<RangePicker
placeholder={['开始时间','结束时间']}
defaultValue={[dayjs().subtract(7,'day'),dayjs().add(7,'day')]}
allowEmpty={[true, true]}
onChange={(dates, dateStrings)=>{
console.log('onChange:',dates,dateStrings);
if(!dates){
setExpectedStartTime('')
return
}
let expectStartTimeList=[];
if (dates[0]) {
expectStartTimeList.push({'name':"expectedStartTime",'value':dates[0],'operateType':">="});
}
if (dates[1]) {
expectStartTimeList.push({'name':"expectedStartTime",'value':dates[1].add(1,'day'),'operateType':"<"})
}
setExpectedStartTime(JSON.stringify(expectStartTimeList))
}}
/> />
</Space> <span style={{whiteSpace: 'nowrap'}}>:</span>
{/*</Flex>*/} <RangePicker
placeholder={['开始时间', '结束时间']}
defaultValue={[dayjs().subtract(7, 'day'), dayjs().add(7, 'day')]}
allowEmpty={[true, true]}
onChange={(dates, dateStrings) => {
console.log('onChange:', dates, dateStrings);
if (!dates) {
setExpectedStartTime('')
return
}
let expectStartTimeList = [];
if (dates[0]) {
expectStartTimeList.push({
'name': "expectedStartTime",
'value': dates[0],
'operateType': ">="
});
}
if (dates[1]) {
expectStartTimeList.push({
'name': "expectedStartTime",
'value': dates[1].add(1, 'day'),
'operateType': "<"
})
}
setExpectedStartTime(JSON.stringify(expectStartTimeList))
}}
/>
</>
}
</Space>
} }

View File

@ -1,6 +1,6 @@
'use client' 'use client'
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import '@/app/ui/task/project/detailForm.modules.css' import '@/app/ui/task/four/detailForm.modules.css'
import {PlusOutlined} from '@ant-design/icons'; import {PlusOutlined} from '@ant-design/icons';
import { import {
Button, Button,

View File

@ -4,9 +4,9 @@ import {ConfigProvider, Table} from 'antd';
import type {TableColumnsType, TableProps} from 'antd'; import type {TableColumnsType, TableProps} from 'antd';
import {getTaskTreeResult, taskPriorityList, taskStateList, taskTreeResult} from "@/app/lib/task/project/data"; import {getTaskTreeResult, taskPriorityList, taskStateList, taskTreeResult} from "@/app/lib/task/project/data";
import {DataType, ResponseVO, ResultPage} from "@/app/lib/definitions"; import {DataType, ResponseVO, ResultPage} from "@/app/lib/definitions";
import OperationButton from "@/app/ui/task/project/OperationButton"; import OperationButton from "@/app/ui/task/OperationButton";
import dayjs from "dayjs"; import dayjs from "dayjs";
import "@/app/ui/task/project/detailForm.modules.css" import "@/app/ui/task/four/detailForm.modules.css"
type TableRowSelection<T> = TableProps<T>['rowSelection']; type TableRowSelection<T> = TableProps<T>['rowSelection'];
@ -113,7 +113,6 @@ const TreeTable: React.FC<TableSearchType> = (props) => {
} }
}) })
} }
console.log('taskPriorityList.find((item)=>item.code===props.priority)?.color',props.priority,taskPriorityList.find((item)=>item.code===props.search.priority)?.color)
useEffect(() => { useEffect(() => {
refreshDate(); refreshDate();
}, [props.search]); }, [props.search]);

View File

@ -4,12 +4,13 @@ import {
ProForm, ProForm,
ProFormDateRangePicker, ProFormDateRangePicker,
ProFormSelect, ProFormSelect,
ProFormText, ProFormText, ProFormTextArea, ProFormTreeSelect,
} from '@ant-design/pro-components'; } from '@ant-design/pro-components';
import { Button, Form, message } from 'antd'; import { Button, Form, message } from 'antd';
import React from "react"; import React from "react";
import {DetailFormProps} from "@/app/ui/task/project/DetailForm"; import {getTaskTreeResult, OPERATION_BUTTON_TYPE, taskPriorityList, taskStateList} from "@/app/lib/task/project/data";
import {OPERATION_BUTTON_TYPE} from "@/app/lib/task/project/data"; import {DataType} from "@/app/lib/definitions";
import {string} from "prop-types";
const waitTime = (time: number = 100) => { const waitTime = (time: number = 100) => {
return new Promise((resolve) => { return new Promise((resolve) => {
@ -25,14 +26,22 @@ export type DetailModelFormProps={
description:string, description:string,
handleCancel?: () => void handleCancel?: () => void
} }
export type PidSelectTree= { label: string; value: number; children?: PidSelectTree[] }
export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => { export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
const [form] = Form.useForm<{ name: string; company: string }>(); const [form] = Form.useForm<DataType>();
function childReduce(child:DataType[]):PidSelectTree[]{
const result:PidSelectTree[] = [];
child.map(data=> {
const resultData:PidSelectTree = {label:data.name,value:data.id};
if (data.children){
resultData.children=childReduce(data.children);
}
result.push(resultData);
})
return result;
}
return ( return (
<ModalForm<{ <ModalForm<DataType>
name: string;
company: string;
}>
title={ title={
props.operationId === OPERATION_BUTTON_TYPE.DETAIL ? "任务详情": props.operationId === OPERATION_BUTTON_TYPE.DETAIL ? "任务详情":
props.operationId === OPERATION_BUTTON_TYPE.ADD?"添加任务": props.operationId === OPERATION_BUTTON_TYPE.ADD?"添加任务":
@ -50,7 +59,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
destroyOnClose: true, destroyOnClose: true,
onCancel: () => console.log('run'), onCancel: () => console.log('run'),
}} }}
submitTimeout={2000} // submitTimeout={2000}
onFinish={async (values) => { onFinish={async (values) => {
await waitTime(2000); await waitTime(2000);
console.log(values.name); console.log(values.name);
@ -58,69 +67,79 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
return true; return true;
}} }}
> >
<ProFormText width="sm" name="id" hidden={true} label="主键" />
<ProFormText width="sm" name="code" hidden={true} label="任务编码" />
<ProFormText width="sm" name="pPid" hidden={true} label="祖宗id" />
<ProForm.Group> <ProForm.Group>
<ProFormTreeSelect
width="md"
request={() =>{
return getTaskTreeResult(JSON.stringify(
{pageSize:1000,pageNumber:1,data:[{code:'pid',value:'0',operateType:'='},{code:'',value:true,operateType: "TREE"}]}
)).then(result=> childReduce(result.data.content))
}}
name="pid"
label="父级任务"
disabled ={props.operationId === OPERATION_BUTTON_TYPE.DETAIL}
/>
<ProFormText <ProFormText
width="md" width="md"
name="name" name="name"
label="签约客户名称" label="任务名称"
tooltip="最长为 24 位" tooltip="最长为 24 位"
placeholder="请输入名称" placeholder="请输入任务名称"
disabled ={props.operationId === OPERATION_BUTTON_TYPE.DETAIL}
/> />
</ProForm.Group>
<ProFormTextArea
// width="md"
name="description"
label="任务描述"
// tooltip="最长为 24 位"
placeholder="请输入任务描述"
disabled ={props.operationId === OPERATION_BUTTON_TYPE.DETAIL}
/>
<ProFormText
width="md"
name="company"
label="我方公司名称"
placeholder="请输入名称"
/>
</ProForm.Group>
<ProForm.Group>
<ProFormText
width="md"
name="contract"
label="合同名称"
placeholder="请输入名称"
/>
<ProFormDateRangePicker name="contractTime" label="合同生效时间" />
</ProForm.Group>
<ProForm.Group> <ProForm.Group>
<ProFormSelect <ProFormSelect
request={async () => [ request={async () => taskPriorityList.map(taskState => {
{ return {
value: 'chapter', 'label': taskState.name,
label: '盖章后生效', 'value': taskState.code
}, }
]} })}
width="xs" width="sm"
name="useMode" name="priority"
label="合同约定生效方式" label="任务优先级"
disabled ={props.operationId === OPERATION_BUTTON_TYPE.DETAIL}
/> />
<ProFormSelect <ProFormSelect
width="xs" width="sm"
options={[ options={taskStateList.map(taskState => {
{ return {
value: 'time', 'label': taskState.name,
label: '履行完终止', 'value': taskState.code
}, }
]} })}
name="unusedMode" name="state"
label="合同约定失效效方式" label="任务状态"
disabled ={props.operationId === OPERATION_BUTTON_TYPE.DETAIL}
/> />
</ProForm.Group> </ProForm.Group>
<ProFormText width="sm" name="id" label="主合同编号" />
<ProFormText <ProForm.Group>
name="project" <ProFormDateRangePicker
disabled name="expectedTimeRange"
label="项目名称" label="期望时间"
initialValue="xxxx项目" disabled ={props.operationId === OPERATION_BUTTON_TYPE.DETAIL}
/> />
<ProFormText <ProFormDateRangePicker
width="xs" name="actualTimeRange"
name="mangerName" label="实际时间"
disabled disabled ={props.operationId === OPERATION_BUTTON_TYPE.DETAIL}
label="商务经理" />
initialValue="启途" </ProForm.Group>
/>
</ModalForm> </ModalForm>
); );
}; };

View File

@ -1,12 +1,19 @@
'use client' 'use client'
import {EllipsisOutlined, PlusOutlined} from '@ant-design/icons'; import {CheckSquareFilled, EllipsisOutlined, HeartFilled, HeartOutlined, PlusOutlined} from '@ant-design/icons';
import type {ActionType, ProColumns} from '@ant-design/pro-components'; import type {ActionType, ProColumns} from '@ant-design/pro-components';
import {ProTable, TableDropdown} from '@ant-design/pro-components'; import {ProTable, TableDropdown} from '@ant-design/pro-components';
import {Button, Dropdown, Space, Tag} from 'antd'; import {Button, Dropdown, Space, Switch, Tag} from 'antd';
import React, {useRef} from 'react'; import React, {useRef} from 'react';
import {DataType} from "@/app/lib/definitions"; import {DataType} from "@/app/lib/definitions";
import {OPERATION_BUTTON_TYPE, taskPriorityList, taskStateList, taskTreeResult} from "@/app/lib/task/project/data"; import {
getTaskTreeResult,
OPERATION_BUTTON_TYPE,
taskPriorityList,
taskStateList,
taskTreeResult
} from "@/app/lib/task/project/data";
import {DetailModelForm} from "@/app/ui/task/project/DetailModelForm"; import {DetailModelForm} from "@/app/ui/task/project/DetailModelForm";
import OperationButton from "@/app/ui/task/OperationButton";
const columns: ProColumns<DataType>[] = [ const columns: ProColumns<DataType>[] = [
{ {
@ -43,16 +50,21 @@ const columns: ProColumns<DataType>[] = [
return {label: item.name, value: item.code} return {label: item.name, value: item.code}
}) })
}, },
// renderFormItem: (_, { defaultRender }) => { renderFormItem: (_, { defaultRender }) => {
// return defaultRender(_); return defaultRender(_);
// }, },
render: (_, record) => ( render: (_, record) => (
<Space> <Space>
{ {
<Tag color={taskPriorityList.find(item => item.code === record.priority?.toString())?.color} // <Tag color={taskPriorityList.find(item => item.code === record.priority?.toString())?.color}
key={taskPriorityList.find(item => item.code === record.priority?.toString())?.code}> // key={taskPriorityList.find(item => item.code === record.priority?.toString())?.code}>
// {taskPriorityList.find(item => item.code === record.priority?.toString())?.name}
// </Tag>
<div>
{/*< HeartFilled/>*/}
<CheckSquareFilled style={{color:taskPriorityList.find(item => item.code === record.priority?.toString())?.color}}/>
{taskPriorityList.find(item => item.code === record.priority?.toString())?.name} {taskPriorityList.find(item => item.code === record.priority?.toString())?.name}
</Tag> </div>
} }
</Space> </Space>
), ),
@ -61,7 +73,10 @@ const columns: ProColumns<DataType>[] = [
title: '任务状态', title: '任务状态',
dataIndex: 'state', dataIndex: 'state',
valueType: 'select', valueType: 'select',
initialValue:['8','9'],
fieldProps: { fieldProps: {
defaultValue:['8','9'],
mode:"tags",
options: taskStateList.map(item => { options: taskStateList.map(item => {
return {label: item.name, value: item.code} return {label: item.name, value: item.code}
}) })
@ -69,16 +84,16 @@ const columns: ProColumns<DataType>[] = [
// renderFormItem: (_, { defaultRender }) => { // renderFormItem: (_, { defaultRender }) => {
// return defaultRender(_); // return defaultRender(_);
// }, // },
render: (_, record) => ( // render: (_, record) => (
<Space> // <Space>
{ // {
<Tag color={taskStateList.find(item => item.code === record.state?.toString())?.color} // <Tag color={taskStateList.find(item => item.code === record.state?.toString())?.color}
key={taskStateList.find(item => item.code === record.state?.toString())?.code}> // key={taskStateList.find(item => item.code === record.state?.toString())?.code}>
{taskStateList.find(item => item.code === record.state?.toString())?.name} // {taskStateList.find(item => item.code === record.state?.toString())?.name}
</Tag> // </Tag>
} // }
</Space> // </Space>
), // ),
}, },
{ {
title: '期望开始时间', title: '期望开始时间',
@ -100,22 +115,53 @@ const columns: ProColumns<DataType>[] = [
dataIndex: 'actualEndTime', dataIndex: 'actualEndTime',
valueType: 'date', valueType: 'date',
}, },
{
title: '操作',
key: 'option',
valueType: 'option',
render: (_, record) => <OperationButton itemId={record.id} pid={record.pid} pPid={record.pPid} refreshDate={()=>{}}/>,
}
]; ];
const TreeTablePro: React.FC = () => { const TreeTablePro: React.FC = () => {
// const actionRef = useRef<ActionType>(); const actionRef = useRef<ActionType>();
const [switchChecked, setSwitchChecked] = React.useState(true);
return ( return (
<ProTable<DataType> <ProTable<DataType>
columns={columns} columns={columns}
// actionRef={actionRef} actionRef={actionRef}
cardBordered cardBordered
request={async (params, sort, filter) => { request={async (params, sort, filter) => {
console.log('request',params,sort, filter); console.log('request',params,params.keyword,sort, filter);
const response = await taskTreeResult() const searchList=[]
if (switchChecked) {
searchList.push({name:'pid',value:'0',operateType:"="},{name:'tree',value:'TRUE',operateType:"TREE"})
}
if (params.state){
searchList.push({name:'state',value:params.state.join(','),operateType:"IN"})
}
if (params.priority){
searchList.push({name:'priority',value:params.priority.join(','),operateType:"IN"})
}
if (params.name){
searchList.push({name:'name',value:params.name,operateType:"LIKE"})
}
if (params.description){
searchList.push({name:'description',value:params.description,operateType:"LIKE"})
}
if (params.code){
searchList.push({name:'code',value:params.code,operateType:"="})
}
let request = JSON.stringify({
pageSize:params.pageSize,
pageNumber:params.current,
data: searchList
})
const response = await getTaskTreeResult(request)
return { return {
data: response.data.content, data: response.data.content,
success: response.status.success, success: response.status.success,
total :response.data.totalElements,
} }
}} }}
editable={{ editable={{
@ -137,9 +183,11 @@ const TreeTablePro: React.FC = () => {
onChange: (page) => console.log(page), onChange: (page) => console.log(page),
}} }}
dateFormatter="string" dateFormatter="string"
headerTitle="任务管理" // headerTitle="任务管理"
toolBarRender={() => [ toolBarRender={() => [
<DetailModelForm operationId={OPERATION_BUTTON_TYPE.ADD} description='添加主线任务'/>, <DetailModelForm operationId={OPERATION_BUTTON_TYPE.ADD} description='添加主线任务'/>,
<Switch checkedChildren="树" unCheckedChildren="列表" checked={switchChecked}
onChange={(checked, event) => {setSwitchChecked(checked);actionRef.current?.reload();}} />
]}></ProTable> ]}></ProTable>
); );
}; };