| @@ -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, "设置成功", ""); | |||
| } | |||
| } | |||
| @@ -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) { | |||
| @@ -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 '渠道锁定库存'; | |||
| @@ -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) { | |||
| @@ -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 | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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; | |||
| @@ -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<Integer,EnumCacheKey> map = new HashMap<Integer,EnumCacheKey>(); | |||
| static { | |||
| @@ -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) { | |||
| @@ -55,7 +55,15 @@ public interface WxCouponChannelMapper extends CommonMapper<WxCouponChannel, Str | |||
| * @return | |||
| */ | |||
| List<Long> 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); | |||
| } | |||
| @@ -39,7 +39,7 @@ public interface WxCouponMapper extends CommonMapper<WxCoupon, Long> { | |||
| 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); | |||
| @@ -61,4 +61,11 @@ public interface WxCouponChannelService { | |||
| List<WxCouponChannelVo> newfindListVo(WxCouponChannel wxCouponChannel); | |||
| PageInfo<WxCouponChannelVo> 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); | |||
| } | |||
| @@ -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); | |||
| /** | |||
| * 下订单成功后处理 | |||
| @@ -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()); | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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<Long,WxCouponChannel> 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) { | |||
| @@ -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); | |||
| /** | |||
| * 计算每一个子订单的补贴 | |||
| @@ -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<Long,WxCouponChannel> couponChannelMap; | |||
| } | |||
| @@ -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 | |||
| @@ -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<OrderComposeSaveDto> orderSave,EnumPayWay payWay,EnumComposeOrder composeOrderType) { | |||
| int payment = 0; | |||
| Map<Long,WxCouponChannel> couponChannelMap = new HashMap<Long,WxCouponChannel>(); | |||
| 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<Long,WxCouponChannel> 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; | |||
| } | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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(); | |||
| @@ -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; | |||
| } | |||
| //------------------------------------------------------------------------------------------------------- | |||
| // 时间紧迫,,,后面再做封装 | |||
| @@ -21,10 +21,13 @@ | |||
| <result column="qr_code" jdbcType="VARCHAR" property="qrCode"/> | |||
| <result column="tt_qr_code" jdbcType="VARCHAR" property="ttQrCode"/> | |||
| <result column="tt_spu_id" jdbcType="VARCHAR" property="ttSpuId"/> | |||
| <result column="channel_price" jdbcType="INTEGER" property="channelPrice"/> | |||
| <result column="channel_stock" jdbcType="INTEGER" property="channelStock"/> | |||
| </resultMap> | |||
| <sql id="allColumns"> | |||
| 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` | |||
| </sql> | |||
| <sql id="dynamicWhereConditions"> | |||
| @@ -167,7 +170,8 @@ | |||
| <select id="findVoDetail" parameterType="java.util.HashMap" resultMap="BaseResultMap"> | |||
| select | |||
| cc.id,cc.coupon_id,cc.target_ad,cc.begin_time,cc.end_time,cc.tenant_id,cc.parent_tenant_id,cc.qr_code,cc.tt_qr_code | |||
| cc.id,cc.coupon_id,cc.target_ad,cc.begin_time,cc.end_time,cc.tenant_id,cc.parent_tenant_id,cc.qr_code,cc.tt_qr_code, | |||
| cc.channel_price,cc.channel_stock | |||
| from wx_coupon_channel cc where cc.id = #{id} and cc.tenant_id = #{tenantId} | |||
| </select> | |||
| @@ -244,7 +248,7 @@ | |||
| <select id="newfindCList" parameterType="com.iformall.domain.po.WxCouponChannel" resultMap="BaseResultMap"> | |||
| select 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_spu_id | |||
| cc.`create_date`,cc.`update_date`,cc.`sub_target_id`,cc.qr_code,cc.tt_spu_id,cc.channel_price,cc.channel_stock | |||
| from wx_coupon_channel cc | |||
| where cc.`tenant_id` = #{tenantId} | |||
| @@ -332,5 +336,25 @@ | |||
| and `coupon_id` = #{couponId} | |||
| and `tt_spu_id` is not null | |||
| </select> | |||
| <update id="reduceChannelStock"> | |||
| 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> | |||
| <update id="backChannelStock"> | |||
| update wx_coupon_channel SET channel_stock = channel_stock + #{number} where id = #{id} and tenant_id =#{tenantId} and channel_stock is not null | |||
| </update> | |||
| <update id="setChannelStock"> | |||
| update wx_coupon_channel SET channel_stock = #{number} where id = #{id} and tenant_id =#{tenantId} and channel_stock is not null | |||
| </update> | |||
| <update id="clearChannelStock"> | |||
| update wx_coupon_channel SET channel_stock = null where id = #{id} and tenant_id =#{tenantId} | |||
| </update> | |||
| <update id="setChannelPrice"> | |||
| update wx_coupon_channel SET channel_price = #{price} where id = #{id} and tenant_id =#{tenantId} | |||
| </update> | |||
| </mapper> | |||