This commit is contained in:
zpc 2026-03-14 15:31:08 +08:00
parent db81e13b58
commit 4db5042b20
5 changed files with 128 additions and 21 deletions

View File

@ -5,15 +5,20 @@
:statusBar="true" :border="false" @clickLeft="goBack"></uni-nav-bar>
<view class="detail-content-wrap">
<!-- 商品主-->
<view class="goods-banner">
<image :src="goodsInfo.imgurl_banner || goodsInfo.imgurl" mode="widthFix" class="banner-img"></image>
<!-- Banner-->
<view class="goods-banner" v-if="goodsInfo.imgurl_banner">
<image :src="goodsInfo.imgurl_banner" mode="widthFix" class="banner-img"></image>
</view>
<!-- 价格区域 -->
<view class="price-section">
<text class="price-symbol">¥</text>
<text class="price-value">{{ goodsInfo.price }}</text>
<view class="price-left">
<text class="price-symbol">¥</text>
<text class="price-value">{{ goodsInfo.price }}</text>
</view>
<text class="price-coupon" v-if="orderData && orderData.goods_extend && orderData.goods_extend.pay_currency2 == 1">
{{ goodsInfo.price * 100 }}{{ $config.getAppSetting('currency2_name') }}
</text>
</view>
<!-- 商品标题 -->
@ -25,13 +30,13 @@
<view class="info-section">
<view class="info-row">
<text class="info-label">库存</text>
<text class="info-value">{{ goodsInfo.goodslist_surplus_stock != null ? goodsInfo.goodslist_surplus_stock : (goodsInfo.stock || 0) }}</text>
<text class="info-value info-value-inline">{{ goodsInfo.goodslist_surplus_stock != null ? goodsInfo.goodslist_surplus_stock : (goodsInfo.stock || 0) }}</text>
</view>
</view>
<view class="info-section" v-if="orderData && orderData.goods_extend && orderData.goods_extend.pay_currency2 == 1">
<view class="info-row">
<text class="info-label">{{ $config.getAppSetting('currency2_name') }}{{ goodsInfo.price * 100 }}</text>
<text class="info-value info-sub">(剩余:{{ orderData.score || 0 }})</text>
<text class="info-value info-sub info-value-inline">(剩余{{ orderData.score || 0 }})</text>
</view>
</view>
@ -51,13 +56,7 @@
</view>
</view>
<!-- 商品描述 -->
<view class="detail-section" v-if="goodsInfo.goods_describe">
<text class="detail-title" v-if="!goodsInfo.imgurl_detail">商品详情</text>
<view class="detail-content">
<rich-text :nodes="goodsInfo.goods_describe"></rich-text>
</view>
</view>
<!-- 底部占位 -->
<view style="height: 180rpx;"></view>
@ -205,6 +204,9 @@ export default {
if (detailRes.status == 1 && detailRes.data) {
// goods_detail { data: { goods: {...}, goodslist: [...] } }
this.goodsInfo = detailRes.data.goods || detailRes.data;
// [] - goods_detail
const g = this.goodsInfo;
console.log(`[商城详情] goods_detail: id=${g.id} stock=${g.stock} sale_stock=${g.sale_stock} goodslist_stock=${g.goodslist_stock} goodslist_surplus_stock=${g.goodslist_surplus_stock} imgurl_banner=${g.imgurl_banner}`);
}
} catch (e) {
console.log('获取商品详情失败', e);
@ -223,7 +225,13 @@ export default {
this.orderData = res.data;
// imgurl_detailgoods_describe
if (res.data.goods) {
// [] - calcMallOrderMoney
const mg = res.data.goods;
console.log(`[商城详情] mall_ordermoney: id=${mg.id} stock=${mg.stock} sale_stock=${mg.sale_stock} goodslist_surplus_stock=${mg.goodslist_surplus_stock} imgurl_banner=${mg.imgurl_banner}`);
this.goodsInfo = { ...this.goodsInfo, ...res.data.goods };
// []
const fg = this.goodsInfo;
console.log(`[商城详情] 合并后: stock=${fg.stock} sale_stock=${fg.sale_stock} goodslist_surplus_stock=${fg.goodslist_surplus_stock} imgurl_banner=${fg.imgurl_banner}`);
}
const ext = res.data.goods_extend || {};
if (ext.pay_wechat == 1) {
@ -282,6 +290,8 @@ export default {
const remainStock = this.goodsInfo.goodslist_surplus_stock != null
? this.goodsInfo.goodslist_surplus_stock
: (this.goodsInfo.stock || 0) - (this.goodsInfo.sale_stock || 0);
// [] -
console.log(`[商城详情] 兑换校验: goodslist_surplus_stock=${this.goodsInfo.goodslist_surplus_stock} stock=${this.goodsInfo.stock} sale_stock=${this.goodsInfo.sale_stock} remainStock=${remainStock}`);
if (remainStock <= 0) {
this.$c.msg('库存不足,兑换失败');
return;
@ -396,6 +406,14 @@ export default {
.price-section {
padding: 30rpx 30rpx 10rpx;
background: #fff;
display: flex;
justify-content: space-between;
align-items: baseline;
.price-left {
display: flex;
align-items: baseline;
}
.price-symbol {
font-size: 28rpx;
@ -408,6 +426,12 @@ export default {
color: #ff4d4f;
font-weight: 600;
}
.price-coupon {
font-size: 26rpx;
color: #f5a623;
font-weight: 500;
}
}
.title-section {
@ -428,7 +452,6 @@ export default {
.info-row {
display: flex;
justify-content: space-between;
align-items: center;
}
@ -442,6 +465,10 @@ export default {
color: #333;
}
.info-value-inline {
margin-left: 20rpx;
}
.info-sub {
color: #999;
font-size: 24rpx;
@ -450,6 +477,7 @@ export default {
.info-arrow {
font-size: 36rpx;
color: #999;
margin-left: auto;
}
}
@ -478,16 +506,16 @@ export default {
background: #fff;
.buy-btn {
width: 100%;
height: 88rpx;
background: #5CE5D5;
border-radius: 44rpx;
width: 694rpx;
height: 86rpx;
background: #03D8F4;
border-radius: 108rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 30rpx;
font-weight: 500;
color: #333;
color: #fff;
}
}

View File

@ -194,6 +194,10 @@ export default {
});
if (res.status == 1 && res.data && res.data.data) {
// [] -
res.data.data.forEach(item => {
console.log(`[商城列表] id=${item.id} title=${item.title} stock=${item.stock} sale_stock=${item.sale_stock}`);
});
if (isWXPay) {
if (this.datas.length > 0) {
this.datas = this.datas.slice(0, this.datas.length);

View File

@ -51,7 +51,7 @@
<view v-if="isLoggedIn" class="divider-line"></view>
<view v-if="isLoggedIn" class="settings-item" @click="handleCancelAccount">
<view class="item-left">
<image class="item-icon" :src="$img1('my/s10.png')" mode=""></image>
<image class="item-icon" :src="$img1('ms/s12.png')" mode=""></image>
<text class="item-title">注销账号</text>
</view>
<view class="item-right">

View File

@ -550,6 +550,28 @@ public class GoodsService : IGoodsService
// 更新商品奖品数量(按第一箱的奖品数计算)
goods.PrizeNum = await _dbContext.GoodsItems.CountAsync(gi => gi.GoodsId == goodsId && gi.Num == 1);
// 商城赏(type=10):同步 goods.stock/sale_stock 与 goods_items 汇总值
// 商城赏的库存模型是多批次进货,每批一条 goods_items需要保持 goods 表的汇总值同步
if (goods.Type == 10)
{
var stockSummary = await _dbContext.GoodsItems
.Where(gi => gi.GoodsId == goodsId)
.GroupBy(gi => 1)
.Select(g => new
{
TotalStock = g.Sum(x => x.Stock),
TotalSold = g.Sum(x => x.Stock) - g.Sum(x => x.SurplusStock)
})
.FirstOrDefaultAsync();
if (stockSummary != null)
{
goods.Stock = stockSummary.TotalStock;
goods.SaleStock = stockSummary.TotalSold;
}
}
goods.UpdatedAt = now;
await _dbContext.SaveChangesAsync();
@ -690,6 +712,28 @@ public class GoodsService : IGoodsService
prize.IsLingzhu = (byte)request.IsLingzhu;
prize.UpdatedAt = now;
// 商城赏(type=10):同步 goods.stock/sale_stock
var goods = await _dbContext.Goods.FirstOrDefaultAsync(g => g.Id == prize.GoodsId);
if (goods != null && goods.Type == 10)
{
var stockSummary = await _dbContext.GoodsItems
.Where(gi => gi.GoodsId == prize.GoodsId)
.GroupBy(gi => 1)
.Select(g => new
{
TotalStock = g.Sum(x => x.Stock),
TotalSold = g.Sum(x => x.Stock) - g.Sum(x => x.SurplusStock)
})
.FirstOrDefaultAsync();
if (stockSummary != null)
{
goods.Stock = stockSummary.TotalStock;
goods.SaleStock = stockSummary.TotalSold;
goods.UpdatedAt = now;
}
}
var result = await _dbContext.SaveChangesAsync() > 0;
_logger.LogInformation("更新奖品成功: PrizeId={PrizeId}, Title={Title}", prizeId, prize.Title);
@ -715,6 +759,24 @@ public class GoodsService : IGoodsService
if (goods != null)
{
goods.PrizeNum = await _dbContext.GoodsItems.CountAsync(gi => gi.GoodsId == goodsId) - 1;
// 商城赏(type=10):同步 goods.stock/sale_stock
if (goods.Type == 10)
{
var stockSummary = await _dbContext.GoodsItems
.Where(gi => gi.GoodsId == goodsId && gi.Id != prizeId)
.GroupBy(gi => 1)
.Select(g => new
{
TotalStock = g.Sum(x => x.Stock),
TotalSold = g.Sum(x => x.Stock) - g.Sum(x => x.SurplusStock)
})
.FirstOrDefaultAsync();
goods.Stock = stockSummary?.TotalStock ?? 0;
goods.SaleStock = stockSummary?.TotalSold ?? 0;
}
goods.UpdatedAt = DateTime.Now;
}

View File

@ -807,6 +807,17 @@ public class OrderService : IOrderService
// 3. 获取商品扩展配置
var goodsExtend = await GetGoodsExtendAsync(request.GoodsId, goods.Type);
// 3.1 查询 goods_items 汇总库存(商城赏的真实库存在 goods_items 表)
var itemsStockSummary = await _dbContext.GoodsItems
.Where(gi => gi.GoodsId == request.GoodsId)
.GroupBy(gi => 1)
.Select(g => new
{
TotalStock = g.Sum(x => x.Stock),
SurplusStock = g.Sum(x => x.SurplusStock)
})
.FirstOrDefaultAsync();
// 4. 计算价格
// 商城订单使用积分(money2)支付比例为1:100
var price = goods.Price;
@ -840,6 +851,8 @@ public class OrderService : IOrderService
Price = goods.Price.ToString("0.##"),
Stock = goods.Stock,
SaleStock = goods.SaleStock,
GoodslistStock = itemsStockSummary?.TotalStock ?? 0,
GoodslistSurplusStock = itemsStockSummary?.SurplusStock ?? 0,
Type = goods.Type,
IsShouZhe = goods.IsShouZhe,
PrizeNum = request.PrizeNum,