This commit is contained in:
ylj20011123 2025-06-06 19:21:18 +08:00
parent cdd335218f
commit 499a72203f
50 changed files with 3263 additions and 440 deletions

View File

@ -7,6 +7,7 @@
<script setup>
import { onMounted } from "vue";
import { useRouter } from "vue-router";
import './assets/css/fonts.less'
const router = useRouter();

18
src/assets/css/fonts.less Normal file
View File

@ -0,0 +1,18 @@
/* 常规字体 */
@font-face {
font-family: 'YouSheBiaoTiHei';
src: url('../font/YouSheBiaoTiHei-2.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
/* 避免文字渲染阻塞 */
}
// /* 粗体字体 */
// @font-face {
// font-family: 'YouSheBiaoTiHei';
// src: url('../font/YouSheBiaoTiHei-2.ttf') format('truetype');
// font-weight: 700;
// font-style: normal;
// font-display: swap;
// }

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,103 @@
.AssessmentScoringBox {
width: 100%;
.AssessmentScoringListBox {
width: 100%;
margin-top: 20px;
.AssessmentScoringItem {
width: 100%;
box-sizing: border-box;
padding: 10px;
background: linear-gradient(30deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0.05) 100%);
.AssessmentScoringItemTop {
width: 100%;
display: flex;
align-items: center;
.AssessmentScoringItemTopIndex {
font-family: Impact, Impact;
font-weight: 400;
font-size: 15px;
color: #171B2D;
letter-spacing: 1px;
text-align: center;
font-style: normal;
padding: 2px 8px;
display: inline-block;
margin-right: 5px;
}
.AssessmentScoringItemTopName {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 12px;
color: #FFFFFF;
text-align: left;
font-style: normal;
}
}
.AssessmentScoringItemBottom {
width: 100%;
margin-top: 16px;
display: flex;
align-items: center;
justify-content: space-between;
.AssessmentScoringPositionItem {
width: calc((100% - 10px) / 2);
display: flex;
align-items: center;
.AssessmentScoringPosition {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 12px;
color: #018AEE;
text-align: left;
font-style: normal;
padding: 5px 6px;
background-color: rgba(0, 148, 255, 0.3);
border-radius: 5px;
margin-right: 5px;
}
.AssessmentScoringProgress {
flex: 1;
.AssessmentScoringMark {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 12px;
color: #FFFFFF;
text-align: right;
font-style: normal;
text-transform: none;
}
.AssessmentScoringALLProgress {
margin-top: 4px;
width: 100%;
height: 3px;
background-color: rgba(125, 76, 210, 0.3);
border-radius: 5px;
position: relative;
.AssessmentScoringHave {
position: absolute;
top: 0;
left: 0;
height: 100%;
background-color: rgba(125, 76, 210, 1);
border-radius: 5px;
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,34 @@
<script setup lang="ts">
import SmallTitle from '../smallTitle/smallTitle.vue';
import './AssessmentScoring.less'
</script>
<template>
<div class="AssessmentScoringBox">
<SmallTitle title="考核打分排行榜" />
<div class="AssessmentScoringListBox">
<div class="AssessmentScoringItem">
<div class="AssessmentScoringItemTop">
<div class="AssessmentScoringItemTopIndex"></div>
<div class="AssessmentScoringItemTopName"></div>
</div>
<div class="AssessmentScoringItemBottom">
<div class="AssessmentScoringPositionItem">
<div class="AssessmentScoringPosition"></div>
<div class="AssessmentScoringProgress">
<div class="AssessmentScoringMark"></div>
<div class="AssessmentScoringALLProgress">
<div class="AssessmentScoringHave"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>

View File

@ -1,5 +1,6 @@
.BasicMessageBox {
width: 100%;
height: 25px;
.rightBox {
// position: absolute;
@ -26,14 +27,15 @@
white-space: nowrap;
.weatherIcon {
width: 20px;
height: 20px;
width: 18px;
height: 18px;
margin-right: 10px;
}
.weatherText {
font-weight: 400;
font-size: 20px;
font-size: 19px;
line-height: 19px;
color: #FFFFFF;
text-align: center;
font-style: normal;

View File

@ -0,0 +1,156 @@
.BrandDetailBox {
width: 100%;
box-sizing: border-box;
padding: 20px;
.brandTypeBox {
width: 100%;
.brandChartBox {
width: 100%;
height: 132px;
margin-top: 35px;
position: relative;
}
}
.brandList {
width: 100%;
margin-top: 42px;
.tabBox {
width: 100%;
.tabItem {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 15px;
color: #89929E;
text-align: left;
font-style: normal;
margin: 0 20px;
display: inline-block;
cursor: pointer;
}
.selectTab {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 15px;
color: #FFFFFF;
text-align: left;
font-style: normal;
position: relative;
display: inline-block;
}
.selectTab::after {
content: '';
width: 100%;
height: 1px;
background: linear-gradient(180deg, #00F6FF 0%, #008CFF 100%);
position: absolute;
left: 0;
bottom: -5px;
}
}
.brandListBox {
width: 100%;
box-sizing: border-box;
padding: 20px 11px;
.brandItem {
width: 100%;
margin-bottom: 10px;
background-color: #0F1625;
box-sizing: border-box;
padding: 10px;
display: flex;
align-items: center;
.brandLeft {
width: 66px;
height: 66px;
border-radius: 10px;
overflow: hidden;
margin-right: 10px;
.brandIcon {
width: 100%;
height: 100%;
}
}
.brandRight {
flex: 1;
height: 100%;
box-sizing: border-box;
padding: 10px 0;
.brandRightTop {
width: 100%;
.brandRightTopLeft {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 12px;
color: #FFFFFF;
text-align: left;
font-style: normal;
}
.brandRightTopRight {
display: flex;
align-items: center;
.brandRightTopRightIcon {
width: 15px;
height: 15px;
margin-right: 10px;
}
.brandRightTopRightValue {
font-family: Impact, Impact;
font-weight: 400;
font-size: 15px;
color: #FFFFFF;
letter-spacing: 1px;
text-align: right;
font-style: normal;
}
.brandRightTopRightUnit {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 12px;
color: #626670;
text-align: left;
font-style: normal;
margin-left: 4px;
}
}
}
.brandRightBottom {
margin-top: 13px;
.brandRightBottomItem {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 10px;
color: #0094FF;
text-align: center;
font-style: normal;
display: inline-block;
padding: 2px 10px;
background-color: rgba(0, 148, 255, 0.3);
border-radius: 3px;
}
}
}
}
}
}
}

View File

@ -0,0 +1,240 @@
<script setup lang="ts">
import SmallTitle from '../smallTitle/smallTitle.vue';
import './BrandDetail.less'
import * as echarts from 'echarts/core';
import { PieChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { handleGetBusinessTradeTree, handleGetCombineBrandList, handleGetFieldEnumTree } from '../../service';
//
echarts.use([
PieChart,
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
CanvasRenderer
]);
let myChart: echarts.ECharts;
//
const colorList = ['#FF9500', '#0094FF', '#7D4CD2'];
// tab
let tabList = ref<any>([
])
// tab
let selectTab = ref<number>(1)
//
let brandListData = ref<any>([])
//
const props = defineProps<{
currentService?: any;
}>();
//
watch(
() => props.currentService,
(newVal, oldVal) => {
handleGoMounted()
},
{ deep: true }
);
onMounted(async () => {
await handleGoMounted()
})
const handleGoMounted = async () => {
const res: any = await handleGetData()
const chartDom = document.getElementById('brandChartBox');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
legend: {
orient: 'vertical', //
left: '50%', // 5%
top: 'center', //
itemWidth: 12, //
itemHeight: 12, //
textStyle: {
color: '#666', //
rich: {
//
value: {
color: '#333',
fontWeight: 'bold',
padding: [0, 0, 0, 5] //
}
}
},
//
formatter: function (name: string) {
return `1111`
// //
// const dataItem = res.pieData.find((item: any) => item.name === name);
// //
// return `{name|${name}} {value|${dataItem?.value}}`;
}
},
// tooltip: { // tooltip
// trigger: 'item', //
// axisPointer: { //
// type: 'shadow' //
// },
// formatter: function (params: any) { //
// return `
// <div style="font-weight:bold">${params.data.name} ${params?.percent}% ${res.realData[params.dataIndex].toLocaleString()}</div>
// `;
// }
// },
series: [
{
name: 'Access From',
type: 'pie',
radius: ['0%', '100%'],
center: ['25%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
color: function (params: any) {
return colorList[params.dataIndex];
}
},
label: {
show: false
},
emphasis: false,
labelLine: {
show: false
},
data: res.pieData
}
]
};
myChart.setOption(option);
myChart.resize();
window.addEventListener('resize', resizeChart);
}
//
const handleGetData = async () => {
//
const enumData: any = await handleGetFieldEnumTree({
FieldExplainField: "BRAND_TYPE",
sessionName: "BRAND_TYPE"
})
console.log('enumDataenumDataenumDataenumData', enumData);
let category: any = ["全国品牌", "地方连锁", "本地个体"]
let pieData: any = [
{ name: "全国品牌", value: 33.3 },
{ name: "地方连锁", value: 33.3 },
{ name: "本地个体", value: 33.3 }
]
let realData: any = []
const req: any = {
ProvinceCode: "530000"
}
const data = await handleGetBusinessTradeTree(req)
const listData = await handleGetCombineBrandList({
PROVINCE_CODE: "530000",
BRAND_STATE: 1,
SERVERPART_IDS: props.currentService?.SERVERPART_ID || ""
})
console.log('dksjaihudvbujscjsalda', data);
console.log('listDatalistDatalistData', listData);
let res: any = {
category: category,// x
pieData: pieData,// y
realData: realData//
}
return res
}
// tab
const handleChangeTab = (value: number) => {
selectTab.value = value
}
const resizeChart = () => {
myChart?.resize();
};
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
});
</script>
<template>
<div class="BrandDetailBox">
<div class="brandTypeBox">
<SmallTitle title="商户类别比例图" />
<div class="brandChartBox" id="brandChartBox">
</div>
</div>
<div class="brandList">
<SmallTitle>
<template #extra>
<div class="tabBox">
<div :class="selectTab === item.value ? 'tabItem selectTab' : 'tabItem'"
v-for="(item, index) in tabList" :key="index" @click="handleChangeTab(item.value)">
{{ item.label }}
</div>
</div>
<div class="brandListBox">
<div class="brandItem" v-for="(item, index) in brandListData" :key="index">
<div class="brandLeft">
<img class="brandIcon" />
</div>
<div class="brandRight">
<div class="brandRightTop">
<div class="brandRightTopLeft"></div>
<div class="brandRightTopRight">
<img class="brandRightTopRightIcon" />
<div class="brandRightTopRightValue"></div>
<div class="brandRightTopRightUnit"></div>
</div>
</div>
<div class="brandRightBottom">
<div class="brandRightBottomItem"></div>
</div>
</div>
</div>
</div>
</template>
</SmallTitle>
</div>
</div>
</template>

View File

@ -0,0 +1,159 @@
.BusinessCaseBox {
width: 100%;
.BusinessCaseTabBox {
width: 100%;
display: flex;
align-items: center;
.BusinessCaseItem {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 15px;
color: #87919C;
text-align: left;
font-style: normal;
margin: 0 10px;
cursor: pointer;
}
.selectBusinessCaseItem {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 15px;
color: #FFFFFF;
text-align: left;
font-style: normal;
position: relative;
}
.selectBusinessCaseItem::after {
content: "";
width: 100%;
height: 1px;
background: linear-gradient(180deg, #00F6FF 0%, #008CFF 100%);
position: absolute;
left: 0;
bottom: -4px;
}
}
.BusinessCaseRevenueYOY {
width: 100%;
margin-top: 26px;
background: linear-gradient(30deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0) 100%);
box-sizing: border-box;
padding: 20px 15px;
display: flex;
align-items: center;
.BusinessCaseLeftItem {
width: 53px;
height: 53px;
margin-right: 10px;
.BusinessIcon {
width: 53px;
height: 53px;
}
}
.BusinessCaseRightItem {
flex: 1;
display: flex;
align-items: flex-end;
justify-content: space-between;
.rightItemLeft {
.rightItemTitle {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 14px;
color: #FFFFFF;
text-align: left;
font-style: normal;
margin-top: 5px;
}
.rightItemBottom {
margin-top: 8px;
display: flex;
align-items: center;
.compareTitle {
font-family: Inter, Inter;
font-weight: 400;
font-size: 12px;
color: #78828E;
text-align: left;
font-style: normal;
}
.changeBox {
margin-left: 5px;
.changeIcon {
width: 6px;
height: 8px;
margin-right: 2px;
}
.changeText {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 10px;
color: #00FF00;
text-align: left;
font-style: normal;
}
}
}
}
.rightItemRight {
display: flex;
align-items: center;
.BusinessCaseRevenueValue {
font-family: Impact, Impact;
font-weight: 400;
font-size: 25px;
color: #FFFFFF;
letter-spacing: 2px;
text-align: right;
font-style: normal;
}
.BusinessCaseRevenueUnit {
font-family: Inter, Inter;
font-weight: 400;
font-size: 12px;
color: #788390;
text-align: right;
font-style: normal;
margin-left: 10px;
}
}
}
}
.featureAnalysis {
width: 100%;
height: 283px;
.featureAnalysisBox {
width: 100%;
height: 283px;
}
.featureAnalysisBottom {
width: 100%;
height: 283px;
margin-top: 23px;
}
}
}

View File

@ -0,0 +1,432 @@
<script setup lang="ts">
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import SmallTitle from '../smallTitle/smallTitle.vue'
import RevenueYOYIcon from '../../../../assets/image/RevenueYOYIcon.png'
import './BusinessCase.less'
import moment from 'moment';
import { handleCodeGetRevenueCompare, handleGetRevenueTrend } from '../../service';
import * as echarts from 'echarts/core';
import { BarChart, LineChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
DatasetComponent, // dataset
TransformComponent // 使 dataset.source
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
//
echarts.use([
LineChart,
BarChart,
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
DatasetComponent, //
TransformComponent, //
CanvasRenderer
]);
let myChart: echarts.ECharts;
let myChartBottom: echarts.ECharts;
const tabList: any = [
{ label: "营收金额", value: 1 },
{ label: "客单量", value: 2 },
{ label: "客单均价", value: 3 },
]
let selectTab = ref<number>(1)
//
let realData = ref<any>()
//
const props = defineProps<{
currentService?: any;
}>();
//
watch(
() => props.currentService,
(newVal, oldVal) => {
handleGetData()
handleGetBottomData()
},
{ deep: true }
);
onMounted(async () => {
// tab
await handleGetData()
await handleGetBottomData()
})
// tab
const handleChangeTab = async (value: number) => {
selectTab.value = value
handleShowData(value)
}
//
const handleGetData = async () => {
const req: any = {
ProvinceCode: "340000",
StatisticsDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
ServerpartId: props.currentService?.SERVERPART_ID || "",
}
const data = await handleCodeGetRevenueCompare(req)
console.log('djsakjdaskldjasoifioad', data);
//
let category: any = ['product']
let monthList: number[] = []
let list = data.RevenueAmountList
if (list && list.length > 0) {
list.forEach((item: any, index: number) => {
category.push(item.name)
if (index === 0 && item.data && item.data.length > 0) {
item.data.forEach((subItem: any) => {
monthList.push(subItem[0])
})
}
})
}
//
let res: any = []
if (monthList && monthList.length > 0) {
monthList.forEach((item: number) => {
let list: any = [`${item}`]
data.RevenueAmountList.forEach((subItem: any) => {
let newData: any = subItem.data
list.push(newData[item - 1][1])
})
res.push(list)
})
}
//
let res2: any = []
if (monthList && monthList.length > 0) {
monthList.forEach((item: number) => {
let list: any = [`${item}`]
data.TicketCountList.forEach((subItem: any) => {
let newData: any = subItem.data
list.push(newData[item - 1][1])
})
res2.push(list)
})
}
//
let res3: any = []
if (monthList && monthList.length > 0) {
monthList.forEach((item: number) => {
let list: any = [`${item}`]
data.AvgTicketAmountList.forEach((subItem: any) => {
let newData: any = subItem.data
list.push(newData[item - 1][1])
})
res3.push(list)
})
}
let obj: any = {
1: [category, ...res],
2: [category, ...res2],
3: [category, ...res3],
}
console.log('dhsauhdasjhdak', obj);
realData.value = obj
handleShowData(selectTab.value)
}
//
const handleGetBottomData = async () => {
const req: any = {
ProvinceCode: "530000",
StatisticsDate: moment().format('YYYY'),
StatisticsType: 1,
ServerpartId: props.currentService?.SERVERPART_ID || "",
}
const yesReq: any = {
ProvinceCode: "530000",
StatisticsDate: moment().subtract(1, 'y').format('YYYY'),
StatisticsType: 1,
ServerpartId: props.currentService?.SERVERPART_ID || "",
}
const data = await handleGetRevenueTrend(req)
const yesData = await handleGetRevenueTrend(yesReq)
console.log('datadatadatadata', data);
console.log('yesDatayesDatayesDatayesData', yesData);
let category: string[] = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
let currentYear: number[] = []
let lastYear: number[] = []
if (data && data.length > 0) {
data.forEach((item: any) => {
currentYear.push(item.value)
})
}
if (yesData && yesData.length > 0) {
yesData.forEach((item: any) => {
lastYear.push(item.value)
})
}
await handleShowBottomData({
category: category,
currentYear: currentYear,
lastYear: lastYear,
})
}
//
const handleShowData = async (value: number) => {
let data = realData.value[value]
const chartDom = document.getElementById('featureAnalysis');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
legend: {
top: 10,
right: 10,
textStyle: {
color: '#ffffff' //
}
},
tooltip: { trigger: 'axis' },
dataset: { source: data },
xAxis: {
type: 'category',
axisLabel: {
interval: 0,
},
axisTick: {
show: false // 线
}
},
yAxis: {
splitLine: { show: false },
axisLabel: {
width: 40,
overflow: 'truncate',
}
},
series: [{
type: 'bar',
itemStyle: {
color: '#0094FF' //
}
},
{
type: 'bar',
itemStyle: {
color: '#69BCFF' //
}
},
{
type: 'bar',
itemStyle: {
color: '#6B7C8B' //
}
}],
grid: {
left: '0', //
right: '0', //
bottom: '0', //
top: '50', //
containLabel: true // grid
},
};
myChart.setOption(option);
window.addEventListener('resize', resizeChart);
}
//
const handleShowBottomData = async (res: any) => {
const chartDom = document.getElementById('featureAnalysisBottom');
if (!chartDom) return;
myChartBottom = echarts.init(chartDom);
const option = {
legend: {
top: 0, //
right: 0,
itemWidth: 20, //
itemHeight: 10, //
textStyle: {
color: '#fff' //
}
},
xAxis: {
type: 'category',
data: res.category,
boundaryGap: true,
axisLabel: {
interval: 0,
},
axisTick: {
show: false // 线
}
},
yAxis: {
type: 'value',
name: '万元',
splitLine: { show: false },
axisLine: {
show: true,
},
axisLabel: {
}
},
grid: {
left: '10', //
right: '10', //
bottom: '10',
top: '10',
containLabel: true
},
series: [
{
name: '今年',
data: res.currentYear,
type: 'line',
lineStyle: {
width: 2,
color: '#0094FF'
},
itemStyle: {
color: '#0094FF'
},
},
{
name: '去年',
data: res.lastYear,
type: 'line',
lineStyle: {
width: 2,
color: '#00FFB7' //
},
itemStyle: {
color: '#00FFB7' //
},
}
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line' // 线
},
formatter: function (params: any) {
console.log('paramsparamsparams', params);
return `${params.map((item: any) => {
return `<div>
${item.seriesName}${item.value}
</div>`
}).join("")}`
}
}
};
myChartBottom.setOption(option);
window.addEventListener('resize', resizeChartBottom);
}
const resizeChart = () => {
myChart?.resize();
};
const resizeChartBottom = () => {
myChart?.resize();
};
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
window.removeEventListener('resize', resizeChartBottom);
myChartBottom?.dispose();
});
</script>
<template>
<div class="BusinessCaseBox">
<SmallTitle>
<template #extra>
<div class="BusinessCaseTabBox">
<div :class="selectTab === item.value ? 'BusinessCaseItem selectBusinessCaseItem' : 'BusinessCaseItem'"
v-for="(item, index) in tabList" :key="index" @click="handleChangeTab(item.value)">
{{ item.label }}
</div>
</div>
</template>
</SmallTitle>
<!-- 营收同比 -->
<div class="BusinessCaseRevenueYOY">
<div class="BusinessCaseLeftItem">
<img class="BusinessIcon" :src="RevenueYOYIcon" />
</div>
<div class="BusinessCaseRightItem">
<div class="rightItemLeft">
<div class="rightItemTitle">营收同比</div>
<div class="rightItemBottom">
<div class="compareTitle">相比去年同日</div>
<div class="changeBox">
<img class="changeIcon" />
<!-- >0 #00FF00 <0 #FF0000 -->
<div class="changeText"></div>
</div>
</div>
</div>
<div class="rightItemRight">
<div class="BusinessCaseRevenueValue">3,329,828.91</div>
<div class="BusinessCaseRevenueUnit"></div>
</div>
</div>
</div>
<!-- 营收特征分析 -->
<div class="featureAnalysis">
<SmallTitle title="营收特征分析" style="margin-top: 20px;" />
<div class="featureAnalysisBox" id="featureAnalysis"></div>
<SmallTitle title="营收同比分析" style="margin-top: 20px;" />
<div class="featureAnalysisBottom" id="featureAnalysisBottom"></div>
</div>
</div>
</template>

View File

@ -4,7 +4,7 @@
.busninessBox {
width: 100%;
height: 106px;
background-image: url('../../../../assets/image/businessCenterBg.png');
// background-image: url('../../../../assets/image/businessCenterBg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
box-sizing: border-box;
@ -93,7 +93,7 @@
.busninessItemValue {
font-family: Impact, Impact;
font-weight: 400;
font-size: 24px;
font-size: 20px;
color: #FFFFFF;
letter-spacing: 2px;
text-align: left;
@ -115,4 +115,63 @@
}
}
.newCoreBusinessBox {
display: flex;
align-items: center;
.newCoreBusinessItem {
box-sizing: border-box;
padding: 3px 55px;
.newCoreBusinessItemLabel {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: bold;
font-size: 12px;
color: #C1ECF7;
text-align: center;
font-style: normal;
}
.newCoreBusinessItemValue {
font-family: Bahnschrift, Bahnschrift;
font-weight: 400;
font-size: 25px;
color: #48A9F6;
text-align: center;
font-style: normal;
}
.newCoreBusinessItemCompare {
display: flex;
align-items: center;
.newCoreBusinessItemText {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 9px;
color: #C1ECF7;
text-align: left;
font-style: normal;
text-transform: none;
}
.newCoreBusinessItemAddIcon {
width: 6px;
height: 8px;
margin: 0 2px;
}
.newCoreBusinessItemAddValue {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 10px;
color: #00FF00;
text-align: left;
font-style: normal;
}
}
}
}
}

View File

@ -141,8 +141,72 @@ const handleGetPonitFixed = (str: string) => {
<template>
<div class="CoreBusinessDataBox">
<CenterTitle :pageTitle="'核心经营数据'" v-if="!props.noTitle" />
<div class="busninessBox">
<div class="newCoreBusinessBox">
<div class="newCoreBusinessItem">
<div class="newCoreBusinessItemLabel">营收/{{ revenueAmonut.unit }}</div>
<div class="newCoreBusinessItemValue">{{ revenueAmonut.value }}</div>
<!-- <div class="newCoreBusinessItemCompare">
<div class="newCoreBusinessItemText"></div>
<img class="newCoreBusinessItemAddIcon" />
<div class="newCoreBusinessItemAddValue"></div>
</div> -->
</div>
<div class="newCoreBusinessItem">
<div class="newCoreBusinessItemLabel">油品消耗/{{ oilConsumption.unit }}</div>
<div class="newCoreBusinessItemValue">{{ oilConsumption.value }}</div>
<!-- <div class="newCoreBusinessItemCompare">
<div class="newCoreBusinessItemText"></div>
<img class="newCoreBusinessItemAddIcon" />
<div class="newCoreBusinessItemAddValue"></div>
</div> -->
</div>
<div class="newCoreBusinessItem">
<div class="newCoreBusinessItemLabel">加水量/{{ waterAddition.unit }}</div>
<div class="newCoreBusinessItemValue">{{ waterAddition.value }}</div>
<!-- <div class="newCoreBusinessItemCompare">
<div class="newCoreBusinessItemText"></div>
<img class="newCoreBusinessItemAddIcon" />
<div class="newCoreBusinessItemAddValue"></div>
</div> -->
</div>
<div class="newCoreBusinessItem">
<div class="newCoreBusinessItemLabel">尿素/{{ urea.unit }}</div>
<div class="newCoreBusinessItemValue">{{ urea.value }}</div>
<!-- <div class="newCoreBusinessItemCompare">
<div class="newCoreBusinessItemText"></div>
<img class="newCoreBusinessItemAddIcon" />
<div class="newCoreBusinessItemAddValue"></div>
</div> -->
</div>
<div class="newCoreBusinessItem">
<div class="newCoreBusinessItemLabel">充电次数/{{ chargingCycles.unit }}</div>
<div class="newCoreBusinessItemValue">{{ chargingCycles.value }}</div>
<!-- <div class="newCoreBusinessItemCompare">
<div class="newCoreBusinessItemText"></div>
<img class="newCoreBusinessItemAddIcon" />
<div class="newCoreBusinessItemAddValue"></div>
</div> -->
</div>
</div>
<!-- <CenterTitle :pageTitle="'核心经营数据'" v-if="!props.noTitle" /> -->
<div class="busninessBox" v-if="false">
<!-- 营收 -->
<div class="busninessItem">
<div class="busninessItemLeft">
@ -168,9 +232,6 @@ const handleGetPonitFixed = (str: string) => {
</div>
</div>
<!-- 油品消耗 -->
<div class="busninessItem">
<div class="busninessItemLeft">
@ -222,9 +283,6 @@ const handleGetPonitFixed = (str: string) => {
</div>
</div>
<!-- 尿素 -->
<div class="busninessItem">
<div class="busninessItemLeft">
@ -250,7 +308,6 @@ const handleGetPonitFixed = (str: string) => {
</div>
</div>
<!-- 充电次数 -->
<div class="busninessItem">
<div class="busninessItemLeft">

View File

@ -0,0 +1,14 @@
.CustomerConsumptionPreferencesBox {
width: 100%;
.CustomerConsumptionPreferencesContent {
margin-top: 25px;
width: 100%;
height: 212px;
.CustomerConsumptionPreferencesCharts {
width: 100%;
height: 212px;
}
}
}

View File

@ -0,0 +1,200 @@
<script setup lang="ts">
import SmallTitle from '../smallTitle/smallTitle.vue';
import './CustomerConsumptionPreferences.less'
import * as echarts from 'echarts/core';
import { BarChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { onBeforeUnmount, onMounted, watch } from 'vue';
import { handleGetCustomerSaleRatio } from '../../service';
import moment from 'moment';
//
echarts.use([
BarChart,
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
CanvasRenderer
]);
let myChart: echarts.ECharts;
onMounted(async () => {
await handleGoMounted()
});
//
const props = defineProps<{
currentService?: any;
}>();
//
watch(
() => props.currentService,
(newVal, oldVal) => {
handleGoMounted()
},
{ deep: true }
);
//
const handleGoMounted = async () => {
const res = await handleGetData()
const chartDom = document.getElementById('CustomerConsumptionPreferencesCharts');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
xAxis: {
type: 'category',
data: res.category,
axisLabel: {
width: 40, // 60px
overflow: 'truncate', //
ellipsis: '...', //
interval: 0 //
// rotate: 30, // 30
},
// data: res.category
},
yAxis: {
type: 'value',
name: "万辆",
splitLine: { show: false } // 线
},
series: [
{
// data: [120, 200, 150, 80, 70, 110, 130],
data: res.seriesData,
realData: res.realData,
type: 'bar',
barWidth: '6',
showBackground: true,
smooth: true,
backgroundStyle: {
borderRadius: [4, 4, 0, 0],
color: 'rgba(23, 42, 70, 1)'
},
itemStyle: {
borderRadius: [4, 4, 0, 0],
//
color: function (params: any) {
const index = params.dataIndex; //
// 3Mon, Tue, Wed使1
if (index < 3) {
return new echarts.graphic.LinearGradient(
0, 0, 0, 1, //
[
{ offset: 0, color: '#FF4F00' }, //
{ offset: 1, color: '#D3B70E' } //
]
);
}
// 3Thu, Fri, Sat使2
else {
return new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{ offset: 0, color: '#018FFF' }, //
{ offset: 1, color: '#00F4FF' } //
]
);
}
}
}
},
],
grid: {
left: '0', //
right: '0', //
bottom: '0', //
top: '10', //
containLabel: true // grid
},
tooltip: { // tooltip
trigger: 'axis', //
axisPointer: { //
type: 'shadow' //
},
formatter: function (params: any) { //
// params hover
const data = params[0];
let realData = res.realData[params[0].dataIndex]
return `
<div style="font-weight:bold">${data.name}</div>
<div>车流量${realData ? realData + '%' : data.value + '%'} </div>
`;
}
},
};
myChart.setOption(option);
window.addEventListener('resize', resizeChart);
}
const handleGetData = async () => {
const req: any = {
statisticsType: 1,
startMonth: moment().subtract(1, 'd').startOf('y').format('YYYYMM'),
endMonth: moment().subtract(1, 'm').format('YYYYMM'),
provinceCode: '530000',
serverpartId: props.currentService?.SERVERPART_ID || "",
sortStr: 'TOTAL_COUNT desc'
}
const data = await handleGetCustomerSaleRatio(req)
let category: string[] = []
let seriesData: number[] = []
let realData: string[] = []
if (data.CustomerSaleList && data.CustomerSaleList.length > 0) {
let list = data.CustomerSaleList.slice(0, 10)
list.forEach((item: any) => {
category.push(item.BusinessTradeName)
seriesData.push(item.TotalRatio)
realData.push(item.TotalRatio)
})
}
return {
category: category,
seriesData: seriesData,
realData: realData,
}
}
const resizeChart = () => {
myChart?.resize();
};
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
});
</script>
<template>
<div class="CustomerConsumptionPreferencesBox">
<SmallTitle title="客群消费偏好" />
<div class="CustomerConsumptionPreferencesContent">
<div class="CustomerConsumptionPreferencesCharts" id="CustomerConsumptionPreferencesCharts"></div>
</div>
</div>
</template>

View File

@ -0,0 +1,9 @@
.CustomerGroupBox {
width: 100%;
.CustomerGroupBoxContent{
width: 100%;
height: 173px;
margin-top: 20px;
}
}

View File

@ -0,0 +1,200 @@
<script setup lang="ts">
import SmallTitle from '../smallTitle/smallTitle.vue'
import './CustomerGroup.less'
import * as echarts from 'echarts/core';
import { ScatterChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
DatasetComponent, // dataset
TransformComponent // 使 dataset.source
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { onBeforeUnmount, onMounted, watch } from 'vue';
import { handleGetCustomerGroupRatio } from '../../service';
import moment from 'moment';
//
echarts.use([
ScatterChart,
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
DatasetComponent, //
TransformComponent, //
CanvasRenderer
]);
let myChart: echarts.ECharts;
onMounted(async () => {
await handleShowCharts()
})
//
const props = defineProps<{
currentService?: any;
}>();
//
watch(
() => props.currentService,
(newVal, oldVal) => {
handleShowCharts()
},
{ deep: true }
);
const handleShowCharts = async () => {
const res = await handleGetData()
console.log('handleShowChartshandleShowChartshandleShowChartshandleShowCharts', res);
const chartDom = document.getElementById('CustomerGroupBoxContent');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
grid: {
left: '0',
right: '10',
bottom: '0',
top: '10',
containLabel: true
},
xAxis: {
type: 'value',
name: '年龄',
nameLocation: 'middle',
nameGap: 25,
axisLabel: {
formatter: '{value}岁'
},
axisTick: {
show: false // 线
},
axisLine: {
show: false // 线
},
splitLine: {
show: false // 线
}
},
yAxis: {
type: 'value',
name: '交易金额',
axisLabel: {
formatter: '{value}'
},
axisTick: {
show: false // 线
},
axisLine: {
show: false // 线
},
splitLine: {
show: false // 线
}
},
series: [{
name: '用户交易',
type: 'scatter',
symbolSize: function (data) {
return Math.sqrt(data[2]) * 5; //
},
data: res,
itemStyle: {
color: function (params) {
//
const gender = params.data[3]; //
return gender === '男性' ? '#0094FF' : '#FF307C'; //
},
opacity: 0.8,
// borderColor: '#fff',
// borderWidth: 1
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}],
//
legend: {
data: ['男性', '女性'],
itemGap: 20,
textStyle: {
color: '#333'
}
},
//
tooltip: {
trigger: 'item',
formatter: function (params) {
const data = params.data;
return `
年龄: ${data[0]}<br>
性别: ${data[3]}<br>
交易金额: ${data[1]}<br>
占比: ${data[2]}%
`;
}
}
};
myChart.setOption(option);
window.addEventListener('resize', resizeChart);
}
const handleGetData = async () => {
const req: any = {
provinceCode: "530000",
statisticsMonth: moment().subtract(1, 'M').format('YYYYMM'),
serverpartId: props.currentService?.SERVERPART_ID || "",
}
const data = await handleGetCustomerGroupRatio(req)
console.log('jfdjsfklasjflsd', data);
let res: any = []
if (data && data.length > 0) {
data.forEach((item: any) => {
// let list: any = []
if (item.data && item.data.length > 0) {
item.data.forEach((subItem: any) => {
subItem.push(item.name)
res.push(subItem)
})
}
// res.push(list)
})
}
return res
}
const resizeChart = () => {
myChart?.resize();
};
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
});
</script>
<template>
<div class="CustomerGroupBox">
<SmallTitle title="客群特征分析" />
<div class="CustomerGroupBoxContent" id="CustomerGroupBoxContent">
</div>
</div>
</template>

View File

@ -5,9 +5,9 @@
// padding: 35px 20px 40px; // 老的
padding: 20px 10px 30px;
background: linear-gradient(0deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0) 100%);
backdrop-filter: blur(10px);
// backdrop-filter: blur(10px);
/* 高斯模糊效果 */
-webkit-backdrop-filter: blur(10px);
// -webkit-backdrop-filter: blur(10px);
/* Safari 兼容 */
.FestivalRevenue {

View File

@ -111,10 +111,11 @@ onMounted(async () => {
const data = params[0];
return `
<div style="font-weight:bold">${data.name}服务区</div>
<div>销售量${data.value + '笔'} </div>
<div style="font-weight:bold">${data.name}</div>
<div>销售量${data.value} </div>
`;
}
// + ''
}
};

View File

@ -1,9 +1,89 @@
.MerchantRatingRankingBox {
width: 100%;
.MerchantRatingRankingCharts {
// .MerchantRatingRankingCharts {
// width: 100%;
// height: 196px;
// margin-top: 10px;
// }
.MerchantRatingRankingList {
width: 100%;
height: 196px;
margin-top: 10px;
.MerchantRatingRankingItem {
width: 100%;
box-sizing: border-box;
padding: 10px;
background: linear-gradient(30deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0.05) 100%);
.MerchantRatingRankingItemTop {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.MerchantRatingRankingItemTopLeft {
display: flex;
align-items: center;
.MerchantRatingRankingItemTopLeftIndex {
font-family: Impact, Impact;
font-weight: 400;
font-size: 15px;
color: #171B2D;
letter-spacing: 1px;
text-align: center;
font-style: normal;
display: inline-block;
padding: 1px 8px 2px 4px;
margin-right: 5px;
}
.MerchantRatingRankingItemTopLeftName {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 12px;
color: #FFFFFF;
text-align: left;
font-style: normal;
}
}
.MerchantRatingRankingItemTopRight {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 12px;
color: #FFFFFF;
text-align: right;
font-style: normal;
}
}
.MerchantRatingRankingItemBottom {
width: 100%;
margin-top: 12px;
.MerchantRatingRankingItemBottomAllProgress {
width: 100%;
height: 3px;
background-color: rgba(125, 76, 210, 0.3);
border-radius: 5px;
position: relative;
.MerchantRatingRankingItemBottomHaveProgress {
position: absolute;
left: 0;
top: 0;
height: 3px;
background-color: rgba(125, 76, 210, 1);
border-radius: 5px;
}
}
}
}
}
}

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import SmallTitle from '../smallTitle/smallTitle.vue'
import { onMounted, onBeforeUnmount } from 'vue';
import { onMounted, onBeforeUnmount, ref } from 'vue';
import * as echarts from 'echarts/core';
import { BarChart } from 'echarts/charts';
import {
@ -26,7 +26,8 @@ echarts.use([
let myChart: echarts.ECharts;
//
let rankList = ref<any>()
//
const props = defineProps<{
@ -38,89 +39,89 @@ onMounted(async () => {
const res = await handleGetData()
const chartDom = document.getElementById('MerchantRatingRanking');
if (!chartDom) return;
// const chartDom = document.getElementById('MerchantRatingRanking');
// if (!chartDom) return;
myChart = echarts.init(chartDom);
// myChart = echarts.init(chartDom);
const option = {
yAxis: { // yAxis
type: 'category',
data: res.category,
axisLabel: {
width: 80,
overflow: 'truncate',
ellipsis: '...',
interval: 0
}
},
xAxis: { // xAxis
type: 'value',
name: "笔",
splitLine: { show: false }
},
series: [
{
data: res.seriesData,
realData: res.seriesData,
type: 'bar',
barWidth: '6', //
showBackground: true,
backgroundStyle: {
borderRadius: [0, 4, 4, 0], //
color: 'rgba(23, 42, 70, 1)'
},
itemStyle: {
borderRadius: [0, 4, 4, 0], //
color: function (params: any) {
const index = params.dataIndex;
if (index > 6) {
return new echarts.graphic.LinearGradient(
0, 0, 1, 0, //
[
{ offset: 0, color: '#FF4F00' },
{ offset: 1, color: '#D3B70E' }
]
);
}
else {
// const option = {
// yAxis: { // yAxis
// type: 'category',
// data: res.category,
// axisLabel: {
// width: 80,
// overflow: 'truncate',
// ellipsis: '...',
// interval: 0
// }
// },
// xAxis: { // xAxis
// type: 'value',
// name: "",
// splitLine: { show: false }
// },
// series: [
// {
// data: res.seriesData,
// realData: res.seriesData,
// type: 'bar',
// barWidth: '6', //
// showBackground: true,
// backgroundStyle: {
// borderRadius: [0, 4, 4, 0], //
// color: 'rgba(23, 42, 70, 1)'
// },
// itemStyle: {
// borderRadius: [0, 4, 4, 0], //
// color: function (params: any) {
// const index = params.dataIndex;
// if (index > 6) {
// return new echarts.graphic.LinearGradient(
// 0, 0, 1, 0, //
// [
// { offset: 0, color: '#FF4F00' },
// { offset: 1, color: '#D3B70E' }
// ]
// );
// }
// else {
return new echarts.graphic.LinearGradient(
0, 0, 1, 0, //
[
{ offset: 0, color: '#018FFF' },
{ offset: 1, color: '#00F4FF' }
]
);
}
}
}
},
],
grid: {
left: '0', // y
right: '10%',
bottom: '5%',
top: '0',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
formatter: function (params: any) {
// return new echarts.graphic.LinearGradient(
// 0, 0, 1, 0, //
// [
// { offset: 0, color: '#018FFF' },
// { offset: 1, color: '#00F4FF' }
// ]
// );
// }
// }
// }
// },
// ],
// grid: {
// left: '0', // y
// right: '10%',
// bottom: '5%',
// top: '0',
// containLabel: true
// },
// tooltip: {
// trigger: 'axis',
// axisPointer: { type: 'shadow' },
// formatter: function (params: any) {
const data = params[0];
return `
<div style="font-weight:bold">${data.name}服务区</div>
<div>销售量${data.value + '笔'} </div>
`;
}
}
};
// const data = params[0];
// return `
// <div style="font-weight:bold">${data.name}</div>
// <div>${data.value + ''} </div>
// `;
// }
// }
// };
myChart.setOption(option);
window.addEventListener('resize', resizeChart);
// myChart.setOption(option);
// window.addEventListener('resize', resizeChart);
});
//
@ -143,21 +144,42 @@ const handleGetData = async () => {
return res
}
const resizeChart = () => {
myChart?.resize();
};
// const resizeChart = () => {
// myChart?.resize();
// };
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
});
// onBeforeUnmount(() => {
// window.removeEventListener('resize', resizeChart);
// myChart?.dispose();
// });
</script>
<template>
<div class="MerchantRatingRankingBox">
<SmallTitle :title="'商户评分排行榜'" />
<div class="MerchantRatingRankingCharts" id="MerchantRatingRanking">
<!-- <div class="MerchantRatingRankingCharts" id="MerchantRatingRanking">
</div> -->
<div class="MerchantRatingRankingList">
<div class="MerchantRatingRankingItem" v-for="(item, index) in rankList" :key="index">
<div class="MerchantRatingRankingItemTop">
<div class="MerchantRatingRankingItemTopLeft">
<div class="MerchantRatingRankingItemTopLeftIndex"></div>
<div class="MerchantRatingRankingItemTopLeftName"></div>
</div>
<div class="MerchantRatingRankingItemTopRight">
</div>
</div>
<div class="MerchantRatingRankingItemBottom">
<div class="MerchantRatingRankingItemBottomAllProgress">
<div class="MerchantRatingRankingItemBottomHaveProgress"></div>
</div>
</div>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,160 @@
.OverviewOfServiceAreaBox {
width: 100%;
.OverviewOfServiceAreaContent {
width: 100%;
box-sizing: border-box;
padding: 10px 11px 0;
.OverviewOfServiceAreaContentTop {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
.OverviewOfServiceAreaContentTopItem {
width: calc((100% - 20px) / 2);
min-height: 56px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-image: url(../../../../assets/image/serviceAreaBg.png);
background-repeat: no-repeat;
background-size: 100% 100%;
.OverviewOfServiceAreaContentTopItemLabel {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: bold;
font-size: 12px;
color: #FFFFFF;
text-align: center;
font-style: normal;
}
.OverviewOfServiceAreaContentTopItemvalue {
font-family: Bahnschrift, Bahnschrift;
font-weight: 400;
font-size: 25px;
color: #56BCE6;
text-align: center;
font-style: normal;
}
}
}
.OverviewOfServiceAreaContentBottom {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
.OverviewOfServiceAreaContentBottomItem {
width: calc((100% - 20px) / 3);
min-height: 50px;
margin-bottom: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-image: url(../../../../assets/image/serviceAreaBg.png);
background-repeat: no-repeat;
background-size: 100% 100%;
border: 1px solid rgba(78, 173, 245, 0.3);
.OverviewOfServiceAreaContentBottomItemLabel {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: bold;
font-size: 12px;
color: #FFFFFF;
text-align: center;
font-style: normal;
}
.OverviewOfServiceAreaContentBottomItemValue {
font-family: Bahnschrift, Bahnschrift;
font-weight: 400;
font-size: 20px;
color: #FFFFFF;
text-align: center;
font-style: normal;
margin-top: 2px;
}
}
}
}
.OverviewOfServiceAreaBusyContent {
width: 100%;
box-sizing: border-box;
padding: 10px 11px 0;
display: flex;
align-items: center;
justify-content: space-between;
.OverviewOfServiceAreaBusyContentItem {
width: calc((100% - 10px) / 2);
background: linear-gradient(0, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0) 100%);
box-sizing: border-box;
padding: 10px 15px;
display: flex;
align-items: center;
.OverviewOfServiceAreaBusyContentItemLeft {
width: 46px;
height: 46px;
margin-right: 10px;
.OverviewOfServiceAreaBusyContentItemLeftImg {
width: 100%;
height: 100%;
}
}
.OverviewOfServiceAreaBusyContentItemRight {
flex: 1;
.OverviewOfServiceAreaBusyContentItemRightTitle {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 14px;
color: #FF5E5E;
text-align: left;
font-style: normal;
}
.OverviewOfServiceAreaBusyContentItemRightValueBox {
display: flex;
align-items: center;
justify-content: flex-end;
.OverviewOfServiceAreaBusyContentItemRightNumber {
font-family: Impact, Impact;
font-weight: 400;
font-size: 25px;
color: #D24343;
letter-spacing: 2px;
text-align: right;
font-style: normal;
text-transform: none;
}
.OverviewOfServiceAreaBusyContentItemRightUnit {
font-family: Inter, Inter;
font-weight: 400;
font-size: 12px;
color: #808A96;
text-align: right;
font-style: normal;
text-transform: none;
margin-left: 10px;
}
}
}
}
}
}

View File

@ -0,0 +1,236 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import NewBigTitleBox from '../newBigTitleBox/newBigTitleBox.vue';
import './OverviewOfServiceArea.less'
import { handleGetCurBusyRank, handleGetServerpartList } from '../../service';
onMounted(async () => {
await handleGetData()
})
//
const serviceInfo = ref<any>()
//
const businessInfo = ref<any>()
//
const handleGetData = async () => {
const req: any = {
Province_Code: "530000",
ShowService: true
}
const data = await handleGetServerpartList(req)
console.log('fhdushgsu9dgvuisdvgsudvhnjldsfas', data);
//
let serviceAllTotal: number = 0
//
let HASPILOTLOUNGETotal: number = 0
//
let REFUELINGGUNTotal: number = 0
//
let ChargingStationTotal: number = 0
//
let ParkingSpaceTotal: number = 0
//
let toiletTotal: number = 0
//
let NursingRoomTotal: number = 0
// 尿
let URECOUNTTotal: number = 0
if (data && data.length > 0) {
data.forEach((item: any) => {
serviceAllTotal += 1
if (item.RegionInfo && item.RegionInfo.length > 0) {
item.RegionInfo.forEach((subItem: any) => {
if (subItem.HASPILOTLOUNGE > 0) {
HASPILOTLOUNGETotal += 1
}
if (subItem.STATEGRIDCHARGE > 0 || subItem.LIAUTOCHARGE > 0 || subItem.GACENERGYCHARGE > 0 || subItem.OTHERCHARGE > 0) {
ChargingStationTotal += (subItem.STATEGRIDCHARGE || 0)
ChargingStationTotal += (subItem.LIAUTOCHARGE || 0)
ChargingStationTotal += (subItem.GACENERGYCHARGE || 0)
ChargingStationTotal += (subItem.OTHERCHARGE || 0)
}
if (subItem.REFUELINGGUN98 > 0 || subItem.REFUELINGGUN92 > 0 || subItem.REFUELINGGUN95 > 0 || subItem.REFUELINGGUN0 > 0) {
REFUELINGGUNTotal += (subItem.REFUELINGGUN98 || 0)
REFUELINGGUNTotal += (subItem.REFUELINGGUN92 || 0)
REFUELINGGUNTotal += (subItem.REFUELINGGUN95 || 0)
REFUELINGGUNTotal += (subItem.REFUELINGGUN0 || 0)
}
if (subItem.SMALLPARKING > 0 || subItem.PACKING > 0 || subItem.TRUCKPACKING > 0 || subItem.LONGPACKING > 0 || subItem.DANPACKING > 0 || subItem.LIVESTOCKPACKING > 0) {
ParkingSpaceTotal += (subItem.SMALLPARKING || 0)
ParkingSpaceTotal += (subItem.PACKING || 0)
ParkingSpaceTotal += (subItem.TRUCKPACKING || 0)
ParkingSpaceTotal += (subItem.LONGPACKING || 0)
ParkingSpaceTotal += (subItem.DANPACKING || 0)
ParkingSpaceTotal += (subItem.LIVESTOCKPACKING || 0)
}
if (subItem.TOILETCOUNT > 0 || subItem.HASWIFI > 0 || subItem.HASPANTRY > 0) {
toiletTotal += (subItem.TOILETCOUNT || 0)
toiletTotal += (subItem.HASWIFI || 0)
toiletTotal += (subItem.HASPANTRY || 0)
}
if (subItem.HASMOTHER) {
NursingRoomTotal += 1
}
if (subItem.UREA_COUNT > 0) {
URECOUNTTotal += (subItem.UREA_COUNT || 0)
}
})
}
})
}
let res: any = {
serviceAllTotal: serviceAllTotal,
HASPILOTLOUNGETotal: HASPILOTLOUNGETotal,
REFUELINGGUNTotal: REFUELINGGUNTotal,
ChargingStationTotal: ChargingStationTotal,
ParkingSpaceTotal: ParkingSpaceTotal,
toiletTotal: toiletTotal,
NursingRoomTotal: NursingRoomTotal,
URECOUNTTotal: URECOUNTTotal,
}
console.log('fdjsifjasjfs', res);
serviceInfo.value = res
//
const businessReq: any = {
// action_type: "getCurHalfCollect",
// province_code: 5564
ProvinceCode: '530000',
ServerpartId: "",
DataType: '1'
}
// const data = await handleGetCurHalfCollect(req)
const businessData = await handleGetCurBusyRank(businessReq)
console.log('服务区繁忙度数据:', businessData);
//
let businessTotal: number = 0
//
let noramlTotal: number = 0
if (businessData && businessData.length > 0) {
businessData.forEach((item: any) => {
if (item.TicketCount > 30) {
businessTotal += 1
} else {
noramlTotal += 1
}
})
}
businessInfo.value = {
businessTotal: businessTotal,
noramlTotal: noramlTotal,
}
}
</script>
<template>
<div class="OverviewOfServiceAreaBox">
<NewBigTitleBox title="服务区概况" />
<div class="OverviewOfServiceAreaContent">
<div class="OverviewOfServiceAreaContentTop">
<div class="OverviewOfServiceAreaContentTopItem">
<div class="OverviewOfServiceAreaContentTopItemLabel">服务区总数/</div>
<div class="OverviewOfServiceAreaContentTopItemvalue" style="color: #56BCE6;">{{
serviceInfo?.serviceAllTotal || "0" }}</div>
</div>
<div class="OverviewOfServiceAreaContentTopItem">
<div class="OverviewOfServiceAreaContentTopItemLabel">司机之家/</div>
<div class="OverviewOfServiceAreaContentTopItemvalue" style="color: #5ABE89;">{{
serviceInfo?.HASPILOTLOUNGETotal || "0" }}</div>
</div>
</div>
<div class="OverviewOfServiceAreaContentBottom">
<div class="OverviewOfServiceAreaContentBottomItem">
<div class="OverviewOfServiceAreaContentBottomItemLabel">加油站/</div>
<div class="OverviewOfServiceAreaContentBottomItemValue">{{ serviceInfo?.REFUELINGGUNTotal || "0"
}}</div>
</div>
<div class="OverviewOfServiceAreaContentBottomItem">
<div class="OverviewOfServiceAreaContentBottomItemLabel">充电桩/</div>
<div class="OverviewOfServiceAreaContentBottomItemValue">{{ serviceInfo?.ChargingStationTotal || "0"
}}</div>
</div>
<div class="OverviewOfServiceAreaContentBottomItem">
<div class="OverviewOfServiceAreaContentBottomItemLabel">停车位/</div>
<div class="OverviewOfServiceAreaContentBottomItemValue">{{ serviceInfo?.ParkingSpaceTotal || "0"
}}</div>
</div>
<div class="OverviewOfServiceAreaContentBottomItem">
<div class="OverviewOfServiceAreaContentBottomItemLabel">卫生间/</div>
<div class="OverviewOfServiceAreaContentBottomItemValue">{{ serviceInfo?.toiletTotal || "0"
}}</div>
</div>
<div class="OverviewOfServiceAreaContentBottomItem">
<div class="OverviewOfServiceAreaContentBottomItemLabel">母婴室/</div>
<div class="OverviewOfServiceAreaContentBottomItemValue">{{ serviceInfo?.NursingRoomTotal || "0"
}}</div>
</div>
<div class="OverviewOfServiceAreaContentBottomItem">
<div class="OverviewOfServiceAreaContentBottomItemLabel">尿素/</div>
<div class="OverviewOfServiceAreaContentBottomItemValue">{{ serviceInfo?.URECOUNTTotal || "0"
}}</div>
</div>
</div>
</div>
<NewBigTitleBox title="服务承载" style="margin-top: 23px;" />
<div class="OverviewOfServiceAreaBusyContent">
<div class="OverviewOfServiceAreaBusyContentItem">
<div class="OverviewOfServiceAreaBusyContentItemLeft">
<img class="OverviewOfServiceAreaBusyContentItemLeftImg"
src="../../../../assets/image/busyIcon.png" />
</div>
<div class="OverviewOfServiceAreaBusyContentItemRight">
<div class="OverviewOfServiceAreaBusyContentItemRightTitle">繁忙</div>
<div class="OverviewOfServiceAreaBusyContentItemRightValueBox">
<div class="OverviewOfServiceAreaBusyContentItemRightNumber">{{ businessInfo?.businessTotal }}
</div>
<div class="OverviewOfServiceAreaBusyContentItemRightUnit"></div>
</div>
</div>
</div>
<div class="OverviewOfServiceAreaBusyContentItem">
<div class="OverviewOfServiceAreaBusyContentItemLeft">
<img class="OverviewOfServiceAreaBusyContentItemLeftImg"
src="../../../../assets/image/normalIcon.png" />
</div>
<div class="OverviewOfServiceAreaBusyContentItemRight">
<div class="OverviewOfServiceAreaBusyContentItemRightTitle" style="color: #fff;">空闲</div>
<div class="OverviewOfServiceAreaBusyContentItemRightValueBox">
<div class="OverviewOfServiceAreaBusyContentItemRightNumber" style="color: #fff;">
{{ businessInfo?.noramlTotal }}</div>
<div class="OverviewOfServiceAreaBusyContentItemRightUnit"></div>
</div>
</div>
</div>
</div>
</div>
</template>

View File

@ -15,5 +15,16 @@
.amap-container {
left: 0;
}
.l7-control-container {
.l7-bottom {
.l7-control-logo {
.l7-control-logo-link {
display: none;
}
}
}
}
}
}

View File

@ -184,6 +184,7 @@ const handleGetData = async () => {
const data = await handleGetTransactionConvert(req)
//
let customerOrder = data.TransactionList

View File

@ -47,159 +47,159 @@ onMounted(async () => {
handleGetOnlineData()
const res: any = await handleGetData()
// const res: any = await handleGetData()
const chartDom = document.getElementById('TodayTrend');
if (!chartDom) return;
// const chartDom = document.getElementById('TodayTrend');
// if (!chartDom) return;
myChart = echarts.init(chartDom);
// myChart = echarts.init(chartDom);
const option = {
xAxis: {
type: 'category',
data: res.category,
// boundaryGap: true,
axisLabel: {
interval: 3,
showMinLabel: true,
showMaxLabel: true
}
},
yAxis: [
{
type: 'value',
name: '营收',
nameTextStyle: {
color: '#00FFFF'
},
splitLine: { show: false },
axisLine: {
show: true,
lineStyle: {
color: '#00FFFF'
}
},
axisLabel: {
color: '#00FFFF',
formatter: '{value}'
}
},
{
type: 'value',
name: '客单',
nameTextStyle: {
color: '#FFA500'
},
splitLine: { show: false },
position: 'right',
axisLine: {
show: true,
lineStyle: {
color: '#FFA500'
}
},
axisLabel: {
color: '#FFA500',
formatter: '{value}'
},
offset: 0
}
],
grid: {
left: '10',
right: '10',
bottom: '10',
top: '10',
containLabel: true
},
series: [
{
name: '营收',
data: res.seriesData.map((value: any, index: any) => ({
value: value,
symbol: index % 3 === 0 ? 'circle' : 'none',
symbolSize: 6
})),
type: 'line',
smooth: true,
lineStyle: {
width: 2,
color: '#00FFFF'
},
itemStyle: {
color: '#00FFFF'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(0, 255, 255, 0.3)'
},
{
offset: 1,
color: 'rgba(0, 255, 255, 0.1)'
}
])
},
yAxisIndex: 0
},
{
name: '客单',
data: res.seriesDataSecond.map((value: any, index: any) => ({
value: value,
symbol: index % 3 === 0 ? 'circle' : 'none',
symbolSize: 6
})),
type: 'line',
smooth: true,
lineStyle: {
width: 2,
color: '#FFA500'
},
itemStyle: {
color: '#FFA500'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(255, 165, 0, 0.3)'
},
{
offset: 1,
color: 'rgba(255, 165, 0, 0.1)'
}
])
},
yAxisIndex: 1
}
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
snap: true, //
lineStyle: {
color: '#FFF', // 线
width: 1
}
},
formatter: function (params: any) {
let tip = `<div style="font-weight:bold">${params[0].name}</div>`;
params.forEach((param: any) => {
const unit = param.seriesName === '营收' ? '元' : '单';
let value = param.seriesName === '营收' ? res.seriesData[param.dataIndex] : res.seriesDataSecond[param.dataIndex]
tip += `<div>${param.seriesName}: ${value ? value.toLocaleString() : ''}${unit}</div>`;
});
// const option = {
// xAxis: {
// type: 'category',
// data: res.category,
// // boundaryGap: true,
// axisLabel: {
// interval: 3,
// showMinLabel: true,
// showMaxLabel: true
// }
// },
// yAxis: [
// {
// type: 'value',
// name: '',
// nameTextStyle: {
// color: '#00FFFF'
// },
// splitLine: { show: false },
// axisLine: {
// show: true,
// lineStyle: {
// color: '#00FFFF'
// }
// },
// axisLabel: {
// color: '#00FFFF',
// formatter: '{value}'
// }
// },
// {
// type: 'value',
// name: '',
// nameTextStyle: {
// color: '#FFA500'
// },
// splitLine: { show: false },
// position: 'right',
// axisLine: {
// show: true,
// lineStyle: {
// color: '#FFA500'
// }
// },
// axisLabel: {
// color: '#FFA500',
// formatter: '{value}'
// },
// offset: 0
// }
// ],
// grid: {
// left: '10',
// right: '10',
// bottom: '10',
// top: '10',
// containLabel: true
// },
// series: [
// {
// name: '',
// data: res.seriesData.map((value: any, index: any) => ({
// value: value,
// symbol: index % 3 === 0 ? 'circle' : 'none',
// symbolSize: 6
// })),
// type: 'line',
// smooth: true,
// lineStyle: {
// width: 2,
// color: '#00FFFF'
// },
// itemStyle: {
// color: '#00FFFF'
// },
// areaStyle: {
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// {
// offset: 0,
// color: 'rgba(0, 255, 255, 0.3)'
// },
// {
// offset: 1,
// color: 'rgba(0, 255, 255, 0.1)'
// }
// ])
// },
// yAxisIndex: 0
// },
// {
// name: '',
// data: res.seriesDataSecond.map((value: any, index: any) => ({
// value: value,
// symbol: index % 3 === 0 ? 'circle' : 'none',
// symbolSize: 6
// })),
// type: 'line',
// smooth: true,
// lineStyle: {
// width: 2,
// color: '#FFA500'
// },
// itemStyle: {
// color: '#FFA500'
// },
// areaStyle: {
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// {
// offset: 0,
// color: 'rgba(255, 165, 0, 0.3)'
// },
// {
// offset: 1,
// color: 'rgba(255, 165, 0, 0.1)'
// }
// ])
// },
// yAxisIndex: 1
// }
// ],
// tooltip: {
// trigger: 'axis',
// axisPointer: {
// type: 'line',
// snap: true, //
// lineStyle: {
// color: '#FFF', // 线
// width: 1
// }
// },
// formatter: function (params: any) {
// let tip = `<div style="font-weight:bold">${params[0].name}</div>`;
// params.forEach((param: any) => {
// const unit = param.seriesName === '' ? '' : '';
// let value = param.seriesName === '' ? res.seriesData[param.dataIndex] : res.seriesDataSecond[param.dataIndex]
// tip += `<div>${param.seriesName}: ${value ? value.toLocaleString() : ''}${unit}</div>`;
// });
return tip
}
}
};
// return tip
// }
// }
// };
myChart.setOption(option);
myChart.resize();
window.addEventListener('resize', resizeChart);
// myChart.setOption(option);
// myChart.resize();
// window.addEventListener('resize', resizeChart);
})
//
@ -276,29 +276,29 @@ const handleGetOnlineData = async () => {
onlineCashRegisterValue.value = handleGetFiveNumber(res.MACHINECOUNT)
}
const resizeChart = () => {
myChart?.resize();
};
// const resizeChart = () => {
// myChart?.resize();
// };
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
});
// onBeforeUnmount(() => {
// window.removeEventListener('resize', resizeChart);
// myChart?.dispose();
// });
</script>
<template>
<div class="TodayTrendBox">
<SmallTitle :title="'今日走势图'"></SmallTitle>
<!-- <SmallTitle :title="'今日走势图'"></SmallTitle> -->
<div class="TodayTrendUnit">
<!-- <div class="TodayTrendUnit">
<span></span>
<span></span>
</div>
<div class="TodayTrendContent">
</div> -->
<!-- <div class="TodayTrendContent">
<div class="TodayTrend" id="TodayTrend"></div>
</div>
</div> -->
<div class="onlineServiceBox">
<div class="onlineServiceItem">

