TaskDetail.tsx 12 KB

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