<template> <view class="spec-content"> <view class="topBar" :style="{'top':topBarTop+'px','height':topBarHeight+'px'}"> <u-icon @click="goBack" name="arrow-left" color="#000000" size="20"></u-icon> </view> <view v-if="goodInfo"> <view class="uni-margin-wrap"> <swiper v-if="goodInfo.pics.introImagesApplet" class="swiper"> <swiper-item v-for="item in goodInfo.pics.introImagesApplet" :key="item"> <image :src="item" class="swiper_img" mode="scaleToFill"></image> </swiper-item> </swiper> <swiper v-else class="swiper"> <swiper-item v-for="item in goodInfo.pics.introImages" :key="item"> <image :src="item" class="swiper_img" mode="scaleToFill"></image> </swiper-item> </swiper> </view> <view class="good spec-info-left"> <view class="good-name">{{ goodInfo.name }}</view> <view class="specs"> <!-- 规格 --> <view v-for="specItem in goodInfo.specs" :key="specItem.specId"> <div class="good-spec-name">{{ specItem.specName }}</div> <view class="good-spec-rule"> <div v-for="specItemRule in specItem.rules" class="div_item" :key="specItemRule.ruleId" @click="selectRoles(specItemRule, specItem)"> <div v-if="specItemRule.isRecommend=='1'" :class="[UseIt(specItemRule.ruleId)?'disabledStyle':'']" class="default"></div> <button class="good-spec-rule-item" :disabled="UseIt(specItemRule.ruleId)" :class="{ active: isActvie(specItemRule) }"> <view @click.prevent="checkSku(specItemRule)">{{ specItemRule.ruleName }}</view> </button> </div> </view> </view> </view> </view> <view class="spec-detail"> <view class="spec-detail-title spec-info-left">商品详细</view> <view v-if="goodInfo.pics.detailImagesApplet"> <view class="spec-detail-img" v-for="item in goodInfo.pics.detailImagesApplet" :key="item"> <image class="spec-detail-img-item" :src="item" mode="scaleToFill"></image> </view> </view> <view v-else class="spec-detail-img" v-for="item in goodInfo.pics.detailImages" :key="item"> <image class="spec-detail-img-item" :src="item" mode="scaleToFill"></image> </view> <!-- 底部空白 --> <view class="good-select-height"></view> </view> <view class="good-select" :style="{'padding-bottom':BottomSafeHeight+'px; height:'+(getPx(268)-BottomSafeHeight)+'px'}"> <view class="good-select-price"> <div class="price"> <view class="good-select-price-normal"><text class="moneyLog">¥</text>{{ Utils.isInteger(priceTotal.discount) }}</view> <view class="good-select-price-small" v-show="priceTotal.price!=priceTotal.discount">¥<text class="num">{{ Utils.isInteger(priceTotal.price) }}</text></view> </div> <div v-if="!size > 0" style="color: orangered">已售罄</div> <div v-else class="set_size"> <view class="subtract" @click="reduceGood"></view> <span>{{ size }}</span> <view class="add" @click="addGood" ></view> </div> </view> <view v-if="size > 0" class="good-select-cont"> <view> <a class="good-select-btn1" @click="getallNum()" v-if="userms"> 立即购买 </a> <button v-if="!userms" class="good-select-btn1" style="border-radius: 0;" open-type="getPhoneNumber" @getphonenumber="getallNum"> 立即购买 </button> </view> <span class="good-select-btn2" @click="shoppingCart" type="default">加入购物袋</span> </view> </view> </view> <show-toast ref="toast"/> </view> </template> <script> import Utils from '@/utils/utils' import User from '@/request/user'; import Order from '@/request/order' import Menu from '@/request/menu' export default { data() { return { title: 'Hello1', imglist: [{ img: "/static/logo.png" }, { img: "/static/ggxz01.png" }], goodInfo: null, selected: [], available: [], goods: {}, skusDefault: [], skusSellout: [], loginInfo:"", pirce: 0, size: 1, topBarTop:0, topBarHeight:0, BottomSafeHeight:0, Utils, } }, onShow() { uni.removeStorageSync('goodsList'); this.BottomSafeHeight = uni.getStorageSync('BottomSafeHeight') }, mounted(){ // 获取胶囊坐标位置 const res = wx.getMenuButtonBoundingClientRect() const menuInfoTop = res.top const menuInfoBottom = res.bottom const menuHeight = res.height let headHeight = 0 wx.getSystemInfo({ success: (res) => { headHeight = res.statusBarHeight } }) this.topBarTop = menuInfoTop this.topBarHeight = menuHeight }, onLoad() { if(!this.userms){ User.wxLoginAndGetOpenid(true).then(loginInfo=>{ this.loginInfo = loginInfo }) } uni.removeStorageSync('goodsList'); const goodsInfo = JSON.parse(uni.getStorageSync('goodsInfo')); this.goodInfo = goodsInfo; console.log(JSON.parse(JSON.stringify(this.goodInfo))); this.initInfo(this.goodInfo) }, // watch:{ // selected(val){ // console.log(val,'val') // const {skus,specs} = this.goodInfo // console.log(skus,'--------skus',specs,'--------specs') // const ruleIdList = val.map(res=>res.ruleId) // console.log(ruleIdList) // } // }, methods: { getPx(rpx) { return rpx * (wx.getSystemInfoSync().windowWidth / 750); }, initInfo(goodsInfo){ this.available = [] this.selected = [] const skus = goodsInfo.skus; if (skus) { const sku = skus.find(v => v.isDefault == 1 && v.state == 1) || skus.find(v => v.isDefault == 0 && v.state == 1); this.skusDefault = skus.find(v => v.isDefault == 1); this.skusSellout = skus.find(v => v.isDefault == 1 && v.state == 1) || skus.find(v => v.state == 1) || skus.find(v => v.isDefault == 1) || skus[0] if (sku){ this.selected.push(...sku.rules) }else{ this.selected = [] }; skus.forEach(item => { if (item.state == 1) { item.rules.forEach(rule => { this.available.push(rule.ruleId) }) } }) } this.$nextTick(() => { this.buildGoods(e => { if (e) { this.size = 1 } else { this.size = 0 } }) this.$forceUpdate() }) }, goBack(){ wx.navigateBack({ delta: 1 }); }, setDefaultStyle(id) { let selected = false; if (this.skusDefault && this.skusDefault.rules) { this.skusDefault.rules.forEach(item => { if (item.ruleId == id) { selected = true } }); } return selected }, checkSku(specItemRule) { const value = this.UseIt(specItemRule.ruleId) if(value) { this.showToast({ title: '该选项已售罄', icon: 'none' }); return } }, selectRoles(specItemRule, parent) { const value = this.UseIt(specItemRule.ruleId) if(value) { this.showToast({ title: '该选项已售罄', icon: 'none' }); return } const { selected } = this; selected.forEach((item, index) => { if (item.specId == parent.specId) { selected.splice(index, 1) } }); this.selected.push({ ...specItemRule, specId: parent.specId }) this.buildGoods() }, isActvie(data) { return this.selected.filter(item => item.ruleId == data.ruleId).length > 0 }, buildGoods(callback) { const skusObj = {}; let selectedSku = null const skus = this.goodInfo.skus; skus.forEach(item => { const ruleId = item.rules.map(item => item.ruleId); skusObj[item.skuId] = ruleId.sort() }); const selectedrules = this.selected.map(item => item.ruleId).sort() for (let item in skusObj) { const selStr = selectedrules.toString() const itemStr = skusObj[item].toString() if (selStr === itemStr) selectedSku = item; } const [sku] = skus.filter(item => item.skuId == selectedSku); if (!sku || skus.state == 2) { this.showToast({ title: '本商品已经售罄', icon: 'none' }); callback && callback() } else { const { category, ...goods } = this.goodInfo; goods.skus = [sku]; goods.sku = sku goods.flag = true; goods.skuId = selectedSku goods.categoryId = category.id; goods.goodsName = category.name; this.goods = goods callback && callback(true) } }, checkNum(type){ const shopCarInfo = uni.getStorageSync('shopCarInfo') || [] let shopCarNum = (type=='add'?1:0) shopCarInfo.forEach(item=> shopCarNum+=item.num) let countOfOrder = uni.getStorageSync('countOfOrder'); if ((Number(this.size) + Number(shopCarNum)) <= countOfOrder) { return true } else { this.showToast({ title: '最多可一次购买'+countOfOrder+'杯', icon: 'none', }); } }, addGood() { if(this.checkNum('add')){ this.size = this.size + 1; } }, reduceGood() { const { size } = this if (size > 1) { this.size = size - 1; } }, async shoppingCart() { if(this.checkNum('addShop')){ const { goods } = this; const { data } = await Order.checkSku({skuId:goods.skuId}) const {state,goods:newgoods} = data.data const newInfo = JSON.parse(JSON.stringify(newgoods)) newInfo.category = this.goodInfo.category // newInfo.skus.map(res=>res.state = '2') // newInfo.skus[0].state = '2' this.goodInfo = {...newInfo} this.initInfo(this.goodInfo) if(state == 2){ this.showToast({ title: '本商品已经售罄', icon: 'none' }); this.getMenuList() return; }else{ goods.num = this.size; Utils.getallNum(goods) uni.switchTab({ url: '/pages/menu/menu' }) } // return // const { data } = await Order.checkSku({skuId:goods.skuId}) // else{ // goods.num = this.size; // Utils.getallNum(goods) // uni.switchTab({ url: '/pages/menu/menu' }) // } } }, async getallNum(e) { let Authorization = uni.getStorageSync('Authorization'); if (!Authorization) { this.loginByPhoneNumber(e); return } const { goods } = this; const { data } = await Order.checkSku({skuId:goods.skuId}) const {state,goods:newgoods} = data.data const newInfo = JSON.parse(JSON.stringify(newgoods)) newInfo.category = this.goodInfo.category // newInfo.skus.map(res=>res.state = '2') // newInfo.skus[0].state = '2' this.goodInfo = {...newInfo} this.initInfo(this.goodInfo) if(state == 2){ this.showToast({ title: '本商品已经售罄', icon: 'none' }); this.getMenuList() return; }else{ goods.num = this.size Utils.addGoods(goods) uni.navigateTo({ url: `/orderSubPackage/pages/settlement/index?buyType=1&goodsList=1` }) } }, async getMenuList() { const shopId = uni.getStorageSync('shopData').id let { data } = await Menu.getMenuList(shopId); // console.log("menus:"+JSON.stringify(data)); if (data.code == 200) { data.data = data.data; this.$store.commit('setMenuAllInfo', data.data); this.$store.commit('setMenuCategorys', data.data.categorys); uni.setStorageSync('countOfOrder', parseInt(data.data.countOfOrder)); // this.$refs.MenuAssembly.createList(data.data.categorys) } }, // 付款前未登录发起授权 loginByPhoneNumber(e) { if (e.detail.errMsg == 'getPhoneNumber:ok') { e.loginInfo = this.loginInfo User.getPhoneNumber(e); } else if (e.detail.errMsg == "getPhoneNumber:fail user deny") { this.showToast({ title: '已拒绝手机号授权', icon: 'error' }) } }, UseIt(ruleId) { return this.available.indexOf(ruleId) == -1 } }, computed: { userms() { return this.$store.getters.Authorization; }, priceTotal() { let discount = 0; let price = 0; const { goods,skusSellout } = this; if (goods.sku) { discount = goods.sku.discount * this.size price = goods.sku.price * this.size }else if(skusSellout){ discount = Number(skusSellout.discount) price = Number(skusSellout.price) } return { discount: discount.toFixed(2), price: price.toFixed(2) } } } } </script> <style lang="scss"> .topBar{ // border: 1px solid red; position: fixed; z-index: 99999999; width: 100%; display: flex; align-items: center; padding-left: 34rpx; } .uni-margin-wrap { width: 100%; } .swiper { height: 561rpx; width: 100%; } .swiper_img { width: 100%; height: 100% !important; vertical-align: bottom; } .spec-content { width: 100%; overflow-x: hidden; } .spec-info-left { padding: 24rpx 32rpx; } .good { display: block; width: 100%; text-align: left; .good-name { font-size: 28rpx; font-family: PingFangSC-Medium, PingFang SC; font-weight: 500; color: #333333; line-height: 40rpx; padding-bottom: 22rpx; // background-color: #000000; } .specs { // margin-top: 30rpx; } .good-spec-name { padding-top: 30rpx; font-family: PingFangSC-Regular, PingFang SC; color: #999999; font-weight: 400; font-size: 24rpx; text-align: left; line-height: 34rpx; // background-color: blue; } .good-spec-rule { display: flex; flex-direction: row; justify-content: flex-start; margin-top: 26rpx; flex-wrap: wrap; border-radius: 0rpx; .div_item { position: relative; height: 48rpx; margin-right: 32rpx; line-height: 48rpx; min-width: 120rpx; z-index: 999999; .default { width: 45rpx; height: 48rpx; background: url('@/static/imgs/tuijian.png') center center no-repeat; background-size: 100%; position: absolute; right: -17rpx; top: -30rpx; z-index: 9; } } } } .good-spec-rule-item { padding: 7rpx 48rpx; width: 100%; height: 100%; font-size: 24rpx; color: #333333; text-align: center; font-weight: 400; display: inline-block; margin: 0; margin: 0; line-height: 40rpx; border-radius: 0rpx; border: none; font-family: PingFangSC-Regular, PingFang SC; background: #EAEAEA; pointer-events: none; &.active { font-weight: 400; padding: 7rpx 48rpx 6rpx 48rpx; background: #0050F6; color: #FFFFFF; border-radius: 0rpx; border: 0rpx; font-family: PingFangSC-Regular, PingFang SC; } view { pointer-events: none; } } .good-spec-rule-item::after{ border-radius: 0rpx; border: 0rpx; } button[disabled]:not([type]) { background: url('@/static/imgs/shouqingsku.png') no-repeat; background-size: 100% 48rpx; } .spec-detail { width: 100%; height: 100%; } .spec-detail-title { width: 112rpx; height: 40rpx; font-size: 28rpx; font-family: PingFangSC-Medium, PingFang SC; color: #333333; padding-top: 32rpx !important; padding-bottom:22rpx !important } .spec-detail-img { margin-left: 30rpx; margin-right: 30rpx; height: 500rpx; } .spec-detail-img:last-child{ margin-bottom: 115rpx; } .spec-detail-img-item { width: 100%; height: 100%; } .good-select-height { height: 200rpx; } .good-select { width: 100%; position: fixed; bottom: 0rpx; text-align: center; // height: 268rpx; background-color: #fff; height: auto; padding-bottom: 20rpx; box-shadow: 0px -2px 8px 0px rgba(214, 214, 214, 0.5); } .good-select-price { display: flex; align-items: center; // height: 68rpx; background: #FFFFFF; justify-content: space-between; align-items: center; padding: 24rpx 32rpx 24rpx 32rpx; .price{ display: flex; align-items: flex-end; justify-content: flex-start; .good-select-price-normal { font-family: Futura-Medium, Futura; letter-spacing: 1px; font-size: 36rpx; color: #333333; margin-right: 12rpx; font-weight: 500; line-height: 38rpx; .moneyLog { font-size: 32rpx; font-weight: 900; } } .good-select-price-small { font-size: 20rpx; font-family: ArialMT; line-height: 32rpx; color: #999999; .num { text-decoration: line-through; } } } } .good-select-cont { display: flex; flex-direction: row; align-items: center; justify-content: center; justify-content: space-between; padding: 0 30rpx; } .good-select-btn1 { width: 328rpx; height: 104rpx; border: 2rpx solid #0050F6; font-size: 28rpx; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #0050F6; border-radius: 2px; line-height: 104rpx; text-align: center; background: #FFFFFF; } .good-select-btn2 { width: 328rpx; height: 106rpx; border-radius: 2px; font-size: 28rpx; font-family: PingFangSC-Regular, PingFang SC; background: #0050F6; line-height: 104rpx; text-align: center; color: #fff; } .set_size { display: flex; width: 150rpx; justify-content: space-between; align-items: center; .subtract { width: 40rpx; height: 40rpx; background: url('@/static/imgs/jianhao.png') center center no-repeat; background-size:100% 100%; } .add { width: 40rpx; height: 40rpx; background: url('@/static/imgs/jiahao.png') center center no-repeat; background-size:100% 100%; } span { margin: 0 22rpx 0 26rpx; font-size: 32rpx; font-family: ArialMT; color: #000000; } } </style>