浏览代码

Merge branch 'ol_12_30' into wxl_01_15

lex-xin 4 年之前
父节点
当前提交
2494f8c59e

+ 2 - 0
debug.log

@@ -14,3 +14,5 @@
 [0105/101053.212:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
 [0106/093923.589:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
 [0107/093708.765:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
+[0108/093931.571:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
+[0111/093600.762:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)

+ 2 - 0
src/main.js

@@ -5,6 +5,7 @@ import dayjs from 'dayjs'
 import numeral from 'numeral'
 import lodash from 'lodash'
 import qs from 'qs'
+import { permission } from "@/utils/directivePage";
 
 import * as constant from '@/constant'
 
@@ -118,6 +119,7 @@ Vue.mixin({
         numeral,
         lodash,
         qs,
+        permission,
       }
     },
     $constant() {

+ 0 - 1
src/utils/downLoadFile.js

@@ -54,7 +54,6 @@ export const Export = (that, params, message) => {
                     let objectUrl = URL.createObjectURL(blob);
                     let link = document.createElement("a");
                     let fname = params.fileName || "导出文件.xlsx"; //下载文件的名字
-                    console.log(params)
                     link.href = objectUrl;
                     link.setAttribute("download", fname);
                     document.body.appendChild(link);

+ 2 - 0
src/utils/searchArray.js

@@ -107,6 +107,8 @@ export const musicGroupStatus = [
   { value: 'AUDIT_FAILED', text: '审核失败' },
   { value: 'PAUSE', text: '暂停' },
   { value: 'CANCELED', text: '取消' },
+  { value: 'FEE_AUDIT', text: '费用审核中' },
+  { value: 'CLOSE', text: '已关闭' },
 ]
 
 export const vipGroupStatus = [

+ 2 - 1
src/utils/vueFilter.js

@@ -325,7 +325,8 @@ Vue.filter('teamStatus', value => {
     AUDIT: '乐团审核中',
     DRAFT: '编辑中',
     AUDIT_FAILED: '审核失败',
-    FEE_AUDIT: '费用审核中'
+    FEE_AUDIT: '费用审核中',
+    CLOSE: '已关闭',
   }
   return template[value]
 })

+ 3 - 3
src/views/accompanyManager/accompanyList.vue

@@ -8,9 +8,9 @@
         class="newBand"
         v-permission="'export/practiceGroup'"
         @click="onStudentExport"
-        style="width: 120px"
+        style="width: 150px; max-width:150px"
       >
-        网管课续费提醒
+        网管课续费提醒导出
       </div>
       <div
         class="newBand"
@@ -476,7 +476,7 @@ export default {
                 } else {
                   let objectUrl = URL.createObjectURL(blob);
                   let link = document.createElement("a");
-                  let fname = "网管课续费提醒" + new Date().getTime(); //下载文件的名字
+                  let fname = "网管课续费提醒" + new Date().getTime() + '.xls'; //下载文件的名字
                   link.href = objectUrl;
                   link.setAttribute("download", fname);
                   document.body.appendChild(link);

+ 57 - 36
src/views/accompanyManager/accompanys.vue

@@ -206,14 +206,15 @@
                           type="date"
                           value-format="yyyy-MM-dd"
                           :picker-options="{
-        firstDayOfWeek: 1
-    }"
+                            firstDayOfWeek: 1
+                            }"
                           placeholder="选择日期"></el-date-picker>
         </el-form-item>
         <el-form-item label="开始时间"
-                      prop="startTime">
+                      prop="startTime"
+                      :rules="[{ required: true, message: '请选择开始时间', trigger: 'change' }]">
           <el-time-picker placeholder="起始时间"
-                          v-model="startTime"
+                          v-model="maskForm.startTime"
                           @change="changeStartTime"
                           format='HH:mm'
                           value-format='HH:mm'
@@ -249,7 +250,7 @@
       </el-form>
       <div slot="footer"
            class="dialog-footer">
-        <el-button @click="courseVisible = false">取 消</el-button>
+        <el-button @click="handleClose">取 消</el-button>
         <el-button type="primary"
                    @click="submitResetClass">确 定</el-button>
       </div>
@@ -819,14 +820,15 @@ export default {
       this.teacherVisible = false;
     },
     handleClose () {
-      this.courseVisible = false;
-      this.startTime = "";
-      this.maskForm = {
-        date: "",
-        startTime: "",
-        id: ""
-      };
+      console.log(true)
       this.$refs["maskForm"].resetFields();
+      this.courseVisible = false;
+      // this.startTime = "";
+      // this.maskForm = {
+      //   date: "",
+      //   startTime: "",
+      //   id: ""
+      // };
     },
     expireClose () {
       this.expireVisible = false;
@@ -835,36 +837,55 @@ export default {
     },
     submitResetClass () {
       //   endClassTimeStr: this.maskForm.endTime,
-      if (!this.startTime) {
-        this.$message.error("请填写修改时间");
-        return;
-      }
-      let obj = {
-        startClassTime: dayjs(this.maskForm.date + ' ' + this.startTime).format('YYYY-MM-DD HH:mm:ss'),
-        id: this.maskForm.id,
-        classDate: this.maskForm.date,
-        groupType: 'PRACTICE'
-      };
-      resetCourse(obj).then(res => {
-        if (res.code == 200) {
-          this.$message.success("修改成功");
-          this.courseVisible = false;
-          this.getList();
-        } //else {
-        //     this.$message.error(res.msg)
-        //   }
-      });
+      this.$refs.maskForm.validate(valid => {
+        if(valid) {
+          let obj = {
+            startClassTime: dayjs(this.maskForm.date + ' ' + this.startTime).format('YYYY-MM-DD HH:mm:ss'),
+            id: this.maskForm.id,
+            classDate: this.maskForm.date,
+            groupType: 'PRACTICE'
+          };
+          resetCourse(obj).then(res => {
+            if (res.code == 200) {
+              this.$message.success("修改成功");
+              this.courseVisible = false;
+              this.getList();
+            }
+          });
+        }
+      })
+      // if (!this.startTime) {
+      //   this.$message.error("请填写修改时间");
+      //   return;
+      // }
+      // let obj = {
+      //   startClassTime: dayjs(this.maskForm.date + ' ' + this.startTime).format('YYYY-MM-DD HH:mm:ss'),
+      //   id: this.maskForm.id,
+      //   classDate: this.maskForm.date,
+      //   groupType: 'PRACTICE'
+      // };
+      // resetCourse(obj).then(res => {
+      //   if (res.code == 200) {
+      //     this.$message.success("修改成功");
+      //     this.courseVisible = false;
+      //     this.getList();
+      //   }
+      // });
     },
     resetClass (row) {
       /**
        * maskForm.startTime
        *
        */
-
-      this.maskForm.date = dayjs(row.classDate).format('YYYY-MM-DD');
-      this.startTime = row.startClassTimeStr.substring(0, 5);
-      this.maskForm.endTime = row.endClassTimeStr.substring(0, 5);
-      this.maskForm.id = row.id;
+      this.$nextTick(() => {
+        this.maskForm = {
+          date: dayjs(row.classDate).format('YYYY-MM-DD'),
+          startTime: row.startClassTimeStr.substring(0, 5),
+          endTime: row.endClassTimeStr.substring(0, 5),
+          id: row.id
+        }
+        // this.startTime = row.startClassTimeStr.substring(0, 5);
+      })
       this.coursesExpireDate = row.coursesExpireDate;
       // 修改课时
       this.courseVisible = true;

+ 8 - 45
src/views/afterSchoolManager/afterWorkList.vue

@@ -259,6 +259,7 @@ import {
   findStudentExtraExerciseDetail
 } from "@/api/afterSchool";
 import { getEmployeeOrgan } from "@/api/buildTeam";
+import { Export } from '@/utils/downLoadFile'
 import axios from "axios";
 import { getToken } from "@/utils/auth";
 export default {
@@ -341,52 +342,14 @@ export default {
       this.getList();
     },
     // 导出
-    onExport () {
-      let url = "/api-web/export/extraExercisesReplys";
+    async onExport () {
       let obj = this.getDate();
-      const options = {
-        method: "get",
-        headers: {
-          Authorization: getToken()
-        },
-        url,
-        params: obj,
-        responseType: "blob"
-      };
-
-      this.$confirm("您确定导出列表?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning"
-      })
-        .then(() => {
-          axios(options).then(res => {
-            let blob = new Blob([res.data], {
-              // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
-              type: "application/vnd.ms-excel;charset=utf-8"
-              // word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
-            });
-            let objectUrl = URL.createObjectURL(blob);
-            let link = document.createElement("a");
-            let nowTime = new Date();
-            let ymd =
-              nowTime.getFullYear() +
-              "" +
-              (nowTime.getMonth() + 1) +
-              "" +
-              nowTime.getDate() +
-              "" +
-              nowTime.getHours() +
-              "" +
-              nowTime.getMinutes();
-            let fname = ymd + "课外训练(学员).xls";
-            link.href = objectUrl;
-            link.setAttribute("download", fname);
-            document.body.appendChild(link);
-            link.click();
-          });
-        })
-        .catch(() => { });
+      await Export(this, {
+        url: '/api-web/export/extraExercisesReplys',
+        fileName: '课外训练(学员).xlsx',
+        method: 'get',
+        params: obj
+      }, '您确定导出列表?')
     },
     getDate () {
       let obj = {};

+ 1 - 0
src/views/businessManager/orderManager/businessStatement.vue

@@ -43,6 +43,7 @@
         <el-form-item>
           <el-date-picker
             v-model="searchForm.month"
+            style="width: 100% !important"
             type="month"
             placeholder="选择经营月份"
           >

+ 33 - 0
src/views/teamBuild/api.js

@@ -0,0 +1,33 @@
+import request2 from '@/utils/request2'
+
+// 填加学员接口
+export const addMusicGroupRegs = data => request2({
+  url: '/api-web/musicGroup/addMusicGroupRegs',
+  data,
+  method: 'post',
+  requestType: 'json'
+})
+
+// 删除学员
+export const delStudentRegistration = data => request2({
+  url: '/api-web/studentRegistration/del',
+  data,
+  method: 'post',
+  requestType: 'json'
+})
+
+// 删除学员
+export const batchDelStudentRegistration = data => request2({
+  url: '/api-web/studentRegistration/batchDel',
+  data,
+  method: 'post',
+  requestType: 'json'
+})
+
+// 关闭乐团
+export const closeMusicGroup = data => request2({
+  url: '/api-web/musicGroup/closeMusicGroup',
+  data,
+  method: 'post',
+  requestType: 'json'
+})

+ 224 - 0
src/views/teamBuild/components/merge-music.vue

@@ -0,0 +1,224 @@
+<template>
+  <div class="merge-music">
+    <el-button type="primary" @click="visible = true">选择乐团</el-button>
+    <el-button type="primary" @click="studentsVisible = true">已合并学生</el-button>
+    <empty v-if="isEmpty" desc="暂未选择乐团"/>
+    <el-collapse v-model="active" @change="changeActive" class="items" v-else>
+      <el-collapse-item class="item" v-for="(item, key) in items" :key="key" :name="key" >
+        <template #title>
+          <div class="header">
+            <span class="title">
+              <span>{{item.name}}</span>
+            </span>
+            <span style="width: 20%;">
+              <span>学员人数:已选{{item.num}}人</span>
+              <i @click.stop="remove(key)" class="icon el-icon-circle-close"></i>
+            </span>
+          </div>
+        </template>
+        <selectItem :active="active" :id="item.id" @selected="selected"/>
+      </el-collapse-item>
+    </el-collapse>
+    <div class="btns">
+      <el-button @click="$emit('close')">关闭</el-button>
+      <el-button type="primary" @click="merge">确认合并</el-button>
+    </div>
+    <el-dialog
+      title="选择乐团"
+      :visible.sync="visible"
+      width="700px"
+      append-to-body
+    >
+      <selectMusic
+        :visible="visible"
+        @close="visible = false"
+        @submited="submited"
+        :organId="organId"
+      />
+    </el-dialog>
+    <el-dialog
+      title="查看已合并学生"
+      :visible.sync="studentsVisible"
+      width="700px"
+      append-to-body
+    >
+      <mergedStudents
+        @close="studentsVisible = false"
+        @submited="submited"
+      />
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { getTeamList, getPayType } from "@/api/teamServer";
+import { addMusicGroupRegs } from '../api'
+import selectMusic from './select-msic'
+import selectItem from './select-item'
+import mergedStudents from './merged-students'
+export default {
+  props: ['organId']
+,  components: {
+    selectMusic,
+    selectItem,
+    mergedStudents,
+  },
+  data() {
+    return {
+      active: '',
+      visible: false,
+      studentsVisible: false,
+      tableData: [],
+      passed: [],
+      items: {},
+      studentsByMusicId: {}
+    };
+  },
+  computed: {
+    isEmpty() {
+      return Object.keys(this.items).length === 0
+    },
+  },
+  mounted() {
+    // this.FetchList()
+  },
+  methods: {
+    changeActive(val) {
+      this.active = val
+    },
+    submited(vals) {
+      const data = {}
+      for (const item of vals) {
+        if (!data[item.id]) {
+          data[item.id] = {...item, num: 0}
+        } else {
+          data[item.id] = {
+            ...data[item.id],
+            ...item,
+          }
+        }
+      }
+      this.items = data
+    },
+    remove(key) {
+      const data = {...this.items}
+      const select = {...this.studentsByMusicId}
+      delete data[key]
+      delete select[key]
+      this.items = {...data}
+      this.studentsByMusicId = {...select}
+    },
+    selected(list, key) {
+      const data = this.studentsByMusicId
+      if (!data[key]) {
+        data[key] = []
+      }
+      data[key] = list
+      this.items[key].num = list.length
+      this.items = this.items
+      this.studentsByMusicId = data
+    },
+    async merge() {
+      let allId = []
+      for (const key in this.studentsByMusicId) {
+        if (Object.hasOwnProperty.call(this.studentsByMusicId, key)) {
+          const item = this.studentsByMusicId[key]
+          allId = allId.concat(item)
+        }
+      }
+      if (!allId.length) {
+        this.$message.error('请至少选择一个需要合并的学生')
+        return
+      }
+      try {
+        await this.$confirm('是否确认合并乐团?', '提示', {
+          type: 'warning'
+        })
+        await addMusicGroupRegs({
+          musicGroupId: this.$route.query.id,
+          registerIds: allId
+        })
+        this.$message.success('合并成功')
+        this.$emit('chiosetab', 2)
+      } catch (error) {}
+    },
+    handleSelectionChange(arr) {
+      const passed = [];
+      for (let i in arr) {
+        passed.push(arr[i].id);
+      }
+      this.passed = passed;
+    },
+    async FetchList() {
+      try {
+        const res = await getTeamList({
+          organId: this.organId,
+        })
+        this.tableData = res.data.rows
+      } catch (error) {}
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.merge-music{
+  /deep/ .items{
+    margin-top: 20px;
+  }
+  /deep/ .item{
+    /deep/ .el-collapse-item__header.is-active {
+      border-bottom-color: #EBEEF5;
+    }
+    >div:first-child{
+      margin-bottom: 10px;
+    }
+    // margin-bottom: 10px;
+  }
+  /deep/ .header{
+    display: flex;
+    align-items: center;
+    width: 98%;
+    justify-content: space-between;
+    // margin-bottom: 10px;
+    >span:first-child{
+      display: flex;
+      &::before{
+        content: '';
+        display: inline-block;
+        width: 5px;
+        background-color: #14928A;
+        margin-right: 10px;
+        border-radius: 2px;
+        height: 48px;
+        position: absolute;
+      }
+    }
+    .icon{
+      font-size: 18px;
+      font-weight: normal;
+      margin-right: 20px;
+    }
+  }
+}
+.title{
+  position: relative;
+  display: block;
+  max-width: 60%;
+  >span{
+    display: block;
+    margin-left: 20px;
+    font-weight: normal;
+    flex: 1;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    height: 48px;
+    line-height: 48px;
+    white-space: pre;
+  }
+}
+.btns{
+  margin-top: 20px;
+  text-align: right;
+}
+</style>

+ 117 - 0
src/views/teamBuild/components/merged-students.vue

@@ -0,0 +1,117 @@
+<template>
+  <div>
+    <el-form ref="search" :model="search" inline @submit.stop.native="submit" @reset.stop.native="reset">
+      <el-form-item prop="keyword">
+        <el-input v-model.trim="search.keyword" clearable placeholder="学生姓名(手机、编号)"/>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" native-type="submit">搜索</el-button>
+        <el-button type="danger" native-type="reset">重置</el-button>
+        <el-button type="primary" @click="removeStuden" :disabled="!passed.length">删除学员</el-button>
+      </el-form-item>
+    </el-form>
+    <el-table
+      style="width: 100%"
+      max-height="300px"
+      @selection-change="handleSelectionChange"
+      :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+      :data="filterlist"
+    >
+      <el-table-column type="selection"
+        width="50">
+      </el-table-column>
+      <el-table-column prop="realName" align="center" label="学员姓名">
+        <template slot-scope="scope">
+          <copy-text>{{ scope.row.realName }}</copy-text>
+        </template>
+      </el-table-column>
+      <el-table-column prop="phone" align="center" label="手机号码">
+        <template slot-scope="scope">
+          <copy-text>{{ scope.row.phone }}</copy-text>
+        </template>
+      </el-table-column>
+      <el-table-column prop="subjectName" align="center" label="声部">
+        <template slot-scope="scope">
+          <copy-text>{{ scope.row.subjectName }}</copy-text>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+<script>
+import { getTeamStudentList } from '@/api/buildTeam'
+import { batchDelStudentRegistration } from '../api'
+export default {
+  data() {
+    return {
+      id: this.$route.query.id,
+      list: [],
+      filterlist: [],
+      passed: [],
+      search: {
+        keyword: '',
+        hastimer: ''
+      }
+    }
+  },
+  mounted() {
+    this.FetchDetail()
+  },
+  methods: {
+    filter() {
+      const { keyword, hastimer } = this.search
+      this.filterlist = this.list.filter(item => {
+        const user = !keyword || (
+          ('' + item.userId).indexOf(keyword) > -1 ||
+          ('' + item.phone).indexOf(keyword) > -1 ||
+          ('' + item.realName).indexOf(keyword) > -1
+        )
+        return user
+      })
+    },
+    submit(evt) {
+      evt.stopPropagation()
+      evt.stopImmediatePropagation()
+      evt.preventDefault()
+      this.filter()
+    },
+    reset(evt) {
+      evt.stopPropagation()
+      evt.stopImmediatePropagation()
+      evt.preventDefault()
+      this.search = {
+        keyword: '',
+        hastimer: ''
+      }
+      this.filter()
+    },
+    handleSelectionChange(arr) {
+      const passed = [];
+      for (let i in arr) {
+        passed.push(arr[i].userId);
+      }
+      this.passed = passed;
+      // this.$emit('selected', this.passed, this.id)
+    },
+    async removeStuden() {
+      try {
+        await this.$confirm('是否确认删除已选择学员?', '提示', {
+          type: 'warning'
+        })
+        await batchDelStudentRegistration(this.passed)
+        this.$message.success('删除成功')
+        this.FetchDetail()
+      } catch (error) {}
+    },
+    async FetchDetail() {
+      try {
+        const res = await getTeamStudentList({
+          musicGroupId: this.id,
+        })
+        this.list = res.data.rows
+        this.filterlist = res.data.rows
+      } catch (error) {}
+    }
+  }
+}
+</script>

+ 123 - 0
src/views/teamBuild/components/select-item.vue

@@ -0,0 +1,123 @@
+<template>
+  <div>
+    <el-form ref="search" :model="search" inline @submit.stop.native="submit" @reset.stop.native="reset">
+      <el-form-item prop="keyword">
+        <el-input v-model.trim="search.keyword" clearable placeholder="学生姓名(手机、编号)"/>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" native-type="submit">搜索</el-button>
+        <el-button type="danger" native-type="reset">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-table
+      style="width: 100%"
+      max-height="300px"
+      @selection-change="handleSelectionChange"
+      :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+      :data="filterlist"
+    >
+      <el-table-column type="selection"
+        width="50">
+      </el-table-column>
+        <el-table-column prop="id" width="100" align="center" label="乐团编号">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.id }}</copy-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="name" align="center" label="学员姓名">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.name }}</copy-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="parentsName" align="center" label="家长姓名">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.parentsName }}</copy-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="parentsPhone" align="center" label="家长电话">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.parentsPhone }}</copy-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="subjectName" align="center" label="声部">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.subjectName }}</copy-text>
+          </template>
+        </el-table-column>
+    </el-table>
+  </div>
+</template>
+<script>
+import { getMusicGroupStu } from '@/views/resetTeaming/api'
+export default {
+  props: ['id', 'active', 'name'],
+  data() {
+    return {
+      list: [],
+      filterlist: [],
+      passed: [],
+      search: {
+        keyword: '',
+        hastimer: ''
+      }
+    }
+  },
+  watch: {
+    active: {
+      immediate: true,
+      handler() {
+        if (this.active.includes(this.id) && !this.list.length) {
+          this.FetchDetail()
+        }
+      }
+    }
+  },
+  methods: {
+    filter() {
+      const { keyword, hastimer } = this.search
+      this.filterlist = this.list.filter(item => {
+        const user = !keyword || (
+          ('' + item.userId).indexOf(keyword) > -1 ||
+          ('' + item.parentsName).indexOf(keyword) > -1 ||
+          ('' + item.parentsPhone).indexOf(keyword) > -1 ||
+          ('' + item.name).indexOf(keyword) > -1
+        )
+        return user
+      })
+    },
+    submit(evt) {
+      evt.stopPropagation()
+      evt.stopImmediatePropagation()
+      evt.preventDefault()
+      this.filter()
+    },
+    reset(evt) {
+      evt.stopPropagation()
+      evt.stopImmediatePropagation()
+      evt.preventDefault()
+      this.search = {
+        keyword: '',
+        hastimer: ''
+      }
+      this.filter()
+    },
+    handleSelectionChange(arr) {
+      const passed = [];
+      for (let i in arr) {
+        passed.push(arr[i].id);
+      }
+      this.passed = passed;
+      this.$emit('selected', this.passed, this.id)
+    },
+    async FetchDetail() {
+      try {
+        const res = await getMusicGroupStu({
+          musicGroupId: this.id,
+        })
+        this.list = res.data
+        this.filterlist = res.data
+      } catch (error) {}
+    }
+  }
+}
+</script>

+ 151 - 0
src/views/teamBuild/components/select-msic.vue

@@ -0,0 +1,151 @@
+<template>
+  <div class="container" style="width: 100%">
+    <el-form ref="search" :model="search" inline @submit.stop.native="submit" @reset.stop.native="reset">
+      <el-form-item prop="musicGroupName">
+        <el-input v-model.trim="search.musicGroupName" clearable placeholder="乐团名称"/>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" native-type="submit">搜索</el-button>
+        <el-button type="danger" native-type="reset">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-table
+      style="width: 100%"
+      max-height="300px"
+      ref="table"
+      @selection-change="handleSelectionChange"
+      :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+      :data="tableData"
+    >
+      <el-table-column type="selection"
+        :selectable="checkSelectable"
+        width="50">
+      </el-table-column>
+      <el-table-column prop="id" width="100" align="center" label="乐团编号">
+        <template slot-scope="scope">
+          <copy-text>{{ scope.row.id }}</copy-text>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="name"
+        width="200px"
+        align="center"
+        label="乐团名称"
+      >
+        <template slot-scope="scope">
+          <copy-text>{{ scope.row.name }}</copy-text>
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        prop="cooperationOrganName"
+        max-width="274"
+        label="合作单位"
+      >
+      </el-table-column>
+    </el-table>
+    <pagination
+      :total.sync="rules.total"
+      :page.sync="rules.page"
+      :limit.sync="rules.limit"
+      :page-sizes="rules.page_size"
+      layout="prev, pager, next"
+      style="padding: 10px"
+      @pagination="FetchList" />
+    <div class="footer" slot="footer">
+      <el-button @click="$emit('close')">取消</el-button>
+      <el-button @click="submited" type="primary">确认</el-button>
+    </div>
+  </div>
+</template>
+<script>
+import pagination from '@/components/Pagination/index'
+import { getTeamList, getPayType } from "@/api/teamServer";
+export default {
+  props: ['visible', 'organId'],
+  components: { pagination },
+  data() {
+    return {
+      tableData: [],
+      passed: [],
+      rules: {
+        // 分页规则
+        limit: 10, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [10, 20, 40, 50] // 选择限制显示条数
+      },
+      search: {
+        musicGroupName: '',
+        hastimer: ''
+      }
+    };
+  },
+  mounted() {
+    this.FetchList()
+  },
+  watch: {
+    visible() {
+      this.$refs.table.clearSelection()
+      this.passed = []
+    }
+  },
+  methods: {
+    submit(evt) {
+      this.rules.page = 1;
+      evt.stopPropagation()
+      evt.stopImmediatePropagation()
+      evt.preventDefault()
+      this.FetchList()
+    },
+    reset(evt) {
+      this.rules.page = 1;
+      evt.stopPropagation()
+      evt.stopImmediatePropagation()
+      evt.preventDefault()
+      this.search = {
+        musicGroupName: '',
+        hastimer: ''
+      }
+      this.FetchList()
+    },
+    checkSelectable (row) {
+      return true
+    },
+    handleSelectionChange(arr) {
+      const passed = [];
+      for (let i in arr) {
+        let obj = {};
+        obj.id = arr[i].id;
+        obj.name = arr[i].name;
+        passed.push(obj);
+      }
+      this.passed = passed;
+    },
+    async FetchList() {
+      try {
+        const res = await getTeamList({
+          rows: this.rules.limit,
+          page: this.rules.page,
+          organId: this.organId,
+          ...this.search
+        })
+        this.tableData = res.data.rows.filter(item => item.id !== this.$route.query.id)
+          this.rules.total = res.data.total
+      } catch (error) {}
+    },
+    submited() {
+      this.$emit('close')
+      this.$emit('submited', this.passed)
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+.container{
+  /deep/ .footer{
+    text-align: right;
+    margin-top: 20px;
+  }
+}
+</style>

+ 11 - 14
src/views/teamBuild/components/teamBaseInfo.vue

@@ -305,20 +305,7 @@
         <div
           class="nextBtn"
           @click="gotoNext(1)"
-          v-if="
-            teamStatus == 'newTeam' ||
-            teamStatus == 'teamDraft' ||
-            teamStatus == 'teamAudit' ||
-            teamStatus == 'feeAudit'
-          "
-        >
-          下一步
-        </div>
-        <!-- 跨团调整的下一步 -->
-        <div
-          class="nextBtn"
-          v-if="teamStatus == 'teamList'"
-          @click="gotoNext(2)"
+          v-if="showNext"
         >
           下一步
         </div>
@@ -843,6 +830,16 @@ export default {
         })
         .join(",");
     },
+    showNext() {
+      const teamStatus = this.teamStatus
+      console.log(teamStatus)
+      return (
+        teamStatus == 'newTeam' ||
+        teamStatus == 'teamDraft' ||
+        teamStatus == 'teamAudit' ||
+        teamStatus == 'feeAudit'
+      )
+    }
   },
 };
 </script>

+ 15 - 6
src/views/teamBuild/components/teamSoundSet.vue

@@ -9,15 +9,16 @@
                   @getBaseInfo="getBaseInfo"
                   @getNumber="getNumber" />
     <div class="btnWrap">
-      <div class="PrevBtn"
-           @click="goback">上一步</div>
+      <el-button type="primary" @click="goback" style="margin-right: 10px;">上一步</el-button>
       <!--  v-if="teamStatus != 'teamAudit'" -->
-      <div class="submitBtn"
-           v-permission="{
+      <div
+        class="submitBtn"
+        v-permission="{
           child: 'musicGroup/createGroup',
           parent: '/teamBuild/soundMoney',
         }"
