停车场项目web, 互联网仓库, 开发完成后, 需要将代码回传云桌面.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

568 lines
21 KiB

  1. import React, { useState, useRef, useEffect } from "react";
  2. import { ResultFlowResult } from "@/components"
  3. import { Select, Input, Button, Table, message, Pagination, Popover, Modal, Col, Row, Form, Tabs } from 'antd'
  4. import {
  5. pageSizeOptions
  6. } from '@/config/character.config.js'
  7. import { SearchOutlined, DeleteOutlined, PlayCircleOutlined, EditOutlined, PlusCircleOutlined, InfoCircleOutlined } from '@ant-design/icons';
  8. import ajax from '@/services'
  9. import "./index.scss";
  10. import { useSessionStorageState } from "ahooks"
  11. function Road(props) {
  12. const [form] = Form.useForm()
  13. const [ajaxLoading, setAjaxLoading] = useState(false)
  14. const [deviceDetail, setDeviceDetail] = useState({})
  15. const [editModalVisible, setEditModalVisible] = useState(false)
  16. const [editStatus, setEditStatus] = useState(false)
  17. const [storeData, setStoreData] = useState([]) //所属商户
  18. const [deviceTypeData, setDeviceTypeData] = useState([{ label: '全部', value: -1 }]) //设备类型
  19. const [brandData, setBrandData] = useState([{ label: '全部', value: -1 }]) // 品牌list
  20. const [resultData, setResultData] = useState({
  21. data: [],
  22. total_records: 0,
  23. export_url: '',
  24. process_url: ""
  25. })
  26. const parameter = {
  27. device_name: '',
  28. device_code: '',
  29. pole_position_code: '',
  30. type_id: -1, //设备类型
  31. road_name: '',
  32. operator: "0", //所属商户
  33. operate_status: -1, //运营状态
  34. device_status: -1, //设备状态
  35. pn: 1,
  36. length: Number(pageSizeOptions[0]), // 每页条数
  37. }
  38. const [formData, setFormData] = useState(parameter)
  39. const [lastFormData, setLastFormData] = useState(formData)
  40. const lastFormDataRef = useRef(formData)
  41. const getOperatorData = () => {
  42. ajax.getOperator().then((e) => {
  43. setStoreData([
  44. ...storeData,
  45. ...e.data
  46. ])
  47. })
  48. }
  49. const getDeviceType = () => {
  50. ajax.getDeviceTypeList().then((e) => {
  51. setDeviceTypeData([
  52. ...deviceTypeData,
  53. ...e.data
  54. ])
  55. })
  56. }
  57. const getBrandData = () => {
  58. ajax.getAllBrandNameList().then((e) => {
  59. setBrandData([
  60. ...brandData,
  61. ...e.data
  62. ])
  63. })
  64. }
  65. const handleDelToServer = (id) => {
  66. return new Promise((resolved, rejected) => {
  67. ajax.nvrDel(id).then((e) => {
  68. if (e.status == 20000) {
  69. resolved(e.message)
  70. }
  71. }).catch((err) => {
  72. rejected(err)
  73. })
  74. })
  75. }
  76. const getDeviceDetail = (id) => {
  77. return new Promise((resolved, rejected) => {
  78. ajax.getDeviceDimensionDetail({id: id}).then((e) => {
  79. if (e.status == 20000) {
  80. resolved(e.data)
  81. }
  82. }).catch((err) => {
  83. rejected(err)
  84. })
  85. })
  86. }
  87. const handleEdit = (item) => {
  88. getDeviceDetail(item.id).then((data) => {
  89. setEditStatus(true)
  90. form.setFieldsValue({
  91. ...data
  92. })
  93. setDeviceDetail(data)
  94. setEditModalVisible(true)
  95. })
  96. }
  97. const editModalCancel = () => {
  98. setEditModalVisible(false)
  99. form.resetFields()
  100. }
  101. //列表
  102. const handleColumns = (tab) => {
  103. let result = [...tableColumns];
  104. switch (tab) {
  105. case '1':
  106. result.splice(9, 1)
  107. break;
  108. }
  109. return result;
  110. }
  111. //列表
  112. const tableColumns = [
  113. {
  114. title: '设备名称',
  115. dataIndex: 'name'
  116. },
  117. {
  118. title: '设备编号',
  119. dataIndex: 'code'
  120. },
  121. {
  122. title: '设备类型',
  123. dataIndex: 'type_name',
  124. },
  125. {
  126. title: '所属路段',
  127. dataIndex: 'road_name',
  128. },
  129. {
  130. title: '对应杆位号',
  131. dataIndex: 'pole_position_code',
  132. },
  133. {
  134. title: '区域',
  135. dataIndex: 'region_name',
  136. },
  137. {
  138. title: '设备厂商',
  139. dataIndex: 'operqator',
  140. },
  141. {
  142. title: '运营状态',
  143. dataIndex: 'operate_status',
  144. },
  145. {
  146. title: '设备状态',
  147. dataIndex: 'device_status',
  148. render: (text, record, index) => {
  149. return (
  150. <div className="device_status">
  151. <div className={(text == '在线' || text == '上线') ? 'text-online' : 'text-offline'}>{text}</div>
  152. </div>
  153. )
  154. }
  155. },
  156. {
  157. title: '更新时间',
  158. dataIndex: 'update_time',
  159. },
  160. {
  161. title: '操作',
  162. width: 135,
  163. // render: (text, record, index) => {
  164. // return <>
  165. // <div className="action-wrapper">
  166. // <Button type="primary" shape="circle" s size="middle" icon={<InfoCircleOutlined />} onClick={() => handleEdit(record)}/>
  167. // </div>
  168. // </>
  169. // },
  170. render: (text, record) => {
  171. return <>
  172. <Popover content={
  173. <div className="black">
  174. <div className="yisa-btn" onClick={() => handleEdit(record)}>查看设备</div>
  175. </div>}>
  176. <Button type="primary" size="middle">操作</Button>
  177. </Popover>
  178. </>
  179. },
  180. }
  181. ]
  182. // 获取列表数据
  183. const getData = (data = formData) => {
  184. setAjaxLoading(true)
  185. ajax.getDeviceDimensionList(data).then(res => {
  186. setAjaxLoading(false)
  187. if (res.status === 20000) {
  188. let resDataArr = res.data.list.map((item) => {
  189. item.key = item.id
  190. return item
  191. })
  192. setResultData({
  193. ...resultData,
  194. data: resDataArr,
  195. total_records: res.data.total
  196. })
  197. } else {
  198. setResultData({
  199. data: [],
  200. total_records: 0,
  201. export_url: '',
  202. process_url: ""
  203. })
  204. message.error(res.message)
  205. }
  206. }, err => {
  207. console.log(err)
  208. })
  209. }
  210. //切换分页
  211. const changePn = (pn, length) => {
  212. if (lastFormData.length === length) {
  213. setFormData(Object.assign({}, formData, { pn: pn, length: length}))
  214. setLastFormData(Object.assign({}, lastFormData, { pn: pn, length: length }))
  215. lastFormDataRef.current = Object.assign({}, lastFormData, { pn: pn , length: length})
  216. getData(Object.assign({}, formData, { pn: pn, length: length }))
  217. }
  218. }
  219. //切换每页条数
  220. const changeLength = (pn, length) => {
  221. setFormData(Object.assign({}, formData, { pn: 1, length: length }))
  222. setLastFormData(Object.assign({}, lastFormData, { pn: 1, length: length }))
  223. lastFormDataRef.current = Object.assign({}, lastFormData, { pn: 1, length: length })
  224. getData(Object.assign({}, formData, { pn: 1, length: length }))
  225. }
  226. //检索数据
  227. const getSearchData = (data = formData) => {
  228. getData(data)
  229. }
  230. //重置表单
  231. const formReset = () => {
  232. setFormData({
  233. ...parameter
  234. })
  235. getData({...parameter})
  236. }
  237. const handleExport = () => {
  238. ajax.deviceDimensionExport(formData).then(e => {
  239. if (e.status == 20000) {
  240. window.open(e.data.url)
  241. }
  242. })
  243. }
  244. const brandEdit = (params) => {
  245. return new Promise((resolved, rejected) => {
  246. ajax.brandEdit(params).then((e) => {
  247. if (e.status == 20000) {
  248. resolved(e.message)
  249. }
  250. }).catch(err => {
  251. rejected(err)
  252. })
  253. })
  254. }
  255. const brandAdd = (params) => {
  256. return new Promise((resolved, rejected) => {
  257. ajax.brandAdd(params).then((e) => {
  258. if (e.status == 20000) {
  259. resolved(e.message)
  260. }
  261. }).catch(err => {
  262. rejected(err)
  263. })
  264. })
  265. }
  266. const [sessionTabList, setSessionTabList] = useSessionStorageState('equipmentStatus', {
  267. value: {
  268. }
  269. })
  270. useEffect(() => {
  271. if (sessionTabList && Object.values(sessionTabList).length > 0) {
  272. setFormData({
  273. device_name: sessionTabList?.device_name,
  274. device_code: sessionTabList?.device_code,
  275. pole_position_code: sessionTabList?.pole_position_code,
  276. type_id: -1,
  277. road_name: sessionTabList?.road_name,
  278. operator: "0",
  279. device_status: -1,
  280. operate_status: -1
  281. })
  282. }
  283. }, [])
  284. useEffect(() => {
  285. setSessionTabList({
  286. ...formData
  287. })
  288. }, [formData])
  289. useEffect(() => {
  290. getData()
  291. getOperatorData()
  292. getDeviceType()
  293. getBrandData()
  294. }, [])
  295. return (
  296. <>
  297. <div className="road-container">
  298. <div className="road-search">
  299. <label className="search">查询条件</label>
  300. <div className="yisa-search">
  301. <label>设备名称</label>
  302. <Input
  303. placeholder="请输入设备名称"
  304. style={{ width: 260, marginLeft: 14 }}
  305. value={formData.device_name}
  306. onChange={(e) => setFormData({...formData, device_name: e.target.value})}
  307. />
  308. </div>
  309. <div className="yisa-search">
  310. <label>设备编号</label>
  311. <Input
  312. placeholder="请输入设备编号"
  313. style={{ width: 260, marginLeft: 14 }}
  314. value={formData.device_code}
  315. onChange={(e) => setFormData({...formData, device_code: e.target.value})}
  316. />
  317. </div>
  318. <div className="yisa-search">
  319. <label>对应杆位</label>
  320. <Input
  321. placeholder="请输入对应杆位"
  322. style={{ width: 260, marginLeft: 14 }}
  323. value={formData.pole_position_code}
  324. onChange={(e) => setFormData({...formData, pole_position_code: e.target.value})}
  325. />
  326. </div>
  327. <div className="yisa-search">
  328. <label>设备类型</label>
  329. <Select
  330. style={{ width: 260, marginLeft: 14 }}
  331. placeholder="请选择"
  332. value={formData.type_id}
  333. options={deviceTypeData}
  334. onChange={(v) => setFormData({...formData, type_id: v})}
  335. />
  336. </div>
  337. <div className="yisa-search">
  338. <label>所属路段</label>
  339. <Input
  340. placeholder="请输入所属路段"
  341. value={formData.road_name}
  342. style={{ width: 260, marginLeft: 14 }}
  343. onChange={(e) => setFormData({...formData, road_name: e.target.value})}
  344. />
  345. </div>
  346. <div className="yisa-search">
  347. <label>商户</label>
  348. <Select
  349. style={{ width: 260, marginLeft: 42 }}
  350. placeholder="请选择"
  351. value={formData.operator}
  352. options={storeData}
  353. onChange={(v) => setFormData({...formData, operator: v})}
  354. />
  355. </div>
  356. <div className="yisa-search">
  357. <label>运营状态</label>
  358. <Select
  359. style={{ width: 260, marginLeft: 14 }}
  360. placeholder="请选择"
  361. value={formData.operate_status}
  362. options={[
  363. {
  364. value: -1,
  365. label: '全部'
  366. },
  367. {
  368. value: '1',
  369. label: '上线'
  370. }, {
  371. value: '2',
  372. label: '下线'
  373. }
  374. ]}
  375. onChange={(v) => {
  376. if (v == 2) {
  377. setFormData({...formData, operate_status: v, device_status: -1})
  378. } else {
  379. setFormData({...formData, operate_status: v})
  380. }
  381. }}
  382. />
  383. </div>
  384. {
  385. formData.operate_status != 2 ? (
  386. <div className="yisa-search">
  387. <label>设备状态</label>
  388. <Select
  389. style={{ width: 260, marginLeft: 14 }}
  390. placeholder="请选择"
  391. value={formData.device_status}
  392. options={[
  393. {
  394. value: -1,
  395. label: '全部'
  396. },
  397. {
  398. value: '1',
  399. label: '在线'
  400. }, {
  401. value: '2',
  402. label: '离线'
  403. }
  404. ]}
  405. onChange={(v) => setFormData({...formData, device_status: v})}
  406. />
  407. </div>
  408. ) : (<></>)
  409. }
  410. <div className="timePicker yisa-search">
  411. <div className="btnBox">
  412. <Button type="primary" className="yisa-btn colorBtn" icon={<SearchOutlined />} onClick={() => { getSearchData() }}>
  413. 搜索
  414. </Button>
  415. <Button type="primary" className="yisa-btn colorReset" icon={<DeleteOutlined />} onClick={() => { formReset() }}>
  416. 清空
  417. </Button>
  418. {/* <Button type="primary" className="yisa-btn" icon={<PlusCircleOutlined />} onClick={() => { handleAdd() }}>
  419. 添加
  420. </Button> */}
  421. </div>
  422. </div>
  423. </div>
  424. <div className="road-result">
  425. <div className="result">
  426. <div className="result-title">
  427. <span className="font">共检索到<em>{resultData.total_records}</em>条结果</span>
  428. <div className="export-btn" onClick={handleExport}>导出</div>
  429. </div>
  430. <ResultFlowResult ajaxLoad={ajaxLoading} resultData={resultData.data ? resultData.data : []}>
  431. <Table
  432. bordered
  433. className='yisa-table'
  434. dataSource={resultData.data}
  435. columns={
  436. handleColumns()
  437. }
  438. scroll={{y: 560}}
  439. pagination={false}
  440. loading={ajaxLoading}
  441. />
  442. <Pagination
  443. className="pagination-common"
  444. showSizeChanger
  445. showQuickJumper
  446. showTotal={() => `${resultData.total_records}`}
  447. total={resultData.total_records}
  448. current={lastFormData.pn}
  449. pageSize={lastFormData.length}
  450. pageSizeOptions={pageSizeOptions}
  451. onChange={changePn}
  452. onShowSizeChange={changeLength}
  453. />
  454. </ResultFlowResult>
  455. </div>
  456. </div>
  457. <Modal
  458. open={editModalVisible}
  459. onCancel={editModalCancel}
  460. footer={null}
  461. className="device-detail"
  462. title={'设备详情'}
  463. >
  464. <div className="device-detail-container">
  465. <Tabs
  466. className="yisa-tabs"
  467. defaultActiveKey={1}
  468. destroyInactiveTabPane={true}
  469. items={[
  470. {
  471. label: `设备基本信息`,
  472. key: 1,
  473. children: (
  474. <>
  475. <div className="device-detail-wrapper">
  476. <div className="device-row">
  477. <div className="device-item">
  478. <div className="device-label">设备名称</div>
  479. <div className="device-content">{deviceDetail.name}</div>
  480. </div>
  481. <div className="device-item">
  482. <div className="device-label">硬件编码</div>
  483. <div className="device-content">{deviceDetail.code}</div>
  484. </div>
  485. </div>
  486. <div className="device-row">
  487. <div className="device-item">
  488. <div className="device-label">设备类型</div>
  489. <div className="device-content">{deviceDetail.type_name}</div>
  490. </div>
  491. <div className="device-item">
  492. <div className="device-label">设备品牌</div>
  493. <div className="device-content">{deviceDetail.brand_name}</div>
  494. </div>
  495. </div>
  496. <div className="device-row">
  497. <div className="device-item">
  498. <div className="device-label">设备功能</div>
  499. <div className="device-content">{deviceDetail.function}</div>
  500. </div>
  501. <div className="device-item">
  502. <div className="device-label">备注</div>
  503. <div className="device-content">{deviceDetail.note}</div>
  504. </div>
  505. </div>
  506. <div className="device-row">
  507. <div className="device-item">
  508. <div className="device-label">对应泊位号</div>
  509. <div className="device-content">{deviceDetail.berth}</div>
  510. </div>
  511. <div className="device-item">
  512. <div className="device-label"></div>
  513. <div className="device-content"></div>
  514. </div>
  515. </div>
  516. </div>
  517. </>
  518. )
  519. },
  520. {
  521. label: `设备运营信息`,
  522. key: 2,
  523. children: (
  524. <>
  525. <div className="device-detail-wrapper">
  526. <div className="device-row">
  527. <div className="device-item">
  528. <div className="device-label">设备厂商</div>
  529. <div className="device-content">{deviceDetail.brand_name}</div>
  530. </div>
  531. <div className="device-item">
  532. <div className="device-label">运营状态</div>
  533. <div className="device-content">{deviceDetail.operate_status}</div>
  534. </div>
  535. </div>
  536. <div className="device-row">
  537. <div className="device-item">
  538. <div className="device-label">设备状态</div>
  539. <div className="device-content">
  540. <div className={(deviceDetail.device_status == '在线' || deviceDetail.device_status == '上线') ? 'text-online' : 'text-offline'}>{deviceDetail.device_status}</div>
  541. </div>
  542. </div>
  543. <div className="device-item">
  544. <div className="device-label">状态变更时间</div>
  545. <div className="device-content">{deviceDetail.status_change_time}</div>
  546. </div>
  547. </div>
  548. </div>
  549. </>
  550. )
  551. },
  552. ]}
  553. />
  554. </div>
  555. </Modal>
  556. </div>
  557. </>
  558. )
  559. }
  560. export default Road;