form.vue 14 KB

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