signupList.vue 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342
  1. <template>
  2. <div class="sigup-container">
  3. <div class="topWrap">
  4. <div>
  5. <h2>
  6. <el-page-header @back="onCancel"
  7. :content="teamName + '报名详情'">
  8. </el-page-header>
  9. </h2>
  10. <p style="margin-bottom:15px; font-size:18px;
  11. font-weight:400">报名缴费截止时间:{{ applyExpireDate | formatTimer }}</p>
  12. <div class="btnList">
  13. <div class='newBand close'
  14. v-permission="'musicGroup/cancelMusicGroup'"
  15. @click="onClose">停止乐团</div>
  16. <div class='newBand'
  17. @click="payStart"
  18. v-permission="'musicGroup/openPay'"
  19. v-if="status=='APPLY'">开始缴费</div>
  20. <!-- v-if="status=='PAY'" -->
  21. <div class='newBand'
  22. v-permission="'musicGroup/found'"
  23. @click="onGoHome">确认开团</div>
  24. <div class='newBand'
  25. v-permission="'musicGroup/extensionPayment'"
  26. @click="extendPaymentStatus = true"
  27. v-if="status=='PAY'">延长缴费</div>
  28. <div class='newBand'
  29. @click="onCreateQRCode">报名链接</div>
  30. <div class='newBand'
  31. @click="onCreateQRCode2">缴费详情</div>
  32. <div class='newBand'
  33. v-if="rightList.length > 0"
  34. v-permission="'studentRegistration/queryStudentApplyDetailExport'"
  35. @click='onDownLoadExecl'>报表导出</div>
  36. </div>
  37. </div>
  38. <!-- stepImgs: {
  39. APPLY: require('@/assets/images/base/clock.png'),
  40. PAY: require('@/assets/images/base/pay.png')
  41. }, -->
  42. <p class='msg'
  43. :class="status=='PAY'? 'pay' : '' "> <img :src="status=='APPLY'?stepImgs.APPLY:stepImgs.PAY"
  44. alt="">
  45. {{ status=='APPLY'?'报名中':'缴费中' }}</p>
  46. </div>
  47. <div class="searchList">
  48. <el-form :inline="true"
  49. :model="searchFrom">
  50. <el-form-item label="专业">
  51. <el-select v-model.trim="searchFrom.subject"
  52. filterable
  53. clearable>
  54. <el-option v-for="(item,index) in soundList"
  55. :key='index'
  56. :label="item.name"
  57. :value="item.id"></el-option>
  58. </el-select>
  59. </el-form-item>
  60. <el-form-item label="是否允许调剂">
  61. <el-select v-model.trim="searchFrom.isAllowAdjust"
  62. filterable
  63. clearable>
  64. <el-option label="是"
  65. value="1"></el-option>
  66. <el-option label="否"
  67. value="0"></el-option>
  68. </el-select>
  69. </el-form-item>
  70. <el-form-item label="用户名或手机号">
  71. <el-input v-model.trim="searchFrom.name"></el-input>
  72. </el-form-item>
  73. <!-- 专业actualSubjectId 调剂isAllowAdjust 手机号name -->
  74. <el-form-item>
  75. <el-button type='danger'
  76. @click='search'>搜索</el-button>
  77. <el-button type='primary'
  78. @click="onReset">重置</el-button>
  79. </el-form-item>
  80. </el-form>
  81. </div>
  82. <div class="sigup-core">
  83. <div class="left">
  84. <el-table :data='leftList'
  85. :header-cell-style="{background:'#EDEEF0',color:'#444'}">
  86. <el-table-column label="乐团声部"
  87. prop="subjectName"
  88. align='center'>
  89. </el-table-column>
  90. <el-table-column label="计划招生"
  91. prop="expectedStudentNum"
  92. align='center'>
  93. <template slot-scope="scope">
  94. <div>
  95. <p v-if="!isEdit">{{ scope.row.expectedStudentNum }}</p>
  96. <el-input v-if="isEdit"
  97. v-model.trim="scope.row.expectedStudentNum"></el-input>
  98. </div>
  99. </template>
  100. </el-table-column>
  101. <el-table-column label="已报名"
  102. prop='applyStudentNum'
  103. align='center'>
  104. </el-table-column>
  105. <el-table-column label="已缴费"
  106. prop='payNum'
  107. align='center'>
  108. </el-table-column>
  109. </el-table>
  110. <div class="btnWrap"
  111. v-permission="'musicGroup/updateExpectedStudentNum'"
  112. style="margin-right:20px; margin-top:20px;">
  113. <el-button v-if="!isEdit"
  114. @click="isEdit = true">编辑</el-button>
  115. <el-button v-if="isEdit"
  116. @click="saveIsEdit">保存</el-button>
  117. </div>
  118. </div>
  119. <div class="right">
  120. <el-table :data='rightList'
  121. ref="multipleTable"
  122. :header-cell-style="{background:'#EDEEF0',color:'#444'}"
  123. @selection-change="handleSelectionChange">
  124. <el-table-column type="selection"
  125. width="55">
  126. </el-table-column>
  127. <el-table-column label="学员姓名"
  128. prop="studentName"
  129. align='center'>
  130. </el-table-column>
  131. <el-table-column label="家长姓名"
  132. prop="parentsName"
  133. align='center'>
  134. </el-table-column>
  135. <el-table-column label="年级班级"
  136. align='center'>
  137. <template slot-scope="scope">
  138. <div>
  139. {{scope.row.currentGrade+scope.row.currentClass}}
  140. </div>
  141. </template>
  142. </el-table-column>
  143. <el-table-column label="性别"
  144. prop="gender"
  145. align='center'>
  146. <template slot-scope="scope">
  147. <div>
  148. {{scope.row.gender | sex}}
  149. </div>
  150. </template>
  151. </el-table-column>
  152. <el-table-column label="服从调剂"
  153. prop="isAllowAdjust"
  154. align='center'>
  155. <template slot-scope="scope">
  156. <div>
  157. {{ scope.row.isAllowAdjust | isAllowAdjust}}
  158. </div>
  159. </template>
  160. </el-table-column>
  161. <el-table-column label="报名专业"
  162. prop="subjectName"
  163. align='center'>
  164. </el-table-column>
  165. <el-table-column label="调剂专业"
  166. prop="actualSubjectName"
  167. align='center'>
  168. </el-table-column>
  169. <el-table-column label="联系电话"
  170. prop="parentsPhone"
  171. align='center'>
  172. </el-table-column>
  173. <!-- v-if='status == "PAY"' -->
  174. <el-table-column label="学员状态"
  175. fixed='right'
  176. prop="paymentStatus"
  177. align='center'>
  178. <template slot-scope="scope">
  179. <div>
  180. {{ scope.row.paymentStatus | paymentStatus }}
  181. </div>
  182. </template>
  183. </el-table-column>
  184. <el-table-column label="操作"
  185. fixed='right'
  186. width="240"
  187. align='center'>
  188. <template slot-scope="scope">
  189. <div>
  190. <el-button type='text'
  191. v-permission="'studentRegistration/batchUpdateSubject'"
  192. v-if="scope.row.paymentStatus != 2"
  193. @click='resetSubject(scope.row)'>修改专业</el-button>
  194. <!-- APPLY status == "APPLY" || s-->
  195. <el-popover v-if='scope.row.remark'
  196. placement="top-start"
  197. title="备注"
  198. width="200"
  199. trigger="hover"
  200. :content="scope.row.remark">
  201. <el-button type="text"
  202. slot="reference">备注</el-button>
  203. </el-popover>
  204. <!-- PAY -->
  205. <!-- && status == "PAY"-->
  206. <el-button type='text'
  207. v-permission="'studentRegistration/queryFeeDetail'"
  208. v-if='scope.row.paymentStatus==2'
  209. @click='lookdetail(scope.row)'>查看</el-button>
  210. <el-button type='text'
  211. v-permission="'studentRegistration/queryFeeDetail'"
  212. v-if='scope.row.paymentStatus==2'
  213. @click='quitTeam(scope.row)'>退团</el-button>
  214. <el-button type="text"
  215. v-if="permission('visit/add')"
  216. @click="addVisit(scope.row)">新增回访</el-button>
  217. <el-button type="text"
  218. v-if="scope.row.paymentStatus==2"
  219. v-permission="'subjectChange/getStudentOriginal'"
  220. @click="openChangeVoice(scope.row)">更改声部</el-button>
  221. </div>
  222. </template>
  223. </el-table-column>
  224. </el-table>
  225. <div style="margin-top: 10px; margin-bottom: 10px;"
  226. v-if="status=='APPLY'">
  227. <el-button @click="onSelectAll">全选/取消</el-button>
  228. <el-button style="background-color: #14928a;border: 1px solid #14928a;"
  229. @click="onPartPayment"
  230. v-permission="'studentRegistration/openPayment'"
  231. type="primary">提前缴费</el-button>
  232. <!-- <div class='newBand' v-if="status=='APPLY'">允许缴费</div> -->
  233. </div>
  234. <pagination :total="rules.total"
  235. :page.sync="rules.page"
  236. :limit.sync="rules.limit"
  237. :page-sizes="rules.page_size"
  238. @pagination="getList" />
  239. </div>
  240. </div>
  241. <el-dialog title="修改专业"
  242. :visible.sync="subjectVisible"
  243. width="400px">
  244. <el-form :model="maskForm">
  245. <el-form-item label="选择专业">
  246. <el-select v-model.trim="maskForm.subject"
  247. filterable
  248. clearable>
  249. <el-option v-for="(item,index) in soundList"
  250. :key='index'
  251. :label="item.name"
  252. :value="item.id"></el-option>
  253. </el-select>
  254. </el-form-item>
  255. </el-form>
  256. <div slot="footer"
  257. class="dialog-footer">
  258. <el-button @click="subjectVisible = false">取 消</el-button>
  259. <el-button type="primary"
  260. @click="okReset">确 定</el-button>
  261. </div>
  262. </el-dialog>
  263. <el-dialog title="延长缴费"
  264. :visible.sync="extendPaymentStatus"
  265. width="400px">
  266. <el-form :model="extendForm"
  267. ref="extendForm"
  268. :rules="extendRule">
  269. <el-form-item label="延长时间"
  270. prop="expireDate">
  271. <el-date-picker v-model.trim="extendForm.expireDate"
  272. value-format="yyyy-MM-dd"
  273. type="date"
  274. :picker-options="{
  275. firstDayOfWeek:1
  276. }"
  277. placeholder="选择日期">
  278. </el-date-picker>
  279. </el-form-item>
  280. </el-form>
  281. <div slot="footer"
  282. class="dialog-footer">
  283. <el-button @click="extendPaymentStatus = false">取 消</el-button>
  284. <el-button type="primary"
  285. @click="onExtendPayment('extendForm')">确 定</el-button>
  286. </div>
  287. </el-dialog>
  288. <el-dialog title="订单详情"
  289. :visible.sync="orderVisible"
  290. width="600px">
  291. <el-form :model="orderForm"
  292. :inline="true">
  293. <!-- name: '',
  294. totalAmount: '',
  295. subject: '',
  296. subjectFee: '',
  297. axe: '',
  298. axePrice: '',
  299. others: '',
  300. othersPrice: '' -->
  301. <el-form-item label="学员姓名">
  302. <el-input v-model.trim="orderForm.name"
  303. disabled=""></el-input>
  304. </el-form-item>
  305. <el-form-item label="实缴金额">
  306. <el-input v-model.trim="orderForm.totalAmount"
  307. disabled=""></el-input>
  308. </el-form-item>
  309. <el-form-item label="实际专业">
  310. <el-input v-model.trim="orderForm.subject"
  311. disabled=""></el-input>
  312. </el-form-item>
  313. <el-form-item label="课程费用">
  314. <el-input v-model.trim="orderForm.subjectFee"
  315. disabled=""></el-input>
  316. </el-form-item>
  317. <el-form-item label="选择乐器">
  318. <el-input v-model.trim="orderForm.axe"
  319. disabled=""></el-input>
  320. </el-form-item>
  321. <el-form-item label="乐器价格">
  322. <el-input v-model.trim="orderForm.axePrice"
  323. disabled=""></el-input>
  324. </el-form-item>
  325. <el-form-item label="教辅组合">
  326. <el-input v-model.trim="orderForm.others"
  327. disabled=""></el-input>
  328. </el-form-item>
  329. <el-form-item label="组合价格">
  330. <el-input v-model.trim="orderForm.othersPrice"
  331. disabled=""></el-input>
  332. </el-form-item>
  333. </el-form>
  334. <div slot="footer"
  335. class="dialog-footer">
  336. <!-- <el-button>取 消</el-button> -->
  337. <el-button type="primary"
  338. @click="orderVisible = false">确 定</el-button>
  339. </div>
  340. </el-dialog>
  341. <el-dialog title="开始缴费"
  342. :visible.sync="paymentStatus"
  343. width="400px">
  344. <el-form ref="paymentForm"
  345. class="paymentForm"
  346. :model="paymentForm"
  347. label-position="top"
  348. :rules="paymentRules">
  349. <el-form-item label="请设置缴费截止日期"
  350. prop="paymentExpireDate">
  351. <el-date-picker v-model.trim="paymentForm.paymentExpireDate"
  352. type="date"
  353. value-format="yyyy-MM-dd"
  354. :picker-options="{
  355. firstDayOfWeek:1
  356. }"
  357. style="width: 100%"
  358. placeholder="选择日期">
  359. </el-date-picker>
  360. </el-form-item>
  361. <!-- <el-form-item label="是否排乐团网管课"
  362. :rules="[{ required: true, message: '请选择是否排乐团网管课'}]"
  363. prop="feeType">
  364. <el-select v-model="paymentForm.feeType"
  365. style="width: 100%!imoprtant">
  366. <el-option label="需要排线上课"
  367. value="ONLINE"></el-option>
  368. <el-option label="只排线下课"
  369. value="OFFLINE"></el-option>
  370. </el-select>
  371. </el-form-item> -->
  372. </el-form>
  373. <div slot="footer"
  374. class="dialog-footer">
  375. <el-button @click="paymentStatus = false">取 消</el-button>
  376. <el-button type="primary"
  377. @click="onStartPayment('paymentForm')">确 定</el-button>
  378. </div>
  379. </el-dialog>
  380. <el-dialog title="报名二维码"
  381. :visible.sync="qrcodeStatus"
  382. width="300px">
  383. <div class="left-code">
  384. <h2>学员报名连接</h2>
  385. <div id="qrcode"
  386. class="qrcode code"
  387. ref="qrCodeUrl"></div>
  388. <p class="code-url"
  389. v-if="codeUrl">{{ codeUrl }}</p>
  390. </div>
  391. </el-dialog>
  392. <el-dialog title="缴费详情二维码"
  393. :visible.sync="qrcodeStatus2"
  394. width="300px">
  395. <div class="right-code">
  396. <h2>报名缴费详情</h2>
  397. <div id="qrcode2"
  398. class="qrcode code"
  399. ref="qrCodeUrl"></div>
  400. <p class="code-url"
  401. v-if="codeUrl2">{{ codeUrl2 }}</p>
  402. </div>
  403. </el-dialog>
  404. <!-- 退团弹窗 -->
  405. <el-dialog title="退团信息确认"
  406. :destroy-on-close="true"
  407. width="640px"
  408. :visible.sync="quitVisible">
  409. <el-form :model="quitForm"
  410. ref="quitForm"
  411. :rules="quitRules">
  412. <el-form-item label="退还课程费用"
  413. prop="isRefundCourseFee">
  414. <el-radio v-model.trim="quitForm.isRefundCourseFee"
  415. :label="true">是</el-radio>
  416. <el-radio v-model.trim="quitForm.isRefundCourseFee"
  417. :label="false">否</el-radio>
  418. </el-form-item>
  419. <el-form-item label="退还乐器费用"
  420. prop="isRefundInstrumentFee">
  421. <el-radio v-model.trim="quitForm.isRefundInstrumentFee"
  422. :label="true">是</el-radio>
  423. <el-radio v-model.trim="quitForm.isRefundInstrumentFee"
  424. :label="false">否</el-radio>
  425. </el-form-item>
  426. <el-form-item label="退还教辅费用"
  427. prop="isRefundTeachingAssistantsFee">
  428. <el-radio v-model.trim="quitForm.isRefundTeachingAssistantsFee"
  429. :label="true">是</el-radio>
  430. <el-radio v-model.trim="quitForm.isRefundTeachingAssistantsFee"
  431. :label="false">否</el-radio>
  432. </el-form-item>
  433. <el-form-item label="退团原因">
  434. <el-input type="textarea"
  435. v-model.trim="quitForm.reason"></el-input>
  436. </el-form-item>
  437. </el-form>
  438. <span slot="footer"
  439. class="dialog-footer">
  440. <el-button @click="quitVisible = false">取 消</el-button>
  441. <el-button type="primary"
  442. @click="chioseType">确 定</el-button>
  443. </span>
  444. </el-dialog>
  445. <!-- 回访记录 -->
  446. <el-dialog title="新增回访"
  447. width="600px"
  448. destroy-on-close
  449. :close-on-click-modal='false'
  450. :visible.sync="visitVisiable">
  451. <el-form :model="visitForm"
  452. label-width="120px"
  453. label-position='right'
  454. ref='visitForm'
  455. :rules="visitRules">
  456. <el-form-item label="学生姓名">
  457. <p>{{visitForm.studentName}}</p>
  458. </el-form-item>
  459. <el-form-item label="回访类型"
  460. prop='visitType'>
  461. <el-cascader expand-trigger="hover"
  462. clearable
  463. placeholder="请选择回访类型"
  464. :options="visitChiose"
  465. @change="handleChange"
  466. style="width:220px!important;"
  467. v-model="visitForm.visitType">
  468. </el-cascader>
  469. </el-form-item>
  470. <el-form-item label="回访日期"
  471. prop='visitTime'>
  472. <el-date-picker v-model.trim="visitForm.visitTime"
  473. align="right"
  474. style="width:220px!important;"
  475. type="date"
  476. placeholder="选择日期"
  477. :picker-options="pickerOptions"
  478. value-format="yyyy-MM-dd"></el-date-picker>
  479. </el-form-item>
  480. <el-form-item label="学员情况"
  481. prop="overview">
  482. <el-input type="textarea"
  483. v-model="visitForm.overview"
  484. style="width:80%!important;"
  485. :rows="3"
  486. maxlength="50"
  487. show-word-limit></el-input>
  488. </el-form-item>
  489. <el-form-item label="家长反馈"
  490. prop='feedback'>
  491. <el-input type="textarea"
  492. v-model="visitForm.feedback"
  493. style="width:80%!important;"
  494. :rows="3"
  495. maxlength="50"
  496. show-word-limit></el-input>
  497. </el-form-item>
  498. </el-form>
  499. <span slot="footer"
  500. class="dialog-footer">
  501. <el-button @click="visitVisiable = false">取 消</el-button>
  502. <el-button type="primary"
  503. @click="submitAddVisit">确 定</el-button>
  504. </span>
  505. </el-dialog>
  506. <el-dialog
  507. title="更改声部"
  508. :visible.sync="changeVoiceVisible"
  509. @close="closeChangeVoice"
  510. :destroy-on-close="true"
  511. width="500px"
  512. >
  513. <changeVoice
  514. @close="closeChangeVoice"
  515. @submited="closeChangeVoice"
  516. :detail.sync="rowDetail"
  517. :musicGroupId="id"
  518. :voiceList="leftList"
  519. />
  520. </el-dialog>
  521. </div>
  522. </template>
  523. <script>
  524. import pagination from '@/components/Pagination/index'
  525. import { getintoClass, getStudentList, findSound, musicGroupOpenPay, openPayment, musicGroupFound, extensionPayment, resetPlanNum, cancelMusicGroup, getTeamBaseInfo, studentApplyDetailExport, StudentQuit } from '@/api/buildTeam'
  526. import { resetStudentSubject, getStudentFeeDetail } from '@/api/studentManager'
  527. import { vaildStudentUrl, vaildTeacherUrl } from '@/utils/validate'
  528. import { addVisit } from "@/views/returnVisitManager/api.js"
  529. import QRCode from 'qrcodejs2'
  530. import { visitChiose } from '@/utils/searchArray'
  531. import axios from 'axios'
  532. import { getToken } from '@/utils/auth'
  533. import load from '@/utils/loading'
  534. import qs from 'qs'
  535. import { permission } from "@/utils/directivePage";
  536. import cleanDeep from 'clean-deep'
  537. import changeVoice from './modals/change-voice'
  538. export default {
  539. name: 'signupList',
  540. components: {
  541. pagination,
  542. changeVoice,
  543. },
  544. data () {
  545. return {
  546. multipleSelection: [], //
  547. isEdit: false,
  548. rowDetail: null,
  549. changeVoiceVisible: false,
  550. subjectVisible: false,
  551. orderVisible: false,
  552. quitVisible: false,
  553. leftList: [],
  554. rightList: [],
  555. searchFrom: {
  556. name: '',
  557. subject: '', // 专业
  558. isAllowAdjust: '' // 是否允许调剂
  559. },
  560. quitForm: {
  561. // 退团信息确认
  562. isRefundCourseFee: null,
  563. isRefundInstrumentFee: null,
  564. isRefundTeachingAssistantsFee: null,
  565. reason: ""
  566. },
  567. stepImgs: {
  568. APPLY: require('@/assets/images/base/clock.png'),
  569. PAY: require('@/assets/images/base/pay.png')
  570. },
  571. status: '',
  572. id: '',
  573. rules: {
  574. // 分页规则
  575. limit: 10, // 限制显示条数
  576. page: 1, // 当前页
  577. total: 0, // 总条数
  578. page_size: [10, 20, 30, 40] // 选择限制显示条数
  579. },
  580. teamName: '',
  581. maskForm: {
  582. subject: ''
  583. },
  584. activeId: '',
  585. soundList: [],
  586. orderForm: {
  587. name: '',
  588. totalAmount: '',
  589. subject: '',
  590. subjectFee: '',
  591. axe: '',
  592. axePrice: '',
  593. others: '',
  594. othersPrice: ''
  595. },
  596. paymentStatus: false,
  597. paymentForm: {
  598. paymentExpireDate: null,
  599. // feeType: null
  600. },
  601. paymentRules: {
  602. paymentExpireDate: [{ required: true, message: '请设置缴费截止日期', trigger: 'blur' }]
  603. },
  604. paymentNum: 0, // 缴费了多少人
  605. qrcodeStatus: false, // 生成二维码
  606. qrcodes: true,
  607. qrcode: null,
  608. codeUrl: null,
  609. qrcodeStatus2: false, // 生成二维码
  610. qrcodes2: true,
  611. qrcode2: null,
  612. codeUrl2: null,
  613. extendPaymentStatus: false,
  614. extendForm: {
  615. expireDate: null,
  616. },
  617. extendRule: {
  618. expireDate: [{ required: true, message: '请选择延长时间', trigger: 'change' }]
  619. },
  620. quitRules: {
  621. isRefundCourseFee: [
  622. { required: true, message: "请选择是否退还课程费用" }
  623. ],
  624. isRefundInstrumentFee: [
  625. { required: true, message: "选择是否退还乐器费用" }
  626. ],
  627. isRefundTeachingAssistantsFee: [
  628. { required: true, message: "选择是否退还教辅费用" }
  629. ]
  630. },
  631. Fsearch: null,
  632. Frules: null,
  633. applyExpireDate: '',
  634. activeRow: null,
  635. visitVisiable: false,
  636. visitForm: {
  637. musicGroupId: '',
  638. overview: '',
  639. purpose: '',
  640. studentId: '',
  641. type: '',
  642. visitTime: '',
  643. visitType: '',
  644. feedback: '',
  645. studentName: ''
  646. },
  647. visitChiose,
  648. visitRules: {
  649. overview: [{ required: true, message: "请输入学生近况" }],
  650. feedback: [{ required: true, message: "请输入家长反馈" }],
  651. visitTime: [{ required: true, message: "请输入回访时间" }],
  652. visitType: [{ required: true, message: "请选择回访类型" }]
  653. }
  654. }
  655. },
  656. created () {
  657. // 通过乐团状态判断显示隐藏的东西
  658. this.init()
  659. },
  660. activated () {
  661. this.init()
  662. },
  663. methods: {
  664. permission (str) {
  665. return permission(str);
  666. },
  667. init () {
  668. this.status = this.$route.query.status;
  669. // 通过乐团id 获取乐团招生状态
  670. this.id = this.$route.query.id;
  671. this.teamName = this.$route.query.name
  672. // 判断是否带缓存参数
  673. if (this.$route.query.search) {
  674. this.Fsearch = this.$route.query.search;
  675. }
  676. if (this.$route.query.rules) {
  677. this.Frules = this.$route.query.rules
  678. }
  679. this.pickerOptions = this.beginDate();
  680. getTeamBaseInfo({ musicGroupId: this.id }).then(res => {
  681. if (res.code == 200) {
  682. this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  683. }
  684. })
  685. // 根据乐团id获乐团声部
  686. findSound({ musicGroupId: this.id }).then(res => {
  687. if (res.code == 200) {
  688. this.soundList = res.data;
  689. }
  690. })
  691. // 通过乐团id获取乐团学生列表
  692. this.getList()
  693. },
  694. search () {
  695. this.rules.page = 1;
  696. this.getList();
  697. },
  698. onReset () {
  699. this.rules.page = 1
  700. this.rules.limit = 10
  701. this.searchFrom = {
  702. name: null,
  703. subject: null, // 专业
  704. isAllowAdjust: null // 是否允许调剂
  705. }
  706. this.getList()
  707. },
  708. onCancel () {
  709. this.$router.push({ path: '/business/teamDetail', query: { search: this.Fsearch, rules: this.Frules } })
  710. },
  711. payStart () {
  712. this.paymentStatus = true;
  713. getTeamBaseInfo({ musicGroupId: this.id }).then(res => {
  714. if (res.code == 200) {
  715. this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  716. }
  717. })
  718. },
  719. getList () {
  720. let obj = {
  721. musicGroupId: this.id,
  722. actualSubjectId: this.searchFrom.subject || null,
  723. isAllowAdjust: this.searchFrom.isAllowAdjust || null,
  724. name: this.searchFrom.name || null,
  725. page: this.rules.page,
  726. rows: this.rules.limit
  727. }
  728. getStudentList(obj).then(res => {
  729. if (res.code == 200) {
  730. res.data.rows.forEach(item => {
  731. // '未开启缴费', '开启缴费', '已缴费'
  732. if (item.paymentStatus == 2) {
  733. this.paymentNum += 1
  734. }
  735. })
  736. this.rightList = res.data.rows
  737. this.rules.total = res.data.total
  738. }
  739. })
  740. // 根据乐团id获取学团情况
  741. getintoClass({ musicGroupId: this.id }).then(res => {
  742. if (res.code == 200) {
  743. this.leftList = res.data;
  744. }
  745. })
  746. },
  747. onStartPayment (formName) { // 开启缴费
  748. this.$refs[formName].validate((valid) => {
  749. if (valid) {
  750. musicGroupOpenPay({
  751. musicGroupId: this.id,
  752. expireDate: this.paymentForm.paymentExpireDate,
  753. // feeType: this.paymentForm.feeType
  754. }).then(res => {
  755. if (res.code == 200) {
  756. this.$message.success('开启成功')
  757. this.paymentStatus = false
  758. this.$router.push({
  759. path: '/business/signupList',
  760. query: {
  761. status: 'PAY',
  762. id: this.$route.query.id,
  763. name: this.$route.query.name
  764. }
  765. })
  766. this.status = 'PAY'
  767. this.getList();
  768. }
  769. })
  770. } else {
  771. return false;
  772. }
  773. })
  774. // this.id
  775. },
  776. onSelectAll () { // 选中全部
  777. this.$refs.multipleTable.toggleAllSelection()
  778. },
  779. onPartPayment () { // 部分缴费
  780. let selection = this.multipleSelection
  781. if (selection.length <= 0) {
  782. this.$message.success('您还没有选择学生')
  783. return false
  784. }
  785. let ids = []
  786. selection.forEach(item => {
  787. ids.push(item.id)
  788. })
  789. this.$confirm(`是否确认提前缴费?`, '提示', {
  790. confirmButtonText: '确定',
  791. cancelButtonText: '取消',
  792. type: 'warning'
  793. }).then(() => {
  794. openPayment({
  795. ids: ids.join(',')
  796. }).then(res => {
  797. if (res.code == 200) {
  798. this.$message.success('开启成功')
  799. this.getList()
  800. } else {
  801. this.$message.error(res.msg)
  802. }
  803. })
  804. }).catch(() => { })
  805. },
  806. onCreateQRCode () { // 生成报名二维码
  807. this.qrcodeStatus = true
  808. let id = this.id
  809. let teamName = this.$route.query.name
  810. setTimeout(() => {
  811. document.getElementById('qrcode').innerHTML = '';
  812. this.qrcode = new QRCode('qrcode', {
  813. width: 200,
  814. height: 200,
  815. colorDark: '#000000',
  816. colorLight: '#ffffff',
  817. correctLevel: QRCode.CorrectLevel.H
  818. })
  819. this.qrcode.makeCode(vaildStudentUrl() + '/#/login?musicGroupId=' + id)
  820. this.codeUrl = vaildStudentUrl() + '/#/login?musicGroupId=' + id
  821. }, 500)
  822. },
  823. onCreateQRCode2 () { // 生成报名二维码
  824. this.qrcodeStatus2 = true
  825. let id = this.id
  826. let teamName = this.$route.query.name
  827. setTimeout(() => {
  828. document.getElementById('qrcode2').innerHTML = '';
  829. this.qrcode2 = new QRCode('qrcode2', {
  830. width: 200,
  831. height: 200,
  832. colorDark: '#000000',
  833. colorLight: '#ffffff',
  834. correctLevel: QRCode.CorrectLevel.H
  835. })
  836. this.qrcode2.makeCode(vaildTeacherUrl() + '/#/order?musicGroupId=' + id + '&musicGroupName=' + teamName)
  837. this.codeUrl2 = vaildTeacherUrl() + '/#/order?musicGroupId=' + id + '&musicGroupName=' + teamName
  838. }, 500)
  839. },
  840. onDownLoadExecl () { // 报表导出
  841. let url = '/api-web/studentRegistration/queryStudentApplyDetailExport'
  842. let data = {
  843. musicGroupId: this.$route.query.id,
  844. page: 1,
  845. rows: 9999
  846. }
  847. const options = {
  848. method: 'POST',
  849. headers: {
  850. 'Authorization': getToken()
  851. },
  852. data: qs.stringify(data),
  853. url,
  854. responseType: 'blob'
  855. }
  856. this.$confirm('您确定导出吗?', '提示', {
  857. confirmButtonText: '确定',
  858. cancelButtonText: '取消',
  859. type: 'warning'
  860. }).then(() => {
  861. load.startLoading()
  862. axios(options).then(res => {
  863. let blob = new Blob([res.data], {
  864. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  865. type: 'application/vnd.ms-excel;charset=utf-8'
  866. //word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  867. })
  868. let text = (new Response(blob)).text()
  869. text.then(res => {
  870. // 判断是否报错
  871. if (res.indexOf('code') != -1) {
  872. let json = JSON.parse(res)
  873. this.$message.error(json.msg)
  874. } else {
  875. let objectUrl = URL.createObjectURL(blob)
  876. let link = document.createElement("a")
  877. let nowTime = new Date()
  878. let ymd = nowTime.getFullYear() + '' + (nowTime.getMonth() + 1) + '' + nowTime.getDate() + '' + nowTime.getHours() + '' + nowTime.getMinutes()
  879. let fname = this.$route.query.id + '-' + ymd //下载文件的名字
  880. link.href = objectUrl
  881. link.setAttribute("download", fname)
  882. document.body.appendChild(link)
  883. link.click()
  884. }
  885. })
  886. load.endLoading();
  887. }).catch(error => {
  888. this.$message.error('导出数据失败,请联系管理员');
  889. load.endLoading();
  890. })
  891. }).catch(() => { })
  892. },
  893. onGoHome () { // 确认开团
  894. // 判断是否有学生缴费
  895. if (this.paymentNum <= 0) {
  896. this.$message.error('当前缴费人数为0,无法开团')
  897. return
  898. }
  899. this.$confirm(`是否确认开团?`, '提示', {
  900. confirmButtonText: '确定',
  901. cancelButtonText: '取消',
  902. type: 'warning'
  903. }).then(() => {
  904. musicGroupFound({
  905. musicGroupId: this.$route.query.id
  906. }).then(res => {
  907. if (res.code == 200) {
  908. this.$message.success('开启成功')
  909. this.$router.push({
  910. path: '/business/teamSeting',
  911. query: {
  912. status: 'PREPARE',
  913. id: this.$route.query.id,
  914. name: this.$route.query.name
  915. }
  916. })
  917. }
  918. })
  919. }).catch(() => {
  920. })
  921. },
  922. onClose () { // 停止乐团
  923. this.$confirm('您确定停止乐团吗?', '提示', {
  924. confirmButtonText: '确定',
  925. cancelButtonText: '取消',
  926. type: 'warning'
  927. }).then(() => {
  928. cancelMusicGroup({
  929. musicGroupId: this.$route.query.id
  930. }).then(res => {
  931. if (res.code == 200) {
  932. this.$message.success('停止成功')
  933. this.$router.push({
  934. path: '/business/teamDetail',
  935. query: { search: this.Fsearch, rules: this.Frules }
  936. })
  937. }
  938. })
  939. }).catch(() => {
  940. })
  941. },
  942. handleSelectionChange (val) {
  943. this.multipleSelection = val;
  944. },
  945. // 修改专业
  946. resetSubject (row) {
  947. this.activeId = row.studentId
  948. this.subjectVisible = true;
  949. // resetStudentSubject().then(res=>{]})
  950. },
  951. // 确认修改
  952. okReset () {
  953. if (!this.maskForm.subject) {
  954. this.$message.error('请选择调剂专业');
  955. return
  956. }
  957. resetStudentSubject({ musicGroupId: this.id, userId: this.activeId, subId: this.maskForm.subject }).then(res => {
  958. if (res.code == 200) {
  959. this.$message.success('修改成功');
  960. this.subjectVisible = false;
  961. this.maskForm.subject = '';
  962. getintoClass({ musicGroupId: this.id }).then(res => {
  963. if (res.code == 200) {
  964. this.leftList = res.data;
  965. }
  966. })
  967. this.getList();
  968. }
  969. })
  970. },
  971. onExtendPayment (formName) {
  972. this.$refs[formName].validate(valid => {
  973. if (valid) {
  974. extensionPayment({
  975. musicGroupId: this.id,
  976. expireDate: this.extendForm.expireDate
  977. }).then(res => {
  978. if (res.code == 200) {
  979. this.$message.success('延长缴费成功')
  980. this.extendPaymentStatus = false
  981. getTeamBaseInfo({ musicGroupId: this.id }).then(res => {
  982. if (res.code == 200) {
  983. this.applyExpireDate = res.data.musicGroup.applyExpireDate;
  984. }
  985. })
  986. } else {
  987. this.$message.error(res.msg);
  988. }
  989. })
  990. }
  991. })
  992. },
  993. lookdetail (row) {
  994. this.orderVisible = true;
  995. this.activeId = row.studentId;
  996. this.orderForm.name = row.studentName;
  997. this.orderForm.subject = row.subjectName;
  998. getStudentFeeDetail({ musicGroupId: this.id, studentId: row.studentId }).then(res => {
  999. if (res.code == 200) {
  1000. if (res.data) {
  1001. this.orderForm.totalAmount = res.data.totalAmount;
  1002. // this.orderForm.subjectFee = res.data.courseFee;
  1003. let goodStr = '';
  1004. let goodPrice = 0;
  1005. let otherStr = '';
  1006. let othersPrice = 0;
  1007. for (let i in res.data.goods) {
  1008. if (res.data.goods[i].goodsType == 'INSTRUMENT') {
  1009. goodStr += res.data.goods[i].goodsName + ',';
  1010. goodPrice += parseFloat(res.data.goods[i].musicalFee);
  1011. // this.orderForm.axe = res.data.goods[i].goodsName;
  1012. // this.orderForm.axePrice = res.data.goods[i].musicalFee;
  1013. } else if (res.data.goods[i].goodsType == 'ACCESSORIES') {
  1014. otherStr += res.data.goods[i].goodsName + ',';
  1015. othersPrice += parseFloat(res.data.goods[i].musicalFee);
  1016. // this.orderForm.others = res.data.goods[i].goodsName;
  1017. // this.orderForm.othersPrice = res.data.goods[i].musicalFee;
  1018. } else if (res.data.goods[i].goodsType == 'COURSE') {
  1019. this.orderForm.subjectFee = res.data.goods[i].musicalFee
  1020. }
  1021. }
  1022. this.orderForm.others = otherStr.substring(0, otherStr.length - 1);
  1023. this.orderForm.othersPrice = othersPrice;
  1024. this.orderForm.axe = goodStr.substring(0, goodStr.length - 1);
  1025. this.orderForm.axePrice = goodPrice;
  1026. }
  1027. }
  1028. })
  1029. },
  1030. saveIsEdit () {
  1031. // 提交数据
  1032. this.isEdit = false;
  1033. resetPlanNum(this.leftList).then(res => {
  1034. })
  1035. },
  1036. quitTeam (row) {
  1037. this.activeRow = row;
  1038. this.quitVisible = true;
  1039. },
  1040. chioseType () {
  1041. this.$refs["quitForm"].validate(res => {
  1042. if (res) {
  1043. this.$confirm("确定退团?", "提示", {
  1044. confirmButtonText: "确定",
  1045. cancelButtonText: "取消",
  1046. type: "warning"
  1047. })
  1048. .then(() => {
  1049. let row = this.activeRow;
  1050. // 发请求 退团
  1051. StudentQuit({
  1052. musicGroupId: this.id,
  1053. userId: row.studentId,
  1054. reason: this.quitForm.reason,
  1055. isRefundCourseFee: this.quitForm.isRefundCourseFee,
  1056. isRefundInstrumentFee: this.quitForm.isRefundInstrumentFee,
  1057. isRefundTeachingAssistantsFee: this.quitForm
  1058. .isRefundTeachingAssistantsFee
  1059. }).then(res => {
  1060. this.quitForm = {
  1061. // 退团信息确认
  1062. isRefundCourseFee: null,
  1063. isRefundInstrumentFee: null,
  1064. isRefundTeachingAssistantsFee: null,
  1065. reason: ""
  1066. };
  1067. if (res.code == 200) {
  1068. this.$message.success("退团成功");
  1069. this.getList();
  1070. this.quitVisible = false;
  1071. }
  1072. });
  1073. })
  1074. .catch(() => { });
  1075. } else {
  1076. }
  1077. });
  1078. // row.typeVisible = false;
  1079. },
  1080. addVisit (row) {
  1081. this.visitForm.studentName = row.studentName;
  1082. this.visitForm.musicGroupId = this.teamid
  1083. this.visitForm.studentId = row.studentId
  1084. this.visitVisiable = true;
  1085. },
  1086. openChangeVoice(row) {
  1087. this.rowDetail = {...row}
  1088. this.changeVoiceVisible = true
  1089. },
  1090. closeChangeVoice() {
  1091. this.changeVoiceVisible = false
  1092. // this.rowDetail = null
  1093. },
  1094. handleChange (val) {
  1095. this.visitForm.type = val[0]
  1096. this.visitForm.purpose = val[1]
  1097. },
  1098. submitAddVisit () {
  1099. this.$refs.visitForm.validate(res => {
  1100. if (res) {
  1101. this.visitForm.visitType = null;
  1102. addVisit(cleanDeep(this.visitForm)).then(res => {
  1103. if (res.code === 200) {
  1104. this.$message.success('新增成功')
  1105. this.visitVisiable = false
  1106. }
  1107. })
  1108. }
  1109. })
  1110. },
  1111. beginDate () {
  1112. let self = this;
  1113. return {
  1114. firstDayOfWeek: 1,
  1115. disabledDate (time) {
  1116. return time.getTime() >= new Date().getTime(); //开始时间不选时,结束时间最大值小于等于当天
  1117. }
  1118. };
  1119. },
  1120. },
  1121. watch: {
  1122. orderVisible (val) {
  1123. if (!val) {
  1124. this.orderForm = {
  1125. name: '',
  1126. totalAmount: '',
  1127. subject: '',
  1128. subjectFee: '',
  1129. axe: '',
  1130. axePrice: '',
  1131. others: '',
  1132. othersPrice: ''
  1133. }
  1134. }
  1135. },
  1136. qrcodeStatus (val) {
  1137. if (!val) {
  1138. this.qrcode.clear()
  1139. }
  1140. },
  1141. qrcodeStatus2 (val) {
  1142. if (!val) {
  1143. this.qrcode2.clear()
  1144. }
  1145. },
  1146. paymentStatus (val) {
  1147. if (!val) {
  1148. this.paymentForm = {
  1149. paymentExpireDate: null,
  1150. // feeType: null
  1151. }
  1152. }
  1153. },
  1154. quitVisible (val) {
  1155. if (!val) {
  1156. this.quitForm = {
  1157. // 退团信息确认
  1158. isRefundCourseFee: null,
  1159. isRefundInstrumentFee: null,
  1160. isRefundTeachingAssistantsFee: null,
  1161. reason: ""
  1162. };
  1163. this.$refs["quitForm"].resetFields();
  1164. }
  1165. },
  1166. visitVisiable (val) {
  1167. if (!val) {
  1168. this.$refs["visitForm"].resetFields();
  1169. }
  1170. }
  1171. }
  1172. }
  1173. </script>
  1174. <style lang="scss" scoped>
  1175. .sigup-container {
  1176. margin-left: 12px;
  1177. .topWrap {
  1178. padding: 18px 58px;
  1179. // height: 136px;
  1180. background-color: #fff;
  1181. display: flex;
  1182. flex-direction: row;
  1183. justify-content: space-between;
  1184. .msg.pay {
  1185. color: #f85043;
  1186. }
  1187. .msg {
  1188. text-align: right;
  1189. color: #f97215;
  1190. font-size: 32px;
  1191. font-weight: bold;
  1192. padding-top: 30px;
  1193. box-sizing: border-box;
  1194. img {
  1195. width: 36px;
  1196. height: 36px;
  1197. position: relative;
  1198. top: 5px;
  1199. margin-right: 8px;
  1200. }
  1201. }
  1202. h2 {
  1203. height: 48px;
  1204. line-height: 48px;
  1205. position: relative;
  1206. // padding-left: 30px;
  1207. font-size: 32px;
  1208. font-weight: 600;
  1209. margin-bottom: 10px;
  1210. display: flex;
  1211. flex-direction: row;
  1212. justify-content: flex-start;
  1213. align-items: center;
  1214. .term {
  1215. height: 32px;
  1216. line-height: 32px;
  1217. border-radius: 24px;
  1218. width: 100px;
  1219. color: #14928a;
  1220. border: 1px solid rgba(20, 146, 138, 1);
  1221. font-size: 14px;
  1222. text-align: center;
  1223. margin-right: 12px;
  1224. &:nth-child(1) {
  1225. margin-left: 47px;
  1226. }
  1227. }
  1228. .term.active {
  1229. color: #fff;
  1230. background-color: #14928a;
  1231. }
  1232. .squrt {
  1233. position: absolute;
  1234. left: -25px;
  1235. top: 8px;
  1236. height: 34px;
  1237. width: 8px;
  1238. background-color: #14928a;
  1239. }
  1240. }
  1241. .btnList {
  1242. display: flex;
  1243. flex-direction: row;
  1244. justify-content: flex-start;
  1245. align-items: center;
  1246. div {
  1247. margin-right: 15px;
  1248. }
  1249. }
  1250. .newBand.close {
  1251. background-color: #777;
  1252. border: 1px solid #777;
  1253. }
  1254. }
  1255. .searchList {
  1256. background-color: #fff;
  1257. padding: 0 58px;
  1258. }
  1259. .sigup-core {
  1260. margin-top: 12px;
  1261. display: flex;
  1262. flex-direction: row;
  1263. justify-content: flex-start;
  1264. .left {
  1265. width: 340px;
  1266. background-color: #fff;
  1267. height: 80vh;
  1268. overflow: auto;
  1269. }
  1270. .right {
  1271. width: calc(100% - 340px);
  1272. margin-left: 12px;
  1273. flex-grow: 1;
  1274. }
  1275. }
  1276. }
  1277. .el-dialog__body {
  1278. overflow: hidden;
  1279. }
  1280. .left-code,
  1281. .right-code {
  1282. // width: 50%;
  1283. // float: left;
  1284. h2 {
  1285. font-size: 18px;
  1286. text-align: center;
  1287. padding-bottom: 8px;
  1288. }
  1289. .qrcode {
  1290. display: flex;
  1291. flex-direction: column;
  1292. align-items: center;
  1293. img {
  1294. width: 200px;
  1295. height: 200px;
  1296. margin: 0 auto;
  1297. }
  1298. }
  1299. .code-url {
  1300. font-size: 18px;
  1301. text-align: center;
  1302. padding: 15px 15px 0 15px;
  1303. }
  1304. }
  1305. .newBand {
  1306. margin-bottom: 0;
  1307. }
  1308. /deep/.el-button--danger {
  1309. background: #f85043;
  1310. }
  1311. .paymentForm {
  1312. /deep/.el-input__inner,
  1313. /deep/.el-input.el-input--suffix {
  1314. width: 360px !important;
  1315. }
  1316. }
  1317. </style>