SignUpLevel.vue 43 KB

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