Files
2025-08-26 16:17:24 +08:00

323 lines
8.9 KiB
Vue

<template>
<view class="container">
<scroll-view scroll-y="true" class="scroll">
<view class="market-box">
<view class="title">
<view class="label">今日门票销售额</view>
<view class="num">{{saleDataVo.todaySaleAmount}}</view>
</view>
<view class="chart6-box">
<view class="left">
<qiun-data-charts type="arcbar" :opts="arcbarOpts" canvas2d :animation="false" :chartData="arcbarChartData" />
<image class="icon" src="../../static/img/Frame.png" mode=""></image>
</view>
<view class="right">
<view class="row">
<view class="col1">
<view class="dot"></view>
<view class="label">今日门票核销数量</view>
</view>
<view class="col2">{{saleDataVo.todayVerificationNum}}</view>
</view>
<view class="row">
<view class="col1">
<view class="dot"></view>
<view class="label">今日门票销售数量</view>
</view>
<view class="col2">{{saleDataVo.todaySaleNum}}</view>
</view>
</view>
</view>
</view>
<view class="card statistics-box">
<view class="title-box">
<image class="headline" src="../../static/img/sjpsjtj.png" mode=""></image>
<view class="label">售检票数据统计</view>
</view>
<view class="chart1-box">
<view class="btns">
<view class="btn btn1" :class="[btnIndex == 1 ? 'activeBtn' : '' ]" @click="changeBtn(1)">近7天</view>
<view class="btn btn2" :class="[btnIndex == 2 ? 'activeBtn' : (btnIndex == 1 || btnIndex == 2) ? 'bl' : (btnIndex == 2 || btnIndex == 3) ? 'br' : '']" @click="changeBtn(2)">近半年</view>
<view class="btn btn3" :class="[btnIndex == 3 ? 'activeBtn' : '']" @click="changeBtn(3)">近三年</view>
</view>
<view class="column-box">
<qiun-data-charts type="column" :opts="columnOpts" canvas2d :chartData="columnChartData" />
</view>
</view>
</view>
<view class="card ratio-box">
<view class="title-box">
<image class="headline" src="../../static/img/ykbl.png" mode=""></image>
<view class="label">游客比例</view>
</view>
<view class="chart2-box">
<view class="scale">
<view :class="['label1', index == 0 ? 'label2' : 'label3']" v-for="(item, index) in touristRateVo" :key="index">
{{(item.value == 0 && sjpsjtjTotal == 0) ? '0%' : (item.value * 100 / sjpsjtjTotal).toFixed(2) + '%'}}
</view>
<view class="when when1 polygon" :style="'width: ' + when1Width + 'rpx'"></view>
</view>
<view class="labels">
<view v-for="(item, index) in touristRateVo" :key="index">{{item.name}}</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
saleDataVo: {},
saleVerificationDataVoList: [],
touristRateVo: [],
sjpsjtjTotal: 0,
btnIndex: 1,
arcbarOpts: {
color: ["#03AE80","#347BEA"],
padding: undefined,
title: {
name: "",
fontSize: 0,
color: "#1890ff"
},
subtitle: {
name: "",
fontSize: 0,
color: "#666666"
},
extra: {
arcbar: {
type: "circle",
width: 12,
backgroundColor: "#E9E9E9",
startAngle: 1.5,
endAngle: 0.25,
gap: 12
}
}
},
columnOpts: {
color: ["#03AE80"],
padding: [15,15,5,15],
enableScroll: false,
legend: {
show: false,
},
xAxis: {
disableGrid: true
},
yAxis: {
data: [
{
min: 0
}
]
},
extra: {
column: {
type: "group",
width: 30,
activeBgColor: "#000000",
activeBgOpacity: 0.08,
linearType: "custom",
seriesGap: 5,
linearOpacity: 0.5,
customColor: [
"#03AE80",
"#03AE80"
]
}
}
},
arcbarChartData: {},
columnChartData: {},
when1Width: 0,
};
},
mounted() {
this.getOperationalAnalysis();
},
methods: {
async getOperationalAnalysis() {
let info = await this.$http.getOperationalAnalysis();
this.saleDataVo = info.data.saleDataVo;
this.saleVerificationDataVoList = info.data.saleVerificationDataVoList;
this.touristRateVo = info.data.touristRateVo;
this.changeBtn(1);
this.touristRateVo.forEach(m => {
this.sjpsjtjTotal += m.value;
})
if (!this.touristRateVo[0].value) {
this.when1Width = 0;
} else {
let num = this.touristRateVo[0].value / this.sjpsjtjTotal;
this.when1Width = num * 630 + 35;
}
let res1 = {
series: [
{
name: "今日门票核销数量",
data: this.saleDataVo.todayVerificationNum
},
{
name: "今日门票销售数量",
data: this.saleDataVo.todaySaleNum
}
]
};
this.arcbarChartData = JSON.parse(JSON.stringify(res1));
},
changeBtn(i) {
this.btnIndex = i;
let name = '';
let categories = [];
let data = [];
this.saleVerificationDataVoList.forEach(m => {
if (m.type == i) {
name = m.typeName;
m.data.forEach(e => {
categories.push(e.name);
data.push(e.value);
})
}
})
let res = {
categories: categories,
series: [
{
name: name,
data: data
}
]
};
this.columnChartData = JSON.parse(JSON.stringify(res));
}
}
}
</script>
<style lang="scss" scoped>
.container {
height: 100%;
.scroll {
height: 100%;
}
.market-box {
width: 686rpx;
height: 428rpx;
background: #FFFFFF;
border-radius: 10rpx;
padding: 32rpx;
box-sizing: border-box;
.title {
display: flex; align-items: center; justify-content: space-between;
.label { font-weight: 500; font-size: 32rpx; color: #333333; }
.num { font-weight: bold; font-size: 40rpx; color: #333333; }
}
.chart6-box {
display: flex; align-items: center;
.left {
width: 320rpx; height: 320rpx; position: relative; margin-right: 48rpx;
.icon {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 52rpx; height: 52rpx;
}
}
.right {
flex: 1;
.row {
margin-top: 74rpx;
&:nth-child(1) {
margin-top: 0;
.dot { background: #03AE80; }
}
&:nth-child(2) {
.dot { background: #347BEA; }
}
.col1 {
display: flex; align-items: center;
.dot {
width: 14rpx; height: 14rpx; border-radius: 50%; margin-right: 10rpx;
}
.label { font-size: 28rpx; color: #333333; line-height: 33rpx; }
}
.col2 { margin: 12rpx 0 0 24rpx; font-weight: bold; font-size: 32rpx; color: #333333; line-height: 38rpx; }
}
}
}
}
.title-box {
width: 686rpx;
height: 90rpx;
box-sizing: border-box;
border-radius: 10rpx 10rpx 0 0;
padding: 23rpx 28rpx;
display: flex;
align-items: center;
.headline {
width: 44rpx;
height: 44rpx;
margin-right: 16rpx;
}
.label {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
}
.card {
width: 100%;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 10rpx;
margin-top: 20rpx;
}
.statistics-box {
.title-box { background: linear-gradient( 90deg, rgba(3,174,128,0.2) 0%, rgba(255,255,255,0.05) 100%); }
.chart1-box {
.btns {
height: 49rpx; display: flex; align-items: center; justify-content: flex-end; margin: 20rpx 28rpx 20rpx 0;
.btn { width: 90rpx; height: 47rpx; line-height: 47rpx; text-align: center; font-size: 22rpx; color: #999999; }
.btn1 { border-radius: 28rpx 0 0 28rpx; border: 1rpx solid #E8E8E8; border-right: none; }
.btn2 { border: 1rpx solid #E8E8E8; }
.btn3 { border-radius: 0 28rpx 28rpx 0; border: 1rpx solid #E8E8E8; border-left: none; }
.activeBtn { border-color: #03AE80; color: #FFFFFF; background-color: #03AE80; }
.bl { border-left: 1rpx solid #03AE80; }
.br { border-right: 1rpx solid #03AE80; }
}
.column-box { height: 317rpx; }
}
}
.ratio-box {
.title-box { background: linear-gradient( 90deg, rgba(43,117,233,0.2) 0%, rgba(255,255,255,0.05) 100%); }
.chart2-box {
height: 194rpx; padding: 32rpx 28rpx; box-sizing: border-box;
.scale {
width: 630rpx;
height: 70rpx;
background: #B3E7D9;
border-radius: 40rpx;
position: relative;
overflow: hidden;
.label1 {
font-weight: 500; font-size: 28rpx; color: #FFFFFF; line-height: 70rpx; z-index: 2;
position: absolute; top: 50%; transform: translateY(-50%);
}
.label2 { left: 40rpx; }
.label3 { right: 40rpx; }
.when { height: 70rpx; position: absolute; top: 0; }
.when1 { left: 0; background-color: #03AE80; z-index: 1; }
.polygon { clip-path: polygon(0 0, 100% 0, 92% 100%, 0 100%); }
}
.labels {
display: flex; align-items: center; justify-content: space-between; margin-top: 20rpx; font-size: 28rpx; color: #333333;
}
}
}
}
</style>