View File

@ -3,7 +3,7 @@
.TrendOfTrafficFlowCharts {
width: 100%;
margin-top: 10px;
margin-top: 15px;
position: relative;
.trafficFlowCarUnit {
@ -21,7 +21,7 @@
.TrendOfTrafficFlow {
width: 100%;
height: 134px;
height: 133px;
}
}
}

View File

@ -84,7 +84,8 @@ const handleGoMounted = async () => {
smooth: true,
backgroundStyle: {
borderRadius: [4, 4, 0, 0],
color: 'rgba(23, 42, 70, 1)'
// color: 'rgba(23, 42, 70, 1)'
color: 'rgba(0, 148, 255, 0.1)'
},
itemStyle: {
borderRadius: [4, 4, 0, 0],
@ -133,7 +134,7 @@ const handleGoMounted = async () => {
let realData = res.realData[params[0].dataIndex]
return `
<div style="font-weight:bold">${data.name}服务区</div>
<div style="font-weight:bold">${data.name}</div>
<div>车流量${realData ? realData + '辆' : data.value + '万辆'} </div>
`;
}
@ -148,7 +149,8 @@ const handleGoMounted = async () => {
//
const handleGetSectionFlowCount = async () => {
const req: any = {
StatisticsMonth: moment().subtract(1, 'M').format('YYYYMM'),
// StatisticsMonth: moment().subtract(1, 'M').format('YYYYMM'),
StatisticsMonth: "202504",
Serverpart_ID: props.currentService?.SERVERPART_ID || "",
SortStr: "SectionFlow_Count desc",
ProvinceCode: "530000"
@ -188,7 +190,7 @@ onBeforeUnmount(() => {
<template>
<div class="TrendOfTrafficFlowBox">
<SmallTitle :title="'车流断面趋势'" />
<SmallTitle :title="`车流断面趋势(04月)`" />
<div class="TrendOfTrafficFlowCharts">
<div class="trafficFlowCarUnit"></div>

View File

@ -0,0 +1,14 @@
.VehicleStayAnalysisBox {
width: 100%;
.VehicleStayAnalysisContent {
margin-top: 18px;
width: 100%;
height: 174px;
.VehicleStayAnalysisCharts {
width: 100%;
height: 174px;
}
}
}

View File

@ -0,0 +1,197 @@
<script setup lang="ts">
import SmallTitle from '../smallTitle/smallTitle.vue';
import './VehicleStayAnalysis.less'
import * as echarts from 'echarts/core';
import { BarChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { onBeforeUnmount, onMounted, watch } from 'vue';
import { handleGetBayonetSTAList } from '../../service';
import moment from 'moment';
//
echarts.use([
BarChart,
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
CanvasRenderer
]);
let myChart: echarts.ECharts;
onMounted(async () => {
await handleGoMounted()
});
//
const props = defineProps<{
currentService?: any;
}>();
//
watch(
() => props.currentService,
(newVal, oldVal) => {
handleGoMounted()
},
{ deep: true }
);
//
const handleGoMounted = async () => {
const res = await handleGetData()
console.log('handleGetDatahandleGetDatahandleGetDatahandleGetData', res);
const chartDom = document.getElementById('VehicleStayAnalysisCharts');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
formatter: function (params: any) {
return `
<div style="font-weight:bold">${params[0].name}</div>
<div>车辆占比: ${params[0].value}%</div>
<div>停留时间: ${params[1].value}分钟</div>
`;
}
},
legend: {
data: ['车辆占比', '停留时间']
},
grid: {
left: '5%',
right: '5%',
bottom: '5%',
containLabel: true
},
xAxis: {
type: 'category',
data: res.category,
axisLabel: {
interval: 0,
width: 60,
overflow: 'truncate'
}
},
yAxis: [
{ // Y
type: 'value',
name: '车辆占比(%)',
min: 0,
max: 100,
axisLine: { show: true },
splitLine: { show: false }
},
{ // Y
type: 'value',
name: '停留时间(分钟)',
axisLine: { show: true },
splitLine: { show: false },
position: 'right'
}
],
series: [
{ //
name: '车辆占比',
type: 'bar',
data: res.realData,
yAxisIndex: 0, // 使Y
barWidth: 5,
itemStyle: {
borderRadius: [4, 4, 0, 0],
color: '#0094FF'
}
},
{ // 线
name: '停留时间',
type: 'bar',
yAxisIndex: 1, // 使Y
data: res.seriesData,
barWidth: 5,
itemStyle: {
borderRadius: [4, 4, 0, 0],
color: '#00FFB7',
}
}
]
};
myChart.setOption(option);
window.addEventListener('resize', resizeChart);
}
const handleGetData = async () => {
const req: any = {
ContainWhole: true,
StatisticsDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
Serverpart_ID: props.currentService?.SERVERPART_ID || "",
}
const data = await handleGetBayonetSTAList(req)
console.log('daskdhjfhsidugfajskdfhsjalkfhsduifhsdi', data);
let category: string[] = []
let seriesData: number[] = []
let realData: number[] = []
let obj: any = data[0]
category = obj.Vehicle_Type
if (obj.StayTimesList && obj.StayTimesList.length > 0) {
obj.StayTimesList.forEach((item: any) => {
seriesData.push(Number(item.value))
})
}
if (obj.VehicleCountList && obj.VehicleCountList.length > 0) {
let sum: number = 0
obj.VehicleCountList.forEach((item: any) => {
sum += Number(item.value)
})
obj.VehicleCountList.forEach((item: any) => {
realData.push(Number((Number(item.value) / sum * 100).toFixed(2)))
})
}
return {
category: category,
seriesData: seriesData,
realData: realData,
}
}
const resizeChart = () => {
myChart?.resize();
};
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
});
</script>
<template>
<div class="VehicleStayAnalysisBox">
<SmallTitle title="车型停留分析/日均" />
<div class="VehicleStayAnalysisContent">
<div class="VehicleStayAnalysisCharts" id="VehicleStayAnalysisCharts"></div>
</div>
</div>
</template>

View File

@ -20,7 +20,8 @@
.VehiclesEntering {
width: 100%;
height: 134px;
// height: 134px;
height: 167px;
}
}
}

View File

@ -3,7 +3,7 @@ import SmallTitle from '../smallTitle/smallTitle.vue'
import './VehiclesEntering.less'
import { onMounted, onBeforeUnmount, watch } from 'vue';
import * as echarts from 'echarts/core';
import { BarChart } from 'echarts/charts';
import { BarChart, LineChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
@ -12,11 +12,12 @@ import {
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import moment from 'moment';
import { handleGetSPBayonetList } from '../../service';
import { handleGetMonthAnalysis, handleGetSPBayonetList } from '../../service';
//
echarts.use([
BarChart,
LineChart,
GridComponent,
TitleComponent,
TooltipComponent,
@ -50,47 +51,102 @@ const handleGoMounted = async () => {
const chartDom = document.getElementById('VehiclesEntering');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
legend: {
data: [`${res.currentYear}年车流量`, `${res.yesYear}年车流量`, `${res.currentYear}年交易额`, `${res.yesYear}年交易额`],
textStyle: {
color: '#fff',
fontSize: 12 // 12px
},
right: '4%',
top: '0%',
orient: 'horizontal',
type: 'scroll' //
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
top: '30%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: true,
data: res.category
data: res.category,
axisPointer: {
type: 'shadow'
}
},
yAxis: {
type: 'value',
splitLine: { show: false } // 线
},
grid: {
left: '0', //
right: '0', //
bottom: '0', //
top: '10', //
containLabel: true // grid
},
series: [
yAxis: [
{
data: res.seriesData,
realData: res.realData,
type: 'bar',
smooth: true,
barWidth: '18',
type: 'value',
name: '车流量(万辆)',
splitLine: { show: false },
axisLabel: {
formatter: '{value}'
},
splitNumber: 4
},
{
type: 'value',
name: '交易金额(万元)',
splitLine: { show: false },
axisLabel: {
formatter: '{value}'
},
splitNumber: 4
}
],
tooltip: { // tooltip
trigger: 'axis', //
axisPointer: { //
type: 'shadow' //
series: [
{
name: `${res.currentYear}年车流量`,
type: 'bar',
barWidth: '6',
data: res.seriesDataCar,
yAxisIndex: 0
},
formatter: function (params: any) { //
// params hover
const data = params[0];
let realData = res.realData[params[0].dataIndex]
return `
<div style="font-weight:bold">${data.name}</div>
<div>车流量${realData ? realData + '辆' : data.value + '万辆'} </div>
`;
{
name: `${res.yesYear}年车流量`,
type: 'bar',
smooth: true,
data: res.yesSeriesDataCar,
yAxisIndex: 0,
barWidth: '6',
lineStyle: {
width: 3
}
},
{
name: `${res.currentYear}年交易额`,
type: 'line',
data: res.seriesDataRevenue,
yAxisIndex: 1,
symbol: 'circle',
symbolSize: 8,
},
{
name: `${res.yesYear}年交易额`,
type: 'line',
data: res.yesSeriesDataRevenue,
yAxisIndex: 1,
symbol: 'circle',
symbolSize: 8
}
},
],
color: ['#008CFF', '#69BCFF', '#FF5E5E', '#FF9500'] // Custom colors for each series
};
myChart.setOption(option);
myChart.resize();
@ -99,49 +155,74 @@ const handleGoMounted = async () => {
//
const handleGetSectionFlowCount = async () => {
const req: any = {
Province_Code: '340000',
Statistics_Date: moment().subtract(1, 'd').format('YYYY-MM-DD'),
GroupType: 2,
Serverpart_ID: props.currentService?.SERVERPART_ID || "",
}
const data = await handleGetSPBayonetList(req)
//
let smallCar: number = 0
//
let middleCar: number = 0
//
let bigCar: number = 0
// const req: any = {
// Province_Code: '340000',
// Statistics_Date: moment().subtract(1, 'd').format('YYYY-MM-DD'),
// GroupType: 2,
// Serverpart_ID: props.currentService?.SERVERPART_ID || "",
// }
// const data = await handleGetSPBayonetList(req)
const req: any = {
StartDate: moment().startOf('y').format('YYYY-MM-DD'),
EndDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
Serverpart_ID: props.currentService?.SERVERPART_ID || "1143,1144,1186,1188,1189,1190,1191,1192,1193,979,999,1023,1029,1030,1031,1033,1037,1041,1078,1087,1095,1137,1141,1147,1157,1159,1164,1165,1170,1174,981,985,987,994,1007,1009,1010,1012,1016,971,996,1002,1017,1018,1022,1027,1032,1073,1076,1099,1118,1122,1140,1142,1150,1171,970,969,978,1001,1005,1015,1050,1051,1052,1053,1064,1066,1096,1097,1101,1103,1104,1105,1106,1109,1112,1114,1115,1116,1117,991,995,1039,1080,1094,1100,1107,1123,1127,1133,1154,1155,1161,1163,1179,1180,1019,1021,1048,1049,1056,1059,1062,1063,1069,1093,1067,1228,1008,1070,1072,1166,1113,1148,1153,986,1086,1075,1182,1068,1226,1218,1088,1090,1058,1044,1084,1077,1089,1081,1091,1083,1162,1036,1092,988,993,1111,1158,1194,1202,1230,1198,1207,1216,1221,1203,1206,1209,1215,1227,1201,1205,1208,1214,1217,1229,1212,1065,1085,1055,1071,982,1168,1185,1110,977,1169,973,974,1011,1151,1121,1046,1045,1172,1146,976,1187,1156,1181,1136,1138,1211,983,1195,1131,1176,1167,1223,997,1252,1225,1043,1129,992,1149,975,1382,989,1047,1197,1025,1199,1183,1222,1178,1003,1013,1224,1139,1125,1173,1135,1038,1177,1060,1175,1184,1035,1026,1028,1079,1119,1120,1489"
}
const data = await handleGetMonthAnalysis(req)
const yesReq: any = {
StartDate: moment().subtract(1, 'y').startOf('y').format('YYYY-MM-DD'),
EndDate: moment().subtract(1, 'y').endOf('y').format('YYYY-MM-DD'),
Serverpart_ID: props.currentService?.SERVERPART_ID || "1143,1144,1186,1188,1189,1190,1191,1192,1193,979,999,1023,1029,1030,1031,1033,1037,1041,1078,1087,1095,1137,1141,1147,1157,1159,1164,1165,1170,1174,981,985,987,994,1007,1009,1010,1012,1016,971,996,1002,1017,1018,1022,1027,1032,1073,1076,1099,1118,1122,1140,1142,1150,1171,970,969,978,1001,1005,1015,1050,1051,1052,1053,1064,1066,1096,1097,1101,1103,1104,1105,1106,1109,1112,1114,1115,1116,1117,991,995,1039,1080,1094,1100,1107,1123,1127,1133,1154,1155,1161,1163,1179,1180,1019,1021,1048,1049,1056,1059,1062,1063,1069,1093,1067,1228,1008,1070,1072,1166,1113,1148,1153,986,1086,1075,1182,1068,1226,1218,1088,1090,1058,1044,1084,1077,1089,1081,1091,1083,1162,1036,1092,988,993,1111,1158,1194,1202,1230,1198,1207,1216,1221,1203,1206,1209,1215,1227,1201,1205,1208,1214,1217,1229,1212,1065,1085,1055,1071,982,1168,1185,1110,977,1169,973,974,1011,1151,1121,1046,1045,1172,1146,976,1187,1156,1181,1136,1138,1211,983,1195,1131,1176,1167,1223,997,1252,1225,1043,1129,992,1149,975,1382,989,1047,1197,1025,1199,1183,1222,1178,1003,1013,1224,1139,1125,1173,1135,1038,1177,1060,1175,1184,1035,1026,1028,1079,1119,1120,1489"
}
const yesData = await handleGetMonthAnalysis(yesReq)
let category: string[] = []
let seriesDataCar: number[] = []
let seriesDataRevenue: number[] = []
let realDataCar: number[] = []
let realDataRevenue: number[] = []
console.log('dnasfhuaidhsdaghsakjlhsldk', data);
if (data && data.length > 0) {
data.forEach((item: any) => {
smallCar += item.MinVehicle_Count
middleCar += item.MediumVehicle_Count
bigCar += item.LargeVehicle_Count
category.push(`${item.Statistics_Month < 10 ? '0' + item.Statistics_Month : item.Statistics_Month}`)
seriesDataCar.push(item.Vehicle_Count / 10000)
realDataCar.push(item.Vehicle_Count)
seriesDataRevenue.push(item.RevenueAmount / 10000)
realDataRevenue.push(item.RevenueAmount)
})
}
let yesSeriesDataCar: number[] = []
let yesSeriesDataRevenue: number[] = []
let yesRealDataCar: number[] = []
let yesRealDataRevenue: number[] = []
if (yesData && yesData.length > 0) {
yesData.forEach((item: any) => {
yesSeriesDataCar.push(item.Vehicle_Count / 10000)
yesSeriesDataRevenue.push(item.RevenueAmount / 10000)
yesRealDataCar.push(item.Vehicle_Count)
yesRealDataRevenue.push(item.RevenueAmount)
})
}
let res: any = {
category: ["小型车", "中型车", "大型车"],// x
seriesData: [{
value: Number((smallCar / 10000).toFixed(2)),
itemStyle: {
color: '#7D4CD2'
}
},
{
value: Number((middleCar / 10000).toFixed(2)),
itemStyle: {
color: '#0094FF'
}
},
{
value: Number((bigCar / 10000).toFixed(2)),
itemStyle: {
color: '#FF9500'
}
},
],// y
realData: [smallCar.toLocaleString(), middleCar.toLocaleString(), bigCar.toLocaleString()]//
category: category,// x
seriesDataCar: seriesDataCar, //
seriesDataRevenue: seriesDataRevenue,//
realDataCar: realDataCar,//
realDataRevenue: realDataRevenue,//
yesSeriesDataCar: yesSeriesDataCar,//
yesSeriesDataRevenue: yesSeriesDataRevenue,//
yesRealDataCar: yesRealDataCar,//
yesRealDataRevenue: yesRealDataRevenue,//
currentYear: moment().format('YYYY'), //
yesYear: moment().subtract(1, 'y').format('YYYY')//
}
return res
}
@ -163,7 +244,7 @@ onBeforeUnmount(() => {
<template>
<div class="VehiclesEnteringBox">
<SmallTitle :title="'入区车辆趋势'">
<SmallTitle :title="'月度车流累计'">
<!-- <template #extra>
<div class="legendBox" style="display: flex;align-items: center;">
<div class="legendItem" style="display: flex;align-items: center;margin-right: 20px;">
@ -189,7 +270,7 @@ onBeforeUnmount(() => {
</SmallTitle>
<div class="VehiclesEnteringCharts">
<div class="VehiclesEnteringUnit"></div>
<!-- <div class="VehiclesEnteringUnit"></div> -->
<div class="VehiclesEntering" id="VehiclesEntering"></div>
</div>
</div>

View File

@ -0,0 +1,16 @@
.newBigTitleBox {
width: 100%;
height: 31px;
background-image: url(../../../../assets/image/newBigTitleBg.png);
background-repeat: no-repeat;
background-size: 100% 100%;
font-family: YouSheBiaoTiHei;
font-weight: 400;
font-size: 20px;
line-height: 20px;
color: #4CA9EF;
text-align: left;
font-style: normal;
box-sizing: border-box;
padding-left: 38px;
}

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import './newBigTitleBox.less'
//
const props = defineProps<{
title?: string;
}>();
</script>
<template>
<div class="newBigTitleBox">
{{ props?.title || "" }}
</div>
</template>

View File

@ -1,55 +1,128 @@
// 横向滚动
.noticeListBigBox {
width: 100%;
height: 25px;
// background: rgba(255, 255, 255, 1);
border-radius: 18px;
display: flex;
align-items: center;
padding: 0 10px;
box-sizing: border-box;
.noticeIcon {
width: 18px;
height: 18px;
margin-right: 10px;
margin-right: 5px;
}
.noticeListBox {
height: 26px; // 2条高度按你需求调整
width: 100%;
height: 20px;
overflow: hidden;
position: relative;
border-radius: 8px;
.noticeList {
display: flex;
flex-direction: column;
&.scrolling {
animation: scrollAnimation 20s linear infinite;
}
white-space: nowrap;
transition: none;
position: relative;
.noticeItem {
width: 100%;
box-sizing: border-box;
padding: 6px 0;
display: flex;
align-items: center;
margin-right: 15px; // 调整item之间的间距
.icon {
width: 8px;
height: 8px;
background: #fff;
transform: rotate(45deg);
margin-right: 8px;
width: 3px;
height: 3px;
background: #1989FA;
border-radius: 50%;
margin-right: 5px;
}
.contentMessage {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16px;
color: #fff;
line-height: 26px;
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: 400;
font-size: 19px;
line-height: 19px;
color: #FFFFFF;
text-align: left;
font-style: normal;
}
}
// 实现无缝滚动
&.scrolling {
animation: scrollNotice var(--scroll-duration, 10s) linear infinite;
}
}
}
}
// 关键帧动画
@keyframes scrollNotice {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-VAR_PX);
}
}
// 纵向滚动
// .noticeListBigBox {
// display: flex;
// align-items: center;
// .noticeIcon {
// width: 18px;
// height: 18px;
// margin-right: 10px;
// }
// .noticeListBox {
// height: 26px; // 2条高度按你需求调整
// overflow: hidden;
// position: relative;
// border-radius: 8px;
// .noticeList {
// display: flex;
// flex-direction: column;
// &.scrolling {
// animation: scrollAnimation 20s linear infinite;
// }
// .noticeItem {
// width: 100%;
// box-sizing: border-box;
// padding: 6px 0;
// display: flex;
// align-items: center;
// .icon {
// width: 8px;
// height: 8px;
// background: #fff;
// transform: rotate(45deg);
// margin-right: 8px;
// }
// .contentMessage {
// white-space: nowrap;
// overflow: hidden;
// text-overflow: ellipsis;
// font-size: 16px;
// color: #fff;
// line-height: 26px;
// text-align: left;
// }
// }
// }
// }
// }

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import './noticeListBox.less'
import noticeIcon from '../../../../assets/image/noticeIcon.png'
import { onMounted, reactive, ref, watch } from 'vue'
import { nextTick, onMounted, reactive, ref, watch } from 'vue'
import { handleGetGDNearServiceList } from '../../service'
@ -11,6 +11,8 @@ let noticeList = reactive<any>([]);
let currentIndex = ref<number>(0)
//
let scrollInterval = ref<any>(null)
let isScrolling = ref<boolean>(false);
let scrollDuration = ref('10s'); //
onMounted(async () => {
//
@ -52,44 +54,94 @@ const handleGetNoticeList = async () => {
noticeList.length = 0;
list && list.forEach((item: any) => noticeList.push(item));
if (list && list.length > 0) {
startScrolling()
}
console.log('noticeList:', noticeList); //
nextTick(() => {
//
startScrolling();
})
}
//
const startScrolling = () => {
stopScrolling();
if (noticeList.length <= 1) return;
const duration = 3000;
scrollInterval.value = setInterval(() => {
currentIndex.value++;
if (currentIndex.value >= noticeList.length) {
setTimeout(() => {
const container = document.querySelector('.noticeContainer') as HTMLElement;
if (container) container.style.transition = 'none';
currentIndex.value = 0;
setTimeout(() => {
if (container) container.style.transition = '';
}, 50);
}, 500);
isScrolling.value = false;
nextTick(() => {
const listEl = document.querySelector('.noticeList') as HTMLElement;
if (listEl) {
const originWidth = listEl.scrollWidth / 2;
const speed = 100; // px/s
const duration = originWidth / speed;
scrollDuration.value = duration + 's';
// keyframes
const styleId = 'dynamic-scroll-keyframes';
let styleEl = document.getElementById(styleId) as HTMLStyleElement;
if (!styleEl) {
styleEl = document.createElement('style');
styleEl.id = styleId;
document.head.appendChild(styleEl);
}
styleEl.innerHTML = `
@keyframes scrollNotice {
0% { transform: translateX(0); }
100% { transform: translateX(-${originWidth}px); }
}`;
isScrolling.value = true;
}
}, duration);
});
// stopScrolling();
// if (noticeList.length <= 1) return;
// const duration = 3000;
// scrollInterval.value = setInterval(() => {
// currentIndex.value++;
// if (currentIndex.value >= noticeList.length) {
// setTimeout(() => {
// const container = document.querySelector('.noticeContainer') as HTMLElement;
// if (container) container.style.transition = 'none';
// currentIndex.value = 0;
// setTimeout(() => {
// if (container) container.style.transition = '';
// }, 50);
// }, 500);
// }
// }, duration);
}
//
const stopScrolling = () => {
isScrolling.value = false;
if (scrollInterval.value) {
clearInterval(scrollInterval.value)
scrollInterval.value = null
}
// if (scrollInterval.value) {
// clearInterval(scrollInterval.value)
// scrollInterval.value = null
// }
}
</script>
<template>
<!-- 横向滚动 -->
<div class="noticeListBigBox">
<img class="noticeIcon" :src="noticeIcon" />
<div class="noticeListBox">
<div :class="['noticeList', { 'scrolling': isScrolling }]" :style="{ '--scroll-duration': scrollDuration }">
<div class="noticeItem" v-for="(item, index) in noticeList.concat(noticeList)" :key="index">
<div class="icon"></div>
<div class="contentMessage">
{{ item.NOTICEINFO_TITLE || '-' }}
</div>
</div>
</div>
</div>
</div>
<!-- 纵向滚动 -->
<!-- <div class="noticeListBigBox">
<img class="noticeIcon" :src="noticeIcon" />
<div class="noticeListBox">
<div :class="noticeList.length > 1 ? 'noticeList scrolling' : 'noticeList'">
@ -101,7 +153,7 @@ const stopScrolling = () => {
</div>
</div>
</template>
<template v-else>
<template v-else>
<div class="noticeItem" v-for="(item, index) in noticeList" :key="index">
<div class="icon"></div>
<div class="contentMessage">
@ -109,7 +161,7 @@ const stopScrolling = () => {
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div> -->
</template>

View File

@ -165,22 +165,27 @@
.pageTop169 {
width: 100vw;
height: 48px;
background: linear-gradient(180deg, #182950 0%, #18223F 100%);
border-bottom: 1px solid #0E789A;
// height: 48px;
height: 86px;
// background: linear-gradient(180deg, #182950 0%, #18223F 100%);
// border-bottom: 1px solid #0E789A;
position: relative;
box-sizing: border-box;
display: flex;
align-items: center;
// align-items: center;
justify-content: space-between;
background-image: url('../../../../assets/image/allPageTopBg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
// padding: 0 30px;
.centerBox {
width: 40%;
height: 80px;
background-image: url('../../../../assets//image/pageTitle.png');
background-repeat: no-repeat;
background-size: 100% 100%;
// background-image: url('../../../../assets//image/pageTitle.png');
// background-image: url('../../../../assets/image/newPageTitle.png');
// background-repeat: no-repeat;
// background-size: 100% 100%;
position: absolute;
top: 0;
// left: 50%;
@ -210,19 +215,20 @@
.leftTabBox {
width: 30%;
height: 100%;
// height: 100%;
height: 48px;
box-sizing: border-box;
padding-left: 30px;
display: flex;
align-items: center;
// align-items: center;
.pageTopTabItem {
width: 50%;
height: 100%;
font-family: Inter, Inter;
font-weight: 400;
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: bold;
font-size: 20px;
color: #5D6780;
color: #ffffff;
text-align: center;
font-style: normal;
display: flex;
@ -232,8 +238,8 @@
}
.selectPageTopTabItem {
color: #FFFFFF;
background-image: url('../../../../assets//image/pageTabBg.png');
color: #4CA9EF;
background-image: url('../../../../assets//image/newSelectPageTop.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}

View File

@ -123,7 +123,6 @@ const handleGetNowWeather = async () => {
weatherInfo.value = weatherObj
}
//
const emit = defineEmits<{
(e: "handleChangePageType"): void; //
@ -187,8 +186,8 @@ onBeforeUnmount(() => {
<div :class="props.pageType === 'left' ? 'centerBox leftBgBox' : 'centerBox'"
:style="{ left: props.pageType === 'left' ? '0' : '50%', transform: props.pageType === 'left' ? 'translateX(-50px)' : 'translateX(-50%)' }">
<!-- @click="handleChangePageType" -->
<img class="pageLogo" :src="cyyLogo" />
<span class="pageTitle">云南高速服务区智慧数智大屏</span>
<!-- <img class="pageLogo" :src="cyyLogo" /> -->
<!-- <span class="pageTitle">云南高速服务区智慧数智大屏</span> -->
</div>
<!-- 最初版的内容 -->

View File

@ -1,17 +1,19 @@
.smallTitleBox {
height: 28px;
// height: 28px;
height: 20px;
box-sizing: border-box;
padding: 4px 10px;
background: linear-gradient(90deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0) 100%);
border-left: 1px solid #01F0FE;
// padding: 4px 10px;
// background: linear-gradient(90deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0) 100%);
// border-left: 1px solid #01F0FE;
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 10px;
.title {
font-family: "Microsoft YaHei";
font-weight: 400;
font-size: 16px;
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: bold;
font-size: 15px;
color: #FFFFFF;
text-align: left;
font-style: normal;

View File

@ -4,7 +4,7 @@ import './smallTitle.less'
//
const props = defineProps<{
pageType?: any;
title: string
title?: string
}>();
</script>

View File

@ -42,6 +42,14 @@ import MerchantRatingRanking from './components/MerchantRatingRanking/MerchantRa
import HighQualityMerchants from './components/HighQualityMerchants/HighQualityMerchants.vue'
import ThisMonthBenefits from './components/ThisMonthBenefits/ThisMonthBenefits.vue';
import CoreCategory from './components/CoreCategory/CoreCategory.vue'
import BusinessCase from './components/BusinessCase/BusinessCase.vue'
import CustomerGroup from './components/CustomerGroup/CustomerGroup.vue'
import CustomerConsumptionPreferences from './components/CustomerConsumptionPreferences/CustomerConsumptionPreferences.vue'
import VehicleStayAnalysis from './components/VehicleStayAnalysis/VehicleStayAnalysis.vue'
import BrandDetail from './components/BrandDetail/BrandDetail.vue'
import AssessmentScoring from './components/AssessmentScoring/AssessmentScoring.vue';
import OverviewOfServiceArea from './components/OverviewOfServiceArea/OverviewOfServiceArea.vue'
import NewBigTitleBox from './components/newBigTitleBox/newBigTitleBox.vue'
//
let pageType = ref<string>("center")
@ -92,15 +100,16 @@ const handleChangePageTab = (value: number) => {
<!-- 消息轮播框 -->
<NoticeListBox :currentService="currentService" />
<modalTitle :title="'流量趋势'" style="margin-top: 20px;" />
<div class="leftContentBox">
<!-- <modalTitle :title="'流量趋势'" style="margin-top: 20px;" /> -->
<NewBigTitleBox title="流量趋势" style="margin-top: 37px;" />
<div class="content169LeftContent">
<div class="leftContentBoxItem">
<!-- 车流断面趋势 -->
<TrendOfTrafficFlow :currentService="currentService" />
</div>
<div class="leftContentBoxItem" style="margin-top: 20px;">
<div class="leftContentBoxItem" style="margin-top: 30px;">
<!-- 入区车辆趋势 -->
<VehiclesEntering :currentService="currentService" />
</div>
@ -112,6 +121,7 @@ const handleChangePageTab = (value: number) => {
</div>
<modalTitle :title="'节假日营收分析'" style="margin-top: 20px;">
<template #extra>
<div class="FestivalBox">
@ -148,7 +158,7 @@ const handleChangePageTab = (value: number) => {
<MultiIndustryIncome style="margin-top: 20px;" :currentService="currentService" />
<!-- 区域营收占比 -->
<RegionalRevenue :currentService="currentService" style="margin-top: 56px;" />
<RegionalRevenue :currentService="currentService" style="margin-top: 90px;" />
<!-- 业态结构占比 -->
<BusinessStructure :currentService="currentService" style="margin-top: 30px;" />
@ -160,7 +170,7 @@ const handleChangePageTab = (value: number) => {
<div class="content1692st" v-if="selectPageTab === 2">
<div class="content1692stLeft">
<!-- 消息轮播框 -->
<NoticeListBox />
<NoticeListBox style="margin-top: 20px;" />
<!-- 核心经营数据 -->
<modalTitle :title="'核心经营数据'" style="margin-top: 20px;" />
<CoreBusinessData style="position: relative;z-index: 9;" :noTitle="true" />
@ -220,7 +230,7 @@ const handleChangePageTab = (value: number) => {
</div>
<div class="content1692stRight">
<!-- 时间天气等内容 -->
<BasicMessageBox />
<BasicMessageBox style="margin-top: 19px;" />
<!-- 电商模块 -->
<modalTitle :title="'电商模块'" style="margin-top: 20px;" />
@ -291,7 +301,44 @@ const handleChangePageTab = (value: number) => {
</div>
<div class="content1693stItem">
<!-- 经营数据同比分析 -->
<BusinessCase :currentService="currentService" />
</div>
</div>
<!-- 分区四 -->
<div class="content1694st" v-if="selectPageTab === 4">
<div class="content1694stItem">
<!-- 客群特征分析 -->
<CustomerGroup />
<!-- 客群消费偏好 -->
<CustomerConsumptionPreferences style="margin-top: 140px;" />
<!-- 车型停留分析/日均 -->
<VehicleStayAnalysis style="margin-top: 130px;" />
</div>
<div class="content1694stItem">
<!-- 商户类别比例图 下面的列表 -->
<BrandDetail />
</div>
<div class="content1694stItem">
<!-- 在线服务区和在线收银机 -->
<TodayTrend />
<!-- 交易预警 -->
<TradingAlert />
<!-- 考核打分排行榜 -->
<AssessmentScoring style="margin-top: 130px;" />
</div>
<div class="content1694stItem">
<!-- 服务区概况 -->
<OverviewOfServiceArea />
</div>
</div>

View File

@ -287,3 +287,93 @@ export async function handleGetCombineBrandList(params: any) {
}
return data.Result_Data.List
}
// 获取营收同比数据
export async function handleCodeGetRevenueCompare(params: any) {
const data: any = await requestCode.get('/Revenue/GetRevenueCompare', params)
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data
}
// 获取营收趋势图
export async function handleGetRevenueTrend(params: any) {
const data: any = await requestCode.get('/Revenue/GetRevenueTrend', params)
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data.List
}
// 获取客群特征分析
export async function handleGetCustomerGroupRatio(params: any) {
const data: any = await requestCode.get('/Customer/GetCustomerGroupRatio', params)
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data.List
}
// 获取客群消费偏好数据
export async function handleGetCustomerSaleRatio(params: any) {
const data: any = await requestCode.get('/Customer/GetCustomerSaleRatio', params)
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data
}
// 获取服务区车辆时段停留时长分析
export async function handleGetBayonetSTAList(params: any) {
const data: any = await requestCode.get('/Revenue/GetBayonetSTAList', params)
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data.List
}
// 查询经营业态树
export async function handleGetBusinessTradeTree(params: any) {
const data: any = await request.get('/BaseInfo/GetBusinessTradeTree', params)
if (data.Result_Code !== 100) {
return data
}
return wrapTreeNode(data.Result_Data.List)
}
// 获取品牌表列表
export async function handleGetBrandList(params: any) {
const data: any = await request.post('/BaseInfo/GetBrandList', params)
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data.List
}
// 拿枚举
export async function handleGetFieldEnumTree(params: any) {
const data: any = await request.get('/FrameWork/GetFieldEnumTree', params)
if (data.Result_Code !== 100) {
return data
}
return wrapTreeNode(data.Result_Data.List)
}
// 获取月度车流分析数据
export async function handleGetMonthAnalysis(params: any) {
const data: any = await requestCode.get('/BigData/GetMonthAnalysis', params)
if (data.Result_Code !== 100) {
return data
}
return data.Result_Data.List
}

View File

@ -256,29 +256,38 @@
.content169 {
width: 100%;
height: calc(100% - 48px);
// height: calc(100% - 48px);
height: calc(100% - 86px);
box-sizing: border-box;
padding: 0 20px 35px;
// padding: 0 20px 35px;
padding: 0 35px;
display: flex;
align-items: center;
justify-content: space-between;
.content169Left {
width: 22%;
width: calc((100% - 105px) / 4);
height: 100%;
position: relative;
z-index: 9;
box-sizing: border-box;
padding-top: 20px;
padding-top: 21px;
// padding-top: 20px;
.content169LeftContent {
width: 100%;
box-sizing: border-box;
padding: 21px 11px;
}
.leftContentBox {
width: 100%;
box-sizing: border-box;
padding: 20px 11px 0;
background: linear-gradient(0deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0) 100%);
backdrop-filter: blur(10px);
// background: linear-gradient(0deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0) 100%);
// backdrop-filter: blur(10px);
/* 高斯模糊效果 */
-webkit-backdrop-filter: blur(10px);
// -webkit-backdrop-filter: blur(10px);
/* Safari 兼容 */
}
@ -300,7 +309,7 @@
}
.content169Center {
width: 47%;
width: calc((100% - 105px) / 4 * 2 + 35px);
height: 100%;
box-sizing: border-box;
padding-top: 66px;
@ -309,21 +318,21 @@
}
.content169Right {
width: 22%;
width: calc((100% - 105px) / 4);
height: 100%;
position: relative;
z-index: 9;
box-sizing: border-box;
padding-top: 20px;
padding-top: 21px;
.rightContentBox {
width: 100%;
box-sizing: border-box;
padding: 20px 11px 0;
background: linear-gradient(0deg, rgba(0, 148, 255, 0.1) 0%, rgba(0, 148, 255, 0) 100%);
backdrop-filter: blur(10px);
// backdrop-filter: blur(10px);
/* 高斯模糊效果 */
-webkit-backdrop-filter: blur(10px);
// -webkit-backdrop-filter: blur(10px);
/* Safari 兼容 */
}
@ -335,7 +344,7 @@
width: 100%;
height: calc(100% - 48px);
box-sizing: border-box;
padding: 20px 35px;
padding: 0 20px 35px;
display: flex;
align-items: center;
justify-content: space-between;
@ -374,7 +383,7 @@
width: 22%;
height: 100%;
box-sizing: border-box;
padding-top: 46px;
padding-top: 66px;
.left4stContent {
width: 100%;
@ -426,4 +435,24 @@
}
}
.content1694st {
width: 100%;
height: calc(100% - 48px);
box-sizing: border-box;
padding: 20px 35px;
display: flex;
align-items: center;
justify-content: space-between;
.content1694stItem {
width: 22%;
height: 100%;
box-sizing: border-box;
}
}
}