subject-preview.vue 41 KB

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