TaskList.tsx 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. import PageContent from '@/components/PageContent';
  2. import PageTitle from '@/components/PageTitle';
  3. import {
  4. IPropsType,
  5. ITopFilter,
  6. IUserType,
  7. } from '@/pages/TaskManage/Detail/TaskList/taskList.types';
  8. import {
  9. MandateClass,
  10. MandateStatus,
  11. MandateType,
  12. OrderStatus,
  13. OrderType,
  14. } from '@/pages/TaskManage/constent';
  15. import { connect, useLocation, useRequest } from '@umijs/max';
  16. import TopFilter from '@/pages/TaskManage/components/TopFilter';
  17. import { IMandateType } from '@/pages/TaskManage/index.types';
  18. import { useNavigate } from '@@/exports';
  19. import { DownOutlined } from '@ant-design/icons';
  20. import {
  21. Button,
  22. Col,
  23. Collapse,
  24. CollapseProps,
  25. Divider,
  26. List,
  27. Row,
  28. Spin,
  29. } from 'antd';
  30. import { getMandateList } from '@/services/TaskManage';
  31. import moment from 'moment';
  32. import { useEffect, useState } from 'react';
  33. import styles from './taskList.less';
  34. const TaskList: React.FC<IPropsType> = (props) => {
  35. const { userList, loading, dispatch } = props;
  36. const location = useLocation();
  37. const queryParams = new URLSearchParams(location.search);
  38. const project_id = Number(queryParams.get('project_id'));
  39. const mandateType = Number(queryParams.get('mandateType'));
  40. const navigate = useNavigate();
  41. // 用于展示的任务列表
  42. const [mandateListShow, setMandateListShow] = useState<IMandateType[]>([]);
  43. // 顶部选择器配置
  44. const [topFiltersConfig, setTopFiltersConfig] = useState<ITopFilter[]>([]);
  45. const [mandateList, setMandateList] = useState<IMandateType[]>([]);
  46. const [mandatePage, setMandatePage] = useState({
  47. pageSize: 20,
  48. total: 0,
  49. current: 1,
  50. });
  51. const [currentParams, setCurrentParams] = useState({
  52. project_id,
  53. mandate_type: mandateType,
  54. pageSize: 20,
  55. currentPage: 2,
  56. });
  57. const { run: getList, loading: loadData } = useRequest(getMandateList, {
  58. defaultParams: [
  59. {
  60. project_id,
  61. mandate_type: mandateType,
  62. pageSize: mandatePage.pageSize,
  63. currentPage: mandatePage.current,
  64. },
  65. ],
  66. formatResult: (result) => {
  67. if (result.data.pagination.current === 1) {
  68. setMandateList(result.data.list);
  69. } else {
  70. setMandateList([...mandateList, ...result.data.list]);
  71. }
  72. const pageInfo = result.data.pagination;
  73. pageInfo.current += 1;
  74. setMandatePage(pageInfo);
  75. },
  76. });
  77. // 获取用户
  78. useEffect(() => {
  79. if (userList.length === 0) {
  80. dispatch({
  81. type: 'taskUser/fetchUserList',
  82. payload: { project_id },
  83. });
  84. }
  85. }, []);
  86. // 首次获取任务数据
  87. useEffect(() => {
  88. setMandateListShow(mandateList);
  89. }, [mandateList]);
  90. // 顶部下拉过滤器配置
  91. useEffect(() => {
  92. const filters: ITopFilter[] = [];
  93. filters.push({
  94. key: 'mandate_class',
  95. placeholder: '任务类别',
  96. // @ts-ignore
  97. options: MandateClass.map((item) => {
  98. if (item.MandateType === mandateType) {
  99. return {
  100. value: item.value,
  101. label: item.label,
  102. key: item.value + '任务类别',
  103. };
  104. }
  105. return undefined;
  106. }).filter((item) => item),
  107. });
  108. filters.push({
  109. key: 'status',
  110. placeholder: '任务状态',
  111. options: MandateStatus.map((item) => {
  112. return {
  113. ...item,
  114. };
  115. }),
  116. });
  117. setTopFiltersConfig(filters);
  118. // setMandateListShow(
  119. // mandateList.filter((item) => item.MandateType === mandateType),
  120. // );
  121. }, [mandateType]);
  122. /**
  123. * 处理选择器变化
  124. * @param value 选择的值,当清空时等于null
  125. */
  126. const onTopFilterChange = (value: any) => {
  127. if (topFiltersConfig.length === 0) {
  128. return;
  129. }
  130. const params: any = {
  131. project_id,
  132. mandate_type: mandateType,
  133. pageSize: mandatePage.pageSize,
  134. currentPage: 1,
  135. };
  136. for (let i = 0; i < value.length; i++) {
  137. if (value[i] !== null && topFiltersConfig[i] !== undefined) {
  138. params[topFiltersConfig[i].key] = value[i];
  139. }
  140. }
  141. getList(params);
  142. params.currentPage += 1;
  143. setCurrentParams(params);
  144. };
  145. const loadMoreMandate =
  146. !loadData && mandateListShow.length > mandatePage.total ? (
  147. <div
  148. style={{
  149. textAlign: 'center',
  150. marginTop: 12,
  151. height: 32,
  152. lineHeight: '32px',
  153. fontSize: '28px',
  154. }}
  155. >
  156. <Button
  157. type="text"
  158. size="large"
  159. style={{ fontSize: '28px', height: '56px', width: '160px' }}
  160. >
  161. 加载更多
  162. </Button>
  163. </div>
  164. ) : null;
  165. const goTaskDetail = (mandate: IMandateType) => {
  166. navigate(
  167. `/task-manage/list/detail?project_id=${project_id}&mandate_id=${mandate.Id}`,
  168. );
  169. };
  170. const goTaskOrder = (orderID: number, orderType: number | undefined) => {
  171. if (orderType === undefined) {
  172. return;
  173. }
  174. navigate(
  175. `/task-manage/list/order-detail?project_id=${project_id}&order_id=${orderID}&order_type=${orderType}`,
  176. );
  177. };
  178. const buildTaskList = (item: IMandateType) => {
  179. const formatItem = {
  180. ...item,
  181. Status: MandateStatus.find((status) => status.value === item.Status),
  182. MandateType: MandateType.find((type) => type.value === item.MandateType),
  183. MandateClass: MandateClass.find(
  184. (itemClass) => itemClass.value === item.MandateClass,
  185. ),
  186. ResponsiblePeople: userList.find(
  187. (user) => user.ID === item.ResponsiblePeople,
  188. ),
  189. CreateTime: moment(item.CreateTime).format('YYYY-MM-DD HH:mm'),
  190. };
  191. const workOrder = item.Records.map((record) => {
  192. return {
  193. ...record,
  194. key: record.Id,
  195. Status: OrderStatus.find((status) => status.value === record.Status),
  196. RecordType: OrderType.find((type) => type.value === record.RecordType),
  197. Responsible: userList.find((user) => user.ID === record.Responsible),
  198. CreateTime: moment(record.CreateTime).format('YYYY-MM-DD HH:mm'),
  199. };
  200. });
  201. const collapseData: CollapseProps['items'] = [
  202. {
  203. key: '1',
  204. label: (
  205. <span style={{ color: '#5697e4' }}>关联工单({workOrder.length})</span>
  206. ),
  207. children: workOrder.map((order) => {
  208. return (
  209. <div key={order.Id} className={styles.workOrderCard}>
  210. <div className={styles.leftInfo}>
  211. <Row style={{ marginBottom: '15px' }}>
  212. <Col className={styles.fontS24} span={12}>
  213. 工单编号:{order.Id}
  214. </Col>
  215. <Col className={styles.fontS24} span={12}>
  216. 时间:{order.CreateTime}
  217. </Col>
  218. </Row>
  219. <Row>
  220. <Col className={styles.fontS24} span={12}>
  221. 工单状态:
  222. <span style={{ color: '#5697e4' }}>
  223. {order.Status?.label}
  224. </span>
  225. </Col>
  226. <Col className={styles.fontS24} span={12}>
  227. 工单负责人:{order.Responsible?.CName}
  228. </Col>
  229. </Row>
  230. </div>
  231. <Divider type="vertical" style={{ height: '40px' }} />
  232. <div
  233. className={styles.rightButton}
  234. style={{ color: '#5697e4' }}
  235. onClick={() => {
  236. goTaskOrder(order.Id, order.RecordType?.value);
  237. }}
  238. >
  239. 查看工单
  240. </div>
  241. </div>
  242. );
  243. }),
  244. },
  245. ];
  246. return (
  247. <List.Item>
  248. <div className={`${styles.cardContainer} card-box`}>
  249. <Row justify="space-between" style={{ marginBottom: '20px' }}>
  250. <Col className={styles.fontS24}>时间:{formatItem.CreateTime}</Col>
  251. <Col className={styles.fontS24}>
  252. 任务类别:{formatItem.MandateClass?.label}
  253. </Col>
  254. <Col className={styles.fontS24}>
  255. 任务负责人:{formatItem.ResponsiblePeople?.CName || '-'}
  256. </Col>
  257. </Row>
  258. <Row
  259. justify="space-between"
  260. style={{
  261. paddingBottom: '10px',
  262. borderBottom: '1px solid #D5D5D5',
  263. }}
  264. >
  265. <Col className={styles.fontS24}>
  266. 任务状态:{formatItem.Status?.label || '-'}
  267. </Col>
  268. <Col>
  269. <div
  270. className={styles.fontS24}
  271. style={{
  272. backgroundColor: '#f5a623',
  273. color: 'white',
  274. width: '150px',
  275. height: '50px',
  276. display: 'flex',
  277. justifyContent: 'center',
  278. alignItems: 'center',
  279. }}
  280. onClick={() => {
  281. goTaskDetail(item);
  282. }}
  283. >
  284. 任务详情
  285. </div>
  286. </Col>
  287. </Row>
  288. <Row>
  289. <Collapse
  290. className={styles.collapseLabel}
  291. ghost
  292. expandIcon={({ isActive }) => (
  293. <DownOutlined
  294. style={{ color: '#5697e4' }}
  295. rotate={isActive ? 180 : 0}
  296. />
  297. )}
  298. items={collapseData}
  299. />
  300. </Row>
  301. </div>
  302. </List.Item>
  303. );
  304. };
  305. return (
  306. <PageContent closeable={false}>
  307. <PageTitle returnable>
  308. {MandateType.find((item) => item.value === mandateType)?.label}
  309. </PageTitle>
  310. <TopFilter filters={topFiltersConfig} onChange={onTopFilterChange} />
  311. <Spin spinning={loading || loadData}>
  312. <List
  313. itemLayout="horizontal"
  314. dataSource={mandateListShow}
  315. renderItem={buildTaskList}
  316. loadMore={loadMoreMandate}
  317. />
  318. </Spin>
  319. </PageContent>
  320. );
  321. };
  322. export default connect(
  323. ({
  324. taskUser,
  325. mandate,
  326. loading,
  327. }: any): {
  328. userList: IUserType[];
  329. loading: boolean;
  330. } => {
  331. return {
  332. userList: taskUser.userList,
  333. loading: loading.models['taskUser'],
  334. };
  335. },
  336. )(TaskList);