studentList.vue 53 KB

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