瀏覽代碼

Merge branch '10/23-test' into online

王新雷 4 年之前
父節點
當前提交
a29f340c13
共有 67 個文件被更改,包括 7908 次插入1143 次删除
  1. 9 0
      README-zh.md
  2. 1 0
      debug.log
  3. 1 0
      package.json
  4. 1 1
      src/App.vue
  5. 40 0
      src/api/auditManager.js
  6. 21 1
      src/api/buildTeam.js
  7. 118 0
      src/api/specialSetting.js
  8. 3 1
      src/components/Descriptions/Descriptions.vue
  9. 86 0
      src/components/QrCode/index.vue
  10. 0 3
      src/components/Upload/index.vue
  11. 73 0
      src/constant/index.js
  12. 1 1
      src/layout/components/AppMain.vue
  13. 3 1
      src/router/index.js
  14. 26 0
      src/utils/index.js
  15. 4 2
      src/utils/request2.js
  16. 27 2
      src/utils/searchArray.js
  17. 31 1
      src/utils/vueFilter.js
  18. 4 2
      src/views/accompanyManager/accompanys.vue
  19. 316 0
      src/views/auditList/index.vue
  20. 62 26
      src/views/categroyManager/globalConfig.vue
  21. 2 0
      src/views/categroyManager/insideSetting/branchActive.vue
  22. 64 67
      src/views/categroyManager/specialSetup/chargesList.vue
  23. 326 0
      src/views/categroyManager/specialSetup/discountManage.vue
  24. 359 0
      src/views/categroyManager/specialSetup/modals/chargesForm.vue
  25. 108 0
      src/views/categroyManager/specialSetup/modals/create-discount.vue
  26. 448 0
      src/views/categroyManager/specialSetup/musicCourseFee.vue
  27. 18 77
      src/views/categroyManager/specialSetup/typesManager.vue
  28. 1 1
      src/views/luckyDraw/trophyManager.vue
  29. 41 0
      src/views/resetTeaming/api.js
  30. 527 286
      src/views/resetTeaming/components/resetPayList.vue
  31. 718 0
      src/views/resetTeaming/components/resetPayListSchool.vue
  32. 44 0
      src/views/resetTeaming/components/resetSoundv2.vue
  33. 441 298
      src/views/resetTeaming/components/strudentPayInfo.vue
  34. 14 11
      src/views/resetTeaming/components/studentPayBase.vue
  35. 29 7
      src/views/resetTeaming/index.vue
  36. 50 0
      src/views/resetTeaming/modals/classrooms.vue
  37. 203 0
      src/views/resetTeaming/modals/extra-class.vue
  38. 40 0
      src/views/resetTeaming/modals/other.vue
  39. 89 0
      src/views/resetTeaming/modals/payment-cycle.vue
  40. 149 0
      src/views/resetTeaming/modals/review-detail.vue
  41. 68 0
      src/views/resetTeaming/modals/review.vue
  42. 11 0
      src/views/resetTeaming/modals/school-pay-form.vue
  43. 535 0
      src/views/resetTeaming/modals/subject-preview.vue
  44. 83 0
      src/views/resetTeaming/modals/user-baseinfo.vue
  45. 357 0
      src/views/resetTeaming/modals/user-pay-form.vue
  46. 54 0
      src/views/teamBuild/components/soundSetComponents/chioseAccessory.vue
  47. 140 0
      src/views/teamBuild/components/soundSetComponents/chioseMusic.vue
  48. 102 0
      src/views/teamBuild/components/soundSetComponents/chioseSoundList.vue
  49. 549 0
      src/views/teamBuild/components/soundSetComponents/soundSetCore.vue
  50. 50 169
      src/views/teamBuild/components/teamBaseInfo.vue
  51. 78 0
      src/views/teamBuild/components/teamPayInfo.vue
  52. 2 12
      src/views/teamBuild/components/teamResetSound.vue
  53. 21 30
      src/views/teamBuild/components/teamSoundMoney.vue
  54. 202 0
      src/views/teamBuild/components/teamSoundSet.vue
  55. 99 72
      src/views/teamBuild/index.vue
  56. 3 4
      src/views/teamBuild/signupList.vue
  57. 8 0
      src/views/teamDetail/api.js
  58. 198 0
      src/views/teamDetail/components/modals/classroom-setting-item.vue
  59. 256 0
      src/views/teamDetail/components/modals/classroom-setting.vue
  60. 131 0
      src/views/teamDetail/components/modals/create-user-pay.vue
  61. 165 0
      src/views/teamDetail/components/modals/select-student.vue
  62. 49 0
      src/views/teamDetail/components/modals/view-student-list.vue
  63. 128 39
      src/views/teamDetail/components/resetClass.vue
  64. 118 26
      src/views/teamDetail/components/studentList.vue
  65. 1 1
      src/views/teamDetail/teamInfo.vue
  66. 1 1
      src/views/teamDetail/teamList.vue
  67. 1 1
      vue.config.js

+ 9 - 0
README-zh.md

@@ -70,6 +70,15 @@ npm run preview -- --report
 
 ```
 
+## 组件
+组件使用的文件统一放到:src/components 目录下,首字母大写
+
+Upload -- 目前只实现了图片上传
+QrCode -- 生成二维码弹窗
+Editor -- 富文本编辑器(如果要用到上传视屏,则需要在处理一下)
+Tooltip --
+
+
 ## 注意事项
 
 ```bash

+ 1 - 0
debug.log

@@ -0,0 +1 @@
+[1102/141000.893:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)

+ 1 - 0
package.json

@@ -27,6 +27,7 @@
     "i": "^0.3.6",
     "js-cookie": "2.2.0",
     "linq": "^3.2.2",
+    "lodash": "^4.17.20",
     "node-sass": "^4.13.1",
     "normalize.css": "7.0.0",
     "npm": "^6.13.0",

+ 1 - 1
src/App.vue

@@ -319,7 +319,7 @@ input[type="number"] {
   .nextBtn {
     width: 120px;
     height: 40px;
-    background-color: #444;
+    background-color: #13817a;
   }
   .okBtn {
     width: 120px;

+ 40 - 0
src/api/auditManager.js

@@ -0,0 +1,40 @@
+import request from '@/utils/request'
+import qs from 'qs'
+let api = '/api-web'
+
+// 分页查询活动列表
+export function getAuditList(data) {
+    return request({
+      url: api + '/musicGroupPaymentCalender/auditList',
+      method: 'get',
+      params: data
+    })
+}
+
+// 查看缴费详情
+export function getAuditListDetail(data) {
+    return request({
+      url: api + '/musicGroupPaymentCalender/auditListDetail',
+      method: 'get',
+      params: data
+    })
+}
+
+// 审核通过
+
+export function auditPass(data) {
+    return request({
+      url: api + '/musicGroupPaymentCalender/auditPass',
+      method: 'post',
+     data:qs.stringify(data)
+    })
+}
+
+// 驳回
+export function auditRefuse(data) {
+    return request({
+      url: api + '/musicGroupPaymentCalender/auditRefuse',
+      method: 'post',
+     data:qs.stringify(data)
+    })
+}

+ 21 - 1
src/api/buildTeam.js

@@ -1,4 +1,5 @@
 import request from '@/utils/request'
+import request2 from '@/utils/request2'
 import qs from 'qs'
 let api = '/api-web'
 // 获取分部
@@ -805,6 +806,16 @@ export function getHoliday (data) {
   })
 }
 
+// 获取指定学员在指定乐团下本次课排课时长
+export function getMusicCourseSettingsWithStudents (data) {
+  return request2({
+    url: api + `/musicGroupPaymentCalender/getMusicCourseSettingsWithStudents`,
+    method: 'GET',
+    params: data,
+    data: {},
+  })
+}
+
 // 获取乐团(声部)的(没有某种班级类型)学生
 export function getMusicGroupStuNoClassType (data) {
   return request({
@@ -1339,4 +1350,13 @@ export function getCourseScheduleDetail (data) {
     method: 'get',
     params: data
   })
-}
+}
+
+// 获取商品和商品折扣
+export function getSubjectGoods (data) {
+  return request({
+    url: api + '/musicGroupSubjectPlan/getSubjectGoods',
+    method: 'get',
+    params: data
+  })
+}

+ 118 - 0
src/api/specialSetting.js

@@ -1,5 +1,6 @@
 // 系统专项设置api文件
 import request from '@/utils/request'
+import request2 from '@/utils/request2'
 import qs from 'qs'
 let api = '/api-web'
 // 分页查询分部列表
@@ -180,3 +181,120 @@ export function findEducationTeacher (data) {
     params: data
   })
 }
+
+// 获取收费类型与科目的关联服务
+export function chargeTypeSubjectMapper (data) {
+  return request2({
+    url: api + '/chargeTypeSubjectMapper/queryPage',
+    method: 'get',
+    data: {},
+    params: data,
+    requestType: 'form',
+  })
+}
+
+// 新增收费类型与科目的关联服务
+export function insertChargeTypeSubjectMapper (data) {
+  return request2({
+    url: api + '/chargeTypeSubjectMapper/insert',
+    method: 'post',
+    data,
+  })
+}
+
+// 修改收费类型与科目的关联服务
+export function updateChargeTypeSubjectMapper (data) {
+  return request2({
+    url: api + '/chargeTypeSubjectMapper/update',
+    method: 'post',
+    data,
+  })
+}
+
+// 删除收费类型与科目的关联服务
+export function delChargeTypeSubjectMapper (data) {
+  const { id, ...rest } = data
+  return request2({
+    url: api + '/chargeTypeSubjectMapper/del/' + id,
+    method: 'post',
+    params: rest,
+  })
+}
+
+// 收费方式添加
+export function musicGroupOrganizationCourseSettingsAdd (data) {
+  return request2({
+    url: api + '/musicGroupOrganizationCourseSettings/add',
+    method: 'post',
+    data
+  })
+}
+
+// 收费方式修改
+export function musicGroupOrganizationCourseSettingsUpdate (data) {
+  return request2({
+    url: api + '/musicGroupOrganizationCourseSettings/update',
+    method: 'post',
+    data
+  })
+}
+
+// 收费方式删除
+export function musicGroupOrganizationCourseSettingsDel (data) {
+  return request2({
+    url: api + '/musicGroupOrganizationCourseSettings/delSetting',
+    method: 'post',
+    data: {},
+    params: data,
+    requestType: 'form',
+  })
+}
+
+// 收费方式列表
+export function musicGroupOrganizationCourseSettingsQueryPage (data) {
+  return request2({
+    url: api + '/musicGroupOrganizationCourseSettings/queryPage',
+    method: 'get',
+    data: {},
+    params: data,
+    requestType: 'form',
+  })
+}
+
+// 课程费用查询
+export function getOrganizationCourseUnitPriceSettings (data) {
+  return request2({
+    url: api + `/organizationCourseUnitPriceSettings/queryPage`,
+    method: 'get',
+    params: data,
+    data: {},
+    requestType: 'form',
+  })
+}
+
+// 新增课程费用
+export function addOrganizationCourseUnitPrice (data) {
+  return request2({
+    url: api + `/organizationCourseUnitPriceSettings/insert`,
+    method: 'post',
+    data
+  })
+}
+
+// 修改课程费用
+export function resetOrganizationCourseUnitPrice (data) {
+  return request2({
+    url: api + `/organizationCourseUnitPriceSettings/update`,
+    method: 'post',
+    data
+  })
+}
+
+// 删除课程费用
+export function deleteOrganizationCourseUnitPrice (data) {
+  return request2({
+    url: api + `/organizationCourseUnitPriceSettings/del`,
+    method: 'post',
+    data
+  })
+}

+ 3 - 1
src/components/Descriptions/Descriptions.vue

