studentList.vue 58 KB

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