ソースを参照

Merge branch 'master' of http://git.cc-lotus.info/service-platform/web-test

guhongwei 4 年 前
コミット
78d20ec2c7

+ 1 - 0
package.json

@@ -8,6 +8,7 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@antv/g2plot": "^1.1.8",
     "@stomp/stompjs": "^5.4.4",
     "axios": "^0.19.2",
     "bar": "^0.1.2",

+ 127 - 0
src/components/statistics/bar.vue

@@ -0,0 +1,127 @@
+<template>
+  <div id="bar">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { Bar, Column } from '@antv/g2plot';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'bar',
+  props: {
+    data: { type: [Object, Array], default: () => [] },
+    axis: { type: Object, default: () => {} },
+    gid: { type: String, default: `${new Date().getTime()}` },
+    horizontal: { type: Boolean, default: true },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: [],
+    };
+  },
+  created() {},
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (!this.list) {
+        //未获得数据
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ data: this.list });
+      } else {
+        let { x, y, xAlias, yAlias } = this.axis;
+        let meta = {};
+        meta[x] = { alias: xAlias };
+        meta[y] = { alias: yAlias };
+        let options = {
+          pixelRatio: 1,
+          data: this.list,
+          //条形和柱状的x,y轴需要互换
+          xField: this.horizontal ? y : x,
+          yField: this.horizontal ? x : y,
+          meta: meta,
+          point: {
+            visible: true,
+          },
+          label: {
+            visible: true,
+          },
+          //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+          stackField: x,
+          legend: {
+            visible: true,
+            position: 'right-top',
+          },
+          xAxis: {
+            nice: true,
+            visible: true,
+            line: {
+              visible: true,
+            },
+            grid: {
+              visible: true,
+            },
+            tickLine: {
+              visible: true,
+            },
+          },
+          yAxis: {
+            nice: true,
+            visible: true,
+            grid: {
+              visible: true,
+            },
+            line: {
+              visible: true,
+            },
+          },
+
+          events: {
+            // onColumnClick: e => this.gclick(e),
+          },
+        };
+        if (this.horizontal) this.chart = new Bar(this.gid, options);
+        else this.chart = new Column(this.gid, options);
+      }
+      this.chart.render();
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val.length > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    list: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 102 - 0
src/components/statistics/donut.vue

@@ -0,0 +1,102 @@
+<template>
+  <div id="donut">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import { Donut } from '@antv/g2plot';
+export default {
+  name: 'donut',
+  props: {
+    data: { type: Array, default: () => [] },
+    axis: { type: Object, default: () => {} }, //{x:x轴字段名; xAlias:x轴名称; y:y轴字段名; yAlias:y轴名称}
+    gid: { type: String, default: `${new Date().getTime()}` },
+    headTitle: { type: String, default: '' },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: undefined,
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (!this.list) {
+        //未获得数据
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ data: this.list });
+      } else {
+        let { x, y, xAlias, yAlias } = this.axis;
+        let meta = {};
+        meta[x] = { alias: xAlias };
+        meta[y] = { alias: yAlias };
+        this.chart = new Donut(this.gid, {
+          title: { visible: true, text: this.headTitle },
+          pixelRatio: 4,
+          data: this.list,
+          colorField: x,
+          angleField: y,
+          meta: meta,
+          point: {
+            visible: true,
+          },
+          label: {
+            visible: true,
+            type: 'spider',
+            formatter: (text, item) => `${item._origin[x]}: ${item._origin[y]}`,
+          },
+          //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+          stackField: x,
+          legend: {
+            visible: true,
+            position: 'right-top',
+          },
+          events: {
+            // onPieClick: e => this.gclick(e),
+          },
+        });
+      }
+
+      this.chart.render();
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val.length > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    list: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 81 - 0
src/components/statistics/liquid.vue

