Files
frontend-app/pages/productInfo/productInfo.vue
T

729 lines
19 KiB
Vue
Raw Normal View History

2025-03-20 08:46:07 +08:00
<template>
<view class="product_info_warp">
<!-- 头部产品描述图 -->
<view class="product_info_header_warp">
<up-swiper
:list="swiperList"
height="280"
>
<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.maxPrice && orderInfo.maxPrice !==0">{{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>销量1.5万件</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">
2025-03-23 20:36:06 +08:00
<up-image src="/static/product/home.png" width="20" height="20" bgColor="#f1f6ff00" @click="jumpOther('home')"></up-image>
2025-03-20 08:46:07 +08:00
<view>首页</view>
</view>
<view class="left_item">
2025-03-23 20:36:06 +08:00
<up-image src="/static/product/kefu.png" width="20" height="20" bgColor="#f1f6ff00" @click="jumpOther('share')"></up-image>
2025-03-20 08:46:07 +08:00
<view>咨询</view>
</view>
2025-03-23 20:36:06 +08:00
<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>
2025-03-20 08:46:07 +08:00
</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
2025-03-23 20:36:06 +08:00
:show="specificationShow"
2025-03-20 08:46:07 +08:00
:round="10"
:closeOnClickOverlay="false"
:closeable="true"
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}} - {{orderInfo.maxPrice}}
</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="byFun">去支付</view>
<view v-else-if="specificationShowType === 'addCart'" class="specification_buy_but" @click="addCart">加入购物车</view>
<view v-else class="product_but_right popup_but">
<view class ='but_comm join_warp' @click="addCart">加入购物车</view>
<view class="but_comm buy_warp" @click="byFun">立即购买</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:1,
specificationShow:false,
specificationShowType:'',// 弹框类型
2025-03-23 20:36:06 +08:00
orderInfo:{},
2025-03-20 08:46:07 +08:00
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,返回到上一级
});
},
2025-03-23 20:36:06 +08:00
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',
})
}
2025-03-20 08:46:07 +08:00
},
/**
* 查询详细内容
*/
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;
2025-03-23 20:36:06 +08:00
2025-03-20 08:46:07 +08:00
}
},
2025-03-23 20:36:06 +08:00
async checkSpecification(val,type){
2025-03-20 08:46:07 +08:00
// 需要查询一下最新的规格
if(val){
2025-03-23 20:36:06 +08:00
await this.querySpecification()
const data = this.orderInfo;
this.getSpecification(data.specs);
2025-03-20 08:46:07 +08:00
}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;
},
2025-03-23 20:36:06 +08:00
// 立即购买,确定订单页面
2025-03-20 08:46:07 +08:00
byFun(){
// 先加入购物车,再去购买
this.addCart();
uni.navigateTo({
url: '/pages/order_submit/order_submit',
})
},
2025-03-23 20:36:06 +08:00
// 加入购入车
2025-03-20 08:46:07 +08:00
async addCart(){
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){
uni.showToast({
title: '成功加入购物车',
icon: 'success', // 可选 success/loading/none
duration: 2000 // 持续时长,单位ms
});
setTimeout(()=>{
this.checkSpecification(false,null);
},2000)
}
}
}
}
</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;
2025-03-23 20:36:06 +08:00
width: 36%;
2025-03-20 08:46:07 +08:00
.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{
.but_comm{
width: 40%;
}
}
</style>