form.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <template>
  2. <div>
  3. <el-form ref="form" :model="form" label-width="100px">
  4. <el-form-item
  5. prop="sysMusicScore.name"
  6. label="曲名"
  7. :rules="[{required: true, message: '请输入曲名'}]"
  8. >
  9. <el-input placeholder="请输入曲名" v-model="form.sysMusicScore.name"/>
  10. </el-form-item>
  11. <el-form-item
  12. prop="sysMusicScore.musicScoreCategoriesId"
  13. label="分类"
  14. :rules="[{required: true, message: '请选择分类'}]"
  15. >
  16. <el-cascader v-model="form.sysMusicScore.musicScoreCategoriesId"
  17. style="width:100%"
  18. :options="tree"
  19. placeholder="请选择分类"
  20. :props="treeProps"></el-cascader>
  21. <!-- <el-select style="width: 100%!important;" v-model="form.sysMusicScore.musicScoreCategoriesId" placeholder="请选择声部">
  22. <el-option
  23. v-for="item in selects.subjects"
  24. :value="item.id"
  25. :label="item.name"
  26. :key="item.id"
  27. ></el-option>
  28. </el-select> -->
  29. </el-form-item>
  30. <!-- 是否收费 免费 收费 -->
  31. <el-form-item
  32. prop="rankIdType"
  33. label="是否收费"
  34. :rules="[{required: true, message: '请选择是否收费'}]"
  35. >
  36. <el-select style="width: 100%!important;" v-model="form.rankIdType" placeholder="请选择是否收费" @change="rankChange">
  37. <!-- <el-option
  38. :value="item.id"
  39. :label="item.name"
  40. v-for="item in memberRankList"
  41. :key="item.id"
  42. ></el-option> -->
  43. <el-option
  44. :value="0"
  45. label="免费"
  46. ></el-option>
  47. <el-option
  48. :value="1"
  49. label="收费"
  50. ></el-option>
  51. </el-select>
  52. </el-form-item>
  53. <el-form-item
  54. prop="sysMusicScore.clientType"
  55. label="客户端类型"
  56. :rules="[{required: true, message: '请选择客户端类型'}]"
  57. >
  58. <el-select style="width: 100%!important;" v-model="form.sysMusicScore.clientType" placeholder="请选择客户端类型">
  59. <el-option
  60. value="NETWORK_ROOM"
  61. label="网络教室"
  62. ></el-option>
  63. <el-option
  64. value="SMART_PRACTICE"
  65. label="智能陪练"
  66. ></el-option>
  67. </el-select>
  68. </el-form-item>
  69. <el-form-item
  70. prop="sysMusicScore.order"
  71. label="排序"
  72. :rules="[{required: true, message: '请输入排序'}]"
  73. >
  74. <el-input placeholder="请输入排序" v-model="form.sysMusicScore.order"/>
  75. </el-form-item>
  76. <el-form-item
  77. label="原音"
  78. prop="sysMusicScore.url"
  79. >
  80. <singe-file-upload
  81. tips="仅支持上传 mp3/aac 格式音频文件"
  82. accept=".mp3, .aac"
  83. v-model="form.sysMusicScore.url"
  84. />
  85. </el-form-item>
  86. <div class="files" v-for="(song, index) in form.sysMusicScoreAccompaniments" :key="index">
  87. <el-row>
  88. <el-col :span="12">
  89. <el-form-item
  90. :prop="`sysMusicScoreAccompaniments.${index}.subjectId`"
  91. label="声部"
  92. >
  93. <!-- :rules="[{required: true, message: '请选择声部'}]" -->
  94. <el-select style="width: 100%!important;" v-model="song.subjectId" clearable placeholder="请选择声部">
  95. <el-option
  96. v-for="item in selects.subjects"
  97. :value="item.id"
  98. :label="item.name"
  99. :key="item.id"
  100. :disabled="hasSubjectId(item.id)"
  101. ></el-option>
  102. </el-select>
  103. </el-form-item>
  104. </el-col>
  105. <el-col :span="12">
  106. <el-form-item
  107. :prop="`sysMusicScoreAccompaniments.${index}.speed`"
  108. label="速度"
  109. :rules="[{required: true, message: '请输入速度'}]"
  110. >
  111. <el-input type="number" placeholder="请输入速度" v-model="song.speed"/>
  112. </el-form-item>
  113. </el-col>
  114. <el-col :span="12">
  115. <el-form-item
  116. :prop="`sysMusicScoreAccompaniments.${index}.isShowFingering`"
  117. label="指法展示"
  118. :rules="[{required: true, message: '请选择是否展示指法'}]"
  119. >
  120. <el-select style="width: 100%!important;" v-model="song.isShowFingering" placeholder="请选择是否展示指法">
  121. <el-option
  122. :value="true"
  123. label="是"
  124. ></el-option>
  125. <el-option
  126. :value="false"
  127. label="否"
  128. ></el-option>
  129. </el-select>
  130. </el-form-item>
  131. </el-col>
  132. <el-col :span="12">
  133. <el-form-item
  134. :prop="`sysMusicScoreAccompaniments.${index}.memo`"
  135. label="描述"
  136. >
  137. <el-input placeholder="请输入描述" v-model="song.memo"/>
  138. </el-form-item>
  139. </el-col>
  140. <el-col :span="12">
  141. <el-form-item
  142. label="mp3文件"
  143. :prop="`sysMusicScoreAccompaniments.${index}.mp3Url`"
  144. >
  145. <singe-file-upload
  146. tips="仅支持上传 mp3/aac 格式音频文件"
  147. accept=".mp3, .aac"
  148. v-model="song.mp3Url"
  149. />
  150. </el-form-item>
  151. </el-col>
  152. <el-col :span="12">
  153. <el-form-item
  154. label="MusicXML"
  155. :prop="`sysMusicScoreAccompaniments.${index}.xmlUrl`"
  156. :rules="[{required: true, message: '请选择MusicXML文件'}]"
  157. >
  158. <singe-file-upload
  159. tips="仅支持上传 xml 格式文件"
  160. accept=".xml"
  161. v-model="song.xmlUrl"
  162. />
  163. </el-form-item>
  164. </el-col>
  165. </el-row>
  166. <el-button class="file-remove" type="text" @click="removeSys(index)" :disabled="form.sysMusicScoreAccompaniments.length == 1">删除</el-button>
  167. </div>
  168. <el-button @click="createSys" type="info" style="width: 100%;margin-bottom: 20px;" plain>添加伴奏</el-button>
  169. <div class="btns">
  170. <el-button type="primary" @click="submit">提交</el-button>
  171. <el-button @click="$listeners.close">取消</el-button>
  172. </div>
  173. </el-form>
  174. </div>
  175. </template>
  176. <script>
  177. import { Add, Update, queryPageSysExam, queryTree } from '../api'
  178. import { getAllmemberRank } from "@/views/resetTeaming/api";
  179. export default {
  180. props: ['detail', 'type'],
  181. data() {
  182. return {
  183. tree: [],
  184. memberRankList: [], // 会员列表
  185. form: {
  186. rankIdType: 0, // 收费会员类型 默认免费
  187. sysMusicScore: {
  188. name: '',
  189. rankIds: '', // 收费会员编号
  190. url: '',
  191. order: '',
  192. musicScoreCategoriesId: [],
  193. clientType: '',
  194. },
  195. sysMusicScoreAccompaniments: [
  196. {
  197. subjectId: '',
  198. speed: '',
  199. mp3Url: '',
  200. xmlUrl: '',
  201. isShowFingering: null,
  202. mome: '',
  203. },
  204. ],
  205. delExamSongAccompanimentIds: []
  206. },
  207. treeProps: {
  208. value: 'id',
  209. label: 'name',
  210. children: 'sysMusicScoreCategoriesList',
  211. }
  212. }
  213. },
  214. async mounted() {
  215. this.$store.dispatch('setSubjects')
  216. await this.FetchTree()
  217. await this.memberRank()
  218. if (this.detail) {
  219. // console.log(this.detail)
  220. this.$set(this.form, 'sysMusicScore', {
  221. name: this.detail.name,
  222. url: this.detail.url,
  223. rankIds: this.detail.rankIds,
  224. order: this.detail.order,
  225. clientType: this.detail.clientType,
  226. musicScoreCategoriesId: this.detail.categoriesId ? this.formatParentId(this.detail.categoriesId, this.tree) : [],
  227. })
  228. if(this.detail.rankIds) {
  229. this.form.rankIdType = 1
  230. } else {
  231. this.form.rankIdType = 0
  232. }
  233. this.FeatchDetailList()
  234. }
  235. },
  236. methods: {
  237. rankChange(value) {
  238. if(value) {
  239. let tempIds = []
  240. this.memberRankList.forEach(item => {
  241. tempIds.push(item.id)
  242. })
  243. this.form.sysMusicScore.rankIds = tempIds.join(',')
  244. } else {
  245. // 会员购买重置
  246. this.form.sysMusicScore.rankIds = ''
  247. }
  248. },
  249. async memberRank() {
  250. try {
  251. const res = await getAllmemberRank({ isDefault: 0 });
  252. this.memberRankList = res.data || [];
  253. } catch (e) {
  254. console.log(e);
  255. }
  256. },
  257. formatParentId(id, list, ids = []) {
  258. for (const item of list) {
  259. if (item.sysMusicScoreCategoriesList) {
  260. const cIds = this.formatParentId(id, item.sysMusicScoreCategoriesList, [...ids, item.id])
  261. if(cIds.includes(id)) {
  262. return cIds
  263. }
  264. }
  265. if (item.id === id) {
  266. return [...ids, id]
  267. }
  268. }
  269. return ids
  270. },
  271. async FetchTree() {
  272. try {
  273. const res = await queryTree()
  274. this.tree = res.data
  275. } catch (error) {
  276. }
  277. },
  278. async FeatchDetailList() {
  279. try {
  280. const res = await queryPageSysExam({
  281. sysMusicScoreId: this.detail.id
  282. })
  283. const result = res.data || []
  284. result.forEach(item => {
  285. if(!item.subjectId) {
  286. item.subjectId = null
  287. }
  288. })
  289. this.$set(this.form, 'sysMusicScoreAccompaniments', result)
  290. } catch (error) {}
  291. },
  292. createSys() {
  293. this.form.sysMusicScoreAccompaniments.push({
  294. subjectId: '',
  295. speed: '',
  296. mp3Url: '',
  297. xmlUrl: ''
  298. })
  299. },
  300. async removeSys(index) {
  301. try {
  302. await this.$confirm('是否确认删除此伴奏?', '提示', {
  303. type: 'warning'
  304. })
  305. if (this.form.sysMusicScoreAccompaniments[index]) {
  306. this.form.delExamSongAccompanimentIds.push(this.form.sysMusicScoreAccompaniments[index].id)
  307. }
  308. this.form.sysMusicScoreAccompaniments.splice(index, 1)
  309. } catch (error) {}
  310. },
  311. hasSubjectId(id) {
  312. const ids = []
  313. for (const item of this.form.sysMusicScoreAccompaniments) {
  314. ids.push(item.subjectId)
  315. }
  316. return ids.includes(id)
  317. },
  318. async submit() {
  319. this.$refs.form.validate(async (valid) => {
  320. if (valid) {
  321. if (!this.detail) {
  322. await Add({
  323. ...this.form,
  324. sysMusicScore: {
  325. ...this.form.sysMusicScore,
  326. type: 'COMMON',
  327. showFlag: 0,
  328. musicScoreCategoriesId: (this.form.sysMusicScore.musicScoreCategoriesId || []).pop(),
  329. }
  330. })
  331. this.$message.success('提交成功')
  332. } else {
  333. await Update({
  334. ...this.form,
  335. sysMusicScore: {
  336. ...this.form.sysMusicScore,
  337. type: 'COMMON',
  338. id: this.detail.id,
  339. showFlag: this.detail.showFlag,
  340. musicScoreCategoriesId: (this.form.sysMusicScore.musicScoreCategoriesId || []).pop(),
  341. }
  342. })
  343. this.$message.success('修改成功')
  344. }
  345. this.$listeners.close()
  346. this.$listeners.submited()
  347. }
  348. })
  349. }
  350. }
  351. }
  352. </script>
  353. <style lang="less" scoped>
  354. .btns{
  355. text-align: right;
  356. }
  357. .files{
  358. background-color: #f8f8f8;
  359. padding: 20px 0;
  360. padding-right: 20px;
  361. margin-bottom: 20px;
  362. border-radius: 5px;
  363. position: relative;
  364. .file-remove{
  365. position: absolute;
  366. right: 20px;
  367. bottom: 10px;
  368. }
  369. }
  370. </style>