砍价活动,下单前检查 库存

This commit is contained in:
Jack 2025-11-20 00:10:07 +08:00
parent 3ca6dcbec9
commit a3fa5a3fa8
4 changed files with 99 additions and 20 deletions

View File

@ -305,17 +305,19 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl<ShopActivit
queryWrapper.eq("activity_id", activity_id).eq("user_id", user_id);
ShopActivityCutprice cutprice_row = findOne(queryWrapper);
// 需要检查活动有效期和活动商品库存是否足够
Pair<Boolean, String> checkStockResult = checkCutPriceExpiredAndStock(activityBase);
// 立即参与活动
boolean is_join_activity = false;
// 如果用户未参与该砍价活动则创建新的砍价记录
if (cutprice_row == null) {
// 需要检查活动有效期和活动商品库存是否足够
Pair<Boolean, String> check_result = checkCutPriceExpiredAndStock(activityBase);
if (!check_result.getFirst()) {
if (!checkStockResult.getFirst()) {
// 库存不够立即更改活动状态为已结束
shopStoreActivityBaseService.updateActivityState(activity_id, StateCode.ACTIVITY_STATE_FINISHED);
throw new ApiException(check_result.getSecond());
throw new ApiException(checkStockResult.getSecond());
}
cutprice_row = new ShopActivityCutprice();
@ -375,6 +377,10 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl<ShopActivit
// 设置活动规则信息
activity_row.put("activity_rule", JSONUtil.parseObj(activity_row.get("activity_rule")));
if (!checkStockResult.getFirst()) {
activity_row.put("can_buy_now", CommonConstant.Disable2);
activity_row.put("cannot_buy_now_reason", "抱歉,您慢了一步,商品已抢空!");
} else {
// 判断是否可以立即购买
boolean canBuyNow = cutprice_row != null
&& CheckUtil.isNotEmpty(cutprice_row.getAc_sale_price())
@ -388,6 +394,7 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl<ShopActivit
activity_row.put("cannot_buy_now_reason",
canBuyNow ? "恭喜您,商品可以立即出手了。" :
String.format("还剩%.2f元到达商品底价,请继续加油!", subtractPrice));
}
return activity_row;
}

View File

@ -1585,7 +1585,12 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
// 判断是否为砍价活动
Boolean isCutPriceActivity = shopStoreActivityBaseService.isCutPriceActivity(activityId);
if (CheckUtil.isNotEmpty(acId) && isCutPriceActivity) {
cartData.put("ac_id", acId);
cartData.put("ac_id", acId); // shop_activity_cutprice 活动参与记录的自增id
// 判断砍价商品库存是否已售罄
if (shopStoreActivityBaseService.isActProdSoldOut(activityId)) {
throw new ApiException(I18nUtil._("砍价商品已售罄,请选择其他商品。"));
}
// 校验砍价活动用户是否可以立即购买了
Pair<Boolean, String> canDoOrderCutPriceActivity = shopActivityCutpriceService.canDoOrderCutPriceActivity(acId, userId);
@ -1673,10 +1678,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
}
}
// 判断是否砍价购买
if (acId != null) {
}
PayUserResource userResRow = payService.getPayUserResource(userId);
if (userResRow != null) {
cartData.put("user_money", userResRow.getUser_money());

View File

@ -209,4 +209,11 @@ public interface ShopStoreActivityBaseService extends IBaseService<ShopStoreActi
boolean updateActivityState(Integer activity_id, Integer activity_state);
/**
* 判断活动商品是否售完
*
* @param activity_id
* @return
*/
boolean isActProdSoldOut(Integer activity_id);
}

View File

@ -48,6 +48,7 @@ import com.suisung.mall.shop.base.service.ShopBaseCurrencyService;
import com.suisung.mall.shop.base.service.ShopBaseStateCodeService;
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
import com.suisung.mall.shop.order.service.ShopOrderDataService;
import com.suisung.mall.shop.order.service.ShopOrderInfoService;
import com.suisung.mall.shop.product.pojo.vo.ProductVo;
import com.suisung.mall.shop.product.service.ShopProductBaseService;
import com.suisung.mall.shop.product.service.ShopProductImageService;
@ -92,6 +93,9 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
ShopOrderBaseService shopOrderBaseService;
@Autowired
ShopUserVoucherService shopUserVoucherService;
@Lazy
@Autowired
ShopOrderInfoService shopOrderInfoService;
@Autowired
private ShopStoreActivityBaseMapper shopStoreActivityBaseMapper;
@Lazy
@ -134,6 +138,7 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
private ShopActivityGroupbookingService shopActivityGroupbookingService;
@Autowired
private ShopStoreActivityCodeService shopStoreActivityCodeService;
@Lazy
@Autowired
private ShopOrderDataService shopOrderDataService;
@Autowired
@ -4473,6 +4478,65 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
}
}
/**
* 判断活动商品是否售完
*
* @param activity_id 活动ID
* @return boolean 是否已售完
*/
@Override
public boolean isActProdSoldOut(Integer activity_id) {
// 参数校验检查活动ID是否有效
if (activity_id == null || activity_id <= 0) {
logger.warn("活动商品售完检查失败无效的活动ID - {}", activity_id);
return true; // 将无效输入视为"已售完"
}
try {
// 直接从数据库查询活动记录只获取需要的字段以提高性能
ShopStoreActivityBase activity = lambdaQuery()
.select(ShopStoreActivityBase::getProduct_count) // 只查询库存字段
.eq(ShopStoreActivityBase::getActivity_id, activity_id)
.one();
// 如果活动不存在视为已售完
if (activity == null) {
logger.warn("活动商品售完检查未找到活动记录activity_id={}", activity_id);
return true;
}
// 获取商品库存数量
Integer productCount = activity.getProduct_count();
logger.debug("活动商品库存检查activity_id={}, 库存数量={}", activity_id, productCount);
// 如果库存为null或小于等于0视为已售完
if (productCount == null || productCount <= 0) {
logger.info("活动商品售完检查库存为0或空activity_id={}", activity_id);
return true;
}
// 获取该活动已成功的订单数量
long soldCount = shopOrderInfoService.fetchActivityOrderSuccessCount(
Convert.toStr(activity_id),
Convert.toStr(StateCode.ACTIVITY_TYPE_CUTPRICE));
logger.debug("活动商品售完检查activity_id={}, 已售数量={}, 库存数量={}",
activity_id, soldCount, productCount);
// 如果已售数量大于等于库存数量则已售完
boolean isSoldOut = soldCount >= productCount;
if (isSoldOut) {
logger.info("活动商品已售完activity_id={}, 已售数量={}, 库存数量={}",
activity_id, soldCount, productCount);
}
return isSoldOut;
} catch (Exception e) {
logger.error("活动商品售完检查异常activity_id={}", activity_id, e);
return true; // 出现异常时保守地返回已售完
}
}
@Transactional
public boolean removeActivityBase(Integer activity_id, ShopStoreActivityBase activity_row) {