Bladeren bron

学员统计和活动导出

1
mo 2 jaren geleden
bovenliggende
commit
919c8b2c21

+ 2 - 1
src/constant/index.js

@@ -296,7 +296,8 @@ export const downListType = {
   7: '学员小课数据统计',
   8: '订单汇总',
   9: '乐团课表详情',
-  10: '乐团数据导出'
+  10: '乐团数据导出',
+  11: '活动资格导出'
 }
 
 export const withdrawalStatus = {

+ 37 - 23
src/views/categroyManager/vipActiveList.vue

@@ -6,27 +6,30 @@
     </h2>
 
     <div class="m-core">
-      <el-button
-        type="primary"
-        style="margin-bottom: 20px"
-        v-permission="'/vipNewActive'"
-        @click="gotoNewActive"
-        >新建</el-button
-      >
-      <!-- <el-button
+      <div class="btnList" style="margin-bottom: 20px">
+        <el-button
+          type="primary"
+          v-permission="'/vipNewActive'"
+          @click="gotoNewActive"
+          >新建</el-button
+        >
+        <!-- <el-button
         type="primary"
         style="margin-bottom: 20px"
         v-permission="'export/vipGroupActivity'"
         @click="onExport"
         >活动导出</el-button
       > -->
-            <el-button
+        <!-- <el-button
         type="primary"
         style="margin-bottom: 20px"
         v-permission="'export/vipGroupActivity'"
         @click="onActiveExport"
         >活动资格导出</el-button
-      >
+      > -->
+
+      </div>
+
       <save-form
         :inline="true"
         class="searchForm"
@@ -150,7 +153,7 @@
           <el-table-column align="center" prop="activityType" label="活动渠道">
             <template slot-scope="scope">
               <div>
-                {{ scope.row.activityChannel ==1 ? "乐团小课" : "常规小课" }}
+                {{ scope.row.activityChannel == 1 ? "乐团小课" : "常规小课" }}
               </div>
             </template>
           </el-table-column>
@@ -355,7 +358,7 @@ import cleanDeep from "clean-deep";
 import { vipResetTypeList } from "@/utils/searchArray";
 export default {
   name: "vipActiveList",
-  components: { pagination,ExportChiose },
+  components: { pagination, ExportChiose },
   data() {
     return {
       vipResetTypeList,
@@ -572,7 +575,7 @@ export default {
         rows: this.rules.limit,
         page: this.rules.page,
         status: this.searchForm.status,
-        activityChannel:this.searchForm.activityChannel,
+        activityChannel: this.searchForm.activityChannel,
         enable,
         search,
       }).then((res) => {
@@ -676,12 +679,15 @@ export default {
     },
     // 点击列表修改同步状态
     reset(row) {
-      this.$router.push({
-        path: "/operateManager/vipNewActive?type=reset",
-        query: { id: row.id },
-      },(router) => {
+      this.$router.push(
+        {
+          path: "/operateManager/vipNewActive?type=reset",
+          query: { id: row.id },
+        },
+        (router) => {
           router.meta.title = "修改活动方案";
-        });
+        }
+      );
     },
     look(row) {
       this.$router.push({
@@ -711,12 +717,15 @@ export default {
       // 带参数 searchForm: { organId: null } 搜索条件
       // let rules = JSON.stringify(this.rules);
       // let searchForm = JSON.stringify(this.searchForm);
-      this.$router.push({
-        path: "/operateManager/vipNewActive?type=create",
-        // query: { rules, searchForm },
-      },(router) => {
+      this.$router.push(
+        {
+          path: "/operateManager/vipNewActive?type=create",
+          // query: { rules, searchForm },
+        },
+        (router) => {
           router.meta.title = "新建活动方案";
-        });
+        }
+      );
     },
     closeVipform() {
       this.$refs["vipform"].resetFields();
@@ -780,6 +789,11 @@ export default {
 };
 </script>
 <style lang="scss" scoped>
+.btnList {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+}
 .activeType {
   .right {
     .el-input {

+ 50 - 4
src/views/reportForm/index.vue

@@ -206,7 +206,9 @@
             $helpers.permission('export/studentVipPractice') ||
             $helpers.permission('export/exercisesSituation') ||
             $helpers.permission('export/exportIndexErrData') ||
-            $helpers.permission('export/exportMusicGroupCourseList')
+            $helpers.permission('export/exportMusicGroupCourseList')||
+            $helpers.permission('export/EXPORT_STUDENT_SUBCOURSE')
+
           "
         >
           <template slot="title">
@@ -473,7 +475,7 @@
             > -->
             <ExportChiose
               style="margin-left: 10px"
-              ExportEnum="EXPORT_INDEX_ERR_DATA"
+              ExportEnum="EXPORT_STUDENT_SUBCOURSE"
               :exportData="exportAbnormal"
               fileName="异常处理数据导出"
               errorMsg="请选择分部"
@@ -543,7 +545,10 @@
             />
           </div>
 
-          <div class="m-wrap" v-permission="'export/exportMusicGroupCourseList'">
+          <div
+            class="m-wrap"
+            v-permission="'export/exportMusicGroupCourseList'"
+          >
             <div class="title">乐团数据导出:</div>
             <select-all
               v-model.trim="teamOrganId"
@@ -588,6 +593,38 @@
               errorMsg="请选择导出月份"
             /> -->
           </div>
+          <div
+            class="m-wrap"
+            v-permission="'export/EXPORT_STUDENT_SUBCOURSE'"
+          >
+            <div class="title">活动资格导出:</div>
+            <select-all
+              v-model.trim="activeOrganId"
+              class="organSelect"
+              style="width: 100%"
+              filterable
+              multiple
+              placeholder="请选择分部"
+              clearable
+            >
+              <el-option
+                v-for="(item, index) in selects.branchs"
+                :key="index"
+                :label="item.name"
+                :value="item.id"
+              ></el-option>
+            </select-all>
+
+            <ExportChiose
+              style="margin-left: 10px"
+              ExportEnum="EXPORT_STUDENT_SUBCOURSE"
+              :exportData="exportActive"
+              fileName="活动资格导出"
+              errorMsg="请选择分部"
+
+              :isDownList="true"
+            />
+          </div>
         </el-collapse-item>
         <el-collapse-item
           name="3"
@@ -829,6 +866,7 @@ export default {
       VipStudentOrganId: [],
       teamOrganId: [],
       teamTimer: [],
+      activeOrganId: [],
     };
   },
   mounted() {
@@ -1516,7 +1554,9 @@ export default {
     //   );
     // },
     exportMusicGroup() {
-      let params = { ...getTimes(this.teamTimer, ["startTime", "endTime"]) ,organId:this.teamOrganId.join(',')
+      let params = {
+        ...getTimes(this.teamTimer, ["startTime", "endTime"]),
+        organId: this.teamOrganId.join(","),
       };
 
       Export(
@@ -1591,6 +1631,12 @@ export default {
       };
       return data;
     },
+    exportActive() {
+      let data = {
+        organId: this.activeOrganId.join(","),
+      };
+      return data;
+    },
 
     exportDetailService() {
       let sunday, monday;

+ 115 - 63
src/views/teamBuild/components/teamRemainTime.vue

@@ -1,11 +1,25 @@
 <template>
   <div>
-    <el-form ref="search" :model="search" inline @submit.stop.native="submit" @reset.stop.native="reset">
-      <el-form-item prop="keyword">
-        <el-input v-model.trim="search.keyword" clearable placeholder="学生姓名(手机/编号)"/>
+    <el-form
+      ref="search"
+      :model="search"
+      inline
+      @submit.stop.native="submit"
+      @reset.stop.native="reset"
+    >
+      <el-form-item prop="search">
+        <el-input
+          v-model.trim="search.search"
+          clearable
+          placeholder="学生姓名(手机/编号)"
+        />
       </el-form-item>
       <el-form-item prop="hastimer">
-        <el-select v-model.trim="search.hastimer" clearable placeholder="是否存在剩余时长">
+        <el-select
+          v-model.trim="search.hastimer"
+          clearable
+          placeholder="是否存在剩余时长"
+        >
           <el-option label="是" value="1"></el-option>
           <el-option label="否" value="0"></el-option>
         </el-select>
@@ -30,9 +44,12 @@
         <el-button type="danger" native-type="reset">重置</el-button>
       </el-form-item>
     </el-form>
+    <div  style="font-size: 14px; color: #f85043; padding-bottom: 10px">
+      当前共有{{studentNumber}}名学生有剩余时长未排课
+    </div>
     <el-table
-      :data="filterlist"
-      :header-cell-style="{background:'#EDEEF0',color:'#444'}"
+      :data="list"
+      :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
     >
       <!-- <el-table-column
         prop="type"
@@ -50,7 +67,7 @@
         align="center"
       >
         <template slot-scope="scope">
-          <copy-text>{{scope.row.userId}}</copy-text>
+          <copy-text>{{ scope.row.userId }}</copy-text>
         </template>
       </el-table-column>
       <el-table-column
@@ -60,7 +77,7 @@
         align="center"
       >
         <template slot-scope="scope">
-          <copy-text>{{scope.row.username}}</copy-text>
+          <copy-text>{{ scope.row.username }}</copy-text>
         </template>
       </el-table-column>
       <el-table-column
@@ -70,20 +87,18 @@
         align="center"
       >
         <template slot-scope="scope">
-          <copy-text>{{scope.row.phone}}</copy-text>
+          <copy-text>{{ scope.row.phone }}</copy-text>
         </template>
       </el-table-column>
-      <el-table-column
-        label="课程时长"
-      >
+      <el-table-column label="课程时长">
         <template slot-scope="scope">
           <el-tag
-            style="margin-right: 5px;margin-bottom: 5px;"
+            style="margin-right: 5px; margin-bottom: 5px"
             v-for="item in scope.row.mapDtos"
             :key="item.key"
             type="info"
-
-          >{{courseType[item.key]}}: {{item.value}}分钟</el-tag>
+            >{{ courseType[item.key] }}: {{ item.value }}分钟</el-tag
+          >
         </template>
       </el-table-column>
       <!-- <el-table-column
@@ -92,15 +107,24 @@
         align="center"
       /> -->
     </el-table>
+    <pagination
+      sync
+      :total.sync="rules.total"
+      :page.sync="rules.page"
+      :limit.sync="rules.limit"
+      :page-sizes="rules.page_size"
+      @pagination="FetchDetail"
+    />
   </div>
 </template>
 
 <script>
-import { queryStudentSubTotalCourseTimes } from '@/views/teamDetail/api'
+import { queryStudentSubTotalCourseTimes,countStudentSubTotalCourseTimes } from "@/views/teamDetail/api";
+import pagination from "@/components/Pagination/index";
 import { getMusicGroupAllClass } from "@/api/buildTeam";
-import { courseType } from '@/constant'
+import { courseType } from "@/constant";
 export default {
-  props: ['detail'],
+  props: ["detail"],
   data() {
     return {
       courseType,
@@ -108,75 +132,103 @@ export default {
       filterlist: [],
       extra: [],
       search: {
-        keyword: '',
-        hastimer: '',
+        search: "",
+        hastimer: "",
         classGroupId: null,
       },
-      classList: []
-    }
+      classList: [],
+      studentNumber:0,
+      rules: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+    };
+  },
+  components: {
+    pagination,
   },
   mounted() {
-    this.FetchDetail()
-    this.getMusicClass()
+    this.FetchDetail();
+    this.getMusicClass();
+    this.getTeamStudentNum()
+    //countStudentSubTotalCourseTimes
   },
   methods: {
+   async getTeamStudentNum(){
+    try {
+        const res = await countStudentSubTotalCourseTimes({
+          musicGroupId: this.$route.query.id,
+         hastimer:true,
+        });
+        this.studentNumber = res.data || 0;
+        // this.list = Object.keys(res.data).map(item => ({type: item, time: res.data[item]}))
+      } catch (error) {}
+    },
     getMusicClass() {
-      getMusicGroupAllClass({ musicGroupId: this.$route.query.id, }).then((res) => {
-        if (res.code == 200) {
-          this.classList = res.data;
+      getMusicGroupAllClass({ musicGroupId: this.$route.query.id }).then(
+        (res) => {
+          if (res.code == 200) {
+            this.classList = res.data;
+          }
         }
-      });
+      );
     },
     array2object(list = []) {
-      const data = {}
+      const data = {};
       for (const item of list) {
-        data[item.key] = item.value
+        data[item.key] = item.value;
       }
-      return data
+      return data;
     },
     filter() {
-      const { keyword, hastimer, classGroupId } = this.search
-      this.filterlist = this.list.filter(item => {
-        const user = !keyword || (
-          ('' + item.userId).indexOf(keyword) > -1 ||
-          ('' + item.phone).indexOf(keyword) > -1 ||
-          ('' + item.username).indexOf(keyword) > -1
-        )
-        const length = item.mapDtos.filter(dto => dto.value > 0).length
-        const couse = !hastimer || (hastimer == '1' && length || hastimer == '0' && !length)
-        const classGroup = !classGroupId || item.classGroupId.indexOf(classGroupId) >= 0
-        return user && couse && classGroup
-      })
+      const { keyword, hastimer, classGroupId } = this.search;
+      this.filterlist = this.list.filter((item) => {
+        const user =
+          !keyword ||
+          ("" + item.userId).indexOf(keyword) > -1 ||
+          ("" + item.phone).indexOf(keyword) > -1 ||
+          ("" + item.username).indexOf(keyword) > -1;
+        const length = item.mapDtos.filter((dto) => dto.value > 0).length;
+        const couse =
+          !hastimer ||
+          (hastimer == "1" && length) ||
+          (hastimer == "0" && !length);
+        const classGroup =
+          !classGroupId || item.classGroupId.indexOf(classGroupId) >= 0;
+        return user && couse && classGroup;
+      });
     },
     submit(evt) {
-      evt.stopPropagation()
-      evt.stopImmediatePropagation()
-      evt.preventDefault()
-      this.filter()
+      this.rules.page = 1;
+      this.FetchDetail();
     },
     reset(evt) {
-      evt.stopPropagation()
-      evt.stopImmediatePropagation()
-      evt.preventDefault()
+      // evt.stopPropagation();
+      // evt.stopImmediatePropagation();
+      // evt.preventDefault();
       this.search = {
-        keyword: '',
-        hastimer: ''
-      }
-      this.filter()
+        search: "",
+        hastimer: "",
+        classGroupId: null,
+      };
+      this.submit();
     },
     async FetchDetail() {
       try {
         const res = await queryStudentSubTotalCourseTimes({
           musicGroupId: this.$route.query.id,
-        })
-        this.list = res.data
-        this.filter()
-        if (res.data[0]) {
-          this.extra = res.data[0].mapDtos
-        }
+          ...this.search,
+          page: this.rules.page,
+          rows: this.rules.limit,
+        });
+        this.list = res.data.rows;
+        this.rules.total = res.data.total;
         // this.list = Object.keys(res.data).map(item => ({type: item, time: res.data[item]}))
       } catch (error) {}
-    }
-  }
-}
+    },
+  },
+};
 </script>

+ 7 - 1
src/views/teamDetail/api.js

@@ -48,4 +48,10 @@ export const resetClassName = data => request2({
   method: 'post'
 })
 
-
+// 获取乐团剩余为排课学员数
+export const countStudentSubTotalCourseTimes = data => request2({
+  url: '/api-web/studentManage/countStudentSubTotalCourseTimes',
+  params: data,
+  method: 'get',
+  requestType: 'form'
+})