|
@@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.cyksj.common.constant.Constant;
|
|
import com.cyksj.common.constant.Constant;
|
|
|
import com.cyksj.common.exception.BusinessRuntimeException;
|
|
import com.cyksj.common.exception.BusinessRuntimeException;
|
|
|
|
|
+import com.cyksj.common.snowflake.Sequence;
|
|
|
import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
|
|
import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
|
|
|
import com.cyksj.common.util.Jsons;
|
|
import com.cyksj.common.util.Jsons;
|
|
|
import com.cyksj.common.util.StringUtil;
|
|
import com.cyksj.common.util.StringUtil;
|
|
@@ -28,9 +29,12 @@ import com.cyksj.mapper.sys.SysConfigMapper;
|
|
|
import com.cyksj.mapper.sys.SysEmailMapper;
|
|
import com.cyksj.mapper.sys.SysEmailMapper;
|
|
|
import com.cyksj.mapper.vip.VipGoodsSkuMapper;
|
|
import com.cyksj.mapper.vip.VipGoodsSkuMapper;
|
|
|
import com.cyksj.mapper.vip.VipUserMapper;
|
|
import com.cyksj.mapper.vip.VipUserMapper;
|
|
|
|
|
+import com.cyksj.model.dto.ErrorNetflixChangeOtherSkuTicketDto;
|
|
|
|
|
+import com.cyksj.model.dto.TicketChangeDto;
|
|
|
import com.cyksj.model.entity.*;
|
|
import com.cyksj.model.entity.*;
|
|
|
import com.cyksj.model.manage.views.AccountView;
|
|
import com.cyksj.model.manage.views.AccountView;
|
|
|
import com.cyksj.model.manage.views.GroupsRelationView;
|
|
import com.cyksj.model.manage.views.GroupsRelationView;
|
|
|
|
|
+import com.cyksj.model.request.ErrorNetflixChangeReq;
|
|
|
import com.cyksj.model.request.SpecialGoodsTicketReq;
|
|
import com.cyksj.model.request.SpecialGoodsTicketReq;
|
|
|
import com.cyksj.model.request.TicketLoginReq;
|
|
import com.cyksj.model.request.TicketLoginReq;
|
|
|
import com.cyksj.model.views.*;
|
|
import com.cyksj.model.views.*;
|
|
@@ -57,6 +61,7 @@ import com.ejlchina.searcher.util.MapUtils;
|
|
|
import com.github.rholder.retry.*;
|
|
import com.github.rholder.retry.*;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.dao.DuplicateKeyException;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
@@ -178,6 +183,12 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
|
|
|
|
|
private final VipGoodsSkuMapper vipGoodsSkuMapper;
|
|
private final VipGoodsSkuMapper vipGoodsSkuMapper;
|
|
|
|
|
|
|
|
|
|
+ private static final Sequence SEQUENCE = new Sequence(0);
|
|
|
|
|
+
|
|
|
|
|
+ private final NetflixUserChangeOtherTicketRecordMapper netflixUserChangeOtherTicketRecordMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final NetflixUserAccountSubmitRecoverRecordMapper netflixUserAccountSubmitRecoverRecordMapper;
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account, String orderNo, Integer cmt) {
|
|
public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account, String orderNo, Integer cmt) {
|
|
|
User u = userMapper.selectById(userId);
|
|
User u = userMapper.selectById(userId);
|
|
@@ -1406,6 +1417,97 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void netflixSubmitRecover(ErrorNetflixChangeReq req) {
|
|
|
|
|
+ Long relationId = req.getRelationId();
|
|
|
|
|
+ Long userId = req.getUserId();
|
|
|
|
|
+ //校验奈飞账号状态
|
|
|
|
|
+ GroupsRelationView netflixRelationView = checkNetflixErrorStatus(relationId, userId);
|
|
|
|
|
+ Date expiryTime = netflixRelationView.getExpiryTime();
|
|
|
|
|
+ NetflixUserAccountSubmitRecoverRecord recoverRecord = new NetflixUserAccountSubmitRecoverRecord();
|
|
|
|
|
+ recoverRecord.setRelationId(relationId);
|
|
|
|
|
+ recoverRecord.setUserId(netflixRelationView.getUserId());
|
|
|
|
|
+ recoverRecord.setSkuId(netflixRelationView.getSkuId());
|
|
|
|
|
+ recoverRecord.setAccount(netflixRelationView.getAccount());
|
|
|
|
|
+ Long betweenDay = DateUtil.betweenDay(DateTime.now(), expiryTime, false) + 1;
|
|
|
|
|
+ recoverRecord.setRemainDays(betweenDay);
|
|
|
|
|
+ try {
|
|
|
|
|
+ netflixUserAccountSubmitRecoverRecordMapper.insert(recoverRecord);
|
|
|
|
|
+ } catch (DuplicateKeyException e) {
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("您已申请恢复");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void errorNetflixSubmitChangeOtherTicket(ErrorNetflixChangeReq req) throws Exception {
|
|
|
|
|
+ Long relationId = req.getRelationId();
|
|
|
|
|
+ Long userId = req.getUserId();
|
|
|
|
|
+ //校验奈飞账号状态
|
|
|
|
|
+ GroupsRelationView netflixRelationView = checkNetflixErrorStatus(relationId, userId);
|
|
|
|
|
+ Date expiryTime = netflixRelationView.getExpiryTime();
|
|
|
|
|
+ //小于15 不可替换其他车票
|
|
|
|
|
+ Long betweenDay = DateUtil.betweenDay(DateTime.now(), expiryTime, false) + 1;
|
|
|
|
|
+ if (betweenDay <= 15) {
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("您的车票有效期未超过15天");
|
|
|
|
|
+ }
|
|
|
|
|
+ Long skuId = req.getSkuId();
|
|
|
|
|
+ SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
|
|
|
|
|
+ .eq(SysConfig::getSysKey, Constant.ERROR_NETFLIX_CHANGE_OTHER_SKU_KEY)
|
|
|
|
|
+ .last("limit 1"));
|
|
|
|
|
+ List<ErrorNetflixChangeOtherSkuTicketDto> errorNetflixChangeOtherSkuTicketDtos = Jsons.parseList(sysConfig.getSysValue(), ErrorNetflixChangeOtherSkuTicketDto.class);
|
|
|
|
|
+ ErrorNetflixChangeOtherSkuTicketDto errorNetflixChangeOtherSkuTicketDto;
|
|
|
|
|
+ //自定义顺序 直接获取
|
|
|
|
|
+ if (betweenDay <= 60) {
|
|
|
|
|
+ //检验规格
|
|
|
|
|
+ errorNetflixChangeOtherSkuTicketDto = errorNetflixChangeOtherSkuTicketDtos.get(0);
|
|
|
|
|
+ } else if (betweenDay <= 120) {
|
|
|
|
|
+ errorNetflixChangeOtherSkuTicketDto = errorNetflixChangeOtherSkuTicketDtos.get(1);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ errorNetflixChangeOtherSkuTicketDto = errorNetflixChangeOtherSkuTicketDtos.get(2);
|
|
|
|
|
+ }
|
|
|
|
|
+ List<Long> availableSkuIds = errorNetflixChangeOtherSkuTicketDto.getSkuIds();
|
|
|
|
|
+ if (!availableSkuIds.contains(skuId)) {
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("不支持更换该类型车票");
|
|
|
|
|
+ }
|
|
|
|
|
+ //替换车票
|
|
|
|
|
+ TicketChangeDto changeDto = getTicketAndGenerateOrder(userId, skuId, netflixRelationView.getStartTime(), expiryTime);
|
|
|
|
|
+ //替换记录
|
|
|
|
|
+ NetflixUserChangeOtherTicketRecord changeOtherTicketRecord = new NetflixUserChangeOtherTicketRecord();
|
|
|
|
|
+ changeOtherTicketRecord.setUserId(userId);
|
|
|
|
|
+ changeOtherTicketRecord.setRelationId(relationId);
|
|
|
|
|
+ changeOtherTicketRecord.setOtherRelationId(changeDto.getOtherRelationId());
|
|
|
|
|
+ changeOtherTicketRecord.setRelateOrderId(changeDto.getOtherOrderId());
|
|
|
|
|
+ netflixUserChangeOtherTicketRecordMapper.insert(changeOtherTicketRecord);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<GoodsCategorySkuView> getNetflixReplaceOtherSkus(long userId, Long relationId) throws Exception {
|
|
|
|
|
+ //校验奈飞账号状态
|
|
|
|
|
+ GroupsRelationView netflixRelationView = checkNetflixErrorStatus(relationId, userId);
|
|
|
|
|
+ Date expiryTime = netflixRelationView.getExpiryTime();
|
|
|
|
|
+ //小于15 不可替换其他车票
|
|
|
|
|
+ Long betweenDay = DateUtil.betweenDay(DateTime.now(), expiryTime, false) + 1;
|
|
|
|
|
+ SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
|
|
|
|
|
+ .eq(SysConfig::getSysKey, Constant.ERROR_NETFLIX_CHANGE_OTHER_SKU_KEY)
|
|
|
|
|
+ .last("limit 1"));
|
|
|
|
|
+ List<ErrorNetflixChangeOtherSkuTicketDto> errorNetflixChangeOtherSkuTicketDtos = Jsons.parseList(sysConfig.getSysValue(), ErrorNetflixChangeOtherSkuTicketDto.class);
|
|
|
|
|
+ ErrorNetflixChangeOtherSkuTicketDto errorNetflixChangeOtherSkuTicketDto;
|
|
|
|
|
+ if (betweenDay <= 15) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ //自定义顺序 直接获取
|
|
|
|
|
+ if (betweenDay <= 60) {
|
|
|
|
|
+ //检验规格
|
|
|
|
|
+ errorNetflixChangeOtherSkuTicketDto = errorNetflixChangeOtherSkuTicketDtos.get(0);
|
|
|
|
|
+ } else if (betweenDay <= 120) {
|
|
|
|
|
+ errorNetflixChangeOtherSkuTicketDto = errorNetflixChangeOtherSkuTicketDtos.get(1);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ errorNetflixChangeOtherSkuTicketDto = errorNetflixChangeOtherSkuTicketDtos.get(2);
|
|
|
|
|
+ }
|
|
|
|
|
+ List<GoodsCategorySkuView> goodsCategorySkuViews = beanSearcher.searchAll(GoodsCategorySkuView.class, MapUtils.builder().field(GoodsCategorySkuView::getSkuId, errorNetflixChangeOtherSkuTicketDto.getSkuIds()).build());
|
|
|
|
|
+ return goodsCategorySkuViews;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private DistributePosterGoodsDetailView setGoodsPoster(RenewalView ticket, User user, List<Long> userIds) {
|
|
private DistributePosterGoodsDetailView setGoodsPoster(RenewalView ticket, User user, List<Long> userIds) {
|
|
|
DistributePosterGoodsDetailView distributePosterGoodsDetailView = beanSearcher.searchFirst(DistributePosterGoodsDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
|
|
DistributePosterGoodsDetailView distributePosterGoodsDetailView = beanSearcher.searchFirst(DistributePosterGoodsDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
|
|
|
.field(DistributePosterGoodsFrontView::getGoodsId, ticket.getGoodsId()).build());
|
|
.field(DistributePosterGoodsFrontView::getGoodsId, ticket.getGoodsId()).build());
|
|
@@ -1625,4 +1727,116 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检验奈飞账号状态
|
|
|
|
|
+ */
|
|
|
|
|
+ public GroupsRelationView checkNetflixErrorStatus(Long relationId, Long userId) {
|
|
|
|
|
+ List<Long> 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();
|
|
|
|
|
+ if (state == 0) {
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("您的账号检测中");
|
|
|
|
|
+ }
|
|
|
|
|
+ //2是登录失败 3是被封号
|
|
|
|
|
+ if (state != 3) {
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("您的账号未封禁");
|
|
|
|
|
+ }
|
|
|
|
|
+ GroupsRelationView netflixRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder()
|
|
|
|
|
+ .field(GroupsRelationView::getId, relationId)
|
|
|
|
|
+ .field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
|
|
|
|
|
+ .field(GroupsRelationView::getGoodsId, Constant.NETFLIX_GID)
|
|
|
|
|
+ .field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
|
|
|
|
|
+ .build());
|
|
|
|
|
+ if (netflixRelationView == null) {
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("奈飞车票已过期");
|
|
|
|
|
+ }
|
|
|
|
|
+ return netflixRelationView;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取车票 并生成订单
|
|
|
|
|
+ */
|
|
|
|
|
+ public TicketChangeDto getTicketAndGenerateOrder(Long userId, Long skuId, Date startTime, Date expiryTime) {
|
|
|
|
|
+ Retryer<TicketChangeDto> build = RetryerBuilder.<TicketChangeDto>newBuilder()
|
|
|
|
|
+ .retryIfException()
|
|
|
|
|
+ //运行时异常重试
|
|
|
|
|
+ .retryIfRuntimeException()
|
|
|
|
|
+ //false重试
|
|
|
|
|
+ .retryIfResult(res -> res == null)
|
|
|
|
|
+ //1s 间隔
|
|
|
|
|
+ .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
|
|
|
|
|
+ //停止策略 : 尝试请求1次
|
|
|
|
|
+ .withStopStrategy(StopStrategies.stopAfterAttempt(1)).build();
|
|
|
|
|
+ if (startTime == null) {
|
|
|
|
|
+ startTime = DateTime.now();
|
|
|
|
|
+ }
|
|
|
|
|
+ GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
|
|
|
|
|
+ if (expiryTime == null) {
|
|
|
|
|
+ if (sku.getDays() != null) {
|
|
|
|
|
+ expiryTime = DateUtil.offsetDay(startTime, sku.getDays());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ expiryTime = DateUtil.offsetMonth(startTime, sku.getMonths());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ Date finalStartTime = startTime;
|
|
|
|
|
+ Date finalExpiryTime = expiryTime;
|
|
|
|
|
+ try {
|
|
|
|
|
+ return build.call(() -> {
|
|
|
|
|
+ GroupsTrips groups = groupsMapper.selectCollegeStudentUserGptTicket(skuId);
|
|
|
|
|
+ GroupsRelation relation = null;
|
|
|
|
|
+ if (groups != null) {
|
|
|
|
|
+ relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ //生成空车队
|
|
|
|
|
+ if (relation == null) {
|
|
|
|
|
+ relation = groupsFuncService.createNewGroupsTrips(sku);
|
|
|
|
|
+ }
|
|
|
|
|
+ int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
|
|
|
|
|
+ .set(GroupsRelation::getUserId, userId)
|
|
|
|
|
+ .set(GroupsRelation::getStartTime, finalStartTime)
|
|
|
|
|
+ .set(GroupsRelation::getExpiryTime, finalExpiryTime)
|
|
|
|
|
+ .set(GroupsRelation::getStatus, GroupsRelation.Status.validity)
|
|
|
|
|
+ .eq(GroupsRelation::getId, relation.getId())
|
|
|
|
|
+ .eq(GroupsRelation::getUserId, 0));
|
|
|
|
|
+ if (update > 0) {
|
|
|
|
|
+ groupsMapper.decrAvailableNum(groups.getId());
|
|
|
|
|
+ Long relationId = relation.getId();
|
|
|
|
|
+ //生成新的订单
|
|
|
|
|
+ OrderDon otherOrderDon = generateNewTicketOrder(relationId, userId, sku);
|
|
|
|
|
+
|
|
|
|
|
+ TicketChangeDto ticketChangeDto = new TicketChangeDto();
|
|
|
|
|
+ ticketChangeDto.setOtherRelationId(relationId);
|
|
|
|
|
+ ticketChangeDto.setOtherOrderId(otherOrderDon.getId());
|
|
|
|
|
+ return ticketChangeDto;
|
|
|
|
|
+ }
|
|
|
|
|
+ log.error("发送用户:{} GPT镜像车票失败,进行重试", userId);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch (ExecutionException | RetryException e) {
|
|
|
|
|
+ log.error("发送用户GPT镜像失败:{}", StringUtil.getErrorText(e));
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private OrderDon generateNewTicketOrder(Long relationId, Long userId, GoodsDonSku sku) {
|
|
|
|
|
+ OrderDon orderDon = new OrderDon();
|
|
|
|
|
+ orderDon.setUserId(userId);
|
|
|
|
|
+ orderDon.setOrderNo(SEQUENCE.nextId().toString());
|
|
|
|
|
+ orderDon.setMoney(BigDecimal.ZERO);
|
|
|
|
|
+ orderDon.setRelationId(relationId);
|
|
|
|
|
+ orderDon.setGoodsId(sku.getGoodsId());
|
|
|
|
|
+ orderDon.setSkuId(sku.getId());
|
|
|
|
|
+ orderDon.setType(OrderDon.Type.TICKET_REPLACE);
|
|
|
|
|
+ orderDon.setStatus(OrderDon.Status.complete);
|
|
|
|
|
+ orderDonMapper.insert(orderDon);
|
|
|
|
|
+ return orderDon;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|