14 changed files with 1405 additions and 210 deletions
-
BINsrc/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingFalseAlarms/blue.png
-
BINsrc/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingFalseAlarms/green.png
-
6src/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingFalseAlarms/index.jsx
-
278src/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingFalseAlarms/index.scss
-
760src/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingFalseAlarms/loadable.jsx
-
BINsrc/pages/DataAnalysisPrediction/ParkingBusinessAly/ParkingFalseAlarms/red.png
-
5src/pages/DataAnalysisPrediction/ParkingBusinessAly/index.jsx
-
304src/pages/OperationCenter/UserMgm/UserTag/index.scss
-
231src/pages/OperationCenter/UserMgm/UserTag/loadable.jsx
-
8src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/AddParking.jsx
-
6src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/ConfigParking/BusinessParameterConfig.jsx
-
1src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/loadable.jsx
-
6src/router/router.config.js
-
10src/services/OperationCenter/UserMgm/index.js
After Width: 423 | Height: 108 | Size: 5.0 KiB |
After Width: 423 | Height: 108 | Size: 5.2 KiB |
@ -0,0 +1,6 @@ |
|||||
|
import React from "react" |
||||
|
import loadable from "@loadable/component" |
||||
|
import { LoadingImg } from "@/components" |
||||
|
|
||||
|
const ExceptionParkReportLoadable = loadable(() => import("./loadable")) |
||||
|
export default (pros) => <ExceptionParkReportLoadable {...pros} fallback={<LoadingImg />} /> |
@ -0,0 +1,278 @@ |
|||||
|
@import "@/assets/css/mixin.scss"; |
||||
|
|
||||
|
$color-container-bg : var(--color-container-bg); |
||||
|
$color-user-list-bg : var(--color-user-list-bg); |
||||
|
$color-text : var(--color-text); |
||||
|
$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; |
||||
|
} |
||||
|
.period-result { |
||||
|
overflow: auto; |
||||
|
} |
||||
|
.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; |
||||
|
} |
||||
|
.bhd-select { |
||||
|
float: right; |
||||
|
margin: 12px 28px; |
||||
|
} |
||||
|
.ant-table .ant-table-thead tr th { |
||||
|
background: #3e4557; |
||||
|
} |
||||
|
} |
||||
|
.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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.edit-order-inquiry { |
||||
|
/*定义滚动条高宽及背景 |
||||
|
高宽分别对应横竖滚动条的尺寸*/ |
||||
|
::-webkit-scrollbar { |
||||
|
width: 6px; |
||||
|
height: 16px; |
||||
|
background-color: #5c5c5c; |
||||
|
} |
||||
|
|
||||
|
/*定义滚动条轨道 |
||||
|
内阴影+圆角*/ |
||||
|
::-webkit-scrollbar-track { |
||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); |
||||
|
border-radius: 10px; |
||||
|
background-color: #9da2ab; |
||||
|
} |
||||
|
|
||||
|
/*定义滑块 |
||||
|
内阴影+圆角*/ |
||||
|
::-webkit-scrollbar-thumb { |
||||
|
border-radius: 10px; |
||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3); |
||||
|
background-color: #3b97ff; |
||||
|
} |
||||
|
} |
||||
|
.no-data-box { |
||||
|
text-align: center; |
||||
|
height: 100px; |
||||
|
line-height: 100px; |
||||
|
} |
@ -0,0 +1,760 @@ |
|||||
|
import React, { useState, useEffect } from "react"; |
||||
|
import { ResultFlowResult } from "@/components"; |
||||
|
import { Select, Input, Button, Table, message, Pagination, DatePicker, Modal, Cascader, Tooltip } from "antd"; |
||||
|
import { Icon, ResultFlow } from "@/components" |
||||
|
import { useSessionStorageState } from "ahooks"; |
||||
|
import { lineChartOption, ringChartOption } from "../echarts.config"; |
||||
|
import moment from "moment"; |
||||
|
import ReactEcharts from "echarts-for-react"; |
||||
|
import "./index.scss"; |
||||
|
import ajax from "@/services"; |
||||
|
//误报情况分析 |
||||
|
function ParkingFalseAlarms() { |
||||
|
// session缓存 |
||||
|
const [defaultParams, setDefaultParams] = useSessionStorageState( |
||||
|
"formData_parkingAlyPeriod", |
||||
|
{ 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"), |
||||
|
operator_id: '0', |
||||
|
area_id: '0', |
||||
|
car_parking_type: '3', |
||||
|
date_type: '1', |
||||
|
paytype: '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 [keyVal, setKeyVal] = useState() |
||||
|
//出入场车流量分析 |
||||
|
const [revenueData, setRevenueData] = useState({}); |
||||
|
//停车饱和度趋势分析 |
||||
|
const [parkData, setParkData] = useState({}); |
||||
|
const [hourData, setHourData] = useState({}); |
||||
|
const [searchSelectList, setSearchSelectList] = useState([]); //搜索下拉数据 |
||||
|
const [sessionTabList, setSessionTabList] = useSessionStorageState('parkingAlyPeriod', { |
||||
|
value: { |
||||
|
} |
||||
|
}) |
||||
|
useEffect(() => { |
||||
|
if (sessionTabList && Object.values(sessionTabList).length > 0) { |
||||
|
setFormData({ |
||||
|
...formData, ...sessionTabList |
||||
|
}) |
||||
|
getCheck({ |
||||
|
...sessionTabList |
||||
|
}) |
||||
|
} else { |
||||
|
getCheck() |
||||
|
} |
||||
|
}, [isAjax]) |
||||
|
useEffect(() => { |
||||
|
setSessionTabList({ |
||||
|
...formData |
||||
|
}) |
||||
|
}, [formData]) |
||||
|
useEffect(() => { |
||||
|
getSelectList(); |
||||
|
}, []); |
||||
|
|
||||
|
// 访问接口,获取表格 |
||||
|
// useEffect(() => { |
||||
|
// getData(); |
||||
|
// }, [isAjax]); |
||||
|
//时间状态切换 |
||||
|
const TimeChange = () => { |
||||
|
let e = formData.date_type; |
||||
|
let str = "date"; |
||||
|
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 columns = [ |
||||
|
{ |
||||
|
title: "序号", |
||||
|
dataIndex: "index", |
||||
|
key: "iindex", |
||||
|
align: "center", |
||||
|
fixed: "right", |
||||
|
render: (text, record, index) => index + 1, |
||||
|
}, |
||||
|
{ |
||||
|
title: "标签名称", |
||||
|
dataIndex: "name", |
||||
|
key: "name", |
||||
|
align: "center", |
||||
|
fixed: "right", |
||||
|
}, |
||||
|
{ |
||||
|
title: "人数(人)", |
||||
|
dataIndex: "nums", |
||||
|
key: "nums", |
||||
|
align: "center", |
||||
|
fixed: "right", |
||||
|
}, |
||||
|
{ |
||||
|
title: "标签描述", |
||||
|
dataIndex: "describe", |
||||
|
key: "describe", |
||||
|
align: "center", |
||||
|
fixed: "right", |
||||
|
}, |
||||
|
{ |
||||
|
title: "创建人", |
||||
|
dataIndex: "edit_name", |
||||
|
key: "edit_name", |
||||
|
align: "center", |
||||
|
fixed: "right", |
||||
|
}, |
||||
|
{ |
||||
|
title: "操作日期", |
||||
|
dataIndex: "time", |
||||
|
key: "time", |
||||
|
align: "center", |
||||
|
fixed: "right", |
||||
|
}, |
||||
|
{ |
||||
|
title: "操作", |
||||
|
dataIndex: "operation", |
||||
|
key: "operation", |
||||
|
align: "center", |
||||
|
fixed: "right", |
||||
|
render: (_, record, index) => { |
||||
|
return ( |
||||
|
<div className="popover-content"> |
||||
|
<div> |
||||
|
<a |
||||
|
onClick={() => { |
||||
|
searchDetail({ id: record.id }); |
||||
|
setMyId(record.id) |
||||
|
setIndexBy(index); |
||||
|
setTag('2') |
||||
|
}} |
||||
|
> |
||||
|
查看 |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
); |
||||
|
}, |
||||
|
}, |
||||
|
]; |
||||
|
//出入场车流量分析 折线图 |
||||
|
const getRevenueOption = (data) => { |
||||
|
if (!data || data.length <= 0) { |
||||
|
setRevenueData({}) |
||||
|
return |
||||
|
} |
||||
|
const areaNames = data[0].name ? [...new Set(data.map((item) => item.name))] : ['出场车次', '入场车次']; |
||||
|
// 获取所有横坐标 |
||||
|
const dates = [...new Set(data.map((item) => item.hour))].sort( |
||||
|
(a, b) => a.hour - b.hour |
||||
|
); |
||||
|
// 构建数据对象 |
||||
|
const seriesData = areaNames.map((areaName, index) => { |
||||
|
// 获取数据 |
||||
|
const areaData = data[0].name ? data.filter((item) => item.name === areaName) : data |
||||
|
// 构建数据对象 |
||||
|
return { |
||||
|
name: areaNames.length > 1 ? areaName : '', |
||||
|
type: "line", |
||||
|
itemStyle: { |
||||
|
label: { |
||||
|
show: true, //开启显示 |
||||
|
position: 'top', //在上方显示 |
||||
|
color: 'white',//字体颜色 |
||||
|
fontSize: 10//字体大小 |
||||
|
}, |
||||
|
}, |
||||
|
data: dates.map((item) => { |
||||
|
for (const { hour, total_in_records, total_out_records } of areaData) { |
||||
|
if (hour === item) return index == 1 ? total_in_records : total_out_records; |
||||
|
} |
||||
|
return 0; |
||||
|
}), |
||||
|
}; |
||||
|
}); |
||||
|
// 构建X轴数据 |
||||
|
const xAxisData = dates.map((date) => { |
||||
|
return { |
||||
|
value: date, |
||||
|
align: "center", |
||||
|
lineStyle: { |
||||
|
color: "skyblue", // 设置线的颜色为天蓝色 |
||||
|
shadowBlur: 6, |
||||
|
}, |
||||
|
|
||||
|
}; |
||||
|
}); |
||||
|
let tooltip = { |
||||
|
formatter: (params) => { |
||||
|
var str = ""; |
||||
|
str = params[0].axisValue.match(/(\S*):/) ? params[0].axisValue.match(/(\S*):/) : params[0].axisValue |
||||
|
str = str[1] ? str[1] + ':59时' : str |
||||
|
return `<div class="tooltip-box"> |
||||
|
${params[0].axisValue}-${str}<br/> |
||||
|
出场次数:${params[0].data}(次)<br/> |
||||
|
入场次数:${params[1].data}(次) |
||||
|
</div>` |
||||
|
} |
||||
|
} |
||||
|
setRevenueData({ ...lineChartOption(areaNames, xAxisData, "车次数(个)", seriesData), ...tooltip }); |
||||
|
}; |
||||
|
//停车饱和趋势分析分析 折线图 |
||||
|
const getParkOption = (data) => { |
||||
|
if (!data || data.length <= 0) { |
||||
|
setParkData({}) |
||||
|
return |
||||
|
} |
||||
|
let areaNames = data[0].charge_type_name ? [...new Set(data.map((item) => item.charge_type_name))] : ['']; |
||||
|
// areaNames = [...new Set(areaNames.map((item) => item.hour))].sort( |
||||
|
// (a, b) => a.date - b.hour |
||||
|
// ); |
||||
|
// 获取所有横坐标 |
||||
|
let dates = [...new Set(data.map((item) => item.hour))].sort( |
||||
|
(a, b) => a.hour - b.hour |
||||
|
); |
||||
|
// 构建数据对象 |
||||
|
let seriesData = areaNames.map((areaName, index) => { |
||||
|
// 获取数据 |
||||
|
let areaData = data[0].charge_type_name ? data.filter((item) => item.charge_type_name === areaName) : data |
||||
|
// 构建数据对象 |
||||
|
return { |
||||
|
name: areaName, |
||||
|
type: "line", |
||||
|
itemStyle: { |
||||
|
label: { |
||||
|
show: true, //开启显示 |
||||
|
position: 'top', //在上方显示 |
||||
|
color: 'white',//字体颜色 |
||||
|
fontSize: 10//字体大小 |
||||
|
}, |
||||
|
}, |
||||
|
data: dates.map((item) => { |
||||
|
for (var { hour, occupancy_rate } of areaData) { |
||||
|
if (hour === item) return parseFloat(occupancy_rate); |
||||
|
} |
||||
|
return 0; |
||||
|
}), |
||||
|
}; |
||||
|
}); |
||||
|
// 构建X轴数据 |
||||
|
let xAxisData = dates.map((date) => { |
||||
|
return { |
||||
|
value: date, |
||||
|
align: "center", |
||||
|
lineStyle: { |
||||
|
color: "skyblue", // 设置线的颜色为天蓝色 |
||||
|
shadowBlur: 6, |
||||
|
}, |
||||
|
|
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
setParkData(lineChartOption(areaNames, xAxisData, "饱和度", seriesData, areaNames)); |
||||
|
}; |
||||
|
const randerColor = () => { |
||||
|
let arr = []; |
||||
|
this.alarmTypeLine.forEach(item => { |
||||
|
random(arr) |
||||
|
}) |
||||
|
return arr; |
||||
|
} |
||||
|
|
||||
|
const random = (arr) => { |
||||
|
let color = 'rgb(' + [ |
||||
|
Math.round(Math.random() * 255), |
||||
|
Math.round(Math.random() * 255), |
||||
|
Math.round(Math.random() * 255) |
||||
|
].join(',') + ')'; |
||||
|
if (!arr.some(i => i == color)) { |
||||
|
arr.push(color) |
||||
|
} else { |
||||
|
this.random(arr) |
||||
|
} |
||||
|
} |
||||
|
const color = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#fc8452', '#3ba272', '#9a60b4', '#ee7ccc'] |
||||
|
//停车饱和趋势分析分析 折线图 hour 时间对比 |
||||
|
const getParkOptionHour = (data) => { |
||||
|
console.log(data) |
||||
|
if (!data || data.length <= 0) { |
||||
|
setHourData({}) |
||||
|
return |
||||
|
} |
||||
|
let areaNames = data[0].date ? [...new Set(data.map((item) => item.date))].sort() : ['']; |
||||
|
// 获取所有横坐标 |
||||
|
let dates = [...new Set(data.map((item) => item.hour))].sort( |
||||
|
(a, b) => a.hour - b.hour |
||||
|
); |
||||
|
// 构建数据对象 |
||||
|
let seriesData = areaNames.map((areaName, index) => { |
||||
|
let color2 = color[Math.round(Math.random() * 10)] |
||||
|
// 获取数据 |
||||
|
let areaData = data[0].date ? data.filter((item) => item.date === areaName) : data |
||||
|
// 构建数据对象 |
||||
|
return { |
||||
|
name: areaName, |
||||
|
type: "line", |
||||
|
itemStyle: { |
||||
|
label: { |
||||
|
show: true, //开启显示 |
||||
|
position: 'top', //在上方显示 |
||||
|
color: 'white',//字体颜色 |
||||
|
fontSize: 10//字体大小 |
||||
|
}, |
||||
|
normal: { |
||||
|
color: color2, //改变折线点的颜色 |
||||
|
lineStyle: { |
||||
|
color: color2, |
||||
|
} |
||||
|
//改变折线颜色 |
||||
|
} |
||||
|
}, |
||||
|
data: dates.map((item) => { |
||||
|
for (var { hour, occupancy_rate } of areaData) { |
||||
|
if (hour === item) return parseFloat(occupancy_rate); |
||||
|
} |
||||
|
return 0; |
||||
|
}), |
||||
|
}; |
||||
|
}); |
||||
|
// 构建X轴数据 |
||||
|
let xAxisData = dates.map((date) => { |
||||
|
return { |
||||
|
value: date, |
||||
|
align: "center", |
||||
|
lineStyle: { |
||||
|
color: "skyblue", // 设置线的颜色为天蓝色 |
||||
|
shadowBlur: 6, |
||||
|
}, |
||||
|
|
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
setHourData({ ...lineChartOption(areaNames, xAxisData, "饱和度", seriesData) }); |
||||
|
}; |
||||
|
function getParkingIncome(data) { |
||||
|
ajax |
||||
|
.getParkingAlyPeriodLine(data) |
||||
|
.then((res) => { |
||||
|
if (res.status === 20000) { |
||||
|
getRevenueOption(res.data.list); |
||||
|
setResultData(res.data) |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => console.error(err)); |
||||
|
} |
||||
|
function getParkingData(data) { |
||||
|
setLoading(true) |
||||
|
setHourData({}) |
||||
|
ajax |
||||
|
.getParkingAlyPeriodParkLine(data) |
||||
|
.then((res) => { |
||||
|
if (res.status === 20000) { |
||||
|
getParkOption(res.data.list?.area_list); |
||||
|
setKeyVal(res.data.list?.hour_list.length) |
||||
|
//setHourData({}) |
||||
|
getParkOptionHour(res.data.list?.hour_list); |
||||
|
setLoading(false) |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => console.error(err)); |
||||
|
} |
||||
|
// 获取下拉数据 |
||||
|
const getSelectList = () => { |
||||
|
ajax.getOperator().then((e) => { |
||||
|
setSearchSelectList([ |
||||
|
...searchSelectList, |
||||
|
...e.data |
||||
|
]) |
||||
|
}) |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// 携带参数处理 |
||||
|
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 |
||||
|
} |
||||
|
setLoading(false); |
||||
|
setTabLoading(false); |
||||
|
let params = { ...postData, ...v, ...pageInfo } |
||||
|
//请求接口 |
||||
|
getParkingIncome(params) |
||||
|
getParkingData(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("暂无数据"); |
||||
|
} |
||||
|
}; |
||||
|
// 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> |
||||
|
<Select |
||||
|
className="form-con" |
||||
|
placeholder="请选择" |
||||
|
//options={searchSelectList || []} |
||||
|
value={formData.device_code} |
||||
|
onChange={(v) => |
||||
|
setFormData({ ...formData, device_code: v }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>设备名称</label> |
||||
|
<Input |
||||
|
className="form-con" |
||||
|
placeholder="请输入" |
||||
|
value={formData?.device_name} |
||||
|
onChange={(e) => |
||||
|
setFormData({ ...formData, device_name: e.target.value }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>设备编号</label> |
||||
|
<Input |
||||
|
className="form-con" |
||||
|
placeholder="请输入" |
||||
|
value={formData?.device_code} |
||||
|
onChange={(e) => |
||||
|
setFormData({ ...formData, device_code: e.target.value }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>所属路段</label> |
||||
|
<Input |
||||
|
className="form-con" |
||||
|
placeholder="请输入" |
||||
|
value={formData?.road_name} |
||||
|
onChange={(e) => |
||||
|
setFormData({ ...formData, road_name: e.target.value }) |
||||
|
} |
||||
|
/> |
||||
|
</div> |
||||
|
<div className="yisa-search"> |
||||
|
<label>商户名称</label> |
||||
|
<Select |
||||
|
className="form-con" |
||||
|
placeholder="请选择" |
||||
|
//options={searchSelectList || []} |
||||
|
value={formData.operator_id} |
||||
|
onChange={(v) => |
||||
|
setFormData({ ...formData, operator_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: "月", |
||||
|
}, |
||||
|
]} |
||||
|
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 if (TimeChange().str == "month") { |
||||
|
setFormData({ ...formData, start_time: moment(date).format("YYYY-MM-DD"), end_time: moment(date).endOf("month").format("YYYY-MM-DD") }); |
||||
|
} 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 if (TimeChange().str == "month") { |
||||
|
setFormData({ ...formData, start_time: moment(date).startOf('month').format("YYYY-MM-DD"), end_time: moment(date).format("YYYY-MM-DD") }); |
||||
|
} 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 period-result"> |
||||
|
<div className="result"> |
||||
|
<div className="result-box"> |
||||
|
<div className="result-box-title">误报情况结果详情</div> |
||||
|
<ResultFlow |
||||
|
hasLoad={true} |
||||
|
loading={loading} |
||||
|
resultData={resultData} |
||||
|
message={"暂无数据"} |
||||
|
> |
||||
|
<div className="table-wrap"> |
||||
|
<Table |
||||
|
columns={columns} |
||||
|
dataSource={resultData.list} |
||||
|
pagination={false} |
||||
|
scroll={{ y: 400 }} |
||||
|
/> |
||||
|
</div> |
||||
|
{/* <div> |
||||
|
<Pagination |
||||
|
className="pagination-common" |
||||
|
showSizeChanger={true} |
||||
|
showQuickJumper={true} |
||||
|
//showTotal={() => `共 ${total} 条`} |
||||
|
total={detailTotal} |
||||
|
current={pageData.pn} |
||||
|
pageSize={pageData.length} |
||||
|
pageSizeOptions={dictionary?.pageSizeOptions} |
||||
|
onChange={onShowSizeChange} |
||||
|
onShowSizeChange={onShowSizeChange} |
||||
|
/> |
||||
|
</div> */} |
||||
|
</ResultFlow> |
||||
|
</div> |
||||
|
<div className="result-box"> |
||||
|
<div className="result-box-title">误报情况分析</div> |
||||
|
<div className="result-hd"> |
||||
|
<div className="result-header rea"> |
||||
|
<div className="result-icon"><Icon type="shijian" /></div> |
||||
|
<div className="result-content"> |
||||
|
<div className="title">停车高峰时段</div> |
||||
|
<div className="time">{resultData.peak_hours || "--"}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className="result-header reb"> |
||||
|
<div className="result-icon"><Icon type="shijian" /></div> |
||||
|
<div className="result-content"> |
||||
|
<div className="title">入场压力时段</div> |
||||
|
<div className="time">{resultData.entry_pressure_hours || "--"}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className="result-header rec"> |
||||
|
<div className="result-icon"><Icon type="shijian" /></div> |
||||
|
<div className="result-content"> |
||||
|
<div className="title">出场压力时段</div> |
||||
|
<div className="time">{resultData.exit_pressure_hours || "--"}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
{hourData.series ? |
||||
|
<ReactEcharts |
||||
|
key={keyVal} |
||||
|
option={hourData} |
||||
|
style={{ height: "300px", width: "72%", overflow: "hidden", background: '#545d74' ,marginLeft:'350px'}} |
||||
|
/> : |
||||
|
<div className="no-data-box">{loading ? "加载中" : "暂无数据"}</div> |
||||
|
} |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</> |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
export default ParkingFalseAlarms; |
After Width: 423 | Height: 108 | Size: 5.1 KiB |
Write
Preview
Loading…
Cancel
Save
Reference in new issue