850 lines
21 KiB
Vue
850 lines
21 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="goods-detail">
|
|||
|
|
<!-- 顶部导航栏 -->
|
|||
|
|
<view class="nav-bar">
|
|||
|
|
<view class="nav-back" @click="goBack">
|
|||
|
|
<text class="iconfont icon-fanhui"></text>
|
|||
|
|
</view>
|
|||
|
|
<text class="nav-title">商品详情</text>
|
|||
|
|
<view class="nav-right"></view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 商品图片轮播 -->
|
|||
|
|
<swiper
|
|||
|
|
class="goods-swiper"
|
|||
|
|
:indicator-dots="true"
|
|||
|
|
indicator-color="rgba(0,0,0,0.3)"
|
|||
|
|
indicator-active-color="#FF4D4F"
|
|||
|
|
>
|
|||
|
|
<swiper-item v-for="(image, index) in sliderImage" :key="index">
|
|||
|
|
<image
|
|||
|
|
:src="image"
|
|||
|
|
class="swiper-image"
|
|||
|
|
mode="aspectFill"
|
|||
|
|
@click="previewImage(index)"
|
|||
|
|
/>
|
|||
|
|
</swiper-item>
|
|||
|
|
</swiper>
|
|||
|
|
|
|||
|
|
<!-- 商品信息 -->
|
|||
|
|
<view class="wrapper" v-if="attr.productSelect">
|
|||
|
|
<view class="share-section">
|
|||
|
|
<view class="money-box">
|
|||
|
|
<text class="points-symbol">积分</text>
|
|||
|
|
<text class="points-num">{{ attr.productSelect.price || 0 }}</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="introduce">{{ productInfo.storeName }}</view>
|
|||
|
|
|
|||
|
|
<!-- <view class="label">
|
|||
|
|
<view>原价:¥{{ attr.productSelect.otPrice || 0 }}</view>
|
|||
|
|
<view>库存:{{ attr.productSelect.stock || 0 }}{{ productInfo.unitName }}</view>
|
|||
|
|
<view>销量:{{ Number(productInfo.sales) + Number(productInfo.ficti) }}{{ productInfo.unitName }}</view>
|
|||
|
|
</view> -->
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 规格选择 -->
|
|||
|
|
<view class="attribute" @click="selecAttr">
|
|||
|
|
<view class="attr-row">
|
|||
|
|
<view class="attr-text">{{attrTxt}}:<text class="selected-attr">{{attrValue}}</text></view>
|
|||
|
|
<view class="iconfont icon-jiantou arrow-right"></view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 属性选择组件 -->
|
|||
|
|
<productWindow
|
|||
|
|
:attr="attr"
|
|||
|
|
:isShow='1'
|
|||
|
|
:iSplus='1'
|
|||
|
|
@myevent="onMyEvent"
|
|||
|
|
@ChangeAttr="ChangeAttr"
|
|||
|
|
@ChangeCartNum="ChangeCartNum"
|
|||
|
|
@attrVal="attrVal"
|
|||
|
|
@iptCartNum="iptCartNum">
|
|||
|
|
</productWindow>
|
|||
|
|
|
|||
|
|
<!-- 商品详情 -->
|
|||
|
|
<view class="detail-section">
|
|||
|
|
<view class="detail-info-list" v-if="attr.productSelect">
|
|||
|
|
<view class="detail-item">库存:{{ attr.productSelect.stock || 0 }}件</view>
|
|||
|
|
<!-- <view class="detail-item">已兑换:{{ Number(productInfo.sales) + Number(productInfo.ficti) }}件</view> -->
|
|||
|
|
</view>
|
|||
|
|
<view class="detail-content">
|
|||
|
|
<rich-text :nodes="description" />
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 浮动购物车按钮 -->
|
|||
|
|
<view class="floating-cart animated" :class="animated ? 'bounceIn' : ''" @click="goToCart">
|
|||
|
|
<view class='iconfont icon-gouwuche1'>
|
|||
|
|
<text v-if="Math.floor(CartCount) > 0" class='cart-badge'>{{CartCount}}</text>
|
|||
|
|
</view>
|
|||
|
|
<!-- <view class="cart-text">购物车</view> -->
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 底部操作栏 -->
|
|||
|
|
<view class="bottom-bar safe-area-inset-bottom">
|
|||
|
|
<view class="btn-group">
|
|||
|
|
<view class="btn-cart" @click="onCartAdd">
|
|||
|
|
<text>加入购物车</text>
|
|||
|
|
</view>
|
|||
|
|
<view
|
|||
|
|
class="btn-buy"
|
|||
|
|
:class="{ disabled: attr.productSelect && attr.productSelect.stock <= 0 }"
|
|||
|
|
@click="onExchange"
|
|||
|
|
>
|
|||
|
|
<text>{{ exchangeButtonText }}</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import { collectIntegralGoods } from '@/api/miao.js'
|
|||
|
|
import { getProductDetail, postCartAdd } from '@/api/store.js';
|
|||
|
|
import { getCartCounts } from '@/api/order.js';
|
|||
|
|
import { toLogin } from '@/libs/login.js';
|
|||
|
|
import { mapGetters } from "vuex";
|
|||
|
|
import productWindow from '@/components/productWindow';
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
components: {
|
|||
|
|
productWindow
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
goodsId: 0,
|
|||
|
|
productInfo: {
|
|||
|
|
sales: 0,
|
|||
|
|
ficti: 0,
|
|||
|
|
unitName: '件'
|
|||
|
|
},
|
|||
|
|
productValue: {},
|
|||
|
|
skuArr: [],
|
|||
|
|
sliderImage: [],
|
|||
|
|
attr: {
|
|||
|
|
cartAttr: false,
|
|||
|
|
productAttr: [],
|
|||
|
|
productSelect: {
|
|||
|
|
price: 0,
|
|||
|
|
stock: 0,
|
|||
|
|
otPrice: 0,
|
|||
|
|
unique: '',
|
|||
|
|
cart_num: 1
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
attrValue: '',
|
|||
|
|
attrTxt: '请选择',
|
|||
|
|
reply: [],
|
|||
|
|
replyCount: 0,
|
|||
|
|
replyChance: 0,
|
|||
|
|
description: '',
|
|||
|
|
isOpen: false, // 是否打开过属性选择器
|
|||
|
|
CartCount: 0, // 购物车数量
|
|||
|
|
animated: false // 购物车动画
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
computed: {
|
|||
|
|
...mapGetters(['isLogin', 'uid']),
|
|||
|
|
|
|||
|
|
exchangeButtonText() {
|
|||
|
|
if (this.attr.productSelect && this.attr.productSelect.stock <= 0) {
|
|||
|
|
return '库存不足'
|
|||
|
|
}
|
|||
|
|
return '立即兑换'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onLoad(options) {
|
|||
|
|
if (options.id) {
|
|||
|
|
this.goodsId = parseInt(options.id)
|
|||
|
|
this.getDetail()
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onShow() {
|
|||
|
|
// 从兑换页面返回时刷新数据
|
|||
|
|
if (this.goodsId) {
|
|||
|
|
this.getDetail()
|
|||
|
|
}
|
|||
|
|
// 获取购物车数量
|
|||
|
|
this.getCartCount();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
methods: {
|
|||
|
|
// 获取商品详情
|
|||
|
|
getDetail() {
|
|||
|
|
let that = this;
|
|||
|
|
uni.showLoading({
|
|||
|
|
title: '加载中...'
|
|||
|
|
})
|
|||
|
|
getProductDetail(that.goodsId, 1).then(res => {
|
|||
|
|
let productInfo = res.data.productInfo;
|
|||
|
|
// 字符串数组转数组;
|
|||
|
|
let arrayImg = productInfo.sliderImage;
|
|||
|
|
let sliderImage = JSON.parse(arrayImg);
|
|||
|
|
that.$set(that, 'sliderImage', sliderImage);
|
|||
|
|
that.$set(that, 'productInfo', productInfo);
|
|||
|
|
that.$set(that, 'description', productInfo.content);
|
|||
|
|
that.$set(that.attr, 'productAttr', res.data.productAttr);
|
|||
|
|
that.$set(that, 'productValue', res.data.productValue);
|
|||
|
|
that.skuArr = [];
|
|||
|
|
for (let key in res.data.productValue) {
|
|||
|
|
let obj = res.data.productValue[key];
|
|||
|
|
that.skuArr.push(obj)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let productAttr = that.attr.productAttr.map(item => {
|
|||
|
|
return {
|
|||
|
|
attrName: item.attrName,
|
|||
|
|
attrValues: item.attrValues.split(','),
|
|||
|
|
id: item.id,
|
|||
|
|
isDel: item.isDel,
|
|||
|
|
productId: item.productId,
|
|||
|
|
type: item.type
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
that.$set(that.attr, 'productAttr', productAttr);
|
|||
|
|
|
|||
|
|
that.DefaultSelect();
|
|||
|
|
uni.hideLoading();
|
|||
|
|
}).catch(err => {
|
|||
|
|
uni.hideLoading();
|
|||
|
|
uni.showToast({
|
|||
|
|
title: err.msg || '加载失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 默认选中属性
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
DefaultSelect: function() {
|
|||
|
|
let productAttr = this.attr.productAttr;
|
|||
|
|
let value = [];
|
|||
|
|
//默认选中每种规格的第一个
|
|||
|
|
for (let key in this.productValue) {
|
|||
|
|
if (this.productValue[key].stock > 0) {
|
|||
|
|
value = this.attr.productAttr.length ? key.split(",") : [];
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for (let i = 0; i < value.length; i++) {
|
|||
|
|
this.$set(productAttr[i], "index", value[i]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//sort();排序函数:数字-英文-汉字;
|
|||
|
|
let productSelect = this.productValue[value.join(",")];
|
|||
|
|
if (productSelect && productAttr.length) {
|
|||
|
|
this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
|
|||
|
|
this.$set(this.attr.productSelect, "image", productSelect.image);
|
|||
|
|
this.$set(this.attr.productSelect, "price", productSelect.price);
|
|||
|
|
this.$set(this.attr.productSelect, "stock", productSelect.stock);
|
|||
|
|
this.$set(this.attr.productSelect, "unique", productSelect.id);
|
|||
|
|
this.$set(this.attr.productSelect, "cart_num", 1);
|
|||
|
|
this.$set(this.attr.productSelect, "vipPrice", productSelect.vipPrice);
|
|||
|
|
this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice);
|
|||
|
|
this.$set(this, "attrValue", value.join(","));
|
|||
|
|
this.$set(this, "attrTxt", "已选择");
|
|||
|
|
} else if (!productSelect && productAttr.length) {
|
|||
|
|
this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
|
|||
|
|
this.$set(this.attr.productSelect, "image", this.productInfo.image);
|
|||
|
|
this.$set(this.attr.productSelect, "price", this.productInfo.price);
|
|||
|
|
this.$set(this.attr.productSelect, "stock", 0);
|
|||
|
|
this.$set(this.attr.productSelect, "unique", this.productInfo.id);
|
|||
|
|
this.$set(this.attr.productSelect, "cart_num", 1);
|
|||
|
|
this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
|
|||
|
|
this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
|
|||
|
|
this.$set(this, "attrValue", "");
|
|||
|
|
this.$set(this, "attrTxt", "请选择");
|
|||
|
|
} else if (!productSelect && !productAttr.length) {
|
|||
|
|
this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
|
|||
|
|
this.$set(this.attr.productSelect, "image", this.productInfo.image);
|
|||
|
|
this.$set(this.attr.productSelect, "price", this.productInfo.price);
|
|||
|
|
this.$set(this.attr.productSelect, "stock", this.productInfo.stock);
|
|||
|
|
this.$set(this.attr.productSelect, "unique", this.productInfo.id || "");
|
|||
|
|
this.$set(this.attr.productSelect, "cart_num", 1);
|
|||
|
|
this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
|
|||
|
|
this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
|
|||
|
|
this.$set(this, "attrValue", "");
|
|||
|
|
this.$set(this, "attrTxt", "已选择");
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 预览图片
|
|||
|
|
previewImage(index) {
|
|||
|
|
uni.previewImage({
|
|||
|
|
urls: this.sliderImage,
|
|||
|
|
current: index
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 打开属性选择器
|
|||
|
|
selecAttr() {
|
|||
|
|
this.$set(this.attr, 'cartAttr', true);
|
|||
|
|
this.$set(this, 'isOpen', true);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 关闭属性选择器
|
|||
|
|
onMyEvent() {
|
|||
|
|
this.$set(this.attr, 'cartAttr', false);
|
|||
|
|
this.$set(this, 'isOpen', false);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 属性变动赋值
|
|||
|
|
ChangeAttr(res) {
|
|||
|
|
let productSelect = this.productValue[res];
|
|||
|
|
if (productSelect) {
|
|||
|
|
this.$set(this.attr.productSelect, "image", productSelect.image);
|
|||
|
|
this.$set(this.attr.productSelect, "price", productSelect.price);
|
|||
|
|
this.$set(this.attr.productSelect, "stock", productSelect.stock);
|
|||
|
|
this.$set(this.attr.productSelect, "unique", productSelect.id);
|
|||
|
|
this.$set(this.attr.productSelect, "cart_num", 1);
|
|||
|
|
this.$set(this.attr.productSelect, "vipPrice", productSelect.vipPrice);
|
|||
|
|
this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice);
|
|||
|
|
this.$set(this, "attrValue", res);
|
|||
|
|
this.$set(this, "attrTxt", "已选择");
|
|||
|
|
} else {
|
|||
|
|
this.$set(this.attr.productSelect, "image", this.productInfo.image);
|
|||
|
|
this.$set(this.attr.productSelect, "price", this.productInfo.price);
|
|||
|
|
this.$set(this.attr.productSelect, "stock", 0);
|
|||
|
|
this.$set(this.attr.productSelect, "unique", this.productInfo.id);
|
|||
|
|
this.$set(this.attr.productSelect, "cart_num", 1);
|
|||
|
|
this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
|
|||
|
|
this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
|
|||
|
|
this.$set(this, "attrValue", "");
|
|||
|
|
this.$set(this, "attrTxt", "请选择");
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 购物车数量加减
|
|||
|
|
ChangeCartNum(changeValue) {
|
|||
|
|
let productSelect = this.productValue[this.attrValue];
|
|||
|
|
if (productSelect === undefined && !this.attr.productAttr.length)
|
|||
|
|
productSelect = this.attr.productSelect;
|
|||
|
|
if (productSelect === undefined) return;
|
|||
|
|
|
|||
|
|
let stock = productSelect.stock || 0;
|
|||
|
|
let num = this.attr.productSelect;
|
|||
|
|
if (changeValue) {
|
|||
|
|
num.cart_num++;
|
|||
|
|
if (num.cart_num > stock) {
|
|||
|
|
this.$set(this.attr.productSelect, "cart_num", stock);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
num.cart_num--;
|
|||
|
|
if (num.cart_num < 1) {
|
|||
|
|
this.$set(this.attr.productSelect, "cart_num", 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 属性值选择
|
|||
|
|
attrVal(val) {
|
|||
|
|
this.$set(this.attr.productAttr[val.indexw], 'index', this.attr.productAttr[val.indexw].attrValues[val.indexn]);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 购物车手动填写
|
|||
|
|
iptCartNum(e) {
|
|||
|
|
this.$set(this.attr.productSelect, 'cart_num', e ? e : 1);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加入购物车
|
|||
|
|
onCartAdd() {
|
|||
|
|
// 检查是否登录
|
|||
|
|
if (this.isLogin === false) {
|
|||
|
|
toLogin();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 调用统一的处理方法,1 表示加入购物车
|
|||
|
|
this.goCat(1);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 立即兑换
|
|||
|
|
onExchange() {
|
|||
|
|
// 检查库存
|
|||
|
|
if (this.attr.productSelect && this.attr.productSelect.stock <= 0) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '库存不足',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查是否登录
|
|||
|
|
if (this.isLogin === false) {
|
|||
|
|
toLogin();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 调用统一的处理方法,0 表示立即购买
|
|||
|
|
this.goCat(0);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 统一处理加入购物车和立即兑换
|
|||
|
|
* @param {Number} num 1-加入购物车 0-立即购买/兑换
|
|||
|
|
*/
|
|||
|
|
goCat(num) {
|
|||
|
|
let that = this;
|
|||
|
|
let productSelect = that.productValue[this.attrValue];
|
|||
|
|
|
|||
|
|
// 打开属性选择器
|
|||
|
|
if (that.attrValue) {
|
|||
|
|
// 默认选中了属性,但是没有打开过属性弹窗还是自动打开让用户查看默认选中的属性
|
|||
|
|
that.attr.cartAttr = !that.isOpen ? true : false;
|
|||
|
|
} else {
|
|||
|
|
if (that.isOpen) that.attr.cartAttr = true;
|
|||
|
|
else that.attr.cartAttr = !that.attr.cartAttr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 只有关闭属性弹窗时进行操作
|
|||
|
|
if (that.attr.cartAttr === true && that.isOpen === false) {
|
|||
|
|
return (that.isOpen = true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果有属性,没有选择或库存为0,提示用户选择
|
|||
|
|
if (
|
|||
|
|
that.attr.productAttr.length &&
|
|||
|
|
productSelect &&
|
|||
|
|
productSelect.stock === 0 &&
|
|||
|
|
that.isOpen === true
|
|||
|
|
) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: "产品库存不足,请选择其它",
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 执行对应操作
|
|||
|
|
if (num === 1) {
|
|||
|
|
// 加入购物车
|
|||
|
|
let q = {
|
|||
|
|
productId: parseFloat(that.goodsId),
|
|||
|
|
cartNum: parseFloat(that.attr.productSelect.cart_num),
|
|||
|
|
isNew: false,
|
|||
|
|
productAttrUnique: that.attr.productSelect !== undefined ?
|
|||
|
|
that.attr.productSelect.unique : that.productInfo.id
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
postCartAdd(q).then(function(res) {
|
|||
|
|
that.isOpen = false;
|
|||
|
|
that.attr.cartAttr = false;
|
|||
|
|
uni.showToast({
|
|||
|
|
title: "添加购物车成功",
|
|||
|
|
icon: 'success'
|
|||
|
|
});
|
|||
|
|
// 更新购物车数量
|
|||
|
|
that.getCartCount(true);
|
|||
|
|
}).catch(res => {
|
|||
|
|
that.isOpen = false;
|
|||
|
|
that.attr.cartAttr = false;
|
|||
|
|
uni.showToast({
|
|||
|
|
title: res.msg || '添加失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
// 立即兑换 - 直接跳转到积分商城下单页面
|
|||
|
|
this.goToConfirm();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 直接跳转到积分商城下单页面
|
|||
|
|
goToConfirm() {
|
|||
|
|
// 保存商品信息到缓存
|
|||
|
|
const goodsInfo = {
|
|||
|
|
id: this.goodsId,
|
|||
|
|
name: this.productInfo.storeName,
|
|||
|
|
storeName: this.productInfo.storeName,
|
|||
|
|
image: this.attr.productSelect.image || this.productInfo.image,
|
|||
|
|
pic: this.attr.productSelect.image || this.productInfo.image,
|
|||
|
|
points: this.attr.productSelect.price || this.productInfo.price,
|
|||
|
|
integral: this.attr.productSelect.price || this.productInfo.price,
|
|||
|
|
quantity: this.attr.productSelect.cart_num || 1,
|
|||
|
|
attrValueId: this.attr.productSelect.unique || '',
|
|||
|
|
unique: this.attr.productSelect.unique || '',
|
|||
|
|
productAttrUnique: this.attr.productSelect.unique || '',
|
|||
|
|
sku: this.attrValue || ''
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
uni.setStorageSync('buy_now_goods', goodsInfo);
|
|||
|
|
|
|||
|
|
this.isOpen = false;
|
|||
|
|
this.attr.cartAttr = false;
|
|||
|
|
|
|||
|
|
// 跳转到积分商城下单页面
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: `/pages/integral/confirm?id=${this.goodsId}&quantity=${this.attr.productSelect.cart_num || 1}`
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取购物车数量
|
|||
|
|
* @param {Boolean} isAnima 是否展示购物车动画和重置属性
|
|||
|
|
*/
|
|||
|
|
getCartCount(isAnima) {
|
|||
|
|
let that = this;
|
|||
|
|
const isLogin = that.isLogin;
|
|||
|
|
if (isLogin) {
|
|||
|
|
getCartCounts(true, 'total').then(res => {
|
|||
|
|
that.CartCount = res.data.count;
|
|||
|
|
// 加入购物车后重置属性
|
|||
|
|
if (isAnima) {
|
|||
|
|
that.animated = true;
|
|||
|
|
setTimeout(function() {
|
|||
|
|
that.animated = false;
|
|||
|
|
}, 500);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 跳转购物车
|
|||
|
|
goToCart() {
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: '/pages/integral/cart',
|
|||
|
|
fail: (err) => {
|
|||
|
|
console.error('跳转购物车失败:', err);
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '跳转失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 返回上一页
|
|||
|
|
goBack() {
|
|||
|
|
uni.navigateBack()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.goods-detail {
|
|||
|
|
min-height: 100vh;
|
|||
|
|
background-color: #F5F5F5;
|
|||
|
|
padding-bottom: 120rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 顶部导航栏
|
|||
|
|
.nav-bar {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
height: 113.344rpx;
|
|||
|
|
background: linear-gradient(180deg, rgba(0, 0, 0, 0.4) 0%, rgba(0, 0, 0, 0) 100%);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
padding: 0 31.996rpx;
|
|||
|
|
z-index: 200;
|
|||
|
|
padding-top: constant(safe-area-inset-top);
|
|||
|
|
padding-top: env(safe-area-inset-top);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav-back {
|
|||
|
|
width: 72rpx;
|
|||
|
|
height: 64rpx;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
background: rgba(0, 0, 0, 0.3);
|
|||
|
|
border-radius: 50%;
|
|||
|
|
|
|||
|
|
.iconfont {
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav-title {
|
|||
|
|
flex: 1;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
font-weight: normal;
|
|||
|
|
text-align: center;
|
|||
|
|
line-height: 48rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.nav-right {
|
|||
|
|
width: 72rpx;
|
|||
|
|
height: 64rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 图片轮播
|
|||
|
|
.goods-swiper {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 750rpx;
|
|||
|
|
background-color: #FFFFFF;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.swiper-image {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 仿照 goods_details 的 wrapper 样式
|
|||
|
|
.wrapper {
|
|||
|
|
background-color: #fff;
|
|||
|
|
margin: 20rpx;
|
|||
|
|
padding: 30rpx;
|
|||
|
|
border-radius: 14rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.share-section {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: flex-end;
|
|||
|
|
margin-bottom: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.money-box {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: baseline;
|
|||
|
|
color: #FF4D4F;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.points-num {
|
|||
|
|
font-size: 48rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.points-symbol {
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
margin-right: 4rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.introduce {
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #282828;
|
|||
|
|
font-weight: bold;
|
|||
|
|
line-height: 1.5;
|
|||
|
|
margin-bottom: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.label {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #999;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 仿照 goods_details 的 attribute 样式
|
|||
|
|
.attribute {
|
|||
|
|
background-color: #fff;
|
|||
|
|
margin: 20rpx;
|
|||
|
|
padding: 30rpx;
|
|||
|
|
border-radius: 14rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.attr-row {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.attr-text {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #282828;
|
|||
|
|
width: 600rpx;
|
|||
|
|
overflow: hidden;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.selected-attr {
|
|||
|
|
color: #666;
|
|||
|
|
margin-left: 10rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.arrow-right {
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #999;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 兑换规则
|
|||
|
|
.rules-section,
|
|||
|
|
.detail-section {
|
|||
|
|
margin: 20rpx;
|
|||
|
|
padding: 30rpx;
|
|||
|
|
background-color: #FFFFFF;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-title {
|
|||
|
|
font-size: 30rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: #333333;
|
|||
|
|
margin-bottom: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-info-list {
|
|||
|
|
margin-bottom: 30rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.detail-item {
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
color: #666666;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
line-height: 1.5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 底部操作栏
|
|||
|
|
.bottom-bar {
|
|||
|
|
position: fixed;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
background-color: #FFFFFF;
|
|||
|
|
border-top: 1px solid #EEEEEE;
|
|||
|
|
padding: 20rpx 30rpx;
|
|||
|
|
z-index: 100;
|
|||
|
|
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
|
|||
|
|
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 浮动购物车按钮
|
|||
|
|
.floating-cart {
|
|||
|
|
position: fixed;
|
|||
|
|
right: 30rpx;
|
|||
|
|
bottom: calc(240rpx + constant(safe-area-inset-bottom));
|
|||
|
|
bottom: calc(240rpx + env(safe-area-inset-bottom));
|
|||
|
|
width: 100rpx;
|
|||
|
|
height: 100rpx;
|
|||
|
|
background: #FFFFFF;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15);
|
|||
|
|
z-index: 101;
|
|||
|
|
|
|||
|
|
.iconfont {
|
|||
|
|
font-size: 44rpx;
|
|||
|
|
color: #FF4D4F;
|
|||
|
|
position: relative;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cart-badge {
|
|||
|
|
position: absolute;
|
|||
|
|
top: -8rpx;
|
|||
|
|
right: -16rpx;
|
|||
|
|
background: linear-gradient(90deg, #FF6900 0%, #FF4D4F 100%);
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
font-size: 18rpx;
|
|||
|
|
padding: 2rpx 8rpx 3rpx;
|
|||
|
|
border-radius: 200rpx;
|
|||
|
|
min-width: 28rpx;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cart-text {
|
|||
|
|
font-size: 18rpx;
|
|||
|
|
color: #666666;
|
|||
|
|
margin-top: 2rpx;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.animated {
|
|||
|
|
animation-duration: 0.5s;
|
|||
|
|
animation-fill-mode: both;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.bounceIn {
|
|||
|
|
animation-name: bounceIn;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes bounceIn {
|
|||
|
|
from,
|
|||
|
|
20%,
|
|||
|
|
40%,
|
|||
|
|
60%,
|
|||
|
|
80%,
|
|||
|
|
to {
|
|||
|
|
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
0% {
|
|||
|
|
opacity: 0;
|
|||
|
|
transform: scale3d(0.3, 0.3, 0.3);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
20% {
|
|||
|
|
transform: scale3d(1.1, 1.1, 1.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
40% {
|
|||
|
|
transform: scale3d(0.9, 0.9, 0.9);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
60% {
|
|||
|
|
opacity: 1;
|
|||
|
|
transform: scale3d(1.03, 1.03, 1.03);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
80% {
|
|||
|
|
transform: scale3d(0.97, 0.97, 0.97);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
to {
|
|||
|
|
opacity: 1;
|
|||
|
|
transform: scale3d(1, 1, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-group {
|
|||
|
|
flex: 1;
|
|||
|
|
display: flex;
|
|||
|
|
gap: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-cart,
|
|||
|
|
.btn-buy {
|
|||
|
|
flex: 1;
|
|||
|
|
height: 80rpx;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
border-radius: 8rpx;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: 500;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-cart {
|
|||
|
|
background-color: #FFFFFF;
|
|||
|
|
border: 1px solid #EEEEEE;
|
|||
|
|
color: #333333;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-buy {
|
|||
|
|
background: linear-gradient(90deg, #FF6900 0%, #FF4D4F 100%);
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
|
|||
|
|
&.disabled {
|
|||
|
|
background: #CCCCCC;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.detail-content img, .detail-content image{
|
|||
|
|
width: 100%;
|
|||
|
|
}
|
|||
|
|
</style>
|