lex-xin 3 år sedan
förälder
incheckning
afc372a5e5

+ 1 - 1
src/api/audition.js

@@ -98,7 +98,7 @@ const addHomeWork = (data) => {
   return axios({
       url: api + '/courseReview/addHomeWork',
       method: 'post',
-      data: qs.stringify(data)
+      data
   })
 }
 

+ 19 - 0
src/helpers/deep-clone.js

@@ -0,0 +1,19 @@
+// form: https://www.30secondsofcode.org/js/s/deep-clone
+
+const deepClone = obj => {
+    if (obj === null) return null;
+    let clone = Object.assign({}, obj);
+    Object.keys(clone).forEach(
+      key =>
+        (clone[key] =
+          typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
+    );
+    if (Array.isArray(obj)) {
+      clone.length = obj.length;
+      return Array.from(clone);
+    }
+    return clone;
+  };
+  
+  export default deepClone
+  

+ 119 - 24
src/views/audition/ArrangeWork.vue

@@ -1,15 +1,15 @@
 <template>
   <div class="arrangeWork">
     <m-header v-if="headerStatus" />
-    <van-cell title="服务指标课外训练" title-style="font-size: .18rem; color: #333333;">
+    <van-cell :title="classGroupName" title-style="font-size: .18rem; color: #333333;">
       <template #extra>
         <van-tag type="primary" plain style="background-color: #F1FCF9">课后训练</van-tag>
       </template>
     </van-cell>
     <van-cell class="endTime" readonly is-link title-style="font-size: .16rem; color: #333333;">
       <template #title>
-        <span style="padding-right: .3rem">学员共<i style="font-style: normal; color: #01C1B5">34</i>人</span>
-        <span>会员 <i style="font-style: normal; color: #FF802C">34</i>人</span>
+        <span style="padding-right: .3rem">学员共<i style="font-style: normal; color: #01C1B5">{{ params.studentCount }}</i>人</span>
+        <span>会员 <i style="font-style: normal; color: #FF802C">{{ params.studentMemberCount }}</i>人</span>
       </template>
     </van-cell>
     <div class="container">
@@ -21,7 +21,7 @@
       <div class="formGroup">
         <div class="dot"></div>
         <div class="formTitle">训练内容</div>
-        <van-field rows="8" v-model="content" maxlength="600" show-word-limit type="textarea" placeholder="请输入训练内容" />
+        <van-field rows="4" v-model="content" maxlength="600" show-word-limit type="textarea" placeholder="请输入训练内容" />
       </div>
     </div>
     <van-cell class="endTime" title="训练提交截止时间" @click="onEndTime" is-link readonly placeholder="请选择截止时间" >
@@ -33,18 +33,18 @@
     <div class="accompanyHeader">
       云教练曲目选择<span>(若作业内容非云教练曲目则无需选择)</span>
     </div>
-    <van-tabs class="van-hairline--bottom" v-model="tabActive" color="#01C1B5">
-      <van-tab title="长笛" name="1"></van-tab>
-      <van-tab title="单簧管" name="2"></van-tab>
+    <van-tabs v-model="tabActive" color="#01C1B5">
+      <van-tab v-for="(item, i) in params.subjectList" :title="item.subjectName" :name="item.id" :key="i" class="van-hairline--bottom">
+        <van-cell class="endTime" v-for="(music, index) in item.musicScoreIdList" :key="index" style="margin-top: 0;" title="训练曲目" @click="onSelectAccompany(item, index)" readonly is-link placeholder="请选择训练曲目" >
+          <template #default>
+            {{ music.name }}
+          </template>
+        </van-cell>
+        <div class="addAccompaniment" v-if="item.musicScoreIdList.length < 3" @click="addCloud(item)">
+          <van-icon name="plus" size="16px" />增加云教练训练曲目
+        </div>
+      </van-tab>
     </van-tabs>
-    <van-cell class="endTime" style="margin-top: 0;" title="训练曲目" @click="accompanimentStatus = true" readonly is-link placeholder="请选择训练曲目" >
-      <template #default>
-        {{ dateSection.musicScoreName }}
-      </template>
-    </van-cell>
-    <div class="addAccompaniment">
-      <van-icon name="plus" size="16px" />增加云教练训练曲目
-    </div>
 
     <div class="button-group">
       <van-button type="primary" round size="large" @click="onSubmit">确定</van-button>
@@ -67,7 +67,7 @@
       <van-sticky>
         <m-header name="作业曲目" :backUrl="backUrl" />
       </van-sticky>
-      <accompaniment-modal isHead @onSelectMusic="onSelectMusic" />
+      <accompaniment-modal isHead @onSelectMusic="onSelectMusic" :searchSubjectId="tabActive" />
     </van-popup>
   </div>
 </template>
@@ -79,12 +79,14 @@ import { addHomeWork } from '@/api/audition'
 import { getCourseStudents } from '@/api/teacher'
 import AccompanimentModal from './modal/accompanimentModal'
 import cleanDeep from 'clean-deep'
+import deepClone from '@/helpers/deep-clone'
 export default {
   name: "teacherList",
   components: { MHeader, AccompanimentModal },
   data() {
     let tempDate = new Date() // 默认显示T+3
     tempDate.setDate(tempDate.getDate() + 3)
+    let query = this.$route.query
     return {
       headerStatus: true,
       backUrl: {
@@ -93,6 +95,8 @@ export default {
           this.accompanimentStatus = false
         }
       },
+      classGroupName: query.classGroupName,
+      courseId: query.courseId,
       dateSection: {
         status: false,
         minDate: new Date(),
@@ -106,7 +110,16 @@ export default {
       content: null, // 课程编号
       expiryDate: null, // 作业截止日期
       accompanimentStatus: false, // 伴奏弹窗
-      tabActive: 'changDi'
+      tabActive: 0,
+      tabActiveList: {}, // 选中当前信息
+      tabActiveIndex: 0,
+      params: {
+        studentCount: 0, // 学员总数
+        studentMemberCount: 0, // 学员会员数
+        subjectIdList: [],
+        subjectList: []
+      }
+
     };
   },
   async mounted() {
@@ -120,10 +133,55 @@ export default {
       this.headerStatus = false
     }
     await getCourseStudents({ courseScheduleId: this.courseId }).then(res => {
-      console.log(res)
+      const result = res.data
+      if(result.code != 200) { return }
+      const tempData = result.data || []
+      let params = {
+        studentCount: tempData.length, // 学员总数
+        studentMemberCount: 0, // 学员会员数
+        subjectIdList: [],
+        subjectList: []
+      }
+      tempData.forEach(item => {
+        // 判断当前学员是否有会员
+        if(item.memberRankSettingId) {
+          params.studentMemberCount++
+        }
+        if(!params.subjectIdList.includes(item.subjectIdList)) {
+          params.subjectIdList.push(item.subjectIdList)
+          params.subjectList.push({
+            id: item.subjectIdList,
+            subjectName: item.subjectName,
+            userIdList: [item.userId],
+            musicScoreIdList: [{
+              id: null,
+              name: null,
+            }], // 默认加一个空的,做占位
+          })
+        } else {
+          params.subjectList.forEach(subject => {
+            if(subject.id == item.subjectIdList) {
+              subject.userIdList.push(item.userId)
+            }
+          })
+        }
+      });
+      // 默认选中第1条数据
+      this.tabActive = deepClone(params.subjectIdList[0])
+      this.params = params
     })
   },
   methods: {
+    onSelectAccompany(item, index) {
+      this.accompanimentStatus = true
+      this.tabActiveList = item
+      this.tabActiveIndex = index
+    },
+    addCloud(item) {
+      if(item.musicScoreIdList.length < 3) {
+        item.musicScoreIdList.push('')
+      }
+    },
     formatter(type, val) {
       if (type === "year") {
         return `${val}年`
@@ -135,8 +193,10 @@ export default {
       return val
     },
     onSelectMusic(value) {
-      this.dateSection.musicScoreName = value.examSongName
-      this.dateSection.musicScoreId = value.examSongId
+      this.tabActiveList.musicScoreIdList[this.tabActiveIndex] = {
+        id: value.examSongId,
+        name: value.examSongName
+      }
       this.accompanimentStatus = false
     },
     confirmStartTime() {
@@ -147,10 +207,37 @@ export default {
       this.dateSection.status = true
     },
     onSubmit: _throttle(function() {
+      if(!this.title) {
+        this.$toast('请输入训练标题')
+        return
+      }
       if(!this.content) {
-        this.$toast('请输入作业内容')
+        this.$toast('请输入训练内容')
         return
       }
+      let tempSubjectList = this.params.subjectList
+      let musicScoreSubjectDto = []
+      let notAccompanySong = [] // 用于判断没有设置训练曲目的数据
+      let subjectLength = this.params.subjectIdList.length
+      tempSubjectList.forEach(subject => {
+        let scoreIdList = []
+        subject.musicScoreIdList.forEach(music => {
+          if(music.id) {
+            scoreIdList.push(music.id)
+          }
+        })
+        if(scoreIdList.length <= 0) {
+          notAccompanySong.push(subject.subjectName)
+        }
+        musicScoreSubjectDto.push({
+          musicScoreIdList: scoreIdList,
+          userIdList: subject.userIdList
+        })
+      })
+      if(notAccompanySong.length - subjectLength < 0 && notAccompanySong != 0) {
+        console.log('选择曲目')
+      }
+      
       this.$toast.loading({
         message: '加载中...',
         duration: 10000,
@@ -159,18 +246,26 @@ export default {
       })
       let query = this.$route.query
       let params = {
+        title: this.title,
         content: this.content,
-        courseId: query.courseId,
+        courseScheduleId: query.courseId,
         expiryDate: dayjs(this.dateSection.currentDate).format('YYYY-MM-DD'),
-        musicScoreId: this.dateSection.musicScoreId
+        musicScoreSubjectDto: musicScoreSubjectDto
       }
       addHomeWork(cleanDeep({...params})).then(res => {
         let result = res.data
         this.$toast.clear()
         if(result.code == 200) {
           this.$toast('作业布置成功')
+          let query = this.$route.query
           this.$router.replace({
-            path: '/manageEvaluation'
+            path: '/courseEvaluation',
+            query: {
+              id: query.id,
+              reviewId: query.reviewId,
+              isInside: query.isInside,
+              work: 1
+            }
           })
         } else {
           this.$toast(result.msg)

+ 37 - 59
src/views/audition/CourseEvaluation.vue

@@ -3,7 +3,10 @@
     <m-header v-if="headerStatus" />
     <div class="course-header">
       <div class="title-info">
-        <span class="teachMode">线上</span>
+        <span class="teachMode" v-if="teachMode">
+          {{ teachMode == 'ONLINE' ? '线上' : null }}
+          {{ teachMode == 'OFFLINE' ? '线下' : null }}
+        </span>
         <span :class="['courseType', classType]">{{ classType | coursesType }}</span>
         <span style="font-size: .18rem; font-weight: 500; color: #333;line-height: 18px;vertical-align: middle;">{{ classGroupName }}</span>
       </div>
@@ -13,16 +16,8 @@
     </div>
     <van-cell-group>
       <div class="dot"></div>
-      <!-- <van-button
-        type="primary"
-        :disabled="homeWork ? true : false"
-        v-if="enableAssignHomework"
-        round
-        @click="onWork(isAssignHomework)"
-        >{{ homeWork ? "已布置作业" : "布置作业" }}</van-button
-      > -->
        <!-- v-if="enableAssignHomework" -->
-      <van-cell class="input" :is-link="homeWork ? true : false" title="课后训练" :value='homeWork ? "已布置" : "未布置"' @click="onWork(isAssignHomework)"></van-cell>
+      <van-cell class="input" :is-link="!isAssignHomework ? true : false" title="课后训练" :value='isAssignHomework ? "已布置" : "未布置"' @click="onWork()"></van-cell>
     </van-cell-group>
     <van-cell-group>
        <div class="dot"></div>
@@ -118,26 +113,12 @@
     </van-cell-group>
 
     <div class="button-group" v-if="!reviewId">
-      <van-button type="primary" round size="large" @click="submitReview"
-        >提交评价</van-button
-      >
-    </div>
-    <!--  btn-operation -->
-    <div class="button-group" v-if="reviewId">
-      <!-- <van-button
-        type="primary"
-        :disabled="homeWork ? true : false"
-        v-if="enableAssignHomework"
-        round
-        @click="onWork(isAssignHomework)"
-        >{{ homeWork ? "已布置作业" : "布置作业" }}</van-button
-      > -->
-      <van-button type="primary" round class="btn-plain" @click="submitReview"
-        >修改评价</van-button
-      >
+      <van-button type="primary" round size="large" @click="submitReview">
+        {{ !reviewId ? '提交评价' : '修改评价' }}
+      </van-button>
     </div>
 
-    <van-popup v-model="showWork">
+    <!-- <van-popup v-model="showWork">
       <van-icon class="closeable" @click="onClose" name="cross" />
       <div class="popup_container">
         <p class="content">
@@ -152,7 +133,7 @@
           <span @click="onWork(0)">布置作业</span>
         </div>
       </div>
-    </van-popup>
+    </van-popup> -->
   </div>
 </template>
 <script>
@@ -172,13 +153,14 @@ export default {
   data() {
     return {
       headerStatus: true,
-      showWork: false, // 是否布置作业
+      // showWork: false, // 是否布置作业
       radio: 1,
       voice: 0,
       courseId: null,
       reviewId: null,
       classTimer: null,
       classGroupName: null,
+      teachMode: null,
       classType: null, // 课程类型
       teachingMaterial: null, //教材
       song: null, // 曲目
@@ -187,7 +169,6 @@ export default {
       musicTheory: null, // 乐理
       memo: null, // 备注
       homeWork: null, // 作业
-      handHomework: null, // 是否完成作业
       hasLiaison: null,
       subjectNames: null,
       // isReset: false,
@@ -212,7 +193,12 @@ export default {
     if (browser().android || browser().iPhone) {
       this.headerStatus = false;
     }
-
+    this.$toast.loading({
+      message: "加载中...",
+      duration: 10000,
+      forbidClick: true,
+      loadingType: "spinner",
+    });
     await checkeIsAssignHomework({ courseScheduleId: this.courseId }).then((res) => {
       let result = res.data;
       if (result.code == 200) {
@@ -232,14 +218,7 @@ export default {
     // 获取头部信息
     if (this.reviewId) {
       // 获取老评价
-      this.$toast.loading({
-        message: "加载中...",
-        duration: 10000,
-        forbidClick: true,
-        loadingType: "spinner",
-      });
       await getReviewInfo({ id: this.reviewId }).then((res) => {
-        this.$toast.clear();
         if (res.data.code == 200) {
           let result = res.data.data;
           let teacherClassHeadInfo = result.teacherClassHeadInfo;
@@ -250,6 +229,7 @@ export default {
             teacherClassHeadInfo.endClassTime;
           this.subjectNames = teacherClassHeadInfo.subjectNames;
           this.classGroupName = teacherClassHeadInfo.classGroupName;
+          this.teachMode = teacherClassHeadInfo.teachMode
           this.classType = teacherClassHeadInfo.courseScheduleType;
 
           // 评价内容
@@ -262,7 +242,6 @@ export default {
           this.memo = courseScheduleReview.memo;
           this.homeWork = courseScheduleReview.homeWork;
           this.hasLiaison = courseScheduleReview.hasLiaison.toString();
-          this.handHomework = courseScheduleReview.handHomework.toString();
         }
       });
     } else {
@@ -276,6 +255,7 @@ export default {
             result.endClassTime;
           this.subjectNames = result.subjectNames;
           this.classGroupName = result.classGroupName;
+          this.teachMode = result.teachMode
           this.classType = result.courseScheduleType;
         }
       });
@@ -292,11 +272,10 @@ export default {
         this.musicTheory = courseEvaluationObj.musicTheory
         this.memo = courseEvaluationObj.memo
         this.hasLiaison = courseEvaluationObj.hasLiaison
-        this.handHomework = courseEvaluationObj.handHomework
         this.courseId = courseEvaluationObj.courseId
       }
-      // console.log(courseEvaluationObj)
     }
+    this.$toast.clear();
   },
   methods: {
     submitReview() {
@@ -324,9 +303,7 @@ export default {
         tempo: this.tempo, //节奏
         musicTheory: this.musicTheory, // 乐理
         memo: this.memo, // 备注
-        // homeWork: this.homeWork,
         hasLiaison: this.hasLiaison,
-        handHomework: this.handHomework,
         courseScheduleId: this.courseId,
       };
       if (this.reviewId) {
@@ -344,23 +321,19 @@ export default {
       } else {
         courseReviewAdd(obj).then((res) => {
           if (res.data.code == 200) {
-            if (this.enableAssignHomework) {
-              this.showWork = true;
-            } else {
-              this.$toast("提交成功");
-              setTimeout((res) => {
-                if (this.isInside) {
-                  this.$router.push({ path: "/manageEvaluation" });
-                } else {
-                  this.onAppBack();
-                }
-              }, 1000);
-            }
+            this.$toast("提交成功");
+            setTimeout((res) => {
+              if (this.isInside) {
+                this.$router.push({ path: "/manageEvaluation" });
+              } else {
+                this.onAppBack();
+              }
+            }, 1000);
           }
         });
       }
     },
-    onWork(isAssignHomework) {
+    onWork() {
       const obj = {
         teachingMaterial: this.teachingMaterial, //教材
         song: this.song, // 曲目
@@ -368,16 +341,19 @@ export default {
         tempo: this.tempo, //节奏
         musicTheory: this.musicTheory, // 乐理
         memo: this.memo, // 备注
-        // homeWork: this.homeWork,
         hasLiaison: this.hasLiaison,
         handHomework: this.handHomework,
         courseScheduleId: this.courseId,
       }
-      if (isAssignHomework == 1) {
+      if(this.isAssignHomework == 1) {
+        return
+      }
+      if (this.enableAssignHomework == 1) {
         this.$dialog
           .confirm({
             message: "您课程所在周已经布置作业,是否继续布置?",
             confirmButtonText: "布置作业",
+            confirmButtonColor: '#01C1B5'
           })
           .then(() => {
             // on confirm
@@ -387,6 +363,7 @@ export default {
               query: {
                 courseId: this.courseId,
                 memberNum: this.memberStatus,
+                classGroupName: this.classGroupName,
                 ...this.$route.query
               }
             });
@@ -401,6 +378,7 @@ export default {
           query: {
             courseId: this.courseId,
             memberNum: this.memberStatus,
+            classGroupName: this.classGroupName,
             ...this.$route.query
           },
         });

+ 14 - 3
src/views/audition/modal/accompanimentModal.vue

@@ -28,6 +28,7 @@
             key="data"
             :finished="finished"
             finished-text="没有更多数据了"
+            :immediate-check="false"
             @load="FetchList"
         >
             <van-cell-group>
@@ -73,13 +74,17 @@ export default {
             default() {
                 return false
             }
+        },
+        searchSubjectId: {
+            type: [Number, String],
+            default: 0
         }
     },
     data() {
         return {
             MusicIcon,
             levelId: 0,
-            subjectId: 0,
+            tempSubjectId: 0,
             levelOptions: [
                 // { text: '全部等级', value: 0 },
             ],
@@ -99,8 +104,14 @@ export default {
             list: [],
         }
     },
+    computed: {
+        subjectId() {
+            return this.tempSubjectId || Number(this.searchSubjectId)
+        }
+    },
     async mounted() {
-        this.FetchLevel()
+        await this.FetchLevel()
+        await this.FetchList()
     },
     methods: {
         async FetchLevel() {
@@ -174,7 +185,7 @@ export default {
             this.onSearch()
         },
         subjectChange(val) {
-            this.subjectId = val
+            this.tempSubjectId = val
             this.onSearch()
         },
         typeChange(val) {

+ 185 - 0
src/views/audition/modal/studentListModel.vue

@@ -0,0 +1,185 @@
+<template>
+    <div class="accompanimentModal">
+        <van-sticky :offset-top="isHead ? '.46rem' : 0">
+            <van-dropdown-menu class="cateDropDown" active-color="#01C1B5">
+                <van-dropdown-item v-model="levelId" :options="levelOptions" @change="levelChange" />
+                <van-dropdown-item v-model="subjectId" :options="subjectOptions" @change="subjectChange" />
+            </van-dropdown-menu>
+            <van-search
+                v-model="search"
+                show-action
+                placeholder="请输入搜索关键词"
+                shape="round"
+            >
+                <template #action>
+                    <div @click="onSearch">搜索</div>
+                </template>
+            </van-search>
+        </van-sticky>
+
+        <van-list
+            v-model="loading"
+            v-if="show"
+            key="data"
+            :finished="finished"
+            finished-text="没有更多数据了"
+            :immediate-check="false"
+            @load="FetchList"
+        >
+            <van-cell-group>
+                <van-cell
+                    v-for="(item, index) in list"
+                    :key="index"
+                    class="input-cell"
+                    clickable
+                    @click="onSelect(item)"
+                    :center="true"
+                >
+                    <template slot="icon">
+                        <van-icon class="iconMusic" :name="MusicIcon" />
+                        <div class='icon' v-if="item.rankIds">
+                            <img src='./icons/vip_icon.png' />
+                        </div>
+                    </template>
+                    <template slot="title">
+                        <!-- {{ item.examSongName }} -->
+                        <van-notice-bar
+                            background="none"
+                            :style="{ paddingLeft: (item.rankIds ? '.04rem' : '.15rem') + '!important' }"
+                            color="#444"
+                            :scrollable="false"
+                            :text="item.examSongName"
+                        />
+                    </template>
+                </van-cell>
+            </van-cell-group>
+        </van-list>
+        <m-empty class="empty" v-else key="data" />
+    </div>
+</template>
+
+<script>
+import { getCourseStudents } from '@/api/teacher'
+import MusicIcon from './icons/music.png'
+export default {
+    props: {
+        isHead: {
+            type: Boolean,
+            default() {
+                return false
+            }
+        },
+        subjectList: {
+            type: Array,
+            default() {
+                return []
+            }
+        }
+    },
+    data() {
+        return {
+            MusicIcon,
+            levelId: 0,
+            tempSubjectId: 0,
+            levelOptions: [
+                { text: '全部声部', value: 0 },
+                { text: '会员学员', value: 0 },
+                { text: '非会员学员', value: 0 },
+            ],
+            subjectOptions: [
+                { text: '全部声部', value: 0 }
+            ],
+            typeId: 0,
+            typeOptions: [],
+            search: null,
+            loading: false,
+            finished: false,
+            show: true,
+            params: {
+                page: 1,
+                rows: 20,
+            },
+            list: [],
+        }
+    },
+    async mounted() {
+        
+    },
+    methods: {
+        
+        subjectChange(val) {
+            this.tempSubjectId = val
+            this.onSearch()
+        },
+        typeChange(val) {
+            this.typeId = val
+            this.onSearch()
+        },
+        onSearch() {
+            this.params.page = 1
+            this.list = []
+            this.show = true
+            this.finished = false
+            this.FetchList()
+        },
+        onSelect(item) {
+            this.$emit('onSelectMusic', item)
+        }
+    }
+}
+</script>
+
+<style lang="less" scoped>
+.accompanimentModal {
+    background-color: #f5f5f5;
+    min-height: 100vh;
+
+    /deep/.van-search {
+        .van-cell {
+            font-size: 0.14rem;
+            padding: 0.05rem 0.08rem;
+            line-height: 0.24rem;
+        }
+        .van-dropdown-menu__bar {
+            height: .36rem;
+            background: transparent;
+            box-shadow: none;
+        }
+    }
+
+    .headDropDown {
+        height: .36rem;
+        background: transparent;
+        /deep/.van-dropdown-menu__title {
+            font-size: .14rem;
+        }
+    }
+    /deep/.van-field__control {
+        font-size: .14rem;
+    }
+    /deep/.van-dropdown-item .van-cell {
+        padding: 0.12rem 0.16rem;
+    }
+
+    .iconMusic {
+        /deep/.van-icon__image {
+            width: .38rem;
+            height: .38rem;
+            margin: auto;
+            vertical-align: middle;
+            // padding-right: .1rem;
+        }
+    }
+
+    .icon{
+        display: flex;
+        align-items: center;
+        margin-left: .15rem;
+        img{
+            width: .4rem;
+            // margin-top: -.02rem;
+        }
+    }
+
+}
+</style>