subject-preview.vue 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  1. <template>
  2. <div style="background: #f3f4f8; overflow: hidden;">
  3. <tips />
  4. <course-model
  5. v-if="mypreViewData && mypreViewData.isShowMusicCourseForPay"
  6. :isShowSalePrice="isShowSalePrice"
  7. :courseViewType="courseViewType"
  8. :courseShowInfo="courseShowInfo"
  9. :remissionCourseFeeStatus="remissionCourseFeeStatus"
  10. :courseInfo="courseInfo"
  11. :trainSmallBg="trainSmallBg"
  12. :serviceValidDate="serviceValidDate"
  13. :cloudTeacherFee="cloudTeacherFee"
  14. :chargeTypeName="chargeTypeName"
  15. :memberCoursePrice="memberCoursePrice"
  16. :memberCourseShowFlag="memberCourseShowFlag"
  17. @onCourseChange="onCheckItem"
  18. @onQuestions="onQuestions"
  19. />
  20. <member
  21. v-if="
  22. toolsPackage &&
  23. toolsPackage.length > 0 &&
  24. mypreViewData &&
  25. mypreViewData.isShowMemberForPay
  26. "
  27. :isShowSalePrice="isShowSalePrice"
  28. :toolsPackage="toolsPackage"
  29. :isGiveAccessories="isGiveAccessories"
  30. :accessStatus="accessOries.length > 0"
  31. @onCheckItem="onCheckItem"
  32. >
  33. <div class="section" v-if="toolsPackage.length > 0" key="toolsPackage">
  34. <el-row class="title-row">
  35. <el-col :span="12"
  36. >练习系统{{
  37. isGiveAccessories && accessStatus ? "(赠送辅件一套)" : null
  38. }}</el-col
  39. >
  40. <el-col :span="5" style="text-align: right;">时长</el-col>
  41. <el-col :span="7" style="text-align: right;">原价</el-col>
  42. <!-- <el-col :span="5" style="text-align: right;" v-if="isShowSalePrice"
  43. >售价</el-col
  44. > -->
  45. </el-row>
  46. <div v-for="(item, index) in toolsPackage" :key="index">
  47. <template v-for="(child, index) in formatList">
  48. <el-row class="option-row" style="cursor: default;" :key="index">
  49. <el-col :span="12" style="padding-left: 0.05rem">
  50. <span style="display: flex; align-items: center;">
  51. {{ child.title }}
  52. </span>
  53. </el-col>
  54. <el-col :span="5">
  55. <span style="color: #AAA; font-size: 12px;"
  56. >{{ item.num | unitFormatMonth(item.period) }}个月</span
  57. >
  58. </el-col>
  59. <el-col :span="7" style="text-align: right;">
  60. <del style="color: #1A1A1A; font-size: 14px;width: 100%"
  61. >¥{{
  62. child.monthPrice
  63. | unitFormatPrice(
  64. item.period,
  65. item.num,
  66. child.halfYearPrice
  67. )
  68. }}</del
  69. >
  70. </el-col>
  71. </el-row>
  72. </template>
  73. <div class="paymentSection" @click="onCheckItem(item, 'train')">
  74. <i
  75. class="check_default"
  76. :class="[
  77. item.isStatus ? 'check_active' : '',
  78. item.optionalFlag ? 'disabled' : ''
  79. ]"
  80. ></i>
  81. <div class="paymentPrice">
  82. <span>优惠价:¥{{ item.actualAmount | moneyFormat }}</span>
  83. <del>原价:¥ {{ onCalcSinglePrice(item) }}</del>
  84. </div>
  85. </div>
  86. </div>
  87. </div>
  88. </member>
  89. <instrument-model
  90. :isShowSalePrice="isShowSalePrice"
  91. :instrumentResultList="instrumentResultList"
  92. :buyMaintenance="buyMaintenance"
  93. :trainSmallBg="trainSmallBg"
  94. :courseViewType="courseViewType"
  95. :toolsPackage="toolsPackage"
  96. :organId="organId"
  97. @instrumentF="onCheckItem"
  98. @onQuestions="onQuestions"
  99. />
  100. <div
  101. class="courseModel"
  102. style="margin-top: 12px;"
  103. v-if="
  104. instrumentRepair &&
  105. instrumentRepair.length > 0 &&
  106. mypreViewData &&
  107. mypreViewData.isShowMusicInsuranceForPay
  108. "
  109. >
  110. <h2 class="titles">
  111. <img :src="trainSmallBg" />
  112. <span>乐器保养</span>
  113. </h2>
  114. <!-- 可选课程信息集合 -->
  115. <div class="section">
  116. <el-row class="title-row">
  117. <el-col :span="isShowSalePrice ? 9 : 14">服务项目</el-col>
  118. <!-- 原价 -->
  119. <el-col :span="5" style="text-align: right;">时间</el-col>
  120. <el-col :span="5" style="text-align: right;">原价</el-col>
  121. <el-col :span="5" style="text-align: right;" v-if="isShowSalePrice"
  122. >售价</el-col
  123. >
  124. </el-row>
  125. <el-row
  126. class="option-row"
  127. v-for="(item, index) in instrumentRepair"
  128. :key="index"
  129. @click.native="onCheckItem(item)"
  130. >
  131. <el-col :span="isShowSalePrice ? 9 : 14">
  132. <i
  133. class="check_default"
  134. :class="[
  135. item.isStatus ? 'check_active' : '',
  136. item.optionalFlag ? 'disabled' : '',
  137. item.noSelect ? 'noSelect' : ''
  138. ]"
  139. ></i>
  140. {{ item.name }}
  141. </el-col>
  142. <el-col :span="5">
  143. <span style="color: #AAA; font-size: 12px;"
  144. >{{ item.num }}(年)</span
  145. >
  146. </el-col>
  147. <el-col :span="5">
  148. <del style="color: #AAA; font-size: 12px;"
  149. >¥{{ item.originalAmount | moneyFormat }}</del
  150. >
  151. </el-col>
  152. <el-col :span="5" v-if="isShowSalePrice">
  153. <span style="color: #1A1A1A"
  154. >¥{{ item.actualAmount | moneyFormat }}</span
  155. >
  156. </el-col>
  157. </el-row>
  158. </div>
  159. </div>
  160. <accessories
  161. :isShowSalePrice="isShowSalePrice"
  162. :trainSmallBg="trainSmallBg"
  163. :accessOries="accessOries"
  164. :isGiveAccessories="giveAccessoriesStatus"
  165. @onAuxiliarie="onCheckItem"
  166. />
  167. <activity
  168. v-if="
  169. activityList &&
  170. activityList.length > 0 &&
  171. mypreViewData &&
  172. mypreViewData.isShowVipCourseForPay
  173. "
  174. :isShowSalePrice="isShowSalePrice"
  175. :trainSmallBg="trainSmallBg"
  176. :activityList="activityList"
  177. @onCheckItem="onCheckItem"
  178. />
  179. <!-- <div class="buy">
  180. <div class="price">
  181. <p class="oldprice">
  182. <del class="text">原价</del>
  183. <del style="font-size: 13px"
  184. >¥{{ orderInfo.marketPrice | moneyFormat }}</del
  185. >
  186. </p>
  187. <p class="now_price">
  188. <span class="text">仅需支付</span>
  189. <span style="font-weight: bold">¥{{ needPrice | moneyFormat }}</span>
  190. </p>
  191. </div>
  192. <a class="btn-submit">购买</a>
  193. </div> -->
  194. </div>
  195. </template>
  196. <script>
  197. import { permission } from "@/utils/directivePage";
  198. import { getSubjectGoodsAndInfoPreview, getType } from "@/api/buildTeam";
  199. import dayjs from "dayjs";
  200. import numeral from "numeral";
  201. const paymentPatternType = {
  202. 0: "按月",
  203. 1: "按学期",
  204. 2: "一次性"
  205. };
  206. import Tips from "./tips";
  207. import courseModel from "@/views/resetTeaming/modals/courseModel";
  208. import InstrumentModel from "./instrumentModel";
  209. import accessories from "./accessories";
  210. import activity from "./activity";
  211. import member from "./member";
  212. export default {
  213. props: ["subjectId", "calenderId", "preViewData"],
  214. components: {
  215. Tips,
  216. courseModel,
  217. InstrumentModel,
  218. accessories,
  219. activity,
  220. member
  221. },
  222. data() {
  223. const query = this.$route.query;
  224. return {
  225. videoStatus: false,
  226. trainBg: require("../../../assets/images/musicGroup/yunTrain_bg.png"),
  227. trainSmallBg: require("../../../assets/images/musicGroup/yunTrain_small_bg.png"),
  228. musicGroupId: query.id,
  229. organId: null,
  230. result: {}, // 返回结果
  231. instrument: {}, // 乐器类型
  232. baseInfo: {}, // 其它类
  233. money: 580,
  234. balance: 0, // 余额
  235. needPrice: 0, // 还需支付
  236. payType: false, // 是否余额支付
  237. cloudTeacherFee: 0, // 云教练费用
  238. cloudTeacherPlusFee: 0, // 云教练+
  239. orderInfo: {
  240. marketPrice: 0,
  241. amount: 0, // 现价总金额
  242. groupPurchasePrice: 0, // 现价
  243. goodsGroupIds: null,
  244. goodsIds: null,
  245. contractGoodsIds: null, // 选中所有商品ID
  246. couponPrice: 0, //
  247. musicClassFee: 0, // 课程现价
  248. musicMarketClassFee: 0, // 课程原价
  249. accessPrice: 0, // 辅件现价
  250. accessMarketPrice: 0, // 辅件原价
  251. goodsPrice: 0, // 乐器现价
  252. goodsMarketPrice: 0 // 乐器原价
  253. }, // 金额列表,金额计算
  254. toolsPackage: [], // 学习工具包
  255. instrumentRepair: [], // 乐保信息
  256. activityList: [], // 小班课信息
  257. courseInfo: [], // 课程信息
  258. courseShowInfo: [], // 课程信息显示用
  259. musicGroupSubject: null, // 基本信息
  260. instrumentResult: [], //乐器
  261. accessOries: [], // 辅件(打包)
  262. agreeStatus: true,
  263. authStatus: false,
  264. ids: [],
  265. instrumentResultList: [],
  266. paymentStatus: null,
  267. paymentPattern: null,
  268. serviceValidDate: null, // 服务时间
  269. courseShowStatus: false,
  270. chargeTypeList: [],
  271. chargeTypeName: null,
  272. courseViewType: 0, // 收费模式,0 课程显示,1 AMR系统 2会员 3免费
  273. leBaoStatus: false,
  274. buyMaintenance: false, // 是否开启乐保
  275. isClickStatus: false,
  276. accessStatus: false, // 是否有辅件乐保
  277. accessIsShowStatus: false, // 是否显示辅件 true 显示, false 不显示
  278. memberCoursePrice: [], // 云教练,显示赠送的课程
  279. memberCourseShowFlag: false, // 是否显示赠送课程
  280. buyCloudTeacher: false, // 是否购买云教练
  281. remissionCourseFeeStatus: false,
  282. isGiveAccessories: false, // 是否赠送辅件
  283. giveAccessoriesStatus: false,
  284. mypreViewData: {
  285. isShowMemberForPay: true,
  286. isShowMusicInsuranceForPay: true,
  287. isShowVipCourseForPay: true,
  288. isShowMusicCourseForPay: true
  289. },
  290. isShowSalePrice: true, // 是否显示原价
  291. formatList: [
  292. {
  293. title: "声部云练",
  294. monthPrice: 240,
  295. halfYearPrice: 980
  296. },
  297. {
  298. title: "合奏云练",
  299. monthPrice: 160,
  300. halfYearPrice: 580
  301. },
  302. {
  303. title: "独奏云练",
  304. monthPrice: 160,
  305. halfYearPrice: 580
  306. },
  307. {
  308. title: "考级云练",
  309. monthPrice: 160,
  310. halfYearPrice: 580
  311. },
  312. {
  313. title: "云课程",
  314. monthPrice: 240,
  315. halfYearPrice: 980
  316. }
  317. ],
  318. tempNum: {
  319. YEAR: 12,
  320. MONTH: 1,
  321. QUARTERLY: 3,
  322. YEAR_HALF: 6
  323. }
  324. };
  325. },
  326. mounted() {
  327. this.__init();
  328. },
  329. methods: {
  330. async __init() {
  331. // 获取数据
  332. let params = {
  333. musicGroupId: this.musicGroupId,
  334. subjectId: this.subjectId,
  335. calenderId: this.calenderId
  336. };
  337. await getSubjectGoodsAndInfoPreview(params).then(res => {
  338. let result = res;
  339. if (result.code == 200) {
  340. let tempResult = result.data;
  341. this.__dataFormat(tempResult);
  342. }
  343. // 初始化计算金额
  344. this.calcPrice();
  345. });
  346. },
  347. __dataFormat(tempResult) {
  348. this.mypreViewData =
  349. this.preViewData && this.preViewData.paymentCalender
  350. ? JSON.parse(JSON.stringify(this.preViewData))
  351. : {
  352. isShowMemberForPay: true,
  353. isShowMusicInsuranceForPay: true,
  354. isShowVipCourseForPay: true,
  355. isShowMusicCourseForPay: true
  356. };
  357. this.courseViewType = tempResult.musicGroup.courseViewType || 0;
  358. this.isGiveAccessories =
  359. (tempResult.musicGroup && tempResult.musicGroup.isGiveAccessories) ||
  360. false; // 是否赠送辅件
  361. this.organId = tempResult.musicGroup.organId;
  362. const musicGroupStatus = tempResult.musicGroup.status;
  363. this.cloudTeacherFee = tempResult.cloudTeacherFee || 0;
  364. this.cloudTeacherPlusFee = tempResult.cloudTeacherPlusFee || 0;
  365. let memberCoursePrice = tempResult.memberCoursePrice || {};
  366. for (let i in memberCoursePrice) {
  367. this.memberCoursePrice.push({
  368. name: coursesType[i],
  369. price: memberCoursePrice[i]
  370. });
  371. }
  372. this.memberCourseShowFlag =
  373. tempResult.musicGroup.memberCourseShowFlag || false;
  374. this.paymentPattern = 2;
  375. if (tempResult.musicGroupPaymentCalender) {
  376. this.paymentPattern =
  377. tempResult.musicGroupPaymentCalender.paymentPattern;
  378. this.serviceValidDate =
  379. dayjs(
  380. tempResult.musicGroupPaymentCalender.paymentValidStartDate
  381. ).format("YYYY/MM/DD") +
  382. "~" +
  383. dayjs(
  384. tempResult.musicGroupPaymentCalender.paymentValidEndDate
  385. ).format("YYYY/MM/DD");
  386. }
  387. const paymentCalender =
  388. this.mypreViewData && this.mypreViewData.paymentCalender
  389. ? this.mypreViewData.paymentCalender
  390. : tempResult.paymentCalender || null;
  391. if (paymentCalender && paymentCalender.calender) {
  392. this.isShowSalePrice =
  393. paymentCalender.calender.isShowSalePrice || false;
  394. if (paymentCalender.calender.paymentItemShowState) {
  395. let obj = JSON.parse(paymentCalender.calender.paymentItemShowState);
  396. for (let key in obj) {
  397. this.mypreViewData[key] = obj[key];
  398. }
  399. }
  400. }
  401. let tempInfo =
  402. paymentCalender && paymentCalender.course ? paymentCalender.course : [];
  403. let memberPrivilegesItemList = tempResult.memberPrivilegesItemList
  404. ? tempResult.memberPrivilegesItemList
  405. : [];
  406. let tempMember = [];
  407. memberPrivilegesItemList.forEach(member => {
  408. if (
  409. member.memberPrivilegesItems &&
  410. member.memberPrivilegesItems.length > 0
  411. ) {
  412. member.memberPrivilegesItems.forEach(item => {
  413. tempMember.push(item.name);
  414. });
  415. }
  416. });
  417. // 云教练
  418. const member =
  419. paymentCalender && paymentCalender.member ? paymentCalender.member : {};
  420. member.isStatus = true;
  421. this.toolsPackage = member && !member.memberRankSettingId ? [] : [member];
  422. console.log(this.toolsPackage, "this.toolsPackage");
  423. // 乐器保养
  424. const repair =
  425. paymentCalender && paymentCalender.repair ? paymentCalender.repair : {};
  426. repair.name = "乐器保养";
  427. repair.isStatus = true; // 默认不选择乐器保养
  428. this.instrumentRepair = Number(repair.actualAmount) ? [repair] : [];
  429. // 小班课
  430. const activity =
  431. paymentCalender && paymentCalender.activity
  432. ? paymentCalender.activity
  433. : [];
  434. activity.map(i => {
  435. i.isStatus = true;
  436. });
  437. this.activityList = [...activity];
  438. // 判断是否有课程
  439. if (tempInfo && tempInfo.length > 0) {
  440. // 默认课程都选中
  441. tempInfo.forEach(item => {
  442. // if (item && item.isStudentOptional) {
  443. // item.isStatus = false;
  444. // } else {
  445. item.isStatus = true;
  446. // }
  447. });
  448. this.courseInfo = tempInfo;
  449. }
  450. this.musicGroupSubject = tempResult.musicGroupSubjectPlan || [];
  451. let instrumentInfo = {};
  452. let tempInstrument = [];
  453. let musicGroupSubjectGoodsGroupList =
  454. this.preViewData?.payUserType == "SCHOOL" ||
  455. musicGroupStatus == "PROGRESS"
  456. ? []
  457. : tempResult.musicGroupSubjectGoodsGroupList;
  458. musicGroupSubjectGoodsGroupList?.forEach(item => {
  459. if (item.type == "INSTRUMENT") {
  460. // 获取乐器所有提供方式
  461. let KGPTJ = item.kitGroupPurchaseTypeJson
  462. ? JSON.parse(item.kitGroupPurchaseTypeJson)
  463. : {};
  464. for (let single in KGPTJ) {
  465. let tempItem = Object.assign({}, item); // 深拷贝
  466. tempItem.marketPrice = tempItem.goodsList[0].marketPrice;
  467. tempItem.kitType = single; // 优惠模式
  468. tempItem.coupon = KGPTJ[single]; // 优惠金额
  469. tempItem.discountPrice = tempItem.goodsList[0].discountPrice;
  470. if (instrumentInfo.id) {
  471. tempItem.isStatus = false;
  472. if (single == "GROUP") {
  473. // 团购
  474. if (
  475. (instrumentInfo.kitType == "GROUP" &&
  476. instrumentInfo.price < tempItem.price) ||
  477. instrumentInfo.kitType == "LEASE" ||
  478. instrumentInfo.kitType == "FREE"
  479. ) {
  480. this.instrumentResult.forEach(instrRes => {
  481. instrRes.isStatus = false;
  482. });
  483. tempItem.isStatus = true;
  484. instrumentInfo = {
  485. id: tempItem.id,
  486. price: tempItem.price,
  487. kitType: single,
  488. groupRemissionCourseFee: tempItem.groupRemissionCourseFee
  489. };
  490. }
  491. } else if (single == "LEASE") {
  492. // 租赁
  493. if (
  494. instrumentInfo.kitType == "LEASE" &&
  495. instrumentInfo.price < tempItem.price
  496. ) {
  497. this.instrumentResult.forEach(instrRes => {
  498. instrRes.isStatus = false;
  499. });
  500. tempItem.isStatus = true;
  501. instrumentInfo = {
  502. id: tempItem.id,
  503. price: tempItem.price,
  504. kitType: single,
  505. groupRemissionCourseFee: tempItem.groupRemissionCourseFee
  506. };
  507. }
  508. } else if (single == "FREE") {
  509. // 免费
  510. if (
  511. instrumentInfo.kitType == "FREE" &&
  512. instrumentInfo.price < tempItem.price
  513. ) {
  514. this.instrumentResult.forEach(instrRes => {
  515. instrRes.isStatus = false;
  516. });
  517. tempItem.isStatus = true;
  518. instrumentInfo = {
  519. id: tempItem.id,
  520. price: tempItem.price,
  521. kitType: single,
  522. groupRemissionCourseFee: tempItem.groupRemissionCourseFee
  523. };
  524. }
  525. }
  526. } else {
  527. tempItem.isStatus = true;
  528. instrumentInfo = {
  529. id: tempItem.id,
  530. price: tempItem.price,
  531. kitType: single,
  532. groupRemissionCourseFee: tempItem.groupRemissionCourseFee
  533. };
  534. }
  535. let childGoodsNameList = [];
  536. if (tempItem.childGoodsList && tempItem.childGoodsList.length > 0) {
  537. tempItem.childGoodsList.forEach(child => {
  538. if (child.type != "INSTRUMENT" && child.type != "OTHER") {
  539. childGoodsNameList.push(child.name);
  540. }
  541. });
  542. tempItem.childGoodsNames = childGoodsNameList.join("、");
  543. }
  544. this.instrumentResult.push(tempItem);
  545. tempInstrument.push(tempItem);
  546. }
  547. } else if (item.type == "ACCESSORIES") {
  548. item.isStatus = true;
  549. this.accessOries.push(item);
  550. }
  551. });
  552. // 添加自备选项
  553. if (this.instrumentResult.length > 0) {
  554. let sorted = this.groupBy(tempInstrument, item => {
  555. return [item.kitType];
  556. });
  557. this.instrumentResultList = sorted;
  558. // 设置是否有减免金额
  559. this.instrumentGetStatus();
  560. this.setLeBaoStatus();
  561. }
  562. // 如果选择的是乐保,则把所有辅件价格设置为0
  563. this.giveAccessoriesSetStatus();
  564. // 初始化计算金额
  565. this.calcPrice();
  566. console.log({
  567. toolsPackage: this.toolsPackage,
  568. instrumentRepair: this.instrumentRepair,
  569. activityList: this.activityList,
  570. courseInfo: this.courseInfo,
  571. instrumentResult: this.instrumentResult,
  572. accessOries: this.accessOries,
  573. musicGroupSubject: this.musicGroupSubject
  574. });
  575. this.$forceUpdate();
  576. },
  577. groupBy(array, f) {
  578. var groups = {};
  579. array.forEach(function(o) {
  580. var group = JSON.stringify(f(o));
  581. groups[group] = groups[group] || [];
  582. groups[group].push(o);
  583. });
  584. return Object.keys(groups).map(function(group) {
  585. return groups[group];
  586. });
  587. },
  588. onQuestions(type) {
  589. if (type == "amr") {
  590. this.$alert(
  591. `<b>革命性的“AMR器乐练习系统”</b><br />它的诞生是基于世界上最优秀的华人管乐指导专家唐嘉宏先生的教育理念,创新开发的一种新型“音乐感官植入程序”,这个程序抛弃了传统的“数线式识谱、机械式节奏、死记式乐理”,它营造出沉浸式可变速演奏过程,采用画面与音乐刺激序列组合而成的特定场景,在趣味性挑战的反复刺激中逐步促进器乐演奏的三核心:“音质→音准→音型”,从而达成演奏各环节水准的均匀提高,产生永久性条件反射式大脑记忆,将多板块知识融会贯通,让抽象的音乐知识刻入脑海里!<br /><br /><b>本练习系统的特点:</b><br /> 1.轻松快速掌握要点,让练习者沉浸其中,远离枯燥!<br /> 2.不假思索就能瞬间唤起反射式记忆,演奏识谱不再慢吞吞!<br /> 3.真正的实践记忆,摆脱纸上谈兵,与实际演奏紧密结合!<br />4.思维+肌肉的双重强化!无缝整合复习系统!<br /> 5.每条练习都经过严谨的编曲,你以为你只是在练习旋律线?其实是整个乐团在为你伴奏!`,
  592. "AMR器乐练习系统",
  593. {
  594. confirmButtonText: "确定",
  595. dangerouslyUseHTMLString: true,
  596. callback: action => {}
  597. }
  598. );
  599. } else if (type == "instrument") {
  600. this.$alert(
  601. `<p style="text-align: justify">1.乐器保养是管乐迷针对乐团学员提供的乐器检查、保养及维修优惠特权;<br />2.该特权为包年制,从开通特权之日起365天内有效;<br />3.特权用户可享受管乐迷提供专业的高级乐器维修技师一年不低于两次下校检查乐器使用情况;<br />4.特权有效期内凭该特权绑定的乐器编号可享受保养人工费减免、非返厂维修人工费优惠等特权;<br />感谢您的信任和支持!</p>`,
  602. "乐器保养特权",
  603. {
  604. confirmButtonText: "确定",
  605. dangerouslyUseHTMLString: true,
  606. callback: action => {}
  607. }
  608. );
  609. }
  610. },
  611. // onTrainChange(item) {
  612. // // 云教练点击时
  613. // // this.$emit("onCheckItem", item, "train");
  614. // },
  615. onCheckItem(item, type) {
  616. // 默认选中不可改
  617. if (item.optionalFlag) return;
  618. // 判断乐保是否可选
  619. if (item.noSelect) return;
  620. // 如果选择的是乐器先把所有选中的取消
  621. if (type == "INSTRUMENT") {
  622. this.instrumentResultList.forEach(group => {
  623. group.forEach(child => {
  624. if (
  625. child.id != item.id ||
  626. (child.id == item.id && child.kitType != item.kitType)
  627. ) {
  628. child.isStatus = false;
  629. }
  630. });
  631. });
  632. }
  633. item.isStatus = !item.isStatus;
  634. console.log(item.isStatus, "onCheckItem");
  635. if (type == "train") {
  636. // 如果选择的是乐保,则把所有辅件价格设置为0
  637. this.giveAccessoriesSetStatus();
  638. }
  639. // 设置是否有减免金额
  640. this.instrumentGetStatus();
  641. // 重新设置乐保状态
  642. this.setLeBaoStatus();
  643. // 重新计算金额
  644. this.calcPrice();
  645. this.$forceUpdate();
  646. },
  647. giveAccessoriesSetStatus() {
  648. let status = false; // 是否有选中云教练
  649. this.toolsPackage.forEach(item => {
  650. if (item.isStatus) {
  651. status = true;
  652. } else {
  653. status = false;
  654. }
  655. });
  656. this.giveAccessoriesStatus = this.isGiveAccessories && status;
  657. this.$forceUpdate();
  658. },
  659. instrumentGetStatus() {
  660. let childItem = {};
  661. this.instrumentResultList.forEach(group => {
  662. group.forEach(child => {
  663. if (child.isStatus) {
  664. childItem = child;
  665. }
  666. });
  667. });
  668. this.remissionCourseFeeStatus =
  669. childItem.kitType == "GROUP" && childItem.groupRemissionCourseFee == 1
  670. ? true
  671. : false;
  672. },
  673. setLeBaoStatus() {
  674. // 设置乐保状态
  675. let status = false; // 是否有选中乐器
  676. this.instrumentResultList.forEach(group => {
  677. group.forEach(item => {
  678. if (item.isStatus) {
  679. status = true;
  680. }
  681. });
  682. });
  683. this.instrumentRepair.forEach(repair => {
  684. if (status) {
  685. repair.noSelect = false;
  686. } else {
  687. repair.noSelect = true;
  688. repair.isStatus = false;
  689. }
  690. });
  691. this.$forceUpdate();
  692. },
  693. calcPrice() {
  694. let ids = [];
  695. let amount = 0,
  696. marketPrice = 0,
  697. goodsPrice = 0, // 乐器两现价
  698. goodsMarketPrice = 0, // 乐器原价
  699. goodsGroupIds = {},
  700. courseKeys = [],
  701. couponPrice = 0, // 优惠金额
  702. goodsIds = [],
  703. buyCalenderActivityId = [], // 小班课
  704. tempCourseFee = 0,
  705. musicClassFee = 0,
  706. tempAccessPrice = 0,
  707. tempAccessMarketPrice = 0,
  708. tempGroupRemissionCourseFee = 0, // 乐团减免费用
  709. contractGoodsIds = ""; // 合同所需要的商品Id (只需要乐器编号)
  710. // 课程
  711. let mgs = this.musicGroupSubject;
  712. let csi = this.courseInfo;
  713. // 加上判断是否有课程信息
  714. if (mgs) {
  715. csi.forEach(item => {
  716. if (item.isStatus) {
  717. musicClassFee += parseFloat(item.courseCurrentPrice);
  718. // if (this.courseViewType != 2) {
  719. // }
  720. if (item.id > 0) {
  721. courseKeys.push(item.id);
  722. }
  723. // 不可选的课程才会减免课程费用
  724. if (!item.isStudentOptional) {
  725. tempGroupRemissionCourseFee += parseFloat(
  726. item.courseCurrentPrice
  727. );
  728. }
  729. marketPrice += parseFloat(item.courseOriginalPrice);
  730. // else {
  731. // marketPrice += parseFloat(item.courseCurrentPrice);
  732. // }
  733. // if (this.courseViewType == 0 && !item.isStudentOptional) {
  734. // marketPrice += parseFloat(item.courseCurrentPrice);
  735. // }
  736. }
  737. });
  738. }
  739. // 云教练
  740. const toolsPackage = this.toolsPackage;
  741. if (toolsPackage.length > 0) {
  742. toolsPackage.forEach(item => {
  743. if (item.isStatus) {
  744. this.buyCloudTeacher = true; // 临时处理,原因一条数据事要使用,如果多条数据会有问题
  745. marketPrice += parseFloat(item.originalAmount);
  746. amount += parseFloat(item.actualAmount);
  747. } else {
  748. this.buyCloudTeacher = false;
  749. }
  750. });
  751. }
  752. // 乐器
  753. let ir = this.instrumentResult;
  754. if (ir.length > 0) {
  755. ir.forEach(item => {
  756. if (item.isStatus) {
  757. if (item.name != "自备乐器") {
  758. contractGoodsIds += item.goodsIdList;
  759. }
  760. if (item.kitType == "FREE") {
  761. amount += 0;
  762. couponPrice = 0; // 优惠金额
  763. } else if (item.kitType == "LEASE") {
  764. couponPrice = item.coupon; // 优惠金额
  765. if (item.name != "自备乐器") {
  766. amount += item.depositFee;
  767. goodsPrice += item.depositFee;
  768. } else {
  769. amount += 0;
  770. }
  771. } else if (item.kitType == "GROUP") {
  772. // 团购
  773. if (
  774. this.courseViewType == 2 &&
  775. this.organId == 55 &&
  776. !this.toolsPackage[0].isStatus
  777. ) {
  778. amount += parseFloat(item.discountPrice);
  779. goodsPrice += parseFloat(item.discountPrice);
  780. couponPrice = item.coupon ? item.coupon : 0;
  781. } else {
  782. amount += parseFloat(item.price);
  783. goodsPrice += parseFloat(item.price);
  784. couponPrice = item.coupon ? item.coupon : 0;
  785. }
  786. }
  787. if (item.kitType == "LEASE") {
  788. if (item.name != "自备乐器") {
  789. marketPrice += parseFloat(item.marketPrice);
  790. goodsMarketPrice += item.depositFee;
  791. }
  792. } else {
  793. marketPrice += parseFloat(item.marketPrice);
  794. goodsMarketPrice += parseFloat(item.marketPrice);
  795. }
  796. // item.id ? goodsGroupIds[item.id] : null
  797. if (item.id) {
  798. goodsGroupIds[item.id] = item.kitType;
  799. }
  800. // 是否减免课程费用,必须团购,并且开启了减免课程费用
  801. if (item.kitType == "GROUP" && item.groupRemissionCourseFee == 1) {
  802. musicClassFee = parseFloat(
  803. musicClassFee - tempGroupRemissionCourseFee
  804. );
  805. }
  806. }
  807. });
  808. }
  809. // 乐器保养
  810. const instrumentRepair = this.instrumentRepair;
  811. if (instrumentRepair.length > 0) {
  812. instrumentRepair.forEach(item => {
  813. if (item.isStatus) {
  814. this.buyMaintenance = true;
  815. marketPrice += item.originalAmount;
  816. amount += parseFloat(item.actualAmount);
  817. } else {
  818. this.buyMaintenance = false;
  819. }
  820. });
  821. }
  822. amount += parseFloat(tempCourseFee + musicClassFee);
  823. // 辅件
  824. if (this.accessOries.length > 0) {
  825. this.accessOries.forEach(item => {
  826. // && this.accessIsShowStatus
  827. if (item.isStatus) {
  828. tempAccessPrice += this.giveAccessoriesStatus
  829. ? 0
  830. : parseFloat(item.price);
  831. amount += this.giveAccessoriesStatus ? 0 : parseFloat(item.price);
  832. if (item.goodsList && item.goodsList.length > 0) {
  833. item.goodsList.forEach(childGoods => {
  834. tempAccessMarketPrice += parseFloat(childGoods.marketPrice);
  835. marketPrice += parseFloat(childGoods.marketPrice);
  836. });
  837. }
  838. goodsGroupIds[item.id] = "ACCESSORIES";
  839. }
  840. });
  841. }
  842. // 小班课
  843. const activityList = this.activityList;
  844. if (activityList.length > 0) {
  845. activityList.forEach(item => {
  846. if (item.isStatus) {
  847. buyCalenderActivityId.push(item.id);
  848. marketPrice += item.originalAmount;
  849. amount += parseFloat(item.actualAmount);
  850. }
  851. });
  852. }
  853. let tempGroupPurchasePrice = amount;
  854. this.payCountMoney = amount;
  855. // 判断减去优惠金额,是否大于0(这里有可能出现负数)
  856. this.ids = ids;
  857. this.needPrice = Number(amount.toFixed(2));
  858. this.orderInfo = {
  859. amount: Number(amount.toFixed(2)),
  860. marketPrice: Number(marketPrice.toFixed(2)),
  861. groupPurchasePrice: tempGroupPurchasePrice,
  862. couponPrice: couponPrice,
  863. goodsGroupIds: goodsGroupIds,
  864. goodsIds: goodsIds.join(","),
  865. contractGoodsIds: contractGoodsIds,
  866. buyCalenderActivityId,
  867. courseKeys: courseKeys,
  868. musicClassFee: musicClassFee,
  869. accessMarketPrice: tempAccessMarketPrice,
  870. accessPrice: tempAccessPrice,
  871. goodsPrice: goodsPrice,
  872. goodsMarketPrice: goodsMarketPrice
  873. };
  874. },
  875. permission(str) {
  876. return permission(str);
  877. },
  878. onCalcSinglePrice(item) {
  879. const tempNum = {
  880. YEAR: 12,
  881. MONTH: 1,
  882. QUARTERLY: 3,
  883. YEAR_HALF: 6
  884. };
  885. const num = (tempNum[item.period] || 1) * item.num;
  886. let price = 0;
  887. if (num % 6 === 0) {
  888. const halfYearNum = Number(num / 6);
  889. this.formatList.forEach(format => {
  890. price += Number(format.halfYearPrice * halfYearNum);
  891. });
  892. } else {
  893. this.formatList.forEach(format => {
  894. price += Number(format.monthPrice * num);
  895. });
  896. }
  897. return numeral(Number(price)).format("0,0.00");
  898. }
  899. },
  900. filters: {
  901. unitFormat(val) {
  902. let template = {
  903. YEAR: "年",
  904. MONTH: "月",
  905. QUARTERLY: "季度",
  906. YEAR_HALF: "半年"
  907. };
  908. return template[val];
  909. },
  910. unitFormatMonth(val, period) {
  911. const tempNum = {
  912. YEAR: 12,
  913. MONTH: 1,
  914. QUARTERLY: 3,
  915. YEAR_HALF: 6
  916. };
  917. return val * (tempNum[period] || 1);
  918. },
  919. unitFormatPrice(val, type, nums, halfYearPrice) {
  920. const tempNum = {
  921. YEAR: 12,
  922. MONTH: 1,
  923. QUARTERLY: 3,
  924. YEAR_HALF: 6
  925. };
  926. const num = (tempNum[type] || 1) * nums;
  927. let price = 0;
  928. if (num % 6 === 0) {
  929. const halfYearNum = Number(num / 6);
  930. price += Number(halfYearPrice * halfYearNum);
  931. } else {
  932. price += Number(val * num);
  933. }
  934. return numeral(price).format("0,0.00");
  935. }
  936. }
  937. };
  938. </script>
  939. <style lang="less" scoped>
  940. @import url("./signUpPayment.less");
  941. .paymentSection {
  942. display: flex;
  943. align-items: center;
  944. margin-top: 13px;
  945. background: #f7f7f7;
  946. border-radius: 6px;
  947. padding: 10px 6px;
  948. cursor: pointer;
  949. .paymentPrice {
  950. span {
  951. font-size: 15px;
  952. font-weight: 500;
  953. color: #f10100;
  954. line-height: 21px;
  955. }
  956. del {
  957. padding-left: 8px;
  958. font-size: 13px;
  959. color: #777777;
  960. }
  961. }
  962. }
  963. </style>