studentList.vue 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922
  1. <template>
  2. <div class="stu-container">
  3. <div class="studentListWrap" v-if="team_status == 'PROGRESS'">
  4. <div
  5. class="newBand"
  6. v-permission="'studentRegistration/insertStudent'"
  7. @click="createStudentFrom"
  8. >
  9. 新增学员
  10. </div>
  11. <div
  12. class="newBand"
  13. v-permission="'studentRegistration/insertStudent'"
  14. @click="addTryTime"
  15. >
  16. 增加会员试用期
  17. </div>
  18. </div>
  19. <!-- 搜索类型 -->
  20. <save-form
  21. ref="searchForm"
  22. :inline="true"
  23. :save-key="saveKey"
  24. class="searchForm"
  25. @submit="search"
  26. @reset="onReSet"
  27. :model="searchForm"
  28. >
  29. <el-form-item prop="search">
  30. <el-input
  31. v-model.trim="searchForm.search"
  32. clearable
  33. placeholder="学生姓名或电话"
  34. @keyup.enter.native="search"
  35. ></el-input>
  36. </el-form-item>
  37. <el-form-item prop="studentStatus">
  38. <el-select
  39. v-model.trim="searchForm.studentStatus"
  40. clearable
  41. filterable
  42. placeholder="学员状态"
  43. >
  44. <el-option label="在读" value="NORMAL"></el-option>
  45. <el-option label="请假" value="LEAVE"></el-option>
  46. <el-option label="退团" value="QUIT"></el-option>
  47. <el-option label="报名" value="APPLY"></el-option>
  48. </el-select>
  49. </el-form-item>
  50. <el-form-item prop="createYear">
  51. <el-date-picker
  52. v-model="searchForm.createYear"
  53. type="year"
  54. value-format="yyyy"
  55. placeholder="选择入团年份"
  56. >
  57. </el-date-picker>
  58. </el-form-item>
  59. <el-form-item prop="currentGrade">
  60. <!-- <el-input
  61. v-model.trim="searchForm.currentGrade"
  62. clearable
  63. placeholder="学员年级"
  64. ></el-input> -->
  65. <el-select
  66. v-model.trim="searchForm.currentGrade"
  67. filterable
  68. clearable
  69. placeholder="请选择年级"
  70. >
  71. <el-option
  72. v-for="(item, index) in gradeList"
  73. :key="index"
  74. :label="item.label"
  75. :value="item.label"
  76. ></el-option>
  77. </el-select>
  78. </el-form-item>
  79. <el-form-item prop="classGroupId">
  80. <el-select
  81. v-model.trim="searchForm.classGroupId"
  82. clearable
  83. filterable
  84. placeholder="请选择班级"
  85. >
  86. <el-option
  87. v-for="(item, index) in classList"
  88. :key="index"
  89. :value="item.id"
  90. :label="item.name"
  91. ></el-option>
  92. </el-select>
  93. </el-form-item>
  94. <el-form-item prop="major">
  95. <el-select
  96. v-model.trim="searchForm.major"
  97. clearable
  98. filterable
  99. placeholder="所选专业"
  100. >
  101. <el-option
  102. v-for="(item, index) in soundList"
  103. :key="index"
  104. :value="item.id"
  105. :label="item.name"
  106. ></el-option>
  107. </el-select>
  108. </el-form-item>
  109. <el-form-item prop="isPay">
  110. <el-select
  111. v-model.trim="searchForm.isPay"
  112. clearable
  113. filterable
  114. placeholder="报名缴费"
  115. >
  116. <el-option label="未开启缴费" value="0"></el-option>
  117. <el-option label="开启缴费" value="1"></el-option>
  118. <el-option label="已缴费" value="2"></el-option>
  119. </el-select>
  120. </el-form-item>
  121. <el-form-item prop="oweFlag">
  122. <el-select
  123. v-model.trim="searchForm.oweFlag"
  124. clearable
  125. filterable
  126. placeholder="是否欠费"
  127. >
  128. <el-option label="否" value="0"></el-option>
  129. <el-option label="是" value="1"></el-option>
  130. </el-select>
  131. </el-form-item>
  132. <el-form-item prop="isActive">
  133. <el-select
  134. v-model.trim="searchForm.isActive"
  135. clearable
  136. filterable
  137. placeholder="是否激活"
  138. >
  139. <el-option label="是" value="1"></el-option>
  140. <el-option label="否" value="0"></el-option>
  141. </el-select>
  142. </el-form-item>
  143. <el-form-item prop="hasCourse">
  144. <el-select
  145. v-model.trim="searchForm.hasCourse"
  146. clearable
  147. placeholder="VIP/网管是否有课"
  148. >
  149. <el-option label="是" value="true"></el-option>
  150. <el-option label="否" value="false"></el-option>
  151. </el-select>
  152. </el-form-item>
  153. <el-form-item prop="carePackage">
  154. <el-select
  155. class="multiple"
  156. v-model.trim="searchForm.carePackage"
  157. clearable
  158. placeholder="关心包"
  159. >
  160. <el-option label="不可用" :value="0"></el-option>
  161. <el-option label="可用" :value="1"></el-option>
  162. <el-option label="已使用" :value="2"></el-option>
  163. </el-select>
  164. </el-form-item>
  165. <el-form-item prop="comeOnPackage">
  166. <el-select
  167. class="multiple"
  168. v-model.trim="searchForm.comeOnPackage"
  169. clearable
  170. placeholder="加油包"
  171. >
  172. <el-option label="不可用" :value="0"></el-option>
  173. <el-option label="可用" :value="1"></el-option>
  174. <el-option label="已使用" :value="2"></el-option>
  175. </el-select>
  176. </el-form-item>
  177. <el-form-item>
  178. <el-button native-type="submit" type="danger">搜索</el-button>
  179. <el-button type="primary" native-type="reset">重置</el-button>
  180. <el-button
  181. type="primary"
  182. v-permission="'export/musicGroupStudent'"
  183. @click="onMusicGroupExport"
  184. >导出</el-button
  185. >
  186. </el-form-item>
  187. </save-form>
  188. <div style="font-size: 14px; color: #f85043; padding-bottom: 10px">
  189. 在读人数:{{ studentListInfo.studying
  190. }}<i style="width: 10px; display: inline-block"></i> 退团人数:{{
  191. studentListInfo.quit
  192. }}<i style="width: 10px; display: inline-block"></i> VIP&网管转化率:{{
  193. studentListInfo.courseRate
  194. }}<i style="width: 10px; display: inline-block"></i>
  195. </div>
  196. <!-- 列表 -->
  197. <div class="tableWrap">
  198. <el-table
  199. :data="tableList"
  200. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  201. @selection-change="handleSelectionChange"
  202. >
  203. <el-table-column
  204. type="selection"
  205. width="55"
  206. :selectable="checkboxSelect"
  207. ></el-table-column>
  208. <el-table-column label="学员编号" width="120px;" prop="userId">
  209. <template slot-scope="scope">
  210. <div
  211. @click="gotoStudent(scope.row.userId)"
  212. style="color: #14928a; cursor: pointer"
  213. >
  214. <copy-text>
  215. {{ scope.row.userId }}
  216. </copy-text>
  217. </div>
  218. </template>
  219. </el-table-column>
  220. <el-table-column label="学员姓名" width="120px;" prop="realName">
  221. <template slot-scope="scope">
  222. <div
  223. @click="gotoStudent(scope.row.realName)"
  224. style="color: #14928a; cursor: pointer"
  225. >
  226. <copy-text>
  227. {{ scope.row.realName }}
  228. </copy-text>
  229. </div>
  230. </template>
  231. </el-table-column>
  232. <el-table-column
  233. align="center"
  234. prop="gender"
  235. width="50px;"
  236. label="性别"
  237. >
  238. <template slot-scope="scope">
  239. <div>{{ scope.row.gender | sex }}</div>
  240. </template>
  241. </el-table-column>
  242. <el-table-column align="center" prop="phone" label="联系电话">
  243. <template slot-scope="scope">
  244. <copy-text>
  245. {{ scope.row.phone }}
  246. </copy-text>
  247. </template>
  248. </el-table-column>
  249. <el-table-column align="center" label="入团年份">
  250. <template slot-scope="scope">
  251. <div>{{ scope.row.registerTime | dayjsFormat("YYYY年") }}</div>
  252. </template>
  253. </el-table-column>
  254. <el-table-column align="center" label="年级班级">
  255. <template slot-scope="scope">
  256. <div>{{ scope.row.currentGrade + scope.row.currentClass }}</div>
  257. </template>
  258. </el-table-column>
  259. <el-table-column align="center" label="报名专业" prop="subjectName">
  260. <template slot-scope="scope">
  261. <copy-text>
  262. {{ scope.row.regSubjectName }}
  263. </copy-text>
  264. </template>
  265. </el-table-column>
  266. <el-table-column align="center" label="入团专业" prop="subjectName">
  267. <template slot-scope="scope">
  268. <copy-text>
  269. {{ scope.row.subjectName }}
  270. </copy-text>
  271. </template>
  272. </el-table-column>
  273. <el-table-column align="center" prop="studentStatus" label="学员状态">
  274. <template slot-scope="scope">
  275. <div>{{ scope.row.studentStatus | musicGroupStudentType }}</div>
  276. </template>
  277. </el-table-column>
  278. <!-- <el-table-column align="center" label="新增学员">
  279. <template slot-scope="scope">
  280. <div>{{ scope.row.isNewStudent | yesOrNo }}</div>
  281. </template>
  282. </el-table-column> -->
  283. <el-table-column align="center" label="报名缴费">
  284. <template slot-scope="scope">
  285. <div>{{ scope.row.paymentStatus | paymentStatus }}</div>
  286. </template>
  287. </el-table-column>
  288. <el-table-column align="center" label="是否激活">
  289. <template slot-scope="scope">
  290. <div>{{ scope.row.isActive ? "是" : "否" }}</div>
  291. </template>
  292. </el-table-column>
  293. <el-table-column align="center" label="VIP/网管是否有课">
  294. <template slot-scope="scope">
  295. <div>{{ scope.row.hasCourse ? "是" : "否" }}</div>
  296. </template>
  297. </el-table-column>
  298. <el-table-column align="center" label="关心包">
  299. <template slot-scope="scope">{{
  300. scope.row.carePackage | studentPackage
  301. }}</template>
  302. </el-table-column>
  303. <el-table-column align="center" label="加油包">
  304. <template slot-scope="scope">{{
  305. scope.row.comeOnPackage | studentPackage
  306. }}</template>
  307. </el-table-column>
  308. <el-table-column align="center" label="欠费金额(元)">
  309. <template slot-scope="scope">
  310. <div :class="[scope.row.noPaymentAmount > 0 ? 'error' : null]">
  311. {{ scope.row.noPaymentAmount | moneyFormat }}
  312. <!-- musicGroupPaymentCalenderDetail/queryPage/studentList -->
  313. <auth
  314. auths="musicGroupPaymentCalenderDetail/queryPage/studentList"
  315. :router="['/business/resetTeaming']"
  316. >
  317. <i
  318. style="color: #14928a; font-size: 17px"
  319. title="缴费记录"
  320. class="el-icon-view"
  321. @click="onPaymentDetail(scope.row)"
  322. ></i>
  323. </auth>
  324. </div>
  325. </template>
  326. </el-table-column>
  327. <el-table-column label="退团原因" align="center">
  328. <template slot-scope="scope">
  329. <div>
  330. <Tooltip :content="scope.row.quitReason" />
  331. </div>
  332. </template>
  333. </el-table-column>
  334. <el-table-column label="乐团会员有效期" align="center" width="100px">
  335. <template slot-scope="scope">
  336. <div>
  337. {{ scope.row.membershipEndTime | dayjsFormat }}
  338. </div>
  339. </template>
  340. </el-table-column>
  341. <el-table-column label="备注" prop="remark" align="center">
  342. <template slot-scope="scope">
  343. <div>
  344. <overflow-text :text="scope.row.remark"></overflow-text>
  345. </div>
  346. </template>
  347. </el-table-column>
  348. <el-table-column
  349. align="center"
  350. fixed="right"
  351. width="360px;"
  352. label="操作"
  353. >
  354. <template slot-scope="scope">
  355. <div>
  356. <el-button
  357. type="text"
  358. v-if="
  359. permission('studentManage/queryStudentClassGroup') &&
  360. scope.row.studentStatus != 'QUIT'
  361. "
  362. @click="lookClass(scope.row)"
  363. >查看班级</el-button
  364. >
  365. <el-button
  366. type="text"
  367. v-if="
  368. permission('musicGroupPaymentCalender/add') &&
  369. scope.row.studentStatus == 'APPLY' &&
  370. scope.row.paymentStatus != '2' &&
  371. team_status == 'PROGRESS'
  372. "
  373. @click="addPay(scope.row)"
  374. >添加缴费</el-button
  375. >
  376. <el-button
  377. type="text"
  378. v-if="
  379. permission('musicGroupQuit/directQuitMusicGroup/3852') &&
  380. scope.row.studentStatus != 'QUIT'
  381. "
  382. @click="quieTeamMask(scope.row)"
  383. >退团退费</el-button
  384. >
  385. <el-button
  386. type="text"
  387. v-if="
  388. permission('musicGroupQuit/directQuitMusicGroup/3851') &&
  389. scope.row.studentStatus != 'QUIT'
  390. "
  391. @click="quieTeam(scope.row)"
  392. >退团</el-button
  393. >
  394. <el-button
  395. type="text"
  396. v-if="permission('visit/add/teamStudentList')"
  397. @click="addVisit(scope.row)"
  398. >新增回访</el-button
  399. >
  400. <!-- <el-popover
  401. v-show="scope.row.remark"
  402. placement="top-start"
  403. title="备注"
  404. width="200"
  405. trigger="hover"
  406. :content="scope.row.remark"
  407. >
  408. <el-button type="text" slot="reference">备注</el-button>
  409. </el-popover> -->
  410. </div>
  411. </template>
  412. </el-table-column>
  413. </el-table>
  414. <pagination
  415. :save-key="saveKey"
  416. sync
  417. :total.sync="rules.total"
  418. :page.sync="rules.page"
  419. :limit.sync="rules.limit"
  420. :page-sizes="rules.page_size"
  421. @pagination="getList"
  422. />
  423. </div>
  424. <el-dialog
  425. title="新增学员"
  426. width="700px"
  427. class="studentInfo"
  428. :visible.sync="addStudentVisible"
  429. >
  430. <el-form
  431. :model="maskForm"
  432. label-position="right"
  433. label-width="120px"
  434. ref="maskForm"
  435. :rules="maskRules"
  436. :inline="true"
  437. >
  438. <el-alert title="基本信息" :closable="false" class="alert" type="info">
  439. </el-alert>
  440. <el-form-item
  441. label="联系电话"
  442. prop="phone"
  443. :rules="[
  444. { required: true, message: '请输入手机号' },
  445. {
  446. pattern: /^1[3456789]\d{9}$/,
  447. message: '请输入正确的手机号',
  448. trigger: 'blur',
  449. },
  450. ]"
  451. >
  452. <el-input
  453. v-model.trim="maskForm.phone"
  454. placeholder="联系电话"
  455. @blur="checkPhone(maskForm.phone)"
  456. ></el-input>
  457. </el-form-item>
  458. <el-form-item label="学员姓名" prop="studentName">
  459. <el-input
  460. v-model.trim="maskForm.studentName"
  461. placeholder="学员姓名"
  462. ></el-input>
  463. </el-form-item>
  464. <el-form-item label="学员性别" prop="sex">
  465. <el-select
  466. v-model.trim="maskForm.sex"
  467. clearable
  468. style="width: 185px !important"
  469. >
  470. <el-option label="男" :value="1"></el-option>
  471. <el-option label="女" :value="0"></el-option>
  472. </el-select>
  473. </el-form-item>
  474. <!-- <el-form-item label="家长姓名" prop="parentName">
  475. <el-input
  476. v-model.trim="maskForm.parentName"
  477. placeholder="家长姓名"
  478. ></el-input>
  479. </el-form-item> -->
  480. <el-form-item label="年级" prop="currentGradeNum">
  481. <el-select
  482. placeholder="起始年级"
  483. filterable
  484. clearable
  485. v-model.trim="maskForm.currentGradeNum"
  486. style="width: 185px !important"
  487. >
  488. <el-option
  489. v-for="item in gradeList"
  490. :key="item.value"
  491. :label="item.label"
  492. :value="item.value"
  493. ></el-option>
  494. <!-- <el-option value="一年级" label="一年级"></el-option>
  495. <el-option value="二年级" label="二年级"></el-option>
  496. <el-option value="三年级" label="三年级"></el-option>
  497. <el-option value="四年级" label="四年级"></el-option>
  498. <el-option value="五年级" label="五年级"></el-option>
  499. <el-option value="六年级" label="六年级"></el-option>
  500. <el-option value="初一" label="初一"></el-option>
  501. <el-option value="初二" label="初二"></el-option>
  502. <el-option value="初三" label="初三"></el-option>
  503. <el-option value="高一" label="高一"></el-option>
  504. <el-option value="高二" label="高二"></el-option>
  505. <el-option value="高三" label="高三"></el-option> -->
  506. </el-select>
  507. </el-form-item>
  508. <el-form-item label="班级" prop="course">
  509. <el-input
  510. v-model.trim="maskForm.course"
  511. placeholder="班级"
  512. ></el-input>
  513. </el-form-item>
  514. <el-form-item label="学员声部" prop="sound">
  515. <el-select
  516. v-model.trim="maskForm.sound"
  517. clearable
  518. filterable
  519. @change="onSoundChange"
  520. style="width: 185px !important"
  521. >
  522. <el-option
  523. v-for="(item, index) in soundList"
  524. :key="index"
  525. :value="item.id"
  526. :label="item.name"
  527. ></el-option>
  528. </el-select>
  529. </el-form-item>
  530. <!-- <el-form-item label="证件号"
  531. prop="id">
  532. <el-input v-model.trim="maskForm.id"></el-input>
  533. </el-form-item>-->
  534. <el-form-item label="出生日期" style="margin-right: 0" prop="timer">
  535. <el-col :span="24">
  536. <el-date-picker
  537. v-model.trim="maskForm.timer"
  538. value-format="yyyy-MM-dd"
  539. type="date"
  540. :picker-options="{
  541. firstDayOfWeek: 1,
  542. }"
  543. placeholder="选择日期"
  544. ></el-date-picker>
  545. </el-col>
  546. </el-form-item>
  547. </el-form>
  548. <div slot="footer" class="dialog-footer">
  549. <!-- <el-button @click="addStudentVisible = false">取 消</el-button> -->
  550. <el-button type="primary" @click="addStudent">确 定</el-button>
  551. </div>
  552. </el-dialog>
  553. <el-dialog
  554. title="学员所在班级"
  555. width="640px"
  556. :visible.sync="studentClassVisible"
  557. >
  558. <el-form :model="classMask">
  559. <el-form-item label="学生姓名">{{
  560. classMask.studentName
  561. }}</el-form-item>
  562. <el-form-item
  563. label="所在班级"
  564. v-for="(item, index) in classLists"
  565. :key="index"
  566. >{{ item.name }}</el-form-item
  567. >
  568. </el-form>
  569. </el-dialog>
  570. <!-- 退团弹窗 -->
  571. <el-dialog title="退团信息确认" width="640px" :visible.sync="quitVisible">
  572. <quiteTeam :quitForm="quitForm" :activeRow="activeRow" ref="quitForm" />
  573. <span slot="footer" class="dialog-footer question">
  574. <div>
  575. <el-popover placement="right" width="500" trigger="click">
  576. <div class="popoverWrap">
  577. <p>乐团退团退费规则:</p>
  578. <p>退还乐器练习云教练费用:报名缴费时缴费的乐器练习云教练费用</p>
  579. <p>退还课程费用:缴费总额-已结束课时单价之和</p>
  580. <p>退还乐器费用:报名缴费时缴纳的乐器费用(团购、租金)</p>
  581. <p>退还教辅费用:报名缴费时缴费的教辅费用</p>
  582. <p>退还乐保费用:报名缴费时缴费的乐保费用</p>
  583. </div>
  584. <el-button
  585. type="text"
  586. icon="el-icon-question"
  587. slot="reference"
  588. style="color: red"
  589. >退团退费说明</el-button
  590. >
  591. </el-popover>
  592. </div>
  593. <div>
  594. <el-button @click="quitVisible = false">取 消</el-button>
  595. <el-button type="primary" @click="chioseType">确 定</el-button>
  596. </div>
  597. </span>
  598. </el-dialog>
  599. <el-dialog
  600. title="修改缴费周期"
  601. :before-close="closePayVisible"
  602. width="600px"
  603. :visible.sync="payVisible"
  604. >
  605. <el-form :model="payForm" ref="payForm" :inline="true">
  606. <el-form-item label="学生姓名" prop="studentName">
  607. <el-input v-model.trim="payForm.studentName" disabled></el-input>
  608. </el-form-item>
  609. <br />
  610. <el-form-item label="缴费金额" prop="payMoney">
  611. <el-input
  612. type="number"
  613. v-model.trim="payForm.payMoney"
  614. @mousewheel.native.prevent
  615. ></el-input>
  616. </el-form-item>
  617. <el-form-item label="缴费月份" prop="payMonth">
  618. <el-checkbox-group
  619. v-model.trim="payForm.payMonth"
  620. fill="#14928A"
  621. text-color="#474747"
  622. >
  623. <el-checkbox label="1">一月</el-checkbox>
  624. <el-checkbox label="2">二月</el-checkbox>
  625. <el-checkbox label="3">三月</el-checkbox>
  626. <el-checkbox label="4">四月</el-checkbox>
  627. <el-checkbox label="5">五月</el-checkbox>
  628. <el-checkbox label="6">六月</el-checkbox>
  629. <el-checkbox label="7">七月</el-checkbox>
  630. <el-checkbox label="8">八月</el-checkbox>
  631. <el-checkbox label="9">九月</el-checkbox>
  632. <el-checkbox label="10">十月</el-checkbox>
  633. <el-checkbox label="11">十一月</el-checkbox>
  634. <el-checkbox label="12">十二月</el-checkbox>
  635. </el-checkbox-group>
  636. </el-form-item>
  637. <!-- studentName: '',
  638. payMoney: '',
  639. payMonth-->
  640. </el-form>
  641. <div slot="footer" class="dialog-footer">
  642. <el-button @click="quitVisible = false">取 消</el-button>
  643. <el-button type="primary" @click="submitPay">确 定</el-button>
  644. </div>
  645. </el-dialog>
  646. <el-dialog
  647. title="新增回访"
  648. width="500px"
  649. destroy-on-close
  650. :close-on-click-modal="false"
  651. :visible.sync="visitVisiable"
  652. >
  653. <visit
  654. v-if="visitVisiable && detail"
  655. :detail="detail"
  656. @close="visitVisiable = false"
  657. @submited="getList"
  658. />
  659. </el-dialog>
  660. <el-dialog
  661. title="选择班级"
  662. destroy-on-close
  663. width="830px"
  664. :visible.sync="createUserPayVisible"
  665. >
  666. <createUserPay
  667. :signList="signList"
  668. :mixList="mixList"
  669. :highList="highList"
  670. :snapList="snapList"
  671. :highonlineList="highonlineList"
  672. :musicGroupId="this.teamid"
  673. :organizationCourseUnitPriceSettings="
  674. organizationCourseUnitPriceSettings
  675. "
  676. :createdUserId="createdUserId"
  677. :baseInfo="baseInfo"
  678. @submited="getList"
  679. @close="createUserPayVisible = false"
  680. />
  681. </el-dialog>
  682. <el-dialog
  683. title="缴费记录"
  684. width="900px"
  685. :visible.sync="paymentDetailVisible"
  686. >
  687. <payment-list
  688. v-if="paymentDetailVisible"
  689. :paymentDetail="paymentDetail"
  690. @close="paymentDetailVisible = false"
  691. />
  692. </el-dialog>
  693. <el-dialog
  694. title="订单详情"
  695. :visible.sync="orderVisible"
  696. width="600px"
  697. v-if="orderVisible"
  698. >
  699. <el-form :model="orderForm" :inline="true">
  700. <el-form-item label="学员姓名">
  701. <el-input v-model.trim="orderForm.name" disabled=""></el-input>
  702. </el-form-item>
  703. <el-form-item label="实缴金额">
  704. <el-input v-model.trim="orderForm.totalAmount" disabled=""></el-input>
  705. </el-form-item>
  706. <el-form-item label="实际专业">
  707. <el-input v-model.trim="orderForm.subject" disabled=""></el-input>
  708. </el-form-item>
  709. <el-form-item label="课程费用">
  710. <el-input v-model.trim="orderForm.subjectFee" disabled=""></el-input>
  711. </el-form-item>
  712. <el-form-item label="选择乐器">
  713. <el-input v-model.trim="orderForm.axe" disabled=""></el-input>
  714. </el-form-item>
  715. <el-form-item label="乐器价格">
  716. <el-input v-model.trim="orderForm.axePrice" disabled=""></el-input>
  717. </el-form-item>
  718. <el-form-item label="教辅组合">
  719. <el-input v-model.trim="orderForm.others" disabled=""></el-input>
  720. </el-form-item>
  721. <el-form-item label="组合价格">
  722. <el-input v-model.trim="orderForm.othersPrice" disabled=""></el-input>
  723. </el-form-item>
  724. </el-form>
  725. <div slot="footer" class="dialog-footer">
  726. <!-- <el-button>取 消</el-button> -->
  727. <el-button type="primary" @click="orderVisible = false"
  728. >确 定</el-button
  729. >
  730. </div>
  731. </el-dialog>
  732. <el-dialog
  733. title="新增会员试用期"
  734. width="600px"
  735. :visible.sync="addTryVisible"
  736. >
  737. <addTryList
  738. ref="addTry"
  739. v-if="addTryVisible"
  740. :multipleSelection="multipleSelection"
  741. :memberRankList="memberRankList"
  742. @close="addTryVisible = false"
  743. @submited="getList"
  744. />
  745. <div slot="footer" class="dialog-footer">
  746. <el-button @click="addTryVisible = false">取 消</el-button>
  747. <el-button type="primary" @click="submitAddTryTime"
  748. >确 定</el-button
  749. >
  750. </div>
  751. </el-dialog>
  752. </div>
  753. </template>
  754. <script>
  755. import {
  756. getTeamStudentList,
  757. getTeamStudentInfo,
  758. findSound,
  759. StudentQuit,
  760. findSubjectPlan,
  761. getGoods,
  762. getMusicGroup,
  763. getMusicGroupAllClass,
  764. StudentFeeIsLock,
  765. updateStudentFee,
  766. getMusicGroupGradeList,
  767. } from "@/api/buildTeam";
  768. import {
  769. addStudent,
  770. getStudentClass,
  771. getStudentInfoByPhone,
  772. } from "@/api/studentManager";
  773. import { getAllmemberRank } from "@/views/resetTeaming/api";
  774. import qrCode from "@/components/QrCode/index";
  775. import { getOrganizationCourseUnitPriceSettings } from "@/api/specialSetting";
  776. import { visitChiose } from "@/utils/searchArray";
  777. import pagination from "@/components/Pagination/index";
  778. import { vaildStudentUrl, vaildTeacherUrl } from "@/utils/validate";
  779. import QRCode from "qrcodejs2";
  780. import axios from "axios";
  781. import { getToken } from "@/utils/auth";
  782. import { permission } from "@/utils/directivePage";
  783. import { addVisit } from "@/views/returnVisitManager/api.js";
  784. import cleanDeep from "clean-deep";
  785. import createUserPay from "./modals/create-user-pay.vue";
  786. import TimesView from "./modals/course-time-detail";
  787. import paymentCycle from "../../resetTeaming/modals/payment-cycle";
  788. import paymentList from "./modals/payment-list";
  789. import Tooltip from "@/components/Tooltip/index";
  790. import changeVoice from "@/views/teamBuild/modals/change-voice";
  791. //import changeVoice from "./modals/change-voice";
  792. import visit from "@/views/withdrawal-application/modals/visit";
  793. import mergeMusic from "@/views/teamBuild/components/merge-music";
  794. import quiteTeam from "@/views/teamDetail/components/modals/quite-team";
  795. import addTryList from "@/views/teamDetail/components/modals/addTryList";
  796. export default {
  797. name: "tstudentList",
  798. data() {
  799. return {
  800. detail: null,
  801. teamid: "",
  802. paymentDetailVisible: false,
  803. paymentDetail: {},
  804. payVisible: false,
  805. quitVisible: false, // 退团信息确认的弹窗
  806. studentClassVisible: false, // 学员所在班级弹窗
  807. addStudentVisible: false, //新增学员弹窗
  808. timesVisible: false,
  809. timerDetail: null,
  810. topFrom: {
  811. // 顶部的禁选框集合
  812. expect: "2", // 预期招生
  813. studing: "5", // 在读人数
  814. allmoney: "100", //实收总额
  815. students: "5", // 实际招生人数
  816. signout: "10", // 退团总数
  817. },
  818. searchForm: {
  819. studentStatus: "", // 学生状态
  820. major: "", // 报名专业
  821. isPay: "", // 是否缴费
  822. search: "",
  823. isActive: "",
  824. oweFlag: "",
  825. currentGrade: null,
  826. createYear: null,
  827. classGroupId: null,
  828. hasCourse: null,
  829. carePackage: null,
  830. comeOnPackage: null,
  831. },
  832. organizationCourseUnitPriceSettings: [],
  833. quitForm: {
  834. // 退团信息确认
  835. isCloudTeacherAmount: null,
  836. cloudTeacherAmount: null,
  837. isRefundCourseFee: null,
  838. isRefundInstrumentFee: null,
  839. isRefundTeachingAssistantsFee: null,
  840. isMaintenanceFee: null,
  841. maintenanceFee: 0,
  842. reason: "",
  843. },
  844. classMask: {
  845. studentName: "",
  846. },
  847. baseInfo: {},
  848. searchLsit: [],
  849. tableList: [], //
  850. rules: {
  851. // 分页规则
  852. limit: 10, // 限制显示条数
  853. page: 1, // 当前页
  854. total: 0, // 总条数
  855. page_size: [10, 20, 40, 50], // 选择限制显示条数
  856. },
  857. studentListInfo: {
  858. add: "",
  859. quit: "",
  860. studying: "",
  861. courseRate: "",
  862. },
  863. signList: [],
  864. mixList: [],
  865. highList: [],
  866. snapList: [],
  867. soundList: [],
  868. highonlineList: [],
  869. muiscnetworkList: [],
  870. qrcodeStatus: false, // 生成二维码
  871. qrcodes: true,
  872. qrcode: null,
  873. codeUrl: null,
  874. gradeList: [], // 学生
  875. maskForm: {
  876. studentName: "",
  877. sex: "",
  878. parentName: "",
  879. course: "",
  880. phone: "",
  881. sound: "",
  882. timer: "",
  883. signClass: "",
  884. mixClass: "",
  885. highClass: "",
  886. snapClass: [],
  887. highonline: "",
  888. muiscnetwork: "",
  889. startClass: "",
  890. currentGradeNum: null,
  891. id: "",
  892. // courseFee: null, // 声部费用
  893. temporaryCourseFee: null, // 本次课程费用
  894. musicGoodsIdList: null, // 乐器商品编号
  895. kitGroupPurchaseType: "GROUP", // 乐器购买方式
  896. musicPrice: null, // 乐器购买金额
  897. instrGoodsIdList: [], // 辅件商品编号
  898. instrPrice: null, // 辅件购买金额
  899. },
  900. remark: "", // 退团原因
  901. classList: [],
  902. maskRules: {
  903. studentName: [{ required: true, message: "请输入学生姓名" }],
  904. sex: [{ required: true, message: "请选择学生姓名" }],
  905. parentName: [{ required: true, message: "请输入家长姓名" }],
  906. course: [{ required: true, message: "请输入班级" }],
  907. // phone: [{ required: true, message: '请输入手机号' }, { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }],
  908. sound: [{ required: true, message: "请选择声部" }],
  909. timer: [{ required: true, message: "请选择出生日期" }],
  910. signClass: [{ required: true, message: "请选择声部班" }],
  911. // price: [{ required: true, message: '请输入首缴金额' },],
  912. currentGradeNum: [{ required: true, message: "请选择年级" }],
  913. id: [{ required: true, message: "请输入证件号" }],
  914. // courseFee: [{ required: true, message: "请输入声部费用" }],
  915. temporaryCourseFee: [{ required: true, message: "请输课程费用" }],
  916. musicGoodsIdList: [
  917. { required: true, message: "请选择乐器", trigger: "change" },
  918. ],
  919. musicPrice: [{ required: true, message: "请输入乐器购买金额" }],
  920. instrGoodsIdList: [{ required: true, message: "请选择辅件" }],
  921. instrPrice: [{ required: true, message: "请输入辅件金额" }],
  922. },
  923. INSTRUMENTLIST: [], // 乐器列表
  924. ACCESSORIESLIST: [], // 辅件列表
  925. activeRow: { hasMaintenance: false },
  926. Fsearch: null,
  927. Frules: null,
  928. payForm: {
  929. studentName: "",
  930. payMoney: "",
  931. payMonth: [],
  932. },
  933. kitStatus: false, // 乐器提供方式
  934. // 新增回访记录弹窗
  935. visitVisiable: false,
  936. visitForm: {
  937. musicGroupId: "",
  938. overview: "",
  939. purpose: "",
  940. studentId: "",
  941. type: "",
  942. visitTime: "",
  943. visitType: "",
  944. feedback: "",
  945. studentName: "",
  946. },
  947. cycles: [{}],
  948. collapse: [0],
  949. visitChiose,
  950. visitRules: {
  951. overview: [{ required: true, message: "请输入学生近况" }],
  952. feedback: [{ required: true, message: "请输入家长反馈" }],
  953. visitTime: [{ required: true, message: "请输入回访时间" }],
  954. visitType: [{ required: true, message: "请选择回访类型" }],
  955. },
  956. pickerOptions: null,
  957. classLists: null,
  958. createdUserId: 0,
  959. createUserPayVisible: false,
  960. team_status: "",
  961. // 整合报名中
  962. orderVisible: false,
  963. orderForm: {
  964. name: "",
  965. totalAmount: "",
  966. subject: "",
  967. subjectFee: "",
  968. axe: "",
  969. axePrice: "",
  970. others: "",
  971. othersPrice: "",
  972. },
  973. maskSoundForm: {
  974. subject: "",
  975. },
  976. subjectVisible: false,
  977. multipleSelection: [],
  978. isCanReg: false,
  979. organId: "",
  980. addTryVisible: false,
  981. memberRankList: [],
  982. };
  983. },
  984. components: {
  985. pagination,
  986. paymentCycle,
  987. createUserPay,
  988. Tooltip,
  989. "times-view": TimesView,
  990. paymentList,
  991. visit,
  992. qrCode,
  993. changeVoice,
  994. mergeMusic,
  995. quiteTeam,
  996. addTryList,
  997. },
  998. created() {},
  999. filters: {
  1000. studentPays(val) {
  1001. let template = {
  1002. 0: "未缴费",
  1003. 1: "已缴费",
  1004. };
  1005. return template[val];
  1006. },
  1007. },
  1008. // activated() {
  1009. // this.init();
  1010. // },
  1011. async mounted() {
  1012. try {
  1013. const res = await getOrganizationCourseUnitPriceSettings({
  1014. rows: 9999,
  1015. });
  1016. this.organizationCourseUnitPriceSettings = res.data.rows;
  1017. } catch (error) {}
  1018. try {
  1019. const res = await getAllmemberRank({ isDefault: 0 });
  1020. this.memberRankList = res.data;
  1021. } catch (e) {
  1022. console.log(e);
  1023. }
  1024. this.init();
  1025. },
  1026. methods: {
  1027. onPaymentDetail(row) {
  1028. this.paymentDetail = row;
  1029. this.paymentDetailVisible = true;
  1030. },
  1031. viewTimer(row) {
  1032. // this.timerDetail = row
  1033. this.timesVisible = true;
  1034. },
  1035. permission(str) {
  1036. return permission(str);
  1037. },
  1038. async init() {
  1039. this.teamid = this.$route.query.id;
  1040. this.team_status = this.$route.query.team_status;
  1041. this.organId = this.$route.query.organId;
  1042. // 获取乐团是否能补招
  1043. // try {
  1044. // const ruselt = await checkCanReg({ musicGroupId: this.teamid });
  1045. // this.isCanReg = ruselt.data;
  1046. // } catch (e) {
  1047. // console.log(e);
  1048. // }
  1049. getMusicGroupGradeList({ musicGroupId: this.teamid }).then((res) => {
  1050. let result = res.data;
  1051. if (res.code == 200 && result) {
  1052. for (let i in result) {
  1053. this.gradeList.push({
  1054. value: i,
  1055. label: result[i],
  1056. });
  1057. }
  1058. }
  1059. });
  1060. // 获取报名截止日期和缴费截止日期
  1061. // getTeamBaseInfo({ musicGroupId: this.teamid }).then((res) => {
  1062. // if (res.code == 200) {
  1063. // this.paymentExpireDate = res.data.musicGroup.paymentExpireDate;
  1064. // this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  1065. // this.organId = res.data.musicGroup.organId;
  1066. // }
  1067. // });
  1068. // 获取汇总数据
  1069. // this.getTeamStudent();
  1070. this.pickerOptions = this.beginDate();
  1071. this.getList();
  1072. // 获取乐团内所有声部
  1073. findSound({ musicGroupId: this.teamid }).then((res) => {
  1074. if (res.code == 200) {
  1075. this.soundList = res.data;
  1076. }
  1077. });
  1078. // this.getMusicClass()
  1079. // 获取乐团基本信息
  1080. getMusicGroup({ musicGroupId: this.teamid }).then(
  1081. (res) => (this.baseInfo = res.data)
  1082. );
  1083. // 获取乐团所有合奏课
  1084. },
  1085. getMusicClass() {
  1086. getMusicGroupAllClass({ musicGroupId: this.teamid }).then((res) => {
  1087. if (res.code == 200) {
  1088. this.classList = res.data;
  1089. this.signList = [];
  1090. this.mixList = [];
  1091. this.highList = [];
  1092. this.snapList = [];
  1093. this.highonlineList = [];
  1094. this.classList.forEach((item) => {
  1095. if (item.type == "NORMAL") {
  1096. this.signList.push(item);
  1097. } else if (item.type == "MIX") {
  1098. this.mixList.push(item);
  1099. } else if (item.type == "HIGH") {
  1100. this.highList.push(item);
  1101. } else if (item.type == "HIGH_ONLINE" && item.studentNum < 6) {
  1102. this.highonlineList.push(item);
  1103. } else if (item.type == "SNAP") {
  1104. this.snapList.push(item);
  1105. } else if (item.type == "MUSIC_NETWORK") {
  1106. this.muiscnetworkList.push(item);
  1107. }
  1108. });
  1109. }
  1110. });
  1111. },
  1112. getTeamStudent() {
  1113. getTeamStudentInfo({ musicGroupId: this.teamid }).then((res) => {
  1114. if (res.code == 200) {
  1115. this.studentListInfo = res.data;
  1116. }
  1117. });
  1118. },
  1119. permission(str) {
  1120. return permission(str);
  1121. },
  1122. onInstrumentChange() {
  1123. // 乐器切换时
  1124. // 乐器切换时
  1125. // let tempkitType = this.maskForm.kitGroupPurchaseType
  1126. // if(tempkitType == 'GROUP') {
  1127. // this.INSTRUMENTLIST.forEach(item => {
  1128. // if(item.value == value) {
  1129. // this.maskForm.musicPrice = item.marketPrice
  1130. // }
  1131. // })
  1132. // }
  1133. },
  1134. onKitGroupChnage(value) {
  1135. // 乐器提供方式
  1136. this.kitStatus = false;
  1137. if (value == "FREE") {
  1138. this.kitStatus = true;
  1139. this.maskForm.musicPrice = 0;
  1140. } else {
  1141. this.maskForm.musicPrice = null;
  1142. }
  1143. },
  1144. onMusicGroupExport() {
  1145. let url = "/api-web/export/musicGroupStudent";
  1146. let data = {
  1147. musicGroupId: this.teamid,
  1148. studentStatus: this.searchForm.studentStatus || null,
  1149. paymentStatus: this.searchForm.isPay || null,
  1150. subjectId: this.searchForm.major || null,
  1151. search: this.searchForm.search || null,
  1152. isActive: this.searchForm.isActive || null,
  1153. classGroupId: this.searchForm.classGroupId || null,
  1154. currentGrade: this.searchForm.currentGrade || null,
  1155. createYear: this.searchForm.createYear || null,
  1156. hasCourse: this.searchForm.hasCourse || null,
  1157. comeOnPackage: this.searchForm.comeOnPackage,
  1158. carePackage: this.searchForm.carePackage,
  1159. };
  1160. const options = {
  1161. method: "get",
  1162. headers: {
  1163. Authorization: getToken(),
  1164. },
  1165. url,
  1166. params: data,
  1167. responseType: "blob",
  1168. };
  1169. this.$confirm("您确定导出学员列表?", "提示", {
  1170. confirmButtonText: "确定",
  1171. cancelButtonText: "取消",
  1172. type: "warning",
  1173. })
  1174. .then(() => {
  1175. axios(options).then((res) => {
  1176. let blob = new Blob([res.data], {
  1177. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
  1178. type: "application/vnd.ms-excel;charset=utf-8",
  1179. // word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  1180. });
  1181. let objectUrl = URL.createObjectURL(blob);
  1182. let link = document.createElement("a");
  1183. let fname = this.$route.query.name + "学员列表.xls";
  1184. link.href = objectUrl;
  1185. link.setAttribute("download", fname);
  1186. document.body.appendChild(link);
  1187. link.click();
  1188. });
  1189. })
  1190. .catch(() => {});
  1191. },
  1192. search() {
  1193. this.rules.page = 1;
  1194. this.getList();
  1195. },
  1196. onReSet() {
  1197. this.$refs.searchForm.resetFields();
  1198. this.search();
  1199. },
  1200. getList() {
  1201. // getintoClass({ musicGroupId: this.teamid }).then((res) => {
  1202. // if (res.code == 200) {
  1203. // this.$set(this, "leftList", res.data);
  1204. // // this.leftList = res.data;
  1205. // }
  1206. // });
  1207. this.getTeamStudent();
  1208. let obj = {
  1209. musicGroupId: this.teamid,
  1210. page: this.rules.page,
  1211. rows: this.rules.limit,
  1212. studentStatus: this.searchForm.studentStatus || null,
  1213. paymentStatus: this.searchForm.isPay || null,
  1214. subjectId: this.searchForm.major || null,
  1215. search: this.searchForm.search || null,
  1216. isActive: this.searchForm.isActive || null,
  1217. classGroupId: this.searchForm.classGroupId || null,
  1218. currentGrade: this.searchForm.currentGrade || null,
  1219. createYear: this.searchForm.createYear || null,
  1220. oweFlag: this.searchForm.oweFlag || null,
  1221. hasCourse: this.searchForm.hasCourse || null,
  1222. oweFlag: this.searchForm.oweFlag || null,
  1223. comeOnPackage: this.searchForm.comeOnPackage,
  1224. carePackage: this.searchForm.carePackage,
  1225. };
  1226. return getTeamStudentList(obj).then((res) => {
  1227. if (res.code == 200) {
  1228. this.tableList = res.data.rows;
  1229. this.rules.total = res.data.total;
  1230. return res;
  1231. }
  1232. });
  1233. },
  1234. addPay(row) {
  1235. this.createUserPayVisible = true;
  1236. this.createdUserId = row.userId;
  1237. },
  1238. addCycle() {
  1239. this.cycles.push({});
  1240. this.collapse.push(this.collapse.length);
  1241. },
  1242. removeCycle(index) {
  1243. this.cycles[index] = null;
  1244. this.cycles = this.cycles.filter((item) => !!item);
  1245. this.collapse.pop();
  1246. },
  1247. collapseChange(val) {
  1248. this.collapse = val;
  1249. },
  1250. gotoSignin() {
  1251. this.$router.push({
  1252. path: "/business/studentSignin",
  1253. query: {
  1254. id: this.teamid,
  1255. status: this.$route.query.status,
  1256. name: this.$route.query.name,
  1257. rules: this.Frules,
  1258. search: this.Fsearch,
  1259. },
  1260. });
  1261. },
  1262. chioseType() {
  1263. // 父级验证子集表单
  1264. this.$refs["quitForm"].$refs["quitForm"].validate((res) => {
  1265. if (res) {
  1266. this.$confirm("确定退团?", "提示", {
  1267. confirmButtonText: "确定",
  1268. cancelButtonText: "取消",
  1269. type: "warning",
  1270. })
  1271. .then(() => {
  1272. let row = this.activeRow;
  1273. let params = {
  1274. musicGroupId: this.teamid,
  1275. userId: row.userId,
  1276. reason: this.quitForm.reason,
  1277. isRefundCourseFee: this.quitForm.isRefundCourseFee,
  1278. isRefundInstrumentFee: this.quitForm.isRefundInstrumentFee,
  1279. isRefundTeachingAssistantsFee:
  1280. this.quitForm.isRefundTeachingAssistantsFee,
  1281. maintenanceFee: this.quitForm.maintenanceFee,
  1282. isRefundMemberFee: this.quitForm.isRefundMemberFee,
  1283. };
  1284. // 退还乐器练习云教练费用
  1285. if (this.quitForm.isRefundMemberFee) {
  1286. params.cloudTeacherAmount = this.quitForm.cloudTeacherAmount;
  1287. } else {
  1288. params.cloudTeacherAmount = 0;
  1289. }
  1290. // 发请求 退团
  1291. StudentQuit(params).then((res) => {
  1292. this.quitForm = {
  1293. // 退团信息确认
  1294. isRefundCourseFee: null,
  1295. isRefundInstrumentFee: null,
  1296. isRefundTeachingAssistantsFee: null,
  1297. isMaintenanceFee: null,
  1298. cloudTeacherAmount: null,
  1299. isCloudTeacherAmount: null,
  1300. isRefundMemberFee: null,
  1301. maintenanceFee: 0,
  1302. reason: "",
  1303. };
  1304. if (res.code == 200) {
  1305. this.$message.success("退团成功");
  1306. this.getList();
  1307. this.quitVisible = false;
  1308. }
  1309. });
  1310. })
  1311. .catch(() => {});
  1312. } else {
  1313. }
  1314. });
  1315. // row.typeVisible = false;
  1316. },
  1317. //
  1318. addStudent() {
  1319. // 发请求添加学员
  1320. this.$refs["maskForm"].validate((res) => {
  1321. if (res) {
  1322. // this.maskForm.parentName.timer 少个生日的字段
  1323. // classGroupId: maskForm.signClass
  1324. /** <!-- signClass: '',
  1325. mixClass: '',
  1326. highClass: '',
  1327. snapClass: [], --> */
  1328. let maskForm = this.maskForm;
  1329. // if (
  1330. // !maskForm.signClass &&
  1331. // !maskForm.mixClass &&
  1332. // !maskForm.highClass &&
  1333. // !maskForm.highonline &&
  1334. // !maskForm.muiscnetwork
  1335. // ) {
  1336. // if (
  1337. // !maskForm.snapClass ||
  1338. // !(maskForm.snapClass && maskForm.snapClass.length >= 1)
  1339. // ) {
  1340. // this.$message.error("该学生必须加入一个班级");
  1341. // return;
  1342. // }
  1343. // }
  1344. if (
  1345. maskForm.musicGoodsIdList &&
  1346. (maskForm.musicPrice === "" || maskForm.musicPrice === null)
  1347. ) {
  1348. this.$message.error("请输入乐器金额");
  1349. return;
  1350. }
  1351. if (
  1352. maskForm.instrGoodsIdList &&
  1353. maskForm.instrGoodsIdList.length > 0 &&
  1354. (maskForm.instrPrice === "" || maskForm.instrPrice === null)
  1355. ) {
  1356. this.$message.error("请输入辅件金额");
  1357. return;
  1358. }
  1359. let snapClassIds;
  1360. maskForm.snapClass
  1361. ? (snapClassIds = maskForm.snapClass.join(","))
  1362. : (snapClassIds = null);
  1363. let params = {
  1364. signClassId: maskForm.signClass,
  1365. mixClassId: maskForm.mixClass,
  1366. snapClassIds,
  1367. highClassId: maskForm.highClass,
  1368. courseFee: maskForm.courseFee,
  1369. temporaryCourseFee: maskForm.temporaryCourseFee,
  1370. studentRegistration: {
  1371. name: maskForm.studentName,
  1372. gender: maskForm.sex,
  1373. birthdate: maskForm.timer,
  1374. parentsName: maskForm.parentName,
  1375. parentsPhone: maskForm.phone,
  1376. currentGrade: maskForm.startClass,
  1377. currentGradeNum: maskForm.currentGradeNum,
  1378. currentClass: maskForm.course,
  1379. subjectId: maskForm.sound,
  1380. musicGroupId: this.teamid,
  1381. },
  1382. };
  1383. params.studentPaymentOrderDetails = [];
  1384. if (maskForm.musicGoodsIdList) {
  1385. params.studentPaymentOrderDetails.push({
  1386. goodsIdList: maskForm.musicGoodsIdList,
  1387. kitGroupPurchaseType: maskForm.kitGroupPurchaseType,
  1388. type: "MUSICAL",
  1389. price: maskForm.musicPrice,
  1390. });
  1391. }
  1392. if (maskForm.instrGoodsIdList && maskForm.instrGoodsIdList != "") {
  1393. params.studentPaymentOrderDetails.push({
  1394. goodsIdList: maskForm.instrGoodsIdList.join(","),
  1395. type: "ACCESSORIES",
  1396. price: maskForm.instrPrice,
  1397. });
  1398. }
  1399. addStudent(params).then((res) => {
  1400. if (res.code == 200) {
  1401. this.$message.success("添加学生成功");
  1402. this.getList();
  1403. this.addStudentVisible = false;
  1404. this.createUserPayVisible = true;
  1405. this.createdUserId = res.data;
  1406. }
  1407. this.$refs.maskForm.resetFields();
  1408. });
  1409. }
  1410. });
  1411. },
  1412. onSoundChange(value) {
  1413. // 学员声部切换时
  1414. // this.findSubjectPlan(value)
  1415. // this.ACCESSORIESLIST = [];
  1416. // this.maskForm.instrGoodsIdList = [];
  1417. // this.maskForm.instrPrice = null;
  1418. // this.INSTRUMENTLIST = [];
  1419. // this.maskForm.musicPrice = null;
  1420. // this.maskForm.musicGoodsIdList = null;
  1421. // this.getGoodsList(value, "INSTRUMENT"); // 乐器
  1422. // this.getGoodsList(value, "ACCESSORIES"); // 辅件
  1423. },
  1424. // 获取购买方式
  1425. findSubjectPlan(subjectId) {
  1426. findSubjectPlan({
  1427. musicGroupId: this.teamid,
  1428. subjectId: subjectId,
  1429. }).then((res) => {
  1430. let result = res.data;
  1431. if (res.code == 200) {
  1432. this.maskForm.musicMode = this.getBranchType(
  1433. result.kitGroupPurchaseType
  1434. );
  1435. }
  1436. });
  1437. },
  1438. getGoodsList(subjectId, type) {
  1439. getGoods({
  1440. subjectId: subjectId,
  1441. type: type,
  1442. organId: this.organId,
  1443. }).then((res) => {
  1444. let result = res.data;
  1445. if (res.code == 200) {
  1446. let tempArr = [];
  1447. result.forEach((item) => {
  1448. tempArr.push({
  1449. label: item.name,
  1450. value: item.id,
  1451. marketPrice: item.marketPrice,
  1452. });
  1453. });
  1454. if (type == "ACCESSORIES") {
  1455. this.ACCESSORIESLIST = tempArr;
  1456. }
  1457. if (type == "INSTRUMENT") {
  1458. this.INSTRUMENTLIST = tempArr;
  1459. }
  1460. }
  1461. });
  1462. },
  1463. getBranchType(status) {
  1464. let common = {
  1465. FREE: "免费",
  1466. GROUP: "团购",
  1467. LEASE: "租赁",
  1468. };
  1469. return common[status];
  1470. },
  1471. lookClass(row) {
  1472. this.classMask.studentName = row.realName;
  1473. getStudentClass({
  1474. musicGroupId: this.teamid,
  1475. teacherId: row.userId,
  1476. }).then((res) => {
  1477. if (res.code == 200) {
  1478. this.classLists = res.data;
  1479. this.studentClassVisible = true;
  1480. }
  1481. });
  1482. },
  1483. quieTeamMask(row) {
  1484. this.activeRow = row;
  1485. this.activeRow.courseViewType = this.baseInfo.courseViewType;
  1486. this.quitVisible = true;
  1487. this.quitForm.cloudTeacherAmount = row.cloudTeacherAmount;
  1488. },
  1489. quieTeam(row) {
  1490. this.$prompt("请输入退团原因", "提示", {
  1491. confirmButtonText: "确定",
  1492. cancelButtonText: "取消",
  1493. type: "warning",
  1494. inputPattern: /\S/,
  1495. inputErrorMessage: "请输入退团原因",
  1496. })
  1497. .then((val) => {
  1498. // 发请求 退团
  1499. StudentQuit({
  1500. musicGroupId: this.teamid,
  1501. userId: row.userId,
  1502. reason: val.value,
  1503. isRefundCourseFee: false,
  1504. isRefundInstrumentFee: false,
  1505. isRefundTeachingAssistantsFee: false,
  1506. }).then((res) => {
  1507. this.quitForm = {
  1508. // 退团信息确认
  1509. isRefundCourseFee: null,
  1510. isRefundInstrumentFee: null,
  1511. isRefundTeachingAssistantsFee: null,
  1512. isMaintenanceFee: null,
  1513. cloudTeacherAmount: null,
  1514. isCloudTeacherAmount: null,
  1515. maintenanceFee: 0,
  1516. reason: "",
  1517. };
  1518. if (res.code == 200) {
  1519. this.$message.success("退团成功");
  1520. this.getList();
  1521. this.quitVisible = false;
  1522. }
  1523. });
  1524. })
  1525. .catch(() => {});
  1526. },
  1527. checkPhone(val) {
  1528. var regu = /^1[3456789]\d{9}$/;
  1529. var re = new RegExp(regu);
  1530. if (re.test(val)) {
  1531. getStudentInfoByPhone({ mobile: this.maskForm.phone }).then((res) => {
  1532. if (res.code == 200) {
  1533. if (res.data) {
  1534. this.maskForm.studentName = res.data.name;
  1535. this.maskForm.sex = res.data.gender;
  1536. this.maskForm.parentName = res.data.parentsName;
  1537. this.maskForm.course = res.data.currentClass;
  1538. this.maskForm.startClass = res.data.currentGrade;
  1539. this.maskForm.currentGradeNum = res.data.currentGradeNum
  1540. ? res.data.currentGradeNum + ""
  1541. : null;
  1542. this.maskForm.phone = val;
  1543. this.maskForm.timer = res.data.birthdate;
  1544. }
  1545. }
  1546. });
  1547. }
  1548. },
  1549. lockStudent(row) {
  1550. this.$confirm("是否锁定/解锁学生缴费周期?", "提示", {
  1551. confirmButtonText: "确定",
  1552. cancelButtonText: "取消",
  1553. type: "warning",
  1554. })
  1555. .then(() => {
  1556. let musicGroupId = this.teamid;
  1557. let studentId = row.userId;
  1558. let isLock;
  1559. row.isLock == 0 ? (isLock = 1) : (isLock = 0);
  1560. StudentFeeIsLock({ musicGroupId, studentId, isLock }).then((res) => {
  1561. if (res.code == 200) {
  1562. this.$message.success("修改成功");
  1563. this.getList();
  1564. }
  1565. });
  1566. })
  1567. .catch(() => {});
  1568. },
  1569. resetPay(row) {
  1570. this.activeRow = row;
  1571. this.payVisible = true;
  1572. this.payForm.studentName = row.realName;
  1573. this.payForm.payMoney = row.courseFee;
  1574. this.payForm.payMonth = row.paymentPeriodList.split(",");
  1575. if (this.payForm.payMonth[0] == "") {
  1576. this.payForm.payMonth = [];
  1577. }
  1578. },
  1579. submitPay() {
  1580. let studentId = this.activeRow.userId;
  1581. let musicGroupId = this.teamid;
  1582. let month = this.payForm.payMonth.join(",") || null;
  1583. let amount = this.payForm.payMoney;
  1584. let obj = {
  1585. studentId,
  1586. musicGroupId,
  1587. month,
  1588. amount,
  1589. };
  1590. updateStudentFee(obj).then((res) => {
  1591. if (res.code == 200) {
  1592. this.$message.success("修改成功");
  1593. this.payVisible = false;
  1594. this.getList();
  1595. }
  1596. });
  1597. },
  1598. closePayVisible() {
  1599. this.$refs["payForm"].resetFields();
  1600. this.payVisible = false;
  1601. },
  1602. addVisit(row) {
  1603. console.log(row);
  1604. this.detail = row;
  1605. // this.visitForm.studentName = row.realName;
  1606. // this.visitForm.musicGroupId = this.teamid;
  1607. // this.visitForm.studentId = row.userId;
  1608. this.visitVisiable = true;
  1609. },
  1610. handleChange(val) {
  1611. this.visitForm.type = val[0];
  1612. this.visitForm.purpose = val[1];
  1613. },
  1614. submitAddVisit() {
  1615. console.log(this.$refs.visitForm);
  1616. this.$refs.visitForm.validate((res) => {
  1617. if (res) {
  1618. addVisit(cleanDeep(this.visitForm)).then((res) => {
  1619. if (res.code === 200) {
  1620. this.$message.success("新增成功");
  1621. this.visitVisiable = false;
  1622. }
  1623. });
  1624. }
  1625. });
  1626. },
  1627. beginDate() {
  1628. let self = this;
  1629. return {
  1630. firstDayOfWeek: 1,
  1631. disabledDate(time) {
  1632. return time.getTime() >= new Date().getTime(); //开始时间不选时,结束时间最大值小于等于当天
  1633. },
  1634. };
  1635. },
  1636. createStudentFrom() {
  1637. this.addStudentVisible = true;
  1638. },
  1639. // 报名缴费功能
  1640. payDate() {
  1641. let self = this;
  1642. return {
  1643. firstDayOfWeek: 1,
  1644. disabledDate(time) {
  1645. if (self.applyExpireDate) {
  1646. return (
  1647. time.getTime() <=
  1648. new Date(self.applyExpireDate.replace(/-/g, "/")).getTime()
  1649. );
  1650. } else {
  1651. return false;
  1652. }
  1653. },
  1654. };
  1655. },
  1656. applyDate() {
  1657. let self = this;
  1658. return {
  1659. firstDayOfWeek: 1,
  1660. disabledDate(time) {
  1661. if (self.paymentExpireDate) {
  1662. return (
  1663. time.getTime() >
  1664. new Date(self.paymentExpireDate.replace(/-/g, "/")).getTime()
  1665. );
  1666. } else {
  1667. return false;
  1668. }
  1669. },
  1670. };
  1671. },
  1672. handleSelectionChange(val) {
  1673. this.multipleSelection = val;
  1674. },
  1675. checkboxSelect(row) {
  1676. return row.studentStatus == "NORMAL";
  1677. },
  1678. gotoStudent(search) {
  1679. // this.$router.push({
  1680. // name: "teamCourseList",
  1681. // params: { courseIdSearch: row.id },
  1682. // });
  1683. this.$router.push({
  1684. name: "studentList",
  1685. params: { search: search },
  1686. });
  1687. },
  1688. addTryTime() {
  1689. if (this.multipleSelection.length > 0) {
  1690. this.addTryVisible = true;
  1691. } else {
  1692. this.$message.error("请至少选择一名学员");
  1693. }
  1694. },
  1695. submitAddTryTime(){
  1696. this.$refs.addTry.submit()
  1697. }
  1698. },
  1699. watch: {
  1700. createUserPayVisible(val) {
  1701. if (val) {
  1702. this.getMusicClass();
  1703. }
  1704. },
  1705. "quitForm.isMaintenanceFee"(val) {
  1706. if (val) {
  1707. this.quitForm.maintenanceFee = 300;
  1708. } else {
  1709. this.quitForm.maintenanceFee = 0;
  1710. }
  1711. },
  1712. quitVisible(val) {
  1713. if (!val) {
  1714. this.quitForm = {
  1715. // 退团信息确认
  1716. isRefundCourseFee: null,
  1717. isRefundInstrumentFee: null,
  1718. isRefundTeachingAssistantsFee: null,
  1719. isMaintenanceFee: null,
  1720. cloudTeacherAmount: null,
  1721. isCloudTeacherAmount: null,
  1722. isRefundMemberFee: null,
  1723. maintenanceFee: 0,
  1724. reason: "",
  1725. };
  1726. this.$refs["quitForm"].$refs["quitForm"].resetFields();
  1727. }
  1728. },
  1729. // visitVisiable(val) {
  1730. // if (!val) {
  1731. // this.$refs["visitForm"].resetFields();
  1732. // }
  1733. // },
  1734. },
  1735. computed: {
  1736. saveKey() {
  1737. // return 'teamDetails-'+this.$route.query.id
  1738. return "teamDetails-studentList|id|" + this.$route.query.id;
  1739. },
  1740. },
  1741. };
  1742. </script>
  1743. <style lang="scss" scoped>
  1744. .dialog-footer.question {
  1745. display: flex;
  1746. flex-direction: row;
  1747. justify-content: space-between;
  1748. }
  1749. // .moreInput {
  1750. // width: 100%;
  1751. // display: flex;
  1752. // /deep/.el-form-item__content {
  1753. // display: flex;
  1754. // flex-direction: row;
  1755. // }
  1756. // }
  1757. .error {
  1758. color: red;
  1759. }
  1760. .el-select {
  1761. width: 180px !important;
  1762. }
  1763. .headWrap {
  1764. padding: 20px 0;
  1765. }
  1766. /deep/.el-date-editor.el-input {
  1767. width: auto;
  1768. .el-input__inner {
  1769. padding-right: 0;
  1770. }
  1771. }
  1772. .studentInfo {
  1773. /deep/.el-dialog__body {
  1774. // padding-top: 0;
  1775. // padding-bottom: 0;
  1776. }
  1777. }
  1778. // .instrList {
  1779. // display: flex;
  1780. // /deep/.el-form-item__content {
  1781. // width: 80%;
  1782. // }
  1783. // .el-col {
  1784. // /deep/.el-form-item__content {
  1785. // width: 100%;
  1786. // }
  1787. // }
  1788. // }
  1789. .stu-container {
  1790. .topFrom {
  1791. margin: 20px 30px 0;
  1792. width: 1000px;
  1793. }
  1794. .newStudent {
  1795. width: 121px;
  1796. height: 40px;
  1797. background: rgba(20, 146, 138, 1);
  1798. border-radius: 4px;
  1799. color: #fff;
  1800. text-align: center;
  1801. line-height: 40px;
  1802. font-size: 14px;
  1803. cursor: pointer;
  1804. }
  1805. }
  1806. .left-code,
  1807. .right-code {
  1808. // width: 50%;
  1809. // float: left;
  1810. h2 {
  1811. display: block;
  1812. font-size: 18px;
  1813. text-align: center;
  1814. padding-bottom: 8px;
  1815. line-height: 1;
  1816. height: 30px;
  1817. margin-bottom: 0;
  1818. }
  1819. .qrcode {
  1820. display: flex;
  1821. justify-content: center;
  1822. img {
  1823. width: 200px;
  1824. height: 200px;
  1825. // margin: 0 auto;
  1826. }
  1827. }
  1828. .code-url {
  1829. font-size: 18px;
  1830. text-align: center;
  1831. padding: 15px 15px 0 15px;
  1832. }
  1833. }
  1834. .export {
  1835. background: #14928a;
  1836. }
  1837. .alert {
  1838. margin-bottom: 10px;
  1839. }
  1840. .collapse-title {
  1841. display: flex;
  1842. justify-content: space-between;
  1843. align-items: center;
  1844. width: 100%;
  1845. .el-icon-circle-close {
  1846. font-size: 16px;
  1847. margin-right: 10px;
  1848. }
  1849. }
  1850. /deep/ .el-collapse-item__wrap {
  1851. padding-top: 20px;
  1852. }
  1853. .cycleForm {
  1854. /deep/ .el-form-item {
  1855. display: flex;
  1856. width: 100%;
  1857. /deep/ .el-form-item__content {
  1858. margin-left: 0 !important;
  1859. flex: 1;
  1860. }
  1861. }
  1862. }
  1863. .statistic {
  1864. padding: 20px 0;
  1865. text-align: center;
  1866. width: 100%;
  1867. margin: auto !important;
  1868. }
  1869. .popoverWrap {
  1870. p {
  1871. line-height: 25px;
  1872. }
  1873. }
  1874. .studentListWrap {
  1875. display: flex;
  1876. flex-direction: row;
  1877. justify-content: flex-start;
  1878. align-items: center;
  1879. div {
  1880. margin-right: 15px;
  1881. }
  1882. }
  1883. .btnList {
  1884. display: flex;
  1885. flex-direction: row;
  1886. justify-content: flex-start;
  1887. align-items: center;
  1888. flex-wrap: wrap;
  1889. & > div {
  1890. margin-right: 15px;
  1891. margin-bottom: 10px;
  1892. }
  1893. }
  1894. </style>