期限释放问题列表 - 项目管理系统
<div id="root"></div>
<script>
import React, { useEffect, useState } from 'react';
import type { ProSelectProps, Params, RequestDate } from './interface';
import { Select, Spin } from 'antd';
import { debounce } from 'lodash';
<p>const ProSelect: React.FC<ProSelectProps> = ({ request, style = { width: 300 }, ...props }) => {
const [optionsData, setOptionsData] = useState<RequestDate>({
data: [],
total: 0,
});
const [pageOption, setPageOption] = useState<Params>({
pageSize: 20,
current: 1,
keyWord: '',
});
const [loadding, setLoadding] = useState<boolean>(false);</p>
<pre><code>const handlePopupScroll: React.UIEventHandler<HTMLDivElement> = (e) => {
const { scrollTop, scrollHeight, clientHeight } = e.target as HTMLElement;
const isScrollEnd = scrollHeight - scrollTop === clientHeight;
if (isScrollEnd && optionsData && optionsData.data.length < optionsData?.total) {
setPageOption((prePageOptions) => {
return {
...prePageOptions,
current: prePageOptions.current + 1,
};
});
}
};
const handelSearch = debounce((keyWord: string) => {
setPageOption({
pageSize: 20,
current: 1,
keyWord,
});
setOptionsData({
data: [],
total: 0,
});
}, 800);
useEffect(() => {
if (request) {
setLoadding(true);
request({ ...pageOption }).then((res) => {
setLoadding(false);
setOptionsData((preOptions) => {
return {
data: [...preOptions.data, ...res.data],
success: true,
total: res.total,
};
});
});
}
}, [pageOption, request]);
return (
<Select
{...props}
options={props.options || optionsData.data}
onPopupScroll={handlePopupScroll}
notFoundContent={loadding ? <Spin size="small" /> : null}
style={style}
filterOption={false}
onSearch={handelSearch}
showSearch
/>
);
</code></pre>
<p>};</p>
<p>export default React.memo(ProSelect);
import { PageContainer } from '@ant-design/pro-layout';
import type { ProColumns } from '@ant-design/pro-table';
import ProCard from '@/components/ProCard';
import ProTable from '@ant-design/pro-table';
import { Typography, Radio } from 'antd';
import React, { useEffect, useState } from 'react';
import ContentCard from '@/components/ContentCard';
import {
getProjectMilepostList,
getDropdownPage,
sapUserCentAndDept,
} from '@/services/project/kanban/index';
import { history } from 'umi';
import './index.less';
import { isArray } from 'lodash';
import ProSelect from '@/components/ProSelect';</p>
<p>const { Link } = Typography;
interface NodeItems {
[x: string]: any;
id: number;
projectId: string;
projectName: string;
spmUserName: string;
summary: string;
assignee: string;
dep: string;
issueStatus: string;
dueDate: string;
timeEnding1: string;
delayDays: string;
keyWord: string;
issueLink: string;
}
let day = 0;
let days = 0;</p>
<p>const DeparmentDiList: React.FC = () => {
const [radioValue, setRadioValue] = useState<boolean>(false);
const [deptData, setDeptData] = useState([]);
const [deadlineList, setDeadlineList] = useState({});
const [projectList, setProjectList] = useState<{ name: string; code: string }[]>([]);
const [searchData, setSearchData] = useState({
pagination: { current: 1, size: 10, totals: 0 },
searchValue: '',
});</p>
<pre><code>const {
pagination: { current, size, totals },
searchValue,
} = searchData;
// const getDropdownPages = async () => {
// // 页码,及搜索值变化时,发请求
// const params = {
// current,
// size,
// keyword: searchValue,
// kanbanDropdownType: 'SPM_ROLE',
// };
// const { data } = await getDropdownPage(params);
// setProjectList((preOptions) => {
// return [...preOptions, ...data.records];
// });
// setSearchData({
// ...searchData,
// pagination: {
// current: data.current,
// totals: data.total,
// size: data.size,
// },
// });
// };
</code></pre>
<p>const getDropdownPages=async()=>{
const { data } = await getDropdownPage({ kanbanDropdownType: 'SPM_ROLE',});
setProjectList((preOptions) => {
return [...preOptions, ...data.records];
});
}
useEffect(() => {
getDropdownPages();</p>
<pre><code>}, []);
useEffect(() => {
const scrollEnd: React.UIEventHandler<HTMLElement> = (e) => {
e.persist();
const { target } = e;
// 滚动 触底 看接口是否还有剩余的值没传过来
if (
(target as HTMLElement).scrollTop + (target as HTMLElement).offsetHeight ===
(target as HTMLElement).scrollHeight
) {
if (current * size < totals) {
setSearchData({
...searchData,
pagination: {
...searchData.pagination,
current: current + 1,
},
});
}
}
};
document.getElementById('table-container')?.addEventListener('scroll', scrollEnd);
return () => {
document.getElementById('table-container')?.removeEventListener('scroll', scrollEnd);
};
}, [current, size, totals, searchData.searchValue]);
const columns: ProColumns<NodeItems>[] = [
{
title: '序号',
width: 50,
dataIndex: 'index',
align: 'center',
valueType: 'index',
},
{
title: '项目ID',
dataIndex: 'projectId',
align: 'center',
hideInSearch: true,
width: 60,
},
{
title: '项目名称',
dataIndex: 'projectName',
align: 'center',
width: 300,
hideInSearch: true,
render: (_, record) => (
<div style={{ textAlign: 'left' }}>
<Link
onClick={() => history.push(`/project/operation/home?projectId=${record.projectId}`)}
>
{record.projectName}
</Link>
</div>
),
},
{
title: '业务中心',
dataIndex: 'cent',
valueType: 'select',
hideInTable: true,
request: async () => {
const { data } = await sapUserCentAndDept({});
if (!isArray(data)) throw new Error('');
const centerData = data.map((item: any) => {
const childrenCenter = (item.deptList || []).map((child: any) => {
return {
label: child,
value: `${child}`,
};
});
return {
label: item.cent,
value: `${item.cent}`,
childrenCenter,
};
});
return centerData;
},
fieldProps: {
showSearch: true,
fieldNames: {
label: 'label',
value: 'value',
},
onChange: (val: any, option: any) => {
if (val) {
const deparSlect = option.childrenCenter.filter((item: any) => item.label);
setDeptData(deparSlect);
} else {
setDeptData([]);
}
},
},
},
{
title: '所在部门',
dataIndex: 'dep',
align: 'center',
valueType: 'select',
fieldProps: { options: deptData },
width: 110,
render: (_, record) => {
return <span>{`${record.cent}/${record.dep}`}</span>;
},
},
{
title: 'SPM',
dataIndex: 'spmUserName',
align: 'center',
valueType: 'select',
width: 60,
// request: async () => {
// const { data } = await getDropdownPage({ kanbanDropdownType: 'SPM_ROLE' });
// return data.records;
// },
fieldProps: {
showSearch: true,
fieldNames: {
label: 'name',
value: 'code',
},
// options: projectList,
// filterOption: true,
// onPopupScroll: scrollEnd,
},
renderFormItem: () => {
return <ProSelect options={projectList} />;
},
},
{
title: 'Bug概要',
dataIndex: 'summary',
align: 'center',
width: 400,
hideInSearch: true,
render: (record, rowRecord) => {
return (
<div style={{ textAlign: 'left' }}>
<Link href={rowRecord.issueLink} target={'_blank'}>
{record}
</Link>
</div>
);
},
},
{
title: '关键字',
dataIndex: 'issueKey',
align: 'center',
valueType: 'select',
width: 100,
request: async () => {
const { data } = await getDropdownPage({ kanbanDropdownType: 'ISSUE_KEY' });
return data.records;
},
fieldProps: {
showSearch: true,
fieldNames: {
label: 'name',
value: 'code',
},
},
},
{
title: '经办人',
dataIndex: 'assignee',
align: 'center',
hideInSearch: true,
valueType: 'select',
width: 60,
},
{
title: '状态',
dataIndex: 'issueStatus',
align: 'center',
hideInSearch: true,
width: 80,
},
{
title: '到期时间',
dataIndex: 'dueDate',
align: 'center',
width: 90,
hideInSearch: true,
render: (_, record) => {
return <span>{record.dueDate}</span>;
},
},
{
title: '倒计时(天)',
dataIndex: 'timeEnding1',
align: 'center',
hideInSearch: true,
width: 90,
render: (_, record) => {
if (record && record?.dueDate) {
const setTime = new Date(record?.dueDate as any);
const nowTime = new Date();
const restSec: any = setTime.getTime() - nowTime.getTime();
day = parseInt((restSec / (60 * 60 * 24 * 1000)) as any);
}
return <span>{record?.dueDate ? day : '-'}</span>;
},
},
{
title: '延期天数',
dataIndex: 'delayDays',
align: 'center',
hideInSearch: true,
width: 80,
render: (_, record) => {
if (record && record?.dueDate) {
const setTime = new Date(record?.dueDate as any);
const nowTime = new Date();
const restSec: any = nowTime.getTime() - setTime.getTime();
days = parseInt((restSec / (60 * 60 * 24 * 1000)) as any);
}
return <span>{record?.dueDate ? days : '-'}</span>;
},
},
{
title: '项目',
dataIndex: 'projectId',
align: 'center',
valueType: 'select',
hideInTable: true,
request: async () => {
const { data } = await getDropdownPage({ kanbanDropdownType: 'PROJECT_INFO' });
return data.records;
},
fieldProps: {
showSearch: true,
fieldNames: {
label: 'name',
value: 'code',
},
},
},
// {
// title: '区域',
// dataIndex: 'regison',
// align: 'center',
// valueType: 'select',
// hideInTable: true,
// },
];
const radioChange = (e: any) => {
setRadioValue(e.target.value);
setDeadlineList({ solveFlag: e.target.value });
};
return (
<PageContainer className="pageNodes">
<ProCard>
<ContentCard title={'期限释放问题'}>
<div className="TableStyle" id="table-container">
<ProTable
rowKey={'id'}
className="nodeLists"
columns={columns}
options={false}
bordered
scroll={{ y: 'calc(100vh - 366px)', x: 'max-content' }}
search={{
labelWidth: 100,
}}
pagination={{
pageSize: 10,
showSizeChanger: false,
}}
headerTitle={
<div className="deadline-bug">
<div className="table-radio-box">
<Radio.Group
defaultValue={radioValue}
buttonStyle="solid"
onChange={radioChange}
>
<Radio.Button value={false}>未解决</Radio.Button>
<Radio.Button value={true}>已解决</Radio.Button>
</Radio.Group>
</div>
</div>
}
params={deadlineList}
request={async (params) => {
const { keyword } = params;
try {
delete params.pageSize;
const {
data: { total, records },
} = await getProjectMilepostList({
...params,
current: params.current || 1,
size: params.pageSize || 10,
solveFlag: radioValue,
keyword,
});
return {
success: true,
data: records,
total,
};
} catch (error) {
return { success: false };
}
}}
/>
</div>
</ContentCard>
</ProCard>
</PageContainer>
);
</code></pre>
<p>};
export default DeparmentDiList;
</script></p>
原文地址: https://www.cveoy.top/t/topic/orYa 著作权归作者所有。请勿转载和采集!