| @@ -57,7 +57,8 @@ public class WxMerchantController extends BaseController { | |||||
| @GetMapping("list") | @GetMapping("list") | ||||
| @ApiImplicitParams({ | @ApiImplicitParams({ | ||||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | ||||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true), | |||||
| }) | |||||
| @SystemControllerLog(description = "商户-列表") | @SystemControllerLog(description = "商户-列表") | ||||
| public ResultData list(@ModelAttribute WxMerchant wxMerchant, Integer pageNum, Integer pageSize) { | public ResultData list(@ModelAttribute WxMerchant wxMerchant, Integer pageNum, Integer pageSize) { | ||||
| logger.debug("[" + getIpAddr() + "] WxMerchantController::list"); | logger.debug("[" + getIpAddr() + "] WxMerchantController::list"); | ||||
| @@ -38,12 +38,8 @@ public class WxCouponSendConfigController extends BaseController { | |||||
| PageInfo<WxCouponSendConfig> page = wxCouponSendConfigService.listAsPage(wxCouponSendConfig, 1, 1); | PageInfo<WxCouponSendConfig> page = wxCouponSendConfigService.listAsPage(wxCouponSendConfig, 1, 1); | ||||
| if (page.getSize() > 0) { | if (page.getSize() > 0) { | ||||
| return new ResultData(page.getList().get(0)); | return new ResultData(page.getList().get(0)); | ||||
| } else { | |||||
| //默认停用 | |||||
| wxCouponSendConfig.setRemark(EnumCouponSendSendType.getEnum(wxCouponSendConfig.getSendType()).getMessage() + "开关"); | |||||
| wxCouponSendConfig.setValue(0); | |||||
| return new ResultData(wxCouponSendConfig); | |||||
| } | } | ||||
| return new ResultData(); | |||||
| } | } | ||||
| @@ -3,11 +3,12 @@ package com.iformall.controller; | |||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.iformall.common.ErrorCode; | import com.iformall.common.ErrorCode; | ||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.domain.po.BaseEntity; | |||||
| import com.iformall.domain.po.WxCouponSend; | |||||
| import com.iformall.domain.po.*; | |||||
| import com.iformall.domain.vo.WxCouponSendVo; | import com.iformall.domain.vo.WxCouponSendVo; | ||||
| import com.iformall.enums.EnumCouponSendSendType; | |||||
| import com.iformall.enums.EnumCouponSendStatus; | import com.iformall.enums.EnumCouponSendStatus; | ||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.mapper.WxCUserMapper; | |||||
| import com.iformall.service.WxCouponActionLogService; | import com.iformall.service.WxCouponActionLogService; | ||||
| import com.iformall.service.WxCouponSendService; | import com.iformall.service.WxCouponSendService; | ||||
| import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
| @@ -22,7 +23,8 @@ import org.springframework.web.bind.annotation.GetMapping; | |||||
| import org.springframework.web.bind.annotation.RequestMapping; | import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||
| import javax.validation.constraints.NotNull; | |||||
| import javax.annotation.Resource; | |||||
| import java.util.Arrays; | |||||
| import java.util.Objects; | import java.util.Objects; | ||||
| @RestController | @RestController | ||||
| @@ -30,18 +32,19 @@ import java.util.Objects; | |||||
| @Api(description = "商户注券相关接口") | @Api(description = "商户注券相关接口") | ||||
| public class WxCouponSendController extends BaseController { | public class WxCouponSendController extends BaseController { | ||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||||
| @Autowired | @Autowired | ||||
| private WxCouponSendService wxCouponSendService; | private WxCouponSendService wxCouponSendService; | ||||
| @Autowired | @Autowired | ||||
| private WxCouponActionLogService wxCouponActionLogService; | private WxCouponActionLogService wxCouponActionLogService; | ||||
| @Resource | |||||
| private WxCUserMapper wxCUserMapper; | |||||
| @ApiOperation("查询商户注券列表") | @ApiOperation("查询商户注券列表") | ||||
| @GetMapping("/list") | @GetMapping("/list") | ||||
| @ApiImplicitParams({ | @ApiImplicitParams({ | ||||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | ||||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true), | @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true), | ||||
| @ApiImplicitParam(name = "merchantId", value = "商户ID", dataType = "long", paramType = "query",required = true), | |||||
| }) | }) | ||||
| public ResultData list(WxCouponSend wxCouponSend, Integer pageNum, Integer pageSize) { | public ResultData list(WxCouponSend wxCouponSend, Integer pageNum, Integer pageSize) { | ||||
| logger.debug("[" + getIpAddr() + "] WxCouponSendController::list"); | logger.debug("[" + getIpAddr() + "] WxCouponSendController::list"); | ||||
| @@ -49,6 +52,7 @@ public class WxCouponSendController extends BaseController { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL); | throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL); | ||||
| } | } | ||||
| wxCouponSend.setTenantId(getTenantId()); | wxCouponSend.setTenantId(getTenantId()); | ||||
| wxCouponSend.setMerchantId(getUser().getMerchantId()); | |||||
| wxCouponSend.setStatus(Objects.isNull(wxCouponSend.getStatus()) ? null : wxCouponSend.getStatus()); | wxCouponSend.setStatus(Objects.isNull(wxCouponSend.getStatus()) ? null : wxCouponSend.getStatus()); | ||||
| //库存大于0 | //库存大于0 | ||||
| wxCouponSend.setMerchantLnventory(0); | wxCouponSend.setMerchantLnventory(0); | ||||
| @@ -62,15 +66,27 @@ public class WxCouponSendController extends BaseController { | |||||
| } | } | ||||
| @ApiOperation("商户注券") | @ApiOperation("商户注券") | ||||
| @GetMapping("/handsel") | |||||
| @GetMapping("/handSel") | |||||
| @ApiImplicitParams({ | @ApiImplicitParams({ | ||||
| @ApiImplicitParam(name = "wxCouponSendId", value = "wxCouponSendId", dataType = "long", paramType = "query",required = true), | |||||
| @ApiImplicitParam(name = "cUserId", value = "用户ID", dataType = "long", paramType = "query",required = true), | |||||
| @ApiImplicitParam(name = "wxCouponSendId", value = "wxCouponSendId", dataType = "long", paramType = "query", required = true), | |||||
| @ApiImplicitParam(name = "cUserId", value = "用户ID", dataType = "long", paramType = "query", required = true), | |||||
| }) | }) | ||||
| public ResultData handsel(Long[] wxCouponSendIds,Long cUserId) { | |||||
| if(ArrayUtils.isEmpty(wxCouponSendIds)||Objects.isNull(cUserId)) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||||
| public ResultData handSel(Long[] wxCouponSendIds, Long cUserId) { | |||||
| WxCUser cu = wxCUserMapper.selectByPrimaryKey(cUserId); | |||||
| if (Objects.isNull(cu)) { | |||||
| throw new MallinkException(ErrorCode.USER_IS_EMPTY); | |||||
| } | |||||
| if (ArrayUtils.isEmpty(wxCouponSendIds) || Objects.isNull(cUserId)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_IS_EMPTY); | |||||
| } | } | ||||
| WxCouponSend wxCouponSend = new WxCouponSend(); | |||||
| wxCouponSend.setIds(Arrays.asList(wxCouponSendIds)); | |||||
| wxCouponSend.setTenantId(getTenantId()); | |||||
| wxCouponSend.setSendType(EnumCouponSendSendType.MERCHANT.getCode()); | |||||
| wxCouponSend.setStatus(EnumCouponSendStatus.VALID.getCode()); | |||||
| wxCouponSendService.handSel(wxCouponSend,cu); | |||||
| return new ResultData(); | return new ResultData(); | ||||
| } | } | ||||
| @@ -180,7 +180,7 @@ public class CouponSendSchedule { | |||||
| // 发放免费券 | // 发放免费券 | ||||
| try { | try { | ||||
| WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId()); | |||||
| WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId(),null); | |||||
| wxCouponActionLogService.addOne(l.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId()); | wxCouponActionLogService.addOne(l.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId()); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| logger.error("定时发券:发券失败 levelId=" + l.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage()); | logger.error("定时发券:发券失败 levelId=" + l.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage()); | ||||
| @@ -304,7 +304,7 @@ public class CouponSendSchedule { | |||||
| } | } | ||||
| // 发放免费券 | // 发放免费券 | ||||
| try { | try { | ||||
| WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId()); | |||||
| WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId(),null); | |||||
| wxCouponActionLogService.addOne(cu.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId()); | wxCouponActionLogService.addOne(cu.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId()); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| logger.error("定时发券:发券失败 levelId=" + cu.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage()); | logger.error("定时发券:发券失败 levelId=" + cu.getId() + " couponId=" + cs.getCouponId() + " userId=" + cu.getId() + e.getMessage()); | ||||
| @@ -4,6 +4,8 @@ import cn.afterturn.easypoi.excel.annotation.Excel; | |||||
| import com.iformall.domain.vo.WxShopVo; | import com.iformall.domain.vo.WxShopVo; | ||||
| import com.iformall.enums.EnumBusiness; | import com.iformall.enums.EnumBusiness; | ||||
| import com.iformall.enums.EnumSubBusiness; | import com.iformall.enums.EnumSubBusiness; | ||||
| import io.swagger.annotations.ApiImplicitParam; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||
| import lombok.ToString; | import lombok.ToString; | ||||
| @@ -25,7 +27,8 @@ import java.util.stream.Collectors; | |||||
| public class WxMerchant extends BaseEntity { | public class WxMerchant extends BaseEntity { | ||||
| @Id | @Id | ||||
| protected Long id; | protected Long id; | ||||
| @ApiModelProperty(name = "ids", value = "商户ID数组") | |||||
| @Transient | @Transient | ||||
| protected List<Long> ids; | protected List<Long> ids; | ||||
| @@ -16,4 +16,22 @@ public interface WxCouponSendMapper extends CommonMapper<WxCouponSend, String> { | |||||
| void updateBirthdayConfig(WxCouponSend wxCouponSend); | void updateBirthdayConfig(WxCouponSend wxCouponSend); | ||||
| /** | |||||
| * 商户注券 库存减少 | |||||
| * | |||||
| * @param id 券ID | |||||
| * @param remainInventory 当前库存 | |||||
| * @param number 减少数量 | |||||
| */ | |||||
| Integer reduceMerchantRemainInventory(Long id, Integer remainInventory, Integer number); | |||||
| /** | |||||
| * 商户注券 库存退回 | |||||
| * | |||||
| * @param id 券ID | |||||
| * @param remainInventory 当前库存 | |||||
| * @param number 回退数量 | |||||
| */ | |||||
| Integer backMerchantRemainInventory(Long id, Integer remainInventory, Integer number); | |||||
| } | } | ||||
| @@ -1,6 +1,7 @@ | |||||
| package com.iformall.service; | package com.iformall.service; | ||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.iformall.domain.po.WxCUser; | |||||
| import com.iformall.domain.po.WxCouponSend; | import com.iformall.domain.po.WxCouponSend; | ||||
| import com.iformall.domain.vo.WxCouponSendVo; | import com.iformall.domain.vo.WxCouponSendVo; | ||||
| import com.iformall.enums.EnumCouponSendSendType; | import com.iformall.enums.EnumCouponSendSendType; | ||||
| @@ -72,9 +73,24 @@ public interface WxCouponSendService { | |||||
| */ | */ | ||||
| WxCouponSend getConfig(Integer sendType,String tenantId) ; | WxCouponSend getConfig(Integer sendType,String tenantId) ; | ||||
| /** | |||||
| * 商户注券 库存减少 | |||||
| * | |||||
| * @param id 券ID | |||||
| * @param remainInventory 当前库存 | |||||
| * @param number 减少数量 | |||||
| */ | |||||
| void reduceMerchantRemainInventory(Long id, Integer remainInventory, Integer number); | |||||
| /** | |||||
| * 商户注券 库存退回 | |||||
| * | |||||
| * @param id 券ID | |||||
| * @param remainInventory 当前库存 | |||||
| * @param number 回退数量 | |||||
| */ | |||||
| void backMerchantRemainInventory(Long id, Integer remainInventory, Integer number); | |||||
| void handSel(WxCouponSend wxCouponSend, WxCUser user) ; | |||||
| } | } | ||||
| @@ -4,6 +4,7 @@ import com.github.pagehelper.PageInfo; | |||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.domain.dto.OrderSaveDto; | import com.iformall.domain.dto.OrderSaveDto; | ||||
| import com.iformall.domain.po.*; | import com.iformall.domain.po.*; | ||||
| import com.iformall.domain.vo.WxCouponSendVo; | |||||
| import com.iformall.domain.vo.WxOrderCouponPressVo; | import com.iformall.domain.vo.WxOrderCouponPressVo; | ||||
| import com.iformall.domain.vo.WxOrderCouponVo; | import com.iformall.domain.vo.WxOrderCouponVo; | ||||
| import com.iformall.domain.vo.WxOrderQueryVo; | import com.iformall.domain.vo.WxOrderQueryVo; | ||||
| @@ -55,9 +56,10 @@ public interface WxOrderService { | |||||
| * 免费券订单接口 | * 免费券订单接口 | ||||
| * @param userId | * @param userId | ||||
| * @param couponId | * @param couponId | ||||
| * @param wxCouponSendVo 商户注券时必须指定 | |||||
| * @return WxCouponOrder | * @return WxCouponOrder | ||||
| */ | */ | ||||
| WxCouponOrder sendFreeCouponToUser(Long userId, Long couponId); | |||||
| WxCouponOrder sendFreeCouponToUser(Long userId, Long couponId, WxCouponSendVo wxCouponSendVo); | |||||
| /** | /** | ||||
| * orderSuccess 订单已支付 | * orderSuccess 订单已支付 | ||||
| @@ -272,7 +272,7 @@ public class WxCouponInjectServiceImpl implements WxCouponInjectService { | |||||
| // 发放免费券 | // 发放免费券 | ||||
| WxCouponOrder couponOrder = null; | WxCouponOrder couponOrder = null; | ||||
| try { | try { | ||||
| couponOrder = wxOrderService.sendFreeCouponToUser(tempCUser.getId(), wxCoupon.getId()); | |||||
| couponOrder = wxOrderService.sendFreeCouponToUser(tempCUser.getId(), wxCoupon.getId(),null); | |||||
| if (couponOrder != null) { | if (couponOrder != null) { | ||||
| wxCouponActionLogService.addOne(tempCUser.getTenantId(), wxCoupon.getId(), couponOrder.getId(), EnumCouponSendSendType.INJECT.getCode(), couponInjectId); | wxCouponActionLogService.addOne(tempCUser.getTenantId(), wxCoupon.getId(), couponOrder.getId(), EnumCouponSendSendType.INJECT.getCode(), couponInjectId); | ||||
| } | } | ||||
| @@ -25,6 +25,7 @@ import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Isolation; | |||||
| import org.springframework.transaction.annotation.Propagation; | import org.springframework.transaction.annotation.Propagation; | ||||
| import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
| @@ -32,7 +33,7 @@ import java.text.SimpleDateFormat; | |||||
| import java.util.*; | import java.util.*; | ||||
| @Service | @Service | ||||
| public class WxCouponSendServiceImpl implements WxCouponSendService { | |||||
| public class WxCouponSendServiceImpl implements WxCouponSendService { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||||
| @Autowired | @Autowired | ||||
| @@ -63,6 +64,8 @@ import java.util.*; | |||||
| WxAuthorizerInfoMapper authorizerInfoMapper; | WxAuthorizerInfoMapper authorizerInfoMapper; | ||||
| @Autowired | @Autowired | ||||
| WxMsgLimitService wxMsgLimitService; | WxMsgLimitService wxMsgLimitService; | ||||
| @Autowired | |||||
| WxCouponMerchantMapper wxCouponMerchantMapper; | |||||
| @Override | @Override | ||||
| public PageInfo<WxCouponSendVo> listAsPage(WxCouponSend record, Integer pageIndex, Integer pageSize) { | public PageInfo<WxCouponSendVo> listAsPage(WxCouponSend record, Integer pageIndex, Integer pageSize) { | ||||
| @@ -90,32 +93,46 @@ import java.util.*; | |||||
| @Override | @Override | ||||
| public void saveOrUpdate(WxCouponSend record) { | public void saveOrUpdate(WxCouponSend record) { | ||||
| //会员生日券配置 | //会员生日券配置 | ||||
| if(Objects.equals(record.getSendType(),EnumCouponSendSendType.BIRTHDAY.getCode())) { | |||||
| WxCouponSend config = getConfig(record.getSendType(),record.getTenantId()) ; | |||||
| if(Objects.nonNull(config)) { | |||||
| if (Objects.equals(record.getSendType(), EnumCouponSendSendType.BIRTHDAY.getCode())) { | |||||
| WxCouponSend config = getConfig(record.getSendType(), record.getTenantId()); | |||||
| if (Objects.nonNull(config)) { | |||||
| record.setConditions(config.getConditions()); | record.setConditions(config.getConditions()); | ||||
| } | } | ||||
| } | } | ||||
| //商户卡库存校验 | //商户卡库存校验 | ||||
| if(Objects.equals(record.getSendType(),EnumCouponSendSendType.MERCHANT.getCode())) { | |||||
| JSONObject jo = JSONObject.parseObject(record.getConditions()) ; | |||||
| if(Objects.isNull(jo)||!jo.containsKey(WxCouponSend.KEY_MERCHANT_LNVENTORY)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_SEND_LIMIT_VERIFY) ; | |||||
| if (Objects.equals(record.getSendType(), EnumCouponSendSendType.MERCHANT.getCode())) { | |||||
| JSONObject jo = JSONObject.parseObject(record.getConditions()); | |||||
| if (Objects.isNull(jo) || !jo.containsKey(WxCouponSend.KEY_MERCHANT_LNVENTORY)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_SEND_LIMIT_VERIFY); | |||||
| } | } | ||||
| //查询总库存 | //查询总库存 | ||||
| WxCoupon queryById = new WxCoupon() ; | |||||
| WxCoupon queryById = new WxCoupon(); | |||||
| queryById.setId(record.getCouponId()); | queryById.setId(record.getCouponId()); | ||||
| WxCoupon wxCouponOfDb = wxCouponService.findById(queryById); | |||||
| if(Objects.isNull(wxCouponOfDb)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_IS_EMPTY) ; | |||||
| WxCoupon wxCouponOfDb = wxCouponService.findById(queryById); | |||||
| if (Objects.isNull(wxCouponOfDb)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_IS_EMPTY); | |||||
| } | |||||
| String merchantIdStr = jo.getString("id"); | |||||
| if (Objects.isNull(merchantIdStr)) { | |||||
| throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_FOUND); | |||||
| } | |||||
| WxCouponMerchant couponMerchantQ = new WxCouponMerchant(); | |||||
| couponMerchantQ.setTenantId(record.getTenantId()); | |||||
| couponMerchantQ.setProductId(record.getCouponId()); | |||||
| couponMerchantQ.setMerchantId(Long.parseLong(merchantIdStr)); | |||||
| couponMerchantQ.setStatus(EnumCouponMerchantStatus.COUPON_MERCHANT_STATUS_VALID.getCode()); | |||||
| WxCouponMerchant couponMerchant = wxCouponMerchantMapper.selectOne(couponMerchantQ); | |||||
| if (Objects.isNull(couponMerchant)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_MERCHANT_NOT_FOUND); | |||||
| } | } | ||||
| int merchantLnventory = jo.getInteger(WxCouponSend.KEY_MERCHANT_LNVENTORY) ; | |||||
| int merchantLnventory = jo.getInteger(WxCouponSend.KEY_MERCHANT_LNVENTORY); | |||||
| //商家购券数不能大于总库存 | //商家购券数不能大于总库存 | ||||
| if(merchantLnventory > wxCouponOfDb.getRemainInventory()) { | |||||
| throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY) ; | |||||
| if (merchantLnventory > wxCouponOfDb.getRemainInventory()) { | |||||
| throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY); | |||||
| } | } | ||||
| //更新库存 | //更新库存 | ||||
| wxCouponService.reduceRemainInventory(wxCouponOfDb.getId(),wxCouponOfDb.getRemainInventory(),merchantLnventory); | |||||
| wxCouponService.reduceRemainInventory(wxCouponOfDb.getId(), wxCouponOfDb.getRemainInventory(), merchantLnventory); | |||||
| } | } | ||||
| if (record.getId() == null) { | if (record.getId() == null) { | ||||
| //record.setId(UUID.randomUUID().toString().replaceAll("-", "")); | //record.setId(UUID.randomUUID().toString().replaceAll("-", "")); | ||||
| @@ -132,22 +149,22 @@ import java.util.*; | |||||
| public void updateInvalid(WxCouponSend record) { | public void updateInvalid(WxCouponSend record) { | ||||
| record.setStatus(EnumCouponSendStatus.INVALID.getCode()); | record.setStatus(EnumCouponSendStatus.INVALID.getCode()); | ||||
| record.setUpdateDate(new Date()); | record.setUpdateDate(new Date()); | ||||
| if(Objects.equals(record.getSendType(),EnumCouponSendSendType.MERCHANT.getCode())) { | |||||
| if (Objects.equals(record.getSendType(), EnumCouponSendSendType.MERCHANT.getCode())) { | |||||
| //查询总库存 | //查询总库存 | ||||
| WxCoupon queryById = new WxCoupon() ; | |||||
| WxCoupon queryById = new WxCoupon(); | |||||
| queryById.setId(record.getCouponId()); | queryById.setId(record.getCouponId()); | ||||
| WxCoupon wxCouponOfDb = wxCouponService.findById(queryById); | |||||
| if(Objects.isNull(wxCouponOfDb)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_IS_EMPTY) ; | |||||
| WxCoupon wxCouponOfDb = wxCouponService.findById(queryById); | |||||
| if (Objects.isNull(wxCouponOfDb)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_IS_EMPTY); | |||||
| } | } | ||||
| //查询商家 | //查询商家 | ||||
| JSONObject jo = JSONObject.parseObject(record.getConditions()) ; | |||||
| if(Objects.isNull(jo)||!jo.containsKey(WxCouponSend.KEY_MERCHANT_LNVENTORY)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_SEND_LIMIT_VERIFY) ; | |||||
| JSONObject jo = JSONObject.parseObject(record.getConditions()); | |||||
| if (Objects.isNull(jo) || !jo.containsKey(WxCouponSend.KEY_MERCHANT_LNVENTORY)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_SEND_LIMIT_VERIFY); | |||||
| } | } | ||||
| int merchantLnventory = jo.getInteger(WxCouponSend.KEY_MERCHANT_LNVENTORY) ; | |||||
| //退回库存 | |||||
| wxCouponService.backRemainInventory(queryById.getId(),wxCouponOfDb.getRemainInventory(),merchantLnventory); | |||||
| int merchantLnventory = jo.getInteger(WxCouponSend.KEY_MERCHANT_LNVENTORY); | |||||
| //退回coupon库存 | |||||
| wxCouponService.backRemainInventory(queryById.getId(), wxCouponOfDb.getRemainInventory(), merchantLnventory); | |||||
| } | } | ||||
| wxCouponSendMapper.updateByPrimaryKeySelective(record); | wxCouponSendMapper.updateByPrimaryKeySelective(record); | ||||
| } | } | ||||
| @@ -298,7 +315,7 @@ import java.util.*; | |||||
| // 发放免费券 | // 发放免费券 | ||||
| WxCouponOrder couponOrder = null; | WxCouponOrder couponOrder = null; | ||||
| try { | try { | ||||
| couponOrder = wxOrderService.sendFreeCouponToUser(cUserId, send.getCouponId()); | |||||
| couponOrder = wxOrderService.sendFreeCouponToUser(cUserId, send.getCouponId(), null); | |||||
| if (couponOrder != null) { | if (couponOrder != null) { | ||||
| bRet = true; | bRet = true; | ||||
| @@ -472,13 +489,13 @@ import java.util.*; | |||||
| @Override | @Override | ||||
| public void saveOrUpdateConfig(Integer beforeDays, Integer sendType, String tenantId) { | public void saveOrUpdateConfig(Integer beforeDays, Integer sendType, String tenantId) { | ||||
| WxCouponSend config = getConfig(sendType, tenantId) ; | |||||
| WxCouponSend config = getConfig(sendType, tenantId); | |||||
| if (Objects.isNull(config)) { | if (Objects.isNull(config)) { | ||||
| WxCouponSend couponSendQuery = new WxCouponSend(); | WxCouponSend couponSendQuery = new WxCouponSend(); | ||||
| couponSendQuery.setSendType(sendType); | couponSendQuery.setSendType(sendType); | ||||
| couponSendQuery.setTenantId(tenantId); | couponSendQuery.setTenantId(tenantId); | ||||
| couponSendQuery.setCouponId(0L); | couponSendQuery.setCouponId(0L); | ||||
| couponSendQuery.setTitle(EnumCouponSendSendType.BIRTHDAY.getMessage()+"配置信息 "); | |||||
| couponSendQuery.setTitle(EnumCouponSendSendType.BIRTHDAY.getMessage() + "配置信息 "); | |||||
| final IdWorker idWorker = IdWorker.get(); | final IdWorker idWorker = IdWorker.get(); | ||||
| couponSendQuery.setId(idWorker.nextId()); | couponSendQuery.setId(idWorker.nextId()); | ||||
| couponSendQuery.setStatus(EnumCouponSendStatus.INVALID.getCode()); | couponSendQuery.setStatus(EnumCouponSendStatus.INVALID.getCode()); | ||||
| @@ -489,7 +506,7 @@ import java.util.*; | |||||
| wxCouponSendMapper.insertSelective(couponSendQuery); | wxCouponSendMapper.insertSelective(couponSendQuery); | ||||
| } else { | } else { | ||||
| JSONObject couponSendJo = JSONObject.parseObject(config.getConditions()); | JSONObject couponSendJo = JSONObject.parseObject(config.getConditions()); | ||||
| if(Objects.isNull(couponSendJo)) { | |||||
| if (Objects.isNull(couponSendJo)) { | |||||
| couponSendJo = new JSONObject(); | couponSendJo = new JSONObject(); | ||||
| } | } | ||||
| couponSendJo.put(WxCouponSend.KEY_BEFOREDAYS, beforeDays); | couponSendJo.put(WxCouponSend.KEY_BEFOREDAYS, beforeDays); | ||||
| @@ -500,7 +517,7 @@ import java.util.*; | |||||
| } | } | ||||
| @Override | @Override | ||||
| public WxCouponSend getConfig(Integer sendType,String tenantId) { | |||||
| public WxCouponSend getConfig(Integer sendType, String tenantId) { | |||||
| WxCouponSend couponSendQuery = new WxCouponSend(); | WxCouponSend couponSendQuery = new WxCouponSend(); | ||||
| couponSendQuery.setSendType(sendType); | couponSendQuery.setSendType(sendType); | ||||
| couponSendQuery.setTenantId(tenantId); | couponSendQuery.setTenantId(tenantId); | ||||
| @@ -517,4 +534,35 @@ import java.util.*; | |||||
| } | } | ||||
| return wxCouponSendList.get(0); | return wxCouponSendList.get(0); | ||||
| } | } | ||||
| @Override | |||||
| public void reduceMerchantRemainInventory(Long id, Integer remainInventory, Integer number) { | |||||
| int num = wxCouponSendMapper.reduceMerchantRemainInventory(id, remainInventory, number); | |||||
| if (num == 0) { | |||||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public void backMerchantRemainInventory(Long id, Integer remainInventory, Integer number) { | |||||
| int num = wxCouponSendMapper.backMerchantRemainInventory(id, remainInventory, number); | |||||
| if (num == 0) { | |||||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||||
| public void handSel(WxCouponSend wxCouponSend, WxCUser user) { | |||||
| List<WxCouponSendVo> couponSendList = wxCouponSendMapper.findListVo(wxCouponSend); | |||||
| if (CollectionUtils.isEmpty(couponSendList)) { | |||||
| throw new MallinkException(ErrorCode.COUPON_IS_EMPTY); | |||||
| } | |||||
| couponSendList.forEach(cs -> { | |||||
| // 发放免费券 | |||||
| WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(user.getId(), cs.getCouponId(), cs); | |||||
| wxCouponActionLogService.addOne(user.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId()); | |||||
| }); | |||||
| } | |||||
| } | } | ||||
| @@ -121,6 +121,9 @@ public class WxOrderServiceImpl implements WxOrderService { | |||||
| @Autowired | @Autowired | ||||
| private WxMsgLimitService wxMsgLimitService; | private WxMsgLimitService wxMsgLimitService; | ||||
| @Autowired | |||||
| private WxCouponSendService wxCouponSendService; | |||||
| @Override | @Override | ||||
| public PageInfo<WxOrder> listAsPage(WxOrder record, Integer pageIndex, Integer pageSize) { | public PageInfo<WxOrder> listAsPage(WxOrder record, Integer pageIndex, Integer pageSize) { | ||||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxOrderMapper.findList(record)); | return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxOrderMapper.findList(record)); | ||||
| @@ -302,6 +305,78 @@ public class WxOrderServiceImpl implements WxOrderService { | |||||
| } | } | ||||
| /** | |||||
| * 商户注券减库存 | |||||
| * @param user | |||||
| * @param coupon | |||||
| * @param couponIdStr | |||||
| * @param wxCouponSendVo | |||||
| */ | |||||
| private void stockMerchantReduce(WxCUser user, WxCoupon coupon, String couponIdStr, WxCouponSendVo wxCouponSendVo) { | |||||
| 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); | |||||
| } | |||||
| JSONObject jo = JSONObject.parseObject(wxCouponSendVo.getConditions()) ; | |||||
| int merchantLnventory = jo.getInteger(WxCouponSend.KEY_MERCHANT_LNVENTORY) ; | |||||
| // 检查 优惠券 库存 | |||||
| if (merchantLnventory <= 0) { | |||||
| //解锁 | |||||
| redisLock.unlock(couponIdStr, timeStr); | |||||
| logger.error("此券库存为0, couponId: " + couponIdStr); | |||||
| throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY); | |||||
| } | |||||
| int count = 0; | |||||
| // 有价券 TODO 当前只支持系统券(免费券) | |||||
| // 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 = 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 { | |||||
| // 减库存 | |||||
| wxCouponSendService.reduceMerchantRemainInventory(wxCouponSendVo.getId(),merchantLnventory,1); | |||||
| } catch (RuntimeException e) { | |||||
| logger.error("此券减库存失败, couponId: " + couponIdStr); | |||||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||||
| } finally { | |||||
| //解锁 | |||||
| redisLock.unlock(couponIdStr, timeStr); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * 减库存 | * 减库存 | ||||
| @@ -612,7 +687,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||||
| @Override | @Override | ||||
| @Transactional(propagation = Propagation.NESTED, readOnly = false, rollbackFor = {Exception.class}) | @Transactional(propagation = Propagation.NESTED, readOnly = false, rollbackFor = {Exception.class}) | ||||
| public WxCouponOrder sendFreeCouponToUser(Long userId, Long couponId) { | |||||
| public WxCouponOrder sendFreeCouponToUser(Long userId, Long couponId,WxCouponSendVo wxCouponSendVo) { | |||||
| // check 用户状态 | // check 用户状态 | ||||
| WxCUser user = null; | WxCUser user = null; | ||||
| try { | try { | ||||
| @@ -641,8 +716,13 @@ public class WxOrderServiceImpl implements WxOrderService { | |||||
| throw new MallinkException(ErrorCode.COUPON_IS_NOT_FREE); | throw new MallinkException(ErrorCode.COUPON_IS_NOT_FREE); | ||||
| } | } | ||||
| // 减库存操作 | |||||
| stockReduce(user, coupon, couponIdStr); | |||||
| if (Objects.nonNull(wxCouponSendVo) && Objects.equals(EnumCouponSendSendType.MERCHANT.getCode(), wxCouponSendVo.getSendType())) { | |||||
| // 商户注券减库存操作 | |||||
| stockMerchantReduce(user,coupon,couponIdStr,wxCouponSendVo); | |||||
| } else { | |||||
| // 减库存操作 | |||||
| stockReduce(user, coupon, couponIdStr); | |||||
| } | |||||
| int payment = coupon.getSalePrice(); | int payment = coupon.getSalePrice(); | ||||
| @@ -143,7 +143,10 @@ | |||||
| where c.id = cs.coupon_id and cs.status = 0 and | where c.id = cs.coupon_id and cs.status = 0 and | ||||
| ((c.status = 1) or (c.valid_type = 1 and c.valid_end_date < now())) | ((c.status = 1) or (c.valid_type = 1 and c.valid_end_date < now())) | ||||
| </update> | </update> | ||||
| <update id="reduceMerchantRemainInventory"> | |||||
| update wx_coupon_send SET conditions = JSON_SET(conditions,'$.merchantLnventory',#{remainInventory} - #{number}) where id = #{id} and conditions->'$.merchantLnventory' = #{remainInventory} | |||||
| </update> | |||||
| <update id="backMerchantRemainInventory"> | |||||
| update wx_coupon_send SET conditions = JSON_SET(conditions,'$.merchantLnventory',#{remainInventory} + #{number}) where id = #{id} and conditions->'$.merchantLnventory' = #{remainInventory} | |||||
| </update> | |||||
| </mapper> | </mapper> | ||||