diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponChannelController.java b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponChannelController.java index 83c680ed7..481de6f9b 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponChannelController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxCouponChannelController.java @@ -12,6 +12,9 @@ import com.iformall.domain.vo.WxCouponChannelVo; import com.iformall.enums.EnumCouponSourceType; import com.iformall.domain.po.base.BaseEntity; import com.iformall.service.WxCouponChannelService; +import com.iformall.service.WxCouponService; +import com.iformall.utils.RedisLock; + import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -35,6 +38,12 @@ public class WxCouponChannelController extends BaseController { @Autowired private WxCouponChannelService wxCouponChannelService; + + @Autowired + RedisLock redisLock; + + @Autowired + private WxCouponService wxCouponService; @ApiOperation("分页列表接口") @GetMapping("list") @@ -121,6 +130,44 @@ public class WxCouponChannelController extends BaseController { } return new ResultData(Result.SUCCESS, "查询成功", JSON.toJSONString(channellist)); } + + @ApiOperation("设置库存") + @PostMapping("/setChannelStock") + @SystemControllerLog(description = "设置渠道库存") + public ResultData setChannelStock(@RequestBody WxCouponChannel wxCouponChannel) { + if (null == wxCouponChannel.getChannelStock() || wxCouponChannel.getChannelStock() <= 0) { + return new ResultData(Result.ERROR, "库存未设置或者库存小于0, 如不需要可点击释放库存."); + } + wxCouponChannel.updateTenantInfo(getTenantInfo()); + wxCouponChannelService.setChannelStock(wxCouponChannel, wxCouponChannel.getChannelStock()); + WxCoupon coupon = wxCouponService.getById(wxCouponChannel.getCouponId(), wxCouponChannel.getTenantId()); + redisLock.setCouponStock(wxCouponChannel.getCouponId(), coupon.getRemainInventory()); + redisLock.setCouponChannelStock(wxCouponChannel.getId(), wxCouponChannel.getChannelStock()); + return new ResultData(Result.SUCCESS, "设置成功", ""); + } + + @ApiOperation("释放库存") + @PostMapping("/releaseChannelStock") + @SystemControllerLog(description = "释放渠道库存") + public ResultData releaseChannelStock(@RequestBody WxCouponChannel wxCouponChannel) { + wxCouponChannel.updateTenantInfo(getTenantInfo()); + wxCouponChannelService.releaseChannelStock(wxCouponChannel); + redisLock.removeCouponStock(wxCouponChannel.getCouponId()); + redisLock.removeCouponChannelStock(wxCouponChannel.getId()); + return new ResultData(Result.SUCCESS, "设置成功", ""); + } + + @ApiOperation("设置价格") + @PostMapping("/setChannelPrice") + @SystemControllerLog(description = "设置渠道价格") + public ResultData findChannelByCouponId(@RequestBody WxCouponChannel wxCouponChannel) { + if (null != wxCouponChannel.getChannelPrice() && wxCouponChannel.getChannelPrice() <= 0) { + return new ResultData(Result.ERROR, "价格不能小于0, 如不需要可设置为空."); + } + wxCouponChannel.updateTenantInfo(getTenantInfo()); + wxCouponChannelService.setChannelPrice(wxCouponChannel); + return new ResultData(Result.SUCCESS, "设置成功", ""); + } } diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxOrderController.java b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxOrderController.java index d74bc704c..940bd65ca 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/market/WxOrderController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/market/WxOrderController.java @@ -187,13 +187,13 @@ public class WxOrderController extends BaseController { if (coupon == null) { return new ResultData(ErrorCode.COUPON_IS_EMPTY); } - if (!wxOrderService.checkCouponIsFree(coupon,null)) { + if (!wxOrderService.checkCouponIsFree(coupon,wxCouponChannel,null)) { return new ResultData(ErrorCode.COUPON_IS_NOT_FREE); } // 免费券 WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(EnumComposeOrder.SINGLE.getCode()).createDBMainOrder(coupon, user, 0, EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT); - order = wxOrderService.saveFreeOrderForCoupon(false,composeOrder,user, coupon, 1, - orderSaveDto.getCouponChannelId(), orderSaveDto.getFormId(), null,EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT, + order = wxOrderService.saveFreeOrderForCoupon(new Date(),false,composeOrder,user, coupon, 1, + wxCouponChannel, orderSaveDto.getFormId(), null,EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT, EnumOrderShopingType.ONLINE_PURCHASE.getCode(),null); return new ResultData(order); } catch (MallinkException e) { diff --git a/mallinkAdmin/src/main/resources/db/migration/V2022042600002__coupon_channel.sql b/mallinkAdmin/src/main/resources/db/migration/V2022042600002__coupon_channel.sql new file mode 100644 index 000000000..c3525cf97 --- /dev/null +++ b/mallinkAdmin/src/main/resources/db/migration/V2022042600002__coupon_channel.sql @@ -0,0 +1,201 @@ +alter table wx_coupon_channel_0 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_1 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_2 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_3 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_4 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_5 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_6 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_7 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_8 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_9 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_10 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_11 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_12 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_13 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_14 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_15 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_16 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_17 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_18 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_19 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_20 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_21 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_22 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_23 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_24 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_25 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_26 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_27 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_28 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_29 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_30 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_31 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_32 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_33 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_34 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_35 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_36 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_37 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_38 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_39 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_40 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_41 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_42 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_43 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_44 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_45 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_46 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_47 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_48 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_49 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_50 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_51 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_52 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_53 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_54 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_55 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_56 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_57 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_58 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_59 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_60 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_61 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_62 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_63 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_64 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_65 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_66 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_67 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_68 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_69 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_70 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_71 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_72 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_73 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_74 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_75 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_76 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_77 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_78 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_79 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_80 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_81 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_82 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_83 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_84 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_85 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_86 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_87 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_88 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_89 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_90 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_91 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_92 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_93 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_94 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_95 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_96 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_97 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_98 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; +alter table wx_coupon_channel_99 ADD COLUMN `channel_price` int(11) COMMENT '渠道价格'; + +alter table wx_coupon_channel_0 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_1 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_2 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_3 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_4 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_5 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_6 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_7 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_8 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_9 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_10 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_11 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_12 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_13 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_14 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_15 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_16 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_17 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_18 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_19 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_20 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_21 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_22 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_23 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_24 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_25 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_26 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_27 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_28 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_29 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_30 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_31 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_32 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_33 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_34 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_35 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_36 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_37 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_38 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_39 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_40 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_41 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_42 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_43 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_44 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_45 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_46 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_47 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_48 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_49 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_50 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_51 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_52 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_53 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_54 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_55 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_56 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_57 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_58 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_59 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_60 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_61 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_62 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_63 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_64 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_65 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_66 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_67 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_68 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_69 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_70 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_71 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_72 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_73 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_74 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_75 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_76 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_77 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_78 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_79 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_80 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_81 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_82 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_83 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_84 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_85 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_86 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_87 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_88 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_89 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_90 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_91 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_92 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_93 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_94 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_95 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_96 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_97 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_98 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; +alter table wx_coupon_channel_99 ADD COLUMN `channel_stock` int(11) COMMENT '渠道锁定库存'; \ No newline at end of file diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxCouponPasswordController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxCouponPasswordController.java index 742b08a3e..51da9b028 100644 --- a/mallinkCApi/src/main/java/com/iformall/controller/WxCouponPasswordController.java +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxCouponPasswordController.java @@ -102,7 +102,7 @@ public class WxCouponPasswordController extends BaseController { // 3. 领取free coupon try { WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(EnumComposeOrder.SINGLE.getCode()).createDBMainOrder(coupon, member, 0, payWay); - WxOrder order = orderService.saveFreeOrderForCoupon(false,composeOrder,member, coupon, 1, + WxOrder order = orderService.saveFreeOrderForCoupon(new Date(),false,composeOrder,member, coupon, 1, null, formId, couponPassword.getId(),payWay, EnumOrderShopingType.ONLINE_PURCHASE.getCode(),null); } catch (MallinkException e) { diff --git a/mallinkService/src/main/java/com/iformall/common/ErrorCode.java b/mallinkService/src/main/java/com/iformall/common/ErrorCode.java index 027298d8e..e4f374b6b 100644 --- a/mallinkService/src/main/java/com/iformall/common/ErrorCode.java +++ b/mallinkService/src/main/java/com/iformall/common/ErrorCode.java @@ -153,6 +153,8 @@ public enum ErrorCode{ COUPON_IS_TAKE_OFF_GIFT(2122, "子券存在作废券"), COUPON_VALID_DATE_ERR_GIFT(2135, "存在子券有效期在券包有效期之前"), COUPON_GIFT_NOTUPD_INVENTORY(2136, "子券没有库存"), + + COUPON_CHANNEL_STOCK_ZERO(2137, "渠道库存已售罄"), /** * 车流 2040 diff --git a/mallinkService/src/main/java/com/iformall/domain/dto/OrderComposeSaveDto.java b/mallinkService/src/main/java/com/iformall/domain/dto/OrderComposeSaveDto.java index 5fd68fa13..9461a6eb4 100644 --- a/mallinkService/src/main/java/com/iformall/domain/dto/OrderComposeSaveDto.java +++ b/mallinkService/src/main/java/com/iformall/domain/dto/OrderComposeSaveDto.java @@ -6,6 +6,7 @@ import lombok.Data; import java.io.Serializable; import com.iformall.domain.po.WxCoupon; +import com.iformall.domain.po.WxCouponChannel; @Data public class OrderComposeSaveDto implements Serializable { @@ -21,5 +22,7 @@ public class OrderComposeSaveDto implements Serializable { UserBasicInfoAddress address;//配送地址 WxCoupon wxCoupon; + + WxCouponChannel wxCouponChannel; } diff --git a/mallinkService/src/main/java/com/iformall/domain/po/SingleOrderCheckResult.java b/mallinkService/src/main/java/com/iformall/domain/po/SingleOrderCheckResult.java new file mode 100644 index 000000000..3ad4a254f --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/po/SingleOrderCheckResult.java @@ -0,0 +1,20 @@ +package com.iformall.domain.po; + +public class SingleOrderCheckResult { + + private WxCoupon coupon; + private WxCouponChannel couponChannel; + + public WxCoupon getCoupon() { + return coupon; + } + public void setCoupon(WxCoupon coupon) { + this.coupon = coupon; + } + public WxCouponChannel getCouponChannel() { + return couponChannel; + } + public void setCouponChannel(WxCouponChannel couponChannel) { + this.couponChannel = couponChannel; + } +} diff --git a/mallinkService/src/main/java/com/iformall/domain/po/StockReduceResult.java b/mallinkService/src/main/java/com/iformall/domain/po/StockReduceResult.java new file mode 100644 index 000000000..c2ff53e31 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/po/StockReduceResult.java @@ -0,0 +1,20 @@ +package com.iformall.domain.po; + +public class StockReduceResult { + + private boolean isChannelStockReduce; + private Integer currentPrice; + + public boolean isChannelStockReduce() { + return isChannelStockReduce; + } + public void setChannelStockReduce(boolean isChannelStockReduce) { + this.isChannelStockReduce = isChannelStockReduce; + } + public Integer getCurrentPrice() { + return currentPrice; + } + public void setCurrentPrice(Integer currentPrice) { + this.currentPrice = currentPrice; + } +} diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxCouponChannel.java b/mallinkService/src/main/java/com/iformall/domain/po/WxCouponChannel.java index 2fd14d45f..0977ad95c 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxCouponChannel.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxCouponChannel.java @@ -72,6 +72,10 @@ public class WxCouponChannel extends TenantEntity { private String ttQrCode; @io.swagger.annotations.ApiModelProperty(value="抖音平台SPU ID(poi同步)",name="ttSpuId") private String ttSpuId; + @io.swagger.annotations.ApiModelProperty(value="渠道价格",name="channelPrice") + private Integer channelPrice; + @io.swagger.annotations.ApiModelProperty(value="渠道锁定库存",name="channelStock") + private Integer channelStock; @TableField(exist = false) @io.swagger.annotations.ApiModelProperty(value="券状态 0:可投放 1:作废",name="couponStatus") @@ -80,7 +84,7 @@ public class WxCouponChannel extends TenantEntity { @TableField(exist = false) @io.swagger.annotations.ApiModelProperty(value="积分售价(适用于类型10,11)",name="creditPrice") private Integer creditPrice; - + @TableField(exist = false) @SortColumn(column = "sale_price") private String salePriceStr; diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumCacheKey.java b/mallinkService/src/main/java/com/iformall/enums/EnumCacheKey.java index 3ed79fc03..3faa9f06c 100644 --- a/mallinkService/src/main/java/com/iformall/enums/EnumCacheKey.java +++ b/mallinkService/src/main/java/com/iformall/enums/EnumCacheKey.java @@ -15,6 +15,7 @@ public enum EnumCacheKey { MERCHANT_COUPON_PAGE_LIST(4, "merchantCouponList_"), TOPIC_ONE(5, "topicOne_"), TOPIC_LIST(6, "topiList_"), + COUPON_CHANNEL_STOCK(7, "couponChannelStock:couponChannelStock_"), ; private static Map map = new HashMap(); static { diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumCouponChannelType.java b/mallinkService/src/main/java/com/iformall/enums/EnumCouponChannelType.java index eddc145d1..37868742c 100644 --- a/mallinkService/src/main/java/com/iformall/enums/EnumCouponChannelType.java +++ b/mallinkService/src/main/java/com/iformall/enums/EnumCouponChannelType.java @@ -17,6 +17,8 @@ public enum EnumCouponChannelType { COUPON_CHANNEL_ID_H5(100, "DSP的H5页面"), COUPON_CHANNEL_ID_DOUYIN_LIST(101, "抖音列表"), + + COUPON_CHANNEL_ID_WXLIVE_LIST(102, "微信直播列表") ; public static EnumCouponChannelType getEnum(Integer code) { diff --git a/mallinkService/src/main/java/com/iformall/mapper/WxCouponChannelMapper.java b/mallinkService/src/main/java/com/iformall/mapper/WxCouponChannelMapper.java index edfe49916..aca14c27d 100644 --- a/mallinkService/src/main/java/com/iformall/mapper/WxCouponChannelMapper.java +++ b/mallinkService/src/main/java/com/iformall/mapper/WxCouponChannelMapper.java @@ -55,7 +55,15 @@ public interface WxCouponChannelMapper extends CommonMapper getPoiProductIdList(@Param("tenantId")String tenantId, @Param("couponId")Long couponId); - - + + Integer reduceChannelStock(@Param("id")Long id,@Param("tenantId")String tenantId,@Param("number")Integer number); + + Integer backChannelStock(@Param("id")Long id,@Param("tenantId")String tenantId,@Param("number")Integer number); + + Integer setChannelStock(@Param("id")Long id,@Param("tenantId")String tenantId,@Param("number")Integer number); + + Integer clearChannelStock(@Param("id")Long id,@Param("tenantId")String tenantId); + + Integer setChannelPrice(@Param("id")Long id,@Param("tenantId")String tenantId,@Param("price")Integer price); } diff --git a/mallinkService/src/main/java/com/iformall/mapper/WxCouponMapper.java b/mallinkService/src/main/java/com/iformall/mapper/WxCouponMapper.java index 7509079bf..981a309a7 100644 --- a/mallinkService/src/main/java/com/iformall/mapper/WxCouponMapper.java +++ b/mallinkService/src/main/java/com/iformall/mapper/WxCouponMapper.java @@ -39,7 +39,7 @@ public interface WxCouponMapper extends CommonMapper { Integer reduceInventory(@Param("id")Long id,@Param("tenantId")String tenantId,@Param("number")Integer number); - Integer backInventory(@Param("id")Long id,@Param("tenantId")String tenantId, @Param("number")Integer number,@Param("remainInventory")Integer remainInventory); + Integer backInventory(@Param("id")Long id,@Param("tenantId")String tenantId, @Param("number")Integer number); void offExpiriedCouponByValidDate(@Param("tenantId")String tenantId); diff --git a/mallinkService/src/main/java/com/iformall/service/WxCouponChannelService.java b/mallinkService/src/main/java/com/iformall/service/WxCouponChannelService.java index ae70ded22..266bf65e0 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxCouponChannelService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxCouponChannelService.java @@ -61,4 +61,11 @@ public interface WxCouponChannelService { List newfindListVo(WxCouponChannel wxCouponChannel); PageInfo newListPageVo(WxCouponChannel record, Integer pageIndex, Integer pageSize); + + void reduceChannelStock(TenantEntity tenantEntity,Long couponChannelId, Integer number); + void backChannelStock(TenantEntity tenantEntity,Long couponChannelId, Integer number); + void setChannelStock(WxCouponChannel record,Integer number); + void releaseChannelStock(WxCouponChannel record); + void setChannelPrice(WxCouponChannel record); + } diff --git a/mallinkService/src/main/java/com/iformall/service/WxOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxOrderService.java index 51d57d9d1..66893db2c 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxOrderService.java @@ -1,5 +1,6 @@ package com.iformall.service; +import java.util.Date; import java.util.List; import java.util.Map; @@ -206,15 +207,16 @@ public interface WxOrderService { * 订单处理 * 1. 检查coupon是否免费 */ - boolean checkCouponIsFree(WxCoupon coupon,Integer shippingType); + boolean checkCouponIsFree(WxCoupon coupon,WxCouponChannel couponChannel,Integer shippingType); // 2. 创建免费订单, 领取 couponOrder - WxOrder saveFreeOrderForCoupon(boolean allowUnPayOrder,WxComposeOrder composeOrder, WxCUserBasicInfo user, WxCoupon coupon, int couponNumber, - Long couponChannelId, String formId, Long couponPasswordId, EnumPayWay payWay, + WxOrder saveFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder, WxCUserBasicInfo user, WxCoupon coupon, int couponNumber, + WxCouponChannel couponChannel, String formId, Long couponPasswordId, EnumPayWay payWay, Integer shippingType, UserBasicInfoAddress address); // 3. 创建有价订单 - WxOrder saveNoFreeOrderForCoupon(boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber,OrderComposeSaveDto orderdto,EnumPayWay payWay); + WxOrder saveNoFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber,WxCouponChannel couponChannel, + OrderComposeSaveDto orderdto,EnumPayWay payWay); /** * 下订单成功后处理 diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponChannelServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponChannelServiceImpl.java index 7268c094f..05dc57ef8 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponChannelServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponChannelServiceImpl.java @@ -16,10 +16,12 @@ import com.iformall.domain.vo.WxCouponChannelAddVo; import com.iformall.domain.vo.WxCouponChannelVo; import com.iformall.domain.vo.WxMerchantVo; import com.iformall.enums.*; +import com.iformall.exception.MallinkException; import com.iformall.mapper.*; import com.iformall.mq.MqBaseProducer; import com.iformall.service.*; import com.iformall.utils.Constant; +import com.iformall.utils.RedisLock; import org.apache.commons.beanutils.BeanUtils; import org.slf4j.Logger; @@ -29,6 +31,9 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Lazy; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import java.lang.reflect.InvocationTargetException; import java.util.*; @@ -640,5 +645,61 @@ public class WxCouponChannelServiceImpl implements WxCouponChannelService { return cvo; } + @Override + @Transactional(isolation= Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + public void reduceChannelStock(TenantEntity tenantEntity, Long couponChannelId, Integer number) { + int num = wxCouponChannelMapper.reduceChannelStock(couponChannelId,tenantEntity.getTenantId(), number); + if (num == 0) { + throw new MallinkException(ErrorCode.ORDER_SAVE_ERR); + } + } + + @Override + @Transactional(isolation= Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + public void backChannelStock(TenantEntity tenantEntity,Long couponChannelId, Integer number) { + int num = wxCouponChannelMapper.backChannelStock(couponChannelId,tenantEntity.getTenantId(), number); + if (num == 0) { + throw new MallinkException(ErrorCode.REMAIN_BACK_FAIL); + } + } + + @Override + @Transactional(isolation= Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + public void setChannelStock(WxCouponChannel record,Integer number) { + //设置渠道库存, + int num = wxCouponChannelMapper.setChannelStock(record.getId(), record.getTenantId(), number); + if (num == 0) { + throw new MallinkException(ErrorCode.REMAIN_BACK_FAIL); + } + + //减掉券库存 + int num1 = wxCouponMapper.reduceInventory(record.getCouponId(), record.getTenantId(), number); + if (num1 == 0) { + throw new MallinkException(ErrorCode.REMAIN_BACK_FAIL); + } + } + + @Override + @Transactional(isolation= Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + public void releaseChannelStock(WxCouponChannel record) { + //释放渠道库存 + WxCouponChannel couponChannel = wxCouponChannelMapper.selectById(record.getId(), record.getTenantId()); + int num = wxCouponChannelMapper.clearChannelStock(record.getId(), record.getTenantId()); + if (num == 0) { + throw new MallinkException(ErrorCode.REMAIN_BACK_FAIL); + } + + //减掉券库存 + int num1 = wxCouponMapper.backInventory(record.getCouponId(), record.getTenantId(), couponChannel.getChannelStock()); + if (num1 == 0) { + throw new MallinkException(ErrorCode.REMAIN_BACK_FAIL); + } + } + + @Override + public void setChannelPrice(WxCouponChannel record) { + wxCouponChannelMapper.setChannelPrice(record.getId(), record.getTenantId(), record.getChannelPrice()); + } + } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponServiceImpl.java index 26bece179..1181973c8 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxCouponServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxCouponServiceImpl.java @@ -957,7 +957,7 @@ public class WxCouponServiceImpl implements WxCouponService { @Override @Transactional(isolation= Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) public void backRemainInventory(TenantEntity tenantEntity,Long id, Integer number, Integer remainInventory) { - int num = wxCouponMapper.backInventory(id,tenantEntity.getTenantId(), number, remainInventory); + int num = wxCouponMapper.backInventory(id,tenantEntity.getTenantId(), number); if (num == 0) { throw new MallinkException(ErrorCode.REMAIN_BACK_FAIL); } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java index 627444e5c..d564b0e51 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxOrderServiceImpl.java @@ -835,52 +835,107 @@ public class WxOrderServiceImpl implements WxOrderService { } } - /** - * 减库存 - * - * @param user - * @param coupon - * @param couponIdStr - */ - @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public void stockReduce(boolean allowUnPayOrder,WxCUserBasicInfo user, WxCoupon coupon, String couponIdStr,int number) { + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + public void setCouponStockCache(Long couponId,String couponTitle,String tenantId) { //如果缓存中不存在这个key,则从coupon中取 - if(!redisLock.hasCouponStockCache(coupon.getId())) { + if(!redisLock.hasCouponStockCache(couponId)) { //此处需要加锁,防止并发设置 long time = System.currentTimeMillis() + RedisLock.TIMEOUT; String timeStr = String.valueOf(time); - boolean stocksetlock = redisLock.lock("couponLockStockSet_"+coupon.getId(), timeStr); + boolean stocksetlock = redisLock.lock("couponLockStockSet_"+couponId, timeStr); if (stocksetlock) { - if (!redisLock.hasCouponStockCache(coupon.getId())) { - WxCoupon cou = wxCouponMapper.selectById(coupon.getId(),coupon.getTenantId()); + if (!redisLock.hasCouponStockCache(couponId)) { + WxCoupon cou = wxCouponMapper.selectById(couponId,tenantId); if (null == cou) { - redisLock.unlock("couponLockStockSet_"+coupon.getId(), timeStr); - throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"未查询到券!"+coupon.getId()); + redisLock.unlock("couponLockStockSet_"+couponId, timeStr); + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"未查询到券!"+couponId); } try { - redisLock.setCouponStock(coupon.getId(), cou.getRemainInventory()); + redisLock.setCouponStock(couponId, cou.getRemainInventory()); }catch(Exception e) { logger.error("set couponstock to redis fail.",e); - throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"redis设置券库存失败"+coupon.getId()); + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"redis设置券库存失败"+couponId); }finally { - redisLock.unlock("couponLockStockSet_"+coupon.getId(), timeStr); + redisLock.unlock("couponLockStockSet_"+couponId, timeStr); } }else { - redisLock.unlock("couponLockStockSet_"+coupon.getId(), timeStr); + redisLock.unlock("couponLockStockSet_"+couponId, timeStr); } } - } - - long redisStock = redisLock.getCouponStock(Long.parseLong(couponIdStr)); + long redisStock = redisLock.getCouponStock(couponId); if (redisStock<=0) { - throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券库存已为零!:"+coupon.getTitle()+"["+couponIdStr+"]"); + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券库存已为零!:"+couponTitle+"["+couponId+"]"); } - // 检查 优惠券 库存 - if (coupon.getRemainInventory() <= 0) { - throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY.getCode(),coupon.getTitle()+"["+couponIdStr+"]库存不足"); - } - + } + + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + public void setCouponChanenlStockCache(Long couponChannelId,String couponTitle,String tenantId) { + //如果缓存中不存在这个key,则从coupon中取 + if(!redisLock.hasCouponChannelStockCache(couponChannelId)) { + //此处需要加锁,防止并发设置 + long time = System.currentTimeMillis() + RedisLock.TIMEOUT; + String timeStr = String.valueOf(time); + boolean stocksetlock = redisLock.lock("couponChannelLockStockSet_"+couponChannelId, timeStr); + if (stocksetlock) { + if (!redisLock.hasCouponChannelStockCache(couponChannelId)) { + WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(couponChannelId,tenantId); + if (null == wxCouponChannel) { + redisLock.unlock("couponChannelLockStockSet_"+couponChannelId, timeStr); + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"未查询到渠道!"+couponChannelId); + } + try { + redisLock.setCouponChannelStock(couponChannelId, wxCouponChannel.getChannelStock()); + }catch(Exception e) { + logger.error("set couponstock to redis fail.",e); + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"redis设置券库存失败"+couponChannelId); + }finally { + redisLock.unlock("couponChannelLockStockSet_"+couponChannelId, timeStr); + } + }else { + redisLock.unlock("couponChannelLockStockSet_"+couponChannelId, timeStr); + } + } + } + long redisStock = redisLock.getCouponChannelStock(couponChannelId); + if (redisStock<=0) { + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券渠道库存已为零!:"+couponTitle+"[渠道编码:"+couponChannelId+"]"); + } + } + + /** + * 减库存 + * + * @param user + * @param coupon + * @param couponIdStr + */ + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + public StockReduceResult stockReduce(boolean allowUnPayOrder,WxCUserBasicInfo user, WxCoupon coupon, WxCouponChannel couponChannel,int number) { + + StockReduceResult reduceResult = new StockReduceResult(); + + boolean isChannelStockReduce = false; + Integer currentPrice = coupon.getSalePrice(); + if (null != couponChannel ) { + if (null != couponChannel.getChannelStock()) { + isChannelStockReduce = true; + } + if (null != couponChannel.getChannelPrice()) { + currentPrice = couponChannel.getChannelPrice(); + } + } + + if (isChannelStockReduce) { + setCouponChanenlStockCache(couponChannel.getId(), coupon.getTitle(),coupon.getTenantId()); + }else { + setCouponStockCache(coupon.getId(),coupon.getTitle(),coupon.getTenantId()); + // 检查 优惠券 库存 + if (coupon.getRemainInventory() <= 0) { + throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY.getCode(),coupon.getTitle()+"["+coupon.getId()+"]库存不足"); + } + } + int unPaidcount = 0; // 有价券 if (coupon.getSalePrice() > 0) { @@ -892,7 +947,6 @@ public class WxOrderServiceImpl implements WxOrderService { } if (!allowUnPayOrder) { if (unPaidcount > 0) { - logger.error("此券有未支付的订单, couponId: " + couponIdStr + ", count: " + unPaidcount); throw new MallinkException(ErrorCode.ORDER_UNPAID.getCode(),"["+coupon.getTitle()+"]您有未支付的订单."); } } @@ -905,7 +959,6 @@ public class WxOrderServiceImpl implements WxOrderService { throw new MallinkException(ErrorCode.DB_FAIL.getCode(),"["+coupon.getTitle()+"]查询拼团中订单错误."); } if (grouponCount >= coupon.getUseLimitQuantity()) { - logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + grouponCount); throw new MallinkException(ErrorCode.ORDER_IS_LIMITED.getCode(),"["+coupon.getTitle()+"]购买超限."); } @@ -917,126 +970,44 @@ public class WxOrderServiceImpl implements WxOrderService { throw new MallinkException(ErrorCode.DB_FAIL.getCode(),"["+coupon.getTitle()+"]查询待使用订单错误."); } if (paidCount > coupon.getUseLimitQuantity()) { - logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + paidCount); - throw new MallinkException(ErrorCode.ORDER_IS_LIMITED.getCode(),"此券购买数量已超限["+coupon.getTitle()+"], couponId: " + couponIdStr + ", count: " + paidCount); + throw new MallinkException(ErrorCode.ORDER_IS_LIMITED.getCode(),"此券购买数量已超限["+coupon.getTitle()+"], couponId: " + coupon.getId() + ", count: " + paidCount); } //如果允许未支付的,则未支付的+已支付的不能超过限购 if ((unPaidcount+paidCount) > coupon.getUseLimitQuantity()) { - logger.error("此券[未支付+已支付]购买数量已超限, couponId: " + couponIdStr + ", count: " + paidCount); - throw new MallinkException(ErrorCode.ORDER_IS_LIMITED.getCode(),"此券[未支付+已支付]购买数量已超限["+coupon.getTitle()+"], couponId: " + couponIdStr + ", count: " + paidCount); + throw new MallinkException(ErrorCode.ORDER_IS_LIMITED.getCode(),"此券[未支付+已支付]购买数量已超限["+coupon.getTitle()+"], couponId: " + coupon.getId()+ ", count: " + paidCount); } - try { - //减库存, - wxCouponService.reduceRemainInventory(coupon,coupon.getId(),number); - - long stock = redisLock.decrease(EnumCacheKey.COUPON_STOCK.getMessage()+coupon.getId(), number); - if (stock < 0 ) { - throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券["+coupon.getTitle()+"]库存已为零!"); - } - - -// UpdateCouponStockMsg msg = new UpdateCouponStockMsg(); -// msg.setCouponId(coupon.getId()); -// msg.setNumber(1); -// msg.setOperateType(UpdateCouponStockMsg.OPERATE_TYPE_DECREASE); -// msg.setMsgType(EnumMsgRecordType.COUPON_STOCK.getCode()); -// mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.STOCK.getCode(), "*", "decrease_stock_"+coupon.getId()); - } catch (RuntimeException e) { - logger.error("此券减库存失败, couponId: " + couponIdStr,e); - throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券["+coupon.getTitle()+"]库存更新失败!"+e.getMessage()); - } + + //减库存, + if (isChannelStockReduce) { + try { + wxCouponChannelService.reduceChannelStock(coupon,couponChannel.getId(),number); + long stock = redisLock.decrease(EnumCacheKey.COUPON_CHANNEL_STOCK.getMessage()+couponChannel.getId(), number); + if (stock < 0 ) { + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券["+coupon.getTitle()+"]渠道["+couponChannel.getId()+"]库存已为零!"); + } + } catch (RuntimeException e) { + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券["+coupon.getTitle()+"]渠道["+couponChannel.getId()+"]库存更新失败!"+e.getMessage()); + } + + }else { + try { + wxCouponService.reduceRemainInventory(coupon,coupon.getId(),number); + long stock = redisLock.decrease(EnumCacheKey.COUPON_STOCK.getMessage()+coupon.getId(), number); + if (stock < 0 ) { + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券["+coupon.getTitle()+"]库存已为零!"); + } + } catch (RuntimeException e) { + logger.error("此券减库存失败, couponId: " + coupon.getId(),e); + throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"券["+coupon.getTitle()+"]库存更新失败!"+e.getMessage()); + } + } + reduceResult.setChannelStockReduce(isChannelStockReduce); + reduceResult.setCurrentPrice(currentPrice); + return reduceResult; } -// /** -// * 减库存 -// * -// * @param user -// * @param coupon -// * @param couponIdStr -// */ -// private void stockReduce(WxCUser user, WxCoupon coupon, String couponIdStr) { -// long time = System.currentTimeMillis() + RedisLock.TIMEOUT; -// String timeStr = String.valueOf(time); -// // 库存加锁 -// if (!redisLock.lock(couponIdStr, timeStr)) { -// logger.error("此券被锁定, couponId: " + couponIdStr); -// throw new MallinkException(ErrorCode.TOO_MANY_REQUEST); -// } -// -// // 检查 优惠券 库存 -// if (coupon.getRemainInventory() <= 0) { -// //解锁 -// redisLock.unlock(couponIdStr, timeStr); -// logger.error("此券库存为0, couponId: " + couponIdStr); -// throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY); -// } -// -// int count = 0; -// // 有价券 -// if (coupon.getSalePrice() > 0) { -// // 检查是否未支付订单 -// try { -// count = getUserOrderCount(user, coupon); -// } catch (Exception e) { -// //解锁 -// redisLock.unlock(couponIdStr, timeStr); -// throw new MallinkException(ErrorCode.DB_FAIL); -// } -// if (count > 0) { -// //解锁 -// redisLock.unlock(couponIdStr, timeStr); -// logger.error("此券有未支付的订单, couponId: " + couponIdStr + ", count: " + count); -// throw new MallinkException(ErrorCode.ORDER_UNPAID); -// } -// } -// //检查拼团中的数量 -// try { -// count = getUserOrderGroupCount(user, coupon); -// } catch (Exception e) { -// //解锁 -// redisLock.unlock(couponIdStr, timeStr); -// throw new MallinkException(ErrorCode.DB_FAIL); -// } -// if (count >= coupon.getUseLimitQuantity()) { -// //解锁 -// redisLock.unlock(couponIdStr, timeStr); -// logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); -// throw new MallinkException(ErrorCode.ORDER_IS_LIMITED); -// } -// -// // 检查用户已购买数量 -// try { -// count = getUserCouponOrderCount(user, coupon); -// } catch (Exception e) { -// //解锁 -// redisLock.unlock(couponIdStr, timeStr); -// throw new MallinkException(ErrorCode.DB_FAIL); -// } -// if (count >= coupon.getUseLimitQuantity()) { -// //解锁 -// redisLock.unlock(couponIdStr, timeStr); -// logger.error("此券购买数量已超限, couponId: " + couponIdStr + ", count: " + count); -// throw new MallinkException(ErrorCode.ORDER_IS_LIMITED); -// } -// -// try { -// // 减库存 -// int num = wxCouponMapper.reduceInventory(coupon.getId(), 1); -// if (num <= 0) { -// logger.error("此券减库存失败, couponId: " + couponIdStr); -// throw new MallinkException(ErrorCode.ORDER_IS_FAIL); -// } -// } catch (RuntimeException e) { -// logger.error("此券减库存失败, couponId: " + couponIdStr); -// throw new MallinkException(ErrorCode.ORDER_IS_FAIL); -// } finally { -// // 解锁 -// redisLock.unlock(couponIdStr, timeStr); -// } -// } - @Override public void stockBack(WxOrder updateOrder) { // 已取消/已退款,库存加1 @@ -1303,8 +1274,7 @@ public class WxOrderServiceImpl implements WxOrderService { * @param coupon */ @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public WxCouponOrder createCouponOrder(WxOrder order, WxCUserBasicInfo user, WxCoupon coupon, Long couponPasswordId,EnumPayWay payWay,Long merchantId,Long bUserId,Long parentCouponOrderId) { - Date curr = new Date(); + public WxCouponOrder createCouponOrder(Date curr,WxOrder order, WxCUserBasicInfo user, WxCoupon coupon, Long couponPasswordId,EnumPayWay payWay,Long merchantId,Long bUserId,Long parentCouponOrderId) { Date valid_date = null; //int limit_days = Constant.WX_LIMIT_DAYS; WxPayAccount payAccount = null; @@ -1829,7 +1799,7 @@ public class WxOrderServiceImpl implements WxOrderService { } else { // 减库存操作 try { - stockReduce(false,user, coupon, couponIdStr,1); + stockReduce(false,user, coupon,null,1); }catch(Exception e) { throw new MallinkException(ErrorCode.COUPON_STOCK_ERR.getCode(), e.getMessage()); } @@ -1874,7 +1844,7 @@ public class WxOrderServiceImpl implements WxOrderService { // 创建couponOrder WxCouponOrder couponOrder = null; try { - couponOrder = createCouponOrder(record, user, coupon, null,payWay,merchantId,bUserId,null); + couponOrder = createCouponOrder(new Date(),record, user, coupon, null,payWay,merchantId,bUserId,null); } catch (Exception e) { logger.error("保存订单:" + e.getMessage()); throw new MallinkException(ErrorCode.COUPON_ORDER_SAVE_ERR.getCode(), coupon.getTitle() + ErrorCode.COUPON_ORDER_SAVE_ERR.getMessage()); @@ -1949,7 +1919,7 @@ public class WxOrderServiceImpl implements WxOrderService { // 创建couponOrder try { - createCouponOrder(record, user, coupon, null,EnumPayWay.PAY_WAY_NOT_UNPAY_GIFTLIST,null,null,couponOrder.getId()); + createCouponOrder(new Date(),record, user, coupon, null,EnumPayWay.PAY_WAY_NOT_UNPAY_GIFTLIST,null,null,couponOrder.getId()); } catch (Exception e) { logger.error("保存订单:" + e.getMessage()); throw new MallinkException(ErrorCode.COUPON_ORDER_SAVE_ERR.getCode(), coupon.getTitle() + ErrorCode.COUPON_ORDER_SAVE_ERR.getMessage()); @@ -1997,7 +1967,7 @@ public class WxOrderServiceImpl implements WxOrderService { // 创建couponOrder try { - return createCouponOrder(updateOrder, user, coupon, null,null,null,null,null); + return createCouponOrder(currentDate,updateOrder, user, coupon, null,null,null,null,null); } catch (Exception e) { logger.error("创建券包:" + e.getMessage()); throw new MallinkException(ErrorCode.COUPON_ORDER_SAVE_ERR); @@ -2793,18 +2763,26 @@ public class WxOrderServiceImpl implements WxOrderService { cUserBasicInfoRedisTemplate.opsForValue().set(key, user, 1000, TimeUnit.MILLISECONDS); OrderAdapterService orderAdapterService = orderFactory.getOrderAdapterService(composeOrderType.getCode()); + //从这里开始,就需要锁住渠道的价格,不能修改 WxComposeOrder composeOrder = orderAdapterService.createDBMainOrder(tenantEntity,user, orderSave, payWay); + Date orderDate = new Date(); WxOrder lastOrder = null; for (int i = 0 ; i < orderSave.size(); i ++) { OrderComposeSaveDto orderdto = orderSave.get(i); + + Map couponChannelMap = composeOrder.getCouponChannelMap(); + Long couponChannelId = orderdto.getSignleOrder().getCouponChannelId(); + WxCouponChannel couponChannel = couponChannelMap.get(couponChannelId); + orderdto.setWxCouponChannel(couponChannel); + //券一个数量创建一个订单 boolean isOneNumberOneOrder = orderAdapterService.isOneNumberOneOrder(); if (isOneNumberOneOrder) { for (int j = 0; j < orderdto.getCount(); j++) { - lastOrder = proxy.handleSaveOrderForCouponSingle(allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), 1, orderdto, payWay); + lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), 1, orderdto, payWay); } }else { - lastOrder = proxy.handleSaveOrderForCouponSingle(allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), orderdto.getCount(), orderdto, payWay); + lastOrder = proxy.handleSaveOrderForCouponSingle(orderDate,allowUnPayOrder,composeOrder, user, orderdto.getWxCoupon(), orderdto.getCount(), orderdto, payWay); } } //如果没有orderId,则用lastOrder的信息 @@ -2815,13 +2793,14 @@ public class WxOrderServiceImpl implements WxOrderService { } @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public WxOrder handleSaveOrderForCouponSingle(boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user,WxCoupon coupon,int perCouponNumber,OrderComposeSaveDto orderdto,EnumPayWay payWay) { + public WxOrder handleSaveOrderForCouponSingle(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user,WxCoupon coupon,int perCouponNumber,OrderComposeSaveDto orderdto,EnumPayWay payWay) { WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); // 是否砍价 WxOrder order = null; - if (checkCouponIsFree(coupon,orderdto.getShippingType())) { + WxCouponChannel couponChannel = orderdto.getWxCouponChannel(); + if (checkCouponIsFree(coupon,couponChannel,orderdto.getShippingType())) { // 免费券 - order = proxy.saveFreeOrderForCoupon(allowUnPayOrder,composeOrder,user, coupon,perCouponNumber,orderdto.getSignleOrder().getCouponChannelId(), + order = proxy.saveFreeOrderForCoupon(orderDate,allowUnPayOrder,composeOrder,user, coupon,perCouponNumber,couponChannel, orderdto.getSignleOrder().getFormId(),null,payWay,orderdto.getShippingType(),orderdto.getAddress()); if (order != null) { // 6. 下订单完成,发送内部消息 @@ -2835,7 +2814,7 @@ public class WxOrderServiceImpl implements WxOrderService { } } else { // 有价券 - order = proxy.saveNoFreeOrderForCoupon(allowUnPayOrder,composeOrder,user, orderdto.getWxCoupon(),perCouponNumber, orderdto,payWay); + order = proxy.saveNoFreeOrderForCoupon(orderDate,allowUnPayOrder,composeOrder,user, orderdto.getWxCoupon(),perCouponNumber,couponChannel,orderdto,payWay); } // couponActionLog // try { @@ -2851,22 +2830,35 @@ public class WxOrderServiceImpl implements WxOrderService { @Override - public boolean checkCouponIsFree(WxCoupon coupon,Integer shippingType) { + public boolean checkCouponIsFree(WxCoupon coupon,WxCouponChannel couponChannel,Integer shippingType) { if(EnumOrderShopingType.DISTRIBUTION.getCode().equals(shippingType)){ return coupon.getSalePrice().intValue() + coupon.getFreightPrice().intValue() == 0; } - return coupon.getSalePrice().intValue() == 0; + if (null == couponChannel) { + return coupon.getSalePrice().intValue() == 0; + }else { + if (null != couponChannel.getChannelPrice()) { + return couponChannel.getChannelPrice().intValue() == 0; + }else { + return coupon.getSalePrice().intValue() == 0; + } + } } + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + public void checkPriceAndStockBeforeCreateOrder(Long couponChannelId,WxCoupon coupon) { + + } + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) @Override - public WxOrder saveFreeOrderForCoupon(boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber, - Long couponChannelId, String formId, Long couponPasswordId,EnumPayWay payWay, + public WxOrder saveFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber, + WxCouponChannel couponChannel, String formId, Long couponPasswordId,EnumPayWay payWay, Integer shippingType, UserBasicInfoAddress address) { WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); + // 减库存操作 - String couponIdStr = String.valueOf(coupon.getId()); - proxy.stockReduce(allowUnPayOrder,user, coupon, couponIdStr,couponNumber); + StockReduceResult stockReduceResult = proxy.stockReduce(allowUnPayOrder,user, coupon,couponChannel,couponNumber); // 当积分券或者积分停车券时 则进行积分支付 Integer orderType; @@ -2877,9 +2869,24 @@ public class WxOrderServiceImpl implements WxOrderService { orderType = EnumOrderType.COUPON.getCode(); } + //渠道的库存和价格可以随时修改。这里需要校验一下 + if (stockReduceResult.isChannelStockReduce()) { + //再查询一下,此时有可能价格已经修改 + WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(couponChannel.getId(),coupon.getTenantId()); + //如果这个时候渠道价格已经清空了 + if (null == wxCouponChannel.getChannelPrice()) { + throw new MallinkException(ErrorCode.ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]渠道价格已变动[清空],请刷新后重新下单."); + } + if (wxCouponChannel.getChannelPrice().intValue() > 0 ) { + throw new MallinkException(ErrorCode.ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]渠道价格已非免费,请刷新后重新下单."); + } + } + // 4. 保存Order WxOrder record = new WxOrder(); - record.setCouponChannelId(couponChannelId); + if (null != couponChannel) { + record.setCouponChannelId(couponChannel.getId()); + } record.setType(orderType); record.setPayVendor(payWay.getCode()); record.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PAYMENT_SUCCESS.getCode()); @@ -2896,14 +2903,14 @@ public class WxOrderServiceImpl implements WxOrderService { record.setComposeOrderType(composeOrder.getComposeOrderType()); record.setCouponNumber(couponNumber); try { - proxy.saveFreeOrder(record, user, coupon); + proxy.saveFreeOrder(orderDate,record, user, coupon); } catch (Exception e) { logger.error("下订单错误:" + e.getMessage(),e); throw new MallinkException(ErrorCode.ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]保存订单错误."+e.getMessage()); } // 5. 创建couponOrder try { - proxy.createCouponOrder(record, user, coupon, couponPasswordId,payWay,null,null,null); + proxy.createCouponOrder(orderDate,record, user, coupon, couponPasswordId,payWay,null,null,null); } catch (Exception e) { logger.error("couponOrder失败:" + e.getMessage(),e); throw new MallinkException(ErrorCode.COUPON_ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]保存券订单错误."+e.getMessage()); @@ -2913,11 +2920,11 @@ public class WxOrderServiceImpl implements WxOrderService { @Override @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public WxOrder saveNoFreeOrderForCoupon(boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber,OrderComposeSaveDto orderdto,EnumPayWay payWay) { + public WxOrder saveNoFreeOrderForCoupon(Date orderDate,boolean allowUnPayOrder,WxComposeOrder composeOrder,WxCUserBasicInfo user, WxCoupon coupon,int couponNumber,WxCouponChannel couponChannel,OrderComposeSaveDto orderdto,EnumPayWay payWay) { WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); - String couponIdStr = String.valueOf(coupon.getId()); + // 3. 减库存操作 - proxy.stockReduce(allowUnPayOrder,user, coupon, couponIdStr,couponNumber); + StockReduceResult stockReduceResult = proxy.stockReduce(allowUnPayOrder,user, coupon, couponChannel,couponNumber); // 3. 当积分券或者积分停车券时 则进行积分支付 Integer orderType; @@ -2927,12 +2934,25 @@ public class WxOrderServiceImpl implements WxOrderService { } else { orderType = EnumOrderType.COUPON.getCode(); } - + + //渠道的库存和价格可以随时修改。这里需要校验一下 + if (stockReduceResult.isChannelStockReduce()) { + //再查询一下,此时有可能价格已经修改 + WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(couponChannel.getId(),coupon.getTenantId()); + //如果这个时候渠道价格已经清空了 + if (null == wxCouponChannel.getChannelPrice()) { + throw new MallinkException(ErrorCode.ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]渠道价格已变动[清空],请刷新后重新下单."); + } + if (wxCouponChannel.getChannelPrice().intValue() != couponChannel.getChannelPrice().intValue()) { + throw new MallinkException(ErrorCode.ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]渠道价格已变更,请刷新后重新下单."); + } + } + // 4. 保存订单 Long orderNumber; - // 4.1 券价格 + // 4.1 价格 渠道/券 WxComposeChildOrderPrice price = orderFactory.getOrderAdapterService(composeOrder.getComposeOrderType()) - .getChildCouponOrderPrice(orderdto,coupon, orderdto.getSignleOrder().isPressOrder(), orderdto.getSignleOrder().getOrderGroupId(), couponNumber); + .getChildCouponOrderPrice(orderdto,coupon,couponChannel, orderdto.getSignleOrder().isPressOrder(), orderdto.getSignleOrder().getOrderGroupId(), couponNumber); Integer orderStatus = OrderHelper.getOrderStatusWxCoupon(coupon, orderdto.getSignleOrder().getOrderGroupId()); @@ -2943,7 +2963,6 @@ public class WxOrderServiceImpl implements WxOrderService { record.setCouponChannelId(orderdto.getSignleOrder().getCouponChannelId()); record.setOrderGroupId(orderdto.getSignleOrder().getOrderGroupId()); record.setFormId(orderdto.getSignleOrder().getFormId()); - record.setPayment(price.getRealPayMent()); record.setShippingType(orderdto.getShippingType()); if(EnumOrderShopingType.DISTRIBUTION.getCode().equals(orderdto.getShippingType())){ @@ -2961,7 +2980,7 @@ public class WxOrderServiceImpl implements WxOrderService { record.setCouponNumber(couponNumber); try { - orderNumber = proxy.saveNoFreeOrder(record, user, coupon, orderdto.getSignleOrder().isPressOrder()); + orderNumber = proxy.saveNoFreeOrder(orderDate,record, user, coupon, orderdto.getSignleOrder().isPressOrder()); } catch (Exception e) { logger.error("保存订单:" + e.getMessage(),e); throw new MallinkException(ErrorCode.ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]订单保存错误,"+e.getMessage()); @@ -2970,7 +2989,7 @@ public class WxOrderServiceImpl implements WxOrderService { if (orderdto.getSignleOrder().isPressOrder()) { // 5. 第一次砍价 try { - proxy.firstPress(record, user, coupon, orderNumber); + proxy.firstPress(orderDate,record, user, coupon, orderNumber); } catch (Exception e) { logger.error("第一次砍价失败:" + e.getMessage(),e); throw new MallinkException(ErrorCode.ORDER_SAVE_ERR.getCode(),"["+coupon.getTitle()+"]第一次砍价错误,"+e.getMessage()); @@ -2983,7 +3002,12 @@ public class WxOrderServiceImpl implements WxOrderService { @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) public Long saveOuterOrderForCoupon(WxCUserBasicInfo user, WxCoupon coupon, Long couponChannelId, String formId, Long couponPasswordId) { // 1. check user info and coupon info - userCouponMerchantCheck(user, coupon,"此券"); + WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(couponChannelId,coupon.getTenantId()); + if (wxCouponChannel == null) { + logger.error("couponChannelId find error, " + couponChannelId); + throw new MallinkException(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF.getCode(),"投放渠道不存在"); + } + userCouponMerchantCheck(user, coupon,wxCouponChannel,"此券"); if (coupon.checkIsCreditCoupon()) { //若用户剩余积分比积分售价低则不能支付 if (user.getCredit() == null || user.getCredit() < coupon.getCreditPrice()) { @@ -2991,8 +3015,7 @@ public class WxOrderServiceImpl implements WxOrderService { } } // 2. 减库存操作 - String couponIdStr = String.valueOf(coupon.getId()); - stockReduce(false,user, coupon, couponIdStr,1); + stockReduce(false,user, coupon, wxCouponChannel,1); // 3. 当积分券或者积分停车券时 则进行积分支付 Integer orderType; @@ -3017,7 +3040,7 @@ public class WxOrderServiceImpl implements WxOrderService { record.setComposeOrderType(EnumComposeOrder.SINGLE.getCode()); record.setCouponNumber(1); try { - saveFreeOrder(record, user, coupon); + saveFreeOrder(new Date(),record, user, coupon); } catch (Exception e) { logger.error("下订单:" + e.getMessage()); throw new MallinkException(ErrorCode.ORDER_SAVE_ERR); @@ -3041,8 +3064,7 @@ public class WxOrderServiceImpl implements WxOrderService { * @param coupon */ @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public void saveFreeOrder(WxOrder record, WxCUserBasicInfo user, WxCoupon coupon) { - Date curr = new Date(); + public void saveFreeOrder(Date curr,WxOrder record, WxCUserBasicInfo user, WxCoupon coupon) { // body String bodyStr = ""; try { @@ -3067,23 +3089,26 @@ public class WxOrderServiceImpl implements WxOrderService { wxOrderMapper.insert(record); } - private void userCouponMerchantCheck(WxCUserBasicInfo user, WxCoupon coupon,String premsg) throws MallinkException { + private void userCouponMerchantCheck(WxCUserBasicInfo user, WxCoupon coupon,WxCouponChannel wxCouponChannel,String premsg) throws MallinkException { // 检查券 if (coupon == null) { - logger.error("券不存在"); throw new MallinkException(ErrorCode.COUPON_IS_EMPTY.getCode(),premsg+"不存在"); } if (EnumCouponType.mustHasMerchant(coupon.getType())) { // 检查券商户信息 if (!isCouponMerchantValid(coupon.getId(),coupon)) { - logger.error("商户不存在, couponId: " + coupon.getId()); throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_FOUND.getCode(),premsg+"商户信息没找到"); } } // 检查 优惠券 库存 - if (coupon.getRemainInventory() <= 0) { - logger.error("此券库存为0, couponId: " + coupon.getId()); - throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY.getCode(),premsg+"库存不足"); + if (null != wxCouponChannel.getChannelStock()) { + if (wxCouponChannel.getChannelStock() <= 0) { + throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY.getCode(),premsg+"渠道库存不足"); + } + }else { + if (coupon.getRemainInventory() <= 0) { + throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY.getCode(),premsg+"库存不足"); + } } } @@ -3126,7 +3151,7 @@ public class WxOrderServiceImpl implements WxOrderService { * @param orderNumber */ @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public void firstPress(WxOrder record, WxCUserBasicInfo user, WxCoupon coupon, Long orderNumber) { + public void firstPress(Date currDate,WxOrder record, WxCUserBasicInfo user, WxCoupon coupon, Long orderNumber) { // 保存砍价信息 int total = coupon.getPrice() - coupon.getSalePrice(); int left_total = total; @@ -3136,7 +3161,7 @@ public class WxOrderServiceImpl implements WxOrderService { orderPress.setCouponId(record.getProductId()); orderPress.setOrderId(orderNumber); orderPress.setUserId(user.getId()); - orderPress.setCreateDate(new Date()); + orderPress.setCreateDate(currDate); orderPress.setFirst(EnumOrderPressType.FIRST.getCode()); int lPressValue = PressUtils.stateLessPressValue(total, left_total, coupon.getPressLimitNum(), 0); orderPress.setPressValue(lPressValue); @@ -3147,14 +3172,13 @@ public class WxOrderServiceImpl implements WxOrderService { orderUpdatePress.setPressCurrentNum(1); orderUpdatePress.setPressCurrentValue(left_total - orderPress.getPressValue()); orderUpdatePress.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PRESSING.getCode()); - orderUpdatePress.setUpdateDate(new Date()); + orderUpdatePress.setUpdateDate(currDate); wxOrderMapper.updateById(orderUpdatePress); } @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - public Long saveNoFreeOrder(WxOrder record, WxCUserBasicInfo user, WxCoupon coupon, boolean isPress) { + public Long saveNoFreeOrder(Date curr,WxOrder record, WxCUserBasicInfo user, WxCoupon coupon, boolean isPress) { Long orderNumber; - Date curr = new Date(); // body // tenant_id + merchant_id + title + subtitle @@ -3279,8 +3303,6 @@ public class WxOrderServiceImpl implements WxOrderService { WxOrderServiceImpl proxy = (WxOrderServiceImpl) AopContext.currentProxy(); try { WxComposeOrder order = proxy.saveOrderForCoupon(tenantEntity,allowUnPayOrder,composeOrderType,wxCUserBasicInfo, composeOrderSaveDto, payWay); - //订单同步消息 -// sendInsideOrderPushMsg(order,order.getMainOrderId()); return new ResultData(order); } catch (MallinkException e) { logger.error("saveOrderForCoupon error.",e); @@ -3453,25 +3475,49 @@ public class WxOrderServiceImpl implements WxOrderService { throw new MallinkException(ErrorCode.COUPON_IS_EMPTY.getCode(),premsg+"未查询到详细信息."); } - //此处判断是否存在绝对保证库存不超卖的缓存,如果没有,则把当前的库存设置为最大值。如果有,则是后台设置的时候保存的,以那个为准。 - boolean hascache = redisLock.hasCouponStockCache(wxCouponCVo.getCouponId()); - if (!hascache) { - long time = System.currentTimeMillis() + RedisLock.TIMEOUT; - String timeStr = String.valueOf(time); - boolean stocksetlock = redisLock.lock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); - if (stocksetlock) { - try { - if (!redisLock.hasCouponStockCache(wxCouponCVo.getCouponId())) { - redisLock.setCouponStock(wxCouponCVo.getCouponId(), coupon.getRemainInventory()); - } - }catch(Exception e) { - logger.error("save order stock cache error.",e); - }finally { - redisLock.unlock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); - } - }else { - redisLock.unlock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); - } + //如果couponChannel设置了库存锁定,则订单需要走那个库存 + if (null != wxCouponChannel.getChannelStock()) { + boolean hascache = redisLock.hasCouponChannelStockCache(wxCouponChannel.getId()); + if (!hascache) { + long time = System.currentTimeMillis() + RedisLock.TIMEOUT; + String timeStr = String.valueOf(time); + boolean stocksetlock = redisLock.lock("couponChannelLockStockSetByOrder_"+wxCouponChannel.getId(), timeStr); + if (stocksetlock) { + try { + if (!redisLock.hasCouponChannelStockCache(wxCouponChannel.getId())) { + redisLock.setCouponChannelStock(wxCouponChannel.getId(), wxCouponChannel.getChannelStock()); + } + }catch(Exception e) { + logger.error("save order channel stock cache error.",e); + }finally { + redisLock.unlock("couponChannelLockStockSetByOrder_"+wxCouponChannel.getId(), timeStr); + } + }else { + redisLock.unlock("couponChannelLockStockSetByOrder_"+wxCouponChannel.getId(), timeStr); + } + } + + }else { + //此处判断是否存在绝对保证库存不超卖的缓存,如果没有,则把当前的库存设置为最大值。如果有,则是后台设置的时候保存的,以那个为准。 + boolean hascache = redisLock.hasCouponStockCache(wxCouponCVo.getCouponId()); + if (!hascache) { + long time = System.currentTimeMillis() + RedisLock.TIMEOUT; + String timeStr = String.valueOf(time); + boolean stocksetlock = redisLock.lock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); + if (stocksetlock) { + try { + if (!redisLock.hasCouponStockCache(wxCouponCVo.getCouponId())) { + redisLock.setCouponStock(wxCouponCVo.getCouponId(), coupon.getRemainInventory()); + } + }catch(Exception e) { + logger.error("save order stock cache error.",e); + }finally { + redisLock.unlock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); + } + }else { + redisLock.unlock("couponLockStockSetByOrder_"+coupon.getId(), timeStr); + } + } } couponUserCheck(wxCUserBasicInfo, wxCouponCVo,premsg); @@ -3482,7 +3528,7 @@ public class WxOrderServiceImpl implements WxOrderService { throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), premsg+"couponChannelId或者couponId不能为空"); } - userCouponMerchantCheck(wxCUserBasicInfo, coupon,premsg); + userCouponMerchantCheck(wxCUserBasicInfo, coupon,wxCouponChannel,premsg); if (coupon.checkIsCreditCoupon()) { //若用户剩余积分比积分售价低则不能支付 @@ -3491,7 +3537,7 @@ public class WxOrderServiceImpl implements WxOrderService { } } - if (!checkCouponIsFree(coupon,null)) { + if (!checkCouponIsFree(coupon,wxCouponChannel,null)) { // 有价,拼团检查 if (isOrderGroup(orderSaveDto.getOrderGroupId())) { checkOrderGroup(wxCUserBasicInfo, orderSaveDto.getOrderGroupId(),coupon,premsg); @@ -3504,19 +3550,20 @@ public class WxOrderServiceImpl implements WxOrderService { if (wxCouponChannel.getTargetAd().equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())) { Date now = new Date(); if (wxCouponChannel.getBeginTime().getTime() > now.getTime()) { - logger.error("此券活动未开始:" + orderSaveDto.getCouponChannelId()); throw new MallinkException(ErrorCode.COUPON_CHANNEL_IS_NOT_STARTED.getCode(),premsg+"活动未开始"); } if (wxCouponChannel.getEndTime().getTime() < now.getTime()) { - logger.error("此券活动已结束:" + orderSaveDto.getCouponChannelId()); throw new MallinkException(ErrorCode.COUPON_CHANNEL_IS_END.getCode(),premsg+"活动已结束"); } } if (wxCouponChannel.getStatus() == EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode()) { - logger.error("此券已下架:" + orderSaveDto.getCouponChannelId()); throw new MallinkException(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF.getCode(),premsg+"已下架"); } + + if (null != wxCouponChannel.getChannelStock() && wxCouponChannel.getChannelStock() <= 0) { + throw new MallinkException(ErrorCode.COUPON_CHANNEL_STOCK_ZERO.getCode(),premsg+"渠道库存已售罄"); + } } private void couponUserCheck(WxCUserBasicInfo user, WxCouponCVo coupon,String premsg) { diff --git a/mallinkService/src/main/java/com/iformall/service/order/OrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/OrderAdapterService.java index 024b9367d..5168a097f 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/OrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/OrderAdapterService.java @@ -1,5 +1,6 @@ package com.iformall.service.order; +import java.util.Date; import java.util.List; import com.iformall.domain.dto.OrderComposeSaveDto; @@ -37,7 +38,7 @@ public interface OrderAdapterService { * @param coupon * @return */ - WxComposeChildOrderPrice getChildCouponOrderPrice(OrderComposeSaveDto orderdto,WxCoupon coupon,boolean isPress,Long orderGroupId,Integer couponNumber); + WxComposeChildOrderPrice getChildCouponOrderPrice(OrderComposeSaveDto orderdto,WxCoupon coupon,WxCouponChannel couponChannel,boolean isPress,Long orderGroupId,Integer couponNumber); /** * 计算每一个子订单的补贴 diff --git a/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeOrder.java b/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeOrder.java index 69db6b9ed..9ed64d1ba 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeOrder.java +++ b/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeOrder.java @@ -1,6 +1,9 @@ package com.iformall.service.order.entity; +import java.util.Map; + import com.iformall.domain.po.WxBatchOrder; +import com.iformall.domain.po.WxCouponChannel; import com.iformall.domain.po.WxOrder; import com.iformall.domain.po.base.TenantEntity; @@ -30,4 +33,6 @@ public class WxComposeOrder extends TenantEntity{ private WxBatchOrder mainOrder;//真正的主订单对象,批量下单时才有 + private Map couponChannelMap; + } diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/SingleOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/SingleOrderAdapterService.java index 1d8098c2e..ec369460c 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/SingleOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/SingleOrderAdapterService.java @@ -48,7 +48,7 @@ public class SingleOrderAdapterService extends BaseBatchOrderAdapterService { @Override public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, EnumPayWay payWay) { - return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.SINGLE); + return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.SINGLE,null); } @Override diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/BaseBatchOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/BaseBatchOrderAdapterService.java index 858468f4e..f89b67314 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/BaseBatchOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/BaseBatchOrderAdapterService.java @@ -2,27 +2,34 @@ package com.iformall.service.order.impl.batch; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import com.iformall.mapper.WxCouponMapper; import com.iformall.mapper.WxCouponOrderMapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import com.iformall.common.ErrorCode; import com.iformall.common.IdWorker; import com.iformall.domain.dto.OrderComposeSaveDto; import com.iformall.domain.po.WxBatchOrder; import com.iformall.domain.po.WxCUserBasicInfo; import com.iformall.domain.po.WxCoupon; +import com.iformall.domain.po.WxCouponChannel; import com.iformall.domain.po.WxOrder; import com.iformall.domain.po.base.TenantEntity; import com.iformall.enums.EnumComposeOrder; import com.iformall.enums.EnumOrderShopingType; import com.iformall.enums.EnumPayWay; +import com.iformall.exception.MallinkException; import com.iformall.mapper.WxBatchOrderMapper; import com.iformall.mapper.WxOrderMapper; +import com.iformall.service.WxCouponChannelService; import com.iformall.service.WxOrderService; import com.iformall.service.order.OrderAdapterService; import com.iformall.service.order.entity.WxComposeChildOrderPrice; @@ -44,13 +51,19 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic WxCouponOrderMapper wxCouponOrderMapper; @Autowired WxCouponMapper wxCouponMapper; + + @Lazy @Autowired WxOrderService wxOrderService; + + @Lazy + @Autowired + WxCouponChannelService wxCouponChannelService; @Override - public WxComposeChildOrderPrice getChildCouponOrderPrice(OrderComposeSaveDto orderdto,WxCoupon coupon,boolean isPress,Long orderGroupId,Integer couponNumber) { - Integer perPrice = OrderHelper.getCouponPerPayment(coupon, isPress, orderGroupId); + public WxComposeChildOrderPrice getChildCouponOrderPrice(OrderComposeSaveDto orderdto,WxCoupon coupon,WxCouponChannel couponChannel,boolean isPress,Long orderGroupId,Integer couponNumber) { + Integer perPrice = OrderHelper.getCouponPerPayment(coupon,couponChannel, isPress, orderGroupId); Integer freightPrice = 0; //在线配送加上运费 if (EnumOrderShopingType.DISTRIBUTION.getCode().equals(orderdto.getShippingType())) { @@ -62,17 +75,23 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) protected WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,List orderSave,EnumPayWay payWay,EnumComposeOrder composeOrderType) { int payment = 0; + Map couponChannelMap = new HashMap(); for (OrderComposeSaveDto ocsd : orderSave) { + WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(ocsd.getSignleOrder().getCouponChannelId(),tenantEntity.getTenantId()); + if (null == wxCouponChannel) { + throw new MallinkException(ErrorCode.MSG_INSIDE_ERROR.getCode(),"渠道不存在:"+ocsd.getSignleOrder().getCouponChannelId()); + } boolean isPress = ocsd.getSignleOrder().isPressOrder(); - WxComposeChildOrderPrice price = getChildCouponOrderPrice(ocsd,ocsd.getWxCoupon(), isPress, ocsd.getSignleOrder().getOrderGroupId(), ocsd.getCount()); + WxComposeChildOrderPrice price = getChildCouponOrderPrice(ocsd,ocsd.getWxCoupon(),wxCouponChannel, isPress, ocsd.getSignleOrder().getOrderGroupId(), ocsd.getCount()); payment = payment+price.getRealPayMent(); - + couponChannelMap.put(wxCouponChannel.getId(), wxCouponChannel); } - return createDBMainOrder(tenantEntity, user, payment, payWay, composeOrderType); + + return createDBMainOrder(tenantEntity, user, payment, payWay, composeOrderType,couponChannelMap); } @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) - protected WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,int payment,EnumPayWay payWay,EnumComposeOrder composeOrderType) { + protected WxComposeOrder createDBMainOrder(TenantEntity tenantEntity,WxCUserBasicInfo user,int payment,EnumPayWay payWay,EnumComposeOrder composeOrderType,Map couponChannelMap) { WxBatchOrder order =new WxBatchOrder(); final IdWorker idWorker = IdWorker.get(); order.setId(idWorker.nextId()); @@ -85,6 +104,9 @@ public abstract class BaseBatchOrderAdapterService implements OrderAdapterServic wxBatchOrderMapper.insert(order); WxComposeOrder composeOrder = new WxComposeOrder(order.getId(), composeOrderType.getCode(), payment); composeOrder.updateTenantInfo(tenantEntity); + if (null != couponChannelMap) { + composeOrder.setCouponChannelMap(couponChannelMap); + } return composeOrder; } diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/CouponPackageOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/CouponPackageOrderAdapterService.java index d24d80431..c4ebb524e 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/CouponPackageOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/CouponPackageOrderAdapterService.java @@ -38,7 +38,7 @@ public class CouponPackageOrderAdapterService extends BaseBatchOrderAdapterServi @Override public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, EnumPayWay payWay) { - return super.createDBMainOrder(tenantEntity, user, payment, payWay, EnumComposeOrder.PACKAGECOUPON); + return super.createDBMainOrder(tenantEntity, user, payment, payWay, EnumComposeOrder.PACKAGECOUPON,null); } @Override diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/MulityNumberOneOrderBatchOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/MulityNumberOneOrderBatchOrderAdapterService.java index aba1f282d..541e7490e 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/MulityNumberOneOrderBatchOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/MulityNumberOneOrderBatchOrderAdapterService.java @@ -39,7 +39,7 @@ public class MulityNumberOneOrderBatchOrderAdapterService extends BaseBatchOrder @Override public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, EnumPayWay payWay) { - return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.MULITY_NUMBER_ORDER_BATCH); + return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.MULITY_NUMBER_ORDER_BATCH,null); } @Override diff --git a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/OneNumberOneOrderBatchOrderAdapterService.java b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/OneNumberOneOrderBatchOrderAdapterService.java index ee52e406c..abed93602 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/impl/batch/OneNumberOneOrderBatchOrderAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/order/impl/batch/OneNumberOneOrderBatchOrderAdapterService.java @@ -38,7 +38,7 @@ public class OneNumberOneOrderBatchOrderAdapterService extends BaseBatchOrderAda @Override public WxComposeOrder createDBMainOrder(TenantEntity tenantEntity, WxCUserBasicInfo user, int payment, EnumPayWay payWay) { - return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.ONE_NUMBER_ORDER_BATCH); + return super.createDBMainOrder(tenantEntity,user, payment, payWay, EnumComposeOrder.ONE_NUMBER_ORDER_BATCH,null); } @Override diff --git a/mallinkService/src/main/java/com/iformall/service/order/util/OrderHelper.java b/mallinkService/src/main/java/com/iformall/service/order/util/OrderHelper.java index 878c774e8..7a4df1b73 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/util/OrderHelper.java +++ b/mallinkService/src/main/java/com/iformall/service/order/util/OrderHelper.java @@ -1,6 +1,7 @@ package com.iformall.service.order.util; import com.iformall.domain.po.WxCoupon; +import com.iformall.domain.po.WxCouponChannel; import com.iformall.domain.po.WxPayAccount; import com.iformall.enums.EnumCouponType; import com.iformall.enums.EnumOrderStatus; @@ -16,9 +17,14 @@ public class OrderHelper { * @param orderGroupId * @return */ - public static int getCouponPerPayment(WxCoupon coupon,boolean isPress,Long orderGroupId) { + public static int getCouponPerPayment(WxCoupon coupon,WxCouponChannel couponChannel,boolean isPress,Long orderGroupId) { // 4.1 券价格 int payment = coupon.getSalePrice(); + + if (null != couponChannel && null != couponChannel.getChannelPrice()) { + payment = couponChannel.getChannelPrice(); + } + if (isPress || coupon.getType().equals(EnumCouponType.COUPON_PRESS.getCode())) { // 砍价券 初始是全价即面额 payment = coupon.getPrice(); diff --git a/mallinkService/src/main/java/com/iformall/utils/RedisLock.java b/mallinkService/src/main/java/com/iformall/utils/RedisLock.java index 9dddc9788..1ad01957a 100644 --- a/mallinkService/src/main/java/com/iformall/utils/RedisLock.java +++ b/mallinkService/src/main/java/com/iformall/utils/RedisLock.java @@ -132,6 +132,29 @@ public class RedisLock { stringRedisTemplate.opsForValue().set(EnumCacheKey.COUPON_STOCK.getMessage()+String.valueOf(couponId), String.valueOf(number)); } + public void removeCouponStock(long couponId) { + boolean booleanHasCache = stringRedisTemplate.hasKey(EnumCacheKey.COUPON_STOCK.getMessage()+String.valueOf(couponId)); + if (booleanHasCache) { + stringRedisTemplate.delete(EnumCacheKey.COUPON_STOCK.getMessage()+String.valueOf(couponId)); + } + } + + public long getCouponChannelStock(long couponChannelId) { + String longstr = stringRedisTemplate.opsForValue().get(EnumCacheKey.COUPON_CHANNEL_STOCK.getMessage()+String.valueOf(couponChannelId)); + return Long.parseLong(longstr); + } + + public void setCouponChannelStock(long couponChannelId,long number) { + stringRedisTemplate.opsForValue().set(EnumCacheKey.COUPON_CHANNEL_STOCK.getMessage()+String.valueOf(couponChannelId), String.valueOf(number)); + } + + public void removeCouponChannelStock(long couponChannelId) { + boolean booleanHasCache = stringRedisTemplate.hasKey(EnumCacheKey.COUPON_CHANNEL_STOCK.getMessage()+String.valueOf(couponChannelId)); + if (booleanHasCache) { + stringRedisTemplate.delete(EnumCacheKey.COUPON_CHANNEL_STOCK.getMessage()+String.valueOf(couponChannelId)); + } + } + public boolean hasCouponStockCache(long couponId) { //如果库存为零,这个时候同步一下数据库的库存,因为有的时候系统报错事务会胡滚,但是redis扣减库存执行了,所以为0的时候,跟数据库的同步一下 boolean booleanHasCache = stringRedisTemplate.hasKey(EnumCacheKey.COUPON_STOCK.getMessage()+String.valueOf(couponId)); @@ -155,7 +178,21 @@ public class RedisLock { return rs <= 1L; } - + public boolean hasCouponChannelStockCache(long couponChannelId) { + //如果库存为零,这个时候同步一下数据库的库存,因为有的时候系统报错事务会胡滚,但是redis扣减库存执行了,所以为0的时候,跟数据库的同步一下 + boolean booleanHasCache = stringRedisTemplate.hasKey(EnumCacheKey.COUPON_CHANNEL_STOCK.getMessage()+String.valueOf(couponChannelId)); + if (booleanHasCache) { + long stockvalue = getCouponChannelStock(couponChannelId); + if (stockvalue > 0) { + return true; + }else { + return false; + } + } + return false; + } + + //------------------------------------------------------------------------------------------------------- // 时间紧迫,,,后面再做封装 diff --git a/mallinkService/src/main/resources/mapper/WxCouponChannelMapper.xml b/mallinkService/src/main/resources/mapper/WxCouponChannelMapper.xml index 4b63d6419..2fb768fa3 100644 --- a/mallinkService/src/main/resources/mapper/WxCouponChannelMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxCouponChannelMapper.xml @@ -21,10 +21,13 @@ + + - distinct cc.`id`,cc.`tenant_id`,cc.`parent_tenant_id`,cc.`coupon_id`,cc.`coupon_status`,cc.`type`,cc.`title`,cc.`target_ad`,cc.`business`,cc.`sub_business`,cc.`show_begin_time`,cc.`begin_time`,cc.`end_time`,cc.`status`,cc.`create_date`,cc.`update_date`,cc.`sub_target_id`,cc.qr_code,cc.tt_qr_code,cc.tt_spu_id + distinct cc.`id`,cc.`tenant_id`,cc.`parent_tenant_id`,cc.`coupon_id`,cc.`coupon_status`,cc.`type`,cc.`title`,cc.`target_ad`,cc.`business`,cc.`sub_business`,cc.`show_begin_time`,cc.`begin_time`,cc.`end_time`,cc.`status`,cc.`create_date`,cc.`update_date`,cc.`sub_target_id`,cc.`qr_code`, + cc.`tt_qr_code`,cc.`tt_spu_id`,cc.`channel_price`,cc.`channel_stock` @@ -167,7 +170,8 @@ @@ -244,7 +248,7 @@ + + + update wx_coupon_channel SET channel_stock = channel_stock - #{number} where id = #{id} and tenant_id =#{tenantId} and channel_stock is not null and channel_stock - #{number} >= 0 + + + + update wx_coupon_channel SET channel_stock = channel_stock + #{number} where id = #{id} and tenant_id =#{tenantId} and channel_stock is not null + + + + update wx_coupon_channel SET channel_stock = #{number} where id = #{id} and tenant_id =#{tenantId} and channel_stock is not null + + + + update wx_coupon_channel SET channel_stock = null where id = #{id} and tenant_id =#{tenantId} + + + + update wx_coupon_channel SET channel_price = #{price} where id = #{id} and tenant_id =#{tenantId} +