-           @click="submitInfo()">
+        @click="submitInfo()"
+      >
         下一步
       </div>
       <!-- <div
@@ -76,6 +77,7 @@ export default {
     };
   },
   mounted () {
+    console.log(this)
     this.teamid = this.$route.query.id;
     this.teamStatus = this.$route.query.type;
   },
@@ -84,6 +86,9 @@ export default {
     this.teamStatus = this.$route.query.type;
   },
   methods: {
+    handleClick(evt) {
+      console.log(evt)
+    },
     goback () {
       this.$emit("chiosetab", 0);
     },
@@ -96,6 +101,10 @@ export default {
     submitAudit (val) {
       this.$refs.soundSetCore.submitInfo(val);
     },
+    selectMusic() {
+      this.$refs.soundSetCore.submitInfo()
+      this.$emit('chiosetab', 3)
+    },
     getNumber (chioseSoundNum, PlannedCount) {
       this.chioseSoundNum = chioseSoundNum;
       this.PlannedCount = PlannedCount;
@@ -206,4 +215,4 @@ export default {
     width: 120px;
   }
 }
-</style>
+</style>

+ 104 - 0
src/views/teamBuild/modals/close-studens.vue

@@ -0,0 +1,104 @@
+<template>
+  <div>
+    <el-form :model="moneys" ref="form">
+      <el-table
+        style="width: 100%"
+        max-height="300px"
+        :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
+        :data="list"
+      >
+        <el-table-column prop="name" align="center" label="学员姓名">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.name }}</copy-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="parentsName" align="center" label="家长姓名">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.parentsName }}</copy-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="parentsPhone" align="center" label="手机号码" width="130">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.parentsPhone }}</copy-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="classGroupName" align="center" label="班级">
+        </el-table-column>
+        <el-table-column prop="subjectName" align="center" label="声部">
+          <template slot-scope="scope">
+            <copy-text>{{ scope.row.subjectName }}</copy-text>
+          </template>
+        </el-table-column>
+        <el-table-column prop="surplusCourseFee" align="center" label="退费金额(元)" width="150">
+          <template slot-scope="scope">
+            <el-form-item :prop="'' + scope.row.userId">
+              <el-input-number
+                :min="0"
+                :max="scope.row.surplusCourseFee"
+                size="mini"
+                :controls="false"
+                :precision="0"
+                v-model="moneys[scope.row.userId]"
+                placeholder="请输入退费金额"
+              />
+            </el-form-item>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button @click="$emit('close')">取 消</el-button>
+      <el-button type="primary" @click="submit">确认</el-button>
+    </div>
+  </div>
+</template>
+<script>
+import { teamSoundStudent } from '@/api/buildTeam'
+import { closeMusicGroup } from '../api'
+export default {
+  props: ['detail'],
+  mounted() {
+    this.FetchList()
+  },
+  data() {
+    return {
+       list: [],
+       moneys: {}
+    }
+  },
+  methods: {
+    async FetchList() {
+      const res = await teamSoundStudent({
+        musicGroupId: this.detail?.id,
+      })
+      this.list = res.data
+      const data = {}
+      for (const item of res.data) {
+        data[item.userId] = item.surplusCourseFee
+      }
+      this.moneys = data
+    },
+    async submit() {
+      try {
+        await this.$confirm('是否确认关闭乐团', '提示', {
+          type: 'warning'
+        })
+        await closeMusicGroup({
+          musicGroupId: this.detail?.id,
+          userReBack: this.moneys
+        })
+        this.$message.success('关闭成功')
+        this.$emit('submited')
+        this.$emit('close')
+      } catch (error) {}
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+  .dialog-footer{
+    margin-top: 20px;
+    display: block;
+    text-align: right;
+  }
+</style>

+ 15 - 0
src/views/teamBuild/signupList.vue

@@ -56,8 +56,18 @@
           >
             报表导出
           </div>
+          <div
+            class="newBand"
+            v-permission="'musicGroup/addMusicGroupRegs'"
+            @click="mergeVisible = true"
+          >
+            合并学员
+          </div>
         </div>
       </div>
+      <el-dialog title="选择合并乐团" :visible.sync="mergeVisible" width="950px">
+        <mergeMusic v-if="mergeVisible" style="padding: 0 20px;" :organId="organId" @close="mergeVisible = false"/>
+      </el-dialog>
       <!--  stepImgs: {
         APPLY: require('@/assets/images/base/clock.png'),
         PAY: require('@/assets/images/base/pay.png')
@@ -607,6 +617,7 @@ import {
   studentApplyDetailExport,
   StudentQuit,
 } from "@/api/buildTeam";
+import mergeMusic from './components/merge-music'
 import { resetStudentSubject, getStudentFeeDetail } from "@/api/studentManager";
 import { vaildStudentUrl, vaildTeacherUrl } from "@/utils/validate";
 import { addVisit } from "@/views/returnVisitManager/api.js";
@@ -624,12 +635,14 @@ export default {
   components: {
     pagination,
     changeVoice,
+    mergeMusic,
   },
   data() {
     return {
       multipleSelection: [], //
       isEdit: false,
       rowDetail: null,
+      mergeVisible: false,
       changeVoiceVisible: false,
       subjectVisible: false,
       orderVisible: false,
@@ -696,6 +709,7 @@ export default {
       qrcodes2: true,
       qrcode2: null,
       codeUrl2: null,
+      organId: '',
       extendPaymentStatus: false,
       extendForm: {
         expireDate: null,
@@ -764,6 +778,7 @@ export default {
       this.pickerOptions = this.beginDate(new Date());
       getTeamBaseInfo({ musicGroupId: this.id }).then((res) => {
         if (res.code == 200) {
+          this.organId = res.data.musicGroup.organId
           this.applyExpireDate = res.data.musicGroup.applyExpireDate;
           this.paymentExpireDate = res.data.musicGroup.paymentExpireDate;
         }

+ 36 - 36
src/views/teamBuild/teamSeting/components/setClassV2.vue

@@ -1669,42 +1669,42 @@ export default {
 
     changeMemo(val) {
       // 声部id
-      let flag = false;
-      if (val.length < 1) {
-        this.soundList.forEach((sound) => {
-          sound.disabled = false;
-          this.appoint = false;
-        });
-      } else {
-        this.soundList.forEach((sound) => {
-          if (sound.id == val[0]) {
-            if (
-              sound.name.indexOf("上低音号") > -1 ||
-              sound.name.indexOf("长号") > -1
-            ) {
-              // 要么选中长号  要么选中上低音号
-              sound.disabled = false;
-              flag = true;
-            } else {
-              sound.disabled = true;
-              this.appoint = true;
-            }
-          }
-        });
-        if (flag) {
-          this.soundList.forEach((sound) => {
-            if (
-              sound.name.indexOf("上低音号") > -1 ||
-              sound.name.indexOf("长号") > -1
-            ) {
-              // 要么选中长号  要么选中上低音号
-              sound.disabled = false;
-            } else {
-              sound.disabled = true;
-            }
-          });
-        }
-      }
+      // let flag = false;
+      // if (val.length < 1) {
+      //   this.soundList.forEach((sound) => {
+      //     sound.disabled = false;
+      //     this.appoint = false;
+      //   });
+      // } else {
+      //   this.soundList.forEach((sound) => {
+      //     if (sound.id == val[0]) {
+      //       if (
+      //         sound.name.indexOf("上低音号") > -1 ||
+      //         sound.name.indexOf("长号") > -1
+      //       ) {
+      //         // 要么选中长号  要么选中上低音号
+      //         sound.disabled = false;
+      //         flag = true;
+      //       } else {
+      //         sound.disabled = true;
+      //         this.appoint = true;
+      //       }
+      //     }
+      //   });
+      //   if (flag) {
+      //     this.soundList.forEach((sound) => {
+      //       if (
+      //         sound.name.indexOf("上低音号") > -1 ||
+      //         sound.name.indexOf("长号") > -1
+      //       ) {
+      //         // 要么选中长号  要么选中上低音号
+      //         sound.disabled = false;
+      //       } else {
+      //         sound.disabled = true;
+      //       }
+      //     });
+      //   }
+      // }
     },
     checkSubject(item) {
       // newClassForm.memo

+ 1 - 1
src/views/teamDetail/components/baseInfo.vue

@@ -193,7 +193,7 @@ export default {
               let ymd = nowTime.getFullYear() + '' + (nowTime.getMonth() + 1) + '' + nowTime.getDate() + '' +
                 nowTime.getHours() +
                 '' + nowTime.getMinutes()
-              let fname = this.$route.query.id + '-' + ymd + '订货清单' //下载文件的名字
+              let fname = this.$route.query.id + '-' + ymd + '订货清单.xls' //下载文件的名字
               link.href = objectUrl
               link.setAttribute("download", fname)
               document.body.appendChild(link)

+ 36 - 36
src/views/teamDetail/components/resetClass.vue

@@ -1439,42 +1439,42 @@ export default {
     },
     changeMemo(val) {
       // 声部id
-      let flag = false;
-      if (val.length < 1) {
-        this.soundList.forEach((sound) => {
-          sound.disabled = false;
-          this.appoint = false;
-        });
-      } else {
-        this.soundList.forEach((sound) => {
-          if (sound.id == val[0]) {
-            if (
-              sound.name.indexOf("上低音号") > -1 ||
-              sound.name.indexOf("长号") > -1
-            ) {
-              // 要么选中长号  要么选中上低音号
-              sound.disabled = false;
-              flag = true;
-            } else {
-              sound.disabled = true;
-              this.appoint = true;
-            }
-          }
-        });
-        if (flag) {
-          this.soundList.forEach((sound) => {
-            if (
-              sound.name.indexOf("上低音号") > -1 ||
-              sound.name.indexOf("长号") > -1
-            ) {
-              // 要么选中长号  要么选中上低音号
-              sound.disabled = false;
-            } else {
-              sound.disabled = true;
-            }
-          });
-        }
-      }
+      // let flag = false;
+      // if (val.length < 1) {
+      //   this.soundList.forEach((sound) => {
+      //     sound.disabled = false;
+      //     this.appoint = false;
+      //   });
+      // } else {
+      //   this.soundList.forEach((sound) => {
+      //     if (sound.id == val[0]) {
+      //       if (
+      //         sound.name.indexOf("上低音号") > -1 ||
+      //         sound.name.indexOf("长号") > -1
+      //       ) {
+      //         // 要么选中长号  要么选中上低音号
+      //         sound.disabled = false;
+      //         flag = true;
+      //       } else {
+      //         sound.disabled = true;
+      //         this.appoint = true;
+      //       }
+      //     }
+      //   });
+      //   if (flag) {
+      //     this.soundList.forEach((sound) => {
+      //       if (
+      //         sound.name.indexOf("上低音号") > -1 ||
+      //         sound.name.indexOf("长号") > -1
+      //       ) {
+      //         // 要么选中长号  要么选中上低音号
+      //         sound.disabled = false;
+      //       } else {
+      //         sound.disabled = true;
+      //       }
+      //     });
+      //   }
+      // }
     },
   },
   watch: {

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

@@ -192,6 +192,10 @@
                 <el-button v-if="permission('recharge/findAll')"
                            type="text"
                            @click="lookSteam(scope.row)">乐团日志</el-button>
+                <!-- 进行中 关闭 -->
+                <el-button type="text"
+                           v-if="scope.row.status == 'PROGRESS' && permission('musicGroup/closeMusicGroup')"
+                           @click="closeTeamDetail(scope.row)">关闭乐团</el-button>
                 <!-- 进行中 查看 -->
                 <el-button type="text"
                            v-if="scope.row.status == 'PROGRESS' && permission('/teamDetails')"
@@ -272,6 +276,9 @@
                      @click="showSteam=false">确 定</el-button>
         </div>
       </el-dialog>
+      <el-dialog :visible.sync="closeVisible" title="确认学员" width="800px">
+        <closeStudens v-if="closeVisible" :detail="closeDetail" @close="closeVisible = false" @submited="getList"/>
+      </el-dialog>
 
     </div>
   </div>
@@ -284,10 +291,13 @@ import { musicGroupStatus } from '@/utils/searchArray'
 import { isObject } from 'util'
 import { permission } from '@/utils/directivePage'
 import teamSteam from './teamListComponent/teamSteam'
+import closeStudens from '../teamBuild/modals/close-studens'
 export default {
   name: "teamList",
   data () {
     return {
+      closeDetail: {},
+      closeVisible: false,
       topForm: {
         teamName: '',
         status: '',
@@ -314,7 +324,8 @@ export default {
   },
   components: {
     pagination,
-    teamSteam
+    teamSteam,
+    closeStudens
   },
   mounted () {
     this.init();
@@ -450,6 +461,10 @@ export default {
 
       }
     },
+    closeTeamDetail(row) {
+      this.closeVisible = true
+      this.closeDetail = {...row}
+    },
     onTeamOpeation (type, row) {
       if (type == 'start') {
         this.$confirm('是否确定开启乐团?', '提示', {