index.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. import PageContent from '@/components/PageContent';
  2. import TabsContent from '@/components/TabsContent';
  3. import { queryMainChartList } from '@/services/StorageManagement';
  4. import {
  5. queryDeviceList,
  6. queryMaintainRecord,
  7. queryRepairRecord,
  8. } from '@/services/device';
  9. import { UnityAction } from '@/utils/utils';
  10. import { RightOutlined } from '@ant-design/icons';
  11. import { useNavigate, useParams, useRequest } from '@umijs/max';
  12. import { Collapse, List, Space, Spin, Table } from 'antd';
  13. import dayjs from 'dayjs';
  14. import { useEffect, useMemo, useState } from 'react';
  15. import styles from './index.less';
  16. const deviceIcon = require('@/assets/deviceManager/deviceIcon.png');
  17. const spareIcon = require('@/assets/deviceManager/spareIcon.png');
  18. // const chartIcon = require('@/assets/deviceManager/chartIcon.png');
  19. export const PageType = {
  20. in: 0, //入库管理
  21. out: 1, //出库管理
  22. scrap: 2, //报废处置
  23. warning: 3, //报警数量
  24. base: 4, //基础库存
  25. };
  26. const DeviceManager = () => {
  27. const { projectId } = useParams();
  28. const [defaultActiveKey, setDefaultActiveKey] = useState(
  29. localStorage.deviceTab || '1',
  30. );
  31. useEffect(() => {
  32. // 重置默认显示tab
  33. localStorage.deviceTab = '1';
  34. }, []);
  35. return (
  36. <PageContent tabs>
  37. <TabsContent
  38. defaultActiveKey={defaultActiveKey}
  39. onChange={setDefaultActiveKey}
  40. items={[
  41. {
  42. label: `设备管理`,
  43. key: '1',
  44. children: <Device projectId={projectId} />,
  45. },
  46. {
  47. label: `备品管理`,
  48. key: '2',
  49. children: <SparePart projectId={projectId} />,
  50. },
  51. ]}
  52. />
  53. </PageContent>
  54. );
  55. };
  56. const Device = ({ projectId }) => {
  57. const [type, setType] = useState(0); //0 全部 1维修 2保养
  58. const [activeCode, setActiveCode] = useState();
  59. const columnsRepair = [
  60. {
  61. title: '设备位号',
  62. dataIndex: 'DeviceCode',
  63. key: 'DeviceCode',
  64. align: 'center',
  65. },
  66. {
  67. title: '设备名称',
  68. dataIndex: 'DeviceName',
  69. key: 'DeviceName',
  70. align: 'center',
  71. },
  72. {
  73. title: '维修时间',
  74. dataIndex: 'RepairTime',
  75. key: 'RepairTime',
  76. align: 'center',
  77. render: (text) => {
  78. return text ? dayjs(text).format('YYYY-MM-DD HH:mm') : null;
  79. },
  80. },
  81. {
  82. title: '维修状态',
  83. dataIndex: 'AcceptanceStatus',
  84. render: (text) => {
  85. switch (text) {
  86. case 0:
  87. return '维修中';
  88. case 1:
  89. return '已提交';
  90. case 2:
  91. return '已维修';
  92. default:
  93. return '';
  94. }
  95. },
  96. },
  97. ];
  98. const columns = [
  99. {
  100. title: '设备位号',
  101. dataIndex: 'DeviceCode',
  102. },
  103. {
  104. title: '设备名称',
  105. dataIndex: 'DeviceName',
  106. },
  107. {
  108. title: '保养日期',
  109. dataIndex: 'MaintainTime',
  110. render: (text) => {
  111. return text ? dayjs(text).format('YYYY-MM-DD HH:mm') : null;
  112. },
  113. },
  114. {
  115. title: '保养人',
  116. dataIndex: 'Operators',
  117. // width: 300,
  118. render: (text) => {
  119. let arr = [];
  120. if (text && text.length > 0) {
  121. text.map((item) => {
  122. if (item && item.Operator && item.Operator.CName) {
  123. arr.push(item.Operator.CName);
  124. }
  125. });
  126. }
  127. return arr && arr.join(',');
  128. },
  129. },
  130. ];
  131. //请求 全部设备列表
  132. const {
  133. data,
  134. run: runDevice,
  135. loading: loadingDevice,
  136. } = useRequest(queryDeviceList, {
  137. defaultParams: [projectId],
  138. });
  139. const allData = useMemo(() => {
  140. const total = data?.reduce((total, item) => item.Count, 0);
  141. const items = data?.map((item, idx) => {
  142. const itemLen = item?.List?.length;
  143. return {
  144. key: `${idx + 1}`,
  145. label: (
  146. <div className={styles.lineContent}>
  147. <span>{item.Type}</span>
  148. <span>{itemLen}个</span>
  149. </div>
  150. ),
  151. children: (
  152. <div style={{ position: 'relative' }}>
  153. <List
  154. header={null}
  155. footer={null}
  156. dataSource={item.List}
  157. renderItem={(cur) => (
  158. <List.Item
  159. className={`${styles.itemText} ${
  160. activeCode == cur.Code ? styles.itemTextActive : ''
  161. }`}
  162. onClick={() => handleItemClick(cur.Code)}
  163. >
  164. <span style={{ width: '30%', textAlign: 'left' }}>
  165. {cur.Code}
  166. </span>
  167. <span> {cur.Name} </span>
  168. </List.Item>
  169. )}
  170. />
  171. </div>
  172. ),
  173. };
  174. });
  175. return { total, items };
  176. }, [data, activeCode]);
  177. //请求维修中设备列表queryRepairRecord
  178. const {
  179. data: repairData,
  180. run: runRepair,
  181. loading: repairLoading,
  182. } = useRequest(
  183. () =>
  184. queryRepairRecord({
  185. pageSize: 9999,
  186. recordId: Number(projectId),
  187. }),
  188. {
  189. manual: true,
  190. },
  191. );
  192. //请求保养记录
  193. const {
  194. data: maintainData,
  195. run: runMaintain,
  196. loading: maintaiLoading,
  197. } = useRequest(
  198. () =>
  199. queryMaintainRecord({
  200. pageSize: 9999,
  201. recordId: Number(projectId),
  202. }),
  203. {
  204. manual: true,
  205. },
  206. );
  207. const handleItemClick = (code) => {
  208. UnityAction.sendMsg('deviceCode', code);
  209. console.log(code);
  210. setActiveCode(code);
  211. };
  212. const handleBtnClick = (type) => {
  213. setType(type);
  214. switch (type) {
  215. case 0:
  216. runDevice(projectId);
  217. break;
  218. case 1:
  219. runRepair();
  220. break;
  221. case 2:
  222. runMaintain();
  223. break;
  224. }
  225. };
  226. return (
  227. <div className={`content-tab ${styles.sparePart}`}>
  228. <Spin spinning={loadingDevice}>
  229. <div className={styles.titleContent}>
  230. <img className={styles.img} src={deviceIcon} />
  231. <div>
  232. <div className="value-number">{allData?.total}</div>
  233. <div className={styles.text}>设备总数(个)</div>
  234. </div>
  235. </div>
  236. <Space className={styles.btns} size={28}>
  237. <div
  238. className={`${styles.btn} ${type == 0 ? styles.active : ''}`}
  239. onClick={() => handleBtnClick(0)}
  240. >
  241. <span style={{ lineHeight: '0.6rem' }}>全部</span>
  242. </div>
  243. <div
  244. className={`${styles.btn} ${type == 1 ? styles.active : ''}`}
  245. onClick={() => handleBtnClick(1)}
  246. >
  247. <span style={{ lineHeight: '0.6rem' }}>维修</span>
  248. </div>
  249. <div
  250. className={`${styles.btn} ${type == 2 ? styles.active : ''}`}
  251. onClick={() => handleBtnClick(2)}
  252. >
  253. <span style={{ lineHeight: '0.6rem' }}>保养</span>
  254. </div>
  255. </Space>
  256. </Spin>
  257. {type == 0 && <Collapse bordered={false} items={allData?.items} />}
  258. {type == 1 && (
  259. <Table
  260. loading={repairLoading}
  261. style={{ marginTop: '0.1rem' }}
  262. dataSource={repairData?.filter((item) => item.DeviceCode)}
  263. columns={columnsRepair}
  264. pagination={false}
  265. />
  266. )}
  267. {type == 2 && (
  268. <Table
  269. loading={maintaiLoading}
  270. style={{ marginTop: '0.1rem' }}
  271. dataSource={maintainData?.filter((item) => item.DeviceCode)}
  272. columns={columns}
  273. pagination={false}
  274. />
  275. )}
  276. </div>
  277. );
  278. };
  279. const SparePart = ({ projectId }) => {
  280. const navigate = useNavigate();
  281. const year = dayjs().format('YYYY');
  282. const currentMonth = dayjs().format('MM');
  283. const defaultParams = {
  284. project_id: Number(projectId),
  285. month: Number(currentMonth),
  286. year: Number(year),
  287. };
  288. //请求备品列表
  289. const { data, loading } = useRequest(() => queryMainChartList(defaultParams));
  290. const changePage = (type) => {
  291. navigate(`/device/detail/${projectId}/${type}`);
  292. // 设置默认显示tab为备品管理
  293. localStorage.deviceTab = '2';
  294. };
  295. const handleTotalPage = () => {
  296. navigate(`/device/storage/${projectId}`);
  297. // 设置默认显示tab为备品管理
  298. localStorage.deviceTab = '2';
  299. };
  300. const list = useMemo(() => {
  301. const result = [
  302. {
  303. title: '基础库存',
  304. type: PageType.base,
  305. },
  306. {
  307. title: '入库数量',
  308. type: PageType.in,
  309. num: data?.in_amount || 0,
  310. },
  311. {
  312. title: '出库数量',
  313. type: PageType.out,
  314. num: data?.out_amount || 0,
  315. },
  316. {
  317. title: '报废数量',
  318. type: PageType.scrap,
  319. num: data?.scrap_amount || 0,
  320. },
  321. {
  322. title: '报警数量',
  323. type: PageType.warning,
  324. num: data?.warning_stat || 0,
  325. },
  326. ];
  327. return result;
  328. }, [data]);
  329. return (
  330. <Spin spinning={loading}>
  331. <div className="content-tab">
  332. <Space direction="vertical" size={16} className={styles.sparePart}>
  333. <div className={styles.titleContent}>
  334. <img className={styles.img} src={spareIcon} />
  335. <div>
  336. <div className="value-number">{data?.on_amount || 0}</div>
  337. <div className={styles.text}>在库数量(个)</div>
  338. </div>
  339. <div
  340. onClick={handleTotalPage}
  341. className={styles.iconFundFilled}
  342. ></div>
  343. </div>
  344. {list.map((item) => (
  345. <div
  346. className={`card-box ${styles.cardItem}`}
  347. onClick={() => changePage(item.type)}
  348. >
  349. <span className={styles.spareText}>{item.title}</span>
  350. <Space size={30}>
  351. {/* <span className={styles.spareText}>{item.num}个</span> */}
  352. <RightOutlined style={{ fontSize: '0.28rem' }} />
  353. </Space>
  354. </div>
  355. ))}
  356. </Space>
  357. </div>
  358. </Spin>
  359. );
  360. };
  361. export default DeviceManager;