diff --git a/honey_box/pages/mall/detail.vue b/honey_box/pages/mall/detail.vue
index fa681400..cbf01455 100644
--- a/honey_box/pages/mall/detail.vue
+++ b/honey_box/pages/mall/detail.vue
@@ -5,15 +5,20 @@
:statusBar="true" :border="false" @clickLeft="goBack">
-
-
-
+
+
+
- ¥
- {{ goodsInfo.price }}
+
+ ¥
+ {{ goodsInfo.price }}
+
+
+ {{ goodsInfo.price * 100 }}{{ $config.getAppSetting('currency2_name') }}
+
@@ -25,13 +30,13 @@
库存
- {{ goodsInfo.goodslist_surplus_stock != null ? goodsInfo.goodslist_surplus_stock : (goodsInfo.stock || 0) }}
+ {{ goodsInfo.goodslist_surplus_stock != null ? goodsInfo.goodslist_surplus_stock : (goodsInfo.stock || 0) }}
{{ $config.getAppSetting('currency2_name') }}{{ goodsInfo.price * 100 }}
- (剩余:{{ orderData.score || 0 }})
+ (剩余{{ orderData.score || 0 }})
@@ -51,13 +56,7 @@
-
-
- 商品详情
-
-
-
-
+
@@ -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_detail、goods_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;
}
}
diff --git a/honey_box/pages/mall/index.vue b/honey_box/pages/mall/index.vue
index 70bdea05..d6f5c1c5 100644
--- a/honey_box/pages/mall/index.vue
+++ b/honey_box/pages/mall/index.vue
@@ -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);
diff --git a/honey_box/pages/user/settings.vue b/honey_box/pages/user/settings.vue
index 090a4e50..91361098 100644
--- a/honey_box/pages/user/settings.vue
+++ b/honey_box/pages/user/settings.vue
@@ -51,7 +51,7 @@
-
+
注销账号
diff --git a/server/HoneyBox/src/HoneyBox.Admin.Business/Services/GoodsService.cs b/server/HoneyBox/src/HoneyBox.Admin.Business/Services/GoodsService.cs
index 617660df..947c2648 100644
--- a/server/HoneyBox/src/HoneyBox.Admin.Business/Services/GoodsService.cs
+++ b/server/HoneyBox/src/HoneyBox.Admin.Business/Services/GoodsService.cs
@@ -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;
}
diff --git a/server/HoneyBox/src/HoneyBox.Core/Services/OrderService.cs b/server/HoneyBox/src/HoneyBox.Core/Services/OrderService.cs
index 157de6ce..bbeb4cb5 100644
--- a/server/HoneyBox/src/HoneyBox.Core/Services/OrderService.cs
+++ b/server/HoneyBox/src/HoneyBox.Core/Services/OrderService.cs
@@ -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,