@@ -60,11 +60,13 @@ export default {
   mounted() {
     this.generateChildrenRow(this.$slots.default || [])
   },
+  beforeUpdate() {
+    this.generateChildrenRow(this.$slots.default || [])
+  },
   methods: {
     // 获取描述内容子项
     generateChildrenRow(dataSource) {
       const dataList = dataSource.filter(item => item.tag === 'descriptions-item')
-      console.log(dataList)
       this.rows = []
       let leftSpan = this.column
       let children = []

+ 86 - 0
src/components/QrCode/index.vue

@@ -0,0 +1,86 @@
+
+<template>
+    <div class="qrCode">
+        <el-dialog :title="title"
+               :visible.sync="status"
+               @close="onDialogClose"
+               width="300px">
+            <div class="left-code">
+                <vue-qr :text="codeUrl" style="width: 100%" :margin="0"></vue-qr>
+                <p class="code-url" v-if="codeUrl">{{ codeUrl }} <el-link @click="copyUrl(codeUrl)" class="link-btn" type="primary">复制</el-link></p>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import VueQr from 'vue-qr'
+import copy from 'copy-to-clipboard'
+export default {
+    data() {
+        return {
+            status: false
+        };
+    },
+    components: {
+        VueQr
+    },
+    props: {
+        value: {
+            // 组件状态
+            type: Boolean,
+            required: true,
+            default() {
+                return false
+            }
+        },
+        title: {
+            type: String,
+            default() {
+                return '查看二维码'
+            }
+        },
+        codeUrl: {
+            type: String
+        }
+    },
+    mounted() {
+        this.status = this.value
+    },
+    methods: {
+        onDialogClose() {
+            this.status = false
+            this.$emit('input', false)
+        },
+        copyUrl(url) {
+            copy(url)
+            this.$message.success('复制成功')
+        },
+    },
+    watch: {
+        value(newValue) {
+            this.status = newValue;
+        },
+        title(newValue, oldValue) {
+            if(newValue != oldValue) {
+                this.title = newValue
+            }
+        }
+    },
+    beforeDestroy() {},
+};
+</script>
+
+<style lang="scss">
+.left-code{
+    .code-url{
+        margin-top: 10px;
+        margin-bottom: 10px;
+        .link-btn{
+            margin-top: 0;
+            margin-bottom: 0;
+            font-size: 12px;
+        }
+    }
+}
+</style>

+ 0 - 3
src/components/Upload/index.vue

@@ -83,7 +83,6 @@ export default {
       const isLt2M = file.size / 1024 / 1024 < this.imageSizeM;
       const imageWidth = this.imageWidthM
       const imageHeigh = this.imageHeightM
-      console.log(file)
       const _URL = window.URL || window.webkitURL
       const isSize = new Promise((resolve, reject) => {
         const img = new Image()
@@ -112,8 +111,6 @@ export default {
           return Promise.reject()
         }
       )
-      console.log(isSize)
-
       if (!isImage) {
         this.$message.error("只能上传图片格式!");
 

+ 73 - 0
src/constant/index.js

@@ -26,9 +26,82 @@ export const feeProject = {
   19: '退费',
 }
 
+export const courseType = {
+  SINGLE: '单技课',
+  MIX: '合奏课',
+  HIGH: '基础训练课',
+  COMPREHENSIVE: '综合课',
+  ENLIGHTENMENT: '启蒙课',
+  TRAINING_SINGLE: '集训单技课',
+  TRAINING_MIX: '集训合奏课',
+  HIGH_ONLINE: '网络基础训练课',
+  MUSIC_NETWORK: '乐团网管课',
+}
+
+export const boolOptions = {
+  false: '否',
+  true: '是',
+}
+
 export const saleType = {
   INSTRUMENT: '乐器销售',
   ACCESSORIES: '配件销售',
   SCHOOL_BUY: '学校采购',
   OTHER: '其他',
 }
+
+export const genderType = {
+  1: '男',
+  0: '女',
+}
+
+export const paymentPatternType = {
+  0: '按月',
+  1: '按学期',
+  2: '一次性',
+}
+
+export const payUserType = {
+  STUDENT: '学员',
+  SCHOOL: '学校',
+}
+
+export const paymentType = {
+  0: '续费',
+  1: '报名',
+}
+
+export const userPaymentType = {
+  ADD_STUDEN: '新增学员',
+  ADD_COURSE: '临时加课',
+  MUSIC_APPLY: '乐团报名',
+  MUSIC_RENEW: '乐团续费',
+}
+
+export const payStatus = {
+  AUDITING: '审核中',
+  REJECT: '拒绝',
+  NO: '未开启缴费',
+  OPEN: '开启缴费',
+  OVER: '缴费已结束',
+}
+
+export const payOrderType = {
+  STUDENT:'个人',
+  SCHOOL:'学校' 
+}
+
+export const auditType = {
+  AUDITING:'审核中',
+  REJECT:'拒绝',
+  NO:'未开启缴费',
+  OPEN:'开启缴费',
+  OVER:'缴费已结束'
+}
+
+export const auditPaymentType = {
+  ADD_STUDENT:'新增学员',
+  ADD_COURSE:'临时加课',
+  MUSIC_APPLY:'乐团报名',
+  MUSIC_RENEW:'乐团续费'
+}

+ 1 - 1
src/layout/components/AppMain.vue

@@ -3,7 +3,7 @@
     <!--   -->
     <transition name="fade-transform"
                 mode="out-in">
-      <keep-alive>
+      <keep-alive exclude="modal-chargesForm">
         <router-view :key="key" />
       </keep-alive>
     </transition>

+ 3 - 1
src/router/index.js

@@ -338,6 +338,8 @@ export const asyncRoutes = {
   // 活动奖品设置
   trophyManager: () => import('@/views/luckyDraw/trophyManager'),
   // 抽奖记录
-  lotteryRecord: () => import('@/views/luckyDraw/lotteryRecord')
+  lotteryRecord: () => import('@/views/luckyDraw/lotteryRecord'),
+  // 审核列表
+  auditList: () => import('@/views/auditList/index')
 }
 export default router

+ 26 - 0
src/utils/index.js

@@ -8,6 +8,7 @@
  * @param {string} cFormat
  * @returns {string}
  */
+import dayjs from 'dayjs'
 export function parseTime (time, cFormat) {
   if (arguments.length === 0) {
     return null
@@ -135,3 +136,28 @@ export function formatDuring (mss) {
   return hours + ":" + minutes + ":" + seconds;
 
 }
+
+export const objectToOptions = data => {
+  const options = []
+  for (const key in data) {
+    if (data.hasOwnProperty(key)) {
+      const item = data[key]
+      const upkey = key.toLocaleUpperCase()
+      options.push({
+        label: item,
+        value: (upkey === 'TRUE' || upkey === 'FALSE' ? upkey === 'TRUE' : key)
+      })
+    }
+  }
+  return options
+}
+
+export const getTimes = (times, keys = []) => {
+  if (times && times.length) {
+    return {
+      [keys[0] || 'start']: dayjs(times[0]).format('YYYY-MM-DD'),
+      [keys[1] || 'start']: dayjs(times[1]).format('YYYY-MM-DD'),
+    }
+  }
+  return {}
+}

+ 4 - 2
src/utils/request2.js

@@ -96,10 +96,12 @@ service.interceptors.request.use(
       // ['X-Token'] is a custom headers key
       // please modify it according to the actual situation
       config.headers['Authorization'] = getToken()
-      // config.headers['content-type'] = "application/x-www-form-urlencoded"
+      if (config.requestType === 'form') {
+        config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
+      }
     }
     config.params = cleanDeep(config.params)
-    //  params: cleanDeep(options.params),
+    config.data = cleanDeep(config.data)
     return config
   },
   error => {

+ 27 - 2
src/utils/searchArray.js

@@ -1,5 +1,5 @@
 // 搜索用的下拉数据列表
-
+import { payOrderType,auditType,auditPaymentType } from '../constant'
 // 课程类型
 export const courseType = [
   { label: "单技课", value: "SINGLE" },
@@ -17,11 +17,25 @@ export const courseType = [
   { label: "课堂课", value: "CLASSROOM" },
   { label: "对外课", value: "COMM" }
 ]
+
+export const musicCourseType = [
+  { label: "单技课", value: "SINGLE" },
+  { label: "合奏课", value: "MIX" },
+  { label: "基础技能课", value: "HIGH" },
+  { label: "线上基础技能课", value: "HIGH_ONLINE" },
+  { label: "网管课", value: "PRACTICE" },
+  { label: "乐团网管课", value: "MUSIC_NETWORK" },
+  { label: "启蒙课", value: "ENLIGHTENMENT" },
+  { label: "集训单技课", value: "TRAINING_SINGLE" },
+  { label: "集训合奏课", value: "TRAINING_MIX" },
+  { label: "课堂课", value: "CLASSROOM" },
+]
+
 export const courseListType = [
   { label: "乐团课", value: "MUSIC" },
   { label: "VIP课", value: "VIP" },
   { label: "网管课", value: "PRACTICE" },
-
+  { label: "综合课", value: "COMPREHENSIVE" },
 ]
 
 // 考勤状态
@@ -194,6 +208,17 @@ export const classTimeList = [
   { label: "40", value: "CLASSROOM" },
 ]
 
+export const payOrderTypeList = getValueForKey(payOrderType)
+export const auditTypeList = getValueForKey(auditType)
+export const auditPaymentTypeList = getValueForKey(auditPaymentType)
+
+function getValueForKey(obj){
+  let arr = []
+  for(let k in obj){
+    arr.push({label:obj[k],value:k})
+  }
+  return arr
+}
 
 // export {
 //   courseType,

+ 31 - 1
src/utils/vueFilter.js

@@ -1,7 +1,7 @@
 import Vue from 'vue'
 import dayjs from 'dayjs'
 import numeral from 'numeral'
-import { feeProject, feeType, saleType } from '../constant'
+import { feeProject, feeType, saleType, payStatus, payOrderType, paymentPatternType, payUserType, userPaymentType, courseType,auditType,auditPaymentType } from '../constant'
 
 // 合并数组
 Vue.filter('joinArray', (value, type) => {
@@ -162,6 +162,15 @@ Vue.filter('dateForMinFormat', (value) => {
   }
 })
 
+Vue.filter('paymentPatternTypeFormat', val => paymentPatternType[val])
+// 支付用户类型
+Vue.filter('payUserTypeFormat', val => payUserType[val])
+// 支付缴费方式
+Vue.filter('userPaymentTypeFormat', val => userPaymentType[val])
+// 课程类型格式化
+Vue.filter('courseTypeFormat', val => courseType[val])
+
+
 // 时间处理
 Vue.filter('timer', (value) => {
   if (value) {
@@ -282,6 +291,11 @@ Vue.filter('returnStatus', value => {
   return template[value]
 })
 
+// 缴费状态
+Vue.filter('payTypeStatus', val => {
+  return payStatus[val]
+})
+
 // 性别
 Vue.filter('sex', value => {
   let template = ['女', '男']
@@ -652,3 +666,19 @@ Vue.filter('receiveFormat', value => {
   }
   return template[value]
 })
+
+// 缴费方式
+
+Vue.filter('payOrderType', value => {
+  return payOrderType[value]
+})
+
+// 审核状态 auditType
+Vue.filter('auditType', value => {
+  return auditType[value]
+})
+
+// 审核申请类型 auditPaymentType
+Vue.filter('auditPaymentType', value => {
+  return auditPaymentType[value]
+})

+ 4 - 2
src/views/accompanyManager/accompanys.vue

@@ -723,11 +723,13 @@ export default {
           this.courseData = res.data.rows;
           if (this.courseData.length > 0) {
             this.name = this.courseData[0].name;
+            this.expireForm.coursesExpireDate = this.courseData[0].coursesExpireDate.substring(0, 10);
             this.timers =
               this.courseData[0].coursesStartDate.substring(0, 10) +
               "至" +
               this.courseData[0].coursesExpireDate.substring(0, 10);
-            this.expireForm.coursesExpireDate = this.courseData[0].coursesExpireDate.substring(0, 10);
+
+
             let originalStartDate = this.courseData[0].coursesStartDate ? new Date(this.courseData[0].coursesStartDate) : new Date()
             let buyMonths = this.courseData[0].buyMonths
             let lastDayNum = nextMonthLastDay(originalStartDate.getFullYear(), (originalStartDate.getMonth() + buyMonths + 1))
@@ -808,7 +810,7 @@ export default {
       });
     },
     getList () {
-      findPracticeGroupCourseSchedules({ practiceId: this.practiceId }).then(
+      findPracticeGroupCourseSchedules({ practiceId: this.practiceId, page: this.pageInfo.page, rows: this.pageInfo.limit }).then(
         res => {
           if (res.code == 200) {
             this.tableList = res.data.pageInfo.rows;

+ 316 - 0
src/views/auditList/index.vue

@@ -0,0 +1,316 @@
+
+<template>
+  <div class="m-container">
+    <h2>
+      <div class="squrt"></div>
+      审核列表
+    </h2>
+    <div class="m-core">
+      <!-- 搜索标题 -->
+      <el-form :inline="true" class="searchForm" v-model.trim="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
+            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
+            class="multiple"
+            v-model.trim="searchForm.paymentType"
+            filterable
+            clearable
+            placeholder="申请类型"
+          >
+            <el-option
+              v-for="(item, index) in paymentTypeList"
+              :key="index"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-select
+            class="multiple"
+            v-model.trim="searchForm.status"
+            filterable
+            clearable
+            placeholder="审核状态"
+          >
+            <el-option
+              v-for="(item, index) in statusList"
+              :key="index"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="getList" type="danger">搜索</el-button>
+        </el-form-item>
+      </el-form>
+      <div class="tableWrap">
+        <el-table
+          :data="tableList"
+          :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+        >
+          <!-- <el-table-column type="selection" width="55"></el-table-column> -->
+          <el-table-column
+            align="center"
+            prop="organName"
+            label="分部名称"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="musicGroupName"
+            label="乐团名称"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            width="180px"
+            prop="musicGroupId"
+            label="乐团编号"
+          ></el-table-column>
+          <el-table-column align="center" prop="paymentType" label="申请类型">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.paymentType | auditPaymentType }}
+              </div>
+            </template></el-table-column
+          >
+          <el-table-column align="center" prop="payUserType" label="订单类型">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.payUserType | payOrderType }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="addCourseTotalTime"
+            label="加课总时长(分钟)"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="courseOriginalPrice"
+            label="原现价(元)"
+          >
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.courseOriginalPrice | moneyFormat }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="courseCurrentPrice"
+            label="申请价格(元)"
+          >
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.courseCurrentPrice | moneyFormat }}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="memo" label="备注">
+            <template slot-scope="scope">
+              <tooltip :content="scope.row.memo" />
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="operatorName"
+            label="申请人"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="auditStatus"
+            label="状态"
+            width="100px"
+          >
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.auditStatus | auditType }} 
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="createTime"
+            label="申请时间"
+            width="140px"
+          >
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.createTime | dateForMinFormat }}
+              </div>
+            </template></el-table-column
+          >
+          <!--  -->
+          <el-table-column
+            align="center"
+            label="操作"
+            width="100px"
+            fixed="right"
+          >
+            <template slot-scope="scope">
+              <el-button
+                v-permission="'helpCenterContent/modify'"
+                @click="lookDetail(scope.row)"
+                type="text"
+                >查看</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          :total="pageInfo.total"
+          :page.sync="pageInfo.page"
+          :limit.sync="pageInfo.limit"
+          :page-sizes="pageInfo.page_size"
+          @pagination="getList"
+        />
+      </div>
+    </div>
+    <el-dialog title="申请详情" width="900px" :visible.sync="typeStatus" destroy-on-close>
+      <review :detail="detail" @close="close" />
+    </el-dialog>
+  </div>
+</template>
+<script>
+import pagination from "@/components/Pagination/index";
+import review from "@/views/resetTeaming/modals/review.vue";
+// import store from '@/store'
+import { getAuditList, getAuditListDetail } from "@/api/auditManager";
+import { getEmployeeOrgan } from "@/api/buildTeam";
+import Tooltip from "@/components/Tooltip/index";
+import { auditTypeList, auditPaymentTypeList } from "@/utils/searchArray";
+
+export default {
+  components: { pagination, Tooltip, review },
+  name: "helpCategory",
+  data() {
+    return {
+      paymentTypeList: auditPaymentTypeList,
+      organList: [],
+      statusList: auditTypeList,
+      searchForm: {
+        search: null,
+        paymentType: null,
+        status: null,
+        organId: null,
+      },
+      tableList: [],
+
+      pageInfo: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+      detail: null,
+      typeStatus: false,
+    };
+  },
+  activated() {
+    this.getList();
+  },
+  mounted() {
+    getEmployeeOrgan().then((res) => {
+      if (res.code == 200) {
+        this.organList = res.data;
+      }
+    });
+    this.getList();
+  },
+  methods: {
+    getList() {
+      let params = {
+        page: this.pageInfo.page,
+        rows: this.pageInfo.limit,
+        ...this.searchForm,
+      };
+      getAuditList(params).then((res) => {
+        let result = res.data;
+        if (res.code == 200) {
+          this.tableList = result.rows;
+          this.pageInfo.total = result.total;
+        }
+      });
+    },
+
+    lookDetail(row) {
+      // this.detail = res.data
+      this.detail = {
+        id:row.musicGroupPaymentCalenderId,
+        musicGroupId:row.musicGroupId,
+        status:row.auditStatus
+      }
+      this.typeStatus = true;
+    },
+    close() {
+      this.typeStatus = false;
+      this.getList()
+    },
+  },
+  watch: {
+    typeStatus(val) {
+      if (!val) {
+        this.detail = null;
+      }
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.el-button--primary {
+  background: #14928a;
+  border-color: #14928a;
+  color: #fff;
+  &:hover,
+  &:active,
+  &:focus {
+    background: #14928a;
+    border-color: #14928a;
+    color: #fff;
+  }
+}
+/deep/.el-date-editor.el-input {
+  width: 100% !important;
+}
+/deep/.el-select {
+  width: 100% !important;
+}
+/deep/.el-table .cell {
+  display: -webkit-box;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+}
+/deep/.el-dialog__body {
+  padding: 10px 20px;
+}
+.newBand {
+  display: inline-block;
+}
+</style>

+ 62 - 26
src/views/categroyManager/globalConfig.vue

@@ -5,36 +5,67 @@
     </h2>
     <div class="m-core">
       <!-- navMenu -->
-      <el-tabs v-model.trim="activeIndex" type="card" @tab-click="handleClick">
-        
-        <el-tab-pane label="声部设置(对内)" name="0" v-if="permissionList.musicalManager">
-            <musicalManager v-if="activeIndex == 0" />
+      <el-tabs v-model.trim="activeIndex"
+               type="card"
+               @tab-click="handleClick">
+
+        <el-tab-pane label="声部设置(对内)"
+                     name="0"
+                     v-if="permissionList.musicalManager">
+          <musicalManager v-if="activeIndex == 0" />
         </el-tab-pane>
-        <el-tab-pane label="声部设置(对外)" name="1" v-if="permissionList.musicalManagerOut">
-            <musicalManagerOut v-if="activeIndex == 1" />
+        <el-tab-pane label="声部设置(对外)"
+                     name="1"
+                     v-if="permissionList.musicalManagerOut">
+          <musicalManagerOut v-if="activeIndex == 1" />
         </el-tab-pane>
-        <el-tab-pane label="乐团收费类型" name="2" v-if="permissionList.typesManager">
-            <typesManager v-if="activeIndex == 2" />
+        <el-tab-pane label="乐团收费类型"
+                     name="2"
+                     v-if="permissionList.typesManager">
+          <typesManager v-if="activeIndex == 2" />
         </el-tab-pane>
-        <el-tab-pane label="乐团收费标准" name="3" v-if="permissionList.chargesList">
+        <el-tab-pane label="折扣设置"
+                     name="9"
+                     v-if="permissionList.typesManager">
+          <discountManage v-if="activeIndex == 9" />
+        </el-tab-pane>
+        <el-tab-pane label="乐团收费标准"
+                     name="3"
+                     v-if="permissionList.chargesList">
           <chargesList v-if="activeIndex == 3" />
         </el-tab-pane>
-        <el-tab-pane label="乐团作业模板" name="4" v-if="permissionList.jobTemplateSetting">
-            <jobTemplateSetting v-if="activeIndex == 4" />
+        <el-tab-pane label="乐团课程费用"
+                     name="10"
+                     v-if="permissionList.musicCourseFee">
+          <musicCourseFee v-if="activeIndex == 10" />
+        </el-tab-pane>
+        <el-tab-pane label="乐团作业模板"
+                     name="4"
+                     v-if="permissionList.jobTemplateSetting">
+          <jobTemplateSetting v-if="activeIndex == 4" />
         </el-tab-pane>
-        <el-tab-pane label="热词标签" name="5" v-if="permissionList.errorManager">
+        <el-tab-pane label="热词标签"
+                     name="5"
+                     v-if="permissionList.errorManager">
           <errorManager v-if="activeIndex == 5" />
         </el-tab-pane>
-        <el-tab-pane label="参数设置" name="6" v-if="permissionList.overallManager">
-            <overallManager v-if="activeIndex == 6" />
+        <el-tab-pane label="参数设置"
+                     name="6"
+                     v-if="permissionList.overallManager">
+          <overallManager v-if="activeIndex == 6" />
         </el-tab-pane>
-        <el-tab-pane label="收费分润配置" name="7" v-if="permissionList.overallManagerTwo">
-            <overallManagerTwo v-if="activeIndex == 7" />
+        <el-tab-pane label="收费分润配置"
+                     name="7"
+                     v-if="permissionList.overallManagerTwo">
+          <overallManagerTwo v-if="activeIndex == 7" />
         </el-tab-pane>
         <!-- holiday_setting -->
-        <el-tab-pane label="节假日设置" name="8" v-if="permissionList.holidaySetting">
-            <holidaySetting v-if="activeIndex == 8" />
+        <el-tab-pane label="节假日设置"
+                     name="8"
+                     v-if="permissionList.holidaySetting">
+          <holidaySetting v-if="activeIndex == 8" />
         </el-tab-pane>
+
       </el-tabs>
     </div>
   </div>
@@ -46,21 +77,25 @@ import holidaySetting from './generalSettings/holidaySetting'
 import musicalManager from './specialSetup/musicalManager'
 import musicalManagerOut from './specialSetup/musicalManagerOut'
 import typesManager from './specialSetup/typesManager'
+import discountManage from './specialSetup/discountManage'
 import jobTemplateSetting from './specialSetup/jobTemplateSetting'
 import errorManager from './generalSettings/errorManager'
 import chargesList from './specialSetup/chargesList'
+import musicCourseFee from './specialSetup/musicCourseFee'
 import { permission } from '@/utils/directivePage'
 export default {
   components: {
     overallManager,
     overallManagerTwo,
     holidaySetting,
-    musicalManager, 
-    musicalManagerOut, 
-    typesManager, 
-    jobTemplateSetting, 
+    musicalManager,
+    musicalManagerOut,
+    typesManager,
+    discountManage,
+    jobTemplateSetting,
     errorManager,
-    chargesList
+    chargesList,
+    musicCourseFee
   },
   name: 'globalConfig',
   data () {
@@ -75,7 +110,8 @@ export default {
         chargesList: permission('/globalConfig/chargesList'),
         jobTemplateSetting: permission('/globalConfig/jobTemplateSetting'),
         errorManager: permission('/globalConfig/errorManager'),
-        holidaySetting: permission('/globalConfig/holidaySetting')
+        holidaySetting: permission('/globalConfig/holidaySetting'),
+        musicCourseFee:permission('/globalConfig/musicCourseFee'),
       }
     }
   },
@@ -88,6 +124,6 @@ export default {
 </script>
 <style lang="scss" scoped>
 /deep/.m-container {
-  padding: 0 10px 40px
+  padding: 0 10px 40px;
 }
-</style>
+</style>

+ 2 - 0
src/views/categroyManager/insideSetting/branchActive.vue

@@ -155,6 +155,7 @@ export default {
     async __init () {
       let vipGroupCategoryList = await vipGroupCategory({ page: 1, rows: 9999 })
       if (vipGroupCategoryList.code == 200) {
+        this.vipGroupCategoryList = []
         vipGroupCategoryList.data.forEach(item => {
           this.vipGroupCategoryList.push({
             label: item.name,
@@ -165,6 +166,7 @@ export default {
 
       let teacherList = await getTeacher()
       if (teacherList.code == 200) {
+        this.teacherList = []
         teacherList.data.forEach(item => {
           this.teacherList.push({
             label: item.realName,

+ 64 - 67
src/views/categroyManager/specialSetup/chargesList.vue

@@ -7,14 +7,35 @@
       <div class="tableWrap">
         <el-table :data="dataList"
                   :header-cell-style="{background:'#EDEEF0',color:'#444'}">
-          <el-table-column prop="organName"
+          <el-table-column prop="organId"
                            label="所属分部">
+            <template slot-scope="scope">
+              {{ branchById[scope.row.organId] }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="chargeTypeId"
+                    label="乐团模式">
+            <template slot-scope="scope">
+              {{ typesById[scope.row.chargeTypeId] }}
+            </template>
           </el-table-column>
-          <el-table-column prop="chargeTypeName"
-                           label="收费类型">
+          <el-table-column prop="name"
+                           label="收费方式名称">
           </el-table-column>
-          <el-table-column prop="courseFee"
-                           label="课程费用">
+          <el-table-column prop="totalCurrentPrice"
+                           label="现价(元)">
+            <template slot-scope="scope">
+              {{ scope.row.totalCurrentPrice | moneyFormat }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="totalOriginalPrice"
+                           label="原价(元)">
+            <template slot-scope="scope">
+              {{ scope.row.totalOriginalPrice | moneyFormat }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="updateTime"
+                           label="修改时间">
           </el-table-column>
           <el-table-column align='center'
                            label="操作">
@@ -37,68 +58,39 @@
 
       <el-dialog :title="formTitle[formActionTitle]"
                  :visible.sync="chargeStatus"
-                 @close="onFormClose('ruleForm')"
-                 width="500px">
-        <el-form :model="form"
-                 :rules="rules"
-                 ref="ruleForm">
-          <el-form-item label="所属分部"
-                        prop="organId"
-                        :label-width="formLabelWidth">
-            <el-select v-model.trim="form.organId"
-                       clearable
-                       filterable>
-              <el-option v-for="(item, index) in branchList"
-                         :key="index"
-                         :label="item.label"
-                         :value="item.value">
-              </el-option>
-            </el-select>
-          </el-form-item>
-          <el-form-item label="收费类型"
-                        prop="chargeTypeId"
-                        :label-width="formLabelWidth">
-            <el-select v-model.trim="form.chargeTypeId"
-                       clearable
-                       filterable>
-              <el-option v-for="(item, index) in typesList"
-                         :key="index"
-                         :label="item.label"
-                         :value="item.value">
-              </el-option>
-            </el-select>
-          </el-form-item>
-          <el-form-item label="课程费用"
-                        prop="courseFee"
-                        :label-width="formLabelWidth">
-            <el-input type="number"
-                      @mousewheel.native.prevent
-                      v-model.trim="form.courseFee"
-                      autocomplete="off"></el-input>
-          </el-form-item>
-        </el-form>
-        <span slot="footer"
-              class="dialog-footer">
-          <el-button @click="chargeStatus = false">取 消</el-button>
-          <el-button @click="onTypesSubmit('ruleForm')"
-                     type="primary">确 定</el-button>
-        </span>
+                 @close="closeModal"
+                 destroy-on-close
+                 width="850px">
+        <chargesForm
+          :typesList="typesList"
+          :branchList.sync="branchList"
+          :rowDetail="rowDetail"
+          @close="closeModal"
+          @submited="getList"
+        />
       </el-dialog>
     </div>
   </div>
 </template>
 <script>
 import pagination from '@/components/Pagination/index'
-import { chargeTypeList, chargeTypeOrganizationFeeAdd, chargeTypeOrganizationFeeDelete, chargeTypeOrganizationFeeUpdate, chargeTypeOrganizationFee, branchQueryPage } from '@/api/specialSetting'
+import { chargeTypeList, chargeTypeOrganizationFeeAdd, musicGroupOrganizationCourseSettingsDel, chargeTypeOrganizationFeeUpdate, chargeTypeOrganizationFee, branchQueryPage, musicGroupOrganizationCourseSettingsQueryPage } from '@/api/specialSetting'
+import chargesForm from './modals/chargesForm'
 export default {
-  components: { pagination },
+  components: {
+    pagination,
+    chargesForm
+  },
   name: 'chargesList',
   data () {
     return {
       id: null,
+      rowDetail: null,
       dataList: [],
       typesList: [], // 分部列表
       branchList: [], // 分部列表
+      typesById: {},
+      branchById: {},
       formActionTitle: 'create',
       formTitle: {
         create: '添加乐团收费标准',
@@ -124,7 +116,7 @@ export default {
       }
     }
   },
-  mounted () {
+  async mounted () {
     this.getList()
 
     // 收费类型
@@ -133,12 +125,15 @@ export default {
       page: 1
     }).then(res => {
       if (res.code == 200) {
+        const typesById = {}
         res.data.rows.forEach(item => {
+          typesById[item.id] = item.name
           this.typesList.push({
             label: item.name,
             value: item.id
           })
         })
+        this.typesById = typesById
       }
     })
 
@@ -148,12 +143,15 @@ export default {
       page: 1
     }).then(res => {
       if (res.code == 200) {
-        res.data.rows.forEach(item => {
-          this.branchList.push({
+        const branchById = {}
+        this.branchList = res.data.rows.map(item => {
+          branchById[item.id] = item.name
+          return ({
             label: item.name,
             value: item.id
           })
         })
+        this.branchById = branchById
       }
     })
   },
@@ -188,17 +186,13 @@ export default {
       }
     },
     onChargeOperation (type, row) {
-      this.chargeStatus = true
       this.formActionTitle = type
-
       if (type == 'update') {
-        this.form = {
-          chargeTypeId: row.chargeTypeId,
-          courseFee: row.courseFee,
-          organId: row.organId,
-          id: row.id
-        }
+        this.rowDetail = { ...row }
+      } else {
+        this.rowDetail = null
       }
+      this.chargeStatus = true
     },
     onChargeDelete (row) { // 删除
       this.$confirm('您确定删除该收费标准?', '提示', {
@@ -206,14 +200,14 @@ export default {
         cancelButtonText: '取消',
         type: 'warning'
       }).then(() => {
-        chargeTypeOrganizationFeeDelete({ id: row.id }).then(res => {
+        musicGroupOrganizationCourseSettingsDel({ id: row.id }).then(res => {
           this.messageTips('删除', res)
         })
       }).catch(() => { })
 
     },
     getList () {
-      chargeTypeOrganizationFee({
+      musicGroupOrganizationCourseSettingsQueryPage({
         rows: this.pageInfo.limit,
         page: this.pageInfo.page
       }).then(res => {
@@ -230,6 +224,9 @@ export default {
       }
       this.$refs[formName].resetFields()
     },
+    closeModal() {
+      this.chargeStatus = false
+    }
   }
 }
 </script>
@@ -256,4 +253,4 @@ export default {
 /deep/.el-table {
   display: inline-block;
 }
-</style>
+</style>

+ 326 - 0
src/views/categroyManager/specialSetup/discountManage.vue

@@ -0,0 +1,326 @@
+<template>
+  <div class='m-container'>
+    <!-- <h2>折扣设置</h2> -->
+    <div class="m-core">
+      <div class='newBand' v-permission="'chargeType/upSet'"
+           @click="createVisible = true">添加</div>
+      <!-- 列表 -->
+      <div class="tableWrap">
+        <el-table :data='tableList'
+                  :header-cell-style="{background:'#EDEEF0',color:'#444'}">
+          <el-table-column align='center'
+                           prop="chargeTypeId"
+                           label="收费类型">
+                           <template slot-scope="scope">{{ typesListById[scope.row.chargeTypeId] }}</template>
+          </el-table-column>
+          <el-table-column align='center'
+                           prop="subjectId"
+                           label="声部组合">
+                           <template slot-scope="scope">{{ subjectListById[scope.row.subjectId] }}</template>
+          </el-table-column>
+          <el-table-column align='center'
+                  prop="goodsDiscountRate"
+                  label="折扣(%)">
+          </el-table-column>
+          <el-table-column align='center'
+                           label="操作">
+            <template slot-scope="scope">
+              <el-button @click="openTypes('update', scope.row)" v-permission="'chargeType/upSet'"
+                         type="text">修改</el-button>
+              <el-button @click="onTypesDel(scope.row)" v-permission="'chargeType/del'"
+                         type="text">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination :total="pageInfo.total"
+                    :page.sync="pageInfo.page"
+                    :limit.sync="pageInfo.limit"
+                    :page-sizes="pageInfo.page_size"
+                    @pagination="getList" />
+      </div>
+    </div>
+    <el-dialog :title="formTitle[formActionTitle]"
+               :visible.sync="typeStatus"
+               @close="onFormClose('ruleForm')"
+               width="500px">
+      <el-form :model="form"
+               :rules="rules"
+               ref="ruleForm">
+        <el-form-item label="收费类型"
+                      prop="chargeTypeId"
+                      :label-width="formLabelWidth">
+          <el-select v-model.trim="form.chargeTypeId"
+                     filterable
+                     placeholder="请选择收费类型"
+                     clearable>
+            <el-option v-for="item in typesList"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="声部选择"
+                      v-if="form.classGroupType != 'MIX'"
+                      prop="subjectId"
+                      :label-width="formLabelWidth">
+          <el-select v-model.trim="form.subjectId"
+                     filterable
+                     placeholder="请选择声部组合"
+                     clearable>
+            <el-option-group v-for="group in subjectList"
+                             :key="group.label"
+                             :label="group.label">
+              <el-option v-for="item in group.options"
+                         :key="item.value"
+                         :label="item.label"
+                         :value="item.value">
+              </el-option>
+            </el-option-group>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="折扣(%)"
+                      prop="goodsDiscountRate"
+                      :label-width="formLabelWidth">
+          <el-input-number v-model.trim="form.goodsDiscountRate"
+            autocomplete="off"
+            placeholder="请输入折扣 1%-100%"
+            controls-position="right"
+            class="number-input"
+            :min="1"
+            :max="100"
+            :precision="0"
+          ></el-input-number>
+        </el-form-item>
+      </el-form>
+      <span slot="footer"
+            class="dialog-footer">
+        <el-button @click="typeStatus = false">取 消</el-button>
+        <el-button type="primary"
+                   @click="onTypesSubmit('ruleForm')">确 定</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="createVisible"
+      title="添加折扣"
+      width="400px"
+    >
+      <createDiscount
+        @close="createVisible = false"
+        :typesList="typesList"
+        :subjectList="subjectList"
+      />
+    </el-dialog>
+  </div>
+</template>
+<script>
+import pagination from '@/components/Pagination/index'
+import { chargeTypeList, subjectListTree, insertChargeTypeSubjectMapper, updateChargeTypeSubjectMapper, delChargeTypeSubjectMapper, chargeTypeSubjectMapper } from '@/api/specialSetting'
+import createDiscount from './modals/create-discount'
+export default {
+  name: 'typesManager',
+  components: { pagination, createDiscount },
+  data () {
+    return {
+      tableList: [],
+      typesList: [],
+      typesListById: {},
+      subjectList: [], // 声部列表
+      subjectListById: {}, // 声部列表
+      formActionTitle: 'create',
+      formTitle: {
+        create: '添加折扣',
+        update: '修改折扣'
+      },
+      createVisible: false,
+      typeStatus: false, // 添加教学点
+      formLabelWidth: '100px',
+      form: {
+        name: null, //
+        subjectId: null,
+        goodsDiscountRate: null,
+      },
+      rules: {
+        chargeTypeId: [{ required: true, message: '请选择收费类型', trigger: 'blur' }],
+        subjectId: [{ required: true, message: '请选择声部组合', trigger: 'change' }],
+        goodsDiscountRate: [{ required: true, message: '请输入折扣', trigger: 'blur' }],
+      },
+      pageInfo: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50] // 选择限制显示条数
+      }
+    }
+  },
+  mounted () {
+    this.getList()
+    this.getChargeTypeList()
+    this.getSubjectTree()
+  },
+  methods: {
+    onTypesSubmit (formName) { // 添加数据
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          if (this.formActionTitle == 'create') {
+            if (this.form.id) { // 判断有没有Id,如果有则删除
+              delete this.form.id
+            }
+            insertChargeTypeSubjectMapper(this.form).then(res => {
+              this.messageTips('添加', res)
+            })
+          } else if (this.formActionTitle == 'update') {
+            updateChargeTypeSubjectMapper([this.form]).then(res => {
+              this.messageTips('修改', res)
+            })
+          }
+        } else {
+          return false;
+        }
+      })
+    },
+    messageTips (title, res) {
+      if (res.code == 200) {
+        this.$message.success(title + '成功')
+        this.typeStatus = false
+        this.getList()
+      } else {
+        this.$message.error(res.msg)
+      }
+    },
+    async onTypesDel (row) {
+      try {
+        await this.$confirm('是否删除此条数据?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+        delChargeTypeSubjectMapper({id: row.id}).then(res => {
+          this.messageTips('删除', res)
+        })
+      } catch (error) {}
+    },
+    getChargeTypeList() {
+      chargeTypeList({
+        rows: 9999,
+        page: 1
+      }).then(res => {
+        if (res.code == 200) {
+          const typesListById = {}
+          res.data.rows.forEach(item => {
+            typesListById[item.id] = item.name
+            this.typesList.push({
+              label: item.name,
+              value: item.id
+            })
+          })
+          this.typesListById = typesListById
+        }
+      })
+    },
+    getList () {
+      chargeTypeSubjectMapper({
+        rows: this.pageInfo.limit,
+        page: this.pageInfo.page
+      }).then(res => {
+        let result = res.data
+        this.tableList = result.rows
+        // if (res.code == 200) {
+        //   result.data.rows.forEach(row => {
+        //     let subjectname = [],
+        //       subjectIds = []
+        //     row.subjects.forEach(item => {
+        //       subjectname.push(item.name)
+        //       subjectIds.push(item.id)
+        //     })
+        //     row.subjectName = subjectname
+        //     row.subjectIds = subjectIds
+        //   })
+        //   this.tableList = result.rows
+          this.pageInfo.total = result.total
+        // }
+      })
+    },
+    openTypes (type, row) {
+      this.typeStatus = true
+      this.formActionTitle = type
+      // 修改的时候赋值
+      if (type == 'update') {
+        this.form = {
+          id: row.id,
+          chargeTypeId: row.chargeTypeId,
+          subjectId: row.subjectId,
+          goodsDiscountRate: row.goodsDiscountRate,
+        }
+      }
+    },
+    onFormClose (formName) { // 关闭弹窗重置验证
+      this.form = {
+        name: null, // 作业模块名称
+        subjectId: null,
+        goodsDiscountRate: null,
+      }
+      this.$refs[formName].resetFields()
+    },
+    getSubjectTree () { // 获取声部列表
+      subjectListTree({
+        delFlag: 0,
+        rows: 9999
+      }).then(res => {
+        const subjectListById = {}
+        let result = res.data
+        if (res.code == 200) {
+          let tempArray = []
+          result.rows.forEach((item, index) => {
+            let subject = []
+            if (item.subjects) {
+              item.subjects.forEach(s => {
+                subjectListById[s.id] = s.name
+                subject.push({
+                  value: s.id,
+                  label: s.name
+                })
+              })
+            }
+
+            tempArray[index] = {
+              label: item.name,
+              options: subject
+            }
+          })
+          this.subjectListById = subjectListById
+          this.subjectList = tempArray
+        }
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.el-button--primary {
+  background: #14928a;
+  border-color: #14928a;
+  color: #fff;
+  &:hover,
+  &:active,
+  &:focus {
+    background: #14928a;
+    border-color: #14928a;
+    color: #fff;
+  }
+}
+/deep/.el-date-editor.el-input {
+  width: 100% !important;
+}
+.el-select {
+  width: 100% !important;
+}
+.number-input{
+  /deep/ .el-input__inner {
+    text-align: left;
+  }
+
+  width: 100%;
+}
+</style>

+ 359 - 0
src/views/categroyManager/specialSetup/modals/chargesForm.vue

@@ -0,0 +1,359 @@
+<template>
+  <div>
+    <el-form :model="form"
+              label-suffix=": "
+              ref="form">
+      <el-form-item label="所属分部"
+                    prop="organId"
+                    :rules="[{required: true, message: '请选择所属分部', trigger: 'change'}]"
+                    :label-width="formLabelWidth">
+        <el-select v-model.trim="form.organId"
+                    clearable
+                    placeholder="请选择所属分部"
+                    filterable>
+          <el-option v-for="(item, index) in branchList"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="乐团模式"
+                    prop="chargeTypeId"
+                    :rules="[{required: true, message: '请选择乐团模式', trigger: 'change'}]"
+                    :label-width="formLabelWidth">
+        <el-select v-model.trim="form.chargeTypeId"
+                    clearable
+                    placeholder="请选择乐团模式"
+                    filterable>
+          <el-option v-for="(item, index) in typesList"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="收费方式名称"
+                    prop="name"
+                    :rules="[{required: true, message: '请输入收费方式名称', trigger: 'blur'}]"
+                    :label-width="formLabelWidth">
+        <el-input v-model.trim="form.name"
+                  placeholder="请输入收费方式名称"
+                  clearable>
+        </el-input>
+      </el-form-item>
+      <div class="class-items">
+        <div class="items">
+          <div class="items-header">
+            <span class="name">课程类型</span>
+            <span class="name">是否可选</span>
+            <span class="name">课程总时长(分钟)</span>
+            <span class="name">现价(元)</span>
+            <span class="name">原价(元)</span>
+            <span class="ctrl"></span>
+          </div>
+          <div class="item" v-for="(item, index) in form.details" :key="index">
+            <el-form-item
+              :prop="`details.${index}.courseType`"
+              :rules="[{required: true, message: '请选择课程类型', trigger: 'change'}]"
+            >
+              <el-select v-model.trim="item.courseType"
+                          size="mini"
+                          clearable
+                          @change="() => courseItemChange(item, index)"
+                          filterable>
+                <el-option  v-for="item in courseTypes"
+                            :key="item.courseType"
+                            :label="courseType[item.courseType]"
+                            :disabled="isOptionDisabled(item.courseType)"
+                            :value="item.courseType">
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item
+              :prop="`details.${index}.isStudentOptional`"
+              :rules="[{required: true, message: '请选择是否可选', trigger: 'change'}]"
+            >
+              <el-select v-model.trim="item.isStudentOptional"
+                          size="mini"
+                          clearable
+                          filterable>
+                <el-option  v-for="item in boolOptions"
+                            :key="item.label"
+                            :label="item.label"
+                            :value="String(item.value)">
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item
+              :prop="`details.${index}.courseTotalMinuties`"
+              :rules="[{required: true, message: '请输入课程总时长', trigger: 'blur'}]"
+            >
+              <el-input-number
+                size="mini"
+                style="width: 90%!important;"
+                class="number-input"
+                v-model="item.courseTotalMinuties"
+                :controls="false"
+                :precision="0"
+                :min="1"
+                @change="() => courseItemChange(item, index)"
+                placeholder="课程总时长"
+              />
+            </el-form-item>
+            <el-form-item
+              :prop="`details.${index}.courseCurrentPrice`"
+              :rules="[{required: true, message: '请输入课程现价', trigger: 'blur'}]"
+            >
+              <el-input-number
+                size="mini"
+                style="width: 90%!important;"
+                class="number-input"
+                v-model="item.courseCurrentPrice"
+                :controls="false"
+                :precision="0"
+                :min="1"
+                placeholder="课程现价"
+              />
+            </el-form-item>
+            <el-form-item
+              :prop="`details.${index}.courseOriginalPrice`"
+              :rules="[{required: true, message: '请输入课程原价', trigger: 'blur'}]"
+            >
+              <el-input-number
+                size="mini"
+                style="width: 90%!important;"
+                class="number-input"
+                v-model="item.courseOriginalPrice"
+                :controls="false"
+                :precision="0"
+                :min="1"
+                placeholder="课程原价"
+              />
+            </el-form-item>
+            <span class="ctrl">
+              <i @click="removeItem(index)" v-if="form.details.length > 1" class="el-icon-circle-close" />
+            </span>
+          </div>
+        </div>
+        <el-button
+          icon="el-icon-circle-plus-outline"
+          plain class="create-type-button"
+          type="info"
+          size="small"
+          @click="addItem"
+        >新增课程类型</el-button>
+      </div>
+      <el-row>
+        <el-col :span="6">
+          <el-form-item label="原价"
+                        prop="totalOriginalPrice"
+                        label-width="50px">
+                        {{ totalOriginalPrice | moneyFormat}}
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="现价"
+                        prop="totalCurrentPrice"
+                        label-width="50px">
+                        {{ totalCurrentPrice | moneyFormat}}
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <span slot="footer"
+          class="dialog-footer">
+      <el-button @click="$listeners.close">取 消</el-button>
+      <el-button @click="submit"
+                  type="primary">确 定</el-button>
+    </span>
+  </div>
+</template>
+<script>
+const initItem = {
+  courseType: '',
+  isStudentOptional: '',
+  courseTotalMinuties: '',
+  courseOriginalPrice: '',
+  courseCurrentPrice: '',
+}
+import {
+  musicGroupOrganizationCourseSettingsAdd,
+  musicGroupOrganizationCourseSettingsUpdate,
+  getOrganizationCourseUnitPriceSettings
+} from '@/api/specialSetting'
+import { classTimeList } from '@/utils/searchArray'
+import { courseType, boolOptions } from '@/constant'
+import { objectToOptions }  from '@/utils'
+import numeral from 'numeral'
+
+const plusNum = (items = [], key) => {
+  let money = 0
+  const _items = items.filter(item => item.isStudentOptional === 'false')
+  for (const item of _items) {
+    money += parseFloat(parseFloat(item[key] || 0).toFixed(2) || 0)
+  }
+  return money
+}
+
+const initForm = {
+  organId: '',
+  classTimeList: '',
+  chargeTypeId: '',
+  name: '',
+  details: [{}],
+}
+
+export default {
+  name: 'modal-chargesForm',
+  props: ['branchList', 'typesList', 'rowDetail'],
+  data() {
+    return {
+      form: {...initForm},
+      formLabelWidth: '120px',
+      courseType,
+      courseTypeOptions: objectToOptions(courseType),
+      boolOptions: objectToOptions(boolOptions),
+      courseTypes: [],
+      courseTypesByType: {},
+    }
+  },
+  computed: {
+    totalOriginalPrice() {
+      return plusNum(this.form.details, 'courseOriginalPrice')
+    },
+    totalCurrentPrice() {
+      return plusNum(this.form.details, 'courseCurrentPrice')
+    }
+  },
+  watch: {
+    rowDetail() {
+      this.updateForm()
+    },
+    async 'form.chargeTypeId'() {
+      try {
+        const res = await getOrganizationCourseUnitPriceSettings({
+          chargeTypeId: this.form.chargeTypeId,
+          rows: 9999
+        })
+        const d = {}
+        this.courseTypes = res.data.rows
+        for (const item of this.courseTypes) {
+          d[item.courseType] = item
+        }
+        this.courseTypesByType = d
+      } catch (error) {}
+    }
+  },
+  mounted() {
+    this.updateForm()
+  },
+  methods: {
+    courseItemChange(item, index) {
+      if (item.courseType) {
+        const active = this.courseTypesByType[item.courseType] || {}
+        const _list = this.form.details
+        _list[index] = {
+          ...item,
+          courseCurrentPrice: Math.ceil(active.unitPrice * (item.courseTotalMinuties || 1)),
+          courseOriginalPrice: Math.ceil(active.unitPrice * (item.courseTotalMinuties || 1))
+        }
+        this.$set(this.form, `details`, [..._list])
+      }
+    },
+    updateForm() {
+      if (this.rowDetail) {
+        const { organId, classTimeList, chargeTypeId, name, details } = this.rowDetail
+        this.form = {
+          organId,
+          classTimeList,
+          chargeTypeId,
+          name,
+          details: details.map(item => ({
+            ...item,
+            isStudentOptional: String(item.isStudentOptional)
+          }))
+        }
+      } else {
+        this.form = {...initForm}
+      }
+    },
+    isOptionDisabled(key) {
+      const selected = this.form.details.map(item => item.courseType)
+      return selected.includes(key)
+    },
+    addItem() {
+      const _items = [...this.form.details, {}]
+      this.form.details = _items
+    },
+    removeItem(index) {
+      const _items = [...this.form.details]
+      _items[index] = null
+      this.form.details = _items.filter(item => !!item)
+    },
+    submit() {
+      this.$refs.form.validate(async (valid) => {
+        if (valid) {
+          try {
+            if (this.rowDetail) {
+              const res = await musicGroupOrganizationCourseSettingsUpdate({
+                id: this.rowDetail.id,
+                ...this.form
+              })
+              this.$message.success('更新成功')
+            } else {
+              const res = await musicGroupOrganizationCourseSettingsAdd(this.form)
+              this.$message.success('提交成功')
+            }
+            this.$listeners.close()
+            this.$listeners.submited()
+          } catch (error) {}
+        }
+      })
+    }
+  },
+}
+</script>
+<style lang="less" scoped>
+  .dialog-footer{
+    display: block;
+    text-align: right;
+  }
+  .items{
+    .items-header,
+    .item{
+      display: flex;
+      >.el-form-item,
+      >span{
+        width: 100%;
+        text-align: center;
+        padding: 0 10px;
+        &.ctrl{
+          width: 300px;
+        }
+      }
+    }
+    .items-header{
+      background-color: #f1f1f1;
+      padding: 10px 0;
+      margin-bottom: 10px;
+      >span{
+        line-height: 26px;
+      }
+    }
+  }
+  .create-type-button{
+    width: 100%;
+    margin-bottom: 20px;
+  }
+  .ctrl{
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-bottom: 26px;
+    i{
+      cursor: pointer;
+      font-size: 18px;
+    }
+  }
+</style>

+ 108 - 0
src/views/categroyManager/specialSetup/modals/create-discount.vue

@@ -0,0 +1,108 @@
+<template>
+  <div>
+    <el-form :model="form" ref="form">
+      <el-form-item
+        label="声部选择"
+        prop="subjectId"
+        :label-width="formLabelWidth"
+        :rules="[{ required: true, message: '请选择声部', trigger: 'change' }]"
+      >
+        <el-select
+          v-model.trim="form.subjectId"
+          filterable
+          style="width: 100%!important;"
+          placeholder="请选择声部组合"
+          clearable
+        >
+          <el-option-group
+            v-for="group in subjectList"
+            :key="group.label"
+            :label="group.label"
+          >
+            <el-option
+              v-for="item in group.options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-option-group>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        v-for="item in typesList"
+        :key="item.value"
+        :label="item.label + '模式折扣(%)'"
+        :prop="`types.${item.value}`"
+        :label-width="formLabelWidth"
+        :rules="[{ required: true, message: '请输入折扣', trigger: 'blur' }]"
+      >
+        <el-input-number v-model.trim="form.types[item.value]"
+          autocomplete="off"
+          placeholder="请输入折扣 1%-100%"
+          controls-position="right"
+          class="number-input"
+          :min="1"
+          :max="100"
+          :precision="0"
+        ></el-input-number>
+      </el-form-item>
+    </el-form>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="$listeners.close">取 消</el-button>
+      <el-button type="primary" @click="submit">确 定</el-button>
+    </span>
+  </div>
+</template>
+<script>
+import { insertChargeTypeSubjectMapper } from '@/api/specialSetting'
+export default {
+  props: ['typesList', 'subjectList'],
+  data() {
+    return {
+      formLabelWidth: '130px',
+      form: {
+        subjectId: '',
+        types: {},
+      }
+    }
+  },
+  methods: {
+    submit() {
+      this.$refs.form.validate(async valid => {
+        if (valid) {
+          const data = []
+          for (const key in this.form.types) {
+            if (this.form.types.hasOwnProperty(key)) {
+              const item = this.form.types[key];
+              data.push({
+                chargeTypeId: key,
+                subjectId: this.form.subjectId,
+                goodsDiscountRate: item
+              })
+            }
+          }
+          try {
+            await insertChargeTypeSubjectMapper(data)
+            this.$message.success('创建成功')
+            this.$listeners.close()
+          } catch (error) {}
+        }
+      })
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+  .dialog-footer{
+    display: block;
+    text-align: right;
+  }
+  .number-input{
+    /deep/ .el-input__inner {
+      text-align: left;
+    }
+
+    width: 100%;
+  }
+</style>

+ 448 - 0
src/views/categroyManager/specialSetup/musicCourseFee.vue

@@ -0,0 +1,448 @@
+<template>
+  <div class="m-container">
+    <!-- <h2>折扣设置</h2> -->
+    <div class="m-core">
+      <el-form :inline="true" :model="searchForm">
+        <el-form-item>
+          <el-select
+            placeholder="请选择分部"
+            v-model="searchForm.organId"
+            clearable
+          >
+            <el-option
+              v-for="(item, index) in organList"
+              :label="item.name"
+              :value="item.id"
+              :key="index"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-select
+            placeholder="课程类型"
+            v-model="searchForm.courseScheduleType"
+            clearable
+            filterable
+          >
+            <el-option
+              v-for="(item, index) in musicCourseType"
+              :label="item.label"
+              :value="item.value"
+              :key="index"
+            ></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-form-item>
+      </el-form>
+      <div
+        class="newBand"
+        v-permission="'organizationCourseUnitPriceSettings/insert'"
+        @click="newVisiable = true"
+      >
+        添加
+      </div>
+      <!-- 列表 -->
+      <div class="tableWrap">
+        <el-table
+          :data="tableList"
+          :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+        >
+          <el-table-column align="center" prop="organName" label="分部名称">
+            <template slot-scope="scope">{{ scope.row.organ.name }}</template>
+          </el-table-column>
+          <el-table-column align="center" prop="courseType" label="课程类型">
+            <template slot-scope="scope">{{
+              scope.row.courseType | coursesType
+            }}</template>
+          </el-table-column>
+          <el-table-column align="center" prop="chargeName" label="缴费形态">
+            <template slot-scope="scope">{{
+              scope.row.chargeType.name
+            }}</template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="goodsDiscountRate"
+            label="缴费金额"
+          >
+            <template slot-scope="scope">{{
+              scope.row.unitPrice | moneyFormat
+            }}</template>
+          </el-table-column>
+          <el-table-column align="center" prop="courseType" label="修改时间">
+            <template slot-scope="scope">{{
+              scope.row.updateTime | formatTimer
+            }}</template>
+          </el-table-column>
+          <el-table-column align="center" label="操作">
+            <template slot-scope="scope">
+              <el-button
+                @click="openTypes(scope.row)"
+                v-permission="'organizationCourseUnitPriceSettings/update'"
+                type="text"
+                >修改</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          :total="pageInfo.total"
+          :page.sync="pageInfo.page"
+          :limit.sync="pageInfo.limit"
+          :page-sizes="pageInfo.page_size"
+          @pagination="getList"
+        />
+      </div>
+    </div>
+    <el-dialog
+      title="新建"
+      destroy-on-close
+      :visible.sync="newVisiable"
+      width="500px"
+    >
+      <el-form :model="createForm" class="createForm" ref="ruleForm">
+        <el-form-item
+          label="所属分部"
+          :rules="[{ required: true, message: '所属分部', trigger: 'blur' }]"
+          prop="organId"
+          :label-width="formLabelWidth"
+        >
+          <el-select
+            placeholder="请选择分部"
+            v-model="createForm.organId"
+            clearable
+          >
+            <el-option
+              v-for="(item, index) in organList"
+              :label="item.name"
+              :value="item.id"
+              :key="index"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label="课程类型"
+          :rules="[
+            { required: true, message: '请选择课程类型', trigger: 'blur' },
+          ]"
+          prop="courseType"
+          :label-width="formLabelWidth"
+        >
+          <el-select
+            v-model.trim="createForm.courseType"
+            filterable
+            placeholder="请选择课程类型"
+            clearable
+          >
+            <el-option
+              v-for="item in musicCourseType"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <div v-for="(item, index) in dataList" :key="index">
+          <el-form-item
+            :label="`${item.name}每分钟费用`"
+            :label-width="formLabelWidth"
+            :rules="[
+              {
+                required: true,
+                message: '请输入每分钟课程费用',
+                trigger: 'blur',
+              },
+            ]"
+            :prop="`unitPriceJson.${item.id}`"
+          >
+            <el-input type="number" v-model="createForm.unitPriceJson[item.id]">
+              <template slot="append">元</template>
+            </el-input>
+          </el-form-item>
+        </div>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="newVisiable = false">取 消</el-button>
+        <el-button type="primary" @click="submitInfo">确 定</el-button>
+      </span>
+    </el-dialog>
+
+    <el-dialog
+      title="修改"
+      :visible.sync="resetVisible"
+      width="500px"
+      destroy-on-close
+    >
+      <el-form :model="resetForm" class="resetForm" ref="resetForm">
+        <el-form-item
+          label="所属分部"
+          :rules="[{ required: true, message: '所属分部', trigger: 'blur' }]"
+          prop="organId"
+          :label-width="formLabelWidth"
+        >
+          <el-select
+            placeholder="请选择分部"
+            v-model="resetForm.organId"
+            clearable
+            disabled
+          >
+            <el-option
+              v-for="(item, index) in organList"
+              :label="item.name"
+              :value="item.id"
+              :key="index"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label="课程类型"
+          :rules="[
+            { required: true, message: '请选择课程类型', trigger: 'blur' },
+          ]"
+          prop="courseType"
+          :label-width="formLabelWidth"
+        >
+          <el-select
+            v-model.trim="resetForm.courseType"
+            filterable
+            placeholder="请选择课程类型"
+            clearable
+            disabled
+          >
+            <el-option
+              v-for="item in musicCourseType"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          v-if="actvieRow"
+          :label="`${actvieRow.chargeType.name}每分钟费用`"
+          :label-width="formLabelWidth"
+          :rules="[
+            {
+              required: true,
+              message: '请输入每分钟课程费用',
+              trigger: 'blur',
+            },
+          ]"
+          prop="unitPrice"
+        >
+          <el-input type="number" v-model="resetForm.unitPrice">
+            <template slot="append">元</template>
+          </el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="resetVisible = false">取 消</el-button>
+        <el-button type="primary" @click="resetSubmit">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import pagination from "@/components/Pagination/index";
+import { getEmployeeOrgan } from "@/api/buildTeam";
+import {
+  chargeTypeList,
+  getOrganizationCourseUnitPriceSettings,
+  addOrganizationCourseUnitPrice,
+  resetOrganizationCourseUnitPrice,
+  deleteOrganizationCourseUnitPrice,
+} from "@/api/specialSetting";
+import createDiscount from "./modals/create-discount";
+import { musicCourseType } from "@/utils/searchArray";
+export default {
+  name: "typesManager",
+  components: { pagination, createDiscount },
+  data() {
+    return {
+      musicCourseType,
+      newVisiable: false,
+      resetVisible: false,
+      tableList: [],
+      dataList: [],
+      organList: [],
+      searchForm: {
+        organId: null,
+        courseScheduleType: null,
+      },
+      createForm: {
+        organId: null,
+        courseType: null,
+        unitPriceJson: {},
+      },
+      resetForm: {
+        unitPrice: null,
+        courseType: null,
+        id: null,
+        organId: null,
+      },
+      pageInfo: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+      formLabelWidth: "120px",
+      actvieRow: null,
+    };
+  },
+  mounted() {
+    chargeTypeList({
+      rows: 99999,
+      page: 1,
+    }).then((res) => {
+      if (res.code == 200) {
+        this.dataList = res.data.rows;
+        this.dataList.forEach((item) => {
+          this.$set(this.createForm.unitPriceJson, item.id, null);
+        });
+        console.log(this.createForm);
+      }
+    });
+    getEmployeeOrgan().then((res) => {
+      if (res.code == 200) {
+        this.organList = res.data;
+      }
+    });
+    this.getList();
+  },
+  methods: {
+    search() {
+      this.pageInfo.page = 1;
+      this.getList();
+    },
+    onReSet() {
+      this.searchForm = {
+        organId: null,
+        courseScheduleType: null,
+      };
+      this.search();
+    },
+
+    async onTypesDel(row) {
+      try {
+        await this.$confirm("是否删除此条数据?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        });
+        delChargeTypeSubjectMapper({ id: row.id }).then((res) => {
+          this.messageTips("删除", res);
+        });
+      } catch (error) {}
+    },
+
+    getList() {
+      getOrganizationCourseUnitPriceSettings({
+        rows: this.pageInfo.limit,
+        page: this.pageInfo.page,
+        organId: this.searchForm.organId,
+        courseScheduleType: this.searchForm.courseScheduleType,
+      }).then((res) => {
+        let result = res.data;
+        this.tableList = result.rows;
+        this.pageInfo.total = result.total;
+        // }
+      });
+    },
+    submitInfo() {
+      this.$refs.ruleForm.validate(async (valid) => {
+        const data = [];
+        for (const key in this.createForm.unitPriceJson) {
+          if (this.createForm.unitPriceJson.hasOwnProperty(key)) {
+            const item = this.createForm.unitPriceJson[key];
+            data.push({
+              chargeTypeId: key,
+              courseType: this.createForm.courseType,
+              organId: this.createForm.organId,
+              unitPrice: item,
+            });
+          }
+        }
+        if (valid) {
+          try {
+            await addOrganizationCourseUnitPrice(data);
+            this.$message.success("创建成功");
+            this.getList();
+            this.newVisiable = false;
+            this.createForm = {
+              organId: null,
+              courseType: null,
+              unitPriceJson: {},
+            };
+            this.dataList.forEach((item) => {
+              this.$set(this.createForm.unitPriceJson, item.id, null);
+            });
+          } catch (error) {}
+        }
+      });
+    },
+    openTypes(row) {
+      this.actvieRow = row;
+      this.resetForm = {
+        chargeTypeId: row.chargeTypeId,
+        unitPrice: row.unitPrice,
+        courseType: row.courseType,
+        id: row.id,
+        organId: row.organId,
+      };
+      this.resetVisible = true;
+    },
+    resetSubmit() {
+      // resetOrganizationCourseUnitPrice
+      this.$refs.resetForm.validate(async (valid) => {
+        if (valid) {
+          try {
+            await resetOrganizationCourseUnitPrice(this.resetForm);
+            this.$message.success("修改成功");
+            this.getList();
+            this.resetVisible = false;
+            this.resetForm = {
+              unitPrice: null,
+              courseType: null,
+              id: null,
+              organId: null,
+            };
+          } catch (error) {}
+        }
+      });
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.el-button--primary {
+  background: #14928a;
+  border-color: #14928a;
+  color: #fff;
+  &:hover,
+  &:active,
+  &:focus {
+    background: #14928a;
+    border-color: #14928a;
+    color: #fff;
+  }
+}
+/deep/.el-date-editor.el-input {
+  width: 100% !important;
+}
+.el-select {
+  width: 100% !important;
+}
+.createForm {
+  /deep/.el-input {
+    width: 340px !important;
+  }
+}
+</style>

+ 18 - 77
src/views/categroyManager/specialSetup/typesManager.vue

@@ -13,18 +13,13 @@
                            label="收费类型">
           </el-table-column>
           <el-table-column align='center'
-                           label="声部组合">
-            <template slot-scope="scope">
-              {{ scope.row.subjectName | joinArray(',') }}
-            </template>
-          </el-table-column>
-          <el-table-column align='center'
                            label="操作">
             <template slot-scope="scope">
               <el-button @click="openTypes('update', scope.row)" v-permission="'chargeType/upSet'"
                          type="text">修改</el-button>
-              <el-button @click="onTypesDel(scope.row)" v-permission="'chargeType/del'"
-                         type="text">删除</el-button>
+              <el-button slot="reference" v-permission="'chargeType/del'"
+                  @click="onTypesDel(scope.row)"
+                  type="text">删除</el-button>
             </template>
           </el-table-column>
         </el-table>
@@ -46,27 +41,9 @@
                       prop="name"
                       :label-width="formLabelWidth">
           <el-input v-model.trim="form.name"
+                    placeholder="请输入收费类型"
                     autocomplete="off"></el-input>
         </el-form-item>
-        <el-form-item label="声部选择"
-                      v-if="form.classGroupType != 'MIX'"
-                      prop="subjectIds"
-                      :label-width="formLabelWidth">
-          <el-select v-model.trim="form.subjectIds"
-                     filterable
-                     clearable
-                     multiple>
-            <el-option-group v-for="group in subjectList"
-                             :key="group.label"
-                             :label="group.label">
-              <el-option v-for="item in group.options"
-                         :key="item.value"
-                         :label="item.label"
-                         :value="item.value">
-              </el-option>
-            </el-option-group>
-          </el-select>
-        </el-form-item>
       </el-form>
       <span slot="footer"
             class="dialog-footer">
@@ -92,15 +69,13 @@ export default {
         create: '添加收费类型',
         update: '修改收费类型'
       },
-      typeStatus: false, // 添加教学点 
+      typeStatus: false, // 添加教学点
       formLabelWidth: '100px',
       form: {
-        name: null, // 
-        subjectIds: []
+        name: null, //
       },
       rules: {
         name: [{ required: true, message: '请输入类型名称', trigger: 'blur' }],
-        subjectIds: [{ required: true, message: '请选择声部组合', trigger: 'change' }]
       },
       pageInfo: {
         // 分页规则
@@ -113,7 +88,6 @@ export default {
   },
   mounted () {
     this.getList()
-    this.getSubjectTree()
   },
   methods: {
     onTypesSubmit (formName) { // 添加数据
@@ -145,10 +119,17 @@ export default {
         this.$message.error(res.msg)
       }
     },
-    onTypesDel (row) {
-      chargeTypeDel(row.id).then(res => {
-        this.messageTips('删除', res)
-      })
+    async onTypesDel (row) {
+      try {
+        await this.$confirm('是否确认删除此条数据?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+        chargeTypeDel(row.id).then(res => {
+          this.messageTips('删除', res)
+        })
+      } catch (error) {}
     },
     getList () {
       chargeTypeList({
@@ -157,16 +138,6 @@ export default {
       }).then(res => {
         let result = res.data
         if (res.code == 200) {
-          result.rows.forEach(row => {
-            let subjectname = [],
-              subjectIds = []
-            row.subjects.forEach(item => {
-              subjectname.push(item.name)
-              subjectIds.push(item.id)
-            })
-            row.subjectName = subjectname
-            row.subjectIds = subjectIds
-          })
           this.tableList = result.rows
           this.pageInfo.total = result.total
         }
@@ -180,45 +151,15 @@ export default {
         this.form = {
           id: row.id,
           name: row.name,
-          subjectIds: row.subjectIds
         }
       }
     },
     onFormClose (formName) { // 关闭弹窗重置验证
       this.form = {
         name: null, // 作业模块名称
-        subjectIds: []
       }
       this.$refs[formName].resetFields()
     },
-    getSubjectTree () { // 获取声部列表
-      subjectListTree({
-        delFlag: 0,
-        rows: 9999
-      }).then(res => {
-        let result = res.data
-        if (res.code == 200) {
-          let tempArray = []
-          result.rows.forEach((item, index) => {
-            let subject = []
-            if (item.subjects) {
-              item.subjects.forEach(s => {
-                subject.push({
-                  value: s.id,
-                  label: s.name
-                })
-              })
-            }
-
-            tempArray[index] = {
-              label: item.name,
-              options: subject
-            }
-          })
-          this.subjectList = tempArray
-        }
-      })
-    }
   }
 }
 </script>
@@ -241,4 +182,4 @@ export default {
 .el-select {
   width: 100% !important;
 }
-</style>
+</style>

+ 1 - 1
src/views/luckyDraw/trophyManager.vue

@@ -66,7 +66,7 @@
                         <tooltip :content="scope.row.memo" />
                     </template>
                 </el-table-column>
-                </el-table-column>
+
                 <el-table-column align="center" label="操作">
                     <template slot-scope="scope">
                         <el-button @click="onOperationTrophy('update', scope.row)" v-permission="'luckDrawPrize/update'" type="text">修改</el-button>

+ 41 - 0
src/views/resetTeaming/api.js

@@ -0,0 +1,41 @@
+import request2 from '@/utils/request2'
+
+export const musicGroupPaymentCalenderQueryPage = data => request2({
+  url: '/api-web/musicGroupPaymentCalender/queryPage',
+  data: {},
+  params: data,
+  requestType: 'form'
+})
+
+export const musicGroupPaymentCalenderAdd = data => request2({
+  url: '/api-web/musicGroupPaymentCalender/add',
+  data,
+  method: 'post',
+})
+
+export const musicGroupPaymentCalenderView = data => request2({
+  url: '/api-web/musicGroupPaymentCalender/auditListDetail',
+  data: {},
+  params: data,
+  method: 'get',
+})
+
+export const getMusicGroupStu = data => request2({
+  url: '/api-web/studentRegistration/getMusicGroupStu',
+  data: {},
+  params: data,
+  method: 'get',
+})
+
+export const musicGroupPaymentCalenderDetailBatchAdd = data => request2({
+  url: '/api-web/musicGroupPaymentCalenderDetail/batchAdd',
+  data: data,
+  method: 'post',
+})
+
+// musicGroupPaymentCalender/update
+export const musicGroupPaymentCalenderDetailBatchUpdate = data => request2({
+  url: '/api-web/musicGroupPaymentCalender/update',
+  data: data,
+  method: 'post',
+})

文件差異過大導致無法顯示
+ 527 - 286
src/views/resetTeaming/components/resetPayList.vue


+ 718 - 0
src/views/resetTeaming/components/resetPayListSchool.vue

@@ -0,0 +1,718 @@
+<!--  -->
+<template>
+  <div class="m-core">
+    <el-form :inline="true" :model="searchForm">
+      <el-form-item>
+        <el-select
+          placeholder="缴费类型"
+          v-model="searchForm.paymentType"
+          clearable
+          filterable
+        >
+          <el-option
+            v-for="(item, index) in payOrderTypeList"
+            :label="item.label"
+            :value="item.value"
+            :key="index"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+
+      <el-form-item>
+        <el-button type="danger" @click="getList">搜索</el-button>
+        <!-- <el-button @click="onReSet" type="primary">重置</el-button> -->
+      </el-form-item>
+    </el-form>
+    <div class="topWrap">
+      <!-- <div class="newBand"
+           @click="newPay"
+           v-permission="'musicGroupPaymentCalender/add'">新建缴费</div> -->
+      <!-- <div class="newBand"
+           @click="newUserPay"
+           v-permission="'musicGroupPaymentCalender/add'">新建学员缴费</div> -->
+      <div class="newBand"
+           @click="newSchoolPay"
+           v-permission="'musicGroupPaymentCalender/add'">新建学校缴费</div>
+      <div class="newBand"
+           v-permission="'/studentPayBase'"
+           @click="setStudentPay">学员缴费设置</div>
+      <!-- <div class="newBand"
+      v-if="!isNewGropu"
+           @click="onCreateQRCode">续费二维码</div> -->
+    </div>
+    <div class="tableWrap">
+      <el-table
+        style="width: 100%"
+        :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+        :data="tableList"
+      >
+        <el-table-column
+          align="center"
+          prop="expectNum"
+          width="120"
+          label="预计缴费人数"
+        ></el-table-column>
+        <el-table-column align="center" prop="paymentPattern" label="缴费方式">
+          <template slot-scope="scope">
+            <div>
+              {{ scope.row.paymentPattern | teamPayStatus }}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column
+          align="center"
+          prop="paymentValidStartDate"
+          width="150"
+          label="缴费有效期开始日期"
+        >
+          <template slot-scope="scope">
+            <div>
+              {{ scope.row.paymentValidStartDate | formatTimer }}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column
+          align="center"
+          prop="paymentValidEndDate"
+          width="150"
+          label="缴费有效期结束日期"
+        >
+          <template slot-scope="scope">
+            <div>
+              {{ scope.row.paymentValidEndDate | formatTimer }}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column
+          align="center"
+          prop="actualNum"
+          width="120"
+          label="实际缴费人数"
+        ></el-table-column>
+        <el-table-column align="center" prop="status" label="缴费状态">
+          <template slot-scope="scope">
+            <div>
+              {{ scope.row.status | payTypeStatus }}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column
+          align="center"
+          prop="isGiveMusicNetwork"
+          width="120"
+          label="是否赠送网管课"
+        >
+          <template slot-scope="scope">
+            <div>
+              {{ scope.row.isGiveMusicNetwork ? "是" : "否" }}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column align="center"
+                         prop="memo"
+                         label="备注"></el-table-column>
+        <el-table-column label="操作" fixed="right" min-width="150px">
+          <template slot-scope="scope">
+            <div>
+              <el-button type="text"
+                         @click="lookDetail(scope.row)"
+                         v-permission="'musicGroupPaymentCalender/auditListDetail'">查看</el-button>
+              <el-button type="text"
+                         v-if="scope.row.status == 'REJECT'"
+                         v-permission="'musicGroupPaymentCalender/update'"
+                         @click="resetPay(scope.row)">修改</el-button>
+
+              <!-- <el-button type="text" v-if="!isNewGropu" @click="onCreateQRCode(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>
+    <el-dialog
+      :visible.sync="payVisible"
+      :close-on-click-modal="false"
+      width="500px"
+      :title="diTitle"
+    >
+      <el-form
+        :model="payForm"
+        :inline="true"
+        label-width="120px"
+        label-position="right"
+        ref="payForm"
+      >
+        <el-form-item
+          label="缴费开始日期"
+          :rules="[
+            { required: true, message: '请设置缴费开始日期', trigger: 'blur' },
+          ]"
+          prop="startPaymentDate"
+        >
+          <el-date-picker
+            v-model.trim="payForm.startPaymentDate"
+            @change="changeStartTime"
+            type="date"
+            :picker-options="pickerOptions"
+            value-format="yyyy-MM-dd"
+            placeholder="开始日期"
+          ></el-date-picker>
+        </el-form-item>
+        <el-form-item
+          label="缴费结束日期"
+          :rules="[
+            { required: true, message: '请设置缴费结束日期', trigger: 'blur' },
+          ]"
+          prop="deadlinePaymentDate"
+        >
+          <el-date-picker
+            v-model.trim="payForm.deadlinePaymentDate"
+            type="date"
+            :picker-options="beginDate(payForm.startPaymentDate)"
+            value-format="yyyy-MM-dd"
+            placeholder="结束日期"
+          ></el-date-picker>
+        </el-form-item>
+        <el-form-item
+          label="缴费方式"
+          prop="paymentPattern"
+          :rules="[{ required: true, message: '请选择缴费方式' }]"
+        >
+          <el-select
+            placeholder="缴费方式"
+            style="width: 220px"
+            clearable
+            filterable
+            @change="paymentPatternChange"
+            v-model.trim="payForm.paymentPattern"
+          >
+            <el-option :value="0" label="按月"></el-option>
+            <el-option :value="1" label="按季"></el-option>
+            <el-option :value="2" label="一次性"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label="缴费有效期开始"
+          :rules="[
+            {
+              required: true,
+              message: '请设置缴费有效期开始日期',
+              trigger: 'blur',
+            },
+          ]"
+          prop="paymentValidStartDate"
+        >
+          <el-date-picker
+            v-model.trim="payForm.paymentValidStartDate"
+            type="date"
+            @change="changePaymentStartTime"
+            :picker-options="pickerOptions"
+            value-format="yyyy-MM-dd"
+            placeholder="有效期开始日期"
+          ></el-date-picker>
+        </el-form-item>
+        <el-form-item
+          label="缴费有效期结束"
+          :rules="[
+            {
+              required: payForm.paymentPattern !== 2,
+              message: '请设置缴费有效期结束日期',
+              trigger: 'blur',
+            },
+          ]"
+          prop="paymentValidEndDate"
+        >
+          <el-date-picker
+            v-model.trim="payForm.paymentValidEndDate"
+            type="date"
+            :disabled="payForm.paymentPattern === 2"
+            :picker-options="beginDate(payForm.paymentValidStartDate)"
+            value-format="yyyy-MM-dd"
+            placeholder="有效期结束日期"
+          ></el-date-picker>
+        </el-form-item>
+        <el-form-item
+          label="收费类型"
+          v-if="isNew"
+          :rules="[
+            { required: true, message: '请选择收费类型', trigger: 'blur' },
+          ]"
+          prop="type"
+        >
+          <el-select
+            v-model.trim="payForm.type"
+            style="width: 220px !important"
+            placeholder="课程类型"
+          >
+            <el-option label="线上" value="ONLINE"></el-option>
+            <el-option label="线下" value="OFFLINE"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label="备注"
+          v-if="isNew"
+          :rules="[{ required: true, message: '请填写备注', trigger: 'blur' }]"
+          prop="memo"
+        >
+          <el-input
+            type="textarea"
+            style="width: 220px !important"
+            :rows="4"
+            placeholder="请填写备注"
+            v-model="payForm.memo"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="payVisible = false">取 消</el-button>
+        <el-button type="primary" v-if="isNew" @click="newPayInfo"
+          >确 定</el-button
+        >
+        <el-button type="primary" v-else @click="resetPayDate">确 定</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog
+      title="查看"
+      :visible.sync="reviewVisible"
+      width="900px"
+      destroy-on-close
+    >
+      <reviewDetail
+        @close="reviewVisible = false"
+        @submited="getList"
+        :detail="viewDetail"
+        :musicGroupId="$route.query.id"
+        destroy-on-close
+      />
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="reviewVisible = false"
+          >关闭</el-button
+        >
+      </div>
+    </el-dialog>
+    <el-dialog
+      :title="payFormTitle"
+      :visible.sync="userVisible"
+      width="800px"
+
+    >
+      <userPayForm
+        v-if="userVisible"
+        @close="userVisible = false"
+        @submited="payedSubmited"
+        @changeActive="$listeners.changeActive"
+        :organizationCourseUnitPriceSettings="organizationCourseUnitPriceSettings"
+        :rowDetail='activeRow'
+        :type="payFormType"
+        :baseInfo="baseInfo"
+        :paymentType="isNewGropu ? 0 : undefined"
+        :musicGroupId="$route.query.id"
+      />
+    </el-dialog>
+
+    <el-dialog title="学员选择"
+               :visible.sync="chioseStudentVisible"
+               destroy-on-close
+               append-to-body
+               width='800px'>
+      <setStudentFee @chioseStudent='chioseStudent'
+                     ref='setStudentFee'
+                     @submited="chioseStudentSubmited"
+                     :clearTale="clearStduent"></setStudentFee>
+      <div slot="footer"
+           class="dialog-footer">
+        <el-button @click="chioseStudentVisible = false">取 消</el-button>
+        <el-button type="primary" @click="submitNewPay">确 定</el-button>
+      </div>
+    </el-dialog>
+
+    <qr-code v-model="qrcodeStatus" title="续费二维码" :codeUrl="codeUrl" />
+  </div>
+</template>
+<script>
+import axios from "axios";
+import { getToken } from "@/utils/auth";
+import pagination from "@/components/Pagination/index";
+import load from "@/utils/loading";
+import qs from "qs";
+import dayjs from 'dayjs'
+import QrCode from "@/components/QrCode/index";
+import { vaildStudentUrl } from '@/utils/validate'
+import { addMusicGroupPaymentCalender, getMusicGroupPaymentCalender, resetMusicGroupPaymentCalender, delMusicGroupPaymentCalender } from "@/api/buildTeam";
+import {
+  getOrganizationCourseUnitPriceSettings
+} from '@/api/specialSetting'
+import { musicGroupPaymentCalenderQueryPage, getMusicGroupStu, musicGroupPaymentCalenderDetailBatchAdd } from '../api'
+import setStudentFee from './studentPayBase'
+import userPayForm from '../modals/user-pay-form'
+import schoolPayForm from '../modals/school-pay-form'
+import review from '../modals/review'
+import reviewDetail from '../modals/review-detail'
+import { userPaymentType } from '@/constant'
+import { objectToOptions } from '@/utils'
+import { payOrderTypeList}  from "@/utils/searchArray";
+export default {
+  props: ["baseInfo", "isNewGropu"],
+  components: {
+    pagination,
+    setStudentFee,
+    userPayForm,
+    schoolPayForm,
+    QrCode,
+    review,
+    reviewDetail,
+  },
+  data() {
+    return {
+      musicGroupStu: [],
+      payFormType: "user",
+      userVisible: false,
+      schoolVisible: false,
+      reviewVisible: false,
+      organizationCourseUnitPriceSettings: [],
+      searchForm: {
+        paymentType: null,
+      },
+      viewDetail: null,
+      tableList: [],
+      rules: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50], // 选择限制显示条数
+      },
+      isInit: false,
+      diTitle: "新增缴费",
+      payVisible: false,
+      payForm: {
+        startPaymentDate: null,
+        deadlinePaymentDate: null,
+        paymentPattern: null,
+        paymentValidStartDate: null,
+        paymentValidEndDate: null,
+        type: null,
+        memo: null,
+      },
+      isNew: false,
+      activeRow: null,
+      pickerOptions: {
+        firstDayOfWeek: 1,
+        disabledDate(time) {
+          return time.getTime() + 86400000 <= new Date().getTime();
+        },
+      },
+      qrcodeStatus: false, // 生成二维码
+      codeUrl: null,
+      chioseStudentVisible: false,
+      chioseStudentList: [],
+      clearStduent: true,
+      musicGroupPaymentCalenderId: "",
+      payOrderTypeLists: payOrderTypeList,
+    };
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  async mounted() {
+    // 获取分部
+    try {
+      const res = await getOrganizationCourseUnitPriceSettings({
+        rows: 9999
+      })
+      this.organizationCourseUnitPriceSettings = res.data.rows
+    } catch (error) {}
+    this.init();
+  },
+  computed: {
+    payOrderTypeList() {
+      return objectToOptions(userPaymentType);
+    },
+    payFormTitle() {
+      if (this.isNew) {
+        return this.payFormType === "user" ? "新增学员缴费" : "新增学校缴费";
+      } else {
+        return this.payFormType === "user" ? "修改学员缴费" : "修改学校缴费";
+      }
+    },
+  },
+  activated() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      try {
+        const res = await getMusicGroupStu({
+          musicGroupId: this.$route.query.id,
+        });
+
+      } catch (error) {}
+      this.getList();
+    },
+    newUserPay() {
+      this.payFormType = "user";
+      this.isNew = true;
+      this.activeRow = null
+      this.userVisible = true;
+    },
+    newSchoolPay() {
+      this.payFormType = "school";
+      this.isNew = true;
+      this.activeRow = null
+      this.userVisible = true;
+    },
+    getList () {
+      let musicGroupId = this.$route.query.id
+      return musicGroupPaymentCalenderQueryPage({
+        page: this.rules.page,
+        rows: this.rules.limit,
+        musicGroupId,
+        payUserType: 'SCHOOL',
+        paymentType: this.searchForm.paymentType,
+      }).then(res => {
+        if (res.code == 200) {
+          this.rules.total = res.data.total;
+          this.tableList = res.data.rows;
+        }
+      });
+    },
+    paymentPatternChange(val) {
+      if (val === 2) {
+        this.payForm.paymentValidEndDate = null;
+      }
+    },
+    onCreateQRCode (row) { // 生成报名二维码
+      this.qrcodeStatus = true
+      this.codeUrl = vaildStudentUrl() + '/#/musicGroupRenew?calenderId=' + row.id
+    },
+    chioseStudent(val) {
+      this.chioseStudentList = val;
+    },
+    newPay() {
+      this.diTitle = "新增缴费";
+      this.isNew = true;
+      this.payVisible = true;
+    },
+    resetPay(row) {
+      this.diTitle = "修改缴费";
+      this.isNew = false;
+      this.activeRow = row;
+      this.payFormType = row.payUserType==='SCHOOL'?'school':'user'
+      this.userVisible = true;
+    },
+    async chioseStudentSubmited() {
+      try {
+        await this.$confirm('缴费创建完成, 是否立即排课?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+        if (this.$listeners.changeActive) {
+          this.$listeners.changeActive({
+            name: '5'
+          })
+        }
+      } catch (error) {}
+    },
+    detelePay(row) {
+      let id = row.id;
+      this.$confirm(`确定删除该缴费周期?`, "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          delMusicGroupPaymentCalender({ id }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success("删除成功");
+              this.getList();
+            }
+          });
+        })
+        .catch(() => {});
+    },
+    lookDetail(row) {
+      let query = this.$route.query;
+      this.$route.query.paymentId = row.id;
+      this.viewDetail = row;
+      if (row.payUserType === "SCHOOL") {
+        this.reviewVisible = true;
+      } else {
+        this.$router.push({ path: "/business/strudentPayInfo", query });
+      }
+    },
+    setStudentPay() {
+      let query = this.$route.query;
+      this.$router.push({ path: "/business/studentPayBase", query });
+    },
+    newPayInfo() {
+      this.$refs["payForm"].validate((res) => {
+        if (res) {
+          /**
+           *   payForm: {
+        startPaymentDate: null,
+        deadlinePaymentDate: null,
+        type: null,
+        memo: null
+      },
+           *
+           */
+          this.chioseStudentVisible = true;
+          return;
+        }
+      });
+    },
+    submitNewPay() {
+      if (this.chioseStudentList.length < 1) {
+        this.$message.error("请至少选择一名学员");
+        return;
+      }
+
+      let obj = {};
+      obj.userIdList = this.chioseStudentList.map((stu) => {
+        return stu.userId;
+      });
+      obj.musicGroupPaymentCalenderId = this.musicGroupPaymentCalenderId;
+      musicGroupPaymentCalenderDetailBatchAdd(obj).then((res) => {
+        if (res.code == 200) {
+          this.$message.success("添加成功");
+          this.$refs.setStudentFee.clearTable();
+          this.payVisible = false;
+          this.chioseStudentVisible = false;
+          this.getList();
+        }
+      });
+    },
+    resetPayDate() {
+      resetMusicGroupPaymentCalender({
+        id: this.activeRow.id,
+        startPaymentDate: this.payForm.startPaymentDate,
+        deadlinePaymentDate: this.payForm.deadlinePaymentDate,
+        paymentValidStartDate: this.payForm.paymentValidStartDate
+          ? dayjs(this.payForm.paymentValidStartDate).format("YYYY-MM-DD")
+          : this.payForm.paymentValidStartDate,
+        paymentValidEndDate: this.payForm.paymentValidEndDate
+          ? dayjs(this.payForm.paymentValidEndDate).format("YYYY-MM-DD")
+          : this.payForm.paymentValidEndDate,
+        paymentPattern: this.payForm.paymentPattern,
+      }).then((res) => {
+        if (res.code == 200) {
+          this.$message.success("修改成功");
+          this.payVisible = false;
+          this.getList();
+        }
+      });
+    },
+    changeStartTime(val) {
+      this.payForm.deadlinePaymentDate = this.dateAddDays(val, 3);
+    },
+    changePaymentStartTime(val) {
+      this.payForm.paymentValidEndDate = null;
+    },
+    dateAddDays(dataStr, dayCount) {
+      let strdate = dataStr; //日期字符串
+      let isdate = new Date(strdate.replace(/-/g, "/")); //把日期字符串转换成日期格式
+      isdate = new Date((isdate / 1000 + 86400 * dayCount) * 1000); //日期加1天
+      let pdate =
+        isdate.getFullYear() +
+        "-" +
+        (isdate.getMonth() + 1) +
+        "-" +
+        isdate.getDate(); //把日期格式转换成字符串
+      return pdate;
+    },
+    beginDate(end) {
+      return {
+        firstDayOfWeek: 1,
+        disabledDate(time) {
+          if (end) {
+            return new Date(end).getTime() - 86400000 >= time.getTime();
+          } else {
+            return time.getTime() + 86400000 < Date.now();
+            //开始时间不选时,结束时间最大值小于等于当天
+          }
+        },
+      };
+    },
+    search() {
+      this.rules.page = 1;
+      this.getList();
+    },
+    onReSet() {
+      this.searchForm = { payUserType: null };
+    },
+    async payedSubmited(data) {
+      try {
+        await this.getList();
+        if (!this.isNewGropu) {
+          this.chioseStudentVisible = true;
+          if (data) {
+            this.musicGroupPaymentCalenderId = data.musicGroupPaymentCalenderId;
+          }
+        }
+      } catch (error) {}
+    },
+  },
+  watch: {
+    chioseStudentVisible() {
+      this.chioseStudentList = [];
+    },
+    payVisible (val) {
+      if (!val) {
+        this.payForm = {
+          startPaymentDate: null,
+          paymentPattern: null,
+          paymentValidStartDate: null,
+          paymentValidEndDate: null,
+          type: null,
+          memo: null,
+          deadlinePaymentDate: null,
+        };
+        this.$refs["payForm"].resetFields();
+      }
+    },
+  },
+};
+</script>
+<style lang='scss' scoped>
+.topWrap {
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-start;
+  div {
+    margin-right: 10px;
+  }
+}
+.left-code,
+.right-code {
+  // width: 50%;
+  // float: left;
+  h2 {
+    font-size: 18px;
+    text-align: center;
+    padding-bottom: 8px;
+  }
+
+  .qrcode {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    img {
+      width: 200px;
+      height: 200px;
+      margin: 0 auto;
+    }
+  }
+  .code-url {
+    font-size: 18px;
+    text-align: center;
+    padding: 15px 15px 0 15px;
+  }
+}
+</style>

+ 44 - 0
src/views/resetTeaming/components/resetSoundv2.vue

@@ -0,0 +1,44 @@
+<template>
+  <div>
+    <soundSetCore ref="soundSetCore" />
+    <div class="btnWrap"
+         v-if="lookType!=='look'"
+         style="margin-top:30px">
+      <div class="closeBtn"
+           @click="getSound">取消</div>
+      <div class="okBtn"
+           v-permission="{child: 'musicGroup/updateSubjectInfo', parent: '/resetTeaming/resetSound'}"
+           @click="saveInfo">保存</div>
+    </div>
+  </div>
+</template>
+<script>
+import soundSetCore from '@/views/teamBuild/components/soundSetComponents/soundSetCore'
+export default {
+  components: { soundSetCore },
+  data () {
+    return {
+      lookType: ''
+    }
+  },
+  mounted(){
+    this.init()
+  },
+  activated(){
+     this.init()
+  },
+  methods: {
+    init(){
+        this.lookType = this.$route.query.type
+    },
+    saveInfo () {
+      this.$refs.soundSetCore.submitInfo()
+    },
+    getSound () {
+      this.$refs.soundSetCore.init()
+    },
+  }
+}
+</script>
+<style lang="scss" scoped>
+</style>

文件差異過大導致無法顯示
+ 441 - 298
src/views/resetTeaming/components/strudentPayInfo.vue


+ 14 - 11
src/views/resetTeaming/components/studentPayBase.vue

@@ -31,9 +31,9 @@
                    type="primary">重置</el-button>
       </el-form-item>
     </el-form>
-    <div class="newBand"
+    <!-- <div class="newBand"
          @click="resetPays"
-         v-permission="'musicGroupStudentFee/batchUpdateCourseFee'">修改缴费金额</div>
+         v-permission="'musicGroupStudentFee/batchUpdateCourseFee'">修改缴费金额</div> -->
     <div class="tableWrap">
       <el-table style="width: 100%"
                 :header-cell-style="{background:'#EDEEF0',color:'#444'}"
@@ -70,8 +70,8 @@
         </el-table-column> -->
         <el-table-column align="center"
                          prop="courseFee"
-                         label="缴费金额"></el-table-column>
-        <el-table-column align="center"
+                         label="缴费金额(元)"></el-table-column>
+        <!-- <el-table-column align="center"
                          label="操作">
           <template slot-scope="scope">
             <div>
@@ -80,7 +80,7 @@
                          @click="resetPay(scope.row)">修改金额</el-button>
             </div>
           </template>
-        </el-table-column>
+        </el-table-column> -->
       </el-table>
       <!-- <pagination :total="rules.total"
                   :page.sync="rules.page"
@@ -254,16 +254,19 @@ export default {
           return item.id
         }).join(',')
       }
-      obj.courseFee = this.resetPayForm.momey;
-      if (!obj.courseFee || obj.courseFee < 0) {
-        this.$message.error('请输入正确的金额')
-        return
-      }
+      // obj.courseFee = this.resetPayForm.momey;
+      // if (!obj.courseFee || obj.courseFee < 0) {
+      //   this.$message.error('请输入正确的金额')
+      //   return
+      // }
       resetMusicGroupStudentFee(obj).then(res => {
         if (res.code == 200) {
           this.$message.success('修改成功')
           this.resetPayVisible = false
           this.getList()
+          if (this.$listeners.submited) {
+            this.$listeners.submited()
+          }
         }
       })
     }
@@ -284,4 +287,4 @@ export default {
   height: 300px;
   overflow: auto;
 }
-</style>
+</style>

+ 29 - 7
src/views/resetTeaming/index.vue

@@ -2,7 +2,7 @@
   <div class="m-container">
     <h2>
       <el-page-header @back="onCancel"
-                      content="乐团修改"></el-page-header>
+                      :content="teamName"></el-page-header>
 
     </h2>
     <div class="m-core">
@@ -14,6 +14,8 @@
                      v-if="permission('/resetTeaming/teamBaseInfo')"
                      name="1">
           <teamBaseInfo v-if="activeIndex == 1"
+                        @getBaseInfo="getBaseInfo"
+                        :baseInfo="baseInfo"
                         @getName='getName' />
         </el-tab-pane>
         <el-tab-pane label="声部设置"
@@ -26,10 +28,23 @@
                      name="4">
           <studentPayBase v-if="activeIndex == 4" />
         </el-tab-pane> -->
-        <el-tab-pane label="缴费设置"
+        <el-tab-pane label="学员缴费设置"
                      v-if="permission('/resetTeaming/resetPayList')"
                      name="3">
-          <resetPayList v-if="activeIndex == 3" />
+          <resetPayList
+            :baseInfo="baseInfo"
+            v-if="activeIndex == 3"
+            @changeActive="handleClick"
+          />
+        </el-tab-pane>
+        <el-tab-pane label="学校缴费设置"
+                     v-if="permission('/resetTeaming/resetPayList')"
+                     name="6">
+          <resetPayListSchool
+            :baseInfo="baseInfo"
+            v-if="activeIndex == 6"
+            @changeActive="handleClick"
+          />
         </el-tab-pane>
 
         <el-tab-pane label="班级调整"
@@ -54,21 +69,23 @@
 </template>
 <script>
 import teamBaseInfo from '@/views/teamBuild/components/teamBaseInfo'
-import resetSound from '@/views/resetTeaming/components/resetSound'
+import resetSound from '@/views/resetTeaming/components/resetSoundv2'
 import resetClass from '@/views/teamDetail/components/resetClass'
 // import coursePlan from '@/views/teamBuild/teamSeting/components/coursePlan'
 // import lookCourse from '@/views/teamBuild/teamSeting/components/lookCourse'
 // import improvement from '@/views/teamBuild/teamSeting/components/improvementClass'
 import resetPayList from '@/views/resetTeaming/components/resetPayList'
+import resetPayListSchool from '@/views/resetTeaming/components/resetPayListSchool'
 import studentPayBase from '@/views/resetTeaming/components/studentPayBase'
 import { permission } from '@/utils/directivePage'
 export default {
-  components: { teamBaseInfo, resetSound, resetClass, resetPayList, studentPayBase },
+  components: { teamBaseInfo, resetSound, resetClass, resetPayList, resetPayListSchool, studentPayBase },
   name: 'resetTeaming',
   data () {
     return {
       activeIndex: '1',
       teamid: '',
+      baseInfo: null,
       // permissionStatus: {
       //   teamBaseInfo: true,
       //   resetSound: true,
@@ -78,7 +95,8 @@ export default {
       // }
       Fsearch: null,
       Frules: null,
-      name: null
+      name: null,
+      teamName:'乐团修改'
     }
   },
   created () {
@@ -114,6 +132,10 @@ export default {
     onCancel () {
       this.$router.push({ path: '/business/teamDetail', query: { search: this.Fsearch, rules: this.Frules } })
     },
+    getBaseInfo(baseInfo) {
+      this.baseInfo = baseInfo
+      this.teamName = baseInfo.musicGroup.name
+    },
     handleClick (val) {
       this.activeIndex = val.name
     },
@@ -127,4 +149,4 @@ export default {
 }
 </script>
 <style lang="scss" scoped>
-</style>
+</style>

+ 50 - 0
src/views/resetTeaming/modals/classrooms.vue

@@ -0,0 +1,50 @@
+<template>
+  <div>
+    <el-table
+      :data="list"
+      style="width: 100%">
+      <el-table-column
+        prop="date"
+        label="班级名称">
+      </el-table-column>
+      <el-table-column
+        prop="date"
+        label="班级类型"
+        width="180">
+      </el-table-column>
+      <el-table-column
+        prop="date"
+        label="班级人数"
+        width="180">
+      </el-table-column>
+    </el-table>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="$listeners.close">取 消</el-button>
+      <el-button
+        type="primary"
+        @click="submit"
+      >确 定</el-button>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      list: []
+    }
+  },
+  methods: {
+    submit() {
+
+    }
+  },
+}
+</script>
+<style lang="less" scoped>
+  .dialog-footer{
+    margin-top: 20px;
+    display: block;
+    text-align: right;
+  }
+</style>

+ 203 - 0
src/views/resetTeaming/modals/extra-class.vue

@@ -0,0 +1,203 @@
+<template>
+  <el-form
+    ref="form"
+    :model="list"
+  >
+    <el-table
+      :data="form"
+      style="width: 100%;text-alogn: center;"
+    >
+      <el-table-column
+        label="课程类型"
+        prop="courseType"
+        key="courseType"
+        width="150">
+        <template slot-scope="scope">
+          <el-form-item
+            :prop="'form.' + scope.$index + '.courseType'"
+            :rules="{ required: true, message: '请选择课程类型', trigger: 'change' }"
+          >
+            <el-select
+              style="width: 90%!important;"
+              size="small"
+              v-model="list.form[scope.$index].courseType"
+              placeholder="课程类型"
+              clearable
+              @change="$listeners.priceChange(scope.row, scope.$index)"
+              :disabled="isDisabled"
+            >
+              <el-option
+                v-for="(item, index) in courseTypeOptions"
+                :key="index"
+                :disabled="isOptionDisabled(item.value)"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="是否可选"
+        v-if="isCommon"
+        prop="isStudentOptional"
+        key="isStudentOptional"
+        width="150">
+        <template slot-scope="scope">
+          <el-form-item
+            :prop="'form.' + scope.$index + '.isStudentOptional'"
+            :rules="{ required: true, message: '请选择是否可选', trigger: 'change' }"
+          >
+            <el-select
+              style="width: 90%!important;"
+              size="small"
+              v-model="list.form[scope.$index].isStudentOptional"
+              placeholder="是否可选"
+              :disabled="isDisabled"
+              clearable
+            >
+              <el-option
+                v-for="(item, index) in boolOptionsOptions"
+                :key="index"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="课程时长(分钟)"
+        prop="courseTotalMinuties"
+        key="courseTotalMinuties"
+        width="150">
+        <template slot-scope="scope">
+          <el-form-item
+            :prop="'form.' + scope.$index + '.courseTotalMinuties'"
+            :rules="{ required: true, message: '请输入课程时长', trigger: 'blur' }"
+          >
+            <el-input-number
+              size="small"
+              style="width: 90%!important;"
+              class="number-input"
+              v-model="list.form[scope.$index].courseTotalMinuties"
+              :controls="false"
+              :precision="0"
+              @change="$listeners.priceChange(scope.row, scope.$index)"
+              :min="1"
+              :disabled="isDisabled"
+              placeholder="课程时长"
+            />
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="现价(元)"
+        prop="courseCurrentPrice"
+        key="courseCurrentPrice"
+        width="150">
+        <template slot-scope="scope">
+          <el-form-item
+            :prop="'form.' + scope.$index + '.courseCurrentPrice'"
+            :rules="{ required: true, message: '请输入现价', trigger: 'blur' }"
+          >
+            <!-- $listeners.moneyChange -->
+            <el-input-number
+              size="small"
+              style="width: 90%!important;"
+              class="number-input"
+              v-model="list.form[scope.$index].courseCurrentPrice"
+              :controls="false"
+              :precision="0"
+              :min="1"
+              @change="change"
+              :disabled="!isUserType"
+              placeholder="请输入现价"
+            />
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="courseOriginalPrice"
+        key="courseOriginalPrice"
+        label="原价(元)">
+        <template slot-scope="scope">
+          <el-form-item
+            :prop="'form.' + scope.$index + '.courseOriginalPrice'"
+            :rules="{ required: true, message: '请输入原价', trigger: 'blur' }"
+          >
+            <el-input-number
+              size="small"
+              style="width: 90%!important;"
+              class="number-input"
+              :disabled="isDisabled"
+              v-model="list.form[scope.$index].courseOriginalPrice"
+              :controls="false"
+              :precision="0"
+              :min="1"
+              placeholder="请输入原价"
+            />
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        v-if="!isCommon"
+        prop="close"
+        key="close"
+        width="60">
+        <template slot-scope="scope">
+          <i v-if="form.length > 1" @click="$listeners.remove(scope.$index)" class="el-icon-circle-close"></i>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-button
+      icon="el-icon-circle-plus-outline"
+      plain
+      v-if="!isCommon"
+      type="info"
+      size="small"
+      style="width: 100%;margin: 20px 0;"
+      @click="$listeners.create"
+    >新增课程类型</el-button>
+  </el-form>
+</template>
+<script>
+import { courseType, boolOptions } from '@/constant'
+import { objectToOptions } from '@/utils'
+import numeral from 'numeral'
+export default {
+  props: ['form', 'isCommon', 'isDisabled', 'isUserType'],
+  data() {
+    return {
+      courseTypeOptions: objectToOptions(courseType),
+      boolOptionsOptions: objectToOptions(boolOptions),
+    }
+  },
+  computed: {
+    list() {
+      return {
+        form: this.form
+      }
+    }
+  },
+  methods: {
+    change(val) {
+      this.$listeners.moneyChange()
+    },
+    isOptionDisabled(key) {
+      const selected = this.form.map(item => item.courseType)
+      return selected.includes(key)
+    },
+    getOldMoney(index) {
+      return numeral(this.list.form[index].courseTotalMinuties * this.list.form[index].unitPrice).format('0,0.00')
+    },
+  },
+}
+</script>
+<style lang="less" scoped>
+.number-input{
+  /deep/ .el-input__inner {
+    text-align: left;
+  }
+}
+</style>

+ 40 - 0
src/views/resetTeaming/modals/other.vue

@@ -0,0 +1,40 @@
+<template>
+  <el-form
+    label-width="160px"
+    :model="form"
+    ref="form"
+    label-suffix=": "
+  >
+    <el-form-item
+      label="是否赠送乐团网管课"
+      prop="isGiveMusicNetwork"
+      :rules="[{required: true, message: '请选择是否赠送乐团网管课', trigger: 'change'}]"
+    >
+      <el-radio-group style="width: 100%" v-model="form.isGiveMusicNetwork">
+        <el-radio :label="true">是</el-radio>
+        <el-radio :label="false">否</el-radio>
+      </el-radio-group>
+    </el-form-item>
+    <el-form-item
+      label="备注"
+      prop="memo"
+      :rules="[{required: true, message: '请输入备注', trigger: 'blur'}]"
+    >
+      <el-input type="textarea" v-model="form.memo"></el-input>
+    </el-form-item>
+  </el-form>
+</template>
+<script>
+export default {
+  props: ['form'],
+}
+</script>
+<style lang="less" scoped>
+.number-input{
+  /deep/ .el-input__inner {
+    text-align: left;
+  }
+
+  width: 100%;
+}
+</style>

+ 89 - 0
src/views/resetTeaming/modals/payment-cycle.vue

@@ -0,0 +1,89 @@
+<template>
+  <el-form
+    label-width="160px"
+    ref="form"
+    :class="className"
+    :model="form"
+    label-suffix=": "
+  >
+    <el-form-item
+      label="缴费金额(元)"
+      prop="paymentAmount"
+      :rules="[{required: true, message: '请输入缴费金额', trigger: 'blur'}]"
+    >
+      <el-input-number
+        class="number-input"
+        v-model="form.paymentAmount"
+        :controls="false"
+        :precision="2"
+        :min="1"
+        :disabled="isUserType && isCommon"
+        placeholder="请输入缴费金额"
+      />
+    </el-form-item>
+    <el-form-item
+      label="缴费方式"
+      prop="paymentPattern"
+      :rules="[{required: true, message: '请选择缴费方式', trigger: 'change'}]"
+    >
+      <el-select style="width: 100%!important;" v-model="form.paymentPattern" placeholder="请选择缴费方式">
+        <el-option
+          v-for="item in paymentPatternTypeOptions"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+        </el-option> 
+      </el-select>
+    </el-form-item>
+    <el-form-item
+      label="缴费时间"
+      prop="paymentDate"
+      v-if="isUserType"
+      :rules="[{required: true, message: '请选择缴费时间', trigger: 'blur'}]"
+    >
+      <el-date-picker
+        v-model="form.paymentDate"
+        type="daterange"
+        style="width: 100%;"
+        range-separator="至"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期">
+      </el-date-picker>
+    </el-form-item>
+    <el-form-item
+      label="缴费有效期"
+      prop="paymentValid"
+      :rules="[{required: true, message: '请选择缴费有效期', trigger: 'blur'}]"
+    >
+      <el-date-picker
+        v-model="form.paymentValid"
+        type="daterange"
+        style="width: 100%;"
+        range-separator="至"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期">
+      </el-date-picker>
+    </el-form-item>
+  </el-form>
+</template>
+<script>
+import { paymentPatternType } from '@/constant'
+import { objectToOptions } from '@/utils'
+export default {
+  props: ['form', 'className', 'isUserType', 'isDisabled', 'isCommon'],
+  data() {
+    return {
+      paymentPatternTypeOptions: objectToOptions(paymentPatternType),
+    }
+  },
+}
+</script>
+<style lang="less" scoped>
+.number-input{
+  /deep/ .el-input__inner {
+    text-align: left;
+  }
+
+  width: 100%;
+}
+</style>

+ 149 - 0
src/views/resetTeaming/modals/review-detail.vue

@@ -0,0 +1,149 @@
+<template>
+  <div>
+    <el-alert title="申请信息" :closable="false" class="alert" type="info">
+    </el-alert>
+    <descriptions :column="2">
+      <descriptions-item label="分部名称:">{{
+        auditDto.organName
+      }}</descriptions-item>
+      <descriptions-item label="乐团名称:">{{
+        auditDto.musicGroupName
+      }}</descriptions-item>
+      <descriptions-item label="乐团编号:">{{
+        auditDto.musicGroupId
+      }}</descriptions-item>
+      <descriptions-item label="申请时间:">{{
+        auditDto.createTime
+      }}</descriptions-item>
+      <descriptions-item label="申请类型:">{{
+        auditDto.paymentType | userPaymentTypeFormat
+      }}</descriptions-item>
+      <descriptions-item label="订单类型:">{{
+        auditDto.payUserType | payUserTypeFormat
+      }}</descriptions-item>
+      <descriptions-item label="学员数量:">{{ studentNum }}</descriptions-item>
+    </descriptions>
+    <el-alert title="课程信息" :closable="false" class="alert" type="info">
+    </el-alert>
+    <descriptions :column="3">
+      <descriptions-item label="收费标准:">{{
+        musicGroupPaymentCalenderCourseSettingName
+      }}</descriptions-item>
+    </descriptions>
+    <el-table
+      :data="musicGroupPaymentCalenderCourseSettings"
+      stripe
+      style="width: 100%; margin-top: 10px"
+    >
+      <el-table-column prop="courseType" label="课程类型" width="120">
+        <template slot-scope="scope">
+          {{ scope.row.courseType | courseTypeFormat }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="isStudentOptional" label="是否免费" width="100">
+      </el-table-column>
+      <el-table-column prop="courseTotalMinuties" label="课程总时长(分钟)">
+      </el-table-column>
+      <el-table-column prop="courseCurrentPrice" label="现价(元)">
+      </el-table-column>
+      <el-table-column prop="courseOriginalPrice" label="原价(元)">
+      </el-table-column>
+    </el-table>
+    <el-alert title="缴费周期" :closable="false" class="alert" type="info">
+    </el-alert>
+    <descriptions :column="2">
+      <descriptions-item label="缴费金额:">{{
+        auditDto.paymentAmount|moneyFormat
+      }}</descriptions-item>
+      <descriptions-item label="缴费方式:">{{
+        auditDto.paymentPattern | paymentPatternTypeFormat
+      }}</descriptions-item>
+      <descriptions-item
+        v-if="auditDto.payUserType !== 'SCHOOL'"
+        label="缴费日期:"
+        >{{ auditDto.startPaymentDate|dayjsFormat }} -
+        {{ auditDto.deadlinePaymentDate|dayjsFormat }}</descriptions-item
+      >
+      <descriptions-item label="缴费有效期:"
+        >{{ auditDto.paymentValidStartDate }} -
+        {{ auditDto.paymentValidEndDate }}</descriptions-item
+      >
+    </descriptions>
+    <el-alert title="其他" :closable="false" class="alert" type="info">
+    </el-alert>
+    <descriptions :column="2">
+      <descriptions-item label="是否赠送乐团网管课:">{{
+        auditDto.isGiveMusicNetwork ? "是" : "否"
+      }}</descriptions-item>
+      <descriptions-item label="备注:">{{ auditDto.memo }}</descriptions-item>
+    </descriptions>
+  </div>
+</template>
+<script>
+import Vue from "vue";
+import { musicGroupPaymentCalenderView } from "../api";
+import descriptions from "@/components/Descriptions";
+Vue.use(descriptions);
+const initData = {
+  auditDto: {},
+  musicGroupPaymentCalenderCourseSettings: [],
+  simpleUserDto: [],
+  studentNum: 0,
+};
+export default {
+  props: ["detail"],
+  data() {
+    return {
+      ...initData,
+    };
+  },
+  computed: {
+    musicGroupPaymentCalenderCourseSettingName() {
+      const active = this.musicGroupPaymentCalenderCourseSettings[0];
+      if (active) {
+        return active.name;
+      }
+      return "";
+    },
+  },
+  mounted() {
+    this.init();
+  },
+  activated() {
+    this.init();
+  },
+  methods: {
+    async init() {
+        try {
+          const res = await musicGroupPaymentCalenderView({
+            calenderId: this.detail.id,
+            musicGroupId: this.detail.musicGroupId,
+          });
+          for (const key in initData) {
+            if (initData.hasOwnProperty(key)) {
+              this[key] = res.data[key];
+            }
+          }
+        } catch (error) {}
+    },
+  }
+};
+</script>
+<style lang="less" scoped>
+.alert {
+  margin: 10px 0;
+}
+// /deep/ .description-view{
+//   border: none;
+//     .description-tr{
+//       border-bottom: none;
+//     }
+//     .description-label{
+//       border-right: none;
+//       background-color: transparent;
+//     }
+//     .description-content{
+//       border-right: none;
+//     }
+// }
+</style>

+ 68 - 0
src/views/resetTeaming/modals/review.vue

@@ -0,0 +1,68 @@
+<template>
+  <div>
+    <reviewDetail v-if="detail && detail.id" :detail="detail" />
+    <el-alert title="审核意见" :closable="false" class="alert" type="info" v-if="detail.status=='AUDITING'">
+    </el-alert>
+    <el-input  v-if="detail.status=='AUDITING'"
+      type="textarea"
+      :autosize="{ minRows: 2, maxRows: 4 }"
+      placeholder="请输入审核意见"
+      v-model="remark"
+    >
+    </el-input>
+    <div slot="footer" class="dialog-footer" v-if="detail.status=='AUDITING'">
+      <!-- <el-button @click="$listeners.close">取 消</el-button> -->
+      <el-button type="primary" @click="submit(1)" v-if="permission('musicGroupPaymentCalender/auditPass')">审核通过</el-button>
+      <el-button type="danger" @click="submit(0)"   v-if="permission('musicGroupPaymentCalender/auditRefuse')">驳回</el-button>
+    </div>
+  </div>
+</template>
+<script>
+import { permission } from '@/utils/directivePage'
+import Vue from "vue";
+import reviewDetail from "./review-detail";
+import { auditPass, auditRefuse } from "@/api/auditManager";
+export default {
+  props: ["detail"],
+  components: {
+    reviewDetail,
+  },
+  data() {
+    return {
+      remark: "",
+    };
+  },
+  methods: {
+    async submit(val) {
+      if (!this.remark) {
+        return this.$message.error("请输入审核意见");
+      }
+      if (val) {
+        auditPass({calenderId:this.detail.id,auditMemo:this.remark}).then((res) => {
+          if(res.code == 200){
+            this.$message.success('审核通过')
+            this.$emit('close')
+          }
+        });
+      } else {
+           auditRefuse({calenderId:this.detail.id,auditMemo:this.remark}).then((res) => {
+          if(res.code == 200){
+            this.$message.success('驳回成功')
+             this.$emit('close')
+          }
+        });
+      }
+    },
+    permission(str){
+      return permission(str)
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+.dialog-footer {
+  margin-top: 20px;
+  display: block;
+  text-align: right;
+}
+</style>

+ 11 - 0
src/views/resetTeaming/modals/school-pay-form.vue

@@ -0,0 +1,11 @@
+<template>
+  <div></div>
+</template>
+<script>
+export default {
+
+}
+</script>
+<style lang="less" scoped>
+
+</style>

+ 535 - 0
src/views/resetTeaming/modals/subject-preview.vue

@@ -0,0 +1,535 @@
+<template>
+    <div>
+        <div class="noticeInfo">
+			<h2>缴费说明</h2>
+			1、为确保声部平衡,请家长确认 注册声部为孩子的最终录取声部。<br />
+			2、为保障每个声部人数达标,我们都进行了超员20%的录取,系统将按照提交注册的先后顺序安排名额。超员后 有可能出现无法注册的情况,请您理解。如果其他声部仍有名额,我们将优先调配您的孩子;
+			<div class="line_bottom" style="margin: .2rem 0 0;"></div>
+		</div>
+
+		<div class="section">
+			<h2 class="title">乐团课程</h2>
+			<div class="options">
+				<div class="option" :class="[!item.isStudentOptional ? 'disabled' : '']" v-for="(item, index) in courseInfo" :key="index" @click="onCourseChange(item)">
+					<div class="o_hd"><i class="check_default" :class="[item.isStatus ? 'check_active' : '']"></i></div>
+					<div class="o_bd">{{ item.courseType | coursesType }}</div>
+					<span class="o_ft" style="color: #1a1a1a;">
+						原价:<del style=" font-size: .16rem; color: #1a1a1a">¥{{ item.courseOriginalPrice | moneyFormat }}</del>
+					</span>
+				</div>
+			</div>
+			<div class="options sale lines">
+				<div class="option">
+					<div class="o_bd"></div>
+					<span class="o_ft">
+						现价 ¥<span style="font-size: .2rem">{{ orderInfo.musicClassFee | moneyFormat }}</span>
+					</span>
+				</div>
+			</div>
+		</div>
+
+		<div class="section" v-if="instrumentResult.length > 0">
+			<h2 class="title">乐器</h2>
+			<div class="options">
+				<div v-for="(con, index) in instrumentResult" :key="index" @click="instrumentF(con)" :class="[ instrumentResult.length > 1 ? 'oc' : '' ]">
+					<div class="option">
+						<div class="o_hd"><i class="check_default" :class="[ con.checked ? 'check_active' : '' ]"></i></div>
+						<div class="o_bd">
+							{{ con.name }}
+						</div>
+						<span class="o_ft o_ft_price" v-if="con.price && con.kitType == 'FREE'">
+							原价<del>:¥{{ con.marketPrice | moneyFormat }}</del>
+						</span>
+						<span class="o_ft o_ft_price" v-if="con.price && con.kitType == 'GROUP'">
+							原价<del>:¥{{ con.marketPrice | moneyFormat }}</del>
+						</span>
+					</div>
+					<div class="configuration" v-if="con.marketPrice">
+						<div class="config config_line">
+							<div class="title"><span>配置</span></div>
+							<div class="content">
+								<p>{{ con.goodsList[0].specification }}</p>
+							</div>
+						</div>
+					</div>
+					<div class="options sale" style="margin-bottom: .05rem;" v-if="con.marketPrice">
+						<div class="option">
+							<div class="o_bd"></div>
+							<template v-if="(con.kitType == 'LEASE')">
+								<span class="o_ft">
+									押金:¥<span style="font-size: .2rem">{{ Number((con.depositFee  - con.coupon).toFixed(2)) | moneyFormat }}</span>
+								</span>
+							</template>
+							<template v-if="con.price && con.kitType == 'FREE'">
+								<span class="o_ft">
+									免费领用
+								</span>
+							</template>
+							<span class="o_ft" v-if="con.price && con.kitType == 'GROUP'">
+								现价:¥<span style="font-size: .2rem">{{ Number((con.price  - con.coupon).toFixed(2)) | moneyFormat }}</span>
+							</span>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+
+		<div class="section" v-if="accessOries.length > 0" key="accessOries">
+			<h2 class="title">辅件</h2>
+			<div class="options" v-for="(instr, index) in accessOries" :key="index" @click="onAuxiliarie(instr)">
+				<div class="option">
+					<div class="o_hd"><i class="check_default" :class="[ instr.checked ? 'check_active' : '' ]"></i></div>
+					<div class="o_bd">{{ instr.name }}</div>
+					<span class="o_ft" style="font-size: .14rem;">
+						<!-- <del>原价:¥{{ instr.marketPrice }}</del> -->
+						<template v-if="instr.price == 0">免费</template>
+						<template v-else>现价:¥{{ instr.price | moneyFormat }}</template>
+						<!-- {{ instr.price == 0 ? '免费' : '现价:¥' + instr.price | moneyFormat }} -->
+					</span>
+				</div>
+				<div class="configuration" v-if="instr.goodsList.length > 1">
+					<div class="config config_other">
+						<div class="title"><span>配置</span></div>
+						<div class="content" v-for="item in instr.goodsList" :key="item.id">
+							<div class="option" style="padding: 0 .05rem;">
+								<div class="o_bd" style="font-size: .14rem">{{ item.name }}</div>
+								<!-- <span class="o_ft">¥{{ item.marketPrice }}</span> -->
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+
+		<!-- 原价现价 -->
+		<div class="section">
+			<div class="needprice markerprice">
+				<del>原价</del>
+				<del>¥{{ orderInfo.marketPrice | moneyFormat }}</del>
+			</div>
+			<div class="needprice grouopprice">
+				<span>仅需支付</span>
+				<span>¥{{ orderInfo.amount | moneyFormat }}</span>
+			</div>
+		</div>
+
+		<div class="buy">
+			<div class="price">
+				<p class="use_price">
+					<img class="logo" src="@/assets/images/mycard.png" alt="">
+					<span>¥{{ needPrice | moneyFormat }}</span>
+				</p>
+			</div>
+			<a class="btn-submit" @click="onCheckSubmit">购买</a>
+		</div>
+    </div>
+</template>
+<script>
+import { permission } from '@/utils/directivePage'
+export default {
+    props: ["subjectId"],
+    data() {
+        return {
+            remark: "",
+        };
+    },
+    methods: {
+
+        permission(str){
+        return permission(str)
+        }
+    },
+};
+</script>
+<style lang="less" scoped>
+.musicGroupPayment {
+		padding-bottom: 0.7rem;
+		min-height: 100vh;
+	}
+
+	.noticeInfo {
+		h2 {
+			font-size: 0.18rem;
+			color: #1a1a1a;
+			padding-bottom: 0.1rem;
+		}
+
+		position: relative;
+		// margin-bottom: .1rem;
+		background: #fff;
+		padding: 0.15rem 0.16rem 0.1rem;
+		font-size: 0.14rem;
+		color: #808080;
+	}
+
+	.protocolbtn {
+		margin: 0.35rem 0;
+		background: #14928a;
+		color: #fff;
+		font-size: 0.18rem;
+		border-radius: 0.5rem;
+		text-align: center;
+		width: 100%;
+	}
+
+	.line_bottom {
+		border-bottom: 1px solid #ededed;
+	}
+
+	.line_top {
+		border-top: 1px solid #ededed;
+	}
+
+	.section {
+		padding: 0.16rem 0.16rem 0.1rem;
+		background: #fff;
+		margin-bottom: 0.1rem;
+
+		>.title {
+			font-size: 0.2rem;
+			line-height: 0.28rem;
+			font-weight: bold;
+			padding-bottom: 0.05rem;
+
+			&::before {
+				content: " ";
+				width: 0.04rem;
+				height: 0.15rem;
+				background: #14928a;
+				display: inline-block;
+				margin-right: 0.07rem;
+				border-radius: 8px;
+			}
+		}
+
+		.indate {
+			font-size: 0.14rem;
+			padding: 0.06rem 0;
+			display: flex;
+			// justify-content: space-between;
+			justify-content: flex-end;
+
+			span {
+				color: #fa101d;
+			}
+		}
+	}
+
+	.options {
+
+		// padding-top: .08rem;
+		.oc {
+			border-bottom: 1px solid #ededed;
+
+			&:last-child {
+				border-bottom: 0;
+				// margin-top: 0.08rem;
+				padding-top: 0.09rem;
+			}
+		}
+
+		.protocol {
+			padding-left: 0.2rem;
+			font-size: 0.1rem;
+			line-height: 0.14rem;
+		}
+
+		&.classInfo {
+			.option .o_ft {
+				color: #1a1a1a;
+			}
+		}
+
+		&.lines {
+			margin-top: 0.05rem;
+			border-top: 1px solid #ededed;
+		}
+
+		&.sale {
+			.option {
+
+				.o_bd,
+				.o_ft {
+					font-size: 0.16rem;
+					color: #f85043;
+					font-weight: bold;
+				}
+			}
+		}
+
+		.option {
+			line-height: 0.26rem;
+			font-size: 0.15rem;
+			display: flex;
+			align-items: center;
+			position: relative;
+			padding: 0.1rem 0.05rem 0.05rem;
+
+			.o_hd {
+				display: flex;
+			}
+
+			.o_bd {
+				color: #1a1a1a;
+				flex: 1;
+				font-size: 0.16rem;
+
+				.c {
+					font-size: 0.12rem;
+				}
+			}
+
+			.o_ft {
+				font-size: 0.16rem;
+				color: #fa101d;
+
+				del {
+					color: #aaaaaa;
+					font-size: 0.12rem;
+				}
+			}
+
+			.o_ft_price,
+			.o_ft_price del {
+				font-size: 0.16rem;
+				color: #1a1a1a;
+			}
+
+			.check_default {
+				margin-right: 0.08rem;
+				display: block;
+				width: 0.18rem;
+				height: 0.18rem;
+				background-color: #e9eaef;
+				border-radius: 50%;
+
+				&.check_active {
+					background: url("../../../assets/images/icon_checkbox.png") no-repeat center;
+					background-size: contain;
+				}
+			}
+		}
+	}
+
+	.configuration {
+		padding-bottom: 0.09rem;
+
+		.config_line {
+			display: flex;
+			justify-content: space-between;
+
+			.content {
+				width: 70%;
+				text-align: right;
+			}
+
+			.title {
+				font-size: 0.14rem;
+				color: #808080;
+
+				span {
+					padding-left: 0.26rem;
+				}
+			}
+		}
+
+		.config_other {
+			.title {
+				// background:rgba(246,246,246,1);
+				// height: 1px;
+				position: relative;
+
+				// margin: .15rem 0;
+				span {
+					// position: absolute;
+					// left: .12rem;
+					// top: -.09rem;
+					font-size: 0.14rem;
+					color: #808080;
+					margin-left: 0.17rem;
+					display: inline-block;
+					background-color: #fff;
+					padding: 0 0.04rem;
+				}
+			}
+		}
+
+		.content {
+			font-size: 0.12rem;
+			padding-left: 0.16rem;
+			line-height: 0.22rem;
+			color: #acacac;
+
+			.o_ft {
+				color: #aaaaaa;
+				font-size: 0.12rem;
+			}
+		}
+
+		.options {
+			padding-top: 0;
+			padding-left: 0.16rem;
+
+			.option {
+				font-size: 0.14rem;
+				color: #6f6f6f;
+			}
+		}
+	}
+
+	.disabled {
+		opacity: 0.7;
+	}
+
+	.buy {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		height: 0.6rem;
+		display: flex;
+		align-items: center;
+		padding: 0 0.2rem;
+		border-top: 1px solid #ffe9e9e9;
+		color: #000000;
+		font-size: 0.12rem;
+		background: #fff;
+
+		.price {
+			flex: 1;
+			font-size: 0.16rem;
+		}
+
+		font-size: 0.16rem;
+
+		span {
+			color: #fa101d;
+		}
+
+		.text {
+			font-size: 0.12rem;
+			width: 0.6rem;
+			display: inline-block;
+			color: #000;
+		}
+
+		del {
+			color: #b5b5b5;
+
+			&.text {
+				color: #b5b5b5;
+			}
+		}
+
+		.btn-submit {
+			display: inline-block;
+			font-size: 0.18rem;
+			color: #fff;
+			background: #f85043;
+			border-radius: 1rem;
+			box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.19);
+			padding: 0.08rem 0.46rem;
+		}
+	}
+
+	.iframe {
+		width: 100%;
+		height: 100%;
+		-webkit-overflow-scrolling: touch;
+		overflow-y: scroll;
+		border-top: none !important;
+		min-height: calc(100vh - 0.41rem);
+	}
+
+	.countDownContent {
+		line-height: 0.4rem;
+		text-align: center;
+		font-size: 0.14rem;
+		border-bottom: 0.01rem solid #ccc;
+
+		.van-count-down {
+			display: inline;
+			color: #f00;
+		}
+	}
+
+	.loadingOrder {
+		width: 90%;
+		height: 1.8rem;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+
+		.van-loading__text {
+			color: #444;
+		}
+	}
+
+	.pay-section {
+		margin-bottom: 0.1rem;
+		padding: 0.1rem 0.08rem;
+	}
+
+	.pay-name {
+		padding-left: 0.1rem;
+		flex: 1 auto;
+		font-weight: bold;
+	}
+
+	.logo {
+		width: 0.24rem;
+		height: 0.24rem;
+	}
+
+	.van-checkbox {
+		float: right;
+
+		/deep/.van-checkbox__icon .van-icon {
+			border-color: #e9eaef;
+			background-color: #e9eaef;
+		}
+
+		/deep/.van-checkbox__icon--checked .van-icon {
+			background-color: #2dc7aa;
+			border-color: #2dc7aa;
+		}
+	}
+
+	.needprice {
+		display: flex;
+		justify-content: space-between;
+		padding: 0.02rem 0;
+
+		del {
+			font-size: 0.14rem;
+			color: #aaa;
+			font-weight: bold;
+		}
+
+		span {
+			font-size: 0.18rem;
+			color: #f85043;
+			font-weight: bold;
+		}
+	}
+
+	.couponprice {
+		display: flex;
+		justify-content: space-between;
+	}
+
+	.use_price {
+		display: flex;
+		align-items: center;
+		font-size: 0.14rem;
+		font-weight: bold;
+
+		img {
+			padding-right: 0.08rem;
+		}
+
+		span {
+			font-size: 0.16rem;
+		}
+	}
+</style>

+ 83 - 0
src/views/resetTeaming/modals/user-baseinfo.vue

@@ -0,0 +1,83 @@
+<template>
+  <el-form
+    label-width="160px"
+    :model="form"
+    ref="form"
+    label-suffix=": "
+  >
+    <el-form-item
+      label="缴费类型"
+      prop="leixing"
+      :rules="[{required: true, message: '请选择缴费类型', trigger: 'change'}]"
+      v-if="typeof paymentType === 'undefined'"
+    >
+      <el-radio-group style="width: 100%" v-model="form.leixing">
+        <el-radio label="1">乐团课程</el-radio>
+        <el-radio label="2">临时加课</el-radio>
+      </el-radio-group>
+    </el-form-item>
+    <!-- <el-form-item
+      label="乐团模式"
+      prop="moshi"
+      v-if="isCommon"
+      :rules="[{required: true, message: '请选择乐团模式', trigger: 'change'}]"
+    >
+      <el-select
+        style="width: 100%!important;"
+        v-model="form.moshi"
+        placeholder="请选择乐团模式"
+        @change="$listeners.getCharges"
+      >
+        <el-option
+          v-for="item in typeList"
+          :key="item.id"
+          :label="item.name"
+          :value="item.id">
+        </el-option>
+      </el-select>
+    </el-form-item> -->
+    <el-form-item
+      label="收费标准"
+      prop="musicGroupOrganizationCourseSettingId"
+      v-if="isCommon"
+      :rules="[{required: true, message: '请选择收费标准', trigger: 'change'}]"
+    >
+      <el-select style="width: 100%!important;" v-model="form.musicGroupOrganizationCourseSettingId" placeholder="请选择收费标准">
+        <el-option
+          v-for="item in charges"
+          :key="item.id"
+          :label="item.name"
+          :value="item.id">
+        </el-option>
+      </el-select>
+    </el-form-item>
+    <el-alert
+      :closable="false"
+      style="margin-left: 160px;width: auto;"
+      v-if="paymentType != 0 && isCommon"
+      type="warning">
+      <template #title>
+        <p>该乐团为3.0模式,若需创建其他模式的收费标准,请先乐团基本信息的乐团模式
+          <strong style="font-weight: 600;margin-left: 10px;cursor: pointer;" @click="$listeners.changeActive({name: '1'})">立即修改>></strong>
+      </p>
+      </template>
+    </el-alert>
+  </el-form>
+</template>
+<script>
+export default {
+  props: ['form', 'isCommon', 'isUserType', 'typeList', 'charges', 'paymentType'],
+  mounted() {
+    console.log(this.form)
+  },
+}
+</script>
+<style lang="less" scoped>
+.number-input{
+  /deep/ .el-input__inner {
+    text-align: left;
+  }
+
+  width: 100%;
+}
+</style>

+ 357 - 0
src/views/resetTeaming/modals/user-pay-form.vue

@@ -0,0 +1,357 @@
+<template>
+  <div>
+    <el-alert title="课程信息设置" :closable="false" class="alert" type="info">
+    </el-alert>
+    <userBaseinfo
+      :form.sync="form"
+      :isCommon="isCommon"
+      :isUserType="isUserType"
+      @getCharges="getCharges"
+      @changeActive="$listeners.changeActive"
+      :typeList="typeList"
+      :charges="charges"
+      :paymentType="paymentType"
+      ref="base"
+    />
+    <template v-if="!isCommon">
+      <el-alert
+        title="加课信息设置"
+        :closable="false"
+        class="alert"
+        type="info"
+      >
+      </el-alert>
+      <extraClass
+        :form.sync="eclass"
+        ref="eclass"
+        :organizationCourseUnitPriceSettings="organizationCourseUnitPriceSettings"
+        @create="addExtraClass"
+        @remove="removeExtraClass"
+        @priceChange="priceChange"
+        @moneyChange="syncAllMoney"
+      />
+    </template>
+    <extraClass
+      v-else-if="(!isCommon && eclass.length) || isCommon"
+      :form="eclass"
+      ref="eclass"
+      :isCommon="isCommon"
+      @create="addExtraClass"
+      @remove="removeExtraClass"
+      @moneyChange="syncAllMoney"
+      :isUserType="isUserType"
+      :isDisabled="form.leixing === '1' || paymentType == '0'"
+    />
+    <template>
+      <el-alert title="缴费设置" :closable="false" class="alert" type="info">
+      </el-alert>
+      <paymentCycle
+        ref="cycle"
+        :isUserType="isUserType"
+        :form.sync="cycle"
+        :isCommon="isCommon"
+        :isDisabled="form.leixing === '1' || paymentType == '0'"
+      />
+    </template>
+    <el-alert title="其它" :closable="false" class="alert" type="info">
+    </el-alert>
+    <otherform :form="other" ref="other" />
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="$listeners.close">取 消</el-button>
+      <el-button type="primary" @click="submit">{{paymentType == '0' ? '确认' : '下一步'}}</el-button>
+    </div>
+    <el-dialog
+      :title="nextTitle"
+      :visible.sync="nextVisible"
+      width="600px"
+      append-to-body
+    >
+      <classrooms @close="closeNext" />
+    </el-dialog>
+  </div>
+</template>
+<script>
+import {
+  chargeTypeList,
+  musicGroupOrganizationCourseSettingsQueryPage,
+} from "@/api/specialSetting";
+import {
+  musicGroupPaymentCalenderAdd,
+  musicGroupPaymentCalenderDetailBatchUpdate,
+} from "../api";
+import { getTimes } from "@/utils";
+import userBaseinfo from "./user-baseinfo";
+import paymentCycle from "./payment-cycle";
+import extraClass from "./extra-class";
+import classrooms from "./classrooms";
+import otherform from "./other";
+import baseInfoVue from '../../teamDetail/components/baseInfo.vue';
+
+const paymentTypeFormat = {
+  0: "MUSIC_APPLY",
+  1: "MUSIC_RENEW",
+  2: "ADD_COURSE",
+  3: "ADD_STUDENT",
+};
+
+export default {
+  props: ["type", "musicGroupId", "baseInfo", "paymentType", "rowDetail", 'organizationCourseUnitPriceSettings'],
+  components: {
+    userBaseinfo,
+    paymentCycle,
+    extraClass,
+    classrooms,
+    otherform,
+  },
+  data() {
+    return {
+      options: [],
+      form: {
+        payUserType: this.type === "user" ? "STUDENT" : "SCHOOL",
+        leixing: "1",
+        musicGroupOrganizationCourseSettingId: null,
+      },
+      other: {},
+      cycles: [{}],
+      cycle: {},
+      eclass: [],
+      collapse: [],
+      nextVisible: false,
+      typeList: [],
+      charges: [],
+    };
+  },
+  computed: {
+    isCommon() {
+      return this.form.leixing === "1";
+    },
+    isDisabled() {
+      return this.form.leixing === "1" || String(this.paymentType) === "0";
+    },
+    isUserType() {
+      return this.type === "user";
+    },
+    nextTitle() {
+      return this.isCommon ? "乐团课程-班级选择" : "临时加课-班级选择";
+    },
+    chargesById() {
+      const data = {};
+      for (const item of this.charges) {
+        data[item.id] = item;
+      }
+      return data;
+    },
+    organizationCourseUnitPriceSettingsByType() {
+      const _ = {}
+      for (const item of this.organizationCourseUnitPriceSettings) {
+        _[item.courseType] = item
+      }
+      return _
+    }
+  },
+  watch: {
+    type() {
+      this.$set(
+        this.form,
+        "payUserType",
+        this.type === "user" ? "STUDENT" : "SCHOOL"
+      );
+    },
+    baseInfo(val) {
+      this.getCharges();
+    },
+    "form.leixing"(val) {
+      this.cycles = [{}];
+      this.collapse = [0];
+      this.cycle = {};
+      this.$set(this.form, "musicGroupOrganizationCourseSettingId", undefined);
+      this.$set(this.cycle, "paymentAmount", undefined);
+      if (val === "1") {
+        this.eclass = [];
+      } else if (val === "2") {
+        this.eclass = [{}];
+      }
+    },
+    "form.musicGroupOrganizationCourseSettingId"(val) {
+      this.getCharges();
+    },
+  },
+  mounted() {
+    this.init();
+  },
+  activated() {
+    this.init();
+  },
+  methods: {
+    init() {
+      this.getCharges();
+      if (this.rowDetail) {
+        this.form.musicGroupOrganizationCourseSettingId = this.rowDetail.musicGroupOrganizationCourseSettingId;
+        this.$set(
+          this.other,
+          "isGiveMusicNetwork",
+          this.rowDetail.isGiveMusicNetwork
+        );
+        this.$set(this.other, "memo", this.rowDetail.memo);
+      }
+    },
+    priceChange(item, index) {
+      const _ = [...this.eclass]
+      const active = this.organizationCourseUnitPriceSettingsByType[item.courseType] || {}
+      const price = Math.ceil((item.courseTotalMinuties || 1) * (active.unitPrice || 1))
+      item.courseCurrentPrice = price
+      item.courseOriginalPrice = price
+      _[index] = item
+      this.eclass = [..._]
+    },
+    syncAllMoney() {
+      let money = 0;
+      for (const item of this.eclass) {
+        money += item.courseCurrentPrice;
+      }
+      if (!money) {
+        this.$set(this.cycle, "paymentAmount", undefined);
+      } else {
+        this.$set(this.cycle, "paymentAmount", money);
+      }
+      if(this.rowDetail){
+          this.$set(
+        this.cycle,
+        "paymentPattern",
+        this.rowDetail?.paymentPattern + ""
+      );
+      let arr = [
+        this.rowDetail?.paymentValidStartDate,
+        this.rowDetail?.paymentValidEndDate,
+      ];
+      // paymentDate startPaymentDate deadlinePaymentDate
+      this.$set(this.cycle, "paymentDate", [ this.rowDetail?.startPaymentDate, this.rowDetail?.deadlinePaymentDate]);
+      this.$set(this.cycle, "paymentValid", arr);
+      }
+
+      return money;
+    },
+    async getChargeTypeList() {
+      try {
+        const res = await chargeTypeList({
+          row: 9999,
+        });
+        this.typeList = res.data.rows;
+      } catch (error) {}
+    },
+    async getCharges() {
+      const chargeTypeId = this.baseInfo?.musicGroup?.chargeTypeId;
+      try {
+        const res = await musicGroupOrganizationCourseSettingsQueryPage({
+          row: 9999,
+          chargeTypeId,
+        });
+        this.charges = res.data.rows;
+        const eclas = this.chargesById[
+          this.form.musicGroupOrganizationCourseSettingId
+        ];
+        this.eclass = eclas?.details || [{}];
+
+        this.syncAllMoney();
+      } catch (error) {}
+    },
+    addExtraClass() {
+      this.eclass.push({});
+    },
+    removeExtraClass(index) {
+      this.eclass[index] = null;
+      this.eclass = this.eclass.filter((item) => !!item);
+    },
+    addCycle() {
+      this.cycles.push({});
+      this.collapse.push(this.collapse.length);
+    },
+    removeCycle(index) {
+      this.cycles[index] = null;
+      this.cycles = this.cycles.filter((item) => !!item);
+      this.collapse.pop();
+    },
+    collapseChange(val) {
+      this.collapse = val;
+    },
+    closeNext() {
+      this.nextVisible = false;
+    },
+    getForms() {
+      const { $refs: refs } = this;
+      return [refs.base, refs.eclass, refs.cycle, refs.other]
+        .filter((item) => !!item)
+        .map((item) => item.$refs.form);
+    },
+    async submit() {
+      const forms = this.getForms();
+      const valided = [];
+      for (const form of forms) {
+        form.validate((valid) => {
+          if (valid) {
+            valided.push(form);
+          }
+        });
+      }
+      if (valided.length === forms.length) {
+        const { paymentDate, paymentValid, leixing, ...rest } = {
+          ...this.form,
+          ...this.other,
+          ...this.cycle,
+          musicGroupPaymentCalenderCourseSettingsList: this.eclass,
+        };
+        const data = {
+          ...rest,
+          paymentType:
+            paymentTypeFormat[
+              this.paymentType == 0 ? this.paymentType : leixing
+            ],
+          musicGroupId: this.musicGroupId,
+          ...getTimes(paymentDate, ["startPaymentDate", "deadlinePaymentDate"]),
+          ...getTimes(paymentValid, [
+            "paymentValidStartDate",
+            "paymentValidEndDate",
+          ]),
+        };
+        if (!this.rowDetail?.id) {
+          try {
+            const res = await musicGroupPaymentCalenderAdd(data);
+            this.$listeners.close();
+            this.$listeners.submited(res.data);
+          } catch (error) {}
+        } else {
+           try {
+            data.id = this.rowDetail.id
+            const res = await musicGroupPaymentCalenderDetailBatchUpdate(data);
+            this.$listeners.close();
+            this.$listeners.submited(res.data);
+          } catch (error) {}
+        }
+      }
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.dialog-footer {
+  margin-top: 20px;
+  display: block;
+  text-align: right;
+}
+.alert {
+  margin-bottom: 10px;
+}
+.collapse-title {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+  .el-icon-circle-close {
+    font-size: 16px;
+    margin-right: 10px;
+  }
+}
+/deep/ .el-collapse-item__wrap {
+  padding-top: 20px;
+}
+</style>

+ 54 - 0
src/views/teamBuild/components/soundSetComponents/chioseAccessory.vue

@@ -0,0 +1,54 @@
+<template>
+  <div class="chioseAccessory">
+    <div class="coreItemRow">
+      <p class="title">教辅组合1:</p>
+      <el-select style="width:558px!important;"
+                 v-model="goods">
+        <el-option label="1"
+                   value="1"></el-option>
+      </el-select>
+      <p class="title">教辅名称:</p>
+      <el-input style="width:140px"></el-input>
+      <p class="title">教辅打包价:</p>
+      <el-input style="width:140px"><template slot="append">元</template></el-input>
+    </div>
+    <div class="coreItemRow">
+      <p class="title"></p>
+      <el-button type="info"
+                 plain
+                 style="width:558px"
+                 size="mini"
+                 icon="el-icon-plus">新增可选乐器</el-button>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  data () {
+    return {
+      goods: ''
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.coreItemRow {
+  padding-left: 20px;
+  height: 50px;
+  line-height: 50px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  p {
+    margin-right: 10px;
+  }
+  .title {
+    width: 100px;
+    text-align: right;
+  }
+}
+
+.marginLeft10 {
+  margin-left: 10px;
+}
+</style>

+ 140 - 0
src/views/teamBuild/components/soundSetComponents/chioseMusic.vue

@@ -0,0 +1,140 @@
+<template>
+  <div>
+    <div v-for="(music,index) in item.chioseMusic" :key="index">
+
+      <el-row class="chioseMusic">
+      <el-col>
+        <div class="flexRow">
+          <p class="title">可选乐器{{index+1}}:</p>
+          <el-select style="width:180px"
+          :disabled='basdisabled'
+                     v-model="music.musical"
+                     @change="(val)=>{chioseMusic(val,music)}">
+            <el-option v-for="(item,index) in item.goodsList"
+                       :key="index"
+                       :label="item.name"
+                       :value="item.id"></el-option>
+          </el-select>
+          <el-checkbox-group v-model="music.type"
+                             class="marginLeft10">
+            <el-checkbox :disabled='basdisabled' label="GROUP">团购</el-checkbox>
+            <el-checkbox :disabled='basdisabled' label="LEASE">租赁</el-checkbox>
+            <el-checkbox :disabled='basdisabled' label="FREE">免费</el-checkbox>
+          </el-checkbox-group>
+        </div>
+      </el-col>
+      <el-col :xs="24"
+              :sm="24"
+              :md="18"
+              :lg="12">
+        <div class="flexRow">
+          <p class="title">团购价:</p>
+          <el-input type="number"
+                    v-if="music.type&&music.type.length>0?music.type.includes('GROUP'):false"
+                    v-model="music.groupPrice"
+                    disabled
+                    style="width:180px"> <template slot="append">元</template></el-input>
+          <el-input value="--"
+                    v-else
+                    disabled
+                    style="width:180px"> <template slot="append">元</template></el-input>
+          <p class="title">租赁押金:</p>
+          <el-input type="number"
+                    v-if="music.type&&music.type.length>0?music.type.includes('LEASE'):false"
+                    v-model="music.borrowPrice"
+                    :disabled='basdisabled'
+                    style="width:180px"> <template slot="append">元</template></el-input>
+          <el-input value="--"
+                    v-else
+                    disabled
+                    style="width:180px"> <template slot="append">元</template></el-input>
+          <i class="el-icon-close marginLeft10"
+             v-if="item.chioseMusic.length >1"
+             @click="deleteMusic(music)"
+             style="font-size:20px; cursor: pointer;"></i>
+        </div>
+
+      </el-col>
+      </el-row>
+    </div>
+    <div class="coreItemRow">
+      <p class="title"></p>
+      <el-button type="info"
+      v-if="!basdisabled"
+                 plain
+                 style="width:558px"
+                 size="mini"
+                 icon="el-icon-plus"
+                 @click="addMusic">新增可选乐器</el-button>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: ['item','basdisabled'],
+  data () {
+    return {
+      radio: '',
+      goods: ''
+    }
+  },
+  created () {  },
+  mounted () {
+
+  },
+  methods: {
+    chioseMusic (val, music) {
+      this.item.goodsList.map((some, index) => {
+        if (some.id == val) {
+          music.groupPrice = some.groupPurchasePrice         
+        }
+      })
+    },
+    addMusic () {
+      this.item.chioseMusic.push({ musical: '', type: ['GROUP'], groupPrice: null, borrowPrice: 1500 })
+      this.$emit('lookMusic')
+    },
+    deleteMusic (music) {
+
+      this.item.chioseMusic.forEach((element, index) => {
+        if (element.musical == music.musical) {
+          this.item.chioseMusic.splice(index, 1)
+        }
+      });
+    }
+  }
+
+}
+</script>
+<style lang="scss" scoped>
+.chioseMusic {
+  width: 100%;
+}
+.coreItemRow {
+  padding-left: 20px;
+  height: 50px;
+  line-height: 50px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  width: 100%;
+}
+p {
+  margin-right: 10px;
+}
+.title {
+  width: 100px;
+  text-align: right;
+  margin-right: 10px;
+}
+.marginLeft10 {
+  margin-left: 10px;
+}
+.flexRow {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding-left: 20px;
+  margin-top: 10px;
+}
+</style>

+ 102 - 0
src/views/teamBuild/components/soundSetComponents/chioseSoundList.vue

@@ -0,0 +1,102 @@
+<template>
+  <div>
+
+    <div class="soundWrap">
+
+      <el-checkbox-group v-model.trim="activeSoundList">
+        <div class="itemList">
+          <div class="categroy"
+               v-for="(item,index) in soundList"
+               :key="index">
+            <p>{{item.name}}</p>
+            <el-checkbox :label="sound.id"
+                         @change="changeCheck"
+                         :disabled="activeSound.includes(sound.id)"
+                         v-for="(sound,indexs) in item.subjects"
+                         :key="indexs">{{sound.name}}</el-checkbox>
+          </div>
+        </div>
+      </el-checkbox-group>
+
+    </div>
+    <p class="soundSubP">当前选择声部数:{{activeSoundList.length}}</p>
+    <div class="btnWraps">
+      <el-button @click="generates"
+                 type="primary">
+        确定
+      </el-button>
+
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: ['soundList', 'childSoundList', 'activeSound'],
+  data () {
+    return {
+      chioseSoundNum: '',
+      activeSoundList: this.activeSound || [],
+    }
+  },
+  mounted () {
+    console.log(this.soundList)
+  },
+  activated () {
+    console.log(this.soundList)
+  },
+  methods: {
+    generates () {
+      this.$emit('chioseSound', this.activeSoundList)
+    },
+    changeCheck () {
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.soundWrap {
+  width: 100%;
+  overflow: auto;
+  .itemList {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    flex-wrap: nowrap;
+    flex-grow: 1;
+    height: 300px;
+    max-height: 300px;
+    overflow: auto;
+    .categroy {
+      z-index: 100;
+      width: 150px;
+      min-width: 150px;
+      color: #606266;
+      .el-checkbox {
+        height: 30px;
+        line-height: 30px;
+        display: block;
+        padding-left: 20px;
+      }
+      p {
+        height: 40px;
+        line-height: 40px;
+        background-color: #edeef0;
+        margin-bottom: 15px;
+        text-align: center;
+      }
+    }
+  }
+}
+.soundSubP {
+  height: 40px;
+  line-height: 40px;
+  background-color: #edeef0;
+  padding-left: 25px;
+  margin-bottom: 20px;
+}
+.btnWraps {
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-end;
+}
+</style>

+ 549 - 0
src/views/teamBuild/components/soundSetComponents/soundSetCore.vue

@@ -0,0 +1,549 @@
+<template>
+  <div>
+    <div class="soundBtnWrap">
+      <el-button type="primary" @click="allin" v-if="teamStatus != 'resetTeam'&&!basdisabled"
+        >全选</el-button
+      >
+      <el-button
+        type="danger"
+        @click="deleteRow"
+        v-if="teamStatus != 'resetTeam'&&!basdisabled"
+        >删除</el-button
+      >
+      <el-button type="primary" @click="soundVisible = true" v-if="!basdisabled">添加</el-button>
+    </div>
+    <div class="coreWrap">
+      <el-checkbox-group v-model="checkList" @change="lookCheck" >
+        <el-collapse v-model="chioseActiveSound">
+          <el-collapse-item
+            v-for="(item, index) in activeSoundList"
+            :name="item.id"
+            :key="index"
+          >
+            <template slot="title">
+              <div class="coreItemTitle">
+                <el-checkbox :label="item.id" :disabled='basdisabled'>{{ item.sound }}</el-checkbox>
+              </div>
+            </template>
+            <div class="coreItem">
+              <div class="coreItemRow">
+                <p class="title">计划招生人数:</p>
+                <el-input
+                :disabled='basdisabled'
+                  style="width: 180px"
+                  v-model="item.expectedStudentNum"
+                ></el-input>
+              </div>
+            </div>
+            <chioseMusic :item="item" @lookMusic="lookMusic" :basdisabled="basdisabled"/>
+            <div class="coreItemRow">
+              <p class="title">教辅:</p>
+              <el-select
+                style="width: 558px !important"
+                v-model="item.markChioseList"
+                :disabled='basdisabled'
+                clearable
+                filterable
+                multiple
+              >
+                <el-option
+                  v-for="(item, index) in item.markList"
+                  :key="index"
+                  :label="item.name"
+                  :value="item.id"
+                ></el-option>
+              </el-select>
+            </div>
+          </el-collapse-item>
+        </el-collapse>
+      </el-checkbox-group>
+    </div>
+    <el-dialog title="声部选择" :visible.sync="soundVisible" destroy-on-close>
+      <chioseSoundList
+        :soundList="soundList"
+        :activeSound="activeSound"
+        @chioseSound="chioseSound"
+      />
+    </el-dialog>
+  </div>
+</template>
+<script>
+import store from "@/store";
+import { formatData } from "@/utils/utils";
+import {
+  getSubject,
+  getDefaultSubject,
+  getGoods,
+  createTeam,
+  getSoundTree,
+  findMusicGroupSubjectInfo,
+  updateSubjectInfo,
+  auditSuccess,
+  auditFailed,
+  getSubjectGoods,
+} from "@/api/buildTeam";
+import dayjs from "dayjs";
+import chioseSoundList from "./chioseSoundList";
+import chioseMusic from "./chioseMusic";
+import { findIndex } from "lodash";
+export default {
+  components: { chioseSoundList, chioseMusic },
+  data() {
+    return {
+      soundList: [], // 接口返回的一级二级声部
+      soundVisible: false, // 设置声部弹窗
+      childSoundList: [],
+      activeSoundList: [], //列表上的声部
+      activeSound: null, // 展开的列表
+      chioseActiveSound: [],
+      soundList: [], // 接口返回的一级二级声部
+      childSoundList: [],
+      teamStatus: "", // 乐团状态
+      checkList: [],
+      basdisabled:false
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  activated() {
+    this.init();
+  },
+  methods: {
+    init() {
+      // 获取第一页的数据
+      this.topfor = this.$store.getters.topinfo;
+      let type = this.topfor.type;
+      this.teamStatus = this.$route.query.type;
+      if (this.$route.query.search) {
+        this.Fsearch = this.$route.query.search;
+      }
+      if (this.$route.query.rules) {
+        this.Frules = this.$route.query.rules;
+      }
+      if (this.teamStatus == "look" || this.teamStatus == "teamAudit") {
+        this.basdisabled = true;
+      } else {
+        this.basdisabled = false;
+      }
+      getSoundTree({ tenantId: 1 }).then((res) => {
+        if (res.code == 200) {
+          this.soundList = res.data.rows;
+          if (this.teamStatus == "newTeam") {
+            getDefaultSubject({
+              chargeTypeId: type,
+              organId: this.topfor.section,
+              number: 1,
+            }).then((res) => {
+              if (res.code == 200) {
+                let activeSound = [];
+                this.activeSoundList = res.data.map((item) => {
+                  activeSound.push(item.id);
+                  return this.initSound(item);
+                });
+                this.activeSound = activeSound;
+                this.chioseActiveSound = activeSound;
+                this.changeActiveSound(activeSound.join(","));
+              }
+            });
+          } else {
+            this.teamid = this.$route.query.id;
+            findMusicGroupSubjectInfo({ musicGroupId: this.teamid }).then(
+              (res) => {
+                if (res.code == 200) {
+                  let activeSound = [];
+                  this.activeSoundList = res.data?.musicGroupSubjectPlans.map(
+                    (item) => {
+                      activeSound.push(item.subjectId);
+                      return {
+                        id: parseInt(item.subjectId),
+                        sound: item.subName,
+                        expectedStudentNum: item.expectedStudentNum,
+                        chioseMusic: [],
+                        markChioseList: [],
+                        goodsList: [],
+                        markList: [],
+                      };
+                    }
+                  );
+                  this.activeSound = activeSound;
+                  this.chioseActiveSound = activeSound;
+                  this.changeActiveSound(activeSound.join(","));
+                  // 格式化商品和教辅
+
+                  res.data.musicGroupSubjectGoodsGroups.forEach((shop) => {
+                    let index = findIndex(this.activeSoundList, (o) => {
+                      return o.id == shop.subjectId;
+                    });
+
+                    if (index != -1) {
+                      if (shop.type == "ACCESSORIES") {
+                        shop.goodsIdList.split(",").forEach((item) => {
+                          this.activeSoundList[index].markChioseList.push(
+                            parseInt(item)
+                          );
+                        });
+                      } else if (shop.type == "INSTRUMENT") {
+                        // 商品
+                        let typeJson = Object.keys(
+                          JSON.parse(shop.kitGroupPurchaseTypeJson)
+                        );
+                        this.activeSoundList[index].chioseMusic.push({
+                          musical: parseInt(shop.goodsIdList),
+                          type: typeJson,
+                          groupPrice: shop.price,
+                          borrowPrice: shop.depositFee,
+                        });
+                      }
+                    }
+                  });
+                }
+              }
+            );
+          }
+        }
+      });
+      getSubject({ tenantId: 1 }).then((res) => {
+        if (res.code == 200) {
+          this.childSoundList = res.data;
+        }
+      });
+    },
+    lookCheck(val) {
+      this.checkList = [...new Set(val)];
+    },
+    chioseSound(activeSound) {
+      // 同步数据
+      this.activeSound = [...new Set(activeSound)];
+      let newSoundList = [];
+
+      for (let i in this.childSoundList) {
+        if (this.activeSound.includes(this.childSoundList[i].id)) {
+          newSoundList.push(this.initSound(this.childSoundList[i]));
+        }
+      }
+      let idList = this.activeSoundList.map((item) => {
+        return item.id;
+      });
+      for (let x in newSoundList) {
+        const indexof = idList.indexOf(newSoundList[x]?.id);
+        if (indexof > -1) {
+          newSoundList[x] = this.activeSoundList[indexof];
+        }
+      }
+      this.activeSoundList = newSoundList;
+      let newActiveSound = [];
+      this.activeSoundList.forEach((item) => {
+        newActiveSound.push(item.id);
+      });
+      this.activeSound = newActiveSound;
+      this.chioseActiveSound = newActiveSound;
+      console.log(newActiveSound.join(","));
+      this.changeActiveSound(newActiveSound.join(","));
+      this.soundVisible = false;
+    },
+    initSound(item) {
+      let obj = {
+        id: item.id,
+        sound: item.name,
+        expectedStudentNum: item.expectedStudentNum,
+        chioseMusic: [
+          { musical: "", type: ["GROUP"], groupPrice: 0, borrowPrice: 1500 },
+        ],
+        markChioseList: [],
+        goodsList: [],
+        markList: [],
+      };
+      return obj;
+    },
+    changeActiveSound(val) {
+      // 写入声部商品和辅件
+      getSubjectGoods({
+        subjectIds: val,
+        chargeTypeId: this.topfor.type,
+      }).then((res) => {
+        if (res.code == 200) {
+          let keys = Object.keys(res.data);
+          this.activeSoundList.forEach((item) => {
+            if (keys.indexOf(item.id + "") != -1) {
+              let goodList = [];
+              let markList = [];
+              res.data[item.id].forEach((shop) => {
+                if (shop.type == "INSTRUMENT") {
+                  goodList.push(shop);
+                } else if (shop.type == "ACCESSORIES") {
+                  markList.push(shop);
+                }
+              });
+              item.goodsList = goodList;
+              item.markList = markList;
+            }
+          });
+        }
+      });
+    },
+
+    // return
+    // if (item.id == val) {
+    //   if (item.goodsList.length < 1 || item.markList.length < 1) {
+    //     getSubjectGoods({
+    //       subjectIds: item.id,
+    //       chargeTypeId: this.topfor.type,
+    //     }).then((res) => {
+    //       if (res.code == 200) {
+    //         let goodList = [];
+    //         let markList = [];
+    //         res.data.forEach((item) => {
+    //           if (item.type == "INSTRUMENT") {
+    //             goodList.push(item);
+    //           } else if (item.type == "ACCESSORIES") {
+    //             markList.push(item);
+    //           }
+    //         });
+    //         item.goodsList = goodList;
+    //         item.markList = markList;
+    //       }
+    //     });
+    //   }
+    // }
+
+    lookMusic() {},
+
+    submitInfo(type) {
+      // 计划招生人数
+      // 可选乐器
+      // 教辅
+      let flag = true;
+      this.activeSoundList.forEach((item) => {
+        if (!item.expectedStudentNum) {
+          this.$message.error(`请填写${item.sound}的预计招生人数`);
+          flag = false;
+          return;
+        }
+        if (!item.chioseMusic[0]?.musical) {
+          this.$message.error(`请至少一个选择${item.sound}的可选乐器`);
+          flag = false;
+          return;
+        }
+      });
+      if (!flag) return;
+      // 新建团
+      let obj = {};
+      if (this.teamStatus == "newTeam") {
+        this.initCreateTeam(obj);
+      }
+      //  初始化声部
+      obj.musicGroupSubjectGoodsGroups = [];
+      obj.musicGroupSubjectPlans = [];
+      this.activeSoundList.forEach((active) => {
+        // 格式化声部数据
+        let item = {
+          expectedStudentNum: active.expectedStudentNum,
+          subName: active.sound,
+          subjectId: active.id,
+        };
+        obj.musicGroupSubjectPlans.push(item);
+        // 格式化商品数据 chioseMusic: [{ musical: '', type: ["GROUP"], groupPrice: 0, borrowPrice: 1500 }],
+        active.chioseMusic.forEach((music) => {
+          let goodsItem = null;
+          let depositFee = music.borrowPrice;
+          let price = music.groupPrice;
+          let index = findIndex(active.goodsList, (o) => {
+            return o.id == music.musical;
+          });
+          if (index != -1) {
+            goodsItem = active.goodsList[index];
+          }
+          let kitGroupPurchaseTypeJson = {};
+          music.type.forEach((type) => {
+            kitGroupPurchaseTypeJson[type] = 0;
+          });
+          kitGroupPurchaseTypeJson = JSON.stringify(kitGroupPurchaseTypeJson);
+          if (goodsItem) {
+            let some = {
+              subjectId: active.id,
+              type: "INSTRUMENT",
+              goodsIdList: music.musical,
+              name: goodsItem.name,
+              kitGroupPurchaseTypeJson,
+              depositFee,
+              price,
+            };
+            obj.musicGroupSubjectGoodsGroups.push(some);
+          }
+        });
+        // 格式化辅件
+        //  markChioseList: [],
+        // goodsList: [],
+        // markList: [],
+        active.markChioseList.forEach((ass) => {
+          let index = findIndex(active.markList, (o) => {
+            return o.id == ass;
+          });
+          let goodsItem = null;
+          if (index != -1) {
+            goodsItem = active.markList[index];
+          }
+          if (goodsItem) {
+            let some = {
+              subjectId: active.id,
+              type: "ACCESSORIES",
+              goodsIdList: ass,
+              name: goodsItem.name,
+              price: goodsItem.groupPurchasePrice,
+            };
+            obj.musicGroupSubjectGoodsGroups.push(some);
+          }
+        });
+        
+      });
+      if (this.teamStatus == "newTeam") {
+          createTeam(obj).then((res) => {
+            if (res.code == 200) {
+              // 成功 跳转到乐团报名详情
+              let query = this.$route.query;
+              query.type = "teamDraft";
+              this.$router.push({
+                query: {
+                  ...query,
+                  id: res.data,
+                },
+              });
+              this.$emit("chiosetab", 2);
+            }
+          });
+        } else {
+          obj.musicGroupId = this.teamid;
+
+          if (type) {
+            obj.musicGroupStatus = "AUDIT";
+          } else {
+            obj.musicGroupStatus = "DRAFT";
+          }
+
+          updateSubjectInfo(obj).then((res) => {
+            if (res.code == 200) {
+              this.$message.success("提交成功");
+              this.$emit("chiosetab", 2);
+            }
+          });
+        }
+    },
+    deleteRow() {
+      if (this.checkList.length < 1) {
+        this.$message.error("请至少勾选一个");
+        return;
+      }
+      for (let i = 0; i < this.activeSoundList.length; i++) {
+        let index = this.checkList.indexOf(this.activeSoundList[i].id);
+        if (index != -1) {
+          this.activeSoundList.splice(i, 1);
+          this.activeSound.splice(i, 1);
+          i--;
+        }
+      }
+      this.checkList = [];
+    },
+    allin() {
+      this.checkList = [];
+      this.activeSoundList.forEach((item, index) => {
+        this.checkList.push(item.id);
+      });
+    },
+
+    initCreateTeam(obj) {
+      let enrollClasses;
+      this.topfor.startClass
+        ? (enrollClasses = this.topfor.startClass.join(","))
+        : (enrollClasses = null);
+      obj.musicGroup = {
+        settlementType: this.topfor.salary,
+        applyExpireDate: dayjs(this.topfor.time).format("YYYY-MM-DD HH:mm:ss"),
+        chargeTypeId: this.topfor.type,
+        cooperationOrganId: this.topfor.school,
+        teamTeacherId: this.topfor.boss,
+        educationalTeacherId: this.topfor.teacher,
+        enrollClasses,
+        name: this.topfor.name,
+        organId: this.topfor.section,
+        paymentPattern: this.topfor.paymentPattern,
+        paymentValidStartDate: this.topfor.paymentValidStartDate
+          ? dayjs(this.topfor.paymentValidStartDate).format("YYYY-MM-DD")
+          : this.topfor.paymentValidStartDate,
+        paymentValidEndDate: this.topfor.paymentValidEndDate
+          ? dayjs(this.topfor.paymentValidEndDate).format("YYYY-MM-DD")
+          : this.topfor.paymentValidEndDate,
+        // paymentMonths:obj.months  有待确认
+        schoolId: this.topfor.address,
+        expectStartGroupDate: this.topfor.startTime,
+        isClassroomLessons: this.topfor.isClass,
+        status: 'DRAFT',
+        ownershipType: this.topfor.ownershipType,
+        repairUserId: this.topfor.repairUserId,
+        feeType: this.topfor.feeType,
+      };
+      return obj;
+    },
+  },
+  watch: {
+    activeSoundList: {
+      immediate: true,
+      deep: true,
+      handler(n) {
+        let chioseSoundNum = 0;
+        let PlannedCount = 0;
+        let activeSoundList = this.activeSoundList;
+        if (n) {
+          let Count = 0;
+          if (n.length > 0) {
+            for (let item in n) {
+              Count += parseInt(n[item]?.expectedStudentNum) || 0;
+            }
+          }
+
+          chioseSoundNum = Count;
+          PlannedCount = n.length;
+          this.$emit("getNumber", chioseSoundNum, PlannedCount);
+        }
+      },
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.soundBtnWrap {
+  margin-bottom: 20px;
+}
+/deep/.el-collapse-item__header {
+  background-color: #edeef0;
+}
+.coreItemTitle {
+  background-color: #edeef0;
+  height: 46px;
+  line-height: 46px;
+  padding: 0 20px;
+}
+.coreItem {
+  padding: 25px 0 0;
+}
+.coreItemRow {
+  padding: 0 20px;
+  line-height: 50px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  p {
+    margin-right: 10px;
+  }
+  .title {
+    width: 100px;
+    text-align: right;
+  }
+}
+.marginLeft10 {
+  margin-left: 10px;
+}
+/deep/.el-collapse-item__header {
+  border-bottom: 1px solid #fff;
+}
+</style>

+ 50 - 169
src/views/teamBuild/components/teamBaseInfo.vue

@@ -8,33 +8,34 @@
                ref="topinfo"
                label-width="120px"
                style="margin-left: 11px">
-        <el-form-item label="收费类型"
-                      prop="type"
-                      :rules="[{ required: true, message: '收费类型不能为空' }]">
-          <el-select v-model.trim="topFrom.type"
+        <el-form-item label="所属分部"
+                      prop="section"
+                      :rules="[{ required: true, message: '所属分部不能为空' }]">
+          <el-select v-model.trim="topFrom.section"
                      filterable
                      :disabled="basdisabled"
+                     @change="changeSection"
                      clearable>
-            <el-option v-for="(item, index) in typeList"
+            <el-option v-for="(item, index) in sectionList"
                        :key="index"
                        :label="item.name"
                        :value="item.id"></el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="所属分部"
-                      prop="section"
-                      :rules="[{ required: true, message: '所属分部不能为空' }]">
-          <el-select v-model.trim="topFrom.section"
+        <el-form-item label="收费类型"
+                      prop="type"
+                      :rules="[{ required: true, message: '收费类型不能为空' }]">
+          <el-select v-model.trim="topFrom.type"
                      filterable
                      :disabled="basdisabled"
-                     @change="changeSection"
                      clearable>
-            <el-option v-for="(item, index) in sectionList"
+            <el-option v-for="(item, index) in typeList"
                        :key="index"
                        :label="item.name"
                        :value="item.id"></el-option>
           </el-select>
         </el-form-item>
+
         <el-form-item label="合作单位"
                       prop="school"
                       :rules="[{ required: true, message: '合作单位不能为空' }]">
@@ -131,7 +132,7 @@
             }"
                           placeholder="选择日期"></el-date-picker>
         </el-form-item>
-        <el-form-item label="缴费方式"
+        <!-- <el-form-item label="缴费方式"
                       prop="paymentPattern"
                       :rules="[{ required: !isNotEditing(), message: '请选择缴费方式' }]">
           <el-select placeholder="缴费方式"
@@ -175,7 +176,7 @@
                           :picker-options="beginDate(topFrom.paymentValidStartDate)"
                           placeholder="结束日期">
           </el-date-picker>
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item label="招生年级"
                       v-if="basdisabled">
           <el-tooltip class="item"
@@ -214,8 +215,8 @@
                        value="TEACHER_DEFAULT"></el-option>
             <el-option label="3.0课酬"
                        value="GRADIENT_SALARY"></el-option>
-            <!-- <el-option label="课堂课酬"
-            value="CLASSROOM_SALARY"></el-option>-->
+            <el-option label="课堂课酬"
+            value="CLASSROOM_SALARY"></el-option>
           </el-select>
         </el-form-item>
         <el-form-item label="机构类型"
@@ -230,12 +231,12 @@
             value="LEASE"></el-option>-->
           </el-select>
         </el-form-item>
-
+        <!-- v-if="teamStatus == 'resetTeam' || teamStatus == 'teamList'" -->
         <el-form-item label="乐队指导"
-                      v-if="teamStatus == 'resetTeam' || teamStatus == 'teamList'"
                       prop="head">
           <el-select v-model.trim="topFrom.head"
                      filterable
+                     :disabled="basdisabled"
                      clearable>
             <el-option v-for="(item, index) in orgianList"
                        :key="index"
@@ -243,7 +244,7 @@
                        :value="item.id"></el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="乐团网管课"
+        <!-- <el-form-item label="乐团网管课"
                       :rules="[{ required: true, message: '请选择是否排乐团网管课' }]"
                       prop="feeType">
           <el-select v-model="topFrom.feeType"
@@ -255,14 +256,14 @@
             <el-option label="只排线下课"
                        value="OFFLINE"></el-option>
           </el-select>
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item label
                       prop="isClass">
           <el-checkbox v-model.trim="topFrom.isClass"
                        :disabled="basdisabled">课堂课乐团</el-checkbox>
         </el-form-item>
       </el-form>
-      <div class="checkList">
+      <!-- <div class="checkList">
         <div class="head noMargin">乐团课程:</div>
         <div class="checkRow">
           <el-checkbox label="乐团声部训练"
@@ -275,9 +276,6 @@
                       :disabled="basdisabled"
                       v-model.trim="checkList.soundInfo.value" />
           </div>
-          <!-- <div class="inputWrap">
-            <el-checkbox v-model="checkList.soundInfo.checkBuy">是否可选择购买</el-checkbox>
-          </div> -->
         </div>
         <div class="checkRow">
           <el-checkbox label="乐团合奏训练"
@@ -290,9 +288,6 @@
                       :disabled="basdisabled"
                       v-model.trim="checkList.allInfo.value" />
           </div>
-          <!-- <div class="inputWrap">
-            <el-checkbox v-model="checkList.allInfo.checkBuy">是否可选择购买</el-checkbox>
-          </div> -->
         </div>
         <div class="checkRow">
           <el-checkbox label="假期集中训练"
@@ -306,9 +301,6 @@
                       placeholder="请输入"
                       v-model.trim="checkList.holidayInfo.value" />
           </div>
-          <!-- <div class="inputWrap">
-            <el-checkbox v-model="checkList.holidayInfo.checkBuy">是否可选择购买</el-checkbox>
-          </div> -->
         </div>
         <div class="checkRow"
              v-if="checkList.networkInfo">
@@ -323,9 +315,6 @@
                       placeholder="请输入"
                       v-model.trim="checkList.networkInfo.value" />
           </div>
-          <!-- <div class="inputWrap">
-            <el-checkbox v-model="checkList.networkInfo.checkBuy">是否可选择购买</el-checkbox>
-          </div> -->
         </div>
         <div class="checkRow">
           <el-checkbox label="网络基础训练"
@@ -339,9 +328,6 @@
                       placeholder="请输入"
                       v-model.trim="checkList.baseInfo.value" />
           </div>
-          <!-- <div class="inputWrap">
-            <el-checkbox v-model="checkList.baseInfo.checkBuy">是否可选择购买</el-checkbox>
-          </div> -->
         </div>
         <div class="checkRow">
           <el-checkbox label="课程提示"
@@ -380,9 +366,6 @@
                       placeholder="请输入"
                       v-model.trim="newStudentList.baseInfo.value" />
           </div>
-          <!-- <div class="inputWrap">
-            <el-checkbox v-model="newStudentList.baseInfo.checkBuy">是否可选择购买</el-checkbox>
-          </div> -->
         </div>
         <div class="head noMargin">付费方式:</div>
         <div class="checkRow">
@@ -399,33 +382,6 @@
               <el-radio-button label="TERM">一学期</el-radio-button>
               <el-radio-button label="YEAR">一学年</el-radio-button>
             </el-radio-group>
-            <!-- <el-tag :effect="payList.school.chiose == 'ONE_OFF' ? 'dark' : 'plain'"
-                    @click="!basdisabled ? (payList.school.chiose = 'ONE_OFF') : null">一次性</el-tag>
-            <el-tag :effect="payList.school.chiose == 'MONTHLY' ? 'dark' : 'plain'"
-                    @click="!basdisabled ? (payList.school.chiose = 'MONTHLY') : null">一个月</el-tag>
-            <el-tag :effect="payList.school.chiose == 'TERM' ? 'dark' : 'plain'"
-                    @click="!basdisabled ? (payList.school.chiose = 'TERM') : null">一学期</el-tag>
-            <el-tag :effect="payList.school.chiose == 'YEAR' ? 'dark' : 'plain'"
-                    @click="!basdisabled ? (payList.school.chiose = 'YEAR') : null">一学年</el-tag> -->
-            <!-- <div class="chioseItem"
-                 :class="">
-
-            </div> -->
-            <!-- <div class="chioseItem"
-                 :class="payList.school.chiose == 'MONTHLY' ? 'active' : ''"
-                 @click="!basdisabled ? (payList.school.chiose = 'MONTHLY') : null">
-              一个月
-            </div>
-            <div class="chioseItem"
-                 :class="payList.school.chiose == 'TERM' ? 'active' : ''"
-                 @click="!basdisabled ? (payList.school.chiose = 'TERM') : null">
-              一学期
-            </div>
-            <div class="chioseItem"
-                 :class="payList.school.chiose == 'YEAR' ? 'active' : ''"
-                 @click="!basdisabled ? (payList.school.chiose = 'YEAR') : null">
-              一学年
-            </div> -->
           </div>
           <div class="inputWrap">
             <div>
@@ -459,30 +415,6 @@
               <el-radio-button label="TERM">一学期</el-radio-button>
               <el-radio-button label="YEAR">一学年</el-radio-button>
             </el-radio-group>
-            <!-- <div class="chioseItem"
-                 :class="payList.company.chiose == 'ONE_OFF' ? 'active' : ''"
-                 @click="
-                !basdisabled ? (payList.company.chiose = 'ONE_OFF') : null
-              ">
-              一次性
-            </div>
-            <div class="chioseItem"
-                 :class="payList.company.chiose == 'MONTHLY' ? 'active' : ''"
-                 @click="
-                !basdisabled ? (payList.company.chiose = 'MONTHLY') : null
-              ">
-              一个月
-            </div>
-            <div class="chioseItem"
-                 :class="payList.company.chiose == 'TERM' ? 'active' : ''"
-                 @click="!basdisabled ? (payList.company.chiose = 'TERM') : null">
-              一学期
-            </div>
-            <div class="chioseItem"
-                 :class="payList.company.chiose == 'YEAR' ? 'active' : ''"
-                 @click="!basdisabled ? (payList.company.chiose = 'YEAR') : null">
-              一学年
-            </div> -->
           </div>
           <div class="inputWrap">
             <div>
@@ -503,7 +435,7 @@
 
           </div>
         </div>
-      </div>
+      </div> -->
       <div class="btnWrap">
         <div class="nextBtn"
              v-if="teamStatus == 'resetTeam'"
@@ -687,7 +619,6 @@ export default {
   },
   created () { },
   activated () {
-    console.log(dayjs('2014-12-03').format('YYYY-MM-DD HH:mm:ss'))
     this.payList = {
       school: {
         ischeck: false,
@@ -716,8 +647,9 @@ export default {
   },
   beforeDestroy () { },
   methods: {
+    //|| this.teamStatus === 'teamAudit'
     isNotEditing: function () {
-      return !(this.teamStatus === 'teamDraft' || this.teamStatus === 'teamAudit' || this.teamStatus === 'newTeam' || this.teamStatus === 'teamList')
+      return !(this.teamStatus === 'teamDraft' || this.teamStatus === 'newTeam' || this.teamStatus === 'teamList')
     },
     changeFeeType (val) {
       // console.log(val == "ONLINE");
@@ -747,87 +679,36 @@ export default {
       };
     },
     init () {
-      (this.checkList = {
-        soundInfo: {
-          // 声部
-          ischeck: false,
-          value: "",
-          checkBuy: false,
-          isNew: 0,
-          isStatus: false,
-        },
-        allInfo: {
-          // 合奏
-          ischeck: false,
-          value: "",
-          checkBuy: false,
-          isNew: 0,
-          isStatus: false,
-        },
-        baseInfo: {
-          // 基础
-          ischeck: false,
-          value: "",
-          checkBuy: false,
-          isNew: 0,
-          isStatus: false,
-        },
-        holidayInfo: {
-          // 假期
-          ischeck: false,
-          value: "",
-          checkBuy: false,
-          isNew: 0,
-          isStatus: false,
-        },
-        networkInfo: {
-          ischeck: false,
-          value: "",
-          checkBuy: false,
-          isNew: 0,
-          isStatus: false,
-        },
-        submit: {
-          ischeck: false,
-          value:
-            "年度安排个月共xxx课时,课时,原价xxx元,现价xxxx元/月(约 xxxx元/课时 )",
-        },
-      }),
-        (this.newStudentList = {
-          baseInfo: {
-            // 基础
-            ischeck: false,
-            value: "",
-            checkBuy: true,
-            nowValue: "",
-            isNew: 1,
-            isStatus: false,
-          },
-        });
+
       this.isInit = true;
       // 分为3种  this.teamStatus
       //          1.resetTeam 乐团修改
       //          2. newTeam  新建乐团
-      //          3.teamList 跨团修改
+      //          3.teamList  跨团修改
       //          4.teamDraft 乐团草稿
       this.teamStatus = this.$route.query.type;
       // 传过来的乐团信息
       this.activeTeam = this.getTeamList;
-      if (this.teamStatus == "look") {
+      if (this.teamStatus == "look" || this.teamStatus == "teamAudit") {
         this.basdisabled = true;
       } else {
         this.basdisabled = false;
       }
       if (
-        this.teamStatus == "resetTeam" ||
-        this.teamStatus == "teamDraft" ||
-        this.teamStatus == "teamAudit" ||
-        this.teamStatus == "look"
+        // this.teamStatus == "resetTeam" ||
+        // this.teamStatus == "teamDraft" ||
+        // this.teamStatus == "teamAudit" ||
+        // this.teamStatus == "look"
+        this.$route.query.id
       ) {
         // 单团修改
         this.teamid = this.$route.query.id;
         getTeamBaseInfo({ musicGroupId: this.teamid }).then((res) => {
           if (res.code == 200) {
+            if(this.$listeners.getBaseInfo){
+               this.$listeners.getBaseInfo(res.data)
+            }
+           
             // 头部
             this.topFrom.name = res.data.musicGroup.name;
             this.$emit("getName", this.topFrom.name);
@@ -891,7 +772,7 @@ export default {
                   res.data.musicGroupPaymentEntities[i].paymentMethod;
               }
 
-              if (res.data.months.length > 0) {
+              if (res.data?.months?.length > 0) {
                 this.payList.student.ischeck = true;
                 this.payList.student.chiose = "loop";
                 this.chioseMonth = res.data.months;
@@ -959,7 +840,7 @@ export default {
           ownershipType: "OWN", // 合作机构类型
           feeType: null,
         }),
-          this.$refs["topinfo"].resetFields();
+        this.$refs["topinfo"].resetFields();
       }
       // 1.获取各个选项卡的数据内容
       // getSection({ 'delFlag': 0, 'rows': 1000 }).then(res => {
@@ -1055,10 +936,10 @@ export default {
       check.forEach((item) => {
         checkFlag = checkFlag || item;
       });
-      if (!checkFlag) {
-        this.$message.error("请至少选择一种乐团课程类型");
-        return;
-      }
+      // if (!checkFlag) {
+      //   this.$message.error("请至少选择一种乐团课程类型");
+      //   return;
+      // }
       this.$refs["topinfo"].validate((valid, object) => {
         if (!valid) {
           this.$message.error("请填写建团必要参数");
@@ -1115,14 +996,14 @@ export default {
           check.push(this.checkList[i].ischeck);
         }
       }
-      let checkFlag = false;
-      check.forEach((item) => {
-        checkFlag = checkFlag || item;
-      });
-      if (!checkFlag) {
-        this.$message.error("请至少选择一种乐团课程类型");
-        return;
-      }
+      // let checkFlag = false;
+      // check.forEach((item) => {
+      //   checkFlag = checkFlag || item;
+      // });
+      // if (!checkFlag) {
+      //   this.$message.error("请至少选择一种乐团课程类型");
+      //   return;
+      // }
       this.$refs["topinfo"].validate((valid, object) => {
         if (!valid) {
           this.$message.error("请填写必要参数");

+ 78 - 0
src/views/teamBuild/components/teamPayInfo.vue

@@ -0,0 +1,78 @@
+<template>
+  <div class="pay-container">
+    <el-tabs v-model.trim="activeIndex" type="card" @tab-click="handleClick">
+      <el-tab-pane
+        label="学员缴费"
+        v-if="permission('/resetTeaming/teamBaseInfo')"
+        name="1"
+      >
+          <resetPayList :isNewGropu="true" :baseInfo="baseInfo" />
+      </el-tab-pane>
+      <el-tab-pane
+        label="学校缴费"
+        v-if="permission('/resetTeaming/resetSound')"
+        name="2"
+      >
+        <resetPayListSchool :isNewGropu="true" :baseInfo="baseInfo"  v-if="activeIndex == 2" />
+      </el-tab-pane>
+    </el-tabs>
+  
+    <div class="btnWrap">
+      <div class="PrevBtn" @click="goback">上一步</div>
+      <!--  v-if="teamStatus != 'teamAudit'" -->
+      <div class="submitBtn" @click="goHome">确定</div>
+    </div>
+  </div>
+</template>
+<script>
+// import { payOrderTypeList}  from "@/utils/searchArray";
+import resetPayList from "@/views/resetTeaming/components/resetPayList";
+import resetPayListSchool from '@/views/resetTeaming/components/resetPayListSchool'
+import { permission } from '@/utils/directivePage'
+export default {
+  props: ["baseInfo"],
+  components: { resetPayList,resetPayListSchool },
+  data() {
+    return {
+      activeIndex: '1',
+    };
+  },
+  created() {},
+  methods: {
+    goback() {
+      this.$emit("chiosetab", 1);
+    },
+    submitAudit() {
+      let teamId = this.$route.query.id;
+    },
+    handleClick(val){
+      this.activeIndex = val.name
+    },
+       permission (str) {
+      return permission(str)
+    },
+    goHome(){
+      let query = this.$route.query
+      this.$router.push({
+              path: '/business/teamDetail',
+              query: {
+               ...query
+              }
+            })
+    }
+  },
+};
+</script>
+<style lang="scss" scoped>
+.btnWrap {
+  margin-top: 40px;
+  .PrevBtn {
+    background-color: #13817a;
+    width: 120px;
+  }
+  .submitBtn {
+    background-color: #13817a;
+    width: 120px;
+  }
+}
+</style>

+ 2 - 12
src/views/teamBuild/components/teamResetSound.vue

@@ -13,7 +13,7 @@
                          width="150"
                          prop="sound">
         </el-table-column>
-        <el-table-column label="乐团课程费用"
+        <!-- <el-table-column label="乐团课程费用"
                          width="150"
                          prop="yuji">
           <template slot-scope="scope">
@@ -24,7 +24,7 @@
             </div>
           </template>
 
-        </el-table-column>
+        </el-table-column> -->
         <el-table-column label="声部学员">
           <template slot-scope="scope">
             <div>
@@ -53,15 +53,6 @@
             <p>{{item.name }}</p>
             <el-checkbox-group v-model.trim="soundLists[index]"
                                @change='changeList'>
-              <!--  sound: this.activeSoundList[item].name,  // id
-                 jihua: '10', //计划招生人数
-                 yuji: '10', // 预计收费
-                 zhonglei: [], // 可选乐器种类
-                 fangshi: 2, // 乐器提供方式
-                 jiaopu: 'jiaopu1', // 教辅组合
-                 type: 1, // 操作
-                 id: this.activeSoundList[item].id, //声部id
-                 visible: false, // 当前乐器提供方式的pop提示框显示隐藏 -->
               <el-checkbox :label="sound.id"
                            @change="checkinlist({'id':sound.id,'sound':sound.name,'yuji':0,studentList:[]})"
                            v-for="(sound,indexs) in item.subjects"
@@ -261,7 +252,6 @@ export default {
 
                 }
               }
-              console.log('删除');
               this.activeSoundList.splice(i, 1);
               // 遍历循环所有的group 删除所选id
               for (let key in this.soundLists) {

+ 21 - 30
src/views/teamBuild/components/teamSoundMoney.vue

@@ -28,13 +28,14 @@
                         @mousewheel.native.prevent
                         type="number"
                         style="width:80px"
+                        :disabled='teamStatus == "teamAudit"'
                         size="mini"
                         v-model.trim="scope.row.jihua"
                         placeholder="请输入"></el-input>
             </div>
           </template>
         </el-table-column>
-        <el-table-column label="乐团课程费用"
+        <!-- <el-table-column label="乐团课程费用"
                          width="120"
                          align="center"
                          prop="yuji">
@@ -49,7 +50,7 @@
                         placeholder="请输入"></el-input>
             </div>
           </template>
-        </el-table-column>
+        </el-table-column> -->
         <el-table-column label="可选乐器规格"
                          align="center"
                          prop="zhonglei"
@@ -63,6 +64,7 @@
                           v-model.trim="scope.row.typeVisible"
                           v-if="scope.row.type == 1">
                 <el-button type="text"
+                           v-if='teamStatus != "teamAudit"'
                            slot="reference">修改</el-button>
                 <!-- zhonglei -->
                 <el-select v-model.trim="scope.row.zhonglei"
@@ -98,6 +100,7 @@
               >选择</div>-->
               <div v-if="scope.row.fangshi.length >0">{{scope.row.fangshi | fangshiFilter(scope.row)}}</div>
               <i class="el-icon-edit"
+                 v-if='teamStatus != "teamAudit"'
                  @click="setGiveMode(scope.row)"></i>
             </div>
           </template>
@@ -161,6 +164,7 @@
                       :key="index">{{item.name?item.name+':':''}}{{item.goods|goodsFilter(scope.row.markChioseList)}}{{' 价格 '+item.price }}</span>
               </span>
               <i class="el-icon-edit"
+                 v-if='teamStatus != "teamAudit"'
                  slot="reference"
                  @click="chioseMark(scope.row)"></i>
             </div>
@@ -665,7 +669,7 @@
             <div class="item">提供方式</div>
             <div class="item">提供方式对应金额</div>
             <div class="item">乐器费用减免</div>
-            <div class="item">乐团课程费用减免</div>
+
           </div>
 
           <div class="lineWrap">
@@ -681,22 +685,23 @@
                         v-model.trim="item.mode.price"
                         disabled></el-input>
             </div>
+            <!--  :disabled="item.id==-1" -->
             <div class="item">
               <el-input style="width:80%"
                         type="number"
                         @mousewheel.native.prevent
                         v-model.trim="item.mode.GROUP"
-                        :disabled="item.id==-1"
+                        :disabled="true"
                         @input="groupInput(item)"></el-input>
             </div>
-            <div class="item">
+            <!-- <div class="item">
               <el-input style="width:80%"
                         type="number"
                         @mousewheel.native.prevent
                         v-model.trim="item.mode.courseGroup"
                         :disabled="item.id==-1"
                         @input="groupCourseInput(item)"></el-input>
-            </div>
+            </div> -->
           </div>
 
           <div class="lineWrap">
@@ -723,11 +728,7 @@
                         @input="deposiInput(item)"
                         v-model.trim="item.mode.LEASE"></el-input>
             </div>
-            <div class="item">
-              <el-input style="width:80%"
-                        disabled
-                        type="number"></el-input>
-            </div>
+
           </div>
 
           <div class="lineWrap">
@@ -746,11 +747,7 @@
                         @mousewheel.native.prevent
                         disabled></el-input>
             </div>
-            <div class="item">
-              <el-input style="width:80%"
-                        disabled
-                        type="number"></el-input>
-            </div>
+
           </div>
         </div>
       </div>
@@ -775,7 +772,8 @@ import {
   findMusicGroupSubjectInfo,
   updateSubjectInfo,
   auditSuccess,
-  auditFailed
+  auditFailed,
+  getSubjectGoods
 } from "@/api/buildTeam";
 import dayjs from 'dayjs'
 export default {
@@ -833,6 +831,7 @@ export default {
   activated () {
     // 判断是否带缓存参
     this.init();
+
   },
   methods: {
     onCourseChange (item) {
@@ -849,20 +848,17 @@ export default {
       if (this.$route.query.rules) {
         this.Frules = this.$route.query.rules;
       }
+      // 获取
       getSoundTree({ tenantId: 1 }).then(res => {
         if (res.code == 200) {
           this.soundList = res.data.rows;
           // // 生成动态的checkList
           for (let key in this.soundList) {
+            console.log(key)
             this.$set(this.soundLists, key, []);
           }
           // 新建团带默认的数据   this.topfor.section
           if (this.teamStatus == "newTeam") {
-            // console.log({
-            //   chargeTypeId: type,
-            //   organId: this.topfor.section,
-            //   number: 1
-            // })
             getDefaultSubject({
               chargeTypeId: type,
               organId: this.topfor.section,
@@ -1134,8 +1130,6 @@ export default {
       // console.log(e)
     },
     changeSoundList (e, sound, arr) {
-
-      console.log(e, arr, this.activeSoundList)
       if (e) {
         this.checkinlist({ 'id': sound.id, 'sound': sound.name, 'jihua': 0, 'yuji': 0, 'zhonglei': [], 'fangshi': [], 'fangshiprice': 1500, 'jiaopu': '', 'type': 1, 'typeVisible': false, 'provideVisible': false, 'markVisible': false, 'goodsList': [], 'markList': [], 'markChioseList': [] })
       } else {
@@ -1222,7 +1216,7 @@ export default {
 
       let id = row.id;
       // 'subjectId': id, ' type'='INSTRUMENT'
-      getGoods({ subjectId: id, type: "INSTRUMENT" }).then(res => {
+      getSubjectGoods({ subjectId: id, type: "INSTRUMENT", chargeTypeId: this.topfor.type }).then(res => {
         if (res.code == 200) {
           row.goodsList = res.data;
         }
@@ -1682,7 +1676,7 @@ export default {
                 mode: {
                   yuji: tyuji,
                   FREE: 0,
-                  GROUP: 0,
+                  GROUP: row.goodsList[i].musicGroupDiscountPrice,
                   LEASE: 0,
                   courseFree: 0,
                   courseLease: null,
@@ -1783,7 +1777,6 @@ export default {
       })
       let groupList = []
       let leaseList = []
-      console.log(row)
       row.fangshi.forEach(item => {
         if (item.id == -1) {
           flag = false;
@@ -2170,9 +2163,7 @@ export default {
     //   let price = val.price
     // }
   },
-  mounted () {
-    this.init();
-  },
+
   watch: {
     previewVisible (val) {
       if (!val) {

+ 202 - 0
src/views/teamBuild/components/teamSoundSet.vue

@@ -0,0 +1,202 @@
+<template>
+  <div class="sound-container">
+    <div class="topMsg">
+      <p>当前选择声部数(个):{{ chioseSoundNum }}</p>
+      <p style="margin-left: 30px">计划招生人数(个):{{ PlannedCount }}</p>
+    </div>
+    <soundSetCore
+      ref="soundSetCore"
+      @chiosetab="chiosetab"
+      @getNumber="getNumber"
+    />
+    <div class="btnWrap">
+      <div class="PrevBtn" @click="goback">上一步</div>
+      <!--  v-if="teamStatus != 'teamAudit'" -->
+      <div
+        class="submitBtn"
+        v-permission="{
+          child: 'musicGroup/createGroup',
+          parent: '/teamBuild/soundMoney',
+        }"
+        @click="submitInfo()"
+      >
+        下一步
+      </div>
+      <!-- <div
+        class="submitBtn"
+        @click="submitAudit(1)"
+        v-if="teamStatus != 'teamAudit'"
+      >
+        提交审核
+      </div> -->
+      <div class="submitBtn" @click="approval" v-if="teamStatus == 'teamAudit'"  v-permission="{child: 'musicGroup/auditSuccess', parent: '/teamBuild/teamAudit/soundMoney'}">
+        审核通过
+      </div>
+       <div class="submitBtn" @click="refuse" v-if="teamStatus == 'teamAudit'" v-permission="{child: 'musicGroup/auditFailed', parent: '/teamBuild/teamAudit/soundMoney'}"> 
+        驳回
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import store from "@/store";
+import { formatData } from "@/utils/utils";
+import {
+  getSubject,
+  getDefaultSubject,
+  getGoods,
+  createTeam,
+  getSoundTree,
+  findMusicGroupSubjectInfo,
+  updateSubjectInfo,
+  auditSuccess,
+  auditFailed,
+  getSubjectGoods,
+} from "@/api/buildTeam";
+import dayjs from "dayjs";
+
+import soundSetCore from "./soundSetComponents/soundSetCore";
+
+export default {
+  components: { soundSetCore },
+  data() {
+    return {
+      topfor: null, // 第一页的数据
+      Fsearch: null,
+      Frules: null,
+      activeSoundList: [],
+      chioseSoundNum: 0,
+      PlannedCount: 0,
+      teamStatus: null,
+      teamid:null
+    };
+  },
+  mounted() {
+    this.teamid = this.$route.query.id;
+    this.teamStatus = this.$route.query.type;
+  },
+  activated() {
+    this.teamid = this.$route.query.id;
+    this.teamStatus = this.$route.query.type;
+  },
+  methods: {
+    goback() {
+      this.$emit("chiosetab", 0);
+    },
+    submitInfo() {
+      this.$refs.soundSetCore.submitInfo();
+    },
+    chiosetab(val) {
+      this.$emit("chiosetab", val);
+    },
+    submitAudit(val) {
+      this.$refs.soundSetCore.submitInfo(val);
+    },
+    getNumber(chioseSoundNum, PlannedCount) {
+      this.chioseSoundNum = chioseSoundNum;
+      this.PlannedCount = PlannedCount;
+    },
+    approval() {
+      this.$confirm(`是否审核通过?`, "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          auditSuccess({ musicGroupId: this.teamid }).then((res) => {
+            if (res.code == 200) {
+              this.$message.success("审核通过");
+              this.$router.push({
+                path: "/business/teamDetail",
+                query: { search: this.Fsearch, rules: this.Frules },
+              });
+            }
+          });
+        })
+        .catch(() => {});
+    },
+        refuse () {
+      // auditFailed
+      this.$prompt("请输入拒绝原因", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消"
+      }).then(({ value }) => {
+        //   点击确认  值是value
+        if (!value) {
+          this.$message.error("请输入驳回原因");
+          return;
+        } else {
+          auditFailed({ musicGroupId: this.teamid, memo: value }).then(res => {
+            if (res.code == 200) {
+              this.$message.success("已拒绝");
+              this.$router.push({
+                path: "/business/teamDetail",
+                query: { search: this.Fsearch, rules: this.Frules }
+              });
+            }
+          });
+        }
+      });
+    },
+  },
+
+  computed: {},
+};
+</script>
+<style lang="scss" scoped>
+.topMsg {
+  padding: 0 25px;
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-start;
+  font-size: 14px;
+  color: #444;
+  margin-bottom: 20px;
+}
+.soundBtnWrap {
+  margin-bottom: 20px;
+}
+/deep/.el-collapse-item__header {
+  background-color: #edeef0;
+}
+.coreItemTitle {
+  background-color: #edeef0;
+  height: 46px;
+  line-height: 46px;
+  padding: 0 20px;
+}
+.coreItem {
+  padding: 25px 0 0;
+}
+.coreItemRow {
+  padding: 0 20px;
+  line-height: 50px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  p {
+    margin-right: 10px;
+  }
+  .title {
+    width: 100px;
+    text-align: right;
+  }
+}
+.marginLeft10 {
+  margin-left: 10px;
+}
+/deep/.el-collapse-item__header {
+  border-bottom: 1px solid #fff;
+}
+.btnWrap {
+  margin-top: 40px;
+  .PrevBtn {
+    background-color: #13817a;
+    width: 120px;
+  }
+  .submitBtn {
+    background-color: #13817a;
+    width: 120px;
+  }
+}
+</style>

+ 99 - 72
src/views/teamBuild/index.vue

@@ -1,128 +1,145 @@
 <template>
-  <div class='m-container'>
+  <div class="m-container">
     <div class="line"></div>
     <h2>
-      <el-page-header @back="goBack"
-                      :content="pageName">
-      </el-page-header>
+      <el-page-header @back="goBack" :content="pageName"> </el-page-header>
     </h2>
     <div class="m-core">
       <div class="stepbox">
-        <span class='stepspan  stepspan1'
-              @click="activeIndex=0">
-          <div class="step1 sptep"
-               :class="activeIndex >= 0?'activestep':''">
+        <span class="stepspan stepspan1" @click="activeIndex = 0">
+          <div
+            class="step1 sptep"
+            :class="activeIndex >= 0 ? 'activestep' : ''"
+          >
             基本信息
           </div>
-          <img :src="activeIndex >= 0?stepImgs.nol:stepImgs.active"
-               alt=""
-               class="arrow">
+          <img
+            :src="activeIndex  >=  0 ? stepImgs.nol : stepImgs.active"
+            alt=""
+            class="arrow"
+          />
         </span>
-        <span class='stepspan  stepspan2'
-              v-if="activeIndex==1"
-              @click="activeIndex=1">
+        <span
+          class="stepspan stepspan2"
+          v-if="activeIndex  >= 1"
+          @click="activeIndex = 1"
+        >
           <!--    -->
-          <div class="step2 sptep"
-               :class="activeIndex == 1?'activestep':''">
+          <div
+            class="step2 sptep"
+            :class="activeIndex  >= 1 ? 'activestep' : ''"
+          >
             声部费用
           </div>
-          <img :src="activeIndex == 1?stepImgs.nol:stepImgs.active"
-               alt=""
-               class="
-               arrow">
+          <img
+            :src="activeIndex >=  1 ? stepImgs.nol : stepImgs.active"
+            alt=""
+            class="arrow"
+          />
         </span>
-        <span class='stepspan  stepspan2'
-              v-if="activeIndex==2"
-              @click="activeIndex==2">
-          <div class="step2 sptep"
-               :class="activeIndex == 2?'activestep':''">
-            声部费用
+        <span
+          class="stepspan stepspan3"
+          v-if="activeIndex  >=  2"
+          @click="activeIndex = 2"
+        >
+          <div
+            class="step2 sptep"
+            :class="activeIndex  >=  2 ? 'activestep' : ''"
+          >
+            创建缴费
           </div>
-          <img :src="activeIndex == 2?stepImgs.nol:stepImgs.active"
-               alt=""
-               class="
-               arrow">
+          <img
+            :src="activeIndex <= 2 ? stepImgs.nol : stepImgs.active"
+            alt=""
+            class="arrow"
+          />
         </span>
-
       </div>
 
       <!-- 下面显示的内容 -->
       <div class="stepcontent">
-        <div v-show='activeIndex==0'>
-          <teamBaseInfo @chiosetab='chiosetab'
-                        :getTeamList='getTeamList' />
+        <div v-show="activeIndex == 0">
+          <teamBaseInfo @chiosetab="chiosetab" :getTeamList="getTeamList" @getBaseInfo="getBaseInfo"/>
         </div>
-        <div v-if='activeIndex==1'>
-          <teamSoundMoney @chiosetab='chiosetab'
-                          :getTeamList='getTeamList' />
+        <div v-if="activeIndex == 1">
+          <teamSoundMoney @chiosetab="chiosetab" :getTeamList="getTeamList" />
         </div>
-        <div v-if='activeIndex==2'>
-          <teamResetSound @chiosetab='chiosetab'
-                          :getTeamList='getTeamList' />
+        <div v-if="activeIndex == 2">
+          <teamPayInfo @chiosetab="chiosetab" :getTeamList="getTeamList" :baseInfo="baseInfo"/>
         </div>
       </div>
     </div>
   </div>
 </template>
 <script>
-import teamBaseInfo from '@/views/teamBuild/components/teamBaseInfo'
-import teamSoundMoney from '@/views/teamBuild/components/teamSoundMoney'
-import teamResetSound from '@/views/teamBuild/components/teamResetSound'
+import teamBaseInfo from "@/views/teamBuild/components/teamBaseInfo";
+import teamSoundMoney from "@/views/teamBuild/components/teamSoundSet";
+import teamPayInfo from "@/views/teamBuild/components/teamPayInfo";
 export default {
-  components: { teamBaseInfo, teamSoundMoney, teamResetSound },
-  name: 'teamBuild',
-  data () {
+  components: { teamBaseInfo, teamSoundMoney, teamPayInfo },
+  name: "teamBuild",
+  data() {
     return {
       activeIndex: 0,
       stepImgs: {
-        nol: require('@/assets/images/base/step-arrow-active.png'),
-        active: require('@/assets/images/base/step-arrow.png')
+        nol: require("@/assets/images/base/step-arrow-active.png"),
+        active: require("@/assets/images/base/step-arrow.png"),
       },
-      pageName: '建团申请',
+      pageName: "建团申请",
       getTeamList: [],
-      teamStatus: '',
+      teamStatus: "",
       Fsearch: null,
-      Frules: null
-    }
+      Frules: null,
+    };
   },
-  created () {
-    // 判断 是新建乐团还是修改乐团 
-    this.activeIndex = 0
-    this.init()
+  created() {
+    // 判断 是新建乐团还是修改乐团
+    this.activeIndex = 0;
+    this.init();
   },
-  activated () {
-
-    this.init()
+  activated() {
+    this.init();
   },
   methods: {
-    init () {
+    init() {
       this.teamStatus = this.$route.query.type;
       if (this.$route.query.teamList) {
-        this.getTeamList = this.$route.query.teamList
+        this.getTeamList = this.$route.query.teamList;
+        console.log( this.getTeamList)
       }
       // 判断是否带缓存参数
       if (this.$route.query.search) {
         this.Fsearch = this.$route.query.search;
       }
       if (this.$route.query.rules) {
-        this.Frules = this.$route.query.rules
+        this.Frules = this.$route.query.rules;
       }
 
-      if (this.teamStatus == 'newTeam') {
+      if (this.teamStatus == "newTeam") {
         // 新建团
-        this.pageName = '建团申请'
+        this.pageName = "建团申请";
+         this.activeIndex = 0;
       } else {
-        this.pageName = '乐团修改'
+        this.pageName = "乐团修改";
+         this.activeIndex = 0;
       }
     },
-    chiosetab (val) {
+    chiosetab(val) {
+      console.log(val);
       this.activeIndex = val;
     },
-    goBack () {
-      this.$router.push({ path: '/business/teamDetail', query: { search: this.Fsearch, rules: this.Frules } })
-    }
+    goBack() {
+      this.$router.push({
+        path: "/business/teamDetail",
+        query: { search: this.Fsearch, rules: this.Frules },
+      });
+    },
+     getBaseInfo(baseInfo) {
+      this.baseInfo = baseInfo
+      this.pageName = baseInfo.musicGroup?.name
+    },
   },
-}
+};
 </script>
 <style lang="scss" scoped>
 .stepbox {
@@ -154,13 +171,23 @@ export default {
       width: 17px;
       position: relative;
       top: 1px;
+      z-index: 40;
     }
   }
   .stepspan.stepspan2 {
     position: relative;
-    z-index: 10;
+    z-index: 20;
     left: -17px;
-    padding-right: 33px;
+    .sptep {
+      padding-left: 30px !important;
+      border-radius: 0 !important;
+    }
+  }
+  .stepspan.stepspan3 {
+    position: relative;
+    z-index: 10;
+    left: -34px;
+    background-color: #fff;
     .sptep {
       padding-left: 30px !important;
       border-radius: 0 !important;

+ 3 - 4
src/views/teamBuild/signupList.vue

@@ -950,13 +950,12 @@ export default {
           musicGroupId: this.$route.query.id
         }).then(res => {
           if (res.code == 200) {
+            let query = this.$route.query
             this.$message.success('开启成功')
             this.$router.push({
-              path: '/business/teamSeting',
+              path: '/business/teamDetail',
               query: {
-                status: 'PREPARE',
-                id: this.$route.query.id,
-                name: this.$route.query.name
+               ...query
               }
             })
           }

+ 8 - 0
src/views/teamDetail/api.js

@@ -0,0 +1,8 @@
+import request2 from '@/utils/request2'
+
+export const queryRemainCourseTypeDuration = data => request2({
+  url: '/api-web/classGroup/queryRemainCourseTypeDuration',
+  data: {},
+  params: data,
+  requestType: 'form'
+})

+ 198 - 0
src/views/teamDetail/components/modals/classroom-setting-item.vue

@@ -0,0 +1,198 @@
+<template>
+  <div>
+    <!-- <el-form-item
+      label="排课次数"
+      prop="courseTimes"
+    >
+      <el-input v-model="form.courseTimes" placeholder="请输入排课次数"/>
+    </el-form-item> -->
+    <el-form-item
+      label="排课起始时间"
+      :prop="'classs.' + type + '.courseTime'"
+      :rules="[{ required: true, message: '请选择排课起始时间' }]"
+    >
+      <el-date-picker v-model.trim="form.courseTime"
+        :picker-options="pickerOptions"
+        style="width:100%!important;"
+        type="date"
+        value-format="yyyy-MM-dd"
+        placeholder="选择日期">
+      </el-date-picker>
+    </el-form-item>
+    <el-form-item
+      label="跳过节假日"
+      :prop="'classs.' + type + '.holiday'"
+      :rules="[{ required: true, message: '否跳过节假日' }]"
+    >
+      <el-radio-group v-model="form.holiday">
+        <el-radio :label="true">是</el-radio>
+        <el-radio :label="false">否</el-radio>
+      </el-radio-group>
+    </el-form-item>
+    <el-table
+      v-if="form && form.cycle"
+      :data="form.cycle"
+    >
+      <el-table-column
+        prop="dayOfWeek"
+        label="循环周期"
+        width="180">
+        <template slot-scope="scope">
+          <el-form-item
+            inline-message
+            :rules="[{ required: true, message: '请选择循环周期' }]"
+            :prop="'classs.' + type + '.cycle.' + scope.$index + '.dayOfWeek'"
+          >
+            <el-select v-model.trim="scope.row.dayOfWeek"
+              style="width:100%!important"
+              placeholder="请选择循环周期"
+              clearable
+              filterable>
+              <el-option v-for="(item,index) in weekDateList"
+                :key="index"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="time"
+        label="课程时长(分)"
+        width="180">
+        <template slot-scope="scope">
+          <el-form-item
+            :prop="'classs.' + type + '.cycle.' + scope.$index + '.time'"
+            inline-message>
+            <el-input disabled v-model="scope.row.time" placeholder="请输入课程时长"/>
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="startClassTime"
+        label="开始时间"
+        width="180">
+        <template slot-scope="scope">
+          <el-form-item
+            :prop="'classs.' + type + '.cycle.' + scope.$index + '.startClassTime'"
+            :rules="[{ required: true, message: '请选择开始时间' }]"
+            inline-message>
+            <el-time-picker style="width: 100%!important;"
+              v-model.trim="scope.row.startClassTime"
+              format='HH:mm'
+              value-format='HH:mm'
+              placeholder="请选择时间"
+              @change="val => startTimeChange(val, scope.row)"
+              :picker-options="{
+                selectableRange: ['04:30:00 - 23:59:59']
+              }">
+            </el-time-picker>
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="endClassTime"
+        label="结束时间"
+        width="180">
+        <template slot-scope="scope">
+          <el-form-item
+            :prop="'classs.' + type + '.cycle.' + scope.$index + '.endClassTime'"
+            inline-message>
+            <el-time-picker style="width: 100%!important;"
+              v-model.trim="scope.row.endClassTime"
+              format='HH:mm'
+              disabled
+              value-format='HH:mm'
+              placeholder="请选择时间"
+              :picker-options="{
+                selectableRange: [scope.row.startClassTime + ':00 - 23:59:59']
+              }">
+            </el-time-picker>
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="date"
+        label=""
+        width="180">
+        <template slot-scope="scope">
+          <i @click="remove(scope.$index)" v-if="form.cycle.length > 1" class="close-icon el-icon-circle-close"></i>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-button
+      icon="el-icon-circle-plus-outline"
+      type="info"
+      size="small"
+      plain
+      :disabled="surplustime < classTimeListByType[type]"
+      @click="create"
+      style="margin-top: 10px;width: 100%;"
+    >添加循环</el-button>
+  </div>
+</template>
+<script>
+import { diffTimerFormMinute, addTimerFormMinute } from '@/utils/date'
+import { classTimeList } from '@/utils/searchArray'
+import dayjs from 'dayjs'
+
+const classTimeListByType = {}
+for (const item of classTimeList) {
+  classTimeListByType[item.value] = item.label
+}
+
+export default {
+  props: ['form', 'type', 'surplustime'],
+  data() {
+    return {
+      classTimeListByType,
+    }
+  },
+  computed: {
+    pickerOptions() {
+      return {
+        firstDayOfWeek: 1,
+        disabledDate (time) {
+          return time.getTime() + 86400000 <= new Date().getTime();
+        }
+      }
+    },
+    weekDateList() {
+      return [
+        { value: "1", label: "星期一" },
+        { value: "2", label: "星期二" },
+        { value: "3", label: "星期三" },
+        { value: "4", label: "星期四" },
+        { value: "5", label: "星期五" },
+        { value: "6", label: "星期六" },
+        { value: "7", label: "星期日" }
+      ]
+    }
+  },
+  methods: {
+    create() {
+      this.form.cycle.push({
+        time: classTimeListByType[this.type]
+      })
+    },
+    remove(index) {
+      this.form.cycle.splice(index, 1)
+    },
+    startTimeChange(val, item) {
+      if (val) {
+        let str = dayjs(new Date()).format('YYYY-MM-DD')
+        this.$set(item, 'endClassTime', addTimerFormMinute(str, val, item.time))
+      } else {
+        this.$set(item, 'endClassTime', '')
+      }
+    }
+  },
+}
+</script>
+<style lang="less" scoped>
+  /deep/ .close-icon{
+    cursor: pointer;
+    font-size: 16px;
+  }
+</style>

+ 256 - 0
src/views/teamDetail/components/modals/classroom-setting.vue

@@ -0,0 +1,256 @@
+<template>
+  <div>
+    <el-form
+      :model="form"
+      inline
+      ref="form"
+      label-suffix=": "
+      label-width="110px"
+    >
+      <el-form-item
+        label="主教老师"
+        prop="coreTeacher"
+        :rules="[{ required: true, message: '请选择主教老师' }]"
+      >
+        <el-select
+          v-model.trim="form.coreTeacher"
+          placeholder="请选择主教老师"
+          clearable
+          filterable
+        >
+          <el-option
+            v-for="(item, index) in teacherList"
+            :key="index"
+            :label="item.realName"
+            :value="item.id"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="助教老师"
+        prop="assistant"
+      >
+        <el-select
+          v-model.trim="form.assistant"
+          placeholder="请选择助教老师"
+          filterable
+          clearable
+          multiple
+        >
+          <el-option
+            v-for="(item, index) in cooperationList"
+            :key="index"
+            :label="item.realName"
+            :value="item.id"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-collapse v-model="collapses" @change="collapseChange">
+        <el-collapse-item
+          v-for="(item, key, index) in form.classs"
+          :name="index"
+          :key="key"
+        >
+          <template #title>
+            <p>{{courseTypeListByName[key]}}, 剩余可排课时长{{surplustime[key]}}分钟</p>
+          </template>
+          <courseItem
+            :surplustime="surplustime[key]"
+            :type="key"
+            :form="item"
+          />
+        </el-collapse-item>
+      </el-collapse>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="$listeners.close">取 消</el-button>
+      <el-button type="primary" @click="submit">确 定</el-button>
+    </div>
+  </div>
+</template>
+<script>
+import { getMusicCourseSettingsWithStudents, classGroupUpdate, revisionClassGroup, revisionAddClassGroup } from '@/api/buildTeam'
+import courseItem from "./classroom-setting-item";
+import { classTimeList } from '@/utils/searchArray'
+
+const classTimeListByType = {}
+for (const item of classTimeList) {
+  classTimeListByType[item.value] = item.label
+}
+
+const formatClassGroupTeacherMapperList = (core, ass) => {
+  const list = []
+  if (core) {
+    list.push({ userId: core, teacherRole: "BISHOP" })
+  }
+  if (ass) {
+    for (const item of ass) {
+      list.push({ userId: item, teacherRole: "TEACHING" })
+    }
+  }
+  return list
+}
+
+const plusNum = (items = [], key) => {
+  let money = 0
+  for (const item of items) {
+    money += parseFloat(parseFloat(item[key] || 0).toFixed(2) || 0)
+  }
+  return money
+}
+
+export default {
+  props: ["teacherList", "activeType", "courseTypeList", 'cooperationList', 'musicGroupId', 'detail', 'studentSubmitedData', 'classType'],
+  components: {
+    courseItem,
+  },
+  data() {
+    return {
+      form: {
+        coreTeacher: '',
+        assistant: '',
+        classs: {}
+      },
+      collapses: [0],
+      courseTimes: {},
+      courseTypeListByName: {},
+      classTimeListByType
+    };
+  },
+  watch: {
+    courseTypeList() {
+      this.setCourseTypeListByName()
+    },
+    studentSubmitedData() {
+      this.formatClasss()
+    },
+    detail() {
+      this.formatClasss()
+    }
+  },
+  computed: {
+    surplustime() {
+      const _ = {}
+      for (const key in this.form.classs) {
+        if (this.form.classs.hasOwnProperty(key)) {
+          const item = this.form.classs[key];
+          _[key] = item.courseTotalMinuties - plusNum(item.cycle, 'time')
+        }
+      }
+      return _
+    }
+  },
+  async mounted() {
+    this.setCourseTypeListByName()
+    this.formatClasss()
+  },
+  methods: {
+    setCourseTypeListByName() {
+      const courseTypeListByName = {}
+      for (const item of this.courseTypeList) {
+        courseTypeListByName[item.value] = item.label
+      }
+      this.courseTypeListByName = courseTypeListByName
+    },
+    async formatClasss() {
+      try {
+        const res = await getMusicCourseSettingsWithStudents({
+          musicGroupId: this.musicGroupId,
+          studentIds: (this.detail ? undefined : this.studentSubmitedData?.seleched.join(',')),
+          classGroupId: this.detail?.id
+        })
+        const classs = {}
+        const courseTimes = {}
+        for (const item of res.data) {
+          courseTimes[item.courseType] = item
+        }
+        for (const item of this.courseTypeList) {
+          const key = item.value
+          if (courseTimes[key]) {
+            classs[key] = {
+              courseTotalMinuties: courseTimes[key].courseTotalMinuties,
+              cycle: [{
+                time: classTimeListByType[key]
+              }]
+            }
+          }
+        }
+        this.$set(this.form, 'classs', classs)
+        // this.courseTimes = courseTimes
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    submit() {
+      for (const key in this.surplustime) {
+        if (this.surplustime.hasOwnProperty(key)) {
+          const item = this.surplustime[key];
+          if (item > 0) {
+            this.$message.error(`${this.courseTypeListByName[key]},还剩余${item}分钟剩余可排时长`)
+            return
+          }
+        }
+      }
+      this.$refs.form.validate(async valid => {
+        if (valid) {
+          const list = []
+          for (const key in this.form.classs) {
+            if (this.form.classs.hasOwnProperty(key)) {
+              const item = this.form.classs[key];
+              list.push({
+                type: key,
+                courseType: key,
+                classGroupName: (this.studentSubmitedData?.name || this.detail?.classGroupName),
+                classGroupId: this.detail?.id,
+                musicGroupId: this.musicGroupId,
+                startDate: item.courseTime,
+                classGroupTeacherMapperList: formatClassGroupTeacherMapperList(
+                  this.form.coreTeacher,
+                  this.form.assistant
+                ),
+                holiday: item.holiday,
+                students: this.studentSubmitedData.seleched,
+                courseTimes: item.cycle.length,
+                courseTimeDtoList: item.cycle.map(_ => ({
+                  courseType: key,
+                  dayOfWeek: _.dayOfWeek,
+                  endClassTime: _.endClassTime,
+                  startClassTime: _.startClassTime
+                }))
+              })
+            }
+          }
+          try {
+            if (this.detail) {
+              await classGroupUpdate(list)
+              this.$message.success('排课修改成功')
+            } else {
+              if (this.classType === 1) {
+                await revisionClassGroup(list)
+                this.$message.success('排课成功')
+              } else if (this.classType === 2 || this.classType === 3) {
+                await revisionAddClassGroup(list)
+                this.$message.success('排课成功')
+              }
+            }
+            this.$listeners.submited()
+            this.$listeners.close()
+          } catch (error) {
+            console.log(error)
+          }
+        }
+      })
+    },
+    collapseChange(val) {
+      this.collapses = val
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+  .dialog-footer{
+    margin-top: 20px;
+    display: block;
+    text-align: right;
+  }
+</style>

+ 131 - 0
src/views/teamDetail/components/modals/create-user-pay.vue

@@ -0,0 +1,131 @@
+<template>
+  <div>
+    <el-alert title="班级信息" :closable="false" class="alert" type="info">
+    </el-alert>
+    <el-form :model="form">
+      <el-form-item label="单技班">
+        <el-select v-model.trim="form.signClass" filterable clearable>
+          <el-option
+            v-for="(item, index) in signList"
+            :key="index"
+            :value="item.id"
+            :label="item.name"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="合奏班">
+        <el-select v-model.trim="form.mixClass" filterable clearable>
+          <el-option
+            v-for="(item, index) in mixList"
+            :key="index"
+            :value="item.id"
+            :label="item.name"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="基础技能班">
+        <el-select v-model.trim="form.highClass" filterable clearable>
+          <el-option
+            v-for="(item, index) in highList"
+            :key="index"
+            :value="item.id"
+            :label="item.name"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="临时班">
+        <el-select
+          v-model.trim="form.snapClass"
+          filterable
+          clearable
+          multiple
+        >
+          <el-option
+            v-for="(item, index) in snapList"
+            :key="index"
+            :value="item.id"
+            :label="item.name"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <el-alert title="课程信息设置" :closable="false" class="alert" type="info">
+    </el-alert>
+    <extraClass
+      :form="eclass"
+      ref="eclass"
+      :isUserType="true"
+      :isCommon="false"
+      :isDisabled="true"
+      @create="addExtraClass"
+      @remove="removeExtraClass"
+      @moneyChange="syncAllMoney"
+    />
+    <el-alert title="缴费设置" :closable="false" class="alert" type="info">
+    </el-alert>
+    <paymentCycle
+      ref="cycle"
+      :isUserType="true"
+      :form.sync="cycle"
+      :isCommon="false"
+      :isDisabled="true"
+    />
+  </div>
+</template>
+<script>
+import paymentCycle from "../../../resetTeaming/modals/payment-cycle";
+import extraClass from "../../../resetTeaming/modals/extra-class";
+import { queryRemainCourseTypeDuration } from '../../api'
+export default {
+  props: ["snapList", "highList", "mixList", "signList", 'createdUserId'],
+  components: {
+    paymentCycle,
+    extraClass
+  },
+  data() {
+    return {
+      form: {
+        signClass: '',
+        mixClass: '',
+        highClass: '',
+        snapClass: '',
+      },
+      cycle: {},
+      eclass: [],
+    }
+  },
+  watch: {
+    'form.signClass'() {
+      this.classChange()
+    },
+    'form.mixClass'() {
+      this.classChange()
+    },
+    'form.highClass'() {
+      this.classChange()
+    },
+    'form.snapClass'() {
+      this.classChange()
+    },
+  },
+  methods: {
+    async classChange() {
+      try {
+        await queryRemainCourseTypeDuration({
+          classGroupIdList: [this.form.signClass, this.form.mixClass, this.form.highClass, ...this.form.snapClass].filter(item => !!item).join(',')
+        })
+      } catch (error) {}
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+.dialog-footer {
+  margin-top: 20px;
+  display: block;
+  text-align: right;
+}
+.alert {
+  margin-bottom: 10px;
+}
+</style>

+ 165 - 0
src/views/teamDetail/components/modals/select-student.vue

@@ -0,0 +1,165 @@
+<template>
+  <div>
+    <el-form :model="form" ref="form" label-suffix=": " inline>
+      <el-row>
+        <el-col :span="10">
+          <el-form-item
+            label="班级名称"
+            prop="name"
+            :rules="[
+              { required: true, message: '请输入班级名称', trigger: 'blur' },
+            ]"
+          >
+            <el-input
+              v-model="form.name"
+              style="width: 100%"
+              placeholder="请输入班级名称"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="10" :offset="4">
+          <el-form-item label="声部">
+            <el-select
+              v-model="sound"
+              style="width: 100%"
+              clearable
+              filterable
+              placeholder="请选择声部"
+            >
+              <el-option
+                v-for="(item, index) in soundList"
+                :key="index"
+                :label="item.name"
+                :value="item.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-transfer
+        filterable
+        :titles="['所有学员', '已选学员']"
+        filter-placeholder="请输入学生姓名"
+        :filter-method="filterStudent"
+        v-model="seleched"
+        :render-content="renderFunc"
+        :data="data"
+      >
+        <template #left-footer>
+          <div class="footer line">
+            <span>姓名</span>
+            <span>性别</span>
+            <span>专业</span>
+          </div>
+        </template>
+        <template #right-footer>
+          <div class="footer line">
+            <span>姓名</span>
+            <span>性别</span>
+            <span>专业</span>
+          </div>
+        </template>
+      </el-transfer>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="$listeners.close">取 消</el-button>
+      <el-button type="primary" @click="submit">确 定</el-button>
+    </div>
+  </div>
+</template>
+<script>
+import { genderType } from "@/constant";
+export default {
+  props: ["studentList", "soundList", "activeType"],
+  computed: {
+    data() {
+      return this.studentList.map((item) => ({
+        value: item.id,
+        key: item.id,
+        name: item.name,
+        subjectName: item.subjectName,
+        gender: genderType[item.gender],
+      }));
+    },
+  },
+  data() {
+    return {
+      sound: [],
+      form: {
+        name: '',
+      },
+      seleched: [],
+    };
+  },
+  methods: {
+    filterStudent(query, item) {
+      return (
+        item.name.indexOf(query) > -1 ||
+        item.subjectName.indexOf(query) > -1 ||
+        item.gender.indexOf(query) > -1
+      );
+    },
+    renderFunc(h, option) {
+      return (
+        <div class="line">
+          <span>{option.name}</span>
+          <span>{option.gender}</span>
+          <span>{option.subjectName}</span>
+        </div>
+      );
+    },
+    submit() {
+      if (this.activeType == 'HIGH_ONLINE' && (this.seleched.length < 3 || this.seleched.length > 5)) {
+        return this.$message.error('线上技能班必须为3-5人')
+      }
+      if (this.seleched.length < 1) {
+        return this.$message.error('请至少选择一名学生')
+      }
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.$listeners.submited({
+            seleched: this.seleched,
+            name: this.form.name
+          })
+          this.$listeners.close()
+        }
+      })
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+/deep/ .el-transfer {
+  display: flex;
+  align-items: center;
+  .el-transfer__buttons {
+    display: flex;
+    width: 110px;
+    flex-direction: column;
+    > button {
+      &:last-child {
+        margin-left: 0;
+      }
+    }
+  }
+  .el-transfer-panel {
+    width: 300px;
+  }
+}
+.footer {
+  margin-left: 35px;
+  margin-right: auto;
+  height: 40px;
+  line-height: 40px;
+}
+/deep/ .line {
+  width: 220px;
+  display: flex;
+  justify-content: space-around;
+}
+/deep/ .dialog-footer{
+  margin-top: 20px;
+  display: block;
+  text-align: right;
+}
+</style>

+ 49 - 0
src/views/teamDetail/components/modals/view-student-list.vue

@@ -0,0 +1,49 @@
+<template>
+  <div>
+    <el-table
+      :data="list"
+      style
+      :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+      tooltip-effect="dark"
+    >
+      <el-table-column
+        prop="name"
+        align="center"
+        width="120"
+        label="学员编号"
+      ></el-table-column>
+      <el-table-column
+        prop="name"
+        align="center"
+        width="120"
+        label="学员姓名"
+      ></el-table-column>
+      <el-table-column
+        prop="name"
+        align="center"
+        width="120"
+        label="性别"
+      ></el-table-column>
+      <el-table-column
+        prop="name"
+        align="center"
+        width="120"
+        label="联系电话"
+      ></el-table-column>
+      <el-table-column
+        prop="name"
+        align="center"
+        width="120"
+        label="专业"
+      ></el-table-column>
+    </el-table>
+    <div slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="$listeners.close">确 定</el-button>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: ['list'],
+};
+</script>

+ 128 - 39
src/views/teamDetail/components/resetClass.vue

@@ -86,7 +86,7 @@
             </template>
           </el-table-column>
           <el-table-column align="center"
-                           width="400px"
+                           width="200px"
                            label="操作">
             <template slot-scope="scope">
               <div>
@@ -98,7 +98,7 @@
                            @click="classAdjustment(scope.row)">班级调整</el-button>
                 <!--<el-button type="text"
                 @click="recourse(scope.row)">重新排课</el-button>-->
-                <el-popover placement="top"
+                <!-- <el-popover placement="top"
                             width="160"
                             :ref="`popover-${scope.$index}`">
                   <p>确定删除?</p>
@@ -109,14 +109,14 @@
                     <el-button type="primary"
                                size="mini"
                                @click="removeClass(scope)">确定</el-button>
-                  </div>
+                  </div> -->
                   <!-- v-if="scope.row.type !='MIX'" -->
-                  <el-button type="text"
+                  <!-- <el-button type="text"
                              v-if="scope.row.type != 'MUSIC_NETWORK'"
                              slot="reference">删除班级</el-button>
-                </el-popover>
+                </el-popover> -->
 
-                <el-popover placement="top"
+                <!-- <el-popover placement="top"
                             width="160"
                             :ref="scope.$index">
                   <p>是否清空课表?</p>
@@ -127,11 +127,11 @@
                     <el-button type="primary"
                                size="mini"
                                @click="clearCourse(scope)">确定</el-button>
-                  </div>
+                  </div> -->
                   <!-- v-if="scope.row.type !='MIX'" -->
-                  <el-button type="text"
+                  <!-- <el-button type="text"
                              slot="reference">清空课表</el-button>
-                </el-popover>
+                </el-popover> -->
               </div>
             </template>
           </el-table-column>
@@ -151,7 +151,21 @@
       </div>
     </div>
     <!-- 学员选择 -->
-    <el-dialog title="学员选择"
+    <el-dialog
+      title="学员选择"
+      width="750px"
+      :visible.sync="studentVisible"
+      destroy-on-close
+    >
+      <selectStudent
+        :studentList="studentList"
+        :soundList="soundList"
+        :activeType="activeType"
+        @submited="studentSubmited"
+        @close="studentVisible = false"
+      />
+    </el-dialog>
+    <!-- <el-dialog title="学员选择"
                width="700px"
                :visible.sync="studentVisible"
                :modal-append-to-body="false">
@@ -190,10 +204,10 @@
             </div>
           </div>
         </div>
-        <div class="right">
+        <div class="right"> -->
           <!--  multiple
           collapse-tags v-if="isSearch"  -->
-          <el-select v-model.trim="activeChioseSound"
+          <!-- <el-select v-model.trim="activeChioseSound"
                      style="width:180px"
                      @change="searchStudent"
                      clearable
@@ -203,14 +217,14 @@
                        :key="index"
                        :label="item.name"
                        :value="item.id"></el-option>
-          </el-select>
+          </el-select> -->
           <!-- <el-button v-if="isSearch"
                      type="danger"
                      style="margin-left:20px;"
           @click="searchStudent">搜索</el-button>-->
 
           <!--   列表开始  -->
-          <div class="tableList">
+          <!-- <div class="tableList">
             <el-table tooltip-effect="dark"
                       v-if="!isNewClass"
                       style="width: 100%; margin-top:10px;"
@@ -236,9 +250,9 @@
                                width="100"
                                align="center"
                                label="学员声部"></el-table-column>
-            </el-table>
+            </el-table> -->
             <!-- 临时调整table -->
-            <el-table tooltip-effect="dark"
+            <!-- <el-table tooltip-effect="dark"
                       v-if="isNewClass"
                       style="width: 100%; margin-top:10px;"
                       :data="studentList"
@@ -269,29 +283,62 @@
       </div>
       <div slot="footer"
            class="dialog-footer">
-        <el-button @click="studentVisible = false">取 消</el-button>
+        <el-button @click="studentVisible = false">取 消</el-button> -->
         <!-- 班级学员修改 -->
-        <el-button type="primary"
+        <!-- <el-button type="primary"
                    v-if="!isNewClass"
-                   @click="addSomeStudent">确 定</el-button>
+                   @click="addSomeStudent">确 定</el-button> -->
         <!-- 临时调整或者新建班级 -->
-        <el-button type="primary"
+        <!-- <el-button type="primary"
                    v-if="isNewClass"
                    @click="setInfoMsg">确 定</el-button>
       </div>
-    </el-dialog>
+    </el-dialog> -->
     <!-- 老师以及课程设置 -->
-    <el-dialog title="班级设置"
+    <el-dialog
+      title="班级设置"
+      width="950px"
+      :visible.sync="infoVisible"
+      :modal-append-to-body="false"
+      destroy-on-close
+    >
+      <classroomSetting
+        :classType="classType"
+        :teacherList="teacherList"
+        :musicGroupId="teamid"
+        :activeType="activeType"
+        :courseTypeList="courseTypeList"
+        :cooperationList="cooperationList"
+        :detail="infoDetail"
+        :studentSubmitedData="studentSubmitedData"
+        @close="infoVisible = false"
+        @submited="getList"
+      />
+    </el-dialog>
+    <!-- <el-dialog title="班级设置"
                width="780px"
                :visible.sync="infoVisible"
                :modal-append-to-body="false">
+      <el-alert
+        type="warning"
+        style="margin-bottom: 20px;"
+        :closable="false">
+        <template #title>
+          <div class="alert-content">
+            <span>
+              该班级剩余可排课时长:<strong>1000分钟</strong>
+            </span>
+            <strong>学员列表&gt;&gt;</strong>
+          </div>
+        </template>
+      </el-alert>
       <el-form :inline="true"
                :model="teacherForm"
                ref="teacherForm"
                :rules="teacherRules"
                label-position="right"
-               label-width="100px;">
-        <el-form-item label="调整方式"
+               label-width="100px;"> -->
+        <!-- <el-form-item label="调整方式"
                       v-if="!isNewClass"
                       prop="isAdd">
           <el-radio v-model.trim="teacherForm.isAdd"
@@ -299,7 +346,7 @@
           <el-radio v-model.trim="teacherForm.isAdd"
                     label="renew">重新排课</el-radio>
           <el-radio v-model.trim="teacherForm.isAdd"
-                    label="onlyUpdateTeacher">修改老师
+                    label="onlyUpdateTeacher">修改老师 -->
             <!-- <el-tooltip placement="top"
                         popper-class="mTooltip">
               <div slot="content">
@@ -308,12 +355,12 @@
               <i class="el-icon-question micon el-tooltip"
                  style="font-size: 18px; color: #F56C6C"></i>
             </el-tooltip> -->
-          </el-radio>
+          <!-- </el-radio>
 
-        </el-form-item>
+        </el-form-item> -->
 
-        <br />
-        <el-form-item label="主教老师"
+        <!-- <br /> -->
+        <!-- <el-form-item label="主教老师"
                       prop="coreTeacher">
           <el-select v-model.trim="teacherForm.coreTeacher"
                      placeholder="请选择主教老师"
@@ -355,9 +402,9 @@
                        :value="item.value"
                        :label="item.label"></el-option>
           </el-select>
-        </el-form-item>
+        </el-form-item> -->
         <!--  v-if="!isNewClass" -->
-        <el-form-item label="声部"
+        <!-- <el-form-item label="声部"
                       v-if="activeType=='HIGH_ONLINE'&&isNewClass"
                       prop="sound">
           <el-select v-model.trim="teacherForm.sound"
@@ -461,21 +508,21 @@
         </div>
       </div>
       <div slot="footer"
-           class="dialog-footer">
+           class="dialog-footer"> -->
         <!-- 1为临时班级 -->
-        <el-button type="primary"
+        <!-- <el-button type="primary"
                    v-if="isTemporary&&isNewClass"
-                   @click="submitTemporary(1)">确 定</el-button>
+                   @click="submitTemporary(1)">确 定</el-button> -->
         <!-- 2为新增班级 -->
-        <el-button type="primary"
+        <!-- <el-button type="primary"
                    v-if="!isTemporary&&isNewClass"
-                   @click="submitTemporary(2)">确 定</el-button>
+                   @click="submitTemporary(2)">确 定</el-button> -->
         <!-- 修改班级信息 -->
-        <el-button type="primary"
+        <!-- <el-button type="primary"
                    v-if="!isNewClass"
                    @click="submitTemporary(3)">确 定</el-button>
       </div>
-    </el-dialog>
+    </el-dialog> -->
     <!-- 新增合奏班 -->
     <el-dialog title="新增合奏班"
                width="700px"
@@ -664,6 +711,16 @@
                    @click="newClassHight">确 定</el-button>
       </div>
     </el-dialog>
+    <el-dialog
+      title="学员列表"
+      :visible.sync="studentListModalVisible"
+      destroy-on-close
+    >
+      <viewStudentList
+        :list="studentListModal"
+        @close="studentListModalVisible = false"
+      />
+    </el-dialog>
   </div>
 </template>
 <script>
@@ -699,11 +756,20 @@ import { diffTimerFormMinute, addTimerFormMinute } from '@/utils/date'
 import dayjs from 'dayjs'
 import axios from "axios";
 import { classTimeList } from "@/utils/searchArray";
+import viewStudentList from './modals/view-student-list'
+import selectStudent from './modals/select-student'
+import classroomSetting from './modals/classroom-setting'
 import qs from "qs";
 export default {
   name: "tresetClass",
+  components: {
+    viewStudentList,
+    selectStudent,
+    classroomSetting
+  },
   data () {
     return {
+      classType: 0,
       pickerOptions: {
         firstDayOfWeek: 1,
         disabledDate (time) {
@@ -715,10 +781,14 @@ export default {
       topForm: {
         classType: ""
       },
+      studentSubmitedData: null,
+      infoDetail: null,
       classTimeList,
       tableList: [],
       maxClassList: [],
       activeSingleList: [],
+      studentListModal: [],
+      studentListModalVisible: false,
       resetCourseVisible: false, // 重新排课弹窗
       resetClassVisible: false, // 班级调整弹窗
       studentVisible: false,
@@ -892,6 +962,10 @@ export default {
       // 获取分部所有老师
       // 助教是从员工表里选
     },
+    studentSubmited(data) {
+      this.studentSubmitedData = data
+      this.infoVisible = true
+    },
     recourse (row) {
       (this.weekList = [
         {
@@ -930,6 +1004,7 @@ export default {
     },
     // 临时调整
     temporary () {
+      this.classType = 1;
       this.activeClass = "";
       this.activeListStudent = [];
       this.studentList = [];
@@ -994,6 +1069,7 @@ export default {
     },
     // 新增班级
     addNewClass (type) {
+      this.classType = (type === 'NORMAL' ? 2 : 3)
       /**
        *      { value: 'NORMAL', label: '单技班' },
         { value: 'MIX', label: '合奏班' },
@@ -1114,6 +1190,7 @@ export default {
     },
     // 班级调整
     classAdjustment (row) {
+      this.infoDetail = row
       this.activeType = row.type;
       this.activeClass = row.id;
       // this.activeListStudent = row.subjectIdList.split(',')
@@ -1687,7 +1764,8 @@ export default {
           sound: "",
           expectStudentNum: ""
         };
-        this.$refs["teacherForm"].resetFields();
+        this.infoDetail = null
+        // this.$refs["teacherForm"].resetFields();
         this.weekList = [];
       }
     },
@@ -1795,4 +1873,15 @@ export default {
     height: 40px !important;
   }
 }
+/deep/ .el-alert__content{
+  display: block;
+  width: 100%;
+}
+.alert-content{
+  display: flex;
+  justify-content: space-between;
+  >strong{
+    cursor: pointer;
+  }
+}
 </style>

+ 118 - 26
src/views/teamDetail/components/studentList.vue

@@ -239,7 +239,7 @@
                   @pagination="getList" />
     </div>
     <el-dialog title="新增学员"
-               width="680px"
+               width="700px"
                class="studentInfo"
                :visible.sync="addStudentVisible">
       <el-form :model="maskForm"
@@ -248,7 +248,12 @@
                ref="maskForm"
                :rules="maskRules"
                :inline="true">
-        <el-divider>基本信息</el-divider>
+        <el-alert
+          title="基本信息"
+          :closable="false"
+          class="alert"
+          type="info">
+        </el-alert>
         <el-form-item label="联系电话"
                       prop="phone"
                       :rules="[{ required: true, message: '请输入手机号' }, { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }]">
@@ -344,14 +349,7 @@
                             placeholder="选择日期"></el-date-picker>
           </el-col>
         </el-form-item>
-        <el-form-item label="课程费用"
-                      prop="courseFee">
-          <el-input v-model.trim="maskForm.courseFee"
-                    type="number"
-                    @mousewheel.native.prevent
-                    placeholder="续费金额"></el-input>
-        </el-form-item>
-        <br />
+        <!-- <br />
         <el-form-item label="单技班">
           <el-select v-model.trim="maskForm.signClass"
                      filterable
@@ -361,8 +359,8 @@
                        :value="item.id"
                        :label="item.name"></el-option>
           </el-select>
-        </el-form-item>
-        <el-form-item label="合奏班">
+        </el-form-item> -->
+        <!-- <el-form-item label="合奏班">
           <el-select v-model.trim="maskForm.mixClass"
                      filterable
                      clearable>
@@ -371,8 +369,8 @@
                        :value="item.id"
                        :label="item.name"></el-option>
           </el-select>
-        </el-form-item>
-        <el-form-item label="基础技能班">
+        </el-form-item> -->
+        <!-- <el-form-item label="基础技能班">
           <el-select v-model.trim="maskForm.highClass"
                      filterable
                      clearable>
@@ -381,8 +379,8 @@
                        :value="item.id"
                        :label="item.name"></el-option>
           </el-select>
-        </el-form-item>
-        <el-form-item label="临时班">
+        </el-form-item> -->
+        <!-- <el-form-item label="临时班">
           <el-select v-model.trim="maskForm.snapClass"
                      filterable
                      clearable
@@ -392,7 +390,7 @@
                        :value="item.id"
                        :label="item.name"></el-option>
           </el-select>
-        </el-form-item>
+        </el-form-item> -->
         <!-- <el-form-item label="线上基础技能班">
           <el-select v-model.trim="maskForm.highonline"
                      filterable
@@ -416,7 +414,7 @@
           </el-select>
         </el-form-item>-->
 
-        <el-divider>首缴订单信息</el-divider>
+        <!-- <el-divider>首缴订单信息</el-divider>
         <el-form-item label="课程费用"
                       prop="temporaryCourseFee">
           <el-input type="number"
@@ -488,7 +486,40 @@
                         placeholder="输入金额"></el-input>
             </el-form-item>
           </el-col>
-        </el-form-item>
+        </el-form-item> -->
+        <!-- <el-alert
+          title="缴费周期设置"
+          :closable="false"
+          class="alert"
+          type="info">
+        </el-alert>
+        <el-collapse :value="collapse" @change="collapseChange" >
+          <el-collapse-item
+            v-for="(item, index) in cycles"
+            :key="index"
+            :name="index"
+          >
+            <template slot="title">
+              <div class="collapse-title">
+                <span>缴费周期 {{index + 1}}</span>
+                <i v-if="cycles.length > 1" class="el-icon-circle-close" @click.stop="removeCycle(index)"></i>
+              </div>
+            </template>
+            <paymentCycle
+              ref="cycles"
+              className="cycleForm"
+              :form="item"
+            />
+          </el-collapse-item>
+        </el-collapse>
+        <el-button
+          icon="el-icon-circle-plus-outline"
+          plain
+          type="info"
+          size="small"
+          style="width: 100%;margin: 20px 0;"
+          @click="addCycle"
+        >新增缴费周期</el-button> -->
       </el-form>
       <div slot="footer"
            class="dialog-footer">
@@ -670,8 +701,22 @@
                    @click="submitAddVisit">确 定</el-button>
       </span>
     </el-dialog>
+    <el-dialog
+      title="选择班级"
+      destroy-on-close
+      width="600px"
+      :visible.sync="createUserPayVisible"
+    >
+      <createUserPay
+        :signList="signList"
+        :mixList="mixList"
+        :highList="highList"
+        :snapList="snapList"
+        :createdUserId="createdUserId"
+      />
+    </el-dialog>
   </div>
-</template> 
+</template>
 <script>
 import {
   getTeamStudentList,
@@ -700,6 +745,8 @@ import { getToken } from "@/utils/auth";
 import { permission } from "@/utils/directivePage";
 import { addVisit } from "@/views/returnVisitManager/api.js"
 import cleanDeep from 'clean-deep'
+import createUserPay from './modals/create-user-pay.vue'
+import paymentCycle from '../../resetTeaming/modals/payment-cycle'
 export default {
   name: "tstudentList",
   data () {
@@ -775,7 +822,7 @@ export default {
         muiscnetwork: "",
         startClass: "",
         id: "",
-        courseFee: null, // 声部费用
+        // courseFee: null, // 声部费用
         temporaryCourseFee: null, // 本次课程费用
         musicGoodsIdList: null, // 乐器商品编号
         kitGroupPurchaseType: "GROUP", // 乐器购买方式
@@ -808,7 +855,7 @@ export default {
         // price: [{ required: true, message: '请输入首缴金额' },],
         startClass: [{ required: true, message: "请选择年级" }],
         id: [{ required: true, message: "请输入证件号" }],
-        courseFee: [{ required: true, message: "请输入声部费用" }],
+        // courseFee: [{ required: true, message: "请输入声部费用" }],
         temporaryCourseFee: [{ required: true, message: "请输课程费用" }],
         musicGoodsIdList: [
           { required: true, message: "请选择乐器", trigger: "change" }
@@ -841,7 +888,8 @@ export default {
         feedback: '',
         studentName: ''
       },
-
+      cycles: [{}],
+      collapse: [0],
       visitChiose,
       visitRules: {
         overview: [{ required: true, message: "请输入学生近况" }],
@@ -850,11 +898,15 @@ export default {
         visitType: [{ required: true, message: "请选择回访类型" }]
       },
       pickerOptions: null,
-      classLists: null
+      classLists: null,
+      createdUserId: 2109142,
+      createUserPayVisible: true,
     };
   },
   components: {
-    pagination
+    pagination,
+    paymentCycle,
+    createUserPay
   },
   created () {
     // 判断是否带缓存参数
@@ -1057,6 +1109,18 @@ export default {
         }
       });
     },
+    addCycle() {
+      this.cycles.push({})
+      this.collapse.push(this.collapse.length)
+    },
+    removeCycle(index) {
+      this.cycles[index] = null
+      this.cycles = this.cycles.filter(item => !!item)
+      this.collapse.pop()
+    },
+    collapseChange(val) {
+      this.collapse = val
+    },
     gotoSignin () {
       this.$router.push({
         path: "/business/studentSignin",
@@ -1203,6 +1267,8 @@ export default {
               this.$message.success("添加学生成功");
               this.getList();
               this.addStudentVisible = false;
+              this.createUserPayVisible = true
+              this.createdUserId = res.data
             }
             this.$refs.maskForm.resetFields();
           });
@@ -1533,4 +1599,30 @@ export default {
 .export {
   background: #14928a;
 }
-</style>
+.alert{
+  margin-bottom: 10px;
+}
+.collapse-title{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+  .el-icon-circle-close{
+    font-size: 16px;
+    margin-right: 10px;
+  }
+}
+/deep/ .el-collapse-item__wrap{
+  padding-top: 20px;
+}
+.cycleForm{
+  /deep/ .el-form-item{
+    display: flex;
+    width: 100%;
+    /deep/ .el-form-item__content{
+      margin-left: 0!important;
+      flex: 1;
+    }
+  }
+}
+</style>

+ 1 - 1
src/views/teamDetail/teamInfo.vue

@@ -30,7 +30,7 @@
 </template>
 <script>
 import baseInfo from '@/views/teamBuild/components/teamBaseInfo'
-import soundeDetail from '@/views/resetTeaming/components/resetSound'
+import soundeDetail from '@/views/resetTeaming/components/resetSoundv2' 
 export default {
   data () {
     return {

+ 1 - 1
src/views/teamDetail/teamList.vue

@@ -201,7 +201,7 @@
                 <!-- 审核中 编辑 -->
                 <el-button type="text"
                            v-if="scope.row.status == 'AUDIT' && permission('teamDetail/audit/update')"
-                           @click="lookTeamDetail(scope.row)">编辑</el-button>
+                           @click="lookTeamDetail(scope.row)">审核</el-button>
                 <!-- 编辑中 编辑 -->
                 <el-button type="text"
                            v-if="scope.row.status == 'DRAFT' && permission('teamDetail/draft/update')"

+ 1 - 1
vue.config.js

@@ -20,7 +20,7 @@ const name = defaultSettings.title || '管乐迷后台管理系统' // page titl
 // let target = 'http://dyme.utools.club' //test环境
 // let target = 'http://192.168.3.139:8000' // 箭河
 // let target = 'http://192.168.3.248:8000' //邹璇
-// let target = 'http://192.168.3.8:8000' //勇哥
+// let target = 'http://192.168.3.204:8000' //勇哥
 let target = 'http://dev.dayaedu.com' // 测试服
 // let target = 'http://192.168.3.196' // 乔
 // All configuration item explanations can be find in https://cli.vuejs.org/config/

部分文件因文件數量過多而無法顯示