修改:统计

Signed-off-by: skyselang <215817969@qq.com>
This commit is contained in:
skyselang 2022-05-19 17:56:28 +08:00
parent dcdf16411b
commit ea63d84a89
8 changed files with 924 additions and 930 deletions

View File

@ -13,7 +13,7 @@
"axios": "0.26.0",
"clipboard": "2.0.10",
"core-js": "3.21.1",
"echarts": "5.3.0",
"echarts": "5.3.2",
"element-ui": "2.15.7",
"fuse.js": "3.6.1",
"js-cookie": "3.0.1",

View File

@ -47,12 +47,12 @@ export function clear(data) {
}
/**
* 会员日志统计
* @param {array} data 请求数据
* @param {array} params 请求参数
*/
export function stat(data) {
export function stat(params) {
return request({
url: url + 'stat',
method: 'post',
data
method: 'get',
params: params
})
}

View File

@ -0,0 +1,111 @@
<template>
<transition :name="transitionName">
<div v-show="visible" :style="customStyle" class="back-to-ceiling" @click="backToTop">
<i class="el-icon-top" />
</div>
</transition>
</template>
<script>
export default {
name: 'BackToTop',
props: {
visibilityHeight: {
type: Number,
default: 200
},
backPosition: {
type: Number,
default: 0
},
customStyle: {
type: Object,
default: function() {
return {
right: '50px',
bottom: '50px',
width: '40px',
height: '40px',
'border-radius': '4px',
'line-height': '45px',
background: '#e7eaf1'
}
}
},
transitionName: {
type: String,
default: 'fade'
}
},
data() {
return {
visible: false,
interval: null,
isMoving: false
}
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
if (this.interval) {
clearInterval(this.interval)
}
},
methods: {
handleScroll() {
this.visible = window.pageYOffset > this.visibilityHeight
},
backToTop() {
if (this.isMoving) return
const start = window.pageYOffset
let i = 0
this.isMoving = true
this.interval = setInterval(() => {
const next = Math.floor(this.easeInOutQuad(10 * i, start, -start, 500))
if (next <= this.backPosition) {
window.scrollTo(0, this.backPosition)
clearInterval(this.interval)
this.isMoving = false
} else {
window.scrollTo(0, next)
}
i++
}, 16.7)
},
easeInOutQuad(t, b, c, d) {
if ((t /= d / 2) < 1) return (c / 2) * t * t + b
return (-c / 2) * (--t * (t - 2) - 1) + b
}
}
}
</script>
<style scoped>
.back-to-ceiling {
position: fixed;
display: inline-block;
text-align: center;
cursor: pointer;
}
.back-to-ceiling:hover {
background: #d5dbe7;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.back-to-ceiling .Icon {
fill: #9aaabf;
background: none;
}
</style>

View File

@ -1,146 +1,94 @@
<template>
<div class="app-container dialog-body" :style="{height:height+'px'}">
<el-card v-loading="loading" class="box-card">
<el-row :gutter="10">
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>总计</span>
</div>
<div class="text color-tot">
{{ num.total }}
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>今天</span>
</div>
<div class="text">
{{ num.today }}
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>昨天</span>
</div>
<div class="text">
{{ num.yesterday }}
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>本周</span>
</div>
<div class="text">
{{ num.thisweek }}
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>上周</span>
</div>
<div class="text">
{{ num.lastweek }}
</div>
</el-card>
</el-col>
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>本月</span>
</div>
<div class="text">
{{ num.thismonth }}
</div>
</el-card>
</el-col>
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>上月</span>
</div>
<div class="text">
{{ num.lastmonth }}
</div>
</el-card>
</el-col>
</el-row>
</el-card>
<el-card v-loading="loading" class="box-card ya-margin-top">
<el-row>
<el-col>
<el-date-picker
v-model="date.date"
type="daterange"
value-format="yyyy-MM-dd"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="echartUserDateChange()"
/>
</el-col>
</el-row>
<el-row>
<el-col>
<div id="echartUserDate" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
<el-card class="box-card ya-margin-top" :body-style="cardBodyStyle">
<el-row>
<el-col>
<el-date-picker
v-model="field.date"
type="daterange"
range-separator="-"
value-format="yyyy-MM-dd"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="echartFieldChange()"
/>
<el-select v-model="fieldValue" placeholder="请选择" @change="echartFieldChange()">
<el-option v-for="item in fieldType" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-col>
</el-row>
<el-divider />
<el-row v-loading="loading">
<el-col>
<div id="echartUserLine" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
<el-divider />
<el-row v-loading="loading">
<el-col>
<div id="echartUserPie" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
<div class="app-container">
<div class="dialog-body" :style="{height:height+'px'}">
<el-card v-loading="loading" class="box-card">
<el-row :gutter="6">
<el-col v-for="(item, index) in count" :key="index" :span="3">
<el-card class="box-card" :body-style="{padding: '10px 0px 0px 0px'}">
<div slot="header" class="clearfix">
<span>{{ item.name }}</span>
</div>
<div class="text">
<el-row style="padding-bottom:10px">
<el-col :title="item.title">
{{ item.count }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-row>
</el-card>
<el-card v-for="(item, index) in echart_num" :key="index" v-loading="loading" class="box-card ya-margin-top">
<el-row style="text-align:center;">
<el-col>
<el-select v-model="date_type" class="filter-item" @change="typeChange">
<el-option label="日" value="day" />
<el-option label="月" value="month" />
</el-select>
<el-date-picker
v-model="date_range"
class="filter-item"
style="width:350px"
:type="date_ptype"
:value-format="date_format"
:picker-options="date_options"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="dateChange"
/>
</el-col>
<el-col>
<div :id="echart_id+index" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
<el-card v-loading="loading" class="box-card ya-margin-top">
<el-row style="text-align:center;">
<el-col>
<el-select v-model="date_type" class="filter-item" @change="typeChange">
<el-option label="日" value="day" />
<el-option label="月" value="month" />
</el-select>
<el-date-picker
v-model="date_range"
class="filter-item"
style="width:350px"
:type="date_ptype"
:value-format="date_format"
:picker-options="date_options"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="dateChange"
/>
<el-select v-model="fieldValue" class="filter-item" placeholder="请选择" @change="fieldChange">
<el-option v-for="item in fieldType" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-col>
<el-col>
<div :id="echart_id+'field'" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
</div>
</div>
</template>
<script>
import screenHeight from '@/utils/screen-height'
import { stat } from '@/api/admin/user-log'
// ECharts
// echarts echarts 使
import * as echarts from 'echarts/core'
// Chart
import { LineChart, BarChart, PieChart } from 'echarts/charts'
// Component
import { LegendComponent, TitleComponent, TooltipComponent, GridComponent } from 'echarts/components'
// Chart
import { LineChart, BarChart } from 'echarts/charts'
// Component
import { TitleComponent, LegendComponent, GridComponent, TooltipComponent, ToolboxComponent } from 'echarts/components'
// Canvas CanvasRenderer SVGRenderer
import { CanvasRenderer } from 'echarts/renderers'
//
echarts.use([LegendComponent, TitleComponent, TooltipComponent, GridComponent, LineChart, BarChart, PieChart, CanvasRenderer])
import { stat } from '@/api/admin/user-log'
echarts.use([LineChart, BarChart, TitleComponent, LegendComponent, GridComponent, TooltipComponent, ToolboxComponent, CanvasRenderer])
export default {
name: 'AuthUserLogStat',
@ -150,113 +98,187 @@ export default {
name: '用户日志统计',
height: 600,
loading: false,
num: {
total: '--',
today: '--',
yesterday: '--',
thisweek: '--',
lastweek: '--',
thismonth: '--',
lastmonth: '--'
count: [],
echart_id: 'echartid',
echart_num: 0,
echart_data: [],
date_type: 'day',
date_range: [],
date_options: {},
date_ptype: 'monthrange',
date_format: 'yyyy-MM',
picker_options_day: {
shortcuts: [{
text: '最近7天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 6)
picker.$emit('pick', [start, end])
}
}, {
text: '最近30天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 29)
picker.$emit('pick', [start, end])
}
}, {
text: '最近90天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 89)
picker.$emit('pick', [start, end])
}
}, {
text: '最近120天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 119)
picker.$emit('pick', [start, end])
}
}]
},
date: {
x: [],
s: [],
date: []
},
field: {
x: [],
s: [],
date: []
picker_options_month: {
shortcuts: [{
text: '最近3个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 2)
picker.$emit('pick', [start, end])
}
}, {
text: '最近6个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 5)
picker.$emit('pick', [start, end])
}
}, {
text: '最近9个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 8)
picker.$emit('pick', [start, end])
}
}, {
text: '最近12个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 11)
picker.$emit('pick', [start, end])
}
}]
},
fieldType: [
{
value: 'country',
value: 'request_country',
label: '国家'
},
{
value: 'province',
value: 'request_province',
label: '省份'
},
{
value: 'city',
value: 'request_city',
label: '城市'
},
{
value: 'isp',
value: 'request_isp',
label: 'ISP'
},
{
value: 'user',
value: 'admin_user_id',
label: '用户'
}
],
fieldValue: 'user',
fieldLabel: '用户',
cardBodyStyle: {
padding: '10px 0px 0px 0px'
}
fieldValue: 'request_province'
}
},
computed: {},
watch: {
echart_data() {
this.$nextTick(() => {
this.setEchart()
})
}
},
created() {
this.height = screenHeight(100)
this.height = screenHeight(120)
this.stat()
},
mounted() {},
methods: {
stat() {
this.loading = true
stat().then(res => {
this.num = res.data.num
this.date = res.data.date
this.field = res.data.field
this.echartUserDate(res.data.date)
this.echartUserLine(res.data.field)
this.echartUserPie(res.data.field)
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartUserDateChange() {
this.loading = true
stat({
type: 'date',
date: this.date.date
}).then(res => {
this.echartUserDate(res.data.date)
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartFieldChange() {
this.loading = true
stat({
type: 'field',
date: this.field.date,
type: this.date_type,
date: this.date_range,
field: this.fieldValue
}).then(res => {
this.echartUserLine(res.data.field)
this.echartUserPie(res.data.field)
this.count = res.data.count
this.echart_data = res.data.echart
this.echart_num = res.data.echart.length
this.initEchart(res.data.field, this.echart_id + 'field')
this.dateOptions()
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartUserDate(data) {
var echart = echarts.init(document.getElementById('echartUserDate'))
typeChange() {
this.dateOptions()
this.date_range = []
},
dateOptions() {
const type = this.date_type
if (type === 'day') {
this.date_ptype = 'daterange'
this.date_format = 'yyyy-MM-dd'
this.date_options = this.picker_options_day
} else if (type === 'month') {
this.date_ptype = 'monthrange'
this.date_format = 'yyyy-MM'
this.date_options = this.picker_options_month
}
},
dateChange() {
this.stat()
},
fieldChange() {
this.stat()
},
setEchart() {
const data = this.echart_data
const num = this.echart_num
const id = this.echart_id
for (let i = 0; i < num; i++) {
this.initEchart(data[i], id + i)
this.date_type = data[i].type
this.date_range = data[i].date
}
},
initEchart(data, id) {
var myChart = echarts.init(document.getElementById(id))
var option = {
title: {
text: ''
text: data.title,
textStyle: { fontSize: 12 }
},
color: ['#1890ff'],
tooltip: {
trigger: 'axis'
legend: {
top: '20px',
data: data.legend
},
grid: {
left: '3%',
top: '80px',
left: '1%',
right: '3%',
bottom: '3%',
containLabel: true
@ -264,105 +286,27 @@ export default {
xAxis: {
type: 'category',
boundaryGap: false,
data: data.x
data: data.xAxis
},
yAxis: {
type: 'value'
},
series: [
{
name: '',
type: 'line',
smooth: true,
data: data.s,
label: {
show: true,
position: 'top'
}
}
]
}
echart.setOption(option)
},
echartUserLine(data) {
var echart = echarts.init(document.getElementById('echartUserLine'))
var option = {
title: {
text: ''
},
color: ['#3398DB'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
textStyle: {
align: 'left'
}
},
grid: {
left: '3%',
right: '3%',
bottom: '3%',
containLabel: true
toolbox: {
feature: {
magicType: { show: true, type: ['line', 'bar'] },
dataView: { show: true, readOnly: true },
saveAsImage: { show: true, name: this.name + data.date[0] + '-' + data.date[1] }
}
},
xAxis: [
{
type: 'category',
data: data.x
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
type: 'bar',
data: data.s,
label: {
show: true,
position: 'top'
}
}
]
series: data.series
}
echart.setOption(option)
},
echartUserPie(data) {
var echart = echarts.init(document.getElementById('echartUserPie'))
var option = {
title: {
text: ''
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: '3%',
top: '20px'
},
series: [
{
name: '',
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: data.sp,
itemStyle: {
borderRadius: 8,
normal: {
label: {
show: true,
formatter: '{b} : {c} ({d}%)'
},
labelLine: { show: true }
}
}
}
]
}
echart.setOption(option)
myChart.setOption(option)
}
}
}
@ -373,11 +317,9 @@ export default {
text-align: center;
}
.box-card .text {
text-align: center;
color: #666;
font-size: 20px;
line-height: 32px;
font-weight: 700;
margin-bottom: 10px;
text-align: center;
}
</style>

View File

@ -1,21 +1,26 @@
<template>
<div style="margin-bottom:15px">
<el-card v-loading="loading" style="text-align:center">
<el-row>
<div class="dialog-body">
<el-card v-loading="loading" class="box-card">
<el-row style="text-align:center;">
<el-col>
<el-select v-model="date_type" class="filter-item" @change="typeChange">
<el-option label="日" value="day" />
<el-option label="月" value="month" />
</el-select>
<el-date-picker
v-model="date"
type="daterange"
value-format="yyyy-MM-dd"
v-model="date_range"
class="filter-item"
style="width:350px"
:type="date_ptype"
:value-format="date_format"
:picker-options="date_options"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="echartIndexMemberChange()"
@change="dateChange"
/>
</el-col>
</el-row>
<el-row>
<el-col>
<div id="echartIndexMember" style="height:450px" />
<div id="numberEchart" :style="{height:height+'px'}" />
</el-col>
</el-row>
</el-card>
@ -27,66 +32,157 @@
// echarts echarts 使
import * as echarts from 'echarts/core'
// Chart
import { LineChart } from 'echarts/charts'
import { LineChart, BarChart } from 'echarts/charts'
// Component
import { TitleComponent, LegendComponent, TooltipComponent, GridComponent } from 'echarts/components'
import { TitleComponent, LegendComponent, GridComponent, TooltipComponent, ToolboxComponent } from 'echarts/components'
// Canvas CanvasRenderer SVGRenderer
import { CanvasRenderer } from 'echarts/renderers'
//
echarts.use([LineChart, TitleComponent, LegendComponent, TooltipComponent, GridComponent, CanvasRenderer])
echarts.use([LineChart, BarChart, TitleComponent, LegendComponent, GridComponent, TooltipComponent, ToolboxComponent, CanvasRenderer])
import { member } from '@/api/admin/index'
import { member as stat } from '@/api/admin/index'
export default {
name: 'IndexMember',
name: 'MemberStat',
components: { },
directives: { },
data() {
return {
name: '会员统计',
height: 500,
loading: false,
date: []
date_type: 'day',
date_range: [],
date_ptype: 'monthrange',
date_format: 'yyyy-MM',
date_options: {},
date_options_day: {
shortcuts: [{
text: '最近7天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 6)
picker.$emit('pick', [start, end])
}
}, {
text: '最近30天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 29)
picker.$emit('pick', [start, end])
}
}, {
text: '最近90天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 89)
picker.$emit('pick', [start, end])
}
}, {
text: '最近120天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 119)
picker.$emit('pick', [start, end])
}
}]
},
date_options_month: {
shortcuts: [{
text: '最近3个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 2)
picker.$emit('pick', [start, end])
}
}, {
text: '最近6个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 5)
picker.$emit('pick', [start, end])
}
}, {
text: '最近9个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 8)
picker.$emit('pick', [start, end])
}
}, {
text: '最近12个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 11)
picker.$emit('pick', [start, end])
}
}]
}
}
},
computed: {},
created() {
this.member()
this.stat()
},
mounted() {},
methods: {
member() {
stat() {
this.loading = true
member().then(res => {
this.date = res.data.date
this.echartIndexMember(res.data)
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartIndexMemberChange() {
this.loading = true
member({
date: this.date
stat({
type: this.date_type,
date: this.date_range
}).then(res => {
this.echartIndexMember(res.data)
this.date_type = res.data.number.type
this.date_range = res.data.number.date
this.dateEchart(res.data.number, 'numberEchart')
this.dateOptions()
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartIndexMember(data) {
var echart = echarts.init(document.getElementById('echartIndexMember'))
typeChange() {
this.dateOptions()
this.date_range = []
},
dateOptions() {
const type = this.date_type
if (type === 'day') {
this.date_ptype = 'daterange'
this.date_format = 'yyyy-MM-dd'
this.date_options = this.date_options_day
} else if (type === 'month') {
this.date_ptype = 'monthrange'
this.date_format = 'yyyy-MM'
this.date_options = this.date_options_month
}
},
dateChange() {
this.stat()
},
dateEchart(data, id) {
var echart = echarts.init(document.getElementById(id))
var option = {
tooltip: {
trigger: 'axis'
title: {
text: '会员',
textStyle: { fontSize: 12 }
},
legend: {
data: ['新增会员', '活跃会员', '会员总数'],
selected: { '会员总数': false },
top: 15
top: '20px',
data: data.legend,
selected: { '会员总数': false }
},
grid: {
left: '3%',
top: '80px',
left: '1%',
right: '3%',
bottom: '3%',
containLabel: true
@ -94,43 +190,25 @@ export default {
xAxis: {
type: 'category',
boundaryGap: false,
data: data.new.x
data: data.xAxis
},
yAxis: {
type: 'value'
},
series: [
{
name: '新增会员',
type: 'line',
smooth: true,
data: data.new.s,
label: {
show: true,
position: 'top'
}
},
{
name: '活跃会员',
type: 'line',
smooth: true,
data: data.act.s,
label: {
show: true,
position: 'top'
}
},
{
name: '会员总数',
type: 'line',
smooth: true,
data: data.count.s,
label: {
show: true,
position: 'top'
}
tooltip: {
trigger: 'axis',
textStyle: {
align: 'left'
}
]
},
toolbox: {
feature: {
magicType: { show: true, type: ['line', 'bar'] },
dataView: { show: true, readOnly: true },
saveAsImage: { show: true, name: this.name + data.date[0] + '-' + data.date[1] }
}
},
series: data.series
}
echart.setOption(option)
}
@ -139,4 +217,5 @@ export default {
</script>
<style scoped>
</style>

View File

@ -6,7 +6,7 @@
</el-col>
</el-row>
<div class="app-container">
<el-row>
<el-row style="margin-bottom:15px">
<el-col>
<index-member v-if="checkPermission(['admin/Index/member'])" />
</el-col>

View File

@ -1,144 +1,94 @@
<template>
<div class="app-container dialog-body" :style="{height:height+'px'}">
<el-card v-loading="loading" class="box-card">
<el-row :gutter="10">
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>总计</span>
</div>
<div class="text color-tot">
{{ num.total }}
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>今天</span>
</div>
<div class="text">
{{ num.today }}
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>昨天</span>
</div>
<div class="text">
{{ num.yesterday }}
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>本周</span>
</div>
<div class="text">
{{ num.thisweek }}
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>上周</span>
</div>
<div class="text">
{{ num.lastweek }}
</div>
</el-card>
</el-col>
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>本月</span>
</div>
<div class="text">
{{ num.thismonth }}
</div>
</el-card>
</el-col>
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>上月</span>
</div>
<div class="text">
{{ num.lastmonth }}
</div>
</el-card>
</el-col>
</el-row>
</el-card>
<el-card v-loading="loading" class="box-card ya-margin-top">
<el-row>
<el-col>
<el-date-picker
v-model="date.date"
type="daterange"
value-format="yyyy-MM-dd"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="echartDateChange"
/>
</el-col>
</el-row>
<el-row>
<el-col>
<div id="echartDate" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
<el-card class="box-card ya-margin-top">
<el-row>
<el-col>
<el-date-picker
v-model="field.date"
type="daterange"
value-format="yyyy-MM-dd"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="echartFieldChange"
/>
<el-select v-model="fieldValue" placeholder="请选择" @change="echartFieldChange">
<el-option v-for="item in fieldType" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-col>
</el-row>
<el-row v-loading="loading">
<el-col>
<div id="echartFieldLine" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
<el-divider />
<el-row v-loading="loading">
<el-col>
<div id="echartFieldPie" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
<div class="app-container">
<div class="dialog-body" :style="{height:height+'px'}">
<el-card v-loading="loading" class="box-card">
<el-row :gutter="6">
<el-col v-for="(item, index) in count" :key="index" :span="3">
<el-card class="box-card" :body-style="{padding: '10px 0px 0px 0px'}">
<div slot="header" class="clearfix">
<span>{{ item.name }}</span>
</div>
<div class="text">
<el-row style="padding-bottom:10px">
<el-col :title="item.title">
{{ item.count }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-row>
</el-card>
<el-card v-for="(item, index) in echart_num" :key="index" v-loading="loading" class="box-card ya-margin-top">
<el-row style="text-align:center;">
<el-col>
<el-select v-model="date_type" class="filter-item" @change="typeChange">
<el-option label="日" value="day" />
<el-option label="月" value="month" />
</el-select>
<el-date-picker
v-model="date_range"
class="filter-item"
style="width:350px"
:type="date_ptype"
:value-format="date_format"
:picker-options="date_options"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="dateChange"
/>
</el-col>
<el-col>
<div :id="echart_id+index" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
<el-card v-loading="loading" class="box-card ya-margin-top">
<el-row style="text-align:center;">
<el-col>
<el-select v-model="date_type" class="filter-item" @change="typeChange">
<el-option label="日" value="day" />
<el-option label="月" value="month" />
</el-select>
<el-date-picker
v-model="date_range"
class="filter-item"
style="width:350px"
:type="date_ptype"
:value-format="date_format"
:picker-options="date_options"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="dateChange"
/>
<el-select v-model="fieldValue" class="filter-item" placeholder="请选择" @change="fieldChange">
<el-option v-for="item in fieldType" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-col>
<el-col>
<div :id="echart_id+'field'" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
</div>
</div>
</template>
<script>
import screenHeight from '@/utils/screen-height'
import { stat } from '@/api/member/member-log'
// ECharts
// echarts echarts 使
import * as echarts from 'echarts/core'
// Chart
import { LineChart, BarChart, PieChart } from 'echarts/charts'
// Component
import { LegendComponent, TitleComponent, TooltipComponent, GridComponent } from 'echarts/components'
// Chart
import { LineChart, BarChart } from 'echarts/charts'
// Component
import { TitleComponent, LegendComponent, GridComponent, TooltipComponent, ToolboxComponent } from 'echarts/components'
// Canvas CanvasRenderer SVGRenderer
import { CanvasRenderer } from 'echarts/renderers'
//
echarts.use([LegendComponent, TitleComponent, TooltipComponent, GridComponent, LineChart, BarChart, PieChart, CanvasRenderer])
import screenHeight from '@/utils/screen-height'
import { stat } from '@/api/member/member-log'
echarts.use([LineChart, BarChart, TitleComponent, LegendComponent, GridComponent, TooltipComponent, ToolboxComponent, CanvasRenderer])
export default {
name: 'MemberLogStat',
@ -148,109 +98,187 @@ export default {
name: '会员日志统计',
height: 600,
loading: false,
num: {
total: '--',
today: '--',
yesterday: '--',
thisweek: '--',
lastweek: '--',
thismonth: '--',
lastmonth: '--'
count: [],
echart_id: 'echartid',
echart_num: 0,
echart_data: [],
date_type: 'day',
date_range: [],
date_options: {},
date_ptype: 'monthrange',
date_format: 'yyyy-MM',
picker_options_day: {
shortcuts: [{
text: '最近7天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 6)
picker.$emit('pick', [start, end])
}
}, {
text: '最近30天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 29)
picker.$emit('pick', [start, end])
}
}, {
text: '最近90天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 89)
picker.$emit('pick', [start, end])
}
}, {
text: '最近120天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 119)
picker.$emit('pick', [start, end])
}
}]
},
date: {
x_data: [],
y_data: [],
date: []
},
field: {
x_data: [],
y_data: [],
date: []
picker_options_month: {
shortcuts: [{
text: '最近3个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 2)
picker.$emit('pick', [start, end])
}
}, {
text: '最近6个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 5)
picker.$emit('pick', [start, end])
}
}, {
text: '最近9个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 8)
picker.$emit('pick', [start, end])
}
}, {
text: '最近12个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 11)
picker.$emit('pick', [start, end])
}
}]
},
fieldType: [
{
value: 'country',
value: 'request_country',
label: '国家'
},
{
value: 'province',
value: 'request_province',
label: '省份'
},
{
value: 'city',
value: 'request_city',
label: '城市'
},
{
value: 'isp',
value: 'request_isp',
label: 'ISP'
},
{
value: 'member',
value: 'member_id',
label: '会员'
}
],
fieldValue: 'member',
fieldLabel: '会员',
cardBodyStyle: {
padding: '10px 0px 0px 0px'
}
fieldValue: 'request_province'
}
},
computed: {},
watch: {
echart_data() {
this.$nextTick(() => {
this.setEchart()
})
}
},
created() {
this.height = screenHeight(100)
this.height = screenHeight(120)
this.stat()
},
mounted() {},
methods: {
stat() {
this.loading = true
stat().then(res => {
this.num = res.data.num
this.date = res.data.date
this.field = res.data.field
this.echartDate(res.data.date)
this.echartFieldLine(res.data.field)
this.echartFieldPie(res.data.field)
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartDateChange() {
this.loading = true
stat({
type: 'date', date: this.date.date
}).then(res => {
this.echartDate(res.data.date)
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartFieldChange(value) {
this.loading = true
stat({
type: 'field',
date: this.field.date,
type: this.date_type,
date: this.date_range,
field: this.fieldValue
}).then(res => {
this.echartFieldLine(res.data.field)
this.echartFieldPie(res.data.field)
this.count = res.data.count
this.echart_data = res.data.echart
this.echart_num = res.data.echart.length
this.initEchart(res.data.field, this.echart_id + 'field')
this.dateOptions()
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartDate(data) {
var echart = echarts.init(document.getElementById('echartDate'))
typeChange() {
this.dateOptions()
this.date_range = []
},
dateOptions() {
const type = this.date_type
if (type === 'day') {
this.date_ptype = 'daterange'
this.date_format = 'yyyy-MM-dd'
this.date_options = this.picker_options_day
} else if (type === 'month') {
this.date_ptype = 'monthrange'
this.date_format = 'yyyy-MM'
this.date_options = this.picker_options_month
}
},
dateChange() {
this.stat()
},
fieldChange() {
this.stat()
},
setEchart() {
const data = this.echart_data
const num = this.echart_num
const id = this.echart_id
for (let i = 0; i < num; i++) {
this.initEchart(data[i], id + i)
this.date_type = data[i].type
this.date_range = data[i].date
}
},
initEchart(data, id) {
var myChart = echarts.init(document.getElementById(id))
var option = {
title: {
text: ''
text: data.title,
textStyle: { fontSize: 12 }
},
tooltip: {
trigger: 'axis'
legend: {
top: '20px',
data: data.legend
},
grid: {
left: '3%',
top: '80px',
left: '1%',
right: '3%',
bottom: '3%',
containLabel: true
@ -258,104 +286,27 @@ export default {
xAxis: {
type: 'category',
boundaryGap: false,
data: data.x_data
data: data.xAxis
},
yAxis: {
type: 'value'
},
series: [
{
type: 'line',
smooth: true,
data: data.y_data,
label: {
show: true,
position: 'top'
}
}
]
}
echart.setOption(option)
},
echartFieldLine(data) {
var echart = echarts.init(document.getElementById('echartFieldLine'))
var option = {
title: {
text: ''
},
color: ['#3398DB'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
textStyle: {
align: 'left'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
toolbox: {
feature: {
magicType: { show: true, type: ['line', 'bar'] },
dataView: { show: true, readOnly: true },
saveAsImage: { show: true, name: this.name + data.date[0] + '-' + data.date[1] }
}
},
xAxis: [
{
type: 'category',
data: data.x_data
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
type: 'bar',
data: data.y_data,
label: {
show: true,
position: 'top'
}
}
]
series: data.series
}
echart.setOption(option)
},
echartFieldPie(data) {
var echart = echarts.init(document.getElementById('echartFieldPie'))
var option = {
title: {
text: ''
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: '3%',
top: '20px'
},
series: [
{
name: '',
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
itemStyle: {
borderRadius: 8,
normal: {
label: {
show: true,
formatter: '{b} : {c} ({d}%)'
},
labelLine: { show: true }
}
},
data: data.p_data
}
]
}
echart.setOption(option)
myChart.setOption(option)
}
}
}
@ -366,11 +317,9 @@ export default {
text-align: center;
}
.box-card .text {
text-align: center;
color: #666;
font-size: 20px;
line-height: 32px;
font-weight: 700;
margin-bottom: 10px;
text-align: center;
}
</style>

View File

@ -1,169 +1,67 @@
<template>
<div class="app-container dialog-body" :style="{height:height+'px'}">
<el-card v-loading="loading" class="box-card">
<el-row :gutter="10">
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>会员</span>
</div>
<div class="text">
<el-row>
<el-col class="color-tot" title="总数">
{{ number.total }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>今天</span>
</div>
<div class="text">
<el-row>
<el-col :span="12" class="color-new" title="新增会员">
{{ number.today }}
</el-col>
<el-col :span="12" class="color-act" title="活跃会员">
{{ active.today }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>昨天</span>
</div>
<div class="text">
<el-row>
<el-col :span="12" class="color-new" title="新增会员">
{{ number.yesterday }}
</el-col>
<el-col :span="12" class="color-act" title="活跃会员">
{{ active.yesterday }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>本周</span>
</div>
<div class="text">
<el-row>
<el-col :span="12" class="color-new" title="新增会员">
{{ number.yesterday }}
</el-col>
<el-col :span="12" class="color-act" title="活跃会员">
{{ active.thisweek }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :sm="3">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>上周</span>
</div>
<div class="text">
<el-row>
<el-col :span="12" class="color-new" title="新增会员">
{{ number.yesterday }}
</el-col>
<el-col :span="12" class="color-act" title="活跃会员">
{{ active.lastweek }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>本月</span>
</div>
<div class="text">
<el-row>
<el-col :span="12" class="color-new" title="新增会员">
{{ number.yesterday }}
</el-col>
<el-col :span="12" class="color-act" title="活跃会员">
{{ active.thismonth }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :sm="4">
<el-card class="box-card" :body-style="cardBodyStyle">
<div slot="header" class="clearfix">
<span>上月</span>
</div>
<div class="text">
<el-row>
<el-col :span="12" class="color-new" title="新增会员">
{{ number.yesterday }}
</el-col>
<el-col :span="12" class="color-act" title="活跃会员">
{{ active.lastmonth }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-row>
</el-card>
<el-card v-loading="loading" class="box-card ya-margin-top">
<el-row>
<el-col>
<el-date-picker
v-model="date"
type="daterange"
value-format="yyyy-MM-dd"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="echartMemberDateChange"
/>
</el-col>
</el-row>
<el-row>
<el-col>
<div id="echartMemberDate" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
<el-card v-loading="loading" class="box-card ya-margin-top">
<el-row>
<el-col>
<div id="echartMemberCount" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
<div class="app-container">
<div class="dialog-body" :style="{height:height+'px'}">
<el-card v-loading="loading" class="box-card">
<el-row :gutter="6">
<el-col v-for="(item, index) in count" :key="index" :span="3">
<el-card class="box-card" :body-style="{padding: '10px 0px 0px 0px'}">
<div slot="header" class="clearfix">
<span>{{ item.name }}</span>
</div>
<div class="text">
<el-row style="padding-bottom:10px">
<el-col :title="item.title">
{{ item.count }}
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-row>
</el-card>
<el-card v-for="(item, index) in echart_num" :key="index" v-loading="loading" class="box-card ya-margin-top">
<el-row style="text-align:center;">
<el-col>
<el-select v-model="date_type" class="filter-item" @change="typeChange">
<el-option label="日" value="day" />
<el-option label="月" value="month" />
</el-select>
<el-date-picker
v-model="date_range"
class="filter-item"
style="width:350px"
:type="date_ptype"
:value-format="date_format"
:picker-options="date_options"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="dateChange"
/>
</el-col>
<el-col>
<div :id="echart_id+index" :style="{height:height-300+'px'}" />
</el-col>
</el-row>
</el-card>
</div>
</div>
</template>
<script>
import screenHeight from '@/utils/screen-height'
import { stat } from '@/api/member/member'
// ECharts
// echarts echarts 使
import * as echarts from 'echarts/core'
// Chart
import { LineChart } from 'echarts/charts'
import { LineChart, BarChart } from 'echarts/charts'
// Component
import { TitleComponent, LegendComponent, TooltipComponent, GridComponent } from 'echarts/components'
import { TitleComponent, LegendComponent, GridComponent, TooltipComponent, ToolboxComponent } from 'echarts/components'
// Canvas CanvasRenderer SVGRenderer
import { CanvasRenderer } from 'echarts/renderers'
//
echarts.use([LineChart, TitleComponent, LegendComponent, TooltipComponent, GridComponent, CanvasRenderer])
import { stat } from '@/api/member/member'
echarts.use([LineChart, BarChart, TitleComponent, LegendComponent, GridComponent, TooltipComponent, ToolboxComponent, CanvasRenderer])
export default {
name: 'MemberStat',
@ -174,158 +72,187 @@ export default {
name: '会员统计',
height: 680,
loading: false,
number: {
total: '-',
today: '-',
yesterday: '-',
thisweek: '-',
lastweek: '-',
thismonth: '-',
lastmonth: '-'
count: [],
echart_id: 'echartid',
echart_num: 0,
echart_data: [],
date_type: 'day',
date_range: [],
date_options: {},
date_ptype: 'monthrange',
date_format: 'yyyy-MM',
picker_options_day: {
shortcuts: [{
text: '最近7天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 6)
picker.$emit('pick', [start, end])
}
}, {
text: '最近30天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 29)
picker.$emit('pick', [start, end])
}
}, {
text: '最近90天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 89)
picker.$emit('pick', [start, end])
}
}, {
text: '最近120天',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 119)
picker.$emit('pick', [start, end])
}
}]
},
active: {
total: '-',
today: '-',
yesterday: '-',
thisweek: '-',
lastweek: '-',
thismonth: '-',
lastmonth: '-'
},
date: [],
cardBodyStyle: {
padding: '10px 0px 0px 0px'
picker_options_month: {
shortcuts: [{
text: '最近3个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 2)
picker.$emit('pick', [start, end])
}
}, {
text: '最近6个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 5)
picker.$emit('pick', [start, end])
}
}, {
text: '最近9个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 8)
picker.$emit('pick', [start, end])
}
}, {
text: '最近12个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 11)
picker.$emit('pick', [start, end])
}
}]
}
}
},
computed: {},
watch: {
echart_data() {
this.$nextTick(() => {
this.setEchart()
})
}
},
created() {
this.height = screenHeight(100)
this.height = screenHeight(120)
this.stat()
},
mounted() {},
methods: {
stat() {
this.loading = true
stat().then(res => {
this.number = res.data.number
this.active = res.data.active
this.region = res.data.region
this.date = res.data.date.date
this.echartMemberDate(res.data.date)
this.echartMemberCount(res.data.count)
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartMemberDateChange() {
this.loading = true
stat({
date: this.date
type: this.date_type,
date: this.date_range
}).then(res => {
this.echartMemberDate(res.data.date)
this.count = res.data.count
this.echart_data = res.data.echart
this.echart_num = res.data.echart.length
this.dateOptions()
this.loading = false
}).catch(() => {
this.loading = false
})
},
echartMemberDate(data) {
var echart = echarts.init(document.getElementById('echartMemberDate'))
var option = {
tooltip: {
trigger: 'axis'
},
legend: {
data: ['新增会员', '活跃会员', '会员总数'],
selected: { '会员总数': false }
},
grid: {
left: '3%',
right: '3%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: data.new.x
},
yAxis: {
type: 'value'
},
series: [
{
name: '新增会员',
type: 'line',
smooth: true,
data: data.new.s,
label: {
show: true,
position: 'top'
}
},
{
name: '活跃会员',
type: 'line',
smooth: true,
data: data.act.s,
label: {
show: true,
position: 'top'
}
},
{
name: '会员总数',
type: 'line',
smooth: true,
data: data.count.s,
label: {
show: true,
position: 'top'
}
}
]
}
echart.setOption(option)
typeChange() {
this.dateOptions()
this.date_range = []
},
echartMemberCount(data) {
var echart = echarts.init(document.getElementById('echartMemberCount'))
dateOptions() {
const type = this.date_type
if (type === 'day') {
this.date_ptype = 'daterange'
this.date_format = 'yyyy-MM-dd'
this.date_options = this.picker_options_day
} else if (type === 'month') {
this.date_ptype = 'monthrange'
this.date_format = 'yyyy-MM'
this.date_options = this.picker_options_month
}
},
dateChange() {
this.stat()
},
setEchart() {
const data = this.echart_data
const num = this.echart_num
const id = this.echart_id
for (let i = 0; i < num; i++) {
this.initEchart(data[i], id + i)
this.date_type = data[i].type
this.date_range = data[i].date
}
},
initEchart(data, id) {
var myChart = echarts.init(document.getElementById(id))
var option = {
title: {
text: data.title,
textStyle: { fontSize: 12 }
},
legend: {
data: ['会员总数']
top: '20px',
data: data.legend
},
grid: {
left: '3%',
top: '80px',
left: '1%',
right: '3%',
bottom: '3%',
containLabel: true
},
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
boundaryGap: false,
data: data.x
data: data.xAxis
},
yAxis: {
type: 'value'
},
series: [
{
name: '会员总数',
data: data.s,
type: 'line',
areaStyle: {},
label: {
show: true,
position: 'top'
}
tooltip: {
trigger: 'axis',
textStyle: {
align: 'left'
}
]
},
toolbox: {
feature: {
magicType: { show: true, type: ['line', 'bar'] },
dataView: { show: true, readOnly: true },
saveAsImage: { show: true, name: this.name + data.date[0] + '-' + data.date[1] }
}
},
series: data.series
}
echart.setOption(option)
myChart.setOption(option)
}
}
}
@ -336,23 +263,9 @@ export default {
text-align: center;
}
.box-card .text {
color: #666;
font-size: 20px;
line-height: 32px;
font-weight: 700;
text-align: center;
}
.el-row {
margin-bottom: 10px;
}
.color-tot {
color: #1890ff;
}
.color-new {
color: #5470c6;
border-right: 1px solid #e6ebf5;
}
.color-act {
color: #91cc75;
}
</style>