停车场项目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.

1315 lines
55 KiB

  1. import React, { useState, useRef, useEffect } from "react";
  2. import {
  3. message,
  4. Pagination,
  5. Table,
  6. Input,
  7. Space,
  8. Modal,
  9. Button,
  10. Select,
  11. Tabs,
  12. Descriptions,
  13. Timeline
  14. } from "antd";
  15. const { TextArea } = Input;
  16. import moment from "moment";
  17. import errorImg from '@/assets/images/error-img-new.png'
  18. import ajax from '@/config/ajax.js'
  19. import { TableModule, QuickMenu } from "@/components";
  20. import {
  21. bindColumns,
  22. modiColumns,
  23. formRefundColumns
  24. } from "./dataSource";
  25. import { dictionary } from "@/config/common.js";
  26. import "./index.scss";
  27. import { useSessionStorageState } from 'ahooks';
  28. function CarInfo() {
  29. const [carId, setCarId] = useState()
  30. const columns = [
  31. {
  32. title: "序号",
  33. dataIndex: "index",
  34. key: "index",
  35. align: "center",
  36. fixed: "left",
  37. render: (text, record, index) => index + 1,
  38. width: 100,
  39. },
  40. {
  41. title: "车牌号",
  42. dataIndex: "plate_number",
  43. key: "plate_number",
  44. fixed: "right",
  45. align: "center",
  46. },
  47. {
  48. title: "会员姓名",
  49. dataIndex: "name",
  50. key: "name",
  51. fixed: "right",
  52. align: "center",
  53. },
  54. {
  55. title: "会员手机号",
  56. dataIndex: "mobile",
  57. key: "mobile",
  58. fixed: "right",
  59. align: "center",
  60. },
  61. {
  62. title: "PDA录入号码",
  63. dataIndex: "pda_mobile",
  64. key: "pda_mobile",
  65. fixed: "right",
  66. align: "center",
  67. },
  68. {
  69. title: "行驶本认证",
  70. dataIndex: "authStateName",
  71. key: "authStateName",
  72. fixed: "right",
  73. align: "center",
  74. },
  75. {
  76. title: "欠费金额",
  77. dataIndex: "arrears_money",
  78. key: "arrears_money",
  79. fixed: "right",
  80. align: "center",
  81. },
  82. {
  83. title: "创建时间",
  84. dataIndex: "create_time",
  85. key: "create_time",
  86. fixed: "right",
  87. align: "center",
  88. },
  89. {
  90. title: "操作",
  91. dataIndex: "operation",
  92. key: "operation",
  93. fixed: "right",
  94. align: "center",
  95. render: (text, record) => (
  96. <>
  97. <span type="primary" style={{ display: 'block', textAlign: 'center' }} onClick={() => {
  98. setCarId(record.carId);
  99. searchDetail(record);
  100. }}>
  101. <a>详情</a>
  102. </span>
  103. </>
  104. ),
  105. },
  106. ];
  107. //构建表头
  108. const createCol = (label, name, type) => {
  109. label.length == name.length ? null : console.log('参数缺失', label, label.length, name.length)
  110. var arr = []
  111. label?.map((item, index) => {
  112. let cm = {
  113. title: item,
  114. dataIndex: name[index],
  115. key: name[index],
  116. align: "center",
  117. }
  118. switch (item) {
  119. case "序号":
  120. cm.render = (text, record, index) => index + 1
  121. break
  122. case "退款订单ID":
  123. case "业务订单ID":
  124. case "支付订单ID":
  125. cm.render = (text) => (
  126. <>
  127. <a onClick={() => {
  128. navigator.clipboard.writeText(`${text}`).then(() => { message.success("已复制到剪切板") });
  129. }}>{text}</a>
  130. </>
  131. )
  132. break
  133. default: break
  134. }
  135. arr.push(cm)
  136. })
  137. var obj = {
  138. title: "操作",
  139. dataIndex: "operation",
  140. key: "operation",
  141. fixed: "right",
  142. align: "center",
  143. }
  144. switch (type) {
  145. case 2:
  146. obj.render = (text, record) => (<>
  147. <span type="primary" style={{ display: 'block', textAlign: 'center' }} onClick={() => {
  148. setYcddData(record)
  149. setDetailVisible(true)
  150. }}>
  151. <a>详情</a>
  152. </span>
  153. </>)
  154. arr.push(obj)
  155. break
  156. case 5:
  157. obj.render = (text, record) => (<>
  158. <span type="primary" style={{ display: 'block', textAlign: 'center' }} onClick={() => {
  159. refundSearch(record)
  160. setTkddVisible(true)
  161. }}>
  162. <a>详情</a>
  163. </span>
  164. </>)
  165. arr.push(obj)
  166. break
  167. case 6:
  168. obj.render = (text, record) => (<>
  169. <span type="primary" style={{ display: 'block', textAlign: 'center' }} onClick={() => {
  170. setTkddVisible(true)
  171. }}>
  172. <a>详情</a>
  173. </span>
  174. </>)
  175. arr.push(obj)
  176. break
  177. case 7:
  178. obj.render = (text, record) => (<>
  179. <span type="primary" style={{ display: 'block', textAlign: 'center' }} onClick={() => {
  180. setTkddVisible(true)
  181. }}>
  182. <a>详情</a>
  183. </span>
  184. </>)
  185. arr.push(obj)
  186. break
  187. case 8:
  188. obj.render = (text, record) => (<>
  189. <span type="primary" style={{ display: 'block', textAlign: 'center' }} onClick={() => {
  190. }}>
  191. <a>详情</a>
  192. </span>
  193. </>)
  194. arr.push(obj)
  195. break
  196. default: break
  197. }
  198. return arr
  199. }
  200. //基本信息检索条件
  201. const formSearch = [
  202. {
  203. name: "carId",
  204. type: "PlateSelect",
  205. label: "车牌号",
  206. placeholder: "请输入车牌号",
  207. },
  208. {
  209. name: "mobile",
  210. type: "Input",
  211. label: "会员手机号",
  212. placeholder: "请输入会员手机号",
  213. },
  214. {
  215. name: "authState",
  216. type: "Select",
  217. label: "认证状态",
  218. options: [
  219. {
  220. label: "已认证",
  221. value: 2,
  222. },
  223. {
  224. label: "未认证",
  225. value: 1,
  226. },
  227. ],
  228. },
  229. {
  230. name: "bingState",
  231. type: "Select",
  232. label: "绑定状态",
  233. options: [
  234. {
  235. label: "已绑定",
  236. value: 0,
  237. },
  238. {
  239. label: "未绑定",
  240. value: 1,
  241. },
  242. ],
  243. },
  244. {
  245. name: "timePeriod",
  246. type: "RangePicker",
  247. label: "时间段",
  248. defaultValue: [moment().subtract(89, "day"), moment()],
  249. },
  250. ];
  251. //退费记录检索条件
  252. const formRefundSearch = [
  253. {
  254. name: "refund_id",
  255. type: "Input",
  256. label: "退款订单号",
  257. placeholder: "请输入退款订单号",
  258. },
  259. {
  260. name: "type",
  261. type: "Select",
  262. label: "业务订单类型",
  263. options: sysConfig.businessOrderType,
  264. },
  265. {
  266. name: "park_id",
  267. type: "Input",
  268. label: "业务订单ID",
  269. placeholder: "请输入业务订单ID",
  270. },
  271. {
  272. name: "order_id",
  273. type: "Input",
  274. label: "支付订单ID",
  275. placeholder: "请输入支付订单ID",
  276. },
  277. {
  278. name: "state",
  279. type: "Select",
  280. label: "退款状态",
  281. options: [
  282. {
  283. label: "全部",
  284. value: 0,
  285. },
  286. {
  287. label: "待确认",
  288. value: 1,
  289. },
  290. {
  291. label: "退款中",
  292. value: 2,
  293. },
  294. {
  295. label: "已完成",
  296. value: 3,
  297. },
  298. {
  299. label: "退款失败",
  300. value: 4,
  301. },
  302. ],
  303. },
  304. {
  305. name: "reason",
  306. type: "Select",
  307. label: "退款原因",
  308. options: [
  309. {
  310. label: "全部",
  311. value: 0,
  312. },
  313. {
  314. label: "异常订单处理",
  315. value: 1,
  316. },
  317. {
  318. label: "自动平单退款",
  319. value: 2,
  320. },
  321. ],
  322. },
  323. {
  324. name: "flow_id",
  325. type: "Input",
  326. label: "渠道流水号",
  327. placeholder: "请输入渠道流水号",
  328. },
  329. {
  330. name: "timePeriod",
  331. type: "RangePicker",
  332. label: "时间段",
  333. defaultTitle: ['退款时间', '至'],
  334. defaultValue: [moment().subtract(1, "month"), moment()],
  335. },
  336. ];
  337. //所有检索条件
  338. const ash = [
  339. {//1
  340. name: "region",
  341. type: "TreeSelect",
  342. label: "区域",
  343. },
  344. {//2
  345. name: "operator",
  346. type: "Select",
  347. label: "商户名称",
  348. options: dictionary.MerchantName,
  349. },
  350. {//3
  351. name: "road",
  352. type: "SearchSelect",
  353. label: "停车场名称",
  354. id: 2,
  355. placeholder: "请输入停车场名称",
  356. },
  357. {//4
  358. name: "road_type",
  359. type: "Select",
  360. label: "车场类型",
  361. options: [
  362. {
  363. label: "全部",
  364. value: 0,
  365. },
  366. {
  367. label: "路侧平行",
  368. value: 1,
  369. },
  370. {
  371. label: "路侧垂停",
  372. value: 2,
  373. },
  374. {
  375. label: "封闭车场",
  376. value: 3,
  377. },
  378. {
  379. label: "半封闭车场",
  380. value: 4,
  381. },
  382. ],
  383. },
  384. {//5
  385. name: "phone",
  386. type: "Input",
  387. label: "手机号",
  388. placeholder: "请输入手机号",
  389. },
  390. {//6
  391. name: "type",
  392. type: "Select",
  393. label: "出入场类型",
  394. placeholder: "请选择出入场类型",
  395. defaultValue: 1,
  396. options: [
  397. {
  398. label: "入场",
  399. value: 1,
  400. },
  401. {
  402. label: "出场",
  403. value: 2,
  404. },
  405. ],
  406. },
  407. {//7
  408. name: "b",
  409. type: "Input",
  410. label: "商品名称",
  411. placeholder: "请输入商品名称",
  412. },
  413. {//8
  414. name: "b",
  415. type: "Select",
  416. label: "购买渠道",
  417. placeholder: "请选择购买渠道",
  418. options: [
  419. {
  420. label: "全部",
  421. value: 0,
  422. },
  423. {
  424. label: "线上渠道",
  425. value: 1,
  426. },
  427. {
  428. label: "后台录入",
  429. value: 2,
  430. },
  431. ],
  432. },
  433. {//9
  434. name: "b",
  435. type: "Select",
  436. label: "订单状态",
  437. placeholder: "请选择订单状态",
  438. options: [
  439. {
  440. label: "全部",
  441. value: 0,
  442. },
  443. {
  444. label: "未生效",
  445. value: 1,
  446. },
  447. {
  448. label: "生效中",
  449. value: 2,
  450. },
  451. {
  452. label: "已失效",
  453. value: 3,
  454. },
  455. ],
  456. },
  457. {//10
  458. name: "PayChannel",
  459. type: "Select",
  460. label: "支付渠道",
  461. placeholder: "请选择支付渠道",
  462. options: dictionary.PayChannel,
  463. },
  464. {//11
  465. name: "payment_equipment",
  466. type: "Select",
  467. label: "支付设备",
  468. placeholder: "请选择支付设备",
  469. options: dictionary.PayDevice
  470. },
  471. {//12
  472. name: "pay_type",
  473. type: "Select",
  474. label: "支付方式",
  475. placeholder: "请选择支付方式",
  476. options: dictionary.PaydMethod,
  477. },
  478. {//13
  479. name: "timePeriod",
  480. type: "RangePicker",
  481. label: "时间段",
  482. defaultValue: [moment().subtract(1, "month"), moment()],
  483. },
  484. {//14
  485. name: "b",
  486. type: "Select",
  487. label: "退款方式",
  488. placeholder: "请选择退款方式",
  489. options: dictionary.PaydMethod,
  490. },
  491. {//15
  492. name: "b",
  493. type: "Input",
  494. label: "第三方流水号",
  495. placeholder: "请输入第三方流水号",
  496. },
  497. {//16
  498. name: "timePeriod",
  499. type: "RangePicker",
  500. label: "时间段",
  501. defaultTitle: ['支付时间', '至']
  502. // defaultValue: [moment().startOf("day"), moment()],
  503. },
  504. {//17
  505. name: "timePeriod",
  506. type: "RangePicker",
  507. label: "时间段",
  508. defaultTitle: ['订购时间', '至']
  509. // defaultValue: [moment().startOf("day"), moment()],
  510. },
  511. {//18
  512. name: "timePeriod",
  513. type: "RangePicker",
  514. label: "时间段",
  515. defaultTitle: ['预约到场时间', '至']
  516. // defaultValue: [moment().startOf("day"), moment()],
  517. },
  518. {//19
  519. name: "plate",
  520. type: "Input",
  521. label: "车牌号",
  522. placeholder: "请输入车牌号",
  523. },
  524. ];
  525. const [sessionTabList, setSessionTablist] = useSessionStorageState('carInfo', {
  526. value: ''
  527. })
  528. const [tag, setTag] = useState('1');
  529. const [edit, setEdit] = useState(true);
  530. const [resultData, setResultData] = useState([])
  531. const [baseData, setBaseData] = useState({
  532. //car_type:2
  533. })
  534. const [bindData, setBindData] = useState([])//绑定
  535. const [modiData, setModiData] = useState([])//修改
  536. const [detailData, setDetailData] = useState([])//
  537. const [ycddData, setYcddData] = useState([])//异常订单数据
  538. const [detailVisible, setDetailVisible] = useState(false);
  539. const [ltcVisible, setLtcVisible] = useState(false);
  540. const [timesVisible, setTimesVisible] = useState(false); //退款尝试次数展开
  541. const [ycddVisible, setYcddVisible] = useState(false);
  542. const [tkddVisible, setTkddVisible] = useState(false);
  543. const [cardVisible, setCardVisible] = useState(false);
  544. const [eaeVisible, setEaeVisible] = useState(false);//出入场图片
  545. const [bigpicVisible, setBigpicVisible] = useState(false);//大图展示
  546. const [bigPic, setBigPic] = useState();
  547. const [total, setTotal] = useState(0);
  548. const [tabKey, setTabKey] = useState("1");
  549. const [stopCarTab,setStopCarTop]=useState("1")
  550. function openModal(params) {
  551. setDetailVisible(true);
  552. }
  553. function changeKey(key) {
  554. setTabKey(key);
  555. }
  556. //基本信息查询
  557. function search(e) {
  558. // if (!e.type) {
  559. // e.type = 1
  560. // }
  561. ajax({
  562. url: "/api/ope/car/list",
  563. type: "post",
  564. data: { ...e },
  565. }).then((res) => {
  566. let { status, data, total } = res
  567. if (status == 20000) {
  568. setResultData(data)
  569. setTotal(total)
  570. } else {
  571. message.error(res.message)
  572. }
  573. })
  574. }
  575. //基本信息详情
  576. function searchDetail(e) {
  577. ajax({
  578. url: "/api/ope/car/get_base_info",
  579. type: "get",
  580. data: { carId: e?.carId || carId },
  581. }).then((res) => {
  582. let { status, data, total } = res
  583. if (status == 20000) {
  584. setBaseData(data)
  585. setTag('2')
  586. } else {
  587. message.error(res.message)
  588. }
  589. })
  590. ajax({//绑定
  591. url: "/api/ope/car/get_bind_records",
  592. type: "get",
  593. data: { carId: e?.carId || carId },
  594. }).then((res) => {
  595. let { status, data, total } = res
  596. if (status == 20000) {
  597. setBindData(data)
  598. } else {
  599. message.error(res.message)
  600. }
  601. })
  602. ajax({//修改数据
  603. url: "/api/ope/car/get_edit_records",
  604. type: "get",
  605. data: { carId: e?.carId || carId },
  606. }).then((res) => {
  607. let { status, data, total } = res
  608. if (status == 20000) {
  609. setModiData(data)
  610. } else {
  611. message.error(res.message)
  612. }
  613. })
  614. }
  615. //编辑车辆外观信息
  616. function editDetail() {
  617. ajax({
  618. url: "/api/ope/car/edit_car",
  619. type: "post",
  620. data: {
  621. carId: baseData.carId,
  622. car_brand: baseData.car_brand,
  623. car_model: baseData.car_model,
  624. car_color: baseData.car_color,
  625. car_type: baseData.car_type,
  626. plate_type: baseData.plate_type,
  627. },
  628. }).then((res) => {
  629. let { status, data } = res
  630. if (status == 20000) {
  631. setEdit(true)
  632. //window.location.reload()
  633. //setTag('2')
  634. searchDetail()
  635. } else {
  636. message.error(res.message)
  637. }
  638. })
  639. }
  640. //详情其他模块查询
  641. function searchOther(e) {
  642. var url = ''
  643. switch (tabKey) {
  644. case "1":
  645. url = ""
  646. break
  647. case "2":
  648. url = "/api/bpm/record/get_record_list"//停车记录
  649. break
  650. case "3":
  651. url = "/api/bpm/record/get_parking_arrears_list"//欠费记录
  652. break
  653. case "4":
  654. url = "/api/bpm/record/get_payment_list"//支付记录
  655. break
  656. case "5":
  657. url = "/api/ope/record/get_refund_list"//退费订单
  658. break
  659. case "6":
  660. url = ""
  661. break
  662. case "7":
  663. url = ""
  664. break
  665. case "8":
  666. url = ""
  667. break
  668. default: break
  669. }
  670. if (tabKey == '3' && e && !e?.type) {
  671. e.type = 1
  672. }
  673. ajax({
  674. url: url,
  675. type: "post",
  676. data: { ...e, carId: carId, startTime: e?.start_time, endTime: e?.end_time },
  677. }).then((res) => {
  678. let { status, data, total } = res
  679. if (status == 20000) {
  680. if (data.list) {
  681. setResultData(data.list)
  682. setTotal(data.total)
  683. } else {
  684. setResultData(data)
  685. setTotal(total)
  686. }
  687. } else {
  688. setResultData([])
  689. message.error(res.message)
  690. }
  691. })
  692. }
  693. //退款订单详情
  694. function refundSearch(e) {
  695. ajax({
  696. url: "/api/ope/record/get_refund_info",
  697. type: "get",
  698. data: { id: e.refund_id },
  699. }).then((res) => {
  700. let { status, data } = res
  701. if (status == 20000) {
  702. //setResultData(data)
  703. setYcddData(data)
  704. } else {
  705. message.error(res.message)
  706. }
  707. })
  708. }
  709. //停车记录信息渲染
  710. function renderParkRecord(params) {
  711. return (
  712. <div className="ltc-box">
  713. <div className="ltc-box-title"><div className="text">停车场信息</div><div className="line"></div></div>
  714. <div className="ltc-content">
  715. <div className="ltc-item">
  716. <div className="new-item">停车场名称</div><div className="new-value">{params?.road || "--"}</div>
  717. </div>
  718. <div className="ltc-item">
  719. <div className="new-item">泊位号</div><div className="new-value">{params.berth_id || "--"}</div>
  720. </div>
  721. <div className="ltc-item">
  722. <div className="new-item">区域</div><div className="new-value">{params.region || "--"}</div>
  723. </div>
  724. <div className="ltc-item">
  725. <div className="new-item">商户</div><div className="new-value">{params.operator || "--"}</div>
  726. </div>
  727. <div className="ltc-item">
  728. <div className="new-item">车场类型</div><div className="new-value">{params.road_type || "--"}</div>
  729. </div>
  730. </div>
  731. <div className="ltc-box-title"><div className="text">停车信息</div><div className="line"></div></div>
  732. <div className="ltc-content">
  733. <div className="ltc-item">
  734. <div className="new-item">车牌号</div><div className="new-value">{params.plate || "--"}</div>
  735. </div>
  736. <div className="ltc-item">
  737. <div className="new-item">会员手机号</div><div className="new-value">{params.phone || "--"}</div>
  738. </div>
  739. <div className="ltc-item">
  740. <div className="new-item">入场时间</div><div className="new-value">{params.in_time || "--"}</div>
  741. </div>
  742. <div className="ltc-item">
  743. <div className="new-item">出场时间</div><div className="new-value">{params.out_time || "--"}</div>
  744. </div>
  745. <div className="ltc-item">
  746. <div className="new-item">停车时长</div><div className="new-value">{params.admission_time || "--"}</div>
  747. </div>
  748. <div className="ltc-item">
  749. <div className="new-item">订单金额</div><div className="new-value">{params.order_amount || "--"}</div>
  750. </div>
  751. <div className="ltc-item">
  752. <div className="new-item">停车卡折扣</div><div className="new-value">{params.parking_card_discount || "--"}</div>
  753. </div>
  754. <div className="ltc-item">
  755. <div className="new-item">车场折扣</div><div className="new-value">{params.road_discount || "--"}</div>
  756. </div>
  757. <div className="ltc-item">
  758. <div className="new-item">应收金额</div><div className="new-value">{params.receivable_amount || "--"}</div>
  759. </div>
  760. <div className="ltc-item">
  761. <div className="new-item">优惠券</div><div className="new-value">{params.preferential_amount || "--"}</div>
  762. </div>
  763. <div className="ltc-item">
  764. <div className="new-item">优惠总计</div><div className="new-value">{params.preferential_total || "--"}</div>
  765. </div>
  766. <div className="ltc-item">
  767. <div className="new-item">实付金额</div><div className="new-value">{params.actual_amount || "--"}</div>
  768. </div>
  769. <div className="ltc-item">
  770. <div className="new-item">优惠退款</div><div className="new-value">{params.refund_discount || "--"}</div>
  771. </div>
  772. <div className="ltc-item">
  773. <div className="new-item">实付退款</div><div className="new-value">{params.actual_refund || "--"}</div>
  774. </div>
  775. <div className="ltc-item">
  776. <div className="new-item">退款总计</div><div className="new-value">{params.refund_total || "--"}</div>
  777. </div>
  778. <div className="ltc-item">
  779. <div className="new-item">入场收费员</div><div className="new-value">{params.in_person || "--"}</div>
  780. </div>
  781. <div className="ltc-item">
  782. <div className="new-item">出场收费员</div><div className="new-value">{params.out_person || "--"}</div>
  783. </div>
  784. </div>
  785. <div className="ltc-box-title"><div className="text">入场照片</div><div className="line"></div></div>
  786. <div className="ltc-content">
  787. <div className="ltc-item ltc-item-img ">
  788. <img src={params.in_veh_pic} onError={handleImgError} onClick={() => { setBigPic(params.in_veh_pic); setBigpicVisible(true) }} />
  789. </div>
  790. <div className="ltc-item ltc-item-img ">
  791. <img src={params.in_plate_pic} onError={handleImgError} onClick={() => { setBigPic(params.in_plate_pic); setBigpicVisible(true) }} />
  792. </div>
  793. </div>
  794. </div>
  795. );
  796. }
  797. //基本信息渲染
  798. function renderRecord(params) {
  799. return (
  800. <div style={{ padding: '18px' }}>
  801. <div className="base-ltc">
  802. <div className="ltc-img">
  803. <img src={baseData.car_img || require("../../../../../src/assets/images/error-img.png")} onError={handleImgError} width={600} />
  804. </div>
  805. <div className="ltc-box">
  806. <div className="ltc-box-title"><div className="ltc-icon"></div>车辆归属信息</div>
  807. <div className="ltc-content">
  808. <div className="ltc-item">
  809. <div className="new-item">车牌颜色</div>
  810. <div className="new-value">{baseData.plate_color || "--"}</div>
  811. </div>
  812. <div className="ltc-item">
  813. <div className="new-item">车牌号:</div>
  814. <div className="new-value">{baseData.plate_number || "--"}</div>
  815. </div>
  816. <div className="ltc-item">
  817. <div className="new-item">绑定会员账户:</div>
  818. <div className="new-value">{baseData.mobile || "--"}</div>
  819. </div>
  820. <div className="ltc-item">
  821. <div className="new-item">认证状态:</div>
  822. <div className="new-value"> {baseData.authStateName || "--"}</div>
  823. </div>
  824. <div className="ltc-item">
  825. <div className="new-item">车牌归属地:</div>
  826. <div className="new-value"> {baseData.home_location || "--"}</div>
  827. </div>
  828. <div className="ltc-item">
  829. <div className="new-item">创建时间:</div>
  830. <div className="new-value">{baseData.create_time || "--"}</div>
  831. </div>
  832. </div>
  833. <div className="ltc-box-title">
  834. <div className="ltc-icon"></div>车辆外观信息
  835. {
  836. edit ? <div className="ltc-btn" onClick={() => { setEdit(false) }}>编辑</div> :
  837. <>
  838. <div className="ltc-btn" onClick={() => { editDetail(); }}>保存</div>
  839. <div className="ltc-btn ltc-cancel" onClick={() => { setEdit(true) }}>取消</div>
  840. </>
  841. }
  842. </div>
  843. <div className="ltc-content">
  844. <div className="ltc-item">
  845. <div className="new-item">车辆品牌</div>
  846. <Input className="ltc-item-input" value={baseData.car_brand} onChange={(e) => { setBaseData({ ...baseData, car_brand: e.target.value }) }} placeholder="请输入车辆品牌" disabled={edit}></Input>
  847. </div>
  848. <div className="ltc-item">
  849. <div className="new-item">车辆型号</div>
  850. <Input className="ltc-item-input" value={baseData.car_model} onChange={(e) => { setBaseData({ ...baseData, car_model: e.target.value }) }} placeholder="请输入车辆型号" disabled={edit}></Input>
  851. </div>
  852. <div className="ltc-item">
  853. <div className="new-item">车身颜色</div>
  854. <Input className="ltc-item-input" value={baseData.car_color} onChange={(e) => { setBaseData({ ...baseData, car_color: e.target.value }) }} placeholder="请输入车身颜色" disabled={edit}></Input>
  855. </div>
  856. <div className="ltc-item">
  857. <div className="new-item"> 车辆类型</div>
  858. <Select
  859. disabled={edit}
  860. defaultValue={baseData.car_type}
  861. onChange={(v) => setBaseData({ ...baseData, car_type: v })}
  862. options={sysConfig.vehicleTypeNOAll}
  863. placeholder={''}
  864. />
  865. </div>
  866. <div className="ltc-item">
  867. <div className="new-item">号牌类型</div>
  868. <Select
  869. disabled={edit}
  870. options={sysConfig.plateType}
  871. onChange={(v) => setBaseData({ ...baseData, plate_type: v })}
  872. defaultValue={baseData?.plate_type}
  873. placeholder={''}
  874. />
  875. </div>
  876. </div>
  877. </div>
  878. </div>
  879. <div className="ltc-box">
  880. <div className="ltc-box-title"><div className="ltc-icon"></div>车辆绑定记录</div>
  881. <div className="table-wrap">
  882. <Table
  883. columns={bindColumns}
  884. dataSource={bindData}
  885. scroll={{ x: 1000 }}
  886. // className="yisa-table"
  887. pagination={false}
  888. rowKey={(record) => record.id}
  889. />
  890. </div>
  891. <div className="ltc-box-title"><div className="ltc-icon"></div>车辆信息修改记录</div>
  892. <Table
  893. columns={modiColumns}
  894. dataSource={modiData}
  895. scroll={{ x: 1000 }}
  896. // className="yisa-table"
  897. pagination={false}
  898. rowKey={(record) => record.id}
  899. />
  900. </div>
  901. </div>
  902. );
  903. }
  904. //其他页面渲染
  905. function renderTable(columns, arr, dataSource, exportUrl ) {
  906. return (
  907. <TableModule
  908. columns={columns}
  909. tableData={dataSource}
  910. formSearch={arr}
  911. total={total}
  912. search={searchOther}
  913. isExport={exportUrl ? true : false}
  914. exportUrl={exportUrl}
  915. export_other={{carId:carId}}
  916. rowKey={(record) => record.id}
  917. />
  918. );
  919. }
  920. const handleImgError = (e) => {
  921. let evn = e || event
  922. let img = evn.srcElement ? evn.srcElement : evn.target
  923. img.src = errorImg
  924. }
  925. //退款订单详情
  926. const tkddModal = <div className="ltc-box">
  927. <div className="ltc-box-title"><div className="text">退款订单:{ycddData?.refund_id}</div><div className="line"></div></div>
  928. <div className="ltc-content">
  929. <div className="ltc-item">
  930. <div className="new-item">生成时间</div><div className="new-value">{ycddData?.refund_time || "--"}</div>
  931. </div>
  932. <div className="ltc-item">
  933. <div className="new-item">退款状态</div><div className="new-value">{ycddData.refund_state || "--"}</div>
  934. </div>
  935. <div className="ltc-item">
  936. <div className="new-item">支付渠道</div><div className="new-value">{ycddData.payment_channels || "--"}</div>
  937. </div>
  938. <div className="ltc-item">
  939. <div className="new-item">退款方式</div><div className="new-value">{ycddData.refund_type || "--"}</div>
  940. </div>
  941. <div className="ltc-item">
  942. <div className="new-item">应退实付金额</div><div className="new-value">{ycddData.refund_actual_amount || "--"}</div>
  943. </div>
  944. <div className="ltc-item">
  945. <div className="new-item">已退实付金额</div><div className="new-value">{ycddData.has_refund_actual_amount || "--"}</div>
  946. </div>
  947. <div className="ltc-item">
  948. <div className="new-item">应退优惠金额</div><div className="new-value">{ycddData.refund_discount_amount || "--"}</div>
  949. </div>
  950. <div className="ltc-item">
  951. <div className="new-item">已退优惠金额</div><div className="new-value">{ycddData.has_refund_discount_amount || "--"}</div>
  952. </div>
  953. <div className="ltc-item">
  954. <div className="new-item">退款尝试次数</div><div className="new-value">{ycddData.try_count || "--"}
  955. {timesVisible ?
  956. <a onClick={() => { setTimesVisible(false) }}>收起</a> :
  957. <a onClick={() => { setTimesVisible(true) }}>查看</a>}
  958. </div>
  959. </div>
  960. <div className="ltc-item">
  961. <div className="new-item">最近尝试时间</div><div className="new-value">{ycddData.latest_try_time || "--"}</div>
  962. </div>
  963. </div>
  964. {timesVisible ? <>
  965. <div className="ltc-box-title"><div className="text">退款尝试详情</div><div className="line"></div></div>
  966. <Table
  967. columns={formRefundColumns}
  968. dataSource={ycddData.try_list}
  969. scroll={{ x: 1000 }}
  970. // className="yisa-table"
  971. pagination={false}
  972. rowKey={(record) => record.id}
  973. /> </> :
  974. <>
  975. <div className="ltc-box-title"><div className="text">支付订单:{ycddData.order_id}</div><div className="line"></div></div>
  976. <div className="ltc-content">
  977. <div className="ltc-item">
  978. <div className="new-item">平台商户</div><div className="new-value">{ycddData.payment_operator_name}</div>
  979. </div>
  980. <div className="ltc-item">
  981. <div className="new-item">生成时间</div><div className="new-value">{ycddData.payment_create_time}</div>
  982. </div>
  983. <div className="ltc-item">
  984. <div className="new-item">支付时间</div><div className="new-value">{ycddData.pay_time}</div>
  985. </div>
  986. <div className="ltc-item">
  987. <div className="new-item">支付渠道</div><div className="new-value">{ycddData.payment_equipment}</div>
  988. </div>
  989. <div className="ltc-item">
  990. <div className="new-item">优惠金额</div><div className="new-value">{ycddData.discount_amount}</div>
  991. </div>
  992. <div className="ltc-item">
  993. <div className="new-item">支付应用</div><div className="new-value">{ycddData.payment_equipment}</div>
  994. </div>
  995. <div className="ltc-item">
  996. <div className="new-item">实付金额</div><div className="new-value">{ycddData.paid_in_money}</div>
  997. </div>
  998. </div>
  999. <div className="ltc-box-title"><div className="text">停车订单:{ycddData.park_record_id}</div><div className="line"></div></div>
  1000. <div className="ltc-box-title"><div className="text">车厂详情</div></div>
  1001. <div className="ltc-content">
  1002. <div className="ltc-item">
  1003. <div className="new-item">平台商户</div><div className="new-value">{ycddData.payment_operator_name}</div>
  1004. </div>
  1005. <div className="ltc-item">
  1006. <div className="new-item">停车场名称</div><div className="new-value">{ycddData?.road_name}</div>
  1007. </div>
  1008. <div className="ltc-item">
  1009. <div className="new-item">区域</div><div className="new-value">{ycddData.area_name}</div>
  1010. </div>
  1011. <div className="ltc-item">
  1012. <div className="new-item">商户名称</div><div className="new-value">{ycddData.park_operator_name}</div>
  1013. </div>
  1014. <div className="ltc-item">
  1015. <div className="new-item">泊位号</div><div className="new-value">{ycddData.berth_code}</div>
  1016. </div>
  1017. <div className="ltc-item">
  1018. <div className="new-item">车场类型</div><div className="new-value">{ycddData.road_type}</div>
  1019. </div>
  1020. </div>
  1021. <div className="ltc-box-title"><div className="text">车辆详情</div></div>
  1022. <div className="ltc-content">
  1023. <div className="ltc-item">
  1024. <div className="new-item">车牌号</div><div className="new-value">{ycddData.plate_number}</div>
  1025. </div>
  1026. <div className="ltc-item">
  1027. <div className="new-item">停车时长</div><div className="new-value">{ycddData.parking_duration}</div>
  1028. </div>
  1029. <div className="ltc-item">
  1030. <div className="new-item">入场时间</div><div className="new-value">{ycddData.in_time}</div>
  1031. </div>
  1032. <div className="ltc-item">
  1033. <div className="new-item">出场时间</div><div className="new-value">{ycddData.out_time}</div>
  1034. </div>
  1035. <div className="ltc-item">
  1036. <div className="new-item">入场记录来源</div><div className="new-value">{ycddData.inSource}</div>
  1037. </div>
  1038. <div className="ltc-item">
  1039. <div className="new-item">出场记录来源</div><div className="new-value">{ycddData.outSource}</div>
  1040. </div>
  1041. <div className="ltc-item">
  1042. <div className="new-item">证据图像</div><div className="new-value"><a onClick={() => { setEaeVisible(true) }}>查看</a></div>
  1043. </div>
  1044. </div>
  1045. </>}
  1046. </div>
  1047. //停车卡详情
  1048. const tckModal = <div className="ltc-box">
  1049. <div className="ltc-box-title">订单信息:</div>
  1050. <div className="ltc-box-line"></div>
  1051. <Descriptions title="">
  1052. <Descriptions.Item label="订单状态">{ycddData?.t || "--"}</Descriptions.Item>
  1053. <Descriptions.Item label="支付时间">{ycddData.r || "--"}</Descriptions.Item>
  1054. <Descriptions.Item label="车牌号">{ycddData.o || "--"}</Descriptions.Item>
  1055. <Descriptions.Item label="车牌颜色">{ycddData.r || "--"}</Descriptions.Item>
  1056. <Descriptions.Item label="手机号">{ycddData.mobile || "--"}</Descriptions.Item>
  1057. <Descriptions.Item label="购买渠道">{ycddData.r || "--"}</Descriptions.Item>
  1058. <Descriptions.Item label="实付金额">{ycddData.r || "--"}</Descriptions.Item>
  1059. <Descriptions.Item label="支付渠道">{ycddData.r || "--"}</Descriptions.Item>
  1060. <Descriptions.Item label="支付设备">{ycddData.r || "--"}</Descriptions.Item>
  1061. </Descriptions>
  1062. <div className="ltc-box-title">商品信息:</div>
  1063. <div className="ltc-box-line"></div>
  1064. <Descriptions title="">
  1065. <Descriptions.Item label="商品名称">{ycddData.plate}</Descriptions.Item>
  1066. <Descriptions.Item label="商户名称">{ycddData.admission_time}</Descriptions.Item>
  1067. <Descriptions.Item label="适用范围">{ycddData.in_time}</Descriptions.Item>
  1068. <Descriptions.Item label="生效开始日期">{ycddData.out_time}</Descriptions.Item>
  1069. <Descriptions.Item label="有效天数">{ycddData.in_source}</Descriptions.Item>
  1070. <Descriptions.Item label="生效结束日期">{ycddData.out_source}</Descriptions.Item>
  1071. <Descriptions.Item label="实付金额"></Descriptions.Item>
  1072. </Descriptions>
  1073. </div>
  1074. //错峰卡详情
  1075. const cfkModal = <div className="ltc-box">
  1076. <div className="ltc-box-title">订单信息:</div>
  1077. <div className="ltc-box-line"></div>
  1078. <Descriptions title="">
  1079. <Descriptions.Item label="停车场名称">{ycddData?.road || "--"}</Descriptions.Item>
  1080. <Descriptions.Item label="手机号">{ycddData.mobile || "--"}</Descriptions.Item>
  1081. <Descriptions.Item label="车牌号">{ycddData.plate_number || "--"}</Descriptions.Item>
  1082. <Descriptions.Item label="同步MS状态">{ycddData.r || "--"}</Descriptions.Item>
  1083. <Descriptions.Item label="订购时间">{ycddData.r || "--"}</Descriptions.Item>
  1084. <Descriptions.Item label="支付方式">{ycddData.r || "--"}</Descriptions.Item>
  1085. <Descriptions.Item label="订单金额">{ycddData.r || "--"}</Descriptions.Item>
  1086. </Descriptions>
  1087. <div className="ltc-box-title">商品信息:</div>
  1088. <div className="ltc-box-line"></div>
  1089. <Descriptions title="">
  1090. <Descriptions.Item label="销售金额">{ycddData.plate}</Descriptions.Item>
  1091. <Descriptions.Item label="有效时间">{ycddData.admission_time}</Descriptions.Item>
  1092. </Descriptions>
  1093. </div>
  1094. // useEffect(() => {
  1095. // searchOther()
  1096. // }, [tabKey])
  1097. //车辆信息,列表 限制条件
  1098. const limitCon = (e) => {
  1099. if (e && moment(e.end_time) - moment(e.start_time) > 90 * 24 * 1000 * 3600) {
  1100. //console.log(typeof e.order_mount_down, e.order_mount_up, e.order_mount_down > e.order_mount_up)
  1101. message.error('查询范围不超过90天!')
  1102. return 1
  1103. }
  1104. }
  1105. return (
  1106. <div className="carinfo-box">
  1107. {tag == 1 ?
  1108. <TableModule
  1109. columns={columns}
  1110. tableData={resultData}
  1111. formSearch={formSearch}
  1112. total={total}
  1113. search={search}
  1114. limitCon={limitCon}
  1115. exportUrl={'/api/ope/car/export'}
  1116. // mandatory={'plate'}
  1117. // mandatory_name={'车牌号'}
  1118. isQuickMenu={[{ text: '昨日', value: 1 },
  1119. { text: '今日', value: 0 },
  1120. { text: '近三日', value: 2 },
  1121. { text: '近一周', value: 6 },
  1122. { text: '近一月', value: 29 },
  1123. { text: '近三月', value: 89 },]}
  1124. rowKey={(record) => record.carId}
  1125. pageName={'carInfo'}
  1126. /> :
  1127. <>
  1128. <div className="back-btn" onClick={() => { setTag('1'); setTabKey('1') }}>返回</div>
  1129. <Tabs activeKey={tabKey} onChange={changeKey}>
  1130. <Tabs.TabPane tab="基本信息" key="1">
  1131. {renderRecord(detailData)}
  1132. </Tabs.TabPane>
  1133. <Tabs.TabPane tab="停车记录" key="2">
  1134. {tabKey == 2 ?
  1135. renderTable(
  1136. createCol(['序号', '区域', '商户名称', '停车场名称', '车场类型', '车牌号', '泊位号', '入场时间', '离场时间', '停车时长', '应收金额', '优惠金额', '实收金额'],
  1137. ['index', 'region', 'operator', 'road', 'road_type', 'plate', 'berth_id', 'in_time', 'out_time', 'admission_time', 'receivable_amount', 'preferential_amount', 'actual_amount'], 2),
  1138. [ash[0], ash[1], ash[2], ash[3], ash[4], ash[5], ash[12]],
  1139. resultData,
  1140. "/api/bpm/record/get_record_export"
  1141. ) : null}
  1142. </Tabs.TabPane>
  1143. <Tabs.TabPane tab="欠费记录" key="3">
  1144. {tabKey == 3 ?
  1145. renderTable(
  1146. createCol(['商户名称', '区域', '停车场名称', '车牌号', '入场时间', '出场时间', '欠费金额'],
  1147. ['merchantName', 'area', 'sectionName', 'licensePlateNumber', 'entryTime', 'exitTime', 'arrearsAmount'], 3),
  1148. [ash[0], ash[1], ash[2], ash[3], ash[5], ash[12]],
  1149. resultData
  1150. ) : null}
  1151. </Tabs.TabPane>
  1152. <Tabs.TabPane tab="支付记录" key="4">
  1153. {tabKey == 4 ?
  1154. renderTable(
  1155. createCol(['订单ID', '停车场名称', '车牌号', '泊位号', '入场时间', '计费时间', '停车时长', '应收金额', '优惠金额', '实收金额', '支付渠道', '支付设备', '操作人', '付款车场', '支付时间', '第三方流水ID'],
  1156. ['order_id', 'road', 'plate', 'berth_id', 'admission_time', 'charging_time', 'parking_duration', 'receivable_amount', 'discount_amount', 'paid_in_money', 'payment_channels', 'payment_equipment', 'dealer', 'pay_road', 'pay_time', 'third_party_flow_id'], 4),
  1157. [ash[2], ash[9], ash[10], ash[15]],
  1158. resultData,
  1159. '/api/bpm/record/get_payment_export'
  1160. ) : null}
  1161. </Tabs.TabPane>
  1162. <Tabs.TabPane tab="退费订单" key="5">
  1163. {tabKey == 5 ?
  1164. renderTable(
  1165. createCol(['序号', '最近尝试时间', '支付渠道', '应退实付(元)', '应退优惠(元)', '退款原因', '退款申请时间', '退款订单ID', '业务订单类型', '业务订单ID', '支付订单类型', '支付订单ID', '渠道流水号', '状态'],
  1166. ['index', 'latest_try_time', 'payment_channels_name', 'refund_actual_amount', 'refund_discount_amount', 'reason', 'refund_time', 'id', 'parking_type_name', 'park_record_id', 'payment_type_name', 'payment_order_id', 'flow_id', 'state_name'], 5),
  1167. formRefundSearch,
  1168. resultData
  1169. ) : null}
  1170. </Tabs.TabPane>
  1171. <Tabs.TabPane tab="停车卡购买记录" key="6">
  1172. {tabKey == 6 ?
  1173. renderTable(
  1174. createCol(['车牌号', '车辆颜色', '手机号', '商户名称', '实付金额', '支付渠道', '支付设备', '购买渠道', '支付时间', '订单状态'],
  1175. ['plate', '', 'phone', 'operator', 'actual_amount', '', '', '', '', ''], 6),
  1176. [ash[4], ash[6], ash[7], ash[8], ash[9], ash[10], ash[15]],
  1177. resultData
  1178. ) : null}
  1179. </Tabs.TabPane>
  1180. <Tabs.TabPane tab="错峰卡购买记录" key="7">
  1181. {tabKey == 7 ?
  1182. renderTable(
  1183. createCol(['序号', '停车场名称', '车牌号', '手机号', '订单金额', '支付方式', '同步MS状态', '订购状态'],
  1184. ['index', 'road', 'plate', 'phone', 'order_amount', '', '', ''], 7),
  1185. [ash[2], ash[4], ash[11], ash[16]],
  1186. resultData
  1187. ) : null}
  1188. </Tabs.TabPane>
  1189. <Tabs.TabPane tab="预约处理" key="8">
  1190. <Tabs defaultActiveKey="1">
  1191. <Tabs.TabPane tab="预约订单" key="1">
  1192. {
  1193. renderTable(
  1194. createCol(['序号', '车牌号', '手机号', '停车场名称', '实付金额', '支付方式', '下单时间', '订单状态', '第三方流水号'],
  1195. ['index', 'plate', 'phone', 'road', 'actual_amount', '', '', '',''], 8),
  1196. [ash[4], ash[2], ash[17], ash[11], ash[14], ash[15], ash[8]],
  1197. resultData
  1198. )}
  1199. </Tabs.TabPane>
  1200. <Tabs.TabPane tab="预约订单退款" key="2">
  1201. {
  1202. renderTable(
  1203. createCol(['序号', '车牌号', '手机号', '停车场名称', '预约到场时间', '实付金额', '退款金额', '退款方式', '退款时间', '第三方流水号'],
  1204. ['index', 'plate', 'phone', 'road', '', 'actual_amount', 'refund_total', '', '', ''], 9),
  1205. [ash[4], ash[2], ash[12], ash[13], ash[12], ash[14]],
  1206. resultData
  1207. )}
  1208. </Tabs.TabPane>
  1209. </Tabs>
  1210. </Tabs.TabPane>
  1211. </Tabs>
  1212. </>
  1213. }
  1214. <Modal
  1215. open={detailVisible}
  1216. width={1500}
  1217. onCancel={() => {
  1218. setDetailVisible(false);
  1219. setStopCarTop("1")
  1220. }}
  1221. footer={null}
  1222. >
  1223. <Tabs activeKey={stopCarTab} onChange={(e)=>{
  1224. setStopCarTop(e)
  1225. }}>
  1226. <Tabs.TabPane tab="停车记录信息" key="1">
  1227. {/* {renderParkRecord(detailData)} */}
  1228. {renderParkRecord(ycddData)}
  1229. </Tabs.TabPane>
  1230. <Tabs.TabPane tab="历史处理" key="2">
  1231. {/* {renderModalTable(payRecordColumns, payRecord)} */}
  1232. </Tabs.TabPane>
  1233. </Tabs>
  1234. </Modal>
  1235. <Modal
  1236. open={bigpicVisible}
  1237. width={1600}
  1238. title={'图片展示'}
  1239. className="eae-modal"
  1240. onCancel={() => {
  1241. setBigpicVisible(false);
  1242. }}
  1243. footer={false}
  1244. >
  1245. <div>
  1246. <div className="eae-modal-item">
  1247. <img src={bigPic} width={1550} onError={handleImgError}/>
  1248. </div>
  1249. </div>
  1250. </Modal>
  1251. <Modal
  1252. open={tkddVisible}
  1253. width={1500}
  1254. title={'订单详情'}
  1255. onCancel={() => {
  1256. setTkddVisible(false);
  1257. }}
  1258. footer={[
  1259. <Button key="back" onClick={() => {
  1260. setTkddVisible(false);
  1261. }}>
  1262. 关闭窗口
  1263. </Button>]}
  1264. >
  1265. {/* {tkddModal} */}
  1266. {tabKey == '5' ? tkddModal : tabKey == '6' ? tckModal : tabKey == '7' ? cfkModal : null}
  1267. </Modal>
  1268. <Modal
  1269. open={eaeVisible}
  1270. width={1600}
  1271. title={'证据图像'}
  1272. className="eae-modal"
  1273. onCancel={() => {
  1274. setEaeVisible(false);
  1275. }}
  1276. footer={false}
  1277. >
  1278. <div>
  1279. <div className="eae-modal-title"><div className="ltc-icon"></div>入场图片</div>
  1280. <div className="eae-modal-item">
  1281. <div>车辆照片</div>
  1282. <img src={ycddData.in_veh_pic} width={750} onError={handleImgError}/>
  1283. </div>
  1284. <div className="eae-modal-item">
  1285. <div>车牌照片</div>
  1286. <img src={ycddData.in_plate_pic} width={750} onError={handleImgError}/>
  1287. </div>
  1288. </div>
  1289. </Modal>
  1290. </div>
  1291. );
  1292. }
  1293. export default CarInfo;