import React, { useState, useEffect } from "react"; import { ResultFlowResult } from "@/components"; import { Select, Input, Button, Table, message, Pagination, DatePicker, Modal, Cascader, Tooltip, Tabs } from "antd"; import { useSessionStorageState } from "ahooks"; import { dictionary } from "@/config/common"; import { useNavigate } from "react-router-dom"; import { setTabList } from "@/store/common.js"; import { useSelector, useDispatch } from "react-redux"; import { QuestionCircleFilled } from "@ant-design/icons" import moment from "moment"; import ReactEcharts from "echarts-for-react"; import echarts from "echarts"; import "./index.scss"; import ajax from "@/services"; //停车时长分析 function ParkingAlyDuration() { // session缓存 const [defaultParams, setDefaultParams] = useSessionStorageState( "formData_parkingAlyDuration", { defaultValue: null } ); //区域的下拉数据 const [areaList, setAreaList] = useState([]); // 默认数据 const defaultData = { start_time: moment().subtract('days').startOf('day').format("YYYY-MM-DD"), end_time: moment().endOf("day").format("YYYY-MM-DD"), date_type: '1', //date_type: 1, }; // 分页数据 const [pageInfo, setPageInfo] = useState({ pn: 1, page_size: 10 }); // 表单数据 const [formData, setFormData] = useState({ ...defaultData, ...defaultParams, }); // 搜索提交数据-存储 const [holdData, setHoldData] = useState(formData); // 访问接口,isAjax改变时执行 const [isAjax, setIsAjax] = useState(false); // 检索按钮加载状态 const [loading, setLoading] = useState(false); // 表格加载状态 const [tabLoading, setTabLoading] = useState(false); // 表格返回数据 const [resultData, setResultData] = useState({ total: 0, list: [], }); // 泊位周转排行榜返回数据 const [tableData, setTableData] = useState({ area_list: [], road_list: [], }); // 停车排行榜返回数据setTableCarData const [tableCarData, setTableCarData] = useState({ area_list: [], road_list: [], }); //停车场收入概览数据 const [revenueData, setRevenueData] = useState({}); const [searchSelectList, setSearchSelectList] = useState([]); //搜索下拉数据 const [sessionTabList, setSessionTabList] = useSessionStorageState('parkingAlyDuration', { value: { } }) useEffect(() => { if (sessionTabList && Object.values(sessionTabList).length > 0) { setFormData({ ...formData, ...sessionTabList }) // getData({ // ...sessionTabList // }) getCheck({ ...sessionTabList }) } else { //getData() getCheck() } }, [isAjax]) const [tabKey, setTabKey] = useState("1"); const [tabCarKey, setTabCarKey] = useState("1"); const columns = [ { title: '序号', dataIndex: 'index', key: 'index', width: 100, render: (text, record, index) => index + 1 }, { title: '区域', dataIndex: 'area_name', key: 'area_name', width: 280, }, { title: '泊位数(个)', dataIndex: 'area_total_berths', key: 'area_total_berths', //width: 200, }, { title: '利用率', dataIndex: 'area_rate', key: 'area_rate', width: 120, }, ] const parkColumns = [ { title: '序号', dataIndex: 'index', key: 'index', width: 100, render: (text, record, index) => index + 1 }, { title: '停车场', dataIndex: 'road_name', key: 'road_name', width: 280, }, { title: '泊位数(个)', dataIndex: 'road_total_berths', key: 'road_total_berths', //width: 200, }, { title: '利用率', dataIndex: 'road_rate', key: 'road_rate', width: 120, }, ] const columns1 = [ { title: '序号', dataIndex: 'index', key: 'index', width: 100, render: (text, record, index) => index + 1 }, { title: '区域', dataIndex: 'area_name', key: 'area_name', width: 280, }, { title: '泊位数(个)', dataIndex: 'area_total_parkings', key: 'area_total_parkings', //width: 200, }, { title: '利用率', dataIndex: 'area_rate', key: 'area_rate', width: 120, }, ] const parkColumns1 = [ { title: '序号', dataIndex: 'index', key: 'index', width: 100, render: (text, record, index) => index + 1 }, { title: '停车场', dataIndex: 'road_name', key: 'road_name', width: 280, }, { title: '泊位数(个)', dataIndex: 'road_total_parkings', key: 'road_total_parkings', //width: 200, }, { title: '利用率', dataIndex: 'road_rate', key: 'road_rate', width: 120, }, ] const paginationProps = { className: "pagination-common", showQuickJumper: true, showSizeChanger: true, current: pageInfo.pn, //total: resultData?.totalRecords, pageSize: pageInfo.page_size, pageSizeOptions: Array.from( new Set([...[15], ...(dictionary?.pageSizeOptions || [])]) ), onChange: (current, size) => { setPageInfo({ ...pageInfo, ...{ pn: current, length: size } }); setIsAjax(!isAjax) //getListData({}) }, } // useEffect(() => { // getData() // }, [pageInfo]) useEffect(() => { setSessionTabList({ ...formData }) }, [formData]) useEffect(() => { getSelectList(); }, []); // 访问接口,获取表格 // useEffect(() => { // getData(); // }, [isAjax]); //时间状态切换 const TimeChange = () => { let e = formData.date_type; let str = "day"; let mat = "YYYY-MM-DD"; if (e == 4) { str = "year"; mat = "YYYY"; } else if (e == 3) { str = "month"; mat = "YYYY-MM"; } else if (e == 2) { str = "week"; mat = "YYYY-MM-DD"; } return { str, mat }; }; //切换时间变化 const SetTimeNow = (e) => { let start = ""; let end = ""; if (e == 4) { start = moment().format("YYYY"); end = moment().format("YYYY"); } else if (e == 3) { start = moment().startOf('month').format("YYYY-MM-DD"); end = moment().endOf("month").format("YYYY-MM-DD"); } else if (e == 2) { start = moment().day(1).format("YYYY-MM-DD"); end = moment().day(7).format("YYYY-MM-DD"); } else { start = moment().startOf("day").format("YYYY-MM-DD"); end = moment().endOf("day").format("YYYY-MM-DD"); } setFormData({ ...formData, date_type: e, start_time: start, end_time: end, }); }; //停车场收入概览 柱状图 const getRevenueOption = (data) => { console.log(data) // data = [ // { // "hour": "0", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "1", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "2", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "3", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "4", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "5", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "6", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "7", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "8", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "9", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "10", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "11", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "12", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "13", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "14", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "15", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "16", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "17", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "18", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "19", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "20", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "21", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "22", // "record_count": "0", // "total_duration": "0" // }, // { // "hour": "23", // "record_count": "0", // "total_duration": "0" // } // ] let ac = [ { "hour": "0", "record_count": "0", "total_duration": "0" }, { "hour": "1", "record_count": "0", "total_duration": "0" }, { "hour": "2", "record_count": "0", "total_duration": "0" }, { "hour": "3", "record_count": "0", "total_duration": "0" }, { "hour": "4", "record_count": "0", "total_duration": "0" }, { "hour": "5", "record_count": "0", "total_duration": "0" }, { "hour": "6", "record_count": "0", "total_duration": "0" }, { "hour": "7", "record_count": "0", "total_duration": "0" }, { "hour": "8", "record_count": "0", "total_duration": "0" }, { "hour": "9", "record_count": "0", "total_duration": "0" }, { "hour": "10", "record_count": "0", "total_duration": "0" }, { "hour": "11", "record_count": "0", "total_duration": "0" }, { "hour": "12", "record_count": "0", "total_duration": "0" }, { "hour": "13", "record_count": "0", "total_duration": "0" }, { "hour": "14", "record_count": "0", "total_duration": "0" }, { "hour": "15", "record_count": "0", "total_duration": "0" }, { "hour": "16", "record_count": "0", "total_duration": "0" }, { "hour": "17", "record_count": "0", "total_duration": "0" }, { "hour": "18", "record_count": "0", "total_duration": "0" }, { "hour": "19", "record_count": "0", "total_duration": "0" }, { "hour": "20", "record_count": "0", "total_duration": "0" }, { "hour": "21", "record_count": "0", "total_duration": "0" }, { "hour": "22", "record_count": "0", "total_duration": "0" }, { "hour": "23", "record_count": "0", "total_duration": "0" } ] let leftData = [] let rightData = [] let yData = [] data.map(item => { yData.push(item.houer) leftData.push(item.record_count) leftData.push(item.total_duration) }) data.sort((a, b) => { return new Date(a.hour) - new Date(b.hour); }); const areaNames = ['停车次数', '停车时长']; // 获取所有日期 // const dates = [...new Set(data.map((item) => item.pay_date))].sort( // (a, b) => a.pay_date - b.pay_date // ); // 构建数据对象 // const seriesData = areaNames.map((areaName, index) => { // // 获取该地区的数据 // const areaData = data.filter((item) => item.area_name === areaName); // // 构建该地区的数据对象 // return { // name: areaName, // type: "bar", // // itemStyle: { // // normal: { // // label: { // // show: true, //开启显示 // // position: 'top', //在上方显示 // // textStyle: { //数值样式 // // color: 'white',//字体颜色 // // fontSize: 10//字体大小 // // } // // }, // // }, // // }, // data: dates.map((item) => { // for (const { pay_date, income } of areaData) { // if (pay_date === item) return income; // } // return 0; // }), // yAxisIndex: index == 1 ? 1 : null, // }; // }); setRevenueData({ title: { text: "", textStyle: { color: "#fff", }, }, tooltip: { trigger: "axis", }, legend: { type: "scroll", x: "center", data: areaNames, itemWidth: 18, itemHeight: 12, textStyle: { fontSize: 14, color: "#fff", }, }, xAxis: { //data: xAxisData, data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], type: 'category', axisLine: { lineStyle: { color: "#bbb", }, }, axisLabel: { textStyle: { color: "#bbb", }, }, axisTick: { show: false, } }, yAxis: [{ type: "value", name: '停车次数(次)', min: 0, interval: 10, splitNumber: 6, //设置坐标轴的分割段数 axisLabel: { textStyle: { color: "#ffffffa6", }, }, axisLine: { lineStyle: { color: "#ffffffa6", }, }, splitLine: { show: true, // 是否显示分隔线。默认数值轴显示,类目轴不显示 interval: '0', // 坐标轴刻度标签的显示间隔,在类目轴中有效.0显示所有 lineStyle: { color: ['#cccccc42'], // 分隔线颜色,可以设置成单个颜色,也可以设置成颜色数组,分隔线会按数组中颜色的顺序依次循环设置颜色 width: 2, // 分隔线线宽 type: 'dashed', // 坐标轴线线的类型('solid',实线类型;'dashed',虚线类型;'dotted',点状类型) }, }, }, { type: "value", name: '停车时长(时)', splitLine: { show: false }, axisLine: { lineStyle: { color: "#ffffffa6", }, }, splitLine: { show: true, // 是否显示分隔线。默认数值轴显示,类目轴不显示 interval: '0', // 坐标轴刻度标签的显示间隔,在类目轴中有效.0显示所有 lineStyle: { color: ['#cccccc42'], // 分隔线颜色,可以设置成单个颜色,也可以设置成颜色数组,分隔线会按数组中颜色的顺序依次循环设置颜色 width: 1.3, // 分隔线线宽 type: 'dashed', // 坐标轴线线的类型('solid',实线类型;'dashed',虚线类型;'dotted',点状类型) }, }, }, ], color: ["#4DC3FF", "#FFD767"], series: [ { name: "停车次数", type: "bar", data: leftData, //data:[1,24,6,8,4,32,5,2,5,25,6,34], barWidth: 12, itemStyle: { barBorderRadius: [2, 2, 0, 0], // (顺时针左上,右上,右下,左下) color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [{ offset: 0, color: '#99EBFF' // 0% 处的颜色 }, { offset: 1, color: '#3AA9FF' // 100% 处的颜色 }], globalCoord: false // 缺省为 false }, }, }, { name: "停车时长", type: "bar", yAxisIndex: 1, data: rightData, //data:[1,24,6,8,4,32,5,2,5,25,6,34], barWidth: 12, itemStyle: { barBorderRadius: [2, 2, 0, 0], // (顺时针左上,右上,右下,左下) color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [{ offset: 0, color: '#FFB8B8' // 0% 处的颜色 }, { offset: 1, color: '#F481F8' // 100% 处的颜色 }], globalCoord: false // 缺省为 false } }, } ], grid: { x: 50, y: 55, x2: 70, y2: 30, }, }); }; //获取柱状图数据 function getParkingIncome(data) { ajax .getParkingAlyDurationBar(data) .then((res) => { if (res.status === 20000) { console.log(res) getRevenueOption(res.data.list); } }) .catch((err) => console.error(err)); } // 获取下拉数据 const getSelectList = () => { ajax.getOperator().then((e) => { setSearchSelectList([ ...searchSelectList, ...e.data ]) }) }; // 获取日均泊位列表数据 const getData = (v, pn = {}) => { ajax.getParkingAlyDurationBerthList({ ...v, ...pn }).then( (res) => { if (parseInt(res?.status) === 20000) { setTableData(res?.data || {}); } else { message.error(res?.message); } setLoading(false); setTabLoading(false); }, (err) => { console.log(err); setLoading(false); setTabLoading(false); } ); }; // 获取停车时长列表数据 const getListData = (v, pn = {}) => { let postData = { ...formData, sort: 2 }; if (!loading) { postData = { ...holdData }; } setDefaultParams({ ...postData, ...pageInfo }); setTabLoading(true); ajax.getParkingAlyDurationParkingList({ ...postData, ...v, ...pageInfo, ...pn }).then( (res) => { if (parseInt(res?.status) === 20000) { setTableCarData(res?.data || {}); } else { message.error(res?.message); } setLoading(false); setTabLoading(false); }, (err) => { console.log(err); setLoading(false); setTabLoading(false); } ); }; // 携带参数处理 const getCheck = (v) => { let postData = { ...formData }; if (!loading) { postData = { ...holdData }; } setDefaultParams({ ...postData, ...pageInfo }); if (moment(formData.end_time) - moment(formData.start_time) > 1000 * 31 * 24 * 3600) { message.error("时间范围限制为31天!") setLoading(false); setTabLoading(false); return } setTabLoading(true); let params = { ...postData, ...v, ...pageInfo } //请求接口 getParkingIncome(params) getData(params) getListData(params) }; // 检索数据 const handleSearch = () => { setLoading(true); setPageInfo({ ...pageInfo, ...{ pn: 1 } }); setHoldData(formData); setIsAjax(!isAjax); }; // 日均周转次数导出 const handleExport = () => { if (tableData.list.area_list?.length > 0) { let { pn, page_size, ...params } = defaultParams; ajax.getParkingAlyDurationParkingExp(defaultParams).then( (res) => { if (res) { window.open(res.data.export_url) } else { message.error(res?.message); } }, (err) => { console.log(err); } ); } else { message.error("暂无数据"); } }; // 停车排行导出 const handleExportCar = () => { if (tableData.list.area_list?.length > 0) { let { pn, page_size, ...params } = defaultParams; ajax.getParkingAlyDurationExp(defaultParams).then( (res) => { if (res) { window.open(res.data.export_url) } else { message.error(res?.message); } }, (err) => { console.log(err); } ); } else { message.error("暂无数据"); } }; //区域下拉框数据 useEffect(() => { ajax .getAreaTree() .then((res) => { if (res.status === 20000) { setAreaList(res.data); } }) .catch((err) => { console.error(err); }); }, []); return ( <>