Kaynağa Gözat

数据大屏完成

yuhao 2 yıl önce
ebeveyn
işleme
6958a10967

+ 5 - 0
.env.development

@@ -0,0 +1,5 @@
1
+#开发环境
2
+
3
+#接口地址
4
+//.env.development文件
5
+VUE_APP_SERVER_URL = 'https://test-api.ijolijoli.com/'

+ 2 - 0
.env.production

@@ -0,0 +1,2 @@
1
+//.env.production文件
2
+VUE_APP_SERVER_URL = 'https://api.ijolijoli.com/'

+ 2 - 0
.env.test

@@ -0,0 +1,2 @@
1
+//.env.test
2
+VUE_APP_SERVER_URL = 'https://test-api.ijolijoli.com/'

+ 23 - 0
.gitignore

@@ -0,0 +1,23 @@
1
+.DS_Store
2
+node_modules
3
+/dist
4
+
5
+
6
+# local env files
7
+.env.local
8
+.env.*.local
9
+
10
+# Log files
11
+npm-debug.log*
12
+yarn-debug.log*
13
+yarn-error.log*
14
+pnpm-debug.log*
15
+
16
+# Editor directories and files
17
+.idea
18
+.vscode
19
+*.suo
20
+*.ntvs*
21
+*.njsproj
22
+*.sln
23
+*.sw?

+ 19 - 0
README.md

