TaskList.tsx 9.7 KB

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