zhibin 6 rokov pred
rodič
commit
3668f17b9f

+ 2 - 1
src/page/layout/slide.vue

@@ -59,7 +59,8 @@ export default {
           { text: '设备管理', link: {name: 'device'} }
         ],
         top: 154
-      }
+      },
+      { text: '设备管理', link: {name: 'Statistics'}, top: 42 }
       // ,
       // {
       //   text: 'BBS',

+ 3 - 1
src/page/login/index.vue

@@ -115,7 +115,9 @@ export default {
       } else {
         this.$alert('登录失败', '提示', {
           confirmButtonText: '确定',
-          callback: action => {}
+          callback: action => {
+            this.fullscreenLoading = false
+          }
         })
       }
     }

+ 37 - 0
src/page/statistics/case.js

@@ -0,0 +1,37 @@
+export default
+  {
+    title: {
+      text: '同名数量统计',
+      x: 'center'
+    },
+    tooltip: {
+      trigger: 'item',
+      formatter: "{a} <br/>{b} : {c} ({d}%)"
+    },
+    legend: {
+      type: 'scroll',
+      orient: 'vertical',
+      right: 10,
+      top: 20,
+      bottom: 20,
+      data: [],
+
+      selected: false
+    },
+    series: [
+      {
+        name: '',
+        type: 'pie',
+        radius: '55%',
+        center: ['50%', '50%'],
+        data: [],
+        itemStyle: {
+          emphasis: {
+            shadowBlur: 10,
+            shadowOffsetX: 0,
+            shadowColor: 'rgba(0, 0, 0, 0.5)'
+          }
+        }
+      }
+    ]
+  };

+ 236 - 0
src/page/statistics/index.vue