@@ -0,0 +1,19 @@
1
+# daping
2
+
3
+## Project setup
4
+```
5
+npm install
6
+```
7
+
8
+### Compiles and hot-reloads for development
9
+```
10
+npm run serve
11
+```
12
+
13
+### Compiles and minifies for production
14
+```
15
+npm run build
16
+```
17
+
18
+### Customize configuration
19
+See [Configuration Reference](https://cli.vuejs.org/config/).

+ 5 - 0
babel.config.js

@@ -0,0 +1,5 @@
1
+module.exports = {
2
+  presets: [
3
+    '@vue/cli-plugin-babel/preset'
4
+  ]
5
+}

+ 19 - 0
jsconfig.json

@@ -0,0 +1,19 @@
1
+{
2
+  "compilerOptions": {
3
+    "target": "es5",
4
+    "module": "esnext",
5
+    "baseUrl": "./",
6
+    "moduleResolution": "node",
7
+    "paths": {
8
+      "@/*": [
9
+        "src/*"
10
+      ]
11
+    },
12
+    "lib": [
13
+      "esnext",
14
+      "dom",
15
+      "dom.iterable",
16
+      "scripthost"
17
+    ]
18
+  }
19
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 8011 - 0
package-lock.json


+ 34 - 0
package.json

@@ -0,0 +1,34 @@
1
+{
2
+  "name": "daping",
3
+  "version": "0.1.0",
4
+  "private": true,
5
+  "scripts": {
6
+    "serve": "vue-cli-service serve",
7
+    "build": "vue-cli-service build"
8
+  },
9
+  "dependencies": {
10
+    "axios": "^0.27.2",
11
+    "core-js": "^3.8.3",
12
+    "echarts": "^5.3.3",
13
+    "element-ui": "^2.15.9",
14
+    "vue": "^2.6.14",
15
+    "vue-router": "^3.5.1",
16
+    "vuex": "^3.6.2"
17
+  },
18
+  "devDependencies": {
19
+    "@vue/cli-plugin-babel": "~5.0.0",
20
+    "@vue/cli-plugin-router": "~5.0.0",
21
+    "@vue/cli-plugin-vuex": "~5.0.0",
22
+    "@vue/cli-service": "~5.0.0",
23
+    "less": "^4.1.3",
24
+    "less-loader": "^11.0.0",
25
+    "postcss-pxtorem": "^5.1.1",
26
+    "vue-socket.io": "^3.0.10",
27
+    "vue-template-compiler": "^2.6.14"
28
+  },
29
+  "browserslist": [
30
+    "> 1%",
31
+    "last 2 versions",
32
+    "not dead"
33
+  ]
34
+}

+ 9 - 0
postcss.config.js

@@ -0,0 +1,9 @@
1
+module.exports={
2
+    plugins: [
3
+        require('postcss-pxtorem')({
4
+          rootValue : 16, // 换算的基数
5
+          selectorBlackList  : [], // 忽略转换正则匹配项 列入一些ui库, ['.el'] 就是忽略elementUI库
6
+          propList   : ['*'],
7
+        }),
8
+      ]
9
+}

BIN
public/favicon.ico


+ 29 - 0
public/index.html

@@ -0,0 +1,29 @@
1
+<!DOCTYPE html>
2
+<html lang="">
3
+
4
+<head>
5
+  <meta charset="utf-8">
6
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+  <meta name="viewport" content="width=device-width,initial-scale=1.0">
8
+  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
9
+  <title>
10
+    <%= htmlWebpackPlugin.options.title %>
11
+  </title>
12
+  <style>
13
+    body {
14
+      margin: 0;
15
+      padding: 0;
16
+    }
17
+  </style>
18
+</head>
19
+
20
+<body>
21
+  <noscript>
22
+    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
23
+        Please enable it to continue.</strong>
24
+  </noscript>
25
+  <div id="app"></div>
26
+  <!-- built files will be auto injected -->
27
+</body>
28
+
29
+</html>

+ 20 - 0
src/App.vue

@@ -0,0 +1,20 @@
1
+<template>
2
+<div>
3
+  <demo02></demo02>
4
+</div>
5
+</template>
6
+<script>
7
+import demo02 from './views/demo02.vue'
8
+export default{
9
+  components: { demo02 },
10
+  data(){
11
+    return{
12
+
13
+    }
14
+  }
15
+}
16
+</script>
17
+
18
+<style lang="less">
19
+
20
+</style>

+ 15 - 0
src/api/index.js

@@ -0,0 +1,15 @@
1
+import request from "../util/request";
2
+
3
+export const getStoreList = ()=>{
4
+    return request({
5
+        url:'/v2/api/large/store',
6
+        method:'get',
7
+    })
8
+}
9
+export const getData = (params)=>{
10
+    return request({
11
+        url:'/v2/api/large/statistics',
12
+        method:'get',
13
+        params
14
+    })
15
+}

+ 19 - 0
src/main.js

@@ -0,0 +1,19 @@
1
+import Vue from 'vue'
2
+import App from './App.vue'
3
+import router from './router'
4
+import store from './store'
5
+import axios from 'axios'
6
+// 导入echarts
7
+import * as Echarts from 'echarts' 
8
+import ElementUI from 'element-ui'
9
+import 'element-ui/lib/theme-chalk/index.css'
10
+import '@/util/rem'
11
+Vue.prototype.$axios = axios
12
+Vue.prototype.$echarts = Echarts
13
+Vue.config.productionTip = false
14
+Vue.use(ElementUI)
15
+new Vue({
16
+  router,
17
+  store,
18
+  render: h => h(App)
19
+}).$mount('#app')

+ 14 - 0
src/router/index.js

@@ -0,0 +1,14 @@
1
+import Vue from 'vue'
2
+import VueRouter from 'vue-router'
3
+
4
+Vue.use(VueRouter)
5
+
6
+const routes = [
7
+
8
+]
9
+
10
+const router = new VueRouter({
11
+  routes
12
+})
13
+
14
+export default router

+ 17 - 0
src/store/index.js

@@ -0,0 +1,17 @@
1
+import Vue from 'vue'
2
+import Vuex from 'vuex'
3
+
4
+Vue.use(Vuex)
5
+
6
+export default new Vuex.Store({
7
+  state: {
8
+  },
9
+  getters: {
10
+  },
11
+  mutations: {
12
+  },
13
+  actions: {
14
+  },
15
+  modules: {
16
+  }
17
+})

+ 66 - 0
src/util/Resize.vue

@@ -0,0 +1,66 @@
1
+<template>
2
+  <div id="resize" :ref="ref">
3
+    <template v-if="ready">
4
+      <slot></slot>
5
+    </template>
6
+  </div>
7
+</template>
8
+<style>
9
+#resize {
10
+  position: fixed;
11
+  top: 0px;
12
+  left: 0px;
13
+  overflow: hidden;
14
+  transform-origin: left top;
15
+  z-index: 999;
16
+}
17
+</style>
18
+<script>
19
+import autoResize from "./autoResize";
20
+
21
+export default {
22
+  name: "DvFullScreenContainer",
23
+  mixins: [autoResize],
24
+  data() {
25
+    return {
26
+      ref: "full-screen-container",
27
+      allWidth: 0,
28
+      scale: 0,
29
+      datavRoot: "",
30
+      ready: false,
31
+    };
32
+  },
33
+  methods: {
34
+    afterAutoResizeMixinInit() {
35
+      const { initConfig, setAppScale } = this;
36
+
37
+      initConfig();
38
+
39
+      setAppScale();
40
+
41
+      this.ready = true;
42
+    },
43
+    initConfig() {
44
+      const { dom } = this;
45
+      const { width, height } = screen;
46
+
47
+      this.allWidth = width;
48
+
49
+      dom.style.width = `${width}px`;
50
+      dom.style.height = `${height}px`;
51
+    },
52
+    setAppScale() {
53
+      const { allWidth, dom } = this;
54
+
55
+      const currentWidth = document.body.clientWidth;
56
+
57
+      dom.style.transform = `scale(${currentWidth / allWidth})`;
58
+    },
59
+    onResize() {
60
+      const { setAppScale } = this;
61
+
62
+      setAppScale();
63
+    },
64
+  },
65
+};
66
+</script>

+ 86 - 0
src/util/autoResize.js

@@ -0,0 +1,86 @@
1
+import { debounce, observerDomResize } from '../util/index'
2
+
3
+export default {
4
+  data () {
5
+    return {
6
+      dom: '',
7
+
8
+      width: 0,
9
+      height: 0,
10
+
11
+      debounceInitWHFun: '',
12
+
13
+      domObserver: ''
14
+    }
15
+  },
16
+  methods: {
17
+    async autoResizeMixinInit () {
18
+      const { initWH, getDebounceInitWHFun, bindDomResizeCallback, afterAutoResizeMixinInit } = this
19
+
20
+      await initWH(false)
21
+
22
+      getDebounceInitWHFun()
23
+
24
+      bindDomResizeCallback()
25
+
26
+      if (typeof afterAutoResizeMixinInit === 'function') afterAutoResizeMixinInit()
27
+    },
28
+    initWH (resize = true) {
29
+      const { $nextTick, $refs, ref, onResize } = this
30
+
31
+      return new Promise(resolve => {
32
+        // eslint-disable-next-line no-unused-vars
33
+        $nextTick(_ => {
34
+          const dom = this.dom = $refs[ref]
35
+
36
+          this.width = dom ? dom.clientWidth : 0
37
+          this.height = dom ? dom.clientHeight : 0
38
+
39
+          if (!dom) {
40
+            console.warn('DataV: Failed to get dom node, component rendering may be abnormal!')
41
+          } else if (!this.width || !this.height) {
42
+            console.warn('DataV: Component width or height is 0px, rendering abnormality may occur!')
43
+          }
44
+
45
+          if (typeof onResize === 'function' && resize) onResize()
46
+
47
+          resolve()
48
+        })
49
+      })
50
+    },
51
+    getDebounceInitWHFun () {
52
+      const { initWH } = this
53
+
54
+      this.debounceInitWHFun = debounce(100, initWH)
55
+    },
56
+    bindDomResizeCallback () {
57
+      const { dom, debounceInitWHFun } = this
58
+
59
+      this.domObserver = observerDomResize(dom, debounceInitWHFun)
60
+
61
+      window.addEventListener('resize', debounceInitWHFun)
62
+    },
63
+    unbindDomResizeCallback () {
64
+      let { domObserver, debounceInitWHFun } = this
65
+
66
+      if (!domObserver) return
67
+
68
+      domObserver.disconnect()
69
+      domObserver.takeRecords()
70
+      domObserver = null
71
+
72
+      window.removeEventListener('resize', debounceInitWHFun)
73
+    }
74
+  },
75
+  mounted () {
76
+    const { autoResizeMixinInit } = this
77
+
78
+    autoResizeMixinInit()
79
+  },
80
+  beforeDestroy () {
81
+    const { unbindDomResizeCallback } = this
82
+
83
+    unbindDomResizeCallback()
84
+  }
85
+}
86
+

+ 130 - 0
src/util/flexible.js

@@ -0,0 +1,130 @@
1
+
2
+;(function(win, lib) {
3
+    var doc = win.document;
4
+    var docEl = doc.documentElement;
5
+    var metaEl = doc.querySelector('meta[name="viewport"]');
6
+    var flexibleEl = doc.querySelector('meta[name="flexible"]');
7
+    var dpr = 0;
8
+    var scale = 0;
9
+    var tid;
10
+    var flexible = lib.flexible || (lib.flexible = {});
11
+
12
+    if (metaEl) {
13
+        console.warn('将根据已有的meta标签来设置缩放比例');
14
+        var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
15
+        if (match) {
16
+            scale = parseFloat(match[1]);
17
+            dpr = parseInt(1 / scale);
18
+        }
19
+    } else if (flexibleEl) {
20
+        var content = flexibleEl.getAttribute('content');
21
+        if (content) {
22
+            var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
23
+            var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
24
+            if (initialDpr) {
25
+                dpr = parseFloat(initialDpr[1]);
26
+                scale = parseFloat((1 / dpr).toFixed(2));
27
+            }
28
+            if (maximumDpr) {
29
+                dpr = parseFloat(maximumDpr[1]);
30
+                scale = parseFloat((1 / dpr).toFixed(2));
31
+            }
32
+        }
33
+    }
34
+
35
+    if (!dpr && !scale) {
36
+        var isAndroid = win.navigator.appVersion.match(/android/gi);
37
+        var isIPhone = win.navigator.appVersion.match(/iphone/gi);
38
+        var devicePixelRatio = win.devicePixelRatio;
39
+        if (isIPhone) {
40
+            // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
41
+            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
42
+                dpr = 3;
43
+            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
44
+                dpr = 2;
45
+            } else {
46
+                dpr = 1;
47
+            }
48
+        } else {
49
+            // 其他设备下,仍旧使用1倍的方案
50
+            dpr = 1;
51
+        }
52
+        scale = 1 / dpr;
53
+    }
54
+
55
+    docEl.setAttribute('data-dpr', dpr);
56
+    if (!metaEl) {
57
+        metaEl = doc.createElement('meta');
58
+        metaEl.setAttribute('name', 'viewport');
59
+        metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
60
+        if (docEl.firstElementChild) {
61
+            docEl.firstElementChild.appendChild(metaEl);
62
+        } else {
63
+            var wrap = doc.createElement('div');
64
+            wrap.appendChild(metaEl);
65
+            doc.write(wrap.innerHTML);
66
+        }
67
+    }
68
+
69
+    function refreshRem() {
70
+        var width = docEl.getBoundingClientRect().width;
71
+        // if (width / dpr > 540) {
72
+        //     width = 540 * dpr;
73
+        // }
74
+        if (width / dpr < 810) {
75
+          width = 810 * dpr;
76
+        }
77
+        if (width / dpr < 1300) {
78
+          width = 1300 * dpr;
79
+        }
80
+        if (width / dpr < 1920) {
81
+          width = 1920 * dpr;
82
+        }
83
+          if (width / dpr < 2560) {
84
+          width = 2560 * dpr;
85
+        }
86
+        var rem = width / 10;
87
+        docEl.style.fontSize = rem + "px";
88
+        flexible.rem = win.rem = rem;
89
+      }
90
+    
91
+    win.addEventListener('resize', function() {
92
+        clearTimeout(tid);
93
+        tid = setTimeout(refreshRem, 300);
94
+    }, false);
95
+    win.addEventListener('pageshow', function(e) {
96
+        if (e.persisted) {
97
+            clearTimeout(tid);
98
+            tid = setTimeout(refreshRem, 300);
99
+        }
100
+    }, false);
101
+
102
+    if (doc.readyState === 'complete') {
103
+        doc.body.style.fontSize = 12 * dpr + 'px';
104
+    } else {
105
+        doc.addEventListener('DOMContentLoaded', function(e) {
106
+            doc.body.style.fontSize = 12 * dpr + 'px';
107
+        }, false);
108
+    }
109
+
110
+
111
+    refreshRem();
112
+
113
+    flexible.dpr = win.dpr = dpr;
114
+    flexible.refreshRem = refreshRem;
115
+    flexible.rem2px = function(d) {
116
+        var val = parseFloat(d) * this.rem;
117
+        if (typeof d === 'string' && d.match(/rem$/)) {
118
+            val += 'px';
119
+        }
120
+        return val;
121
+    }
122
+    flexible.px2rem = function(d) {
123
+        var val = parseFloat(d) / this.rem;
124
+        if (typeof d === 'string' && d.match(/px$/)) {
125
+            val += 'rem';
126
+        }
127
+        return val;
128
+    }
129
+
130
+})(window, window['lib'] || (window['lib'] = {}));

