From 6e7caed58506108c8b39876c04c2552e599859c5 Mon Sep 17 00:00:00 2001 From: wanghx Date: Tue, 21 Nov 2023 15:38:43 +0800 Subject: [PATCH] =?UTF-8?q?feat():=20=E5=9F=8E=E5=B8=82=E6=94=B6=E5=85=A5?= =?UTF-8?q?=E5=88=86=E6=9E=90page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/character.config.js | 101 +++++ .../ParkingIncomeAly/CityIncomeAly/index.scss | 254 +++++++++++ .../ParkingIncomeAly/CityIncomeAly/loadable.jsx | 478 ++++++++++++++++++++- .../ParkingIncomeAly/index.js | 9 +- 4 files changed, 829 insertions(+), 13 deletions(-) diff --git a/src/config/character.config.js b/src/config/character.config.js index 5ec0cf3..581506a 100644 --- a/src/config/character.config.js +++ b/src/config/character.config.js @@ -1024,3 +1024,104 @@ export const stackBarChartOption = { data: [] }] } + +export const barChartOption = { + // color: colorList, + grid: { + top: '15%', + left: '0%', + right: '4%', + bottom: '3%', + containLabel: true + }, + tooltip: { + trigger: "axis", + axisPointer: { + type: "shadow", + textStyle: { + color: "#fff" + } + } + }, + legend: { + icon: 'rect', + top: '5%', + left: 'center', + itemHeight: 6, + itemGap: 20, + textStyle: { + color: '#fff' + } + }, + calculable: true, + xAxis: { + type: 'category', + boundaryGap: true, + data: [], + axisLabel: { + color: 'rgba(255, 255, 255, .65)' + } + }, + yAxis: { + type: 'value', + axisLine: { + show: false + }, + axisLabel: { + color: 'rgba(255, 255, 255, .65)' + }, + splitLine: { + show: true, + lineStyle: { + type: 'dashed', + color: '#fff', + opacity: .15 + } + } + }, + series: [{ + name: "", + type: "bar", + barMaxWidth: 12, + barGap: "10%", + itemStyle: { + barBorderRadius: [2, 2, 0, 0], + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: '#99EBFF' + }, { + offset: 1, color: '#3AA9FF' + }], + globalCoord: false + } + }, + data: [] + }, { + name: "", + type: "bar", + barMaxWidth: 12, + barGap: "10%", + itemStyle: { + barBorderRadius: [2, 2, 0, 0], + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: '#FFB8B8' + }, { + offset: 1, color: '#F481F8' + }], + globalCoord: false + } + }, + data: [] + }] +} diff --git a/src/pages/DataAnalysisPrediction/ParkingIncomeAly/CityIncomeAly/index.scss b/src/pages/DataAnalysisPrediction/ParkingIncomeAly/CityIncomeAly/index.scss index 1838f71..027a301 100644 --- a/src/pages/DataAnalysisPrediction/ParkingIncomeAly/CityIncomeAly/index.scss +++ b/src/pages/DataAnalysisPrediction/ParkingIncomeAly/CityIncomeAly/index.scss @@ -1,5 +1,259 @@ @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); + +.parking-container { + display: flex; + padding-top: 10px; + height: 100%; + .parking-container-left { + display: block; + width: 375px; + padding: 10px 10px 20px 20px; + } + .parking-container-right { + 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); + display: flex; + flex-direction: column; + .ant-tabs .ant-tabs-nav-wrap .ant-tabs-nav-list { + width: unset; + } + .ant-tabs-tab { + padding: unset; + } + + .parking-content { + height: 100%; + display: flex; + flex-direction: column; + .parking-tabs { + margin-bottom: 10px; + } + .parking-wrapper { + flex: 1; + } + } + } +} +.parking-container { + .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; + } + + .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); + } + + .btn-export { + width: 90px; + height: 36px; + } + + .submit { + width: calc(100% - 100px); + height: 36px; + } + } + .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; + } + .ant-picker { + width: 100%; + } + .parking-search { + .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 { + display: flex; + flex-direction: column; + } +} +.ant-cascader-menu { + width: 260px; +} + + +.parking-container-right { + .export-container { + margin-bottom: 10px; + text-align: right; + } + .parking-item { + height: 350px; + } + .park-table-content { + margin-top: 20px; + .park-table { + flex: 1; + .ant-table-body { + @include scrollBar(var(--color-user-list-bg), #3B97FF); + } + .ant-table-fixed-header .ant-table-tbody tr:nth-child(2n+1) > td { + background: unset !important; + background-color: #3e4557 !important; + } + } + } +} + +.parking-item { + color: #fff; + background: #3e4557; + border-radius: 4px; + display: flex; + flex-direction: column; + padding: 20px; + &-title { + height: 18px; + display: flex; + align-items: center; + position: relative; + text-indent: .5rem; + font-size: 16px; + font-weight: 700; + user-select: none; + &::before { + position: absolute; + content: ""; + height: 100%; + width: 4px; + left: -2px; + background: var(--color-menu-selected-text-item); + } + } + &-content { + flex: 1; + .echarts-for-react { + height: 100% !important; + } + } +} + +.parking-bottom { + display: flex; + margin-top: 20px; + min-height: 0; + flex: 1; + .parking-item { + flex: 1; + height: 100% !important; + &:nth-child(2) { + margin: 0 20px; + } + &:last-child { + .parking-item-title { + margin-bottom: 10px; + } + } + } + .parking-item-content { + min-height: 0; + overflow-y: hidden; + &:hover { + overflow-y: auto; + @include scrollBar(var(--color-user-list-bg), #3B97FF); + } + } + .item-tab-content { + flex: 1; + margin-top: 10px; + display: flex; + flex-direction: column; + user-select: none; + padding-right: 10px; + .rank-item { + display: flex; + justify-content: space-between; + align-items: center; + height: 30px; + margin-bottom: 5px; + font-size: 16px; + .rank-left { + display: flex; + font-weight: 700; + .rank-no { + width: 25px; + height: 25px; + margin: 0 5px; + margin-right: 10px; + text-align: center; + } + } + &:nth-child(1) { + .rank-no { + background: url('@/assets/images/icon-rank-1.png') no-repeat 100% 100%; + background-size: 100% 100%; + } + } + &:nth-child(2) { + .rank-no { + background: url('@/assets/images/icon-rank-2.png') no-repeat 100% 100%; + background-size: 100% 100%; + } + } + &:nth-child(3) { + .rank-no { + background: url('@/assets/images/icon-rank-3.png') no-repeat 100% 100%; + background-size: 100% 100%; + } + } + } + } +} \ No newline at end of file diff --git a/src/pages/DataAnalysisPrediction/ParkingIncomeAly/CityIncomeAly/loadable.jsx b/src/pages/DataAnalysisPrediction/ParkingIncomeAly/CityIncomeAly/loadable.jsx index fcc12d6..40f9ad7 100644 --- a/src/pages/DataAnalysisPrediction/ParkingIncomeAly/CityIncomeAly/loadable.jsx +++ b/src/pages/DataAnalysisPrediction/ParkingIncomeAly/CityIncomeAly/loadable.jsx @@ -1,15 +1,469 @@ -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"; -function CityIncomeAly() { - return
CityIncomeAly
+import React, { useState, useRef, useEffect } from "react" +import { Select, Input, Button, Table, message, Pagination, DatePicker, Cascader, Tooltip } from "antd" +import { dictionary } from "@/config/common" +import ReactEcharts from "echarts-for-react" +import { barChartOption, pieChartOption } from "@/config/character.config" +import utils from "@/config/utils" +import ajax from "@/services" +import moment from "moment" +import './index.scss' + +function CityIncomeAly(props) { + const { + + } = props + + const [loading, setLoading] = useState(false) + const defaultFormData = { + region: [], + operator_id: "0", + park_type: 0, + date_type: "day", + start_time: "", + end_time: "", + park_bussiness_type: 0 + } + const [formData, setFormData] = useState({ + ...defaultFormData + }) + const [pageInfo, setPageInfo] = useState({ + pn: 1, + length: 10 + }) + const [resultData, setResultDate] = useState({ + list: [], + totalRecords: 0 + }) + const [barOption, setBarOption] = useState({...barChartOption}) + const [ysPieChartOption, setYsPieChartOption] = useState({...pieChartOption}) + const [ssPieChartOption, setSsPieChartOption] = useState({...pieChartOption}) + const [rankData, setRankData] = useState([]) + const [areaList, setAreaList] = useState([]) + const [Yunying, setYunying] = useState([]) + const ajaxGetAreaData = () => { + ajax.getAreaTree().then((res) => { + if (res.status === 20000) { + setAreaList(res.data); + } + }).catch((err) => { + console.error(err) + }); + } + const ajaxGetOperatorData = () => { + ajax.getAllOperator().then((res) => { + if (parseInt(res?.status) === 20000) { + setYunying(res.data); + } else { + message.error(res?.message); + } + }).catch(err => { + console.log(err) + }) + } + const ajaxGetListData = () => { + setLoading(true) + ajax.getCityRevenueAlyData({...formData}).then(res => { + if (res.status == 20000) { + initBarChart([...res.data.trend]) + initPieChart([...res.data.ysAmount], 'ys' , '元') + initPieChart([...res.data.ssAmount], 'ss', '元') + setRankData([...res.data.rank]) + } + setLoading(false) + }) + } + + const initBarChart = (data) => { + setBarOption({ + ...barChartOption, + xAxis: { + ...barChartOption.xAxis, + data: [...data.map(item => item.name)] + }, + yAxis: { + ...barChartOption.yAxis, + axisLabel: { + ...barChartOption.yAxis.axisLabel, + formatter: '{value} 元' + } + }, + series: [ + { + ...barChartOption.series[0], + name: '应收', + data: [...data.map(item => item.ys)] + }, + { + ...barChartOption.series[1], + name: '实收', + data: [...data.map(item => item.ss)] + } + ] + }) + } + + const initPieChart = (data, chartName, unit) => { + let total = 0 + data.map((item) => { + total += item.value + }) + if (chartName == 'ys') { + setYsPieChartOption({ + ...ysPieChartOption, + title: { + ...ysPieChartOption.title, + text: `总应收金额:${utils.parseFormatNum(total)}(${unit})` + }, + tooltip: { + ...ysPieChartOption.tooltip, + formatter: (params) => { + return ` +
+ ${params.marker} + ${params.name}: +    + ${utils.parseFormatNum(params?.value || 0)} + ${unit} +
+ ` + } + }, + series: [ + { + ...ysPieChartOption.series[0], + data: data + } + ] + }) + } else { + setSsPieChartOption({ + ...ssPieChartOption, + title: { + ...ssPieChartOption.title, + text: `总实收金额:${utils.parseFormatNum(total)}(${unit})` + }, + tooltip: { + ...ssPieChartOption.tooltip, + formatter: (params) => { + return ` +
+ ${params.marker} + ${params.name}: +    + ${utils.parseFormatNum(params?.value || 0)} + ${unit} +
+ ` + } + }, + series: [ + { + ...ssPieChartOption.series[0], + data: data + } + ] + }) + } + } + + const TimeChange = () => { + let e = formData.date_type; + let str = "day"; + let mat = "YYYY-MM-DD"; + if (e == "year") { + str = "year"; + mat = "YYYY"; + } else if (e == "month") { + str = "month"; + mat = "YYYY-MM"; + } else if (e == "week") { + str = "week"; + mat = "YYYY-MM-DD"; + } + return { str, mat }; + } + + const SetTimeNow = (e) => { + let start = ""; + let end = ""; + if (e == 'year') { + start = moment().format("YYYY"); + end = moment().format("YYYY"); + } else if (e == 'month') { + start = moment().format("YYYY-MM"); + end = moment().format("YYYY-MM"); + } else if (e == 'week') { + 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 handleReset = () => { + setFormData({ + ...defaultFormData + }) + } + + const handleSearch = () => { + ajaxGetListData() + } + + useEffect(() => { + ajaxGetAreaData() + ajaxGetOperatorData() + ajaxGetListData() + }, []) + + return ( +
+
+
+
查询条件
+
+
+ + { + setFormData({ ...formData, region: v ? v : null }); + }} + /> +
+
+ + + setFormData({ + ...formData, + operator_id: e, + }) + } + /> +
+
+ + SetTimeNow(e)} + /> +
+ + { + 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)} + /> + +
+
+ + { + 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) + } + /> +
+
+ + +
+
+
+
+
+
+
订单收入对比
+
+ +
+
+
+
+
应收金额对比
+
+ +
+
+
+
实收金额对比
+
+ +
+
+ +
+
金额实缴率排行榜
+
+
+ { + rankData && rankData.map((item, index) => ( +
+
+
{index+1 > 3 ? (index+1) : ''}
+
{item.name}
+
+
+
{utils.parseFormatNum(item.value || 0)}
+
+
+ )) + } +
+
+
+
+
+ + ) } export default CityIncomeAly; \ No newline at end of file diff --git a/src/services/DataAnalysisPrediction/ParkingIncomeAly/index.js b/src/services/DataAnalysisPrediction/ParkingIncomeAly/index.js index 0402c5c..b2c22ed 100644 --- a/src/services/DataAnalysisPrediction/ParkingIncomeAly/index.js +++ b/src/services/DataAnalysisPrediction/ParkingIncomeAly/index.js @@ -77,5 +77,12 @@ export default { type: 'post', data }) - } + }, + getCityRevenueAlyData: function(data) { + return ajax({ + url: '/api/dataAnalysis/cityRevenueAnalysis', + type: 'post', + data + }) + }, }