detail.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. <template>
  2. <app-layout>
  3. <app-list v-if="loading" :hidden="false" top="0" :theme="getTheme" :list="list" v-on:update="update" v-on:change="getTotal" v-on:updateList="updateList"></app-list>
  4. <view class="list" v-if="other.length > 0">
  5. <view class="title">其他套餐</view>
  6. <view v-for="(item, index) in other" :key="index" class="item dir-left-nowrap">
  7. <app-composition :theme="getTheme" @click="choose(item)" @look="choose(item)" :item="item"></app-composition>
  8. </view>
  9. </view>
  10. <view v-if="list.length > 0" :class="['bottom-space', `${iphone_x? 'iphone_x':''}`]"></view>
  11. <view v-if="list.length > 0" :class="['bottom','main-between','cross-center', `${iphone_x? 'iphone_x':''}`]">
  12. <view>
  13. <view class="dir-left-nowrap cross-center">
  14. <view>总计</view>
  15. <view class="total-price" :class="getTheme + '-m-text ' + getTheme">¥{{total == 0 ? '0.00' : total}}</view>
  16. </view>
  17. <view class="discount" :class="getTheme + '-m-text ' + getTheme">已省¥{{max_discount}}</view>
  18. </view>
  19. <view @click="toBuy" class="submit-btn" :class="getTheme + '-m-back ' + getTheme">立即购买</view>
  20. </view>
  21. <view class="dialog-bg" v-if="showNoAttr">
  22. <view class="dialog">
  23. <view class="dialog-title">
  24. <view class="dialog-big-title">以下商品未选择规格</view>
  25. <view>请选择规格后购买</view>
  26. </view>
  27. <view :class="[`${noAttrList.length > 4 ? 'dir-left-wrap' : 'main-center'}`,`dialog-goods-list`]">
  28. <view class="dialog-goods" v-for="(item, index) in noAttrList" :key="index">
  29. <image :src="item.cover_pic"></image>
  30. </view>
  31. </view>
  32. <view @click="close" class="dialog-close" :class="getTheme + '-m-text ' + getTheme">我知道了</view>
  33. </view>
  34. </view>
  35. <view class='no-tip' v-if="list.length == 0 && loading">
  36. <image src="/static/image/pull-off.png"></image>
  37. <view>您选购的套餐已下架</view>
  38. <view @click="toComposition" class="to-composition" :class="getTheme + '-m-back ' + getTheme">逛逛套餐专区</view>
  39. </view>
  40. </app-layout>
  41. </template>
  42. <script>
  43. import {mapGetters} from "vuex";
  44. import appList from '../components/app-list/app-list';
  45. import appComposition from "../../../components/basic-component/app-composition/app-composition.vue";
  46. export default {
  47. data() {
  48. return {
  49. list: [],
  50. other: [],
  51. total: 0,
  52. showNoAttr: false,
  53. noAttrList: [],
  54. goods_id: '',
  55. max_discount: '0.00',
  56. page: 2,
  57. hidden: false,
  58. iphone_x: false,
  59. noMore: false,
  60. composition_id: '',
  61. loading: false
  62. }
  63. },
  64. components: {
  65. 'app-list': appList,
  66. 'app-composition': appComposition
  67. },
  68. computed: {
  69. ...mapGetters('mallConfig', {
  70. getTheme: 'getTheme',
  71. })
  72. },
  73. methods: {
  74. choose(item) {
  75. this.composition_id = item.id;
  76. this.total = '0.00';
  77. this.max_discount = '0.00';
  78. this.getDetail();
  79. },
  80. toComposition() {
  81. uni.redirectTo({
  82. url: '/plugins/composition/index/index'
  83. });
  84. },
  85. isCanbuy(goods){
  86. if (this.$user.isLogin() && this.$store.state.user.info) {
  87. let member_level =this.$store.state.user.info.identity.member_level;
  88. if(member_level<goods.member_level){
  89. uni.showModal({
  90. title:"提示",
  91. content:"套餐中有商品"+goods.name+"不能购买,需达到"+goods.member_name+"会员才可购买",
  92. showCancel:true,
  93. buttonText: '升级',
  94. success:(res)=>{
  95. if (res.confirm) {
  96. uni.navigateTo({
  97. // url:"/pages/member/index/index",
  98. url: '/pages/member/upgrade/upgrade?level=' + member_level + '&other=' +goods.member_level
  99. })
  100. return false;
  101. } else if (res.cancel) {
  102. console.log('用户点击取消');
  103. return true;
  104. }
  105. }
  106. })
  107. return true;
  108. }
  109. //return true;
  110. }
  111. },
  112. toBuy() {
  113. let that = this;
  114. let attr = [];
  115. let list = [
  116. {
  117. mch_id: 0,
  118. composition_list: []
  119. }
  120. ]
  121. let isCanbuy = true;
  122. for(let i in that.list) {
  123. // console.log(that.list[i])
  124. // if(!that.isCanbuy(that.list[i].host_list[0])){
  125. // isCanbuy = false;
  126. // }
  127. for(let j in that.list[i].goods_list){
  128. if(!that.isCanbuy(that.list[i].goods_list[j])){
  129. isCanbuy = false;
  130. }
  131. }
  132. }
  133. if(!isCanbuy){
  134. return;
  135. }
  136. if(that.noAttrList.length > 0) {
  137. that.showNoAttr = true;
  138. // for(let i in that.noAttrList) {
  139. // if(!that.isCanbuy(that.noAttrList[i]))
  140. // return;
  141. // }
  142. }
  143. //else {
  144. for(let i in that.list) {
  145. attr = [];
  146. if(that.list[i].choose) {
  147. let arr = {
  148. composition_id: that.list[i].id,
  149. goods_list: []
  150. }
  151. if(that.list[i].host_list.length > 0) {
  152. for(let x in that.list[i].host_list[0].choose_attr.attr_list) {
  153. attr.push({
  154. attr_id: that.list[i].host_list[0].choose_attr.attr_list[x].attr_id,
  155. attr_group_id: that.list[i].host_list[0].choose_attr.attr_list[x].attr_group_id,
  156. })
  157. }
  158. arr.goods_list.push({
  159. id: that.list[i].host_list[0].goods_id,
  160. num: 1,
  161. goods_attr_id: that.list[i].host_list[0].choose_attr.goods_attr_id,
  162. attr: []
  163. })
  164. }
  165. let goods_attr = [];
  166. for(let y in that.list[i].goods_list) {
  167. if(that.list[i].goods_list[y].choose_attr && that.list[i].goods_list[y].choose_attr.attr_list.length > 0) {
  168. for(let x in that.list[i].goods_list[y].choose_attr.attr_list) {
  169. attr.push({
  170. attr_id: that.list[i].goods_list[y].choose_attr.attr_list[x].attr_id,
  171. attr_group_id: that.list[i].goods_list[y].choose_attr.attr_list[x].attr_group_id,
  172. })
  173. }
  174. arr.goods_list.push({
  175. id: that.list[i].goods_list[y].goods_id,
  176. num: 1,
  177. goods_attr_id: that.list[i].goods_list[y].choose_attr.goods_attr_id,
  178. attr: attr,
  179. service_label:that.list[i].goods_list[y].choose_attr.service_label
  180. })
  181. }
  182. }
  183. list[0].composition_list.push(arr);
  184. }else {
  185. let arr = {
  186. composition_id: that.list[i].id,
  187. goods_list: []
  188. }
  189. if(that.list[i].host_list.length > 0 && that.list[i].host_list[0].choose_goods) {
  190. for(let x in that.list[i].host_list[0].choose_attr.attr_list) {
  191. attr.push({
  192. attr_id: that.list[i].host_list[0].choose_attr.attr_list[x].attr_id,
  193. attr_group_id: that.list[i].host_list[0].choose_attr.attr_list[x].attr_group_id,
  194. })
  195. }
  196. arr.goods_list.push({
  197. id: that.list[i].host_list[0].goods_id,
  198. num: 1,
  199. goods_attr_id: that.list[i].host_list[0].choose_attr.goods_attr_id,
  200. attr: attr
  201. })
  202. }
  203. let noChoose = true;
  204. for(let y in that.list[i].goods_list) {
  205. if(that.list[i].goods_list[y].choose_goods && that.list[i].goods_list[y].choose_attr.attr_list) {
  206. noChoose = false;
  207. for(let x in that.list[i].goods_list[y].choose_attr.attr_list) {
  208. attr.push({
  209. attr_id: that.list[i].goods_list[y].choose_attr.attr_list[x].attr_id,
  210. attr_group_id: that.list[i].goods_list[y].choose_attr.attr_list[x].attr_group_id,
  211. })
  212. }
  213. arr.goods_list.push({
  214. id: that.list[i].goods_list[y].goods_id,
  215. num: 1,
  216. goods_attr_id: that.list[i].goods_list[y].choose_attr.goods_attr_id,
  217. attr: attr,
  218. service_label:that.list[i].goods_list[y].choose_attr.service_label
  219. })
  220. }
  221. }
  222. if(arr.goods_list.length > 0) {
  223. list[0].composition_list.push(arr);
  224. }
  225. }
  226. }
  227. if(list[0].composition_list.length == 0) {
  228. uni.showToast({
  229. title: '请选择套餐',
  230. icon: 'none',
  231. duration: 1000
  232. });
  233. }else {
  234. for(let i in list[0].composition_list) {
  235. if(list[0].composition_list[i].goods_list.length == 1) {
  236. list[0].composition_list.splice(i,1)
  237. }
  238. }
  239. if(list[0].composition_list.length == 0) {
  240. uni.showToast({
  241. title: '请选择搭配商品',
  242. icon: 'none',
  243. duration: 1000
  244. });
  245. }else {
  246. list[0].goods_list = [];
  247. for (let j in list[0].composition_list) {
  248. for (let y in list[0].composition_list[j].goods_list) {
  249. list[0].composition_list[j].goods_list[y].cart_id = 0;
  250. list[0].goods_list.push(list[0].composition_list[j].goods_list[y])
  251. }
  252. }
  253. let jump_url = `/pages/order-submit/order-submit?mch_list=${JSON.stringify(list)}`;
  254. jump_url += `&preview_url=${encodeURIComponent(this.$api.composition.order_preview)}&submit_url=${encodeURIComponent(this.$api.composition.order_submit)}&plugin=composition`;
  255. this.$jump({
  256. open_type: 'navigate',
  257. url: jump_url,
  258. });
  259. }
  260. }
  261. //}
  262. },
  263. close () {
  264. this.showNoAttr = false;
  265. },
  266. updateList(e) {
  267. console.log(e)
  268. this.list = e;
  269. },
  270. update(e) {
  271. this.noAttrList = e;
  272. },
  273. getTotal(e,max_discount) {
  274. console.log(e)
  275. this.total = e;
  276. if(max_discount) {
  277. this.max_discount = max_discount.toFixed(2)
  278. }
  279. },
  280. getDetail() {
  281. let that = this;
  282. that.loading = false;
  283. uni.showLoading({
  284. mask: true,
  285. title: '加载中...',
  286. });
  287. let para = {
  288. composition_id: that.composition_id
  289. }
  290. if(that.goods_id > 0) {
  291. para.goods_id = that.goods_id
  292. }
  293. that.$request({
  294. url: that.goods_id > 0 ? that.$api.composition.detail : that.$api.composition.composition_detail,
  295. data: para
  296. }).then(response=>{
  297. that.loading = true;
  298. uni.hideLoading();
  299. if(response.code == 0) {
  300. if(that.goods_id > 0) {
  301. that.list = response.data.other_list;
  302. that.other = response.data.list;
  303. }else {
  304. that.list = [];
  305. that.list[0] = response.data.composition;
  306. }
  307. if(that.other.length < 4) {
  308. that.noMore = true;
  309. }
  310. for(let i in that.list) {
  311. that.list[i].choose = false;
  312. for(let idx in that.list[i].goods_list) {
  313. that.list[i].goods_list[idx].choose_attr = null;
  314. if(that.list[i].goods_list[idx].goods_attr.length == 1) {
  315. that.list[i].goods_list[idx].choose_attr = that.list[i].goods_list[idx].goods_attr[0];
  316. that.list[i].goods_list[idx].choose_attr.number = 1;
  317. that.list[i].goods_list[idx].total_price = (+that.list[i].goods_list[idx].choose_attr.price - +that.list[i].goods_list[idx].price).toFixed(2)
  318. }
  319. if(that.list[i].type == 2) {
  320. that.list[i].host_list[0].choose_attr = null;
  321. if(that.list[i].host_list[0].goods_attr.length == 1) {
  322. that.list[i].host_list[0].choose_attr = that.list[i].host_list[0].goods_attr[0];
  323. that.list[i].host_list[0].choose_attr.number = 1;
  324. that.list[i].host_list[0].total_price = (+that.list[i].host_list[0].choose_attr.price - +that.list[i].host_list[0].price).toFixed(2)
  325. }
  326. that.list[i].goods_list[idx].choose_goods = false;
  327. that.list[i].host_list[0].choose_goods = true;
  328. that.list[i].host_list[0].opacity = 0.3;
  329. }
  330. }
  331. }
  332. if(that.list[0].type == 1) {
  333. that.list[0].choose = true;
  334. that.max_discount = that.list[0].max_discount;
  335. }
  336. }else {
  337. uni.hideLoading();
  338. uni.showToast({
  339. title: response.msg,
  340. icon: 'none',
  341. duration: 1000
  342. });
  343. }
  344. }).catch(response => {
  345. that.loading = true;
  346. uni.hideLoading();
  347. that.$hideLoading();
  348. });
  349. },
  350. getMore() {
  351. let that = this;
  352. uni.showLoading({
  353. title: '加载中'
  354. });
  355. that.$request({
  356. url: that.$api.composition.detail,
  357. data: {
  358. goods_id: that.goods_id,
  359. composition_id: that.composition_id,
  360. page: that.page
  361. }
  362. }).then(response=>{
  363. uni.hideLoading();
  364. if(response.code == 0) {
  365. if(response.data.list.length == 0) {
  366. this.noMore = true;
  367. return false;
  368. }
  369. that.page++;
  370. that.other = that.other.concat(response.data.list);
  371. for(let i in that.list) {
  372. that.list[i].choose = false;
  373. for(let idx in that.list[i].goods_list) {
  374. that.list[i].goods_list[idx].choose_attr = null;
  375. if(that.list[i].type == 2) {
  376. that.list[i].host_list[0].choose_attr = null;
  377. that.list[i].host_list[0].opacity = 1;
  378. that.list[i].goods_list[idx].choose_goods = false;
  379. that.list[i].host_list[0].choose_goods = false;
  380. }
  381. }
  382. }
  383. }else {
  384. uni.hideLoading();
  385. uni.showToast({
  386. title: response.msg,
  387. icon: 'none',
  388. duration: 1000
  389. });
  390. }
  391. }).catch(response => {
  392. that.$hideLoading();
  393. });
  394. },
  395. },
  396. onReachBottom() {
  397. if(!this.noMore) {
  398. this.getMore();
  399. }
  400. },
  401. onLoad(option) {
  402. let that = this;
  403. uni.getSystemInfo({
  404. success: function (res) {
  405. if(res.model.indexOf('iPhone X') > -1 || res.model.indexOf('iPhone 11') > -1 || res.model.indexOf('iPhone11') > -1 || res.model.indexOf('iPhone12') > -1 || res.model.indexOf('Unknown Device') > -1) {
  406. that.iphone_x = true;
  407. }
  408. }
  409. })
  410. this.goods_id = option.goods_id > 0 ? option.goods_id : '';
  411. this.composition_id = option.composition_id;
  412. that.getDetail();
  413. },
  414. }
  415. </script>
  416. <style scoped lang="scss">
  417. .no-tip {
  418. position: fixed;
  419. top: #{120rpx};
  420. left: 0;
  421. right: 0;
  422. margin: 0 auto;
  423. color: #666666;
  424. font-size: #{24rpx};
  425. width: #{240rpx};
  426. text-align: center;
  427. image {
  428. height: #{240rpx};
  429. width: #{240rpx};
  430. margin-bottom: #{20rpx};
  431. }
  432. .to-composition {
  433. border-radius: #{33rpx};
  434. width: #{246rpx};
  435. text-align: center;
  436. height: #{66rpx};
  437. line-height: #{66rpx};
  438. margin-top: #{38rpx};
  439. color: #fff;
  440. }
  441. }
  442. .list {
  443. padding: #{24rpx};
  444. .title {
  445. font-size: #{28rpx};
  446. color: #353535;
  447. }
  448. .item {
  449. margin-top: #{20rpx};
  450. padding: #{24rpx};
  451. border-radius: #{16rpx};
  452. background-color: #fff;
  453. }
  454. }
  455. .dialog-bg {
  456. position: fixed;
  457. top: 0;
  458. left: 0;
  459. width: 100%;
  460. height: 100%;
  461. background-color: rgba(0,0,0,.3);
  462. z-index: 202;
  463. .dialog {
  464. width: #{630rpx};
  465. margin: #{260rpx} auto 0;
  466. background-color: #fff;
  467. padding-top: #{40rpx};
  468. border-radius: #{16rpx};
  469. .dialog-title {
  470. text-align: center;
  471. font-size: #{26rpx};
  472. color: #999999;
  473. .dialog-big-title {
  474. font-size: #{32rpx};
  475. color: #353535;
  476. margin-bottom: #{10rpx};
  477. }
  478. }
  479. .dialog-goods-list {
  480. padding: 0 #{65rpx};
  481. margin: #{26rpx} 0 #{48rpx};
  482. .dialog-goods {
  483. width: #{80rpx};
  484. height: #{80rpx};
  485. border-radius: #{8rpx};
  486. margin: #{10rpx};
  487. image {
  488. border-radius: #{8rpx};
  489. width: #{80rpx};
  490. height: #{80rpx};
  491. }
  492. }
  493. }
  494. .dialog-close {
  495. width: #{630rpx};
  496. border-top: #{2rpx} solid #e2e2e2;
  497. font-size: #{32rpx};
  498. text-align: center;
  499. padding: #{25rpx} 0;
  500. }
  501. }
  502. }
  503. .bottom {
  504. width: 100%;
  505. height: #{120rpx};
  506. position: fixed;
  507. bottom: 0;
  508. left: 0;
  509. z-index: 30;
  510. background-color: #fff;
  511. border-top: #{2rpx} solid #e2e2e2;
  512. font-size: #{24rpx};
  513. color: #353535;
  514. padding: 0 #{20rpx};
  515. &.iphone_x {
  516. height: #{150rpx};
  517. padding-bottom: #{50rpx};
  518. }
  519. .total-price {
  520. font-size: #{36rpx};
  521. margin-left: #{8rpx};
  522. }
  523. .submit-btn {
  524. width: #{222rpx};
  525. height: #{78rpx};
  526. border-radius: #{39rpx};
  527. color: #fff;
  528. font-size: #{32rpx};
  529. line-height: #{78rpx};
  530. text-align: center;
  531. }
  532. .discount {
  533. font-size: #{24rpx};
  534. }
  535. }
  536. .bottom-space {
  537. height: #{110rpx};
  538. &.iphone_x {
  539. height: #{160rpx};
  540. }
  541. }
  542. </style>