mo 2 tahun lalu
induk
melakukan
3e46b8dac1

+ 341 - 31
src/views/main/cloudDate/exerciseDuration.vue

@@ -24,7 +24,32 @@
         <el-button @click="onReSet" type="primary">重置</el-button>
       </el-form-item>
     </saveform>
-
+    <!-- 分组添加柱状图  -->
+    <el-tabs v-model="activeName" class="submitTab" >
+    <el-tab-pane label="人数图表" name="first">
+      <ve-histogram
+      v-if="activeName=='first'"
+        style="width: 100%"
+        height="350px"
+        :data="chartData"
+        :data-empty="dataEmpty"
+        :extend="chartExtend"
+        :legend="legend"
+        :data-zoom="dataZoom"
+      ></ve-histogram>
+    </el-tab-pane>
+    <el-tab-pane label="比例图标" name="second" >  <ve-histogram
+      v-if="activeName=='second'"
+        style="width: 100%"
+        height="350px"
+        :data="scaleCharData"
+        :data-empty="dataEmpty"
+        :extend="scalChartExtend"
+        :legend="legend"
+        :data-zoom="dataZoom"
+      ></ve-histogram>
+      </el-tab-pane>
+  </el-tabs>
     <div class="tableWrap">
       <el-table
         :data="tableList"
@@ -35,57 +60,116 @@
           align="center"
           prop="id"
           label="排名"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.$index+1}}
+          </div>
+        </template>
+        </el-table-column>
         <el-table-column
           align="center"
-          prop="id"
+          prop="organName"
           label="分部名称"
         ></el-table-column>
         <el-table-column
           align="center"
-          prop="id"
+          prop="normalNum"
           label="会员人数"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.normalNum}}人
+          </div>
+        </template>
+        </el-table-column>
         <el-table-column
           align="center"
-          prop="id"
+          prop="trainStudentNum"
           label="练习人数"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.trainStudentNum}}人
+          </div>
+        </template></el-table-column>
         <el-table-column
           align="center"
-          prop="id"
+          prop="trainRate"
           label="练习率"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.trainRate}}%
+          </div>
+        </template>
+        </el-table-column>
         <el-table-column
           align="center"
           prop="id"
           label="≤60分钟"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.train1}}人
+          </div>
+        </template></el-table-column>
+
         <el-table-column
           align="center"
           prop="id"
           label="60~120分钟"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.train2}}人
+          </div>
+        </template>
+        </el-table-column>
         <el-table-column
           align="center"
           prop="id"
           label="120~240分钟"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.train3}}人
+          </div>
+        </template>
+        </el-table-column>
         <el-table-column
           align="center"
           prop="id"
           label=">240分钟"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.train4}}人
+          </div>
+        </template>
+        </el-table-column>
         <el-table-column
           align="center"
           prop="id"
           label="平均练习时长"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.avgTrainTime}}分钟
+          </div>
+        </template>
+        </el-table-column>
         <el-table-column
           align="center"
           prop="id"
           label="练习达标占比"
-        ></el-table-column>
+        >
+        <template slot-scope="scope">
+          <div>
+            {{scope.row.trainStandRate}}%
+          </div>
+        </template>
+        </el-table-column>
 
         <el-table-column align="center" label="操作" fixed="right">
           <template slot-scope="scope">
@@ -104,6 +188,7 @@
 <script>
 import saveform from "@/components/save-form";
 import dayjs from "dayjs";
