首页报表更新
This commit is contained in:
parent
4d0a9085ac
commit
2dacef722a
|
@ -36,4 +36,13 @@ export function getTodoList() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取服务费、月费等收入和渠道成本
|
||||||
|
export function getServiceIncome(params) {
|
||||||
|
return request({
|
||||||
|
url: '/system/dashboard/serviceIncome',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -460,3 +460,60 @@ export function findLabel(options, value, prop = 'value', propLabel = 'label') {
|
||||||
let obj = options.find(item => item[prop] === value);
|
let obj = options.find(item => item[prop] === value);
|
||||||
return obj == null ? null : obj[propLabel]
|
return obj == null ? null : obj[propLabel]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取前n天的日期
|
||||||
|
export function getLastDate(n) {
|
||||||
|
let now = new Date();
|
||||||
|
return new Date(now.getTime() - n * 24 * 3600 * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取前n月的日期
|
||||||
|
export function getLastMonth(n) {
|
||||||
|
const date = new Date();
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = date.getMonth();
|
||||||
|
const day = date.getDate();
|
||||||
|
|
||||||
|
// 减去 n 个月
|
||||||
|
date.setMonth(month - n);
|
||||||
|
|
||||||
|
// 确保日期不超过当月的最大天数
|
||||||
|
const maxDay = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
||||||
|
date.setDate(Math.min(day, maxDay));
|
||||||
|
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取前n月的日期字符串
|
||||||
|
export function getLastMonthDateStr(n) {
|
||||||
|
let date = getLastMonth(n);
|
||||||
|
return parseTime(date, "{y}-{m}-{d}")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取前n天的日期字符串
|
||||||
|
export function getLastDateStr(n) {
|
||||||
|
let date = getLastDate(n);
|
||||||
|
return parseTime(date, "{y}-{m}-{d}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取前n天的日期时间字符串00:00:00
|
||||||
|
export function getLastDateTimeStartStr(n) {
|
||||||
|
let date = getLastDate(n);
|
||||||
|
return parseTime(date, "{y}-{m}-{d} 00:00:00");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取前n天的日期时间字符串23:59:59
|
||||||
|
export function getLastDateTimeEndStr(n) {
|
||||||
|
let date = getLastDate(n);
|
||||||
|
return parseTime(date, "{y}-{m}-{d} 23:59:59");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取前n天的日期时间00:00:00
|
||||||
|
export function getLastDateTimeStart(n) {
|
||||||
|
return new Date(getLastDateTimeStartStr(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取前n天的日期时间23:59:59
|
||||||
|
export function getLastDateTimeEnd(n) {
|
||||||
|
return new Date(getLastDateTimeEndStr(n));
|
||||||
|
}
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
<template>
|
<template>
|
||||||
<el-row :gutter="12" class="panel-group" v-loading="loading">
|
<el-row :gutter="12" class="panel-group" v-loading="loading">
|
||||||
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
||||||
<div class="card-panel panel-device" @click="handleSetLineChartData('newVisitis')">
|
<div class="card-panel panel-device">
|
||||||
<div class="card-panel-description">
|
<div class="card-panel-description">
|
||||||
<div class="card-panel-text">
|
<div class="card-panel-text">
|
||||||
设备总数
|
设备总数
|
||||||
</div>
|
</div>
|
||||||
<count-to :start-val="0" :end-val="briefData.deviceCount" :duration="2600" class="card-panel-num" />
|
<count-to :start-val="0" :end-val="briefData.totalDeviceCount" :duration="2600" class="card-panel-num" />
|
||||||
<div class="card-panel-compare">
|
<div class="card-panel-compare">
|
||||||
在线
|
在线
|
||||||
<span class="up">
|
<span class="up">
|
||||||
{{briefData.onlineCount}} 台
|
{{briefData.totalOnlineCount}} 台
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-panel-icon-wrapper">
|
<div class="card-panel-icon-wrapper">
|
||||||
<device-line-chart class-name="panel-chart" :data="deviceChartData" width="100%" height="100%"/>
|
<small-line-chart class-name="panel-chart" :data="totalDeviceChartData" name="设备数量" color="#165DFF" type="bar" y-axis-min="0"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
||||||
<div class="card-panel panel-yellow" @click="handleSetLineChartData('newVisitis')">
|
<div class="card-panel panel-model">
|
||||||
<div class="card-panel-description">
|
<div class="card-panel-description">
|
||||||
<div class="card-panel-text">
|
<div class="card-panel-text">
|
||||||
订单总数
|
订单总数
|
||||||
|
@ -35,72 +35,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-panel-icon-wrapper">
|
<div class="card-panel-icon-wrapper">
|
||||||
<small-line-chart class-name="panel-chart" :data="rechargeCountChartData" name="订单数量" color="#FFA830"/>
|
<small-line-chart class-name="panel-chart" :data="rechargeCountChartData" name="日订单数量" color="#2CAB40"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
||||||
<div class="card-panel panel-yellow" @click="handleSetLineChartData('newVisitis')">
|
<div class="card-panel panel-user">
|
||||||
<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="#FFA830"/>
|
|
||||||
</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="8" 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-description">
|
||||||
<div class="card-panel-text">
|
<div class="card-panel-text">
|
||||||
注册用户
|
注册用户
|
||||||
|
@ -119,6 +59,65 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
||||||
|
<div class="card-panel panel-device" >
|
||||||
|
<div class="card-panel-description">
|
||||||
|
<div class="card-panel-text">
|
||||||
|
用户设备数
|
||||||
|
</div>
|
||||||
|
<count-to :start-val="0" :end-val="briefData.deviceCount" :duration="3000" class="card-panel-num" :decimals="0"/>
|
||||||
|
<div class="card-panel-compare">
|
||||||
|
在线
|
||||||
|
<span class="up">
|
||||||
|
{{briefData.onlineCount | defaultValue}} 台
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-panel-icon-wrapper">
|
||||||
|
<small-line-chart class-name="panel-chart" :data="deviceChartData" name="设备数量" color="#165DFF" type="bar" y-axis-min="0"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
||||||
|
<div class="card-panel panel-model">
|
||||||
|
<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-user">
|
||||||
|
<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="商户余额" color="#8D4EDA"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -169,11 +168,11 @@ export default {
|
||||||
},
|
},
|
||||||
// 订单数据
|
// 订单数据
|
||||||
rechargeCountChartData() {
|
rechargeCountChartData() {
|
||||||
return this.parseToChart('rechargeCount', 'rechargeCount');
|
return this.parseToChart('todayRechargeCount', 'todayRechargeCount');
|
||||||
},
|
},
|
||||||
// 订单金额数据
|
// 订单金额数据
|
||||||
rechargeAmountChartData() {
|
rechargeAmountChartData() {
|
||||||
return this.parseToChart('rechargeAmount', 'totalRecharge', 2);
|
return this.parseToChart('todayRechargeAmount', 'todayRechargeAmount', 2);
|
||||||
},
|
},
|
||||||
// 月费数据
|
// 月费数据
|
||||||
monthAmountChartData() {
|
monthAmountChartData() {
|
||||||
|
@ -183,10 +182,14 @@ export default {
|
||||||
userBalanceChartData() {
|
userBalanceChartData() {
|
||||||
return this.parseToChart('totalUserBalance', 'userBalance', 2);
|
return this.parseToChart('totalUserBalance', 'userBalance', 2);
|
||||||
},
|
},
|
||||||
// 设备数据
|
// 用户设备数据
|
||||||
deviceChartData() {
|
deviceChartData() {
|
||||||
return this.parseToChart('deviceCount', 'totalDevice');
|
return this.parseToChart('deviceCount', 'totalDevice');
|
||||||
},
|
},
|
||||||
|
// 总设备数据
|
||||||
|
totalDeviceChartData() {
|
||||||
|
return this.parseToChart('totalDeviceCount', 'deviceCount');
|
||||||
|
},
|
||||||
// 用户图表数据
|
// 用户图表数据
|
||||||
peopleChartData() {
|
peopleChartData() {
|
||||||
if (this.briefData == null) {
|
if (this.briefData == null) {
|
||||||
|
@ -222,6 +225,7 @@ export default {
|
||||||
this.getBriefData();
|
this.getBriefData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 转换为图表
|
||||||
parseToChart(currentProp, historyProp, fixed = 0) {
|
parseToChart(currentProp, historyProp, fixed = 0) {
|
||||||
if (this.briefData == null) {
|
if (this.briefData == null) {
|
||||||
return []
|
return []
|
||||||
|
@ -238,9 +242,6 @@ export default {
|
||||||
})
|
})
|
||||||
return list;
|
return list;
|
||||||
},
|
},
|
||||||
handleSetLineChartData(type) {
|
|
||||||
this.$emit('handleSetLineChartData', type)
|
|
||||||
},
|
|
||||||
// 获取舆情分析数据
|
// 获取舆情分析数据
|
||||||
getBriefData() {
|
getBriefData() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
require('echarts/theme/macarons') // echarts theme
|
require('echarts/theme/macarons') // echarts theme
|
||||||
import resize from './mixins/resize'
|
import resize from './mixins/resize'
|
||||||
import {getTimeArray} from "@/utils";
|
import { getTimeArray } from '@/utils'
|
||||||
import {hourBillCount} from "@/api/system/dashboard";
|
|
||||||
import {parseTime} from "@/utils/ruoyi";
|
|
||||||
|
|
||||||
const animationDuration = 6000
|
const animationDuration = 6000
|
||||||
|
|
||||||
|
@ -27,23 +25,24 @@ export default {
|
||||||
height: {
|
height: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '300px'
|
default: '300px'
|
||||||
|
},
|
||||||
|
billData: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
chart: null,
|
chart: null,
|
||||||
billData: [], // 记录统计数据
|
|
||||||
// x轴配置
|
// x轴配置
|
||||||
x: {
|
x: {
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 22,
|
end: 22,
|
||||||
step: 2
|
step: 2
|
||||||
},
|
},
|
||||||
// 查询条件
|
|
||||||
queryParams: {
|
|
||||||
createDate: parseTime(new Date(), "{y}-{m}-{d}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -56,9 +55,6 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
this.getBillList();
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.initChart()
|
this.initChart()
|
||||||
|
@ -84,19 +80,10 @@ export default {
|
||||||
data.filter(item => item.createHour >= i && item.createHour < i + this.x.step).forEach(item => {
|
data.filter(item => item.createHour >= i && item.createHour < i + this.x.step).forEach(item => {
|
||||||
sum += item[key] == null ? 0 : item[key];
|
sum += item[key] == null ? 0 : item[key];
|
||||||
})
|
})
|
||||||
list.push(sum);
|
list.push(sum.toFixed(2));
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
},
|
},
|
||||||
// 获取分时记录统计
|
|
||||||
getBillList() {
|
|
||||||
this.loading = true;
|
|
||||||
hourBillCount(this.queryParams).then(res => {
|
|
||||||
this.billData = res.data;
|
|
||||||
}).finally(() => {
|
|
||||||
this.loading = false;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 初始化图表
|
// 初始化图表
|
||||||
initChart() {
|
initChart() {
|
||||||
this.chart = echarts.init(this.$el, 'macarons')
|
this.chart = echarts.init(this.$el, 'macarons')
|
||||||
|
@ -132,7 +119,7 @@ export default {
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
series: [{
|
series: [{
|
||||||
name: '充值',
|
name: '充值(元)',
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
stack: 'vistors',
|
stack: 'vistors',
|
||||||
barWidth: '30%',
|
barWidth: '30%',
|
||||||
|
@ -144,7 +131,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
name: '提现',
|
name: '提现(元)',
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
stack: 'vistors',
|
stack: 'vistors',
|
||||||
barWidth: '30%',
|
barWidth: '30%',
|
||||||
|
|
49
src/views/dashboard/DailyHourBillChart.vue
Normal file
49
src/views/dashboard/DailyHourBillChart.vue
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-row style="margin-bottom: 16px">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createDate"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
type="date"
|
||||||
|
:clearable="false"
|
||||||
|
@change="getBillList"
|
||||||
|
/>
|
||||||
|
</el-row>
|
||||||
|
<daily-bill-report :bill-data="billData" width="100%" height="250px"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getLastDateStr } from '@/utils'
|
||||||
|
import { hourBillCount } from '@/api/system/dashboard'
|
||||||
|
import DailyBillReport from '@/views/dashboard/DailyBillReport.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DailyHourBillChart',
|
||||||
|
components: { DailyBillReport },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 查询条件
|
||||||
|
queryParams: {
|
||||||
|
createDate: getLastDateStr(0)
|
||||||
|
},
|
||||||
|
billData: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 获取分时记录统计
|
||||||
|
getBillList() {
|
||||||
|
this.loading = true;
|
||||||
|
hourBillCount(this.queryParams).then(res => {
|
||||||
|
this.billData = res.data;
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
|
@ -27,23 +27,24 @@ export default {
|
||||||
height: {
|
height: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '300px'
|
default: '300px'
|
||||||
|
},
|
||||||
|
billData: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
chart: null,
|
chart: null,
|
||||||
billData: [], // 记录统计数据
|
|
||||||
// x轴配置
|
// x轴配置
|
||||||
x: {
|
x: {
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 22,
|
end: 22,
|
||||||
step: 2
|
step: 2
|
||||||
},
|
},
|
||||||
// 查询条件
|
|
||||||
queryParams: {
|
|
||||||
createDate: parseTime(new Date(), "{y}-{m}-{d}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -56,9 +57,6 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
this.getBillList();
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.initChart()
|
this.initChart()
|
||||||
|
@ -72,30 +70,12 @@ export default {
|
||||||
this.chart = null
|
this.chart = null
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 获取分时数据
|
// 获取图表数据
|
||||||
getHourData(data, key) {
|
getChartData(data, key) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
// 将数据分组求和
|
return data.map(item => item[key]);
|
||||||
let list = [];
|
|
||||||
for(let i = this.x.start; i <= this.x.end; i += this.x.step) {
|
|
||||||
let sum = 0;
|
|
||||||
data.filter(item => item.createHour >= i && item.createHour < i + this.x.step).forEach(item => {
|
|
||||||
sum += item[key] == null ? 0 : item[key];
|
|
||||||
})
|
|
||||||
list.push(sum);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
},
|
|
||||||
// 获取分时记录统计
|
|
||||||
getBillList() {
|
|
||||||
this.loading = true;
|
|
||||||
hourBillCount(this.queryParams).then(res => {
|
|
||||||
this.billData = res.data;
|
|
||||||
}).finally(() => {
|
|
||||||
this.loading = false;
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
// 初始化图表
|
// 初始化图表
|
||||||
initChart() {
|
initChart() {
|
||||||
|
@ -120,60 +100,52 @@ export default {
|
||||||
},
|
},
|
||||||
xAxis: [{
|
xAxis: [{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
data: getTimeArray(this.x.start, this.x.end, this.x.step),
|
data: this.getChartData(this.billData, 'date'),
|
||||||
axisTick: {
|
axisTick: {
|
||||||
alignWithLabel: true
|
alignWithLabel: true
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
yAxis: [{
|
yAxis:{
|
||||||
type: 'value',
|
type: 'value',
|
||||||
axisTick: {
|
axisTick: {
|
||||||
show: false
|
show: false
|
||||||
}
|
}
|
||||||
}, {
|
},
|
||||||
name: '充值',
|
|
||||||
show: true
|
|
||||||
}],
|
|
||||||
series: [{
|
series: [{
|
||||||
name: '利润',
|
name: '月费收入(元)',
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
stack: 'vistors',
|
stack: 'vistors',
|
||||||
barWidth: '30%',
|
barWidth: '50%',
|
||||||
yAxisIndex: 0,
|
data: this.getChartData(this.billData, 'monthAmount'),
|
||||||
data: this.getHourData(this.billData, 'profit'),
|
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
normal: {
|
normal: {
|
||||||
color: '#246EFF',
|
color: '#246EFF',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
name: '成本',
|
name: '服务费收入(元)',
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
stack: 'vistors',
|
stack: 'vistors',
|
||||||
barWidth: '30%',
|
barWidth: '50%',
|
||||||
yAxisIndex: 0,
|
data: this.getChartData(this.billData, 'serviceAmount'),
|
||||||
data: this.getHourData(this.billData, 'channelCost'),
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
color: '#81E2FF',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
name: '充值',
|
|
||||||
type: 'line',
|
|
||||||
stack: 'vistors',
|
|
||||||
barWidth: '30%',
|
|
||||||
yAxisIndex: 1,
|
|
||||||
data: this.getHourData(this.billData, 'recharge'),
|
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
normal: {
|
normal: {
|
||||||
color: '#313CA9',
|
color: '#313CA9',
|
||||||
lineStyle: {
|
|
||||||
type: 'dashed'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}]
|
},{
|
||||||
|
name: '渠道成本(元)',
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: '50%',
|
||||||
|
stack: 'vistors',
|
||||||
|
data: this.getChartData(this.billData, 'channelCost'),
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#68bfe4',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
91
src/views/dashboard/ServiceIncomeChart.vue
Normal file
91
src/views/dashboard/ServiceIncomeChart.vue
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-row style="margin-bottom: 16px">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
type="daterange"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
@change="getData"
|
||||||
|
:picker-options="pickerOptions"
|
||||||
|
/>
|
||||||
|
</el-row>
|
||||||
|
<daily-profit-report :bill-data="billData" width="100%" height="250px"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import DailyProfitReport from '@/views/dashboard/DailyProfitReport.vue'
|
||||||
|
import { getServiceIncome } from '@/api/system/dashboard'
|
||||||
|
import { getLastDate, getLastDateStr, getLastMonth } from '@/utils'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ServiceIncomeChart',
|
||||||
|
components: { DailyProfitReport },
|
||||||
|
computed: {
|
||||||
|
dateRange: {
|
||||||
|
get() {
|
||||||
|
return [this.queryParams.startDate, this.queryParams.endDate];
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.queryParams.startDate = val[0];
|
||||||
|
this.queryParams.endDate = val[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
billData: [],
|
||||||
|
queryParams: {
|
||||||
|
startDate: getLastDateStr(6),
|
||||||
|
endDate: getLastDateStr(0),
|
||||||
|
},
|
||||||
|
pickerOptions: {
|
||||||
|
shortcuts: [{
|
||||||
|
text: '最近一周',
|
||||||
|
onClick(picker) {
|
||||||
|
const end = getLastDate(0);
|
||||||
|
const start = getLastDate(6);
|
||||||
|
picker.$emit('pick', [start, end]);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: '最近一个月',
|
||||||
|
onClick(picker) {
|
||||||
|
const end = getLastDate(0);
|
||||||
|
const start = getLastMonth(1);
|
||||||
|
picker.$emit('pick', [start, end]);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: '最近三个月',
|
||||||
|
onClick(picker) {
|
||||||
|
const end = getLastDate(0);
|
||||||
|
const start = getLastMonth(3);
|
||||||
|
picker.$emit('pick', [start, end]);
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getData() {
|
||||||
|
this.loading = true;
|
||||||
|
getServiceIncome(this.queryParams).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.billData = res.data;
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
|
@ -37,6 +37,14 @@ export default {
|
||||||
color: {
|
color: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '#165DFF'
|
default: '#165DFF'
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'line'
|
||||||
|
},
|
||||||
|
yAxisMin: {
|
||||||
|
type: String,
|
||||||
|
default: 'dataMin'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -91,14 +99,14 @@ export default {
|
||||||
yAxis: {
|
yAxis: {
|
||||||
show: false,
|
show: false,
|
||||||
type: 'value',
|
type: 'value',
|
||||||
min: 'dataMin',
|
min: this.yAxisMin,
|
||||||
max: 'dataMax',
|
max: 'dataMax',
|
||||||
},
|
},
|
||||||
series: [{
|
series: [{
|
||||||
name: this.name,
|
name: this.name,
|
||||||
color: this.color,
|
color: this.color,
|
||||||
data: data.map(item => item.value),
|
data: data.map(item => item.value),
|
||||||
type: 'line',
|
type: this.type,
|
||||||
smooth: true
|
smooth: true
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="todo-list" v-loading="loading">
|
<div class="todo-list" v-loading="loading">
|
||||||
<div class="todo-item" @click="$router.push('/mch/mchApply?status=0')">
|
<div class="todo-item" @click="$router.push('/mch/mchApply?status=0')">
|
||||||
<div class="label"><svg-icon icon-class="apply"/> 商家合作申请</div>
|
<div class="label"><svg-icon icon-class="apply"/> 商家加盟</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<count-to :start-val="0" :end-val="data.mchApplyCount" :duration="3000"/>
|
<count-to :start-val="0" :end-val="data.mchApplyCount" :duration="3000"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="unit">条</div>
|
<div class="unit">条</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="todo-item" @click="$router.push('/mch/storeApply?status=1')">
|
|
||||||
<div class="label"><svg-icon icon-class="store"/> 店铺审核</div>
|
|
||||||
<div class="value">
|
|
||||||
<count-to :start-val="0" :end-val="data.storeApplyCount" :duration="3000"/>
|
|
||||||
</div>
|
|
||||||
<div class="unit">条</div>
|
|
||||||
</div>
|
|
||||||
<div class="todo-item" @click="$router.push('/money/withdraw?status=11')">
|
<div class="todo-item" @click="$router.push('/money/withdraw?status=11')">
|
||||||
<div class="label"><svg-icon icon-class="withdraw"/> 提现申请</div>
|
<div class="label"><svg-icon icon-class="withdraw"/> 提现申请</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
|
@ -22,14 +15,21 @@
|
||||||
<div class="unit">条</div>
|
<div class="unit">条</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="todo-item" @click="$router.push('/smDevice/device?isArrears=1')">
|
<div class="todo-item" @click="$router.push('/smDevice/device?isArrears=1')">
|
||||||
<div class="label"><svg-icon icon-class="monitor"/> 设备到期</div>
|
<div class="label"><svg-icon icon-class="monitor"/> 到期设备</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<count-to :start-val="0" :end-val="data.arrearsDeviceCount" :duration="3000"/>
|
<count-to :start-val="0" :end-val="data.arrearsDeviceCount" :duration="3000"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="unit">台</div>
|
<div class="unit">台</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="todo-item" @click="$router.push('/mch/storeApply?status=1')">
|
||||||
|
<div class="label"><svg-icon icon-class="store"/> 店铺审核</div>
|
||||||
|
<div class="value">
|
||||||
|
<count-to :start-val="0" :end-val="data.storeApplyCount" :duration="3000"/>
|
||||||
|
</div>
|
||||||
|
<div class="unit">条</div>
|
||||||
|
</div>
|
||||||
<div class="todo-item" @click="$router.push('/complaint/abnormal?status=1')">
|
<div class="todo-item" @click="$router.push('/complaint/abnormal?status=1')">
|
||||||
<div class="label"><svg-icon icon-class="bug"/> 设备故障</div>
|
<div class="label"><svg-icon icon-class="bug"/> 待处理故障信息</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<count-to :start-val="0" :end-val="data.abnormalCount" :duration="3000"/>
|
<count-to :start-val="0" :end-val="data.abnormalCount" :duration="3000"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,12 +16,12 @@
|
||||||
<el-row :gutter="8">
|
<el-row :gutter="8">
|
||||||
<el-col :lg="12" :xs="24">
|
<el-col :lg="12" :xs="24">
|
||||||
<el-card header="每日充值提现" class="card-box">
|
<el-card header="每日充值提现" class="card-box">
|
||||||
<daily-bill-report />
|
<daily-hour-bill-chart/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :lg="12" :xs="24">
|
<el-col :lg="12" :xs="24">
|
||||||
<el-card header="每日充值利润" class="card-box">
|
<el-card header="收入及成本" class="card-box">
|
||||||
<daily-profit-report />
|
<service-income-chart/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -38,10 +38,12 @@ import TodoList from '@/views/dashboard/component/TodoList.vue'
|
||||||
import DailyProfitReport from '@/views/dashboard/DailyProfitReport.vue'
|
import DailyProfitReport from '@/views/dashboard/DailyProfitReport.vue'
|
||||||
import BalancePeriodReport from '@/views/dashboard/BalancePeriodReport.vue'
|
import BalancePeriodReport from '@/views/dashboard/BalancePeriodReport.vue'
|
||||||
import Brief from '@/views/dashboard/Brief.vue'
|
import Brief from '@/views/dashboard/Brief.vue'
|
||||||
|
import DailyHourBillChart from '@/views/dashboard/DailyHourBillChart.vue'
|
||||||
|
import ServiceIncomeChart from '@/views/dashboard/ServiceIncomeChart.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AdminIndex',
|
name: 'AdminIndex',
|
||||||
components: { Brief, BalancePeriodReport, DailyProfitReport, TodoList, DailyBillReport }
|
components: { ServiceIncomeChart, DailyHourBillChart, Brief, BalancePeriodReport, DailyProfitReport, TodoList, DailyBillReport }
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user