19 changed files with 2811 additions and 474 deletions
-
144src/components/DataSelect/index.jsx
-
17src/components/DataSelect/index.scss
-
16src/components/TableModule/index.jsx
-
2src/components/index.jsx
-
250src/pages/DataAnalysisPrediction/ParkingBusinessAly/CarTypeAly/index.scss
-
817src/pages/DataAnalysisPrediction/ParkingBusinessAly/CarTypeAly/loadable.jsx
-
581src/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkBerthAly/loadable.jsx
-
656src/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkTurnoverAly/loadable.jsx
-
199src/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingAlyOverview/index.scss
-
563src/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingAlyOverview/loadable.jsx
-
4src/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingLiveData/loadable.jsx
-
14src/pages/FinancialMgm/OrderInquiry/ReturnOrderInquiry/index.jsx
-
2src/pages/InRoadMgm/RecordInquiry/ArrearsInquiries/loadable.jsx
-
2src/pages/InRoadMgm/RecordInquiry/ArrearsRecordTotal/loadable.jsx
-
2src/pages/InRoadMgm/RecordInquiry/DisabledCarParkRecordTotal/loadable.jsx
-
2src/pages/InRoadMgm/RecordInquiry/EntryExitOptPDA/loadable.jsx
-
2src/pages/InRoadMgm/RecordInquiry/GeomagneticSignalMgm/loadable.jsx
-
2src/pages/InRoadMgm/RecordInquiry/ParkRecordTotal/loadable.jsx
-
2src/pages/InRoadMgm/RecordInquiry/UnRecordOrder/loadable.jsx
@ -0,0 +1,144 @@ |
|||||
|
import React, { useState, useEffect } from 'react' |
||||
|
import moment from 'moment' |
||||
|
import { Select, DatePicker, } from "antd"; |
||||
|
// import { Dropdown, Menu } from 'antd' |
||||
|
// import Icon from '../Icon' |
||||
|
import './index.scss' |
||||
|
|
||||
|
function DataSelect(props) { |
||||
|
console.log(props) |
||||
|
const { |
||||
|
formData = { |
||||
|
date_type:'4' |
||||
|
}, |
||||
|
SetTimeNow, |
||||
|
} = props |
||||
|
|
||||
|
//时间状态切换 |
||||
|
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 }; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<div className="yisa-search"> |
||||
|
<label>日期 |
||||
|
<div className="daf"> |
||||
|
<Select |
||||
|
value={formData?.date_type||''} |
||||
|
placeholder="请选择" |
||||
|
options={[ |
||||
|
{ |
||||
|
value: "1", |
||||
|
label: "日", |
||||
|
}, |
||||
|
{ |
||||
|
value: "2", |
||||
|
label: "周", |
||||
|
}, |
||||
|
{ |
||||
|
value: "3", |
||||
|
label: "月", |
||||
|
}, |
||||
|
{ |
||||
|
value: "4", |
||||
|
label: "年", |
||||
|
}, |
||||
|
]} |
||||
|
onChange={(e) => SetTimeNow(e)} |
||||
|
/> |
||||
|
</div> |
||||
|
</label> |
||||
|
<DatePicker |
||||
|
style={{ width: "100%" }} |
||||
|
format={TimeChange().mat} |
||||
|
picker={TimeChange().str} |
||||
|
allowClear={false} |
||||
|
value={formData.start_time ? moment(formData.start_time) : null} |
||||
|
onChange={(date, dateString) => { |
||||
|
if (TimeChange().str == "week") { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: date |
||||
|
? moment(date).day(1).format("YYYY-MM-DD") |
||||
|
: null, |
||||
|
}); |
||||
|
} else if (TimeChange().str == "day") { |
||||
|
if (date > moment(formData.end_time)) { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: dateString, |
||||
|
start_time: formData.end_time, |
||||
|
}); |
||||
|
} else { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: dateString, |
||||
|
}); |
||||
|
} |
||||
|
} else { |
||||
|
setFormData({ ...formData, start_time: dateString }); |
||||
|
} |
||||
|
}} |
||||
|
disabledDate={(current) => current > moment(formData.end_time)} |
||||
|
/> |
||||
|
|
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>至</label> |
||||
|
<DatePicker |
||||
|
style={{ width: "100%" }} |
||||
|
// showTime |
||||
|
format={TimeChange().mat} |
||||
|
picker={TimeChange().str} |
||||
|
allowClear={false} |
||||
|
value={formData.end_time ? moment(formData.end_time) : null} |
||||
|
onChange={(date, dateString) => { |
||||
|
if (TimeChange().str == "week") { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: date |
||||
|
? moment(date).day(7).format("YYYY-MM-DD") |
||||
|
: null, |
||||
|
}); |
||||
|
} else if (TimeChange().str == "day") { |
||||
|
if (date < moment(formData.start_time)) { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: dateString, |
||||
|
end_time: formData.start_time, |
||||
|
}); |
||||
|
} else { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: dateString, |
||||
|
}); |
||||
|
} |
||||
|
} else { |
||||
|
setFormData({ ...formData, end_time: dateString }); |
||||
|
} |
||||
|
}} |
||||
|
disabledDate={(current) => |
||||
|
current < moment(formData.start_time) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default DataSelect |
@ -0,0 +1,17 @@ |
|||||
|
.quick-menu { |
||||
|
flex: 1; |
||||
|
width: 100%; |
||||
|
padding: 5px 0; |
||||
|
color: #3d97eb; |
||||
|
ul { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
margin-bottom: 0; |
||||
|
li { |
||||
|
display: inline-block; |
||||
|
flex: auto; |
||||
|
text-align: center; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -1,5 +1,255 @@ |
|||||
@import "@/assets/css/mixin.scss"; |
@import "@/assets/css/mixin.scss"; |
||||
|
|
||||
$color-container-bg : var(--color-container-bg); |
$color-container-bg : var(--color-container-bg); |
||||
$color-user-list-bg : var(--color-user-list-bg); |
$color-user-list-bg : var(--color-user-list-bg); |
||||
$color-text : var(--color-text); |
$color-text : var(--color-text); |
||||
$color-primary : var(--color-primary); |
$color-primary : var(--color-primary); |
||||
|
|
||||
|
.edit-order-inquiry { |
||||
|
display: flex; |
||||
|
padding-top: 10px; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
overflow-y: auto; |
||||
|
@include scrollBar(var(--color-user-list-bg), #3B97FF); |
||||
|
|
||||
|
.paid-search { |
||||
|
display: block; |
||||
|
width: 375px; |
||||
|
padding: 10px 10px 20px 20px; |
||||
|
|
||||
|
.title { |
||||
|
width: 100%; |
||||
|
font-size: 16px; |
||||
|
font-family: Microsoft YaHei, Microsoft YaHei-Bold; |
||||
|
font-weight: 700; |
||||
|
text-align: left; |
||||
|
color: var(--color-text); |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.form-Wrap { |
||||
|
height: calc(100% - 45px); |
||||
|
overflow-y: auto; |
||||
|
scrollbar-width: none; |
||||
|
-ms-overflow-style: none; |
||||
|
|
||||
|
&::-webkit-scrollbar { |
||||
|
display: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.ant-select-selector, |
||||
|
.ant-picker, |
||||
|
.ant-input { |
||||
|
background-color: var(--color-search-list-item-bg) !important; |
||||
|
box-shadow: none !important; |
||||
|
color: var(--color-search-list-item-value); |
||||
|
border-color: var(--color-search-list-item-bd) !important; |
||||
|
} |
||||
|
|
||||
|
.yisa-search { |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-bottom: 24px; |
||||
|
|
||||
|
label { |
||||
|
color: var(--color-search-list-item-text); |
||||
|
flex: 0 0 27%; |
||||
|
max-width: 27%; |
||||
|
text-align: right; |
||||
|
padding-right: 8px; |
||||
|
.daf { |
||||
|
display: inline-block; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.form-con { |
||||
|
flex: 1; |
||||
|
width: 220px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.form-btn { |
||||
|
display: flex; |
||||
|
flex-flow: row nowrap; |
||||
|
justify-content: space-between; |
||||
|
margin: 40px 0px 0px; |
||||
|
padding: 0 3px; |
||||
|
|
||||
|
.ant-btn+.ant-btn { |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.ant-btn span { |
||||
|
font-size: 16px; |
||||
|
font-family: Microsoft YaHei, Microsoft YaHei-Regular; |
||||
|
font-weight: 400; |
||||
|
text-align: center; |
||||
|
color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
.reset { |
||||
|
width: 90px; |
||||
|
height: 36px; |
||||
|
background: var(--button-default-bg); |
||||
|
} |
||||
|
|
||||
|
.submit { |
||||
|
width: calc(100% - 100px); |
||||
|
height: 36px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.ant-btn+.ant-btn { |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.green { |
||||
|
background-color: #67c23a; |
||||
|
border-color: #67c23a; |
||||
|
} |
||||
|
.soll-result { |
||||
|
overflow: auto; |
||||
|
.result { |
||||
|
display: block !important; |
||||
|
} |
||||
|
} |
||||
|
.paid-result { |
||||
|
width: calc(100% - 375px); |
||||
|
padding-bottom: 15px; |
||||
|
padding: 20px; |
||||
|
background: var(--color-user-list-bg); |
||||
|
border-top-left-radius: 20px; |
||||
|
box-shadow: 0px 3px 8px 0px rgba(0, 0, 0, 0.08); |
||||
|
|
||||
|
.result { |
||||
|
@include flex-columns; |
||||
|
.result-box { |
||||
|
color: #ffffff; |
||||
|
background: #3e4557; |
||||
|
border-radius: 4px; |
||||
|
margin-bottom: 20px; |
||||
|
.result-box-title { |
||||
|
height: 21px; |
||||
|
font-size: 16px; |
||||
|
font-family: Microsoft YaHei, Microsoft YaHei-Bold; |
||||
|
font-weight: 700; |
||||
|
text-align: left; |
||||
|
margin: 18px 0 18px 18px; |
||||
|
display: inline-block; |
||||
|
|
||||
|
} |
||||
|
i { |
||||
|
border: 1px solid; |
||||
|
border-radius: 22px; |
||||
|
display: inline-block; |
||||
|
text-align: center; |
||||
|
font-size: 12px; |
||||
|
width: 22px; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.ant-table .ant-table-thead tr th { |
||||
|
background: #3e4557; |
||||
|
} |
||||
|
} |
||||
|
.overview-left { |
||||
|
display: inline-block; |
||||
|
width: 46%; |
||||
|
margin-right: 20px; |
||||
|
} |
||||
|
.overview-right { |
||||
|
display: inline-block; |
||||
|
width: 50%; |
||||
|
} |
||||
|
.row-head { |
||||
|
height: 32px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
margin-bottom: 13px; |
||||
|
|
||||
|
.number-wrapper { |
||||
|
display: inline-flex; |
||||
|
align-items: center; |
||||
|
font-size: 14px; |
||||
|
|
||||
|
.letter { |
||||
|
color: var(--color-text); |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.total-number { |
||||
|
color: var(--color-primary); |
||||
|
font-weight: bold; |
||||
|
margin: 0 4px; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.cc-result-flow { |
||||
|
width: 100%; |
||||
|
height: calc(100% - 34px - 13px); |
||||
|
|
||||
|
.yisa-table { |
||||
|
width: 100%; |
||||
|
height: calc(100% - 32px - 15px); |
||||
|
overflow-y: auto !important; |
||||
|
@include scrollBar(var(--color-user-list-bg), #3B97FF); |
||||
|
|
||||
|
.ant-table-thead { |
||||
|
th { |
||||
|
background: #616b83 !important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.ant-table-tbody { |
||||
|
td { |
||||
|
background: #3E4557 !important; |
||||
|
border-bottom-color: var(--color-table-border-bottom-color); |
||||
|
} |
||||
|
|
||||
|
tr:nth-child(even) { |
||||
|
td { |
||||
|
background: #3E4557 !important; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.modal-pay-configuration { |
||||
|
|
||||
|
.submitBtn { |
||||
|
text-align: center; |
||||
|
margin: 20px 0 0; |
||||
|
|
||||
|
.ant-btn { |
||||
|
width: 80px; |
||||
|
height: 35px; |
||||
|
border: none; |
||||
|
border-radius: 4px; |
||||
|
|
||||
|
span { |
||||
|
color: #ffffff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.submit { |
||||
|
background: #409eff; |
||||
|
} |
||||
|
|
||||
|
.cancel { |
||||
|
background: var(--button-default-bg); |
||||
|
margin-left: 20px; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -1,15 +1,810 @@ |
|||||
import React, { useState, useRef, useEffect } from "react"; |
|
||||
// import { message, Pagination, Table, Space, Modal, } from "antd"; |
|
||||
// import { dictionary, utils } from "@/config/common"; |
|
||||
// import moment from 'moment' |
|
||||
// import { useSessionStorageState, useUpdateEffect, useSize, useUpdate } from 'ahooks'; |
|
||||
// import ajax from "@/services" |
|
||||
// import { FormInput, FormSelect, OptionPanel, ResultPanel, FormSliderPicker, AreaCascader, ImgResize, ImgZoom, } from "@/components" |
|
||||
// import "./index.scss"; |
|
||||
// import errorImg from "@/assets/images/layout/error.png" |
|
||||
// import { useLocation } from "react-router-dom"; |
|
||||
|
import React, { useState, useEffect } from "react"; |
||||
|
import { ResultFlowResult, DataSelect } from "@/components"; |
||||
|
import { Select, Input, Button, Table, message, Pagination, DatePicker, Modal, Cascader, Tooltip } 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 "./index.scss"; |
||||
|
import ajax from "@/services"; |
||||
|
//车辆类型分析 |
||||
function CarTypeAly() { |
function CarTypeAly() { |
||||
return <div>CarTypeAly</div> |
|
||||
|
// session缓存 |
||||
|
const [defaultParams, setDefaultParams] = useSessionStorageState( |
||||
|
"formData_carTypeAly", |
||||
|
{ defaultValue: null } |
||||
|
); |
||||
|
//区域的下拉数据 |
||||
|
const [areaList, setAreaList] = useState([]); |
||||
|
// 默认数据 |
||||
|
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"), |
||||
|
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"), |
||||
|
app_name: "", // 应用名称 |
||||
|
app_type: 0, //应用类型 |
||||
|
pay_merchant_id: 0, //支付商户名称 |
||||
|
}; |
||||
|
// 分页数据 |
||||
|
const [pageInfo, setPageInfo] = useState({ |
||||
|
pn: defaultParams ? defaultParams?.pn : 1, |
||||
|
page_size: defaultParams ? defaultParams?.page_size : 15, |
||||
|
}); |
||||
|
// 表单数据 |
||||
|
const [formData, setFormData] = useState({ |
||||
|
data_type:'1', |
||||
|
...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 [revenueData, setRevenueData] = useState({}); |
||||
|
const [parkingData, setParkingData] = useState({}); |
||||
|
// |
||||
|
const [ringData, setRingData] = useState({}); |
||||
|
const [searchSelectList, setSearchSelectList] = useState([]); //搜索下拉数据 |
||||
|
const [sessionTabList, setSessionTabList] = useSessionStorageState('carTypeAly', { |
||||
|
value: { |
||||
|
} |
||||
|
}) |
||||
|
useEffect(() => { |
||||
|
if (sessionTabList && Object.values(sessionTabList).length > 0) { |
||||
|
setFormData({ |
||||
|
...formData, ...sessionTabList |
||||
|
}) |
||||
|
getData({ |
||||
|
...sessionTabList |
||||
|
}) |
||||
|
} else { |
||||
|
getData() |
||||
|
} |
||||
|
}, [isAjax]) |
||||
|
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().format("YYYY-MM"); |
||||
|
end = moment().format("YYYY-MM"); |
||||
|
} 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) => { |
||||
|
// 获取所有地区名称 |
||||
|
data.sort((a, b) => { |
||||
|
return new Date(a.pay_date) - new Date(b.pay_date); |
||||
|
}); |
||||
|
console.log(data); |
||||
|
const areaNames = [...new Set(data.map((item) => item.area_name))]; |
||||
|
// 获取所有日期 |
||||
|
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: "line", |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
label: { |
||||
|
show: true, //开启显示 |
||||
|
position: 'top', //在上方显示 |
||||
|
textStyle: { //数值样式 |
||||
|
color: 'white',//字体颜色 |
||||
|
fontSize: 10//字体大小 |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: dates.map((item) => { |
||||
|
for (const { pay_date, income } of areaData) { |
||||
|
console.log(pay_date, income); |
||||
|
if (pay_date === item) return income; |
||||
|
} |
||||
|
return 0; |
||||
|
}), |
||||
|
yAxisIndex: index == 1 ? 1 : null, |
||||
|
}; |
||||
|
}); |
||||
|
console.log(21, areaNames, seriesData) |
||||
|
// 构建X轴数据 |
||||
|
const xAxisData = dates.map((date) => { |
||||
|
return { |
||||
|
value: date, |
||||
|
textStyle: { |
||||
|
align: "center", |
||||
|
lineStyle: { |
||||
|
color: "skyblue", // 设置线的颜色为天蓝色 |
||||
|
shadowBlur: 6, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
setRevenueData({ |
||||
|
title: { |
||||
|
text: "", |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: "axis", |
||||
|
}, |
||||
|
legend: { |
||||
|
type: "scroll", |
||||
|
right: "5%", |
||||
|
//data: areaNames, |
||||
|
data: ["临时停车次数", "常时停车次数"], |
||||
|
itemWidth: 18, |
||||
|
itemHeight: 12, |
||||
|
textStyle: { |
||||
|
fontSize: 14, |
||||
|
color: 'white', |
||||
|
}, |
||||
|
}, |
||||
|
xAxis: { |
||||
|
//data: xAxisData, |
||||
|
data: ["00:00", "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", "11:00", "12:00"], |
||||
|
type: 'category', |
||||
|
boundaryGap: false, // 不留白,从原点开始 |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
textStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: "value", |
||||
|
name: '数量(次)', |
||||
|
min: 0, |
||||
|
//max: 50, |
||||
|
//interval: 10, |
||||
|
//splitNumber: 6, //设置坐标轴的分割段数 |
||||
|
}, |
||||
|
color: ["#4DC3FF", "#FFD767"], |
||||
|
//series: seriesData, |
||||
|
series: [ |
||||
|
{ |
||||
|
"name": "临时停车次数", |
||||
|
"type": "line", |
||||
|
"data": [ |
||||
|
12, |
||||
|
12, |
||||
|
24 |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"name": "常时停车次数", |
||||
|
"type": "line", |
||||
|
"data": [ |
||||
|
9, |
||||
|
4, |
||||
|
4 |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
grid: { |
||||
|
x: 50, |
||||
|
y: 55, |
||||
|
x2: 70, |
||||
|
y2: 20, |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
//泊位占用趋势 |
||||
|
const getParkingOption = (data) => { |
||||
|
// 获取所有地区名称 |
||||
|
data.sort((a, b) => { |
||||
|
return new Date(a.pay_date) - new Date(b.pay_date); |
||||
|
}); |
||||
|
console.log(data); |
||||
|
const areaNames = [...new Set(data.map((item) => item.area_name))]; |
||||
|
// 获取所有日期 |
||||
|
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: "line", |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
label: { |
||||
|
show: true, //开启显示 |
||||
|
position: 'top', //在上方显示 |
||||
|
textStyle: { //数值样式 |
||||
|
color: 'white',//字体颜色 |
||||
|
fontSize: 10//字体大小 |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: dates.map((item) => { |
||||
|
for (const { pay_date, income } of areaData) { |
||||
|
console.log(pay_date, income); |
||||
|
if (pay_date === item) return income; |
||||
|
} |
||||
|
return 0; |
||||
|
}), |
||||
|
yAxisIndex: index == 1 ? 1 : null, |
||||
|
}; |
||||
|
}); |
||||
|
console.log(21, areaNames, seriesData) |
||||
|
// 构建X轴数据 |
||||
|
const xAxisData = dates.map((date) => { |
||||
|
return { |
||||
|
value: date, |
||||
|
textStyle: { |
||||
|
align: "center", |
||||
|
lineStyle: { |
||||
|
color: "skyblue", // 设置线的颜色为天蓝色 |
||||
|
shadowBlur: 6, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
setParkingData({ |
||||
|
title: { |
||||
|
text: "", |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: "axis", |
||||
|
}, |
||||
|
// legend: { |
||||
|
// type: "scroll", |
||||
|
// right: "5%", |
||||
|
// //data: areaNames, |
||||
|
// //data: ["临时停车次数", "常时停车次数"], |
||||
|
// itemWidth: 18, |
||||
|
// itemHeight: 12, |
||||
|
// textStyle: { |
||||
|
// fontSize: 14, |
||||
|
// color: 'white', |
||||
|
// }, |
||||
|
// }, |
||||
|
xAxis: { |
||||
|
//data: xAxisData, |
||||
|
data: ["00:00", "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", "11:00", "12:00"], |
||||
|
type: 'category', |
||||
|
boundaryGap: false, // 不留白,从原点开始 |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
textStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: "value", |
||||
|
name: '泊位占用率', |
||||
|
min: 0, |
||||
|
max: 100, |
||||
|
interval: 10, |
||||
|
//splitNumber: 6, //设置坐标轴的分割段数 |
||||
|
axisLabel: { |
||||
|
formatter: "{value}%", |
||||
|
textStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
color: ["#4DC3FF", "#FFD767"], |
||||
|
//series: seriesData, |
||||
|
series: |
||||
|
{ |
||||
|
"name": "临时停车次数", |
||||
|
"type": "line", |
||||
|
"data": [40, 0, 90, 34, 98, 100, 70, 80], |
||||
|
areaStyle: { |
||||
|
normal: {//自定义颜色,渐变色填充折线图区域 |
||||
|
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: 20, |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
// |
||||
|
const getRingOption = (data) => { |
||||
|
// 获取所有地区名称 |
||||
|
data.sort((a, b) => { |
||||
|
return new Date(a.pay_date) - new Date(b.pay_date); |
||||
|
}); |
||||
|
console.log(data); |
||||
|
const areaNames = [...new Set(data.map((item) => item.area_name))]; |
||||
|
|
||||
|
setRingData({ |
||||
|
title: { |
||||
|
text: "", |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: "axis", |
||||
|
}, |
||||
|
legend: { |
||||
|
type: "scroll", |
||||
|
//right: "5%", |
||||
|
top: 'bottom', |
||||
|
bottom: 'center', |
||||
|
//data: areaNames, |
||||
|
data: ["常时停车", "临时停车"], |
||||
|
itemWidth: 18, |
||||
|
itemHeight: 12, |
||||
|
textStyle: { |
||||
|
fontSize: 14, |
||||
|
color: 'white', |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
color: ["#4DC3FF", "#FFD767"], |
||||
|
//series: seriesData, |
||||
|
series: [ |
||||
|
{ |
||||
|
// name: 'Access From', |
||||
|
type: 'pie', |
||||
|
radius: ['60%', '70%'], |
||||
|
avoidLabelOverlap: false, |
||||
|
label: { |
||||
|
show: false, |
||||
|
position: 'center' |
||||
|
}, |
||||
|
emphasis: { |
||||
|
label: { |
||||
|
show: true, |
||||
|
fontSize: 40, |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
labelLine: { |
||||
|
show: false |
||||
|
}, |
||||
|
data: [ |
||||
|
{ value: 1048, name: '常时停车' }, |
||||
|
{ value: 735, name: '临时停车' }, |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
grid: { |
||||
|
x: 50, |
||||
|
y: 55, |
||||
|
x2: 70, |
||||
|
y2: 20, |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
function getParkingIncome() { |
||||
|
ajax |
||||
|
.getParkingIncome() |
||||
|
.then((res) => { |
||||
|
if (res.status === 20000) { |
||||
|
console.log(res) |
||||
|
getRevenueOption(res.data); |
||||
|
getParkingOption(res.data); |
||||
|
getRingOption(res.data) |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => console.error(err)); |
||||
|
} |
||||
|
|
||||
|
// 获取下拉数据 |
||||
|
const getSelectList = () => { |
||||
|
ajax.getPayRecordTotalSelect().then( |
||||
|
(res) => { |
||||
|
if (parseInt(res?.status) === 20000) { |
||||
|
setSearchSelectList(res.data || {}); |
||||
|
} |
||||
|
}, |
||||
|
(err) => { |
||||
|
console.log(err); |
||||
|
} |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
// 获取列表数据 |
||||
|
const getData = (v) => { |
||||
|
let postData = { ...formData }; |
||||
|
if (!loading) { |
||||
|
postData = { ...holdData }; |
||||
|
} |
||||
|
setDefaultParams({ ...postData, ...pageInfo }); |
||||
|
setTabLoading(true); |
||||
|
ajax.getAppList({ ...postData, ...pageInfo, ...v }).then( |
||||
|
(res) => { |
||||
|
if (parseInt(res?.status) === 20000) { |
||||
|
setResultData(res?.data || {}); |
||||
|
} else { |
||||
|
message.error(res?.message); |
||||
|
} |
||||
|
setLoading(false); |
||||
|
setTabLoading(false); |
||||
|
}, |
||||
|
(err) => { |
||||
|
console.log(err); |
||||
|
setLoading(false); |
||||
|
setTabLoading(false); |
||||
|
} |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
// 检索数据 |
||||
|
const handleSearch = () => { |
||||
|
setLoading(true); |
||||
|
setPageInfo({ ...pageInfo, ...{ pn: 1 } }); |
||||
|
setHoldData(formData); |
||||
|
setIsAjax(!isAjax); |
||||
|
}; |
||||
|
|
||||
|
useEffect(() => { |
||||
|
getParkingIncome(); |
||||
|
}, []); |
||||
|
//区域下拉框数据 |
||||
|
useEffect(() => { |
||||
|
ajax |
||||
|
.getAreaTree() |
||||
|
.then((res) => { |
||||
|
if (res.status === 20000) { |
||||
|
setAreaList(res.data); |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => { |
||||
|
console.error(err); |
||||
|
}); |
||||
|
}, []); |
||||
|
return ( |
||||
|
<> |
||||
|
<div className="edit-order-inquiry"> |
||||
|
<div className="paid-search"> |
||||
|
<div className="title">查询条件</div> |
||||
|
<div className="form-Wrap"> |
||||
|
<div className="yisa-search"> |
||||
|
<label>区域</label> |
||||
|
<Cascader |
||||
|
className="form-con" |
||||
|
popupClassName="start-exception-deal-cascader" |
||||
|
options={areaList} |
||||
|
placeholder="请选择区域" |
||||
|
expandTrigger="hover" |
||||
|
fieldNames={{ |
||||
|
label: "name", |
||||
|
value: "id", |
||||
|
children: "children", |
||||
|
}} |
||||
|
value={formData.region} |
||||
|
onChange={(v, option) => { |
||||
|
setFormData({ ...formData, region: v ? v : null }); |
||||
|
}} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>运营商</label> |
||||
|
<Select |
||||
|
className="form-con" |
||||
|
placeholder="请选择" |
||||
|
options={searchSelectList?.flow_type_list || []} |
||||
|
value={formData.pay_merchant_id} |
||||
|
onChange={(v) => |
||||
|
setFormData({ ...formData, pay_merchant_id: v }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>车场类型</label> |
||||
|
<Select |
||||
|
className="form-con" |
||||
|
placeholder="请选择车场类型" |
||||
|
options={[ |
||||
|
{ |
||||
|
label: '全部', |
||||
|
value: '0', |
||||
|
}, |
||||
|
{ |
||||
|
label: '路内车场', |
||||
|
value: '1', |
||||
|
}, |
||||
|
{ |
||||
|
label: '路外车场', |
||||
|
value: '2', |
||||
|
}, |
||||
|
]} |
||||
|
value={formData.pay_merchant_id} |
||||
|
onChange={(v) => |
||||
|
setFormData({ ...formData, pay_merchant_id: v }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>停车场</label> |
||||
|
<Input |
||||
|
className="form-con" |
||||
|
placeholder="请输入" |
||||
|
value={formData?.park} |
||||
|
onChange={(e) => |
||||
|
setFormData({ ...formData, park: e.target.value }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>日期 |
||||
|
<div className="daf"> |
||||
|
<Select |
||||
|
value={formData.date_type} |
||||
|
// style={{ |
||||
|
// width: "100%", |
||||
|
// }} |
||||
|
placeholder="请选择" |
||||
|
options={[ |
||||
|
{ |
||||
|
value: "1", |
||||
|
label: "日", |
||||
|
}, |
||||
|
{ |
||||
|
value: "2", |
||||
|
label: "周", |
||||
|
}, |
||||
|
{ |
||||
|
value: "3", |
||||
|
label: "月", |
||||
|
}, |
||||
|
{ |
||||
|
value: "4", |
||||
|
label: "年", |
||||
|
}, |
||||
|
]} |
||||
|
onChange={(e) => SetTimeNow(e)} |
||||
|
/> |
||||
|
</div> |
||||
|
</label> |
||||
|
<DatePicker |
||||
|
style={{ width: "100%" }} |
||||
|
// showTime |
||||
|
format={TimeChange().mat} |
||||
|
picker={TimeChange().str} |
||||
|
allowClear={false} |
||||
|
value={formData.start_time ? moment(formData.start_time) : null} |
||||
|
onChange={(date, dateString) => { |
||||
|
if (TimeChange().str == "week") { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: date |
||||
|
? moment(date).day(1).format("YYYY-MM-DD") |
||||
|
: null, |
||||
|
}); |
||||
|
} else if (TimeChange().str == "day") { |
||||
|
if (date > moment(formData.end_time)) { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: dateString, |
||||
|
start_time: formData.end_time, |
||||
|
}); |
||||
|
} else { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: dateString, |
||||
|
}); |
||||
|
} |
||||
|
} else { |
||||
|
setFormData({ ...formData, start_time: dateString }); |
||||
|
} |
||||
|
}} |
||||
|
disabledDate={(current) => current > moment(formData.end_time)} |
||||
|
/> |
||||
|
|
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>至</label> |
||||
|
<DatePicker |
||||
|
style={{ width: "100%" }} |
||||
|
// showTime |
||||
|
format={TimeChange().mat} |
||||
|
picker={TimeChange().str} |
||||
|
allowClear={false} |
||||
|
value={formData.end_time ? moment(formData.end_time) : null} |
||||
|
onChange={(date, dateString) => { |
||||
|
if (TimeChange().str == "week") { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: date |
||||
|
? moment(date).day(7).format("YYYY-MM-DD") |
||||
|
: null, |
||||
|
}); |
||||
|
} else if (TimeChange().str == "day") { |
||||
|
if (date < moment(formData.start_time)) { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: dateString, |
||||
|
end_time: formData.start_time, |
||||
|
}); |
||||
|
} else { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: dateString, |
||||
|
}); |
||||
|
} |
||||
|
} else { |
||||
|
setFormData({ ...formData, end_time: dateString }); |
||||
|
} |
||||
|
}} |
||||
|
disabledDate={(current) => |
||||
|
current < moment(formData.start_time) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="form-btn"> |
||||
|
<Button |
||||
|
className="reset" |
||||
|
onClick={() => setFormData(defaultData)} |
||||
|
> |
||||
|
重置 |
||||
|
</Button> |
||||
|
<Button |
||||
|
className="submit" |
||||
|
type="primary" |
||||
|
onClick={handleSearch} |
||||
|
loading={loading} |
||||
|
> |
||||
|
查询 |
||||
|
</Button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className="paid-result soll-result"> |
||||
|
<div className="result"> |
||||
|
<div className="parkinglive-box"> |
||||
|
<div className="result-box parkinglive-left"> |
||||
|
<div className="result-box-title">新能源车辆占比</div> |
||||
|
<Tooltip |
||||
|
placement="topLeft" |
||||
|
title={<span>展示统计期间出现过的能源车辆数与非新能源车辆数之间的对比情况</span>} |
||||
|
> |
||||
|
<i>?</i> |
||||
|
</Tooltip> |
||||
|
<ReactEcharts |
||||
|
option={ringData} |
||||
|
style={{ height: "300px", width: "100%", overflow: "hidden" }} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="result-box parkinglive-right"> |
||||
|
<div className="result-box-title">车型分类</div> |
||||
|
<Tooltip |
||||
|
placement="topLeft" |
||||
|
title={<span>展示统计时间段内不同车型车之间数量的对比情况</span>} |
||||
|
> |
||||
|
<i>?</i> |
||||
|
</Tooltip> |
||||
|
<ReactEcharts |
||||
|
option={ringData} |
||||
|
style={{ height: "300px", width: "100%", overflow: "hidden" }} |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className="parkinglive-box"> |
||||
|
<div className="result-box parkinglive-left"> |
||||
|
<div className="result-box-title">新能源趋势分析</div> |
||||
|
<Tooltip |
||||
|
placement="topLeft" |
||||
|
title={<span>展示统计时间段内的新能源停车和非新能源停车数量的变化趋势</span>} |
||||
|
> |
||||
|
<i>?</i> |
||||
|
</Tooltip> |
||||
|
<ReactEcharts |
||||
|
option={revenueData} |
||||
|
style={{ height: "300px", width: "100%", overflow: "hidden" }} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="result-box parkinglive-right"> |
||||
|
<div className="result-box-title">新能源车排行</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</> |
||||
|
); |
||||
} |
} |
||||
|
|
||||
export default CarTypeAly; |
export default CarTypeAly; |
@ -1,15 +1,574 @@ |
|||||
import React, { useState, useRef, useEffect } from "react"; |
|
||||
// import { message, Pagination, Table, Space, Modal, } from "antd"; |
|
||||
// import { dictionary, utils } from "@/config/common"; |
|
||||
// import moment from 'moment' |
|
||||
// import { useSessionStorageState, useUpdateEffect, useSize, useUpdate } from 'ahooks'; |
|
||||
// import ajax from "@/services" |
|
||||
// import { FormInput, FormSelect, OptionPanel, ResultPanel, FormSliderPicker, AreaCascader, ImgResize, ImgZoom, } from "@/components" |
|
||||
// import "./index.scss"; |
|
||||
// import errorImg from "@/assets/images/layout/error.png" |
|
||||
// import { useLocation } from "react-router-dom"; |
|
||||
|
import React, { useState, useEffect } from "react"; |
||||
|
import { ResultFlowResult, DataSelect } from "@/components"; |
||||
|
import { Select, Input, Button, Table, message, Pagination, DatePicker, Modal, Cascader, Tooltip } 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 "./index.scss"; |
||||
|
import ajax from "@/services"; |
||||
function ParkBerthAly() { |
function ParkBerthAly() { |
||||
return <div>ParkBerthAly</div> |
|
||||
|
// session缓存 |
||||
|
const [defaultParams, setDefaultParams] = useSessionStorageState( |
||||
|
"formData_carTypeAly", |
||||
|
{ defaultValue: null } |
||||
|
); |
||||
|
//区域的下拉数据 |
||||
|
const [areaList, setAreaList] = useState([]); |
||||
|
// 默认数据 |
||||
|
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"), |
||||
|
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"), |
||||
|
app_name: "", // 应用名称 |
||||
|
app_type: 0, //应用类型 |
||||
|
pay_merchant_id: 0, //支付商户名称 |
||||
|
}; |
||||
|
// 分页数据 |
||||
|
const [pageInfo, setPageInfo] = useState({ |
||||
|
pn: defaultParams ? defaultParams?.pn : 1, |
||||
|
page_size: defaultParams ? defaultParams?.page_size : 15, |
||||
|
}); |
||||
|
// 表单数据 |
||||
|
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 [revenueData, setRevenueData] = useState({}); |
||||
|
const [parkingData, setParkingData] = useState({}); |
||||
|
// |
||||
|
const [ringData, setRingData] = useState({}); |
||||
|
const [searchSelectList, setSearchSelectList] = useState([]); //搜索下拉数据 |
||||
|
const [sessionTabList, setSessionTabList] = useSessionStorageState('carTypeAly', { |
||||
|
value: { |
||||
|
} |
||||
|
}) |
||||
|
useEffect(() => { |
||||
|
if (sessionTabList && Object.values(sessionTabList).length > 0) { |
||||
|
setFormData({ |
||||
|
...formData, ...sessionTabList |
||||
|
}) |
||||
|
getData({ |
||||
|
...sessionTabList |
||||
|
}) |
||||
|
} else { |
||||
|
getData() |
||||
|
} |
||||
|
}, [isAjax]) |
||||
|
useEffect(() => { |
||||
|
setSessionTabList({ |
||||
|
...formData |
||||
|
}) |
||||
|
}, [formData]) |
||||
|
useEffect(() => { |
||||
|
getSelectList(); |
||||
|
}, []); |
||||
|
|
||||
|
// 访问接口,获取表格 |
||||
|
// useEffect(() => { |
||||
|
// getData(); |
||||
|
// }, [isAjax]); |
||||
|
|
||||
|
//出入场趋势 |
||||
|
const getRevenueOption = (data) => { |
||||
|
// 获取所有地区名称 |
||||
|
data.sort((a, b) => { |
||||
|
return new Date(a.pay_date) - new Date(b.pay_date); |
||||
|
}); |
||||
|
console.log(data); |
||||
|
const areaNames = [...new Set(data.map((item) => item.area_name))]; |
||||
|
// 获取所有日期 |
||||
|
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: "line", |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
label: { |
||||
|
show: true, //开启显示 |
||||
|
position: 'top', //在上方显示 |
||||
|
textStyle: { //数值样式 |
||||
|
color: 'white',//字体颜色 |
||||
|
fontSize: 10//字体大小 |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: dates.map((item) => { |
||||
|
for (const { pay_date, income } of areaData) { |
||||
|
console.log(pay_date, income); |
||||
|
if (pay_date === item) return income; |
||||
|
} |
||||
|
return 0; |
||||
|
}), |
||||
|
yAxisIndex: index == 1 ? 1 : null, |
||||
|
}; |
||||
|
}); |
||||
|
console.log(21, areaNames, seriesData) |
||||
|
// 构建X轴数据 |
||||
|
const xAxisData = dates.map((date) => { |
||||
|
return { |
||||
|
value: date, |
||||
|
textStyle: { |
||||
|
align: "center", |
||||
|
lineStyle: { |
||||
|
color: "skyblue", // 设置线的颜色为天蓝色 |
||||
|
shadowBlur: 6, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
setRevenueData({ |
||||
|
title: { |
||||
|
text: "", |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: "axis", |
||||
|
}, |
||||
|
legend: { |
||||
|
type: "scroll", |
||||
|
right: "5%", |
||||
|
//data: areaNames, |
||||
|
data: ["临时停车次数", "常时停车次数"], |
||||
|
itemWidth: 18, |
||||
|
itemHeight: 12, |
||||
|
textStyle: { |
||||
|
fontSize: 14, |
||||
|
color: 'white', |
||||
|
}, |
||||
|
}, |
||||
|
xAxis: { |
||||
|
//data: xAxisData, |
||||
|
data: ["00:00", "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", "11:00", "12:00"], |
||||
|
type: 'category', |
||||
|
boundaryGap: false, // 不留白,从原点开始 |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
textStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: "value", |
||||
|
name: '数量(次)', |
||||
|
min: 0, |
||||
|
//max: 50, |
||||
|
//interval: 10, |
||||
|
//splitNumber: 6, //设置坐标轴的分割段数 |
||||
|
}, |
||||
|
color: ["#4DC3FF", "#FFD767"], |
||||
|
//series: seriesData, |
||||
|
series: [ |
||||
|
{ |
||||
|
"name": "临时停车次数", |
||||
|
"type": "line", |
||||
|
"data": [ |
||||
|
12, |
||||
|
12, |
||||
|
24 |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"name": "常时停车次数", |
||||
|
"type": "line", |
||||
|
"data": [ |
||||
|
9, |
||||
|
4, |
||||
|
4 |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
grid: { |
||||
|
x: 50, |
||||
|
y: 55, |
||||
|
x2: 70, |
||||
|
y2: 20, |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
//泊位占用趋势 |
||||
|
const getParkingOption = (data) => { |
||||
|
// 获取所有地区名称 |
||||
|
data.sort((a, b) => { |
||||
|
return new Date(a.pay_date) - new Date(b.pay_date); |
||||
|
}); |
||||
|
console.log(data); |
||||
|
const areaNames = [...new Set(data.map((item) => item.area_name))]; |
||||
|
// 获取所有日期 |
||||
|
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: "line", |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
label: { |
||||
|
show: true, //开启显示 |
||||
|
position: 'top', //在上方显示 |
||||
|
textStyle: { //数值样式 |
||||
|
color: 'white',//字体颜色 |
||||
|
fontSize: 10//字体大小 |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: dates.map((item) => { |
||||
|
for (const { pay_date, income } of areaData) { |
||||
|
console.log(pay_date, income); |
||||
|
if (pay_date === item) return income; |
||||
|
} |
||||
|
return 0; |
||||
|
}), |
||||
|
yAxisIndex: index == 1 ? 1 : null, |
||||
|
}; |
||||
|
}); |
||||
|
console.log(21, areaNames, seriesData) |
||||
|
// 构建X轴数据 |
||||
|
const xAxisData = dates.map((date) => { |
||||
|
return { |
||||
|
value: date, |
||||
|
textStyle: { |
||||
|
align: "center", |
||||
|
lineStyle: { |
||||
|
color: "skyblue", // 设置线的颜色为天蓝色 |
||||
|
shadowBlur: 6, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
setParkingData({ |
||||
|
title: { |
||||
|
text: "", |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: "axis", |
||||
|
}, |
||||
|
// legend: { |
||||
|
// type: "scroll", |
||||
|
// right: "5%", |
||||
|
// //data: areaNames, |
||||
|
// //data: ["临时停车次数", "常时停车次数"], |
||||
|
// itemWidth: 18, |
||||
|
// itemHeight: 12, |
||||
|
// textStyle: { |
||||
|
// fontSize: 14, |
||||
|
// color: 'white', |
||||
|
// }, |
||||
|
// }, |
||||
|
xAxis: { |
||||
|
//data: xAxisData, |
||||
|
data: ["00:00", "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", "11:00", "12:00"], |
||||
|
type: 'category', |
||||
|
boundaryGap: false, // 不留白,从原点开始 |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
textStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: "value", |
||||
|
name: '泊位占用率', |
||||
|
min: 0, |
||||
|
max: 100, |
||||
|
interval: 10, |
||||
|
//splitNumber: 6, //设置坐标轴的分割段数 |
||||
|
axisLabel: { |
||||
|
formatter: "{value}%", |
||||
|
textStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
color: ["#4DC3FF", "#FFD767"], |
||||
|
//series: seriesData, |
||||
|
series: |
||||
|
{ |
||||
|
"name": "临时停车次数", |
||||
|
"type": "line", |
||||
|
"data": [40, 0, 90, 34, 98, 100, 70, 80], |
||||
|
areaStyle: { |
||||
|
normal: {//自定义颜色,渐变色填充折线图区域 |
||||
|
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: 20, |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
// |
||||
|
const getRingOption = (data) => { |
||||
|
// 获取所有地区名称 |
||||
|
data.sort((a, b) => { |
||||
|
return new Date(a.pay_date) - new Date(b.pay_date); |
||||
|
}); |
||||
|
console.log(data); |
||||
|
const areaNames = [...new Set(data.map((item) => item.area_name))]; |
||||
|
|
||||
|
setRingData({ |
||||
|
title: { |
||||
|
text: "", |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: "axis", |
||||
|
}, |
||||
|
legend: { |
||||
|
type: "scroll", |
||||
|
//right: "5%", |
||||
|
top: 'bottom', |
||||
|
bottom: 'center', |
||||
|
//data: areaNames, |
||||
|
data: ["常时停车", "临时停车"], |
||||
|
itemWidth: 18, |
||||
|
itemHeight: 12, |
||||
|
textStyle: { |
||||
|
fontSize: 14, |
||||
|
color: 'white', |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
color: ["#4DC3FF", "#FFD767"], |
||||
|
//series: seriesData, |
||||
|
series: [ |
||||
|
{ |
||||
|
// name: 'Access From', |
||||
|
type: 'pie', |
||||
|
radius: ['60%', '70%'], |
||||
|
avoidLabelOverlap: false, |
||||
|
label: { |
||||
|
show: false, |
||||
|
position: 'center' |
||||
|
}, |
||||
|
emphasis: { |
||||
|
label: { |
||||
|
show: true, |
||||
|
fontSize: 40, |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
labelLine: { |
||||
|
show: false |
||||
|
}, |
||||
|
data: [ |
||||
|
{ value: 1048, name: '常时停车' }, |
||||
|
{ value: 735, name: '临时停车' }, |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
grid: { |
||||
|
x: 50, |
||||
|
y: 55, |
||||
|
x2: 70, |
||||
|
y2: 20, |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
function getParkingIncome() { |
||||
|
ajax |
||||
|
.getParkingIncome() |
||||
|
.then((res) => { |
||||
|
if (res.status === 20000) { |
||||
|
console.log(res) |
||||
|
getRevenueOption(res.data); |
||||
|
getParkingOption(res.data); |
||||
|
getRingOption(res.data) |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => console.error(err)); |
||||
|
} |
||||
|
|
||||
|
// 获取下拉数据 |
||||
|
const getSelectList = () => { |
||||
|
ajax.getPayRecordTotalSelect().then( |
||||
|
(res) => { |
||||
|
if (parseInt(res?.status) === 20000) { |
||||
|
setSearchSelectList(res.data || {}); |
||||
|
} |
||||
|
}, |
||||
|
(err) => { |
||||
|
console.log(err); |
||||
|
} |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
// 获取列表数据 |
||||
|
const getData = (v) => { |
||||
|
let postData = { ...formData }; |
||||
|
if (!loading) { |
||||
|
postData = { ...holdData }; |
||||
|
} |
||||
|
setDefaultParams({ ...postData, ...pageInfo }); |
||||
|
setTabLoading(true); |
||||
|
ajax.getAppList({ ...postData, ...pageInfo, ...v }).then( |
||||
|
(res) => { |
||||
|
if (parseInt(res?.status) === 20000) { |
||||
|
setResultData(res?.data || {}); |
||||
|
} else { |
||||
|
message.error(res?.message); |
||||
|
} |
||||
|
setLoading(false); |
||||
|
setTabLoading(false); |
||||
|
}, |
||||
|
(err) => { |
||||
|
console.log(err); |
||||
|
setLoading(false); |
||||
|
setTabLoading(false); |
||||
|
} |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
// 检索数据 |
||||
|
const handleSearch = () => { |
||||
|
setLoading(true); |
||||
|
setPageInfo({ ...pageInfo, ...{ pn: 1 } }); |
||||
|
setHoldData(formData); |
||||
|
setIsAjax(!isAjax); |
||||
|
}; |
||||
|
|
||||
|
useEffect(() => { |
||||
|
getParkingIncome(); |
||||
|
}, []); |
||||
|
//区域下拉框数据 |
||||
|
useEffect(() => { |
||||
|
ajax |
||||
|
.getAreaTree() |
||||
|
.then((res) => { |
||||
|
if (res.status === 20000) { |
||||
|
setAreaList(res.data); |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => { |
||||
|
console.error(err); |
||||
|
}); |
||||
|
}, []); |
||||
|
return ( |
||||
|
<> |
||||
|
<div className="edit-order-inquiry"> |
||||
|
<div className="paid-result soll-result"> |
||||
|
<div className="result"> |
||||
|
<div className="parkinglive-box"> |
||||
|
<div className="result-box parkinglive-left"> |
||||
|
<div className="result-box-title">新能源车辆占比</div> |
||||
|
<Tooltip |
||||
|
placement="topLeft" |
||||
|
title={<span>展示统计期间出现过的能源车辆数与非新能源车辆数之间的对比情况</span>} |
||||
|
> |
||||
|
<i>?</i> |
||||
|
</Tooltip> |
||||
|
<ReactEcharts |
||||
|
option={ringData} |
||||
|
style={{ height: "300px", width: "100%", overflow: "hidden" }} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="result-box parkinglive-right"> |
||||
|
<div className="result-box-title">车型分类</div> |
||||
|
<Tooltip |
||||
|
placement="topLeft" |
||||
|
title={<span>展示统计时间段内不同车型车之间数量的对比情况</span>} |
||||
|
> |
||||
|
<i>?</i> |
||||
|
</Tooltip> |
||||
|
<ReactEcharts |
||||
|
option={ringData} |
||||
|
style={{ height: "300px", width: "100%", overflow: "hidden" }} |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className="parkinglive-box"> |
||||
|
<div className="result-box parkinglive-left"> |
||||
|
<div className="result-box-title">新能源趋势分析</div> |
||||
|
<Tooltip |
||||
|
placement="topLeft" |
||||
|
title={<span>展示统计时间段内的新能源停车和非新能源停车数量的变化趋势</span>} |
||||
|
> |
||||
|
<i>?</i> |
||||
|
</Tooltip> |
||||
|
<ReactEcharts |
||||
|
option={revenueData} |
||||
|
style={{ height: "300px", width: "100%", overflow: "hidden" }} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="result-box parkinglive-right"> |
||||
|
<div className="result-box-title">新能源车排行</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</> |
||||
|
); |
||||
} |
} |
||||
|
|
||||
export default ParkBerthAly; |
export default ParkBerthAly; |
@ -1,15 +1,649 @@ |
|||||
import React, { useState, useRef, useEffect } from "react"; |
|
||||
// import { message, Pagination, Table, Space, Modal, } from "antd"; |
|
||||
// import { dictionary, utils } from "@/config/common"; |
|
||||
// import moment from 'moment' |
|
||||
// import { useSessionStorageState, useUpdateEffect, useSize, useUpdate } from 'ahooks'; |
|
||||
// import ajax from "@/services" |
|
||||
// import { FormInput, FormSelect, OptionPanel, ResultPanel, FormSliderPicker, AreaCascader, ImgResize, ImgZoom, } from "@/components" |
|
||||
// import "./index.scss"; |
|
||||
// import errorImg from "@/assets/images/layout/error.png" |
|
||||
// import { useLocation } from "react-router-dom"; |
|
||||
|
import React, { useState, useEffect } from "react"; |
||||
|
import { ResultFlowResult } from "@/components"; |
||||
|
import { Select, Input, Button, Table, message, Pagination, DatePicker, Modal, Cascader, Tooltip } 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 "./index.scss"; |
||||
|
import ajax from "@/services"; |
||||
|
|
||||
function ParkTurnoverAly() { |
function ParkTurnoverAly() { |
||||
return <div>ParkTurnoverAly</div> |
|
||||
|
// session缓存 |
||||
|
const [defaultParams, setDefaultParams] = useSessionStorageState( |
||||
|
"formData_parkingAlyPeriod", |
||||
|
{ defaultValue: null } |
||||
|
); |
||||
|
//区域的下拉数据 |
||||
|
const [areaList, setAreaList] = useState([]); |
||||
|
// 默认数据 |
||||
|
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"), |
||||
|
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"), |
||||
|
app_name: "", // 应用名称 |
||||
|
app_type: 0, //应用类型 |
||||
|
pay_merchant_id: 0, //支付商户名称 |
||||
|
}; |
||||
|
// 分页数据 |
||||
|
const [pageInfo, setPageInfo] = useState({ |
||||
|
pn: defaultParams ? defaultParams?.pn : 1, |
||||
|
page_size: defaultParams ? defaultParams?.page_size : 15, |
||||
|
}); |
||||
|
// 表单数据 |
||||
|
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 [revenueData, setRevenueData] = useState({}); |
||||
|
const [searchSelectList, setSearchSelectList] = useState([]); //搜索下拉数据 |
||||
|
const [sessionTabList, setSessionTabList] = useSessionStorageState('parkingAlyPeriod', { |
||||
|
value: { |
||||
|
} |
||||
|
}) |
||||
|
const columns = [ |
||||
|
{ |
||||
|
title: '时间', |
||||
|
dataIndex: 'index', |
||||
|
key: 'index', |
||||
|
// width: 100, |
||||
|
// fixed: 'left', |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
title: '入场次数(次)', |
||||
|
dataIndex: 'age', |
||||
|
key: 'age', |
||||
|
}, |
||||
|
{ |
||||
|
title: '总泊位数(个)', |
||||
|
dataIndex: 'age', |
||||
|
key: 'age', |
||||
|
}, |
||||
|
{ |
||||
|
title: '日均泊位周转次数(次)', |
||||
|
dataIndex: 'age', |
||||
|
key: 'age', |
||||
|
}, |
||||
|
|
||||
|
] |
||||
|
useEffect(() => { |
||||
|
if (sessionTabList && Object.values(sessionTabList).length > 0) { |
||||
|
setFormData({ |
||||
|
...formData, ...sessionTabList |
||||
|
}) |
||||
|
getData({ |
||||
|
...sessionTabList |
||||
|
}) |
||||
|
} else { |
||||
|
getData() |
||||
|
} |
||||
|
}, [isAjax]) |
||||
|
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().format("YYYY-MM"); |
||||
|
end = moment().format("YYYY-MM"); |
||||
|
} 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) => { |
||||
|
// 获取所有地区名称 |
||||
|
data.sort((a, b) => { |
||||
|
return new Date(a.pay_date) - new Date(b.pay_date); |
||||
|
}); |
||||
|
console.log(data); |
||||
|
const areaNames = [...new Set(data.map((item) => item.area_name))]; |
||||
|
// 获取所有日期 |
||||
|
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: "line", |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
label: { |
||||
|
show: true, //开启显示 |
||||
|
position: 'top', //在上方显示 |
||||
|
textStyle: { //数值样式 |
||||
|
color: 'white',//字体颜色 |
||||
|
fontSize: 10//字体大小 |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: dates.map((item) => { |
||||
|
for (const { pay_date, income } of areaData) { |
||||
|
console.log(pay_date, income); |
||||
|
if (pay_date === item) return income; |
||||
|
} |
||||
|
return 0; |
||||
|
}), |
||||
|
yAxisIndex: index == 1 ? 1 : null, |
||||
|
}; |
||||
|
}); |
||||
|
console.log(21, areaNames, seriesData) |
||||
|
// 构建X轴数据 |
||||
|
const xAxisData = dates.map((date) => { |
||||
|
return { |
||||
|
value: date, |
||||
|
textStyle: { |
||||
|
align: "center", |
||||
|
lineStyle: { |
||||
|
color: "skyblue", // 设置线的颜色为天蓝色 |
||||
|
shadowBlur: 6, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
setRevenueData({ |
||||
|
title: { |
||||
|
text: "", |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: "axis", |
||||
|
}, |
||||
|
xAxis: { |
||||
|
data: xAxisData, |
||||
|
type: 'category', |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
textStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: "value", |
||||
|
name: '泊位利用率', |
||||
|
min: 0, |
||||
|
// /max: 50, |
||||
|
interval: 10, |
||||
|
splitNumber: 6, //设置坐标轴的分割段数 |
||||
|
axisLabel: { |
||||
|
formatter: "{value}%", |
||||
|
textStyle: { |
||||
|
color: "#bbb", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
color: ["#4DC3FF", "#FFD767"], |
||||
|
//series: seriesData, |
||||
|
series: |
||||
|
{ |
||||
|
"name": "西区", |
||||
|
"type": "line", |
||||
|
"data": [ |
||||
|
12, |
||||
|
12, |
||||
|
24 |
||||
|
] |
||||
|
}, |
||||
|
grid: { |
||||
|
x: 50, |
||||
|
y: 55, |
||||
|
x2: 70, |
||||
|
y2: 20, |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
function getParkingIncome() { |
||||
|
ajax |
||||
|
.getParkingIncome() |
||||
|
.then((res) => { |
||||
|
if (res.status === 20000) { |
||||
|
console.log(res) |
||||
|
getRevenueOption(res.data); |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => console.error(err)); |
||||
|
} |
||||
|
|
||||
|
// 获取下拉数据 |
||||
|
const getSelectList = () => { |
||||
|
ajax.getPayRecordTotalSelect().then( |
||||
|
(res) => { |
||||
|
if (parseInt(res?.status) === 20000) { |
||||
|
setSearchSelectList(res.data || {}); |
||||
|
} |
||||
|
}, |
||||
|
(err) => { |
||||
|
console.log(err); |
||||
|
} |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
// 获取列表数据 |
||||
|
const getData = (v) => { |
||||
|
let postData = { ...formData }; |
||||
|
if (!loading) { |
||||
|
postData = { ...holdData }; |
||||
|
} |
||||
|
setDefaultParams({ ...postData, ...pageInfo }); |
||||
|
setTabLoading(true); |
||||
|
ajax.getAppList({ ...postData, ...pageInfo, ...v }).then( |
||||
|
(res) => { |
||||
|
if (parseInt(res?.status) === 20000) { |
||||
|
setResultData(res?.data || {}); |
||||
|
} else { |
||||
|
message.error(res?.message); |
||||
|
} |
||||
|
setLoading(false); |
||||
|
setTabLoading(false); |
||||
|
}, |
||||
|
(err) => { |
||||
|
console.log(err); |
||||
|
setLoading(false); |
||||
|
setTabLoading(false); |
||||
|
} |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
// 检索数据 |
||||
|
const handleSearch = () => { |
||||
|
setLoading(true); |
||||
|
setPageInfo({ ...pageInfo, ...{ pn: 1 } }); |
||||
|
setHoldData(formData); |
||||
|
setIsAjax(!isAjax); |
||||
|
}; |
||||
|
|
||||
|
// 导出 |
||||
|
const handleExport = () => { |
||||
|
if (resultData.list?.length > 0) { |
||||
|
let { pn, page_size, ...params } = defaultParams; |
||||
|
ajax.getAppList(params).then( |
||||
|
(res) => { |
||||
|
if (parseInt(res?.status) === 20000) { |
||||
|
message.success(res?.message); |
||||
|
} else { |
||||
|
message.error(res?.message); |
||||
|
} |
||||
|
}, |
||||
|
(err) => { |
||||
|
console.log(err); |
||||
|
} |
||||
|
); |
||||
|
} else { |
||||
|
message.error("暂无数据"); |
||||
|
} |
||||
|
}; |
||||
|
useEffect(() => { |
||||
|
getParkingIncome(); |
||||
|
}, []); |
||||
|
//区域下拉框数据 |
||||
|
useEffect(() => { |
||||
|
ajax |
||||
|
.getAreaTree() |
||||
|
.then((res) => { |
||||
|
if (res.status === 20000) { |
||||
|
setAreaList(res.data); |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => { |
||||
|
console.error(err); |
||||
|
}); |
||||
|
}, []); |
||||
|
return ( |
||||
|
<> |
||||
|
<div className="edit-order-inquiry"> |
||||
|
<div className="paid-search"> |
||||
|
<div className="title">查询条件</div> |
||||
|
<div className="form-Wrap"> |
||||
|
<div className="yisa-search"> |
||||
|
<label>区域</label> |
||||
|
<Cascader |
||||
|
className="form-con" |
||||
|
popupClassName="start-exception-deal-cascader" |
||||
|
options={areaList} |
||||
|
placeholder="请选择区域" |
||||
|
expandTrigger="hover" |
||||
|
fieldNames={{ |
||||
|
label: "name", |
||||
|
value: "id", |
||||
|
children: "children", |
||||
|
}} |
||||
|
value={formData.region} |
||||
|
onChange={(v, option) => { |
||||
|
setFormData({ ...formData, region: v ? v : null }); |
||||
|
}} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>运营商</label> |
||||
|
<Select |
||||
|
className="form-con" |
||||
|
placeholder="请选择" |
||||
|
options={searchSelectList?.flow_type_list || []} |
||||
|
value={formData.pay_merchant_id} |
||||
|
onChange={(v) => |
||||
|
setFormData({ ...formData, pay_merchant_id: v }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>车场类型</label> |
||||
|
<Select |
||||
|
className="form-con" |
||||
|
placeholder="请选择车场类型" |
||||
|
options={[ |
||||
|
{ |
||||
|
label: '全部', |
||||
|
value: '0', |
||||
|
}, |
||||
|
{ |
||||
|
label: '路内车场', |
||||
|
value: '1', |
||||
|
}, |
||||
|
{ |
||||
|
label: '路外车场', |
||||
|
value: '2', |
||||
|
}, |
||||
|
]} |
||||
|
value={formData.pay_merchant_id} |
||||
|
onChange={(v) => |
||||
|
setFormData({ ...formData, pay_merchant_id: v }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>停车场</label> |
||||
|
<Input |
||||
|
className="form-con" |
||||
|
placeholder="请输入" |
||||
|
value={formData?.park} |
||||
|
onChange={(e) => |
||||
|
setFormData({ ...formData, park: e.target.value }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>计费类型</label> |
||||
|
<Select |
||||
|
className="form-con" |
||||
|
placeholder="请选择计费类型" |
||||
|
options={[ |
||||
|
{ |
||||
|
label: '全部', |
||||
|
value: '0', |
||||
|
}, |
||||
|
{ |
||||
|
label: '一类区', |
||||
|
value: '1', |
||||
|
}, |
||||
|
{ |
||||
|
label: '二类区', |
||||
|
value: '2', |
||||
|
}, |
||||
|
{ |
||||
|
label: '三类区', |
||||
|
value: '3', |
||||
|
}, |
||||
|
]} |
||||
|
value={formData.pay_merchant_id} |
||||
|
onChange={(v) => |
||||
|
setFormData({ ...formData, pay_merchant_id: v }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>日期 |
||||
|
<div className="daf"> |
||||
|
<Select |
||||
|
value={formData.date_type} |
||||
|
// style={{ |
||||
|
// width: "100%", |
||||
|
// }} |
||||
|
placeholder="请选择" |
||||
|
options={[ |
||||
|
{ |
||||
|
value: "1", |
||||
|
label: "日", |
||||
|
}, |
||||
|
{ |
||||
|
value: "2", |
||||
|
label: "周", |
||||
|
}, |
||||
|
{ |
||||
|
value: "3", |
||||
|
label: "月", |
||||
|
}, |
||||
|
{ |
||||
|
value: "4", |
||||
|
label: "年", |
||||
|
}, |
||||
|
]} |
||||
|
onChange={(e) => SetTimeNow(e)} |
||||
|
/> |
||||
|
</div> |
||||
|
</label> |
||||
|
<DatePicker |
||||
|
style={{ width: "100%" }} |
||||
|
// showTime |
||||
|
format={TimeChange().mat} |
||||
|
picker={TimeChange().str} |
||||
|
allowClear={false} |
||||
|
value={formData.start_time ? moment(formData.start_time) : null} |
||||
|
onChange={(date, dateString) => { |
||||
|
if (TimeChange().str == "week") { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: date |
||||
|
? moment(date).day(1).format("YYYY-MM-DD") |
||||
|
: null, |
||||
|
}); |
||||
|
} else if (TimeChange().str == "day") { |
||||
|
if (date > moment(formData.end_time)) { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: dateString, |
||||
|
start_time: formData.end_time, |
||||
|
}); |
||||
|
} else { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: dateString, |
||||
|
}); |
||||
|
} |
||||
|
} else { |
||||
|
setFormData({ ...formData, start_time: dateString }); |
||||
|
} |
||||
|
}} |
||||
|
disabledDate={(current) => current > moment(formData.end_time)} |
||||
|
/> |
||||
|
|
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>至</label> |
||||
|
<DatePicker |
||||
|
style={{ width: "100%" }} |
||||
|
// showTime |
||||
|
format={TimeChange().mat} |
||||
|
picker={TimeChange().str} |
||||
|
allowClear={false} |
||||
|
value={formData.end_time ? moment(formData.end_time) : null} |
||||
|
onChange={(date, dateString) => { |
||||
|
if (TimeChange().str == "week") { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: date |
||||
|
? moment(date).day(7).format("YYYY-MM-DD") |
||||
|
: null, |
||||
|
}); |
||||
|
} else if (TimeChange().str == "day") { |
||||
|
if (date < moment(formData.start_time)) { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
start_time: dateString, |
||||
|
end_time: formData.start_time, |
||||
|
}); |
||||
|
} else { |
||||
|
setFormData({ |
||||
|
...formData, |
||||
|
end_time: dateString, |
||||
|
}); |
||||
|
} |
||||
|
} else { |
||||
|
setFormData({ ...formData, end_time: dateString }); |
||||
|
} |
||||
|
}} |
||||
|
disabledDate={(current) => |
||||
|
current < moment(formData.start_time) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="form-btn"> |
||||
|
<Button |
||||
|
className="reset" |
||||
|
onClick={() => setFormData(defaultData)} |
||||
|
> |
||||
|
重置 |
||||
|
</Button> |
||||
|
<Button |
||||
|
className="submit" |
||||
|
type="primary" |
||||
|
onClick={handleSearch} |
||||
|
loading={loading} |
||||
|
> |
||||
|
查询 |
||||
|
</Button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className="paid-result usage-result"> |
||||
|
<div className="result"> |
||||
|
<div className="result-box"> |
||||
|
<div className="result-box-title">泊位利用率变化趋势</div> |
||||
|
<Tooltip |
||||
|
placement="topLeft" |
||||
|
title={<span>展示统计时间段内的泊位利用率的趋势变化情况</span>} |
||||
|
> |
||||
|
<i>?</i> |
||||
|
</Tooltip> |
||||
|
<ReactEcharts |
||||
|
option={revenueData} |
||||
|
style={{ height: "300px", width: "100%", overflow: "hidden" }} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="result-box"> |
||||
|
<Table |
||||
|
columns={columns} |
||||
|
dataSource={[ |
||||
|
{ |
||||
|
index: 1, |
||||
|
}, |
||||
|
{ |
||||
|
index: 1, |
||||
|
}, |
||||
|
{ |
||||
|
index: 1, |
||||
|
}, |
||||
|
{ |
||||
|
index: 1, |
||||
|
}, |
||||
|
{ |
||||
|
index: 1, |
||||
|
}, |
||||
|
{ |
||||
|
index: 1, |
||||
|
}, |
||||
|
{ |
||||
|
index: 1, |
||||
|
}, |
||||
|
]} |
||||
|
bordered |
||||
|
size="middle" |
||||
|
// scroll={{ |
||||
|
// x: 'calc(700px + 50%)', |
||||
|
// y: 240, |
||||
|
// }} |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</> |
||||
|
); |
||||
} |
} |
||||
|
|
||||
export default ParkTurnoverAly; |
export default ParkTurnoverAly; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue