Pārlūkot izejas kodu

05/07 18:09 代码 备份

mo 5 gadi atpakaļ
vecāks
revīzija
0bdbf681ea

+ 31 - 12
src/api/operateManager.js

@@ -3,19 +3,38 @@ import qs from 'qs'
 let api = '/api-web'
 
 // 列表
-export function getOperatingStudents(data) {
-    return request({
-        url: api + '/studentManage/getOperatingStudents',
-        method: 'GET',
-        params: data
-    })
+export function getOperatingStudents (data) {
+  return request({
+    url: api + '/studentManage/getOperatingStudents',
+    method: 'GET',
+    params: data
+  })
 }
 
 // 结转奖励
-export function teacherCourseReward(data) {
-    return request({
-        url: api + '/teacherCourseReward/queryPage',
-        method: 'GET',
-        params: data
-    })
+export function teacherCourseReward (data) {
+  return request({
+    url: api + '/teacherCourseReward/queryPage',
+    method: 'GET',
+    params: data
+  })
+}
+
+
+// 服务指标详情
+export function findServiceStudentDetail (data) {
+  return request({
+    url: api + '/exercisesSituation/findServiceStudentDetail',
+    method: 'GET',
+    params: data
+  })
+}
+
+// 获取 回复查询
+export function findStudentHomeworkComments (data) {
+  return request({
+    url: api + '/exercisesSituation/findStudentHomeworkComments',
+    method: 'GET',
+    params: data
+  })
 }

+ 11 - 7
src/router/index.js

@@ -121,7 +121,7 @@ const createRouter = () => new Router({
 const router = createRouter()
 
 // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
-export function resetRouter() {
+export function resetRouter () {
   const newRouter = createRouter()
   router.matcher = newRouter.matcher // reset router
 }
@@ -134,7 +134,7 @@ export const asyncRoutes = {
   contentOperation: () => import('@/views/contentManager/contentOperation'),
   // 系统日志
   journal: () => import('@/views/workBenchManager/journal/index'),
-   // 课酬确认
+  // 课酬确认
   classFeesIsOk: () => import('@/views/workBenchManager/classFeesIsOk'),
   // 申述处理
   requestProcessing: () => import('@/views/workBenchManager/requestProcessing'),
@@ -251,7 +251,7 @@ export const asyncRoutes = {
   accompanys: () => import('@/views/accompanyManager/accompanys'),
   accompany: () => import('@/views/accompanyManager'),
   // 网管课购买
-  accompanyBuys:() => import('@/views/accompanyManager/accompanyBuys'),
+  accompanyBuys: () => import('@/views/accompanyManager/accompanyBuys'),
   // 版本控制
   editionList: () => import('@/views/editionManager/editionList'),
   // 定时任务
@@ -281,11 +281,15 @@ export const asyncRoutes = {
   // // 课外作业
   // afterWorkList:()=>import('@/views/afterSchoolManager/afterWorkList'),
   // 课外管理
-  afterSchoolManager:()=>import('@/views/afterSchoolManager'),
-  afterSchoolDetail:()=>import('@/views/afterSchoolManager/afterSchoolDetail'),
+  afterSchoolManager: () => import('@/views/afterSchoolManager'),
+  afterSchoolDetail: () => import('@/views/afterSchoolManager/afterSchoolDetail'),
   // 运营管理 学员列表
-  operateStudent:()=>import('@/views/operateManager/operateStudent'),
+  operateStudent: () => import('@/views/operateManager/operateStudent'),
   // 运营管理 结转奖励
-  settlementList:()=>import('@/views/settlementManager/settlementList'),
+  settlementList: () => import('@/views/settlementManager/settlementList'),
+  // 运营管理 服务指标
+  serverIndexList: () => import('@/views/operateManager/serverIndexList'),
+  // 运营管理 服务指标详情
+  serverIndexDetail: () => import('@/views/operateManager/serverIndexDetail'),
 }
 export default router

+ 18 - 15
src/views/afterSchoolManager/index.vue

@@ -5,18 +5,21 @@
       <div class="squrt"></div>课外训练
     </h2>
     <div class="m-core">
-      <el-tabs v-model.trim="activeIndex" type="card" @tab-click="handleClick">
-        <el-tab-pane label="课外训练" name="1">
-          <afterSchoolList v-if="activeIndex == 1" ></afterSchoolList>
+      <el-tabs v-model.trim="activeIndex"
+               type="card"
+               @tab-click="handleClick">
+        <el-tab-pane label="课外训练"
+                     name="1">
+          <afterSchoolList v-if="activeIndex == 1"></afterSchoolList>
         </el-tab-pane>
-        <el-tab-pane label="课外训练(教学)" name="2">
+        <!-- <el-tab-pane label="课外训练(教学)" name="2">
           <afterSchoolTeach
             v-if="activeIndex == 2"
           ></afterSchoolTeach>
-        </el-tab-pane>
-           <el-tab-pane label="课外训练(学员)" name="3">
-          <afterWorkList
-            v-if="activeIndex == 3" ></afterWorkList>
+        </el-tab-pane> -->
+        <el-tab-pane label="课外训练(学员)"
+                     name="3">
+          <afterWorkList v-if="activeIndex == 3"></afterWorkList>
         </el-tab-pane>
       </el-tabs>
     </div>
@@ -28,29 +31,29 @@ import afterSchoolList from "@/views/afterSchoolManager/afterSchoolList";
 import afterWorkList from "@/views/afterSchoolManager/afterWorkList";
 import afterSchoolTeach from "@/views/afterSchoolManager/afterSchoolTeach";
 export default {
-  components: { afterSchoolList, afterWorkList,afterSchoolTeach },
-  data() {
+  components: { afterSchoolList, afterWorkList, afterSchoolTeach },
+  data () {
     return {
       activeIndex: "1",
       extracurricularExercisesId: null
     };
   },
   //生命周期 - 创建完成(可以访问当前this实例)
-  created() {},
+  created () { },
   //生命周期 - 挂载完成(可以访问DOM元素)
-  mounted() {
+  mounted () {
     this.init();
   },
-  activated() {
+  activated () {
     this.init()
   },
   methods: {
-    init() {
+    init () {
       this.$route.query.activeIndex
         ? (this.activeIndex = this.$route.query.activeIndex)
         : this.activeIndex;
     },
-    handleClick(){}
+    handleClick () { }
   }
 };
 </script>

+ 112 - 88
src/views/operateManager/operateStudent.vue

@@ -2,118 +2,142 @@
 <template>
   <div class="m-container">
     <h2>
-      <div class="squrt"></div>运营指标管理
+      <div class="squrt"></div>运营指标
     </h2>
     <div class="m-core">
-      <el-form :inline="true" :model="searchForm">
+      <el-form :inline="true"
+               :model="searchForm">
         <el-form-item>
-          <el-input
-            v-model.trim="searchForm.search"
-            @keyup.enter.native="search"
-            placeholder="学生姓名 编号"
-          ></el-input>
+          <el-input v-model.trim="searchForm.search"
+                    @keyup.enter.native="search"
+                    placeholder="学生姓名 编号"></el-input>
         </el-form-item>
         <el-form-item prop="organId">
-          <el-select
-            class="multiple"
-            v-model.trim="searchForm.organId"
-            filterable
-            clearable
-            placeholder="请选择分部"
-          >
-            <el-option
-              v-for="(item,index) in organList"
-              :key="index"
-              :label="item.name"
-              :value="item.id"
-            ></el-option>
+          <el-select class="multiple"
+                     v-model.trim="searchForm.organId"
+                     filterable
+                     clearable
+                     placeholder="请选择分部">
+            <el-option v-for="(item,index) in organList"
+                       :key="index"
+                       :label="item.name"
+                       :value="item.id"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item>
-          <el-select placeholder="老师姓名" v-model="searchForm.teacherId" clearable filterable>
-            <el-option
-              v-for="(item,index) in teacherList"
-              :label="item.realName"
-              :value="item.id"
-              :key="index"
-            ></el-option>
+          <el-select placeholder="老师姓名"
+                     v-model="searchForm.teacherId"
+                     clearable
+                     filterable>
+            <el-option v-for="(item,index) in teacherList"
+                       :label="item.realName"
+                       :value="item.id"
+                       :key="index"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item>
-          <el-select placeholder="参与运营指标" v-model="searchForm.operatingTag" clearable>
-            <el-option label="是" value="1"></el-option>
-            <el-option label="否" value="0"></el-option>
+          <el-select placeholder="参与运营指标"
+                     v-model="searchForm.operatingTag"
+                     clearable>
+            <el-option label="是"
+                       value="1"></el-option>
+            <el-option label="否"
+                       value="0"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item>
-          <el-select placeholder="有线上vip课" v-model="searchForm.hasVip" clearable>
-            <el-option label="是" value="1"></el-option>
-            <el-option label="否" value="0"></el-option>
+          <el-select placeholder="有线上vip课"
+                     v-model="searchForm.hasVip"
+                     clearable>
+            <el-option label="是"
+                       value="1"></el-option>
+            <el-option label="否"
+                       value="0"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item>
-          <el-select placeholder="参与免费网管课" v-model="searchForm.hasFreePractice" clearable>
-            <el-option label="是" value="1"></el-option>
-            <el-option label="否" value="0"></el-option>
+          <el-select placeholder="参与免费网管课"
+                     v-model="searchForm.hasFreePractice"
+                     clearable>
+            <el-option label="是"
+                       value="1"></el-option>
+            <el-option label="否"
+                       value="0"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item>
-          <el-select placeholder="有付费网管课" v-model="searchForm.hasBuyPractice" clearable>
-            <el-option label="是" value="1"></el-option>
-            <el-option label="否" value="0"></el-option>
+          <el-select placeholder="有付费网管课"
+                     v-model="searchForm.hasBuyPractice"
+                     clearable>
+            <el-option label="是"
+                       value="1"></el-option>
+            <el-option label="否"
+                       value="0"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item>
-          <el-button type="danger" @click="search">搜索</el-button>
-          <el-button @click="onReSet" type="primary">重置</el-button>
+          <el-button type="danger"
+                     @click="search">搜索</el-button>
+          <el-button @click="onReSet"
+                     type="primary">重置</el-button>
           <!-- export/isSettlementCourseSalarys -->
-          <el-button
-            @click="onExport"
-            type="primary"
-            v-permission="'export/operatingStudents'"
-            style=" background: #14928a; border:1px solid #14928a;"
-          >导出</el-button>
+          <el-button @click="onExport"
+                     type="primary"
+                     v-permission="'export/operatingStudents'"
+                     style=" background: #14928a; border:1px solid #14928a;">导出</el-button>
         </el-form-item>
       </el-form>
 
       <div class="tableWrap">
-        <el-table
-          style="width: 100%"
-          :header-cell-style="{background:'#EDEEF0',color:'#444'}"
-          :data="tableList"
-        >
-          <el-table-column align="center" prop="studentId" label="学员编号"></el-table-column>
-          <el-table-column align="center" prop="studentName" label="学员姓名"></el-table-column>
-          <el-table-column align="center" prop="organName" label="所属分部"></el-table-column>
-          <el-table-column align="center" prop="teacherName" label="指导老师"></el-table-column>
-           <el-table-column align="center" prop="operatingTag" label="参与运营指标">
-               <template slot-scope="scope">
+        <el-table style="width: 100%"
+                  :header-cell-style="{background:'#EDEEF0',color:'#444'}"
+                  :data="tableList">
+          <el-table-column align="center"
+                           prop="studentId"
+                           label="学员编号"></el-table-column>
+          <el-table-column align="center"
+                           prop="studentName"
+                           label="学员姓名"></el-table-column>
+          <el-table-column align="center"
+                           prop="organName"
+                           label="所属分部"></el-table-column>
+          <el-table-column align="center"
+                           prop="teacherName"
+                           label="指导老师"></el-table-column>
+          <el-table-column align="center"
+                           prop="operatingTag"
+                           label="参与运营指标">
+            <template slot-scope="scope">
               <div>{{scope.row.operatingTag?'是':'否'}}</div>
             </template>
-           </el-table-column>
-             <el-table-column align="center" prop="vipTimes" label="有线上vip课">
-               <template slot-scope="scope">
+          </el-table-column>
+          <el-table-column align="center"
+                           prop="vipTimes"
+                           label="有线上vip课">
+            <template slot-scope="scope">
               <div>{{scope.row.vipTimes?'是':'否'}}</div>
             </template>
-           </el-table-column>
-             <el-table-column align="center" prop="freePracticeTimes" label="参与免费网管课">
-               <template slot-scope="scope">
+          </el-table-column>
+          <el-table-column align="center"
+                           prop="freePracticeTimes"
+                           label="参与免费网管课">
+            <template slot-scope="scope">
               <div>{{scope.row.freePracticeTimes?'是':'否'}}</div>
             </template>
-           </el-table-column>
-                <el-table-column align="center" prop="buyPracticeTimes" label="有付费网管课">
-               <template slot-scope="scope">
+          </el-table-column>
+          <el-table-column align="center"
+                           prop="buyPracticeTimes"
+                           label="有付费网管课">
+            <template slot-scope="scope">
               <div>{{scope.row.buyPracticeTimes?'是':'否'}}</div>
             </template>
-           </el-table-column>
+          </el-table-column>
         </el-table>
-        <pagination
-          :total="rules.total"
-          :page.sync="rules.page"
-          :limit.sync="rules.limit"
-          :page-sizes="rules.page_size"
-          @pagination="getList"
-        />
+        <pagination :total="rules.total"
+                    :page.sync="rules.page"
+                    :limit.sync="rules.limit"
+                    :page-sizes="rules.page_size"
+                    @pagination="getList" />
       </div>
     </div>
   </div>
@@ -128,7 +152,7 @@ import { getTeacher, getEmployeeOrgan } from "@/api/buildTeam";
 import { getOperatingStudents } from "@/api/operateManager";
 export default {
   components: { pagination },
-  data() {
+  data () {
     return {
       searchForm: {
         search: null,
@@ -152,11 +176,11 @@ export default {
     };
   },
   //生命周期 - 创建完成(可以访问当前this实例)
-  created() {},
-  activated() {
+  created () { },
+  activated () {
     this.init();
   },
-  mounted() {
+  mounted () {
     getTeacher().then(res => {
       if (res.code == 200) {
         this.teacherList = res.data;
@@ -171,16 +195,16 @@ export default {
     this.init();
   },
   methods: {
-    init() {
-      if(this.$route.query.teacherId){
+    init () {
+      if (this.$route.query.teacherId) {
         this.searchForm.teacherId = this.$route.query.teacherId
       }
-      if(this.$route.query.operatingTag){
+      if (this.$route.query.operatingTag) {
         this.searchForm.operatingTag = this.$route.query.operatingTag
       }
       this.getList();
     },
-    getList() {
+    getList () {
       let obj = this.getDate();
       getOperatingStudents(obj).then(res => {
         if (res.code == 200) {
@@ -189,11 +213,11 @@ export default {
         }
       });
     },
-    search() {
+    search () {
       this.rules.page = 1;
       this.getList();
     },
-    onReSet() {
+    onReSet () {
       this.searchForm = {
         search: null,
         organId: null,
@@ -205,7 +229,7 @@ export default {
       };
       this.search();
     },
-    onExport() {
+    onExport () {
       let url = "/api-web/export/operatingStudents";
       let obj = this.getDate();
       const options = {
@@ -267,9 +291,9 @@ export default {
               load.endLoading();
             });
         })
-        .catch(() => {});
+        .catch(() => { });
     },
-    getDate() {
+    getDate () {
       let obj = {
         search: this.searchForm.search || null,
         organId: this.searchForm.organId || null,

+ 346 - 0
src/views/operateManager/serverIndexDetail.vue

@@ -0,0 +1,346 @@
+<template >
+  <div class='m-container'>
+    <h2>
+      <!-- <div class="squrt"></div> -->
+      <el-page-header @back="goBack"
+                      :content="studentName">
+      </el-page-header>
+    </h2>
+    <p class="timeTitle">查询时间 : {{monday}} - {{sunday}}</p>
+    <el-card class="box-card"
+             style="width:1000px">
+      <div class="listWrap"
+           v-for="(item,index) in dataList"
+           :key="index">
+        <div class="m-row">
+          <div class="textWrap">
+            <p class="title">类型 : </p>
+            <p class="contant">{{item.homeworkType=='HOMEWORK'?'网管课':'课外训练'}}</p>
+          </div>
+          <div class="
+               textWrap">
+            <p class="title">布置时间 : </p>
+            <p class="contant"
+               v-if="item.homeworkCreateTime"
+               style="width:150px">{{ item.homeworkCreateTime | dateForMinFormat}}</p>
+          </div>
+          <div class="textWrap">
+            <p class="title">是否点评 : </p>
+            <p class="contant">{{item.isSubmit?'是':'否'}}</p>
+          </div>
+        </div>
+        <div class="m-row"
+             v-if="item.homeworkType == 'HOMEWORK'">
+          <div class="textWrap">
+            <p class="title">课程组 : </p>
+            <p class="contant">{{item.groupName}}</p>
+          </div>
+          <div class="textWrap">
+            <p class="title">上课时间 : </p>
+            <p class="contant"
+               style="width:150px"
+               v-if="item.courseStartTime">{{item.courseStartTime |  dateForMinFormat}}</p>
+          </div>
+        </div>
+        <div class="m-row">
+          <div class="textWrap">
+            <p class="title">指导老师 : </p>
+            <p class="contant">{{item.teacherName}}</p>
+          </div>
+          <div class="textWrap">
+            <p class="title">提交时间 : </p>
+            <p class="contant"
+               v-if="item.submitTime"
+               style="width:150px">{{item.submitTime | dateForMinFormat}}</p>
+          </div>
+
+        </div>
+        <div class="arrowBox"
+             @click="getComment(item)">
+          <div class="border">
+            <i :class="item.up?'el-icon-arrow-up':'el-icon-arrow-down'"></i>
+          </div>
+
+        </div>
+
+        <div style="margin-top: 20px;">
+          <el-collapse-transition>
+            <div v-show="item.up">
+              <div class="transition-box">
+                <div class="cell">
+                  <p style="width:80px; padding-top:4px;">作业内容:</p>
+                  <el-input type="textarea"
+                            :disabled='true'
+                            :rows="3"
+                            :value="111"
+                            style="font-size:16px"
+                            placeholder="老师布置的作业"></el-input>
+                </div>
+                <div class="cell">
+                  <p style="width:80px;">查看作业:</p>
+                  <div v-for='(some,index) in item.homeWork'
+                       :key="index">
+                    <p class="homeWork"
+                       v-if="some"
+                       @click="openVideo(some)">作业{{(index+1)}}</p>
+                  </div>
+
+                </div>
+              </div>
+              <div class="msgWrap">
+                <div class="msgLi"
+                     v-for='(msg,index) in activeCommit'
+                     :key="index">
+                  <div class="info">
+                    <p>{{msg.userName}}</p>
+                    <p style="color:#999"
+                       v-if="msg.createTime">{{msg.createTime | dateForMinFormat}}</p>
+                  </div>
+                  <p class="contant"
+                     v-if='msg.msgType=="TXT"'>{{msg.content}}</p>
+                  <a class="contant"
+                     :href="msg.content"
+                     target="_blank"
+                     style="display:block;color:#1890FF"
+                     v-if='msg.msgType=="IMG"'>查看图片</a>
+                  <p v-if='msg.msgType=="VC"'
+                     class="contant"
+                     style="color:#1890FF"
+                     @click="openAideo(msg.content)">播放语音</p>
+                </div>
+              </div>
+            </div>
+          </el-collapse-transition>
+        </div>
+        <el-divider></el-divider>
+      </div>
+    </el-card>
+    <el-dialog title="查看作业"
+               width="360px"
+               append-to-body
+               :visible.sync="workVisible">
+      <!-- activeUrl -->
+      <video style="width:320px;"
+             :src="activeUrl"
+             ref="dialogVideo"
+             controls="controls">您的浏览器不支持视频播放</video>
+    </el-dialog>
+    <el-dialog title="查看评论"
+               width="680px"
+               append-to-body
+               :visible.sync="comVisible">
+      <!-- activeUrl -->
+      <audio controls
+             style="width:640px;"
+             :src="comUrl"
+             ref="dialogVideo"
+             controls="controls">您的浏览器不支持视频播放</audio>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { findServiceStudentDetail, findStudentHomeworkComments } from "@/api/operateManager";
+export default {
+  data () {
+    return {
+      studentId: null,
+      monday: null,
+      sunday: null,
+      studentName: null,
+      show3: false,
+      dataList: [],
+      activeCommit: [],
+      activeUrl: null,
+      workVisible: false,
+      comUrl: null,
+      comVisible: null,
+      Fsearch: null,
+      Frules: null
+    }
+  },
+  mounted () {
+    this.init()
+  },
+  activated () {
+    this.init()
+  },
+  methods: {
+    init () {
+      this.studentId = this.$route.query.studentId;
+      this.studentName = this.$route.query.studentName;
+      this.monday = this.$route.query.startTime;
+      this.sunday = this.$route.query.endTime;
+      // 判断是否带缓存参数
+      if (this.$route.query.search) {
+        this.Fsearch = this.$route.query.search;
+      }
+      if (this.$route.query.rules) {
+        this.Frules = this.$route.query.rules
+      }
+      findServiceStudentDetail({ studentId: this.studentId, monday: this.monday, sunday: this.sunday, rows: 9999 }).then(res => {
+        if (res.code == 200) {
+          this.dataList = res.data.rows.map(res => {
+            res.up = false;
+            res.homeWork = res.attachments.split(',')
+            console.log(res.homeWork)
+            return res;
+          });
+        }
+      })
+
+    },
+    goBack () {
+      this.$router.push({ path: '/operateManager/serverIndexList', query: { search: this.Fsearch, rules: this.Frules } })
+    },
+    getComment (item) {
+      // 数据处理
+      if (item.up) {
+        item.up = false;
+      } else {
+        let extra;
+        if (item.homeworkType == 'EXTRA') {
+          extra = 1;
+        } else {
+          extra = 0;
+        }
+
+        findStudentHomeworkComments({ studentCourseHomeworkId: item.studentHomeworkId, extra, rows: 9999 }).then(res => {
+          if (res.code == 200) {
+            this.activeCommit = res.data.rows;
+            item.up = false
+            this.dataList.map(res => {
+              res.up = false;
+              return res;
+            })
+            item.up = true;
+          }
+        })
+      }
+
+
+    },
+    openAideo (src) {
+      this.comUrl = src;
+      this.comVisible = true;
+    },
+    openVideo (src) {
+      this.activeUrl = src;
+      this.workVisible = true;
+    }
+
+  },
+  watch: {
+    workVisible (val) {
+      if (!val) {
+        this.activeUrl = null
+      }
+    },
+    comVisible (val) {
+      if (!val) {
+        this.comUrl = null
+      }
+    },
+  }
+
+}
+</script>
+<style lang='scss' scoped>
+.timeTitle {
+  margin-bottom: 20px;
+}
+.box-card {
+  .listWrap {
+    cursor: pointer;
+    margin-bottom: 50px;
+    .m-row {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      font-size: 14px;
+      .textWrap {
+        margin-right: 150px;
+        display: flex;
+        flex-direction: row;
+        justify-content: flex-start;
+        p {
+          line-height: 30px;
+        }
+        .title {
+          width: 80px;
+          margin-right: 10px;
+          text-align: left;
+        }
+        .contant {
+          text-align: left;
+          width: 150px;
+        }
+      }
+    }
+    .arrowBox {
+      display: flex;
+      flex-direction: row;
+      justify-content: center;
+
+      .border {
+        margin-top: 20px;
+        width: 120px;
+        border: 1px solid #dedede;
+        border-radius: 5px;
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        height: 30px;
+        line-height: 30px;
+        i {
+          font-size: 18px;
+          line-height: 30px;
+          color: #999;
+        }
+      }
+    }
+  }
+  .cell {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    margin-bottom: 20px;
+    line-height: 30px;
+    font-size: 14px;
+    .homeWork {
+      width: 80px;
+      text-align: center;
+      border: 1px solid #e5e5e5;
+      height: 30px;
+      line-height: 30px;
+      border-radius: 4px;
+      margin-right: 20px;
+      font-size: 14px;
+      cursor: pointer;
+    }
+  }
+  .msgWrap {
+    border: 1px solid #e5e5e5;
+    padding: 5px 20px;
+    border-radius: 5px;
+    height: 300px;
+    overflow: auto;
+    font-size: 14px;
+    .msgLi {
+      padding: 10px 0;
+      .info {
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        margin-bottom: 10px;
+        padding: 0 10px;
+      }
+      .contant {
+        border-bottom: 1px solid #ededed;
+        line-height: 30px;
+        padding: 0 10px;
+        color: #666;
+      }
+    }
+  }
+}
+</style>

+ 502 - 0
src/views/operateManager/serverIndexList.vue

@@ -0,0 +1,502 @@
+<!--  -->
+<template>
+  <div class="m-container">
+    <h2>
+      <div class="squrt"></div>服务指标
+    </h2>
+    <div class="m-core">
+      <el-form :inline="true"
+               :model="searchForm">
+        <el-form-item>
+          <el-input v-model.trim="searchForm.search"
+                    @keyup.enter.native="search"
+                    placeholder="学生姓名"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-select placeholder="指导老师"
+                     v-model="searchForm.teacherId"
+                     clearable
+                     filterable>
+            <el-option v-for="(item,index) in teacherList"
+                       :label="item.realName"
+                       :value="item.id"
+                       :key="index"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="organId">
+          <el-select class="multiple"
+                     v-model.trim="searchForm.organIdList"
+                     filterable
+                     clearable
+                     placeholder="请选择分部">
+            <el-option v-for="(item,index) in organList"
+                       :key="index"
+                       :label="item.name"
+                       :value="item.id"></el-option>
+          </el-select>
+        </el-form-item>
+        <!-- <el-form-item>
+          <el-select placeholder="当前有VIP课" v-model="searchForm.existVipCourse" clearable>
+            <el-option label="是" value="1"></el-option>
+            <el-option label="否" value="0"></el-option>
+          </el-select>
+        </el-form-item> -->
+        <el-form-item>
+          <el-select placeholder="实际安排"
+                     v-model="searchForm.actualExercisesNumIsAchieve"
+                     clearable>
+            <el-option label="符合预期"
+                       value="1"></el-option>
+            <el-option label="不符合预期"
+                       value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-select placeholder="提交次数"
+                     v-model="searchForm.exercisesReplyNumIsAchieve"
+                     clearable>
+            <el-option label="符合预期"
+                       value="1"></el-option>
+            <el-option label="不符合预期"
+                       value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-select placeholder="评价次数"
+                     v-model="searchForm.exercisesMessageNumIsAchieve"
+                     clearable>
+            <el-option label="符合预期"
+                       value="1"></el-option>
+            <el-option label="不符合预期"
+                       value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-select placeholder="及时评价"
+                     v-model="searchForm.exercisesMessageTimelyNumIsAchieve"
+                     clearable>
+            <el-option label="符合预期"
+                       value="1"></el-option>
+            <el-option label="不符合预期"
+                       value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-select placeholder="是否有VIP课"
+                     v-model="searchForm.existVipCourse"
+                     clearable>
+            <el-option label="是"
+                       value="1"></el-option>
+            <el-option label="否"
+                       value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-select placeholder="是否有付费网管课"
+                     v-model="searchForm.existPracticeCourse"
+                     clearable>
+            <el-option label="是"
+                       value="1"></el-option>
+            <el-option label="否"
+                       value="0"></el-option>
+          </el-select>
+        </el-form-item>
+        <br>
+        <el-form-item label="周次选择">
+          <el-date-picker v-model.trim="searchForm.timer"
+                          style="width:400px;"
+                          type="daterange"
+                          :picker-options="{
+        firstDayOfWeek: 1
+    }"
+                          value-format="yyyy-MM-dd"
+                          range-separator="至"
+                          start-placeholder="开始日期"
+                          end-placeholder="结束日期"
+                          @change="getWeekTime"></el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="danger"
+                     @click="search">搜索</el-button>
+          <el-button @click="onReSet"
+                     type="primary">重置</el-button>
+          <el-button @click="onExport"
+                     type="primary"
+                     v-permission="'export/exercisesSituations'"
+                     style=" background: #14928a; border:1px solid #14928a;">导出</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="tableWrap">
+        <el-table style="width: 100%"
+                  :header-cell-style="{background:'#EDEEF0',color:'#444'}"
+                  :data="tableList">
+          <el-table-column align="center"
+                           prop="studentId"
+                           label="学员编号"></el-table-column>
+          <el-table-column align="center"
+                           prop="studentName"
+                           label="学生姓名"></el-table-column>
+          <el-table-column align="center"
+                           prop="organName"
+                           label="所属分部"></el-table-column>
+          <el-table-column align="center"
+                           prop="teacherName"
+                           label="指导老师"></el-table-column>
+          <!-- <el-table-column align="center" label="当前有VIP课" width="100" >
+            <template slot-scope="scope">
+              <div>{{scope.row.existVipCourse?'是':'否'}}</div>
+            </template>
+          </el-table-column> -->
+          <el-table-column align="center"
+                           prop
+                           label="预期安排">
+            <template slot-scope="scope">
+              <div>{{scope.row.expectExercisesNum+'次'}}</div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center"
+                           prop
+                           label="实际安排">
+            <template slot-scope="scope">
+              <div>{{scope.row.actualExercisesNum+'次'}}</div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center"
+                           prop
+                           label="提交次数">
+            <template slot-scope="scope">
+              <div>{{scope.row.exercisesReplyNum+'次'}}</div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center"
+                           prop
+                           label="评价次数">
+            <template slot-scope="scope">
+              <div>{{scope.row.exercisesMessageNum+'次'}}</div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center"
+                           prop
+                           label="及时评价次数">
+            <template slot-scope="scope">
+              <div>{{scope.row.exercisesMessageTimelyNum+'次'}}</div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center"
+                           label="VIP课">
+            <template slot-scope="scope">
+              <div>{{scope.row.existVipCourse + '节'}}</div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center"
+                           label="付费网管课">
+            <template slot-scope="scope">
+              <div>{{scope.row.existPracticeCourse+ '节'}}</div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center"
+                           label="操作">
+            <!--  -->
+            <template slot-scope="scope">
+              <div v-if="scope.row.actualExercisesNum >0">
+                <el-button type="text"
+                           @click="lookDetail(scope.row)">查看</el-button>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination :total="rules.total"
+                    :page.sync="rules.page"
+                    :limit.sync="rules.limit"
+                    :page-sizes="rules.page_size"
+                    @pagination="getList" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import { getToken } from "@/utils/auth";
+import pagination from "@/components/Pagination/index";
+import load from "@/utils/loading";
+import { getEmployeeOrgan, getTeacher } from "@/api/buildTeam";
+import { findStudentExtracurricularExercisesSituations } from "@/api/afterSchool";
+// findStudentExtracurricularExercisesSituations
+let nowTime = new Date();
+nowTime =
+  nowTime.getFullYear() +
+  "-" +
+  (nowTime.getMonth() + 1) +
+  "-" +
+  nowTime.getDate();
+export default {
+  components: { pagination },
+  data () {
+    return {
+      tableList: [],
+      searchForm: {
+        timer: [],
+        search: null,
+        organIdList: null,
+        actualExercisesNumIsAchieve: null, // 训练次数
+        exercisesMessageNumIsAchieve: null, //评价
+        exercisesMessageTimelyNumIsAchieve: null, //及时评价
+        exercisesReplyNumIsAchieve: null, // 提交次数
+        teacherId: null,
+        existVipCourse: null,
+        existPracticeCourse: null,
+
+      },
+      organList: [],
+      teacherList: [],
+      rules: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50] // 选择限制显示条数
+      }
+    };
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 设置默认为当前周
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {
+    this.searchForm.timer = [];
+    this.searchForm.timer.push(this.getNowDateAndMonday(nowTime));
+    this.searchForm.timer.push(this.getNowDateAndSunday(nowTime));
+    getTeacher().then(res => {
+      if (res.code == 200) {
+        this.teacherList = res.data;
+      }
+    });
+
+    getEmployeeOrgan().then(res => {
+      if (res.code == 200) {
+        this.organList = res.data;
+      }
+    });
+    // 获取分部  老师
+    this.init();
+  },
+  activated () {
+    this.init();
+  },
+  methods: {
+    init () {
+      if (this.$route.query.teacherId) {
+        this.searchForm.teacherId = this.$route.query.teacherId * 1;
+      }
+      if (this.$route.query.search) {
+        this.$route.query.search instanceof Object ? this.topForm = this.$route.query.search : this.topForm = JSON.parse(this.$route.query.search);
+      }
+      if (this.$route.query.rules) {
+        this.$route.query.rules instanceof Object ? this.rules = this.$route.query.rules : this.rules = JSON.parse(this.$route.query.rules);
+      }
+      this.getList();
+    },
+    getDate () {
+      let obj = {
+        search: this.searchForm.search || null,
+        actualExercisesNumIsAchieve:
+          this.searchForm.actualExercisesNumIsAchieve || null, // 训练次数
+        exercisesMessageNumIsAchieve:
+          this.searchForm.exercisesMessageNumIsAchieve || null, //评价
+        exercisesMessageTimelyNumIsAchieve:
+          this.searchForm.exercisesMessageTimelyNumIsAchieve || null, //及时评价
+        exercisesReplyNumIsAchieve:
+          this.searchForm.exercisesReplyNumIsAchieve || null, // 提交次数
+        organIdList: this.searchForm.organIdList || null,
+        teacherId: this.searchForm.teacherId,
+        page: this.rules.page,
+        rows: this.rules.limit,
+        existVipCourse: this.searchForm.existVipCourse || null,
+        existPracticeCourse: this.searchForm.existPracticeCourse || null,
+      };
+      if (this.searchForm.timer && this.searchForm.timer.length > 0) {
+        obj.monday = this.searchForm.timer[0];
+        obj.sunday = this.searchForm.timer[1];
+      } else {
+        this.$message.error("请选择时间段");
+        return false;
+      }
+      return obj;
+    },
+    getList () {
+      let obj = this.getDate();
+      if (!obj) return;
+      findStudentExtracurricularExercisesSituations(obj).then(res => {
+        if (res.code == 200) {
+          this.tableList = res.data.rows;
+          this.rules.total = res.data.total;
+        }
+      });
+    },
+
+    onReSet () {
+      this.searchForm = {
+        timer: [],
+        search: null,
+        actualExercisesNumIsAchieve: null, // 训练次数
+        exercisesMessageNumIsAchieve: null, //评价
+        exercisesMessageTimelyNumIsAchieve: null, //及时评价
+        exercisesReplyNumIsAchieve: null, // 提交次数
+        teacherId: null,
+        existVipCourse: null
+      };
+      this.search();
+    },
+
+    onExport () {
+      let url = "/api-web/export/exercisesSituations";
+      let obj = this.getDate();
+      const options = {
+        method: "get",
+        headers: {
+          Authorization: getToken()
+        },
+        url,
+        params: obj,
+        responseType: "blob"
+      };
+
+      this.$confirm("您确定导出列表?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      })
+        .then(() => {
+          load.startLoading();
+          axios(options)
+            .then(res => {
+              let blob = new Blob([res.data], {
+                // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
+                type: "application/vnd.ms-excel;charset=utf-8"
+                // word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
+              });
+              let text = new Response(blob).text();
+              text.then(res => {
+                // 判断是否报错
+                if (res.indexOf("code") != -1) {
+                  let json = JSON.parse(res);
+                  this.$message.error(json.msg);
+                } else {
+                  let objectUrl = URL.createObjectURL(blob);
+                  let link = document.createElement("a");
+                  let nowTime = new Date();
+                  let ymd =
+                    nowTime.getFullYear() +
+                    "" +
+                    (nowTime.getMonth() + 1) +
+                    "" +
+                    nowTime.getDate() +
+                    "" +
+                    nowTime.getHours() +
+                    "" +
+                    nowTime.getMinutes();
+                  let fname = ymd + "课外训练(教学)";
+                  link.href = objectUrl;
+                  link.setAttribute("download", fname);
+                  document.body.appendChild(link);
+                  link.click();
+                }
+              });
+
+              load.endLoading();
+            })
+            .catch(error => {
+              this.$message.error("导出数据失败,请连接管理员");
+              load.endLoading();
+            });
+        })
+        .catch(() => { });
+    },
+    search () {
+      this.rules.page = 1;
+      this.getList();
+    },
+    getNowDateAndMonday (time) {
+      let timestamp = new Date(time.replace(/-/g, "/")).getTime();
+      let serverDate = new Date(time);
+      if (serverDate.getDay() == 0) {
+        timestamp -= 7 * 24 * 60 * 60 * 1000;
+      }
+      let mondayTime =
+        timestamp - (serverDate.getDay() - 1) * 24 * 60 * 60 * 1000;
+
+      let mondayData = new Date(mondayTime);
+      //年
+      let mondayY = mondayData.getFullYear();
+      //月
+      let mondayM =
+        mondayData.getMonth() + 1 < 10
+          ? "0" + (mondayData.getMonth() + 1)
+          : mondayData.getMonth() + 1;
+      //日
+      let mondayD =
+        mondayData.getDate() < 10
+          ? "0" + mondayData.getDate()
+          : mondayData.getDate();
+
+      let str = mondayY + "-" + mondayM + "-" + mondayD;
+      return str;
+    },
+    getNowDateAndSunday (time) {
+      let timestamp = new Date(time.replace(/-/g, "/")).getTime();
+      let serverDate = new Date(time);
+
+      let num = 7 - serverDate.getDay();
+      if (num == 7) {
+        num = 0;
+      }
+      let sundayTiem = timestamp + num * 24 * 60 * 60 * 1000;
+      let SundayData = new Date(sundayTiem);
+      //年
+      let tomorrowY = SundayData.getFullYear(); //月
+      let tomorrowM =
+        SundayData.getMonth() + 1 < 10
+          ? "0" + (SundayData.getMonth() + 1)
+          : SundayData.getMonth() + 1;
+      //日
+      let tomorrowD =
+        SundayData.getDate() < 10
+          ? "0" + SundayData.getDate()
+          : SundayData.getDate();
+      let str = tomorrowY + "-" + tomorrowM + "-" + tomorrowD;
+      return str;
+    },
+    getWeekTime (val) {
+      if (val && val.length > 0) {
+        let start = this.getNowDateAndMonday(val[0]);
+        let end = this.getNowDateAndSunday(val[1]);
+        this.searchForm.timer.splice(0, 1, start);
+        this.searchForm.timer.splice(1, 1, end);
+      }
+    },
+    lookDetail (row) {
+      // this.afterSchoolVisible = true;
+
+      let rules = JSON.stringify(this.rules);
+      let searchForm = JSON.stringify(this.searchForm);
+      this.$router.push({
+        path: "/operateManager/serverIndexDetail",
+        query: {
+          studentId: row.studentId,
+          studentName: row.studentName,
+          rules,
+          searchForm,
+          title: row.studentName,
+          extracurricularExercisesId: "yes",
+          startTime: this.searchForm.timer[0],
+          endTime: this.searchForm.timer[1]
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang='scss' scoped>
+</style>

+ 2 - 2
vue.config.js

@@ -21,8 +21,8 @@ const name = defaultSettings.title || '管乐迷后台管理系统' // page titl
 // let target = 'http://192.168.3.27:8000' // 箭河
 // let target = 'http://192.168.3.28:8000' //邹璇
 // let target = 'http://192.168.3.8:8000' //勇哥
-let target = 'http://admin.dayaedu.com' // 测试服
-// let target = 'http://192.168.3.48:8080' // 乔
+// let target = 'http://admin.dayaedu.com' // 测试服
+let target = 'http://192.168.3.48:8080' // 乔
 // let target = 'http://dyme.cn1.utools.club'// 乔家
 // let target = 'http://195s22s709.imwork.net/' // 邹璇家
 // All configuration item explanations can be find in https://cli.vuejs.org/config/