+ 48 - 0
src/util/index.js

@@ -0,0 +1,48 @@
1
+export function randomExtend (minNum, maxNum) {
2
+    if (arguments.length === 1) {
3
+      return parseInt(Math.random() * minNum + 1, 10)
4
+    } else {
5
+      return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)
6
+    }
7
+  }
8
+  
9
+  export function debounce (delay, callback) {
10
+    let lastTime
11
+  
12
+    return function () {
13
+      clearTimeout(lastTime)
14
+  
15
+      const [that, args] = [this, arguments]
16
+  
17
+      lastTime = setTimeout(() => {
18
+        callback.apply(that, args)
19
+      }, delay)
20
+    }
21
+  }
22
+  
23
+  export function observerDomResize (dom, callback) {
24
+    const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
25
+  
26
+    const observer = new MutationObserver(callback)
27
+  
28
+    observer.observe(dom, { attributes: true, attributeFilter: ['style'], attributeOldValue: true })
29
+  
30
+    return observer
31
+  }
32
+  
33
+  export function getPointDistance (pointOne, pointTwo) {
34
+    const minusX = Math.abs(pointOne[0] - pointTwo[0])
35
+  
36
+    const minusY = Math.abs(pointOne[1] - pointTwo[1])
37
+  
38
+    return Math.sqrt(minusX * minusX + minusY * minusY)
39
+  }
40
+  
41
+  export function uuid (hasHyphen) {
42
+    return (hasHyphen ? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' : 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx').replace(/[xy]/g, function (c) {
43
+          const r = Math.random() * 16 | 0
44
+          const v = c == 'x' ? r : (r & 0x3 | 0x8)
45
+          return v.toString(16)
46
+    })
47
+  }
48
+  

+ 16 - 0
src/util/rem.js

@@ -0,0 +1,16 @@
1
+// 基准大小
2
+const baseSize = 16
3
+// 设置 rem 函数
4
+function setRem () {
5
+  // 当前页面宽度相对于 1920 宽的缩放比例,可根据自己需要修改。
6
+  const scale = document.documentElement.clientWidth / 1920
7
+  // 设置页面根节点字体大小, 字体大小最小为12
8
+  let fontSize = (baseSize * Math.min(scale, 2))>12 ? (baseSize * Math.min(scale, 2)): 12
9
+  document.documentElement.style.fontSize = fontSize + 'px'
10
+}
11
+//初始化
12
+setRem()
13
+//改变窗口大小时重新设置 rem,这里最好加上节流
14
+window.onresize = function () {
15
+  setRem()
16
+}

+ 7 - 0
src/util/request.js

@@ -0,0 +1,7 @@
1
+import axios from 'axios'
2
+
3
+const request = axios.create({
4
+    baseURL:'https://api.ijolijoli.com/'
5
+    // baseURL:'https://test-api.ijolijoli.com/'
6
+})
7
+export default request

+ 92 - 0
src/views/cardExpend/cardExpend.vue

@@ -0,0 +1,92 @@
1
+<template>
2
+  <div class="chinaMap">
3
+    <div class="map" ref="MapMountNode"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: ["listData"],
10
+  data() {
11
+    return {};
12
+  },
13
+  methods: {
14
+    //先定义个方法
15
+    myEcharts() {
16
+      //把echarts绑定到显示元素上
17
+      const myChart = this.$echarts.init(this.$refs.MapMountNode);
18
+      //设置图表属性
19
+      //   经营数据
20
+      const option = {
21
+        color: ["#42d3a7"],
22
+        title: {
23
+          text: "次卡消耗数据",
24
+          // textStyle: {
25
+          //   color: "#6d767e",
26
+          // },
27
+        },
28
+
29
+        grid: {
30
+          left: 55,
31
+        },
32
+        xAxis: {
33
+          type: "category",
34
+          data: ["次卡购买总次数", "次卡剩余人数", "此卡剩余总数"],
35
+          axisLabel: { interval: 0, rotate: 30 },
36
+        },
37
+        yAxis: {
38
+          type: "value",
39
+        },
40
+        series: [
41
+          {
42
+            data: [
43
+              this.listData.time_card_time,
44
+              this.listData.time_card_residue_people,
45
+              this.listData.time_card_residue,
46
+            ],
47
+            type: "bar",
48
+            itemStyle: {
49
+              normal: {
50
+                label: {
51
+                  show: true, //开启显示数值
52
+                  position: "top", //数值在上方显示
53
+                  textStyle: {
54
+                    //数值样式
55
+                    color: "#9b9ca2", //字体颜色
56
+                    fontSize: 14, //字体大小
57
+                  },
58
+                },
59
+              },
60
+            },
61
+          },
62
+        ],
63
+      };
64
+      //数据绑定到表格
65
+      myChart.setOption(option);
66
+      window.addEventListener("resize", function () {
67
+        myChart.resize(); //myChart指自己定义的echartsDom对象
68
+      });
69
+    },
70
+  },
71
+  // 监听父组件传过来的值的变化
72
+  watch: {
73
+    listData: {
74
+      handler(val) {
75
+        this.myEcharts();
76
+      },
77
+    },
78
+  },
79
+  mounted() {
80
+    this.myEcharts();
81
+  },
82
+};
83
+</script>
84
+
85
+<style scoped>
86
+.map {
87
+  /* width: 280px; */
88
+  width: 99%;
89
+  height: 30vh;
90
+  /* border: 1px solid saddlebrown; */
91
+}
92
+</style>

