SignUpLevel.vue 45 KB

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