TaskDetail.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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}>{mandateDetail?.Summary}</Col>
  280. </Row>
  281. {mandateDetail?.img && (
  282. <Row className={styles.infoRow}>
  283. <Col className={styles.fontS24} span={4}>
  284. 预警图片
  285. </Col>
  286. <Col className={styles.fontS24}>
  287. <ReactZmage
  288. controller={{
  289. // 关闭按钮
  290. close: true,
  291. // 缩放按钮
  292. zoom: false,
  293. // 下载按钮
  294. download: false,
  295. // 翻页按钮
  296. flip: false,
  297. // 多页指示
  298. pagination: false,
  299. }}
  300. backdrop="rgba(255,255,255,0.5)"
  301. style={{ width: '350px' }}
  302. src={mandateDetail?.img}
  303. />
  304. </Col>
  305. </Row>
  306. )}
  307. {mandateDetail?.Files && (
  308. <Row className={styles.infoRow}>
  309. <Col className={styles.fontS24} span={4}>
  310. 截图
  311. </Col>
  312. <Col className={styles.fontS24}>
  313. <ReactZmage
  314. controller={{
  315. // 关闭按钮
  316. close: true,
  317. // 缩放按钮
  318. zoom: false,
  319. // 下载按钮
  320. download: false,
  321. // 翻页按钮
  322. flip: true,
  323. // 多页指示
  324. pagination: true,
  325. }}
  326. backdrop="rgba(255,255,255,0.5)"
  327. style={{ width: '350px' }}
  328. src={mandateDetail?.Files[0].url}
  329. set={mandateDetail?.Files.map((item) => {
  330. return {
  331. src: item.url,
  332. };
  333. })}
  334. />
  335. </Col>
  336. </Row>
  337. )}
  338. <Row>
  339. <Col className={styles.fontS24} span={4}>
  340. 任务内容
  341. </Col>
  342. <Col className={styles.fontS24} span={20}>
  343. {/*{mandateDetail?.Detail}*/}
  344. <Table
  345. rowKey="key"
  346. columns={columnDef}
  347. dataSource={mandateTable}
  348. pagination={false}
  349. />
  350. </Col>
  351. </Row>
  352. </div>
  353. <div className={styles.relatedOrder}>
  354. <Collapse
  355. className={styles.collapseLabel}
  356. ghost
  357. expandIcon={({ isActive }) => (
  358. <UpOutlined
  359. style={{ color: '#5697e4' }}
  360. rotate={isActive ? 180 : 0}
  361. />
  362. )}
  363. items={handledWorkOrder}
  364. />
  365. </div>
  366. </div>
  367. </PageContent>
  368. );
  369. }
  370. export default connect(
  371. ({
  372. taskUser,
  373. }: any): {
  374. userList: IUserType[];
  375. } => {
  376. return {
  377. userList: taskUser.userList,
  378. };
  379. },
  380. )(TaskDetail);