|
@@ -0,0 +1,492 @@
|
|
|
+<template>
|
|
|
+ <div class="dashboard-container">
|
|
|
+
|
|
|
+ <el-row :gutter="10" class="top-container">
|
|
|
+ <el-col :xs="24" :sm="12" :lg="12">
|
|
|
+ <div class="today">今日</div>
|
|
|
+ <div class="today-content">{{ dateFormat }},欢迎登入分销商城后台管理操作系统,累计售出{{ statisticsData.total }}件商品,继续加油</div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :sm="12" :lg="12">
|
|
|
+ <el-row :gutter="20" class="right-row">
|
|
|
+ <el-col :span="3">
|
|
|
+ <svg-icon icon-class="product1" class-name="icon"/>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="3">
|
|
|
+ <div class="num">{{ statisticsData.sold }}</div>
|
|
|
+ <div class="name">已售中商品</div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="3">
|
|
|
+ <svg-icon icon-class="fahuo1" class-name="icon"/>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="3">
|
|
|
+ <div class="num">{{ statisticsData.dfh }}</div>
|
|
|
+ <div class="name">待发货订单</div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="3">
|
|
|
+ <svg-icon icon-class="refund-order1" class-name="icon"/>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="3">
|
|
|
+ <div class="num">{{ statisticsData.refund }}</div>
|
|
|
+ <div class="name">维权中订单</div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="3">
|
|
|
+ <svg-icon icon-class="settlement" class-name="icon"/>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="3">
|
|
|
+ <div class="num">¥{{ statisticsData.orderShareAmount }}</div>
|
|
|
+ <div class="name">待结算金额</div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20" class="middle-container">
|
|
|
+ <el-col :xs="24" :sm="7" :lg="7">
|
|
|
+ <div class="item">
|
|
|
+ <div class="title">登入用户数</div>
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="5">
|
|
|
+ <svg-icon icon-class="history-user" class-name="icon"/>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="19" class="right-data">
|
|
|
+ <div class="data">
|
|
|
+ <span>今日访客</span><span style="color: #f4cc4e;">{{ statisticsData.todayVisit }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="progress">
|
|
|
+ <el-progress :percentage="personCountCompute" :show-text="false" :color="'#f4cc4e'"></el-progress>
|
|
|
+ </div>
|
|
|
+ <div class="data">
|
|
|
+ <span>昨天访客</span><span>{{ statisticsData.yestodayVisit }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :sm="7" :lg="7">
|
|
|
+ <div class="item">
|
|
|
+ <div class="title">订单数</div>
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="5">
|
|
|
+ <svg-icon icon-class="order" class-name="icon"/>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="19" class="right-data">
|
|
|
+ <div class="data">
|
|
|
+ <span>今日订单</span><span style="color: #e6808f;">{{ statisticsData.todayOrder }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="progress">
|
|
|
+ <el-progress :percentage="orderCountCompute" :show-text="false" :color="'#e6808f'"></el-progress>
|
|
|
+ </div>
|
|
|
+ <div class="data">
|
|
|
+ <span>昨天订单</span><span>{{ statisticsData.yestodayOrder }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="20" :sm="7" :lg="7">
|
|
|
+ <div class="item">
|
|
|
+ <div class="title">预估收益</div>
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="5">
|
|
|
+ <svg-icon icon-class="profit1" class-name="icon"/>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="19" class="right-data">
|
|
|
+ <div class="data">
|
|
|
+ <span>今日收益</span><span style="color: #5f71cf;">{{ statisticsData.todayProfit }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="progress">
|
|
|
+ <el-progress :percentage="profitCompute" :show-text="false" color="'#5f71cf'"></el-progress>
|
|
|
+ </div>
|
|
|
+ <div class="data">
|
|
|
+ <span>昨天收益</span><span>{{ statisticsData.yestodayProfit }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="4" :sm="3" :lg="3">
|
|
|
+ <div class="item last-item">
|
|
|
+ <div class="title">下单转化率</div>
|
|
|
+ <div class="content">
|
|
|
+ <div class="num">{{ statisticsData.orderTax }}%</div>
|
|
|
+ <div class="text">今日转化率</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20" class="bottom-container">
|
|
|
+ <el-col :xs="24" :sm="14" :lg="14">
|
|
|
+ <div class="content">
|
|
|
+ <div class="tabs-container clearfix">
|
|
|
+ <div class="fl">
|
|
|
+ <el-radio-group v-model="screenForm.workOrderType" size="small" @change="changeEchartsDateValue">
|
|
|
+ <el-radio-button label="">全部</el-radio-button>
|
|
|
+ <el-radio-button label="INSTALL">产品</el-radio-button>
|
|
|
+ <el-radio-button label="REPAIR">服务</el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ <div class="fr">
|
|
|
+ <el-radio-group v-model="screenForm.echartsFlag" size="small" @change="changeEchartsDateValue">
|
|
|
+ <el-radio-button label="1">今日</el-radio-button>
|
|
|
+ <el-radio-button label="2">昨日</el-radio-button>
|
|
|
+ <el-radio-button label="3">最近7日</el-radio-button>
|
|
|
+ <el-radio-button label="4">本月</el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="padding: 20px;">
|
|
|
+ <el-row style="text-align: center;">
|
|
|
+ <el-col :span="8">
|
|
|
+ <div style="font-size: 20px;font-weight: bold;color: #f65c5c">{{ transaction.orderNum }}</div>
|
|
|
+ <div style="font-size: 12px;padding-top: 10px;">成交量(件)</div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <div style="font-size: 20px;font-weight: bold;color: #f65c5c">{{ transaction.amount }}</div>
|
|
|
+ <div style="font-size: 12px;padding-top: 10px;">成交额(元)</div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <div style="font-size: 20px;font-weight: bold;color: #f65c5c">{{ transaction.avgAmount }}</div>
|
|
|
+ <div style="font-size: 12px;padding-top: 10px;">人均消费(元)</div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ <div class="table" v-resize="DomResize">
|
|
|
+ <div ref="myChart" :style="{width: '100%', height: '300px'}"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :sm="10" :lg="10">
|
|
|
+ <div class="content">
|
|
|
+ <div class="tabs-container clearfix">
|
|
|
+ <div class="fr">
|
|
|
+ <el-radio-group v-model="screenForm.goodsFlag" size="small" @change="changeTableDateValue">
|
|
|
+ <el-radio-button label="1">今日</el-radio-button>
|
|
|
+ <el-radio-button label="2">昨日</el-radio-button>
|
|
|
+ <el-radio-button label="3">最近7日</el-radio-button>
|
|
|
+ <el-radio-button label="4">本月</el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="table">
|
|
|
+ <el-table v-loading="listLoading" :data="dataList" element-loading-text="Loading" border fit highlight-current-row stripe size="mini" height="400">
|
|
|
+ <el-table-column type="index" label="排名" width="50" align="center"></el-table-column>
|
|
|
+ <el-table-column align="center" label="商品名称" prop="goodsName"></el-table-column>
|
|
|
+ <el-table-column align="center" label="成交量" prop="num"></el-table-column>
|
|
|
+ <el-table-column align="center" label="成交金额" prop="payAmount"></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapGetters } from 'vuex'
|
|
|
+import { getInfo, getOrder, getGoodsRank } from '@/api/dashboard'
|
|
|
+import { dateFormat } from '@/utils/util'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'Dashboard',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ statisticsData: {
|
|
|
+ total: 0,
|
|
|
+ sold: 0,
|
|
|
+ dfh: 0,
|
|
|
+ refund: 0,
|
|
|
+ orderShareAmount: 0,
|
|
|
+ todayVisit: 0,
|
|
|
+ yestodayVisit: 0,
|
|
|
+ todayOrder: 0,
|
|
|
+ yestodayOrder: 0,
|
|
|
+ todayProfit: 0,
|
|
|
+ yestodayProfit: 0,
|
|
|
+ orderTax: 0
|
|
|
+ }, // 统计数据
|
|
|
+ dataList: [], // 列表数据
|
|
|
+ transaction: {
|
|
|
+ amount: 0, // 成交额
|
|
|
+ avgAmount: 0, // 人均消费
|
|
|
+ orderNum: 0, // 成交量
|
|
|
+ countAry: []
|
|
|
+ },
|
|
|
+ listLoading: true, // 列表加载loading
|
|
|
+ chartLoading: true, // 图表加载loading
|
|
|
+ screenForm: {
|
|
|
+ workOrderType: '',
|
|
|
+ echartsFlag : '1',
|
|
|
+ goodsFlag: '1'
|
|
|
+ },
|
|
|
+ existChart: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ directives: {
|
|
|
+ resize: { // 指令的名称
|
|
|
+ bind(el, binding) { // el为绑定的元素,binding为绑定给指令的对象
|
|
|
+ // console.log(el,"绑定",binding);
|
|
|
+ let width = '', height = '';
|
|
|
+ function isResize() {
|
|
|
+ const style = document.defaultView.getComputedStyle(el);
|
|
|
+ if (width !== style.width || height !== style.height) {
|
|
|
+ binding.value({width:style.width,height:style.height}); // 关键(这传入的是函数,所以执行此函数)
|
|
|
+ }
|
|
|
+ width = style.width;
|
|
|
+ height = style.height;
|
|
|
+ }
|
|
|
+ el.__vueSetInterval__ = setInterval(isResize, 300);
|
|
|
+ },
|
|
|
+ unbind(el) {
|
|
|
+ // console.log(el,"解绑");
|
|
|
+ clearInterval(el.__vueSetInterval__);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapGetters([
|
|
|
+ 'name'
|
|
|
+ ]),
|
|
|
+ dateFormat() {
|
|
|
+ return dateFormat("YYYY-mm-dd WWW", new Date())
|
|
|
+ },
|
|
|
+ personCountCompute() {
|
|
|
+ if (this.statisticsData.todayVisit >= this.statisticsData.yestodayVisit) {
|
|
|
+ return 100
|
|
|
+ } else {
|
|
|
+ return this.statisticsData.todayVisit / this.statisticsData.yestodayVisit * 100
|
|
|
+ }
|
|
|
+ },
|
|
|
+ orderCountCompute() {
|
|
|
+ if (this.statisticsData.todayOrder >= this.statisticsData.yestodayOrder) {
|
|
|
+ return 100
|
|
|
+ } else {
|
|
|
+ return this.statisticsData.todayOrder / this.statisticsData.yestodayOrder * 100
|
|
|
+ }
|
|
|
+ },
|
|
|
+ profitCompute() {
|
|
|
+ if (this.statisticsData.todayProfit >= this.statisticsData.yestodayProfit) {
|
|
|
+ return 100
|
|
|
+ } else {
|
|
|
+ return this.statisticsData.todayProfit / this.statisticsData.yestodayProfit * 100
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getStatisticsData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 获取统计数据
|
|
|
+ getStatisticsData() {
|
|
|
+ getInfo().then(res => {
|
|
|
+ this.statisticsData = res.data
|
|
|
+ })
|
|
|
+ this.getOrder()
|
|
|
+ this.getGoodsRank()
|
|
|
+ },
|
|
|
+ getOrder() {
|
|
|
+ getOrder({
|
|
|
+ flag: this.screenForm.echartsFlag,
|
|
|
+ workOrderType: this.screenForm.workOrderType
|
|
|
+ }).then(res => {
|
|
|
+ this.transaction = res.data
|
|
|
+ this.drawLine()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getGoodsRank() {
|
|
|
+ this.listLoading = true
|
|
|
+ getGoodsRank({ flag: this.screenForm.goodsFlag }).then(res => {
|
|
|
+ this.dataList = res.data
|
|
|
+ this.listLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 切换tabs
|
|
|
+ changeEchartsDateValue() {
|
|
|
+ this.getOrder()
|
|
|
+ },
|
|
|
+ changeTableDateValue() {
|
|
|
+ this.getGoodsRank()
|
|
|
+ },
|
|
|
+ DomResize(data){
|
|
|
+ let {width,height} = data;
|
|
|
+ // console.log("width:",width,"height:",height," dom尺寸方式改变");
|
|
|
+ if(this.existChart){
|
|
|
+ this.existChart.resize()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ drawLine(){
|
|
|
+ // 基于准备好的dom,初始化echarts实例
|
|
|
+ if (this.existChart) {
|
|
|
+ this.existChart.dispose()
|
|
|
+ }
|
|
|
+ this.existChart = this.$echarts.init(this.$refs.myChart)
|
|
|
+ // 绘制图表
|
|
|
+ this.existChart.setOption({
|
|
|
+ color: ['#80FFA5'],
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'cross',
|
|
|
+ label: {
|
|
|
+ backgroundColor: '#6a7985'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: '3%',
|
|
|
+ right: '7%',
|
|
|
+ bottom: '3%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ xAxis: [
|
|
|
+ {
|
|
|
+ type: 'category',
|
|
|
+ boundaryGap: false,
|
|
|
+ data: this.screenForm.echartsFlag === '1' || this.screenForm.echartsFlag === '2' ? ['0', '1', '2', '3', '4', '5', '6','7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19','20', '21', '22', '23'] : this.transaction.x
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ type: 'value'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '数量',
|
|
|
+ type: 'line',
|
|
|
+ stack: '数量',
|
|
|
+ smooth: true,
|
|
|
+ lineStyle: {
|
|
|
+ width: 0
|
|
|
+ },
|
|
|
+ showSymbol: false,
|
|
|
+ areaStyle: {
|
|
|
+ opacity: 0.8,
|
|
|
+ color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
|
|
+ offset: 0,
|
|
|
+ color: 'rgba(128, 255, 165)'
|
|
|
+ }, {
|
|
|
+ offset: 1,
|
|
|
+ color: 'rgba(1, 191, 236)'
|
|
|
+ }])
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ focus: 'series'
|
|
|
+ },
|
|
|
+ data: this.transaction.countAry
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+
|
|
|
+.dashboard {
|
|
|
+ &-container {
|
|
|
+ background: #f5f5f5;
|
|
|
+ padding: 30px;
|
|
|
+ min-height: calc(100vh - 86px);
|
|
|
+ .top-container {
|
|
|
+ .today {
|
|
|
+ font-weight: bold;
|
|
|
+ padding-bottom: 10px;
|
|
|
+ }
|
|
|
+ .today-content {
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ .right-row {
|
|
|
+ .el-col {
|
|
|
+ height: 44px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ .icon {
|
|
|
+ height: 36px;
|
|
|
+ width: 36px;
|
|
|
+ }
|
|
|
+ .num {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: bold;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .name {
|
|
|
+ text-align: center;
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .middle-container {
|
|
|
+ margin-top: 20px;
|
|
|
+ .item {
|
|
|
+ padding: 15px;
|
|
|
+ background: #ffffff;
|
|
|
+ height: 110px;
|
|
|
+ .title {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 5px;
|
|
|
+ }
|
|
|
+ .icon {
|
|
|
+ height: 50px;
|
|
|
+ width: 50px;
|
|
|
+ padding-top: 15px;
|
|
|
+ }
|
|
|
+ .right-data {
|
|
|
+ padding: 5px 0 0 10px;
|
|
|
+ .progress {
|
|
|
+ margin: 5px 0;
|
|
|
+ }
|
|
|
+ .data {
|
|
|
+ font-size: 14px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .last-item {
|
|
|
+ .content {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ .num {
|
|
|
+ padding: 10px 0 5px 0;
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #76b36b;
|
|
|
+ }
|
|
|
+ .text {
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bottom-container {
|
|
|
+ margin-top: 15px;
|
|
|
+ .content {
|
|
|
+ height: 450px;
|
|
|
+ background: #ffffff;
|
|
|
+ .tabs-container {
|
|
|
+ padding: 10px 10px 0 10px;
|
|
|
+ }
|
|
|
+ .table {
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|