signupList.vue 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025
  1. <template>
  2. <div class="sigup-container">
  3. <div class="topWrap">
  4. <div>
  5. <div style="display: flex; justify-content: space-between">
  6. <div
  7. style="
  8. display: flex;
  9. margin-bottom: 15px;
  10. font-size: 18px;
  11. font-weight: 400;
  12. "
  13. >
  14. <p style="margin-right: 10px" v-if="applyExpireDate">
  15. 报名截止时间:{{ applyExpireDate | formatTimer }}
  16. </p>
  17. <p v-if="paymentExpireDate">
  18. 缴费截止时间:{{ paymentExpireDate | formatTimer }}
  19. </p>
  20. </div>
  21. </div>
  22. <div class="btnList">
  23. <!-- <div class='newBand close'
  24. v-permission="'musicGroup/cancelMusicGroup'"
  25. @click="onClose">停止乐团</div> v-show="status == 'APPLY'"-->
  26. <div
  27. class="newBand"
  28. @click="payStart"
  29. v-permission="'musicGroup/openPay'"
  30. v-if="status == 'APPLY'"
  31. >
  32. 开始缴费
  33. </div>
  34. <!-- v-show="status=='PAY'" -->
  35. <div
  36. class="newBand"
  37. v-permission="'musicGroup/found'"
  38. @click="onGoHome"
  39. v-if="status == 'APPLY' || status == 'PAY'"
  40. >
  41. 确认开团
  42. </div>
  43. <div
  44. class="newBand"
  45. v-permission="'musicGroup/extensionPayment'"
  46. @click="extendTime(true)"
  47. v-show="
  48. status == 'PAY' || status == 'PROGRESS' || status == 'PREPARE'
  49. "
  50. >
  51. 延长缴费
  52. </div>
  53. <div
  54. class="newBand"
  55. v-permission="'musicGroup/extensionApplyExpireDate'"
  56. @click="extendTime(false)"
  57. v-show="
  58. status == 'PAY' ||
  59. status == 'APPLY' ||
  60. status == 'PROGRESS' ||
  61. status == 'PREPARE'
  62. "
  63. >
  64. 延长报名
  65. </div>
  66. <div
  67. class="newBand"
  68. @click="onCreateQRCode('payment')"
  69. v-show="
  70. (status == 'PAY' ||
  71. status == 'APPLY' ||
  72. status == 'PROGRESS' ||
  73. status == 'PREPARE') &&
  74. ischeckCanReg
  75. "
  76. >
  77. 报名链接
  78. </div>
  79. <div class="newBand" @click="onCreateQRCode('detail')">缴费详情</div>
  80. <auth :auths="'studentRegistration/queryPreApplyList/4263'">
  81. <div
  82. class="newBand"
  83. style="margin-right: 0"
  84. @click="forecastVisible = true"
  85. >
  86. 预报名名单
  87. </div>
  88. </auth>
  89. <!-- v-permission="getFullPermission('musicGroup/addMusicGroupRegs')" -->
  90. <div
  91. class="newBand"
  92. v-permission="'musicGroup/addMusicGroupRegs'"
  93. @click="mergeVisible = true"
  94. v-show="
  95. (status == 'PAY' ||
  96. status == 'APPLY' ||
  97. status == 'PROGRESS' ||
  98. status == 'PREPARE') &&
  99. ischeckCanReg
  100. "
  101. >
  102. 合并学员
  103. </div>
  104. <div
  105. class="newBand"
  106. style="background-color: #f97215; border: 1px solid #f97215"
  107. @click="onCreateQRCode('rePayment')"
  108. v-show="
  109. (status == 'PAY' ||
  110. status == 'APPLY' ||
  111. status == 'PROGRESS' ||
  112. status == 'PREPARE') &&
  113. ischeckCanReg
  114. "
  115. >
  116. 报名链接(无乐器)
  117. </div>
  118. <div
  119. class="newBand"
  120. v-permission="'studentRegistration/queryStudentApplyDetailExport'"
  121. @click="onDownLoadExecl"
  122. >
  123. 名单导出
  124. </div>
  125. <auth :auths="'studentRegistration/getRegisterOrPreList'">
  126. <div
  127. class="newBand"
  128. style="margin-right: 0"
  129. @click="newForecastVisible = true"
  130. >
  131. 时间数据统计
  132. </div>
  133. </auth>
  134. <auth :auths="'subject/findSubApplyDetail'">
  135. <el-popover placement="bottom" width="1000" trigger="hover">
  136. <el-table
  137. style="width: 100% !important"
  138. :data="leftList"
  139. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  140. >
  141. <el-table-column
  142. label="乐团声部"
  143. prop="subjectName"
  144. align="center"
  145. >
  146. </el-table-column>
  147. <el-table-column
  148. label="计划招生"
  149. prop="expectedStudentNum"
  150. align="center"
  151. >
  152. <template slot-scope="scope">
  153. <div>
  154. <p v-show="!isEdit">{{ scope.row.expectedStudentNum }}</p>
  155. <el-input
  156. v-show="isEdit"
  157. v-model.trim="scope.row.expectedStudentNum"
  158. ></el-input>
  159. </div>
  160. </template>
  161. </el-table-column>
  162. <el-table-column
  163. label="已报名"
  164. prop="applyStudentNum"
  165. align="center"
  166. >
  167. </el-table-column>
  168. <el-table-column label="已缴费" prop="payNum" align="center">
  169. <template slot-scope="scope">
  170. <div>
  171. <el-button type="text" @click="getpayNum(scope.row)">{{
  172. scope.row.payNum
  173. }}</el-button>
  174. </div>
  175. </template>
  176. </el-table-column>
  177. <el-table-column label="缴费中" prop="payingNum" align="center">
  178. <template slot="header">
  179. <p>
  180. 缴费中
  181. <el-tooltip placement="top" popper-class="mTooltip">
  182. <div slot="content">提交订单尚未支付成功学员</div>
  183. <i
  184. class="el-icon-question"
  185. style="font-size: 18px; color: #f56c6c"
  186. ></i>
  187. </el-tooltip>
  188. </p>
  189. </template>
  190. <template slot-scope="scope">
  191. <div>
  192. <el-button type="text" @click="getpayingNum(scope.row)">{{
  193. scope.row.payingNum
  194. }}</el-button>
  195. </div>
  196. </template>
  197. </el-table-column>
  198. <el-table-column label="审核中" prop="checkNum" align="center">
  199. <template slot="header">
  200. <p>
  201. 审核中
  202. <el-tooltip placement="top" popper-class="mTooltip">
  203. <div slot="content">
  204. 不购买云教练系统学员数量,不包含已缴费学员
  205. </div>
  206. <i
  207. class="el-icon-question"
  208. style="font-size: 18px; color: #f56c6c"
  209. ></i>
  210. </el-tooltip>
  211. </p>
  212. </template>
  213. <template slot-scope="scope">
  214. <div>
  215. <el-button type="text" @click="getCheckNum(scope.row)">{{
  216. scope.row.checkNum
  217. }}</el-button>
  218. </div>
  219. </template>
  220. </el-table-column>
  221. </el-table>
  222. <div
  223. class="btnWrap"
  224. v-permission="'musicGroup/updateExpectedStudentNum'"
  225. style="margin-right: 20px; margin-top: 20px"
  226. >
  227. <el-button
  228. v-show="
  229. !isEdit &&
  230. (status == 'PAY' ||
  231. status == 'APPLY' ||
  232. status == 'PROGRESS' ||
  233. status == 'PREPARE')
  234. "
  235. @click="isEdit = true"
  236. >编辑</el-button
  237. >
  238. <el-button v-show="isEdit" @click="saveIsEdit">保存</el-button>
  239. </div>
  240. <div class="newBand" slot="reference">人数统计</div>
  241. </el-popover>
  242. </auth>
  243. </div>
  244. </div>
  245. <el-dialog
  246. title="选择合并乐团"
  247. :visible.sync="mergeVisible"
  248. width="950px"
  249. >
  250. <mergeMusic
  251. v-if="mergeVisible"
  252. style="padding: 0 20px"
  253. :organId="organId"
  254. @close="mergeVisible = false"
  255. @submited="getList"
  256. />
  257. </el-dialog>
  258. <el-dialog
  259. title="时间数据统计"
  260. :visible.sync="newForecastVisible"
  261. width="1100px"
  262. >
  263. <newForecastList
  264. v-if="newForecastVisible"
  265. @close="newForecastVisible = false"
  266. />
  267. </el-dialog>
  268. <el-dialog
  269. title="预报名名单"
  270. :visible.sync="forecastVisible"
  271. width="1100px"
  272. >
  273. <forecastList v-if="forecastVisible" @close="forecastVisible = false" />
  274. </el-dialog>
  275. <!-- stepImgs: {
  276. APPLY: require('@/assets/images/base/clock.png'),
  277. PAY: require('@/assets/images/base/pay.png')
  278. }, -->
  279. </div>
  280. <div class="searchList">
  281. <save-form
  282. :inline="true"
  283. :model="searchFrom"
  284. @submit="search"
  285. @reset="onReset"
  286. >
  287. <el-form-item>
  288. <el-select
  289. v-model.trim="searchFrom.subject"
  290. filterable
  291. clearable
  292. placeholder="请选择专业"
  293. >
  294. <el-option
  295. v-for="(item, index) in soundList"
  296. :key="index"
  297. :label="item.name"
  298. :value="item.id"
  299. ></el-option>
  300. </el-select>
  301. </el-form-item>
  302. <el-form-item>
  303. <el-select
  304. v-model.trim="searchFrom.isAllowAdjust"
  305. filterable
  306. placeholder="请选择是否允许调剂"
  307. clearable
  308. >
  309. <el-option label="是" value="1"></el-option>
  310. <el-option label="否" value="0"></el-option>
  311. </el-select>
  312. </el-form-item>
  313. <el-form-item>
  314. <el-input
  315. v-model.trim="searchFrom.name"
  316. placeholder="请输入用户名或手机号"
  317. clearable
  318. ></el-input>
  319. </el-form-item>
  320. <el-form-item>
  321. <!-- <el-input v-model.trim="searchFrom.currentGrade" placeholder="请输入年级" clearable></el-input> -->
  322. <el-select
  323. v-model.trim="searchFrom.currentGrade"
  324. filterable
  325. clearable
  326. placeholder="请输入年级"
  327. >
  328. <el-option
  329. v-for="(item, index) in gradeList"
  330. :key="index"
  331. :label="item.label"
  332. :value="item.label"
  333. ></el-option>
  334. </el-select>
  335. </el-form-item>
  336. <el-form-item>
  337. <el-select
  338. v-model.trim="searchFrom.paymentStatus"
  339. clearable
  340. filterable
  341. placeholder="报名缴费"
  342. >
  343. <el-option label="未开启缴费" value="0"></el-option>
  344. <el-option label="开启缴费" value="1"></el-option>
  345. <el-option label="已缴费" value="2"></el-option>
  346. </el-select>
  347. </el-form-item>
  348. <el-form-item>
  349. <el-select
  350. v-model.trim="searchFrom.visited"
  351. clearable
  352. filterable
  353. placeholder="是否回访"
  354. >
  355. <el-option label="否" value="false"></el-option>
  356. <el-option label="是" value="true"></el-option>
  357. </el-select>
  358. </el-form-item>
  359. <el-form-item>
  360. <el-select
  361. v-model.trim="searchFrom.hasCloudTeacher"
  362. clearable
  363. filterable
  364. placeholder="是否购买云教练"
  365. >
  366. <el-option label="是" :value="1"></el-option>
  367. <el-option label="否" :value="0"></el-option>
  368. </el-select>
  369. </el-form-item>
  370. <el-form-item>
  371. <el-select
  372. v-model.trim="searchFrom.noneNeedCloudTeacher"
  373. clearable
  374. filterable
  375. placeholder="是否解除限制"
  376. >
  377. <el-option label="是" :value="1"></el-option>
  378. <el-option label="否" :value="0"></el-option>
  379. </el-select>
  380. </el-form-item>
  381. <el-form-item>
  382. <el-select
  383. v-model.trim="searchFrom.payingStatus"
  384. clearable
  385. filterable
  386. placeholder="订单状态"
  387. >
  388. <el-option label="缴费中" :value="1"></el-option>
  389. <el-option label="审核中" :value="2"></el-option>
  390. </el-select>
  391. </el-form-item>
  392. <!-- 专业actualSubjectId 调剂isAllowAdjust 手机号name -->
  393. <el-form-item>
  394. <el-button type="danger" native-type="search">搜索</el-button>
  395. <el-button type="primary" native-type="reset">重置</el-button>
  396. </el-form-item>
  397. </save-form>
  398. </div>
  399. <div>
  400. <el-table
  401. :data="rightList"
  402. ref="multipleTable"
  403. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  404. @selection-change="handleSelectionChange"
  405. >
  406. <el-table-column
  407. type="selection"
  408. width="55"
  409. :selectable="checkboxSelect"
  410. >
  411. </el-table-column>
  412. <el-table-column label="学员姓名" prop="studentName" align="center">
  413. <template slot-scope="scope">
  414. <div>{{ scope.row.studentName }}({{ scope.row.gender | sex }})</div>
  415. </template>
  416. </el-table-column>
  417. <el-table-column label="家长姓名" prop="parentsName" align="center">
  418. </el-table-column>
  419. <el-table-column align="center" label="入团年份">
  420. <template slot-scope="scope">
  421. <div>
  422. {{ scope.row.createTime | dayjsFormat("YYYY年") }}
  423. </div>
  424. </template>
  425. </el-table-column>
  426. <el-table-column label="联系电话" prop="parentsPhone" align="center">
  427. </el-table-column>
  428. <el-table-column label="年级班级" align="center">
  429. <template slot-scope="scope">
  430. <div>
  431. {{ scope.row.currentGrade + scope.row.currentClass }}
  432. </div>
  433. </template>
  434. </el-table-column>
  435. <!-- <el-table-column label="性别" prop="gender" align="center">
  436. <template slot-scope="scope">
  437. <div>
  438. {{ scope.row.gender | sex }}
  439. </div>
  440. </template>
  441. </el-table-column> -->
  442. <el-table-column label="服从调剂" prop="isAllowAdjust" align="center">
  443. <template slot-scope="scope">
  444. <div>
  445. {{ scope.row.isAllowAdjust | isAllowAdjust }}
  446. </div>
  447. </template>
  448. </el-table-column>
  449. <!-- <el-table-column label="报名专业" prop="subjectName" align="center">
  450. </el-table-column> -->
  451. <el-table-column
  452. label="报名/调剂专业"
  453. prop="actualSubjectName"
  454. align="center"
  455. >
  456. <template slot-scope="scope">
  457. <div>
  458. {{ scope.row.subjectName }} / {{ scope.row.actualSubjectName }}
  459. </div>
  460. </template>
  461. </el-table-column>
  462. <el-table-column label="是否回访" prop="paymentStatus" align="center">
  463. <template slot-scope="scope">
  464. <div>
  465. {{ scope.row.visitNum ? "是" : "否" }}
  466. </div>
  467. </template>
  468. </el-table-column>
  469. <!-- visited -->
  470. <!-- v-show='status == "PAY"' -->
  471. <el-table-column
  472. label="报名缴费状态"
  473. prop="paymentStatus"
  474. align="center"
  475. >
  476. <template slot-scope="scope">
  477. <div>
  478. {{ scope.row.paymentStatus | paymentStatus }}
  479. </div>
  480. </template>
  481. </el-table-column>
  482. <el-table-column label="订单状态" prop="payingStatus" align="center">
  483. <template slot-scope="scope">
  484. <div>
  485. {{ scope.row.payingStatus | filtersPayingStatus }}
  486. </div>
  487. </template>
  488. </el-table-column>
  489. <el-table-column
  490. label="是否购买云教练"
  491. fixed="right"
  492. prop="hasCloudTeacher"
  493. align="center"
  494. >
  495. <template slot-scope="scope">
  496. <div>
  497. {{ scope.row.hasCloudTeacher == 1 ? "是" : "否" }}
  498. </div>
  499. </template>
  500. </el-table-column>
  501. <el-table-column
  502. label="解除限制"
  503. fixed="right"
  504. prop="noneNeedCloudTeacher"
  505. align="center"
  506. >
  507. <template slot="header">
  508. <p style="position: relative; display: flex">
  509. 解除限制
  510. <el-tooltip placement="top" popper-class="mTooltip">
  511. <div slot="content">学员是否受到不购买云教练的缴费限制</div>
  512. <i
  513. class="el-icon-question"
  514. style="font-size: 18px; color: #f56c6c"
  515. ></i>
  516. </el-tooltip>
  517. </p>
  518. </template>
  519. <template slot-scope="scope">
  520. <div>
  521. {{ scope.row.noneNeedCloudTeacher == 1 ? "是" : "否" }}
  522. </div>
  523. </template>
  524. </el-table-column>
  525. <el-table-column
  526. label="操作"
  527. fixed="right"
  528. width="240"
  529. align="center"
  530. v-if="
  531. status == 'PAY' ||
  532. status == 'APPLY' ||
  533. status == 'PROGRESS' ||
  534. status == 'PREPARE'
  535. "
  536. >
  537. <!-- v-show="
  538. status == 'PAY' || status == 'PROGRESS' || status == 'PREPARE' || status=='APPLY'
  539. " -->
  540. <template slot-scope="scope">
  541. <div>
  542. <auth :auths="'studentRegistration/batchUpdateSubject'">
  543. <el-button
  544. type="text"
  545. v-show="scope.row.paymentStatus != 2"
  546. @click="resetSubject(scope.row)"
  547. >修改专业</el-button
  548. >
  549. </auth>
  550. <!-- APPLY status == "APPLY" || s-->
  551. <el-popover
  552. v-show="scope.row.remark"
  553. placement="top-start"
  554. title="备注"
  555. width="200"
  556. trigger="hover"
  557. :content="scope.row.remark"
  558. >
  559. <el-button type="text" slot="reference">备注</el-button>
  560. </el-popover>
  561. <!-- PAY -->
  562. <!-- && status == "PAY"-->
  563. <auth
  564. :auths="'studentRegistration/queryFeeDetail'"
  565. v-show="scope.row.paymentStatus == 2"
  566. >
  567. <el-button type="text" @click="lookdetail(scope.row)"
  568. >查看</el-button
  569. >
  570. </auth>
  571. <auth
  572. :auths="'musicGroupQuit/directQuitMusicGroup2'"
  573. v-show="scope.row.paymentStatus == 2"
  574. >
  575. <el-button type="text" @click="quitTeam(scope.row)"
  576. >退团退费</el-button
  577. >
  578. </auth>
  579. <auth
  580. :auths="'musicGroupQuit/directQuitMusicGroup3'"
  581. v-show="scope.row.paymentStatus == 2"
  582. >
  583. <el-button type="text" @click="quieTeams(scope.row)"
  584. >退团</el-button
  585. >
  586. </auth>
  587. <auth
  588. :auths="'visit/add/teamSignupList'"
  589. v-if="scope.row.visitNum <= 0"
  590. >
  591. <el-button type="text" @click="addVisit(scope.row)"
  592. >新增回访</el-button
  593. >
  594. </auth>
  595. <auth
  596. :auths="'subjectChange/getStudentOriginal'"
  597. v-show="scope.row.paymentStatus == 2"
  598. >
  599. <el-button type="text" @click="openChangeVoice(scope.row)"
  600. >更改声部</el-button
  601. >
  602. </auth>
  603. <!-- -->
  604. <auth
  605. v-show="scope.row.payingStatus == 2 && scope.row.noneNeedCloudTeacher == 0"
  606. :auths="'studentRegistration/setNoneCloudTeacher'"
  607. >
  608. <el-button type="text" @click="relieve(scope.row)"
  609. >解除预约限制</el-button
  610. >
  611. </auth>
  612. </div>
  613. </template>
  614. </el-table-column>
  615. </el-table>
  616. <div
  617. style="margin-top: 10px; margin-bottom: 10px"
  618. v-show="
  619. status == 'APPLY' || status == 'PROGRESS' || status == 'PREPARE'
  620. "
  621. >
  622. <el-button @click="onSelectAll">全选/取消</el-button>
  623. <auth :auths="'studentRegistration/openPayment'">
  624. <el-button
  625. style="background-color: #14928a; border: 1px solid #14928a"
  626. @click="onPartPayment"
  627. type="primary"
  628. >开启缴费</el-button
  629. >
  630. </auth>
  631. <!-- <div class='newBand' v-show="status=='APPLY'">允许缴费</div> -->
  632. </div>
  633. <pagination
  634. sync
  635. :total.sync="rules.total"
  636. :page.sync="rules.page"
  637. :limit.sync="rules.limit"
  638. :page-sizes="rules.page_size"
  639. @pagination="getList"
  640. />
  641. </div>
  642. <el-dialog title="修改专业" :visible.sync="subjectVisible" width="400px">
  643. <el-form :model="maskForm">
  644. <el-form-item label="选择专业">
  645. <el-select v-model.trim="maskForm.subject" filterable clearable>
  646. <el-option
  647. v-for="(item, index) in soundList"
  648. :key="index"
  649. :label="item.name"
  650. :value="item.id"
  651. ></el-option>
  652. </el-select>
  653. </el-form-item>
  654. </el-form>
  655. <div slot="footer" class="dialog-footer">
  656. <el-button @click="subjectVisible = false">取 消</el-button>
  657. <el-button type="primary" @click="okReset">确 定</el-button>
  658. </div>
  659. </el-dialog>
  660. <el-dialog
  661. :title="!isPay ? '延长报名' : '延长缴费'"
  662. :visible.sync="extendPaymentStatus"
  663. destroy-on-close
  664. width="400px"
  665. >
  666. <el-form :model="extendForm" ref="extendForm" :rules="extendRule">
  667. <el-form-item v-if="isPay" label="延长缴费时间" prop="expireDate">
  668. <el-date-picker
  669. v-model.trim="extendForm.expireDate"
  670. value-format="yyyy-MM-dd"
  671. type="date"
  672. :picker-options="payDate()"
  673. placeholder="选择日期"
  674. >
  675. </el-date-picker>
  676. </el-form-item>
  677. <el-form-item label="延长报名时间" v-else prop="expireDate">
  678. <el-date-picker
  679. v-model.trim="extendForm.expireDate"
  680. value-format="yyyy-MM-dd"
  681. type="date"
  682. :picker-options="applyDates"
  683. placeholder="选择日期"
  684. >
  685. </el-date-picker>
  686. </el-form-item>
  687. </el-form>
  688. <div slot="footer" class="dialog-footer">
  689. <el-button @click="extendPaymentStatus = false">取 消</el-button>
  690. <el-button
  691. type="primary"
  692. v-if="isPay"
  693. @click="onExtendPayment('extendForm', isPay)"
  694. >确 定</el-button
  695. >
  696. <el-button
  697. v-else
  698. type="primary"
  699. @click="onExtendPayment('extendForm', isPay)"
  700. >确 定</el-button
  701. >
  702. </div>
  703. </el-dialog>
  704. <el-dialog title="订单详情" :visible.sync="orderVisible" width="600px">
  705. <el-form :model="orderForm" :inline="true">
  706. <!-- name: '',
  707. totalAmount: '',
  708. subject: '',
  709. subjectFee: '',
  710. axe: '',
  711. axePrice: '',
  712. others: '',
  713. othersPrice: '' -->
  714. <el-form-item label="学员姓名">
  715. <el-input v-model.trim="orderForm.name" disabled=""></el-input>
  716. </el-form-item>
  717. <el-form-item label="实缴金额">
  718. <el-input v-model.trim="orderForm.totalAmount" disabled=""></el-input>
  719. </el-form-item>
  720. <el-form-item label="实际专业">
  721. <el-input v-model.trim="orderForm.subject" disabled=""></el-input>
  722. </el-form-item>
  723. <el-form-item label="课程费用">
  724. <el-input v-model.trim="orderForm.subjectFee" disabled=""></el-input>
  725. </el-form-item>
  726. <el-form-item label="选择乐器">
  727. <el-input v-model.trim="orderForm.axe" disabled=""></el-input>
  728. </el-form-item>
  729. <el-form-item label="乐器价格">
  730. <el-input v-model.trim="orderForm.axePrice" disabled=""></el-input>
  731. </el-form-item>
  732. <el-form-item label="教辅组合">
  733. <el-input v-model.trim="orderForm.others" disabled=""></el-input>
  734. </el-form-item>
  735. <el-form-item label="组合价格">
  736. <el-input v-model.trim="orderForm.othersPrice" disabled=""></el-input>
  737. </el-form-item>
  738. </el-form>
  739. <div slot="footer" class="dialog-footer">
  740. <!-- <el-button>取 消</el-button> -->
  741. <el-button type="primary" @click="orderVisible = false"
  742. >确 定</el-button
  743. >
  744. </div>
  745. </el-dialog>
  746. <el-dialog
  747. title="开始缴费"
  748. :visible.sync="paymentStatus"
  749. width="400px"
  750. destroy-on-close
  751. >
  752. <el-form
  753. ref="paymentForm"
  754. class="paymentForm"
  755. :model="paymentForm"
  756. label-position="top"
  757. :rules="paymentRules"
  758. >
  759. <el-form-item label="请设置缴费截止日期" prop="paymentExpireDate">
  760. <el-date-picker
  761. v-model.trim="paymentForm.paymentExpireDate"
  762. type="date"
  763. value-format="yyyy-MM-dd"
  764. :picker-options="payDate()"
  765. style="width: 100%"
  766. placeholder="选择日期"
  767. >
  768. </el-date-picker>
  769. </el-form-item>
  770. </el-form>
  771. <div slot="footer" class="dialog-footer">
  772. <el-button @click="paymentStatus = false">取 消</el-button>
  773. <el-button type="primary" @click="onStartPayment('paymentForm')"
  774. >确 定</el-button
  775. >
  776. </div>
  777. </el-dialog>
  778. <!-- 预报名链接 -->
  779. <qr-code v-model="codeStatus" :title="codeTitle" :codeUrl="qrCodeUrl" />
  780. <!-- 退团弹窗 -->
  781. <el-dialog
  782. title="退团信息确认"
  783. :destroy-on-close="true"
  784. width="640px"
  785. :visible.sync="quitVisible"
  786. >
  787. <quiteTeam :quitForm="quitForm" :activeRow="activeRow" ref="quitForm"/>
  788. <span slot="footer" class="dialog-footer question">
  789. <div>
  790. <el-popover placement="right" width="500" trigger="click">
  791. <div class="popoverWrap">
  792. <p>乐团退团退费规则:</p>
  793. <p>退还乐器练习云教练费用:报名缴费时缴费的乐器练习云教练费用</p>
  794. <p>退还课程费用:缴费总额-已结束课时单价之和</p>
  795. <p>退还乐器费用:报名缴费时缴纳的乐器费用(团购、租金)</p>
  796. <p>退还教辅费用:报名缴费时缴费的教辅费用</p>
  797. <p>退还乐保费用:报名缴费时缴费的乐保费用</p>
  798. </div>
  799. <el-button
  800. type="text"
  801. icon="el-icon-question"
  802. slot="reference"
  803. style="color: red"
  804. >退团退费说明</el-button
  805. >
  806. </el-popover>
  807. </div>
  808. <div>
  809. <el-button @click="quitVisible = false">取 消</el-button>
  810. <el-button type="primary" @click="chioseType">确 定</el-button>
  811. </div>
  812. </span>
  813. </el-dialog>
  814. <!-- 回访记录 -->
  815. <el-dialog
  816. title="新增回访"
  817. width="500px"
  818. destroy-on-close
  819. :close-on-click-modal="false"
  820. :visible.sync="visitVisiable"
  821. >
  822. <visit
  823. v-if="visitVisiable && detail"
  824. :detail="detail"
  825. @close="visitVisiable = false"
  826. @submited="getList"
  827. />
  828. </el-dialog>
  829. <el-dialog
  830. title="更改声部"
  831. :visible.sync="changeVoiceVisible"
  832. v-if="changeVoiceVisible"
  833. width="600px"
  834. >
  835. <changeVoice
  836. @close="closeChangeVoice"
  837. @submited="getList"
  838. :detail.sync="rowDetail"
  839. :musicGroupId="id"
  840. :voiceList="leftList"
  841. />
  842. </el-dialog>
  843. </div>
  844. </template>
  845. <script>
  846. import pagination from "@/components/Pagination/index";
  847. import qrCode from "@/components/QrCode/index";
  848. import {
  849. getintoClass,
  850. getStudentList,
  851. findSound,
  852. musicGroupOpenPay,
  853. openPayment,
  854. musicGroupFound,
  855. extensionPayment,
  856. extensionApplyExpire,
  857. resetPlanNum,
  858. cancelMusicGroup,
  859. getTeamBaseInfo,
  860. studentApplyDetailExport,
  861. StudentQuit,
  862. getMusicGroupGradeList,
  863. checkCanReg,
  864. } from "@/api/buildTeam";
  865. import { setNoneCloudTeacher } from "./api";
  866. import mergeMusic from "./components/merge-music";
  867. import forecastList from "./components/forecast-list";
  868. import newForecastList from "./components/newForecast-list";
  869. import { resetStudentSubject, getStudentFeeDetail } from "@/api/studentManager";
  870. import { vaildStudentUrl, vaildTeacherUrl } from "@/utils/validate";
  871. import { addVisit } from "@/views/returnVisitManager/api.js";
  872. import QRCode from "qrcodejs2";
  873. import { visitChiose } from "@/utils/searchArray";
  874. import axios from "axios";
  875. import { getToken } from "@/utils/auth";
  876. import load from "@/utils/loading";
  877. import qs from "qs";
  878. import { permission } from "@/utils/directivePage";
  879. import cleanDeep from "clean-deep";
  880. import changeVoice from "./modals/change-voice";
  881. import visit from "@/views/withdrawal-application/modals/visit";
  882. import quiteTeam from "@/views/teamDetail/components/modals/quite-team"
  883. export default {
  884. name: "signupList",
  885. components: {
  886. pagination,
  887. qrCode,
  888. changeVoice,
  889. mergeMusic,
  890. forecastList,
  891. visit,
  892. newForecastList,
  893. quiteTeam
  894. },
  895. data() {
  896. return {
  897. multipleSelection: [], //
  898. forecastVisible: false, // 预报名状态
  899. newForecastVisible: false,
  900. isEdit: false,
  901. rowDetail: null,
  902. mergeVisible: false,
  903. changeVoiceVisible: false,
  904. subjectVisible: false,
  905. orderVisible: false,
  906. quitVisible: false,
  907. leftList: [],
  908. rightList: [],
  909. searchFrom: {
  910. name: "",
  911. subject: "", // 专业
  912. isAllowAdjust: "", // 是否允许调剂
  913. currentGrade: null, // 入学年级
  914. paymentStatus: "",
  915. visited: "",
  916. hasCloudTeacher: null, // 是否购买云教练
  917. payingStatus: null,
  918. noneNeedCloudTeacher: null,
  919. },
  920. quitForm: {
  921. // 退团信息确认
  922. isRefundCourseFee: null,
  923. isRefundInstrumentFee: null,
  924. isRefundTeachingAssistantsFee: null,
  925. isMaintenanceFee: null,
  926. cloudTeacherAmount: null,
  927. isCloudTeacherAmount: null,
  928. maintenanceFee: 0,
  929. reason: "",
  930. },
  931. stepImgs: {
  932. APPLY: require("@/assets/images/base/clock.png"),
  933. PAY: require("@/assets/images/base/pay.png"),
  934. },
  935. status: "",
  936. id: "",
  937. rules: {
  938. // 分页规则
  939. limit: 10, // 限制显示条数
  940. page: 1, // 当前页
  941. total: 0, // 总条数
  942. page_size: [10, 20, 30, 40], // 选择限制显示条数
  943. },
  944. teamName: "",
  945. maskForm: {
  946. subject: "",
  947. },
  948. activeId: "",
  949. soundList: [],
  950. orderForm: {
  951. name: "",
  952. totalAmount: "",
  953. subject: "",
  954. subjectFee: "",
  955. axe: "",
  956. axePrice: "",
  957. others: "",
  958. othersPrice: "",
  959. },
  960. paymentStatus: false,
  961. paymentForm: {
  962. paymentExpireDate: null,
  963. // feeType: null
  964. },
  965. paymentRules: {
  966. paymentExpireDate: [
  967. { required: true, message: "请设置缴费截止日期", trigger: "blur" },
  968. ],
  969. },
  970. paymentNum: 0, // 缴费了多少人
  971. qrcodeStatus: false, // 生成二维码
  972. qrcodes: true,
  973. qrcode: null,
  974. codeUrl: null,
  975. qrcodeStatus2: false, // 生成二维码
  976. qrcodes2: true,
  977. qrcode2: null,
  978. codeUrl2: null,
  979. codeStatus: false,
  980. codeTitle: null,
  981. qrCodeUrl: null,
  982. organId: "",
  983. extendPaymentStatus: false,
  984. extendForm: {
  985. expireDate: null,
  986. },
  987. extendRule: {
  988. expireDate: [
  989. { required: true, message: "请选择延长时间", trigger: "change" },
  990. ],
  991. },
  992. quitRules: {
  993. isCloudTeacherAmount: [{ required: true, message: "请输入云教练费用" }],
  994. cloudTeacherAmount: [
  995. { required: true, message: "请输入云教练金额", trigger: "blur" },
  996. ],
  997. isRefundCourseFee: [
  998. { required: true, message: "请选择是否退还课程费用" },
  999. ],
  1000. isRefundInstrumentFee: [
  1001. { required: true, message: "选择是否退还乐器费用" },
  1002. ],
  1003. isRefundTeachingAssistantsFee: [
  1004. { required: true, message: "选择是否退还教辅费用" },
  1005. ],
  1006. isMaintenanceFee: [{ required: true, message: "选择是否退还乐保费用" }],
  1007. maintenanceFee: [{ required: true, message: "请输入退还乐保金额" }],
  1008. reason: [{ required: true, message: "请填写退团退费原因" }],
  1009. },
  1010. applyExpireDate: "",
  1011. paymentExpireDate: "",
  1012. activeRow: { hasMaintenance: false },
  1013. visitVisiable: false,
  1014. visitForm: {
  1015. musicGroupId: "",
  1016. overview: "",
  1017. purpose: "",
  1018. studentId: "",
  1019. type: "",
  1020. visitTime: "",
  1021. visitType: "",
  1022. feedback: "",
  1023. studentName: "",
  1024. },
  1025. visitChiose,
  1026. visitRules: {
  1027. overview: [{ required: true, message: "请输入学生近况" }],
  1028. feedback: [{ required: true, message: "请输入家长反馈" }],
  1029. visitTime: [{ required: true, message: "请输入回访时间" }],
  1030. visitType: [{ required: true, message: "请选择回访类型" }],
  1031. },
  1032. isPay: false,
  1033. applyDates: this.applyDate(),
  1034. detail: null,
  1035. gradeList: [],
  1036. ischeckCanReg: false,
  1037. };
  1038. },
  1039. created() {},
  1040. mounted() {
  1041. // 通过乐团状态判断显示隐藏的东西
  1042. this.init();
  1043. },
  1044. activated() {
  1045. this.init();
  1046. },
  1047. filters: {
  1048. filtersPayingStatus(val) {
  1049. let obj = {
  1050. 0: "--",
  1051. 1: "缴费中",
  1052. 2: "审核中",
  1053. };
  1054. return obj[val];
  1055. },
  1056. },
  1057. methods: {
  1058. permission(str) {
  1059. return permission(str);
  1060. },
  1061. async init() {
  1062. this.status = this.$route.query.team_status;
  1063. // 通过乐团id 获取乐团招生状态
  1064. this.id = this.$route.query.id;
  1065. this.teamName = this.$route.query.name;
  1066. // 判断是否带缓存参数
  1067. this.pickerOptions = this.beginDate(new Date());
  1068. // checkCanReg
  1069. try {
  1070. this.ischeckCanReg = await (
  1071. await checkCanReg({ musicGroupId: this.id })
  1072. ).data;
  1073. console.log(this.ischeckCanReg);
  1074. } catch (e) {
  1075. console.log(e);
  1076. }
  1077. getMusicGroupGradeList({ musicGroupId: this.id }).then((res) => {
  1078. let result = res.data;
  1079. if (res.code == 200 && result) {
  1080. for (let i in result) {
  1081. this.gradeList.push({
  1082. value: i,
  1083. label: result[i],
  1084. });
  1085. }
  1086. }
  1087. });
  1088. getTeamBaseInfo({ musicGroupId: this.id }).then((res) => {
  1089. if (res.code == 200) {
  1090. this.organId = res.data.musicGroup.organId;
  1091. this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  1092. this.paymentExpireDate = res.data.musicGroup.paymentExpireDate;
  1093. }
  1094. });
  1095. // 根据乐团id获乐团声部
  1096. findSound({ musicGroupId: this.id }).then((res) => {
  1097. if (res.code == 200) {
  1098. this.soundList = res.data;
  1099. }
  1100. });
  1101. // 通过乐团id获取乐团学生列表
  1102. this.getList();
  1103. },
  1104. search() {
  1105. this.rules.page = 1;
  1106. this.getList();
  1107. },
  1108. onReset() {
  1109. this.rules.page = 1;
  1110. this.rules.limit = 10;
  1111. this.searchFrom = {
  1112. name: null,
  1113. subject: null, // 专业
  1114. isAllowAdjust: null, // 是否允许调剂
  1115. currentGrade: null,
  1116. paymentStatus: null,
  1117. visited: null,
  1118. hasCloudTeacher: null,
  1119. payingStatus: null,
  1120. noneNeedCloudTeacher: null,
  1121. };
  1122. this.getList();
  1123. },
  1124. onCancel() {
  1125. this.$store.dispatch("delVisitedViews", this.$route);
  1126. this.$router.push({ path: "/teamList" });
  1127. },
  1128. payStart() {
  1129. this.paymentStatus = true;
  1130. getTeamBaseInfo({ musicGroupId: this.id }).then((res) => {
  1131. if (res.code == 200) {
  1132. this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  1133. this.paymentExpireDate = res.data.musicGroup.paymentExpireDate;
  1134. }
  1135. });
  1136. },
  1137. getList() {
  1138. let obj = {
  1139. musicGroupId: this.id,
  1140. actualSubjectId: this.searchFrom.subject || null,
  1141. isAllowAdjust: this.searchFrom.isAllowAdjust || null,
  1142. name: this.searchFrom.name || null,
  1143. currentGrade: this.searchFrom.currentGrade || null,
  1144. paymentStatus: this.searchFrom.paymentStatus || null,
  1145. visited: this.searchFrom.visited || null,
  1146. hasCloudTeacher: this.searchFrom.hasCloudTeacher,
  1147. payingStatus: this.searchFrom.payingStatus,
  1148. noneNeedCloudTeacher: this.searchFrom.noneNeedCloudTeacher,
  1149. page: this.rules.page,
  1150. rows: this.rules.limit,
  1151. };
  1152. // 根据乐团id获取学团情况
  1153. getintoClass({ musicGroupId: this.id }).then((res) => {
  1154. if (res.code == 200) {
  1155. this.leftList = res.data;
  1156. }
  1157. });
  1158. return getStudentList(obj).then((res) => {
  1159. if (res.code == 200) {
  1160. res.data.rows.forEach((item) => {
  1161. // '未开启缴费', '开启缴费', '已缴费'
  1162. if (item.paymentStatus == 2) {
  1163. this.paymentNum += 1;
  1164. }
  1165. });
  1166. this.rightList = res.data.rows;
  1167. this.rules.total = res.data.total;
  1168. return res;
  1169. }
  1170. });
  1171. },
  1172. onStartPayment(formName) {
  1173. // 开启缴费
  1174. this.$refs[formName].validate((valid) => {
  1175. if (valid) {
  1176. musicGroupOpenPay({
  1177. musicGroupId: this.id,
  1178. expireDate: this.paymentForm.paymentExpireDate,
  1179. // feeType: this.paymentForm.feeType
  1180. }).then((res) => {
  1181. if (res.code == 200) {
  1182. this.$message.success("开启成功");
  1183. this.paymentStatus = false;
  1184. this.$store.dispatch("delVisitedViews", this.$route);
  1185. this.$router.push({
  1186. path: "/teamList",
  1187. });
  1188. this.status = "PAY";
  1189. this.paymentExpireDate = this.paymentForm.paymentExpireDate;
  1190. this.getList();
  1191. }
  1192. });
  1193. } else {
  1194. return false;
  1195. }
  1196. });
  1197. },
  1198. onSelectAll() {
  1199. // 选中全部
  1200. this.$refs.multipleTable.toggleAllSelection();
  1201. },
  1202. onPartPayment() {
  1203. // 部分缴费
  1204. let selection = this.multipleSelection;
  1205. if (selection.length <= 0) {
  1206. this.$message.error("您还没有选择学生");
  1207. return false;
  1208. }
  1209. let ids = [];
  1210. selection.forEach((item) => {
  1211. ids.push(item.id);
  1212. });
  1213. this.$confirm(`是否确认开启缴费?`, "提示", {
  1214. confirmButtonText: "确定",
  1215. cancelButtonText: "取消",
  1216. type: "warning",
  1217. })
  1218. .then(() => {
  1219. openPayment({
  1220. ids: ids.join(","),
  1221. }).then((res) => {
  1222. if (res.code == 200) {
  1223. this.$message.success("开启成功");
  1224. this.getList();
  1225. } else {
  1226. this.$message.error(res.msg);
  1227. }
  1228. });
  1229. })
  1230. .catch(() => {});
  1231. },
  1232. onCreateQRCode(type) {
  1233. // 生成报名二维码
  1234. let id = this.id;
  1235. this.codeStatus = true;
  1236. if (type == "payment") {
  1237. this.codeTitle = "学员报名链接";
  1238. this.qrCodeUrl = vaildStudentUrl() + "/#/login?musicGroupId=" + id;
  1239. } else if (type == "detail") {
  1240. let teamName = this.$route.query.name;
  1241. this.codeTitle = "报名缴费详情";
  1242. this.qrCodeUrl =
  1243. vaildTeacherUrl() +
  1244. "/#/order?musicGroupId=" +
  1245. id +
  1246. "&musicGroupName=" +
  1247. teamName;
  1248. } else if (type == "rePayment") {
  1249. this.codeTitle = "学生报名链接(无乐器)";
  1250. this.qrCodeUrl =
  1251. vaildStudentUrl() + "/#/login?musicGroupId=" + id + "&instrument=1";
  1252. }
  1253. },
  1254. onCreateQRCode2() {
  1255. // 生成报名二维码
  1256. this.qrcodeStatus2 = true;
  1257. let id = this.id;
  1258. let teamName = this.$route.query.name;
  1259. setTimeout(() => {
  1260. document.getElementById("qrcode2").innerHTML = "";
  1261. this.qrcode2 = new QRCode("qrcode2", {
  1262. width: 200,
  1263. height: 200,
  1264. colorDark: "#000000",
  1265. colorLight: "#ffffff",
  1266. correctLevel: QRCode.CorrectLevel.H,
  1267. });
  1268. this.qrcode2.makeCode(
  1269. vaildTeacherUrl() +
  1270. "/#/order?musicGroupId=" +
  1271. id +
  1272. "&musicGroupName=" +
  1273. teamName
  1274. );
  1275. this.codeUrl2 =
  1276. vaildTeacherUrl() +
  1277. "/#/order?musicGroupId=" +
  1278. id +
  1279. "&musicGroupName=" +
  1280. teamName;
  1281. }, 500);
  1282. },
  1283. onDownLoadExecl() {
  1284. // 报表导出
  1285. let url = "/api-web/studentRegistration/queryStudentApplyDetailExport";
  1286. let data = {
  1287. musicGroupId: this.$route.query.id,
  1288. page: 1,
  1289. rows: 9999,
  1290. };
  1291. const options = {
  1292. method: "POST",
  1293. headers: {
  1294. Authorization: getToken(),
  1295. },
  1296. data: qs.stringify(data),
  1297. url,
  1298. responseType: "blob",
  1299. };
  1300. this.$confirm("您确定导出吗?", "提示", {
  1301. confirmButtonText: "确定",
  1302. cancelButtonText: "取消",
  1303. type: "warning",
  1304. })
  1305. .then(() => {
  1306. load.startLoading();
  1307. axios(options)
  1308. .then((res) => {
  1309. let blob = new Blob([res.data], {
  1310. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  1311. type: "application/vnd.ms-excel;charset=utf-8",
  1312. //word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  1313. });
  1314. let text = new Response(blob).text();
  1315. text.then((res) => {
  1316. // 判断是否报错
  1317. if (res.indexOf("code") != -1) {
  1318. let json = JSON.parse(res);
  1319. this.$message.error(json.msg);
  1320. } else {
  1321. let objectUrl = URL.createObjectURL(blob);
  1322. let link = document.createElement("a");
  1323. let nowTime = new Date();
  1324. let ymd =
  1325. nowTime.getFullYear() +
  1326. "" +
  1327. (nowTime.getMonth() + 1) +
  1328. "" +
  1329. nowTime.getDate() +
  1330. "" +
  1331. nowTime.getHours() +
  1332. "" +
  1333. nowTime.getMinutes();
  1334. let fname = this.$route.query.id + "-" + ymd + ".xls"; //下载文件的名字
  1335. link.href = objectUrl;
  1336. link.setAttribute("download", fname);
  1337. document.body.appendChild(link);
  1338. link.click();
  1339. }
  1340. });
  1341. load.endLoading();
  1342. })
  1343. .catch((error) => {
  1344. this.$message.error("导出数据失败,请联系管理员");
  1345. load.endLoading();
  1346. });
  1347. })
  1348. .catch(() => {});
  1349. },
  1350. onGoHome() {
  1351. // 确认开团
  1352. // 判断是否有学生缴费
  1353. if (this.paymentNum <= 0) {
  1354. this.$message.error("当前缴费人数为0,无法开团");
  1355. return;
  1356. }
  1357. this.$confirm(`是否确认开团?`, "提示", {
  1358. confirmButtonText: "确定",
  1359. cancelButtonText: "取消",
  1360. type: "warning",
  1361. })
  1362. .then(() => {
  1363. musicGroupFound({
  1364. musicGroupId: this.$route.query.id,
  1365. }).then((res) => {
  1366. if (res.code == 200) {
  1367. // let query = this.$route.query;
  1368. // this.$message.success("开启成功");
  1369. // this.$router.push({
  1370. // path: "/teamList",
  1371. // query: {
  1372. // ...query,
  1373. // },
  1374. // });
  1375. this.onCancel();
  1376. }
  1377. });
  1378. })
  1379. .catch(() => {});
  1380. },
  1381. onClose() {
  1382. // 停止乐团
  1383. this.$confirm("您确定停止乐团吗?", "提示", {
  1384. confirmButtonText: "确定",
  1385. cancelButtonText: "取消",
  1386. type: "warning",
  1387. })
  1388. .then(() => {
  1389. cancelMusicGroup({
  1390. musicGroupId: this.$route.query.id,
  1391. }).then((res) => {
  1392. if (res.code == 200) {
  1393. this.$message.success("停止成功");
  1394. this.$store.dispatch("delVisitedViews", this.$route);
  1395. this.$router.push({
  1396. path: "/teamList",
  1397. });
  1398. }
  1399. });
  1400. })
  1401. .catch(() => {});
  1402. },
  1403. handleSelectionChange(val) {
  1404. this.multipleSelection = val;
  1405. },
  1406. // 修改专业
  1407. resetSubject(row) {
  1408. console.log(row);
  1409. this.activeId = row.studentId;
  1410. this.maskForm.subject = row.actualSubjectId;
  1411. this.subjectVisible = true;
  1412. // resetStudentSubject().then(res=>{]})
  1413. },
  1414. // 确认修改
  1415. okReset() {
  1416. if (!this.maskForm.subject) {
  1417. this.$message.error("请选择调剂专业");
  1418. return;
  1419. }
  1420. resetStudentSubject({
  1421. musicGroupId: this.id,
  1422. userId: this.activeId,
  1423. subId: this.maskForm.subject,
  1424. }).then((res) => {
  1425. if (res.code == 200) {
  1426. this.$message.success("修改成功");
  1427. this.subjectVisible = false;
  1428. this.maskForm.subject = "";
  1429. getintoClass({ musicGroupId: this.id }).then((res) => {
  1430. if (res.code == 200) {
  1431. this.leftList = res.data;
  1432. }
  1433. });
  1434. this.getList();
  1435. }
  1436. });
  1437. },
  1438. onExtendPayment(formName, isPay) {
  1439. this.$refs[formName].validate((valid) => {
  1440. if (valid) {
  1441. if (!isPay) {
  1442. extensionApplyExpire({
  1443. musicGroupId: this.id,
  1444. expireDate: this.extendForm.expireDate,
  1445. }).then((res) => {
  1446. if (res.code == 200) {
  1447. this.$message.success("延长报名成功");
  1448. this.extendPaymentStatus = false;
  1449. getTeamBaseInfo({ musicGroupId: this.id }).then((res) => {
  1450. if (res.code == 200) {
  1451. this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  1452. }
  1453. });
  1454. } else {
  1455. this.$message.error(res.msg);
  1456. }
  1457. });
  1458. } else {
  1459. extensionPayment({
  1460. musicGroupId: this.id,
  1461. expireDate: this.extendForm.expireDate,
  1462. }).then((res) => {
  1463. if (res.code == 200) {
  1464. this.$message.success("延长缴费成功");
  1465. this.extendPaymentStatus = false;
  1466. getTeamBaseInfo({ musicGroupId: this.id }).then((res) => {
  1467. if (res.code == 200) {
  1468. this.paymentExpireDate =
  1469. res.data.musicGroup.paymentExpireDate;
  1470. }
  1471. });
  1472. } else {
  1473. this.$message.error(res.msg);
  1474. }
  1475. });
  1476. }
  1477. }
  1478. });
  1479. },
  1480. lookdetail(row) {
  1481. this.orderVisible = true;
  1482. this.activeId = row.studentId;
  1483. this.orderForm.name = row.studentName;
  1484. this.orderForm.subject = row.subjectName;
  1485. getStudentFeeDetail({
  1486. musicGroupId: this.id,
  1487. studentId: row.studentId,
  1488. }).then((res) => {
  1489. if (res.code == 200) {
  1490. if (res.data) {
  1491. this.orderForm.totalAmount = res.data.totalAmount;
  1492. // this.orderForm.subjectFee = res.data.courseFee;
  1493. let goodStr = "";
  1494. let goodPrice = 0;
  1495. let otherStr = "";
  1496. let othersPrice = 0;
  1497. for (let i in res.data.goods) {
  1498. if (res.data.goods[i].goodsType == "INSTRUMENT") {
  1499. goodStr += res.data.goods[i].goodsName + ",";
  1500. goodPrice += parseFloat(res.data.goods[i].musicalFee);
  1501. // this.orderForm.axe = res.data.goods[i].goodsName;
  1502. // this.orderForm.axePrice = res.data.goods[i].musicalFee;
  1503. } else if (res.data.goods[i].goodsType == "ACCESSORIES") {
  1504. otherStr += res.data.goods[i].goodsName + ",";
  1505. othersPrice += parseFloat(res.data.goods[i].musicalFee);
  1506. // this.orderForm.others = res.data.goods[i].goodsName;
  1507. // this.orderForm.othersPrice = res.data.goods[i].musicalFee;
  1508. } else if (res.data.goods[i].goodsType == "COURSE") {
  1509. this.orderForm.subjectFee = res.data.goods[i].musicalFee;
  1510. }
  1511. }
  1512. this.orderForm.others = otherStr.substring(0, otherStr.length - 1);
  1513. this.orderForm.othersPrice = othersPrice;
  1514. this.orderForm.axe = goodStr.substring(0, goodStr.length - 1);
  1515. this.orderForm.axePrice = goodPrice;
  1516. }
  1517. }
  1518. });
  1519. },
  1520. saveIsEdit() {
  1521. // 提交数据
  1522. this.isEdit = false;
  1523. resetPlanNum(this.leftList).then((res) => {});
  1524. },
  1525. quitTeam(row) {
  1526. this.activeRow = row;
  1527. this.quitVisible = true;
  1528. this.quitForm.cloudTeacherAmount = row.cloudTeacherAmount;
  1529. },
  1530. quieTeams(row) {
  1531. this.$prompt("请输入退团原因", "提示", {
  1532. confirmButtonText: "确定",
  1533. cancelButtonText: "取消",
  1534. inputPattern: /\S/,
  1535. inputErrorMessage: "请输入退团原因",
  1536. type: "warning",
  1537. })
  1538. .then((val) => {
  1539. // 发请求 退团
  1540. StudentQuit({
  1541. musicGroupId: this.id,
  1542. userId: row.studentId,
  1543. reason: val.value,
  1544. isRefundCourseFee: false,
  1545. isRefundInstrumentFee: false,
  1546. isRefundTeachingAssistantsFee: false,
  1547. }).then((res) => {
  1548. this.quitForm = {
  1549. // 退团信息确认
  1550. isRefundCourseFee: null,
  1551. isRefundInstrumentFee: null,
  1552. isRefundTeachingAssistantsFee: null,
  1553. isMaintenanceFee: null,
  1554. cloudTeacherAmount: null,
  1555. isCloudTeacherAmount: null,
  1556. maintenanceFee: 0,
  1557. reason: "",
  1558. };
  1559. if (res.code == 200) {
  1560. this.$message.success("退团成功");
  1561. this.getList();
  1562. this.quitVisible = false;
  1563. }
  1564. });
  1565. })
  1566. .catch(() => {});
  1567. },
  1568. chioseType() {
  1569. this.$refs["quitForm"].$refs["quitForm"].validate((res) => {
  1570. if (res) {
  1571. this.$confirm("确定退团?", "提示", {
  1572. confirmButtonText: "确定",
  1573. cancelButtonText: "取消",
  1574. type: "warning",
  1575. })
  1576. .then(() => {
  1577. let row = this.activeRow;
  1578. let params = {
  1579. musicGroupId: this.id,
  1580. userId: row.studentId,
  1581. reason: this.quitForm.reason,
  1582. isRefundCourseFee: this.quitForm.isRefundCourseFee,
  1583. isRefundInstrumentFee: this.quitForm.isRefundInstrumentFee,
  1584. isRefundTeachingAssistantsFee:
  1585. this.quitForm.isRefundTeachingAssistantsFee,
  1586. maintenanceFee: this.quitForm.maintenanceFee,
  1587. };
  1588. // 退还乐器练习云教练费用
  1589. if (this.quitForm.isCloudTeacherAmount) {
  1590. params.cloudTeacherAmount = this.quitForm.cloudTeacherAmount;
  1591. } else {
  1592. params.cloudTeacherAmount = 0;
  1593. }
  1594. // 发请求 退团
  1595. StudentQuit(params).then((res) => {
  1596. this.quitForm = {
  1597. // 退团信息确认
  1598. isRefundCourseFee: null,
  1599. isRefundInstrumentFee: null,
  1600. isRefundTeachingAssistantsFee: null,
  1601. isMaintenanceFee: null,
  1602. cloudTeacherAmount: null,
  1603. isCloudTeacherAmount: null,
  1604. maintenanceFee: 0,
  1605. reason: "",
  1606. };
  1607. if (res.code == 200) {
  1608. this.$message.success("退团成功");
  1609. this.getList();
  1610. this.quitVisible = false;
  1611. }
  1612. });
  1613. })
  1614. .catch(() => {});
  1615. } else {
  1616. }
  1617. });
  1618. // row.typeVisible = false;
  1619. },
  1620. addVisit(row) {
  1621. // this.visitForm.studentName = row.studentName;
  1622. // this.visitForm.musicGroupId = this.teamid;
  1623. // this.visitForm.studentId = row.studentId;
  1624. row.userId = row.studentId;
  1625. this.detail = row;
  1626. this.detail.musicGroupId = this.$route.query.id;
  1627. this.visitVisiable = true;
  1628. },
  1629. openChangeVoice(row) {
  1630. this.getList().then((res) => {
  1631. for (const item of res.data.rows) {
  1632. if (item.id === row.id) {
  1633. this.rowDetail = { ...item, userId: item.studentId };
  1634. // console.log(this.rowDetail)
  1635. this.changeVoiceVisible = true;
  1636. }
  1637. }
  1638. });
  1639. },
  1640. closeChangeVoice() {
  1641. this.changeVoiceVisible = false;
  1642. // this.rowDetail = null
  1643. },
  1644. handleChange(val) {
  1645. this.visitForm.type = val[0];
  1646. this.visitForm.purpose = val[1];
  1647. },
  1648. submitAddVisit() {
  1649. this.$refs.visitForm.validate((res) => {
  1650. if (res) {
  1651. this.visitForm.visitType = null;
  1652. this.visitForm.musicGroupId = this.id;
  1653. addVisit(cleanDeep(this.visitForm)).then((res) => {
  1654. if (res.code === 200) {
  1655. this.$message.success("新增成功");
  1656. this.visitVisiable = false;
  1657. }
  1658. });
  1659. }
  1660. });
  1661. },
  1662. beginDate(date) {
  1663. let self = this;
  1664. return {
  1665. firstDayOfWeek: 1,
  1666. disabledDate(time) {
  1667. return time.getTime() >= date.getTime(); //开始时间不选时,结束时间最大值小于等于当天
  1668. },
  1669. };
  1670. },
  1671. extendTime(isPay) {
  1672. this.isPay = isPay;
  1673. if (isPay) {
  1674. // 点击的延长缴费
  1675. this.extendForm.expireDate = this.paymentExpireDate;
  1676. } else {
  1677. // 点击的延长报名
  1678. this.extendForm.expireDate = this.applyExpireDate;
  1679. }
  1680. this.extendPaymentStatus = true;
  1681. },
  1682. payDate() {
  1683. let self = this;
  1684. return {
  1685. firstDayOfWeek: 1,
  1686. disabledDate(time) {
  1687. return time.getTime() + 86400000 < new Date().getTime();
  1688. },
  1689. };
  1690. },
  1691. applyDate() {
  1692. let self = this;
  1693. return {
  1694. firstDayOfWeek: 1,
  1695. disabledDate(time) {
  1696. return time.getTime() + 86400000 < new Date().getTime();
  1697. },
  1698. };
  1699. },
  1700. checkboxSelect(row) {
  1701. return row.paymentStatus == 0;
  1702. },
  1703. relieve(row) {
  1704. this.$confirm("操作后该学员即可不购买云教练缴费入团", "提示", {
  1705. confirmButtonText: "确定",
  1706. cancelButtonText: "取消",
  1707. type: "warning",
  1708. }).then(async () => {
  1709. try {
  1710. const res = await setNoneCloudTeacher({ id: row.id });
  1711. this.$message.success("解除预约成功");
  1712. this.getList();
  1713. } catch (e) {
  1714. console.log(e);
  1715. }
  1716. });
  1717. },
  1718. getCheckNum(row) {
  1719. this.rules.page = 1;
  1720. this.rules.limit = 10;
  1721. this.searchFrom = {
  1722. name: null,
  1723. subject: null, // 专业
  1724. isAllowAdjust: null, // 是否允许调剂
  1725. currentGrade: null,
  1726. paymentStatus: null,
  1727. visited: null,
  1728. hasCloudTeacher: null,
  1729. payingStatus: null,
  1730. noneNeedCloudTeacher: null,
  1731. };
  1732. this.searchFrom.subject = row.subjectId;
  1733. this.searchFrom.payingStatus = 2;
  1734. this.searchFrom.hasCloudTeacher = 0;
  1735. this.search();
  1736. },
  1737. getpayingNum(row) {
  1738. this.rules.page = 1;
  1739. this.rules.limit = 10;
  1740. this.searchFrom = {
  1741. name: null,
  1742. subject: null, // 专业
  1743. isAllowAdjust: null, // 是否允许调剂
  1744. currentGrade: null,
  1745. paymentStatus: null,
  1746. visited: null,
  1747. hasCloudTeacher: null,
  1748. payingStatus: null,
  1749. noneNeedCloudTeacher: null,
  1750. };
  1751. this.searchFrom.subject = row.subjectId;
  1752. this.searchFrom.payingStatus = 1;
  1753. this.search();
  1754. },
  1755. getpayNum(row) {
  1756. this.rules.page = 1;
  1757. this.rules.limit = 10;
  1758. this.searchFrom = {
  1759. name: null,
  1760. subject: null, // 专业
  1761. isAllowAdjust: null, // 是否允许调剂
  1762. currentGrade: null,
  1763. paymentStatus: null,
  1764. visited: null,
  1765. hasCloudTeacher: null,
  1766. payingStatus: null,
  1767. noneNeedCloudTeacher: null,
  1768. };
  1769. this.searchFrom.subject = row.subjectId;
  1770. this.searchFrom.paymentStatus = 2 + "";
  1771. this.search();
  1772. },
  1773. },
  1774. watch: {
  1775. "quitForm.isMaintenanceFee"(val) {
  1776. if (val) {
  1777. this.quitForm.maintenanceFee = 300;
  1778. } else {
  1779. this.quitForm.maintenanceFee = 0;
  1780. }
  1781. },
  1782. orderVisible(val) {
  1783. if (!val) {
  1784. this.orderForm = {
  1785. name: "",
  1786. totalAmount: "",
  1787. subject: "",
  1788. subjectFee: "",
  1789. axe: "",
  1790. axePrice: "",
  1791. others: "",
  1792. othersPrice: "",
  1793. };
  1794. }
  1795. },
  1796. qrcodeStatus(val) {
  1797. if (!val) {
  1798. this.qrcode.clear();
  1799. }
  1800. },
  1801. qrcodeStatus2(val) {
  1802. if (!val) {
  1803. this.qrcode2.clear();
  1804. }
  1805. },
  1806. paymentStatus(val) {
  1807. if (!val) {
  1808. this.paymentForm = {
  1809. paymentExpireDate: null,
  1810. // feeType: null
  1811. };
  1812. }
  1813. },
  1814. quitVisible(val) {
  1815. if (!val) {
  1816. this.quitForm = {
  1817. // 退团信息确认
  1818. isRefundCourseFee: null,
  1819. isRefundInstrumentFee: null,
  1820. isRefundTeachingAssistantsFee: null,
  1821. isMaintenanceFee: null,
  1822. cloudTeacherAmount: null,
  1823. isCloudTeacherAmount: null,
  1824. maintenanceFee: 0,
  1825. reason: "",
  1826. };
  1827. this.$refs["quitForm"].$refs["quitForm"].resetFields();
  1828. }
  1829. },
  1830. // visitVisiable(val) {
  1831. // if (!val) {
  1832. // this.$refs["visitForm"].resetFields();
  1833. // }
  1834. // },
  1835. },
  1836. };
  1837. </script>
  1838. <style lang="scss" scoped>
  1839. .auth {
  1840. display: inline-block;
  1841. & + .auth {
  1842. margin-left: 0px;
  1843. }
  1844. }
  1845. .dialog-footer.question {
  1846. display: flex;
  1847. flex-direction: row;
  1848. justify-content: space-between;
  1849. }
  1850. .sigup-container {
  1851. margin-left: 12px;
  1852. .topWrap {
  1853. padding: 18px 58px 18px 0;
  1854. // height: 136px;
  1855. background-color: #fff;
  1856. // display: flex;
  1857. // flex-direction: row;
  1858. // justify-content: space-between;
  1859. .msg.pay {
  1860. color: #f85043;
  1861. }
  1862. .msg {
  1863. text-align: right;
  1864. color: #f97215;
  1865. font-size: 32px;
  1866. font-weight: bold;
  1867. padding-top: 30px;
  1868. box-sizing: border-box;
  1869. img {
  1870. width: 36px;
  1871. height: 36px;
  1872. position: relative;
  1873. top: 5px;
  1874. margin-right: 8px;
  1875. }
  1876. }
  1877. h2 {
  1878. height: 48px;
  1879. line-height: 48px;
  1880. position: relative;
  1881. // padding-left: 30px;
  1882. font-size: 32px;
  1883. font-weight: 600;
  1884. margin-bottom: 10px;
  1885. display: flex;
  1886. flex-direction: row;
  1887. justify-content: flex-start;
  1888. align-items: center;
  1889. .term {
  1890. height: 32px;
  1891. line-height: 32px;
  1892. border-radius: 24px;
  1893. width: 100px;
  1894. color: #14928a;
  1895. border: 1px solid rgba(20, 146, 138, 1);
  1896. font-size: 14px;
  1897. text-align: center;
  1898. margin-right: 12px;
  1899. &:nth-child(1) {
  1900. margin-left: 47px;
  1901. }
  1902. }
  1903. .term.active {
  1904. color: #fff;
  1905. background-color: #14928a;
  1906. }
  1907. .squrt {
  1908. position: absolute;
  1909. left: -25px;
  1910. top: 8px;
  1911. height: 34px;
  1912. width: 8px;
  1913. background-color: #14928a;
  1914. }
  1915. }
  1916. .btnList {
  1917. display: flex;
  1918. flex-direction: row;
  1919. justify-content: flex-start;
  1920. align-items: center;
  1921. flex-wrap: wrap;
  1922. & > div {
  1923. margin-right: 15px;
  1924. margin-top: 10px;
  1925. }
  1926. }
  1927. .newBand.close {
  1928. background-color: #777;
  1929. border: 1px solid #777;
  1930. }
  1931. }
  1932. .searchList {
  1933. background-color: #fff;
  1934. padding: 0 58p 0 0px;
  1935. }
  1936. .sigup-core {
  1937. margin-top: 12px;
  1938. display: flex;
  1939. flex-direction: row;
  1940. justify-content: flex-start;
  1941. .left {
  1942. width: 400px;
  1943. background-color: #fff;
  1944. height: 80vh;
  1945. overflow: auto;
  1946. }
  1947. .right {
  1948. width: calc(100% - 400px);
  1949. margin-left: 12px;
  1950. flex-grow: 1;
  1951. }
  1952. }
  1953. }
  1954. .el-dialog__body {
  1955. overflow: hidden;
  1956. }
  1957. .left-code,
  1958. .right-code {
  1959. // width: 50%;
  1960. // float: left;
  1961. h2 {
  1962. font-size: 18px;
  1963. text-align: center;
  1964. padding-bottom: 8px;
  1965. }
  1966. .qrcode {
  1967. display: flex;
  1968. flex-direction: column;
  1969. align-items: center;
  1970. img {
  1971. width: 200px;
  1972. height: 200px;
  1973. margin: 0 auto;
  1974. }
  1975. }
  1976. .code-url {
  1977. font-size: 18px;
  1978. text-align: center;
  1979. padding: 15px 15px 0 15px;
  1980. }
  1981. }
  1982. .newBand {
  1983. margin-bottom: 0;
  1984. max-width: inherit;
  1985. }
  1986. /deep/.el-button--danger {
  1987. background: #f85043;
  1988. }
  1989. .paymentForm {
  1990. /deep/.el-input__inner,
  1991. /deep/.el-input.el-input--suffix {
  1992. width: 360px !important;
  1993. }
  1994. }
  1995. .popoverWrap {
  1996. p {
  1997. line-height: 25px;
  1998. }
  1999. }
  2000. </style>