+import histogram from "v-charts/lib/histogram.common";
 import { cloudTeacherNum } from "../api";
 export const getTimes = (times, keys = []) => {
   if (times && times.length) {
@@ -115,14 +200,15 @@ export const getTimes = (times, keys = []) => {
   return {};
 };
 export default {
-  components: { saveform },
+  components: { saveform,"ve-histogram": histogram, },
   name: "helpCategory",
   data() {
     return {
       searchForm: {
         dates: []
       },
-      tableList: []
+      tableList: [],
+      activeName:'first'
     };
   },
   async mounted() {
@@ -130,21 +216,21 @@ export default {
   },
   methods: {
     search() {
-      // this.$refs.searchForm.validate((valid) => {
-      //   this.pageInfo = {
-      //     ...this.pageInfo,
-      //     page: 1,
-      //   };
-      //   this.getList();
-      // });
+      this.$refs.searchForm.validate((valid) => {
+        this.pageInfo = {
+          ...this.pageInfo,
+          page: 1,
+        };
+        this.getList();
+      });
     },
     onReSet() {
-      // this.pageInfo = {
-      //   ...this.pageInfo,
-      //   page: 1,
-      // };
-      // this.$refs.searchForm.resetFields();
-      // this.getList();
+      this.pageInfo = {
+        ...this.pageInfo,
+        page: 1,
+      };
+      this.$refs.searchForm.resetFields();
+      this.getList();
     },
     async getList() {
       // cloudTeacherNum
@@ -159,9 +245,213 @@ export default {
           ...params
         });
         this.tableList = [];
-        this.tableList = res.data.list;
+        this.tableList = res.data;
       } catch {}
     }
+  },
+  computed: {
+    items() {
+      let obj = {};
+      //        "eVipStudentNum",
+      let arr = [
+        "normalNum",
+        "train1",
+        "train2",
+        "train3",
+        "train4",
+        "buyRate",
+        "avgTrainTime",
+      ];
+      arr.forEach(str => {
+        if (this.dataList[str] + "") {
+          obj[str] = {
+            title: titles[str],
+            percent: this.dataList[str],
+            desc: descs[str]
+          };
+        }
+      });
+
+      return obj;
+    },
+    scaleItems(){
+      let obj = {};
+      //        "eVipStudentNum",
+      let arr = [
+        "trainRate",
+        "trainStandRate",
+      ];
+      arr.forEach(str => {
+        if (this.dataList[str] + "") {
+          obj[str] = {
+            title: titles[str],
+            percent: this.dataList[str],
+            desc: descs[str]
+          };
+        }
+      });
+
+      return obj;
+    },
+    legend() {
+      return {
+        left: "10px"
+      };
+    },
+    scaleCharData(){
+      const temp = {
+        trainRate: "练习率",
+        trainStandRate: "练习达标率",
+
+      };
+      const values = this.tableList;
+
+      const months = {};
+      for (const key in temp) {
+        for (const item of values) {
+          if (!months[item.organName]) {
+            months[item.organName] = {
+              分部: item.organName
+            };
+          }
+          months[item.organName][temp[key]] = item[key] || 0;
+        }
+      }
+      console.log(months,'months')
+      return {
+        columns: [
+          "分部",
+          "练习率",
+          "练习达标率",
+        ],
+        rows: Object.values(months)
+      };
+    },
+    chartData() {
+      const temp = {
+        normalNum: "会员人数",
+        train1: "<=60分钟",
+        train2: "60-120分钟",
+        train3: "120-240分钟",
+        train3:">240分钟",
+        avgTrainTime: "平均时长",
+      };
+      const values = this.tableList;
+
+      const months = {};
+      for (const key in temp) {
+        for (const item of values) {
+          if (!months[item.organName]) {
+            months[item.organName] = {
+              分部: item.organName
+            };
+          }
+          months[item.organName][temp[key]] = item[key] || 0;
+        }
+      }
+      console.log(months,'months')
+      return {
+        columns: [
+          "分部",
+          "会员人数",
+          "<=60分钟",
+          "60-120分钟",
+          "120-240分钟",
+          ">240分钟",
+          "平均时长",
+        ],
+        rows: Object.values(months)
+      };
+    },
+    chartExtend() {
+      return {
+        yAxis: {
+          //纵轴标尺固定
+          minInterval: 1,
+          type: "value",
+          scale: true,
+          min: 0,
+          axisLabel: {
+            formatter: "{value}人"
+          }
+        },
+        series: {
+          type: "bar",
+          smooth: false
+        },
+        tooltip: {
+          axisPointer: {
+            type: "shadow",
+            shadowStyle: {
+              color: "rgba(150,150,150,0.2)"
+            }
+          },
+          formatter: item => {
+            return [
+              item[0].axisValueLabel,
+              ...item.map(d => {
+                return `<br/>${d.marker}${d.seriesName}: ${d.value}人`;
+              })
+            ].join("");
+          }
+        }
+      };
+    },
+    scalChartExtend() {
+      return {
+        yAxis: {
+          //纵轴标尺固定
+          minInterval: 1,
+          type: "value",
+          scale: true,
+          min: 0,
+          axisLabel: {
+            formatter: "{value}%"
+          }
+        },
+        series: {
+          type: "bar",
+          smooth: false
+        },
+        tooltip: {
+          axisPointer: {
+            type: "shadow",
+            shadowStyle: {
+              color: "rgba(150,150,150,0.2)"
+            }
+          },
+          formatter: item => {
+            return [
+              item[0].axisValueLabel,
+              ...item.map(d => {
+                return `<br/>${d.marker}${d.seriesName}: ${d.value}人`;
+              })
+            ].join("");
+          }
+        }
+      };
+    },
+    dataZoom() {
+      return [
+        {
+          show: true,
+          type: "slider",
+          start: 0,
+          end: 30,
+          filterMode: "empty",
+          zoomLock: true,
+          handleSize: 0
+        }
+      ];
+    },
+    dataEmpty() {
+      return !this.chartData.rows.length;
+    },
+    exporyun() {
+      return {
+        organId: this.organId
+      };
+    }
   }
 };
 </script>
@@ -186,4 +476,24 @@ export default {
 .newBand {
   display: inline-block;
 }
+
+
+
+::v-deep .el-tabs__active-bar {
+  background-color: transparent !important;
+}
+::v-deep.el-tabs__nav-wrap {
+  &:after {
+    background-color: transparent !important;
+  }
+}
+/*去掉切换时el-tab-pane底部的蓝色下划线*/
+::v-deep .el-tabs__nav-wrap::after {
+  background-color: transparent !important;
+
+  }
+
+
+/*去掉tabs底部的下划线*/
+
 </style>

+ 3 - 1
src/views/main/cloudDate/index.vue

@@ -8,11 +8,12 @@
       <tab-router @change="changeKey">
         <el-tab-pane lazy label="数据总览" name="memberList">
           <organMemberList
+          v-if="activeKey=='memberList'"
             v-permission="'studentManage/getCloudStudyStudentOverView'"
           />
         </el-tab-pane>
         <el-tab-pane lazy label="练习时长" name="exerciseDuration">
-          <exerciseDuration />
+          <exerciseDuration  v-if="activeKey=='exerciseDuration'" />
         </el-tab-pane>
       </tab-router>
     </div>
@@ -38,6 +39,7 @@ export default {
   methods: {
     permission,
     changeKey(val) {
+      console.log(val,'val')
       this.activeKey = val;
     }
   }

+ 4 - 2
src/views/main/cloudDate/organMemberList.vue

@@ -11,7 +11,7 @@
       </div>
       <!--
           -->
-      <statistic :col="3" class="statistic" :cols="0">
+      <statistic :col="5" class="statistic" :cols="0">
         <statistic-item
           v-for="(item, key) in items"
           :key="key"
@@ -52,6 +52,7 @@
           </span>
           <span v-else> <count-to :endVal="item.percent || 0" /> </span>
         </statistic-item>
+        <statistic-item></statistic-item>
       </statistic>
 
       <ve-histogram
@@ -413,6 +414,7 @@ export default {
         cloudStudyTodayUseStudentNum: "今日使用人数"
       };
       const values = Object.values(this.tableList);
+
       const months = {};
       for (const key in temp) {
         for (const item of values) {
@@ -424,7 +426,7 @@ export default {
           months[item.organId][temp[key]] = item[key] || 0;
         }
       }
-
+      console.log(months,'months')
       return {
         columns: [
           "分部",

+ 7 - 7
src/views/main/constant.js

@@ -75,20 +75,20 @@ export const descs = {
   VIP_AMOUNT: "VIP课购买、续费、复学、课程组新增学员收入金额总和",
   CURRENT_COURSE_ERROR:
     "剩余课时(未开始+排课资格)大于4的学员,本月排课节数少于4节",
-  vipStudentNum: "待激活及生效中的会员人数(去重)",
+  vipStudentNum: "生效中及待激活的会员人数",
   eVipStudentNum: "如果是试用会员又是付费会员,则不算试用会员数",
   cloudStudyLivelyStudentNum:
-    "过去四周内有三周及以上每周训练时长超过60分钟为活跃学员",
+    "过去四周内有三周及以上每周训练时长超过60分钟的学员人数",
   newCloudStudyStudentNum: "第一次使用云教练的人数",
   cloudStudyTodayUseStudentNum: "今日有练习记录的学员人数",
   // "cloudStudyUseStudentNum":'累计使用的总人数',
-  totalStudentNum: "进行中、暂停乐团的在读学员总数",
+  totalStudentNum: "进行中、暂停乐团的在读学员总数",
   againBuyRate:
-    "在读学员且云教练生效或待激活学员中,有多次付费订单的学员数 / 乐团在读有云教练并且有付费订单的学员数",
+    "会员人数中,有多次云教练付费订单的学员数占比",
   buyRate: "在读学员中云教练生效或待激活学员占比",
-  waitActivateVipStudentNum: "待激活员人数",
+  waitActivateVipStudentNum: "待激活员人数",
   effectiveVipStudentNum: "在读学员中会员生效人数",
-  vipStudentRate: "会员总人数/有效学员数",
+  vipStudentRate: "会员人数/在读人数",
   effectiveStudentNum:
     "(进行中乐团在读学员+有剩余课时的学员+有排课次数的学员)去重"
 };
@@ -103,7 +103,7 @@ export const titles = {
   cloudStudyTodayUseStudentNum: "今日使用人数",
   cloudStudyUseStudentNum: "累计使用人数",
   effectiveStudentNum: "有效学员数",
-  vipStudentRate: "会员人数占比",
+  vipStudentRate: "会员占比",
   againBuyRate: "复购率",
   buyRate: "覆盖率"
 };