4 changed files with 2488 additions and 95 deletions
-
490src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/index.scss
-
701src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/loadable.jsx
-
600src/pages/DataAnalysisPrediction/MemberStat/RegisterAly/index.scss
-
792src/pages/DataAnalysisPrediction/MemberStat/RegisterAly/loadable.jsx
@ -1,15 +1,694 @@ |
|||
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 { |
|||
message, |
|||
Pagination, |
|||
Table, |
|||
Select, |
|||
Input, |
|||
Popover, |
|||
Cascader, |
|||
AutoComplete, |
|||
Tooltip, |
|||
Checkbox, |
|||
Form, |
|||
DatePicker, |
|||
} from "antd"; |
|||
import { dictionary, utils } from "@/config/common"; |
|||
import moment from "moment"; |
|||
import ReactEcharts from "echarts-for-react"; |
|||
import ajax from "@/services"; |
|||
// 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"; |
|||
function ParkingAly() {//停车分析 |
|||
return <div>ParkingAly</div> |
|||
import { ResultFlow } from "@/components"; |
|||
import "./index.scss"; |
|||
|
|||
function ParkingAly() { |
|||
//停车分析 |
|||
//页面检索-重复 |
|||
const formdata = { |
|||
operator_id: "0", //商户 |
|||
park_type: "", //车场类型 1=路内 2=路外 |
|||
date_type: "1", |
|||
is_excel: 0, |
|||
start_time: moment().startOf("day").format("YYYY-MM-DD"), |
|||
end_time: moment().endOf("day").format("YYYY-MM-DD"), |
|||
pn: 1, |
|||
page_size: dictionary?.pageSizeOptions1[0], |
|||
}; |
|||
const col = [ |
|||
{ |
|||
title: "日期", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
{ |
|||
title: "会员停车次数(次)", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
{ |
|||
title: "非会员停车次数(次)", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
{ |
|||
title: "会员停车占比", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
]; |
|||
let form_data = sessionStorage.getItem("FormData_ParkingAly"); |
|||
//检索 |
|||
const [FormData, setFormData] = useState( |
|||
form_data ? JSON.parse(form_data) : formdata |
|||
); |
|||
//检索2 |
|||
const [FormDatas, setFormDatas] = useState( |
|||
form_data ? JSON.parse(form_data) : formdata |
|||
); |
|||
//页码状态 |
|||
const [loading, setLoading] = useState(false); |
|||
//页面数据 |
|||
const [Data, setData] = useState({ |
|||
data: [], |
|||
total: 0, |
|||
}); |
|||
const [revenueData, setRevenueData] = useState({}); |
|||
|
|||
//获取区域 |
|||
const [Area, setArea] = useState([]); |
|||
//商户 |
|||
const [Yunying, setYunying] = useState([]); |
|||
//自动填充 |
|||
const [options, setOptions] = useState([]); |
|||
|
|||
const [Open, setOpen] = useState(true); |
|||
//筛选 |
|||
const [selectArr, setSelectArr] = useState([]); |
|||
//是否展开显示 |
|||
const [Show, setShow] = useState(false); |
|||
const column = (arr) => { |
|||
let copr = []; |
|||
if (arr.length) { |
|||
col.forEach((ele, index) => { |
|||
if (ele.children) { |
|||
var lisr = []; |
|||
let bool = false; |
|||
ele.children.forEach((val) => { |
|||
if (!arr.includes(val.key)) { |
|||
lisr.push(val); |
|||
bool = true; |
|||
} |
|||
}); |
|||
if (bool) { |
|||
copr.push({ ...ele, children: [...lisr] }); |
|||
} |
|||
} else { |
|||
if (!arr.includes(ele.key)) { |
|||
copr.push(ele); |
|||
} |
|||
} |
|||
}); |
|||
} else { |
|||
copr = col; |
|||
} |
|||
return [...copr]; |
|||
}; |
|||
const onSearch = (searchText) => { |
|||
console.log(searchText); |
|||
setOptions([]); |
|||
}; |
|||
|
|||
//时间状态切换 |
|||
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, |
|||
}); |
|||
}; |
|||
|
|||
//页码 |
|||
function onShowSizeChange(pn, page_size) { |
|||
let temFormData = {}; |
|||
if (FormData.page_size == page_size) { |
|||
temFormData = { |
|||
...FormData, |
|||
pn, |
|||
}; |
|||
} else { |
|||
temFormData = { |
|||
...FormData, |
|||
pn: 1, |
|||
page_size, |
|||
}; |
|||
} |
|||
setFormData(temFormData); |
|||
setFormDatas(temFormData); |
|||
} |
|||
|
|||
//获取页面筛选数据 |
|||
const getSelectData = () => { |
|||
ajax.getAllOperator().then( |
|||
(res) => { |
|||
if (parseInt(res?.status) === 20000) { |
|||
setYunying(res.data); |
|||
} else { |
|||
message.error(res?.message); |
|||
} |
|||
setLoading(true); |
|||
}, |
|||
(err) => { |
|||
console.log(err); |
|||
setLoading(true); |
|||
} |
|||
); |
|||
}; |
|||
//下载 |
|||
const Daownload = (url) => { |
|||
var link = document.createElement("a"); |
|||
link.setAttribute("target", "_blank"); |
|||
link.style.display = "none"; |
|||
link.href = url ? url : ""; |
|||
document.body.appendChild(link); |
|||
link.click(); |
|||
document.body.removeChild(link); |
|||
}; |
|||
//导出 |
|||
const ReportPaySummaryReport = () => { |
|||
ajax.ElectInvoice.getOperationReport({ |
|||
...FormDatas, |
|||
is_excel: 1, |
|||
}).then( |
|||
(res) => { |
|||
if (parseInt(res?.status) === 20000) { |
|||
Daownload(res?.data?.url); |
|||
} else { |
|||
message.error(res?.message); |
|||
} |
|||
}, |
|||
(err) => { |
|||
console.log(err); |
|||
} |
|||
); |
|||
}; |
|||
const filterad = (dates, data, name) => { |
|||
const areaData = data.filter((item) => item.type === name); |
|||
const arr = dates.map((item) => { |
|||
for (const { pay_date, income } of areaData) { |
|||
console.log(pay_date, income); |
|||
if (pay_date === item) return income; |
|||
} |
|||
return 0; |
|||
}); |
|||
return arr; |
|||
}; |
|||
const getRevenueOption = ( |
|||
data = [ |
|||
{ |
|||
income: 4, |
|||
// area: "1", |
|||
pay_date: "2023-08-21", |
|||
type: "非会员停车次数", |
|||
}, |
|||
{ |
|||
income: 14, |
|||
// area: "1", |
|||
pay_date: "2023-08-21", |
|||
type: "会员停车次数", |
|||
}, |
|||
{ |
|||
income: 12, |
|||
// area: "2", |
|||
pay_date: "2023-08-19", |
|||
type: "会员停车次数", |
|||
}, |
|||
{ |
|||
income: 40, |
|||
// area: "1", |
|||
pay_date: "2023-08-25", |
|||
type: "非会员停车次数", |
|||
}, |
|||
] |
|||
) => { |
|||
// 获取所有地区名称 |
|||
data.sort((a, b) => { |
|||
return new Date(a.pay_date) - new Date(b.pay_date); |
|||
}); |
|||
const areaNames = [...new Set(data.map((item) => item.type))]; |
|||
// 获取所有日期 |
|||
const dates = [...new Set(data.map((item) => item.pay_date))].sort( |
|||
(a, b) => a.pay_date - b.pay_date |
|||
); |
|||
// 构建X轴数据 |
|||
const xAxisData = dates.map((date) => { |
|||
return { |
|||
value: date, |
|||
textStyle: { |
|||
align: "center", |
|||
lineStyle: { |
|||
color: "#3AA9FF", // 设置线的颜色为天蓝色 |
|||
shadowBlur: 6, |
|||
}, |
|||
}, |
|||
}; |
|||
}); |
|||
|
|||
setRevenueData({ |
|||
title: { |
|||
text: "", |
|||
textStyle: { |
|||
color: "#fff", |
|||
}, |
|||
}, |
|||
tooltip: { |
|||
trigger: "axis", |
|||
formatter: (params) => { |
|||
return `<div class="ttopi"> |
|||
<p>${params[0].axisValue}</p> |
|||
<p> |
|||
${params[0].marker} ${params[0].seriesName} ${ |
|||
params[0].data |
|||
}(次) |
|||
</p> |
|||
<p> |
|||
${params[1].marker} ${params[1].seriesName} ${ |
|||
params[1].data |
|||
}(次) |
|||
</p> |
|||
<p>停车记录总数 ${params[0].data + params[1].data}(次)</p> |
|||
</div>`; |
|||
}, |
|||
}, |
|||
legend: { |
|||
type: "scroll", |
|||
top: 0, |
|||
left: "center", |
|||
data: areaNames, |
|||
itemWidth: 18, |
|||
itemHeight: 12, |
|||
width: "40%", |
|||
textStyle: { |
|||
fontSize: 14, |
|||
color: "white", |
|||
}, |
|||
}, |
|||
xAxis: { |
|||
data: xAxisData, |
|||
type: "category", |
|||
boundaryGap: false, // 不留白,从原点开始 |
|||
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", |
|||
}, |
|||
}, |
|||
splitLine: { |
|||
show: true, // 是否显示分隔线。默认数值轴显示,类目轴不显示 |
|||
interval: "0", // 坐标轴刻度标签的显示间隔,在类目轴中有效.0显示所有 |
|||
lineStyle: { |
|||
color: ["#cccccc42"], // 分隔线颜色,可以设置成单个颜色,也可以设置成颜色数组,分隔线会按数组中颜色的顺序依次循环设置颜色 |
|||
width: 1.3, // 分隔线线宽 |
|||
type: "dashed", // 坐标轴线线的类型('solid',实线类型;'dashed',虚线类型;'dotted',点状类型) |
|||
}, |
|||
}, |
|||
}, |
|||
color: ["#3AA9FF", "#F997DF"], |
|||
//series: seriesData, |
|||
series: [ |
|||
{ |
|||
name: "非会员停车次数", |
|||
type: "line", |
|||
data: filterad(dates, data, "非会员停车次数"), |
|||
}, |
|||
{ |
|||
name: "会员停车次数", |
|||
type: "line", |
|||
data: filterad(dates, data, "会员停车次数"), |
|||
}, |
|||
], |
|||
grid: { |
|||
x: 50, |
|||
y: 55, |
|||
x2: 70, |
|||
y2: 20, |
|||
}, |
|||
}); |
|||
}; |
|||
//获取页面显示数据 |
|||
const getData = (data) => { |
|||
setLoading(false); |
|||
ajax.ElectInvoice.getOperationReport({ |
|||
...data, |
|||
area: data?.area?.length ? data?.area[data.area.length - 1] : "", |
|||
}).then( |
|||
(res) => { |
|||
if (parseInt(res?.status) === 20000) { |
|||
setData({ |
|||
data: res?.data?.list || [], |
|||
total: res?.total || 0, |
|||
}); |
|||
setLoading(true); |
|||
} else { |
|||
message.error(res?.message); |
|||
} |
|||
setLoading(true); |
|||
}, |
|||
(err) => { |
|||
console.log(err); |
|||
setLoading(true); |
|||
} |
|||
); |
|||
}; |
|||
useEffect(() => { |
|||
sessionStorage.setItem("FormData_ParkingAly", JSON.stringify(FormDatas)); |
|||
// getData(FormDatas); |
|||
//调用接口 |
|||
}, [FormDatas]); |
|||
useEffect(() => { |
|||
getSelectData(); |
|||
getRevenueOption(); |
|||
}, []); |
|||
return ( |
|||
<div className="ParkingAly"> |
|||
<div className="body_cenf"> |
|||
<div className="left_search"> |
|||
<div className="hrestit">查询条件</div> |
|||
|
|||
<div className="form_item"> |
|||
<span className="lab">运营商</span> |
|||
<div className="inputs"> |
|||
<Select |
|||
value={FormData.operator_id} |
|||
style={{ |
|||
width: "100%", |
|||
}} |
|||
placeholder="请选择" |
|||
options={Yunying} |
|||
onChange={(e) => |
|||
setFormData({ |
|||
...FormData, |
|||
operator_id: e, |
|||
}) |
|||
} |
|||
/> |
|||
</div> |
|||
</div> |
|||
|
|||
<div className="form_item"> |
|||
<span className="lab">车场类型</span> |
|||
<div className="inputs"> |
|||
<Select |
|||
value={FormData.park_type} |
|||
style={{ |
|||
width: "100%", |
|||
}} |
|||
placeholder="请选择" |
|||
options={[ |
|||
{ |
|||
value: "", |
|||
label: "全部", |
|||
}, |
|||
{ |
|||
value: "1", |
|||
label: "路内车场", |
|||
}, |
|||
{ |
|||
value: "2", |
|||
label: "路外车场", |
|||
}, |
|||
]} |
|||
onChange={(e) => |
|||
setFormData({ |
|||
...FormData, |
|||
park_type: e, |
|||
}) |
|||
} |
|||
/> |
|||
</div> |
|||
</div> |
|||
<div className="form_item"> |
|||
<div className="labb"> |
|||
日期 |
|||
<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> |
|||
</div> |
|||
<div className="inputs"> |
|||
<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> |
|||
<div className="form_item"> |
|||
<span className="lab">至</span> |
|||
<div className="inputs"> |
|||
<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> |
|||
<div className="but_on"> |
|||
<span |
|||
className="sear_res" |
|||
onClick={() => { |
|||
var reset = formdata; |
|||
setFormData(reset); |
|||
setFormDatas(reset); |
|||
}} |
|||
> |
|||
重置 |
|||
</span> |
|||
<span |
|||
className={"sear_ser lent"} |
|||
onClick={() => { |
|||
var fortm = FormData; |
|||
setFormData({ |
|||
...fortm, |
|||
pn: 1, |
|||
}); |
|||
setFormDatas({ |
|||
...fortm, |
|||
pn: 1, |
|||
}); |
|||
}} |
|||
> |
|||
查询 |
|||
</span> |
|||
</div> |
|||
</div> |
|||
<div className="right_tab"> |
|||
<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="sd"> |
|||
<p> |
|||
共查询到<span> {Data?.total || 0}</span>条数据 |
|||
</p> |
|||
<span |
|||
className={"sear_ser"} |
|||
onClick={() => { |
|||
ReportPaySummaryReport(); |
|||
// setFormDatas({ ...FormData }); |
|||
}} |
|||
> |
|||
导出 |
|||
</span> |
|||
</div> |
|||
<ResultFlow |
|||
hasLoad={true} |
|||
loading={loading} |
|||
resultData={Data.data} |
|||
message={"暂无数据"} |
|||
> |
|||
<div className="scrplltab"> |
|||
<div className="table_raps"> |
|||
<Table |
|||
className="yisa_tabled" |
|||
columns={column(selectArr)} |
|||
rowKey={(record) => record.id} |
|||
dataSource={Data.data} |
|||
pagination={false} |
|||
scroll={{ |
|||
// x: 1300, |
|||
y: "calc(100vh - 720px)", |
|||
}} |
|||
/> |
|||
</div> |
|||
</div> |
|||
|
|||
<div> |
|||
<Pagination |
|||
className="pagination-common" |
|||
showSizeChanger={true} |
|||
showQuickJumper={true} |
|||
// showTotal={() => `共 ${total_records} 条`} |
|||
total={Data.total} |
|||
current={FormData.pn} |
|||
pageSize={FormData.page_size} |
|||
pageSizeOptions={dictionary?.pageSizeOptions} |
|||
onChange={onShowSizeChange} |
|||
onShowSizeChange={onShowSizeChange} |
|||
/> |
|||
</div> |
|||
</ResultFlow> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
); |
|||
} |
|||
|
|||
export default ParkingAly; |
|||
export default ParkingAly; |
@ -1,15 +1,787 @@ |
|||
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 { |
|||
message, |
|||
Pagination, |
|||
Table, |
|||
Select, |
|||
Input, |
|||
Popover, |
|||
Cascader, |
|||
AutoComplete, |
|||
Tooltip, |
|||
Checkbox, |
|||
Form, |
|||
DatePicker, |
|||
} from "antd"; |
|||
import { dictionary, utils } from "@/config/common"; |
|||
import moment from "moment"; |
|||
import ReactEcharts from "echarts-for-react"; |
|||
import ajax from "@/services"; |
|||
// 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 { ResultFlow } from "@/components"; |
|||
import "./index.scss"; |
|||
function RegisterAly() { |
|||
return <div>RegisterAly</div> |
|||
const formdata = { |
|||
date_type: "1", |
|||
is_excel: 0, |
|||
start_time: moment().startOf("day").format("YYYY-MM-DD"), |
|||
end_time: moment().endOf("day").format("YYYY-MM-DD"), |
|||
pn: 1, |
|||
page_size: dictionary?.pageSizeOptions1[0], |
|||
}; |
|||
const col = [ |
|||
{ |
|||
title: "日期", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
{ |
|||
title: "会员注册(个)", |
|||
children: [ |
|||
{ |
|||
title: "APP", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
{ |
|||
title: "公众号", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
{ |
|||
title: "其他", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
title: "车牌绑定(个)", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
{ |
|||
title: "累计会员注册(个)", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
{ |
|||
title: "累计车牌绑定(个)", |
|||
dataIndex: "date", |
|||
key: "date", |
|||
align: "center", |
|||
}, |
|||
]; |
|||
let form_data = sessionStorage.getItem("FormData_ParkingAly"); |
|||
//检索 |
|||
const [FormData, setFormData] = useState( |
|||
form_data ? JSON.parse(form_data) : formdata |
|||
); |
|||
//检索2 |
|||
const [FormDatas, setFormDatas] = useState( |
|||
form_data ? JSON.parse(form_data) : formdata |
|||
); |
|||
//页码状态 |
|||
const [loading, setLoading] = useState(false); |
|||
//页面数据 |
|||
const [Data, setData] = useState({ |
|||
data: [], |
|||
total: 0, |
|||
}); |
|||
|
|||
const [ringData, setRingData] = useState({}); |
|||
const [revenueData, setRevenueData] = useState({}); |
|||
|
|||
//获取区域 |
|||
const [Area, setArea] = useState([]); |
|||
//商户 |
|||
const [Yunying, setYunying] = useState([]); |
|||
//自动填充 |
|||
const [options, setOptions] = useState([]); |
|||
|
|||
//筛选 |
|||
const [selectArr, setSelectArr] = useState([]); |
|||
//是否展开显示 |
|||
const column = (arr) => { |
|||
let copr = []; |
|||
if (arr.length) { |
|||
col.forEach((ele, index) => { |
|||
if (ele.children) { |
|||
var lisr = []; |
|||
let bool = false; |
|||
ele.children.forEach((val) => { |
|||
if (!arr.includes(val.key)) { |
|||
lisr.push(val); |
|||
bool = true; |
|||
} |
|||
}); |
|||
if (bool) { |
|||
copr.push({ ...ele, children: [...lisr] }); |
|||
} |
|||
} else { |
|||
if (!arr.includes(ele.key)) { |
|||
copr.push(ele); |
|||
} |
|||
} |
|||
}); |
|||
} else { |
|||
copr = col; |
|||
} |
|||
return [...copr]; |
|||
}; |
|||
|
|||
//时间状态切换 |
|||
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, |
|||
}); |
|||
}; |
|||
|
|||
//页码 |
|||
function onShowSizeChange(pn, page_size) { |
|||
let temFormData = {}; |
|||
if (FormData.page_size == page_size) { |
|||
temFormData = { |
|||
...FormData, |
|||
pn, |
|||
}; |
|||
} else { |
|||
temFormData = { |
|||
...FormData, |
|||
pn: 1, |
|||
page_size, |
|||
}; |
|||
} |
|||
setFormData(temFormData); |
|||
setFormDatas(temFormData); |
|||
} |
|||
|
|||
//获取页面筛选数据 |
|||
const getSelectData = () => { |
|||
ajax.getAllOperator().then( |
|||
(res) => { |
|||
if (parseInt(res?.status) === 20000) { |
|||
setYunying(res.data); |
|||
} else { |
|||
message.error(res?.message); |
|||
} |
|||
setLoading(true); |
|||
}, |
|||
(err) => { |
|||
console.log(err); |
|||
setLoading(true); |
|||
} |
|||
); |
|||
}; |
|||
//下载 |
|||
const Daownload = (url) => { |
|||
var link = document.createElement("a"); |
|||
link.setAttribute("target", "_blank"); |
|||
link.style.display = "none"; |
|||
link.href = url ? url : ""; |
|||
document.body.appendChild(link); |
|||
link.click(); |
|||
document.body.removeChild(link); |
|||
}; |
|||
//导出 |
|||
const ReportPaySummaryReport = () => { |
|||
ajax.ElectInvoice.getOperationReport({ |
|||
...FormDatas, |
|||
is_excel: 1, |
|||
}).then( |
|||
(res) => { |
|||
if (parseInt(res?.status) === 20000) { |
|||
Daownload(res?.data?.url); |
|||
} else { |
|||
message.error(res?.message); |
|||
} |
|||
}, |
|||
(err) => { |
|||
console.log(err); |
|||
} |
|||
); |
|||
}; |
|||
const filterad = (dates, data, name) => { |
|||
const areaData = data.filter((item) => item.type === name); |
|||
const arr = dates.map((item) => { |
|||
for (const { pay_date, income } of areaData) { |
|||
console.log(pay_date, income); |
|||
if (pay_date === item) return income; |
|||
} |
|||
return 0; |
|||
}); |
|||
return arr; |
|||
}; |
|||
const getRingOption = ( |
|||
data = [ |
|||
{ |
|||
income: 4, |
|||
// area: "1", |
|||
pay_date: "2023-08-21", |
|||
type: "非会员停车次数", |
|||
}, |
|||
{ |
|||
income: 14, |
|||
// area: "1", |
|||
pay_date: "2023-08-21", |
|||
type: "会员停车次数", |
|||
}, |
|||
{ |
|||
income: 12, |
|||
// area: "2", |
|||
pay_date: "2023-08-19", |
|||
type: "会员停车次数", |
|||
}, |
|||
{ |
|||
income: 40, |
|||
// area: "1", |
|||
pay_date: "2023-08-25", |
|||
type: "非会员停车次数", |
|||
}, |
|||
] |
|||
) => { |
|||
// 获取所有地区名称 |
|||
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.type))]; |
|||
|
|||
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, |
|||
}, |
|||
}); |
|||
}; |
|||
|
|||
//新增用户趋势图 |
|||
const getRevenueOption = ( |
|||
data = [ |
|||
{ |
|||
income: 4, |
|||
// area: "1", |
|||
pay_date: "2023-08-21", |
|||
type: "会员注册", |
|||
}, |
|||
{ |
|||
income: 14, |
|||
// area: "1", |
|||
pay_date: "2023-08-21", |
|||
type: "车牌绑定", |
|||
}, |
|||
{ |
|||
income: 12, |
|||
// area: "2", |
|||
pay_date: "2023-08-19", |
|||
type: "会员注册", |
|||
}, |
|||
{ |
|||
income: 40, |
|||
// area: "1", |
|||
pay_date: "2023-08-25", |
|||
type: "车牌绑定", |
|||
}, |
|||
] |
|||
) => { |
|||
// 获取所有地区名称 |
|||
data.sort((a, b) => { |
|||
return new Date(a.pay_date) - new Date(b.pay_date); |
|||
}); |
|||
const areaNames = [...new Set(data.map((item) => item.type))]; |
|||
// 获取所有日期 |
|||
const dates = [...new Set(data.map((item) => item.pay_date))].sort( |
|||
(a, b) => a.pay_date - b.pay_date |
|||
); |
|||
// 构建X轴数据 |
|||
const xAxisData = dates.map((date) => { |
|||
return { |
|||
value: date, |
|||
textStyle: { |
|||
align: "center", |
|||
lineStyle: { |
|||
color: "#3AA9FF", // 设置线的颜色为天蓝色 |
|||
shadowBlur: 6, |
|||
}, |
|||
}, |
|||
}; |
|||
}); |
|||
|
|||
setRevenueData({ |
|||
title: { |
|||
text: "", |
|||
textStyle: { |
|||
color: "#fff", |
|||
}, |
|||
}, |
|||
tooltip: { |
|||
trigger: "axis", |
|||
formatter: (params) => { |
|||
return `<div class="ttopi"> |
|||
<p>${params[0].axisValue}</p> |
|||
<p> |
|||
${params[0].marker} 净增${params[0].seriesName} ${params[0].data}(个) |
|||
</p> |
|||
<p> |
|||
${params[1].marker} 净增${params[1].seriesName} ${params[1].data}(个) |
|||
</p> |
|||
</div>`; |
|||
}, |
|||
}, |
|||
legend: { |
|||
type: "scroll", |
|||
top: 0, |
|||
left: "center", |
|||
data: areaNames, |
|||
itemWidth: 18, |
|||
itemHeight: 12, |
|||
width: "40%", |
|||
textStyle: { |
|||
fontSize: 14, |
|||
color: "white", |
|||
}, |
|||
}, |
|||
xAxis: { |
|||
data: xAxisData, |
|||
type: "category", |
|||
boundaryGap: false, // 不留白,从原点开始 |
|||
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", |
|||
}, |
|||
}, |
|||
splitLine: { |
|||
show: true, // 是否显示分隔线。默认数值轴显示,类目轴不显示 |
|||
interval: "0", // 坐标轴刻度标签的显示间隔,在类目轴中有效.0显示所有 |
|||
lineStyle: { |
|||
color: ["#cccccc42"], // 分隔线颜色,可以设置成单个颜色,也可以设置成颜色数组,分隔线会按数组中颜色的顺序依次循环设置颜色 |
|||
width: 1.3, // 分隔线线宽 |
|||
type: "dashed", // 坐标轴线线的类型('solid',实线类型;'dashed',虚线类型;'dotted',点状类型) |
|||
}, |
|||
}, |
|||
}, |
|||
color: ["#3AA9FF", "#F997DF"], |
|||
//series: seriesData, |
|||
series: [ |
|||
{ |
|||
name: "会员注册", |
|||
type: "line", |
|||
data: filterad(dates, data, "会员注册"), |
|||
}, |
|||
{ |
|||
name: "车牌绑定", |
|||
type: "line", |
|||
data: filterad(dates, data, "车牌绑定"), |
|||
}, |
|||
], |
|||
grid: { |
|||
x: 50, |
|||
y: 55, |
|||
x2: 70, |
|||
y2: 20, |
|||
}, |
|||
}); |
|||
}; |
|||
//获取页面显示数据 |
|||
const getData = (data) => { |
|||
setLoading(false); |
|||
ajax.ElectInvoice.getOperationReport({ |
|||
...data, |
|||
area: data?.area?.length ? data?.area[data.area.length - 1] : "", |
|||
}).then( |
|||
(res) => { |
|||
if (parseInt(res?.status) === 20000) { |
|||
setData({ |
|||
data: res?.data?.list || [], |
|||
total: res?.total || 0, |
|||
}); |
|||
setLoading(true); |
|||
} else { |
|||
message.error(res?.message); |
|||
} |
|||
setLoading(true); |
|||
}, |
|||
(err) => { |
|||
console.log(err); |
|||
setLoading(true); |
|||
} |
|||
); |
|||
}; |
|||
useEffect(() => { |
|||
sessionStorage.setItem("FormData_ParkingAly", JSON.stringify(FormDatas)); |
|||
getData(FormDatas); |
|||
//调用接口 |
|||
}, [FormDatas]); |
|||
useEffect(() => { |
|||
getSelectData(); |
|||
getRevenueOption(); |
|||
getRingOption(); |
|||
}, []); |
|||
return ( |
|||
<div className="RegisterAly"> |
|||
<div className="body_cenf"> |
|||
<div className="left_search"> |
|||
<div className="hrestit">查询条件</div> |
|||
<div className="form_item"> |
|||
<div className="labb"> |
|||
日期 |
|||
<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> |
|||
</div> |
|||
<div className="inputs"> |
|||
<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> |
|||
<div className="form_item"> |
|||
<span className="lab">至</span> |
|||
<div className="inputs"> |
|||
<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> |
|||
<div className="but_on"> |
|||
<span |
|||
className="sear_res" |
|||
onClick={() => { |
|||
var reset = formdata; |
|||
setFormData(reset); |
|||
setFormDatas(reset); |
|||
}} |
|||
> |
|||
重置 |
|||
</span> |
|||
<span |
|||
className={"sear_ser lent"} |
|||
onClick={() => { |
|||
var fortm = FormData; |
|||
setFormData({ |
|||
...fortm, |
|||
pn: 1, |
|||
}); |
|||
setFormDatas({ |
|||
...fortm, |
|||
pn: 1, |
|||
}); |
|||
}} |
|||
> |
|||
查询 |
|||
</span> |
|||
</div> |
|||
</div> |
|||
<div className="right_tab"> |
|||
<div className="parkinglive-box"> |
|||
<div className="result-box parkinglive-left"> |
|||
<div className="result-box-title">泊位占用率</div> |
|||
<Tooltip |
|||
placement="topLeft" |
|||
title={ |
|||
<span> |
|||
展示当前的实时泊位利用率泊位利用率=占用泊位数/总泊位数*100% |
|||
</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> |
|||
展示当前的在场会员车占比在场会员车占比=场内会员车辆数/场内车辆总数*100% |
|||
</span> |
|||
} |
|||
> |
|||
<i>?</i> |
|||
</Tooltip> |
|||
<ReactEcharts |
|||
option={ringData} |
|||
style={{ height: "300px", width: "100%", overflow: "hidden" }} |
|||
/> |
|||
</div> |
|||
</div> |
|||
<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="sd"> |
|||
<p> |
|||
共查询到<span> {Data?.total || 0}</span>条数据 |
|||
</p> |
|||
<span |
|||
className={"sear_ser"} |
|||
onClick={() => { |
|||
ReportPaySummaryReport(); |
|||
// setFormDatas({ ...FormData }); |
|||
}} |
|||
> |
|||
导出 |
|||
</span> |
|||
</div> |
|||
<ResultFlow |
|||
hasLoad={true} |
|||
loading={loading} |
|||
resultData={Data.data} |
|||
message={"暂无数据"} |
|||
> |
|||
<div className="scrplltab"> |
|||
<div className="table_raps"> |
|||
<Table |
|||
className="yisa_tabled" |
|||
columns={column(selectArr)} |
|||
rowKey={(record) => record.id} |
|||
dataSource={Data.data} |
|||
pagination={false} |
|||
scroll={{ |
|||
// x: 1300, |
|||
y: "calc(100vh - 720px)", |
|||
}} |
|||
/> |
|||
</div> |
|||
</div> |
|||
|
|||
<div> |
|||
<Pagination |
|||
className="pagination-common" |
|||
showSizeChanger={true} |
|||
showQuickJumper={true} |
|||
// showTotal={() => `共 ${total_records} 条`} |
|||
total={Data.total} |
|||
current={FormData.pn} |
|||
pageSize={FormData.page_size} |
|||
pageSizeOptions={dictionary?.pageSizeOptions} |
|||
onChange={onShowSizeChange} |
|||
onShowSizeChange={onShowSizeChange} |
|||
/> |
|||
</div> |
|||
</ResultFlow> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
); |
|||
} |
|||
|
|||
export default RegisterAly; |
|||
export default RegisterAly; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue