| @@ -1,7 +1,10 @@ | |||
| ALTER TABLE `wx_game` | |||
| ADD COLUMN `play_credit_limit` int(11) NOT NULL DEFAULT -1 AFTER `award_limit`, | |||
| ADD COLUMN `play_credit` int(11) AFTER `play_credit_limit`; | |||
| ADD COLUMN `play_credit` int(11) NOT NULL DEFAULT 0 AFTER `play_credit_limit`; | |||
| ADD COLUMN `limit_type` int(11) NOT NULL DEFAULT 0 COMMENT '次数规则0:总次数 1:每天' AFTER `play_credit`; | |||
| ALTER TABLE `wx_game_action_log` | |||
| ADD COLUMN `type` int(11) NOT NULL DEFAULT 0 AFTER `create_time`; | |||
| ADD COLUMN `type` int(11) NOT NULL DEFAULT 0 AFTER `create_time`, | |||
| ADD COLUMN `used_credit` int(11) NOT NULL DEFAULT 0 AFTER `type`, | |||
| ADD COLUMN `add_credit` int(11) NOT NULL DEFAULT 0 AFTER `used_credit`; | |||
| @@ -69,8 +69,8 @@ public class WxCreditHistoryController extends BaseController{ | |||
| } | |||
| wxCreditHistory.setTenantId(wxCUser.getFinalTenantId()); | |||
| wxCreditHistory.setCUserId(wxCUser.getId()); | |||
| wxCreditHistory.setOperatorId(wxCUser.getId()); | |||
| wxCreditHistory.setCUserId(wxCUser.getUserId()); | |||
| wxCreditHistory.setOperatorId(wxCUser.getUserId()); | |||
| wxCreditHistory.setOperatorType(EnumUserType.CUSER.getCode()); | |||
| if(wxCreditHistory.getCreditType().equals(EnumScoreType.GAME_ADD_CREDIT.getCode())){ | |||
| @@ -12,8 +12,10 @@ import io.swagger.annotations.ApiOperation; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| @RestController | |||
| @@ -87,4 +89,85 @@ public class WxGameController extends BaseController { | |||
| } | |||
| } | |||
| @ApiOperation("免费玩游戏") | |||
| @PostMapping("freeGameGo") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "gameId", value = "游戏ID", dataType = "String", paramType = "query", required = true)}) | |||
| public ResultData freeGameGo(@RequestBody Map<String,String> paramMap) { | |||
| try { | |||
| Long gameIdL = Long.valueOf(paramMap.get("gameId")); | |||
| if(gameIdL == null){ | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| Map<String,Object> data = (Map<String, Object>) wxGameService.getCount(gameIdL, getMemberId()).data; | |||
| if(data == null){ | |||
| return new ResultData(ErrorCode.GAME_NOT_FOUND); | |||
| } | |||
| int playLimit = (int) data.get("playLimit"); | |||
| if(playLimit < 0){ | |||
| return new ResultData(ErrorCode.GAME_NOT_COUNT); | |||
| } | |||
| int AwardLimit = (int) data.get("AwardLimit"); | |||
| int AwardCount = (int) data.get("AwardCount"); | |||
| if(AwardLimit != 0 && AwardCount >= AwardLimit){ | |||
| return new ResultData(ErrorCode.GAME_NOT_WIN_COUNT); | |||
| } | |||
| int playCount = (int) data.get("playCount"); | |||
| if((playLimit > 0 && playCount >= playLimit) || playLimit < 0){ | |||
| return new ResultData(ErrorCode.GAME_NOT_HAVE_COUNT); | |||
| } | |||
| ResultData resultData = wxGameService.luckDraw(gameIdL, getMemberId()); | |||
| removeCacheCUser(); | |||
| return resultData; | |||
| } catch (Exception e){ | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); | |||
| } | |||
| } | |||
| @ApiOperation("积分玩游戏") | |||
| @PostMapping("freeCridetGameGo") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "gameId", value = "游戏ID", dataType = "String", paramType = "query", required = true)}) | |||
| public ResultData freeCridetGameGo(@RequestBody Map<String,String> paramMap) { | |||
| try { | |||
| Long gameIdL = Long.valueOf(paramMap.get("gameId")); | |||
| if(gameIdL == null){ | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| Map<String,Object> data = (Map<String, Object>) wxGameService.getCount(gameIdL, getMemberId()).data; | |||
| if(data == null){ | |||
| return new ResultData(ErrorCode.GAME_NOT_FOUND); | |||
| } | |||
| int playLimit = (int) data.get("playLimit"); | |||
| if(playLimit < 0){ | |||
| return new ResultData(ErrorCode.GAME_NOT_COUNT); | |||
| } | |||
| int AwardLimit = (int) data.get("AwardLimit"); | |||
| int AwardCount = (int) data.get("AwardCount"); | |||
| if(AwardLimit != 0 && AwardCount >= AwardLimit){ | |||
| return new ResultData(ErrorCode.GAME_NOT_WIN_COUNT); | |||
| } | |||
| int playCount = (int) data.get("playCount"); | |||
| if((playLimit > 0 && playCount >= playLimit) || playLimit < 0){ | |||
| int playCreditLimit = (int) data.get("playCreditLimit"); | |||
| int playCreditCount = (int) data.get("playCreditCount"); | |||
| if((playCreditLimit > 0 && playCreditCount >= playCreditLimit) || playCreditLimit < 0){//积分不能玩了 | |||
| return new ResultData(ErrorCode.GAME_NOT_HAVEC_COUNT); | |||
| } | |||
| }else{ | |||
| return new ResultData(ErrorCode.GAME_HAVE_COUNT); | |||
| } | |||
| ResultData resultData = wxGameService.cridetLuckDraw(gameIdL, getMemberId()); | |||
| removeCacheCUser(); | |||
| return resultData; | |||
| } catch (Exception e){ | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,6 +1,5 @@ | |||
| package com.iformall.controller; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| @@ -30,12 +29,10 @@ import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.beans.factory.annotation.Qualifier; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.data.redis.core.ValueOperations; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.util.Date; | |||
| import java.util.Map; | |||
| import java.util.concurrent.TimeUnit; | |||
| @RestController | |||
| @RequestMapping("/api/order/") | |||
| @@ -71,161 +68,161 @@ public class WxOrderController extends BaseController { | |||
| } catch (Exception e) { | |||
| return new ResultData(Result.ERROR,e.getMessage()); | |||
| } | |||
| return saveOrder(orderSaveDto,memberId,EnumPayWay.PAY_WAY_WECHAT); | |||
| return wxOrderService.saveOrder(orderSaveDto,memberId,EnumPayWay.PAY_WAY_WECHAT,getTenantInfo()); | |||
| } | |||
| private ResultData saveOrder(OrderSaveDto orderSaveDto,Long cUserId,EnumPayWay payWay) { | |||
| logger.info("OrderSave: " + orderSaveDto); | |||
| if (orderSaveDto.getCouponChannelId() == null) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId不能为空"); | |||
| } | |||
| WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(orderSaveDto.getCouponChannelId(),getTenantInfo().getTenantId()); | |||
| if (wxCouponChannel == null) { | |||
| logger.error("couponChannelId find error, " + orderSaveDto.getCouponChannelId()); | |||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF); | |||
| } | |||
| ResultData resultData = couponChannelCheck(orderSaveDto, wxCouponChannel); | |||
| if (resultData != null) return resultData; | |||
| WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoService.getById(cUserId,getFinalTenantId()); | |||
| if (wxCUserBasicInfo != null && wxCUserBasicInfo.getStatus().equals(EnumCUserBasicInfoStatus.LOCKED.getCode())) { | |||
| logger.info("会员权益被锁定:cUserId:" + cUserId); | |||
| return new ResultData(ErrorCode.MEMBER_IS_LOCKED); | |||
| } | |||
| WxCoupon coupon = wxCouponService.getById(wxCouponChannel.getCouponId(),wxCouponChannel.getTenantId()); | |||
| if (null == coupon) { | |||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| } | |||
| if (coupon.getStatus().equals(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode())) { | |||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF); | |||
| } | |||
| //判断是否是拼团订单,如果是拼团订单,判断现在进行中的,和已完成的数量是否超出券的限制 | |||
| if (coupon.getType().equals(EnumCouponType.COUPON_GROUP.getCode())) { | |||
| int ordercount = wxOrderService.countUserCouponGroupOrder(cUserId,coupon.getId(),coupon.getTenantId()); | |||
| if (ordercount>=coupon.getUseLimitQuantity()) { | |||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF.getCode(),"您当前此券的有效拼团数量达到券的限购次数。"); | |||
| } | |||
| } | |||
| WxCouponCVo wxCouponCVo = null; | |||
| String key = "cc:" + orderSaveDto.getCouponChannelId(); | |||
| ValueOperations<String, WxCouponCVo> operations = cdRedisTemplate.opsForValue(); | |||
| // 缓存 | |||
| boolean hasKey = cdRedisTemplate.hasKey(key); | |||
| if (hasKey) { | |||
| // 从缓存获取用户信息 | |||
| wxCouponCVo = operations.get(key); | |||
| } else { | |||
| // 游戏没有入缓存,需要从数据库中读取 | |||
| wxCouponCVo = wxCouponChannelService.findDetailVo(orderSaveDto.getCouponChannelId(),wxCouponChannel.getTenantId()); | |||
| if (wxCouponCVo != null) { | |||
| // 游戏优化,进缓存 | |||
| cdRedisTemplate.opsForValue().set(key, wxCouponCVo, 3600, TimeUnit.SECONDS); | |||
| } | |||
| } | |||
| if (wxCouponCVo == null) { | |||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| } | |||
| //此处判断是否存在绝对保证库存不超卖的缓存,如果没有,则把当前的库存设置为最大值。如果有,则是后台设置的时候保存的,以那个为准。 | |||
| 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); | |||
| } | |||
| } | |||
| resultData = couponUserCheck(wxCUserBasicInfo, wxCouponCVo); | |||
| if (resultData != null) return resultData; | |||
| Long couponId = orderSaveDto.getCouponId() == null ? wxCouponChannel.getCouponId() : orderSaveDto.getCouponId(); | |||
| if (couponId == null) { | |||
| logger.error("couponChannelId或者couponId不能为空"); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId或者couponId不能为空"); | |||
| } | |||
| // 是否砍价 | |||
| boolean isPress = orderSaveDto.getPress() != null ? orderSaveDto.getPress() : false; | |||
| try { | |||
| WxOrder order = wxOrderService.saveOrderForCoupon(wxCUserBasicInfo, coupon, orderSaveDto, isPress,payWay); | |||
| return new ResultData(order); | |||
| } catch (MallinkException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(ErrorCode.ORDER_IS_FAIL, e.getMessage()); | |||
| } | |||
| } | |||
| // private ResultData saveOrder(OrderSaveDto orderSaveDto,Long cUserId,EnumPayWay payWay) { | |||
| // logger.info("OrderSave: " + orderSaveDto); | |||
| // if (orderSaveDto.getCouponChannelId() == null) { | |||
| // return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId不能为空"); | |||
| // } | |||
| // WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(orderSaveDto.getCouponChannelId(),getTenantInfo().getTenantId()); | |||
| // if (wxCouponChannel == null) { | |||
| // logger.error("couponChannelId find error, " + orderSaveDto.getCouponChannelId()); | |||
| // return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF); | |||
| // } | |||
| // ResultData resultData = couponChannelCheck(orderSaveDto, wxCouponChannel); | |||
| // if (resultData != null) return resultData; | |||
| // | |||
| // WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoService.getById(cUserId,getFinalTenantId()); | |||
| // if (wxCUserBasicInfo != null && wxCUserBasicInfo.getStatus().equals(EnumCUserBasicInfoStatus.LOCKED.getCode())) { | |||
| // logger.info("会员权益被锁定:cUserId:" + cUserId); | |||
| // return new ResultData(ErrorCode.MEMBER_IS_LOCKED); | |||
| // } | |||
| // | |||
| // WxCoupon coupon = wxCouponService.getById(wxCouponChannel.getCouponId(),wxCouponChannel.getTenantId()); | |||
| // if (null == coupon) { | |||
| // return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| // } | |||
| // if (coupon.getStatus().equals(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode())) { | |||
| // return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF); | |||
| // } | |||
| // //判断是否是拼团订单,如果是拼团订单,判断现在进行中的,和已完成的数量是否超出券的限制 | |||
| // if (coupon.getType().equals(EnumCouponType.COUPON_GROUP.getCode())) { | |||
| // int ordercount = wxOrderService.countUserCouponGroupOrder(cUserId,coupon.getId(),coupon.getTenantId()); | |||
| // if (ordercount>=coupon.getUseLimitQuantity()) { | |||
| // return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF.getCode(),"您当前此券的有效拼团数量达到券的限购次数。"); | |||
| // } | |||
| // } | |||
| // | |||
| // WxCouponCVo wxCouponCVo = null; | |||
| // | |||
| // String key = "cc:" + orderSaveDto.getCouponChannelId(); | |||
| // ValueOperations<String, WxCouponCVo> operations = cdRedisTemplate.opsForValue(); | |||
| // // 缓存 | |||
| // boolean hasKey = cdRedisTemplate.hasKey(key); | |||
| // if (hasKey) { | |||
| // // 从缓存获取用户信息 | |||
| // wxCouponCVo = operations.get(key); | |||
| // } else { | |||
| // // 游戏没有入缓存,需要从数据库中读取 | |||
| // wxCouponCVo = wxCouponChannelService.findDetailVo(orderSaveDto.getCouponChannelId(),wxCouponChannel.getTenantId()); | |||
| // if (wxCouponCVo != null) { | |||
| // // 游戏优化,进缓存 | |||
| // cdRedisTemplate.opsForValue().set(key, wxCouponCVo, 3600, TimeUnit.SECONDS); | |||
| // } | |||
| // } | |||
| // if (wxCouponCVo == null) { | |||
| // return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| // } | |||
| // | |||
| // //此处判断是否存在绝对保证库存不超卖的缓存,如果没有,则把当前的库存设置为最大值。如果有,则是后台设置的时候保存的,以那个为准。 | |||
| // 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); | |||
| // } | |||
| // } | |||
| // | |||
| // resultData = couponUserCheck(wxCUserBasicInfo, wxCouponCVo); | |||
| // if (resultData != null) return resultData; | |||
| // | |||
| // Long couponId = orderSaveDto.getCouponId() == null ? wxCouponChannel.getCouponId() : orderSaveDto.getCouponId(); | |||
| // if (couponId == null) { | |||
| // logger.error("couponChannelId或者couponId不能为空"); | |||
| // return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId或者couponId不能为空"); | |||
| // } | |||
| // // 是否砍价 | |||
| // boolean isPress = orderSaveDto.getPress() != null ? orderSaveDto.getPress() : false; | |||
| // | |||
| // try { | |||
| // WxOrder order = wxOrderService.saveOrderForCoupon(wxCUserBasicInfo, coupon, orderSaveDto, isPress,payWay); | |||
| // return new ResultData(order); | |||
| // } catch (MallinkException e) { | |||
| // logger.error(e.getMessage()); | |||
| // return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| // } catch (Exception e) { | |||
| // logger.error(e.getMessage()); | |||
| // return new ResultData(ErrorCode.ORDER_IS_FAIL, e.getMessage()); | |||
| // } | |||
| // } | |||
| private ResultData couponUserCheck(WxCUserBasicInfo user, WxCouponCVo coupon) { | |||
| if (coupon.getConditions() == null) return null; | |||
| JSONObject jo = null; | |||
| try { | |||
| jo = JSONObject.parseObject(coupon.getConditions()); | |||
| } catch (Exception e) { | |||
| logger.error("购买券条件判断错误:ID=" + coupon.getId() + e.getMessage()); | |||
| } | |||
| if (jo != null) { | |||
| if (jo.getIntValue("type") == EnumCouponConditionType.NEW_MEMBER.getCode()){ | |||
| if (user != null && user.getActRecord() > 0) | |||
| return new ResultData(ErrorCode.COUPON_ONLY_FOR_NEW_MEMBER); | |||
| if (wxOrderService.countCouponConditionType1(coupon.getTenantId(),user.getId()) > 0) | |||
| return new ResultData(ErrorCode.COUPON_ALREADY_IN_NEW_MEMBER); | |||
| }else if (jo.getIntValue("type") == EnumCouponConditionType.SCORE_SCOPE.getCode()){ | |||
| int max = jo.getIntValue("max"); | |||
| int min = jo.getIntValue("min"); | |||
| if (max!=0 && min ==0 && user.getPoins() > max) { | |||
| return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| } | |||
| if (max==0 && min !=0 && user.getPoins() < min) { | |||
| return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| } | |||
| if (max!=0 && min !=0 && (user.getPoins() < min || user.getPoins() > max)) { | |||
| return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| } | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| private ResultData couponChannelCheck(@RequestBody OrderSaveDto orderSaveDto, WxCouponChannel wxCouponChannel) { | |||
| if (wxCouponChannel.getTargetAd().equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())) { | |||
| Date now = new Date(); | |||
| if (wxCouponChannel.getBeginTime().getTime() > now.getTime()) { | |||
| logger.error("此券活动未开始:" + orderSaveDto.getCouponChannelId()); | |||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_NOT_STARTED); | |||
| } | |||
| if (wxCouponChannel.getEndTime().getTime() < now.getTime()) { | |||
| logger.error("此券活动已结束:" + orderSaveDto.getCouponChannelId()); | |||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_END); | |||
| } | |||
| } | |||
| if (wxCouponChannel.getStatus() == EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode()) { | |||
| logger.error("此券已下架:" + orderSaveDto.getCouponChannelId()); | |||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF); | |||
| } | |||
| return null; | |||
| } | |||
| // private ResultData couponUserCheck(WxCUserBasicInfo user, WxCouponCVo coupon) { | |||
| // if (coupon.getConditions() == null) return null; | |||
| // JSONObject jo = null; | |||
| // try { | |||
| // jo = JSONObject.parseObject(coupon.getConditions()); | |||
| // } catch (Exception e) { | |||
| // logger.error("购买券条件判断错误:ID=" + coupon.getId() + e.getMessage()); | |||
| // } | |||
| // if (jo != null) { | |||
| // if (jo.getIntValue("type") == EnumCouponConditionType.NEW_MEMBER.getCode()){ | |||
| // | |||
| // if (user != null && user.getActRecord() > 0) | |||
| // return new ResultData(ErrorCode.COUPON_ONLY_FOR_NEW_MEMBER); | |||
| // if (wxOrderService.countCouponConditionType1(coupon.getTenantId(),user.getId()) > 0) | |||
| // return new ResultData(ErrorCode.COUPON_ALREADY_IN_NEW_MEMBER); | |||
| // }else if (jo.getIntValue("type") == EnumCouponConditionType.SCORE_SCOPE.getCode()){ | |||
| // int max = jo.getIntValue("max"); | |||
| // int min = jo.getIntValue("min"); | |||
| // | |||
| // if (max!=0 && min ==0 && user.getPoins() > max) { | |||
| // return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| // } | |||
| // if (max==0 && min !=0 && user.getPoins() < min) { | |||
| // return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| // } | |||
| // if (max!=0 && min !=0 && (user.getPoins() < min || user.getPoins() > max)) { | |||
| // return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| // } | |||
| // } | |||
| // } | |||
| // | |||
| // return null; | |||
| // } | |||
| // private ResultData couponChannelCheck(@RequestBody OrderSaveDto orderSaveDto, WxCouponChannel wxCouponChannel) { | |||
| // if (wxCouponChannel.getTargetAd().equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())) { | |||
| // Date now = new Date(); | |||
| // if (wxCouponChannel.getBeginTime().getTime() > now.getTime()) { | |||
| // logger.error("此券活动未开始:" + orderSaveDto.getCouponChannelId()); | |||
| // return new ResultData(ErrorCode.COUPON_CHANNEL_IS_NOT_STARTED); | |||
| // } | |||
| // if (wxCouponChannel.getEndTime().getTime() < now.getTime()) { | |||
| // logger.error("此券活动已结束:" + orderSaveDto.getCouponChannelId()); | |||
| // return new ResultData(ErrorCode.COUPON_CHANNEL_IS_END); | |||
| // } | |||
| // } | |||
| // | |||
| // if (wxCouponChannel.getStatus() == EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode()) { | |||
| // logger.error("此券已下架:" + orderSaveDto.getCouponChannelId()); | |||
| // return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF); | |||
| // } | |||
| // return null; | |||
| // } | |||
| @ApiOperation(value = "取消订单", notes = "{\"orderId\":\"string\"}") | |||
| @PostMapping("cancel") | |||
| @@ -171,6 +171,12 @@ public enum ErrorCode{ | |||
| * 游戏 | |||
| */ | |||
| GAME_NOT_FOUND(2070, "游戏未找到"), | |||
| GAME_NOT_COUNT(2071, "该游戏未设置免费次数"), | |||
| GAME_NOT_C_COUNT(2072, "该游戏未设置积分规则"), | |||
| GAME_NOT_WIN_COUNT(2073, "该游戏您已中过奖"), | |||
| GAME_NOT_HAVE_COUNT(2074, "您已没有免费次数"), | |||
| GAME_HAVE_COUNT(2075, "您还有免费次数"), | |||
| GAME_NOT_HAVEC_COUNT(2076, "您已没有积分次数"), | |||
| /** | |||
| * 订单 | |||
| @@ -46,6 +46,10 @@ public class WxGame extends TenantEntity { | |||
| @io.swagger.annotations.ApiModelProperty(value = "限奖次数(0:不受限制,n:限奖次数)", name = "awardLimit") | |||
| private Integer awardLimit; | |||
| @io.swagger.annotations.ApiModelProperty(value = "次数规则0:总次数 1:每天", name = "limitType") | |||
| private Integer limitType; | |||
| @TableField(exist = false) | |||
| @io.swagger.annotations.ApiModelProperty(value = "已投放券信息") | |||
| protected List<Object> couponIdsList; // couponChannel | |||
| @@ -36,5 +36,11 @@ public class WxGameActionLog extends TenantEntity { | |||
| @io.swagger.annotations.ApiModelProperty(value = "", name = "type") | |||
| private Integer type; | |||
| @io.swagger.annotations.ApiModelProperty(value = "", name = "usedCredit") | |||
| private Integer usedCredit; | |||
| @io.swagger.annotations.ApiModelProperty(value = "", name = "usedCredit") | |||
| private Integer addCredit; | |||
| } | |||
| @@ -59,10 +59,7 @@ public interface WxGameService { | |||
| void deleteById(Long id); | |||
| ResultData luckDraw(Long gameId, Long userId); | |||
| ResultData cridetLuckDraw(Long gameIdL, Long memberId); | |||
| } | |||
| @@ -239,4 +239,6 @@ public interface WxOrderService { | |||
| int countUserCouponGroupOrder(Long cuserId,Long couponId,String tenantId); | |||
| ResultData saveOrder(OrderSaveDto orderSaveDto,Long cUserId,EnumPayWay payWay,TenantEntity tenantEntity); | |||
| } | |||
| @@ -8,16 +8,14 @@ import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.dto.OrderSaveDto; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.vo.WxCouponCVo; | |||
| import com.iformall.domain.vo.WxCouponChannelVo; | |||
| import com.iformall.enums.EnumCouponChannelStatus; | |||
| import com.iformall.enums.EnumCouponChannelType; | |||
| import com.iformall.enums.EnumCouponStatus; | |||
| import com.iformall.enums.EnumGameStatus; | |||
| import com.iformall.enums.EnumPayWay; | |||
| import com.iformall.enums.*; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.WxCouponChannelMapper; | |||
| import com.iformall.mapper.WxCouponOrderMapper; | |||
| @@ -38,10 +36,15 @@ import org.springframework.transaction.annotation.Transactional; | |||
| import java.util.*; | |||
| import java.util.concurrent.TimeUnit; | |||
| import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW; | |||
| @Service | |||
| public class WxGameServiceImpl implements WxGameService { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| private WxCreditHistoryService wxCreditHistoryService; | |||
| @Autowired | |||
| WxGameMapper wxGameMapper; | |||
| @@ -66,6 +69,9 @@ public class WxGameServiceImpl implements WxGameService { | |||
| @Autowired | |||
| private QrCodeService qrCodeService; | |||
| @Autowired | |||
| private WxOrderService wxOrderService; | |||
| @Autowired | |||
| @Qualifier("couponDetailRedisTemplate") | |||
| RedisTemplate<String, WxCouponCVo> cdRedisTemplate; | |||
| @@ -149,7 +155,20 @@ public class WxGameServiceImpl implements WxGameService { | |||
| if (wxGame == null) | |||
| return new ResultData(ErrorCode.GAME_NOT_FOUND); | |||
| WxGameActionLog wxGameActionLog = new WxGameActionLog(); | |||
| if(wxGame.getLimitType().equals(1)){//每天 | |||
| Calendar calendar = Calendar.getInstance(); | |||
| calendar.setTime(new Date()); | |||
| calendar.set(Calendar.HOUR_OF_DAY, 0); | |||
| calendar.set(Calendar.MINUTE, 0); | |||
| calendar.set(Calendar.SECOND, 0); | |||
| Date today = calendar.getTime(); | |||
| calendar.add(Calendar.DAY_OF_MONTH,1); | |||
| Date tomorrow =calendar.getTime(); | |||
| wxGameActionLog.setStartTime(today); | |||
| wxGameActionLog.setEndTime(tomorrow); | |||
| } | |||
| wxGameActionLog.updateTenantInfo(wxGame); | |||
| wxGameActionLog.setUserId(userId); | |||
| wxGameActionLog.setGameId(gameId); | |||
| @@ -190,7 +209,6 @@ public class WxGameServiceImpl implements WxGameService { | |||
| } | |||
| map.put("playAble",playAble); | |||
| logger.info(map.toString()); | |||
| return new ResultData(map); | |||
| } | |||
| @@ -217,21 +235,31 @@ public class WxGameServiceImpl implements WxGameService { | |||
| ValueOperations<String, WxCouponCVo> operations = cdRedisTemplate.opsForValue(); | |||
| for(int i=0; i<couponChannelIds.size();i++) { | |||
| JSONObject couponChanObj = (JSONObject) couponChannelIds.get(i); | |||
| Long couponId = couponChanObj.getLong("couponId"); | |||
| WxCouponChannelVo couponChannelVo = wxCouponChannelsMap.get(couponId); | |||
| if (couponChannelVo != null) { | |||
| couponChannelVo.setGameWeight(couponChanObj.getInteger("weight")); | |||
| couponIdsList.add(couponChannelVo); | |||
| String key = "cc:" + couponChannelVo.getId(); | |||
| if (!cdRedisTemplate.hasKey(key)) { | |||
| WxCouponCVo couponCVo = wxCouponChannelService.findVoStatusDetail(couponChannelVo.getId(),couponChannelQ.getTenantId()); | |||
| if(Objects.nonNull(couponCVo)) { | |||
| // 插入缓存 | |||
| operations.set(key, couponCVo, 3600, TimeUnit.SECONDS); | |||
| Integer type = couponChanObj.getInteger("prizeType"); | |||
| if(type != null && type == 0){ | |||
| Map<String,Object> map = new HashMap<>(); | |||
| map.put("prizeType",0); | |||
| map.put("gameWeight",couponChanObj.getInteger("weight")); | |||
| map.put("credit",couponChanObj.getInteger("credit")); | |||
| couponIdsList.add(map); | |||
| }else{ | |||
| Long couponId = couponChanObj.getLong("couponId"); | |||
| WxCouponChannelVo couponChannelVo = wxCouponChannelsMap.get(couponId); | |||
| if (couponChannelVo != null) { | |||
| couponChannelVo.setGameWeight(couponChanObj.getInteger("weight")); | |||
| couponIdsList.add(couponChannelVo); | |||
| String key = "cc:" + couponChannelVo.getId(); | |||
| if (!cdRedisTemplate.hasKey(key)) { | |||
| WxCouponCVo couponCVo = wxCouponChannelService.findVoStatusDetail(couponChannelVo.getId(),couponChannelQ.getTenantId()); | |||
| if(Objects.nonNull(couponCVo)) { | |||
| // 插入缓存 | |||
| operations.set(key, couponCVo, 3600, TimeUnit.SECONDS); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| return couponIdsList; | |||
| @@ -382,4 +410,98 @@ public class WxGameServiceImpl implements WxGameService { | |||
| public void deleteById(Long id) { | |||
| wxGameMapper.deleteById(id); | |||
| } | |||
| @Transactional(rollbackFor = Exception.class) | |||
| @Override | |||
| public ResultData luckDraw(Long gameId,Long userId){ | |||
| ResultData resultData = new ResultData(); | |||
| WxGame wxGame = this.getById(gameId); | |||
| List<Object> couponIdsList = wxGame.getCouponIdsList(); | |||
| int x = (int)(Math.random()*100+1); | |||
| int y = 0; | |||
| if(couponIdsList != null || couponIdsList.size() > 0){ | |||
| for (Object a:couponIdsList) { | |||
| Map map= new org.apache.commons.beanutils.BeanMap(a); | |||
| int weight = (int) map.get("gameWeight"); | |||
| y += weight; | |||
| if(x <= y){ | |||
| resultData.data = a; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| Object data = resultData.data; | |||
| if(data != null){ | |||
| Map dataMap= new org.apache.commons.beanutils.BeanMap(data); | |||
| Integer prizeType = (Integer) dataMap.get("prizeType"); | |||
| if(prizeType != null && prizeType == 0){ | |||
| WxCreditHistory wxCreditHistory = new WxCreditHistory(); | |||
| wxCreditHistory.setTenantId(wxGame.getFinalTenantId()); | |||
| wxCreditHistory.setCUserId(userId); | |||
| wxCreditHistory.setOperatorId(userId); | |||
| wxCreditHistory.setOperatorType(EnumUserType.CUSER.getCode()); | |||
| wxCreditHistory.setCreditNum((Integer) dataMap.get("credit")); | |||
| wxCreditHistory.setCreditType(EnumScoreType.GAME_ADD_CREDIT.getCode()); | |||
| wxCreditHistory.setChangePurpose(EnumScoreType.GAME_ADD_CREDIT.getMessage()); | |||
| wxCreditHistoryService.creditUsercheck(wxCreditHistory.getCUserId(),wxGame) ; | |||
| WxCreditHistory credit = wxCreditHistoryService.saveOrUpdate(wxCreditHistory); | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| WxGameActionLog wxGameActionLog = new WxGameActionLog(); | |||
| wxGameActionLog.setId(idWorker.nextId()); | |||
| wxGameActionLog.setUserId(userId); | |||
| wxGameActionLog.updateTenantInfo(wxGame); | |||
| wxGameActionLog.setGameId(gameId); | |||
| wxGameActionLog.setCreateTime(new Date()); | |||
| wxGameActionLog.setAddCredit(wxCreditHistory.getCreditNum()); | |||
| wxGameActionLogMapper.insert(wxGameActionLog); | |||
| }else{ | |||
| OrderSaveDto orderSaveDto = new OrderSaveDto(); | |||
| orderSaveDto.setCouponChannelId((Long)dataMap.get("id")); | |||
| orderSaveDto.setCouponId((Long)dataMap.get("couponId")); | |||
| ResultData resultData1 = wxOrderService.saveOrder(orderSaveDto, userId, EnumPayWay.PAY_WAY_WECHAT, wxGame); | |||
| if(resultData1.code == Result.SUCCESS && resultData1.data != null){ | |||
| Map map1= new org.apache.commons.beanutils.BeanMap(resultData1.data); | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| WxGameActionLog wxGameActionLog = new WxGameActionLog(); | |||
| wxGameActionLog.setId(idWorker.nextId()); | |||
| wxGameActionLog.setUserId(userId); | |||
| wxGameActionLog.updateTenantInfo(wxGame); | |||
| wxGameActionLog.setGameId(gameId); | |||
| wxGameActionLog.setCreateTime(new Date()); | |||
| wxGameActionLog.setCouponOrderId((Long)map1.get("id")); | |||
| wxGameActionLogMapper.insert(wxGameActionLog); | |||
| }else{ | |||
| return resultData1; | |||
| } | |||
| } | |||
| } | |||
| return resultData; | |||
| } | |||
| @Transactional(propagation = REQUIRES_NEW ,rollbackFor = Exception.class) | |||
| @Override | |||
| public ResultData cridetLuckDraw(Long gameId, Long userId) { | |||
| WxGame wxGame = wxGameMapper.selectById(gameId); | |||
| if(wxGame.getPlayCredit() != null && wxGame.getPlayCredit() > 0){ | |||
| WxCreditHistory wxCreditHistory = new WxCreditHistory(); | |||
| wxCreditHistory.setTenantId(wxGame.getFinalTenantId()); | |||
| wxCreditHistory.setCUserId(userId); | |||
| wxCreditHistory.setOperatorId(userId); | |||
| wxCreditHistory.setOperatorType(EnumUserType.CUSER.getCode()); | |||
| wxCreditHistory.setCreditNum(wxGame.getPlayCredit()); | |||
| wxCreditHistory.setCreditType(EnumScoreType.GAME_LES_CREDIT.getCode()); | |||
| wxCreditHistory.setChangePurpose(EnumScoreType.GAME_LES_CREDIT.getMessage()); | |||
| wxCreditHistoryService.creditUsercheck(wxCreditHistory.getCUserId(),wxGame) ; | |||
| WxCreditHistory credit = wxCreditHistoryService.saveOrUpdate(wxCreditHistory); | |||
| return this.luckDraw(gameId,userId); | |||
| }else{ | |||
| return new ResultData(ErrorCode.GAME_NOT_C_COUNT); | |||
| } | |||
| } | |||
| } | |||
| @@ -16,12 +16,16 @@ import java.util.stream.Collectors; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| import com.iformall.domain.vo.*; | |||
| import com.iformall.enums.*; | |||
| import com.iformall.service.*; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.beans.factory.annotation.Qualifier; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.data.redis.core.ValueOperations; | |||
| import org.springframework.stereotype.Service; | |||
| import org.springframework.transaction.annotation.Propagation; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| @@ -56,43 +60,6 @@ import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.po.WxPayOrder; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.domain.po.msg.FmInsideOrderSuccessMsg; | |||
| import com.iformall.domain.vo.WxCouponSendVo; | |||
| import com.iformall.domain.vo.WxMerchantVo; | |||
| import com.iformall.domain.vo.WxOrderCouponPressVo; | |||
| import com.iformall.domain.vo.WxOrderCouponVo; | |||
| import com.iformall.domain.vo.WxOrderPayExpVo; | |||
| import com.iformall.domain.vo.WxOrderPayVo; | |||
| import com.iformall.domain.vo.WxOrderQueryVo; | |||
| import com.iformall.enums.EnumAssignTagsTrigger; | |||
| import com.iformall.enums.EnumCacheKey; | |||
| import com.iformall.enums.EnumCouponChannelStatus; | |||
| import com.iformall.enums.EnumCouponConditionType; | |||
| import com.iformall.enums.EnumCouponMerchantStatus; | |||
| import com.iformall.enums.EnumCouponOrderStatus; | |||
| import com.iformall.enums.EnumCouponPasswordStatus; | |||
| import com.iformall.enums.EnumCouponPasswordSupport; | |||
| import com.iformall.enums.EnumCouponSendSendType; | |||
| import com.iformall.enums.EnumCouponSendType; | |||
| import com.iformall.enums.EnumCouponStatus; | |||
| import com.iformall.enums.EnumCouponTransfer; | |||
| import com.iformall.enums.EnumCouponType; | |||
| import com.iformall.enums.EnumMerchantStatus; | |||
| import com.iformall.enums.EnumMerchantType; | |||
| import com.iformall.enums.EnumMsgMqKey; | |||
| import com.iformall.enums.EnumMsgMqTag; | |||
| import com.iformall.enums.EnumMsgMqTopic; | |||
| import com.iformall.enums.EnumMsgRecordType; | |||
| import com.iformall.enums.EnumOrderPressType; | |||
| import com.iformall.enums.EnumOrderStatus; | |||
| import com.iformall.enums.EnumOrderType; | |||
| import com.iformall.enums.EnumPayShare; | |||
| import com.iformall.enums.EnumPayStatus; | |||
| import com.iformall.enums.EnumPayType; | |||
| import com.iformall.enums.EnumPayWay; | |||
| import com.iformall.enums.EnumProfitSharingOrderType; | |||
| import com.iformall.enums.EnumScoreType; | |||
| import com.iformall.enums.EnumUserType; | |||
| import com.iformall.enums.EnumValidStatus; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.WxAppinfoMapper; | |||
| import com.iformall.mapper.WxCUserBasicInfoMapper; | |||
| @@ -112,25 +79,13 @@ import com.iformall.mapper.WxOrderPressMapper; | |||
| import com.iformall.mapper.WxPayAccountMapper; | |||
| import com.iformall.mapper.WxPayOrderMapper; | |||
| import com.iformall.mq.MqBaseProducer; | |||
| import com.iformall.service.ExcelService; | |||
| import com.iformall.service.WxAppinfoService; | |||
| import com.iformall.service.WxCUserService; | |||
| import com.iformall.service.WxCUserTagsService; | |||
| import com.iformall.service.WxCouponActionLogService; | |||
| import com.iformall.service.WxCouponSendService; | |||
| import com.iformall.service.WxCouponService; | |||
| import com.iformall.service.WxCreditHistoryService; | |||
| import com.iformall.service.WxMsgLimitService; | |||
| import com.iformall.service.WxOrderService; | |||
| import com.iformall.service.WxPayOrderService; | |||
| import com.iformall.service.WxProfitSharingOrderService; | |||
| import com.iformall.service.WxScoreRulesService; | |||
| import com.iformall.utils.Constant; | |||
| import com.iformall.utils.DateUtils; | |||
| import com.iformall.utils.PayUtils; | |||
| import com.iformall.utils.PressUtils; | |||
| import com.iformall.utils.RedisLock; | |||
| import com.iformall.utils.Utility; | |||
| import org.springframework.web.bind.annotation.RequestBody; | |||
| @Service | |||
| @@ -168,6 +123,9 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| @Autowired | |||
| WxCUserService wxCUserService; | |||
| @Autowired | |||
| WxCUserBasicInfoService wxCUserBasicInfoService; | |||
| @Autowired | |||
| WxPayOrderMapper wxPayOrderMapper; | |||
| @@ -231,6 +189,13 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| @Autowired | |||
| WxCouponService wxCouponService; | |||
| @Autowired | |||
| WxCouponChannelService wxCouponChannelService; | |||
| @Autowired | |||
| @Qualifier("couponDetailRedisTemplate") | |||
| RedisTemplate<String, WxCouponCVo> cdRedisTemplate; | |||
| @Override | |||
| public PageInfo<WxOrder> listAsPage(WxOrder record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxOrderMapper.findList(record)); | |||
| @@ -2426,4 +2391,159 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| return wxOrderMapper.countList(query); | |||
| } | |||
| @Override | |||
| public ResultData saveOrder(OrderSaveDto orderSaveDto,Long cUserId,EnumPayWay payWay,TenantEntity tenantEntity) { | |||
| logger.info("OrderSave: " + orderSaveDto); | |||
| if (orderSaveDto.getCouponChannelId() == null) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId不能为空"); | |||
| } | |||
| WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(orderSaveDto.getCouponChannelId(),tenantEntity.getTenantId()); | |||
| if (wxCouponChannel == null) { | |||
| logger.error("couponChannelId find error, " + orderSaveDto.getCouponChannelId()); | |||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF); | |||
| } | |||
| ResultData resultData = couponChannelCheck(orderSaveDto, wxCouponChannel); | |||
| if (resultData != null) return resultData; | |||
| WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoService.getById(cUserId,tenantEntity.getFinalTenantId()); | |||
| if (wxCUserBasicInfo != null && wxCUserBasicInfo.getStatus().equals(EnumCUserBasicInfoStatus.LOCKED.getCode())) { | |||
| logger.info("会员权益被锁定:cUserId:" + cUserId); | |||
| return new ResultData(ErrorCode.MEMBER_IS_LOCKED); | |||
| } | |||
| WxCoupon coupon = wxCouponService.getById(wxCouponChannel.getCouponId(),wxCouponChannel.getTenantId()); | |||
| if (null == coupon) { | |||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| } | |||
| if (coupon.getStatus().equals(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode())) { | |||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF); | |||
| } | |||
| //判断是否是拼团订单,如果是拼团订单,判断现在进行中的,和已完成的数量是否超出券的限制 | |||
| if (coupon.getType().equals(EnumCouponType.COUPON_GROUP.getCode())) { | |||
| int ordercount = this.countUserCouponGroupOrder(cUserId,coupon.getId(),coupon.getTenantId()); | |||
| if (ordercount>=coupon.getUseLimitQuantity()) { | |||
| return new ResultData(ErrorCode.COUPON_IS_TAKE_OFF.getCode(),"您当前此券的有效拼团数量达到券的限购次数。"); | |||
| } | |||
| } | |||
| WxCouponCVo wxCouponCVo = null; | |||
| String key = "cc:" + orderSaveDto.getCouponChannelId(); | |||
| ValueOperations<String, WxCouponCVo> operations = cdRedisTemplate.opsForValue(); | |||
| // 缓存 | |||
| boolean hasKey = cdRedisTemplate.hasKey(key); | |||
| if (hasKey) { | |||
| // 从缓存获取用户信息 | |||
| wxCouponCVo = operations.get(key); | |||
| } else { | |||
| // 游戏没有入缓存,需要从数据库中读取 | |||
| wxCouponCVo = wxCouponChannelService.findDetailVo(orderSaveDto.getCouponChannelId(),wxCouponChannel.getTenantId()); | |||
| if (wxCouponCVo != null) { | |||
| // 游戏优化,进缓存 | |||
| cdRedisTemplate.opsForValue().set(key, wxCouponCVo, 3600, TimeUnit.SECONDS); | |||
| } | |||
| } | |||
| if (wxCouponCVo == null) { | |||
| return new ResultData(ErrorCode.COUPON_IS_EMPTY); | |||
| } | |||
| //此处判断是否存在绝对保证库存不超卖的缓存,如果没有,则把当前的库存设置为最大值。如果有,则是后台设置的时候保存的,以那个为准。 | |||
| 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); | |||
| } | |||
| } | |||
| resultData = couponUserCheck(wxCUserBasicInfo, wxCouponCVo); | |||
| if (resultData != null) return resultData; | |||
| Long couponId = orderSaveDto.getCouponId() == null ? wxCouponChannel.getCouponId() : orderSaveDto.getCouponId(); | |||
| if (couponId == null) { | |||
| logger.error("couponChannelId或者couponId不能为空"); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId或者couponId不能为空"); | |||
| } | |||
| // 是否砍价 | |||
| boolean isPress = orderSaveDto.getPress() != null ? orderSaveDto.getPress() : false; | |||
| try { | |||
| WxOrder order = this.saveOrderForCoupon(wxCUserBasicInfo, coupon, orderSaveDto, isPress,payWay); | |||
| return new ResultData(order); | |||
| } catch (MallinkException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(ErrorCode.ORDER_IS_FAIL, e.getMessage()); | |||
| } | |||
| } | |||
| private ResultData couponChannelCheck(OrderSaveDto orderSaveDto, WxCouponChannel wxCouponChannel) { | |||
| if (wxCouponChannel.getTargetAd().equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())) { | |||
| Date now = new Date(); | |||
| if (wxCouponChannel.getBeginTime().getTime() > now.getTime()) { | |||
| logger.error("此券活动未开始:" + orderSaveDto.getCouponChannelId()); | |||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_NOT_STARTED); | |||
| } | |||
| if (wxCouponChannel.getEndTime().getTime() < now.getTime()) { | |||
| logger.error("此券活动已结束:" + orderSaveDto.getCouponChannelId()); | |||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_END); | |||
| } | |||
| } | |||
| if (wxCouponChannel.getStatus() == EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode()) { | |||
| logger.error("此券已下架:" + orderSaveDto.getCouponChannelId()); | |||
| return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF); | |||
| } | |||
| return null; | |||
| } | |||
| private ResultData couponUserCheck(WxCUserBasicInfo user, WxCouponCVo coupon) { | |||
| if (coupon.getConditions() == null) return null; | |||
| JSONObject jo = null; | |||
| try { | |||
| jo = JSONObject.parseObject(coupon.getConditions()); | |||
| } catch (Exception e) { | |||
| logger.error("购买券条件判断错误:ID=" + coupon.getId() + e.getMessage()); | |||
| } | |||
| if (jo != null) { | |||
| if (jo.getIntValue("type") == EnumCouponConditionType.NEW_MEMBER.getCode()){ | |||
| if (user != null && user.getActRecord() > 0) | |||
| return new ResultData(ErrorCode.COUPON_ONLY_FOR_NEW_MEMBER); | |||
| if (this.countCouponConditionType1(coupon.getTenantId(),user.getId()) > 0) | |||
| return new ResultData(ErrorCode.COUPON_ALREADY_IN_NEW_MEMBER); | |||
| }else if (jo.getIntValue("type") == EnumCouponConditionType.SCORE_SCOPE.getCode()){ | |||
| int max = jo.getIntValue("max"); | |||
| int min = jo.getIntValue("min"); | |||
| if (max!=0 && min ==0 && user.getPoins() > max) { | |||
| return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| } | |||
| if (max==0 && min !=0 && user.getPoins() < min) { | |||
| return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| } | |||
| if (max!=0 && min !=0 && (user.getPoins() < min || user.getPoins() > max)) { | |||
| return new ResultData(ErrorCode.COUPON_SCORE_NOT_IN_RANGE); | |||
| } | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| @@ -11,10 +11,12 @@ | |||
| <result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> | |||
| <result column="type" jdbcType="INTEGER" property="type" /> | |||
| <result column="used_credit" jdbcType="INTEGER" property="usedCredit" /> | |||
| <result column="add_credit" jdbcType="INTEGER" property="addCredit" /> | |||
| </resultMap> | |||
| <sql id="allColumns"> | |||
| `id`,`tenant_id`,`parent_tenant_id`,`coupon_id`,`coupon_order_id`,`channel_type`,`channel_id`,`create_time`,`type` | |||
| `id`,`tenant_id`,`parent_tenant_id`,`coupon_id`,`coupon_order_id`,`channel_type`,`channel_id`,`create_time`,`type`,`used_credit`,`add_credit` | |||
| </sql> | |||
| <sql id="dynamicWhereConditions"> | |||
| @@ -114,18 +116,13 @@ | |||
| </if> | |||
| <if test=" null != createTime "> | |||
| and `create_time` = #{createTime} | |||
| </if> | |||
| <if test=" null != startTime "> | |||
| and `start_time` >= #{startTime} | |||
| and `create_time` >= #{startTime} | |||
| </if> | |||
| <if test=" null != endTime "> | |||
| and `end_time` <= #{endTime} | |||
| and `create_time` <= #{endTime} | |||
| </if> | |||
| <if test=" null != type "> | |||
| @@ -151,7 +148,7 @@ | |||
| <select id="getAwardCount" resultType="java.lang.Integer" parameterType="com.iformall.domain.po.WxGameActionLog"> | |||
| select COUNT(*) FROM wx_game_action_log a | |||
| <include refid="dynamicCountWhereConditions" /> | |||
| and coupon_order_id != 0 | |||
| and coupon_order_id != 0 and add_credit != 0 | |||
| </select> | |||
| </mapper> | |||
| @@ -16,10 +16,11 @@ | |||
| <result column="play_credit_limit" jdbcType="INTEGER" property="playCreditLimit" /> | |||
| <result column="play_credit" jdbcType="INTEGER" property="playCredit" /> | |||
| <result column="limit_type" jdbcType="INTEGER" property="limitType" /> | |||
| </resultMap> | |||
| <sql id="allColumns"> | |||
| `id`,`tenant_id`,`parent_tenant_id`,`game_id`,`status`,`coupon_ids`,`valid_start_date`,`valid_end_date`,`triggle_action`,`play_limit`,`award_limit`,`play_credit_limit`,`play_credit` | |||
| `id`,`tenant_id`,`parent_tenant_id`,`game_id`,`status`,`coupon_ids`,`valid_start_date`,`valid_end_date`,`triggle_action`,`play_limit`,`award_limit`,`play_credit_limit`,`play_credit`,`limit_type` | |||
| </sql> | |||
| <sql id="dynamicWhereConditions"> | |||