studentList.vue 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560
  1. <template>
  2. <div class="stu-container">
  3. <!-- 头部展示 -->
  4. <!-- <statistic>
  5. <statistic-item>
  6. <span>在读人数</span>
  7. <span>{{ studentListInfo.studying }}</span>
  8. </statistic-item>
  9. <statistic-item>
  10. <span>退团人数</span>
  11. <span>{{ studentListInfo.quit }}</span>
  12. </statistic-item>
  13. <statistic-item>
  14. <span>新增人数</span>
  15. <span>{{ studentListInfo.add }}</span>
  16. </statistic-item>
  17. <statistic-item>
  18. <span>VIP&网管转化率</span>
  19. <span>{{ studentListInfo.courseRate }}</span>
  20. </statistic-item>
  21. </statistic> -->
  22. <!-- style="margin-bottom: 15px" -->
  23. <p
  24. style="margin-bottom: 15px; font-size: 16px; font-weight: 400"
  25. v-if="
  26. team_status == 'PAY' ||
  27. team_status == 'APPLY' ||
  28. (team_status == 'PROGRESS' && isCanReg) ||
  29. team_status == 'PREPARE'
  30. "
  31. >
  32. <span> 报名截止时间:{{ applyExpireDate | formatTimer }} </span>
  33. <span v-if="team_status != 'APPLY'">
  34. 缴费截止时间:{{ paymentExpireDate | formatTimer }}
  35. </span>
  36. </p>
  37. <div class="studentListWrap" v-if="team_status == 'PROGRESS'">
  38. <div
  39. class="newBand"
  40. v-permission="'studentRegistration/insertStudent'"
  41. @click="createStudentFrom"
  42. >
  43. 新增学员
  44. </div>
  45. <!-- 可以直接去学生考勤查看 -->
  46. <!-- <el-button type="primary" v-permission="'/studentSignin'"
  47. @click="gotoSignin">点名总览</el-button> -->
  48. <!-- <div
  49. class="newBand"
  50. v-permission="'studentManage/queryStudentSubTotalCourseTimes'"
  51. @click="viewTimer"
  52. style="margin-right: 15px"
  53. >
  54. 剩余时长明细
  55. </div> -->
  56. </div>
  57. <div
  58. style="display: flex; justify-content: space-between; align-items: center"
  59. v-if="
  60. team_status == 'PAY' ||
  61. team_status == 'APPLY' ||
  62. (team_status == 'PROGRESS' && isCanReg) ||
  63. team_status == 'PREPARE'
  64. "
  65. >
  66. <!-- <h2> -->
  67. <!-- + '报名详情' -->
  68. <!-- <el-page-header @back="onCancel" :content="teamName">
  69. </el-page-header> -->
  70. <!-- </h2> -->
  71. <div
  72. class="btnList"
  73. style="margin-bottom: 15px; font-size: 18px; font-weight: 400"
  74. >
  75. <!-- <div class='newBand close'
  76. v-permission="'musicGroup/cancelMusicGroup'"
  77. @click="onClose">停止乐团</div> v-show="status == 'APPLY'"-->
  78. <div
  79. class="newBand"
  80. @click="payStart"
  81. v-permission="'musicGroup/openPay'"
  82. v-if="team_status == 'APPLY'"
  83. >
  84. 开始缴费
  85. </div>
  86. <!-- v-show="status=='PAY'" -->
  87. <div
  88. class="newBand"
  89. v-permission="'musicGroup/found'"
  90. @click="onGoHome"
  91. v-if="team_status == 'APPLY' || team_status == 'PAY'"
  92. >
  93. 确认开团
  94. </div>
  95. <div
  96. class="newBand"
  97. v-permission="'musicGroup/extensionPayment'"
  98. @click="extendTime(true)"
  99. v-show="
  100. team_status == 'PAY' ||
  101. team_status == 'PROGRESS' ||
  102. team_status == 'PREPARE'
  103. "
  104. >
  105. 延长缴费
  106. </div>
  107. <div
  108. class="newBand"
  109. v-permission="'musicGroup/extensionApplyExpireDate'"
  110. @click="extendTime(false)"
  111. v-show="
  112. team_status == 'PAY' ||
  113. team_status == 'APPLY' ||
  114. team_status == 'PROGRESS' ||
  115. team_status == 'PREPARE'
  116. "
  117. >
  118. 延长报名
  119. </div>
  120. <div class="newBand" @click="onCreateQRCode('payment')">报名链接</div>
  121. <div class="newBand" @click="onCreateQRCode('rePayment')">
  122. 报名链接(无乐器)
  123. </div>
  124. <div class="newBand" @click="onCreateQRCode('detail')">
  125. 报名缴费详情
  126. </div>
  127. <div
  128. class="newBand"
  129. v-permission="'musicGroup/addMusicGroupRegs'"
  130. @click="mergeVisible = true"
  131. v-show="team_status == 'PAY' || team_status == 'APPLY'"
  132. >
  133. 合并学员
  134. </div>
  135. <div
  136. v-if="team_status == 'APPLY'"
  137. v-permission="'studentRegistration/openPayment'"
  138. class="newBand"
  139. style="background-color: #14928a; border: 1px solid #14928a"
  140. @click="onPartPayment"
  141. type="primary"
  142. >
  143. 提前开启缴费
  144. </div>
  145. <el-popover placement="bottom" width="800" trigger="hover">
  146. <div>
  147. <el-table
  148. style="width: 100% !important"
  149. :data="leftList"
  150. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  151. >
  152. <el-table-column
  153. label="乐团声部"
  154. prop="subjectName"
  155. align="center"
  156. >
  157. </el-table-column>
  158. <el-table-column
  159. label="计划招生"
  160. prop="expectedStudentNum"
  161. align="center"
  162. >
  163. <template slot-scope="scope">
  164. <div>
  165. <p v-show="!isEdit">{{ scope.row.expectedStudentNum }}</p>
  166. <el-input
  167. v-show="isEdit"
  168. v-model.trim="scope.row.expectedStudentNum"
  169. ></el-input>
  170. </div>
  171. </template>
  172. </el-table-column>
  173. <el-table-column
  174. label="已报名"
  175. prop="applyStudentNum"
  176. align="center"
  177. >
  178. </el-table-column>
  179. <el-table-column label="已缴费" prop="payNum" align="center">
  180. </el-table-column>
  181. </el-table>
  182. <div
  183. class="btnWrap"
  184. v-permission="'musicGroup/updateExpectedStudentNum'"
  185. style="margin-right: 20px; margin-top: 20px"
  186. >
  187. <el-button v-show="!isEdit" @click="isEdit = true"
  188. >编辑</el-button
  189. >
  190. <el-button v-show="isEdit" @click="saveIsEdit">保存</el-button>
  191. </div>
  192. </div>
  193. <!-- <auth :auths="'studentRegistration/openPayment'">
  194. <el-button
  195. style="background-color: #14928a; border: 1px solid #14928a"
  196. @click="onPartPayment"
  197. type="primary"
  198. >开启缴费</el-button
  199. >
  200. </auth> -->
  201. <div class="newBand" style="margin-bottom: 10px" slot="reference">
  202. 声部报名计划
  203. </div>
  204. </el-popover>
  205. </div>
  206. </div>
  207. <!-- v-if="
  208. team_status == 'PAY' ||
  209. team_status == 'PROGRESS' ||
  210. team_status == 'PREPARE'
  211. " -->
  212. <!-- 搜索类型 -->
  213. <save-form
  214. ref="searchForm"
  215. :inline="true"
  216. :save-key="saveKey"
  217. class="searchForm"
  218. @submit="search"
  219. @reset="onReSet"
  220. :model="searchForm"
  221. >
  222. <el-form-item prop="search">
  223. <el-input
  224. v-model.trim="searchForm.search"
  225. clearable
  226. placeholder="学生姓名或电话"
  227. @keyup.enter.native="search"
  228. ></el-input>
  229. </el-form-item>
  230. <el-form-item prop="studentStatus">
  231. <el-select
  232. v-model.trim="searchForm.studentStatus"
  233. clearable
  234. filterable
  235. placeholder="学员状态"
  236. >
  237. <el-option label="在读" value="NORMAL"></el-option>
  238. <el-option label="请假" value="LEAVE"></el-option>
  239. <el-option label="退团" value="QUIT"></el-option>
  240. <el-option label="报名" value="APPLY"></el-option>
  241. </el-select>
  242. </el-form-item>
  243. <el-form-item prop="createYear">
  244. <el-date-picker
  245. v-model="searchForm.createYear"
  246. type="year"
  247. value-format="yyyy"
  248. placeholder="选择入团年份"
  249. >
  250. </el-date-picker>
  251. </el-form-item>
  252. <el-form-item prop="currentGrade">
  253. <!-- <el-input
  254. v-model.trim="searchForm.currentGrade"
  255. clearable
  256. placeholder="学员年级"
  257. ></el-input> -->
  258. <el-select
  259. v-model.trim="searchForm.currentGrade"
  260. filterable
  261. clearable
  262. placeholder="请输入年级"
  263. >
  264. <el-option
  265. v-for="(item, index) in gradeList"
  266. :key="index"
  267. :label="item.label"
  268. :value="item.label"
  269. ></el-option>
  270. </el-select>
  271. </el-form-item>
  272. <el-form-item prop="classGroupId">
  273. <el-select
  274. v-model.trim="searchForm.classGroupId"
  275. clearable
  276. filterable
  277. placeholder="请选择班级"
  278. >
  279. <el-option
  280. v-for="(item, index) in classList"
  281. :key="index"
  282. :value="item.id"
  283. :label="item.name"
  284. ></el-option>
  285. </el-select>
  286. </el-form-item>
  287. <el-form-item prop="major">
  288. <el-select
  289. v-model.trim="searchForm.major"
  290. clearable
  291. filterable
  292. placeholder="所选专业"
  293. >
  294. <el-option
  295. v-for="(item, index) in soundList"
  296. :key="index"
  297. :value="item.id"
  298. :label="item.name"
  299. ></el-option>
  300. </el-select>
  301. </el-form-item>
  302. <el-form-item prop="isPay">
  303. <el-select
  304. v-model.trim="searchForm.isPay"
  305. clearable
  306. filterable
  307. placeholder="报名缴费"
  308. >
  309. <el-option label="未开启缴费" value="0"></el-option>
  310. <el-option label="开启缴费" value="1"></el-option>
  311. <el-option label="已缴费" value="2"></el-option>
  312. </el-select>
  313. </el-form-item>
  314. <el-form-item prop="oweFlag">
  315. <el-select
  316. v-model.trim="searchForm.oweFlag"
  317. clearable
  318. filterable
  319. placeholder="是否欠费"
  320. >
  321. <el-option label="否" value="0"></el-option>
  322. <el-option label="是" value="1"></el-option>
  323. </el-select>
  324. </el-form-item>
  325. <el-form-item prop="isActive">
  326. <el-select
  327. v-model.trim="searchForm.isActive"
  328. clearable
  329. filterable
  330. placeholder="是否激活"
  331. >
  332. <el-option label="是" value="1"></el-option>
  333. <el-option label="否" value="0"></el-option>
  334. </el-select>
  335. </el-form-item>
  336. <el-form-item prop="hasCourse">
  337. <el-select
  338. v-model.trim="searchForm.hasCourse"
  339. clearable
  340. placeholder="VIP/网管是否有课"
  341. >
  342. <el-option label="是" value="true"></el-option>
  343. <el-option label="否" value="false"></el-option>
  344. </el-select>
  345. </el-form-item>
  346. <el-form-item prop="carePackage">
  347. <el-select
  348. class="multiple"
  349. v-model.trim="searchForm.carePackage"
  350. clearable
  351. placeholder="关心包"
  352. >
  353. <el-option label="不可用" :value="0"></el-option>
  354. <el-option label="可用" :value="1"></el-option>
  355. <el-option label="已使用" :value="2"></el-option>
  356. </el-select>
  357. </el-form-item>
  358. <el-form-item prop="comeOnPackage">
  359. <el-select
  360. class="multiple"
  361. v-model.trim="searchForm.comeOnPackage"
  362. clearable
  363. placeholder="加油包"
  364. >
  365. <el-option label="不可用" :value="0"></el-option>
  366. <el-option label="可用" :value="1"></el-option>
  367. <el-option label="已使用" :value="2"></el-option>
  368. </el-select>
  369. </el-form-item>
  370. <el-form-item>
  371. <el-button native-type="submit" type="danger">搜索</el-button>
  372. <el-button type="primary" native-type="reset">重置</el-button>
  373. <el-button
  374. type="primary"
  375. v-permission="'export/musicGroupStudent'"
  376. @click="onMusicGroupExport"
  377. >导出</el-button
  378. >
  379. </el-form-item>
  380. </save-form>
  381. <div style="font-size: 14px; color: #f85043; padding-bottom: 10px">
  382. 在读人数:{{ studentListInfo.studying
  383. }}<i style="width: 10px; display: inline-block"></i> 退团人数:{{
  384. studentListInfo.quit
  385. }}<i style="width: 10px; display: inline-block"></i> VIP&网管转化率:{{
  386. studentListInfo.courseRate
  387. }}<i style="width: 10px; display: inline-block"></i>
  388. </div>
  389. <!-- 列表 -->
  390. <div class="tableWrap">
  391. <el-table
  392. :data="tableList"
  393. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  394. @selection-change="handleSelectionChange"
  395. >
  396. <el-table-column
  397. type="selection"
  398. width="55"
  399. :selectable="checkboxSelect"
  400. ></el-table-column>
  401. <el-table-column label="学员编号" width="120px;" prop="userId">
  402. <template slot-scope="scope">
  403. <copy-text>
  404. {{ scope.row.userId }}
  405. </copy-text>
  406. </template>
  407. </el-table-column>
  408. <el-table-column label="学员姓名" width="120px;" prop="realName">
  409. <template slot-scope="scope">
  410. <copy-text>
  411. {{ scope.row.realName }}
  412. </copy-text>
  413. </template>
  414. </el-table-column>
  415. <el-table-column
  416. align="center"
  417. prop="gender"
  418. width="50px;"
  419. label="性别"
  420. >
  421. <template slot-scope="scope">
  422. <div>{{ scope.row.gender | sex }}</div>
  423. </template>
  424. </el-table-column>
  425. <el-table-column align="center" prop="phone" label="联系电话">
  426. <template slot-scope="scope">
  427. <copy-text>
  428. {{ scope.row.phone }}
  429. </copy-text>
  430. </template>
  431. </el-table-column>
  432. <el-table-column align="center" label="入团年份">
  433. <template slot-scope="scope">
  434. <div>{{ scope.row.registerTime | dayjsFormat("YYYY年") }}</div>
  435. </template>
  436. </el-table-column>
  437. <el-table-column align="center" label="年级班级">
  438. <template slot-scope="scope">
  439. <div>{{ scope.row.currentGrade + scope.row.currentClass }}</div>
  440. </template>
  441. </el-table-column>
  442. <el-table-column align="center" label="报名专业" prop="subjectName">
  443. <template slot-scope="scope">
  444. <copy-text>
  445. {{ scope.row.regSubjectName }}
  446. </copy-text>
  447. </template>
  448. </el-table-column>
  449. <el-table-column align="center" label="入团专业" prop="subjectName">
  450. <template slot-scope="scope">
  451. <copy-text>
  452. {{ scope.row.subjectName }}
  453. </copy-text>
  454. </template>
  455. </el-table-column>
  456. <el-table-column align="center" prop="studentStatus" label="学员状态">
  457. <template slot-scope="scope">
  458. <div>{{ scope.row.studentStatus | musicGroupStudentType }}</div>
  459. </template>
  460. </el-table-column>
  461. <!-- <el-table-column align="center" label="新增学员">
  462. <template slot-scope="scope">
  463. <div>{{ scope.row.isNewStudent | yesOrNo }}</div>
  464. </template>
  465. </el-table-column> -->
  466. <el-table-column align="center" label="报名缴费">
  467. <template slot-scope="scope">
  468. <div>{{ scope.row.paymentStatus | paymentStatus }}</div>
  469. </template>
  470. </el-table-column>
  471. <el-table-column align="center" label="是否激活">
  472. <template slot-scope="scope">
  473. <div>{{ scope.row.isActive ? "是" : "否" }}</div>
  474. </template>
  475. </el-table-column>
  476. <el-table-column align="center" label="VIP/网管是否有课">
  477. <template slot-scope="scope">
  478. <div>{{ scope.row.hasCourse ? "是" : "否" }}</div>
  479. </template>
  480. </el-table-column>
  481. <el-table-column align="center" label="关心包">
  482. <template slot-scope="scope">{{
  483. scope.row.carePackage | studentPackage
  484. }}</template>
  485. </el-table-column>
  486. <el-table-column align="center" label="加油包">
  487. <template slot-scope="scope">{{
  488. scope.row.comeOnPackage | studentPackage
  489. }}</template>
  490. </el-table-column>
  491. <el-table-column align="center" label="欠费金额(元)">
  492. <template slot-scope="scope">
  493. <div :class="[scope.row.noPaymentAmount > 0 ? 'error' : null]">
  494. {{ scope.row.noPaymentAmount | moneyFormat }}
  495. <!-- musicGroupPaymentCalenderDetail/queryPage/studentList -->
  496. <auth
  497. auths="musicGroupPaymentCalenderDetail/queryPage/studentList"
  498. :router="['/teamLists']"
  499. >
  500. <i
  501. style="color: #14928a; font-size: 17px"
  502. title="缴费记录"
  503. class="el-icon-view"
  504. @click="onPaymentDetail(scope.row)"
  505. ></i>
  506. </auth>
  507. </div>
  508. </template>
  509. </el-table-column>
  510. <el-table-column label="退团原因" align="center">
  511. <template slot-scope="scope">
  512. <div>
  513. <Tooltip :content="scope.row.quitReason" />
  514. </div>
  515. </template>
  516. </el-table-column>
  517. <el-table-column
  518. align="center"
  519. fixed="right"
  520. width="360px;"
  521. label="操作"
  522. >
  523. <template slot-scope="scope">
  524. <div>
  525. <el-button
  526. type="text"
  527. v-if="
  528. permission('studentManage/queryStudentClassGroup') &&
  529. scope.row.studentStatus != 'QUIT'
  530. "
  531. @click="lookClass(scope.row)"
  532. >查看班级</el-button
  533. >
  534. <el-button
  535. type="text"
  536. v-if="
  537. permission('musicGroupPaymentCalender/add') &&
  538. scope.row.studentStatus == 'APPLY' &&
  539. scope.row.paymentStatus != '2' &&
  540. team_status == 'PROGRESS'
  541. "
  542. @click="addPay(scope.row)"
  543. >添加缴费</el-button
  544. >
  545. <el-button
  546. type="text"
  547. v-if="
  548. permission('musicGroupQuit/directQuitMusicGroup2') &&
  549. scope.row.studentStatus != 'QUIT'
  550. "
  551. @click="quieTeamMask(scope.row)"
  552. >退团退费</el-button
  553. >
  554. <el-button
  555. type="text"
  556. v-if="
  557. permission('musicGroupQuit/directQuitMusicGroup3') &&
  558. scope.row.studentStatus != 'QUIT'
  559. "
  560. @click="quieTeam(scope.row)"
  561. >退团</el-button
  562. >
  563. <el-button
  564. type="text"
  565. v-if="permission('visit/add/teamStudentList')"
  566. @click="addVisit(scope.row)"
  567. >新增回访</el-button
  568. >
  569. <auth :auths="'studentRegistration/batchUpdateSubject'">
  570. <el-button
  571. type="text"
  572. v-show="scope.row.paymentStatus != 2 && isShowResSound()&& scope.row.studentStatus != 'QUIT'"
  573. @click="resetSubject(scope.row)"
  574. >修改专业</el-button
  575. >
  576. </auth>
  577. <!-- APPLY status == "APPLY" || s-->
  578. <el-popover
  579. v-show="scope.row.remark"
  580. placement="top-start"
  581. title="备注"
  582. width="200"
  583. trigger="hover"
  584. :content="scope.row.remark"
  585. >
  586. <el-button type="text" slot="reference">备注</el-button>
  587. </el-popover>
  588. <!-- PAY -->
  589. <!-- && status == "PAY"-->
  590. <auth
  591. :auths="'studentRegistration/queryFeeDetail'"
  592. v-show="scope.row.paymentStatus == 2"
  593. >
  594. <el-button type="text" @click="lookdetail(scope.row)"
  595. >查看</el-button
  596. >
  597. </auth>
  598. <auth
  599. :auths="'subjectChange/getStudentOriginal'"
  600. v-show="scope.row.paymentStatus == 2 && isShowResSound()&& scope.row.studentStatus != 'QUIT'"
  601. >
  602. <el-button type="text" @click="openChangeVoice(scope.row)"
  603. >更改声部</el-button
  604. >
  605. </auth>
  606. </div>
  607. </template>
  608. </el-table-column>
  609. </el-table>
  610. <pagination
  611. :save-key="saveKey"
  612. sync
  613. :total.sync="rules.total"
  614. :page.sync="rules.page"
  615. :limit.sync="rules.limit"
  616. :page-sizes="rules.page_size"
  617. @pagination="getList"
  618. />
  619. </div>
  620. <el-dialog
  621. title="新增学员"
  622. width="700px"
  623. class="studentInfo"
  624. :visible.sync="addStudentVisible"
  625. >
  626. <el-form
  627. :model="maskForm"
  628. label-position="right"
  629. label-width="120px"
  630. ref="maskForm"
  631. :rules="maskRules"
  632. :inline="true"
  633. >
  634. <el-alert title="基本信息" :closable="false" class="alert" type="info">
  635. </el-alert>
  636. <el-form-item
  637. label="联系电话"
  638. prop="phone"
  639. :rules="[
  640. { required: true, message: '请输入手机号' },
  641. {
  642. pattern: /^1[3456789]\d{9}$/,
  643. message: '请输入正确的手机号',
  644. trigger: 'blur',
  645. },
  646. ]"
  647. >
  648. <el-input
  649. v-model.trim="maskForm.phone"
  650. placeholder="联系电话"
  651. @blur="checkPhone(maskForm.phone)"
  652. ></el-input>
  653. </el-form-item>
  654. <el-form-item label="学员姓名" prop="studentName">
  655. <el-input
  656. v-model.trim="maskForm.studentName"
  657. placeholder="学员姓名"
  658. ></el-input>
  659. </el-form-item>
  660. <el-form-item label="学员性别" prop="sex">
  661. <el-select v-model.trim="maskForm.sex" clearable>
  662. <el-option label="男" :value="1"></el-option>
  663. <el-option label="女" :value="0"></el-option>
  664. </el-select>
  665. </el-form-item>
  666. <el-form-item label="家长姓名" prop="parentName">
  667. <el-input
  668. v-model.trim="maskForm.parentName"
  669. placeholder="家长姓名"
  670. ></el-input>
  671. </el-form-item>
  672. <el-form-item label="年级" prop="currentGradeNum">
  673. <el-select
  674. placeholder="起始年级"
  675. filterable
  676. clearable
  677. v-model.trim="maskForm.currentGradeNum"
  678. >
  679. <el-option
  680. v-for="item in gradeList"
  681. :key="item.value"
  682. :label="item.label"
  683. :value="item.value"
  684. ></el-option>
  685. <!-- <el-option value="一年级" label="一年级"></el-option>
  686. <el-option value="二年级" label="二年级"></el-option>
  687. <el-option value="三年级" label="三年级"></el-option>
  688. <el-option value="四年级" label="四年级"></el-option>
  689. <el-option value="五年级" label="五年级"></el-option>
  690. <el-option value="六年级" label="六年级"></el-option>
  691. <el-option value="初一" label="初一"></el-option>
  692. <el-option value="初二" label="初二"></el-option>
  693. <el-option value="初三" label="初三"></el-option>
  694. <el-option value="高一" label="高一"></el-option>
  695. <el-option value="高二" label="高二"></el-option>
  696. <el-option value="高三" label="高三"></el-option> -->
  697. </el-select>
  698. </el-form-item>
  699. <el-form-item label="班级" prop="course">
  700. <el-input
  701. v-model.trim="maskForm.course"
  702. placeholder="班级"
  703. ></el-input>
  704. </el-form-item>
  705. <el-form-item label="学员声部" prop="sound">
  706. <el-select
  707. v-model.trim="maskForm.sound"
  708. clearable
  709. filterable
  710. @change="onSoundChange"
  711. >
  712. <el-option
  713. v-for="(item, index) in soundList"
  714. :key="index"
  715. :value="item.id"
  716. :label="item.name"
  717. ></el-option>
  718. </el-select>
  719. </el-form-item>
  720. <!-- <el-form-item label="证件号"
  721. prop="id">
  722. <el-input v-model.trim="maskForm.id"></el-input>
  723. </el-form-item>-->
  724. <el-form-item label="出生日期" style="margin-right: 0" prop="timer">
  725. <el-col :span="24">
  726. <el-date-picker
  727. v-model.trim="maskForm.timer"
  728. value-format="yyyy-MM-dd"
  729. type="date"
  730. :picker-options="{
  731. firstDayOfWeek: 1,
  732. }"
  733. placeholder="选择日期"
  734. ></el-date-picker>
  735. </el-col>
  736. </el-form-item>
  737. </el-form>
  738. <div slot="footer" class="dialog-footer">
  739. <!-- <el-button @click="addStudentVisible = false">取 消</el-button> -->
  740. <el-button type="primary" @click="addStudent">确 定</el-button>
  741. </div>
  742. </el-dialog>
  743. <el-dialog
  744. title="学员所在班级"
  745. width="640px"
  746. :visible.sync="studentClassVisible"
  747. >
  748. <el-form :model="classMask">
  749. <el-form-item label="学生姓名">{{
  750. classMask.studentName
  751. }}</el-form-item>
  752. <el-form-item
  753. label="所在班级"
  754. v-for="(item, index) in classLists"
  755. :key="index"
  756. >{{ item.name }}</el-form-item
  757. >
  758. </el-form>
  759. </el-dialog>
  760. <!-- 退团弹窗 -->
  761. <el-dialog title="退团信息确认" width="640px" :visible.sync="quitVisible">
  762. <el-form :model="quitForm" ref="quitForm" :rules="quitRules">
  763. <el-form-item label="退还课程费用" prop="isRefundCourseFee">
  764. <el-radio v-model.trim="quitForm.isRefundCourseFee" :label="true"
  765. >是</el-radio
  766. >
  767. <el-radio v-model.trim="quitForm.isRefundCourseFee" :label="false"
  768. >否</el-radio
  769. >
  770. </el-form-item>
  771. <el-form-item label="退还乐器费用" prop="isRefundInstrumentFee">
  772. <el-radio v-model.trim="quitForm.isRefundInstrumentFee" :label="true"
  773. >是</el-radio
  774. >
  775. <el-radio v-model.trim="quitForm.isRefundInstrumentFee" :label="false"
  776. >否</el-radio
  777. >
  778. </el-form-item>
  779. <el-form-item label="退还教辅费用" prop="isRefundTeachingAssistantsFee">
  780. <el-radio
  781. v-model.trim="quitForm.isRefundTeachingAssistantsFee"
  782. :label="true"
  783. >是</el-radio
  784. >
  785. <el-radio
  786. v-model.trim="quitForm.isRefundTeachingAssistantsFee"
  787. :label="false"
  788. >否</el-radio
  789. >
  790. </el-form-item>
  791. <el-form-item label="退团原因" prop="reason">
  792. <el-input type="textarea" v-model.trim="quitForm.reason"></el-input>
  793. </el-form-item>
  794. </el-form>
  795. <span slot="footer" class="dialog-footer question">
  796. <div>
  797. <el-popover placement="right" width="500" trigger="click">
  798. <div class="popoverWrap">
  799. <p>乐团退团退费规则:</p>
  800. <p>退还课程费用:缴费总额-已结束课时单价之和</p>
  801. <p>退还乐器费用:报名缴费时缴纳的乐器费用(团购、租金)</p>
  802. <p>退还教辅费用:报名缴费时缴费的教辅费用</p>
  803. </div>
  804. <el-button
  805. type="text"
  806. icon="el-icon-question"
  807. slot="reference"
  808. style="color: red"
  809. >退团退费说明</el-button
  810. >
  811. </el-popover>
  812. </div>
  813. <div>
  814. <el-button @click="quitVisible = false">取 消</el-button>
  815. <el-button type="primary" @click="chioseType">确 定</el-button>
  816. </div>
  817. </span>
  818. </el-dialog>
  819. <el-dialog title="报名二维码" :visible.sync="qrcodeStatus" width="300px">
  820. <div class="left-code">
  821. <h2>学员报名连接</h2>
  822. <div id="qrcode" class="qrcode code" ref="qrCodeUrl"></div>
  823. <p class="code-url" v-if="codeUrl">{{ codeUrl }}</p>
  824. </div>
  825. </el-dialog>
  826. <el-dialog :visible.sync="timesVisible" title="查看剩余可排课时长">
  827. <times-view v-if="timesVisible" @close="timesVisible = false" />
  828. </el-dialog>
  829. <el-dialog
  830. title="修改缴费周期"
  831. :before-close="closePayVisible"
  832. width="600px"
  833. :visible.sync="payVisible"
  834. >
  835. <el-form :model="payForm" ref="payForm" :inline="true">
  836. <el-form-item label="学生姓名" prop="studentName">
  837. <el-input v-model.trim="payForm.studentName" disabled></el-input>
  838. </el-form-item>
  839. <br />
  840. <el-form-item label="缴费金额" prop="payMoney">
  841. <el-input
  842. type="number"
  843. v-model.trim="payForm.payMoney"
  844. @mousewheel.native.prevent
  845. ></el-input>
  846. </el-form-item>
  847. <el-form-item label="缴费月份" prop="payMonth">
  848. <el-checkbox-group
  849. v-model.trim="payForm.payMonth"
  850. fill="#14928A"
  851. text-color="#474747"
  852. >
  853. <el-checkbox label="1">一月</el-checkbox>
  854. <el-checkbox label="2">二月</el-checkbox>
  855. <el-checkbox label="3">三月</el-checkbox>
  856. <el-checkbox label="4">四月</el-checkbox>
  857. <el-checkbox label="5">五月</el-checkbox>
  858. <el-checkbox label="6">六月</el-checkbox>
  859. <el-checkbox label="7">七月</el-checkbox>
  860. <el-checkbox label="8">八月</el-checkbox>
  861. <el-checkbox label="9">九月</el-checkbox>
  862. <el-checkbox label="10">十月</el-checkbox>
  863. <el-checkbox label="11">十一月</el-checkbox>
  864. <el-checkbox label="12">十二月</el-checkbox>
  865. </el-checkbox-group>
  866. </el-form-item>
  867. <!-- studentName: '',
  868. payMoney: '',
  869. payMonth-->
  870. </el-form>
  871. <div slot="footer" class="dialog-footer">
  872. <el-button @click="quitVisible = false">取 消</el-button>
  873. <el-button type="primary" @click="submitPay">确 定</el-button>
  874. </div>
  875. </el-dialog>
  876. <el-dialog
  877. title="新增回访"
  878. width="500px"
  879. destroy-on-close
  880. :close-on-click-modal="false"
  881. :visible.sync="visitVisiable"
  882. >
  883. <visit
  884. v-if="visitVisiable && detail"
  885. :detail="detail"
  886. @close="visitVisiable = false"
  887. @submited="getList"
  888. />
  889. </el-dialog>
  890. <el-dialog
  891. title="选择班级"
  892. destroy-on-close
  893. width="700px"
  894. :visible.sync="createUserPayVisible"
  895. >
  896. <createUserPay
  897. :signList="signList"
  898. :mixList="mixList"
  899. :highList="highList"
  900. :snapList="snapList"
  901. :musicGroupId="this.teamid"
  902. :organizationCourseUnitPriceSettings="
  903. organizationCourseUnitPriceSettings
  904. "
  905. :createdUserId="createdUserId"
  906. :baseInfo="baseInfo"
  907. @submited="getList"
  908. @close="createUserPayVisible = false"
  909. />
  910. </el-dialog>
  911. <el-dialog
  912. title="缴费记录"
  913. width="900px"
  914. :visible.sync="paymentDetailVisible"
  915. >
  916. <payment-list
  917. v-if="paymentDetailVisible"
  918. :paymentDetail="paymentDetail"
  919. @close="paymentDetailVisible = false"
  920. />
  921. </el-dialog>
  922. <el-dialog title="选择合并乐团" :visible.sync="mergeVisible" width="950px">
  923. <mergeMusic
  924. v-if="mergeVisible"
  925. style="padding: 0 20px"
  926. :organId="organId"
  927. @close="mergeVisible = false"
  928. @submited="getList"
  929. />
  930. </el-dialog>
  931. <el-dialog
  932. title="开始缴费"
  933. :visible.sync="paymentStatus"
  934. width="400px"
  935. destroy-on-close
  936. >
  937. <el-form
  938. ref="paymentForm"
  939. class="paymentForm"
  940. :model="paymentForm"
  941. :rules="paymentRules"
  942. >
  943. <el-form-item label="请设置缴费截止日期" prop="paymentExpireDate">
  944. <el-date-picker
  945. v-model.trim="paymentForm.paymentExpireDate"
  946. type="date"
  947. value-format="yyyy-MM-dd"
  948. :picker-options="payDate()"
  949. style="width: 100%"
  950. placeholder="选择日期"
  951. >
  952. </el-date-picker>
  953. </el-form-item>
  954. </el-form>
  955. <div slot="footer" class="dialog-footer">
  956. <el-button @click="paymentStatus = false">取 消</el-button>
  957. <el-button type="primary" @click="onStartPayment('paymentForm')"
  958. >确 定</el-button
  959. >
  960. </div>
  961. </el-dialog>
  962. <el-dialog
  963. :title="!isPay ? '延长报名' : '延长缴费'"
  964. :visible.sync="extendPaymentStatus"
  965. destroy-on-close
  966. width="400px"
  967. >
  968. <el-form :model="extendForm" ref="extendForm" :rules="extendRule">
  969. <el-form-item v-if="isPay" label="延长缴费时间" prop="expireDate">
  970. <el-date-picker
  971. v-model.trim="extendForm.expireDate"
  972. value-format="yyyy-MM-dd"
  973. type="date"
  974. :picker-options="{
  975. firstDayOfWeek: 1,
  976. }"
  977. placeholder="选择日期"
  978. >
  979. </el-date-picker>
  980. </el-form-item>
  981. <el-form-item label="延长报名时间" v-else prop="expireDate">
  982. <el-date-picker
  983. v-model.trim="extendForm.expireDate"
  984. value-format="yyyy-MM-dd"
  985. type="date"
  986. :picker-options="applyDate"
  987. placeholder="选择日期"
  988. >
  989. </el-date-picker>
  990. </el-form-item>
  991. </el-form>
  992. <div slot="footer" class="dialog-footer">
  993. <el-button @click="extendPaymentStatus = false">取 消</el-button>
  994. <el-button
  995. type="primary"
  996. v-if="isPay"
  997. @click="onExtendPayment('extendForm', isPay)"
  998. >确 定</el-button
  999. >
  1000. <el-button
  1001. v-else
  1002. type="primary"
  1003. @click="onExtendPayment('extendForm', isPay)"
  1004. >确 定</el-button
  1005. >
  1006. </div>
  1007. </el-dialog>
  1008. <qr-code v-model="codeStatus" :title="codeTitle" :codeUrl="qrCodeUrl" />
  1009. <el-dialog
  1010. title="更改声部"
  1011. :visible.sync="changeVoiceVisible"
  1012. @close="closeChangeVoice"
  1013. v-if="changeVoiceVisible"
  1014. width="600px"
  1015. >
  1016. <changeVoice
  1017. @close="closeChangeVoice"
  1018. @submited="getList"
  1019. :detail.sync="rowDetail"
  1020. :musicGroupId="teamid"
  1021. :voiceList="leftList"
  1022. />
  1023. </el-dialog>
  1024. <el-dialog
  1025. title="订单详情"
  1026. :visible.sync="orderVisible"
  1027. width="600px"
  1028. v-if="orderVisible"
  1029. >
  1030. <el-form :model="orderForm" :inline="true">
  1031. <!-- name: '',
  1032. totalAmount: '',
  1033. subject: '',
  1034. subjectFee: '',
  1035. axe: '',
  1036. axePrice: '',
  1037. others: '',
  1038. othersPrice: '' -->
  1039. <el-form-item label="学员姓名">
  1040. <el-input v-model.trim="orderForm.name" disabled=""></el-input>
  1041. </el-form-item>
  1042. <el-form-item label="实缴金额">
  1043. <el-input v-model.trim="orderForm.totalAmount" disabled=""></el-input>
  1044. </el-form-item>
  1045. <el-form-item label="实际专业">
  1046. <el-input v-model.trim="orderForm.subject" disabled=""></el-input>
  1047. </el-form-item>
  1048. <el-form-item label="课程费用">
  1049. <el-input v-model.trim="orderForm.subjectFee" disabled=""></el-input>
  1050. </el-form-item>
  1051. <el-form-item label="选择乐器">
  1052. <el-input v-model.trim="orderForm.axe" disabled=""></el-input>
  1053. </el-form-item>
  1054. <el-form-item label="乐器价格">
  1055. <el-input v-model.trim="orderForm.axePrice" disabled=""></el-input>
  1056. </el-form-item>
  1057. <el-form-item label="教辅组合">
  1058. <el-input v-model.trim="orderForm.others" disabled=""></el-input>
  1059. </el-form-item>
  1060. <el-form-item label="组合价格">
  1061. <el-input v-model.trim="orderForm.othersPrice" disabled=""></el-input>
  1062. </el-form-item>
  1063. </el-form>
  1064. <div slot="footer" class="dialog-footer">
  1065. <!-- <el-button>取 消</el-button> -->
  1066. <el-button type="primary" @click="orderVisible = false"
  1067. >确 定</el-button
  1068. >
  1069. </div>
  1070. </el-dialog>
  1071. <el-dialog title="修改专业" :visible.sync="subjectVisible" width="400px">
  1072. <el-form :model="maskSoundForm">
  1073. <el-form-item label="选择专业">
  1074. <el-select v-model.trim="maskSoundForm.subject" filterable clearable>
  1075. <el-option
  1076. v-for="(item, index) in soundList"
  1077. :key="index"
  1078. :label="item.name"
  1079. :value="item.id"
  1080. ></el-option>
  1081. </el-select>
  1082. </el-form-item>
  1083. </el-form>
  1084. <div slot="footer" class="dialog-footer">
  1085. <el-button @click="subjectVisible = false">取 消</el-button>
  1086. <el-button type="primary" @click="okReset">确 定</el-button>
  1087. </div>
  1088. </el-dialog>
  1089. </div>
  1090. </template>
  1091. <script>
  1092. import {
  1093. getTeamStudentList,
  1094. getTeamStudentInfo,
  1095. findSound,
  1096. StudentQuit,
  1097. findSubjectPlan,
  1098. getGoods,
  1099. getMusicGroup,
  1100. getMusicGroupAllClass,
  1101. StudentFeeIsLock,
  1102. updateStudentFee,
  1103. getMusicGroupGradeList,
  1104. getStudentList,
  1105. musicGroupOpenPay,
  1106. extensionPayment,
  1107. extensionApplyExpire,
  1108. getTeamBaseInfo,
  1109. getintoClass,
  1110. resetPlanNum,
  1111. openPayment,
  1112. musicGroupFound,
  1113. checkCanReg,
  1114. } from "@/api/buildTeam";
  1115. import {
  1116. addStudent,
  1117. getStudentClass,
  1118. getStudentInfoByPhone,
  1119. getStudentFeeDetail,
  1120. resetStudentSubject,
  1121. } from "@/api/studentManager";
  1122. import qrCode from "@/components/QrCode/index";
  1123. import { getOrganizationCourseUnitPriceSettings } from "@/api/specialSetting";
  1124. import { visitChiose } from "@/utils/searchArray";
  1125. import pagination from "@/components/Pagination/index";
  1126. import { vaildStudentUrl, vaildTeacherUrl } from "@/utils/validate";
  1127. import QRCode from "qrcodejs2";
  1128. import axios from "axios";
  1129. import { getToken } from "@/utils/auth";
  1130. import { permission } from "@/utils/directivePage";
  1131. import { addVisit } from "@/views/returnVisitManager/api.js";
  1132. import cleanDeep from "clean-deep";
  1133. import createUserPay from "./modals/create-user-pay.vue";
  1134. import TimesView from "./modals/course-time-detail";
  1135. import paymentCycle from "../../resetTeaming/modals/payment-cycle";
  1136. import paymentList from "./modals/payment-list";
  1137. import Tooltip from "@/components/Tooltip/index";
  1138. import changeVoice from "@/views/teamBuild/modals/change-voice";
  1139. //import changeVoice from "./modals/change-voice";
  1140. import visit from "@/views/withdrawal-application/modals/visit";
  1141. import mergeMusic from "@/views/teamBuild/components/merge-music";
  1142. export default {
  1143. name: "tstudentList",
  1144. data() {
  1145. return {
  1146. detail: null,
  1147. teamid: "",
  1148. paymentDetailVisible: false,
  1149. paymentDetail: {},
  1150. payVisible: false,
  1151. quitVisible: false, // 退团信息确认的弹窗
  1152. studentClassVisible: false, // 学员所在班级弹窗
  1153. addStudentVisible: false, //新增学员弹窗
  1154. timesVisible: false,
  1155. timerDetail: null,
  1156. topFrom: {
  1157. // 顶部的禁选框集合
  1158. expect: "2", // 预期招生
  1159. studing: "5", // 在读人数
  1160. allmoney: "100", //实收总额
  1161. students: "5", // 实际招生人数
  1162. signout: "10", // 退团总数
  1163. },
  1164. searchForm: {
  1165. studentStatus: "", // 学生状态
  1166. major: "", // 报名专业
  1167. isPay: "", // 是否缴费
  1168. search: "",
  1169. isActive: "",
  1170. oweFlag: "",
  1171. currentGrade: null,
  1172. createYear: null,
  1173. classGroupId: null,
  1174. hasCourse: null,
  1175. carePackage: null,
  1176. comeOnPackage: null,
  1177. },
  1178. organizationCourseUnitPriceSettings: [],
  1179. quitForm: {
  1180. // 退团信息确认
  1181. isRefundCourseFee: null,
  1182. isRefundInstrumentFee: null,
  1183. isRefundTeachingAssistantsFee: null,
  1184. reason: "",
  1185. },
  1186. classMask: {
  1187. studentName: "",
  1188. },
  1189. baseInfo: {},
  1190. searchLsit: [],
  1191. tableList: [], //
  1192. rules: {
  1193. // 分页规则
  1194. limit: 10, // 限制显示条数
  1195. page: 1, // 当前页
  1196. total: 0, // 总条数
  1197. page_size: [10, 20, 40, 50], // 选择限制显示条数
  1198. },
  1199. studentListInfo: {
  1200. add: "",
  1201. quit: "",
  1202. studying: "",
  1203. courseRate: "",
  1204. },
  1205. signList: [],
  1206. mixList: [],
  1207. highList: [],
  1208. snapList: [],
  1209. soundList: [],
  1210. highonlineList: [],
  1211. muiscnetworkList: [],
  1212. qrcodeStatus: false, // 生成二维码
  1213. qrcodes: true,
  1214. qrcode: null,
  1215. codeUrl: null,
  1216. gradeList: [], // 学生
  1217. maskForm: {
  1218. studentName: "",
  1219. sex: "",
  1220. parentName: "",
  1221. course: "",
  1222. phone: "",
  1223. sound: "",
  1224. timer: "",
  1225. signClass: "",
  1226. mixClass: "",
  1227. highClass: "",
  1228. snapClass: [],
  1229. highonline: "",
  1230. muiscnetwork: "",
  1231. startClass: "",
  1232. currentGradeNum: null,
  1233. id: "",
  1234. // courseFee: null, // 声部费用
  1235. temporaryCourseFee: null, // 本次课程费用
  1236. musicGoodsIdList: null, // 乐器商品编号
  1237. kitGroupPurchaseType: "GROUP", // 乐器购买方式
  1238. musicPrice: null, // 乐器购买金额
  1239. instrGoodsIdList: [], // 辅件商品编号
  1240. instrPrice: null, // 辅件购买金额
  1241. },
  1242. remark: "", // 退团原因
  1243. classList: [],
  1244. quitRules: {
  1245. isRefundCourseFee: [
  1246. { required: true, message: "请选择是否退还课程费用" },
  1247. ],
  1248. isRefundInstrumentFee: [
  1249. { required: true, message: "选择是否退还乐器费用" },
  1250. ],
  1251. isRefundTeachingAssistantsFee: [
  1252. { required: true, message: "选择是否退还教辅费用" },
  1253. ],
  1254. reason: [{ required: true, message: "请填写退团退费原因" }],
  1255. },
  1256. maskRules: {
  1257. studentName: [{ required: true, message: "请输入学生姓名" }],
  1258. sex: [{ required: true, message: "请选择学生姓名" }],
  1259. parentName: [{ required: true, message: "请输入家长姓名" }],
  1260. course: [{ required: true, message: "请输入班级" }],
  1261. // phone: [{ required: true, message: '请输入手机号' }, { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }],
  1262. sound: [{ required: true, message: "请选择声部" }],
  1263. timer: [{ required: true, message: "请选择出生日期" }],
  1264. signClass: [{ required: true, message: "请选择声部班" }],
  1265. // price: [{ required: true, message: '请输入首缴金额' },],
  1266. currentGradeNum: [{ required: true, message: "请选择年级" }],
  1267. id: [{ required: true, message: "请输入证件号" }],
  1268. // courseFee: [{ required: true, message: "请输入声部费用" }],
  1269. temporaryCourseFee: [{ required: true, message: "请输课程费用" }],
  1270. musicGoodsIdList: [
  1271. { required: true, message: "请选择乐器", trigger: "change" },
  1272. ],
  1273. musicPrice: [{ required: true, message: "请输入乐器购买金额" }],
  1274. instrGoodsIdList: [{ required: true, message: "请选择辅件" }],
  1275. instrPrice: [{ required: true, message: "请输入辅件金额" }],
  1276. },
  1277. INSTRUMENTLIST: [], // 乐器列表
  1278. ACCESSORIESLIST: [], // 辅件列表
  1279. activeRow: null,
  1280. Fsearch: null,
  1281. Frules: null,
  1282. payForm: {
  1283. studentName: "",
  1284. payMoney: "",
  1285. payMonth: [],
  1286. },
  1287. kitStatus: false, // 乐器提供方式
  1288. // 新增回访记录弹窗
  1289. visitVisiable: false,
  1290. visitForm: {
  1291. musicGroupId: "",
  1292. overview: "",
  1293. purpose: "",
  1294. studentId: "",
  1295. type: "",
  1296. visitTime: "",
  1297. visitType: "",
  1298. feedback: "",
  1299. studentName: "",
  1300. },
  1301. cycles: [{}],
  1302. collapse: [0],
  1303. visitChiose,
  1304. visitRules: {
  1305. overview: [{ required: true, message: "请输入学生近况" }],
  1306. feedback: [{ required: true, message: "请输入家长反馈" }],
  1307. visitTime: [{ required: true, message: "请输入回访时间" }],
  1308. visitType: [{ required: true, message: "请选择回访类型" }],
  1309. },
  1310. pickerOptions: null,
  1311. classLists: null,
  1312. createdUserId: 0,
  1313. createUserPayVisible: false,
  1314. team_status: "",
  1315. // 整合报名中
  1316. paymentExpireDate: "",
  1317. applyExpireDate: null,
  1318. mergeVisible: false,
  1319. team_status: "",
  1320. paymentNum: 0,
  1321. paymentStatus: false,
  1322. paymentForm: {
  1323. paymentExpireDate: null,
  1324. // feeType: null
  1325. },
  1326. paymentRules: {
  1327. paymentExpireDate: [
  1328. { required: true, message: "请设置缴费截止日期", trigger: "blur" },
  1329. ],
  1330. },
  1331. extendForm: {
  1332. expireDate: null,
  1333. },
  1334. extendRule: {
  1335. expireDate: [
  1336. { required: true, message: "请选择延长时间", trigger: "change" },
  1337. ],
  1338. },
  1339. isPay: false,
  1340. extendPaymentStatus: false, // 延长缴费
  1341. codeStatus: false,
  1342. qrCodeUrl: null,
  1343. codeTitle: null,
  1344. isEdit: false,
  1345. leftList: [],
  1346. changeVoiceVisible: false,
  1347. rowDetail: null,
  1348. orderVisible: false,
  1349. orderForm: {
  1350. name: "",
  1351. totalAmount: "",
  1352. subject: "",
  1353. subjectFee: "",
  1354. axe: "",
  1355. axePrice: "",
  1356. others: "",
  1357. othersPrice: "",
  1358. },
  1359. maskSoundForm: {
  1360. subject: "",
  1361. },
  1362. subjectVisible: false,
  1363. multipleSelection: [],
  1364. isCanReg: false,
  1365. organId: "",
  1366. };
  1367. },
  1368. components: {
  1369. pagination,
  1370. paymentCycle,
  1371. createUserPay,
  1372. Tooltip,
  1373. "times-view": TimesView,
  1374. paymentList,
  1375. visit,
  1376. qrCode,
  1377. changeVoice,
  1378. mergeMusic,
  1379. },
  1380. created() {},
  1381. filters: {
  1382. studentPays(val) {
  1383. let template = {
  1384. 0: "未缴费",
  1385. 1: "已缴费",
  1386. };
  1387. return template[val];
  1388. },
  1389. },
  1390. // activated() {
  1391. // this.init();
  1392. // },
  1393. async mounted() {
  1394. try {
  1395. const res = await getOrganizationCourseUnitPriceSettings({
  1396. rows: 9999,
  1397. });
  1398. this.organizationCourseUnitPriceSettings = res.data.rows;
  1399. } catch (error) {}
  1400. this.init();
  1401. },
  1402. methods: {
  1403. onPaymentDetail(row) {
  1404. this.paymentDetail = row;
  1405. this.paymentDetailVisible = true;
  1406. },
  1407. viewTimer(row) {
  1408. // this.timerDetail = row
  1409. this.timesVisible = true;
  1410. },
  1411. permission(str) {
  1412. return permission(str);
  1413. },
  1414. async init() {
  1415. this.teamid = this.$route.query.id;
  1416. this.team_status = this.$route.query.team_status;
  1417. // 获取乐团是否能补招
  1418. try {
  1419. const ruselt = await checkCanReg({ musicGroupId: this.teamid });
  1420. this.isCanReg = ruselt.data;
  1421. } catch (e) {
  1422. console.log(e);
  1423. }
  1424. getMusicGroupGradeList({ musicGroupId: this.teamid }).then((res) => {
  1425. let result = res.data;
  1426. if (res.code == 200 && result) {
  1427. for (let i in result) {
  1428. this.gradeList.push({
  1429. value: i,
  1430. label: result[i],
  1431. });
  1432. }
  1433. }
  1434. });
  1435. // 获取报名截止日期和缴费截止日期
  1436. getTeamBaseInfo({ musicGroupId: this.teamid }).then((res) => {
  1437. if (res.code == 200) {
  1438. this.paymentExpireDate = res.data.musicGroup.paymentExpireDate;
  1439. this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  1440. this.organId = res.data.musicGroup.organId;
  1441. }
  1442. });
  1443. // 获取汇总数据
  1444. // this.getTeamStudent();
  1445. this.pickerOptions = this.beginDate();
  1446. this.getList();
  1447. // 获取乐团内所有声部
  1448. findSound({ musicGroupId: this.teamid }).then((res) => {
  1449. if (res.code == 200) {
  1450. this.soundList = res.data;
  1451. }
  1452. });
  1453. getintoClass({ musicGroupId: this.teamid }).then((res) => {
  1454. if (res.code == 200) {
  1455. this.leftList = res.data;
  1456. }
  1457. });
  1458. // 获取乐团基本信息
  1459. getMusicGroup({ musicGroupId: this.teamid }).then(
  1460. (res) => (this.baseInfo = res.data)
  1461. );
  1462. // 获取乐团所有合奏课
  1463. getMusicGroupAllClass({ musicGroupId: this.teamid }).then((res) => {
  1464. if (res.code == 200) {
  1465. this.classList = res.data;
  1466. this.signList = [];
  1467. this.mixList = [];
  1468. this.highList = [];
  1469. this.snapList = [];
  1470. this.classList.forEach((item) => {
  1471. if (item.type == "NORMAL") {
  1472. this.signList.push(item);
  1473. } else if (item.type == "MIX") {
  1474. this.mixList.push(item);
  1475. } else if (item.type == "HIGH") {
  1476. this.highList.push(item);
  1477. } else if (item.type == "SNAP") {
  1478. this.snapList.push(item);
  1479. } else if (item.type == "HIGH_ONLINE") {
  1480. this.highonlineList.push(item);
  1481. } else if (item.type == "MUSIC_NETWORK") {
  1482. this.muiscnetworkList.push(item);
  1483. }
  1484. });
  1485. }
  1486. });
  1487. },
  1488. getTeamStudent() {
  1489. getTeamStudentInfo({ musicGroupId: this.teamid }).then((res) => {
  1490. if (res.code == 200) {
  1491. this.studentListInfo = res.data;
  1492. }
  1493. });
  1494. },
  1495. permission(str) {
  1496. return permission(str);
  1497. },
  1498. onInstrumentChange() {
  1499. // 乐器切换时
  1500. // 乐器切换时
  1501. // let tempkitType = this.maskForm.kitGroupPurchaseType
  1502. // if(tempkitType == 'GROUP') {
  1503. // this.INSTRUMENTLIST.forEach(item => {
  1504. // if(item.value == value) {
  1505. // this.maskForm.musicPrice = item.marketPrice
  1506. // }
  1507. // })
  1508. // }
  1509. },
  1510. onKitGroupChnage(value) {
  1511. // 乐器提供方式
  1512. this.kitStatus = false;
  1513. if (value == "FREE") {
  1514. this.kitStatus = true;
  1515. this.maskForm.musicPrice = 0;
  1516. } else {
  1517. this.maskForm.musicPrice = null;
  1518. }
  1519. },
  1520. onMusicGroupExport() {
  1521. let url = "/api-web/export/musicGroupStudent";
  1522. let data = {
  1523. musicGroupId: this.teamid,
  1524. studentStatus: this.searchForm.studentStatus || null,
  1525. paymentStatus: this.searchForm.isPay || null,
  1526. subjectId: this.searchForm.major || null,
  1527. search: this.searchForm.search || null,
  1528. isActive: this.searchForm.isActive || null,
  1529. classGroupId: this.searchForm.classGroupId || null,
  1530. currentGrade: this.searchForm.currentGrade || null,
  1531. createYear: this.searchForm.createYear || null,
  1532. hasCourse: this.searchForm.hasCourse || null,
  1533. comeOnPackage: this.searchForm.comeOnPackage,
  1534. carePackage: this.searchForm.carePackage,
  1535. };
  1536. const options = {
  1537. method: "get",
  1538. headers: {
  1539. Authorization: getToken(),
  1540. },
  1541. url,
  1542. params: data,
  1543. responseType: "blob",
  1544. };
  1545. this.$confirm("您确定导出学员列表?", "提示", {
  1546. confirmButtonText: "确定",
  1547. cancelButtonText: "取消",
  1548. type: "warning",
  1549. })
  1550. .then(() => {
  1551. axios(options).then((res) => {
  1552. let blob = new Blob([res.data], {
  1553. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
  1554. type: "application/vnd.ms-excel;charset=utf-8",
  1555. // word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  1556. });
  1557. let objectUrl = URL.createObjectURL(blob);
  1558. let link = document.createElement("a");
  1559. let fname = this.$route.query.name + "学员列表.xls";
  1560. link.href = objectUrl;
  1561. link.setAttribute("download", fname);
  1562. document.body.appendChild(link);
  1563. link.click();
  1564. });
  1565. })
  1566. .catch(() => {});
  1567. },
  1568. search() {
  1569. this.rules.page = 1;
  1570. this.getList();
  1571. },
  1572. onReSet() {
  1573. this.$refs.searchForm.resetFields();
  1574. this.search();
  1575. },
  1576. onCreateQRCode() {
  1577. // 生成报名二维码
  1578. this.qrcodeStatus = true;
  1579. let id = this.$route.query.id;
  1580. if (this.qrcodes) {
  1581. this.qrcodes = false;
  1582. setTimeout(() => {
  1583. this.qrcode = new QRCode("qrcode", {
  1584. width: 200,
  1585. height: 200,
  1586. colorDark: "#000000",
  1587. colorLight: "#ffffff",
  1588. correctLevel: QRCode.CorrectLevel.H,
  1589. });
  1590. this.qrcode.makeCode(
  1591. vaildStudentUrl() + "/#/login?musicGroupId=" + id
  1592. );
  1593. this.codeUrl = vaildStudentUrl() + "/#/login?musicGroupId=" + id;
  1594. }, 500);
  1595. }
  1596. },
  1597. getList() {
  1598. let obj = {
  1599. musicGroupId: this.teamid,
  1600. page: this.rules.page,
  1601. rows: this.rules.limit,
  1602. studentStatus: this.searchForm.studentStatus || null,
  1603. paymentStatus: this.searchForm.isPay || null,
  1604. subjectId: this.searchForm.major || null,
  1605. search: this.searchForm.search || null,
  1606. isActive: this.searchForm.isActive || null,
  1607. classGroupId: this.searchForm.classGroupId || null,
  1608. currentGrade: this.searchForm.currentGrade || null,
  1609. createYear: this.searchForm.createYear || null,
  1610. oweFlag: this.searchForm.oweFlag || null,
  1611. hasCourse: this.searchForm.hasCourse || null,
  1612. comeOnPackage: this.searchForm.comeOnPackage,
  1613. carePackage: this.searchForm.carePackage,
  1614. };
  1615. getTeamStudentList(obj).then((res) => {
  1616. if (res.code == 200) {
  1617. this.tableList = res.data.rows;
  1618. this.rules.total = res.data.total;
  1619. this.getStudentStatus();
  1620. }
  1621. });
  1622. this.getTeamStudent();
  1623. },
  1624. addPay(row) {
  1625. this.createUserPayVisible = true;
  1626. this.createdUserId = row.userId;
  1627. },
  1628. addCycle() {
  1629. this.cycles.push({});
  1630. this.collapse.push(this.collapse.length);
  1631. },
  1632. removeCycle(index) {
  1633. this.cycles[index] = null;
  1634. this.cycles = this.cycles.filter((item) => !!item);
  1635. this.collapse.pop();
  1636. },
  1637. collapseChange(val) {
  1638. this.collapse = val;
  1639. },
  1640. gotoSignin() {
  1641. this.$router.push({
  1642. path: "/business/studentSignin",
  1643. query: {
  1644. id: this.teamid,
  1645. status: this.$route.query.status,
  1646. name: this.$route.query.name,
  1647. rules: this.Frules,
  1648. search: this.Fsearch,
  1649. },
  1650. });
  1651. },
  1652. chioseType() {
  1653. this.$refs["quitForm"].validate((res) => {
  1654. if (res) {
  1655. this.$confirm("确定退团?", "提示", {
  1656. confirmButtonText: "确定",
  1657. cancelButtonText: "取消",
  1658. type: "warning",
  1659. })
  1660. .then(() => {
  1661. let row = this.activeRow;
  1662. // 发请求 退团
  1663. StudentQuit({
  1664. musicGroupId: this.teamid,
  1665. userId: row.userId,
  1666. reason: this.quitForm.reason,
  1667. isRefundCourseFee: this.quitForm.isRefundCourseFee,
  1668. isRefundInstrumentFee: this.quitForm.isRefundInstrumentFee,
  1669. isRefundTeachingAssistantsFee: this.quitForm
  1670. .isRefundTeachingAssistantsFee,
  1671. }).then((res) => {
  1672. this.quitForm = {
  1673. // 退团信息确认
  1674. isRefundCourseFee: null,
  1675. isRefundInstrumentFee: null,
  1676. isRefundTeachingAssistantsFee: null,
  1677. reason: "",
  1678. };
  1679. if (res.code == 200) {
  1680. this.$message.success("退团成功");
  1681. this.getList();
  1682. this.quitVisible = false;
  1683. }
  1684. });
  1685. })
  1686. .catch(() => {});
  1687. } else {
  1688. }
  1689. });
  1690. // row.typeVisible = false;
  1691. },
  1692. //
  1693. addStudent() {
  1694. // 发请求添加学员
  1695. this.$refs["maskForm"].validate((res) => {
  1696. if (res) {
  1697. // this.maskForm.parentName.timer 少个生日的字段
  1698. // classGroupId: maskForm.signClass
  1699. /** <!-- signClass: '',
  1700. mixClass: '',
  1701. highClass: '',
  1702. snapClass: [], --> */
  1703. let maskForm = this.maskForm;
  1704. // if (
  1705. // !maskForm.signClass &&
  1706. // !maskForm.mixClass &&
  1707. // !maskForm.highClass &&
  1708. // !maskForm.highonline &&
  1709. // !maskForm.muiscnetwork
  1710. // ) {
  1711. // if (
  1712. // !maskForm.snapClass ||
  1713. // !(maskForm.snapClass && maskForm.snapClass.length >= 1)
  1714. // ) {
  1715. // this.$message.error("该学生必须加入一个班级");
  1716. // return;
  1717. // }
  1718. // }
  1719. if (
  1720. maskForm.musicGoodsIdList &&
  1721. (maskForm.musicPrice === "" || maskForm.musicPrice === null)
  1722. ) {
  1723. this.$message.error("请输入乐器金额");
  1724. return;
  1725. }
  1726. if (
  1727. maskForm.instrGoodsIdList &&
  1728. maskForm.instrGoodsIdList.length > 0 &&
  1729. (maskForm.instrPrice === "" || maskForm.instrPrice === null)
  1730. ) {
  1731. this.$message.error("请输入辅件金额");
  1732. return;
  1733. }
  1734. let snapClassIds;
  1735. maskForm.snapClass
  1736. ? (snapClassIds = maskForm.snapClass.join(","))
  1737. : (snapClassIds = null);
  1738. let params = {
  1739. signClassId: maskForm.signClass,
  1740. mixClassId: maskForm.mixClass,
  1741. snapClassIds,
  1742. highClassId: maskForm.highClass,
  1743. courseFee: maskForm.courseFee,
  1744. temporaryCourseFee: maskForm.temporaryCourseFee,
  1745. studentRegistration: {
  1746. name: maskForm.studentName,
  1747. gender: maskForm.sex,
  1748. birthdate: maskForm.timer,
  1749. parentsName: maskForm.parentName,
  1750. parentsPhone: maskForm.phone,
  1751. currentGrade: maskForm.startClass,
  1752. currentGradeNum: maskForm.currentGradeNum,
  1753. currentClass: maskForm.course,
  1754. subjectId: maskForm.sound,
  1755. musicGroupId: this.teamid,
  1756. },
  1757. };
  1758. params.studentPaymentOrderDetails = [];
  1759. if (maskForm.musicGoodsIdList) {
  1760. params.studentPaymentOrderDetails.push({
  1761. goodsIdList: maskForm.musicGoodsIdList,
  1762. kitGroupPurchaseType: maskForm.kitGroupPurchaseType,
  1763. type: "MUSICAL",
  1764. price: maskForm.musicPrice,
  1765. });
  1766. }
  1767. if (maskForm.instrGoodsIdList && maskForm.instrGoodsIdList != "") {
  1768. params.studentPaymentOrderDetails.push({
  1769. goodsIdList: maskForm.instrGoodsIdList.join(","),
  1770. type: "ACCESSORIES",
  1771. price: maskForm.instrPrice,
  1772. });
  1773. }
  1774. addStudent(params).then((res) => {
  1775. if (res.code == 200) {
  1776. this.$message.success("添加学生成功");
  1777. this.getList();
  1778. this.addStudentVisible = false;
  1779. this.createUserPayVisible = true;
  1780. this.createdUserId = res.data;
  1781. }
  1782. this.$refs.maskForm.resetFields();
  1783. });
  1784. }
  1785. });
  1786. },
  1787. onSoundChange(value) {
  1788. // 学员声部切换时
  1789. // this.findSubjectPlan(value)
  1790. this.ACCESSORIESLIST = [];
  1791. this.maskForm.instrGoodsIdList = [];
  1792. this.maskForm.instrPrice = null;
  1793. this.INSTRUMENTLIST = [];
  1794. this.maskForm.musicPrice = null;
  1795. this.maskForm.musicGoodsIdList = null;
  1796. this.getGoodsList(value, "INSTRUMENT"); // 乐器
  1797. this.getGoodsList(value, "ACCESSORIES"); // 辅件
  1798. },
  1799. // 获取购买方式
  1800. findSubjectPlan(subjectId) {
  1801. findSubjectPlan({
  1802. musicGroupId: this.teamid,
  1803. subjectId: subjectId,
  1804. }).then((res) => {
  1805. let result = res.data;
  1806. if (res.code == 200) {
  1807. this.maskForm.musicMode = this.getBranchType(
  1808. result.kitGroupPurchaseType
  1809. );
  1810. }
  1811. });
  1812. },
  1813. getGoodsList(subjectId, type) {
  1814. getGoods({
  1815. subjectId: subjectId,
  1816. type: type,
  1817. }).then((res) => {
  1818. let result = res.data;
  1819. if (res.code == 200) {
  1820. let tempArr = [];
  1821. result.forEach((item) => {
  1822. tempArr.push({
  1823. label: item.name,
  1824. value: item.id,
  1825. marketPrice: item.marketPrice,
  1826. });
  1827. });
  1828. if (type == "ACCESSORIES") {
  1829. this.ACCESSORIESLIST = tempArr;
  1830. }
  1831. if (type == "INSTRUMENT") {
  1832. this.INSTRUMENTLIST = tempArr;
  1833. }
  1834. }
  1835. });
  1836. },
  1837. getBranchType(status) {
  1838. let common = {
  1839. FREE: "免费",
  1840. GROUP: "团购",
  1841. LEASE: "租赁",
  1842. };
  1843. return common[status];
  1844. },
  1845. lookClass(row) {
  1846. this.classMask.studentName = row.realName;
  1847. getStudentClass({
  1848. musicGroupId: this.teamid,
  1849. teacherId: row.userId,
  1850. }).then((res) => {
  1851. if (res.code == 200) {
  1852. this.classLists = res.data;
  1853. this.studentClassVisible = true;
  1854. }
  1855. });
  1856. },
  1857. quieTeamMask(row) {
  1858. this.activeRow = row;
  1859. this.quitVisible = true;
  1860. },
  1861. quieTeam(row) {
  1862. this.$prompt("请输入退团原因", "提示", {
  1863. confirmButtonText: "确定",
  1864. cancelButtonText: "取消",
  1865. type: "warning",
  1866. inputPattern: /\S/,
  1867. inputErrorMessage: "请输入退团原因",
  1868. })
  1869. .then((val) => {
  1870. // 发请求 退团
  1871. StudentQuit({
  1872. musicGroupId: this.teamid,
  1873. userId: row.userId,
  1874. reason: val.value,
  1875. isRefundCourseFee: false,
  1876. isRefundInstrumentFee: false,
  1877. isRefundTeachingAssistantsFee: false,
  1878. }).then((res) => {
  1879. this.quitForm = {
  1880. // 退团信息确认
  1881. isRefundCourseFee: null,
  1882. isRefundInstrumentFee: null,
  1883. isRefundTeachingAssistantsFee: null,
  1884. reason: "",
  1885. };
  1886. if (res.code == 200) {
  1887. this.$message.success("退团成功");
  1888. this.getList();
  1889. this.quitVisible = false;
  1890. }
  1891. });
  1892. })
  1893. .catch(() => {});
  1894. },
  1895. checkPhone(val) {
  1896. var regu = /^1[3456789]\d{9}$/;
  1897. var re = new RegExp(regu);
  1898. if (re.test(val)) {
  1899. getStudentInfoByPhone({ mobile: this.maskForm.phone }).then((res) => {
  1900. if (res.code == 200) {
  1901. if (res.data) {
  1902. this.maskForm.studentName = res.data.name;
  1903. this.maskForm.sex = res.data.gender;
  1904. this.maskForm.parentName = res.data.parentsName;
  1905. this.maskForm.course = res.data.currentClass;
  1906. this.maskForm.startClass = res.data.currentGrade;
  1907. this.maskForm.currentGradeNum = res.data.currentGradeNum
  1908. ? res.data.currentGradeNum + ""
  1909. : null;
  1910. this.maskForm.phone = val;
  1911. this.maskForm.timer = res.data.birthdate;
  1912. }
  1913. }
  1914. });
  1915. }
  1916. },
  1917. lockStudent(row) {
  1918. this.$confirm("是否锁定/解锁学生缴费周期?", "提示", {
  1919. confirmButtonText: "确定",
  1920. cancelButtonText: "取消",
  1921. type: "warning",
  1922. })
  1923. .then(() => {
  1924. let musicGroupId = this.teamid;
  1925. let studentId = row.userId;
  1926. let isLock;
  1927. row.isLock == 0 ? (isLock = 1) : (isLock = 0);
  1928. StudentFeeIsLock({ musicGroupId, studentId, isLock }).then((res) => {
  1929. if (res.code == 200) {
  1930. this.$message.success("修改成功");
  1931. this.getList();
  1932. }
  1933. });
  1934. })
  1935. .catch(() => {});
  1936. },
  1937. resetPay(row) {
  1938. this.activeRow = row;
  1939. this.payVisible = true;
  1940. this.payForm.studentName = row.realName;
  1941. this.payForm.payMoney = row.courseFee;
  1942. this.payForm.payMonth = row.paymentPeriodList.split(",");
  1943. if (this.payForm.payMonth[0] == "") {
  1944. this.payForm.payMonth = [];
  1945. }
  1946. },
  1947. submitPay() {
  1948. let studentId = this.activeRow.userId;
  1949. let musicGroupId = this.teamid;
  1950. let month = this.payForm.payMonth.join(",") || null;
  1951. let amount = this.payForm.payMoney;
  1952. let obj = {
  1953. studentId,
  1954. musicGroupId,
  1955. month,
  1956. amount,
  1957. };
  1958. updateStudentFee(obj).then((res) => {
  1959. if (res.code == 200) {
  1960. this.$message.success("修改成功");
  1961. this.payVisible = false;
  1962. this.getList();
  1963. }
  1964. });
  1965. },
  1966. closePayVisible() {
  1967. this.$refs["payForm"].resetFields();
  1968. this.payVisible = false;
  1969. },
  1970. addVisit(row) {
  1971. console.log(row);
  1972. this.detail = row;
  1973. // this.visitForm.studentName = row.realName;
  1974. // this.visitForm.musicGroupId = this.teamid;
  1975. // this.visitForm.studentId = row.userId;
  1976. this.visitVisiable = true;
  1977. },
  1978. handleChange(val) {
  1979. this.visitForm.type = val[0];
  1980. this.visitForm.purpose = val[1];
  1981. },
  1982. submitAddVisit() {
  1983. console.log(this.$refs.visitForm);
  1984. this.$refs.visitForm.validate((res) => {
  1985. if (res) {
  1986. addVisit(cleanDeep(this.visitForm)).then((res) => {
  1987. if (res.code === 200) {
  1988. this.$message.success("新增成功");
  1989. this.visitVisiable = false;
  1990. }
  1991. });
  1992. }
  1993. });
  1994. },
  1995. beginDate() {
  1996. let self = this;
  1997. return {
  1998. firstDayOfWeek: 1,
  1999. disabledDate(time) {
  2000. return time.getTime() >= new Date().getTime(); //开始时间不选时,结束时间最大值小于等于当天
  2001. },
  2002. };
  2003. },
  2004. createStudentFrom() {
  2005. this.addStudentVisible = true;
  2006. },
  2007. // 报名缴费功能
  2008. onGoHome() {
  2009. if (this.paymentNum <= 0) {
  2010. this.$message.error("当前缴费人数为0,无法开团");
  2011. return;
  2012. }
  2013. this.$confirm(`是否确认开团?`, "提示", {
  2014. confirmButtonText: "确定",
  2015. cancelButtonText: "取消",
  2016. type: "warning",
  2017. })
  2018. .then(() => {
  2019. musicGroupFound({
  2020. musicGroupId: this.$route.query.id,
  2021. }).then((res) => {
  2022. if (res.code == 200) {
  2023. // let query = this.$route.query;
  2024. // this.$message.success("开启成功");
  2025. // this.$router.push({
  2026. // path: "/teamList",
  2027. // query: {
  2028. // ...query,
  2029. // },
  2030. // });
  2031. this.$store.dispatch("delVisitedViews", this.$route);
  2032. this.$router.push({ path: "/teamList" });
  2033. }
  2034. });
  2035. })
  2036. .catch(() => {});
  2037. },
  2038. payStart() {
  2039. this.paymentStatus = true;
  2040. },
  2041. getStudentStatus() {
  2042. let obj = {
  2043. musicGroupId: this.teamid,
  2044. page: 1,
  2045. rows: 9999,
  2046. };
  2047. getStudentList(obj).then((res) => {
  2048. if (res.code == 200) {
  2049. res.data.rows.forEach((item) => {
  2050. // '未开启缴费', '开启缴费', '已缴费'
  2051. if (item.paymentStatus == 2) {
  2052. this.paymentNum += 1;
  2053. }
  2054. });
  2055. // this.rightList = res.data.rows;
  2056. // this.rules.total = res.data.total;
  2057. // return res;
  2058. }
  2059. });
  2060. },
  2061. payDate() {
  2062. let self = this;
  2063. return {
  2064. firstDayOfWeek: 1,
  2065. disabledDate(time) {
  2066. if (self.applyExpireDate) {
  2067. return (
  2068. time.getTime() <=
  2069. new Date(self.applyExpireDate.replace(/-/g, "/")).getTime()
  2070. );
  2071. } else {
  2072. return false;
  2073. }
  2074. },
  2075. };
  2076. },
  2077. onStartPayment(formName) {
  2078. // 开启缴费
  2079. this.$refs[formName].validate((valid) => {
  2080. if (valid) {
  2081. musicGroupOpenPay({
  2082. musicGroupId: this.teamid,
  2083. expireDate: this.paymentForm.paymentExpireDate,
  2084. // feeType: this.paymentForm.feeType
  2085. }).then((res) => {
  2086. if (res.code == 200) {
  2087. this.$message.success("开启成功");
  2088. this.paymentStatus = false;
  2089. this.$store.dispatch("delVisitedViews", this.$route);
  2090. this.$router.push({ path: "/teamList" });
  2091. // this.$router.push({
  2092. // path: "/business/resetTeaming",
  2093. // query: {
  2094. // status: "PAY",
  2095. // id: this.$route.query.id,
  2096. // name: this.$route.query.name,
  2097. // },
  2098. // });
  2099. // this.team_status = "PAY";
  2100. // this.paymentExpireDate = this.paymentForm.paymentExpireDate;
  2101. // this.getList();
  2102. }
  2103. });
  2104. } else {
  2105. return false;
  2106. }
  2107. });
  2108. },
  2109. applyDate() {
  2110. let self = this;
  2111. return {
  2112. firstDayOfWeek: 1,
  2113. disabledDate(time) {
  2114. if (self.paymentExpireDate) {
  2115. return (
  2116. time.getTime() >
  2117. new Date(self.paymentExpireDate.replace(/-/g, "/")).getTime()
  2118. );
  2119. } else {
  2120. return false;
  2121. }
  2122. },
  2123. };
  2124. },
  2125. extendTime(isPay) {
  2126. this.isPay = isPay;
  2127. if (isPay) {
  2128. // 点击的延长缴费
  2129. this.extendForm.expireDate = this.paymentExpireDate;
  2130. } else {
  2131. // 点击的延长报名
  2132. this.extendForm.expireDate = this.applyExpireDate;
  2133. }
  2134. this.extendPaymentStatus = true;
  2135. },
  2136. onExtendPayment(formName, isPay) {
  2137. this.$refs[formName].validate((valid) => {
  2138. if (valid) {
  2139. if (!isPay) {
  2140. extensionApplyExpire({
  2141. musicGroupId: this.teamid,
  2142. expireDate: this.extendForm.expireDate,
  2143. }).then((res) => {
  2144. if (res.code == 200) {
  2145. this.$message.success("延长报名成功");
  2146. this.extendPaymentStatus = false;
  2147. getTeamBaseInfo({ musicGroupId: this.teamid }).then((res) => {
  2148. if (res.code == 200) {
  2149. this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  2150. this.setBase(res);
  2151. }
  2152. });
  2153. } else {
  2154. this.$message.error(res.msg);
  2155. }
  2156. });
  2157. } else {
  2158. extensionPayment({
  2159. musicGroupId: this.teamid,
  2160. expireDate: this.extendForm.expireDate,
  2161. }).then((res) => {
  2162. if (res.code == 200) {
  2163. this.$message.success("延长缴费成功");
  2164. this.extendPaymentStatus = false;
  2165. getTeamBaseInfo({ musicGroupId: this.teamid }).then((res) => {
  2166. if (res.code == 200) {
  2167. this.paymentExpireDate =
  2168. res.data.musicGroup.paymentExpireDate;
  2169. }
  2170. });
  2171. } else {
  2172. this.$message.error(res.msg);
  2173. }
  2174. });
  2175. }
  2176. }
  2177. });
  2178. },
  2179. onCreateQRCode(type) {
  2180. // 生成报名二维码
  2181. let id = this.teamid;
  2182. this.codeStatus = true;
  2183. if (type == "payment") {
  2184. this.codeTitle = "学员报名连接";
  2185. this.qrCodeUrl = vaildStudentUrl() + "/#/login?musicGroupId=" + id;
  2186. } else if (type == "detail") {
  2187. let teamName = this.$route.query.name;
  2188. this.codeTitle = "报名缴费详情";
  2189. this.qrCodeUrl =
  2190. vaildTeacherUrl() +
  2191. "/#/order?musicGroupId=" +
  2192. id +
  2193. "&musicGroupName=" +
  2194. teamName;
  2195. } else if (type == "rePayment") {
  2196. this.codeTitle = "学生报名链接(无乐器)";
  2197. this.qrCodeUrl =
  2198. vaildStudentUrl() + "/#/login?musicGroupId=" + id + "&instrument=1";
  2199. }
  2200. },
  2201. saveIsEdit() {
  2202. // 提交数据
  2203. this.isEdit = false;
  2204. resetPlanNum(this.leftList).then((res) => {});
  2205. },
  2206. openChangeVoice(row) {
  2207. console.log(row);
  2208. // this.getList().then((res) => {
  2209. // for (const item of res.data.rows) {
  2210. // if (item.id === row.id) {
  2211. // this.rowDetail = { ...item, studentId: row.userId };
  2212. // this.changeVoiceVisible = true;
  2213. // console.log( this.rowDetail)
  2214. // }
  2215. // }
  2216. // });
  2217. this.rowDetail = { ...row, studentId: row.userId };
  2218. this.changeVoiceVisible = true;
  2219. },
  2220. closeChangeVoice() {
  2221. this.changeVoiceVisible = false;
  2222. // this.rowDetail = null
  2223. },
  2224. lookdetail(row) {
  2225. this.orderVisible = true;
  2226. this.activeId = row.userId;
  2227. this.orderForm.name = row.realName;
  2228. this.orderForm.subject = row.subjectName;
  2229. getStudentFeeDetail({
  2230. musicGroupId: this.teamid,
  2231. studentId: row.userId,
  2232. }).then((res) => {
  2233. if (res.code == 200) {
  2234. if (res.data) {
  2235. this.orderForm.totalAmount = res.data.totalAmount;
  2236. // this.orderForm.subjectFee = res.data.courseFee;
  2237. let goodStr = "";
  2238. let goodPrice = 0;
  2239. let otherStr = "";
  2240. let othersPrice = 0;
  2241. for (let i in res.data.goods) {
  2242. if (res.data.goods[i].goodsType == "INSTRUMENT") {
  2243. goodStr += res.data.goods[i].goodsName + ",";
  2244. goodPrice += parseFloat(res.data.goods[i].musicalFee);
  2245. // this.orderForm.axe = res.data.goods[i].goodsName;
  2246. // this.orderForm.axePrice = res.data.goods[i].musicalFee;
  2247. } else if (res.data.goods[i].goodsType == "ACCESSORIES") {
  2248. otherStr += res.data.goods[i].goodsName + ",";
  2249. othersPrice += parseFloat(res.data.goods[i].musicalFee);
  2250. // this.orderForm.others = res.data.goods[i].goodsName;
  2251. // this.orderForm.othersPrice = res.data.goods[i].musicalFee;
  2252. } else if (res.data.goods[i].goodsType == "COURSE") {
  2253. this.orderForm.subjectFee = res.data.goods[i].musicalFee;
  2254. }
  2255. }
  2256. this.orderForm.others = otherStr.substring(0, otherStr.length - 1);
  2257. this.orderForm.othersPrice = othersPrice;
  2258. this.orderForm.axe = goodStr.substring(0, goodStr.length - 1);
  2259. this.orderForm.axePrice = goodPrice;
  2260. }
  2261. }
  2262. });
  2263. },
  2264. // 修改专业
  2265. resetSubject(row) {
  2266. this.activeId = row.userId;
  2267. this.subjectVisible = true;
  2268. // resetStudentSubject().then(res=>{]})
  2269. },
  2270. okReset() {
  2271. if (!this.maskSoundForm.subject) {
  2272. this.$message.error("请选择调剂专业");
  2273. return;
  2274. }
  2275. resetStudentSubject({
  2276. musicGroupId: this.teamid,
  2277. userId: this.activeId,
  2278. subId: this.maskSoundForm.subject,
  2279. }).then((res) => {
  2280. if (res.code == 200) {
  2281. this.$message.success("修改成功");
  2282. this.subjectVisible = false;
  2283. this.maskForm.subject = "";
  2284. getintoClass({ musicGroupId: this.id }).then((res) => {
  2285. if (res.code == 200) {
  2286. this.leftList = res.data;
  2287. }
  2288. });
  2289. this.getList();
  2290. }
  2291. });
  2292. },
  2293. onPartPayment() {
  2294. // 部分缴费
  2295. let selection = this.multipleSelection;
  2296. if (selection.length <= 0) {
  2297. this.$message.error("您还没有选择学生");
  2298. return false;
  2299. }
  2300. let ids = [];
  2301. selection.forEach((item) => {
  2302. ids.push(item.studentRegistrationId);
  2303. });
  2304. this.$confirm(`是否确认开启缴费?`, "提示", {
  2305. confirmButtonText: "确定",
  2306. cancelButtonText: "取消",
  2307. type: "warning",
  2308. })
  2309. .then(() => {
  2310. openPayment({
  2311. ids: ids.join(","),
  2312. }).then((res) => {
  2313. if (res.code == 200) {
  2314. this.$message.success("开启成功");
  2315. this.getList();
  2316. } else {
  2317. this.$message.error(res.msg);
  2318. }
  2319. });
  2320. })
  2321. .catch(() => {});
  2322. },
  2323. handleSelectionChange(val) {
  2324. this.multipleSelection = val;
  2325. },
  2326. checkboxSelect(row) {
  2327. return row.paymentStatus == 0;
  2328. },
  2329. isShowResSound() {
  2330. /**
  2331. * team_status == 'PAY' ||
  2332. team_status == 'APPLY' ||
  2333. team_status == 'PROGRESS'&&isCanReg ||
  2334. team_status == 'PREPARE')
  2335. */
  2336. if (this.team_status == "PAY" || this.team_status == "APPLY") {
  2337. return true;
  2338. } else if (
  2339. this.team_status == "PROGRESS" ||
  2340. this.team_status == "PREPARE"
  2341. ) {
  2342. return this.isCanReg;
  2343. } else {
  2344. return false;
  2345. }
  2346. },
  2347. },
  2348. watch: {
  2349. quitVisible(val) {
  2350. if (!val) {
  2351. this.quitForm = {
  2352. // 退团信息确认
  2353. isRefundCourseFee: null,
  2354. isRefundInstrumentFee: null,
  2355. isRefundTeachingAssistantsFee: null,
  2356. reason: "",
  2357. };
  2358. this.$refs["quitForm"].resetFields();
  2359. }
  2360. },
  2361. // visitVisiable(val) {
  2362. // if (!val) {
  2363. // this.$refs["visitForm"].resetFields();
  2364. // }
  2365. // },
  2366. },
  2367. computed: {
  2368. saveKey() {
  2369. // return 'teamDetails-'+this.$route.query.id
  2370. return "teamDetails-studentList|id|" + this.$route.query.id;
  2371. },
  2372. },
  2373. };
  2374. </script>
  2375. <style lang="scss" scoped>
  2376. .dialog-footer.question {
  2377. display: flex;
  2378. flex-direction: row;
  2379. justify-content: space-between;
  2380. }
  2381. // .moreInput {
  2382. // width: 100%;
  2383. // display: flex;
  2384. // /deep/.el-form-item__content {
  2385. // display: flex;
  2386. // flex-direction: row;
  2387. // }
  2388. // }
  2389. .error {
  2390. color: red;
  2391. }
  2392. .el-select {
  2393. width: 180px !important;
  2394. }
  2395. .headWrap {
  2396. padding: 20px 0;
  2397. }
  2398. /deep/.el-date-editor.el-input {
  2399. width: auto;
  2400. .el-input__inner {
  2401. padding-right: 0;
  2402. }
  2403. }
  2404. .studentInfo {
  2405. /deep/.el-dialog__body {
  2406. // padding-top: 0;
  2407. // padding-bottom: 0;
  2408. }
  2409. }
  2410. // .instrList {
  2411. // display: flex;
  2412. // /deep/.el-form-item__content {
  2413. // width: 80%;
  2414. // }
  2415. // .el-col {
  2416. // /deep/.el-form-item__content {
  2417. // width: 100%;
  2418. // }
  2419. // }
  2420. // }
  2421. .stu-container {
  2422. .topFrom {
  2423. margin: 20px 30px 0;
  2424. width: 1000px;
  2425. }
  2426. .newStudent {
  2427. width: 121px;
  2428. height: 40px;
  2429. background: rgba(20, 146, 138, 1);
  2430. border-radius: 4px;
  2431. color: #fff;
  2432. text-align: center;
  2433. line-height: 40px;
  2434. font-size: 14px;
  2435. cursor: pointer;
  2436. }
  2437. }
  2438. .left-code,
  2439. .right-code {
  2440. // width: 50%;
  2441. // float: left;
  2442. h2 {
  2443. display: block;
  2444. font-size: 18px;
  2445. text-align: center;
  2446. padding-bottom: 8px;
  2447. line-height: 1;
  2448. height: 30px;
  2449. margin-bottom: 0;
  2450. }
  2451. .qrcode {
  2452. display: flex;
  2453. justify-content: center;
  2454. img {
  2455. width: 200px;
  2456. height: 200px;
  2457. // margin: 0 auto;
  2458. }
  2459. }
  2460. .code-url {
  2461. font-size: 18px;
  2462. text-align: center;
  2463. padding: 15px 15px 0 15px;
  2464. }
  2465. }
  2466. .export {
  2467. background: #14928a;
  2468. }
  2469. .alert {
  2470. margin-bottom: 10px;
  2471. }
  2472. .collapse-title {
  2473. display: flex;
  2474. justify-content: space-between;
  2475. align-items: center;
  2476. width: 100%;
  2477. .el-icon-circle-close {
  2478. font-size: 16px;
  2479. margin-right: 10px;
  2480. }
  2481. }
  2482. /deep/ .el-collapse-item__wrap {
  2483. padding-top: 20px;
  2484. }
  2485. .cycleForm {
  2486. /deep/ .el-form-item {
  2487. display: flex;
  2488. width: 100%;
  2489. /deep/ .el-form-item__content {
  2490. margin-left: 0 !important;
  2491. flex: 1;
  2492. }
  2493. }
  2494. }
  2495. .statistic {
  2496. padding: 20px 0;
  2497. text-align: center;
  2498. width: 100%;
  2499. margin: auto !important;
  2500. }
  2501. .popoverWrap {
  2502. p {
  2503. line-height: 25px;
  2504. }
  2505. }
  2506. .studentListWrap {
  2507. display: flex;
  2508. flex-direction: row;
  2509. justify-content: flex-start;
  2510. align-items: center;
  2511. div {
  2512. margin-right: 15px;
  2513. }
  2514. }
  2515. .btnList {
  2516. display: flex;
  2517. flex-direction: row;
  2518. justify-content: flex-start;
  2519. align-items: center;
  2520. flex-wrap: wrap;
  2521. & > div {
  2522. margin-right: 15px;
  2523. margin-bottom: 10px;
  2524. }
  2525. }
  2526. </style>