349 lines
11 KiB
Vue
349 lines
11 KiB
Vue
<template>
|
|
<el-row :gutter="12" class="panel-group" v-loading="loading">
|
|
<el-col :xs="24" :sm="12" :lg="6" class="card-panel-col">
|
|
<div class="card-panel panel-device" @click="handleSetLineChartData('newVisitis')">
|
|
<div class="card-panel-description">
|
|
<div class="card-panel-text">
|
|
设备总数
|
|
</div>
|
|
<count-to :start-val="0" :end-val="briefData.deviceCount" :duration="2600" class="card-panel-num" />
|
|
<div class="card-panel-compare">
|
|
<div>
|
|
在线 <span class="up">{{briefData.onlineCount}} 台</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-panel-icon-wrapper">
|
|
<device-line-chart class-name="panel-chart" :data="deviceChartData" width="100%" height="100%"/>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="12" :lg="6" class="card-panel-col">
|
|
<div class="card-panel panel-yellow" @click="handleSetLineChartData('newVisitis')">
|
|
<div class="card-panel-description">
|
|
<div class="card-panel-text">
|
|
订单总数
|
|
</div>
|
|
<count-to :start-val="0" :end-val="briefData.rechargeCount" :duration="2600" class="card-panel-num" />
|
|
<div class="card-panel-compare">
|
|
<div>
|
|
今日<span class="up"> {{briefData.todayRechargeCount}} <svg-icon icon-class="up" /></span>
|
|
</div>
|
|
<div>
|
|
今日<span class="up"> {{briefData.todayRechargeCount}} <svg-icon icon-class="up" /></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-panel-icon-wrapper">
|
|
<small-line-chart class-name="panel-chart" :data="rechargeCountChartData" name="订单数量" color="#FFA830"/>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="12" :lg="6" class="card-panel-col">
|
|
<div class="card-panel panel-green" @click="handleSetLineChartData('newVisitis')">
|
|
<div class="card-panel-description">
|
|
<div class="card-panel-text">
|
|
订单金额
|
|
</div>
|
|
<count-to :start-val="0" :end-val="briefData.rechargeAmount" :duration="2600" class="card-panel-num" :decimals="2"/>
|
|
<div class="card-panel-compare">
|
|
今日
|
|
<span class="up">
|
|
{{briefData.todayRechargeAmount | money}}
|
|
<svg-icon icon-class="up" />
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="card-panel-icon-wrapper">
|
|
<small-line-chart class-name="panel-chart" :data="rechargeAmountChartData" name="订单金额" color="#2CAB40"/>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<!-- <el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">-->
|
|
<!-- <div class="card-panel panel-model" @click="handleSetLineChartData('messages')">-->
|
|
<!-- <div class="card-panel-description">-->
|
|
<!-- <div class="card-panel-text">-->
|
|
<!-- 月费收入-->
|
|
<!-- </div>-->
|
|
<!-- <count-to :start-val="0" :end-val="briefData.totalMonthAmount" :duration="3000" class="card-panel-num" :decimals="2"/>-->
|
|
<!-- <div class="card-panel-compare">-->
|
|
<!-- 今日-->
|
|
<!-- <span class="up">-->
|
|
<!-- {{briefData.todayMonthAmount | money}}-->
|
|
<!-- <svg-icon icon-class="up" />-->
|
|
<!-- </span>-->
|
|
<!-- </div>-->
|
|
<!-- </div>-->
|
|
<!-- <div class="card-panel-icon-wrapper">-->
|
|
<!-- <small-line-chart class-name="panel-chart" :data="monthAmountChartData" name="月费" color="#2CAB40"/>-->
|
|
<!-- </div>-->
|
|
<!-- </div>-->
|
|
<!-- </el-col>-->
|
|
<el-col :xs="24" :sm="12" :lg="6" class="card-panel-col">
|
|
<div class="card-panel panel-device" @click="handleSetLineChartData('purchases')">
|
|
<div class="card-panel-description">
|
|
<div class="card-panel-text">
|
|
用户余额
|
|
</div>
|
|
<count-to :start-val="0" :end-val="briefData.totalUserBalance" :duration="3200" class="card-panel-num" :decimals="2"/>
|
|
<div class="card-panel-compare">
|
|
较昨日
|
|
<span :class="compareBalance >= 0 ? 'up' : 'down'">
|
|
{{compareBalance | money}}
|
|
<svg-icon :icon-class="compareBalance >= 0 ? 'up' : 'down'" />
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="card-panel-icon-wrapper">
|
|
<small-line-chart class-name="panel-chart" :data="userBalanceChartData" name="用户余额"/>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<!-- <el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">-->
|
|
<!-- <div class="card-panel panel-user" @click="handleSetLineChartData('shoppings')">-->
|
|
<!-- <div class="card-panel-description">-->
|
|
<!-- <div class="card-panel-text">-->
|
|
<!-- 注册用户-->
|
|
<!-- </div>-->
|
|
<!-- <count-to :start-val="0" :end-val="briefData.userCount + briefData.tenantCount" :duration="3600" class="card-panel-num" />-->
|
|
<!-- <div class="card-panel-compare">-->
|
|
<!-- 今日-->
|
|
<!-- <span :class="compareUser >= 0 ? 'up' : 'down'">-->
|
|
<!-- {{compareUser}}-->
|
|
<!-- <svg-icon :icon-class="compareUser >= 0 ? 'up' : 'down'" />-->
|
|
<!-- </span>-->
|
|
<!-- </div>-->
|
|
<!-- </div>-->
|
|
<!-- <div class="card-panel-icon-wrapper">-->
|
|
<!-- <user-round-pie-chart class-name="panel-chart" :data="peopleChartData" width="100%" height="100%"/>-->
|
|
<!-- </div>-->
|
|
<!-- </div>-->
|
|
<!-- </el-col>-->
|
|
</el-row>
|
|
</template>
|
|
|
|
<script>
|
|
import CountTo from 'vue-count-to'
|
|
import {brief} from "@/api/system/dashboard";
|
|
import UserRoundPieChart from "@/views/dashboard/component/UserRoundPieChart.vue";
|
|
import {parseTime} from "@/utils/ruoyi";
|
|
import Device from "@/views/system/device/index.vue";
|
|
import DeviceLineChart from "@/views/dashboard/component/DeviceLineChart.vue";
|
|
import OnlineLineChart from "@/views/dashboard/component/OnlineLineChart.vue";
|
|
import ModelBarChart from "@/views/dashboard/component/ModelBarChart.vue";
|
|
import SmallLineChart from '@/views/dashboard/component/SmallLineChart.vue'
|
|
|
|
export default {
|
|
components: {
|
|
SmallLineChart,
|
|
ModelBarChart,
|
|
DeviceLineChart,
|
|
Device,
|
|
UserRoundPieChart,
|
|
CountTo,
|
|
OnlineLineChart
|
|
},
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
// 舆情分析数据
|
|
briefData: {
|
|
deviceCount: 0,
|
|
onlineCount: 0,
|
|
modelCount: 0,
|
|
userCount: 0,
|
|
tenantCount: 0,
|
|
history: [],
|
|
},
|
|
queryParams: {},
|
|
today: parseTime(new Date(), "{y}-{m}-{d}")
|
|
}
|
|
},
|
|
computed: {
|
|
// 昨日数据(最后一次历史数据)
|
|
yesterdayData() {
|
|
if (this.briefData == null || this.briefData.history == null) {
|
|
return null;
|
|
}
|
|
return this.briefData.history[this.briefData.history.length - 1];
|
|
},
|
|
// 订单数据
|
|
rechargeCountChartData() {
|
|
return this.parseToChart('rechargeCount', 'rechargeCount');
|
|
},
|
|
// 订单金额数据
|
|
rechargeAmountChartData() {
|
|
return this.parseToChart('rechargeAmount', 'totalRecharge', 2);
|
|
},
|
|
// 月费数据
|
|
monthAmountChartData() {
|
|
return this.parseToChart('totalMonthAmount', 'totalMonth', 2);
|
|
},
|
|
// 用户余额数据
|
|
userBalanceChartData() {
|
|
return this.parseToChart('totalUserBalance', 'userBalance', 2);
|
|
},
|
|
// 设备数据
|
|
deviceChartData() {
|
|
return this.parseToChart('deviceCount', 'totalDevice');
|
|
},
|
|
// 用户图表数据
|
|
peopleChartData() {
|
|
if (this.briefData == null) {
|
|
return []
|
|
}
|
|
return [
|
|
{value: this.briefData.userCount, name: "商户"},
|
|
{value: this.briefData.tenantCount, name: "用户"}
|
|
]
|
|
},
|
|
// 用户差值
|
|
compareUser() {
|
|
if (this.briefData == null) {
|
|
return 0;
|
|
}
|
|
if (this.yesterdayData == null) {
|
|
return this.briefData.userCount + this.briefData.tenantCount;
|
|
}
|
|
return this.briefData.userCount + this.briefData.tenantCount - this.yesterdayData.totalUser;
|
|
},
|
|
// 余额差值
|
|
compareBalance() {
|
|
if (this.briefData == null) {
|
|
return 0;
|
|
}
|
|
if (this.yesterdayData == null) {
|
|
return this.briefData.totalUserBalance;
|
|
}
|
|
return this.briefData.totalUserBalance - this.yesterdayData.userBalance;
|
|
},
|
|
},
|
|
created() {
|
|
this.getBriefData();
|
|
},
|
|
methods: {
|
|
parseToChart(currentProp, historyProp, fixed = 0) {
|
|
if (this.briefData == null) {
|
|
return []
|
|
}
|
|
let list = this.briefData?.history?.map(item => {
|
|
return {
|
|
x: item.createDate,
|
|
value: item[historyProp]?.toFixed(fixed)
|
|
}
|
|
});
|
|
list.push({
|
|
x: this.today,
|
|
value: this.briefData[currentProp]?.toFixed(fixed)
|
|
})
|
|
return list;
|
|
},
|
|
handleSetLineChartData(type) {
|
|
this.$emit('handleSetLineChartData', type)
|
|
},
|
|
// 获取舆情分析数据
|
|
getBriefData() {
|
|
this.loading = true;
|
|
brief(this.queryParams).then(response => {
|
|
this.briefData = response.data;
|
|
}).finally(() => {
|
|
this.loading = false;
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.panel-group {
|
|
margin-top: 18px;
|
|
|
|
.card-panel {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
height: 134px;
|
|
cursor: pointer;
|
|
font-size: 12px;
|
|
position: relative;
|
|
color: #666;
|
|
background: #fff;
|
|
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
|
|
border-color: rgba(0, 0, 0, .05);
|
|
|
|
.card-panel-icon-wrapper {
|
|
position: relative;
|
|
height: 100%;
|
|
flex: 1;
|
|
padding: 44px 16px 20px 10px;
|
|
|
|
.panel-chart {
|
|
float: right;
|
|
}
|
|
}
|
|
|
|
.card-panel-description {
|
|
font-weight: 700;
|
|
width: fit-content;
|
|
min-width: 10em;
|
|
padding: 20px 0 16px 20px;
|
|
|
|
.card-panel-text {
|
|
line-height: 24px;
|
|
color: #1D252F;
|
|
font-size: 16px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.card-panel-num {
|
|
font-size: 24px;
|
|
line-height: 26px;
|
|
color: #1D2129;
|
|
}
|
|
|
|
.card-panel-compare {
|
|
position: absolute;
|
|
bottom: 16px;
|
|
font-size: 12px;
|
|
line-height: 20px;
|
|
color: #4E5969;
|
|
width: fit-content;
|
|
|
|
.up {
|
|
color: #F53F3F;
|
|
font-size: 14px;
|
|
}
|
|
.down {
|
|
color: #00B42A;
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.panel-user {
|
|
background: linear-gradient(180deg, #F6F7FF -3%, #ECECFF 100%);
|
|
}
|
|
.panel-online {
|
|
background: linear-gradient(180deg, #F2F9FE -3%, #E6F4FE 100%);
|
|
}
|
|
.panel-green {
|
|
background: linear-gradient(180deg, #F5FEF2 -3%, #E6FEEE 100%);
|
|
}
|
|
.panel-device {
|
|
background: linear-gradient(180deg, #F2F9FE -3%, #E6F4FE 100%);
|
|
}
|
|
.panel-yellow {
|
|
background: linear-gradient(180deg, #fefaf2 -3%, #fef4e6 100%);
|
|
}
|
|
.panel-red {
|
|
background: linear-gradient(180deg, #fef2f7 -3%, #ffeef1 100%);
|
|
}
|
|
|
|
}
|
|
|
|
@media (max-width:400px) {
|
|
.card-panel-icon-wrapper {
|
|
display: none;
|
|
}
|
|
}
|
|
</style>
|