张延森 преди 3 години
родител
ревизия
66ca94a295
променени са 9 файла, в които са добавени 220 реда и са изтрити 1 реда
  1. 1
    0
      .npmrc
  2. 1
    0
      package.json
  3. 5
    0
      src/api/stat.js
  4. 45
    0
      src/components/ECharts/Line.vue
  5. 83
    0
      src/components/ECharts/index.vue
  6. 1
    1
      src/utils/request.js
  7. 33
    0
      src/views/dashboard/components/Statistic.vue
  8. 31
    0
      src/views/dashboard/index.vue
  9. 20
    0
      yarn.lock

+ 1
- 0
.npmrc Целия файл

@@ -0,0 +1 @@
1
+registry=https://registry.npm.taobao.org

+ 1
- 0
package.json Целия файл

@@ -19,6 +19,7 @@
19 19
     "axios-retry": "^3.2.4",
20 20
     "core-js": "^2.6.12",
21 21
     "dayjs": "^1.10.7",
22
+    "echarts": "^5.3.0",
22 23
     "element-ui": "2.13.2",
23 24
     "js-cookie": "2.2.0",
24 25
     "js-md5": "^0.7.3",

+ 5
- 0
src/api/stat.js Целия файл

@@ -0,0 +1,5 @@
1
+import request from '@/utils/request'
2
+
3
+export const getStatTotal = () => request({
4
+  url: '/admin/stat-total'
5
+})

+ 45
- 0
src/components/ECharts/Line.vue Целия файл

@@ -0,0 +1,45 @@
1
+<template>
2
+  <echarts :option="option" :loading="loading"></echarts>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  name: 'LineChart',
8
+  props: {
9
+    option: {
10
+      type: Object,
11
+      default: () => ({})
12
+    },
13
+    value: {
14
+      type: Array,
15
+      default: () => []
16
+    },
17
+    loading: Boolean
18
+  },
19
+  computed: {
20
+    opt() {
21
+      return {
22
+        xAxis: {
23
+          type: 'category',
24
+        },
25
+        yAxis: {
26
+          type: 'value'
27
+        },
28
+        series: [
29
+          {
30
+            type: 'line',
31
+            smooth: true
32
+          }
33
+        ],
34
+        dimensions: ['key', 'value'],
35
+        source: this.value,
36
+        ...this.option,
37
+      }
38
+    }
39
+  },
40
+  data() {
41
+    return {
42
+    }
43
+  }
44
+}
45
+</script>

+ 83
- 0
src/components/ECharts/index.vue Целия файл

@@ -0,0 +1,83 @@
1
+<template>
2
+  <div class="echart"></div>
3
+</template>
4
+
5
+<script>
6
+// 按需导入模块
7
+// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
8
+import * as echarts from 'echarts/core';
9
+// 引入图表,图表后缀都为 Chart
10
+import { LineChart } from 'echarts/charts';
11
+// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
12
+import {
13
+  TitleComponent,
14
+  TooltipComponent,
15
+  GridComponent,
16
+  DatasetComponent,
17
+  TransformComponent
18
+} from 'echarts/components';
19
+// 标签自动布局,全局过渡动画等特性
20
+import { LabelLayout, UniversalTransition } from 'echarts/features';
21
+// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
22
+import { CanvasRenderer } from 'echarts/renderers';
23
+
24
+// 注册必须的组件
25
+echarts.use([
26
+  TitleComponent,
27
+  TooltipComponent,
28
+  GridComponent,
29
+  DatasetComponent,
30
+  TransformComponent,
31
+  LineChart,
32
+  LabelLayout,
33
+  UniversalTransition,
34
+  CanvasRenderer
35
+]);
36
+
37
+
38
+export default {
39
+  name: 'ECharts',
40
+  props: {
41
+    option: {
42
+      type: Object,
43
+      default: () => ({})
44
+    },
45
+    loading: Boolean
46
+  },
47
+  data() {
48
+    return {
49
+      echartsRef: undefined,
50
+    }
51
+  },
52
+  watch: {
53
+    option: {
54
+      handler(v) {
55
+        if (this.echartsRef) {
56
+          this.echartsRef.setOption(v)
57
+        }
58
+      },
59
+      immediate: true
60
+    },
61
+    loading(nw) {
62
+      if (!this.echartsRef) return;
63
+
64
+      if (nw) {
65
+        this.echartsRef.showLoading()
66
+      } else {
67
+        this.echartsRef.hideLoading()
68
+      }
69
+    }
70
+  },
71
+  mounted() {
72
+    this.echartsRef = echarts.init(this.$el)
73
+    this.echartsRef.setOption(v)
74
+  }
75
+}
76
+</script>
77
+
78
+<style lang="scss" scope>
79
+.echart {
80
+  width: 100%;
81
+  height: 100%;
82
+}
83
+</style>

+ 1
- 1
src/utils/request.js Целия файл

@@ -54,7 +54,7 @@ service.interceptors.response.use(
54 54
       })
