studentList.vue 47 KB

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