+ 461 - 0
src/views/demo02.vue

@@ -0,0 +1,461 @@
1
+<template>
2
+  <!-- <Resize> -->
3
+  <div class="boxx">
4
+    <!-- 标题 -->
5
+    <div class="title">jolijoli实时数据大屏</div>
6
+    <div class="box">
7
+      <!-- 图表 -->
8
+      <div class="pic">
9
+        <!-- 左边部分 -->
10
+        <div class="left">
11
+          <div class="left-top">
12
+            <el-card
13
+              ><div class="btn">
14
+                <el-button
15
+                  :class="{ bgc: activeClass == 0 }"
16
+                  size="small"
17
+                  type="info"
18
+                  @click="yesterday(0)"
19
+                  :disabled="activeClass == 0"
20
+                  >昨天</el-button
21
+                >
22
+                <el-button
23
+                  size="small"
24
+                  type="info"
25
+                  @click="thisWeek(1)"
26
+                  :class="{ bgc: activeClass == 1 }"
27
+                  :disabled="activeClass == 1"
28
+                  >本周</el-button
29
+                >
30
+                <el-button
31
+                  size="small"
32
+                  type="info"
33
+                  @click="thisMonth(2)"
34
+                  :class="{ bgc: activeClass == 2 }"
35
+                  :disabled="activeClass == 2"
36
+                  >本月</el-button
37
+                >
38
+                <!-- 选择店铺 -->
39
+                <div class="selectStore">
40
+                  <!-- 日期选择 -->
41
+                  <el-date-picker
42
+                    v-model="value1"
43
+                    type="daterange"
44
+                    range-separator="至"
45
+                    start-placeholder="开始日期"
46
+                    end-placeholder="结束日期"
47
+                    size="mini"
48
+                    @change="selectTime"
49
+                  >
50
+                  </el-date-picker>
51
+                  <!-- 选择店铺 -->
52
+                  <div>
53
+                    <el-dropdown class="Store" @command="selectStore">
54
+                      <el-button type="info" size="small">
55
+                        {{ store
56
+                        }}<i class="el-icon-arrow-down el-icon--right"></i>
57
+                      </el-button>
58
+                      <el-dropdown-menu slot="dropdown">
59
+                        <el-dropdown-item
60
+                          :command="item.store_name"
61
+                          v-for="(item, index) in storeList"
62
+                          :key="index"
63
+                          >{{ item.store_name }}</el-dropdown-item
64
+                        >
65
+                      </el-dropdown-menu>
66
+                    </el-dropdown>
67
+                    <el-button
68
+                      :class="{ refresh, bgc: istrue }"
69
+                      size="small"
70
+                      type="info"
71
+                      @click="refresh"
72
+                      :disabled="istrue"
73
+                      >{{ button }}</el-button
74
+                    >
75
+                  </div>
76
+                </div>
77
+              </div></el-card
78
+            >
79
+          </div>
80
+          <div class="left-center1">
81
+            <el-card
82
+              ><div><manage v-if="listData" :listData="listData"></manage></div
83
+            ></el-card>
84
+          </div>
85
+          <div class="left-center2">
86
+            <el-card
87
+              ><project-data v-if="listData" :listData="listData"></project-data
88
+            ></el-card>
89
+          </div>
90
+          <!-- <div class="left-bottom"><el-card></el-card></div> -->
91
+        </div>
92
+        <!-- 中间部分 -->
93
+        <div class="center">
94
+          <div class="center-top">
95
+            <el-card
96
+              ><programAmount
97
+                v-if="listData"
98
+                :listData="listData"
99
+              ></programAmount
100
+            ></el-card>
101
+          </div>
102
+          <div class="center-bottom">
103
+            <el-card
104
+              ><div>
105
+                <product-ratio
106
+                  v-if="listData"
107
+                  :listData="listData.product_ratio"
108
+                ></product-ratio
109
+                ><project-ratio
110
+                  v-if="listData"
111
+                  :listData="listData.project_proportion"
112
+                ></project-ratio></div
113
+            ></el-card>
114
+          </div>
115
+        </div>
116
+        <!-- 右边部分 -->
117
+        <div class="right">
118
+          <div class="right-top">
119
+            <el-card
120
+              ><recharge-data
121
+                v-if="listData"
122
+                :listData="listData"
123
+              ></recharge-data
124
+            ></el-card>
125
+          </div>
126
+          <div class="right-center">
127
+            <el-card
128
+              ><cardExpend v-if="listData" :listData="listData"></cardExpend
129
+            ></el-card>
130
+          </div>
131
+          <div class="right-bottom">
132
+            <el-card>
133
+              <productData v-if="listData" :listData="listData"></productData
134
+            ></el-card>
135
+          </div>
136
+        </div>
137
+      </div>
138
+    </div>
139
+    <!-- </Resize> -->
140
+  </div>
141
+</template>
142
+
143
+<script>
144
+import Resize from "../util/Resize.vue";
145
+import manage from "./manage/manage.vue";
146
+import projectData from "./projectData/projectData.vue";
147
+import programAmount from "./programAmount/programAmount.vue";
148
+import projectRatio from "./projectRatio/projectRatio.vue";
149
+import productRatio from "./productRatio/productRatio.vue";
150
+import rechargeData from "./rechargeData/rechargeData.vue";
151
+import cardExpend from "./cardExpend/cardExpend.vue";
152
+import productData from "./productData/productData.vue";
153
+import { getStoreList, getData } from "../api/index"; //获取店铺列表和数据大屏数据
154
+export default {
155
+  components: {
156
+    Resize,
157
+    manage,
158
+    projectData,
159
+    programAmount,
160
+    projectRatio,
161
+    productRatio,
162
+    rechargeData,
163
+    cardExpend,
164
+    productData,
165
+  },
166
+  data() {
167
+    return {
168
+      store: "全部店铺",
169
+      storeList: "", //店铺列表
170
+      storeId: "", //当前店铺id
171
+      listData: "", //项目总数据
172
+      flag: false, //获取数据开关阀
173
+      start_time: "", //开始时间
174
+      end_time: "", //结束时间
175
+      value1: [new Date(), new Date()], //选择日期当前时间
176
+      button: "刷新", //按钮提交文案
177
+      istrue: false, //刷新禁用
178
+      refreshInfo: "秒",
179
+      count: 10, //点击刷新倒计时
180
+      activeClass: 3, //按钮动态类
181
+    };
182
+  },
183
+  methods: {
184
+    // 选择店铺
185
+    async selectStore(e) {
186
+      this.store = e;
187
+      this.storeList.filter((item) => {
188
+        if (item.store_name == e) {
189
+          this.storeId = item.id;
190
+        }
191
+      });
192
+      this.getListData();
193
+    },
194
+    // 选择昨天
195
+    yesterday(e) {
196
+      this.activeClass = e;
197
+      var startTime = this.getDay1(-1, "-") + " 00:00:00"; //    -1 代表前一天,-2前两天...
198
+      var endTime = this.getDay1(-1, "-") + " 23:59:59"; //    -1 代表前一天,-2前两天...
199
+      this.start_time = Date.parse(startTime) / 1000;
200
+      this.end_time = Date.parse(endTime) / 1000;
201
+      var startTime1 = this.getDay1(-1, "-");
202
+      var endTime1 = this.getDay1(-1, "-");
203
+      this.$set(this.value1, 0, startTime1);
204
+      this.$set(this.value1, 1, endTime1);
205
+      this.getListData();
206
+    },
207
+    //本周
208
+    thisWeek(e) {
209
+      this.activeClass = e;
210
+      var now = new Date();
211
+      var nowDayOfWeek = now.getDay() == 0 ? 6 : now.getDay() - 1;
212
+      var startTime =
213
+        this.getDateStr(
214
+          new Date(now.getTime() - nowDayOfWeek * 24 * 60 * 60 * 1000)
215
+        ) + " 00:00:00";
216
+      var endTime = this.getDateStr(now) + " 23:59:59";
217
+      this.start_time = Date.parse(startTime) / 1000;
218
+      this.end_time = Date.parse(endTime) / 1000;
219
+      var startTime1 = this.getDateStr(
220
+        new Date(now.getTime() - nowDayOfWeek * 24 * 60 * 60 * 1000)
221
+      );
222
+      var endTime1 = this.getDateStr(now);
223
+      this.$set(this.value1, 0, startTime1);
224
+      this.$set(this.value1, 1, endTime1);
225
+      this.getListData();
226
+    },
227
+    // 本月
228
+    thisMonth(e) {
229
+      this.activeClass = e;
230
+      var now = new Date();
231
+      var nowDay = now.getDate() - 1;
232
+      var startTime =
233
+        this.getDateStr(
234
+          new Date(now.getTime() - nowDay * 24 * 60 * 60 * 1000)
235
+        ) + " 00:00:00";
236
+      var endTime = this.getDateStr(now) + " 23:59:59";
237
+      this.start_time = Date.parse(startTime) / 1000;
238
+      this.end_time = Date.parse(endTime) / 1000;
239
+      var startTime1 = this.getDateStr(
240
+        new Date(now.getTime() - nowDay * 24 * 60 * 60 * 1000)
241
+      );
242
+      var endTime1 = this.getDateStr(now);
243
+      this.$set(this.value1, 0, startTime1);
244
+      this.$set(this.value1, 1, endTime1);
245
+      this.getListData();
246
+    },
247
+    // 封装获取时间
248
+    getDateStr(now) {
249
+      var year = now.getFullYear(); // 年
250
+      var month = now.getMonth() + 1; // 月
251
+      var day = now.getDate(); // 日
252
+      if (day < 10) {
253
+        day = "0" + day;
254
+      }
255
+
256
+      if (month < 10) {
257
+        month = "0" + month;
258
+      }
259
+      return year + "-" + month + "-" + day;
260
+    },
261
+    // 封装获取昨天时间
262
+    getDay1(num, str) {
263
+      var today = new Date();
264
+      var nowTime = today.getTime();
265
+      var ms = 24 * 3600 * 1000 * num;
266
+      today.setTime(parseInt(nowTime + ms));
267
+      var oYear = today.getFullYear();
268
+      var oMoth = (today.getMonth() + 1).toString();
269
+      if (oMoth.length <= 1) oMoth = "0" + oMoth;
270
+      var oDay = today.getDate().toString();
271
+      if (oDay.length <= 1) oDay = "0" + oDay;
272
+      return oYear + str + oMoth + str + oDay;
273
+    },
274
+    // 获取图表数据
275
+    async getListData() {
276
+      let res = await getData({
277
+        store_id: this.storeId || "",
278
+        start_time: this.start_time,
279
+        end_time: this.end_time,
280
+      });
281
+      console.log(res);
282
+      this.listData = res.data.data;
283
+    },
284
+    // 获取店铺列表
285
+    async getStoreList() {
286
+      let res = await getStoreList();
287
+      let allStore = { id: "", store_name: "全部店铺" };
288
+      res.data.data.unshift(allStore);
289
+      this.storeList = res.data.data;
290
+    },
291
+    // 选择时间
292
+    selectTime(e) {
293
+      var startTime = this.getDateStr(e[0]) + " 00:00:00";
294
+      var endTime = this.getDateStr(e[1]) + " 00:00:00";
295
+      var start_time = Date.parse(startTime) / 1000;
296
+      var end_time = Date.parse(endTime) / 1000;
297
+      this.start_time = start_time;
298
+      this.end_time = end_time;
299
+      this.getListData();
300
+    },
301
+    // 刷新页面
302
+    refresh() {
303
+      this.getListData();
304
+      this.istrue = true;
305
+      let interval = setInterval(() => {
306
+        this.count--;
307
+        this.button = this.count + this.refreshInfo;
308
+        if (this.count == 0) {
309
+          clearInterval(interval);
310
+          this.istrue = false;
311
+          this.count = 10;
312
+          this.button = "刷新";
313
+        }
314
+      }, 1000);
315
+    },
316
+  },
317
+  async created() {
318
+    // 获取店铺列表
319
+    this.getStoreList();
320
+    // 获取当天时间
321
+    var now = new Date();
322
+    var endTime = this.getDateStr(now) + " 23:59:59";
323
+    var startTime = this.getDateStr(now) + " 00:00:00";
324
+    var start_time = Date.parse(startTime) / 1000;
325
+    var end_time = Date.parse(endTime) / 1000;
326
+    this.start_time = start_time;
327
+    this.end_time = end_time;
328
+    //   获取当天所有店铺数据
329
+    let res = await getData({
330
+      store_id: "",
331
+      start_time: start_time,
332
+      end_time: end_time,
333
+    });
334
+    this.listData = res.data.data;
335
+    this.flag = true;
336
+  },
337
+};
338
+</script>
339
+
340
+<style scoped lang='less'>
341
+.title {
342
+  font-size: 30px;
343
+  font-weight: 700;
344
+  text-align: center;
345
+  background-color: #f0f0f0;
346
+  color: #fa7d22;
347
+  height: 60px;
348
+  line-height: 60px;
349
+  width: 100%;
350
+}
351
+.box {
352
+  width: 100%;
353
+  height: 93%;
354
+  background-color: #f0f0f0;
355
+  .pic {
356
+    width: 100%;
357
+    height: 87%;
358
+    display: flex;
359
+    .left {
360
+      width: 22%;
361
+      height: 100%;
362
+      margin-right: 15px;
363
+      margin-left: 15px;
364
+      .left-top {
365
+        width: 100%;
366
+        height: 24%;
367
+        .el-card {
368
+          .btn {
369
+            button.el-button.el-button--info.el-button--small {
370
+              background-color: #fa7d22;
371
+              border: #fa7d22;
372
+            }
373
+            .selectStore {
374
+              margin-top: 14px;
375
+              /deep/.el-range-editor--mini.el-input__inner {
376
+                height: 30px;
377
+                width: 290px;
378
+                border: 1px solid #fa7d22;
379
+              }
380
+              .Store {
381
+                margin-top: 14px;
382
+                margin-right: 14px;
383
+              }
384
+              .refresh {
385
+                margin-top: 14px;
386
+              }
387
+            }
388
+          }
389
+        }
390
+      }
391
+      .left-center1 {
392
+        width: 100%;
393
+        height: 43%;
394
+        margin-top: 15px;
395
+      }
396
+      .left-center2 {
397
+        width: 100%;
398
+        height: 43%;
399
+        margin-top: 15px;
400
+      }
401
+      //   .left-bottom {
402
+      //     width: 100%;
403
+      //     height: 25%;
404
+      //     margin-top: 15px;
405
+      //   }
406
+    }
407
+    .center {
408
+      width: 50%;
409
+      height: 100%;
410
+      margin-right: 15px;
411
+      .center-top {
412
+        height: 73%;
413
+        width: 100%;
414
+      }
415
+      .center-bottom {
416
+        height: 39%;
417
+        width: 100%;
418
+        margin-top: 15px;
419
+        .el-card {
420
+          div {
421
+            display: flex;
422
+            justify-content: space-around;
423
+          }
424
+        }
425
+      }
426
+    }
427
+    .right {
428
+      width: 28%;
429
+      height: 100%;
430
+      margin-right: 15px;
431
+      .right-top {
432
+        width: 100%;
433
+        height: 39%;
434
+      }
435
+      .right-center {
436
+        height: 39%;
437
+        width: 100%;
438
+        margin-top: 15px;
439
+      }
440
+      .right-bottom {
441
+        height: 32%;
442
+        width: 100%;
443
+        margin-top: 15px;
444
+      }
445
+    }
446
+  }
447
+}
448
+.el-card {
449
+  width: 100%;
450
+  height: 100%;
451
+}
452
+// 点击选中后背景颜色
453
+.bgc {
454
+  background-color: #9fa0a6 !important;
455
+}
456
+.boxx {
457
+  width: 100vw;
458
+  height: 100vh;
459
+  background-color: #f0f0f0;
460
+}
461
+</style>

