527 lines
13 KiB
Vue
527 lines
13 KiB
Vue
|
<template>
|
|||
|
<view class="waper">
|
|||
|
<!-- 导航栏 -->
|
|||
|
<u-navbar bgColor="transparent" leftIconSize="0" borderBottom="false">
|
|||
|
<view slot='center' class="navbar_title">数据统计中心</view>
|
|||
|
</u-navbar>
|
|||
|
|
|||
|
<!-- 顶部横幅 -->
|
|||
|
<view class="banner-box">
|
|||
|
<image class="banner" src="../../static/img/banner.png" mode="widthFix"></image>
|
|||
|
<!-- 统计概览卡片 -->
|
|||
|
<view class="stats-overview">
|
|||
|
<view class="stat-item">
|
|||
|
<view class="stat-label">总销售额</view>
|
|||
|
<view class="stat-value">¥68,532</view>
|
|||
|
<view class="stat-trend positive">
|
|||
|
<uni-icons type="arrowup" size="14"></uni-icons>
|
|||
|
<text>12.5%</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="stat-item">
|
|||
|
<view class="stat-label">总订单量</view>
|
|||
|
<view class="stat-value">8,652</view>
|
|||
|
<view class="stat-trend positive">
|
|||
|
<uni-icons type="arrowup" size="14"></uni-icons>
|
|||
|
<text>8.3%</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="stat-item">
|
|||
|
<view class="stat-label">游客总量</view>
|
|||
|
<view class="stat-value">35,962</view>
|
|||
|
<view class="stat-trend positive">
|
|||
|
<uni-icons type="arrowup" size="14"></uni-icons>
|
|||
|
<text>5.7%</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 主要内容区 -->
|
|||
|
<view class="con-box">
|
|||
|
<!-- 图表统计区域 -->
|
|||
|
<view class="charts-section">
|
|||
|
<!-- 折线图:本月门票销售量和销售额 -->
|
|||
|
<view class="chart-card">
|
|||
|
<view class="chart-header">
|
|||
|
<view class="chart-title">本月销售趋势</view>
|
|||
|
<view class="chart-filter">
|
|||
|
<text class="filter-item active">日</text>
|
|||
|
<text class="filter-item">周</text>
|
|||
|
<text class="filter-item">月</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="chart-container">
|
|||
|
<qiun-data-charts
|
|||
|
type="line"
|
|||
|
:chartData="ticketSalesData"
|
|||
|
:opts="lineChartOpts"
|
|||
|
:canvas2d="true"
|
|||
|
@chartClick="onChartClick"
|
|||
|
class="chart"
|
|||
|
/>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 柱状图:年度用水用电数据 -->
|
|||
|
<view class="chart-card">
|
|||
|
<view class="chart-header">
|
|||
|
<view class="chart-title">年度用水用电统计</view>
|
|||
|
<view class="chart-filter">
|
|||
|
<text class="filter-item active">年</text>
|
|||
|
<text class="filter-item">季</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="chart-container">
|
|||
|
<qiun-data-charts
|
|||
|
type="column"
|
|||
|
:chartData="waterElectricData"
|
|||
|
:opts="barChartOpts"
|
|||
|
:canvas2d="true"
|
|||
|
class="chart"
|
|||
|
/>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 饼图:收益占比 -->
|
|||
|
<view class="chart-card pie-chart-card">
|
|||
|
<view class="chart-header">
|
|||
|
<view class="chart-title">收益来源占比</view>
|
|||
|
<view class="chart-date">
|
|||
|
<text>2023年6月</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="chart-container pie-container">
|
|||
|
<qiun-data-charts
|
|||
|
type="pie"
|
|||
|
:chartData="revenueData"
|
|||
|
:opts="pieChartOpts"
|
|||
|
:canvas2d="true"
|
|||
|
class="chart pie-chart"
|
|||
|
@chartInit="onPieInit"
|
|||
|
/>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<tabbar name="video"></tabbar>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
import tabbar from '@/components/tabbar.vue'
|
|||
|
export default {
|
|||
|
components: { tabbar },
|
|||
|
data() {
|
|||
|
return {
|
|||
|
show: false,
|
|||
|
pieChart: null, // 饼图实例
|
|||
|
|
|||
|
// 折线图数据:本月门票销售量和销售额
|
|||
|
ticketSalesData: {
|
|||
|
categories: ['1日', '5日', '10日', '15日', '20日', '25日', '30日'],
|
|||
|
series: [
|
|||
|
{
|
|||
|
name: '销售量',
|
|||
|
data: [320, 450, 380, 520, 490, 680, 720],
|
|||
|
color: '#42b983'
|
|||
|
},
|
|||
|
{
|
|||
|
name: '销售额(万元)',
|
|||
|
data: [9.6, 13.5, 11.4, 15.6, 14.7, 20.4, 21.6],
|
|||
|
color: '#3498db'
|
|||
|
}
|
|||
|
]
|
|||
|
},
|
|||
|
|
|||
|
// 柱状图数据:年度用水用电数据
|
|||
|
waterElectricData: {
|
|||
|
categories: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
|||
|
series: [
|
|||
|
{
|
|||
|
name: '用水量(吨)',
|
|||
|
data: [3200, 2800, 3100, 3500, 4200, 5800, 6500, 6800, 5200, 4100, 3800, 3500],
|
|||
|
color: '#3498db'
|
|||
|
},
|
|||
|
{
|
|||
|
name: '用电量(度)',
|
|||
|
data: [5800, 5200, 5500, 6200, 7800, 9200, 10500, 11200, 8500, 6800, 6200, 5900],
|
|||
|
color: '#f1c40f'
|
|||
|
}
|
|||
|
]
|
|||
|
},
|
|||
|
|
|||
|
// 饼图数据:收益占比
|
|||
|
revenueData: {
|
|||
|
series: [
|
|||
|
{
|
|||
|
name: '门票',
|
|||
|
data: 45,
|
|||
|
color: '#42b983'
|
|||
|
},
|
|||
|
{
|
|||
|
name: '酒店',
|
|||
|
data: 30,
|
|||
|
color: '#3498db'
|
|||
|
},
|
|||
|
{
|
|||
|
name: '餐饮',
|
|||
|
data: 15,
|
|||
|
color: '#e67e22'
|
|||
|
},
|
|||
|
{
|
|||
|
name: '商城',
|
|||
|
data: 10,
|
|||
|
color: '#9b59b6'
|
|||
|
}
|
|||
|
]
|
|||
|
},
|
|||
|
|
|||
|
// 图表配置
|
|||
|
lineChartOpts: {
|
|||
|
color: ['#42b983', '#3498db'],
|
|||
|
padding: [15, 15, 0, 15],
|
|||
|
legend: {
|
|||
|
position: 'top',
|
|||
|
float: 'right',
|
|||
|
fontSize: 12
|
|||
|
},
|
|||
|
xAxis: {
|
|||
|
gridColor: '#eeeeee',
|
|||
|
labelCount: 7
|
|||
|
},
|
|||
|
yAxis: [
|
|||
|
{
|
|||
|
name: '销售量',
|
|||
|
gridColor: '#eeeeee',
|
|||
|
min: 0
|
|||
|
},
|
|||
|
{
|
|||
|
name: '销售额(万元)',
|
|||
|
gridColor: 'transparent',
|
|||
|
min: 0,
|
|||
|
position: 'right'
|
|||
|
}
|
|||
|
],
|
|||
|
extra: {
|
|||
|
line: {
|
|||
|
type: 'curve',
|
|||
|
width: 3,
|
|||
|
activeType: 'hollow',
|
|||
|
hollowRadius: 5,
|
|||
|
hollowColor: 'auto'
|
|||
|
}
|
|||
|
},
|
|||
|
animation: true,
|
|||
|
animationDuration: 1500
|
|||
|
},
|
|||
|
|
|||
|
barChartOpts: {
|
|||
|
color: ['#3498db', '#f1c40f'],
|
|||
|
padding: [15, 15, 0, 15],
|
|||
|
legend: {
|
|||
|
position: 'top',
|
|||
|
float: 'right',
|
|||
|
fontSize: 12
|
|||
|
},
|
|||
|
xAxis: {
|
|||
|
gridColor: '#eeeeee'
|
|||
|
},
|
|||
|
yAxis: {
|
|||
|
gridColor: '#eeeeee',
|
|||
|
min: 0
|
|||
|
},
|
|||
|
extra: {
|
|||
|
column: {
|
|||
|
width: 20,
|
|||
|
radius: [6, 6, 0, 0],
|
|||
|
// 添加柱子间隔
|
|||
|
space: 15
|
|||
|
}
|
|||
|
},
|
|||
|
animation: true,
|
|||
|
animationDuration: 1500,
|
|||
|
animationEasing: 'elasticOut'
|
|||
|
},
|
|||
|
|
|||
|
pieChartOpts: {
|
|||
|
color: ['#42b983', '#3498db', '#e67e22', '#9b59b6'],
|
|||
|
padding: [15, 15, 0, 15],
|
|||
|
legend: {
|
|||
|
position: 'right',
|
|||
|
float: 'right',
|
|||
|
itemGap: 20,
|
|||
|
fontSize: 14,
|
|||
|
itemWidth: 12,
|
|||
|
itemHeight: 12
|
|||
|
},
|
|||
|
extra: {
|
|||
|
pie: {
|
|||
|
labelWidth: 15,
|
|||
|
offsetAngle: 0,
|
|||
|
radius: 100,
|
|||
|
activeScale: 1.1,
|
|||
|
// 饼图动效配置
|
|||
|
labelLine: true,
|
|||
|
labelLineLength: 20,
|
|||
|
labelLineWidth: 1
|
|||
|
}
|
|||
|
},
|
|||
|
animation: true,
|
|||
|
animationDuration: 2000,
|
|||
|
animationEasing: 'cubicOut'
|
|||
|
}
|
|||
|
};
|
|||
|
},
|
|||
|
methods: {
|
|||
|
async scanCode () {
|
|||
|
let info = await this.$http.getInfo();
|
|||
|
// #ifdef APP-PLUS
|
|||
|
uni.navigateTo({ url: '/pages/scan/index' })
|
|||
|
// #endif
|
|||
|
// #ifdef MP-WEIXIN
|
|||
|
uni.scanCode({
|
|||
|
onlyFromCamera: true,
|
|||
|
success: async (res) => {
|
|||
|
uni.navigateTo({ url: `/pages/info/info?code=${res.result}`})
|
|||
|
}
|
|||
|
});
|
|||
|
// #endif
|
|||
|
},
|
|||
|
// 图表点击事件
|
|||
|
onChartClick(e) {
|
|||
|
console.log('图表点击', e);
|
|||
|
uni.showToast({
|
|||
|
title: `${e.name}: ${e.value}`,
|
|||
|
icon: 'none',
|
|||
|
duration: 2000
|
|||
|
});
|
|||
|
},
|
|||
|
// 饼图初始化完成
|
|||
|
onPieInit(chart) {
|
|||
|
this.pieChart = chart;
|
|||
|
|
|||
|
// 添加交互效果 - 鼠标悬停/点击时的动画
|
|||
|
chart.on('pointClick', (params) => {
|
|||
|
this.pieChart.updateOption({
|
|||
|
extra: {
|
|||
|
pie: {
|
|||
|
offsetAngle: params.dataIndex * (360 / this.revenueData.series.length)
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
});
|
|||
|
|
|||
|
// 自动旋转效果
|
|||
|
let angle = 0;
|
|||
|
setInterval(() => {
|
|||
|
angle += 1;
|
|||
|
if (angle >= 360) angle = 0;
|
|||
|
this.pieChart.updateOption({
|
|||
|
extra: {
|
|||
|
pie: {
|
|||
|
offsetAngle: angle
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}, 100);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss">
|
|||
|
page{
|
|||
|
height: 100%;
|
|||
|
background-color: #f5f7fa;
|
|||
|
}
|
|||
|
.waper{
|
|||
|
width: 100%;
|
|||
|
height: 100%;
|
|||
|
background: #f5f7fa;
|
|||
|
|
|||
|
.navbar_title{
|
|||
|
font-weight: 600;
|
|||
|
font-size: 36rpx;
|
|||
|
color: #FFFFFF;
|
|||
|
text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.2);
|
|||
|
}
|
|||
|
|
|||
|
.banner-box {
|
|||
|
position: relative;
|
|||
|
width: 100%;
|
|||
|
|
|||
|
.banner {
|
|||
|
width: 100%;
|
|||
|
height: auto;
|
|||
|
min-height: 220rpx;
|
|||
|
}
|
|||
|
|
|||
|
// 统计概览卡片
|
|||
|
.stats-overview {
|
|||
|
position: absolute;
|
|||
|
bottom: -60rpx;
|
|||
|
left: 0;
|
|||
|
width: 100%;
|
|||
|
display: flex;
|
|||
|
justify-content: space-around;
|
|||
|
padding: 0 30rpx;
|
|||
|
box-sizing: border-box;
|
|||
|
|
|||
|
.stat-item {
|
|||
|
width: 220rpx;
|
|||
|
height: 120rpx;
|
|||
|
background-color: #fff;
|
|||
|
border-radius: 16rpx;
|
|||
|
padding: 20rpx;
|
|||
|
box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.08);
|
|||
|
text-align: center;
|
|||
|
|
|||
|
.stat-label {
|
|||
|
font-size: 24rpx;
|
|||
|
color: #666;
|
|||
|
margin-bottom: 8rpx;
|
|||
|
}
|
|||
|
|
|||
|
.stat-value {
|
|||
|
font-size: 32rpx;
|
|||
|
font-weight: 600;
|
|||
|
color: #333;
|
|||
|
margin-bottom: 5rpx;
|
|||
|
}
|
|||
|
|
|||
|
.stat-trend {
|
|||
|
font-size: 22rpx;
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
justify-content: center;
|
|||
|
|
|||
|
&.positive {
|
|||
|
color: #42b983;
|
|||
|
}
|
|||
|
|
|||
|
&.negative {
|
|||
|
color: #f56c6c;
|
|||
|
}
|
|||
|
|
|||
|
text {
|
|||
|
margin-left: 5rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.con-box {
|
|||
|
position: relative;
|
|||
|
top: 20rpx;
|
|||
|
padding: 70rpx 30rpx 20rpx;
|
|||
|
background: transparent;
|
|||
|
}
|
|||
|
|
|||
|
.charts-section {
|
|||
|
width: 100%;
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
gap: 30rpx;
|
|||
|
}
|
|||
|
|
|||
|
// 图表卡片样式
|
|||
|
.chart-card {
|
|||
|
width: 100%;
|
|||
|
background-color: #fff;
|
|||
|
border-radius: 20rpx;
|
|||
|
padding: 30rpx;
|
|||
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
|||
|
transition: all 0.3s ease;
|
|||
|
|
|||
|
&:hover {
|
|||
|
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1);
|
|||
|
transform: translateY(-2rpx);
|
|||
|
}
|
|||
|
|
|||
|
.chart-header {
|
|||
|
display: flex;
|
|||
|
justify-content: space-between;
|
|||
|
align-items: center;
|
|||
|
margin-bottom: 25rpx;
|
|||
|
}
|
|||
|
|
|||
|
.chart-title {
|
|||
|
font-size: 30rpx;
|
|||
|
color: #333;
|
|||
|
font-weight: 600;
|
|||
|
position: relative;
|
|||
|
padding-left: 15rpx;
|
|||
|
|
|||
|
&::before {
|
|||
|
content: '';
|
|||
|
position: absolute;
|
|||
|
left: 0;
|
|||
|
top: 50%;
|
|||
|
transform: translateY(-50%);
|
|||
|
width: 6rpx;
|
|||
|
height: 24rpx;
|
|||
|
background-color: #3498db;
|
|||
|
border-radius: 3rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.chart-filter {
|
|||
|
display: flex;
|
|||
|
gap: 15rpx;
|
|||
|
|
|||
|
.filter-item {
|
|||
|
font-size: 24rpx;
|
|||
|
padding: 8rpx 18rpx;
|
|||
|
border-radius: 20rpx;
|
|||
|
color: #999;
|
|||
|
background-color: #f5f5f5;
|
|||
|
transition: all 0.2s ease;
|
|||
|
|
|||
|
&.active {
|
|||
|
color: #fff;
|
|||
|
background-color: #3498db;
|
|||
|
}
|
|||
|
|
|||
|
&:not(.active):hover {
|
|||
|
background-color: #eee;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.chart-date {
|
|||
|
font-size: 24rpx;
|
|||
|
color: #999;
|
|||
|
}
|
|||
|
|
|||
|
.chart-container {
|
|||
|
width: 100%;
|
|||
|
height: 360rpx;
|
|||
|
position: relative;
|
|||
|
}
|
|||
|
|
|||
|
.chart {
|
|||
|
width: 100%;
|
|||
|
height: 100%;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 饼图特殊样式
|
|||
|
.pie-chart-card {
|
|||
|
.pie-container {
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
height: 400rpx;
|
|||
|
}
|
|||
|
|
|||
|
.pie-chart {
|
|||
|
width: auto;
|
|||
|
height: 320rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|