Files
frontend-app/pages/productInfo/productInfo.vue
T
2025-05-23 18:03:45 +08:00

738 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="product_info_warp">
<!-- 头部产品描述图 -->
<view class="product_info_header_warp">
<up-swiper
:list="swiperList"
height="280"
@change="e => currentNum = e.current"
>
<template #indicator>
<view
class="indicator-num"
>
<text class="indicator-num__text">{{ currentNum + 1 }}/{{ swiperList.length }}</text>
</view>
</template>
</up-swiper>
<view class="img_comm left_warp">
<up-image src="/static/common/left_b_st.png" width="30" height="30" bgColor="#f1f6ff00" @click="jumpLeft"></up-image>
</view>
<view class="img_comm right_warp">
<up-image src="/static/common/share_st.png" width="30" height="30" bgColor="#f1f6ff00" @click="jumpShare"></up-image>
</view>
</view>
<!-- 数据详情 -->
<view class="product_content_warp">
<!-- 标题,系列 -->
<view class="content_data">
<view class="content_data_price">
<text>¥</text>
<text style="font-size: 60rpx;" v-if="orderInfo.minPrice && orderInfo.maxPrice">
{{orderInfo.minPrice}} - {{orderInfo.maxPrice}}
</text>
<text style="font-size: 60rpx;" v-else>{{orderInfo.minPrice}}</text>
<text class="price_o">¥{{orderInfo.adPrice}}</text>
</view>
<view class="content_data_title">
{{ orderInfo.name}}
</view>
<view class="content_data_series">
<!-- 暂时隐藏 -->
<view>
</view>
<!-- 销量还需要改 -->
<view>销量{{orderInfo.sales}}件</view>
</view>
</view>
<!-- 具体规格 -->
<view class="content_concrete">
<view class="concrete_item concrete_item_but" @click="checkSpecification(true)">
<view class="concrete_item_">
<view class="concrete_item_title">规格</view>
<view class="concrete_item_value">
{{selectSpecificationTempl.combTypes || '暂未选择规格'}}
</view>
</view>
<up-image src="/static/common/right.png" width="20" height="20" bgColor="#f1f6ff00"></up-image>
</view>
<view class="concrete_item">
<view class="concrete_item_">
<view class="concrete_item_title">发货地址</view>
<view class="concrete_item_value">
<view class="address_warp">
<up-image src="/static/common/address2.png" width="10" height="10" bgColor="#f1f6ff00"></up-image>
<view style="margin-left: 10rpx;">请填写地址</view>
</view>
<view class="address_72_warp">现货{{getValue(PRODUCT_DELIVERY_TIME,orderInfo.deliveryTime)}}</view>
</view>
</view>
<!-- <up-image src="/static/common/right.png" width="20" height="20" bgColor="#f1f6ff00"></up-image> -->
</view>
<view class="concrete_item">
<view class="concrete_item_">
<view class="concrete_item_title">购物保障</view>
<view class="concrete_item_value concrete_item_bz">
<view class="concrete_item_bz concrete_item_bz_item">
<up-image src="/static/product/product_b.png" width="10" height="12" bgColor="#f1f6ff00"></up-image>
<view class="concrete_item_bz_item_left">品质严保</view>
</view>
<view class="concrete_item_bz">
<up-image src="/static/product/product_js.png" width="10" height="10" bgColor="#f1f6ff00"></up-image>
<view class="concrete_item_bz_item_left">极速退款</view>
</view>
</view>
</view>
<!-- <up-image src="/static/common/right.png" width="20" height="20" bgColor="#f1f6ff00"></up-image> -->
</view>
</view>
<!-- 商品详情 -->
<view class="content_details">
<view class="content_details_title">商品详情</view>
<view v-html="orderInfo.detailInfo"></view>
</view>
</view>
<!-- 底部编辑按钮 -->
<view class="product_but_warp">
<view class="product_but_left">
<view class="left_item">
<up-image src="/static/product/home.png" width="20" height="20" bgColor="#f1f6ff00" @click="jumpOther('home')"></up-image>
<view>首页</view>
</view>
<view class="left_item">
<up-image src="/static/product/kefu.png" width="20" height="20" bgColor="#f1f6ff00" @click="jumpOther('share')"></up-image>
<view>咨询</view>
</view>
<view class="left_item">
<up-image src="/static/product/cart.png" width="24" height="20" bgColor="#f1f6ff00" @click="jumpOther('cart')"></up-image>
<view>购物车</view>
</view>
</view>
<view class="product_but_right">
<view class="but_comm join_warp" @click="checkSpecification(true,'addCart')">加入购物车</view>
<view class="but_comm buy_warp" @click="checkSpecification(true,'buy')">立即购买</view>
</view>
</view>
<!-- 选择规格的弹框 -->
<up-popup
:show="specificationShow"
:round="10"
:closeOnClickOverlay="false"
:closeable="true"
@close="specificationShow=false"
mode="bottom"
>
<view class="specification_warp">
<!-- 选择地址 -->
<view class="specification_adress_warp">
<view class="specification_adress_msg">10+刚刚抢购</view>
<!-- <view class="specification_adress_arr">
<up-image src="/static/common/address_st.png" width="30" height="30" bgColor="#f1f6ff00"></up-image>
<view class="address_title address_title_sel" v-if="orderInfo && orderInfo.addressObj">
<text style="font-size: 30rpx;margin-right: 20rpx;">{{orderInfo.addressObj.name}}</text>
<text>{{orderInfo.addressObj.address}}</text>
</view>
<view class="address_title" v-else>暂无收货地址,请添加收货地址!</view>
<view><up-image src="/static/common/right.png" width="16" height="16" bgColor="#f1f6ff00"></up-image></view>
</view> -->
</view>
<!-- 商品 -->
<view class="specification_product_warp">
<up-image :src="orderInfo.mainGraph" width="100" height="100" bgColor="#f1f6ff00"></up-image>
<view class="product_content">
<view class="price_warp">
<view class="price_content_warp">
<view>¥</view>
<text style="font-size: 50rpx;" v-if="selectSpecificationTempl && Object.keys(selectSpecificationTempl).length !==0">
{{selectSpecificationTempl.price}}
</text>
<view style="font-size: 50rpx" v-else>
{{orderInfo.minPrice}}
<text v-if="orderInfo.maxPrice">- {{orderInfo.maxPrice}}</text>
</view>
<view class="price_content_coupon_warp" v-if="orderInfo.couponPrice && orderInfo.couponPrice !==0">优惠卷{{orderInfo.couponPrice}}</view>
</view>
<view class="oOrice_content_warp" >¥{{orderInfo.adPrice}}</view>
<view class="coupon_content_warp" v-if="orderInfo.couponPrice && orderInfo.couponPrice !==0">优惠卷已优惠¥{{orderInfo.couponPrice}}</view>
</view>
<view class="inventory_warp">
<view>库存</view>
<view>{{orderInfo.inventory || 0}}件</view>
</view>
</view>
</view>
<!-- 规格 -->
<view class="specification_list_warp">
<view v-for="(item,index) in specificationList" :key="item.id" class="list_warp">
<view class="list_title_warp">{{item.type}}</view>
<view class="specification_item_warp">
<view
:class="oItem.inventory === 0 ? 'item_Warp item_Warp_no_warp' : item.selectVal === oItem.n?'item_Warp item_Warp_yes_warp':'item_Warp' "
v-for="(oItem,oIndex) in item.items"
:key="oItem.n"
@click="clickSpecification(index,oItem)"
>
{{oItem.n}}
</view>
</view>
</view>
</view>
<!-- 购买数量 -->
<view class="specification_but">
<view class="specification_buy">
<view>数量</view>
<view class="shopping_info_quantity">
<view class="quantity_but" @click="quantityFun('minus')">-</view>
<view class="quantity_value">{{orderInfo.quantity}}</view>
<view class="quantity_but" @click="quantityFun('add')">+</view>
</view>
</view>
<view v-if="specificationShowType === 'buy'" class="specification_buy_but" @click="addCart(true)">去支付</view>
<view v-else-if="specificationShowType === 'addCart'" class="specification_buy_but" @click="addCart(false)">加入购物车</view>
<view v-else class="product_but_right popup_but">
<view class ='but_comm join_warp' @click="addCart(false)">加入购物车</view>
<view class="but_comm buy_warp" @click="addCart(true)">立即购买</view>
</view>
</view>
</view>
</up-popup>
</view>
</template>
<script>
import{ getGoodsDetail,addGoods,getGoodsSpecs } from '@/api/product.js';
import { getValue,PRODUCT_DELIVERY_TIME } from '@/utils/enumUtils.js'
export default {
computed: {
PRODUCT_DELIVERY_TIME() {
return PRODUCT_DELIVERY_TIME;
},
},
data() {
return {
id:0,
swiperList:[],
currentNum:0,
specificationShow:false,
specificationShowType:'',// 弹框类型
orderInfo:{},
specificationList:[],//规格
selectSpecification:[],// 选择的规格
specificationTempl:[],// 规格模版数据
selectSpecificationTempl:{},// 选择规格模版数据
}
},
onLoad(options) {
const id = options.id;
if(id && id !==0){
this.id = id ? parseInt(id,10) : 0;
this.getById();
}
},
methods: {
getValue,
jumpLeft(){
uni.navigateBack({
delta: 1 // 返回的页面数,默认为1,返回到上一级
});
},
jumpOther(type){
if(type === 'home'){
uni.switchTab({// 首页
url: '/pages/home/home',
})
}else if(type === "share"){// 分享
uni.navigateTo({
url: '/pages/invite_friends/invite_friends',
})
}else if(type === "cart"){// 购物车
uni.switchTab({
url: '/pages/shopping_cart/shopping_cart',
})
}
},
/**
* 查询详细内容
*/
async getById(){
const params={
id:this.id,
}
const resp = await getGoodsDetail(params);
if(resp && resp.bizcode === 100){
const data = resp.data;
// 商品图
if(data.goodsGraph){
this.swiperList = data.goodsGraph.split(",");
}
data.addressObj={}// 收件人地址
data.quantity=1// 数量
data.inventory=0// 库存
this.orderInfo = data;
}
},
async checkSpecification(val,type){
// 需要查询一下最新的规格
if(val){
await this.querySpecification()
const data = this.orderInfo;
this.getSpecification(data.specs);
}else{
this.specificationList=[];//规格
this.selectSpecification=[];// 选择的规格
this.specificationTempl=[];// 规格模版数据
}
this.specificationShow = val;
this.specificationShowType = type;
},
// 拆解规格
getSpecification(specs){
const optionArr=[];
if(specs){
const arr = JSON.parse(specs);
arr.map(item=>{
optionArr.push({
type:item.type,
items:item.items,
selectVal:null,
})
})
}
this.specificationList = optionArr;
},
// 获取规格模版数据
async querySpecification(){
const params={
id:this.id,
}
const resp = await getGoodsSpecs(params);
if(resp && resp.bizcode === 100){
const data = resp.data;
let stock=0;
data.map(item=>{
stock = stock+item.stock;
})
this.specificationTempl = data;
this.orderInfo.inventory = stock;// 库存
}
},
//改变规格的样式
clickSpecification(pIndex,oItem){
// if(oItem.inventory<=0){
// return;
// }
this.specificationList[pIndex].selectVal = oItem.n;
// 计算规格的价格
this.selectSpecificationFun(pIndex,oItem);
},
// 选择规格
selectSpecificationFun(index,item){
const currentSelectSpecification = this.selectSpecification;
currentSelectSpecification[index] = item.n;
this.selectSpecification = currentSelectSpecification;
const oldLength = this.specificationList.length;
const newLength = this.selectSpecification.length;
// 开始做校验
if(oldLength === newLength){
const newLengthStr = this.selectSpecification.join("♧");
const specificationTempl = this.specificationTempl;
let selectTempl = {};
specificationTempl.map(item=>{
if(item.combNames === newLengthStr){
selectTempl = item
return;
}
});
this.selectSpecificationTempl = selectTempl;
this.orderInfo.inventory = selectTempl.stock;// 库存
}
},
// 改变数量
quantityFun(type){
let currentQuantity = this.orderInfo.quantity;// 当前数量
if(type === "minus"){
if(currentQuantity === 1){
this.$refs.uToastRef.show({
type: 'error',
message: "不能低于最低购买数量",
});
}else{
currentQuantity = currentQuantity - 1;
}
}else if(type === "add"){
// 需要判断一下库存
currentQuantity = currentQuantity + 1;
}
this.orderInfo.quantity = currentQuantity;
},
// 加入购入车
async addCart(isBy = false){
const selectTempl = this.selectSpecificationTempl;
if(!selectTempl || Object.keys(selectTempl).length ===0){
uni.showToast({
title: '请先选择规格',
icon: 'none', // 可选 success/loading/none
duration: 2000 // 持续时长,单位ms
});
return;
}
const params={
id:this.id,
specsId:selectTempl.id,// 规格ID
goodsNum:this.orderInfo.quantity,// 商品数量
}
const resp = await addGoods(params);
if(resp && resp.bizcode === 100){
if(isBy){
uni.navigateTo({
url: '/pages/order_submit/order_submit?ids='+resp.data,
})
}else{
uni.showToast({
title: '成功加入购物车',
icon: 'success', // 可选 success/loading/none
duration: 2000 // 持续时长,单位ms
});
}
setTimeout(()=>{
this.checkSpecification(false,null);
},2000)
}
},
// 跳转到分享页面
jumpShare(){
}
}
}
</script>
<style lang="scss" scoped>
.product_info_warp{
height: calc(100vh - 196rpx);
background-color: $app-bj;
}
.product_info_header_warp{
position: relative;
.img_comm{
position: absolute;
top: 140rpx;
}
.left_warp{
left: 40rpx;
}
.right_warp{
right: 40rpx;
}
}
.product_content_warp{
// background: linear-gradient(0deg, #F9F9F9 0%, #FFFFFF 100%);
border-radius: 30rpx 30rpx 0rpx 24rpx;
padding: 20rpx;
.content_data{
padding: 20rpx;
}
.content_data_price{
font-weight: bold;
font-size: 36rpx;
color: $app-bt-bj;
.price_o{
font-weight: 500;
font-size: 26rpx;
color: #999999;
text-decoration-line: line-through;
margin-left: 10rpx;
}
}
.content_data_title{
font-weight: bold;
font-size: 36rpx;
color: #111111;
margin-top: 10rpx;
}
.content_data_series{
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 500;
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
}
.content_concrete{
padding: 20rpx;
background: #FFFFFF;
border-radius: 30rpx;
margin-top: 20rpx;
.concrete_item{
display: flex;
justify-content: space-between;
font-size: 28rpx;
padding: 20rpx 0;
}
.concrete_item_{
display: flex;
width: 100%;
}
.concrete_item_but{
border-bottom: 1rpx solid #EEEEEEFF;
}
.concrete_item_title{
color: #808080;
width: 140rpx;
}
.concrete_item_value{
font-weight: 500;
color: #1A1A1A;
width: calc(100% - 140rpx);
.address_warp{
display: flex;
margin-bottom: 10rpx;
}
.address_72_warp{
font-size: 24rpx;
color: #808080;
}
}
.concrete_item_bz{
display: flex;
}
.concrete_item_bz_item{
margin-right: 20rpx;
}
.concrete_item_bz_item_left{
margin-left: 10rpx;
}
}
}
.content_details{
background: #FFFFFF;
border-radius: 24rpx;
padding: 10rpx 10rpx 30rpx;
margin-top: 30rpx;
.content_details_title{
padding: 20rpx 30rpx;
}
img,
img[alt] {
max-width: 100%;
}
}
.product_but_warp{
padding: 20rpx;
position: fixed;
bottom: 0;
height: 160rpx;
width: calc(100% - 40rpx);
background-color: #FFFFFF;
display: flex;
justify-content: space-between;
.product_but_left{
display: flex;
justify-content: space-between;
width: 36%;
.left_item{
width: 50%;
text-align: center;
font-weight: 500;
font-size: 20rpx;
color: #666666;
}
}
}
.product_but_right{
display: flex;
justify-content: center;
.but_comm{
text-align: center;
padding: 20rpx 40rpx;
color: #FFFFFF;
height: 50rpx;
}
.join_warp{
background: #FFA64F;
border-radius: 16rpx 0rpx 0rpx 16rpx;
}
.buy_warp{
background: $app-bt-bj;
border-radius: 0rpx 16rpx 16rpx 0rpx;
}
}
.specification_warp{
background-color: $app-bj;
.specification_adress_warp{
padding: 30rpx;
background: #FFFFFF;
border-radius: 24rpx;
}
.specification_adress_msg{
text-align: center;
font-weight: 500;
font-size: 24rpx;
color: #808080;
margin: 0 10rpx 0 20rpx;
}
.specification_adress_arr{
display: flex;
align-items: center;
margin-top: 20rpx;
}
.address_title{
font-weight: 500;
font-size: 26rpx;
color: #BBBBBB;
margin-bottom: 10rpx;
margin-right: 20rpx;
width: 592rpx;
white-space: nowrap; /* 防止文本换行 */
overflow: hidden; /* 隐藏溢出的文本 */
text-overflow: ellipsis; /* 使用省略号表示溢出的内容 */
}
.address_title_sel{
color: #333333;
}
.specification_product_warp{
display: flex;
background: #FFFFFF;
border-radius: 24rpx;
padding: 30rpx;
margin-top: 20rpx;
.product_content{
margin-left: 10rpx;
display: grid;
}
.price_content_warp{
// font-weight: bold;
font-size: 36rpx;
color: $app-bt-bj;
display: flex;
align-items: center;
}
.price_content_coupon_warp{
margin-left: 20rpx;
padding: 4rpx 10rpx;
text-align: center;
color: $app-bt-bj;
font-size: 22rpx;
font-weight: 500;
border: 1px solid $app-bt-bj;
border-radius: 6rpx;
}
.oOrice_content_warp{
font-size: 26rpx;
color: #808080;
line-height: 11rpx;
text-decoration-line: line-through;
margin-top: 10rpx;
}
.coupon_content_warp{
font-weight: 500;
font-size: 22rpx;
color: $app-bt-bj;
margin-top: 10rpx;
}
.inventory_warp{
display: flex;
font-weight: 500;
font-size: 24rpx;
color: #808080;
}
}
.specification_list_warp{
background: #FFFFFF;
border-radius: 24rpx;
padding: 30rpx;
margin-top: 20rpx;
.list_warp{
margin-bottom: 30rpx;
}
.list_title_warp{
font-weight: 500;
font-size: 30rpx;
color: #1A1A1A;
line-height: 48rpx;
}
.specification_item_warp{
// display: flex;
justify-content: space-between;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.item_Warp{
width: 48%;
background: $app-bj;
border-radius: 10rpx;
color: #333333;
text-align: center;
padding: 10rpx 0;
margin-top: 13rpx;
font-size: 26rpx;
font-weight: 500;
}
.item_Warp_no_warp{
background: #F5F5F5;
color: #999999;
text-decoration-line: line-through;
}
.item_Warp_yes_warp{
border: 1px solid $app-bt-bj;
color: $app-bt-bj;
background: #FFF1EB;
}
}
.specification_but{
background: #FFFFFF;
border-radius: 24rpx;
padding: 30rpx;
margin-top: 30rpx;
.specification_buy{
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.specification_buy_but{
width: 100%;
padding: 20rpx 0;
text-align: center;
background-color: $app-bt-bj;
color: #FFFFFF;
margin-top: 20rpx;
font-weight: 500;
font-size: 28rpx;
color: #FFFFFF;
border-radius: 16rpx;
}
}
}
.popup_but{
background-color: #FFFFFF;
.but_comm{
width: 40%;
}
}
</style>