1.0
This commit is contained in:
@@ -0,0 +1,781 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 商品图片轮播 -->
|
||||
<view class="image-section">
|
||||
<swiper class="image-swiper" :indicator-dots="imageList.length > 1" indicator-color="rgba(255,255,255,0.5)" indicator-active-color="#FF4444" :autoplay="false" :circular="true">
|
||||
<swiper-item v-for="(image, index) in imageList" :key="index">
|
||||
<image :src="getFullImageUrl(image)" class="product-image" mode="aspectFill" @tap="previewImage(index)"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="image-count" v-if="imageList.length > 1">
|
||||
<text>{{ currentImageIndex + 1 }}/{{ imageList.length }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品基本信息 -->
|
||||
<view class="product-info-section">
|
||||
<view class="price-section">
|
||||
<view class="current-price">
|
||||
<text class="price-symbol">¥</text>
|
||||
<text class="price-value">{{ productInfo.current_price || productInfo.selling_price }}</text>
|
||||
</view>
|
||||
<view class="original-price" v-if="productInfo.original_price && productInfo.original_price != productInfo.current_price">
|
||||
<text class="original-price-text">原价 ¥{{ productInfo.original_price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="product-title">
|
||||
<text class="product-name">{{ productInfo.product_name }}</text>
|
||||
</view>
|
||||
|
||||
<view class="product-stats">
|
||||
<text class="stats-item">销量 {{ productInfo.sales_count || 0 }}</text>
|
||||
<text class="stats-item">库存 {{ productInfo.stock_quantity || productInfo.quantity || 0 }}</text>
|
||||
<text class="stats-item">浏览 {{ productInfo.view_count || 0 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 卖家信息(仅二级商品显示) -->
|
||||
<view class="seller-section" v-if="productType === 'secondary' && productInfo.seller">
|
||||
<view class="section-title">卖家信息</view>
|
||||
<view class="seller-info">
|
||||
<image :src="getFullImageUrl(productInfo.seller.avatar)" class="seller-avatar" mode="aspectFill" v-if="productInfo.seller.avatar"></image>
|
||||
<view class="seller-avatar-placeholder" v-else>
|
||||
<uni-icons type="person" size="40" color="#ccc"></uni-icons>
|
||||
</view>
|
||||
<view class="seller-details">
|
||||
<text class="seller-name">{{ productInfo.seller.real_name || productInfo.seller.customer_name }}</text>
|
||||
<text class="seller-code">ID: {{ productInfo.seller.identity_code }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品描述 -->
|
||||
<view class="description-section" v-if="productInfo.product_description">
|
||||
<view class="section-title">商品描述</view>
|
||||
<view class="description-content">
|
||||
<text class="description-text">{{ productInfo.product_description }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 购买数量选择弹窗 -->
|
||||
<uni-popup ref="quantityPopup" type="bottom" background-color="#fff" border-radius="20rpx 20rpx 0 0">
|
||||
<view class="quantity-popup">
|
||||
<view class="popup-content">
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">选择购买数量</text>
|
||||
<view class="close-btn" @tap="closeQuantityPopup">
|
||||
<uni-icons type="close" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="popup-product-info">
|
||||
<image :src="getFullImageUrl(getFirstImage(productInfo.product_images))" class="popup-product-image" mode="aspectFill"></image>
|
||||
<view class="popup-product-details">
|
||||
<text class="popup-product-name">{{ productInfo.product_name }}</text>
|
||||
<text class="popup-product-price">¥{{ productInfo.current_price || productInfo.selling_price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="quantity-selector">
|
||||
<text class="quantity-label">购买数量</text>
|
||||
<view class="quantity-controls">
|
||||
<view class="quantity-btn" @tap="decreaseQuantity" :class="{ disabled: selectedQuantity <= 1 }">
|
||||
<uni-icons type="minus" size="16" color="#666"></uni-icons>
|
||||
</view>
|
||||
<input class="quantity-input" type="number" v-model="selectedQuantity" @input="onQuantityInput" />
|
||||
<view class="quantity-btn" @tap="increaseQuantity" :class="{ disabled: selectedQuantity >= maxQuantity }">
|
||||
<uni-icons type="plus" size="16" color="#666"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<text class="stock-info">库存{{ maxQuantity }}件</text>
|
||||
</view>
|
||||
|
||||
<view class="total-price">
|
||||
<text class="total-label">总价:</text>
|
||||
<text class="total-amount">¥{{ (selectedQuantity * (productInfo.current_price || productInfo.selling_price)).toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="popup-footer">
|
||||
<button class="confirm-buy-btn" @tap="confirmPurchase">
|
||||
立即购买
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<!-- 底部购买栏 -->
|
||||
<view class="bottom-bar">
|
||||
<button class="buy-btn" @tap="showQuantityPopup" :disabled="!canPurchase">
|
||||
<text v-if="!canPurchase">暂时无法购买</text>
|
||||
<text v-else>立即购买</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-overlay" v-if="loading">
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
productId: '',
|
||||
productType: '', // 'primary' 或 'secondary'
|
||||
productInfo: {},
|
||||
imageList: [],
|
||||
currentImageIndex: 0,
|
||||
selectedQuantity: 1,
|
||||
maxQuantity: 0,
|
||||
loading: false,
|
||||
canPurchase: true
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
// 检查登录状态
|
||||
const token = uni.getStorageSync('token')
|
||||
if (!token) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 显示安全提示弹窗
|
||||
this.showSecurityAlert()
|
||||
|
||||
if (options.id && options.type) {
|
||||
this.productId = options.id
|
||||
this.productType = options.type
|
||||
this.loadProductDetail()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '商品信息有误',
|
||||
icon: 'none'
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 显示安全提示弹窗
|
||||
showSecurityAlert() {
|
||||
// 检查是否已经显示过,避免重复提示
|
||||
const hasShownAlert = uni.getStorageSync('security_alert_shown')
|
||||
if (hasShownAlert) {
|
||||
return
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: '安全提示',
|
||||
content: '为了您的账户安全,请在使用过程中:\n\n• 关闭WiFi连接\n• 关闭位置服务\n• 关闭蓝牙功能\n• 关闭热点功能\n\n这样可以防止信息泄露,保护您的隐私安全。',
|
||||
showCancel: true,
|
||||
cancelText: '知道了',
|
||||
confirmText: '不再提示',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 用户选择不再提示,记录到本地存储
|
||||
uni.setStorageSync('security_alert_shown', true)
|
||||
}
|
||||
// 无论用户选择什么,都已经显示过提示了
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 获取完整的图片URL
|
||||
getFullImageUrl(url) {
|
||||
return request.getImageUrl(url)
|
||||
},
|
||||
|
||||
// 获取商品的第一张图片
|
||||
getFirstImage(images) {
|
||||
if (!images) return ''
|
||||
// 如果是逗号分隔的字符串
|
||||
if (typeof images === 'string') {
|
||||
return images.split(',')[0].trim()
|
||||
}
|
||||
// 如果是数组
|
||||
if (Array.isArray(images) && images.length > 0) {
|
||||
return images[0]
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
// 加载商品详情
|
||||
async loadProductDetail() {
|
||||
this.loading = true
|
||||
try {
|
||||
let url = ''
|
||||
if (this.productType === 'primary') {
|
||||
url = `/back/user/products/primary/${this.productId}`
|
||||
} else {
|
||||
url = `/back/user/products/secondary/${this.productId}`
|
||||
}
|
||||
|
||||
const res = await request.get(url)
|
||||
if (res.success) {
|
||||
this.productInfo = res.data
|
||||
this.processProductImages()
|
||||
this.calculateMaxQuantity()
|
||||
this.checkCanPurchase()
|
||||
} else {
|
||||
throw new Error(res.message || '加载商品详情失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载商品详情失败:', error)
|
||||
uni.showToast({
|
||||
title: '加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 处理商品图片
|
||||
processProductImages() {
|
||||
if (this.productInfo.product_images) {
|
||||
if (typeof this.productInfo.product_images === 'string') {
|
||||
this.imageList = this.productInfo.product_images.split(',').map(img => img.trim()).filter(img => img)
|
||||
} else if (Array.isArray(this.productInfo.product_images)) {
|
||||
this.imageList = this.productInfo.product_images
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有图片,设置默认图片
|
||||
if (this.imageList.length === 0) {
|
||||
this.imageList = ['/static/images/default-product.png']
|
||||
}
|
||||
},
|
||||
|
||||
// 计算最大购买数量
|
||||
calculateMaxQuantity() {
|
||||
if (this.productType === 'primary') {
|
||||
this.maxQuantity = this.productInfo.stock_quantity || 0
|
||||
} else {
|
||||
this.maxQuantity = this.productInfo.quantity || 0
|
||||
}
|
||||
},
|
||||
|
||||
// 检查是否可以购买
|
||||
checkCanPurchase() {
|
||||
if (this.maxQuantity <= 0) {
|
||||
this.canPurchase = false
|
||||
return
|
||||
}
|
||||
|
||||
// 如果是二级商品,需要检查是否是自己的商品
|
||||
if (this.productType === 'secondary') {
|
||||
const userInfo = uni.getStorageSync('userInfo')
|
||||
if (userInfo && this.productInfo.seller_id === userInfo.id) {
|
||||
this.canPurchase = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
this.canPurchase = true
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage(index) {
|
||||
const urls = this.imageList.map(img => this.getFullImageUrl(img))
|
||||
uni.previewImage({
|
||||
urls: urls,
|
||||
current: index
|
||||
})
|
||||
},
|
||||
|
||||
// 显示数量选择弹窗
|
||||
showQuantityPopup() {
|
||||
if (!this.canPurchase) return
|
||||
|
||||
this.selectedQuantity = 1
|
||||
this.$refs.quantityPopup.open()
|
||||
},
|
||||
|
||||
// 关闭数量选择弹窗
|
||||
closeQuantityPopup() {
|
||||
this.$refs.quantityPopup.close()
|
||||
},
|
||||
|
||||
// 减少数量
|
||||
decreaseQuantity() {
|
||||
if (this.selectedQuantity > 1) {
|
||||
this.selectedQuantity--
|
||||
}
|
||||
},
|
||||
|
||||
// 增加数量
|
||||
increaseQuantity() {
|
||||
if (this.selectedQuantity < this.maxQuantity) {
|
||||
this.selectedQuantity++
|
||||
}
|
||||
},
|
||||
|
||||
// 数量输入处理
|
||||
onQuantityInput(e) {
|
||||
let value = parseInt(e.detail.value) || 1
|
||||
if (value < 1) value = 1
|
||||
if (value > this.maxQuantity) value = this.maxQuantity
|
||||
this.selectedQuantity = value
|
||||
},
|
||||
|
||||
// 确认购买
|
||||
async confirmPurchase() {
|
||||
if (this.selectedQuantity <= 0 || this.selectedQuantity > this.maxQuantity) {
|
||||
uni.showToast({
|
||||
title: '购买数量有误',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 先检查是否有收货地址
|
||||
try {
|
||||
const addressRes = await request.get('/back/user/addresses')
|
||||
if (!addressRes.success || !addressRes.data || addressRes.data.length === 0) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请先设置收货地址',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/address/edit'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 创建订单
|
||||
const orderData = {
|
||||
product_id: parseInt(this.productId),
|
||||
product_type: this.productType === 'primary' ? 1 : 2,
|
||||
product_name: this.productInfo.product_name,
|
||||
product_images: this.getFirstImage(this.productInfo.product_images),
|
||||
unit_price: this.productInfo.current_price || this.productInfo.selling_price,
|
||||
quantity: this.selectedQuantity,
|
||||
total_amount: parseFloat((this.selectedQuantity * (this.productInfo.current_price || this.productInfo.selling_price)).toFixed(2)),
|
||||
address_id: addressRes.data.find(addr => addr.is_default === 1)?.id || addressRes.data[0].id,
|
||||
remark: ''
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: '创建订单中...',
|
||||
mask: true
|
||||
})
|
||||
|
||||
const orderRes = await request.post('/back/user/orders/purchase', orderData)
|
||||
var isSecond=this.productType === 'primary' ? false : true
|
||||
if (orderRes.success) {
|
||||
uni.hideLoading()
|
||||
|
||||
// 关闭弹窗
|
||||
this.closeQuantityPopup()
|
||||
|
||||
// 跳转到付款页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/payment/purchase?order_id=${orderRes.data.order_id}&order_no=${orderRes.data.order_no}&is_second=${isSecond}`
|
||||
})
|
||||
|
||||
uni.showToast({
|
||||
title: '订单创建成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} else {
|
||||
throw new Error(orderRes.message || '创建订单失败')
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading()
|
||||
console.error('创建订单失败:', error)
|
||||
uni.showToast({
|
||||
title: error.message || '创建订单失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
.image-section {
|
||||
position: relative;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.image-swiper {
|
||||
width: 100%;
|
||||
height: 750rpx;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-count {
|
||||
position: absolute;
|
||||
bottom: 20rpx;
|
||||
right: 20rpx;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.product-info-section {
|
||||
background: white;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.price-section {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.current-price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.price-symbol {
|
||||
font-size: 28rpx;
|
||||
color: #FF4444;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.price-value {
|
||||
font-size: 48rpx;
|
||||
color: #FF4444;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.original-price-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.product-stats {
|
||||
display: flex;
|
||||
gap: 30rpx;
|
||||
}
|
||||
|
||||
.stats-item {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.seller-section {
|
||||
background: white;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.seller-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.seller-avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.seller-avatar-placeholder {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.seller-details {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.seller-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.seller-code {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.description-section {
|
||||
background: white;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.description-content {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
padding: 20rpx 30rpx;
|
||||
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
}
|
||||
|
||||
.buy-btn {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background: linear-gradient(135deg, #FF4444 0%, #FF6666 100%);
|
||||
border: none;
|
||||
border-radius: 40rpx;
|
||||
color: white;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.buy-btn:disabled {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
.quantity-popup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 75vh;
|
||||
background: white;
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
flex: 1;
|
||||
padding: 40rpx 30rpx 20rpx;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.popup-footer {
|
||||
padding: 20rpx 30rpx;
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
border-top: 1rpx solid #f5f5f5;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.popup-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
.popup-product-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
background: #f8f8f8;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.popup-product-image {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.popup-product-details {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.popup-product-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.popup-product-price {
|
||||
font-size: 32rpx;
|
||||
color: #FF4444;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.quantity-selector {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.quantity-label {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.quantity-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.quantity-btn {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.quantity-btn.disabled {
|
||||
background: #f5f5f5;
|
||||
border-color: #eee;
|
||||
}
|
||||
|
||||
.quantity-input {
|
||||
width: 120rpx;
|
||||
height: 60rpx;
|
||||
text-align: center;
|
||||
border: 1rpx solid #ddd;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.stock-info {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.total-price {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.total-label {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.total-amount {
|
||||
font-size: 36rpx;
|
||||
color: #FF4444;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.confirm-buy-btn {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background: linear-gradient(135deg, #FF4444 0%, #FF6666 100%);
|
||||
border: none;
|
||||
border-radius: 40rpx;
|
||||
color: white;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.confirm-buy-btn:disabled {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user