+ 96 - 0
src/views/manage/manage.vue

@@ -0,0 +1,96 @@
1
+<template>
2
+  <div class="chinaMap">
3
+    <div class="map" ref="MapMountNode"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: ["listData"],
10
+  data() {
11
+    return {
12
+      num1: 80,
13
+      num2: 100,
14
+    };
15
+  },
16
+  methods: {
17
+    //先定义个方法
18
+    myEcharts() {
19
+      //把echarts绑定到显示元素上
20
+      const myChart = this.$echarts.init(this.$refs.MapMountNode);
21
+      //设置图表属性
22
+      //   经营数据
23
+      const option = {
24
+        grid: {
25
+    left:55
26
+},
27
+        title: {
28
+          text: "经营数据金额",
29
+          // textStyle: {
30
+          //   color: "#6d767e",
31
+          // },
32
+        },
33
+        xAxis: {
34
+          type: "category",
35
+          data: ["收入金额", "项目付费金额", "次卡付费金额", "美妆收入金额", "充值收入金额"],
36
+          axisLabel: { interval: 0, rotate: 30 },
37
+        },
38
+        yAxis: {
39
+          type: "value",
40
+        },
41
+        series: [
42
+          {
43
+            data: [
44
+              this.listData.total_money,
45
+              this.listData.project_order,
46
+              this.listData.time_card_order,
47
+              this.listData.goods_order,
48
+              this.listData.recharge,
49
+            ],
50
+            type: "bar",
51
+            itemStyle: {
52
+              normal: {
53
+                label: {
54
+                  show: true, //开启显示数值
55
+                  position: "top", //数值在上方显示
56
+                  textStyle: {
57
+                    //数值样式
58
+                    color: "#9b9ca2", //字体颜色
59
+                    fontSize: 14, //字体大小
60
+                  },
61
+                },
62
+              },
63
+            },
64
+          },
65
+        ],
66
+      };
67
+      //数据绑定到表格
68
+      myChart.setOption(option);
69
+            window.addEventListener("resize", function () {
70
+        myChart.resize(); //myChart指自己定义的echartsDom对象
71
+      });
72
+    },
73
+  },
74
+    // 监听父组件传过来的值的变化
75
+  watch: {
76
+    listData: {
77
+      handler(val) {
78
+        this.myEcharts();
79
+      },
80
+    },
81
+  },
82
+  mounted() {
83
+    this.myEcharts();
84
+  },
85
+};
86
+</script>
87
+
88
+<style scoped>
89
+.map {
90
+  width: 110%;
91
+  height: 33vh;
92
+  /* width: 80%; */
93
+  /* height: 80%; */
94
+  /* border: 1px solid saddlebrown; */
95
+}
96
+</style>

