studentList.vue 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  1. <template>
  2. <div class='stu-container'>
  3. <!-- 头部展示 -->
  4. <div class="headWrap">
  5. <div class="left">
  6. <div class="headItem">
  7. <p>在读人数:<span>{{studentListInfo.studying}}</span></p>
  8. </div>
  9. <div class="headItem">
  10. <p>退团人数:<span>{{studentListInfo.quit}}</span></p>
  11. </div>
  12. <div class="headItem">
  13. <p>新增人数:<span>{{studentListInfo.add}}</span></p>
  14. </div>
  15. </div>
  16. <div class="right">
  17. <div class="newStudent"
  18. style="margin-bottom:10px;"
  19. @click="addStudentVisible = true">新增学员</div>
  20. <div class="newStudent"
  21. style="margin-bottom:10px;"
  22. @click="onCreateQRCode">报名连接</div>
  23. <div class="newStudent"
  24. @click='gotoSignin'>点名总览</div>
  25. </div>
  26. </div>
  27. <!-- 搜索类型 -->
  28. <el-form :inline="true"
  29. class="searchForm"
  30. v-model="searchForm">
  31. <el-form-item>
  32. <el-input v-model="searchForm.search"
  33. placeholder="学生姓名或电话"
  34. @keyup.enter.native='search'></el-input>
  35. </el-form-item>
  36. <el-form-item>
  37. <el-select v-model="searchForm.studentStatus"
  38. clearable
  39. filterable
  40. placeholder="学员状态">
  41. <el-option label="在读"
  42. value="NORMAL"></el-option>
  43. <el-option label="请假"
  44. value="LEAVE"></el-option>
  45. <el-option label="退团"
  46. value="QUIT"></el-option>
  47. </el-select>
  48. </el-form-item>
  49. <el-form-item>
  50. <el-select v-model="searchForm.major"
  51. clearable
  52. filterable
  53. placeholder="所选专业">
  54. <el-option v-for='(item,index) in soundList'
  55. :key='index'
  56. :value="item.id"
  57. :label="item.name"></el-option>
  58. </el-select>
  59. </el-form-item>
  60. <el-form-item>
  61. <el-select v-model="searchForm.isPay"
  62. clearable
  63. filterable
  64. placeholder="报名缴费">
  65. <el-option label="完成缴费"
  66. value="PAID_COMPLETED"></el-option>
  67. <el-option label="未缴费"
  68. value="NON_PAYMENT"></el-option>
  69. <el-option label="缴费中"
  70. value="PROCESSING"></el-option>
  71. </el-select>
  72. </el-form-item>
  73. <el-form-item>
  74. <el-select v-model="searchForm.isActive"
  75. clearable
  76. filterable
  77. placeholder="是否激活">
  78. <el-option label="是"
  79. value="1"></el-option>
  80. <el-option label="否"
  81. value="0"></el-option>
  82. </el-select>
  83. </el-form-item>
  84. <!-- <el-form-item>
  85. <el-select v-model="searchForm.school"
  86. placeholder="所在学校">
  87. <el-option label="item.text"
  88. value="1"></el-option>
  89. </el-select>
  90. </el-form-item> -->
  91. <el-form-item>
  92. <div class='searchBtn'
  93. @click='search'>搜索</div>
  94. </el-form-item>
  95. <el-form-item>
  96. <div class='searchBtn export'
  97. v-permission="'export/musicGroupStudent'"
  98. @click='onMusicGroupExport'>导出</div>
  99. </el-form-item>
  100. </el-form>
  101. <!-- 列表 -->
  102. <div class="tableWrap">
  103. <el-table :data='tableList'
  104. :header-cell-style="{background:'#EDEEF0',color:'#444'}">
  105. <el-table-column label="学员编号"
  106. width="120px;"
  107. prop="userId">
  108. </el-table-column>
  109. <el-table-column label="学员姓名"
  110. width="120px;"
  111. prop="realName">
  112. </el-table-column>
  113. <el-table-column align='center'
  114. prop="gender"
  115. width="50px;"
  116. label="性别">
  117. <template slot-scope="scope">
  118. <div>
  119. {{scope.row.gender| sex }}
  120. </div>
  121. </template>
  122. </el-table-column>
  123. <el-table-column align='center'
  124. prop="phone"
  125. label="联系电话">
  126. </el-table-column>
  127. <!-- <el-table-column align='center'
  128. prop=""
  129. label="所在学校">
  130. </el-table-column> -->
  131. <el-table-column align='center'
  132. label="年级班级">
  133. <template slot-scope="scope">
  134. <div>
  135. {{scope.row.currentGrade+scope.row.currentClass}}
  136. </div>
  137. </template>
  138. </el-table-column>
  139. <el-table-column align='center'
  140. label="专业"
  141. prop="subjectName">
  142. </el-table-column>
  143. <!-- <el-table-column align='center'
  144. label="乐团班级">
  145. </el-table-column>
  146. <el-table-column align='center'
  147. label="合奏班">
  148. </el-table-column> -->
  149. <el-table-column align='center'
  150. prop="studentStatus"
  151. label="学员状态">
  152. <template slot-scope="scope">
  153. <div>
  154. {{ scope.row.studentStatus | musicGroupStudentType}}
  155. </div>
  156. </template>
  157. </el-table-column>
  158. <el-table-column align='center'
  159. label="新增学员">
  160. <template slot-scope="scope">
  161. <div>
  162. {{ scope.row.isNewStudent | yesOrNo}}
  163. </div>
  164. </template>
  165. </el-table-column>
  166. <el-table-column align="center"
  167. label="缴费金额"
  168. prop="courseFee">
  169. </el-table-column>
  170. <el-table-column align="center"
  171. label="下次缴费日期"
  172. prop="nextPaymentDate">
  173. <template slot-scope="scope">
  174. {{ scope.row.nextPaymentDate | formatTimer }}
  175. </template>
  176. </el-table-column>
  177. <el-table-column align='center'
  178. label="报名缴费">
  179. <template slot-scope="scope">
  180. <div>
  181. {{ scope.row.paymentStatus | studentPays}}
  182. </div>
  183. </template>
  184. </el-table-column>
  185. <el-table-column align='center'
  186. label="是否激活">
  187. <template slot-scope="scope">
  188. <div>
  189. {{ scope.row.isActive?'是':'否'}}
  190. </div>
  191. </template>
  192. </el-table-column>
  193. <el-table-column align='center'
  194. label="操作">
  195. <template slot-scope="scope">
  196. <div v-if="scope.row.studentStatus != 'QUIT'">
  197. <!-- <el-popover placement="top"
  198. v-model="scope.row.typeVisible">
  199. <el-input v-model="remark"
  200. placeholder="请输入退团原因"></el-input>
  201. <el-button type="text"
  202. slot='reference'
  203. class='chiose'>
  204. 退团
  205. </el-button>
  206. <div style="text-align: right; margin-top: 20px">
  207. <el-button size="mini"
  208. type="text"
  209. @click="scope.row.typeVisible = false">取消</el-button>
  210. <el-button type="primary"
  211. size="mini"
  212. @click="chioseType(scope.row)">确定</el-button>
  213. </div>
  214. </el-popover> -->
  215. <el-button type='text'
  216. @click="quieTeamMask(scope.row)">退团</el-button>
  217. <el-button type="text"
  218. @click="lookClass(scope.row)">查看班级</el-button>
  219. </div>
  220. </template>
  221. </el-table-column>
  222. </el-table>
  223. <pagination :total="rules.total"
  224. :page.sync="rules.page"
  225. :limit.sync="rules.limit"
  226. :page-sizes="rules.page_size"
  227. @pagination="getList" />
  228. </div>
  229. <el-dialog title="新增学员"
  230. width="640px"
  231. class="studentInfo"
  232. :visible.sync="addStudentVisible">
  233. <el-form :model="maskForm"
  234. label-position="right"
  235. label-width="100px"
  236. ref='maskForm'
  237. :rules="maskRules"
  238. :inline="true">
  239. <el-divider>基本信息</el-divider>
  240. <el-form-item label="联系电话"
  241. :rules="[{ required: true, message: '请输入手机号' }, { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }]"
  242. prop="phone">
  243. <el-input v-model="maskForm.phone"
  244. placeholder="联系电话"
  245. @blur="checkPhone(maskForm.phone)"></el-input>
  246. </el-form-item>
  247. <el-form-item label="学员姓名"
  248. prop="studentName">
  249. <el-input v-model="maskForm.studentName"
  250. placeholder="学员姓名"></el-input>
  251. </el-form-item>
  252. <el-form-item label="学员性别"
  253. prop="sex">
  254. <el-select v-model="maskForm.sex"
  255. clearable>
  256. <el-option label="男"
  257. :value="1"></el-option>
  258. <el-option label="女"
  259. :value="0"></el-option>
  260. </el-select>
  261. </el-form-item>
  262. <el-form-item label="家长姓名"
  263. prop="parentName">
  264. <el-input v-model="maskForm.parentName"
  265. placeholder="家长姓名"></el-input>
  266. </el-form-item>
  267. <el-form-item label="年级"
  268. prop="startClass">
  269. <el-select placeholder="起始年级"
  270. filterable
  271. clearable
  272. v-model="maskForm.startClass">
  273. <el-option value="一年级"
  274. label="一年级"></el-option>
  275. <el-option value="二年级"
  276. label="二年级"></el-option>
  277. <el-option value="三年级"
  278. label="三年级"></el-option>
  279. <el-option value="四年级"
  280. label="四年级"></el-option>
  281. <el-option value="五年级"
  282. label="五年级"></el-option>
  283. <el-option value="六年级"
  284. label="六年级"></el-option>
  285. <el-option value="初一"
  286. label="初一"></el-option>
  287. <el-option value="初二"
  288. label="初二"></el-option>
  289. <el-option value="初三"
  290. label="初三"></el-option>
  291. <el-option value="高一"
  292. label="高一"></el-option>
  293. <el-option value="高二"
  294. label="高二"></el-option>
  295. <el-option value="高三"
  296. label="高三"></el-option>
  297. </el-select>
  298. </el-form-item>
  299. <el-form-item label="班级"
  300. prop="course">
  301. <el-input v-model="maskForm.course"
  302. placeholder="班级"></el-input>
  303. </el-form-item>
  304. <el-form-item label="学员声部"
  305. prop="sound">
  306. <el-select v-model="maskForm.sound"
  307. clearable
  308. filterable
  309. @change="onSoundChange">
  310. <el-option v-for='(item,index) in soundList'
  311. :key='index'
  312. :value="item.id"
  313. :label="item.name"></el-option>
  314. </el-select>
  315. </el-form-item>
  316. <!-- <el-form-item label="证件号"
  317. prop="id">
  318. <el-input v-model="maskForm.id"></el-input>
  319. </el-form-item> -->
  320. <el-form-item label="出生日期"
  321. style="margin-right: 0;"
  322. prop="timer">
  323. <el-col :span="24">
  324. <el-date-picker v-model="maskForm.timer"
  325. value-format="yyyy-MM-dd"
  326. type="date"
  327. placeholder="选择日期">
  328. </el-date-picker>
  329. </el-col>
  330. </el-form-item>
  331. <el-form-item label="声部费用"
  332. prop="courseFee">
  333. <el-input v-model="maskForm.courseFee"
  334. placeholder="请输入声部费用"></el-input>
  335. </el-form-item>
  336. <br>
  337. <el-form-item label="单技班">
  338. <el-select v-model="maskForm.signClass"
  339. filterable
  340. clearable>
  341. <el-option v-for="(item,index) in signList"
  342. :key="index"
  343. :value="item.id"
  344. :label="item.name"></el-option>
  345. </el-select>
  346. </el-form-item>
  347. <el-form-item label="合奏班">
  348. <el-select v-model="maskForm.mixClass"
  349. filterable
  350. clearable>
  351. <el-option v-for="(item,index) in mixList"
  352. :key="index"
  353. :value="item.id"
  354. :label="item.name"></el-option>
  355. </el-select>
  356. </el-form-item>
  357. <el-form-item label="基础技能班">
  358. <el-select v-model="maskForm.highClass"
  359. filterable
  360. clearable>
  361. <el-option v-for="(item,index) in highList"
  362. :key="index"
  363. :value="item.id"
  364. :label="item.name"></el-option>
  365. </el-select>
  366. </el-form-item>
  367. <el-form-item label="临时班">
  368. <el-select v-model="maskForm.snapClass"
  369. filterable
  370. clearable
  371. multiple>
  372. <el-option v-for="(item,index) in snapList"
  373. :key="index"
  374. :value="item.id"
  375. :label="item.name"></el-option>
  376. </el-select>
  377. </el-form-item>
  378. <el-divider>订单信息</el-divider>
  379. <el-form-item label="课程费用"
  380. prop="temporaryCourseFee">
  381. <el-input type='number'
  382. @mousewheel.native.prevent
  383. v-model="maskForm.temporaryCourseFee"
  384. placeholder="本次课程费用"></el-input>
  385. </el-form-item>
  386. <el-form-item label="乐器"
  387. class="instrList">
  388. <el-col :span="11"
  389. style="width: auto;">
  390. <el-form-item>
  391. <el-select placeholder="选择乐器"
  392. filterable
  393. clearable
  394. v-model="maskForm.musicGoodsIdList">
  395. <el-option v-for="(item, index) in INSTRUMENTLIST"
  396. :key="index"
  397. :value="item.value"
  398. :label="item.label"></el-option>
  399. </el-select>
  400. </el-form-item>
  401. </el-col>
  402. <el-col :span="1">&nbsp;</el-col>
  403. <el-col :span="11">
  404. <el-form-item>
  405. <el-input v-model="maskForm.musicPrice"
  406. placeholder="输入金额">
  407. <template slot="prepend">
  408. {{ maskForm.musicMode }}
  409. </template>
  410. </el-input>
  411. </el-form-item>
  412. </el-col>
  413. </el-form-item>
  414. <el-form-item label="辅件">
  415. <el-col :span="11"
  416. style="width: auto;">
  417. <el-form-item>
  418. <el-select filterable
  419. clearable
  420. multiple
  421. placeholder="选择辅件"
  422. v-model="maskForm.instrGoodsIdList">
  423. <el-option v-for="(item, index) in ACCESSORIESLIST"
  424. :key="index"
  425. :value="item.value"
  426. :label="item.label"></el-option>
  427. </el-select>
  428. </el-form-item>
  429. </el-col>
  430. <el-col :span="1">&nbsp;</el-col>
  431. <el-col :span="11">
  432. <el-form-item>
  433. <el-input v-model="maskForm.instrPrice"
  434. placeholder="输入金额"></el-input>
  435. </el-form-item>
  436. </el-col>
  437. </el-form-item>
  438. </el-form>
  439. <div slot="footer"
  440. class="dialog-footer">
  441. <!-- <el-button @click="addStudentVisible = false">取 消</el-button> -->
  442. <el-button type="primary"
  443. @click="addStudent">确 定</el-button>
  444. </div>
  445. </el-dialog>
  446. <el-dialog title="学员所在班级"
  447. width="640px"
  448. :visible.sync="studentClassVisible">
  449. <el-form :model="classMask">
  450. <el-form-item label="学生姓名">
  451. {{ classMask.studentName }}
  452. </el-form-item>
  453. <el-form-item label="所在班级"
  454. v-for="(item,index) in classList"
  455. :key="index">
  456. {{ item.name }}
  457. </el-form-item>
  458. </el-form>
  459. </el-dialog>
  460. <!-- 退团弹窗 -->
  461. <el-dialog title="退团信息确认"
  462. width="640px"
  463. :visible.sync="quitVisible">
  464. <el-form :model="quitForm">
  465. <el-form-item label="退还课程费用"
  466. prop="isRefundCourseFee">
  467. <el-radio v-model="quitForm.isRefundCourseFee"
  468. :label="true">是</el-radio>
  469. <el-radio v-model="quitForm.isRefundCourseFee"
  470. :label="false">否</el-radio>
  471. </el-form-item>
  472. <el-form-item label="退还乐器费用"
  473. prop="isRefundInstrumentFee">
  474. <el-radio v-model="quitForm.isRefundInstrumentFee"
  475. :label="true">是</el-radio>
  476. <el-radio v-model="quitForm.isRefundInstrumentFee"
  477. :label="false">否</el-radio>
  478. </el-form-item>
  479. <el-form-item label="退还教辅费用"
  480. prop="isRefundTeachingAssistantsFee">
  481. <el-radio v-model="quitForm.isRefundTeachingAssistantsFee"
  482. :label="true">是</el-radio>
  483. <el-radio v-model="quitForm.isRefundTeachingAssistantsFee"
  484. :label="false">否</el-radio>
  485. </el-form-item>
  486. <el-form-item label="退团原因">
  487. <el-input type="textarea"
  488. v-model="quitForm.reason"></el-input>
  489. </el-form-item>
  490. </el-form>
  491. <span slot="footer"
  492. class="dialog-footer">
  493. <el-button @click="quitVisible = false">取 消</el-button>
  494. <el-button type="primary"
  495. @click="chioseType">确 定</el-button>
  496. </span>
  497. </el-dialog>
  498. <el-dialog title="报名二维码"
  499. :visible.sync="qrcodeStatus"
  500. width="300px">
  501. <div class="left-code">
  502. <h2>学员报名连接</h2>
  503. <div id="qrcode"
  504. class="qrcode code"
  505. ref="qrCodeUrl"></div>
  506. <p class="code-url"
  507. v-if="codeUrl">{{ codeUrl }}</p>
  508. </div>
  509. </el-dialog>
  510. </div>
  511. </template>
  512. <script>
  513. import { getTeamStudentList, getTeamStudentInfo, getSingleClass, findSound, StudentQuit, findSubjectPlan, getGoods, getSubject, getMusicGroupAllClass } from '@/api/buildTeam'
  514. import { addStudent, getStudentClass, getStudentInfoByPhone } from '@/api/studentManager'
  515. import pagination from '@/components/Pagination/index'
  516. import { vaildStudentUrl } from '@/utils/validate'
  517. import QRCode from 'qrcodejs2'
  518. import axios from 'axios'
  519. import { getToken } from '@/utils/auth'
  520. export default {
  521. props: {
  522. teamid: {
  523. type: String,
  524. required: true
  525. },
  526. },
  527. data () {
  528. return {
  529. quitVisible: false, // 退团信息确认的弹窗
  530. studentClassVisible: false, // 学员所在班级弹窗
  531. addStudentVisible: false, //新增学员弹窗
  532. topFrom: { // 顶部的禁选框集合
  533. expect: '2', // 预期招生
  534. studing: '5', // 在读人数
  535. allmoney: '100', //实收总额
  536. students: '5', // 实际招生人数
  537. signout: '10', // 退团总数
  538. },
  539. searchForm: {
  540. studentStatus: '', // 学生状态
  541. major: '', // 报名专业
  542. isPay: '', // 是否缴费
  543. search: '',
  544. isActive: ''
  545. },
  546. quitForm: { // 退团信息确认
  547. isRefundCourseFee: null,
  548. isRefundInstrumentFee: null,
  549. isRefundTeachingAssistantsFee: null,
  550. reason: ''
  551. },
  552. classMask: {
  553. studentName: ''
  554. },
  555. searchLsit: [],
  556. tableList: [], //
  557. rules: {
  558. // 分页规则
  559. limit: 10, // 限制显示条数
  560. page: 1, // 当前页
  561. total: 0, // 总条数
  562. page_size: [10, 20, 40, 50] // 选择限制显示条数
  563. },
  564. studentListInfo: {
  565. add: '',
  566. quit: '',
  567. studying: ''
  568. },
  569. signList: [],
  570. mixList: [],
  571. highList: [],
  572. snapList: [],
  573. soundList: [],
  574. qrcodeStatus: false, // 生成二维码
  575. qrcodes: true,
  576. qrcode: null,
  577. codeUrl: null,
  578. maskForm: {
  579. studentName: '',
  580. sex: '',
  581. parentName: '',
  582. course: '',
  583. phone: '',
  584. sound: '',
  585. timer: '',
  586. signClass: '',
  587. mixClass: '',
  588. highClass: '',
  589. snapClass: new Array(),
  590. // price: '',
  591. startClass: '',
  592. id: '',
  593. courseFee: null, // 声部费用
  594. temporaryCourseFee: null, // 本次课程费用
  595. musicGoodsIdList: null, // 乐器商品编号
  596. musicMode: null, // 乐器购买方式
  597. musicPrice: null, // 乐器购买金额
  598. instrGoodsIdList: [], // 辅件商品编号
  599. instrPrice: null // 辅件购买金额
  600. },
  601. remark: '', // 退团原因
  602. classList: [],
  603. maskRules: {
  604. studentName: [{ required: true, message: '请输入学生姓名' },],
  605. sex: [{ required: true, message: '请选择学生姓名' },],
  606. parentName: [{ required: true, message: '请输入家长姓名' },],
  607. course: [{ required: true, message: '请输入班级' },],
  608. // phone: [{ required: true, message: '请输入手机号' }, { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }],
  609. sound: [{ required: true, message: '请选择声部' },],
  610. timer: [{ required: true, message: '请选择出生日期' },],
  611. signClass: [{ required: true, message: '请选择单技班' },],
  612. // price: [{ required: true, message: '请输入首缴金额' },],
  613. startClass: [{ required: true, message: '请选择年级' }],
  614. id: [{ required: true, message: '请输入证件号' }],
  615. courseFee: [{ required: true, message: '请输入声部费用' }],
  616. temporaryCourseFee: [{ required: true, message: '请输课程费用' }],
  617. musicGoodsIdList: [{ required: true, message: '请选择乐器', trigger: 'change' }],
  618. musicPrice: [{ required: true, message: '请输入乐器购买金额' }],
  619. instrGoodsIdList: [{ required: true, message: '请选择辅件' }],
  620. instrPrice: [{ required: true, message: '请输入辅件金额' }]
  621. },
  622. INSTRUMENTLIST: [], // 乐器列表
  623. ACCESSORIESLIST: [], // 辅件列表
  624. activeRow: null,
  625. Fsearch: null,
  626. Frules: null
  627. }
  628. },
  629. components: {
  630. pagination
  631. },
  632. created () {
  633. // 判断是否带缓存参数
  634. if (this.$route.query.search) {
  635. this.Fsearch = this.$route.query.search;
  636. }
  637. if (this.$route.query.rules) {
  638. this.Frules = this.$route.query.rules
  639. }
  640. },
  641. /** <el-option label="已开启缴费"
  642. value="1"></el-option>
  643. <el-option label="未缴费"
  644. value="0"></el-option>
  645. <el-option label="已缴费"
  646. value="2"></el-option> */
  647. filters: {
  648. studentPays (val) {
  649. let template = {
  650. 'PAID_COMPLETED': "完成缴费",
  651. 'NON_PAYMENT': "未缴费",
  652. 'PROCESSING': "缴费中"
  653. }
  654. return template[val]
  655. }
  656. },
  657. mounted () {
  658. // 获取汇总数据
  659. getTeamStudentInfo({ musicGroupId: this.teamid }).then(res => {
  660. if (res.code == 200) {
  661. this.studentListInfo = res.data;
  662. }
  663. });
  664. this.getList();
  665. // 获取乐团内所有声部
  666. findSound({ musicGroupId: this.teamid }).then(res => {
  667. if (res.code == 200) {
  668. this.soundList = res.data;
  669. }
  670. })
  671. // getSubject().then(res => {
  672. // if (res.code == 200) {
  673. // this.soundList = res.data;
  674. // }
  675. // })
  676. // 获取乐团所有单技课班
  677. // getSingleClass({ musicGroupId: this.teamid }).then(res => {
  678. // if (res.code == 200) {
  679. // this.signList = res.data;
  680. // }
  681. // })
  682. // 获取乐团所有合奏课
  683. getMusicGroupAllClass({ musicGroupId: this.teamid }).then(res => {
  684. if (res.code == 200) {
  685. res.data.forEach(item => {
  686. if (item.type == 'NORMAL') {
  687. this.signList.push(item);
  688. } else if (item.type == 'MIX') {
  689. this.mixList.push(item);
  690. } else if (item.type == 'HIGH') {
  691. this.highList.push(item)
  692. } else if (item.type == 'SNAP') {
  693. this.snapList.push(item);
  694. }
  695. })
  696. }
  697. })
  698. },
  699. methods: {
  700. onMusicGroupExport () {
  701. let url = '/api-web/export/musicGroupStudent'
  702. let data = {
  703. musicGroupId: this.teamid,
  704. studentStatus: this.searchForm.studentStatus || null,
  705. paymentStatus: this.searchForm.isPay || null,
  706. subjectId: this.searchForm.major || null,
  707. search: this.searchForm.search || null,
  708. isActive: this.searchForm.isActive
  709. }
  710. const options = {
  711. method: 'get',
  712. headers: {
  713. 'Authorization': getToken()
  714. },
  715. url,
  716. params: data,
  717. responseType: 'blob'
  718. }
  719. this.$confirm('您确定导出学员列表?', '提示', {
  720. confirmButtonText: '确定',
  721. cancelButtonText: '取消',
  722. type: 'warning'
  723. }).then(() => {
  724. axios(options).then(res => {
  725. let blob = new Blob([res.data], {
  726. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
  727. type: 'application/vnd.ms-excel;charset=utf-8'
  728. // word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  729. })
  730. let objectUrl = URL.createObjectURL(blob)
  731. let link = document.createElement("a")
  732. let fname = this.$route.query.name + '学员列表'
  733. link.href = objectUrl
  734. link.setAttribute("download", fname)
  735. document.body.appendChild(link)
  736. link.click()
  737. })
  738. }).catch(() => { })
  739. },
  740. search () {
  741. this.rules.page = 1;
  742. this.getList()
  743. },
  744. onCreateQRCode () { // 生成报名二维码
  745. this.qrcodeStatus = true
  746. let id = this.$route.query.id
  747. if (this.qrcodes) {
  748. this.qrcodes = false
  749. setTimeout(() => {
  750. this.qrcode = new QRCode('qrcode', {
  751. width: 200,
  752. height: 200,
  753. colorDark: '#000000',
  754. colorLight: '#ffffff',
  755. correctLevel: QRCode.CorrectLevel.H
  756. })
  757. this.qrcode.makeCode(vaildStudentUrl() + '/#/login?musicGroupId=' + id)
  758. this.codeUrl = vaildStudentUrl() + '/#/login?musicGroupId=' + id
  759. }, 500)
  760. }
  761. },
  762. getList () {
  763. let obj = {
  764. musicGroupId: this.teamid,
  765. page: this.rules.page,
  766. rows: this.rules.limit,
  767. studentStatus: this.searchForm.studentStatus || null,
  768. paymentStatus: this.searchForm.isPay || null,
  769. subjectId: this.searchForm.major || null,
  770. search: this.searchForm.search || null,
  771. isActive: this.searchForm.isActive
  772. }
  773. getTeamStudentList(obj).then(res => {
  774. if (res.code == 200) {
  775. this.tableList = res.data.rows;
  776. this.rules.total = res.data.total
  777. }
  778. })
  779. },
  780. gotoSignin () {
  781. this.$router.push({
  782. path: '/business/studentSignin',
  783. query: {
  784. id: this.teamid,
  785. status: this.$route.query.status,
  786. name: this.$route.query.name
  787. }
  788. })
  789. },
  790. chioseType () {
  791. let row = this.activeRow;
  792. /**
  793. * quitForm: { // 退团信息确认
  794. isRefundCourseFee: null,
  795. isRefundInstrumentFee: null,
  796. isRefundTeachingAssistantsFee: null,
  797. reason: ''
  798. },
  799. *
  800. */
  801. // 发请求 退团
  802. StudentQuit({ musicGroupId: this.teamid, userId: row.userId,
  803. reason: this.quitForm.reason,
  804. isRefundCourseFee: this.quitForm.isRefundCourseFee,
  805. isRefundInstrumentFee: this.quitForm.isRefundInstrumentFee,
  806. isRefundTeachingAssistantsFee: this.quitForm.isRefundTeachingAssistantsFee }).then(res => {
  807. this.quitForm = { // 退团信息确认
  808. isRefundCourseFee: null,
  809. isRefundInstrumentFee: null,
  810. isRefundTeachingAssistantsFee: null,
  811. reason: ''
  812. }
  813. if (res.code == 200) {
  814. this.$message.success('退团成功')
  815. this.getList();
  816. this.quitVisible = false;
  817. }
  818. })
  819. // row.typeVisible = false;
  820. },
  821. //
  822. addStudent () {
  823. // 发请求添加学员
  824. this.$refs['maskForm'].validate(res => {
  825. if (res) {
  826. // this.maskForm.parentName.timer 少个生日的字段
  827. // classGroupId: maskForm.signClass
  828. /** <!-- signClass: '',
  829. mixClass: '',
  830. highClass: '',
  831. snapClass: [], --> */
  832. let maskForm = this.maskForm
  833. if (!maskForm.signClass && !maskForm.mixClass && !maskForm.highClass) {
  834. if (!maskForm.snapClass || maskForm.snapClass.length < 1) {
  835. this.$message.error('该学生必须加入一个班级')
  836. return;
  837. }
  838. }
  839. let snapClassIds;
  840. maskForm.snapClass.length > 0 ? snapClassIds = maskForm.snapClass.join(',') : snapClassIds = null
  841. let params = {
  842. signClassId: maskForm.signClass,
  843. mixClassId: maskForm.mixClass,
  844. snapClassIds,
  845. highClassId: maskForm.highClass,
  846. courseFee: maskForm.courseFee,
  847. temporaryCourseFee: maskForm.temporaryCourseFee,
  848. studentRegistration: {
  849. name: maskForm.studentName,
  850. gender: maskForm.sex,
  851. birthdate: maskForm.timer,
  852. parentsName: maskForm.parentName,
  853. parentsPhone: maskForm.phone,
  854. currentGrade: maskForm.startClass,
  855. currentClass: maskForm.course,
  856. subjectId: maskForm.sound,
  857. musicGroupId: this.teamid,
  858. }
  859. }
  860. params.studentPaymentOrderDetails = []
  861. if (maskForm.musicGoodsIdList) {
  862. params.studentPaymentOrderDetails.push({
  863. goodsIdList: maskForm.musicGoodsIdList,
  864. type: 'MUSICAL',
  865. price: maskForm.musicPrice
  866. })
  867. }
  868. if (maskForm.instrGoodsIdList && maskForm.instrGoodsIdList != '') {
  869. params.studentPaymentOrderDetails.push({
  870. goodsIdList: maskForm.instrGoodsIdList.join(','),
  871. type: 'ACCESSORIES',
  872. price: maskForm.instrPrice
  873. })
  874. }
  875. addStudent(params).then(res => {
  876. if (res.code == 200) {
  877. this.$message.success('添加学生成功');
  878. this.getList()
  879. this.addStudentVisible = false
  880. }
  881. this.$refs.maskForm.resetFields()
  882. })
  883. }
  884. })
  885. },
  886. onSoundChange (value) { // 学员声部切换时
  887. this.findSubjectPlan(value)
  888. this.getGoodsList(value, 'INSTRUMENT') // 乐器
  889. this.getGoodsList(value, 'ACCESSORIES') // 辅件
  890. },
  891. // 获取购买方式
  892. findSubjectPlan (subjectId) {
  893. findSubjectPlan({
  894. musicGroupId: this.teamid,
  895. subjectId: subjectId
  896. }).then(res => {
  897. let result = res.data
  898. if (res.code == 200) {
  899. this.maskForm.musicMode = this.getBranchType(result.kitGroupPurchaseType)
  900. }
  901. })
  902. },
  903. getGoodsList (subjectId, type) {
  904. getGoods({
  905. subjectId: subjectId,
  906. type: type
  907. }).then(res => {
  908. let result = res.data
  909. if (res.code == 200) {
  910. let tempArr = []
  911. result.forEach(item => {
  912. tempArr.push({
  913. label: item.name,
  914. value: item.id
  915. })
  916. })
  917. if (type == 'ACCESSORIES') {
  918. this.ACCESSORIESLIST = tempArr
  919. }
  920. if (type == 'INSTRUMENT') {
  921. this.INSTRUMENTLIST = tempArr
  922. }
  923. }
  924. })
  925. },
  926. getBranchType (status) {
  927. let common = {
  928. FREE: "免费",
  929. GROUP: "团购",
  930. LEASE: "租赁"
  931. }
  932. return common[status]
  933. },
  934. lookClass (row) {
  935. this.classMask.studentName = row.realName;
  936. getStudentClass({
  937. musicGroupId: this.teamid,
  938. teacherId: row.userId
  939. }).then(res => {
  940. if (res.code == 200) {
  941. this.classList = res.data;
  942. this.studentClassVisible = true;
  943. }
  944. })
  945. },
  946. quieTeamMask (row) {
  947. this.activeRow = row;
  948. this.quitVisible = true;
  949. },
  950. checkPhone (val) {
  951. var regu = /^1[3456789]\d{9}$/;
  952. var re = new RegExp(regu);
  953. if (re.test(val)) {
  954. getStudentInfoByPhone({ mobile: this.maskForm.phone }).then(res => {
  955. if (res.code == 200) {
  956. if (res.data) {
  957. this.maskForm = {
  958. studentName: res.data.name,
  959. sex: res.data.gender,
  960. parentName: res.data.parentsName,
  961. course: res.data.currentClass,
  962. startClass: res.data.currentGrade,
  963. // sound: parseInt(res.data.subjectId),
  964. phone: val,
  965. timer: res.data.birthdate
  966. }
  967. /**
  968. * name: maskForm.studentName,
  969. gender: maskForm.sex,
  970. parentsName: maskForm.parentName,
  971. parentsPhone: maskForm.phone,
  972. currentGrade: maskForm.startClass,
  973. currentClass: maskForm.course,
  974. subjectId: maskForm.sound,
  975. musicGroupId: this.teamid,
  976. */
  977. /**
  978. maskForm: {
  979. studentName: '',
  980. sex: '',
  981. parentName: '',
  982. course: '',
  983. phone: '',
  984. sound: '',
  985. timer: '',
  986. signClass: '',
  987. // price: '',
  988. startClass: '',
  989. id: '',
  990. courseFee: null, // 声部费用
  991. temporaryCourseFee: null, // 本次课程费用
  992. musicGoodsIdList: null, // 乐器商品编号
  993. musicMode: null, // 乐器购买方式
  994. musicPrice: null, // 乐器购买金额
  995. instrGoodsIdList: [], // 辅件商品编号
  996. instrPrice: null // 辅件购买金额
  997. },
  998. *
  999. */
  1000. }
  1001. }
  1002. })
  1003. }
  1004. }
  1005. }
  1006. }
  1007. </script>
  1008. <style lang="scss" scoped>
  1009. // .moreInput {
  1010. // width: 100%;
  1011. // display: flex;
  1012. // /deep/.el-form-item__content {
  1013. // display: flex;
  1014. // flex-direction: row;
  1015. // }
  1016. // }
  1017. .el-select {
  1018. width: 180px !important;
  1019. }
  1020. .headWrap {
  1021. padding: 20px 0;
  1022. }
  1023. /deep/.el-date-editor.el-input {
  1024. width: auto;
  1025. .el-input__inner {
  1026. padding-right: 0;
  1027. }
  1028. }
  1029. .studentInfo {
  1030. /deep/.el-dialog__body {
  1031. padding-top: 0;
  1032. padding-bottom: 0;
  1033. }
  1034. }
  1035. // .instrList {
  1036. // display: flex;
  1037. // /deep/.el-form-item__content {
  1038. // width: 80%;
  1039. // }
  1040. // .el-col {
  1041. // /deep/.el-form-item__content {
  1042. // width: 100%;
  1043. // }
  1044. // }
  1045. // }
  1046. .stu-container {
  1047. .topFrom {
  1048. margin: 20px 30px 0;
  1049. width: 1000px;
  1050. }
  1051. .newStudent {
  1052. width: 121px;
  1053. height: 40px;
  1054. background: rgba(20, 146, 138, 1);
  1055. border-radius: 4px;
  1056. color: #fff;
  1057. text-align: center;
  1058. line-height: 40px;
  1059. font-size: 14px;
  1060. cursor: pointer;
  1061. }
  1062. }
  1063. .left-code,
  1064. .right-code {
  1065. // width: 50%;
  1066. // float: left;
  1067. h2 {
  1068. display: block;
  1069. font-size: 18px;
  1070. text-align: center;
  1071. padding-bottom: 8px;
  1072. line-height: 1;
  1073. height: 30px;
  1074. margin-bottom: 0;
  1075. }
  1076. .qrcode {
  1077. display: flex;
  1078. justify-content: center;
  1079. img {
  1080. width: 200px;
  1081. height: 200px;
  1082. // margin: 0 auto;
  1083. }
  1084. }
  1085. .code-url {
  1086. font-size: 18px;
  1087. text-align: center;
  1088. padding: 15px 15px 0 15px;
  1089. }
  1090. }
  1091. .export {
  1092. background: #14928a;
  1093. }
  1094. </style>