|
|
@ -3,7 +3,7 @@ |
|
|
|
<view class="gi-header"> |
|
|
|
<!-- banner 图 --> |
|
|
|
<view class="gi-box"> |
|
|
|
<swiper class="gi-banner" @change="curBannerIdx = $event.detail.current" autoplay> |
|
|
|
<swiper class="gi-banner" @change="curBannerIdx = $event.detail.current" autoplay circular> |
|
|
|
<swiper-item v-for="(e, i) in goodsInfo.product_imgs" :key="i"> |
|
|
|
<image class="gb-img" mode="aspectFill" :src="e"></image> |
|
|
|
</swiper-item> |
|
|
@ -47,14 +47,14 @@ |
|
|
|
</view> |
|
|
|
<!-- 配送 说明 已选 --> |
|
|
|
<view class="gi-selected"> |
|
|
|
<view class="gs-item"> |
|
|
|
<view class="gs-item" @click="deliveryLineClick"> |
|
|
|
<view class="gs-name">配送</view> |
|
|
|
<view class="gs-content"> |
|
|
|
<text class="gc-txt">{{ getDeliveryTxt }}</text> |
|
|
|
</view> |
|
|
|
<image class="gs-icon" mode="aspectFit" src="/subpackage/mall/static/images/arrow_9ad.png"></image> |
|
|
|
</view> |
|
|
|
<view class="gs-item"> |
|
|
|
<view class="gs-item" @click="explainLineClick"> |
|
|
|
<view class="gs-name">说明</view> |
|
|
|
<view class="gs-content"> |
|
|
|
<block v-for="(e, i) in getExplianKeyTxt" :key="i"> |
|
|
@ -64,17 +64,37 @@ |
|
|
|
</view> |
|
|
|
<image class="gs-icon" mode="aspectFit" src="/subpackage/mall/static/images/arrow_9ad.png"></image> |
|
|
|
</view> |
|
|
|
<view class="gs-item"> |
|
|
|
<view class="gs-item" @click="specificationLineClick" v-if="goodsInfo.product_spec_multi === 1"> |
|
|
|
<view class="gs-name">已选</view> |
|
|
|
<view class="gs-content"> |
|
|
|
<block v-for="i in 3" :key="i"> |
|
|
|
<image class="gc-icon"></image> |
|
|
|
<text class="gc-txt">配送/自提</text> |
|
|
|
</block> |
|
|
|
<text class="gc-txt">{{ selectedSpecificationText }}</text> |
|
|
|
</view> |
|
|
|
<image class="gs-icon" mode="aspectFit" src="/subpackage/mall/static/images/arrow_9ad.png"></image> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<view class="gi-appraise-info"> |
|
|
|
<view class="gai-title-bar"> |
|
|
|
<view class="gtb-tit">评价({{ appraiseList.length || 0 }})</view> |
|
|
|
<view class="gtb-link"> |
|
|
|
<text>查看全部</text> |
|
|
|
<image class="gl-icon" mode="aspectFit" src="/subpackage/mall/static/images/arrow_874.png"></image> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<view class="gai-ls"> |
|
|
|
<block v-for="(e, i) in appraiseList" :key="i"> |
|
|
|
<appraise-item |
|
|
|
:name="e.sys_optuname" |
|
|
|
:avater="e.sys_optuimgs" |
|
|
|
:time="e.created_at" |
|
|
|
:appraise="e.product_comment_text" |
|
|
|
:level-num="e.product_comment_level" |
|
|
|
:img-list="e.product_comment_imgs" |
|
|
|
></appraise-item> |
|
|
|
</block> |
|
|
|
</view> |
|
|
|
|
|
|
|
</view> |
|
|
|
<!-- 商品详情 --> |
|
|
|
<view class="gi-detail"> |
|
|
|
<view class="gd-title"> |
|
|
@ -94,17 +114,19 @@ |
|
|
|
<view class="gl-box"> |
|
|
|
<image class="gb-icon" mode="aspectFit" src="/subpackage/mall/static/images/shopping_cart.png"></image> |
|
|
|
<view class="gb-txt">购物车</view> |
|
|
|
<view class="gb-num">99</view> |
|
|
|
<view class="gb-num" v-if="goodsCartNum>0">{{ goodsCartNum }}</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<view class="gfb-btns"> |
|
|
|
<view class="gb-item">加入购物车</view> |
|
|
|
<view class="gb-item">立即购买</view> |
|
|
|
<view class="gb-item" @click="addShoppingCart">加入购物车</view> |
|
|
|
<view class="gb-item" @click="buyImmediately">立即购买</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<service-modal ref="serviceModal"></service-modal> |
|
|
|
<delivery-modal ref="deliveryModal"></delivery-modal> |
|
|
|
<service-modal ref="serviceModal" :explian-obj="goodsInfo.product_service_tags"></service-modal> |
|
|
|
<delivery-modal ref="deliveryModal" :explian-str="goodsInfo.product_logistics_desc || ''"></delivery-modal> |
|
|
|
|
|
|
|
<specification-modal ref="specificationModal" ></specification-modal> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
|
|
|
@ -112,17 +134,24 @@ |
|
|
|
import { routeTo, showLoad, hideLoad, showModal, tsRoute, jsonStr, jsonPar } from "@/utils/util.js"; |
|
|
|
import serviceModal from "./modules/goods_info/service_modal.vue"; |
|
|
|
import deliveryModal from "./modules/goods_info/delivery_modal.vue"; |
|
|
|
import specificationModal from "../components/specification_modal.vue"; |
|
|
|
import appraiseItem from "../components/appraise_item.vue"; |
|
|
|
import { MALL_API } from "../js/api"; |
|
|
|
import server from "../js/server"; |
|
|
|
export default { |
|
|
|
components: { |
|
|
|
serviceModal, |
|
|
|
deliveryModal, |
|
|
|
specificationModal, |
|
|
|
appraiseItem, |
|
|
|
}, |
|
|
|
data(){ |
|
|
|
return { |
|
|
|
goodsInfo: {}, |
|
|
|
curBannerIdx: 0, |
|
|
|
goodsInfo: {}, // 商品详情数据 |
|
|
|
curBannerIdx: 0, // 当前banner索引 |
|
|
|
selectedSpecificationInfo: {}, // 已选规格信息 |
|
|
|
goodsCartNum: 0, // 购物车数量 |
|
|
|
appraiseList: [], // 评价列表 |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
@ -180,15 +209,137 @@ export default { |
|
|
|
if(isNaN(_num))return 0; |
|
|
|
let _rNum = Math.round(_num) |
|
|
|
return _rNum > 5 ? 5 : _rNum; |
|
|
|
}, |
|
|
|
selectedSpecificationText(){ |
|
|
|
let { selectedSpecificationInfo } = this; |
|
|
|
if(selectedSpecificationInfo?.spec_arr?.length)return selectedSpecificationInfo?.spec_arr?.join(';'); |
|
|
|
return '' |
|
|
|
} |
|
|
|
}, |
|
|
|
onLoad(options){ |
|
|
|
let _bid = options?.brand_id ?? ''; |
|
|
|
this.getGoodsInfo({ |
|
|
|
brand_id: options?.brand_id ?? '', |
|
|
|
brand_id: _bid, |
|
|
|
id: options?.id ?? '' |
|
|
|
}) |
|
|
|
}); |
|
|
|
this.goodsCartList({ brand_id: _bid }); |
|
|
|
this.goodsComment({ |
|
|
|
brand_id: _bid, |
|
|
|
proid: options?.id ?? '' |
|
|
|
}); |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
specificationLineClick(){ |
|
|
|
let { goodsInfo, getQueryForSpecificationModal } = this; |
|
|
|
let _sModalRef = this.$refs.specificationModal; |
|
|
|
_sModalRef.alert({ |
|
|
|
...getQueryForSpecificationModal(goodsInfo), |
|
|
|
onlyGet: true, |
|
|
|
success: async res => { |
|
|
|
this.selectedSpecificationInfo = res; |
|
|
|
_sModalRef.hide(); |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
// 加入购物车 |
|
|
|
addShoppingCart(){ |
|
|
|
let { goodsInfo, getQueryForSpecificationModal } = this; |
|
|
|
let _sModalRef = this.$refs.specificationModal; |
|
|
|
// 无规格 |
|
|
|
if(goodsInfo?.product_spec_multi === 0)return this.addShoppingCartOperate({ |
|
|
|
brand_id: goodsInfo?.brand_id, |
|
|
|
id: goodsInfo?.id, |
|
|
|
}); |
|
|
|
// 规格弹窗 |
|
|
|
_sModalRef.alert({ |
|
|
|
...getQueryForSpecificationModal(goodsInfo), |
|
|
|
onlyGet: true, |
|
|
|
success: async res => { |
|
|
|
this.selectedSpecificationInfo = res; |
|
|
|
this.addShoppingCartOperate({ |
|
|
|
brand_id: goodsInfo?.brand_id ?? '', |
|
|
|
id: goodsInfo?.id ?? '', |
|
|
|
nums: res?.nums ?? '', |
|
|
|
spec_arr: res?.spec_arr ?? [] |
|
|
|
}) |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
async addShoppingCartOperate({ brand_id, id, nums = 1, spec_arr = [] }){ |
|
|
|
let _sModalRef = this.$refs.specificationModal; |
|
|
|
let _cartAddRes = await _sModalRef.goodsCartAdd({ brand_id, id, nums, spec_arr }); |
|
|
|
if(_cartAddRes){ |
|
|
|
_sModalRef.hide(); |
|
|
|
this.goodsCartList({ brand_id }); |
|
|
|
} |
|
|
|
}, |
|
|
|
// 立即购买 |
|
|
|
buyImmediately(){ |
|
|
|
let { goodsInfo, getQueryForSpecificationModal } = this; |
|
|
|
let _sModalRef = this.$refs.specificationModal; |
|
|
|
// 无规格 |
|
|
|
if(goodsInfo?.product_spec_multi === 0)return this.buyOperate({ |
|
|
|
brand_id: goodsInfo?.brand_id, |
|
|
|
id: goodsInfo?.id, |
|
|
|
}); |
|
|
|
// 规格弹窗 |
|
|
|
_sModalRef.alert({ |
|
|
|
...getQueryForSpecificationModal(goodsInfo), |
|
|
|
onlyGet: true, |
|
|
|
success: async res => { |
|
|
|
this.selectedSpecificationInfo = res; |
|
|
|
this.buyOperate({ |
|
|
|
brand_id: goodsInfo?.brand_id ?? '', |
|
|
|
id: goodsInfo?.id ?? '', |
|
|
|
nums: res?.nums ?? '', |
|
|
|
spec_arr: res?.spec_arr ?? [] |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
async buyOperate({ brand_id, id, nums = 1, spec_arr = [] }){ |
|
|
|
let hgbRes = await this.homeGoodsBuy({ brand_id, id, nums, spec_arr }); |
|
|
|
console.log('hgbRes = ', hgbRes); |
|
|
|
// 预购买成功 |
|
|
|
if(hgbRes?.total&&hgbRes?.list.length){ |
|
|
|
let _amount = hgbRes.list.reduce((total, item, idx)=>{ |
|
|
|
let _unitPrice = 0; |
|
|
|
if(item?.product_spec_multi === 0)_unitPrice = item?.product_spec_single_info?.price ?? 0; |
|
|
|
if(item?.product_spec_multi === 1)_unitPrice = item?.product_spec_multi_info?.price ?? 0; |
|
|
|
let _price = (item?.product_nums ?? 0) * _unitPrice; |
|
|
|
return total + _price; |
|
|
|
}, 0); |
|
|
|
let _query = { |
|
|
|
goodsList: hgbRes?.list, |
|
|
|
product_ids: [ id ], |
|
|
|
go_buy: 1, |
|
|
|
price_amount: _amount |
|
|
|
} |
|
|
|
console.log(_query); |
|
|
|
}else{ |
|
|
|
showModal({content: '购买操作失败,请稍后重试!'}); |
|
|
|
console.warn('homeGoodsBuy res =>', hgbRes); |
|
|
|
} |
|
|
|
}, |
|
|
|
getQueryForSpecificationModal(goodsInfo){ |
|
|
|
return { |
|
|
|
id: goodsInfo?.id ?? '', |
|
|
|
brand_id: goodsInfo?.brand_id ?? '', |
|
|
|
poster: goodsInfo?.product_imgs?.[0] ?? '', |
|
|
|
name: goodsInfo?.product_name ?? '', |
|
|
|
price: goodsInfo?.product_price ?? '', |
|
|
|
specArr: goodsInfo?.product_spec_multi_info?.spec_data ?? [], |
|
|
|
} |
|
|
|
}, |
|
|
|
// 显示服务说明 |
|
|
|
explainLineClick(){ |
|
|
|
this.$refs?.serviceModal?.show?.(); |
|
|
|
}, |
|
|
|
// 显示配送说明 |
|
|
|
deliveryLineClick(){ |
|
|
|
this.$refs?.deliveryModal?.show?.(); |
|
|
|
}, |
|
|
|
// 获取商品详情信息 |
|
|
|
getGoodsInfo({ brand_id, id }){ |
|
|
|
showLoad(); |
|
|
|
return server.post({ |
|
|
@ -215,6 +366,82 @@ export default { |
|
|
|
console.warn('subpackage mall pages goods_info getGoodsInfo err --->', err); |
|
|
|
}) |
|
|
|
}, |
|
|
|
// 立即购买 |
|
|
|
homeGoodsBuy({ brand_id, id, nums, spec_arr }){ |
|
|
|
showLoad(); |
|
|
|
return server.post({ |
|
|
|
url: MALL_API.homeGoodsBuy, |
|
|
|
data: { brand_id, id, nums, spec_arr }, |
|
|
|
isDefaultGet: false, |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
hideLoad(); |
|
|
|
let _data = res?.data || {}; |
|
|
|
if(_data.code === 0){ |
|
|
|
console.log('subpackage mall pages goods_info homeGoodsBuy res --->', _data); |
|
|
|
return _data?.data; |
|
|
|
}else{ |
|
|
|
return Promise.reject(_data); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(err => { |
|
|
|
hideLoad(); |
|
|
|
showModal({ |
|
|
|
title: '提示', |
|
|
|
content: err.message || '操作失败!' |
|
|
|
}) |
|
|
|
console.warn('subpackage mall pages goods_info homeGoodsBuy err --->', err); |
|
|
|
}) |
|
|
|
}, |
|
|
|
// 购物车商品列表 |
|
|
|
goodsCartList({ brand_id }){ |
|
|
|
return server.post({ |
|
|
|
url: MALL_API.goodsCartList, |
|
|
|
data: { brand_id }, |
|
|
|
isDefaultGet: false, |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
let _data = res?.data || {}; |
|
|
|
if(_data.code === 0){ |
|
|
|
console.log('subpackage mall pages goods_info goodsCartList res --->', _data); |
|
|
|
let _ls = _data?.data ?? []; |
|
|
|
//product_invalid 商品状态 0-正常 1-已失效 |
|
|
|
let validLs = _ls.filter(item => item.product_invalid === 0); |
|
|
|
let _length = validLs?.length ?? 0; |
|
|
|
this.goodsCartNum = _length > 100 ? 99 : _length; |
|
|
|
return _ls; |
|
|
|
}else{ |
|
|
|
return Promise.reject(_data); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(err => { |
|
|
|
console.warn('subpackage mall pages goods_info goodsCartList err --->', err); |
|
|
|
}) |
|
|
|
}, |
|
|
|
/** |
|
|
|
* 获取商品评价列表 |
|
|
|
* @param {Number} proid 商品id |
|
|
|
* */ |
|
|
|
goodsComment({ brand_id, proid }){ |
|
|
|
return server.post({ |
|
|
|
url: MALL_API.goodsComment, |
|
|
|
data: { brand_id, proid }, |
|
|
|
isDefaultGet: false, |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
let _data = res?.data || {}; |
|
|
|
if(_data.code === 0){ |
|
|
|
console.log('subpackage mall pages goods_info goodsComment res --->', _data); |
|
|
|
let _ls = _data?.data?.list ?? []; |
|
|
|
return this.appraiseList = _ls; |
|
|
|
}else{ |
|
|
|
return Promise.reject(_data); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(err => { |
|
|
|
console.warn('subpackage mall pages goods_info goodsComment err --->', err); |
|
|
|
}) |
|
|
|
}, |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
@ -382,6 +609,30 @@ export default { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.gi-appraise-info{ |
|
|
|
margin-top: 20rpx; |
|
|
|
padding: 40upx 0upx; |
|
|
|
background: #fff; |
|
|
|
.gai-title-bar{ |
|
|
|
padding: 0 28upx; |
|
|
|
@include ctf(space-between); |
|
|
|
.gtb-tit{ |
|
|
|
@include flcw(28upx, 40upx, #333); |
|
|
|
@include tHide; |
|
|
|
} |
|
|
|
.gtb-link{ |
|
|
|
flex-shrink: 0; |
|
|
|
@include flcw(24upx, 34upx, $mColor); |
|
|
|
.gl-icon{ |
|
|
|
vertical-align: middle; |
|
|
|
width: 28upx; |
|
|
|
height: 28upx; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.gi-detail{ |
|
|
|
margin-top: 20rpx; |
|
|
|
background-color: #fff; |
|
|
@ -462,6 +713,7 @@ export default { |
|
|
|
border-radius: 36rpx; |
|
|
|
background-color: #e60213; |
|
|
|
@include flcw(22rpx, 36rpx, #fff); |
|
|
|
@include tHide; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|