55 55
       return Promise.reject(new Error(res.message || 'Error'))
56 56
     } else {
57
-      return res
57
+      return res.data
58 58
     }
59 59
   },
60 60
   error => {

+ 33
- 0
src/views/dashboard/components/Statistic.vue Целия файл

@@ -0,0 +1,33 @@
1
+<template>
2
+  <el-card class="stat-card">
3
+    <div class="stat-card_title">{{title}}</div>
4
+    <div class="stat-card_content">{{value}}</div>
5
+  </el-card>
6
+</template>
7
+
8
+<script>
9
+export default {
10
+  name: 'Statistic',
11
+  props: {
12
+    title: String,
13
+    value: String,
14
+  }
15
+}
16
+</script>
17
+
18
+<style lang="scss" scoped>
19
+.stat-card {
20
+  width: 100%;
21
+
22
+  &_title {
23
+    margin-bottom: 4px;
24
+    color: #00000073;
25
+    font-size: 14px;
26
+  }
27
+
28
+  &_content {
29
+    font-size: 24px;
30
+    color: #000;
31
+  }
32
+}
33
+</style>

+ 31
- 0
src/views/dashboard/index.vue Целия файл

@@ -1,16 +1,47 @@
1 1
 <template>
2 2
   <div class="dashboard-container">
3 3
     <div class="dashboard-text">欢迎使用{{ name }}</div>
4
+
5
+    <el-row type="flex" class="row-bg" justify="space-between">
6
+      <el-col :span="6">
7
+        <statistic title="报名总数" :value="total.reg" />
8
+      </el-col>
9
+      <el-col :span="6">
10
+        <statistic title="PV 总数" :value="total.pv" />
11
+      </el-col>
12
+      <el-col :span="6">
13
+        <statistic title="UV 总数" :value="total.uv" />
14
+      </el-col>
15
+    </el-row>
4 16
   </div>
5 17
 </template>
6 18
 
7 19
 <script>
8 20
 import { mapGetters } from 'vuex'
21
+import { getStatTotal } from '@/api/stat'
9 22
 
10 23
 export default {
11 24
   name: 'Dashboard',
25
+  components: {
26
+    Statistic: () => import('./components/Statistic.vue')
27
+  },
12 28
   computed: {
13 29
     ...mapGetters(['name'])
30
+  },
31
+  data() {
32
+    return {
33
+      total: {}
34
+    }
35
+  },
36
+  mounted() {
37
+    this.statTotal()
38
+  },
39
+  methods: {
40
+    statTotal() {
41
+      getStatTotal().then(res => {
42
+        this.total = res
43
+      })
44
+    }
14 45
   }
15 46
 }
16 47
 </script>

+ 20
- 0
yarn.lock Целия файл

@@ -4176,6 +4176,14 @@ ecc-jsbn@~0.1.1:
4176 4176
     jsbn "~0.1.0"
4177 4177
     safer-buffer "^2.1.0"
4178 4178
 
4179
+echarts@^5.3.0:
4180
+  version "5.3.0"
4181
+  resolved "https://registry.npmmirror.com/echarts/-/echarts-5.3.0.tgz#39342fcf0f763413fecd9d2afd1c415163de694d"
4182
+  integrity sha512-zENufmwFE6WjM+24tW3xQq4ICqQtI0CGj4bDVDNd3BK3LtaA/5wBp+64ykIyKy3QElz0cieKqSYP4FX9Lv9MwQ==
4183
+  dependencies:
4184
+    tslib "2.3.0"
4185
+    zrender "5.3.0"
4186
+
4179 4187
 editorconfig@^0.15.3:
4180 4188
   version "0.15.3"
4181 4189
   resolved "https://registry.npmmirror.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5"
@@ -10811,6 +10819,11 @@ tsconfig@^7.0.0:
10811 10819
     strip-bom "^3.0.0"
10812 10820
     strip-json-comments "^2.0.0"
10813 10821
 
10822
+tslib@2.3.0:
10823
+  version "2.3.0"
10824
+  resolved "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
10825
+  integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
10826
+
10814 10827
 tslib@^1.9.0:
10815 10828
   version "1.14.1"
10816 10829
   resolved "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@@ -11760,3 +11773,10 @@ yorkie@^2.0.0:
11760 11773
     is-ci "^1.0.10"
11761 11774
     normalize-path "^1.0.0"
11762 11775
     strip-indent "^2.0.0"
11776
+
11777
+zrender@5.3.0:
11778
+  version "5.3.0"
11779
+  resolved "https://registry.npmmirror.com/zrender/-/zrender-5.3.0.tgz#297c05dc2521362816c4ddced10a1e306646bbc8"
11780
+  integrity sha512-Ln2QB5uqI1ftNYMtCRxd+XDq6MOttLgam2tmhKAVA+j0ko47UT+VNlDvKTkqe4K2sJhBvB0EhYNLebqlCTjatQ==
11781
+  dependencies:
11782
+    tslib "2.3.0"