consumer模块完成度95%,优化安卓端界面和小程序测试

This commit is contained in:
cyh666666
2026-03-11 17:17:32 +08:00
parent 5517c93666
commit 77f9968d18
622 changed files with 3100 additions and 1995 deletions

View File

@@ -16,12 +16,14 @@
<view class="product-info">
<view class="price-section">
<text class="current-price">¥{{ product.price }}</text>
<text v-if="memberPrice > 0 && memberPrice < product.price" class="member-price-tag">会员价 ¥{{ memberPrice }}</text>
<!-- 会员价功能已禁用 -->
<!-- <text v-if="memberPrice > 0 && memberPrice < product.price" class="member-price-tag">会员价 ¥{{ memberPrice }}</text> -->
<text v-if="product.original_price" class="original-price">¥{{ product.original_price }}</text>
</view>
<view v-if="memberDiscount > 0" class="member-discount-row">
<!-- 会员专享折扣功能已禁用 -->
<!-- <view v-if="memberDiscount > 0" class="member-discount-row">
<text class="member-discount-text">会员专享 {{ memberDiscount }}折优惠</text>
</view>
</view> -->
<text class="product-name">{{ product.name }}</text>
<text class="sales-info">已售{{ product.sales }}件 · 库存{{ product.stock }}件</text>
</view>
@@ -69,7 +71,7 @@
<view class="detail-cell spec-section" @click="showSpecModal" v-if="productSkus.length > 0">
<text class="cell-label">规格</text>
<view class="cell-content">
<text class="spec-selected">{{ selectedSpec ?? '请选择规格' }}</text>
<text class="spec-selected">{{ selectedSpec != '' ? selectedSpec : '请选择规格' }}</text>
</view>
<text class="cell-arrow"></text>
</view>
@@ -135,23 +137,54 @@
</view>
</view>
<!-- 规格选择弹窗 -->
<!-- 规格选择弹窗 (京东风格) -->
<view v-if="showSpec" class="spec-modal" @click="hideSpecModal">
<view class="spec-content" @click.stop>
<view class="spec-header">
<text class="spec-title">选择规格</text>
<text class="close-btn" @click="hideSpecModal">×</text>
<view class="spec-header-jd">
<image :src="getSelectedSkuImage()" class="spec-product-img" mode="aspectFill" />
<view class="spec-info-jd">
<view class="spec-price-row">
<text class="price-symbol">¥</text>
<text class="price-value">{{ getSelectedSkuPrice() }}</text>
</view>
<text class="spec-stock-jd">库存: {{ getSelectedSkuStock() }}件</text>
<text class="spec-choosed-jd">已选: {{ selectedSpec != '' ? selectedSpec : '请选择规格' }}</text>
</view>
<text class="close-btn-jd" @click="hideSpecModal">×</text>
</view>
<scroll-view class="spec-list" direction="vertical">
<view v-for="sku in productSkus" :key="sku.id"
class="spec-item"
:class="{ active: selectedSkuId === sku.id }"
@click="selectSku(sku)">
<text class="spec-name">{{ getSkuSpecText(sku) }}</text>
<text class="spec-price">¥{{ sku.price }}</text>
<text class="spec-stock">库存{{ sku.stock }}</text>
<scroll-view class="spec-list-jd" scroll-y="true">
<view class="spec-group">
<text class="group-title">规格</text>
<view class="group-tags">
<view v-for="sku in productSkus" :key="sku.id"
class="spec-tag"
:class="{ active: selectedSkuId === sku.id }"
@click="selectSku(sku)">
<text class="tag-text">{{ getSkuSpecText(sku) }}</text>
</view>
</view>
</view>
<!-- 数量选择移入弹窗内容 -->
<view class="spec-quantity-row">
<text class="group-title">数量</text>
<view class="quantity-selector-jd">
<view class="q-btn" @click="decreaseQuantity">
<text class="q-btn-text">-</text>
</view>
<input class="q-input" type="number" :value="quantity.toString()" @input="validateQuantity" />
<view class="q-btn" @click="increaseQuantity">
<text class="q-btn-text">+</text>
</view>
</view>
</view>
</scroll-view>
<view class="spec-footer-jd">
<button class="footer-btn cart" @click="addToCart">加入购物车</button>
<button class="footer-btn buy" @click="buyNow">立即购买</button>
</view>
</view>
</view>
@@ -692,7 +725,33 @@ export default {
}
}
uni.hideLoading()
},
getSelectedSkuImage(): string {
if (this.selectedSkuId != '') {
const sku = this.productSkus.find(s => s.id === this.selectedSkuId)
if (sku != null && sku.image_url != null && sku.image_url != '') {
return sku.image_url as string
}
}
return this.product.images.length > 0 ? this.product.images[0] : '/static/default-product.png'
},
getSelectedSkuPrice(): string {
if (this.selectedSkuId != '') {
const sku = this.productSkus.find(s => s.id === this.selectedSkuId)
if (sku != null) return sku.price.toFixed(2)
}
return this.product.price.toFixed(2)
},
getSelectedSkuStock(): number {
if (this.selectedSkuId != '') {
const sku = this.productSkus.find(s => s.id === this.selectedSkuId)
this.showSpecModal()
if (sku != null) return sku.stock
}
return this.product.stock
if (success === true) {
uni.showToast({ title: '领取成功', icon: 'success' })
} else {
@@ -723,7 +782,6 @@ export default {
selectSku(sku: ProductSkuType) {
this.selectedSkuId = sku.id
this.selectedSpec = this.getSkuSpecText(sku)
this.hideSpecModal()
},
getSkuSpecText(sku: ProductSkuType): string {
@@ -746,6 +804,7 @@ export default {
async addToCart() {
if (this.productSkus.length > 0 && (this.selectedSkuId == null || this.selectedSkuId === '')) {
this.showSpecModal()
uni.showToast({
title: '请选择规格',
icon: 'none'
@@ -766,6 +825,7 @@ export default {
if (success === true) {
uni.showToast({ title: '已添加到购物车', icon: 'success' })
this.hideSpecModal()
} else {
console.error('添加购物车返回失败')
uni.showToast({ title: '添加失败,请登录重试', icon: 'none' })
@@ -779,6 +839,7 @@ export default {
buyNow() {
if (this.productSkus.length > 0 && (this.selectedSkuId == null || this.selectedSkuId === '')) {
this.showSpecModal()
uni.showToast({
title: '请选择规格',
icon: 'none'
@@ -1375,70 +1436,200 @@ export default {
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
background-color: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: flex-end; /* UVUE 推荐用 flex 布局对齐 */
justify-content: flex-end;
flex-direction: column;
z-index: 999;
z-index: 1000;
}
.spec-content {
background-color: #fff;
width: 100%;
border-radius: 20rpx 20rpx 0 0;
border-radius: 24rpx 24rpx 0 0;
padding: 30rpx;
display: flex;
flex-direction: column;
max-height: 1000rpx;
max-height: 80vh;
}
.spec-header {
.spec-header-jd {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
flex-direction: row;
position: relative;
padding-bottom: 30rpx;
border-bottom: 1rpx solid #f2f2f2;
align-items: flex-end;
}
.spec-title {
font-size: 32rpx;
.spec-product-img {
width: 180rpx;
height: 180rpx;
border-radius: 12rpx;
margin-top: -60rpx;
background-color: #fff;
border: 4rpx solid #fff;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
flex-shrink: 0;
}
.spec-info-jd {
flex: 1;
margin-left: 24rpx;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding-bottom: 10rpx;
}
.spec-price-row {
display: flex;
flex-direction: row;
align-items: baseline;
color: #fa2c19;
margin-bottom: 8rpx;
}
.price-symbol {
font-size: 24rpx;
font-weight: bold;
}
.price-value {
font-size: 36rpx;
font-weight: bold;
}
.spec-stock-jd {
font-size: 24rpx;
color: #999;
margin-bottom: 8rpx;
}
.spec-choosed-jd {
font-size: 26rpx;
color: #333;
}
.spec-list {
flex: 1;
.close-btn-jd {
font-size: 48rpx;
color: #999;
position: absolute;
right: -10rpx;
top: -10rpx;
padding: 10rpx;
}
.spec-item {
.spec-list-jd {
flex: 1;
overflow-y: hidden;
}
.spec-group {
padding: 30rpx 0;
}
.group-title {
font-size: 28rpx;
font-weight: bold;
color: #333;
margin-bottom: 24rpx;
display: block;
}
.group-tags {
display: flex;
flex-wrap: wrap;
}
.spec-tag {
background-color: #f6f6f6;
padding: 16rpx 32rpx;
border-radius: 40rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
border: 2rpx solid #f6f6f6;
}
.spec-tag.active {
background-color: #fcedeb;
border-color: #fa2c19;
}
.spec-tag.active .tag-text {
color: #fa2c19;
}
.tag-text {
font-size: 26rpx;
color: #333;
}
.spec-quantity-row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 30rpx 0;
}
.quantity-selector-jd {
display: flex;
flex-direction: row;
align-items: center;
background-color: #f6f6f6;
border-radius: 8rpx;
}
.q-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
padding: 25rpx 0;
border-bottom: 1rpx solid #f5f5f5;
justify-content: center;
}
.spec-item.active {
background-color: #fff3e0;
.q-btn-text {
font-size: 36rpx;
color: #333;
}
.spec-name {
flex: 1;
.q-input {
width: 80rpx;
text-align: center;
font-size: 28rpx;
color: #333;
}
.spec-price {
font-size: 26rpx;
color: #ff5000;
margin-right: 20rpx;
.spec-footer-jd {
display: flex;
flex-direction: row;
padding: 20rpx 0 10rpx;
justify-content: space-between;
}
.spec-stock {
font-size: 24rpx;
color: #666;
width: 100rpx;
text-align: right;
.footer-btn {
flex: 1;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
font-weight: bold;
border-radius: 40rpx;
margin: 0 10rpx;
border: none;
display: flex;
align-items: center;
justify-content: center;
}
.footer-btn.cart {
background: linear-gradient(90deg, #ffba0d, #ffc30d);
color: #fff;
}
.footer-btn.buy {
background: linear-gradient(90deg, #f2140c, #f2270c);
color: #fff;
}
/* 功能主治样式 */