TaskList.js 9.5 KB

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