TaskDetail.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. import PageContent from '@/components/PageContent';
  2. import PageTitle from '@/components/PageTitle';
  3. import {
  4. MandateClass,
  5. MandateStatus,
  6. MandateType,
  7. OrderStatus,
  8. OrderType,
  9. } from '@/pages/TaskManage/constent';
  10. import { getDiagnosticDetail, getMandateDetail } from '@/services/TaskManage';
  11. import { useLocation } from '@@/exports';
  12. import { CaretDownFilled } from '@ant-design/icons';
  13. import { connect, useRequest } from '@umijs/max';
  14. import { Col, Collapse, Divider, Row, Table } from 'antd';
  15. import dayjs from 'dayjs';
  16. import { useEffect, useState } from 'react';
  17. // @ts-ignore
  18. import ReactZmage from 'react-zmage';
  19. import { useNavigate } from 'umi';
  20. import styles from './taskDetail.less';
  21. function TaskDetail(props) {
  22. const { userList, dispatch } = props;
  23. const location = useLocation();
  24. const queryParams = new URLSearchParams(location.search);
  25. const project_id = Number(queryParams.get('project_id'));
  26. const mandate_id = Number(queryParams.get('mandate_id'));
  27. const navigate = useNavigate();
  28. const [mandateDetail, setMandateDetail] = useState();
  29. const [mandateChild, setMandateChild] = useState([]);
  30. const [handledWorkOrder, setHandledWorkOrder] = useState([]);
  31. const [mandateTable, setMandateTable] = useState([]);
  32. const columnDef = [
  33. {
  34. title: '详情',
  35. dataIndex: 'detail',
  36. key: 'key',
  37. render: (value, record) => {
  38. return (
  39. <div style={{ display: 'flex', alignItems: 'center' }}>
  40. <div style={{ width: '100%' }}>{value.text}</div>
  41. </div>
  42. );
  43. },
  44. },
  45. ];
  46. const base64ToImageUrl = (base64String) => {
  47. const byteCharacters = atob(base64String);
  48. const byteArrays = [];
  49. for (let i = 0; i < byteCharacters.length; i++) {
  50. byteArrays.push(byteCharacters.charCodeAt(i));
  51. }
  52. const byteArray = new Uint8Array(byteArrays);
  53. const blob = new Blob([byteArray], { type: 'image/png' });
  54. return URL.createObjectURL(blob);
  55. };
  56. const { refresh: refreshDetail } = useRequest(getMandateDetail, {
  57. defaultParams: [
  58. {
  59. mandate_id,
  60. project_id,
  61. },
  62. ],
  63. formatResult: async (result) => {
  64. const tempMandate = {
  65. ...result.data,
  66. Status: MandateStatus.find((item) => item.value === result.data.Status),
  67. MandateClass: MandateClass.find(
  68. (item) => item.value === result.data.MandateClass,
  69. ),
  70. MandateType: MandateType.find(
  71. (item) => item.value === result.data.MandateType,
  72. ),
  73. ResponsiblePeople: userList.find(
  74. (item) => item.ID === result.data.ResponsiblePeople,
  75. ),
  76. CreateTime: dayjs(result.data.CreateTime).format('YYYY-MM-DD HH:mm'),
  77. };
  78. const workOrder = result.data.Records.map((item) => {
  79. return {
  80. ...item,
  81. CreateTime: dayjs(item.CreateTime).format('YYYY-MM-DD HH:mm'),
  82. Status: OrderStatus.find((status) => status.value === item.Status),
  83. RecordType: OrderType.find((type) => type.value === item.RecordType),
  84. Responsible: userList.find((user) => user.ID === item.Responsible),
  85. };
  86. });
  87. const children = result.data.MandateChild;
  88. const tempOrder = [
  89. {
  90. key: '1',
  91. label: (
  92. <span style={{ color: '#ffffff', marginRight: '0.1rem' }}>
  93. 关联工单({workOrder.length})
  94. </span>
  95. ),
  96. children: workOrder.map((record) => {
  97. return (
  98. <div key={record.Id} className={styles.workOrderCard}>
  99. <div className={styles.leftInfo}>
  100. <Row style={{ marginBottom: '0.15rem' }}>
  101. <Col className={styles.fontS32} span={12}>
  102. <>
  103. 工单类型:
  104. {record.RecordType?.label?.replace('工单', '')}
  105. </>
  106. </Col>
  107. <Col className={styles.fontS32} span={12}>
  108. 时间:{record.CreateTime || '-'}
  109. </Col>
  110. </Row>
  111. <Row>
  112. <Col className={styles.fontS32} span={12}>
  113. 工单状态:
  114. <span style={{ color: '#5697e4' }}>
  115. {typeof record.Status === 'number'
  116. ? '-'
  117. : record.Status?.label}
  118. </span>
  119. </Col>
  120. <Col className={styles.fontS32} span={12}>
  121. 工单负责人:
  122. {typeof record.Responsible === 'number'
  123. ? '-'
  124. : record.Responsible?.CName}
  125. </Col>
  126. </Row>
  127. </div>
  128. <Divider type="vertical" style={{ height: '0.4rem' }} />
  129. <div className={styles.rightButtonContainer}>
  130. <div
  131. className={styles.rightButton}
  132. onClick={() => {
  133. if (typeof record.RecordType === 'number') {
  134. return;
  135. }
  136. // @ts-ignore
  137. goMyWorkOrder(
  138. record.Id,
  139. record.RecordType?.value,
  140. tempMandate?.MandateClass.value,
  141. );
  142. }}
  143. >
  144. 查看
  145. </div>
  146. {/* <div
  147. className={styles.rightButton}
  148. style={{ color: '#5697e4' }}
  149. onClick={() => {
  150. if (typeof record.RecordType === 'number') {
  151. return;
  152. }
  153. // @ts-ignore
  154. goTaskOrder(
  155. record.Id,
  156. record.RecordType?.value,
  157. tempMandate?.MandateClass.value,
  158. );
  159. }}
  160. >
  161. 关闭工单
  162. </div> */}
  163. </div>
  164. </div>
  165. );
  166. }),
  167. },
  168. ];
  169. if (
  170. tempMandate.MandateClass &&
  171. tempMandate.ExtendId &&
  172. /* @ts-ignore */
  173. tempMandate.MandateClass.value === 7
  174. ) {
  175. const image = await getDiagnosticDetail(tempMandate.ExtendId);
  176. tempMandate.img = image.path;
  177. }
  178. setMandateDetail(tempMandate);
  179. setHandledWorkOrder(tempOrder);
  180. if (children && children.length) {
  181. setMandateChild(children);
  182. }
  183. },
  184. });
  185. useEffect(() => {
  186. if (userList.length === 0) {
  187. dispatch({
  188. type: 'taskUser/fetchUserList',
  189. payload: { project_id },
  190. });
  191. }
  192. }, []);
  193. useEffect(() => {
  194. if (!mandateChild.length) {
  195. return;
  196. }
  197. if (mandateDetail?.MandateClass?.value === 2) {
  198. const dataSource = [];
  199. dataSource.push({
  200. detail: {
  201. text: mandateChild[0].Title,
  202. key: 'title',
  203. },
  204. });
  205. dataSource.push(
  206. ...Object.entries(JSON.parse(mandateChild[0].Payload)).map((item) => {
  207. const [key, value] = item;
  208. return {
  209. detail: {
  210. text:
  211. value['item_alias'] +
  212. ' 现有数值:' +
  213. value['old_value'] +
  214. ' 建议调整数值' +
  215. value['new_value'],
  216. key: key,
  217. },
  218. };
  219. }),
  220. );
  221. setMandateTable(dataSource);
  222. return;
  223. }
  224. const dataSource = mandateChild.map((item, index) => {
  225. if (item.MandateClass === 2) {
  226. }
  227. return {
  228. detail: {
  229. text: item.Title + item.Content,
  230. key: item.Title + index + item.Content,
  231. },
  232. };
  233. });
  234. setMandateTable(dataSource);
  235. }, [mandateChild]);
  236. const goMyWorkOrder = (orderID, orderType, mandateClass) => {
  237. if (orderType === undefined) {
  238. return;
  239. }
  240. navigate(
  241. `/center/my-task/work-order-detail?project_id=${project_id}&order_id=${orderID}&order_type=${orderType}&mandate_class=${mandateClass}`,
  242. );
  243. };
  244. return (
  245. <PageContent closeable={false}>
  246. <PageTitle returnable>任务详情</PageTitle>
  247. <div className={`${styles.cardContainer}`}>
  248. <div className={styles.normalInfo}>
  249. <Row className={styles.infoRow}>
  250. <Col span={14} className={styles.fontS32}>
  251. 时间:{mandateDetail?.CreateTime}
  252. </Col>
  253. {/*// @ts-ignore*/}
  254. <Col className={styles.fontS32}>
  255. {/*//@ts-ignore*/}
  256. 任务类别:{mandateDetail?.MandateClass?.label}
  257. </Col>
  258. </Row>
  259. <Row>
  260. <Col span={14} className={styles.fontS32}>
  261. {/*//@ts-ignore*/}
  262. 任务状态:{mandateDetail?.Status?.label}
  263. </Col>
  264. <Col className={styles.fontS32}>
  265. {/*// @ts-ignore*/}
  266. 任务负责人:{mandateDetail?.ResponsiblePeople?.CName}
  267. </Col>
  268. </Row>
  269. </div>
  270. <div className={styles.detailInfo}>
  271. <Row className={styles.infoRow}>
  272. <Col
  273. className={styles.fontS32}
  274. span={4}
  275. style={{ fontWeight: 600 }}
  276. >
  277. 任务总结
  278. </Col>
  279. <Col
  280. className={styles.fontS32}
  281. style={{ color: 'rgba(97, 93, 93, 1)' }}
  282. >
  283. {mandateDetail?.Summary ||
  284. '根据水质相关数据.建议您调节以下参数,水厂运行可达较优状态'}
  285. </Col>
  286. </Row>
  287. {mandateDetail?.img && (
  288. <Row className={styles.infoRow}>
  289. <Col
  290. className={styles.fontS32}
  291. span={4}
  292. style={{ fontWeight: 600 }}
  293. >
  294. 预警图片
  295. </Col>
  296. <Col className={styles.fontS32}>
  297. <ReactZmage
  298. controller={{
  299. // 关闭按钮
  300. close: true,
  301. // 缩放按钮
  302. zoom: false,
  303. // 下载按钮
  304. download: false,
  305. // 翻页按钮
  306. flip: false,
  307. // 多页指示
  308. pagination: false,
  309. }}
  310. backdrop="rgba(255,255,255,0.5)"
  311. style={{ width: '3.5rem' }}
  312. src={mandateDetail?.img}
  313. />
  314. </Col>
  315. </Row>
  316. )}
  317. {mandateDetail?.Files.length > 0 && (
  318. <Row className={styles.infoRow}>
  319. <Col
  320. className={styles.fontS32}
  321. span={4}
  322. style={{ fontWeight: 600 }}
  323. >
  324. 截图
  325. </Col>
  326. <Col className={styles.fontS32}>
  327. <ReactZmage
  328. controller={{
  329. // 关闭按钮
  330. close: true,
  331. // 缩放按钮
  332. zoom: false,
  333. // 下载按钮
  334. download: false,
  335. // 翻页按钮
  336. flip: true,
  337. // 多页指示
  338. pagination: true,
  339. }}
  340. backdrop="rgba(255,255,255,0.5)"
  341. style={{ width: '3.5rem' }}
  342. src={mandateDetail?.Files[0].url}
  343. set={mandateDetail?.Files.map((item) => {
  344. if (item) {
  345. return {
  346. src: item.url,
  347. };
  348. }
  349. return {};
  350. })}
  351. />
  352. </Col>
  353. </Row>
  354. )}
  355. <Row>
  356. <Col
  357. className={styles.fontS32}
  358. span={4}
  359. style={{ fontWeight: 600 }}
  360. >
  361. 任务内容
  362. </Col>
  363. <Col className={styles.fontS32} span={20}>
  364. {/*{mandateDetail?.Detail}*/}
  365. <Table
  366. className={styles.taskTable}
  367. rowKey="key"
  368. columns={columnDef}
  369. dataSource={mandateTable}
  370. pagination={false}
  371. />
  372. </Col>
  373. </Row>
  374. </div>
  375. <div className={styles.relatedOrder}>
  376. <Collapse
  377. className={styles.collapseLabel}
  378. ghost
  379. expandIcon={({ isActive }) => (
  380. <CaretDownFilled
  381. style={{ color: '#ffffff' }}
  382. rotate={isActive ? 180 : 0}
  383. />
  384. )}
  385. items={handledWorkOrder}
  386. />
  387. </div>
  388. </div>
  389. </PageContent>
  390. );
  391. }
  392. export default connect(({ taskUser }) => {
  393. return {
  394. userList: taskUser.userList,
  395. };
  396. })(TaskDetail);