+ 115 - 0
src/views/productData/productData.vue

@@ -0,0 +1,115 @@
1
+<template>
2
+  <div class="chinaMap">
3
+    <div class="map" ref="MapMountNode"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: ["listData"],
10
+  data() {
11
+    return {};
12
+  },
13
+  methods: {
14
+    //先定义个方法
15
+    myEcharts() {
16
+      //把echarts绑定到显示元素上
17
+      const myChart = this.$echarts.init(this.$refs.MapMountNode);
18
+      //设置图表属性
19
+      //   经营数据
20
+      const option = {
21
+        color: ["#91cc75"],
22
+        title: {
23
+          text: "产品数据",
24
+          // textStyle: {
25
+          //   color: "#6d767e",
26
+          // },
27
+        },
28
+        tooltip: {
29
+          trigger: "axis",
30
+          axisPointer: {
31
+            type: "shadow",
32
+          },
33
+        },
34
+        grid: {
35
+          left: "3%",
36
+          right: "4%",
37
+          bottom: "3%",
38
+          containLabel: true,
39
+        },
40
+        xAxis: [
41
+          {
42
+            type: "value",
43
+          },
44
+        ],
45
+        yAxis: [
46
+          {
47
+            type: "category",
48
+            axisTick: {
49
+              show: false,
50
+            },
51
+            data: ["购买订单数", "购买人数", "购买金额"],
52
+          },
53
+        ],
54
+        series: [
55
+          {
56
+            name: "数量",
57
+            type: "bar",
58
+            label: {
59
+              show: true,
60
+              position: "inside",
61
+            },
62
+            itemStyle: {
63
+              normal: {
64
+                label: {
65
+                  show: true, //开启显示数值
66
+                  position: "right", //数值在上方显示
67
+                  textStyle: {
68
+                    //数值样式
69
+                    color: "#9b9ca2", //字体颜色
70
+                    fontSize: 14, //字体大小
71
+                  },
72
+                },
73
+              },
74
+            },
75
+            emphasis: {
76
+              focus: "series",
77
+            },
78
+            data: [
79
+              this.listData.product_data.order,
80
+              this.listData.product_data.people,
81
+              this.listData.product_data.money,
82
+            ],
83
+          },
84
+        ],
85
+      };
86
+
87
+      //数据绑定到表格
88
+      myChart.setOption(option);
89
+      window.addEventListener("resize", function () {
90
+        myChart.resize(); //myChart指自己定义的echartsDom对象
91
+      });
92
+    },
93
+  },
94
+  // 监听父组件传过来的值的变化
95
+  watch: {
96
+    listData: {
97
+      handler(val) {
98
+        this.myEcharts();
99
+      },
100
+    },
101
+  },
102
+  mounted() {
103
+    this.myEcharts();
104
+  },
105
+};
106
+</script>
107
+
108
+<style scoped>
109
+.map {
110
+  width: 99%;
111
+  /* height: 280px; */
112
+  height: 20vh;
113
+  /* border: 1px solid saddlebrown; */
114
+}
115
+</style>

