package com.cyksj.service.exchange.impl; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.cyksj.common.annotation.NoSubmit; import com.cyksj.common.constant.Constant; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.snowflake.Sequence; import com.cyksj.common.task.GlobalThreadPoolTaskExecutor; import com.cyksj.common.util.Jsons; import com.cyksj.common.util.StringUtil; import com.cyksj.dto.RedisKey; import com.cyksj.dto.Result; import com.cyksj.enums.GatewayResponse; import com.cyksj.mapper.*; import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper; import com.cyksj.mapper.manage.exchange.ExchangeCodeMapper; import com.cyksj.mapper.market.draw.LuckyDrawRecordMapper; import com.cyksj.model.entity.*; import com.cyksj.model.excel.ExcelExchangeCodeData; import com.cyksj.model.manage.views.GroupsRelationView; import com.cyksj.model.request.ExchangeCodeReq; import com.cyksj.model.request.ExchangeCodeTicket; import com.cyksj.redis.RedisService; import com.cyksj.service.claude.ClaudeCodeService; import com.cyksj.service.codex.CodexService; import com.cyksj.service.exchange.ExchangeCodeService; import com.cyksj.service.relation.GroupRelationFrontService; import com.cyksj.service.relation.GroupsRelationExpiryRecordService; import com.cyksj.service.shop.YhShopFrontService; import com.cyksj.service.user.UserBindRelationService; import com.ejlchina.searcher.BeanSearcher; import com.ejlchina.searcher.param.Operator; import com.ejlchina.searcher.util.MapUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; /* *项目名: netflix *文件名: ExchangeCodeServiceImpl *创建者: JavaZou *创建时间:2022/11/7 15:41 */ @Service @RequiredArgsConstructor @Slf4j public class ExchangeCodeServiceImpl extends ServiceImpl implements ExchangeCodeService { private final GoodsDonMapper goodsDonMapper; private final GoodsDonSkuMapper goodsDonSkuMapper; private final ExchangeCodeMapper exchangeCodeMapper; private final GroupsRelationMapper groupsRelationMapper; private final GroupsMapper groupsMapper; private final RedisService redisService; private static final Sequence SEQUENCE = new Sequence(0); private final UserMapper userMapper; private final OrderDonMapper orderDonMapper; private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance(); private final LuckyDrawRecordMapper luckyDrawRecordMapper; private final BeanSearcher beanSearcher; private final GroupRelationFrontService groupRelationFrontService; private final OrderDiscountPlusPurchaseSkuRelationMapper orderDiscountPlusPurchaseSkuRelationMapper; private final GroupsRelationExpiryRecordService groupsRelationExpiryRecordService; private final YhShopFrontService yhShopFrontService; private final UserDistributeSharedMapper userDistributeSharedMapper; private final UserDistributeExchangeCodeMapper userDistributeExchangeCodeMapper; private final UserDistributeExchangeCodeUseRecordMapper userDistributeExchangeCodeUseRecordMapper; private final UserBindRelationService userBindRelationService; private final ClaudeCodeService claudeCodeService; private final CodexService codexService; @Override @Transactional(rollbackFor = Throwable.class) public List createExchangeCode(ExchangeCodeReq exchangeCodeReq) throws Exception { String skuIds = exchangeCodeReq.getSkuIds(); if (StrUtil.isEmpty(skuIds)) { throw BusinessRuntimeException.getInstance("请选择对应规格"); } List skuList = Jsons.parseList(skuIds, Long.class); Integer skuCount = goodsDonSkuMapper.selectCount(Wrappers.lambdaQuery(GoodsDonSku.class) .in(GoodsDonSku::getId, skuList)); if (skuCount != skuList.size()) { throw BusinessRuntimeException.getInstance("所选规格已被删除"); } String goodsIds = goodsDonSkuMapper.selectGIdsBySkuIds(skuList).toString(); List data = new ArrayList<>(exchangeCodeReq.getNumber()); GoodsDonSku sku = goodsDonSkuMapper.selectById(skuList.get(0)); for (int i = 0; i < exchangeCodeReq.getNumber(); i++) { StringBuilder sb = new StringBuilder(32); sb.append("YH"); sb.append(getFillByGoodsId(sku.getGoodsId())); sb.append(getFillByMonth(sku.getMonths())); //随即补充12位随即数,组成20位兑换码 StringUtil.getRandomStr(sb, 12); ExchangeCode exchangeCode = new ExchangeCode(); exchangeCode.setSkuIds(exchangeCodeReq.getSkuIds()); exchangeCode.setGoodsIds(goodsIds); exchangeCode.setCode(sb.toString()); exchangeCode.setUseStatus(false); exchangeCode.setType(exchangeCodeReq.getType()); exchangeCode.setOperator(exchangeCodeReq.getOperator()); exchangeCode.setCodeType(exchangeCodeReq.getCodeType()); exchangeCodeMapper.insert(exchangeCode); ExcelExchangeCodeData excelExchangeCodeData = new ExcelExchangeCodeData(); BeanUtils.copyProperties(exchangeCode, excelExchangeCodeData); String title = goodsDonSkuMapper.selectExchangeTitle(skuList); excelExchangeCodeData.setTitle(title); excelExchangeCodeData.setUseStatusStr(exchangeCode.getUseStatus() ? "已使用" : "未使用"); data.add(excelExchangeCodeData); } return data; } @Override @Transactional(rollbackFor = Throwable.class) @NoSubmit public Result getTicketByExchangeCode(ExchangeCodeTicket exchangeCodeTicket, Long userId) throws Exception { if (StrUtil.isEmpty(exchangeCodeTicket.getCode())) { throw BusinessRuntimeException.getInstance("兑换码有误,请使用正确的兑换码"); } //是渠道兑换码 String code = exchangeCodeTicket.getCode(); UserDistributeExchangeCode userDistributeExchangeCode = userDistributeExchangeCodeMapper.selectOne(Wrappers.lambdaQuery(UserDistributeExchangeCode.class) .eq(UserDistributeExchangeCode::getCode, code) .last("limit 1")); if (userDistributeExchangeCode != null) { //是否是该渠道下的用户 Integer bindCount = userDistributeSharedMapper.selectCount(Wrappers.lambdaQuery(UserDistributeShared.class) .eq(UserDistributeShared::getSharedId, userDistributeExchangeCode.getUserId()) .eq(UserDistributeShared::getUserId, userId)); if (bindCount == 0) { throw BusinessRuntimeException.getInstance("您不是该渠道下的分销用户"); } //是否已经兑换过 Integer useCount = userDistributeExchangeCodeUseRecordMapper.selectCount(Wrappers.lambdaQuery(UserDistributeExchangeCodeUseRecord.class) .eq(UserDistributeExchangeCodeUseRecord::getUserId, userId) .eq(UserDistributeExchangeCodeUseRecord::getCode, code)); if (useCount > 0) { throw BusinessRuntimeException.getInstance("您已使用该兑换码"); } try { UserDistributeExchangeCodeUseRecord userDistributeExchangeCodeUseRecord = new UserDistributeExchangeCodeUseRecord(); userDistributeExchangeCodeUseRecord.setUserId(userId); userDistributeExchangeCodeUseRecord.setCode(code); userDistributeExchangeCodeUseRecordMapper.insert(userDistributeExchangeCodeUseRecord); log.info("用户userId:{}兑换渠道兑换码:{}", userId, code); GoodsDonSku sku = goodsDonSkuMapper.selectById(userDistributeExchangeCode.getSkuId()); GroupsRelation relation = getRelationNoOrder(sku, userId, 0l); //重新设置时间 DateField dateField = DateField.MONTH; if (Constant.DAY_DATE.equals(userDistributeExchangeCode.getTimeType())) { dateField = DateField.DAY_OF_YEAR; } else if (Constant.HOUR_DAY_OF_DATE.equals(userDistributeExchangeCode.getTimeType())) { dateField = DateField.HOUR_OF_DAY; } relation.setAqType(2); relation.setExpiryTime(DateUtil.offset(relation.getStartTime(), dateField, userDistributeExchangeCode.getTime())); groupsRelationMapper.updateById(relation); userDistributeExchangeCodeUseRecord.setRelationId(relation.getId()); userDistributeExchangeCodeUseRecordMapper.updateById(userDistributeExchangeCodeUseRecord); } catch (DuplicateKeyException e) { throw BusinessRuntimeException.getInstance("您已使用该兑换码"); } return GatewayResponse.SUCCESS.newBuilder().toResult(); } ExchangeCode exchangeCode = this.getOne(Wrappers.lambdaQuery(ExchangeCode.class).eq(ExchangeCode::getCode, exchangeCodeTicket.getCode()).last("limit 1")); if (exchangeCode == null) { throw BusinessRuntimeException.getInstance("兑换码有误,请使用正确的兑换码"); } if (exchangeCode.getUseStatus()) { throw BusinessRuntimeException.getInstance("该兑换码已使用"); } //店铺中 进行兑换码 兑换 标记订单 座位 String customId = exchangeCodeTicket.getCustomId(); Long yhsId = yhShopFrontService.checkShopCustomIdAndReturnShopId(customId); //兑换成功 exchangeCode.setUseStatus(true); exchangeCode.setUserId(userId); exchangeCode.setUseTime(DateTime.now()); int update = exchangeCodeMapper.update(exchangeCode, Wrappers.lambdaQuery(ExchangeCode.class).eq(ExchangeCode::getId, exchangeCode.getId()).eq(ExchangeCode::getUseStatus, false)); if (update != 1) { throw BusinessRuntimeException.getInstance("该兑换码已使用"); } //是否是推广用户未登录订单关联的兑换码 OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class) .eq(OrderDon::getIsNoLogin, true) .eq(OrderDon::getExCode, exchangeCode.getCode()) .notIn(OrderDon::getStatus, Constant.noOrderStatus) .last("limit 1")); // Long popularizeId = orderDon.getPopularizeId(); // // //360 渠道兑换规则验证. // if(popularizeId != null && popularizeId != 0){ // String channel = channelPopularizeMapper.selectChannelByPid(popularizeId); // if (Constant.CHANNEL_NAME_360.equals(channel)) { // //查询该用户之前是否存在订单. // Integer count = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class) // .eq(OrderDon::getUserId, userId) // .notIn(OrderDon::getStatus, Constant.noOrderStatus)); // if (count > 0) { // throw new BusinessRuntimeException("您不符合360活动条件."); // } // } // } if (orderDon != null && orderDon.getStatus() == OrderDon.Status.refund) { throw BusinessRuntimeException.getInstance("您的订单已退款,无法使用该兑换码"); } List skuIds = Jsons.parseList(exchangeCode.getSkuIds(), Long.class); skuIds.forEach(skuId -> { getGroupTripsTicket(yhsId, goodsDonSkuMapper.selectById(skuId), userId, orderDon, OrderDon.Type.EX_CODE, exchangeCodeTicket.getCode()); }); //生成车票订单 log.info("用户:{}通过兑换码:{}兑换成功", userId, exchangeCodeTicket.getCode()); if (exchangeCode.getType() == 1) { luckyDrawRecordMapper.updateExCodeStatus(userId, exchangeCode.getCode()); } return GatewayResponse.SUCCESS.newBuilder().toResult("兑换成功"); } @Override public String getExCode(Long goodsId, Long skuId, Integer type) { ExchangeCodeReq exchangeCodeReq = new ExchangeCodeReq(); exchangeCodeReq.setNumber(1); // exchangeCodeReq.setGoodsId(goodsId); exchangeCodeReq.setSkuIds(List.of(skuId).toString()); //兑换码 exchangeCodeReq.setCodeType(1); if (type != null) { exchangeCodeReq.setType(type); } try { List exchangeCodes = this.createExchangeCode(exchangeCodeReq); return exchangeCodes.get(0).getCode(); } catch (Exception e) { return null; } } /** * 根据平台id获取填充的字符串 */ private String getFillByGoodsId(Long goodsId) { String goodsIdStr = String.valueOf(goodsId); if (goodsIdStr.length() == 1) { return String.format("%s%s%s", 0, 0, goodsId); } if (goodsIdStr.length() == 2) { return String.format("%s%s", 0, goodsId); } //最大不超过999 if (goodsIdStr.length() > 3) { return goodsIdStr.substring(0, 3); } return goodsIdStr; } /** * 根据月份长度获取填充的字符串 */ private String getFillByMonth(Integer skuMonth) { String goodsIdStr = String.valueOf(skuMonth); if (goodsIdStr.length() == 1) { return String.format("%s%s%s", 0, 0, skuMonth); } return String.format("%s%s", 0, skuMonth); } /** * 获取车位 */ @Override public GroupsRelation getGroupTripsTicket(Long yhsId, GoodsDonSku sku, Long userId, OrderDon exCodeOrderDon, OrderDon.Type orderDonTye, String exCode) { if (sku == null) { throw BusinessRuntimeException.getInstance("规格不存在,请联系客服"); } GoodsDon goodsDon = goodsDonMapper.selectById(sku.getGoodsId()); if (goodsDon == null) { throw BusinessRuntimeException.getInstance("平台不存在,请联系客服"); } User user = userMapper.selectById(userId); if (user == null) { throw BusinessRuntimeException.getInstance("用户不存在"); } GroupsRelation relation = getRelationNoOrder(sku, userId, yhsId); Long relationId = relation.getId(); OrderDon orderDon; if (exCodeOrderDon != null) { orderDon = exCodeOrderDon; orderDon.setRelationId(relationId); orderDon.setUserId(userId); orderDon.setStatus(goodsDon.getType() == 1 && goodsDon.getSecondType() == 2 ? OrderDon.Status.complete : OrderDon.Status.hasPayment); orderDon.setYhsId(yhsId); orderDonMapper.updateById(orderDon); if (orderDon.getIsDp()) { //是否已经发送优惠加购车票 OrderDiscountPlusPurchaseSkuRelation purchaseSkuRelation = orderDiscountPlusPurchaseSkuRelationMapper.selectOne(Wrappers.lambdaQuery(OrderDiscountPlusPurchaseSkuRelation.class) .eq(OrderDiscountPlusPurchaseSkuRelation::getOrderId, orderDon.getId())); if (purchaseSkuRelation != null) { String plusSkuIdsStr = purchaseSkuRelation.getPlusSkuIds(); String relationIdsStr = purchaseSkuRelation.getRelationIds(); if (StrUtil.isNotEmpty(plusSkuIdsStr) && StrUtil.isEmpty(relationIdsStr)) { try { List plusSkuIds = Jsons.parseList(plusSkuIdsStr, Long.class); //发送优惠加购 规格车票 List dis_relation_ids = new ArrayList<>(); plusSkuIds.forEach(plus_skuId -> { GoodsDonSku plus_sku = goodsDonSkuMapper.selectById(plus_skuId); if (plus_sku == null) { log.error("订单id:{}优惠加购规格已被删除 skuId:{},车票未发送", orderDon.getId(), plus_skuId); return; } GroupsRelation relationNoOrder = getRelationNoOrder(plus_sku, orderDon.getUserId(), orderDon.getYhsId()); dis_relation_ids.add(relationNoOrder.getId()); }); //保存订单关联优惠加购车票 orderDiscountPlusPurchaseSkuRelationMapper.update(null, Wrappers.lambdaUpdate(OrderDiscountPlusPurchaseSkuRelation.class) .set(OrderDiscountPlusPurchaseSkuRelation::getRelationIds, dis_relation_ids.toString()) .eq(OrderDiscountPlusPurchaseSkuRelation::getOrderId, orderDon.getId()) .isNull(OrderDiscountPlusPurchaseSkuRelation::getRelationIds)); } catch (Exception e) { } } } } } else { /* 生成订单 */ String donNo = SEQUENCE.nextId().toString(); orderDon = new OrderDon(); orderDon.setOrderNo(donNo); orderDon.setOpenId(user.getOpenId()); orderDon.setMoney(BigDecimal.ZERO); orderDon.setSkuId(sku.getId()); orderDon.setRelationId(relationId); orderDon.setYhsId(yhsId); //默认数量为1 orderDon.setNum(1); orderDon.setGoodsId(sku.getGoodsId()); orderDon.setExCode(exCode); orderDon.setStatus(goodsDon.getType() == 1 && goodsDon.getSecondType() == 2 ? OrderDon.Status.complete : OrderDon.Status.hasPayment); if (relation.getStartTime() == null || relation.getExpiryTime() == null) { orderDon.setStatus(OrderDon.Status.hasPayment); } if (relation != null && relation.getStatus() == GroupsRelation.Status.outside) { orderDon.setIsOt(true); } //兑换码兑换 orderDon.setType(orderDonTye); orderDon.setUserId(user.getId()); StringBuilder payTitle = new StringBuilder(); payTitle.append(goodsDon.getTitle()); payTitle.append(sku.getSpecVal()); orderDon.setPayTitle(payTitle.toString()); orderDonMapper.insert(orderDon); log.info("用户{}兑换规格:{}车位成功", user.getId(), orderDon.getSkuId()); if (relation.getIsRenew() != null && relation.getIsRenew()) { //claude code/codex续费 orderDon.setOrderType(2); orderDonMapper.updateById(orderDon); //claude code续费且升级 if (relation.getIsClaudeCodeUpgrade() != null && relation.getIsClaudeCodeUpgrade()) { claudeCodeService.handleClaudeCodeUserPackageSku(relation, sku, orderDon.getId()); } //codex 续费且升级 if (relation.getIsCodexUpgrade() != null && relation.getIsCodexUpgrade()) { codexService.handleClaudeCodeUserPackageSku(relation, sku, orderDon.getId()); } } } if (orderDonTye == OrderDon.Type.EX_CODE) { //同步车票是否重购 记录 TASK_POOL.execute(() -> { groupsRelationExpiryRecordService.syncGroupsRelationExpiryRecord(orderDon, goodsDon, sku); }); } relation.setOrderId(orderDon.getId()); //邀请制代充平台 if ((goodsDon.getSpecialType() != null && goodsDon.getSpecialType() == GoodsDon.SpecialType.recharge) || Constant.RECHARGE_INVITE_GOODS_IDS.contains(goodsDon.getId())) { relation.setStartTime(null); relation.setExpiryTime(null); relation.setRechargeStatus(GroupsRelation.RechargeStatus.waiting); relation.setSubmitTime(DateTime.now()); //GPT代充 if (goodsDon.getId() == Constant.GPT_RECHARGE_GOODS_ID) { //代充次数 relation.setRechargeNum(sku.getMonths()); relation.setRechargeRemainNum(relation.getRechargeNum()); } groupsRelationMapper.updateById(relation); } return relation; } @Override public GroupsRelation getRelationNoOrder(GoodsDonSku sku, Long userId, Long yhsId) { //claude code商品兑换 if (sku.getGoodsId() == Constant.CLAUDE_CODE_GOODS_ID) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getGoodsId, Constant.CLAUDE_CODE_GOODS_ID).field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan).build()); if (groupsRelationView != null) { GoodsDonSku relationSku = goodsDonSkuMapper.selectById(groupsRelationView.getSkuId()); //兑换的规格 低于当前规格 不让兑换 if (relationSku.getClaudeDailyLimit() > sku.getClaudeDailyLimit()) { throw BusinessRuntimeException.getInstance("请在claude code当前版本过期后再兑换"); } Date expiryTime = groupsRelationView.getExpiryTime(); if (sku.getDays() != null) { expiryTime = DateUtil.offsetDay(expiryTime, sku.getDays()); } else { expiryTime = DateUtil.offsetMonth(expiryTime, sku.getMonths()); } GroupsRelation relation = groupsRelationMapper.selectById(groupsRelationView.getId()); relation.setExpiryTime(expiryTime); groupsRelationMapper.updateById(relation); //同规格只加时长 relation.setIsRenew(Boolean.TRUE); if (relationSku.getClaudeDailyLimit() != sku.getClaudeDailyLimit()) { relation.setIsClaudeCodeUpgrade(true); } return relation; } } //codex 商品兑换 if (sku.getGoodsId() == Constant.CODEX_GOODS_ID) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getGoodsId, Constant.CODEX_GOODS_ID).field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan).build()); if (groupsRelationView != null) { GoodsDonSku relationSku = goodsDonSkuMapper.selectById(groupsRelationView.getSkuId()); //兑换的规格 低于当前规格 不让兑换 if (relationSku.getOpenaiDailyLimit() > sku.getOpenaiDailyLimit()) { throw BusinessRuntimeException.getInstance("请在codex当前版本过期后再兑换"); } Date expiryTime = groupsRelationView.getExpiryTime(); if (sku.getDays() != null) { expiryTime = DateUtil.offsetDay(expiryTime, sku.getDays()); } else { expiryTime = DateUtil.offsetMonth(expiryTime, sku.getMonths()); } GroupsRelation relation = groupsRelationMapper.selectById(groupsRelationView.getId()); relation.setExpiryTime(expiryTime); groupsRelationMapper.updateById(relation); //同规格只加时长 relation.setIsRenew(Boolean.TRUE); if (relationSku.getOpenaiDailyLimit() != sku.getOpenaiDailyLimit()) { relation.setIsCodexUpgrade(true); } return relation; } } Integer retryNum = 1; List errorsRelationIds = new ArrayList<>(); GroupsRelation relation = getFinalRelation(sku, userId, retryNum, yhsId, errorsRelationIds); return relation; } public GroupsRelation getFinalRelation(GoodsDonSku sku, Long userId, Integer retryNum, Long yhsId, List errorsRelationIds) { //获取车票车位 GroupsRelation relation = groupRelationFrontService.getRelation(null, userId, sku, null); try { //锁定座位 setRelation(relation); relation.setUserId(userId); GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId()); if (GroupsTrips.Status.validity.equals(groupsTrips.getStatus())) { //如果续费增加时间,如果首次则设置当前时间为初始时间 Date expiryTime = Optional.ofNullable(relation.getExpiryTime()).orElse(new Date()); Date newDate; if (sku.getDays() != null && sku.getDays() > 0) { newDate = DateUtil.offsetDay(expiryTime, sku.getDays() * 1); } else { //奈飞月付 按30天计算 if (sku.getId() == 4) { newDate = DateUtil.offsetDay(expiryTime, 30); } else { newDate = DateUtil.offset(expiryTime, DateField.MONTH, sku.getMonths() * 1); } } relation.setExpiryTime(newDate); relation.setStartTime(relation.getStartTime() == null ? new Date() : null); } if (relation.getStatus() != GroupsRelation.Status.outside) { relation.setStatus(GroupsRelation.Status.validity); } relation.setYhsId(yhsId); if (yhsId != null && yhsId != 0) { relation.setCmt(1); } groupsRelationMapper.updateById(relation); Long skuId = sku.getId(); Long groupsId = relation.getGroupsId(); //校验指定平台规格的 目前车队的可停车位数 groupRelationFrontService.checkGroupsAvailParkingNum(skuId, groupsId, relation.getGroupsAvailParkingNum(), relation.getMaxNum()); groupRelationFrontService.adjustGroupsParkingTime(relation.getId(), sku); } catch (Exception e) { //删除座位缓存 delRelationKey(relation.getId(), userId); errorsRelationIds.add(relation.getId()); if (retryNum == 15) { log.error("用户:{}获取车票:{}异常", userId, relation.getId()); throw BusinessRuntimeException.getInstance("获取车票异常,请联系客服"); } //失败重新给他分配车位 return getFinalRelation(sku, userId, ++retryNum, yhsId, errorsRelationIds); } return relation; } public void setRelation(GroupsRelation relation) { Long relationId = relation.getId(); Long userId = relation.getUserId(); Long groupsId = relation.getGroupsId(); GroupsRelation.Status status = relation.getStatus(); String relation_num_key = RedisKey.GROUPS_RELATION_NUM_KEY + relationId; if (!redisService.setNx(relation_num_key, userId, 60 * 5L)) { GroupsRelation dbRelation = groupsRelationMapper.selectById(relationId); if (dbRelation.getUserId() != 0) { log.info("=====>用户:{}未抢到座位:{}", userId, relationId); throw new BusinessRuntimeException("系统繁忙,请重试..."); } } if (status == GroupsRelation.Status.outside) { return; } int count = groupsMapper.decrAvailableNum(groupsId); if (count == 0) { log.error("车位异常 groupId:{}", groupsId); groupsMapper.updateAvailableNum(groupsId); //删除座位缓存 delRelationKey(relationId, userId); throw new BusinessRuntimeException("车位异常"); } } /** * 清除座位缓存key */ public void delRelationKey(Long relationId, Long userId) { String relation_num_key = RedisKey.GROUPS_RELATION_NUM_KEY + relationId; Object object = redisService.get(relation_num_key); if (object != null) { try { Long keyUserId = Long.parseLong(object.toString()); //清除车票key if (ObjectUtil.equal(userId, keyUserId)) { redisService.del(relation_num_key); } } catch (Exception e) { log.error("删除缓存key错误:{}", StringUtil.getErrorText(e)); } } } }