@@ -0,0 +1,81 @@
+<template>
+  <div id="liquid">
+    <div :id="gid" style="height:450px"></div>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { mapState, createNamespacedHelpers } from 'vuex';
+import { Liquid } from '@antv/g2plot';
+export default {
+  name: 'liquid',
+  props: {
+    data: { type: [Number, String], default: 0 },
+    max: { type: Number, default: 100 }, //整体上限,调整比例
+    min: { type: Number, default: 0 }, //整体上限,调整比例
+    gid: { type: String, default: `${new Date().getTime()}` },
+    headTitle: { type: String, default: '' },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      value: 0,
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  created() {},
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ value: this.value });
+      } else {
+        this.chart = new Liquid(this.gid, {
+          title: { visible: true, text: this.headTitle },
+          min: this.min,
+          max: this.max,
+          value: this.value, //
+          events: {
+            // onPieClick: e => this.gclick(e),
+          },
+        });
+      }
+
+      this.chart.render();
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val) this.$set(this, `value`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    value: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 114 - 0
src/components/statistics/pie.vue

@@ -0,0 +1,114 @@
+<template>
+  <div id="down-pie">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import { Pie } from '@antv/g2plot';
+export default {
+  name: 'downPie',
+  props: {
+    data: { type: Array, default: () => [] },
+    axis: { type: Object, default: () => {} }, //{x:x轴字段名; xAlias:x轴名称; y:y轴字段名; yAlias:y轴名称}
+    gid: { type: String, default: `${new Date().getTime()}` },
+    headTitle: { type: String, default: '' },
+  },
+  components: {},
+  data: () => {
+    return {
+      chart: null,
+      list: undefined,
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (!this.list) {
+        //未获得数据
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ data: this.list });
+      } else {
+        let { x, y, xAlias, yAlias } = this.axis;
+        let meta = {};
+        meta[x] = { alias: xAlias };
+        meta[y] = { alias: yAlias };
+        this.chart = new Pie(this.gid, {
+          title: { visible: true, text: this.headTitle },
+          pixelRatio: 4,
+          data: this.list,
+          colorField: x,
+          angleField: y,
+          meta: meta,
+          point: {
+            visible: true,
+          },
+          label: {
+            visible: true,
+            type: 'spider',
+            formatter: (text, item) => `${item._origin[x]}: ${item._origin[y]}`,
+          },
+          //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+          stackField: x,
+          legend: {
+            visible: true,
+            position: 'right-top',
+          },
+          events: {
+            // onPieClick: e => this.gclick(e),
+          },
+        });
+      }
+
+      this.chart.render();
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val.length > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    list: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.rightData {
+  padding: 0 30px;
+  height: 391px;
+  overflow: hidden;
+}
+/deep/.el-table td {
+  padding: 8px 0;
+}
+/deep/.el-table th {
+  padding: 8px 0;
+}
+</style>

+ 104 - 0
src/components/statistics/rose.vue

@@ -0,0 +1,104 @@
+<template>
+  <div id="rose">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import { Rose } from '@antv/g2plot';
+export default {
+  name: 'rose',
+  props: {
+    data: { type: Array, default: () => [] },
+    axis: { type: Object, default: () => {} }, //{x:x轴字段名; xAlias:x轴名称; y:y轴字段名; yAlias:y轴名称}
+    gid: { type: String, default: `${new Date().getTime()}` },
+    headTitle: { type: String, default: '' },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: undefined,
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let e = document.getElementById(this.gid);
+      if (!e) {
+        console.warn('没有找到指定渲染容器');
+        return;
+      }
+      if (!this.list) {
+        //未获得数据
+        return;
+      }
+      if (this.chart) {
+        this.chart.updateConfig({ data: this.list });
+      } else {
+        let { x, y, xAlias, yAlias } = this.axis;
+        let meta = {};
+        meta[x] = { alias: xAlias };
+        meta[y] = { alias: yAlias };
+        this.chart = new Rose(this.gid, {
+          title: { visible: true, text: this.headTitle },
+          pixelRatio: 4,
+          data: this.list,
+          radiusField: y,
+          categoryField: x,
+          colorField: x,
+          // angleField: y,
+          meta: meta,
+          point: {
+            visible: true,
+          },
+          label: {
+            visible: true,
+            type: 'spider',
+            formatter: (text, item) => `${item[x]}: ${item[y]}`,
+          },
+          //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+          stackField: x,
+          legend: {
+            visible: true,
+            position: 'right-top',
+          },
+          events: {
+            // onPieClick: e => this.gclick(e),
+          },
+        });
+      }
+
+      this.chart.render();
+    },
+  },
+  watch: {
+    data: {
+      handler(val) {
+        if (val.length > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+    list: {
+      handler(val) {
+        if (val) this.$nextTick(() => this.init());
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 90 - 5
src/views/hallList/zongjie.vue

@@ -61,6 +61,19 @@
                 <span>{{ zjinfo.xuqiu }}次</span>
               </el-col>
             </el-col>
+            <el-col :span="24" class="three">
+              <el-tabs v-model="act">
+                <el-tab-pane name="0" label="产品发布统计">
+                  <pie :data="productList" :axis="proAxis" gid="pie0" v-if="act == 0"></pie>
+                </el-tab-pane>
+                <el-tab-pane name="1" label="人员参会统计">
+                  <donut :data="personList" :axis="perAxis" gid="donut1" v-if="act == 1"></donut>
+                </el-tab-pane>
+                <el-tab-pane name="2" label="交易统计">
+                  <bar :data="transList" :axis="transAxis" gid="bar2" v-if="act == 2"></bar>
+                </el-tab-pane>
+              </el-tabs>
+            </el-col>
           </el-col>
         </el-col>
       </div>
@@ -71,13 +84,25 @@
 <script>
 import _ from 'lodash';
 import { mapState, createNamespacedHelpers } from 'vuex';
-
+import pie from '@c/statistics/pie.vue';
+import bar from '@c/statistics/bar.vue';
+import donut from '@c/statistics/donut.vue';
 const { mapActions: dock } = createNamespacedHelpers('dock');
+const { mapActions: transaction } = createNamespacedHelpers('transaction');
+const { mapActions: marketproduct } = createNamespacedHelpers('marketproduct');
 export default {
   name: 'zongjie',
   props: {},
-  components: {},
+  components: { pie, donut, bar }, //
   data: () => ({
+    act: '0',
+    productList: [],
+    proTitle: ['技术', '产品', '服务'],
+    proAxis: { x: 'name', xAlias: '产品类型', y: 'value', yAlias: '数量' },
+    personList: [],
+    perAxis: { x: 'name', xAlias: '用户类型', y: 'value', yAlias: '人数' },
+    transList: [],
+    transAxis: { x: 'name', xAlias: '交易动态', y: 'value', yAlias: '数量' },
     zjinfo: {
       top: '计算中心',
       title: '测试直播',
@@ -116,12 +141,72 @@ export default {
   },
   methods: {
     ...dock({ dockQuery: 'query', dockFetch: 'fetch' }),
+    ...marketproduct({ productQuery: 'query' }),
+    ...transaction({ transQuery: 'query' }),
     async searchInfo() {
-      console.log('ccc');
       let res = await this.dockFetch(this.id);
-      console.log('dad');
+      let resPro = await this.productQuery();
+      let resTran = await this.transQuery({ dockid: this.id });
+      if (this.$checkRes(res)) this.proPerson(res.data);
+      if (this.$checkRes(resPro)) this.proProduct(resPro.data);
+      if (this.$checkRes(resTran)) this.proTrans(resTran.data);
       this.zjinfo.top = res.data.title;
-      console.log(res.data.title);
+    },
+    proProduct(data) {
+      let garr = _.groupBy(data, 'totaltype');
+      let keys = Object.keys(garr);
+      let res = keys.map(i => {
+        let obj = { value: garr[i].length, type: i };
+        if (i == 0) obj.name = '技术';
+        if (i == 1) obj.name = '产品';
+        if (i == 2) obj.name = '服务';
+        return obj;
+      });
+      let r = res.some(f => f.type == 0);
+      if (!r) res.push({ value: 0, name: '技术', type: 0 });
+      r = res.some(f => f.type == 1);
+      if (!r) res.push({ value: 0, name: '产品', type: 1 });
+      r = res.some(f => f.type == 2);
+      if (!r) res.push({ value: 0, name: '服务', type: 2 });
+      this.$set(this, `productList`, res);
+    },
+    proPerson(data) {
+      let garr = _.groupBy(_.get(data, 'apply', []), 'role');
+      let keys = Object.keys(garr);
+      let res = keys.map(i => {
+        let obj = { value: garr[i].length, type: i };
+        if (i == 2) obj.name = '个人';
+        if (i == 3) obj.name = '机构';
+        if (i == 6) obj.name = '专家';
+        return obj;
+      });
+      //查类型,个人,机构,专家,没有的填0
+      let r = res.some(f => f.type == 2);
+      if (!r) res.push({ value: 0, name: '个人', type: 2 });
+      r = res.some(f => f.type == 3);
+      if (!r) res.push({ value: 0, name: '机构', type: 3 });
+      r = res.some(f => f.type == 6);
+      if (!r) res.push({ value: 0, name: '专家', type: 6 });
+      this.$set(this, `personList`, res);
+    },
+    proTrans(data) {
+      let garr = _.groupBy(data, 'status');
+      let keys = Object.keys(garr);
+      let res = keys.map(i => {
+        let obj = { value: garr[i].length, type: i };
+        if (i == 0) obj.name = '正在洽谈';
+        if (i == 1) obj.name = '达成意向';
+        if (i == 2) obj.name = '对接完成';
+        return obj;
+      });
+      //查类型,个人,机构,专家,没有的填0
+      let r = res.some(f => f.type == 0);
+      if (!r) res.push({ value: 0, name: '正在洽谈', type: 0 });
+      r = res.some(f => f.type == 1);
+      if (!r) res.push({ value: 0, name: '达成意向', type: 1 });
+      r = res.some(f => f.type == 2);
+      if (!r) res.push({ value: 0, name: '对接完成', type: 2 });
+      this.$set(this, `transList`, res);
     },
   },
 };