soundSetCore.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. <template>
  2. <div>
  3. <div :class="isField ? 'soundBtnWrap' : 'soundBtnFixed'" v-if="teamStatus != 'resetTeam' && !basdisabled">
  4. <el-button
  5. type="primary"
  6. @click="allin"
  7. v-if="teamStatus != 'resetTeam' && !basdisabled"
  8. >全选</el-button
  9. >
  10. <el-button
  11. type="danger"
  12. @click="deleteRow"
  13. v-if="teamStatus != 'resetTeam' && !basdisabled"
  14. >删除</el-button
  15. >
  16. <el-button type="primary" @click="soundVisible = true" v-if="!basdisabled"
  17. >添加</el-button
  18. >
  19. </div>
  20. <div class="wall" v-if="teamStatus != 'resetTeam' && !basdisabled"></div>
  21. <div class="coreWrap">
  22. <el-checkbox-group v-model="checkList" @change="lookCheck">
  23. <el-collapse v-model="chioseActiveSound">
  24. <el-collapse-item
  25. v-for="(item, index) in activeSoundList"
  26. :name="item.id"
  27. :key="index"
  28. >
  29. <template slot="title">
  30. <div class="coreItemTitle">
  31. <el-checkbox :label="item.id" :disabled="basdisabled">{{
  32. item.sound
  33. }}</el-checkbox>
  34. </div>
  35. </template>
  36. <div class="coreItem">
  37. <div class="coreItemRow">
  38. <p class="title">计划招生人数:</p>
  39. <el-input
  40. :disabled="basdisabled"
  41. style="width: 180px"
  42. v-model="item.expectedStudentNum"
  43. ></el-input>
  44. </div>
  45. </div>
  46. <el-divider></el-divider>
  47. <chioseMusic
  48. :activeSoundList="activeSoundList"
  49. :item="item"
  50. @lookMusic="lookMusic"
  51. :basdisabled="basdisabled"
  52. />
  53. <div class="coreItemRow">
  54. <p class="title">教辅:</p>
  55. <el-select
  56. style="width: 558px !important"
  57. v-model="item.markChioseList"
  58. :disabled="basdisabled"
  59. clearable
  60. filterable
  61. multiple
  62. >
  63. <el-option
  64. v-for="(item, index) in item.markList"
  65. :key="index"
  66. :label="item.name"
  67. :value="item.id"
  68. >
  69. <span style="float: left">{{ item.name }}</span>
  70. <span
  71. style="
  72. float: right;
  73. color: #8492a6;
  74. font-size: 13px;
  75. padding-right: 20px;
  76. "
  77. >{{ item.groupPurchasePrice | moneyFormat }}元</span
  78. >
  79. </el-option>
  80. </el-select>
  81. </div>
  82. </el-collapse-item>
  83. </el-collapse>
  84. </el-checkbox-group>
  85. </div>
  86. <el-dialog title="声部选择" :visible.sync="soundVisible" destroy-on-close>
  87. <chioseSoundList
  88. :soundList="soundList"
  89. :activeSound="activeSound"
  90. @chioseSound="chioseSound"
  91. />
  92. </el-dialog>
  93. </div>
  94. </template>
  95. <script>
  96. import store from "@/store";
  97. import { formatData } from "@/utils/utils";
  98. import {
  99. getSubject,
  100. getDefaultSubject,
  101. getGoods,
  102. createTeam,
  103. getSoundTree,
  104. findMusicGroupSubjectInfo,
  105. updateSubjectInfo,
  106. auditSuccess,
  107. auditFailed,
  108. getSubjectGoods,
  109. } from "@/api/buildTeam";
  110. import dayjs from "dayjs";
  111. import chioseSoundList from "./chioseSoundList";
  112. import chioseMusic from "./chioseMusic";
  113. import { findIndex } from "lodash";
  114. import numeral from "numeral";
  115. export default {
  116. components: { chioseSoundList, chioseMusic },
  117. data() {
  118. return {
  119. soundList: [], // 接口返回的一级二级声部
  120. soundVisible: false, // 设置声部弹窗
  121. childSoundList: [],
  122. activeSoundList: [], //列表上的声部
  123. activeSound: null, // 展开的列表
  124. chioseActiveSound: [],
  125. soundList: [], // 接口返回的一级二级声部
  126. childSoundList: [],
  127. teamStatus: "", // 乐团状态
  128. checkList: [],
  129. basdisabled: false,
  130. teamid: "",
  131. isField: true,
  132. };
  133. },
  134. mounted() {
  135. if (this.$route.query.id) {
  136. this.teamid = this.$route.query.id;
  137. window.addEventListener("scroll", this.getScroll);
  138. }
  139. this.init();
  140. },
  141. destroyed() {
  142. window.removeEventListener("scroll", this.getScroll);
  143. },
  144. activated() {
  145. if (this.teamid && (this.teamid != this.$route.query.id)||(this.teamStatus !=this.$route.query.type)) {
  146. this.init();
  147. } else {
  148. if (this.activeSoundList.length < 1) {
  149. console.log('进来了',this.teamid,this.activeSoundList.length)
  150. this.init();
  151. }
  152. }
  153. this.teamStatus = this.$route.query.type;
  154. if (
  155. this.teamStatus == "look" ||
  156. this.teamStatus == "teamAudit" ||
  157. this.teamStatus == "feeAudit"
  158. ) {
  159. this.basdisabled = true;
  160. } else {
  161. this.basdisabled = false;
  162. }
  163. },
  164. destroyed() {
  165. this.activeSoundList = [];
  166. },
  167. deactivated() {
  168. },
  169. methods: {
  170. init() {
  171. // 获取第一页的数据
  172. this.topfor = this.$store.getters.topinfo;
  173. let type = this.topfor.type;
  174. let section = this.topfor.section;
  175. this.teamStatus = this.$route.query.type;
  176. if (
  177. this.teamStatus == "look" ||
  178. this.teamStatus == "teamAudit" ||
  179. this.teamStatus == "feeAudit"
  180. ) {
  181. this.basdisabled = true;
  182. } else {
  183. this.basdisabled = false;
  184. }
  185. getSoundTree({ tenantId: 1 }).then((res) => {
  186. if (res.code == 200) {
  187. this.soundList = res.data.rows;
  188. if (this.teamStatus == "newTeam" && type && section) {
  189. getDefaultSubject({
  190. chargeTypeId: type,
  191. organId: section,
  192. number: 1,
  193. }).then((res) => {
  194. if (res.code == 200) {
  195. let activeSound = [];
  196. this.activeSoundList = res.data.map((item) => {
  197. activeSound.push(item.id);
  198. return this.initSound(item);
  199. });
  200. this.activeSound = activeSound;
  201. this.chioseActiveSound = activeSound;
  202. this.changeActiveSound(activeSound.join(","));
  203. }
  204. });
  205. } else {
  206. this.teamid = this.$route.query.id;
  207. if (this.teamid) {
  208. findMusicGroupSubjectInfo({ musicGroupId: this.teamid }).then(
  209. (res) => {
  210. if (res.code == 200) {
  211. let activeSound = [];
  212. this.activeSoundList = res.data?.musicGroupSubjectPlans.map(
  213. (item) => {
  214. activeSound.push(item.subjectId);
  215. return {
  216. id: parseInt(item.subjectId),
  217. sound: item.subName,
  218. expectedStudentNum: item.expectedStudentNum,
  219. chioseMusic: [],
  220. markChioseList: [],
  221. goodsList: [],
  222. markList: [],
  223. };
  224. }
  225. );
  226. this.activeSound = activeSound;
  227. this.chioseActiveSound = activeSound;
  228. this.changeActiveSound(activeSound.join(","));
  229. // 格式化商品和教辅
  230. res.data.musicGroupSubjectGoodsGroups.forEach((shop) => {
  231. let index = findIndex(this.activeSoundList, (o) => {
  232. return o.id == shop.subjectId;
  233. });
  234. if (index != -1) {
  235. if (shop.type == "ACCESSORIES") {
  236. shop.goodsIdList.split(",").forEach((item) => {
  237. this.activeSoundList[index].markChioseList.push(
  238. parseInt(item)
  239. );
  240. });
  241. } else if (shop.type == "INSTRUMENT") {
  242. // 商品
  243. let typeJson = Object.keys(
  244. JSON.parse(shop.kitGroupPurchaseTypeJson)
  245. );
  246. this.activeSoundList[index].chioseMusic.push({
  247. musical: parseInt(shop.goodsIdList),
  248. type: typeJson,
  249. groupPrice: shop.price,
  250. borrowPrice: shop.depositFee,
  251. groupRemissionCourseFee: Boolean(
  252. shop.groupRemissionCourseFee
  253. ),
  254. });
  255. }
  256. }
  257. });
  258. }
  259. }
  260. );
  261. }
  262. }
  263. }
  264. });
  265. getSubject({ tenantId: 1 }).then((res) => {
  266. if (res.code == 200) {
  267. this.childSoundList = res.data;
  268. }
  269. });
  270. },
  271. lookCheck(val) {
  272. this.checkList = [...new Set(val)];
  273. },
  274. chioseSound(activeSound) {
  275. // 同步数据
  276. this.activeSound = [...new Set(activeSound)];
  277. let newSoundList = [];
  278. for (let i in this.childSoundList) {
  279. if (this.activeSound.includes(this.childSoundList[i].id)) {
  280. newSoundList.push(this.initSound(this.childSoundList[i]));
  281. }
  282. }
  283. let idList = this.activeSoundList.map((item) => {
  284. return item.id;
  285. });
  286. for (let x in newSoundList) {
  287. const indexof = idList.indexOf(newSoundList[x]?.id);
  288. if (indexof > -1) {
  289. newSoundList[x] = this.activeSoundList[indexof];
  290. }
  291. }
  292. this.activeSoundList = newSoundList;
  293. let newActiveSound = [];
  294. this.activeSoundList.forEach((item) => {
  295. newActiveSound.push(item.id);
  296. });
  297. this.activeSound = newActiveSound;
  298. this.chioseActiveSound = newActiveSound;
  299. this.changeActiveSound(newActiveSound.join(","));
  300. this.soundVisible = false;
  301. },
  302. initSound(item) {
  303. let obj = {
  304. id: item.id,
  305. sound: item.name,
  306. expectedStudentNum: item.expectedStudentNum,
  307. chioseMusic: [
  308. {
  309. musical: "",
  310. type: ["GROUP"],
  311. groupPrice: 0,
  312. borrowPrice: 1500,
  313. groupRemissionCourseFee: Boolean(item.groupRemissionCourseFee),
  314. },
  315. ],
  316. markChioseList: [],
  317. goodsList: [],
  318. markList: [],
  319. };
  320. return obj;
  321. },
  322. changeActiveSound(val) {
  323. // 写入声部商品和辅件
  324. getSubjectGoods({
  325. subjectIds: val,
  326. chargeTypeId: this.topfor.type,
  327. }).then((res) => {
  328. if (res.code == 200) {
  329. if (res.data) {
  330. let keys = Object.keys(res.data);
  331. this.activeSoundList.forEach((item) => {
  332. if (keys.indexOf(item.id + "") != -1) {
  333. let goodList = [];
  334. let markList = [];
  335. res.data[item.id].forEach((shop) => {
  336. if (shop.type == "INSTRUMENT") {
  337. goodList.push(shop);
  338. } else if (shop.type == "ACCESSORIES") {
  339. markList.push(shop);
  340. }
  341. });
  342. item.goodsList = goodList;
  343. item.markList = markList;
  344. }
  345. });
  346. }
  347. }
  348. });
  349. },
  350. lookMusic() {},
  351. submitInfo(type) {
  352. // 计划招生人数
  353. // 可选乐器
  354. // 教辅
  355. if (this.activeSoundList.length <= 0) {
  356. this.$message.error(`请至少设置一个声部`);
  357. return;
  358. }
  359. let flag = true;
  360. this.activeSoundList.forEach((item) => {
  361. if (!item.expectedStudentNum) {
  362. this.$message.error(`请填写${item.sound}的预计招生人数`);
  363. flag = false;
  364. return;
  365. }
  366. if (!item.chioseMusic[0]?.musical) {
  367. this.$message.error(`请至少一个选择${item.sound}的可选乐器`);
  368. flag = false;
  369. return;
  370. }
  371. item.chioseMusic.forEach((music) => {
  372. if (music.type.indexOf("LEASE") != -1) {
  373. if (!music.borrowPrice || parseFloat(music.borrowPrice) <= 0) {
  374. this.$message.error(`请填写正确的${item.sound}租赁押金`);
  375. flag = false;
  376. }
  377. }
  378. });
  379. });
  380. if (!flag) return;
  381. // 新建团
  382. let obj = {};
  383. if (this.teamStatus == "newTeam") {
  384. this.initCreateTeam(obj);
  385. }
  386. // 初始化声部
  387. obj.musicGroupSubjectGoodsGroups = [];
  388. obj.musicGroupSubjectPlans = [];
  389. this.activeSoundList.forEach((active) => {
  390. // 格式化声部数据
  391. let item = {
  392. expectedStudentNum: active.expectedStudentNum,
  393. subName: active.sound,
  394. subjectId: active.id,
  395. };
  396. obj.musicGroupSubjectPlans.push(item);
  397. // 格式化商品数据 chioseMusic: [{ musical: '', type: ["GROUP"], groupPrice: 0, borrowPrice: 1500 }],
  398. active.chioseMusic.forEach((music) => {
  399. let goodsItem = null;
  400. let depositFee = music.borrowPrice;
  401. let price = music.groupPrice;
  402. let groupRemissionCourseFee;
  403. if (music.type.indexOf("GROUP") != -1) {
  404. groupRemissionCourseFee = music.groupRemissionCourseFee * 1;
  405. } else {
  406. groupRemissionCourseFee = 0;
  407. }
  408. let index = findIndex(active.goodsList, (o) => {
  409. return o.id == music.musical;
  410. });
  411. if (index != -1) {
  412. goodsItem = active.goodsList[index];
  413. }
  414. let kitGroupPurchaseTypeJson = {};
  415. music.type.forEach((type) => {
  416. kitGroupPurchaseTypeJson[type] = 0;
  417. });
  418. // if (Array.isArray(music.type)) {
  419. // music.type.forEach((type) => {
  420. // kitGroupPurchaseTypeJson[type] = 0;
  421. // });
  422. // }else{
  423. // // 字符串
  424. // let arr = [ music.type]
  425. // arr.forEach((type) => {
  426. // kitGroupPurchaseTypeJson[type] = 0;
  427. // });
  428. // }
  429. kitGroupPurchaseTypeJson = JSON.stringify(kitGroupPurchaseTypeJson);
  430. if (goodsItem) {
  431. let some = {
  432. subjectId: active.id,
  433. type: "INSTRUMENT",
  434. goodsIdList: music.musical,
  435. name: goodsItem.name,
  436. kitGroupPurchaseTypeJson,
  437. depositFee,
  438. price,
  439. groupRemissionCourseFee,
  440. };
  441. obj.musicGroupSubjectGoodsGroups.push(some);
  442. }
  443. });
  444. // 格式化辅件
  445. // markChioseList: [],
  446. // goodsList: [],
  447. // markList: [],
  448. active.markChioseList.forEach((ass) => {
  449. let index = findIndex(active.markList, (o) => {
  450. return o.id == ass;
  451. });
  452. let goodsItem = null;
  453. if (index != -1) {
  454. goodsItem = active.markList[index];
  455. }
  456. if (goodsItem) {
  457. let some = {
  458. subjectId: active.id,
  459. type: "ACCESSORIES",
  460. goodsIdList: ass,
  461. name: goodsItem.name,
  462. price: goodsItem.groupPurchasePrice,
  463. };
  464. obj.musicGroupSubjectGoodsGroups.push(some);
  465. }
  466. });
  467. });
  468. if (this.teamStatus == "newTeam") {
  469. createTeam(obj).then((res) => {
  470. if (res.code == 200) {
  471. // 成功 跳转到乐团报名详情
  472. // let query = this.$route.query;
  473. // query.type = "teamDraft";
  474. // this.$router.push({
  475. // query: {
  476. // ...query,
  477. // id: res.data,
  478. // },
  479. // });
  480. // this.$emit("chiosetab", 2);
  481. // this.$emit("getBaseInfo", obj);
  482. // zheli
  483. // 把第3步单独拆出来做成独立的模块
  484. this.$confirm("乐团创建成功,是否提交审核?", "提示", {
  485. confirmButtonText: "确定",
  486. cancelButtonText: "取消",
  487. type: "warning",
  488. })
  489. .then(() => {
  490. this.teamStatus = "teamDraft";
  491. this.teamid = res.data;
  492. this.submitInfo(1);
  493. })
  494. .catch(() => {
  495. this.$store.dispatch("delVisitedViews", this.$route);
  496. this.$router.push({
  497. path: "/business/teamDetail",
  498. });
  499. });
  500. }
  501. });
  502. } else {
  503. obj.musicGroupId = this.teamid;
  504. if (type) {
  505. obj.musicGroupStatus = "AUDIT";
  506. } else {
  507. obj.musicGroupStatus = "DRAFT";
  508. }
  509. updateSubjectInfo(obj).then((res) => {
  510. if (res.code == 200) {
  511. this.$message.success("提交成功");
  512. // this.$emit("chiosetab", 2);
  513. // 创建乐团,只会到声部了
  514. let query = this.$route.query;
  515. this.$store.dispatch("delVisitedViews", this.$route);
  516. this.$router.push({
  517. path: "/business/teamDetail",
  518. query: {
  519. ...query,
  520. },
  521. });
  522. }
  523. });
  524. }
  525. },
  526. deleteRow() {
  527. if (this.checkList.length < 1) {
  528. this.$message.error("请至少勾选一个");
  529. return;
  530. }
  531. this.$confirm("确定删除选中声部?", "提示", {
  532. confirmButtonText: "确定",
  533. cancelButtonText: "取消",
  534. type: "warning",
  535. })
  536. .then(() => {
  537. for (let i = 0; i < this.activeSoundList.length; i++) {
  538. let index = this.checkList.indexOf(this.activeSoundList[i].id);
  539. if (index != -1) {
  540. this.activeSoundList.splice(i, 1);
  541. this.activeSound.splice(i, 1);
  542. i--;
  543. }
  544. }
  545. this.checkList = [];
  546. this.$message.success("删除成功");
  547. })
  548. .catch(() => {});
  549. },
  550. allin() {
  551. this.checkList = [];
  552. this.activeSoundList.forEach((item, index) => {
  553. this.checkList.push(item.id);
  554. });
  555. },
  556. initCreateTeam(obj) {
  557. let enrollClasses;
  558. this.topfor.startClass
  559. ? (enrollClasses = this.topfor.startClass.join(","))
  560. : (enrollClasses = null);
  561. obj.musicGroup = {
  562. settlementType: this.topfor.salary,
  563. applyExpireDate: dayjs(this.topfor.time).format("YYYY-MM-DD HH:mm:ss"),
  564. chargeTypeId: this.topfor.type,
  565. cooperationOrganId: this.topfor.school,
  566. teamTeacherId: this.topfor.boss,
  567. educationalTeacherId: this.topfor.teacher,
  568. enrollClasses,
  569. name: this.topfor.name,
  570. organId: this.topfor.section,
  571. paymentPattern: this.topfor.paymentPattern,
  572. paymentValidStartDate: this.topfor.paymentValidStartDate
  573. ? dayjs(this.topfor.paymentValidStartDate).format("YYYY-MM-DD")
  574. : this.topfor.paymentValidStartDate,
  575. paymentValidEndDate: this.topfor.paymentValidEndDate
  576. ? dayjs(this.topfor.paymentValidEndDate).format("YYYY-MM-DD")
  577. : this.topfor.paymentValidEndDate,
  578. // paymentMonths:obj.months 有待确认
  579. schoolId: this.topfor.address,
  580. expectStartGroupDate: this.topfor.startTime,
  581. isClassroomLessons: this.topfor.isClass,
  582. status: "DRAFT",
  583. ownershipType: this.topfor.ownershipType,
  584. repairUserId: this.topfor.repairUserId,
  585. feeType: this.topfor.feeType,
  586. directorUserId: this.topfor.head,
  587. };
  588. return obj;
  589. },
  590. getScroll() {
  591. this.scrollTop =
  592. window.pageYOffset ||
  593. document.documentElement.scrollTop ||
  594. document.body.scrollTop;
  595. if (
  596. !!this.scrollTop &&
  597. this.scrollTop >= 210
  598. ) {
  599. this.isField = false;
  600. } else {
  601. this.isField = true;
  602. }
  603. },
  604. },
  605. watch: {
  606. activeSoundList: {
  607. immediate: true,
  608. deep: true,
  609. handler(n) {
  610. let chioseSoundNum = 0;
  611. let PlannedCount = 0;
  612. let activeSoundList = this.activeSoundList;
  613. if (n) {
  614. let Count = 0;
  615. if (n.length > 0) {
  616. for (let item in n) {
  617. Count += parseInt(n[item]?.expectedStudentNum) || 0;
  618. }
  619. }
  620. chioseSoundNum = n.length;
  621. PlannedCount = Count;
  622. this.$emit("getNumber", chioseSoundNum, PlannedCount);
  623. }
  624. },
  625. },
  626. },
  627. };
  628. </script>
  629. <style lang="scss" scoped>
  630. .wall {
  631. height: 60px;
  632. margin-bottom: 20px;
  633. }
  634. .soundBtnWrap {
  635. width: 100%;
  636. position: absolute;
  637. background-color: #fff;
  638. z-index: 100;
  639. padding: 20px;
  640. }
  641. .soundBtnFixed {
  642. top: 86px;
  643. left: 205px;
  644. width: 100%;
  645. position: fixed;
  646. background-color: #fff;
  647. z-index: 100;
  648. padding: 20px;
  649. }
  650. /deep/.el-collapse-item__header {
  651. background-color: #edeef0;
  652. }
  653. .coreItemTitle {
  654. background-color: #edeef0;
  655. height: 46px;
  656. line-height: 46px;
  657. padding: 0 20px;
  658. }
  659. .coreItem {
  660. padding: 25px 0 0;
  661. }
  662. .coreItemRow {
  663. padding: 0 20px;
  664. line-height: 50px;
  665. display: flex;
  666. flex-direction: row;
  667. align-items: center;
  668. p {
  669. margin-right: 10px;
  670. }
  671. .title {
  672. width: 140px;
  673. text-align: right;
  674. }
  675. }
  676. .marginLeft10 {
  677. margin-left: 10px;
  678. }
  679. /deep/.el-collapse-item__header {
  680. border-bottom: 1px solid #fff;
  681. }
  682. </style>