@@ -0,0 +1,236 @@
+<template>
+
+  <div>
+    <div class="card-layer">
+      <div class="filter">
+        <el-select v-model="searchKey" clearable filterable placeholder="所有场景">
+          <el-option
+            v-for="item in keyoptions"
+            :key="item"
+            :label="item"
+            :value="item">
+          </el-option>
+        </el-select>
+        <el-select v-model="searchType" filterable placeholder="所有场景">
+          <el-option
+            v-for="item in soptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="case-layer">
+        <div ref="case1">
+        </div>
+        <div ref="case2"></div>
+        <div ref="case3">
+        </div>
+        <div ref="case4"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import temp from './case'
+let echarts = require('echarts/lib/echarts')
+
+// 引入提示框和title组件
+require('echarts/lib/component/tooltip')
+require('echarts/lib/component/title')
+require('echarts/lib/component/legend')
+require('echarts/lib/component/legendScroll')
+
+const data = {
+	"header": {
+		"account_type": 1,
+		"password": "4DAge2018",
+		"token": "17a1e010f1be38abead0066b2b02cb4c",
+		"username": "四维时代"
+	},
+	"body": {
+		"target": 4,
+		"siteId": "13790587",
+		"method": "visit/toppage/a",
+		"start_date": "20160501",
+		"end_date": "20190813",
+		"metrics": "pv_count,visitor_count",
+		"search_word": "123"
+	}
+}
+
+export default {
+  data () {
+    return {
+      body: {...data},
+      result: null,
+      searchKey: null,
+      soptions: [
+        {label: '打开次数', value: 'pv'},
+        {label: '访问人数', value: 'uv'}
+      ],
+      searchType: 'pv'
+    }
+  },
+  computed: {
+    statistics () {
+      if (!this.result) return {}
+      let type = this.searchType
+      let data = {}
+      let keys = this.result.items[0]
+      let vals = this.result.items[1]
+      keys.forEach((item, i) => {
+        data[item[0].name] = vals[i][type === 'pv' ? 0 : 1]
+      })
+      return data
+    },
+    grouping () {
+      let others = []
+      let data = {}
+      Object.keys(this.statistics).forEach(key => {
+        let start = 'm='
+        let end = '&'
+        let startIndex = ~key.indexOf(start) ? key.indexOf(start) + start.length : -1
+        let endIndex = ~startIndex ? key.substr(startIndex).indexOf('&') : -1
+        let ik = ~startIndex ? (~endIndex ? key.substr(startIndex, endIndex) : key.substr(startIndex)) : null
+
+        if (ik) {
+          let ikey = ~key.indexOf('PC.html') ? 'PC' : (~key.indexOf('Mobile.html') ? 'Mobile' : null)
+          if (!data[ik]) {
+            data[ik] = {
+              count: 0, PC: 0, Mobile: 0,
+              children: {wx_friends: 0, wx_friend: 0, weibo: 0, qq_zone: 0, qq: 0, default: 0}
+            }
+          }
+
+          data[ik].count += this.statistics[key]
+          data[ik][ikey] += this.statistics[key]
+        } else {
+          others.push(key)
+        }
+      })
+
+      Object.keys(data).forEach(key => {
+        let start = `/${key}/`
+        let child = Object.keys(this.statistics).filter(k => ~k.indexOf(start))
+        child.forEach(item => {
+          let ck = item.substr(item.indexOf(start) + start.length)
+          if (data[key].children[ck]) {
+            data[key].children[ck] += this.statistics[item]
+          } else {
+            data[key].children[ck] = this.statistics[item]
+          }
+          others.splice(others.indexOf(item), 1)
+        })
+      })
+
+      data.other = {count: 0, children: {}}
+
+      others.forEach(key => {
+        data.other.count += this.statistics[key]
+        data.other.children[key] = this.statistics[key]
+      })
+      return data
+    },
+    keyoptions () {
+      return Object.keys(this.grouping).filter(k => k !== 'other')
+    },
+    openType () {
+      let scene = this.searchKey || ''
+      let grouping = this.grouping
+      let data = JSON.parse(JSON.stringify(temp))
+
+      if (scene) {
+        grouping = { [scene]: this.grouping[scene] }
+      }
+
+      data.legend.data = ['朋友圈', '微信好友', 'QQ好友', 'QQ空间', '微博', '直接打开']
+      data.title.text = scene + '场景打开方式占比'
+      data.series[0].name = '打开场景'+scene+'方式'
+      data.series[0].data = [{
+          name: '朋友圈',
+          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.wx_friends : 0), 0)
+        }, {
+          name: '微信好友',
+          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.wx_friend : 0), 0)
+        }, {
+          name: 'QQ好友',
+          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.qq : 0), 0)
+        }, {
+          name: 'QQ空间',
+          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.qq_zone : 0), 0)
+        }, {
+          name: '微博',
+          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.weibo : 0), 0)
+        }, {
+          name: '直接打开',
+          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].children.default : 0), 0)
+      }]
+      return data;
+    },
+    terminal () {
+      let scene = this.searchKey || ''
+      let grouping = this.grouping
+      let data = JSON.parse(JSON.stringify(temp))
+
+      if (scene) {
+        grouping = { [scene]: this.grouping[scene] }
+      }
+      data.legend.data = ['电脑端', '移动端']
+      data.title.text = scene + '场景终端打开占比'
+      data.series[0].name = '打开场景'+scene+'使用终端'
+      data.series[0].data = [{
+          name: '电脑端',
+          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].PC : 0), 0)
+        }, {
+          name: '移动端',
+          value: Object.keys(grouping).reduce((t, k) => t + (k !== 'other' ? grouping[k].Mobile : 0), 0)
+      }]
+      return data;
+    },
+    secene () {
+      let grouping = this.grouping
+      let data = JSON.parse(JSON.stringify(temp))
+      let keys = Object.keys(grouping).filter(k => k !== 'other')
+      let total = keys.reduce((t, k) => t + grouping[k].count, 0)
+      data.legend.data = keys
+      data.title.text = '场景打开' + (this.searchType === 'uv' ? '人数' : '次数') + '占比'
+      data.legend.selected = {}
+      keys.forEach(key => {
+        data.legend.selected[key] = grouping[key].count / total > 0.01 
+      })
+      data.series[0].data = keys.map(k => ({name: k, value: grouping[k].count}))
+
+      return data;
+    }
+  },
+  methods: {
+    async referData() {
+      this.result = (await this.$http.post('https://api.baidu.com/json/tongji/v1/ReportService/getData', JSON.stringify(this.body))).body.data[0].result
+    }
+  },
+  watch: {
+    openType () {
+      this.case1.setOption(this.openType)
+    },
+    terminal () {
+      this.case2.setOption(this.terminal)
+    },
+    secene () {
+      this.case3.setOption(this.secene)
+    }
+  },
+  mounted () {
+    this.referData()
+    this.case1 = echarts.init(this.$refs.case1)
+    this.case2 = echarts.init(this.$refs.case2)
+    this.case3 = echarts.init(this.$refs.case3)
+    this.case4 = echarts.init(this.$refs.case4)
+  }
+}
+</script>
+
+<style scoped>
+@import url('./style.css');
+</style>

+ 31 - 0
src/page/statistics/style.css

@@ -0,0 +1,31 @@
+.card-layer {
+  background-color: #fff;
+  margin-bottom: 20px;
+}
+
+.filter {
+  text-align: center;
+  padding: 20px;
+}
+
+.card-layer h2 {
+  text-align: center;
+  padding: 15px 0;
+  font-size: 20px;
+}
+
+.case-layer {
+  height: 1200px;
+  overflow: hidden;
+  padding: 10px 0;
+}
+
+.case-layer > div {
+  width: 50%;
+  height: 50%;
+  float: left;
+}
+
+.case-layer > div:nth-child(3) {
+  width: 100%;
+}

+ 6 - 0
src/router/index.js

@@ -76,6 +76,12 @@ export default new Router({
               component: require('@/page/scene').default
             }
           ]
+        },
+        {
+          path: '/statistics',
+          name: 'Statistics',
+          component: require('@/page/statistics').default,
+          meta: { text: '数据统计' }
         }
       ]
     }