停车场项目web, 互联网仓库, 开发完成后, 需要将代码回传云桌面.

1274 lines
50 KiB

  1. import React, { useState, useEffect } from "react";
  2. import { ResultFlowResult } from "@/components";
  3. import { Select, Input, Button, Table, message, Pagination, DatePicker, Modal, Cascader, Tooltip, Tabs } from "antd";
  4. import { useSessionStorageState } from "ahooks";
  5. import { dictionary } from "@/config/common";
  6. import { useNavigate } from "react-router-dom";
  7. import { setTabList } from "@/store/common.js";
  8. import { useSelector, useDispatch } from "react-redux";
  9. import { QuestionCircleFilled } from "@ant-design/icons"
  10. import moment from "moment";
  11. import ReactEcharts from "echarts-for-react";
  12. import echarts from "echarts";
  13. import "./index.scss";
  14. import ajax from "@/services";
  15. //停车时长分析
  16. function ParkingAlyDuration() {
  17. // session缓存
  18. const [defaultParams, setDefaultParams] = useSessionStorageState(
  19. "formData_parkingAlyDuration",
  20. { defaultValue: null }
  21. );
  22. //区域的下拉数据
  23. const [areaList, setAreaList] = useState([]);
  24. // 默认数据
  25. const defaultData = {
  26. start_time: moment().subtract('days').startOf('day').format("YYYY-MM-DD"),
  27. end_time: moment().endOf("day").format("YYYY-MM-DD"),
  28. date_type: '1',
  29. //date_type: 1,
  30. };
  31. // 分页数据
  32. const [pageInfo, setPageInfo] = useState({
  33. pn: 1,
  34. page_size: 10
  35. });
  36. // 表单数据
  37. const [formData, setFormData] = useState({
  38. ...defaultData,
  39. ...defaultParams,
  40. });
  41. // 搜索提交数据-存储
  42. const [holdData, setHoldData] = useState(formData);
  43. // 访问接口,isAjax改变时执行
  44. const [isAjax, setIsAjax] = useState(false);
  45. // 检索按钮加载状态
  46. const [loading, setLoading] = useState(false);
  47. // 表格加载状态
  48. const [tabLoading, setTabLoading] = useState(false);
  49. // 表格返回数据
  50. const [resultData, setResultData] = useState({
  51. total: 0,
  52. list: [],
  53. });
  54. // 泊位周转排行榜返回数据
  55. const [tableData, setTableData] = useState({
  56. area_list: [],
  57. road_list: [],
  58. });
  59. // 停车排行榜返回数据setTableCarData
  60. const [tableCarData, setTableCarData] = useState({
  61. area_list: [],
  62. road_list: [],
  63. });
  64. //停车场收入概览数据
  65. const [revenueData, setRevenueData] = useState({});
  66. const [searchSelectList, setSearchSelectList] = useState([]); //搜索下拉数据
  67. const [sessionTabList, setSessionTabList] = useSessionStorageState('parkingAlyDuration', {
  68. value: {
  69. }
  70. })
  71. useEffect(() => {
  72. if (sessionTabList && Object.values(sessionTabList).length > 0) {
  73. setFormData({
  74. ...formData, ...sessionTabList
  75. })
  76. // getData({
  77. // ...sessionTabList
  78. // })
  79. getCheck({
  80. ...sessionTabList
  81. })
  82. } else {
  83. //getData()
  84. getCheck()
  85. }
  86. }, [isAjax])
  87. const [tabKey, setTabKey] = useState("1");
  88. const [tabCarKey, setTabCarKey] = useState("1");
  89. const columns = [
  90. {
  91. title: '序号',
  92. dataIndex: 'index',
  93. key: 'index',
  94. width: 100,
  95. render: (text, record, index) => index + 1
  96. },
  97. {
  98. title: '区域',
  99. dataIndex: 'area_name',
  100. key: 'area_name',
  101. width: 280,
  102. },
  103. {
  104. title: '泊位数(个)',
  105. dataIndex: 'area_total_berths',
  106. key: 'area_total_berths',
  107. //width: 200,
  108. },
  109. {
  110. title: '利用率',
  111. dataIndex: 'area_rate',
  112. key: 'area_rate',
  113. width: 120,
  114. },
  115. ]
  116. const parkColumns = [
  117. {
  118. title: '序号',
  119. dataIndex: 'index',
  120. key: 'index',
  121. width: 100,
  122. render: (text, record, index) => index + 1
  123. },
  124. {
  125. title: '停车场',
  126. dataIndex: 'road_name',
  127. key: 'road_name',
  128. width: 280,
  129. },
  130. {
  131. title: '泊位数(个)',
  132. dataIndex: 'road_total_berths',
  133. key: 'road_total_berths',
  134. //width: 200,
  135. },
  136. {
  137. title: '利用率',
  138. dataIndex: 'road_rate',
  139. key: 'road_rate',
  140. width: 120,
  141. },
  142. ]
  143. const columns1 = [
  144. {
  145. title: '序号',
  146. dataIndex: 'index',
  147. key: 'index',
  148. width: 100,
  149. render: (text, record, index) => index + 1
  150. },
  151. {
  152. title: '区域',
  153. dataIndex: 'area_name',
  154. key: 'area_name',
  155. width: 280,
  156. },
  157. {
  158. title: '泊位数(个)',
  159. dataIndex: 'area_total_parkings',
  160. key: 'area_total_parkings',
  161. //width: 200,
  162. },
  163. {
  164. title: '利用率',
  165. dataIndex: 'area_rate',
  166. key: 'area_rate',
  167. width: 120,
  168. },
  169. ]
  170. const parkColumns1 = [
  171. {
  172. title: '序号',
  173. dataIndex: 'index',
  174. key: 'index',
  175. width: 100,
  176. render: (text, record, index) => index + 1
  177. },
  178. {
  179. title: '停车场',
  180. dataIndex: 'road_name',
  181. key: 'road_name',
  182. width: 280,
  183. },
  184. {
  185. title: '泊位数(个)',
  186. dataIndex: 'road_total_parkings',
  187. key: 'road_total_parkings',
  188. //width: 200,
  189. },
  190. {
  191. title: '利用率',
  192. dataIndex: 'road_rate',
  193. key: 'road_rate',
  194. width: 120,
  195. },
  196. ]
  197. const paginationProps = {
  198. className: "pagination-common",
  199. showQuickJumper: true,
  200. showSizeChanger: true,
  201. current: pageInfo.pn,
  202. //total: resultData?.totalRecords,
  203. pageSize: pageInfo.page_size,
  204. pageSizeOptions: Array.from(
  205. new Set([...[15], ...(dictionary?.pageSizeOptions || [])])
  206. ),
  207. onChange: (current, size) => {
  208. setPageInfo({
  209. ...pageInfo,
  210. ...{ pn: current, length: size }
  211. });
  212. setIsAjax(!isAjax)
  213. //getListData({})
  214. },
  215. }
  216. // useEffect(() => {
  217. // getData()
  218. // }, [pageInfo])
  219. useEffect(() => {
  220. setSessionTabList({
  221. ...formData
  222. })
  223. }, [formData])
  224. useEffect(() => {
  225. getSelectList();
  226. }, []);
  227. // 访问接口,获取表格
  228. // useEffect(() => {
  229. // getData();
  230. // }, [isAjax]);
  231. //时间状态切换
  232. const TimeChange = () => {
  233. let e = formData.date_type;
  234. let str = "day";
  235. let mat = "YYYY-MM-DD";
  236. if (e == 4) {
  237. str = "year";
  238. mat = "YYYY";
  239. } else if (e == 3) {
  240. str = "month";
  241. mat = "YYYY-MM";
  242. } else if (e == 2) {
  243. str = "week";
  244. mat = "YYYY-MM-DD";
  245. }
  246. return { str, mat };
  247. };
  248. //切换时间变化
  249. const SetTimeNow = (e) => {
  250. let start = "";
  251. let end = "";
  252. if (e == 4) {
  253. start = moment().format("YYYY");
  254. end = moment().format("YYYY");
  255. } else if (e == 3) {
  256. start = moment().startOf('month').format("YYYY-MM-DD");
  257. end = moment().endOf("month").format("YYYY-MM-DD");
  258. } else if (e == 2) {
  259. start = moment().day(1).format("YYYY-MM-DD");
  260. end = moment().day(7).format("YYYY-MM-DD");
  261. } else {
  262. start = moment().startOf("day").format("YYYY-MM-DD");
  263. end = moment().endOf("day").format("YYYY-MM-DD");
  264. }
  265. setFormData({
  266. ...formData,
  267. date_type: e,
  268. start_time: start,
  269. end_time: end,
  270. });
  271. };
  272. //停车场收入概览 柱状图
  273. const getRevenueOption = (data) => {
  274. console.log(data)
  275. // data = [
  276. // {
  277. // "hour": "0",
  278. // "record_count": "0",
  279. // "total_duration": "0"
  280. // },
  281. // {
  282. // "hour": "1",
  283. // "record_count": "0",
  284. // "total_duration": "0"
  285. // },
  286. // {
  287. // "hour": "2",
  288. // "record_count": "0",
  289. // "total_duration": "0"
  290. // },
  291. // {
  292. // "hour": "3",
  293. // "record_count": "0",
  294. // "total_duration": "0"
  295. // },
  296. // {
  297. // "hour": "4",
  298. // "record_count": "0",
  299. // "total_duration": "0"
  300. // },
  301. // {
  302. // "hour": "5",
  303. // "record_count": "0",
  304. // "total_duration": "0"
  305. // },
  306. // {
  307. // "hour": "6",
  308. // "record_count": "0",
  309. // "total_duration": "0"
  310. // },
  311. // {
  312. // "hour": "7",
  313. // "record_count": "0",
  314. // "total_duration": "0"
  315. // },
  316. // {
  317. // "hour": "8",
  318. // "record_count": "0",
  319. // "total_duration": "0"
  320. // },
  321. // {
  322. // "hour": "9",
  323. // "record_count": "0",
  324. // "total_duration": "0"
  325. // },
  326. // {
  327. // "hour": "10",
  328. // "record_count": "0",
  329. // "total_duration": "0"
  330. // },
  331. // {
  332. // "hour": "11",
  333. // "record_count": "0",
  334. // "total_duration": "0"
  335. // },
  336. // {
  337. // "hour": "12",
  338. // "record_count": "0",
  339. // "total_duration": "0"
  340. // },
  341. // {
  342. // "hour": "13",
  343. // "record_count": "0",
  344. // "total_duration": "0"
  345. // },
  346. // {
  347. // "hour": "14",
  348. // "record_count": "0",
  349. // "total_duration": "0"
  350. // },
  351. // {
  352. // "hour": "15",
  353. // "record_count": "0",
  354. // "total_duration": "0"
  355. // },
  356. // {
  357. // "hour": "16",
  358. // "record_count": "0",
  359. // "total_duration": "0"
  360. // },
  361. // {
  362. // "hour": "17",
  363. // "record_count": "0",
  364. // "total_duration": "0"
  365. // },
  366. // {
  367. // "hour": "18",
  368. // "record_count": "0",
  369. // "total_duration": "0"
  370. // },
  371. // {
  372. // "hour": "19",
  373. // "record_count": "0",
  374. // "total_duration": "0"
  375. // },
  376. // {
  377. // "hour": "20",
  378. // "record_count": "0",
  379. // "total_duration": "0"
  380. // },
  381. // {
  382. // "hour": "21",
  383. // "record_count": "0",
  384. // "total_duration": "0"
  385. // },
  386. // {
  387. // "hour": "22",
  388. // "record_count": "0",
  389. // "total_duration": "0"
  390. // },
  391. // {
  392. // "hour": "23",
  393. // "record_count": "0",
  394. // "total_duration": "0"
  395. // }
  396. // ]
  397. let ac = [
  398. {
  399. "hour": "0",
  400. "record_count": "0",
  401. "total_duration": "0"
  402. },
  403. {
  404. "hour": "1",
  405. "record_count": "0",
  406. "total_duration": "0"
  407. },
  408. {
  409. "hour": "2",
  410. "record_count": "0",
  411. "total_duration": "0"
  412. },
  413. {
  414. "hour": "3",
  415. "record_count": "0",
  416. "total_duration": "0"
  417. },
  418. {
  419. "hour": "4",
  420. "record_count": "0",
  421. "total_duration": "0"
  422. },
  423. {
  424. "hour": "5",
  425. "record_count": "0",
  426. "total_duration": "0"
  427. },
  428. {
  429. "hour": "6",
  430. "record_count": "0",
  431. "total_duration": "0"
  432. },
  433. {
  434. "hour": "7",
  435. "record_count": "0",
  436. "total_duration": "0"
  437. },
  438. {
  439. "hour": "8",
  440. "record_count": "0",
  441. "total_duration": "0"
  442. },
  443. {
  444. "hour": "9",
  445. "record_count": "0",
  446. "total_duration": "0"
  447. },
  448. {
  449. "hour": "10",
  450. "record_count": "0",
  451. "total_duration": "0"
  452. },
  453. {
  454. "hour": "11",
  455. "record_count": "0",
  456. "total_duration": "0"
  457. },
  458. {
  459. "hour": "12",
  460. "record_count": "0",
  461. "total_duration": "0"
  462. },
  463. {
  464. "hour": "13",
  465. "record_count": "0",
  466. "total_duration": "0"
  467. },
  468. {
  469. "hour": "14",
  470. "record_count": "0",
  471. "total_duration": "0"
  472. },
  473. {
  474. "hour": "15",
  475. "record_count": "0",
  476. "total_duration": "0"
  477. },
  478. {
  479. "hour": "16",
  480. "record_count": "0",
  481. "total_duration": "0"
  482. },
  483. {
  484. "hour": "17",
  485. "record_count": "0",
  486. "total_duration": "0"
  487. },
  488. {
  489. "hour": "18",
  490. "record_count": "0",
  491. "total_duration": "0"
  492. },
  493. {
  494. "hour": "19",
  495. "record_count": "0",
  496. "total_duration": "0"
  497. },
  498. {
  499. "hour": "20",
  500. "record_count": "0",
  501. "total_duration": "0"
  502. },
  503. {
  504. "hour": "21",
  505. "record_count": "0",
  506. "total_duration": "0"
  507. },
  508. {
  509. "hour": "22",
  510. "record_count": "0",
  511. "total_duration": "0"
  512. },
  513. {
  514. "hour": "23",
  515. "record_count": "0",
  516. "total_duration": "0"
  517. }
  518. ]
  519. let leftData = []
  520. let rightData = []
  521. let yData = []
  522. data.map(item => {
  523. yData.push(item.houer)
  524. leftData.push(item.record_count)
  525. leftData.push(item.total_duration)
  526. })
  527. data.sort((a, b) => {
  528. return new Date(a.hour) - new Date(b.hour);
  529. });
  530. const areaNames = ['停车次数', '停车时长'];
  531. // 获取所有日期
  532. // const dates = [...new Set(data.map((item) => item.pay_date))].sort(
  533. // (a, b) => a.pay_date - b.pay_date
  534. // );
  535. // 构建数据对象
  536. // const seriesData = areaNames.map((areaName, index) => {
  537. // // 获取该地区的数据
  538. // const areaData = data.filter((item) => item.area_name === areaName);
  539. // // 构建该地区的数据对象
  540. // return {
  541. // name: areaName,
  542. // type: "bar",
  543. // // itemStyle: {
  544. // // normal: {
  545. // // label: {
  546. // // show: true, //开启显示
  547. // // position: 'top', //在上方显示
  548. // // textStyle: { //数值样式
  549. // // color: 'white',//字体颜色
  550. // // fontSize: 10//字体大小
  551. // // }
  552. // // },
  553. // // },
  554. // // },
  555. // data: dates.map((item) => {
  556. // for (const { pay_date, income } of areaData) {
  557. // if (pay_date === item) return income;
  558. // }
  559. // return 0;
  560. // }),
  561. // yAxisIndex: index == 1 ? 1 : null,
  562. // };
  563. // });
  564. setRevenueData({
  565. title: {
  566. text: "",
  567. textStyle: {
  568. color: "#fff",
  569. },
  570. },
  571. tooltip: {
  572. trigger: "axis",
  573. },
  574. legend: {
  575. type: "scroll",
  576. x: "center",
  577. data: areaNames,
  578. itemWidth: 18,
  579. itemHeight: 12,
  580. textStyle: {
  581. fontSize: 14,
  582. color: "#fff",
  583. },
  584. },
  585. xAxis: {
  586. //data: xAxisData,
  587. data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
  588. type: 'category',
  589. axisLine: {
  590. lineStyle: {
  591. color: "#bbb",
  592. },
  593. },
  594. axisLabel: {
  595. textStyle: {
  596. color: "#bbb",
  597. },
  598. },
  599. axisTick: {
  600. show: false,
  601. }
  602. },
  603. yAxis: [{
  604. type: "value",
  605. name: '停车次数(次)',
  606. min: 0,
  607. interval: 10,
  608. splitNumber: 6, //设置坐标轴的分割段数
  609. axisLabel: {
  610. textStyle: {
  611. color: "#ffffffa6",
  612. },
  613. },
  614. axisLine: {
  615. lineStyle: {
  616. color: "#ffffffa6",
  617. },
  618. },
  619. splitLine: {
  620. show: true, // 是否显示分隔线。默认数值轴显示,类目轴不显示
  621. interval: '0', // 坐标轴刻度标签的显示间隔,在类目轴中有效.0显示所有
  622. lineStyle: {
  623. color: ['#cccccc42'], // 分隔线颜色,可以设置成单个颜色,也可以设置成颜色数组,分隔线会按数组中颜色的顺序依次循环设置颜色
  624. width: 2, // 分隔线线宽
  625. type: 'dashed', // 坐标轴线线的类型('solid',实线类型;'dashed',虚线类型;'dotted',点状类型)
  626. },
  627. },
  628. },
  629. {
  630. type: "value",
  631. name: '停车时长(时)',
  632. splitLine: {
  633. show: false
  634. },
  635. axisLine: {
  636. lineStyle: {
  637. color: "#ffffffa6",
  638. },
  639. },
  640. splitLine: {
  641. show: true, // 是否显示分隔线。默认数值轴显示,类目轴不显示
  642. interval: '0', // 坐标轴刻度标签的显示间隔,在类目轴中有效.0显示所有
  643. lineStyle: {
  644. color: ['#cccccc42'], // 分隔线颜色,可以设置成单个颜色,也可以设置成颜色数组,分隔线会按数组中颜色的顺序依次循环设置颜色
  645. width: 1.3, // 分隔线线宽
  646. type: 'dashed', // 坐标轴线线的类型('solid',实线类型;'dashed',虚线类型;'dotted',点状类型)
  647. },
  648. },
  649. },
  650. ],
  651. color: ["#4DC3FF", "#FFD767"],
  652. series: [
  653. {
  654. name: "停车次数",
  655. type: "bar",
  656. data: leftData,
  657. //data:[1,24,6,8,4,32,5,2,5,25,6,34],
  658. barWidth: 12,
  659. itemStyle: {
  660. barBorderRadius: [2, 2, 0, 0], // (顺时针左上,右上,右下,左下)
  661. color: {
  662. type: 'linear',
  663. x: 0,
  664. y: 0,
  665. x2: 0,
  666. y2: 1,
  667. colorStops: [{
  668. offset: 0, color: '#99EBFF' // 0% 处的颜色
  669. }, {
  670. offset: 1, color: '#3AA9FF' // 100% 处的颜色
  671. }],
  672. globalCoord: false // 缺省为 false
  673. },
  674. },
  675. },
  676. {
  677. name: "停车时长",
  678. type: "bar",
  679. yAxisIndex: 1,
  680. data: rightData,
  681. //data:[1,24,6,8,4,32,5,2,5,25,6,34],
  682. barWidth: 12,
  683. itemStyle: {
  684. barBorderRadius: [2, 2, 0, 0], // (顺时针左上,右上,右下,左下)
  685. color: {
  686. type: 'linear',
  687. x: 0,
  688. y: 0,
  689. x2: 0,
  690. y2: 1,
  691. colorStops: [{
  692. offset: 0, color: '#FFB8B8' // 0% 处的颜色
  693. }, {
  694. offset: 1, color: '#F481F8' // 100% 处的颜色
  695. }],
  696. globalCoord: false // 缺省为 false
  697. }
  698. },
  699. }
  700. ],
  701. grid: {
  702. x: 50,
  703. y: 55,
  704. x2: 70,
  705. y2: 30,
  706. },
  707. });
  708. };
  709. //获取柱状图数据
  710. function getParkingIncome(data) {
  711. ajax
  712. .getParkingAlyDurationBar(data)
  713. .then((res) => {
  714. if (res.status === 20000) {
  715. console.log(res)
  716. getRevenueOption(res.data.list);
  717. }
  718. })
  719. .catch((err) => console.error(err));
  720. }
  721. // 获取下拉数据
  722. const getSelectList = () => {
  723. ajax.getOperator().then((e) => {
  724. setSearchSelectList([
  725. ...searchSelectList,
  726. ...e.data
  727. ])
  728. })
  729. };
  730. // 获取日均泊位列表数据
  731. const getData = (v, pn = {}) => {
  732. ajax.getParkingAlyDurationBerthList({ ...v, ...pn }).then(
  733. (res) => {
  734. if (parseInt(res?.status) === 20000) {
  735. setTableData(res?.data || {});
  736. } else {
  737. message.error(res?.message);
  738. }
  739. setLoading(false);
  740. setTabLoading(false);
  741. },
  742. (err) => {
  743. console.log(err);
  744. setLoading(false);
  745. setTabLoading(false);
  746. }
  747. );
  748. };
  749. // 获取停车时长列表数据
  750. const getListData = (v, pn = {}) => {
  751. let postData = { ...formData, sort: 2 };
  752. if (!loading) {
  753. postData = { ...holdData };
  754. }
  755. setDefaultParams({ ...postData, ...pageInfo });
  756. setTabLoading(true);
  757. ajax.getParkingAlyDurationParkingList({ ...postData, ...v, ...pageInfo, ...pn }).then(
  758. (res) => {
  759. if (parseInt(res?.status) === 20000) {
  760. setTableCarData(res?.data || {});
  761. } else {
  762. message.error(res?.message);
  763. }
  764. setLoading(false);
  765. setTabLoading(false);
  766. },
  767. (err) => {
  768. console.log(err);
  769. setLoading(false);
  770. setTabLoading(false);
  771. }
  772. );
  773. };
  774. // 携带参数处理
  775. const getCheck = (v) => {
  776. let postData = { ...formData };
  777. if (!loading) {
  778. postData = { ...holdData };
  779. }
  780. setDefaultParams({ ...postData, ...pageInfo });
  781. if (moment(formData.end_time) - moment(formData.start_time) > 1000 * 31 * 24 * 3600) {
  782. message.error("时间范围限制为31天!")
  783. setLoading(false);
  784. setTabLoading(false);
  785. return
  786. }
  787. setTabLoading(true);
  788. let params = { ...postData, ...v, ...pageInfo }
  789. //请求接口
  790. getParkingIncome(params)
  791. getData(params)
  792. getListData(params)
  793. };
  794. // 检索数据
  795. const handleSearch = () => {
  796. setLoading(true);
  797. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  798. setHoldData(formData);
  799. setIsAjax(!isAjax);
  800. };
  801. // 日均周转次数导出
  802. const handleExport = () => {
  803. if (tableData.list.area_list?.length > 0) {
  804. let { pn, page_size, ...params } = defaultParams;
  805. ajax.getParkingAlyDurationParkingExp(defaultParams).then(
  806. (res) => {
  807. if (res) {
  808. window.open(res.data.export_url)
  809. } else {
  810. message.error(res?.message);
  811. }
  812. },
  813. (err) => {
  814. console.log(err);
  815. }
  816. );
  817. } else {
  818. message.error("暂无数据");
  819. }
  820. };
  821. // 停车排行导出
  822. const handleExportCar = () => {
  823. if (tableData.list.area_list?.length > 0) {
  824. let { pn, page_size, ...params } = defaultParams;
  825. ajax.getParkingAlyDurationExp(defaultParams).then(
  826. (res) => {
  827. if (res) {
  828. window.open(res.data.export_url)
  829. } else {
  830. message.error(res?.message);
  831. }
  832. },
  833. (err) => {
  834. console.log(err);
  835. }
  836. );
  837. } else {
  838. message.error("暂无数据");
  839. }
  840. };
  841. //区域下拉框数据
  842. useEffect(() => {
  843. ajax
  844. .getAreaTree()
  845. .then((res) => {
  846. if (res.status === 20000) {
  847. setAreaList(res.data);
  848. }
  849. })
  850. .catch((err) => {
  851. console.error(err);
  852. });
  853. }, []);
  854. return (
  855. <>
  856. <div className="edit-order-inquiry">
  857. <div className="paid-search">
  858. <div className="title">查询条件</div>
  859. <div className="form-Wrap">
  860. <div className="yisa-search">
  861. <label>区域</label>
  862. <Cascader
  863. className="form-con"
  864. popupClassName="start-exception-deal-cascader"
  865. options={areaList}
  866. placeholder="请选择区域"
  867. expandTrigger="hover"
  868. fieldNames={{
  869. label: "name",
  870. value: "id",
  871. children: "children",
  872. }}
  873. value={formData.region}
  874. onChange={(v, option) => {
  875. setFormData({ ...formData, region: v ? v : null });
  876. }}
  877. />
  878. </div>
  879. <div className="yisa-search">
  880. <label>运营商</label>
  881. <Select
  882. className="form-con"
  883. placeholder="请选择"
  884. options={searchSelectList || []}
  885. value={formData.operator_id}
  886. onChange={(v) =>
  887. setFormData({ ...formData, operator_id: v })
  888. }
  889. />
  890. </div>
  891. <div className="yisa-search">
  892. <label>车场类型</label>
  893. <Select
  894. className="form-con"
  895. placeholder="请选择车场类型"
  896. options={[
  897. {
  898. label: '全部',
  899. value: '0',
  900. },
  901. {
  902. label: '路内车场',
  903. value: '1',
  904. },
  905. {
  906. label: '路外车场',
  907. value: '2',
  908. },
  909. ]}
  910. value={formData.car_parking_type}
  911. onChange={(v) =>
  912. setFormData({ ...formData, car_parking_type: v })
  913. }
  914. />
  915. </div>
  916. <div className="yisa-search">
  917. <label>停车场</label>
  918. <Input
  919. className="form-con"
  920. placeholder="请输入"
  921. value={formData?.road_name}
  922. onChange={(e) =>
  923. setFormData({ ...formData, road_name: e.target.value })
  924. }
  925. />
  926. </div>
  927. <div className="yisa-search">
  928. <label>日期
  929. <div className="daf">
  930. <Select
  931. value={formData.date_type}
  932. // style={{
  933. // width: "100%",
  934. // }}
  935. placeholder="请选择"
  936. options={[
  937. {
  938. value: "1",
  939. label: "日",
  940. },
  941. {
  942. value: "2",
  943. label: "周",
  944. },
  945. {
  946. value: "3",
  947. label: "月",
  948. },
  949. ]}
  950. onChange={(e) => SetTimeNow(e)}
  951. />
  952. </div>
  953. </label>
  954. <DatePicker
  955. style={{ width: "100%" }}
  956. // showTime
  957. format={TimeChange().mat}
  958. picker={TimeChange().str}
  959. allowClear={false}
  960. value={formData.start_time ? moment(formData.start_time) : null}
  961. onChange={(date, dateString) => {
  962. if (TimeChange().str == "week") {
  963. setFormData({
  964. ...formData,
  965. start_time: date
  966. ? moment(date).day(1).format("YYYY-MM-DD")
  967. : null,
  968. });
  969. } else if (TimeChange().str == "day") {
  970. if (date > moment(formData.end_time)) {
  971. setFormData({
  972. ...formData,
  973. end_time: dateString,
  974. start_time: formData.end_time,
  975. });
  976. } else {
  977. setFormData({
  978. ...formData,
  979. start_time: dateString,
  980. });
  981. }
  982. } else if (TimeChange().str == "month") {
  983. setFormData({ ...formData, start_time: moment(date).format("YYYY-MM-DD"), end_time: moment(date).endOf("month").format("YYYY-MM-DD") });
  984. } else {
  985. setFormData({ ...formData, start_time: dateString });
  986. }
  987. }}
  988. disabledDate={(current) => current > moment(formData.end_time)}
  989. />
  990. </div>
  991. <div className="yisa-search">
  992. <label></label>
  993. <DatePicker
  994. style={{ width: "100%" }}
  995. // showTime
  996. format={TimeChange().mat}
  997. picker={TimeChange().str}
  998. allowClear={false}
  999. value={formData.end_time ? moment(formData.end_time) : null}
  1000. onChange={(date, dateString) => {
  1001. if (TimeChange().str == "week") {
  1002. setFormData({
  1003. ...formData,
  1004. end_time: date
  1005. ? moment(date).day(7).format("YYYY-MM-DD")
  1006. : null,
  1007. });
  1008. } else if (TimeChange().str == "day") {
  1009. if (date < moment(formData.start_time)) {
  1010. setFormData({
  1011. ...formData,
  1012. start_time: dateString,
  1013. end_time: formData.start_time,
  1014. });
  1015. } else {
  1016. setFormData({
  1017. ...formData,
  1018. end_time: dateString,
  1019. });
  1020. }
  1021. } else if (TimeChange().str == "month") {
  1022. setFormData({ ...formData, start_time: moment(date).startOf('month').format("YYYY-MM-DD"), end_time: moment(date).format("YYYY-MM-DD") });
  1023. } else {
  1024. setFormData({ ...formData, end_time: dateString });
  1025. }
  1026. }}
  1027. disabledDate={(current) =>
  1028. current < moment(formData.start_time)
  1029. }
  1030. />
  1031. </div>
  1032. <div className="form-btn">
  1033. <Button
  1034. className="reset"
  1035. onClick={() => setFormData(defaultData)}
  1036. >
  1037. 重置
  1038. </Button>
  1039. <Button
  1040. className="submit"
  1041. type="primary"
  1042. onClick={handleSearch}
  1043. loading={loading}
  1044. >
  1045. 查询
  1046. </Button>
  1047. </div>
  1048. </div>
  1049. </div>
  1050. <div className="paid-result soll-result">
  1051. <div className="result">
  1052. <div className="result-box">
  1053. <div className="result-box-title">停车时长分析</div>
  1054. <Tooltip
  1055. placement="topLeft"
  1056. title={<span>停车次数: 展示统计期间内各个停车时长区间内的停车记录数<br />
  1057. 停车时长: 展示统计时间段内在各个停车时长区间内的停车记录的总时木</span>}
  1058. >
  1059. <i>?</i>
  1060. </Tooltip>
  1061. <ReactEcharts
  1062. option={revenueData}
  1063. style={{ height: "300px", width: "100%", overflow: "hidden" }}
  1064. />
  1065. </div>
  1066. <div className="duration-box">
  1067. <div className="result-box duration-left">
  1068. <div className="result-box-title">日均泊位周转次数排行榜</div>
  1069. <div className="export-btn" onClick={handleExport}>导出</div>
  1070. <Tabs
  1071. defaultActiveKey="2"
  1072. activeKey={tabKey}
  1073. onChange={(key) => {
  1074. setTabKey(key);
  1075. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1076. getData({}, { pn: 1 })
  1077. }}
  1078. items={[
  1079. {
  1080. label: `序号`,
  1081. key: '0',
  1082. disabled: "true"
  1083. },
  1084. {
  1085. label: <div className="tab-title">
  1086. <div className="title">区域</div>
  1087. <div className="btn">
  1088. <div onClick={() => {
  1089. message.success('升序');
  1090. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1091. getData({ sort: 1 }, { pn: 1 })
  1092. }}></div>
  1093. <div onClick={() => {
  1094. message.success('降序');
  1095. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1096. getData({ sort: 2 }, { pn: 1 })
  1097. }}></div>
  1098. </div>
  1099. </div>,
  1100. key: '1',
  1101. children: <><Table
  1102. showHeader={false}
  1103. columns={columns}
  1104. dataSource={tableData?.list?.area_list || []}
  1105. rowKey={'area_name'}
  1106. bordered
  1107. pagination={false}
  1108. size="middle"
  1109. />
  1110. <Pagination {...paginationProps} className="pagination-common" total={tableData?.area_total_records} />
  1111. </>,
  1112. },
  1113. {
  1114. label: <div className="tab-title">
  1115. <div className="title">停车场</div>
  1116. <div className="btn">
  1117. <div onClick={() => {
  1118. message.success('升序');
  1119. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1120. getData({ sort: 1 }, { pn: 1 })
  1121. }}></div>
  1122. <div onClick={() => {
  1123. message.success('降序');
  1124. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1125. getData({ sort: 2 }, { pn: 1 })
  1126. }}></div>
  1127. </div>
  1128. </div>,
  1129. key: '2',
  1130. children: <><Table
  1131. showHeader={false}
  1132. columns={parkColumns}
  1133. dataSource={tableData?.list?.road_list}
  1134. rowKey={'area_name'}
  1135. bordered
  1136. pagination={false}
  1137. size="middle"
  1138. //scroll={{ y: 305 }}
  1139. // scroll={{
  1140. // x: 'calc(700px + 50%)',
  1141. // y: 240,
  1142. // }}
  1143. />
  1144. <Pagination {...paginationProps} className="pagination-common" total={tableData?.area_total_records} />
  1145. </>,
  1146. },
  1147. {
  1148. label: `泊位数(个)`,
  1149. key: '3',
  1150. disabled: "true"
  1151. },
  1152. {
  1153. label: `利用率`,
  1154. key: '4',
  1155. disabled: "true"
  1156. },
  1157. ]}
  1158. />
  1159. </div>
  1160. <div className="result-box duration-right">
  1161. <div className="result-box-title">平均停车时长排行榜</div>
  1162. <div className="export-btn" onClick={() => { handleExportCar() }}>导出</div>
  1163. <Tabs
  1164. defaultActiveKey="2"
  1165. activeKey={tabCarKey}
  1166. onChange={(key) => {
  1167. setTabCarKey(key);
  1168. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1169. getListData({}, { pn: 1 })
  1170. }}
  1171. items={[
  1172. {
  1173. label: `序号`,
  1174. key: '0',
  1175. disabled: "true"
  1176. },
  1177. {
  1178. label: <div className="tab-title">
  1179. <div className="title">区域</div>
  1180. <div className="btn">
  1181. <div onClick={() => {
  1182. message.success('升序');
  1183. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1184. getListData({ sort: 1 }, { pn: 1 })
  1185. }}></div>
  1186. <div onClick={() => {
  1187. message.success('降序');
  1188. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1189. getListData({ sort: 2 }, { pn: 1 })
  1190. }}></div>
  1191. </div>
  1192. </div>,
  1193. key: '1',
  1194. children: <><Table
  1195. showHeader={false}
  1196. columns={columns1}
  1197. dataSource={tableCarData?.list?.area_list || []}
  1198. rowKey={'area_name'}
  1199. bordered
  1200. pagination={false}
  1201. size="middle"
  1202. />
  1203. <Pagination {...paginationProps} className="pagination-common" total={tableData?.area_total_records} />
  1204. </>,
  1205. },
  1206. {
  1207. label: <div className="tab-title">
  1208. <div className="title">停车场</div>
  1209. <div className="btn">
  1210. <div onClick={() => {
  1211. message.success('升序');
  1212. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1213. getListData({ sort: 1 }, { pn: 1 })
  1214. }}></div>
  1215. <div onClick={() => {
  1216. message.success('降序');
  1217. setPageInfo({ ...pageInfo, ...{ pn: 1 } });
  1218. getListData({ sort: 2 }, { pn: 1 })
  1219. }}></div>
  1220. </div>
  1221. </div>,
  1222. key: '2',
  1223. children: <><Table
  1224. showHeader={false}
  1225. columns={parkColumns1}
  1226. dataSource={tableCarData?.list?.road_list}
  1227. rowKey={'area_name'}
  1228. bordered
  1229. pagination={false}
  1230. size="middle"
  1231. //scroll={{ y: 305 }}
  1232. // scroll={{
  1233. // x: 'calc(700px + 50%)',
  1234. // y: 240,
  1235. // }}
  1236. />
  1237. <Pagination {...paginationProps} className="pagination-common" total={tableData?.area_total_records} />
  1238. </>,
  1239. },
  1240. {
  1241. label: `停车次数`,
  1242. key: '3',
  1243. disabled: "true"
  1244. },
  1245. {
  1246. label: `平均停车时长`,
  1247. key: '4',
  1248. disabled: "true"
  1249. },
  1250. ]}
  1251. />
  1252. </div>
  1253. </div>
  1254. </div>
  1255. </div>
  1256. </div>
  1257. </>
  1258. );
  1259. }
  1260. export default ParkingAlyDuration;