2025-11-25 22:28:34 +08:00

1330 lines
40 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="detail-page">
<!-- 图片轮播 -->
<view class="image-swiper-wrapper">
<swiper class="image-swiper" :indicator-dots="true" :autoplay="false" :circular="true"
:current="currentImageIndex" @change="onSwiperChange" indicator-color="rgba(0,0,0,0.2)"
indicator-active-color="#fff">
<swiper-item v-for="(image, index) in productImages" :key="index">
<image :src="image" mode="aspectFill" class="swiper-image"></image>
</swiper-item>
</swiper>
<!-- 左右箭头 -->
<view class="swiper-nav prev" @click="prevImage" v-if="productImages.length > 1">
<text></text>
</view>
<view class="swiper-nav next" @click="nextImage" v-if="productImages.length > 1">
<text></text>
</view>
</view>
<!-- 商品信息 -->
<view class="product-info">
<!-- 标签 -->
<view class="product-tags">
<view class="tag" v-if="productInfo.is_hot_selling">热销</view>
<view class="tag" v-if="productInfo.is_limited">限量</view>
<view class="tag" v-if="productInfo.is_imported">法国进口</view>
</view>
<!-- 商品名称 -->
<view class="product-name">{{ productInfo.name || '玫瑰香水盲盒' }}</view>
<!-- <view class="product-sub-title">{{ productInfo.description.sub_title || '玫瑰香水盲盒' }}</view> -->
<!-- 评分和喜欢 -->
<view class="product-rating">
<text class="iconfont icon-xingxing star-icon"></text>
<text class="rating-value">{{ productInfo.rating || 4.8 }}</text>
<text class="rating-text">({{ productInfo.review_count || 234 }}条评价)</text>
<text class="like-text">{{ productInfo.like_count || 567 }}人喜欢</text>
</view>
<!-- 价格 -->
<view class="product-price">
<text class="current-price">¥{{ formatPrice(currentPrice) }}</text>
<text class="original-price" v-if="originalPrice > currentPrice">¥{{ formatPrice(originalPrice)
}}</text>
</view>
<view class="sku-hint" v-if="skuList.length > 1 && !selectedSku">
请选择规格
</view>
<!-- 商品描述 -->
<view class="product-description">
{{ productInfo.description.sub_title ||
'经典玫瑰香调,优雅女神范,持久留香8小时。采用法国进口玫瑰精油,层次丰富,前调清新,中调浓郁,后调温暖。适合日常使用,也是送礼的绝佳选择。' }}
</view>
</view>
<!-- 购买选项弹窗 -->
<view class="purchase-modal" v-if="showPurchaseModal" @click="closePurchaseModal">
<view class="modal-content" @click.stop>
<view class="modal-header">
<text class="modal-title">选择规格</text>
<view class="modal-close" @click="closePurchaseModal">
<text>×</text>
</view>
</view>
<view class="modal-body">
<!-- SKU选择列表 -->
<view class="sku-selection" v-if="skuList && skuList.length > 0">
<view class="sku-title-row">
<text class="sku-section-title">选择规格</text>
</view>
<view class="sku-list">
<view class="sku-item" v-for="(sku, index) in skuList"
:key="sku.sku_id !== undefined ? sku.sku_id : index" :class="{
active: selectedSkuId === (sku.sku_id !== undefined ? sku.sku_id : index),
disabled: sku.quantity !== undefined && sku.quantity === 0
}" @click="selectSku(sku, index)">
<view class="sku-info">
<view class="sku-name">{{ sku.name || sku.sku_name || '默认规格' }}</view>
<view class="sku-price-row">
<text class="sku-price-text">¥{{ formatPrice(sku.price) ||
formatPrice(sku.sku_price) }}</text>
<text class="sku-original-price"
v-if="sku.original_price && sku.original_price > sku.price">
¥{{ formatPrice(sku.original_price) }}
</text>
</view>
<view class="sku-stock" v-if="sku.quantity !== undefined">
库存:{{ sku.quantity }}件
</view>
</view>
<view class="sku-check"
v-if="selectedSkuId === (sku.sku_id !== undefined ? sku.sku_id : index)">
<text class="iconfont icon-gou"></text>
</view>
</view>
</view>
</view>
<!-- 数量选择 -->
<view class="quantity-row">
<text class="quantity-label">购买数量</text>
<view class="quantity-control">
<view class="quantity-btn" @click="decreaseQuantity">-</view>
<view class="quantity-value">{{ quantity }}</view>
<view class="quantity-btn" @click="increaseQuantity">+</view>
</view>
</view>
<view class="stock-info">库存{{ currentStock }}件</view>
<view class="subtotal">小计 ¥{{ formatPrice(subtotal) }}</view>
</view>
<view class="modal-footer">
<view class="modal-btn confirm-btn" @click="confirmPurchase">
{{ purchaseAction === 'cart' ? '加入购物车' : '立即购买' }}
</view>
</view>
</view>
</view>
<!-- 导航标签 -->
<view class="nav-tabs">
<view class="nav-tab" :class="{ active: activeTab === 'detail' }" @click="switchTab('detail')">
商品详情
</view>
<view class="nav-tab" :class="{ active: activeTab === 'spec' }" @click="switchTab('spec')">
规格参数
</view>
<view class="nav-tab" :class="{ active: activeTab === 'review' }" @click="switchTab('review')">
用户评价
</view>
</view>
<!-- 内容区域 -->
<view class="content-section">
<!-- 商品详情 -->
<view class="tab-content" v-if="activeTab === 'detail'">
<view class="detail-section">
<rich-text :nodes="productInfo.description.details"></rich-text>
</view>
<view class="detail-section">
<view class="section-title">香调层次</view>
<view class="fragrance-notes">
<view class="note-item">
<text class="note-label">前调:</text>
<text class="note-content">{{ productInfo.scent_level.top_note || '柠檬、佛手柑、粉红胡椒'
}}</text>
</view>
<view class="note-item">
<text class="note-label">中调:</text>
<text class="note-content">{{ productInfo.scent_level.middle_note || '玫瑰、茉莉、牡丹'
}}</text>
</view>
<view class="note-item">
<text class="note-label">后调:</text>
<text class="note-content">{{ productInfo.scent_level.base_note || '白麝香、雪松、香草'
}}</text>
</view>
</view>
</view>
<view class="detail-section">
<view class="section-title">主要成分</view>
<view class="ingredients">
{{ productInfo.main_ingredient || '法国进口玫瑰精油、天然香精、酒精、去离子水' }}
</view>
</view>
<view class="detail-section">
<view class="section-title">使用方法</view>
<view class="ingredients">
<!-- {{ productInfo.usage_instruction || '常温保存' }} -->
<rich-text :nodes="productInfo.usage_instruction"></rich-text>
</view>
</view>
<view class="detail-section">
<view class="section-title">保存方法</view>
<view class="ingredients">
{{ productInfo.storage_instruction || '喷涂' }}
</view>
</view>
</view>
<!-- 规格参数 -->
<view class="tab-content" v-if="activeTab === 'spec'">
<view class="spec-list">
<view class="spec-item">
<text class="spec-label">品牌:</text>
<text class="spec-value">{{ productInfo.attr.brand }}</text>
</view>
<view class="spec-item">
<text class="spec-label">容量:</text>
<text class="spec-value">{{ productInfo.attr.capacity }}ml</text>
</view>
<view class="spec-item">
<text class="spec-label">香型:</text>
<text class="spec-value">{{ productInfo.attr.fragrance_notes }}</text>
</view>
<view class="spec-item">
<text class="spec-label">持香时间:</text>
<text class="spec-value">{{ productInfo.attr.duration }} 小时</text>
</view>
<view class="spec-item">
<text class="spec-label">产地:</text>
<text class="spec-value">{{ productInfo.attr.origin }}</text>
</view>
</view>
</view>
<!-- 用户评价 -->
<view class="tab-content" v-if="activeTab === 'review'">
<view class="review-list">
<view class="review-item" v-for="(review, index) in reviews" :key="index">
<view class="review-header">
<view class="review-user">{{ review.username || '用户' + (index + 1) }}</view>
<view class="review-rating">
<text class="iconfont icon-xingxing" v-for="n in review.rating" :key="n"></text>
</view>
</view>
<view class="review-content">{{ review.content || '商品很不错,香味持久,包装精美!' }}</view>
<view class="review-time">{{ review.time || '2025-01-15' }}</view>
</view>
</view>
</view>
</view>
<!-- 服务保障 -->
<view class="service-guarantee">
<view class="section-title">服务保障</view>
<view class="guarantee-list">
<view class="guarantee-item">
<view class="guarantee-icon guarantee-icon-1">
<text class="iconfont icon-zhengpinbaozhang"></text>
</view>
<text class="guarantee-text">正品保证</text>
</view>
<view class="guarantee-item">
<view class="guarantee-icon guarantee-icon-2">
<text class="iconfont icon-wuliu"></text>
</view>
<text class="guarantee-text">免费配送</text>
</view>
<view class="guarantee-item">
<view class="guarantee-icon guarantee-icon-3">
<text></text>
</view>
<text class="guarantee-text">7天退换</text>
</view>
</view>
</view>
<!-- 底部操作栏 -->
<view class="bottom-bar">
<view class="bar-btn" @click="goHome">
<text class="iconfont icon-caidan"></text>
<text>首页</text>
</view>
<view class="bar-btn" @click="goToCart">
<text class="iconfont icon-gouwuche"></text>
<text>购物车</text>
<view v-if="cartSelectedCount > 0" class="cart-count">{{ cartSelectedCount }}</view>
</view>
<view class="bar-btn cart-btn" @click="addToCart">加入购物车</view>
<!-- <view class="bar-btn primary" @click="buyNow">立即购买</view> -->
</view>
</view>
</template>
<script>
import request from '@/api/request.js';
import { parseDescription } from '/tools/format';
export default {
data() {
return {
productId: '',
currentImageIndex: 0,
productImages: [
'https://via.placeholder.com/750x750/87CEEB/FFFFFF?text=Product+Image+1'
],
productInfo: {
name: '玫瑰香水盲盒',
rating: 4.8,
review_count: 234,
like_count: 567,
price: 139,
original_price: 199,
description: '经典玫瑰香调,优雅女神范,持久留香8小时。采用法国进口玫瑰精油,层次丰富,前调清新,中调浓郁,后调温暖。适合日常使用,也是送礼的绝佳选择。',
is_hot_selling: true,
is_limited: true,
is_imported: true,
quantity: 15,
ingredients: '法国进口玫瑰精油、天然香精、酒精、去离子水',
usage_instruction: '常温保存',
storage_instruction: '喷涂',
scent_level: {
top_note: '柠檬、佛手柑、粉红胡椒',
middle_note: '玫瑰、茉莉、牡丹',
base_note: '白麝香、雪松、香草'
},
attr: {
brand: '香水有毒',
capacity: '50ml',
fragrance_notes: '玫瑰花香调',
duration: '8小时',
origin: '法国'
}
},
skuList: [],
selectedSkuId: null,
selectedSku: null,
quantity: 1,
activeTab: 'detail',
showPurchaseModal: false,
purchaseAction: 'cart', // 'cart' 或 'buy'
cartSelectedCount: 0,
fragranceNotes: {
top: '柠檬、佛手柑、粉红胡椒',
middle: '玫瑰、茉莉、牡丹',
base: '白麝香、雪松、香草'
},
specifications: [
{ label: '品牌', value: '香水有毒' },
{ label: '容量', value: '50ml' },
{ label: '香型', value: '玫瑰花香调' },
{ label: '适用人群', value: '女性' },
{ label: '保质期', value: '36个月' },
{ label: '产地', value: '法国' }
],
reviews: [
{ username: '用户1', rating: 5, content: '商品很不错,香味持久,包装精美!', time: '2025-01-15' },
{ username: '用户2', rating: 5, content: '非常喜欢这个味道,已经回购了!', time: '2025-01-14' },
{ username: '用户3', rating: 4, content: '包装很精美,送人很不错。', time: '2025-01-13' }
]
};
},
computed: {
currentPrice() {
// 直接取第一个SKU的价格
if (this.skuList && this.skuList.length > 0) {
const firstSku = this.skuList[0];
return firstSku.price || firstSku.sku_price || 0;
}
return this.productInfo.price || 139;
},
originalPrice() {
// 直接取第一个SKU的原价
if (this.skuList && this.skuList.length > 0) {
const firstSku = this.skuList[0];
return firstSku.original_price || 0;
}
return this.productInfo.original_price || 199;
},
currentStock() {
if (this.selectedSku && this.selectedSku.quantity !== undefined) {
return this.selectedSku.quantity;
}
return this.productInfo.quantity || 0;
},
subtotal() {
return this.currentPrice * this.quantity;
}
},
onLoad(options) {
// this.productInfo = uni.getStorageSync('product_info');
this.loadProductDetail(uni.getStorageSync('product_info'));
this.fetchCartSelectedCount();
},
onShow() {
this.fetchCartSelectedCount();
},
methods: {
// 格式化价格
formatPrice(value) {
if (!value) {
return 0.00;
}
// 分转换为元
value = value / 100;
// 保留两位小数
return value.toFixed(2);
},
// 加载商品详情
async loadProductDetail(productInfo) {
if (!productInfo) {
console.warn('商品信息为空');
return;
}
this.productInfo = productInfo;
if (productInfo.image_url) {
this.productImages = productInfo.image_url.split(',').filter(url => url.trim());
}
this.productInfo.scent_level = JSON.parse(productInfo.scent_level);
this.productInfo.attr = JSON.parse(productInfo.attr);
this.productInfo.description = parseDescription(productInfo.description);
console.log(this.productInfo.description)
// 处理SKU列表
if (productInfo.skus && Array.isArray(productInfo.skus) && productInfo.skus.length > 0) {
this.skuList = productInfo.skus;
// 默认选择第一个有库存的SKU
const availableSku = productInfo.skus.find(sku => sku && (sku.quantity > 0 || sku.quantity === undefined)) || productInfo.skus[0];
if (availableSku) {
const skuIndex = productInfo.skus.indexOf(availableSku);
this.selectSku(availableSku, skuIndex >= 0 ? skuIndex : 0);
}
} else if (productInfo.sku) {
// 如果只有一个SKU对象
this.skuList = [productInfo.sku];
this.selectSku(productInfo.sku, 0);
} else {
// 如果没有SKU使用商品本身作为默认SKU
this.skuList = [{
id: productInfo.id,
name: '默认规格',
price: productInfo.price,
original_price: productInfo.original_price,
quantity: productInfo.quantity
}];
this.selectSku(this.skuList[0], 0);
}
},
// 轮播图切换
onSwiperChange(e) {
this.currentImageIndex = e.detail.current;
},
// 上一张图片
prevImage() {
if (this.currentImageIndex > 0) {
this.currentImageIndex--;
} else {
this.currentImageIndex = this.productImages.length - 1;
}
},
// 下一张图片
nextImage() {
if (this.currentImageIndex < this.productImages.length - 1) {
this.currentImageIndex++;
} else {
this.currentImageIndex = 0;
}
},
// 减少数量
decreaseQuantity() {
if (this.quantity > 1) {
this.quantity--;
} else {
uni.showToast({
title: '商品数量不能少于1',
icon: 'none'
});
}
},
// 增加数量
increaseQuantity() {
if (this.quantity < this.currentStock) {
this.quantity++;
} else {
uni.showToast({
title: '库存不足',
icon: 'none'
});
}
},
// 选择SKU
selectSku(sku, index) {
if (!sku) {
return;
}
// 检查库存quantity为0时不可选但undefined时允许选择
if (sku.quantity !== undefined && sku.quantity === 0) {
uni.showToast({
title: '该规格暂无库存',
icon: 'none'
});
return;
}
this.selectedSkuId = sku.sku_id !== undefined ? sku.sku_id : index;
this.selectedSku = sku;
// 如果当前数量超过新SKU的库存重置数量
if (sku.quantity !== undefined && this.quantity > sku.quantity) {
this.quantity = sku.quantity;
}
},
// 切换标签
switchTab(tab) {
this.activeTab = tab;
},
async userIsLogin() {
const token = await uni.getStorageSync('access_token')
if (token) {
return
} else {
uni.navigateTo({
url: '/pages/login/index'
})
}
},
// 打开购买弹窗 - 加入购物车
async addToCart() {
await this.userIsLogin().then(async (res) => {
this.purchaseAction = 'cart';
// 如果还没有选择SKU自动选择第一个可用的
if (!this.selectedSku && this.skuList.length > 0) {
const availableSku = this.skuList.find(sku => sku && (sku.quantity > 0 || sku.quantity === undefined)) || this.skuList[0];
if (availableSku) {
const skuIndex = this.skuList.indexOf(availableSku);
this.selectSku(availableSku, skuIndex >= 0 ? skuIndex : 0);
}
}
this.showPurchaseModal = true;
}).catch((err) => {
console.log(err);
});
},
// 打开购买弹窗 - 立即购买
async buyNow() {
await this.userIsLogin().then((res) => {
this.purchaseAction = 'buy';
// 如果还没有选择SKU自动选择第一个可用的
if (!this.selectedSku && this.skuList.length > 0) {
const availableSku = this.skuList.find(sku => sku && (sku.quantity > 0 || sku.quantity === undefined)) || this.skuList[0];
if (availableSku) {
const skuIndex = this.skuList.indexOf(availableSku);
this.selectSku(availableSku, skuIndex >= 0 ? skuIndex : 0);
}
}
this.showPurchaseModal = true;
}).catch((err) => {
console.log(err);
});
},
// 关闭购买弹窗
closePurchaseModal() {
this.showPurchaseModal = false;
},
// 确认购买
async confirmPurchase() {
if (!this.selectedSku) {
uni.showToast({
title: '请选择商品规格',
icon: 'none'
});
return;
}
if (this.purchaseAction === 'cart') {
// 添加到购物车
try {
await request('xcx/cart', 'POST', {
product_id: this.productInfo.id || this.productId,
sku_id: this.selectedSku.sku_id,
quantity: this.quantity
});
this.showPurchaseModal = false;
uni.showToast({
title: '已添加到购物车',
icon: 'success'
});
this.fetchCartSelectedCount();
} catch (error) {
console.error('添加到购物车失败:', error);
uni.showToast({
title: '添加失败,请重试',
icon: 'none'
});
}
} else {
// 立即购买
this.showPurchaseModal = false;
const orderData = [{
product_id: this.productInfo.id || this.productId,
sku_id: this.selectedSku.sku_id,
quantity: this.quantity,
price: this.currentPrice
}];
uni.navigateTo({
url: `/pages/order/create?items=${encodeURIComponent(JSON.stringify(orderData))}`
});
}
},
// 返回首页
goHome() {
uni.switchTab({
url: '/pages/index/index'
});
},
// 跳转到购物车
goToCart() {
uni.navigateTo({
url: '/pages/shoppingCart/index'
});
},
async fetchCartSelectedCount() {
try {
const res = await request('xcx/carts', 'GET', { page: 1, page_size: 99 });
const list = res.list || res.data || res || [];
this.cartSelectedCount = list
.filter(item => item && item.selected === 1)
.reduce((sum, item) => {
const quantity = parseInt(item.quantity || item.count || 0, 10);
return sum + (isNaN(quantity) ? 0 : quantity);
}, 0);
} catch (error) {
console.error('获取购物车数量失败:', error);
}
}
}
};
</script>
<style scoped>
.detail-page {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 120rpx;
}
/* 图片轮播 */
.image-swiper-wrapper {
position: relative;
width: 100%;
height: 750rpx;
background-color: #fff;
}
.image-swiper {
width: 100%;
height: 100%;
}
/* 自定义指示器样式 */
.image-swiper ::v-deep .uni-swiper-dot {
width: 12rpx;
height: 12rpx;
border-radius: 6rpx;
background-color: rgba(0, 0, 0, 0.2);
}
.image-swiper ::v-deep .uni-swiper-dot-active {
width: 24rpx;
background-color: #fff;
}
.swiper-image {
width: 100%;
height: 100%;
}
.swiper-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 60rpx;
height: 60rpx;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
}
.swiper-nav.prev {
left: 24rpx;
}
.swiper-nav.next {
right: 24rpx;
}
.swiper-nav text {
font-size: 48rpx;
color: #666;
font-weight: bold;
line-height: 1;
}
/* 商品信息 */
.product-info {
background-color: #fff;
padding: 32rpx 24rpx;
margin-bottom: 20rpx;
}
.product-tags {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
margin-bottom: 24rpx;
}
.tag {
padding: 6rpx 16rpx;
border: 2rpx solid rgba(152, 16, 250, 0.6);
border-radius: 6rpx;
font-size: 22rpx;
color: rgba(152, 16, 250, 0.9);
background-color: transparent;
}
.product-name {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
line-height: 1.4;
}
.product-sub-title {
font-size: 28rpx;
color: #999;
margin-bottom: 20rpx;
line-height: 1.4;
}
.product-rating {
display: flex;
align-items: center;
margin-bottom: 20rpx;
font-size: 26rpx;
}
.star-icon {
color: #ffd700;
font-size: 28rpx;
margin-right: 8rpx;
}
.rating-value {
color: #333;
font-weight: 500;
margin-right: 8rpx;
}
.rating-text {
color: #999;
margin-right: 24rpx;
}
.like-text {
color: #999;
}
.product-price {
display: flex;
align-items: baseline;
margin-bottom: 24rpx;
}
.current-price {
font-size: 48rpx;
font-weight: bold;
color: #e7000b;
margin-right: 16rpx;
}
.original-price {
font-size: 28rpx;
color: #999;
text-decoration: line-through;
}
.product-description {
font-size: 28rpx;
color: #666;
line-height: 1.6;
}
/* 购买选项弹窗 */
.purchase-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: flex-end;
justify-content: center;
z-index: 1000;
animation: fadeIn 0.3s;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.modal-content {
width: 100%;
max-height: 80vh;
background-color: #fff;
border-radius: 32rpx 32rpx 0 0;
display: flex;
flex-direction: column;
animation: slideUp 0.3s;
}
@keyframes slideUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32rpx 24rpx;
border-bottom: 2rpx solid #f5f5f5;
}
.modal-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.modal-close {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 48rpx;
color: #999;
}
.modal-body {
flex: 1;
padding: 32rpx 24rpx;
overflow-y: auto;
max-height: calc(80vh - 200rpx);
}
.modal-footer {
padding: 24rpx;
border-top: 2rpx solid #f5f5f5;
}
.modal-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
text-align: center;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 500;
}
.confirm-btn {
background: linear-gradient(135deg, #9810fa 0%, #7a0bc7 100%);
color: #fff;
}
/* SKU选择 */
.sku-selection {
margin-bottom: 32rpx;
}
.sku-title-row {
margin-bottom: 24rpx;
}
.sku-section-title {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.sku-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.sku-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx;
border: 2rpx solid #e5e5e5;
border-radius: 12rpx;
background-color: #fff;
transition: all 0.3s;
}
.sku-item.active {
border-color: #9810fa;
background-color: rgba(152, 16, 250, 0.05);
}
.sku-item.disabled {
opacity: 0.5;
background-color: #f5f5f5;
}
.sku-info {
flex: 1;
}
.sku-name {
font-size: 28rpx;
color: #333;
font-weight: 500;
margin-bottom: 12rpx;
}
.sku-price-row {
display: flex;
align-items: baseline;
gap: 16rpx;
margin-bottom: 8rpx;
}
.sku-price-text {
font-size: 32rpx;
color: #e7000b;
font-weight: bold;
}
.sku-original-price {
font-size: 24rpx;
color: #999;
text-decoration: line-through;
}
.sku-stock {
font-size: 24rpx;
color: #999;
}
.sku-check {
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #9810fa 0%, #7a0bc7 100%);
border-radius: 50%;
}
.sku-check .iconfont {
color: #fff;
font-size: 24rpx;
}
.sku-hint {
font-size: 24rpx;
color: #ff9800;
margin-top: 8rpx;
}
.quantity-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.quantity-label {
font-size: 28rpx;
color: #333;
}
.quantity-control {
display: flex;
align-items: center;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
overflow: hidden;
}
.quantity-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
color: #666;
background-color: #f8f8f8;
}
.quantity-btn:active {
background-color: #e8e8e8;
}
.quantity-value {
min-width: 80rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #333;
background-color: #fff;
border-left: 2rpx solid #e5e5e5;
border-right: 2rpx solid #e5e5e5;
}
.stock-info {
font-size: 24rpx;
color: #999;
margin-bottom: 16rpx;
}
.subtotal {
text-align: right;
font-size: 32rpx;
color: #e7000b;
font-weight: bold;
}
/* 导航标签 */
.nav-tabs {
display: flex;
background-color: #fff;
margin-bottom: 20rpx;
padding: 0 24rpx;
}
.nav-tab {
flex: 1;
text-align: center;
padding: 24rpx 0;
font-size: 28rpx;
color: #666;
position: relative;
}
.nav-tab.active {
color: #9810fa;
font-weight: 500;
}
.nav-tab.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 4rpx;
background-color: #9810fa;
border-radius: 2rpx;
}
/* 内容区域 */
.content-section {
background-color: #fff;
padding: 32rpx 24rpx;
min-height: 400rpx;
}
.tab-content {
width: 100%;
}
.detail-section {
margin-bottom: 40rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 24rpx;
}
.fragrance-notes {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.note-item {
font-size: 28rpx;
line-height: 1.6;
}
.note-label {
color: #666;
font-weight: 500;
}
.note-content {
color: #333;
}
.ingredients {
font-size: 28rpx;
color: #666;
line-height: 1.6;
}
/* 服务保障 */
.service-guarantee {
margin-top: 20rpx;
margin-bottom: 40rpx;
/* border-top: 2rpx solid #f5f5f5; */
padding: 32rpx 24rpx;
background-color: #fff;
}
.guarantee-list {
display: flex;
justify-content: space-around;
align-items: center;
padding: 20rpx 0;
}
.guarantee-item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.guarantee-icon {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16rpx;
}
.guarantee-icon-1 {
background-color: rgba(76, 175, 80, 0.1);
color: #4caf50;
}
.guarantee-icon-2 {
background-color: rgba(33, 150, 243, 0.1);
color: #2196f3;
}
.guarantee-icon-3 {
background-color: rgba(156, 39, 176, 0.1);
color: #9c27b0;
}
.guarantee-icon .iconfont {
font-size: 48rpx;
}
.guarantee-icon text {
font-size: 48rpx;
line-height: 1;
}
.guarantee-text {
font-size: 24rpx;
color: #666;
}
.spec-list {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.spec-item {
font-size: 28rpx;
line-height: 1.6;
}
.spec-label {
color: #666;
font-weight: 500;
}
.spec-value {
color: #333;
}
.review-list {
display: flex;
flex-direction: column;
gap: 32rpx;
}
.review-item {
padding-bottom: 32rpx;
border-bottom: 2rpx solid #f5f5f5;
}
.review-item:last-child {
border-bottom: none;
}
.review-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.review-user {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.review-rating {
display: flex;
gap: 4rpx;
}
.review-rating .iconfont {
font-size: 24rpx;
color: #ffd700;
}
.review-content {
font-size: 28rpx;
color: #666;
line-height: 1.6;
margin-bottom: 12rpx;
}
.review-time {
font-size: 24rpx;
color: #999;
}
/* 底部操作栏 */
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx;
background-color: #fff;
display: flex;
align-items: center;
box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.05);
z-index: 100;
}
.bar-btn {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 24rpx;
color: #666;
padding: 12rpx 0;
box-sizing: border-box;
position: relative;
}
.bar-btn .iconfont {
font-size: 36rpx;
margin-bottom: 4rpx;
}
.bar-btn.cart-btn {
flex: 2;
background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);
color: #fff;
font-size: 28rpx;
font-weight: 500;
margin: 0 12rpx;
border-radius: 48rpx;
height: 72rpx;
line-height: 72rpx;
flex-direction: row;
}
.bar-btn.primary {
flex: 2;
background: linear-gradient(135deg, #9810fa 0%, #7a0bc7 100%);
color: #fff;
font-size: 32rpx;
font-weight: 500;
margin: 0 24rpx;
border-radius: 48rpx;
height: 72rpx;
line-height: 72rpx;
}
.cart-count {
position: absolute;
top: 6rpx;
right: 36rpx;
min-width: 32rpx;
padding: 0 8rpx;
height: 32rpx;
border-radius: 16rpx;
background-color: #ff4d4f;
color: #fff;
font-size: 20rpx;
line-height: 32rpx;
text-align: center;
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.15);
}
</style>