index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>
  5. 教学伴奏
  6. </h2>
  7. <div class="m-core">
  8. <el-button
  9. @click="open('COMMON')"
  10. type="primary"
  11. v-permission="'sysMusicScore/add'"
  12. >添加公用伴奏</el-button
  13. >
  14. <!-- <el-button @click="open('PERSON')" type="primary" v-permission="'sysMusicScore/add'">添加个人伴奏</el-button> -->
  15. <saveform
  16. ref="searchForm"
  17. :model.sync="searchForm"
  18. inline
  19. style="margin-top: 20px"
  20. >
  21. <el-form-item prop="search">
  22. <el-input
  23. v-model="searchForm.search"
  24. clearable
  25. placeholder="伴奏编号/伴奏名称"
  26. />
  27. </el-form-item>
  28. <!-- <el-form-item prop="organId">
  29. <el-select
  30. class="multiple"
  31. v-model.trim="searchForm.organId"
  32. filterable
  33. multiple
  34. collapse-tags
  35. clearable
  36. placeholder="请选择分部"
  37. >
  38. <el-option
  39. v-for="(item, index) in selects.branchs"
  40. :key="index"
  41. :label="item.name"
  42. :value="item.id"
  43. ></el-option>
  44. </el-select>
  45. </el-form-item> -->
  46. <el-form-item prop="type">
  47. <el-select
  48. v-model="searchForm.type"
  49. clearable
  50. placeholder="请选择类型"
  51. >
  52. <el-option
  53. v-for="(item, key) in songUseType"
  54. :key="key"
  55. :label="item"
  56. :value="key"
  57. ></el-option>
  58. </el-select>
  59. </el-form-item>
  60. <el-form-item prop="clientType">
  61. <el-select
  62. v-model="searchForm.clientType"
  63. clearable
  64. filterable
  65. placeholder="请选择客户端类型"
  66. >
  67. <el-option value="NETWORK_ROOM" label="网络教室"></el-option>
  68. <el-option value="SMART_PRACTICE" label="智能陪练"></el-option>
  69. </el-select>
  70. </el-form-item>
  71. <el-form-item prop="categoriesId">
  72. <el-cascader
  73. ref="myCascader"
  74. popper-class="myCascader"
  75. @change="changeCategor"
  76. :show-all-levels="true"
  77. clearable
  78. v-model="searchForm.categoriesId"
  79. style="width: 100%"
  80. :options="tree"
  81. placeholder="请选择分类"
  82. :props="treeProps"
  83. ></el-cascader>
  84. </el-form-item>
  85. <el-form-item prop="subjectId">
  86. <el-select
  87. v-model="searchForm.subjectId"
  88. clearable
  89. placeholder="请选择声部"
  90. >
  91. <el-option
  92. v-for="item in selects.subjects"
  93. :value="item.id"
  94. :label="item.name"
  95. :key="item.id"
  96. ></el-option>
  97. </el-select>
  98. </el-form-item>
  99. <el-form-item prop="rankType">
  100. <el-select
  101. v-model="searchForm.rankType"
  102. clearable
  103. filterable
  104. placeholder="请选择是否收费"
  105. >
  106. <el-option :value="0" label="免费"></el-option>
  107. <el-option :value="1" label="收费"></el-option>
  108. </el-select>
  109. </el-form-item>
  110. <el-form-item prop="showFlag">
  111. <el-select
  112. v-model="searchForm.showFlag"
  113. clearable
  114. filterable
  115. placeholder="请选择伴奏状态"
  116. >
  117. <el-option :value="1" label="启用"></el-option>
  118. <el-option :value="0" label="停用"></el-option>
  119. </el-select>
  120. </el-form-item>
  121. <el-form-item>
  122. <el-button @click="submit" type="primary">搜索</el-button>
  123. <el-button @click="reset" type="danger">重置</el-button>
  124. </el-form-item>
  125. </saveform>
  126. <el-table
  127. style="width: 100%"
  128. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  129. :data="tableList"
  130. >
  131. <el-table-column align="center" prop="id" label="编号" width="80px">
  132. <template slot-scope="scope">
  133. <div>
  134. <copy-text>{{ scope.row.id }}</copy-text>
  135. </div>
  136. </template>
  137. </el-table-column>
  138. <el-table-column align="center" prop="name" label="名称" width="180px">
  139. <template slot-scope="scope">
  140. <div>
  141. <copy-text>{{ scope.row.name }}</copy-text>
  142. </div>
  143. </template>
  144. </el-table-column>
  145. <!-- <el-table-column
  146. align="center"
  147. prop="organName"
  148. label="所属分部"
  149. width="180px"
  150. >
  151. <template slot-scope="scope">
  152. <div>
  153. <Tooltip :content="scope.row.organName" />
  154. </div>
  155. </template>
  156. </el-table-column> -->
  157. <el-table-column
  158. align="center"
  159. prop="subjectName"
  160. label="所属声部"
  161. width="180px"
  162. >
  163. <template slot-scope="scope">
  164. <div>
  165. <Tooltip :content="scope.row.subjectName" />
  166. </div>
  167. </template>
  168. </el-table-column>
  169. <el-table-column align="center" prop="type" label="类型">
  170. <template slot-scope="scope">
  171. {{ scope.row.type | songUseTypeFormat }}
  172. </template>
  173. </el-table-column>
  174. <!-- <el-table-column
  175. align="center"
  176. prop="speed"
  177. label="速度"
  178. /> -->
  179. <el-table-column
  180. align="center"
  181. prop="categoriesName"
  182. label="分类"
  183. width="180px"
  184. />
  185. <el-table-column align="center" label="是否收费" width="180px">
  186. <template slot-scope="scope">
  187. {{ scope.row.rankIds ? "收费" : "免费" }}
  188. </template>
  189. </el-table-column>
  190. <el-table-column align="center" label="节拍器" width="180px">
  191. <template slot-scope="scope">
  192. {{ scope.row.isOpenMetronome ? "播放" : "不播放" }}
  193. </template>
  194. </el-table-column>
  195. <el-table-column
  196. align="center"
  197. prop="subjectNames"
  198. label="是否上传伴奏"
  199. width="120px"
  200. >
  201. <template slot-scope="scope">
  202. <div>
  203. <p>
  204. 含节拍器:{{ scope.row.accompanimentMetronomeUrl ? "是" : "否" }}
  205. </p>
  206. <p>不含节拍器:{{ scope.row.accompanimentUrl ? "是" : "否" }}</p>
  207. </div>
  208. </template>
  209. </el-table-column>
  210. <el-table-column align="center" label="伴奏状态" width="180px">
  211. <template slot-scope="scope">
  212. {{ scope.row.showFlag ? "启用" : "停用" }}
  213. </template>
  214. </el-table-column>
  215. <el-table-column
  216. align="center"
  217. prop="categoriesName"
  218. label="客户端类型"
  219. width="180px"
  220. >
  221. <template slot-scope="scope">
  222. <div>
  223. {{ scope.row.clientType | clientType }}
  224. </div>
  225. </template>
  226. </el-table-column>
  227. <!-- clientType -->
  228. <el-table-column
  229. align="center"
  230. prop="createUserName"
  231. label="上传人"
  232. width="180px"
  233. />
  234. <el-table-column
  235. align="center"
  236. prop="createTime"
  237. label="上传时间"
  238. width="180px"
  239. />
  240. <el-table-column
  241. align="center"
  242. width="180px"
  243. label="操作"
  244. fixed="right"
  245. >
  246. <template slot-scope="scope">
  247. <!-- <el-button
  248. type="text"
  249. @click="looker(scope.row)"
  250. :disabled="
  251. (scope.row.isOpenMetronome
  252. ? !scope.row.url
  253. : !scope.row.metronomeUrl) ||
  254. scope.row.clientType != 'SMART_PRACTICE'
  255. "
  256. >预览</el-button
  257. > -->
  258. <el-dropdown :disabled="(scope.row.isOpenMetronome ? !scope.row.url : !scope.row.metronomeUrl) || scope.row.clientType != 'SMART_PRACTICE'">
  259. <span class="el-dropdown-link">
  260. 预览<i class="el-icon-arrow-down el-icon--right"></i>
  261. </span>
  262. <el-dropdown-menu slot="dropdown">
  263. <el-dropdown-item>
  264. <el-button type="text" @click="looker(scope.row, 1)" >系统自带节拍器</el-button></el-dropdown-item>
  265. </el-dropdown-item>
  266. <el-dropdown-item>
  267. <el-button type="text" @click="looker(scope.row, 0)" >原音自带节拍器</el-button></el-dropdown-item>
  268. </el-dropdown-menu>
  269. </el-dropdown>
  270. <el-button
  271. type="text"
  272. @click="player(scope.row)"
  273. :disabled="!scope.row.url"
  274. >播放</el-button
  275. >
  276. <el-button type="text" @click="changeStatus(scope.row)">{{
  277. scope.row.showFlag ? "停用" : "启用"
  278. }}</el-button>
  279. <el-button
  280. type="text"
  281. @click="edit(scope.row)"
  282. :disabled="!!scope.row.showFlag"
  283. v-permission="'sysMusicScore/update'"
  284. >修改</el-button
  285. >
  286. <el-button
  287. type="text"
  288. @click="remove(scope.row)"
  289. v-permission="'sysMusicScore/del'"
  290. >删除</el-button
  291. >
  292. </template>
  293. </el-table-column>
  294. </el-table>
  295. <pagination
  296. sync
  297. :total.sync="rules.total"
  298. :page.sync="rules.page"
  299. :limit.sync="rules.limit"
  300. :page-sizes="rules.page_size"
  301. @pagination="FetchList"
  302. />
  303. </div>
  304. <el-dialog
  305. v-if="audioVisible"
  306. width="400px"
  307. :visible.sync="audioVisible"
  308. title="播放伴奏"
  309. >
  310. <audio style="display: block; margin: auto" controls :src="activeUrl" />
  311. </el-dialog>
  312. <el-dialog
  313. :title="title"
  314. :visible.sync="visible"
  315. width="740px"
  316. v-if="visible"
  317. >
  318. <submit-form
  319. :detail="detail"
  320. :type="type"
  321. @submited="FetchList"
  322. @close="visible = false"
  323. />
  324. </el-dialog>
  325. <el-dialog
  326. v-if="lookVisible"
  327. width="667px"
  328. class="lookForm"
  329. :visible.sync="lookVisible"
  330. title="预览"
  331. >
  332. <iframe
  333. id="iframe"
  334. v-if="lookVisible"
  335. style="width: 667px; height: 386px"
  336. ref="iframe"
  337. :src="accompanyUrl"
  338. />
  339. <div class="iframe_back"></div>
  340. <div class="iframe_help"></div>
  341. <div class="iframe_header_back"></div>
  342. </el-dialog>
  343. </div>
  344. </template>
  345. <script>
  346. import saveform from "@/components/save-form";
  347. import pagination from "@/components/Pagination/index";
  348. import { songUseType } from "@/constant";
  349. import { QueryPage, Del, Show, queryTree } from "./api";
  350. import form from "./modals/form";
  351. import { vaildTeachingUrl } from "@/utils/validate";
  352. import { getToken } from "@/utils/auth";
  353. import deepClone from "@/helpers/deep-clone/";
  354. import Tooltip from "@/components/Tooltip/index";
  355. export default {
  356. name: "accompaniment",
  357. components: {
  358. saveform,
  359. pagination,
  360. "submit-form": form,
  361. Tooltip,
  362. },
  363. data() {
  364. return {
  365. tabName: 'first',
  366. type: "",
  367. activeUrl: "",
  368. songUseType,
  369. lookVisible: false,
  370. accompanyUrl: null, // 预览地址
  371. accompanyUrl2: null, // 预览地址
  372. audioVisible: false,
  373. tableList: [],
  374. searchForm: {
  375. search: "",
  376. type: "",
  377. subjectId: "",
  378. categoriesId: [],
  379. clientType: "",
  380. rankType: null,
  381. showFlag: null,
  382. },
  383. rules: {
  384. // 分页规则
  385. limit: 10, // 限制显示条数
  386. page: 1, // 当前页
  387. total: 0, // 总条数
  388. page_size: [10, 20, 40, 50], // 选择限制显示条数
  389. },
  390. detail: null,
  391. visible: false,
  392. tree: [],
  393. treeProps: {
  394. value: "id",
  395. label: "name",
  396. children: "sysMusicScoreCategoriesList",
  397. checkStrictly: true,
  398. expandTrigger: "hover",
  399. },
  400. };
  401. },
  402. computed: {
  403. title() {
  404. const t1 = this.detail ? "修改" : "添加";
  405. let t2 = this.type === "COMMON" ? "公用" : "个人";
  406. if (this.detail) {
  407. t2 = this.detail.type === "COMMON" ? "公用" : "个人";
  408. }
  409. return t1 + t2 + "伴奏";
  410. },
  411. },
  412. async mounted() {
  413. const { query, params } = this.$route;
  414. await this.FetchTree();
  415. if (params.categoriesId) {
  416. // console.log(this.tree)
  417. // console.log(this.formatParentId(params.categoriesId, this.tree))
  418. this.searchForm.categoriesId = this.formatParentId(params.categoriesId, this.tree);
  419. }
  420. this.$store.dispatch("setSubjects");
  421. this.$store.dispatch("setBranchs");
  422. await this.FetchList();
  423. // 点击Cascader label选中
  424. },
  425. methods: {
  426. formatParentId(id, list, ids = []) {
  427. for (const item of list) {
  428. if (item.sysMusicScoreCategoriesList) {
  429. const cIds = this.formatParentId(
  430. id,
  431. item.sysMusicScoreCategoriesList,
  432. [...ids, item.id]
  433. );
  434. if (cIds.includes(id)) {
  435. return cIds;
  436. }
  437. }
  438. if (item.id === id) {
  439. return [...ids, id];
  440. }
  441. }
  442. return ids;
  443. },
  444. async FetchTree() {
  445. try {
  446. const res = await queryTree();
  447. this.tree = res.data;
  448. } catch (error) {}
  449. },
  450. async FetchList() {
  451. try {
  452. let { categoriesId, organId, ...search } = deepClone(this.searchForm);
  453. const res = await QueryPage({
  454. ...search,
  455. categoriesId:
  456. categoriesId && categoriesId.length > 0 ? categoriesId.pop() : null,
  457. page: this.rules.page,
  458. rows: this.rules.limit,
  459. });
  460. this.tableList = res.data.rows;
  461. this.$set(this.rules, "total", res.data.total);
  462. } catch (error) {}
  463. },
  464. submit() {
  465. this.$set(this.rules, "page", 1);
  466. this.$refs.searchForm.validate((valid) => {
  467. if (valid) {
  468. this.FetchList();
  469. }
  470. });
  471. },
  472. reset() {
  473. this.$refs.searchForm.resetFields();
  474. this.FetchList();
  475. },
  476. looker(row, num) {
  477. this.accompanyUrl =
  478. vaildTeachingUrl() +
  479. "/accompany?Authorization=" +
  480. getToken() +
  481. "&platform=web&isOpenMetronome="+ num +"#/detail/" +
  482. row.id;
  483. this.lookVisible = true;
  484. // this.$nextTick(() => {
  485. // console.log(this.$refs.iframe)
  486. // let iframe = this.$refs.iframe
  487. // iframe.onload = function() {
  488. // console.log('完成', iframe)
  489. // iframe.contentWindow.document.querySelector('#tips-step-0').style.display = 'none'
  490. // }
  491. // })
  492. },
  493. player(row) {
  494. this.activeUrl = row.url;
  495. this.audioVisible = true;
  496. },
  497. async changeStatus(row) {
  498. try {
  499. let status = row.showFlag ? "停用" : "启用";
  500. await this.$confirm("是否确认" + status + "此伴奏?", "提示", {
  501. type: "warning",
  502. });
  503. await Show({
  504. sysMusicScoreId: row.id,
  505. showFlag: row.showFlag ? 0 : 1,
  506. });
  507. this.$message.success(status + "成功");
  508. this.FetchList();
  509. } catch (error) {}
  510. },
  511. edit(row) {
  512. this.detail = row;
  513. this.visible = true;
  514. },
  515. open(type) {
  516. this.type = type;
  517. this.detail = null;
  518. this.visible = true;
  519. },
  520. async remove(row) {
  521. try {
  522. await this.$confirm("是否确认删除此伴奏?", "提示", {
  523. type: "warning",
  524. });
  525. await Del(row.id);
  526. this.$message.success("删除成功");
  527. this.FetchList();
  528. } catch (error) {}
  529. },
  530. changeCategor(e) {
  531. this.$refs.myCascader.dropDownVisible = false;
  532. },
  533. },
  534. };
  535. </script>
  536. <style lang="less">
  537. .myCascader {
  538. .el-radio {
  539. width: 100%;
  540. height: 100%;
  541. z-index: 10;
  542. position: absolute;
  543. top: 10px;
  544. right: 10px;
  545. }
  546. .el-radio__input {
  547. visibility: hidden;
  548. }
  549. .el-cascader-node__postfix {
  550. top: 10px;
  551. }
  552. }
  553. </style>
  554. <style lang="less" scoped>
  555. /deep/.el-dropdown {
  556. margin-right: 10px;
  557. color: #14928A;
  558. }
  559. .remark {
  560. display: inline;
  561. overflow: hidden;
  562. white-space: pre;
  563. }
  564. .lookForm {
  565. /deep/.el-dialog__body {
  566. padding: 0;
  567. }
  568. }
  569. .iframe_back {
  570. width: 195px;
  571. height: 45px;
  572. position: absolute;
  573. bottom: 50px;
  574. background: transparent;
  575. left: 50%;
  576. z-index: 99;
  577. margin-left: -100px;
  578. }
  579. .iframe_help {
  580. position: absolute;
  581. background: transparent;
  582. width: 50px;
  583. height: 120px;
  584. top: 50%;
  585. right: 0;
  586. margin-top: -35px;
  587. }
  588. .iframe_header_back {
  589. background: transparent;
  590. width: 225px;
  591. height: 50px;
  592. position: absolute;
  593. top: 65px;
  594. left: 20px;
  595. }
  596. </style>