+ 88 - 0
src/views/productRatio/productRatio.vue

@@ -0,0 +1,88 @@
1
+<template>
2
+  <div class="chinaMap">
3
+    <div class="map" ref="MapMountNode"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: ["listData"],
10
+  data() {
11
+    return {
12
+      topList: [], //top10信息
13
+    };
14
+  },
15
+  methods: {
16
+    // 保存项目top10信息
17
+    getTopList() {
18
+      this.listData.forEach((item) => {
19
+        let arr = {};
20
+        arr.value = item.num;
21
+        arr.name = item.goods_name;
22
+        this.topList.push(arr);
23
+      });
24
+    },
25
+    //先定义个方法
26
+    myEcharts() {
27
+      //把echarts绑定到显示元素上
28
+      const myChart = this.$echarts.init(this.$refs.MapMountNode);
29
+      //设置图表属性
30
+      //   经营数据
31
+      const option = {
32
+        title: {
33
+          text: "TOP10产品占比",
34
+          left: "center",
35
+        },
36
+        tooltip: {
37
+          trigger: "item",
38
+          position: function (p, params, dom, rect, size) {
39
+            return (dom.style.transform = "translateZ(0)");
40
+          },
41
+        },
42
+        series: [
43
+          {
44
+            // name: "Access From",
45
+            type: "pie",
46
+            radius: "50%",
47
+            data: this.topList,
48
+            emphasis: {
49
+              itemStyle: {
50
+                shadowBlur: 10,
51
+                shadowOffsetX: 0,
52
+                shadowColor: "rgba(0, 0, 0, 0.5)",
53
+              },
54
+            },
55
+          },
56
+        ],
57
+      };
58
+      //数据绑定到表格
59
+      myChart.setOption(option);
60
+      window.addEventListener("resize", function () {
61
+        myChart.resize(); //myChart指自己定义的echartsDom对象
62
+      });
63
+    },
64
+  },
65
+  // 监听父组件传过来的值的变化
66
+  watch: {
67
+    listData: {
68
+      handler(val) {
69
+        this.myEcharts();
70
+      },
71
+    },
72
+  },
73
+  mounted() {
74
+    this.myEcharts();
75
+  },
76
+  created() {
77
+    this.getTopList();
78
+  },
79
+};
80
+</script>
81
+
82
+<style scoped>
83
+.map {
84
+  width: 420px;
85
+  height: 280px;
86
+  /* border: 1px solid saddlebrown; */
87
+}
88
+</style>

+ 137 - 0
src/views/programAmount/programAmount.vue

@@ -0,0 +1,137 @@
1
+<template>
2
+  <div class="chinaMap">
3
+    <div class="map" ref="MapMountNode"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: ["listData"],
10
+  data() {
11
+    return {};
12
+  },
13
+  methods: {
14
+    //先定义个方法
15
+    myEcharts() {
16
+      //把echarts绑定到显示元素上
17
+      const myChart = this.$echarts.init(this.$refs.MapMountNode);
18
+      //设置图表属性
19
+      //   经营数据
20
+      const option = {
21
+        color: ["#fcc524"],
22
+        title: {
23
+          text: "小程序用户量",
24
+          // textStyle: {
25
+          //   color: "#6d767e",
26
+          // },
27
+        },
28
+        tooltip: {
29
+          trigger: "axis",
30
+          axisPointer: {
31
+            type: "shadow",
32
+          },
33
+        },
34
+        grid: {
35
+          left: "3%",
36
+          right: "4%",
37
+          bottom: "3%",
38
+          containLabel: true,
39
+        },
40
+        xAxis: [
41
+          {
42
+            type: "value",
43
+          },
44
+        ],
45
+        yAxis: [
46
+          {
47
+            type: "category",
48
+            axisTick: {
49
+              show: false,
50
+            },
51
+            data: [
52
+              "总用户数",
53
+              "总测肤用户数",
54
+              "付费总用户数",
55
+              "充值总用户数",
56
+              "多次卡购买总用户数",
57
+              "美妆购买总用户数",
58
+              "新注册用户数",
59
+              "新测肤用户数",
60
+              "单次两个项目",
61
+              "3次到店用户数",
62
+              "单次三个项目",
63
+              "2次到店用户数",
64
+            ],
65
+          },
66
+        ],
67
+        series: [
68
+          {
69
+            name: "数量",
70
+            type: "bar",
71
+            label: {
72
+              show: true,
73
+              position: "inside",
74
+            },
75
+            emphasis: {
76
+              focus: "series",
77
+            },
78
+            itemStyle: {
79
+              normal: {
80
+                label: {
81
+                  show: true, //开启显示数值
82
+                  position: "right", //数值在上方显示
83
+                  textStyle: {
84
+                    //数值样式
85
+                    color: "#9b9ca2", //字体颜色
86
+                    fontSize: 14, //字体大小
87
+                  },
88
+                },
89
+              },
90
+            },
91
+            data: [
92
+              this.listData.total_user,
93
+              this.listData.total_skin,
94
+              this.listData.total_consumer_user,
95
+              this.listData.total_recharge_user,
96
+              this.listData.total_time_card,
97
+              this.listData.beauty_products,
98
+              this.listData.new_user,
99
+              this.listData.new_skin,
100
+              this.listData.two_project,
101
+              this.listData.user_three,
102
+              this.listData.three_project,
103
+              this.listData.user_two,
104
+            ],
105
+          },
106
+        ],
107
+      };
108
+
109
+      //数据绑定到表格
110
+      myChart.setOption(option);
111
+      window.addEventListener("resize", function () {
112
+        myChart.resize(); //myChart指自己定义的echartsDom对象
113
+      });
114
+    },
115
+  },
116
+  // 监听父组件传过来的值的变化
117
+  watch: {
118
+    listData: {
119
+      handler(val) {
120
+        this.myEcharts();
121
+      },
122
+    },
123
+  },
124
+  mounted() {
125
+    this.myEcharts();
126
+  },
127
+};
128
+</script>
129
+
130
+<style scoped>
131
+.map {
132
+  width: 96%;
133
+  /* height: 280px; */
134
+  height: 56vh;
135
+  /* border: 1px solid saddlebrown; */
136
+}
137
+</style>

+ 96 - 0
src/views/projectData/projectData.vue

