SignUpLevel.vue 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105
  1. <template>
  2. <div class="signUpLevel">
  3. <!-- <m-header /> -->
  4. <m-step :number="3" />
  5. <div class="title">报考专业</div>
  6. <van-field readonly required @click="onGetSheetList('examSubject')" name="subjectId" label="报考专业" placeholder="请选择" v-model="formText.subjectName" is-link />
  7. <van-field readonly required @click="onGetSheetList('level')" name="levelId" label="专业级别" placeholder="请选择" v-model="formText.levelName" is-link />
  8. <div class="title">报考曲目</div>
  9. <div v-if="form.levelId" class="van-hairline--bottom">
  10. <div class="van-hairline--bottom" v-if="practiceSongIdList" key="practiceNum">
  11. <van-field required readonly v-for="(item, index) in practiceNum" :key="index" :label="`练习曲${numberToCN(index)}名称及作者`" v-model.trim="practiceSelect[index]" @click="onChangePractice('practice', index)" placeholder="请选择" is-link />
  12. </div>
  13. <div class="van-hairline--bottom" v-else key="practiceNum">
  14. <van-field required readonly v-model.trim="practiceSelect[index]" v-for="(item, index) in practiceNum" :key="index" clearable name="code" :label="`练习曲${numberToCN(index)}名称及作者`" >
  15. <template #button>
  16. <span class="codeText" @click="onUploadSong('practiceNum', index)">上传曲目</span>
  17. </template>
  18. </van-field>
  19. </div>
  20. <div v-if="performSongIdList" key="performNum">
  21. <van-field required readonly v-for="(item, index) in performNum" :key="index" :label="`演奏曲${numberToCN(index)}名称及作者`" v-model.trim="performNumSelect[index]" @click="onChangePractice('performNum', index)" placeholder="请选择" is-link />
  22. </div>
  23. <div v-else key="performNum">
  24. <van-field required readonly v-model.trim="performNumSelect[index]" v-for="(item, index) in performNum" :key="index" clearable name="code" :label="`演奏曲${numberToCN(index)}名称及作者`" >
  25. <template #button>
  26. <span class="codeText" @click="onUploadSong('performNum', index)">上传曲目</span>
  27. </template>
  28. </van-field>
  29. </div>
  30. </div>
  31. <!-- <div class="title">上传证书</div> -->
  32. <!-- <van-field readonly clickable name="nation" label="上次考级级别" placeholder="请选择级别" is-link /> -->
  33. <van-field readonly clearable name="code" label="已获最高等级专业证书" >
  34. <template #input>
  35. <van-uploader
  36. name="certificate"
  37. :before-read="beforeRead"
  38. :before-delete="beforeDelete"
  39. :after-read="afterRead"
  40. accept="image/*"
  41. v-model="uploadCertificate"
  42. :max-count="1" />
  43. </template>
  44. </van-field>
  45. <div class="title">乐理知识</div>
  46. <van-field required @click="onGetSheetList('examMusicTheory')" readonly clickable name="nation" label="乐理级别" v-model="formText.examMusicTheoryName" placeholder="请选择乐理级别" is-link />
  47. <!-- <van-field readonly clickable name="nation" label="上次考级级别" placeholder="请选择" is-link /> -->
  48. <!-- 乐理级别为免考 和 专业级别大于2级 -->
  49. <!-- :required="form.examMusicTheoryId == 999 && form.levelId > 2? true : false" -->
  50. <van-field readonly clearable name="code" label="已获最高等级乐理证书" >
  51. <template #input>
  52. <van-uploader
  53. name="certificate2"
  54. :before-read="beforeRead"
  55. :before-delete="beforeDelete"
  56. :after-read="afterRead"
  57. v-model="uploadCertificate2"
  58. accept="image/*"
  59. :max-count="1" />
  60. </template>
  61. </van-field>
  62. <div class="title">指导老师</div>
  63. <van-field name="adviserName" v-model="form.adviserName" label="老师姓名" placeholder="请输入老师姓名" />
  64. <van-field name="adviserPhone" maxlength="11" v-model="form.adviserPhone" label="联系方式" placeholder="请输入联系方式" />
  65. <div class="m-btn-group">
  66. <van-button class="btn_prev" round color="#2DC7AA" @click="onBack" style="background-color: transparent" plain>上一步</van-button>
  67. <van-button round color="#2DC7AA" @click="onSubmit">确认报名</van-button>
  68. </div>
  69. <!-- 报考专业弹窗 -->
  70. <van-popup v-model="sheetForm.sheetStatus" position="bottom">
  71. <van-picker :loading="sheetForm.loading" :default-index="sheetForm.index" :columns="sheetForm.columns" show-toolbar @cancel="sheetForm.sheetStatus = false" @confirm="onSheetConfirm" />
  72. </van-popup>
  73. <!-- 曲目弹窗 -->
  74. <van-popup v-model="sheetSong.status" position="bottom">
  75. <van-picker :default-index="sheetSong.index" :columns="sheetSong.columns" show-toolbar @cancel="sheetSong.status = false" @confirm="onPracticeConfirm" />
  76. </van-popup>
  77. <van-popup class="van-popup-song" v-model="songUpload.songStatus" :close-on-click-overlay="false">
  78. <div class="song-popup">
  79. <div class="title">自定义曲目</div>
  80. <van-field name="songName" v-model="songUpload.name" label="曲名" placeholder="请输入曲名" >
  81. <template #label><i style="color: #ee0a24">*</i>曲名</template>
  82. </van-field>
  83. <van-field name="songAuthor" v-model="songUpload.author" label="作者" placeholder="请输入作者" >
  84. <template #label><i style="color: #ffffff">*</i>作者</template>
  85. </van-field>
  86. <van-field readonly clearable >
  87. <template #input>
  88. <van-uploader
  89. v-if="songUpload.indexName == 'practiceNum'"
  90. :name="songUpload.indexName + '-' + songUpload.index"
  91. :before-read="beforeRead"
  92. :before-delete="beforeDelete"
  93. :after-read="afterRead"
  94. v-model.trim="practiceUpload[songUpload.index]"
  95. multiple
  96. accept="image/*"
  97. :max-count="5" >
  98. </van-uploader>
  99. <van-uploader
  100. v-if="songUpload.indexName == 'performNum'"
  101. :name="songUpload.indexName + '-' + songUpload.index"
  102. :before-read="beforeRead"
  103. :before-delete="beforeDelete"
  104. :after-read="afterRead"
  105. v-model.trim="performNumUpload[songUpload.index]"
  106. multiple
  107. accept="image/*"
  108. :max-count="5" >
  109. </van-uploader>
  110. </template>
  111. </van-field>
  112. <p class="song-popup-tips"><i style="color: #ee0a24">*</i>支持格式:png,jpg,bmp</p>
  113. <div class="popup-group">
  114. <span @click="onSaveCancel">取消</span>
  115. <span class="popup-sure" @click="onSaveUpload">确定</span>
  116. </div>
  117. </div>
  118. </van-popup>
  119. </div>
  120. </template>
  121. <script>
  122. import MStep from '@/components/MStep'
  123. import setLoading from '@/utils/loading'
  124. import { patternPhone } from '@/utils/validateRules'
  125. import { getExamSubjects, getExamSubjectLevel, getExamSubjectSong, uploadFile, getTheoryLevelList, getExamIngOrder, closeOrder } from './SignUpApi'
  126. // import fileUtil from '@/utils/fileUtil'
  127. const levelToCN = {
  128. 1: "壹级",
  129. 2: "贰级",
  130. 3: "叁级",
  131. 4: "肆级",
  132. 5: "伍级",
  133. 6: "陆级",
  134. 7: "柒级",
  135. 8: "捌级",
  136. 9: "玖级",
  137. 10: "拾级",
  138. }
  139. export default {
  140. name: 'signUpLevel',
  141. components: { MStep },
  142. data () {
  143. const examId = localStorage.getItem('examId')
  144. const organId = localStorage.getItem('organId')
  145. const examRegistrationParams = localStorage.getItem("examRegistrationParams") ? JSON.parse(localStorage.getItem("examRegistrationParams")) : null
  146. return {
  147. examId: examId,
  148. organId: organId,
  149. examRegistrationParams: examRegistrationParams,
  150. patternPhone: patternPhone,
  151. sheetForm: { // 上拉弹窗
  152. currentType: null, // 当前选择的类型
  153. sheetStatus: false,
  154. loading: false, // 加载数据
  155. index: 0, // 选中的索引值
  156. columns: []
  157. },
  158. examSubjectList: [], // 报考专业
  159. examSubjectIndex: 0, // 报考专业选择项目索引
  160. levelList: [], // 专业级别
  161. levelIndex: 0, // 专业级别选择项目索引
  162. practiceNum: 0, // 练习曲数量
  163. practiceSongIdList: null,
  164. performNum: 0, // 演奏曲数量
  165. performSongIdList: null,
  166. songList: [], //歌曲数量(包括练习曲和演奏曲)
  167. songUpload: {
  168. songStatus: false, // 曲目状态
  169. indexName: null,
  170. index: null, // 索引
  171. name: null, // 曲名
  172. author: null // 作者
  173. },
  174. form: {
  175. subjectId: null,
  176. levelId: null, // 级别
  177. examSubjectSongId: null, // 级别编号
  178. adviserName: null, // 老师姓名
  179. adviserPhone: null, // 联系电话
  180. lastExamCertificateUrl: null,
  181. lastMusicTheoryCertificateUrl: null,
  182. examMusicTheoryId: null,
  183. examMusicTheoryLevel: null,
  184. levelFee: 0,// 级别费用
  185. theoryLevelFee: 0, // 乐理费用
  186. },
  187. formText: {
  188. subjectName: null,
  189. levelName: null,
  190. examMusicTheoryName: null
  191. },
  192. sheetSong: { // 上拉弹窗
  193. status: false,
  194. index: 0, // 选中的索引值
  195. columns: []
  196. },
  197. practiceSelect: [], // 练习曲循环列表
  198. practiceSelectUploadList: [],
  199. practiceSelectList: [], // 弹窗练习曲列表
  200. practiceSelectIds: [], // 选中练习曲编号
  201. performNumSelect: [], // 演奏曲循环列表
  202. performNumSelectUploadList: [],
  203. performNumSelectList: [], // 弹窗演奏曲列表
  204. performNumSelectIds: [], // 选中演奏曲编号
  205. songSelectIndex: null, // 选中的哪个
  206. uploadCertificate: [], // 上传证书
  207. uploadCertificate2: [], // 上传乐理证书
  208. practiceUpload: [],
  209. practiceUploadTemp: [],
  210. performNumUpload: [],
  211. performNumUploadTemp: [],
  212. examMusicTheoryList: [], // 乐理列表
  213. examMusicTheoryIndex: 0, // 乐理索引
  214. }
  215. },
  216. mounted() {
  217. // 插入token
  218. // let params = this.$route.query
  219. // if(params.Authorization) {
  220. // localStorage.setItem('Authorization', decodeURI(params.Authorization))
  221. // localStorage.setItem('userInfo', decodeURI(params.Authorization))
  222. // }
  223. this.__init()
  224. if(this.examRegistrationParams) {
  225. this.getRegisterInfo(this.examRegistrationParams)
  226. } else {
  227. this.getTheoryLevelList()
  228. }
  229. this.onCheckOrder() // 查询有没有待支付订单
  230. // this.form.levelId = 1
  231. // this.practiceNum = 2
  232. // this.practiceSongIdList = ""
  233. // this.performNum = 2
  234. // this.performSongIdList = ""
  235. // this.getExamSubjectSong()
  236. },
  237. methods: {
  238. async onCheckOrder() {
  239. const order = await getExamIngOrder({ examinationBasicId: this.examId })
  240. const resultOrder = order.data
  241. if(resultOrder.code == 200 && resultOrder.data) {
  242. this.$dialog.confirm({
  243. title: '提示',
  244. message: "您当前有待支付订单",
  245. confirmButtonColor: '#269a93',
  246. cancelButtonText: '取消订单',
  247. confirmButtonText: '去支付'
  248. }).then(() => {
  249. this.$router.push({
  250. path: '/signUpPayment',
  251. query: {
  252. orderNo: resultOrder.data.orderNo,
  253. examRegistrationId: resultOrder.data.examRegistrationId
  254. }
  255. })
  256. }).catch(() => {
  257. const orderNo = resultOrder.data.orderNo
  258. this.$dialog.close()
  259. if(!orderNo) {
  260. return
  261. }
  262. localStorage.removeItem("examRegistrationParams")
  263. this.onCloseOrder(orderNo)
  264. })
  265. } else {
  266. localStorage.removeItem("examRegistrationParams")
  267. }
  268. },
  269. async onCloseOrder(orderNo) {
  270. setLoading(true)
  271. await closeOrder({ orderNo: orderNo })
  272. setLoading(false)
  273. },
  274. async getRegisterInfo(data) {
  275. if(!data) { // 判断是否有数据
  276. return
  277. }
  278. let form = this.form,
  279. formText = this.formText
  280. form.subjectId = data.subjectId // 报考专业专业
  281. formText.subjectName = data.subjectName // 报考专业名称
  282. form.levelFee = data.levelFee,// 级别费用
  283. form.theoryLevelFee = data.theoryLevelFee, // 乐理费用
  284. this.getExamSubjectLevel((tempList) => {
  285. //
  286. tempList.forEach(item => {
  287. if(item.level == data.level) {
  288. form.levelId = item.value
  289. form.examSubjectSongId = item.id
  290. formText.levelName = levelToCN[data.level]
  291. this.practiceNum = item.practiceNum
  292. this.practiceSongIdList = item.practiceSongIdList
  293. this.performNum = item.performNum
  294. this.performSongIdList = item.performSongIdList
  295. }
  296. })
  297. // 报考曲目
  298. this.getExamSubjectSong()
  299. const songJsonParse = data.songJson ? JSON.parse(data.songJson) : []
  300. let tempPracticeArr = [],
  301. tempPracticeStr = [],
  302. tempPerformArr = [],
  303. tempPerformStr = []
  304. songJsonParse.forEach(item => {
  305. const str = item.songName + (item.songAuthor ? "-" + item.songAuthor : "")
  306. if(item.type == "PERFORM") {
  307. tempPerformArr.push(item)
  308. tempPerformStr.push(str)
  309. this.performNumSelectIds.push(item.id)
  310. } else if(item.type == "PRACTICE") {
  311. tempPracticeArr.push(item)
  312. tempPracticeStr.push(str)
  313. this.practiceSelectIds.push(item.id)
  314. }
  315. })
  316. // 练习课 "PRACTICE"
  317. this.practiceSelect = tempPracticeStr
  318. if(this.practiceSongIdList) {
  319. this.practiceSelectList = tempPracticeArr
  320. } else {
  321. tempPracticeArr.forEach(item => {
  322. item.name = item.songName
  323. item.author = item.songAuthor
  324. const urlList = item.uploadUrl ? item.uploadUrl.split(',') : []
  325. let tempUrl = []
  326. urlList.forEach(url => {
  327. tempUrl.push({
  328. url: url
  329. })
  330. })
  331. this.practiceUpload.push(tempUrl)
  332. this.practiceUploadTemp.push(tempUrl)
  333. })
  334. this.practiceSelectUploadList = tempPracticeArr
  335. }
  336. // 演奏课 "PERFORM"
  337. this.performNumSelect = tempPerformStr
  338. if(this.performSongIdList) {
  339. this.performNumSelectList = tempPerformArr
  340. } else {
  341. tempPerformArr.forEach(item => {
  342. item.name = item.songName
  343. item.author = item.songAuthor
  344. const urlList = item.uploadUrl ? item.uploadUrl.split(',') : []
  345. let tempUrl = []
  346. urlList.forEach(url => {
  347. tempUrl.push({
  348. url: url
  349. })
  350. })
  351. this.performNumUpload.push(tempUrl)
  352. this.performNumUploadTemp.push(tempUrl)
  353. })
  354. this.performNumSelectUploadList = tempPerformArr
  355. }
  356. }) // 获取专业级别
  357. // 上传证书(上次考级证书)
  358. if(data.lastExamCertificateUrl) {
  359. form.lastExamCertificateUrl = data.lastExamCertificateUrl
  360. this.uploadCertificate = [{ url: data.lastExamCertificateUrl }]
  361. }
  362. // 乐理知识
  363. this.getTheoryLevelList((tempList) => {
  364. tempList.forEach(item => {
  365. if(!data.examMusicTheoryId && !data.examMusicTheoryLevel) {
  366. form.examMusicTheoryId = 999
  367. form.examMusicTheoryLevel = 999
  368. formText.examMusicTheoryName = "免考"
  369. } else if(item.level == data.examMusicTheoryLevel) {
  370. form.examMusicTheoryId = item.id
  371. form.examMusicTheoryLevel = item.level
  372. formText.examMusicTheoryName = item.text
  373. }
  374. })
  375. })
  376. if(data.lastMusicTheoryCertificateUrl) {
  377. form.lastMusicTheoryCertificateUrl = data.lastMusicTheoryCertificateUrl
  378. this.uploadCertificate2 = [{ url: data.lastMusicTheoryCertificateUrl }]
  379. }
  380. form.adviserName = data.adviserName
  381. form.adviserPhone = data.adviserPhone
  382. },
  383. async __init() {
  384. setLoading(true)
  385. try {
  386. // 获取报考专业
  387. const res = await getExamSubjects({ examId: this.examId })
  388. const result = res.data
  389. if(result.code == 200 && result.data.length > 0) {
  390. let tempArr = []
  391. result.data.forEach(item => {
  392. item.value = item.id
  393. item.text = item.name
  394. tempArr.push(item)
  395. })
  396. this.examSubjectList = tempArr
  397. }
  398. } catch(err) {
  399. //
  400. }
  401. setLoading(false)
  402. },
  403. async getTheoryLevelList(callBack) {
  404. setLoading(true)
  405. try {
  406. const resTheory = await getTheoryLevelList({ examId: this.examId })
  407. const resultTheory = resTheory.data
  408. if(resultTheory.code == 200 && resultTheory.data.length > 0) {
  409. let tempArr2 = [{
  410. id: 999,
  411. value: 999,
  412. text: "免考",
  413. level: 999,
  414. fee: 0
  415. }]
  416. resultTheory.data.forEach(item => {
  417. item.value = item.id
  418. item.text = levelToCN[item.level]
  419. tempArr2.push(item)
  420. })
  421. this.examMusicTheoryList = tempArr2
  422. callBack && callBack(tempArr2)
  423. }
  424. } catch(err) {
  425. //
  426. }
  427. setLoading(false)
  428. },
  429. onGetSheetList(type) {
  430. let sheetForm = this.sheetForm
  431. let form = this.form
  432. sheetForm.columns = []
  433. sheetForm.currentType = type
  434. sheetForm.index = 0
  435. // 报考专业
  436. if(type === "examSubject") {
  437. if(this.examSubjectList.length > 0) {
  438. sheetForm.sheetStatus = true
  439. sheetForm.columns = this.examSubjectList
  440. sheetForm.index = this.examSubjectIndex
  441. } else {
  442. this.$toast("暂无报考专业")
  443. return
  444. }
  445. } else if(type === "level") {
  446. if(!form.subjectId) {
  447. this.$toast("请选择报考专业")
  448. return
  449. }
  450. if(this.levelList.length > 0) {
  451. sheetForm.sheetStatus = true
  452. sheetForm.columns = this.levelList
  453. sheetForm.index = this.levelIndex
  454. } else {
  455. this.$toast("暂无报专业级别")
  456. return
  457. }
  458. } else if(type == "examMusicTheory") {
  459. if(this.examMusicTheoryList.length > 0) {
  460. sheetForm.sheetStatus = true
  461. sheetForm.columns = this.examMusicTheoryList
  462. sheetForm.index = this.examMusicTheoryIndex
  463. } else {
  464. this.$toast("暂无乐理级别")
  465. return
  466. }
  467. }
  468. },
  469. onSheetConfirm(value, index) {
  470. let sheetForm = this.sheetForm,
  471. form = this.form,
  472. formText = this.formText
  473. if(!value) { // 判断是否在选中的值
  474. sheetForm.sheetStatus = false
  475. return
  476. }
  477. if(sheetForm.currentType == "examSubject") {
  478. if(form.subjectId != value.id) {
  479. form.subjectId = value.id
  480. formText.subjectName = value.name
  481. this.examSubjectIndex = index
  482. // 清除专业级别
  483. form.levelId = null
  484. formText.levelName = null
  485. form.examSubjectSongId = null
  486. form.levelFee = 0
  487. this.levelIndex = 0
  488. this.practiceNum = 0 // 练习曲数量
  489. this.practiceSongIdList = null
  490. this.performNum = 0 // 演奏曲数量
  491. this.performSongIdList = null
  492. this.onResetSong()
  493. this.getExamSubjectLevel() // 请求专业级别
  494. }
  495. sheetForm.sheetStatus = false
  496. } else if(sheetForm.currentType == 'level') {
  497. sheetForm.sheetStatus = false
  498. if(form.levelId === value.value) { // 判断两次选择是否是一样
  499. return
  500. }
  501. form.levelId = value.value
  502. form.examSubjectSongId = value.id
  503. form.levelFee = value.registrationFee // 级别费用
  504. formText.levelName = value.text
  505. this.levelIndex = index
  506. this.practiceNum = value.practiceNum
  507. this.practiceSongIdList = value.practiceSongIdList
  508. this.performNum = value.performNum
  509. this.performSongIdList = value.performSongIdList
  510. this.onResetSong()
  511. this.getExamSubjectSong()
  512. } else if(sheetForm.currentType == "examMusicTheory") {
  513. form.examMusicTheoryId = value.value
  514. form.theoryLevelFee = value.fee
  515. form.examMusicTheoryLevel = value.level
  516. formText.examMusicTheoryName = value.text
  517. this.examMusicTheoryIndex = index
  518. sheetForm.sheetStatus = false
  519. }
  520. },
  521. onResetSong() { // 重置报考曲目数据
  522. this.practiceSelect = []
  523. this.practiceUpload = []
  524. this.practiceUploadTemp = []
  525. this.practiceSelectUploadList = []
  526. this.practiceSelectIds = []
  527. this.performNumSelectUploadList = []
  528. this.performNumSelect = []
  529. this.performNumUpload = []
  530. this.performNumUploadTemp = []
  531. this.performNumSelectIds = []
  532. },
  533. async getExamSubjectLevel(callBack) {
  534. setLoading(true)
  535. try {
  536. const form = this.form
  537. const res = await getExamSubjectLevel({ examSubjectId: form.subjectId, examinationBasicId: this.examId })
  538. const result = res.data
  539. if(result.code == 200 && result.data.length > 0) {
  540. let tempArr = []
  541. result.data.forEach(item => {
  542. item.value = item.level
  543. item.text = levelToCN[item.level]
  544. tempArr.push(item)
  545. })
  546. this.levelList = tempArr
  547. callBack && callBack(tempArr)
  548. }
  549. } catch(err) {
  550. //
  551. }
  552. setLoading(false)
  553. },
  554. async getExamSubjectSong(callBack) {
  555. setLoading(true)
  556. try {
  557. const form = this.form
  558. const params = {
  559. examSubjectId: form.subjectId,
  560. examinationBasicId: this.examId,
  561. level: form.levelId
  562. }
  563. const res = await getExamSubjectSong(params)
  564. const result = res.data
  565. if(result.code == 200 && result.data.length > 0) {
  566. let tempArr = []
  567. result.data.forEach(item => {
  568. item.value = item.id
  569. item.text = item.songName + '-' + item.songAuthor
  570. tempArr.push(item)
  571. })
  572. this.songList = tempArr
  573. callBack && callBack(tempArr)
  574. }
  575. } catch(err) {
  576. //
  577. }
  578. setLoading(false)
  579. },
  580. onChangePractice(type, index) {
  581. let songList = this.songList
  582. let sheetSong = this.sheetSong
  583. sheetSong.columns = []
  584. sheetSong.index = 0
  585. let tempPracticeArr = [],
  586. tempPerformArr = []
  587. songList.forEach(item => {
  588. if(item.type == "PERFORM") {
  589. // if(this.performNumSelectIds.includes(item.id)) {
  590. // item.disabled = true
  591. // } else {
  592. // item.disabled = false
  593. // }
  594. tempPerformArr.push(item)
  595. } else if(item.type == "PRACTICE") {
  596. // if(this.practiceSelectIds.includes(item.id)) {
  597. // item.disabled = true
  598. // } else {
  599. // item.disabled = false
  600. // }
  601. tempPracticeArr.push(item)
  602. }
  603. })
  604. if(type == 'practice') {
  605. sheetSong.columns = tempPracticeArr
  606. } else if(type == 'performNum') {
  607. sheetSong.columns = tempPerformArr
  608. }
  609. this.songSelectIndex = index
  610. sheetSong.status = true
  611. },
  612. onPracticeConfirm(value) {
  613. // 没有内容
  614. if(!value) {
  615. return
  616. }
  617. let songSelectIndex = this.songSelectIndex
  618. if(value.type == "PRACTICE") { // 练习
  619. this.practiceSelect[songSelectIndex] = value.text
  620. this.practiceSelectIds[songSelectIndex] = value.value
  621. this.practiceSelectList[songSelectIndex] = value
  622. } else if(value.type == "PERFORM") { // 演奏
  623. this.performNumSelect[songSelectIndex] = value.text
  624. this.performNumSelectIds[songSelectIndex] = value.value
  625. this.performNumSelectList[songSelectIndex] = value
  626. }
  627. this.sheetSong.status = false
  628. },
  629. beforeRead(file) {
  630. const isLt2M = file.size / 1024 / 1024 < 5
  631. if (!isLt2M) {
  632. this.$toast('上传图片大小不能超过 5MB')
  633. return false
  634. }
  635. // return new Promise((resolve) => {
  636. // fileUtil.getOrientation(file).then((orient) => {
  637. // console.log(orient)
  638. // if (orient && orient != "" && orient != 1) {
  639. // let reader = new FileReader()
  640. // let img = new Image()
  641. // reader.onload = (e) => {
  642. // img.src = e.target.result
  643. // img.onload = function () {
  644. // const data = fileUtil.rotateImage(img, img.width, img.height, orient)
  645. // const newFile = fileUtil.dataURLtoFile(data, file.name)
  646. // resolve(newFile)
  647. // }
  648. // }
  649. // reader.readAsDataURL(file)
  650. // } else {
  651. // resolve(file)
  652. // }
  653. // })
  654. // })
  655. return true
  656. },
  657. beforeDelete(file, detail) {
  658. const obj = detail.name.split('-')
  659. let form = this.form
  660. if(obj[0] == "certificate2") {
  661. form.lastMusicTheoryCertificateUrl = "" // 上传图片地址为空
  662. } else if(obj[0] == "certificate") {
  663. form.lastExamCertificateUrl = ""
  664. }
  665. return true
  666. },
  667. async afterRead(file, detail) { // 上传头像
  668. const obj = detail.name.split('-')
  669. try {
  670. file.status = 'uploading'
  671. file.message = '上传中...'
  672. let formData = new FormData()
  673. formData.append('file', file.file)
  674. let res = await uploadFile(formData)
  675. let result = res.data
  676. if(result.code == 200) {
  677. file.status = 'done'
  678. let form = this.form
  679. if(obj[0] == "certificate2") {
  680. form.lastMusicTheoryCertificateUrl = result.data.url // 上传图片地址为空
  681. } else if(obj[0] == "certificate") {
  682. form.lastExamCertificateUrl = result.data.url
  683. } else if(obj[0] == 'practiceNum') {
  684. file.url = result.data.url
  685. } else if(obj[0] == 'performNum') {
  686. file.url = result.data.url
  687. }
  688. } else {
  689. file.status = 'failed'
  690. file.message = '上传失败'
  691. this.$toast(result.msg)
  692. return false
  693. }
  694. } catch (err) {
  695. return false
  696. }
  697. },
  698. onUploadSong(value, index) { // 上传曲目
  699. let songUpload = this.songUpload
  700. songUpload.songStatus = true
  701. songUpload.indexName = value
  702. songUpload.index = index
  703. let practiceSUL = this.practiceSelectUploadList[index]
  704. let performSUL = this.performNumSelectUploadList[index]
  705. if(value == "practiceNum") {
  706. songUpload.name = practiceSUL ? practiceSUL.name : null
  707. songUpload.author = practiceSUL ? practiceSUL.author : null
  708. } else if(value == "performNum") {
  709. songUpload.name = performSUL ? performSUL.name : null
  710. songUpload.author = performSUL ? performSUL.author : null
  711. }
  712. },
  713. onSaveCancel() {
  714. this.songUpload.songStatus = false
  715. this.performNumUpload = JSON.parse(JSON.stringify(this.performNumUploadTemp)) // 回填数据
  716. this.practiceUpload = JSON.parse(JSON.stringify(this.practiceUploadTemp)) // 回填数据
  717. },
  718. onSaveUpload() {
  719. let songUpload = this.songUpload
  720. if(!songUpload.name) {
  721. this.$toast("请输入曲名")
  722. return
  723. }
  724. const nameAuthor = songUpload.name + (songUpload.author ? "-" + songUpload.author : "")
  725. if(songUpload.indexName == "practiceNum") {
  726. const practiceObj = this.practiceUpload[songUpload.index]
  727. const practiceLength = practiceObj ? practiceObj.length : 0
  728. if(practiceObj && practiceLength > 0 && practiceObj[0].url) {
  729. if(practiceObj[practiceLength - 1].url) {
  730. this.practiceSelect[songUpload.index] = nameAuthor
  731. this.practiceSelectUploadList[songUpload.index] = JSON.parse(JSON.stringify(songUpload))
  732. this.practiceUploadTemp = JSON.parse(JSON.stringify(this.practiceUpload))
  733. } else {
  734. this.$toast("上传曲谱中,请稍等")
  735. return
  736. }
  737. } else {
  738. this.$toast("请上传文件")
  739. return
  740. }
  741. } else if(songUpload.indexName == "performNum") {
  742. const performObj = this.performNumUpload[songUpload.index]
  743. const performLength = performObj ? performObj.length : 0
  744. if(performObj && performLength > 0) {
  745. if(performObj[performLength - 1].url) {
  746. this.performNumSelect[songUpload.index] = nameAuthor
  747. this.performNumSelectUploadList[songUpload.index] = JSON.parse(JSON.stringify(songUpload))
  748. this.performNumUploadTemp = JSON.parse(JSON.stringify(this.performNumUpload))
  749. } else {
  750. this.$toast("上传曲谱中,请稍等")
  751. return
  752. }
  753. } else {
  754. this.$toast("请上传文件")
  755. return
  756. }
  757. }
  758. songUpload.name = null
  759. songUpload.author = null
  760. songUpload.songStatus = false
  761. },
  762. async onSubmit() {
  763. setLoading(true)
  764. try {
  765. // 验证
  766. if(!this.onCheckFields()) {
  767. return
  768. }
  769. let songJson = [] // json 数组
  770. // 练习课 "PRACTICE"
  771. if(this.practiceSongIdList) { // 下拉选择
  772. this.practiceSelectList.forEach(item => {
  773. songJson.push({
  774. id: item.id,
  775. type: item.type,
  776. songName: item.songName,
  777. songAuthor: item.songAuthor,
  778. uploadUrl: item.fileUrlList
  779. })
  780. })
  781. } else { // 自选
  782. const practiceUpload = this.practiceUpload
  783. this.practiceSelectUploadList.forEach(item => {
  784. let tempUrl = []
  785. practiceUpload[item.index].forEach(item => {
  786. tempUrl.push(item.url)
  787. })
  788. songJson.push({
  789. songName: item.name,
  790. songAuthor: item.author,
  791. index: item.index,
  792. type: "PRACTICE",
  793. uploadUrl: tempUrl.join(',')
  794. })
  795. })
  796. }
  797. // 演奏课 "PERFORM"
  798. if(this.performSongIdList) {
  799. this.performNumSelectList.forEach(item => {
  800. songJson.push({
  801. id: item.id,
  802. type: item.type,
  803. songName: item.songName,
  804. songAuthor: item.songAuthor,
  805. uploadUrl: item.fileUrlList
  806. })
  807. })
  808. } else {
  809. const performNumUpload = this.performNumUpload
  810. this.performNumSelectUploadList.forEach(item => {
  811. let tempUrl = []
  812. performNumUpload[item.index].forEach(item => {
  813. tempUrl.push(item.url)
  814. })
  815. songJson.push({
  816. songName: item.name,
  817. songAuthor: item.author,
  818. index: item.index,
  819. type: "PERFORM",
  820. uploadUrl: tempUrl.join(',')
  821. })
  822. })
  823. }
  824. let form = this.form,
  825. formText = this.formText
  826. let params = {
  827. // studentName: localStorage.getItem("studentName"),
  828. examStartTime: localStorage.getItem("examStartTime"),
  829. adviserName: form.adviserName,
  830. adviserPhone: form.adviserPhone,
  831. examMusicTheoryId: form.examMusicTheoryId == 999 ? null : form.examMusicTheoryId,
  832. examMusicTheoryLevel: form.examMusicTheoryLevel == 999 ? null : form.examMusicTheoryLevel,
  833. examinationBasicId: this.examId,
  834. lastExamCertificateUrl: form.lastExamCertificateUrl,
  835. lastMusicTheoryCertificateUrl: form.lastMusicTheoryCertificateUrl,
  836. level: form.levelId,
  837. examSubjectSongId: form.examSubjectSongId,
  838. subjectId: form.subjectId, // 考级专业
  839. subjectName: formText.subjectName,
  840. songJson: JSON.stringify(songJson),
  841. organId: this.organId,
  842. levelFee: form.levelFee,
  843. theoryLevelFee: form.theoryLevelFee
  844. }
  845. setLoading(false)
  846. localStorage.setItem("examRegistrationParams", JSON.stringify(params))
  847. this.$router.push({
  848. path: '/signUpPayment'
  849. })
  850. } catch(err) {
  851. //
  852. }
  853. },
  854. onCheckFields() {
  855. // 校验数据
  856. let form = this.form
  857. if(!form.subjectId) {
  858. this.$toast('请选择报考专业')
  859. return false
  860. }
  861. if(!form.levelId) {
  862. this.$toast('请选择专业级别')
  863. return false
  864. }
  865. // 有值说明是列表
  866. if(this.practiceSongIdList) {
  867. if(this.practiceSelectIds.length != this.practiceNum) {
  868. this.$toast('请选择练习曲')
  869. return false
  870. }
  871. const tempIds = new Set(this.practiceSelectIds)
  872. if(this.practiceSelectIds.length != tempIds.size) {
  873. this.$toast("不能选择重复的练习曲")
  874. return false
  875. }
  876. } else {
  877. if(this.practiceUpload.length != this.practiceNum) {
  878. this.$toast('请上传练习曲')
  879. return false
  880. }
  881. }
  882. if(this.performSongIdList) {
  883. if(this.performNumSelectIds.length != this.performNum) {
  884. this.$toast('请选择演奏曲')
  885. return false
  886. }
  887. const tempIds = new Set(this.performNumSelectIds)
  888. if(this.performNumSelectIds.length != tempIds.size) {
  889. this.$toast("不能选择重复的演奏曲")
  890. return false
  891. }
  892. } else {
  893. if(this.performNumUpload.length != this.performNum) {
  894. this.$toast('请上传演奏曲')
  895. return false
  896. }
  897. }
  898. if(!form.examMusicTheoryId) {
  899. this.$toast('请选择乐理级别')
  900. return false
  901. }
  902. // if(form.examMusicTheoryId == 999 && form.levelId > 2 && !form.lastMusicTheoryCertificateUrl) {
  903. // this.$toast('请上传乐理证书')
  904. // return false
  905. // }
  906. if(form.adviserPhone && !this.checkPhone(form.adviserPhone)) {
  907. return false
  908. }
  909. return true
  910. },
  911. checkPhone(phoneNumber) {
  912. let result = true
  913. if(!(this.patternPhone.test(phoneNumber))){
  914. this.$toast('联系方式输入有误')
  915. result = false
  916. }
  917. return result
  918. },
  919. onBack() { // 上一步
  920. window.history.go(-1)
  921. },
  922. numberToCN (value) {
  923. const tempNumber = {
  924. 0: '一',
  925. 1: '二',
  926. 2: '三',
  927. 3: '四',
  928. 4: '五',
  929. }
  930. return tempNumber[value]
  931. }
  932. },
  933. destroyed() {
  934. this.$toast.clear()
  935. this.$dialog.close()
  936. }
  937. }
  938. </script>
  939. <style lang="less" scoped>
  940. @import url("../../assets/commonLess/variable");
  941. .signUpLevel {
  942. // height: 100vh;
  943. padding-bottom: 1rem;
  944. overflow-y: auto;
  945. overflow-x: hidden;
  946. background-color: @--main-bg-color;
  947. position: relative;
  948. .title {
  949. font-size: .16rem;
  950. color: @--font-second-color;
  951. padding: .12rem .16rem;
  952. }
  953. /deep/.van-cell {
  954. padding: .13rem .16rem;
  955. }
  956. /deep/.van-field__label {
  957. font-size: .17rem;
  958. color: @--font-main-color;
  959. width: 1.15rem;
  960. }
  961. /deep/.van-field__body {
  962. font-size: .16rem
  963. }
  964. .codeText {
  965. font-size: .16rem;
  966. color: @--main-color;
  967. }
  968. }
  969. .van-popup-song {
  970. width: 80%;
  971. border-radius: .08rem;
  972. }
  973. .song-popup {
  974. text-align: center;
  975. .title {
  976. font-size: 18px;
  977. font-weight: 500;
  978. color: @--font-main-color;
  979. padding: .2rem 0 .15rem;
  980. }
  981. // .song-upload {
  982. // margin: 0 .5rem;
  983. // padding: .18rem 0 .1rem;
  984. // border-radius: .05rem;
  985. // border: 1px dashed transparent;
  986. // background: linear-gradient(0deg, transparent 6px, #777777 6px) repeat-y,
  987. // linear-gradient(0deg, transparent 50%, #777777 0) repeat-y,
  988. // linear-gradient(90deg, transparent 50%, #777777 0) repeat-x,
  989. // linear-gradient(90deg, transparent 50%, #777777 0) repeat-x;
  990. // background-size: 1px 12px, 1px 12px, 12px 1px, 12px 1px;
  991. // background-position: 0 0, 100% 0, 0 0, 0 100%;
  992. // font-size: .16rem;
  993. // color: #777;
  994. // }
  995. .song-upload {
  996. border-radius: .05rem;
  997. border: 1px solid #c5c7cb;
  998. background-position: 0 0, 100% 0, 0 0, 0 100%;
  999. font-size: .16rem;
  1000. color: #777;
  1001. width: 80px;
  1002. height: 80px;
  1003. display: flex;
  1004. justify-content: center;
  1005. align-items: center;
  1006. text-align: center;
  1007. .van-uploader__preview {
  1008. margin: 0;
  1009. }
  1010. p {
  1011. font-size: 13px;
  1012. }
  1013. }
  1014. /deep/.van-uploader {
  1015. margin: 0 auto;
  1016. }
  1017. /deep/.van-uploader__upload,
  1018. /deep/.van-uploader__preview-image {
  1019. width: 65px;
  1020. height: 65px;
  1021. }
  1022. .song-popup-tips {
  1023. font-size: .14rem;
  1024. color: #808080;
  1025. padding-bottom: .15rem
  1026. // padding-top: .1rem;
  1027. // padding-bottom: .25rem;
  1028. }
  1029. /deep/.van-cell {
  1030. padding: 13px 35px;
  1031. }
  1032. /deep/.van-field__label {
  1033. width: .8rem;
  1034. text-align: left;
  1035. }
  1036. .popup-group {
  1037. width: 100%;
  1038. display: flex;
  1039. color: @--main-color;
  1040. background-color: #F0F0F0;
  1041. font-size: .18rem;
  1042. span {
  1043. padding: .12rem 0;
  1044. flex: 1;
  1045. }
  1046. .popup-sure {
  1047. color: #ffffff;
  1048. background-color: @--main-color;
  1049. }
  1050. }
  1051. }
  1052. /deep/.van-uploader__upload {
  1053. margin-bottom: 0;
  1054. }
  1055. .m-btn-group {
  1056. position: fixed;
  1057. bottom: 0;
  1058. width: calc(100% - .4rem);
  1059. padding: .1rem .2rem;
  1060. display: flex;
  1061. justify-content: space-between;
  1062. background-color: #fff;
  1063. box-shadow:0px -1px 4px 0px rgba(226,226,226,1);
  1064. .van-button {
  1065. font-size: .18rem;
  1066. height: .5rem;
  1067. width: 48%;
  1068. }
  1069. .btn_prev:active {
  1070. color: @--main-color !important;
  1071. background-color: #F5FFFD !important;
  1072. }
  1073. .btn_prev:active::before {
  1074. // background-color: #F5FFFD !important;
  1075. // border-color: @--main-color !important;
  1076. opacity: 0;
  1077. }
  1078. }
  1079. </style>