|
@ -1,12 +1,13 @@ |
|
|
import React, { useState, useEffect } from "react"; |
|
|
import React, { useState, useEffect } from "react"; |
|
|
import { ResultFlowResult, DataSelect } from "@/components"; |
|
|
import { ResultFlowResult, DataSelect } from "@/components"; |
|
|
import { Select, Input, Button, Table, message, Pagination, DatePicker, Modal, Cascader, Tooltip } from "antd"; |
|
|
|
|
|
|
|
|
import { Select, Input, Button, Table, message, Pagination, Tabs, DatePicker, Modal, Cascader, Tooltip } from "antd"; |
|
|
import { useSessionStorageState } from "ahooks"; |
|
|
import { useSessionStorageState } from "ahooks"; |
|
|
import { lineChartOption, stackBarChartOption } from "@/config/character.config.js"; |
|
|
import { lineChartOption, stackBarChartOption } from "@/config/character.config.js"; |
|
|
import { useNavigate } from "react-router-dom"; |
|
|
import { useNavigate } from "react-router-dom"; |
|
|
import { setTabList } from "@/store/common.js"; |
|
|
import { setTabList } from "@/store/common.js"; |
|
|
import { useSelector, useDispatch } from "react-redux"; |
|
|
import { useSelector, useDispatch } from "react-redux"; |
|
|
import { QuestionCircleFilled } from "@ant-design/icons" |
|
|
import { QuestionCircleFilled } from "@ant-design/icons" |
|
|
|
|
|
import { Icon } from "@/components" |
|
|
import moment from "moment"; |
|
|
import moment from "moment"; |
|
|
import ReactEcharts from "echarts-for-react"; |
|
|
import ReactEcharts from "echarts-for-react"; |
|
|
import "./index.scss"; |
|
|
import "./index.scss"; |
|
@ -22,8 +23,8 @@ function ParkingAlyOverview() { |
|
|
const [areaList, setAreaList] = useState([]); |
|
|
const [areaList, setAreaList] = useState([]); |
|
|
// 默认数据 |
|
|
// 默认数据 |
|
|
const defaultData = { |
|
|
const defaultData = { |
|
|
// confirm_start_time: moment().subtract('days').startOf('day').format("YYYY-MM-DD HH:mm:ss"), |
|
|
|
|
|
// confirm_end_time: moment().endOf("day").format("YYYY-MM-DD HH:mm:ss"), |
|
|
|
|
|
|
|
|
start_time: moment().subtract('days').startOf('day').format("YYYY-MM-DD HH:mm:ss"), |
|
|
|
|
|
end_time: moment().endOf("day").format("YYYY-MM-DD HH:mm:ss"), |
|
|
// create_start_time: moment().subtract('days').startOf('day').format("YYYY-MM-DD HH:mm:ss"), |
|
|
// create_start_time: moment().subtract('days').startOf('day').format("YYYY-MM-DD HH:mm:ss"), |
|
|
// create_end_time: moment().endOf("day").format("YYYY-MM-DD HH:mm:ss"), |
|
|
// create_end_time: moment().endOf("day").format("YYYY-MM-DD HH:mm:ss"), |
|
|
date_type: 1, |
|
|
date_type: 1, |
|
@ -52,6 +53,18 @@ function ParkingAlyOverview() { |
|
|
total: 0, |
|
|
total: 0, |
|
|
list: [], |
|
|
list: [], |
|
|
}); |
|
|
}); |
|
|
|
|
|
// 概览返回数据 |
|
|
|
|
|
const [baseData, setBaseData] = useState({ |
|
|
|
|
|
park_record_total: "", |
|
|
|
|
|
turn_times: '', |
|
|
|
|
|
use_parking_persent: "", |
|
|
|
|
|
average_park_time: "", |
|
|
|
|
|
}); |
|
|
|
|
|
// 停车资源利用率排行榜返回数据 |
|
|
|
|
|
const [tableData, setTableData] = useState({ |
|
|
|
|
|
area_list: [], |
|
|
|
|
|
road_list: [], |
|
|
|
|
|
}); |
|
|
//停车场收入概览数据 |
|
|
//停车场收入概览数据 |
|
|
const [revenueData, setRevenueData] = useState({}); |
|
|
const [revenueData, setRevenueData] = useState({}); |
|
|
const [searchSelectList, setSearchSelectList] = useState([]); //搜索下拉数据 |
|
|
const [searchSelectList, setSearchSelectList] = useState([]); //搜索下拉数据 |
|
@ -59,29 +72,63 @@ function ParkingAlyOverview() { |
|
|
value: { |
|
|
value: { |
|
|
} |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
const [tabKey, setTabKey] = useState("1"); |
|
|
|
|
|
function changeKey(key) { |
|
|
|
|
|
setTabKey(key); |
|
|
|
|
|
} |
|
|
const columns = [ |
|
|
const columns = [ |
|
|
{ |
|
|
{ |
|
|
title: '时间', |
|
|
|
|
|
|
|
|
title: '序号', |
|
|
dataIndex: 'index', |
|
|
dataIndex: 'index', |
|
|
key: 'index', |
|
|
key: 'index', |
|
|
// width: 100, |
|
|
|
|
|
// fixed: 'left', |
|
|
|
|
|
|
|
|
width: 100, |
|
|
|
|
|
render: (text, record, index) => index + 1 |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '区域', |
|
|
|
|
|
dataIndex: 'area_name', |
|
|
|
|
|
key: 'area_name', |
|
|
|
|
|
width: 280, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '泊位数(个)', |
|
|
|
|
|
dataIndex: 'used_berths', |
|
|
|
|
|
key: 'used_berths', |
|
|
|
|
|
//width: 200, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '利用率', |
|
|
|
|
|
dataIndex: 'area_rate', |
|
|
|
|
|
key: 'area_rate', |
|
|
|
|
|
width: 120, |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
] |
|
|
|
|
|
const parkColumns = [ |
|
|
{ |
|
|
{ |
|
|
title: '停车总时长', |
|
|
|
|
|
dataIndex: 'age', |
|
|
|
|
|
key: 'age', |
|
|
|
|
|
|
|
|
title: '序号', |
|
|
|
|
|
dataIndex: 'index', |
|
|
|
|
|
key: 'index', |
|
|
|
|
|
width: 100, |
|
|
|
|
|
render: (text, record, index) => index + 1 |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
title: '日均泊位停车时长', |
|
|
|
|
|
dataIndex: 'age', |
|
|
|
|
|
key: 'age', |
|
|
|
|
|
|
|
|
title: '停车场', |
|
|
|
|
|
dataIndex: 'road_name', |
|
|
|
|
|
key: 'road_name', |
|
|
|
|
|
width: 280, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
title: '日均泊位利用率', |
|
|
|
|
|
dataIndex: 'age', |
|
|
|
|
|
key: 'age', |
|
|
|
|
|
|
|
|
title: '泊位数(个)', |
|
|
|
|
|
dataIndex: 'used_berths', |
|
|
|
|
|
key: 'used_berths', |
|
|
|
|
|
//width: 200, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '利用率', |
|
|
|
|
|
dataIndex: 'road_rate', |
|
|
|
|
|
key: 'road_rate', |
|
|
|
|
|
width: 120, |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
] |
|
|
] |
|
@ -93,8 +140,12 @@ function ParkingAlyOverview() { |
|
|
getData({ |
|
|
getData({ |
|
|
...sessionTabList |
|
|
...sessionTabList |
|
|
}) |
|
|
}) |
|
|
|
|
|
getBaseData({ |
|
|
|
|
|
...sessionTabList |
|
|
|
|
|
}) |
|
|
} else { |
|
|
} else { |
|
|
getData() |
|
|
getData() |
|
|
|
|
|
getBaseData() |
|
|
} |
|
|
} |
|
|
}, [isAjax]) |
|
|
}, [isAjax]) |
|
|
useEffect(() => { |
|
|
useEffect(() => { |
|
@ -207,9 +258,9 @@ function ParkingAlyOverview() { |
|
|
}, |
|
|
}, |
|
|
}; |
|
|
}; |
|
|
}); |
|
|
}); |
|
|
//setRevenueData(lineChartOption) |
|
|
|
|
|
|
|
|
//setRevenueData(lineChartOption) |
|
|
|
|
|
|
|
|
console.log(212, lineChartOption) |
|
|
|
|
|
|
|
|
console.log(212, lineChartOption) |
|
|
setRevenueData({ |
|
|
setRevenueData({ |
|
|
title: { |
|
|
title: { |
|
|
text: "", |
|
|
text: "", |
|
@ -335,10 +386,10 @@ function ParkingAlyOverview() { |
|
|
postData = { ...holdData }; |
|
|
postData = { ...holdData }; |
|
|
} |
|
|
} |
|
|
setDefaultParams({ ...postData, ...pageInfo }); |
|
|
setDefaultParams({ ...postData, ...pageInfo }); |
|
|
if(moment(formData.end_time)-moment(formData.start_time)>7*1000*3*24*3600){ |
|
|
|
|
|
message.error("超过三周") |
|
|
|
|
|
|
|
|
if (moment(formData.end_time) - moment(formData.start_time) > 1000 * 31 * 24 * 3600) { |
|
|
|
|
|
message.error("超过31天") |
|
|
setLoading(false); |
|
|
setLoading(false); |
|
|
setTabLoading(false); |
|
|
|
|
|
|
|
|
setTabLoading(false); |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
setTabLoading(true); |
|
|
setTabLoading(true); |
|
@ -359,7 +410,53 @@ function ParkingAlyOverview() { |
|
|
} |
|
|
} |
|
|
); |
|
|
); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 获取列表数据 |
|
|
|
|
|
const getBaseData = (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); |
|
|
|
|
|
ajax.getParkingAlyOverviewBase({ ...postData, ...v, ...pageInfo }).then( |
|
|
|
|
|
(res) => { |
|
|
|
|
|
if (parseInt(res?.status) === 20000) { |
|
|
|
|
|
setBaseData(res?.data.list || {}); |
|
|
|
|
|
} else { |
|
|
|
|
|
message.error(res?.message); |
|
|
|
|
|
} |
|
|
|
|
|
setLoading(false); |
|
|
|
|
|
setTabLoading(false); |
|
|
|
|
|
}, |
|
|
|
|
|
(err) => { |
|
|
|
|
|
console.log(err); |
|
|
|
|
|
setLoading(false); |
|
|
|
|
|
setTabLoading(false); |
|
|
|
|
|
} |
|
|
|
|
|
); |
|
|
|
|
|
ajax.getParkingAlyOverviewList({ ...postData, ...v, ...pageInfo }).then( |
|
|
|
|
|
(res) => { |
|
|
|
|
|
if (parseInt(res?.status) === 20000) { |
|
|
|
|
|
setTableData(res?.data.list || {}); |
|
|
|
|
|
} else { |
|
|
|
|
|
message.error(res?.message); |
|
|
|
|
|
} |
|
|
|
|
|
setLoading(false); |
|
|
|
|
|
setTabLoading(false); |
|
|
|
|
|
}, |
|
|
|
|
|
(err) => { |
|
|
|
|
|
console.log(err); |
|
|
|
|
|
setLoading(false); |
|
|
|
|
|
setTabLoading(false); |
|
|
|
|
|
} |
|
|
|
|
|
); |
|
|
|
|
|
}; |
|
|
// 检索数据 |
|
|
// 检索数据 |
|
|
const handleSearch = () => { |
|
|
const handleSearch = () => { |
|
|
setLoading(true); |
|
|
setLoading(true); |
|
@ -479,7 +576,7 @@ function ParkingAlyOverview() { |
|
|
</div> |
|
|
</div> |
|
|
<div className="yisa-search"> |
|
|
<div className="yisa-search"> |
|
|
<label>日期 |
|
|
<label>日期 |
|
|
<div className="daf"> |
|
|
|
|
|
|
|
|
{/* <div className="daf"> |
|
|
<Select |
|
|
<Select |
|
|
value={formData.date_type} |
|
|
value={formData.date_type} |
|
|
// style={{ |
|
|
// style={{ |
|
@ -502,7 +599,7 @@ function ParkingAlyOverview() { |
|
|
]} |
|
|
]} |
|
|
onChange={(e) => SetTimeNow(e)} |
|
|
onChange={(e) => SetTimeNow(e)} |
|
|
/> |
|
|
/> |
|
|
</div> |
|
|
|
|
|
|
|
|
</div> */} |
|
|
</label> |
|
|
</label> |
|
|
<DatePicker |
|
|
<DatePicker |
|
|
style={{ width: "100%" }} |
|
|
style={{ width: "100%" }} |
|
@ -598,10 +695,57 @@ function ParkingAlyOverview() { |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div className="paid-result soll-result"> |
|
|
<div className="paid-result soll-result"> |
|
|
<div className="result"> |
|
|
|
|
|
<div className="result-box"> |
|
|
|
|
|
<div className="result-box-title">停车指标总览</div> |
|
|
|
|
|
|
|
|
<div className="result-hd-overview"> |
|
|
|
|
|
<div className="result-header rea"> |
|
|
|
|
|
<div className="result-content"> |
|
|
|
|
|
<div className="title">停车记录次数(次)</div> |
|
|
|
|
|
<Tooltip |
|
|
|
|
|
placement="topLeft" |
|
|
|
|
|
title={<span>统计期间内的总停车记录数 以入场为准</span>} |
|
|
|
|
|
> |
|
|
|
|
|
<i>?</i> |
|
|
|
|
|
</Tooltip> |
|
|
|
|
|
<div className="num">{baseData.park_record_total}</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div className="result-header reb"> |
|
|
|
|
|
<div className="result-content"> |
|
|
|
|
|
<div className="title">日均泊位周转次数(次)</div> |
|
|
|
|
|
<Tooltip |
|
|
|
|
|
placement="topLeft" |
|
|
|
|
|
title={<span>统计期间内平均每日每泊位的停车记是数</span>} |
|
|
|
|
|
> |
|
|
|
|
|
<i>?</i> |
|
|
|
|
|
</Tooltip> |
|
|
|
|
|
<div className="num">{baseData.turn_times}</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div className="result-header rec"> |
|
|
|
|
|
<div className="result-content"> |
|
|
|
|
|
<div className="title">停车资源利用率</div> |
|
|
|
|
|
<Tooltip |
|
|
|
|
|
placement="topLeft" |
|
|
|
|
|
title={<span>统计期间内停车资源使用比例</span>} |
|
|
|
|
|
> |
|
|
|
|
|
<i>?</i> |
|
|
|
|
|
</Tooltip> |
|
|
|
|
|
<div className="num">{baseData.use_parking_persent}</div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div className="result-header red"> |
|
|
|
|
|
<div className="result-content"> |
|
|
|
|
|
<div className="title">平均停车时长</div> |
|
|
|
|
|
<Tooltip |
|
|
|
|
|
placement="topLeft" |
|
|
|
|
|
title={<span>统计期间内入场的停车记录的平均停车时长</span>} |
|
|
|
|
|
> |
|
|
|
|
|
<i>?</i> |
|
|
|
|
|
</Tooltip> |
|
|
|
|
|
<div className="num">{baseData.average_park_time}</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div className="result"> |
|
|
<div className="result-box"> |
|
|
<div className="result-box"> |
|
|
<div className="result-box-title">停车趋势分析</div> |
|
|
<div className="result-box-title">停车趋势分析</div> |
|
|
<ReactEcharts |
|
|
<ReactEcharts |
|
@ -616,38 +760,71 @@ function ParkingAlyOverview() { |
|
|
</div> |
|
|
</div> |
|
|
<div className="result-box overview-right"> |
|
|
<div className="result-box overview-right"> |
|
|
<div className="result-box-title">停车资源利用率排行榜</div> |
|
|
<div className="result-box-title">停车资源利用率排行榜</div> |
|
|
<Table |
|
|
|
|
|
columns={columns} |
|
|
|
|
|
dataSource={[ |
|
|
|
|
|
{ |
|
|
|
|
|
index: 1, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
index: 1, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
index: 1, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
index: 1, |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
<div className="export-btn">导出</div> |
|
|
|
|
|
<div> |
|
|
|
|
|
<div onClick={()=>{message.success('up')}}>▲</div> |
|
|
|
|
|
<div onClick={()=>{message.success('down')}}>▼</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<Tabs |
|
|
|
|
|
defaultActiveKey="2" |
|
|
|
|
|
items={[ |
|
|
{ |
|
|
{ |
|
|
index: 1, |
|
|
|
|
|
|
|
|
label: <div> |
|
|
|
|
|
<div onClick={()=>{message.success('up')}}>▲</div> |
|
|
|
|
|
<div onClick={()=>{message.success('down')}}>▼</div> |
|
|
|
|
|
</div>, |
|
|
|
|
|
key: '1', |
|
|
|
|
|
children: `Content of Tab Pane 1`, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
index: 1, |
|
|
|
|
|
|
|
|
label: `Tab 2`, |
|
|
|
|
|
key: '2', |
|
|
|
|
|
children: `Content of Tab Pane 2`, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
index: 1, |
|
|
|
|
|
|
|
|
label: `Tab 3`, |
|
|
|
|
|
key: '3', |
|
|
|
|
|
children: `Content of Tab Pane 3`, |
|
|
}, |
|
|
}, |
|
|
]} |
|
|
|
|
|
bordered |
|
|
|
|
|
size="middle" |
|
|
|
|
|
// scroll={{ |
|
|
|
|
|
// x: 'calc(700px + 50%)', |
|
|
|
|
|
// y: 240, |
|
|
|
|
|
// }} |
|
|
|
|
|
|
|
|
]} |
|
|
/> |
|
|
/> |
|
|
|
|
|
<Tabs activeKey={tabKey} onChange={changeKey} tabBarExtraContent={{ left: "123" }}> |
|
|
|
|
|
<Tabs.TabPane tab="序号" key="0" disabled="true"> |
|
|
|
|
|
</Tabs.TabPane> |
|
|
|
|
|
<Tabs.TabPane tab="区域" key="1" children={{ left: "123" }}> |
|
|
|
|
|
<Table |
|
|
|
|
|
showHeader={false} |
|
|
|
|
|
columns={columns} |
|
|
|
|
|
dataSource={tableData.area_list} |
|
|
|
|
|
bordered |
|
|
|
|
|
size="middle" |
|
|
|
|
|
// scroll={{ |
|
|
|
|
|
// x: 'calc(700px + 50%)', |
|
|
|
|
|
// y: 240, |
|
|
|
|
|
// }} |
|
|
|
|
|
/> |
|
|
|
|
|
</Tabs.TabPane> |
|
|
|
|
|
<Tabs.TabPane tab="停车场" key="2" tabBarExtraContent={() => <div> |
|
|
|
|
|
<div>▲</div> |
|
|
|
|
|
<div>▼</div> |
|
|
|
|
|
</div>}> |
|
|
|
|
|
<Table |
|
|
|
|
|
showHeader={false} |
|
|
|
|
|
columns={parkColumns} |
|
|
|
|
|
dataSource={tableData.road_list} |
|
|
|
|
|
bordered |
|
|
|
|
|
size="middle" |
|
|
|
|
|
// scroll={{ |
|
|
|
|
|
// x: 'calc(700px + 50%)', |
|
|
|
|
|
// y: 240, |
|
|
|
|
|
// }} |
|
|
|
|
|
/> |
|
|
|
|
|
</Tabs.TabPane> |
|
|
|
|
|
<Tabs.TabPane tab="泊位数(个)" key="3" disabled="true"> |
|
|
|
|
|
</Tabs.TabPane> |
|
|
|
|
|
<Tabs.TabPane tab="利用率" key="4" disabled="true"> |
|
|
|
|
|
</Tabs.TabPane> |
|
|
|
|
|
</Tabs> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|