package com.cyksj.service.relation.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.BetweenFormater; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Validator; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.cyksj.common.constant.Constant; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.task.GlobalThreadPoolTaskExecutor; import com.cyksj.common.util.Jsons; import com.cyksj.common.util.StringUtil; import com.cyksj.enums.GatewayApiCode; import com.cyksj.mapper.*; import com.cyksj.mapper.manage.distribute.DistributeGeneralSkuRateMapper; import com.cyksj.mapper.manage.distribute.UserDistributeMapper; import com.cyksj.mapper.manage.distribute.UserPlatDistributeRateMapper; import com.cyksj.mapper.manage.distribute.UserPlatSkuDistributeRateMapper; import com.cyksj.mapper.mirrorshop.UserMirrorShopMapper; import com.cyksj.mapper.renew.RenewUpgradePackageMapper; import com.cyksj.mapper.sys.SysConfigMapper; import com.cyksj.mapper.sys.SysEmailMapper; import com.cyksj.mapper.vip.VipGoodsSkuMapper; import com.cyksj.mapper.vip.VipUserMapper; import com.cyksj.model.entity.*; import com.cyksj.model.manage.views.AccountView; import com.cyksj.model.manage.views.GroupsRelationView; import com.cyksj.model.request.SpecialGoodsTicketReq; import com.cyksj.model.request.TicketLoginReq; import com.cyksj.model.views.*; import com.cyksj.redis.RedisService; import com.cyksj.service.chatgpt.ChatGptAccountService; import com.cyksj.service.chatgpt.ChatGptAuthService; import com.cyksj.service.claude.ClaudeService; import com.cyksj.service.groups.GroupsFuncService; import com.cyksj.service.luma.LumaService; import com.cyksj.service.mail.CommonMailService; import com.cyksj.service.mail.MailService; import com.cyksj.service.mange.coupon.CouponCommonService; import com.cyksj.service.midjourney.MidjourneyAccountService; import com.cyksj.service.relation.GroupRelationFrontService; import com.cyksj.service.relation.GroupsRelationChangeService; import com.cyksj.service.relation.GroupsRelationNetflixService; import com.cyksj.service.user.UserBindRelationService; import com.cyksj.service.user.UserLoginRecordService; import com.ejlchina.searcher.BeanSearcher; import com.ejlchina.searcher.SearchResult; import com.ejlchina.searcher.param.Operator; import com.ejlchina.searcher.util.MapBuilder; import com.ejlchina.searcher.util.MapUtils; import com.github.rholder.retry.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_ALREADY_BE_USER; import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_NOT_FIND; /* *项目名: netflix *文件名: GroupRelationFrontServiceImpl *创建者: JavaZou *创建时间:2022/12/29 15:42 */ @Service @RequiredArgsConstructor @Slf4j public class GroupRelationFrontServiceImpl implements GroupRelationFrontService { private final UserBindRelationService userBindRelationService; private final UserMapper userMapper; private final BeanSearcher beanSearcher; private final CouponCommonService couponCommonService; private final GroupsRelationMapper groupsRelationMapper; private final GroupsMapper groupsMapper; private final ChatGptAuthService chatGptAuthService; private final RedisService redisService; private final MailService mailService; private final OrderDonMapper orderDonMapper; private final GroupsRelationExpiryNotifyRecordMapper groupsRelationExpiryNotifyRecordMapper; private final HttpServletRequest request; private final GroupsFuncService groupsFuncService; private final OrderDiscountPlusPurchaseSkuRelationMapper orderDiscountPlusPurchaseSkuRelationMapper; private final GroupsRelationLoginCodeRecordMapper groupsRelationLoginCodeRecordMapper; private final SysEmailMapper sysEmailMapper; private final GoodsDonSkuMapper goodsDonSkuMapper; private final UserFuncPropertyMapper userFuncPropertyMapper; private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance(); private final UserLoginRecordService userLoginRecordService; private final UserCertRecordMapper userCertRecordMapper; private final MidjourneyAccountService midjourneyAccountService; private final ChatGptAccountService chatGptAccountService; private final UpgradePackageMapper upgradePackageMapper; private final LumaService lumaService; private final GroupsRelationNetflixService groupsRelationNetflixService; private final UserDistributeMapper userDistributeMapper; private final UserPlatDistributeRateMapper userPlatDistributeRateMapper; private final GoodsDonMapper goodsDonMapper; private final UserPlatSkuDistributeRateMapper userPlatSkuDistributeRateMapper; private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper; private final RenewUpgradePackageMapper renewUpgradePackageMapper; private final ClaudeService claudeService; private final UserDistributePosterRecordMapper userDistributePosterRecordMapper; private final OrderDonRenewRecordMapper orderDonRenewRecordMapper; private final AccountMapper accountMapper; private final UserBenefitsMapper userBenefitsMapper; private final GroupsRelationChangeService changeTickerRelation; private final NetflixTempAccountUserMapper netflixTempAccountUserMapper; private final NetflixUserAccountStatusRecordMapper netflixUserAccountStatusRecordMapper; private final AccountNetflixStateMapper accountNetflixStateMapper; private final UserMirrorShopMapper userMirrorShopMapper; private final CommonMailService commonMailService; private final SysConfigMapper sysConfigMapper; private final GptMirrorDayCardGiveawayActivityMapper gptMirrorDayCardGiveawayActivityMapper; private final MirrorTicketPopupsRecordMapper mirrorTicketPopupsRecordMapper; private final VipUserMapper vipUserMapper; private final VipGoodsSkuMapper vipGoodsSkuMapper; @Override public SearchResult getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account, String orderNo, Integer cmt) { User u = userMapper.selectById(userId); if (u == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID); if (u.getIsBlack()) { return new SearchResult<>(); } List userIds = userBindRelationService.getRelationUserIdList(userId, u); MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap()); if (cmt != null && cmt == 2 && StrUtil.isNotBlank(customId)) { UserMirrorShop userMirrorShop = userMirrorShopMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShop.class) .eq(UserMirrorShop::getCustomId, customId) .last("limit 1")); if (userMirrorShop != null) { builder.field(RenewalView::getCmt, cmt).field(RenewalView::getYhsId, userMirrorShop.getId()); } } if (cmt == null || cmt != 2) { builder.field(RenewalView::getCmt, 2).op(Operator.NotEqual); } // Long yhsId = yhShopFrontService.getYhsIdByCustomId(customId); DateTime now = DateTime.now(); if (StrUtil.isNotBlank(account)) { builder.field(RenewalView::getAccount, account).op(Operator.Contain); } String conditionSql = String.format("(gr.expiry_time is null or gr.expiry_time > '%s'", now); //镜像车票 过期7天后清除 //个人店铺和AI店铺 暂不支持过期续费 if (cmt == null && StrUtil.isEmpty(customId)) { conditionSql += String.format(" or (sku.is_mirror and gr.expiry_time > '%s')", DateUtil.offsetDay(now, -7)); } conditionSql += ")"; if (StrUtil.isNotEmpty(orderNo)) { conditionSql += String.format(" and exists(select 1 from order_don o where o.relation_id = gr.id and o.user_id = gr.user_id and o.order_no = %s and o.status not in ('close','noPayment','refund'))", orderNo); } SearchResult list = beanSearcher.search(RenewalView.class, builder .field(RenewalView::getUserId, 0).op(Operator.GreaterThan) .field(RenewalView::getUserId, userIds).op(Operator.InList) .put("condition", conditionSql) .field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList) .orderBy(RenewalView::getExpiryTime).asc() .build()); if (list.getDataList().size() > 0) { //过滤邀请制、已失效的车位 Integer size = list.getTotalCount().intValue(); //赠送GPT日卡 参与平台ids List renewReduceSkuIds = userBenefitsMapper.selectList(Wrappers.lambdaQuery(UserBenefits.class) .eq(UserBenefits::getType, UserBenefits.Type.RENEW).eq(UserBenefits::getStatus, 1).select(UserBenefits::getSkuId)).stream().map(UserBenefits::getSkuId).collect(Collectors.toList()); List gptBuyGids = getGptMirrorGiveawayBuyGids(); //gpt日卡活动 GptMirrorDayCardGiveawayActivity gptMirrorDayCardGiveawayActivity = gptMirrorDayCardGiveawayActivityMapper.selectOne(Wrappers.lambdaQuery(GptMirrorDayCardGiveawayActivity.class) .last("limit 1")); SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class) .eq(SysConfig::getSysKey, Constant.EMAIL_PWD_SHOW_GID_KEY) .last("limit 1")); List showEmailPwdGids = new ArrayList<>(); if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) { try { showEmailPwdGids.addAll(Jsons.parseList(sysConfig.getSysValue(), Long.class)); } catch (Exception e) { } } List vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList()); Integer vipUserCount = vipUserMapper.selectCount(Wrappers.lambdaQuery(VipUser.class) .in(VipUser::getUserId, userIds) .gt(VipUser::getExpiryTime, now)); list.getDataList().forEach(ticket -> { if (ticket.getSkuId() == null || ticket.getGoodsId() == null) { return; } if (ticket.getGoodsId() == 18 && ticket.getSkuNum() > 1) { ticket.setPassword(null); } ticket.setIsMulti(false); if (ticket.getSkuNum() > 1) { ticket.setIsMulti(true); } //chatGPT直连 if (ticket.getGoodsId().equals(42l)) { if (StrUtil.isNotBlank(ticket.getAccount())) { String accessToken; try { accessToken = chatGptAuthService.getAccessToken(ticket.getAccount()); ticket.setGptRefreshToken(accessToken); } catch (Exception e) { redisService.set(RedisService.key.CHAT_GPT_TOKEN_EXCEPTION_KEY.getName() + ticket.getAccount(), ticket.getAccount()); } } ticket.setAccount(null); ticket.setPassword(null); } else { ticket.setGptRefreshToken(null); } if (ticket.getSecondType() == 1) { ticket.setAccount(null); ticket.setPassword(null); } //gpt 2月的独立账号可看到邮箱密码 if (ticket.getGoodsId() == 18l && ticket.getSkuNum() == 1 && ticket.getAccount() != null && ticket.getCreatedTime().compareTo(DateUtil.parse("2025-02-01")) > 0) { } else { if (!showEmailPwdGids.contains(ticket.getGoodsId())) { ticket.setGptEmailPwd(null); } } if (isLoginPopularize != null && isLoginPopularize) { GoodsDonViews views = beanSearcher.searchFirst(GoodsDonViews.class, MapUtils.builder().field(GoodsDonViews::getId, ticket.getGoodsId()).build()); views.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, views.getId()).build())); views.setSkuList(beanSearcher.searchAll(GoodsDonSkuFrontView.class, MapUtils.builder().field(GoodsDonSkuFrontView::getGoodsId, views.getId()).field(GoodsDonSkuFrontView::getStatus, true).build())); ticket.setGoodsDonViews(views); } if (ticket.getMonths() != null && ticket.getMonths() >= 300) { ticket.setExpiryTime(null); } if (ticket.getExpiryTime() != null && ticket.getGoodsType() == 1) { String remainDays = DateUtil.formatBetween(now, ticket.getExpiryTime(), BetweenFormater.Level.DAY); if ("0天".equals(remainDays)) { remainDays = "小于1天"; } else { //当天也算 int days = Integer.parseInt(remainDays.substring(0, remainDays.indexOf("天"))); remainDays = days + 1 + "天"; } ticket.setRemainDays(remainDays); ticket.setTotal(DateUtil.betweenDay(ticket.getStartTime(), ticket.getExpiryTime(), false) + 1); } OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class) .eq(OrderDon::getRelationId, ticket.getRelationId()) .eq(OrderDon::getUserId, ticket.getUserId()) .eq(OrderDon::getOrderType, 1) .notIn(OrderDon::getStatus, Constant.noOrderAllStatus) .orderByDesc(OrderDon::getId) .last("limit 1")); if (orderDon != null) { ticket.setOrderNo(orderDon.getOrderNo()); ticket.setOrderId(orderDon.getId()); ticket.setTransactionId(orderDon.getTransactionId()); if (ticket.getSecondType() == 1) { //是否完成邀请 根据订单状态 ticket.setIsComplete(orderDon.getStatus() == OrderDon.Status.complete ? true : false); } } if (size > 1 && ticket.getGoodsId() != 18) { Date payTime = null; if (orderDon != null) { payTime = Optional.ofNullable(orderDon.getPayTime()).orElse(orderDon.getCreatedTime()); } //加购订单 if (orderDon == null) { List plusPurchaseSkuRelations = orderDiscountPlusPurchaseSkuRelationMapper.selectPlusRelationByIdAndUserId(ticket.getRelationId(), ticket.getUserId()); for (OrderDiscountPlusPurchaseSkuRelation data : plusPurchaseSkuRelations) { String relationIds = data.getRelationIds(); if (StrUtil.isEmpty(relationIds)) { return; } try { List relationList = Jsons.parseList(relationIds, Long.class); if (relationList.contains(ticket.getRelationId())) { OrderDon plusOrder = orderDonMapper.selectById(data.getOrderId()); if (plusOrder != null) { payTime = Optional.ofNullable(plusOrder.getPayTime()).orElse(plusOrder.getCreatedTime()); } break; } } catch (Exception e) { } } } ticket.setPayTime(payTime); } if (ticket.getSkuNum() != null && ticket.getSkuNum() == 1) { } //奈飞、gpt if (ticket.getGoodsId() == 1 || ticket.getGoodsId() == 18 || ticket.getGoodsId() == 33l) { ticket.setEmail(null); } //设置镜像车票信息 setMirrorTicketInfo(ticket); // List relationUserViews = groupsRelationMapper.getUserRelationUserViews(ticket.getGroupId(), ticket.getRelationId(), ticket.getUserId(), List.of(GroupsRelation.Status.validity, GroupsRelation.Status.outside)); // ticket.setRelationViews(relationUserViews); if (ticket.getExpiryTime() != null) { ticket.setExpiryTimeStr(DateUtil.format(ticket.getExpiryTime(), "yyyy-MM-dd")); } //查看双重验证码 if (StrUtil.isNotEmpty(ticket.getApiSecret())) { Boolean isHasVerifyCode = StrUtil.isNotBlank(ticket.getVerifyCode()) ? true : false; Integer codeNum = getUserCodeNumBySkuId(ticket.getUserId(), ticket.getSkuId(), isHasVerifyCode); ticket.setCodeNum(codeNum); } Long qaId = groupsRelationMapper.selectGoodsDonQaByGoodsId(ticket.getGoodsId()); ticket.setQa(qaId > 0 ? true : false); //是否存在海报 ticket.setPosterInfo(setGoodsPoster(ticket, u, userIds)); //续费升级折扣 setRenewDiscount(ticket); if (CollUtil.isNotEmpty(renewReduceSkuIds) && renewReduceSkuIds.contains(ticket.getSkuId())) { ticket.setIsRenewReduce(true); } if (CollUtil.isNotEmpty(gptBuyGids) && gptBuyGids.contains(ticket.getGoodsId())) { if (gptMirrorDayCardGiveawayActivity != null && orderDon != null && orderDon.getCreatedTime().compareTo(gptMirrorDayCardGiveawayActivity.getCreatedTime()) > 0) { //是否领取过GPT日卡 Long orderId = orderDon.getId(); Number count = beanSearcher.searchCount(GptMirrorDayCardActivityRecord.class, MapUtils.builder().field(GptMirrorDayCardActivityRecord::getOrderId, orderId).build()); ticket.setReceivedGptGift(count.intValue() > 0); } } markVipDeductTicket(userIds, ticket, vipSkuIds, vipUserCount > 0); }); } userLoginRecordService.saveUserLoginDayRecord(userId); return list; } @Override public Boolean isJoinCorpWx(Long userId, Boolean isJoin, Boolean noCoupon) { if (!isJoin) { User user = userMapper.selectById(userId); if (user == null || StrUtil.isEmpty(user.getUnionid())) { return true; } // CorpUser corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class) // .ne(CorpUser::getUnionid, "") // .eq(CorpUser::getUnionid, user.getUnionid()) // .last("limit 1") // .select(CorpUser::getId) // ); CorpUserFollowView corpUserFollowView = beanSearcher.searchFirst(CorpUserFollowView.class, MapUtils.builder() .field(CorpUserFollowView::getUnionId, user.getUnionid()) .field(CorpUserFollowView::getStatus, 1).build()); if (corpUserFollowView == null) { return false; } } //用户是否买了奈飞车票 Number number = beanSearcher.searchCount(RenewalView.class, MapUtils.builder() .field(RenewalView::getUserId, userId) .field(RenewalView::getGoodsId, 1) .field(RenewalView::getStatus, List.of("validity", "overdue")).op(Operator.InList) .build()); if (number.intValue() > 0 && !noCoupon) { couponCommonService.sendCouponToUser(userId, 34l, 0l, 0l, 0l, CouponUser.Channel.wxCorp); } return true; } @Override public GroupsRelation getSimilarExpiredGroupRelation(GoodsDonSku sku, List errorsRelationIds, String ip) { Long skuId = sku.getId(); Integer days = sku.getDays(); Integer months = sku.getMonths(); Integer maxNum = sku.getNum(); DateTime expiryTime = null; if (days != null && days > 0) { expiryTime = DateUtil.offsetDay(DateTime.now(), days); } else { expiryTime = DateUtil.offsetMonth(DateTime.now(), months); } Integer extraNum = 5; if (sku.getId() == 178l) { extraNum = 2; } maxNum += extraNum; DateTime minExpiryTime = DateUtil.offsetDay(expiryTime, -5); Long groupsId = groupsRelationMapper.selectSimilarExpiredRelation(skuId, minExpiryTime, maxNum, ip); if (groupsId == null) { log.info("暂无相似过期时间车队"); return null; } GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class) .notIn(errorsRelationIds != null && errorsRelationIds.size() > 0, GroupsRelation::getId, errorsRelationIds) .eq(GroupsRelation::getGroupsId, groupsId) .eq(GroupsRelation::getStatus, GroupsRelation.Status.none) .eq(GroupsRelation::getUserId, 0) .orderByAsc(GroupsRelation::getNum) .last("limit 1")); if (relation != null) { log.info("用户userId:{},获取相似车队的车位relationId:{}", relation.getId()); } return relation; } @Override public Page getRecommendGoodsViews(Boolean isPayNf, List filter_goods_id, Boolean filterCourseGoods, Integer start, Integer limit) { return groupsRelationMapper.getRecommendGoodsViews(new Page<>(start, limit), filter_goods_id, isPayNf, filterCourseGoods); } @Override @Transactional(rollbackFor = Throwable.class) public void sendCourseWare(SpecialGoodsTicketReq request) throws Exception { Long userId = request.getUserId(); Long relationId = request.getRelationId(); String email = request.getEmail(); List userIdList = userBindRelationService.getRelationUserIdList(userId, null); RenewalView relation = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder().field(RenewalView::getRelationId, relationId).build()); Assert.notNull(relation, "您的车票不存在"); Long relationUserId = relation.getUserId(); if (!userIdList.contains(relationUserId)) { throw BusinessRuntimeException.getInstance("您的车票不存在"); } if (relation.getSpecialType() != GoodsDon.SpecialType.courseware) { throw BusinessRuntimeException.getInstance(""); } //是否已发送 if (StrUtil.isNotBlank(relation.getGrAccount())) { throw BusinessRuntimeException.getInstance("已领取课件,请前往邮箱查看"); } if (!Validator.isEmail(email)) { throw BusinessRuntimeException.getInstance("请输入正确的邮箱"); } int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class) .set(GroupsRelation::getAccount, email) .and(qr -> qr.isNull(GroupsRelation::getAccount).or().eq(GroupsRelation::getAccount, StrUtil.EMPTY)) .eq(GroupsRelation::getId, relationId)); if (update > 0) { orderDonMapper.update(null, Wrappers.lambdaUpdate(OrderDon.class) .set(OrderDon::getStatus, OrderDon.Status.complete) .eq(OrderDon::getRelationId, relationId) .eq(OrderDon::getUserId, userId) .eq(OrderDon::getStatus, OrderDon.Status.hasPayment)); mailService.sendCoursewareByGoodsId(relation.getGoodsId(), relation.getRelationId(), relation.getUserId(), relation.getTitle(), email); } } @Override public GroupsRelation getRelation(Long payRelationId, Long userId, GoodsDonSku sku, String ip) { GroupsRelation relation = null; Integer maxNum = sku.getNum(); if (payRelationId != null && payRelationId > 0) { relation = groupsRelationMapper.selectById(payRelationId); if (relation == null) { throw new BusinessRuntimeException(GROUP_INDEX_NOT_FIND.getCode(), GROUP_INDEX_NOT_FIND.getMsg()); } if (relation.getUserId() != null && relation.getUserId() > 0L) { throw new BusinessRuntimeException(GROUP_INDEX_ALREADY_BE_USER.getCode(), GROUP_INDEX_ALREADY_BE_USER.getMsg()); } } else { GroupsTrips groups = null; //ChatGpt Plus、Midjourney非独立规格 上车先获取硬塞座位 硬塞5个座位 //主账号过期时间25天以外 //23-12-06 MidJourney 不硬塞 if (sku.getNum() > 1 && Constant.AI_goodsIds.get(0) == sku.getGoodsId()) { Integer extraNum = 5; if (sku.getId() == 178l || sku.getId() == 423l) { extraNum = 2; } maxNum += extraNum; DateTime time = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), 25); //不塞存在该用户的车队 Long groupsId = groupsRelationMapper.getOutSideGroupsTripsRelationByGoodsId(sku.getId(), time, extraNum, userId, sku.getNum(), maxNum); if (groupsId != null) { relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class) .eq(GroupsRelation::getGroupsId, groupsId) .eq(GroupsRelation::getUserId, 0) .eq(GroupsRelation::getStatus, GroupsRelation.Status.outside) .last("limit 1")); if (relation == null) { relation = new GroupsRelation(); relation.setStatus(GroupsRelation.Status.outside); relation.setUserId(userId); relation.setGroupsId(groupsId); GroupsRelation maxNumRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsId).orderByDesc(GroupsRelation::getNum).last("limit 1")); Integer nextNum = maxNumRelation.getNum() + 1; if (redisService.setNx(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getNameFormat(groupsId, nextNum), nextNum, RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getTimeout())) { relation.setNum(nextNum); groupsRelationMapper.insert(relation); } else { throw BusinessRuntimeException.getInstance("系统繁忙,请重试..."); } } groups = groupsMapper.selectById(groupsId); } } if (groups == null) { //寻找差不多过期时间规格的车位 relation = getSimilarExpiredGroupRelation(sku, null, ip); if (relation == null) { //TODO 如果没指定座位,等待逻辑确认 groups = groupsMapper.selectTicketGroups(sku.getId(), GroupsTrips.Status.validity, maxNum, ip); if (groups == null) { //待发车 groups = groupsMapper.selectTicketGroups(sku.getId(), GroupsTrips.Status.waiting, maxNum, ip); } //新增空车队 if (groups == null) { relation = groupsFuncService.createNewGroupsTrips(sku); } //获取车位 if (relation == null) { //寻找快满编车队进行占座 relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId()); if (relation == null) { Long groupsId = groups.getId(); TASK_EXECUTOR.execute(() -> groupsMapper.updateAvailableNum(groupsId)); throw BusinessRuntimeException.getInstance("系统繁忙,请重试..."); } } } } if (groups == null) { groups = groupsMapper.selectById(relation.getGroupsId()); } //车队目前可用停车数 relation.setGroupsAvailParkingNum(groups.getAvailableParkingNum()); relation.setMaxNum(maxNum); } return relation; } @Override public String getAiVerifyCode(TicketLoginReq loginReq) throws Exception { Integer type = loginReq.getType(); RenewalView renewalView; String account; Long userId = 0l; Long relationId = 0l; if (loginReq.getMerchants()) { renewalView = new RenewalView(); renewalView.setGoodsId(loginReq.getGoodsId()); renewalView.setAccount(loginReq.getAccount()); if (loginReq.getAccountId() != null && loginReq.getAccountId() != 0l) { GroupsTrips groupsTrips = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class) .eq(GroupsTrips::getAccountId, loginReq.getAccountId()) .last("limit 1")); if (groupsTrips != null) { renewalView.setSkuId(groupsTrips.getSkuId()); } } renewalView.setUserId(userId); account = loginReq.getAccount(); } else { userId = loginReq.getUserId(); relationId = loginReq.getRelationId(); List relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null); renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder().field(RenewalView::getUserId, relationUserIdList).op(Operator.InList) .field(RenewalView::getRelationId, relationId).build()); if (renewalView == null) { throw BusinessRuntimeException.getInstance("您的车票不存在..."); } if (StrUtil.isEmpty(renewalView.getAccount())) { throw BusinessRuntimeException.getInstance("车票未配置账号"); } account = renewalView.getAccount(); String password = renewalView.getPassword(); if (StrUtil.hasEmpty(account, password)) { throw BusinessRuntimeException.getInstance("您的车票账号密码异常,请联系客服..."); } } if (renewalView.getGoodsId() == 1l) { Integer linkType = loginReq.getLinkType(); if (type == null && linkType == null) { throw BusinessRuntimeException.getInstance("系统异常"); } if (linkType != null) { String key = RedisService.key.NF_UPGRAD_USER_LIMIT_KEY.getNameFormat(DateUtil.hour(DateTime.now(), true), linkType, renewalView.getUserId()); if (!redisService.hasKey(key)) { redisService.set(key, 0l, RedisService.key.NF_UPGRAD_USER_LIMIT_KEY.getTimeout()); } else { Integer value = (Integer) redisService.get(key); if (value >= 5) { throw BusinessRuntimeException.getInstance("获取奈飞同步更新装置过于频繁"); } } } } String code = commonMailService.getTicketMailCode(renewalView.getGoodsId(), account, renewalView.getRelateEmail(), renewalView.getGptEmailPwd(), renewalView.getCreatedTime(), type, loginReq.getLinkType(), false); GroupsRelationLoginCodeRecord record = new GroupsRelationLoginCodeRecord(); record.setUserId(userId); record.setRelationId(relationId); record.setAccount(renewalView.getAccount()); record.setGoodsId(renewalView.getGoodsId()); record.setSkuId(renewalView.getSkuId()); groupsRelationLoginCodeRecordMapper.insert(record); //奈飞同步装置 if (renewalView.getGoodsId() == 1l && loginReq.getLinkType() != null) { String key = RedisService.key.NF_UPGRAD_USER_LIMIT_KEY.getNameFormat(DateUtil.hour(DateTime.now(), true), loginReq.getLinkType(), renewalView.getUserId()); redisService.incr(key, 1L); } return code; } @Override public void checkGroupsAvailParkingNum(Long skuId, Long groupsId, Integer availableParkingNum, Integer maxNum) { //GPT10人月付、4人月付 if (skuId == 161l || skuId == 178l) { //为0时,不参与限制 if (availableParkingNum == 0) { return; } //目前车队可用停车数 //目前上车人数 Integer currentParkingNum = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class) .eq(GroupsRelation::getGroupsId, groupsId) .ne(GroupsRelation::getUserId, 0) .le(GroupsRelation::getNum, maxNum)); if (currentParkingNum > availableParkingNum) { throw BusinessRuntimeException.getInstance("系统繁忙,请重试..."); } } } @Override public void adjustGroupsParkingTime(Long relationId, GoodsDonSku sku) { if (sku == null) { return; } Long skuId = sku.getId(); //更新GPT Plus10人、4人月付车队状态 待优化 if (skuId == 161l || skuId == 178l || skuId == 422l || skuId == 423l) { GroupsRelation relation = groupsRelationMapper.selectById(relationId); Long groupsId = relation.getGroupsId(); GroupsTrips groupsTrips = groupsMapper.selectById(groupsId); Integer availableParkingNum = groupsTrips.getAvailableParkingNum(); //为0时 不参与限制 if (availableParkingNum == 0) { return; } Integer extraNum = 5; if (skuId == 178l || skuId == 423l) { extraNum = 2; } Integer maxNum = sku.getNum() + extraNum; if (availableParkingNum >= maxNum) { return; } //目前上车人数 Integer currentParkingNum = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class) .eq(GroupsRelation::getGroupsId, groupsId) .ne(GroupsRelation::getUserId, 0) .le(GroupsRelation::getNum, maxNum)); if (currentParkingNum >= availableParkingNum) { //锁住 DateTime parkingTime = DateUtil.offsetDay(DateTime.now(), 1); groupsMapper.update(null, Wrappers.lambdaUpdate(GroupsTrips.class) .eq(GroupsTrips::getId, groupsTrips.getId()) .set(GroupsTrips::getParkingTime, parkingTime) .isNull(GroupsTrips::getParkingTime)); } } } @Override public void setGroupsTripsParkingTimeEmpty(GoodsDonSku sku, Long relationId) { if (sku == null) { return; } Long skuId = sku.getId(); if (skuId == 161l || skuId == 178l) { GroupsRelation relation = groupsRelationMapper.selectById(relationId); Long groupsId = relation.getGroupsId(); GroupsTrips groupsTrips = groupsMapper.selectById(groupsId); Integer availableParkingNum = groupsTrips.getAvailableParkingNum(); if (groupsTrips.getParkingTime() == null || availableParkingNum == 0) { return; } Integer extraNum = 5; if (skuId == 178l) { extraNum = 2; } Integer skuNum = sku.getNum(); if (availableParkingNum >= skuNum + extraNum) { return; } //目前上车人数 Integer currentParkingNum = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class) .eq(GroupsRelation::getGroupsId, groupsId) .ne(GroupsRelation::getUserId, 0)); if (currentParkingNum < availableParkingNum) { groupsMapper.update(null, Wrappers.lambdaUpdate(GroupsTrips.class) .eq(GroupsTrips::getId, groupsTrips.getId()) .set(GroupsTrips::getParkingTime, null) .isNotNull(GroupsTrips::getParkingTime)); } } } @Override public Integer getUserCodeNumBySkuId(Long userId, Long skuId, Boolean isHasVerifyCode) { //查看双重验证码 UserFuncProperty userFuncProperty = userFuncPropertyMapper.selectOne(Wrappers.lambdaQuery(UserFuncProperty.class).eq(UserFuncProperty::getUserId, userId).last("limit 1")); //默认2次 int num = 2; //有安全码查看次数 置为0 if (isHasVerifyCode) { num = 0; //存在身份实名认证有两次机会 List userIdList = userBindRelationService.getRelationUserIdList(userId, null); Integer selectCount = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class) .in(UserCertRecord::getUserId, userIdList)); if (selectCount > 0) { num = 2; } return num; } //查看双重验证码次数 GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId); if (sku.getCodeNum() > 0) { num = sku.getCodeNum(); } if (userFuncProperty != null) num = userFuncProperty.getVerifyCheckNum(); return num; } @Override public List getHasPayGoods(long userId) { User user = userMapper.selectById(userId); List userIds = userBindRelationService.getRelationUserIdList(userId, user); DateTime now = DateTime.now(); List list = groupsRelationMapper.getUserHasPayGoods(userIds, now); return list; } @Override public List getExpiryRenewalNotify(Long userId) { DateTime now = DateTime.now(); DateTime thisZero = DateUtil.beginOfDay(now); String thisDate = thisZero.toDateStr(); Object exists = redisService.get(RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getNameFormat(thisDate, userId)); if (exists != null) { return null; } User u = userMapper.selectById(userId); if (u == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID); if (u.getIsBlack()) { redisService.setNx(RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getNameFormat(thisDate, userId), userId, RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getTimeout()); return null; } List userIds = userBindRelationService.getRelationUserIdList(userId, u); MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap()); List list = beanSearcher.searchAll(RenewalView.class, builder .field(RenewalView::getUserId, 0).op(Operator.GreaterThan) .field(RenewalView::getUserId, userIds).op(Operator.InList) .field(RenewalView::getExpiryTime, now).op(Operator.GreaterThan) .field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList) .field(RenewalView::getAqType, 1) .field(RenewalView::getIsVip, Boolean.TRUE) .orderBy(RenewalView::getExpiryTime).asc() .build()); if (list.size() > 5) { redisService.setNx(RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getNameFormat(thisDate, userId), userId, RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getTimeout()); return null; } List renewReduceSkuIds = userBenefitsMapper.selectList(Wrappers.lambdaQuery(UserBenefits.class) .eq(UserBenefits::getType, UserBenefits.Type.RENEW).eq(UserBenefits::getStatus, 1).select(UserBenefits::getSkuId)).stream().map(UserBenefits::getSkuId).collect(Collectors.toList()); //提前7天 AtomicInteger day = new AtomicInteger(7); List expiryTickets = list.stream().filter(ticket -> { //下架 if (ticket.getGoodsStatus() == null || ticket.getSkuStatus() == null || !ticket.getGoodsStatus() || !ticket.getSkuStatus()) { return false; } Integer skuMonths = ticket.getMonths(); if (skuMonths == null) { return false; } Date expiryTime = ticket.getExpiryTime(); //年付 提前一个月 if (skuMonths >= 12) { day.set(30); } else { day.set(7); } if (DateUtil.beginOfDay(expiryTime).compareTo(DateUtil.offsetDay(thisZero, day.get())) <= 0) { ticket.setExpiryTimeStr(DateUtil.format(ticket.getExpiryTime(), "yyyy-MM-dd")); //GPT镜像信息 setGptMirrorInfo(ticket); ticket.setExpiryTime(null); if (CollUtil.isNotEmpty(renewReduceSkuIds) && renewReduceSkuIds.contains(ticket.getSkuId())) { ticket.setIsRenewReduce(true); } return true; } return false; }).collect(Collectors.toList()); redisService.setNx(RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getNameFormat(thisDate, userId), userId, RedisService.key.TICKET_EXPIRY_NOTIFY_DAY.getTimeout()); if (CollUtil.isNotEmpty(expiryTickets)) { groupsRelationExpiryNotifyRecordMapper.batchInsert(userId, expiryTickets); } return expiryTickets; } @Override public void getCollegeStudentUserGptTicket(Long userId) { Retryer build = RetryerBuilder.newBuilder() .retryIfException() //运行时异常重试 .retryIfRuntimeException() //false重试 .retryIfResult(res -> Objects.equals(res, false)) //1s 间隔 .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS)) //停止策略 : 尝试请求3次 .withStopStrategy(StopStrategies.stopAfterAttempt(3)).build(); try { build.call(() -> { //体验规格 Long gptMirrorSkuId = Constant.GPT_MIRROR_SKU_ID; GroupsTrips groups = groupsMapper.selectCollegeStudentUserGptTicket(gptMirrorSkuId); GroupsRelation relation = null; if (groups != null) { relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId()); } if (relation == null) { //生成空车队 GoodsDonSku sku = goodsDonSkuMapper.selectById(gptMirrorSkuId); relation = groupsFuncService.createNewGroupsTrips(sku); } DateTime startTime = DateTime.now(); DateTime expiryTime = DateUtil.offsetDay(startTime, 1); int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class) .set(GroupsRelation::getUserId, userId) .set(GroupsRelation::getStartTime, startTime) .set(GroupsRelation::getExpiryTime, expiryTime) .set(GroupsRelation::getStatus, GroupsRelation.Status.validity) .set(GroupsRelation::getAqType, 2) .eq(GroupsRelation::getId, relation.getId()) .eq(GroupsRelation::getUserId, 0)); if (update > 0) { groupsMapper.decrAvailableNum(groups.getId()); return true; } log.error("发送用户:{} GPT镜像车票体验失败,进行重试", userId); return false; }); } catch (ExecutionException | RetryException e) { log.error("发送用户GPT镜像体验失败:{}", StringUtil.getErrorText(e)); } } @Override public RenewalView getTicketDetail(long userId, Long relationId) { User u = userMapper.selectById(userId); List userIds = userBindRelationService.getRelationUserIdList(userId, u); MapBuilder builder = MapUtils.builder(); RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, builder .field(RenewalView::getRelationId, relationId) .field(RenewalView::getUserId, 0).op(Operator.GreaterThan) .field(RenewalView::getUserId, userIds).op(Operator.InList) .field("condition", String.format("(gr.expiry_time is null or gr.expiry_time > '%s')", DateTime.now())) .field(RenewalView::getStatus, List.of("validity", "outside")).op(Operator.InList) .orderBy(RenewalView::getExpiryTime).asc() .onlySelect(RenewalView::getRelationId, RenewalView::getExpiryTime, RenewalView::getTitle, RenewalView::getSpecVal, RenewalView::getGoodsId, RenewalView::getSkuId, RenewalView::getSkuNum, RenewalView::getSkuStatus, RenewalView::getGoodsStatus) .build()); if (renewalView != null) { renewalView.setExpiryTimeStr(DateUtil.format(renewalView.getExpiryTime(), "yyyy-MM-dd")); } return renewalView; } @Override public GroupsRelation ticketLogin(TicketLoginReq loginReq) { String account = loginReq.getAccount(); if (StrUtil.isEmpty(account)) { throw BusinessRuntimeException.getInstance("请输入对应账号"); } if (loginReq.getMerchants()) { if (account.contains(Constant.YH_EMAIL_DOMAIN_SUFFIX)) { SysEmail sysEmail = sysEmailMapper.selectOne(Wrappers.lambdaQuery(SysEmail.class) .eq(SysEmail::getEmail, account) .last("limit 1")); if (sysEmail == null) { throw BusinessRuntimeException.getInstance("账号错误,请联系客服"); } } GroupsRelation relation = new GroupsRelation(); relation.setId(0l); return relation; } String password = loginReq.getPassword(); Integer num = loginReq.getNum(); if (ObjectUtil.hasEmpty(password, num)) { throw BusinessRuntimeException.getInstance("参数错误"); } Long goodsId = Optional.ofNullable(loginReq.getGoodsId()).orElse(1l); GroupsRelation relation = groupsRelationMapper.selectRelationByAccountAndNum(account, password, goodsId, num); if (relation == null) { log.info("外部入口使用账号account:{},pwd:{},座位num:{}登录失败...", account, password, num); if (StrUtil.equals(loginReq.getLang(), Constant.EN_US)) { throw BusinessRuntimeException.getInstance("Please enter the correct account information"); } throw BusinessRuntimeException.getInstance("请输入正确的账号信息"); } return relation; } @Override public String outsideTicketVerify(TicketLoginReq loginReq) { String account = loginReq.getAccount(); if (StrUtil.isEmpty(account)) { throw BusinessRuntimeException.getInstance("账号错误"); } if (loginReq.getMerchants()) { if (account.contains(Constant.YH_EMAIL_DOMAIN_SUFFIX)) { SysEmail sysEmail = sysEmailMapper.selectOne(Wrappers.lambdaQuery(SysEmail.class) .eq(SysEmail::getEmail, account) .last("limit 1")); if (sysEmail == null) { throw BusinessRuntimeException.getInstance("账号错误,请联系客服"); } } loginReq.setGoodsId(1l); loginReq.setAccountId(0l); } else { String password = loginReq.getPassword(); Integer num = loginReq.getNum(); if (ObjectUtil.hasEmpty(password, num)) { throw BusinessRuntimeException.getInstance("参数错误"); } Long goodsId = Optional.ofNullable(loginReq.getGoodsId()).orElse(1l); GroupsRelation relation = groupsRelationMapper.selectRelationByAccountAndNum(account, password, goodsId, num); if (relation == null) { log.info("外部入口使用账号account:{},pwd:{},座位num:{}同步验证链接失败...", account, password, num); if (StrUtil.equals(loginReq.getLang(), Constant.EN_US)) { throw BusinessRuntimeException.getInstance("This account is no longer valid"); } throw BusinessRuntimeException.getInstance("该账号已失效"); } loginReq.setUserId(relation.getUserId()); loginReq.setRelationId(relation.getId()); loginReq.setGoodsId(goodsId); } try { String aiVerifyCode = getAiVerifyCode(loginReq); if (StrUtil.isEmpty(aiVerifyCode)) { throw BusinessRuntimeException.getInstance(""); } return aiVerifyCode; } catch (Exception e) { if (StrUtil.equals(loginReq.getLang(), Constant.EN_US)) { throw BusinessRuntimeException.getInstance("Please verify that the link was sent"); } throw BusinessRuntimeException.getInstance("请校验链接是否已发送"); } } @Override public String getNfHouseholdDevice(long userId, Long relationId) throws Exception { List relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null); RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder().field(RenewalView::getUserId, relationUserIdList).op(Operator.InList) .field(RenewalView::getRelationId, relationId).build()); if (renewalView == null) { throw BusinessRuntimeException.getInstance("您的车票不存在..."); } if (StrUtil.isEmpty(renewalView.getAccount())) { throw BusinessRuntimeException.getInstance("车票未配置账号"); } String account = renewalView.getAccount(); String password = renewalView.getPassword(); if (StrUtil.hasEmpty(account, password)) { throw BusinessRuntimeException.getInstance("您的车票账号密码异常,请联系客服..."); } String code = commonMailService.getTicketMailCode(renewalView.getGoodsId(), account, renewalView.getRelateEmail(), renewalView.getGptEmailPwd(), renewalView.getCreatedTime(), null, 1, true); return code; } @Override public String getVerifyCode(String account) throws Exception { Account at = accountMapper.selectOne(Wrappers.lambdaQuery(Account.class) .eq(Account::getAccount, account) .eq(Account::getGoodsId, 18)); if (at == null) { return null; } String password = at.getPassword(); if (StrUtil.hasEmpty(account, password)) { throw BusinessRuntimeException.getInstance("账号异常"); } String code = commonMailService.getTicketMailCode(at.getGoodsId(), account, at.getRelateEmail(), at.getGptEmailPwd(), at.getCreatedTime(), null, null, false); return code; } @Override public void changeTicket(long userId, Long relationId) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder() .field(RenewalView::getUserId, userIdList).op(Operator.InList) .field(RenewalView::getRelationId, relationId) .field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan) .build()); if (renewalView == null) { throw BusinessRuntimeException.getInstance("车票不存在"); } if (renewalView.getGoodsId() != 1) { throw BusinessRuntimeException.getInstance("只针对奈飞车票"); } AccountNetflixState accountNetflixState = accountNetflixStateMapper.selectOne(Wrappers.lambdaQuery(AccountNetflixState.class) .eq(AccountNetflixState::getAccount, renewalView.getAccount()) .orderByDesc(AccountNetflixState::getId) .last("limit 1")); if (accountNetflixState == null || accountNetflixState.getState() != 3) { throw BusinessRuntimeException.getInstance("只支持异常账号更换车票"); } String key = RedisService.key.NETFLIX_CHANGE_TICKET_KEY.getName() + relationId; if (!redisService.setNx(key, relationId, RedisService.key.NETFLIX_CHANGE_TICKET_KEY.getTimeout())) { throw BusinessRuntimeException.getInstance("正在更换车票中.."); } Long groupId = renewalView.getGroupId(); Long skuId = renewalView.getSkuId(); Date expiryTime = renewalView.getExpiryTime(); //随机选择同规格得车票 Long item_groupsId = groupsMapper.selectRandomGroupsTripsBySkuId(groupId, skuId, expiryTime); GroupsRelation newRelation = null; if (item_groupsId != null) { //存在就随机分配一个,没有就不做处理 newRelation = changeTickerRelation.changeTicket(renewalView.getUserId(), relationId, item_groupsId, renewalView.getSkuId()); } //若无移至空车队 if (newRelation == null) { newRelation = changeTickerRelation.getEmptyGroupsRelation(renewalView.getUserId(), renewalView.getRelationId(), renewalView.getSkuId()); } if (newRelation == null) { throw BusinessRuntimeException.getInstance("更换异常,请重新提交"); } NetflixUserAccountStatusRecord netflixUserAccountStatusRecord = netflixUserAccountStatusRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountStatusRecord.class) .eq(NetflixUserAccountStatusRecord::getRelationId, relationId) .last("limit 1")); if (netflixUserAccountStatusRecord != null) { netflixUserAccountStatusRecord.setDeleted(false); netflixUserAccountStatusRecordMapper.updateById(netflixUserAccountStatusRecord); } redisService.del(key); } @Override public AccountView getTempAccount(long userId, Long relationId) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder() .field(RenewalView::getRelationId, relationId) .field(RenewalView::getUserId, userIdList).op(Operator.InList) .field(RenewalView::getGroupsStatus, GroupsTrips.Status.waiting.name()) .field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan) .build()); if (renewalView == null) { throw BusinessRuntimeException.getInstance("车票不存在"); } AccountView accountView = new AccountView(); //奈飞超过3帐车票不给看 Number number = beanSearcher.searchCount(RenewalView.class, MapUtils.builder() .field(RenewalView::getUserId, userIdList).op(Operator.InList) .field(RenewalView::getGoodsId, 1) .field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan) .build()); if (number.intValue() > 2) { return accountView; } NetflixTempAccountUser netflixTempAccountUser = netflixTempAccountUserMapper.selectOne(Wrappers.lambdaQuery(NetflixTempAccountUser.class) .eq(NetflixTempAccountUser::getRelationId, relationId) .in(NetflixTempAccountUser::getUserId, userIdList) .last("limit 1")); Account account; if (netflixTempAccountUser == null) { account = accountMapper.selectNetflixTempAccount(); if (account != null) { netflixTempAccountUser = new NetflixTempAccountUser(); netflixTempAccountUser.setAccountId(account.getId()); netflixTempAccountUser.setRelationId(relationId); netflixTempAccountUser.setUserId(renewalView.getUserId()); netflixTempAccountUserMapper.insert(netflixTempAccountUser); } } else { account = accountMapper.selectById(netflixTempAccountUser.getAccountId()); } if (account != null) { accountView.setAccount(account.getAccount()); accountView.setPassword(account.getPassword()); } return accountView; } @Override public void nfErrorAccountSubmit(long userId, Long relationId) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder() .field(RenewalView::getUserId, userIdList).op(Operator.InList) .field(RenewalView::getRelationId, relationId) .field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan).build()); if (renewalView == null) { throw BusinessRuntimeException.getInstance("车票不存在"); } if (renewalView.getGoodsId() != 1) { throw BusinessRuntimeException.getInstance("只支持奈飞车票"); } String account = renewalView.getAccount(); String password = renewalView.getPassword(); Integer selectCount = netflixUserAccountStatusRecordMapper.selectCount(Wrappers.lambdaQuery(NetflixUserAccountStatusRecord.class) .eq(NetflixUserAccountStatusRecord::getRelationId, relationId) .eq(NetflixUserAccountStatusRecord::getUserId, userId) .eq(NetflixUserAccountStatusRecord::getAccount, account)); if (selectCount > 0) { throw BusinessRuntimeException.getInstance("该账号正在检测中"); } AccountNetflixState accountNetflixState = accountNetflixStateMapper.selectOne(Wrappers.lambdaQuery(AccountNetflixState.class) .eq(AccountNetflixState::getAccount, account) .last("limit 1")); Integer state = 0; if (accountNetflixState != null && accountNetflixState.getState() == 3) { state = accountNetflixState.getState(); } NetflixUserAccountStatusRecord netflixUserAccountStatusRecord = new NetflixUserAccountStatusRecord(); netflixUserAccountStatusRecord.setAccount(account); netflixUserAccountStatusRecord.setRelationId(relationId); netflixUserAccountStatusRecord.setPassword(password); netflixUserAccountStatusRecord.setUserId(renewalView.getUserId()); netflixUserAccountStatusRecord.setState(state); OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class) .eq(OrderDon::getRelationId, renewalView.getRelationId()) .eq(OrderDon::getUserId, renewalView.getUserId()) .notIn(OrderDon::getStatus, Constant.noOrderAllStatus) .orderByDesc(OrderDon::getId) .last("limit 1")); if (orderDon != null) { netflixUserAccountStatusRecord.setOrderId(orderDon.getId()); } netflixUserAccountStatusRecordMapper.insert(netflixUserAccountStatusRecord); } @Override public Integer getNetflixErrorAccountStatus(long userId, Long relationId) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); NetflixUserAccountStatusRecord netflixUseAccountStatusRecord = netflixUserAccountStatusRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountStatusRecord.class) .eq(NetflixUserAccountStatusRecord::getRelationId, relationId) .eq(NetflixUserAccountStatusRecord::getDeleted, 1) .in(NetflixUserAccountStatusRecord::getUserId, userIdList) .last("limit 1")); if (netflixUseAccountStatusRecord == null) { throw BusinessRuntimeException.getInstance("未有提交记录"); } Integer state = netflixUseAccountStatusRecord.getState(); //2是登录失败 3是被封号 if (state == 3) { if (netflixUseAccountStatusRecord.getCreatedTime().compareTo(DateUtil.offsetMinute(DateTime.now(), -10)) > 0) { state = 0; } } //登录失败不算异常 if (state == 2) { state = 1; } return state; } @Override public List getUserNetflixSubmitRecord(long userId) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); List netflixUseAccountStatusRecords = netflixUserAccountStatusRecordMapper.selectList(Wrappers.lambdaQuery(NetflixUserAccountStatusRecord.class) .in(NetflixUserAccountStatusRecord::getUserId, userIdList) .eq(NetflixUserAccountStatusRecord::getDeleted, 1) .select(NetflixUserAccountStatusRecord::getOrderId, NetflixUserAccountStatusRecord::getRelationId, NetflixUserAccountStatusRecord::getState, NetflixUserAccountStatusRecord::getCreatedTime)); return netflixUseAccountStatusRecords; } @Override public Long getTrialTicketByUserIdAndGoodsId(Long userId, Long trialSkuId, Integer ticketType) { Retryer build = RetryerBuilder.newBuilder() .retryIfException() //运行时异常重试 .retryIfRuntimeException() //false重试 .retryIfResult(res -> res == null) //1s 间隔 .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS)) //停止策略 : 尝试请求3次 .withStopStrategy(StopStrategies.stopAfterAttempt(3)).build(); try { return build.call(() -> { //体验规格 GroupsTrips groups = groupsMapper.selectCollegeStudentUserGptTicket(trialSkuId); GroupsRelation relation = null; if (groups != null) { relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId()); } if (relation == null) { //生成空车队 GoodsDonSku sku = goodsDonSkuMapper.selectById(trialSkuId); relation = groupsFuncService.createNewGroupsTrips(sku); } DateTime startTime = DateTime.now(); DateTime expiryTime = DateUtil.offsetDay(startTime, 1); int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class) .set(GroupsRelation::getUserId, userId) .set(GroupsRelation::getStartTime, startTime) .set(GroupsRelation::getExpiryTime, expiryTime) .set(GroupsRelation::getStatus, GroupsRelation.Status.validity) .set(GroupsRelation::getAqType, ticketType) .eq(GroupsRelation::getId, relation.getId()) .eq(GroupsRelation::getUserId, 0)); if (update > 0) { groupsMapper.decrAvailableNum(groups.getId()); return relation.getId(); } log.error("发送用户:{} GPT镜像车票体验失败,进行重试", userId); return null; }); } catch (ExecutionException | RetryException e) { log.error("发送用户GPT镜像体验失败:{}", StringUtil.getErrorText(e)); return null; } } @Override public Boolean getMirrorPopups(long userId) { //是否弹窗 默认否 Boolean flag = false; List userIdList = userBindRelationService.getRelationUserIdList(userId, null); Number number = beanSearcher.searchCount(RenewalView.class, MapUtils.builder() .field(RenewalView::getUserId, userIdList).op(Operator.InList) .field(RenewalView::getStatus, GroupsRelation.Status.validity.name()) .field(RenewalView::getAqType, Constant.WHOLESALE_TICKET_TYPE).op(Operator.NotEqual) .field(RenewalView::getIsMirror, true) .build()); if (number.intValue() == 0) { flag = true; } if (!flag) { String thisWeekBegin = DateUtil.beginOfWeek(DateTime.now()).toDateStr(); Integer selectCount = mirrorTicketPopupsRecordMapper.selectCount(Wrappers.lambdaQuery(MirrorTicketPopupsRecord.class) .in(MirrorTicketPopupsRecord::getUserId, userIdList) .eq(MirrorTicketPopupsRecord::getThisWeek, thisWeekBegin)); if (selectCount == 0) { MirrorTicketPopupsRecord mirrorTicketPopupsRecord = new MirrorTicketPopupsRecord(); mirrorTicketPopupsRecord.setThisWeek(thisWeekBegin); mirrorTicketPopupsRecord.setUserId(userId); mirrorTicketPopupsRecordMapper.insert(mirrorTicketPopupsRecord); } else { flag = true; } } return flag; } @Override public Long getTicket(Long userId, Long skuId, Boolean isVip) { Retryer build = RetryerBuilder.newBuilder() .retryIfException() //运行时异常重试 .retryIfRuntimeException() //false重试 .retryIfResult(res -> res == null) //1s 间隔 .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS)) //停止策略 : 尝试请求1次 .withStopStrategy(StopStrategies.stopAfterAttempt(1)).build(); try { return build.call(() -> { GroupsTrips groups = groupsMapper.selectCollegeStudentUserGptTicket(skuId); GroupsRelation relation = null; if (groups != null) { relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId()); } GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId); //生成空车队 if (relation == null) { relation = groupsFuncService.createNewGroupsTrips(sku); } DateTime startTime = DateTime.now(); DateTime expiryTime; if (sku.getDays() != null) { expiryTime = DateUtil.offsetDay(startTime, sku.getDays()); } else { expiryTime = DateUtil.offsetMonth(startTime, sku.getMonths()); } int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class) .set(GroupsRelation::getUserId, userId) .set(GroupsRelation::getStartTime, startTime) .set(GroupsRelation::getExpiryTime, expiryTime) .set(GroupsRelation::getStatus, GroupsRelation.Status.validity) .set(GroupsRelation::getIsVip, isVip) .eq(GroupsRelation::getId, relation.getId()) .eq(GroupsRelation::getUserId, 0)); if (update > 0) { groupsMapper.decrAvailableNum(groups.getId()); return relation.getId(); } log.error("发送用户:{} GPT镜像车票失败,进行重试", userId); return null; }); } catch (ExecutionException | RetryException e) { log.error("发送用户GPT镜像失败:{}", StringUtil.getErrorText(e)); return null; } } @Override public Boolean getVipMirrorTicketIfEmpty(long userId, Long skuId) { Integer selectCount = vipGoodsSkuMapper.selectCount(Wrappers.lambdaQuery(VipGoodsSku.class) .eq(VipGoodsSku::getSkuId, skuId)); if (selectCount == 0) { return false; } List userIdList = userBindRelationService.getRelationUserIdList(userId, null); VipUser vipUser = vipUserMapper.selectOne(Wrappers.lambdaQuery(VipUser.class) .in(VipUser::getUserId, userIdList) .gt(VipUser::getExpiryTime, DateTime.now()) .last("limit 1")); //不是会员 或已到期 if (vipUser == null) { return false; } Number number = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder() .field(GroupsRelationView::getUserId, userIdList).op(Operator.InList) .field(GroupsRelationView::getSkuId, skuId) .field(GroupsRelationView::getIsVip, Boolean.TRUE) .build()); if (number.intValue() == 0) { Long relationId = getTicket(vipUser.getUserId(), skuId, Boolean.TRUE); //同步时间 groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class) .set(GroupsRelation::getExpiryTime, vipUser.getExpiryTime()) .eq(GroupsRelation::getUserId, vipUser.getUserId()) .eq(GroupsRelation::getId, relationId)); return true; } return false; } private DistributePosterGoodsDetailView setGoodsPoster(RenewalView ticket, User user, List userIds) { DistributePosterGoodsDetailView distributePosterGoodsDetailView = beanSearcher.searchFirst(DistributePosterGoodsDetailView.class, MapUtils.flatBuilder(request.getParameterMap()) .field(DistributePosterGoodsFrontView::getGoodsId, ticket.getGoodsId()).build()); if (distributePosterGoodsDetailView == null) { return null; } distributePosterGoodsDetailView.setNickname(user.getNickname()); UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class) .eq(UserDistribute::getUserId, user.getId()) .eq(UserDistribute::getDeleted, 1) .last("limit 1")); if (userDistribute != null) { UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class) .eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId()) .eq(UserPlatDistributeRate::getGoodsId, ticket.getGoodsId()) .last("limit 1")); if (userPlatDistributeRate != null) { distributePosterGoodsDetailView.setRate(userPlatDistributeRate.getRate()); } } GoodsDon goodsDon = goodsDonMapper.selectById(ticket.getGoodsId()); if (goodsDon.getIsSkuDistribute()) { if (userDistribute != null) { UserPlatSkuDistributeRate userPlatSkuDistributeRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class) .eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId()) .eq(UserPlatSkuDistributeRate::getSkuId, ticket.getSkuId()) .last("limit 1")); if (userPlatSkuDistributeRate != null) { distributePosterGoodsDetailView.setRate(userPlatSkuDistributeRate.getRate()); } } else { DistributeGeneralSkuRate distributeGeneralSkuRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class) .eq(DistributeGeneralSkuRate::getSkuId, ticket.getSkuId()) .last("limit 1")); if (distributeGeneralSkuRate != null) { distributePosterGoodsDetailView.setRate(distributeGeneralSkuRate.getRate()); } } } //用户推广海报记录id Optional.ofNullable(userDistributePosterRecordMapper.selectOne(Wrappers.lambdaQuery(UserDistributePosterRecord.class) .eq(UserDistributePosterRecord::getPosterId, distributePosterGoodsDetailView.getId()) .in(UserDistributePosterRecord::getUserId, userIds) .last("limit 1"))).ifPresent(re -> distributePosterGoodsDetailView.setRid(re.getId())); return distributePosterGoodsDetailView; } private void setRenewDiscount(RenewalView ticket) { //镜像或者独立规格 if (ticket.getIsMirror() || (ticket.getSkuNum() != null && ticket.getSkuNum() == 1)) { RenewUpgradePackage renewUpgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class) .eq(RenewUpgradePackage::getGoodsId, ticket.getGoodsId()) .eq(RenewUpgradePackage::getStatus, 1) .eq(RenewUpgradePackage::getDeleted, 1) .eq(RenewUpgradePackage::getSkuId, ticket.getSkuId()) .orderByAsc(RenewUpgradePackage::getDiscount) .last("limit 1") .select(RenewUpgradePackage::getId, RenewUpgradePackage::getDiscount)); if (renewUpgradePackage != null) { ticket.setDiscount(renewUpgradePackage.getDiscount()); } } } private void setMirrorTicketInfo(RenewalView ticket) { //设置MJ镜像信息 setMjMirrorInfo(ticket); //设置GPT镜像信息 setGptMirrorInfo(ticket); //clause pro setClaudeProInfo(ticket); //luma setLumaInfo(ticket); } private void setMjMirrorInfo(RenewalView ticket) { if (ticket.getGoodsId() == 26 && ticket.getIsMirror()) { List upgradePackages = upgradePackageMapper.selectList(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + ticket.getSkuId() + "\"')").eq(UpgradePackage::getStatus, Boolean.TRUE).eq(UpgradePackage::getDeleted, Boolean.TRUE)); if (CollectionUtil.isNotEmpty(upgradePackages)) { upgradePackages.stream().map(e -> e.getPrice().divide(BigDecimal.valueOf(e.getNum()), 2, RoundingMode.HALF_UP)).min(BigDecimal::compareTo).ifPresent(ticket::setMjPackagePrice); } try { MidjourneyUserView search = beanSearcher.searchFirst(MidjourneyUserView.class, MapUtils.flatBuilder(request.getParameterMap()) .field(MidjourneyUserView::getUserId, ticket.getUserId()).field(MidjourneyUserView::getRelationId, ticket.getRelationId()) .onlySelect(MidjourneyUserView::getMjUserRelaxNum, MidjourneyUserView::getMjUserFastNum, MidjourneyUserView::getIsCar) .build()); if (search == null) { MidjourneyUser midjourneyUser = midjourneyAccountService.getMidjourneyUserToken(ticket.getUserId(), ticket.getRelationId()); ticket.setMjUserFastNum(midjourneyUser.getMjFastNum()); ticket.setMjUserRelaxNum(midjourneyUser.getMjRelaxNum()); ticket.setIsCar(false); } else { ticket.setIsCar(search.getIsCar()); ticket.setMjUserFastNum(search.getMjUserFastNum()); ticket.setMjUserRelaxNum(search.getMjUserRelaxNum()); } midjourneyAccountService.updateUserExpiryTime(ticket.getRelationId(), ticket.getExpiryTime()); } catch (Exception e) { } } } public void setGptMirrorInfo(RenewalView ticket) { if (ticket.getGoodsId() == 18 && ticket.getIsCar() && ticket.getExpiryTime() != null) { try { //gpt用户镜像 ChatGptUserView userInfo = chatGptAccountService.getUserInfo(ticket.getUserId(), ticket.getRelationId()); ticket.setGptUserLimitNum(userInfo.getLimitNum()); ticket.setGptUserLimitTime(userInfo.getLimitTime()); ticket.setUserDsLimitNum(userInfo.getDsLimitNum()); ticket.setUserDsLimitTime(userInfo.getDsLimitTime()); ticket.setUserOtherLimitNum(userInfo.getOtherLimitNum()); ticket.setUserOtherLimitTime(userInfo.getOtherLimitTime()); ticket.setUse(userInfo.getUse()); ticket.setModel(userInfo.getModel()); Integer count = upgradePackageMapper.selectCount(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + ticket.getSkuId() + "\"')") .gt(UpgradePackage::getNum, userInfo.getLimitNum()) .eq(UpgradePackage::getStatus, Boolean.TRUE) .eq(UpgradePackage::getGptType, 0) .eq(UpgradePackage::getDeleted, Boolean.TRUE)); ticket.setUpgrade(count > 0 ? true : false); ticket.setPackageId(userInfo.getPackageId()); if (userInfo.getPackageId() != 0) { UpgradePackage upgradePackage = upgradePackageMapper.selectById(userInfo.getPackageId()); ticket.setPackagePrice(upgradePackage.getPrice()); Long upgradeOrderDonSkuId = upgradePackage.getUpgradeSkuId(); GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, upgradeOrderDonSkuId).build()); renewSku.setPackageId(userInfo.getPackageId()); ticket.setRenewSku(renewSku); } ticket.setIsRenewPackage(userInfo.getIsRenewPackage()); Long renewSkuId = userInfo.getRenewSkuId(); if (renewSkuId != null) { GoodsDonSkuRenewView upgradeSkuRenewView = ticket.getRenewSku(); GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, renewSkuId).build()); //续费升级是更高级规格 if (upgradeSkuRenewView == null || (renewSku.getGptUserLimitNum() >= upgradeSkuRenewView.getGptUserLimitNum() && renewSku.getMonths() >= userInfo.getMonths())) { Optional.ofNullable(orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class) .eq(OrderDonRenewRecord::getOrderId, userInfo.getRenewOrderId()) .last("limit 1"))).ifPresent(e -> renewSku.setOriginalOrderId(e.getOrderId())); ticket.setRenewSku(renewSku); } } } catch (Exception e) { } } } public void setClaudeProInfo(RenewalView ticket) { //clause pro if (ticket.getGoodsId() == 75l && ticket.getExpiryTime() != null) { try { ClaudeUserView userInfo = claudeService.getUserInfo(ticket.getUserId(), ticket.getRelationId()); ticket.setGptUserLimitNum(userInfo.getLimitNum()); ticket.setGptUserLimitTime(userInfo.getLimitTime()); ticket.setUse(userInfo.getUse()); Long renewSkuId = userInfo.getRenewSkuId(); if (renewSkuId != null) { GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, renewSkuId).build()); ticket.setRenewSku(renewSku); } } catch (Exception e) { } } } public void setLumaInfo(RenewalView ticket) { if (ticket.getGoodsId() == Constant.LUMA_GOODS_ID && ticket.getExpiryTime() != null) { try { List upgradePackages = upgradePackageMapper.selectList(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + ticket.getSkuId() + "\"')").eq(UpgradePackage::getStatus, Boolean.TRUE).eq(UpgradePackage::getDeleted, Boolean.TRUE)); if (CollectionUtil.isNotEmpty(upgradePackages)){ upgradePackages.stream().map(e -> e.getPrice().divide(BigDecimal.valueOf(e.getNum()), 2, RoundingMode.HALF_UP)).min(BigDecimal::compareTo).ifPresent(ticket::setLumaPackagePrice); } LumaUser lumaUser = lumaService.getLumaUser(ticket.getUserId(), ticket.getRelationId()); ticket.setLumaUserNum(lumaUser.getNum()); } catch (Exception e) { } } } /** * 获取gpt镜像天卡活动参与平台ids * @return */ private List getGptMirrorGiveawayBuyGids() { GptMirrorDayCardGiveawayActivity gptMirrorDayCardGiveawayActivity = beanSearcher.searchFirst(GptMirrorDayCardGiveawayActivity.class, MapUtils.builder().build()); if (gptMirrorDayCardGiveawayActivity != null) { String buyGoodsIds = gptMirrorDayCardGiveawayActivity.getBuyGoodsIds(); try { return Jsons.parseList(buyGoodsIds, Long.class); } catch (Exception e) { } } return null; } /** * 标记是否可抵扣会员车票 */ private void markVipDeductTicket(List userIds, RenewalView ticket, List vipSkuIds, Boolean isVip) { if (CollUtil.isNotEmpty(vipSkuIds) && !isVip) { Long skuId = ticket.getSkuId(); if (vipSkuIds.contains(skuId)) { //是否时长最长 Number number = beanSearcher.searchCount(RenewalView.class, MapUtils.builder() .field(RenewalView::getRelationId, ticket.getRelationId()).op(Operator.NotEqual) .field(RenewalView::getSkuId, skuId) .field(RenewalView::getUserId, userIds).op(Operator.InList) .field(RenewalView::getAqType, Constant.WHOLESALE_TICKET_TYPE).op(Operator.NotEqual) .field(RenewalView::getExpiryTime, ticket.getExpiryTime()).op(Operator.GreaterThan) .build()); if (number.intValue() == 0) { ticket.setIsVipDeduct(true); } } } } }