Prechádzať zdrojové kódy

Merge branch '03/03GRADE'

lex-xin 3 rokov pred
rodič
commit
340e512aa3

+ 16 - 17
package.json

@@ -14,54 +14,53 @@
     "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
   },
   "dependencies": {
-    "@babel/plugin-proposal-optional-chaining": "^7.11.0",
     "JSONPath": "^0.11.2",
     "axios": "0.18.1",
-    "browserslist": "^4.16.4",
-    "caniuse-lite": "^1.0.30001214",
+    "browserslist": "^4.16.6",
+    "caniuse-lite": "^1.0.30001244",
     "clean-deep": "^3.3.0",
     "copy-to-clipboard": "^3.3.1",
-    "dayjs": "^1.8.35",
+    "dayjs": "^1.10.6",
     "default-passive-events": "^1.0.10",
     "echarts": "^4.8.0",
-    "element-ui": "^2.13.2",
+    "element-ui": "^2.15.3",
     "http-server": "^0.12.3",
     "i": "^0.3.6",
-    "js-base64": "^3.6.0",
+    "js-base64": "^3.6.1",
     "js-cookie": "2.2.0",
     "linq": "^3.2.2",
-    "lodash": "^4.17.20",
+    "lodash": "^4.17.21",
     "moment": "^2.29.1",
     "node-sass": "^4.13.1",
     "normalize.css": "7.0.0",
-    "npm": "^6.13.0",
+    "npm": "^6.14.13",
     "nprogress": "0.2.0",
     "numeral": "^2.0.6",
     "object-diff": "0.0.4",
     "path-to-regexp": "2.4.0",
     "portal-vue": "^2.1.7",
     "qrcodejs2": "0.0.2",
-    "qs": "^6.8.0",
+    "qs": "^6.10.1",
     "screenfull": "^5.1.0",
-    "swiper": "^6.3.5",
+    "swiper": "^6.7.5",
     "v-charts": "^1.19.0",
     "vue": "2.6.10",
     "vue-amap": "^0.5.10",
     "vue-awesome-swiper": "^4.1.1",
     "vue-count-to": "^1.0.13",
     "vue-drag-resize": "^1.5.4",
-    "vue-lunar-calendar-pro": "^1.0.14",
-    "vue-qr": "^2.2.1",
+    "vue-lunar-calendar-pro": "^1.0.16",
+    "vue-qr": "^2.5.0",
     "vue-quill-editor": "^3.0.6",
     "vue-resize": "^1.0.1",
     "vue-router": "3.0.6",
     "vuex": "3.1.0",
-    "wangeditor": "^4.0.0",
-    "webpack-merge": "^5.3.0"
+    "wangeditor": "^4.7.5",
+    "webpack-merge": "^5.8.0"
   },
   "devDependencies": {
     "@babel/core": "7.0.0",
-    "@babel/plugin-proposal-optional-chaining": "^7.11.0",
+    "@babel/plugin-proposal-optional-chaining": "^7.14.5",
     "@babel/register": "7.0.0",
     "@vue/cli-plugin-babel": "3.6.0",
     "@vue/cli-plugin-eslint": "^3.9.1",
@@ -78,7 +77,7 @@
     "eslint": "5.15.3",
     "eslint-plugin-vue": "5.2.2",
     "html-webpack-plugin": "3.2.0",
-    "less": "^3.10.3",
+    "less": "^3.13.1",
     "less-loader": "^5.0.0",
     "mockjs": "1.0.1-beta3",
     "runjs": "^4.3.2",
@@ -89,7 +88,7 @@
     "svg-sprite-loader": "4.1.3",
     "svgo": "1.2.2",
     "vue-template-compiler": "2.6.10",
-    "worker-loader": "^3.0.7"
+    "worker-loader": "^3.0.8"
   },
   "engines": {
     "node": ">=8.9",

+ 1 - 0
src/utils/searchArray.js

@@ -87,6 +87,7 @@ export const orderStatus = [
   { value: 'GOODS_SELL', label: '商品销售' },
   { value: 'SUBJECT_CHANGE', label: '声部更换' },
   { value: 'MAINTENANCE', label: '乐器保养' },
+  { value: 'ADD_STUDENT', label: '进行中乐团加学员' },
   { value: 'REPLACEMENT', label: '乐器置换' },
   { value: "OTHER", label: "其他" },
 

+ 1 - 0
src/utils/vueFilter.js

@@ -276,6 +276,7 @@ Vue.filter('orderType', value => {
     DEGREE_REGISTRATION: '考级报名',
     MAINTENANCE: '乐器保养',
     REPLACEMENT: '乐器置换',
+    ADD_STUDENT: '进行中乐团加学员',
     OTHER: "其他",
   }
   return template[value]

+ 4 - 1
src/views/studentManager/studentList.vue

@@ -260,7 +260,10 @@
             label="会员截止日期"
           >
           <template slot-scope="scope">
-            <div v-if="scope.row.membershipEndTime" :class="checkDate(scope.row.membershipEndTime)?'':'red'">
+            <div v-if="scope.row.membershipEndTime && scope.row.memberRankSettingId == 0" class="red">
+              会员未生效
+            </div>
+            <div v-else-if="scope.row.membershipEndTime && scope.row.memberRankSettingId != 0" :class="checkDate(scope.row.membershipEndTime)?'':'red'">
               {{scope.row.membershipEndTime|dayjsFormat}}
             </div>
             <div v-else class="red">

+ 9 - 1
src/views/teamBuild/api.js

@@ -70,7 +70,13 @@ export const setNoneCloudTeacher = data => request2({
   method: 'get',
   requestType: 'json'
 })
-
+// 拒绝审核
+export const setCloudTeacherToFailed = data => request2({
+  url: '/api-web/studentRegistration/setCloudTeacherToFailed',
+  params: data,
+  method: 'post',
+  requestType: 'json'
+})
 
 // 意向列表
 export const queryPreApplySubjectList = data => request2({
@@ -87,3 +93,5 @@ export const sendParentMeetingNotice = data => request2({
   method: 'post',
   requestType: 'form'
 })
+
+// 审核拒绝

+ 35 - 23
src/views/teamBuild/modals/change-voice.vue

@@ -94,27 +94,31 @@
           kitGroupPurchaseTypeFormater[changeInfo.kitGroupPurchaseType]
         }}</span>
       </el-form-item>
-      <el-form-item
-        v-if="activeAccessories.length || groupList.length || changeInfo"
-        label="更换教辅"
-        prop="name"
-      >
-        <accessories
-          :list.sync="activeAccessories"
-          :groupList.sync="groupList"
-          @change="accessoriesChange"
-          v-if="!changeInfo"
-        />
-        <span v-else-if="changeInfo">{{ changeAccessoriesGoods }}</span>
-        <!-- <el-select style="width: 100%" v-model="form.accessories" clearable placeholder="请选择教辅">
-          <el-option
-            v-for="item in accessories"
-            :key="item.id"
-            :label="item.name"
-            :value="item.id">
-          </el-option>
-        </el-select> -->
-      </el-form-item>
+      <template >
+        <el-form-item
+          v-show="(courseViewType == 2 && form.musicalGoods == 'OWNED') || courseViewType != 2"
+          v-if="activeAccessories.length || groupList.length || changeInfo"
+          label="更换教辅"
+          class="is-required"
+        >
+          <accessories
+            :list.sync="activeAccessories"
+            :groupList.sync="groupList"
+            @change="accessoriesChange"
+            v-if="!changeInfo"
+          />
+          <span v-else-if="changeInfo">{{ changeAccessoriesGoods }}</span>
+          <!-- <el-select style="width: 100%" v-model="form.accessories" clearable placeholder="请选择教辅">
+            <el-option
+              v-for="item in accessories"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id">
+            </el-option>
+          </el-select> -->
+        </el-form-item>
+      </template>
+
       <el-form-item label="查看链接" prop="name" v-if="changeInfo">
         <div class="viewlink">
           <el-tooltip
@@ -278,7 +282,7 @@ const typeAndprice = {
 };
 
 export default {
-  props: ["detail", "musicGroupId", "voiceList"],
+  props: ["detail", "musicGroupId", "voiceList", "courseViewType"],
   components: {
     accessories,
   },
@@ -406,7 +410,6 @@ export default {
     },
   },
   mounted() {
-    console.log(this.detail)
     if (this.detail && (this.detail.userId)) {
       this.fetchDetail();
     }
@@ -471,6 +474,11 @@ export default {
       this.musicalGoodsChange();
     },
     musicalGoodsChange(val) {
+      this.$refs["form"].clearValidate()
+      if(val != 'OWNED') {
+        this.selectAccessories = []
+        this.selectAccessoriesMoney = 0
+      }
       const item = this.musicalGoodsById[val];
       if (item) {
         this.musicalPrice = this.numFormat(
@@ -517,6 +525,10 @@ export default {
       this.$refs["form"].validate((valid) => {
         this.detail.subjectId
         if (valid) {
+          if(this.courseViewType == 2 && this.form.musicalGoods == 'OWNED' && this.selectAccessories && this.selectAccessories.length <= 0) {
+            this.$message.error('请至少选择一个教辅')
+            return
+          }
           subjectChangeAdd({
             changeCourseFee: this.numFormat(
               this.musicGroupSubjectPlanFee -

+ 174 - 97
src/views/teamBuild/signupList.vue

@@ -220,6 +220,75 @@
                     </div>
                   </template>
                 </el-table-column>
+                <el-table-column label="购买云教练人数" prop="buyCloudTeacherNum" align="center">
+                  <template slot="header">
+                    <p>
+                      购买云教练人数
+                      <el-tooltip placement="top" popper-class="mTooltip">
+                        <div slot="content">
+                          已缴费学员中购买了云教练系统的学员总数
+                        </div>
+                        <i
+                          class="el-icon-question"
+                          style="font-size: 18px; color: #f56c6c"
+                        ></i>
+                      </el-tooltip>
+                    </p>
+                  </template>
+                  <template slot-scope="scope">
+                    <div>
+                      <el-button type="text" @click="getCheckNum(scope.row, 'buyCloud')">{{
+                        scope.row.buyCloudTeacherNum
+                      }}</el-button>
+                    </div>
+                  </template>
+                </el-table-column>
+                <el-table-column label="入团未购云教练" prop="noCloudTeacherStudentNumOfNormal" align="center">
+                  <template slot="header">
+                    <p>
+                      入团未购云教练
+                      <el-tooltip placement="top" popper-class="mTooltip">
+                        <div slot="content">
+                          【在读】学员中,未购买【云教练系统】学员数量
+                        </div>
+                        <i
+                          class="el-icon-question"
+                          style="font-size: 18px; color: #f56c6c"
+                        ></i>
+                      </el-tooltip>
+                    </p>
+                  </template>
+                  <template slot-scope="scope">
+                    <div>
+                      <el-button type="text" @click="getCheckNum(scope.row, 'noCloud')">{{
+                        scope.row.noCloudTeacherStudentNumOfNormal
+                      }}</el-button>
+                    </div>
+                  </template>
+                </el-table-column>
+                <!-- <el-table-column label="购买乐器未入团人数" prop="cloudTeacherStudentNumOfApply" align="center">
+                  <template slot="header">
+                    <p>
+                      购买乐器未入团人数
+                      <el-tooltip placement="top" popper-class="mTooltip">
+                        <div slot="content">
+                          只购买乐器未解除限制学员数量(不包括退团学员)
+                        </div>
+                        <i
+                          class="el-icon-question"
+                          style="font-size: 18px; color: #f56c6c"
+                        ></i>
+                      </el-tooltip>
+                    </p>
+                  </template>
+                  <template slot-scope="scope">
+                    <div>
+                      <el-button type="text" @click="getCheckNum(scope.row, 'cloudTeacher')">{{
+                        scope.row.cloudTeacherStudentNumOfApply
+                      }}</el-button>
+                    </div>
+                  </template>
+                </el-table-column> -->
               </el-table>
               <div
                 class="btnWrap"
@@ -391,6 +460,19 @@
             <el-option label="审核中" :value="2"></el-option>
           </el-select>
         </el-form-item>
+        <el-form-item prop="studentStatus">
+          <el-select
+            v-model.trim="searchFrom.studentStatus"
+            clearable
+            filterable
+            placeholder="学员状态"
+          >
+            <el-option label="在读" value="NORMAL"></el-option>
+            <!-- <el-option label="请假" value="LEAVE"></el-option>
+            <el-option label="退团" value="QUIT"></el-option> -->
+            <el-option label="报名" value="APPLY"></el-option>
+          </el-select>
+      </el-form-item>
         <!-- 专业actualSubjectId 调剂isAllowAdjust 手机号name -->
         <el-form-item>
           <el-button type="danger" native-type="search">搜索</el-button>
@@ -482,6 +564,13 @@
             </div>
           </template>
         </el-table-column>
+        <el-table-column label="学员状态" prop="studentStatus" align="center">
+          <template slot-scope="scope">
+            <div>
+              {{ scope.row.studentStatus | musicGroupStudentType }}
+            </div>
+          </template>
+        </el-table-column>
         <el-table-column label="订单状态" prop="payingStatus" align="center">
           <template slot-scope="scope">
             <div>
@@ -617,6 +706,14 @@
                   >解除预约限制</el-button
                 >
               </auth>
+              <auth
+
+                :auths="'studentRegistration/setCloudTeacherToFailed'"
+              >
+                <el-button type="text"    v-if="scope.row.payingStatus == 2" @click="failedRelieve(scope.row)"
+                  >拒绝审核</el-button
+                >
+              </auth>
             </div>
           </template>
         </el-table-column>
@@ -711,43 +808,21 @@
       </div>
     </el-dialog>
 
-    <el-dialog title="订单详情" :visible.sync="orderVisible" width="600px">
-      <el-form :model="orderForm" :inline="true">
-        <!--     name: '',
-        totalAmount: '',
-        subject: '',
-        subjectFee: '',
-        axe: '',
-        axePrice: '',
-        others: '',
-        othersPrice: '' -->
-        <el-form-item label="学员姓名">
-          <el-input v-model.trim="orderForm.name" disabled=""></el-input>
-        </el-form-item>
-        <el-form-item label="实缴金额">
-          <el-input v-model.trim="orderForm.totalAmount" disabled=""></el-input>
-        </el-form-item>
-        <el-form-item label="实际专业">
-          <el-input v-model.trim="orderForm.subject" disabled=""></el-input>
-        </el-form-item>
-        <el-form-item label="课程费用">
-          <el-input v-model.trim="orderForm.subjectFee" disabled=""></el-input>
-        </el-form-item>
-        <el-form-item label="选择乐器">
-          <el-input v-model.trim="orderForm.axe" disabled=""></el-input>
-        </el-form-item>
-        <el-form-item label="乐器价格">
-          <el-input v-model.trim="orderForm.axePrice" disabled=""></el-input>
-        </el-form-item>
-        <el-form-item label="教辅组合">
-          <el-input v-model.trim="orderForm.others" disabled=""></el-input>
-        </el-form-item>
-        <el-form-item label="组合价格">
-          <el-input v-model.trim="orderForm.othersPrice" disabled=""></el-input>
-        </el-form-item>
-      </el-form>
+    <el-dialog title="订单详情" :visible.sync="orderVisible" width="800px">
+      <template v-if="orderForm.length > 0">
+        <descriptions :column="2">
+          <template v-for="(item, index) in orderForm">
+            <descriptions-item :key="index" :label="item.name">{{ item.price | moneyFormat }}元</descriptions-item>
+            <descriptions-item :key="index" label="缴费时间">{{ item.createTime }}</descriptions-item>
+          </template>
+        </descriptions>
+      </template>
+      <el-row v-else>
+        <el-col :span="24">
+          <empty desc="暂无订单详情" />
+        </el-col>
+      </el-row>
       <div slot="footer" class="dialog-footer">
-        <!-- <el-button>取 消</el-button> -->
         <el-button type="primary" @click="orderVisible = false"
           >确 定</el-button
         >
@@ -849,6 +924,7 @@
         @close="closeChangeVoice"
         @submited="getList"
         :detail.sync="rowDetail"
+        :courseViewType="courseViewType"
         :musicGroupId="id"
         :voiceList="leftList"
       />
@@ -876,7 +952,7 @@ import {
   checkCanReg,
 } from "@/api/buildTeam";
 
-import { setNoneCloudTeacher } from "./api";
+import { setNoneCloudTeacher, setCloudTeacherToFailed } from "./api";
 import mergeMusic from "./components/merge-music";
 import forecastList from "./components/forecast-list";
 import newForecastList from "./components/newForecast-list";
@@ -893,7 +969,8 @@ import { permission } from "@/utils/directivePage";
 import cleanDeep from "clean-deep";
 import changeVoice from "./modals/change-voice";
 import visit from "@/views/withdrawal-application/modals/visit";
-import quiteTeam from "@/views/teamDetail/components/modals/quite-team";
+import quiteTeam from "@/views/teamDetail/components/modals/quite-team"
+import { courseType } from '@/constant/index'
 export default {
   name: "signupList",
   components: {
@@ -930,6 +1007,7 @@ export default {
         hasCloudTeacher: null, // 是否购买云教练
         payingStatus: null,
         noneNeedCloudTeacher: null,
+        studentStatus: null
       },
       quitForm: {
         // 退团信息确认
@@ -962,16 +1040,7 @@ export default {
       },
       activeId: "",
       soundList: [],
-      orderForm: {
-        name: "",
-        totalAmount: "",
-        subject: "",
-        subjectFee: "",
-        axe: "",
-        axePrice: "",
-        others: "",
-        othersPrice: "",
-      },
+      orderForm: [],
       paymentStatus: false,
       paymentForm: {
         paymentExpireDate: null,
@@ -1050,6 +1119,7 @@ export default {
       detail: null,
       gradeList: [],
       ischeckCanReg: false,
+      courseViewType: null, // 乐团模式
     };
   },
   created() {},
@@ -1086,7 +1156,6 @@ export default {
         this.ischeckCanReg = await (
           await checkCanReg({ musicGroupId: this.id })
         ).data;
-        console.log(this.ischeckCanReg);
       } catch (e) {
         console.log(e);
       }
@@ -1106,6 +1175,7 @@ export default {
       getTeamBaseInfo({ musicGroupId: this.id }).then((res) => {
         if (res.code == 200) {
           this.organId = res.data.musicGroup.organId;
+          this.courseViewType = res.data.musicGroup.courseViewType;
           this.applyExpireDate = res.data.musicGroup.applyExpireDate;
           this.paymentExpireDate = res.data.musicGroup.paymentExpireDate;
         }
@@ -1136,6 +1206,7 @@ export default {
         visited: null,
         hasCloudTeacher: null,
         payingStatus: null,
+        studentStatus: null,
         noneNeedCloudTeacher: null,
       };
       this.getList();
@@ -1164,6 +1235,7 @@ export default {
         visited: this.searchFrom.visited || null,
         hasCloudTeacher: this.searchFrom.hasCloudTeacher,
         payingStatus: this.searchFrom.payingStatus,
+        studentStatus: this.searchFrom.studentStatus,
         noneNeedCloudTeacher: this.searchFrom.noneNeedCloudTeacher,
         page: this.rules.page,
         rows: this.rules.limit,
@@ -1429,7 +1501,6 @@ export default {
     },
     // 修改专业
     resetSubject(row) {
-      console.log(row);
       this.activeId = row.studentId;
       this.maskForm.subject = row.actualSubjectId;
       this.subjectVisible = true;
@@ -1501,45 +1572,31 @@ export default {
         }
       });
     },
-    lookdetail(row) {
-      this.orderVisible = true;
-      this.activeId = row.studentId;
-      this.orderForm.name = row.studentName;
-      this.orderForm.subject = row.subjectName;
-      getStudentFeeDetail({
+    async lookdetail(row) {
+      await getStudentFeeDetail({
         musicGroupId: this.id,
         studentId: row.studentId,
       }).then((res) => {
         if (res.code == 200) {
-          if (res.data) {
-            this.orderForm.totalAmount = res.data.totalAmount;
-            // this.orderForm.subjectFee = res.data.courseFee;
-            let goodStr = "";
-            let goodPrice = 0;
-            let otherStr = "";
-            let othersPrice = 0;
-            for (let i in res.data.goods) {
-              if (res.data.goods[i].goodsType == "INSTRUMENT") {
-                goodStr += res.data.goods[i].goodsName + ",";
-                goodPrice += parseFloat(res.data.goods[i].musicalFee);
-                // this.orderForm.axe = res.data.goods[i].goodsName;
-                // this.orderForm.axePrice = res.data.goods[i].musicalFee;
-              } else if (res.data.goods[i].goodsType == "ACCESSORIES") {
-                otherStr += res.data.goods[i].goodsName + ",";
-                othersPrice += parseFloat(res.data.goods[i].musicalFee);
-                // this.orderForm.others = res.data.goods[i].goodsName;
-                // this.orderForm.othersPrice = res.data.goods[i].musicalFee;
-              } else if (res.data.goods[i].goodsType == "COURSE") {
-                this.orderForm.subjectFee = res.data.goods[i].musicalFee;
-              }
+          const paymentList = res.data || []
+          paymentList.forEach(item => {
+            if(item.type == 'MAINTENANCE') {
+              item.name = '乐器保养'
+            } else if(item.type == 'CLOUD_TEACHER') {
+              item.name = '乐器练习云教练'
+            } else if(item.type == 'COURSE') {
+              item.name = '课程'
             }
-            this.orderForm.others = otherStr.substring(0, otherStr.length - 1);
-            this.orderForm.othersPrice = othersPrice;
-            this.orderForm.axe = goodStr.substring(0, goodStr.length - 1);
-            this.orderForm.axePrice = goodPrice;
-          }
+            if(courseType[item.type]) {
+              item.name = courseType[item.type]
+            }
+          })
+          this.orderForm = paymentList
         }
       });
+
+      this.activeId = row.studentId;
+      this.orderVisible = true;
     },
     saveIsEdit() {
       // 提交数据
@@ -1658,7 +1715,6 @@ export default {
         for (const item of res.data.rows) {
           if (item.id === row.id) {
             this.rowDetail = { ...item, userId: item.studentId };
-            // console.log(this.rowDetail)
             this.changeVoiceVisible = true;
           }
         }
@@ -1761,7 +1817,22 @@ export default {
         }
       });
     },
-    getCheckNum(row) {
+    failedRelieve(row) {
+      this.$confirm("拒绝后学员需购买会员方可入团", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(async () => {
+        try {
+          const res = await setCloudTeacherToFailed({ id: row.id });
+          this.$message.success("操作成功");
+          this.getList();
+        } catch (e) {
+          console.log(e);
+        }
+      });
+    },
+    getCheckNum(row, type) {
       this.rules.page = 1;
       this.rules.limit = 10;
       this.searchFrom = {
@@ -1773,12 +1844,19 @@ export default {
         visited: null,
         hasCloudTeacher: null,
         payingStatus: null,
+        studentStatus: null,
         noneNeedCloudTeacher: null,
       };
       this.searchFrom.subject = row.subjectId;
-
-      this.searchFrom.payingStatus = 2;
-      this.searchFrom.hasCloudTeacher = 0;
+      if(type == 'buyCloud') {
+        this.searchFrom.hasCloudTeacher = 1
+      } else if(type == 'noCloud') {
+        this.searchFrom.hasCloudTeacher = 0
+        this.searchFrom.studentStatus = 'NORMAL'
+      } else {
+        this.searchFrom.payingStatus = 2;
+        this.searchFrom.hasCloudTeacher = 0;
+      }
       this.search();
     },
     getpayingNum(row) {
@@ -1793,6 +1871,7 @@ export default {
         visited: null,
         hasCloudTeacher: null,
         payingStatus: null,
+        studentStatus: null,
         noneNeedCloudTeacher: null,
       };
       this.searchFrom.subject = row.subjectId;
@@ -1811,6 +1890,7 @@ export default {
         visited: null,
         hasCloudTeacher: null,
         payingStatus: null,
+        studentStatus: null,
         noneNeedCloudTeacher: null,
       };
       this.searchFrom.subject = row.subjectId;
@@ -1828,16 +1908,7 @@ export default {
     },
     orderVisible(val) {
       if (!val) {
-        this.orderForm = {
-          name: "",
-          totalAmount: "",
-          subject: "",
-          subjectFee: "",
-          axe: "",
-          axePrice: "",
-          others: "",
-          othersPrice: "",
-        };
+        this.orderForm = []
       }
     },
     qrcodeStatus(val) {
@@ -2047,4 +2118,10 @@ export default {
     line-height: 25px;
   }
 }
+/deep/.description-title {
+  margin-bottom: 0;
+}
+/deep/.description-label {
+  white-space: normal !important;
+}
 </style>