@@ -0,0 +1,96 @@
1
+<template>
2
+  <div class="chinaMap">
3
+    <div class="map" ref="MapMountNode"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: ["listData"],
10
+  data() {
11
+    return {};
12
+  },
13
+  methods: {
14
+    //先定义个方法
15
+    myEcharts() {
16
+      //把echarts绑定到显示元素上
17
+      const myChart = this.$echarts.init(this.$refs.MapMountNode);
18
+      //设置图表属性
19
+      //   经营数据
20
+      const option = {
21
+        title: {
22
+          text: "项目数据",
23
+          // textStyle: {
24
+          //   color: "#6d767e",
25
+          // },
26
+        },
27
+
28
+        grid: {
29
+          left: 55,
30
+        },
31
+        xAxis: {
32
+          type: "category",
33
+          data: [
34
+            "预约项目数",
35
+            "付费项目数",
36
+            "次卡消耗项目数",
37
+            "余额支付项目数",
38
+          ],
39
+          axisLabel: { interval: 0, rotate: 30 },
40
+        },
41
+        yAxis: {
42
+          type: "value",
43
+        },
44
+        series: [
45
+          {
46
+            data: [
47
+              this.listData.resved_project,
48
+              this.listData.pay_project,
49
+              this.listData.card_project,
50
+              this.listData.balance_project,
51
+            ],
52
+            type: "bar",
53
+            itemStyle: {
54
+              normal: {
55
+                label: {
56
+                  show: true, //开启显示数值
57
+                  position: "top", //数值在上方显示
58
+                  textStyle: {
59
+                    //数值样式
60
+                    color: "#9b9ca2", //字体颜色
61
+                    fontSize: 14, //字体大小
62
+                  },
63
+                },
64
+              },
65
+            },
66
+          },
67
+        ],
68
+      };
69
+      //数据绑定到表格
70
+      myChart.setOption(option);
71
+      window.addEventListener("resize", function () {
72
+        myChart.resize(); //myChart指自己定义的echartsDom对象
73
+      });
74
+    },
75
+  },
76
+  // 监听父组件传过来的值的变化
77
+  watch: {
78
+    listData: {
79
+      handler(val) {
80
+        this.myEcharts();
81
+      },
82
+    },
83
+  },
84
+  mounted() {
85
+    this.myEcharts();
86
+  },
87
+};
88
+</script>
89
+
90
+<style scoped>
91
+.map {
92
+  width: 110%;
93
+  height: 33vh;
94
+  /* border: 1px solid saddlebrown; */
95
+}
96
+</style>

+ 102 - 0
src/views/projectRatio/projectRatio.vue

@@ -0,0 +1,102 @@
1
+<template>
2
+  <div class="chinaMap">
3
+    <div class="map" ref="MapMountNode"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: ["listData"],
10
+  data() {
11
+    return {
12
+      topList: [], //top10信息
13
+    };
14
+  },
15
+  methods: {
16
+    // 保存项目top10信息
17
+    getTopList() {
18
+      this.listData.forEach(item=>{
19
+        let arr = {}
20
+        arr.value = item.num
21
+        arr.name = item.project_name
22
+        this.topList.push(arr)
23
+      })
24
+    },
25
+    //先定义个方法
26
+    myEcharts() {
27
+      //把echarts绑定到显示元素上
28
+      const myChart = this.$echarts.init(this.$refs.MapMountNode);
29
+      //设置图表属性
30
+      //   经营数据
31
+      const option = {
32
+        title: {
33
+          text: "TOP10项目占比",
34
+          left: "center",
35
+        },
36
+        tooltip: {
37
+          trigger: "item",
38
+          position: function (p, params, dom, rect, size) {
39
+            return (dom.style.transform = "translateZ(0)");
40
+          },
41
+        },
42
+        series: [
43
+          {
44
+            // name: "Access From",
45
+            type: "pie",
46
+            radius: "50%",
47
+            data:this.topList,
48
+            // data: [
49
+            //   {
50
+            //     name: this.listData[0].project_name,
51
+            //     value: this.listData[0].num,
52
+            //   },
53
+            //   {
54
+            //     value: this.listData[1].num,
55
+            //     name: this.listData[1].project_name,
56
+            //   },
57
+            //   {
58
+            //     value: this.listData[2].num,
59
+            //     name: this.listData[2].project_name,
60
+            //   },
61
+            // ],
62
+            emphasis: {
63
+              itemStyle: {
64
+                shadowBlur: 10,
65
+                shadowOffsetX: 0,
66
+                shadowColor: "rgba(0, 0, 0, 0.6)",
67
+              },
68
+            },
69
+          },
70
+        ],
71
+      };
72
+      //数据绑定到表格
73
+      myChart.setOption(option);
74
+      window.addEventListener("resize", function () {
75
+        myChart.resize(); //myChart指自己定义的echartsDom对象
76
+      });
77
+    },
78
+  },
79
+  // 监听父组件传过来的值的变化
80
+  watch: {
81
+    listData: {
82
+      handler(val) {
83
+        this.myEcharts();
84
+      },
85
+    },
86
+  },
87
+  mounted() {
88
+    this.myEcharts();
89
+  },
90
+  created() {
91
+    this.getTopList();
92
+  },
93
+};
94
+</script>
95
+
96
+<style scoped>
97
+.map {
98
+  width: 420px;
99
+  height: 280px;
100
+  /* border: 1px solid saddlebrown; */
101
+}
102
+</style>

+ 91 - 0
src/views/rechargeData/rechargeData.vue

@@ -0,0 +1,91 @@
1
+<template>
2
+  <div class="chinaMap">
3
+    <div class="map" ref="MapMountNode"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  props: ["listData"],
10
+  data() {
11
+    return {};
12
+  },
13
+  methods: {
14
+    //先定义个方法
15
+    myEcharts() {
16
+      //把echarts绑定到显示元素上
17
+      const myChart = this.$echarts.init(this.$refs.MapMountNode);
18
+      //设置图表属性
19
+      //   经营数据
20
+      const option = {
21
+        grid: {
22
+          left: 60,
23
+        },
24
+        color: ["#42d3a7"],
25
+        title: {
26
+          text: "充值数据",
27
+          // textStyle: {
28
+          //   color: "#6d767e",
29
+          // },
30
+        },
31
+        xAxis: {
32
+          type: "category",
33
+          data: ["总充值金额", "剩余充值储蓄人数", "剩余充值储蓄额"],
34
+          axisLabel: { interval: 0, rotate: 30 },
35
+        },
36
+        yAxis: {
37
+          type: "value",
38
+        },
39
+        series: [
40
+          {
41
+            data: [
42
+              this.listData.total_recharge_money,
43
+              this.listData.balance_people,
44
+              this.listData.total_recharge_resdue_money,
45
+            ],
46
+            type: "bar",
47
+            itemStyle: {
48
+              normal: {
49
+                label: {
50
+                  show: true, //开启显示数值
51
+                  position: "top", //数值在上方显示
52
+                  textStyle: {
53
+                    //数值样式
54
+                    color: "#9b9ca2", //字体颜色
55
+                    fontSize: 14, //字体大小
56
+                  },
57
+                },
58
+              },
59
+            },
60
+          },
61
+        ],
62
+      };
63
+      //数据绑定到表格
64
+      myChart.setOption(option);
65
+      window.addEventListener("resize", function () {
66
+        myChart.resize(); //myChart指自己定义的echartsDom对象
67
+      });
68
+    },
69
+  },
70
+  // 监听父组件传过来的值的变化
71
+  watch: {
72
+    listData: {
73
+      handler(val) {
74
+        this.myEcharts();
75
+      },
76
+    },
77
+  },
78
+  mounted() {
79
+    this.myEcharts();
80
+  },
81
+};
82
+</script>
83
+
84
+<style scoped>
85
+.map {
86
+  /* width: 300px; */
87
+  width: 99%;
88
+  height: 30vh;
89
+  /* border: 1px solid saddlebrown; */
90
+}
91
+</style>

+ 8 - 0
vue.config.js

@@ -0,0 +1,8 @@
1
+const { defineConfig } = require('@vue/cli-service')
2
+module.exports = defineConfig({
3
+  transpileDependencies: true,
4
+  //基本路径 文件打包后放的位置
5
+  publicPath:'./',
6
+  productionSourceMap: false,
7
+  assetsDir: 'assets',
8
+})