|
|
@@ -13,6 +13,7 @@ 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.snowflake.Sequence;
|
|
|
import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
|
|
|
import com.cyksj.common.util.Jsons;
|
|
|
import com.cyksj.common.util.StringUtil;
|
|
|
@@ -28,11 +29,18 @@ 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.dto.ErrorNetflixChangeOtherSkuTicketDto;
|
|
|
+import com.cyksj.model.dto.TicketChangeDto;
|
|
|
import com.cyksj.model.entity.*;
|
|
|
import com.cyksj.model.manage.views.AccountView;
|
|
|
import com.cyksj.model.manage.views.GroupsRelationView;
|
|
|
+import com.cyksj.model.request.ErrorNetflixChangeReq;
|
|
|
+import com.cyksj.model.request.OrderRefundReq;
|
|
|
import com.cyksj.model.request.SpecialGoodsTicketReq;
|
|
|
import com.cyksj.model.request.TicketLoginReq;
|
|
|
+import com.cyksj.model.response.NetflixErrorAccountStatus;
|
|
|
+import com.cyksj.model.response.NetflixRecoverResp;
|
|
|
+import com.cyksj.model.response.NetflixRefundInfoResp;
|
|
|
import com.cyksj.model.views.*;
|
|
|
import com.cyksj.redis.RedisService;
|
|
|
import com.cyksj.service.chatgpt.ChatGptAccountService;
|
|
|
@@ -44,6 +52,8 @@ 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.order.OrderRefundService;
|
|
|
+import com.cyksj.service.relation.GroupRelationClearService;
|
|
|
import com.cyksj.service.relation.GroupRelationFrontService;
|
|
|
import com.cyksj.service.relation.GroupsRelationChangeService;
|
|
|
import com.cyksj.service.relation.GroupsRelationNetflixService;
|
|
|
@@ -57,6 +67,7 @@ import com.ejlchina.searcher.util.MapUtils;
|
|
|
import com.github.rholder.retry.*;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.dao.DuplicateKeyException;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
@@ -178,6 +189,16 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
|
|
|
private final VipGoodsSkuMapper vipGoodsSkuMapper;
|
|
|
|
|
|
+ private static final Sequence SEQUENCE = new Sequence(0);
|
|
|
+
|
|
|
+ private final NetflixUserChangeOtherTicketRecordMapper netflixUserChangeOtherTicketRecordMapper;
|
|
|
+
|
|
|
+ private final NetflixUserAccountSubmitRecoverRecordMapper netflixUserAccountSubmitRecoverRecordMapper;
|
|
|
+
|
|
|
+ private final OrderRefundService orderRefundService;
|
|
|
+
|
|
|
+ private final GroupRelationClearService clearService;
|
|
|
+
|
|
|
@Override
|
|
|
public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account, String orderNo, Integer cmt) {
|
|
|
User u = userMapper.selectById(userId);
|
|
|
@@ -1177,8 +1198,9 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
|
|
|
Integer selectCount = netflixUserAccountStatusRecordMapper.selectCount(Wrappers.lambdaQuery(NetflixUserAccountStatusRecord.class)
|
|
|
.eq(NetflixUserAccountStatusRecord::getRelationId, relationId)
|
|
|
- .eq(NetflixUserAccountStatusRecord::getUserId, userId)
|
|
|
- .eq(NetflixUserAccountStatusRecord::getAccount, account));
|
|
|
+ .in(NetflixUserAccountStatusRecord::getUserId, userIdList)
|
|
|
+ .eq(NetflixUserAccountStatusRecord::getAccount, account)
|
|
|
+ .eq(NetflixUserAccountStatusRecord::getDeleted, 1));
|
|
|
if (selectCount > 0) {
|
|
|
throw BusinessRuntimeException.getInstance("该账号正在检测中");
|
|
|
}
|
|
|
@@ -1189,16 +1211,22 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
if (accountNetflixState != null && accountNetflixState.getState() == 3) {
|
|
|
state = accountNetflixState.getState();
|
|
|
}
|
|
|
+ //非正常状态
|
|
|
+ if (state != 1) {
|
|
|
+ //20号之前得校验 直接失败
|
|
|
+ if (renewalView.getCreatedTime().compareTo(DateUtil.parse("2025-06-20")) < 0) {
|
|
|
+ state = 3;
|
|
|
+ }
|
|
|
+ }
|
|
|
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())
|
|
|
+ .in(OrderDon::getUserId, userIdList)
|
|
|
.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
|
|
|
.orderByDesc(OrderDon::getId)
|
|
|
.last("limit 1"));
|
|
|
@@ -1209,28 +1237,47 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public Integer getNetflixErrorAccountStatus(long userId, Long relationId) {
|
|
|
+ public NetflixErrorAccountStatus getNetflixErrorAccountStatus(long userId, Long relationId) {
|
|
|
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"));
|
|
|
+ NetflixErrorAccountStatus status = new NetflixErrorAccountStatus();
|
|
|
if (netflixUseAccountStatusRecord == null) {
|
|
|
- throw BusinessRuntimeException.getInstance("未有提交记录");
|
|
|
+ //是否已经更换
|
|
|
+ NetflixUserAccountSubmitRecoverRecord replaceRecover = netflixUserAccountSubmitRecoverRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class)
|
|
|
+ .eq(NetflixUserAccountSubmitRecoverRecord::getUserId, userIdList)
|
|
|
+ .eq(NetflixUserAccountSubmitRecoverRecord::getReplaceRelationId, relationId)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (replaceRecover != null) {
|
|
|
+ status.setRecoverStatus(replaceRecover.getStatus());
|
|
|
+ }
|
|
|
+ return status;
|
|
|
}
|
|
|
Integer state = netflixUseAccountStatusRecord.getState();
|
|
|
//2是登录失败 3是被封号
|
|
|
- if (state == 3) {
|
|
|
- if (netflixUseAccountStatusRecord.getCreatedTime().compareTo(DateUtil.offsetMinute(DateTime.now(), -10)) > 0) {
|
|
|
- state = 0;
|
|
|
- }
|
|
|
- }
|
|
|
+// if (state == 3) {
|
|
|
+// if (netflixUseAccountStatusRecord.getCreatedTime().compareTo(DateUtil.offsetMinute(DateTime.now(), -10)) > 0) {
|
|
|
+// state = 0;
|
|
|
+// }
|
|
|
+// }
|
|
|
//登录失败不算异常
|
|
|
if (state == 2) {
|
|
|
state = 1;
|
|
|
}
|
|
|
- return state;
|
|
|
+ //账号检测状态
|
|
|
+ status.setNfStatus(state);
|
|
|
+ NetflixUserAccountSubmitRecoverRecord recoverRecord = netflixUserAccountSubmitRecoverRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class)
|
|
|
+ .in(NetflixUserAccountSubmitRecoverRecord::getUserId, userIdList)
|
|
|
+ .eq(NetflixUserAccountSubmitRecoverRecord::getRelationId, relationId)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (recoverRecord != null) {
|
|
|
+ //申请恢复状态
|
|
|
+ status.setRecoverStatus(recoverRecord.getStatus());
|
|
|
+ }
|
|
|
+ return status;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -1406,6 +1453,248 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public NetflixRecoverResp netflixSubmitRecover(ErrorNetflixChangeReq req) {
|
|
|
+ Long relationId = req.getRelationId();
|
|
|
+ Long userId = req.getUserId();
|
|
|
+ //校验奈飞账号状态
|
|
|
+ GroupsRelationView netflixRelationView = checkNetflixErrorStatus(relationId, userId);
|
|
|
+ Date expiryTime = netflixRelationView.getExpiryTime();
|
|
|
+ List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
|
|
|
+ NetflixUserAccountSubmitRecoverRecord recoverRecord = netflixUserAccountSubmitRecoverRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class)
|
|
|
+ .eq(NetflixUserAccountSubmitRecoverRecord::getRelationId, relationId)
|
|
|
+ .in(NetflixUserAccountSubmitRecoverRecord::getUserId, userIdList)
|
|
|
+ .eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 0)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (recoverRecord == null) {
|
|
|
+ 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);
|
|
|
+ recoverRecord.setAccount(netflixRelationView.getTripsAccount());
|
|
|
+ try {
|
|
|
+ netflixUserAccountSubmitRecoverRecordMapper.insert(recoverRecord);
|
|
|
+ } catch (DuplicateKeyException e) {
|
|
|
+ throw BusinessRuntimeException.getInstance("您已申请恢复");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //等待位数
|
|
|
+ Integer selectCount = netflixUserAccountSubmitRecoverRecordMapper.selectCount(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class)
|
|
|
+ .lt(NetflixUserAccountSubmitRecoverRecord::getCreatedTime, recoverRecord.getCreatedTime())
|
|
|
+ .eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 0));
|
|
|
+ NetflixRecoverResp recoverResp = new NetflixRecoverResp();
|
|
|
+ recoverResp.setIndex(selectCount + 1);
|
|
|
+ recoverResp.setRemainDays(recoverRecord.getRemainDays());
|
|
|
+ return recoverResp;
|
|
|
+ }
|
|
|
+
|
|
|
+ @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天");
|
|
|
+ }
|
|
|
+ List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
|
|
|
+ Integer count = netflixUserAccountSubmitRecoverRecordMapper.selectCount(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class)
|
|
|
+ .eq(NetflixUserAccountSubmitRecoverRecord::getRelationId, relationId)
|
|
|
+ .in(NetflixUserAccountSubmitRecoverRecord::getUserId, userIdList));
|
|
|
+ if (count > 0) {
|
|
|
+ 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("正在更换其他车票中..");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ 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, null, null);
|
|
|
+ //替换记录
|
|
|
+ NetflixUserChangeOtherTicketRecord changeOtherTicketRecord = new NetflixUserChangeOtherTicketRecord();
|
|
|
+ changeOtherTicketRecord.setUserId(userId);
|
|
|
+ changeOtherTicketRecord.setRelationId(relationId);
|
|
|
+ changeOtherTicketRecord.setOtherRelationId(changeDto.getOtherRelationId());
|
|
|
+ changeOtherTicketRecord.setRelateOrderId(changeDto.getOtherOrderId());
|
|
|
+ //该车票订单id
|
|
|
+ changeOtherTicketRecord.setOrderId(netflixRelationView.getNfOriOrderId());
|
|
|
+ changeOtherTicketRecord.setStartTime(netflixRelationView.getStartTime());
|
|
|
+ changeOtherTicketRecord.setExpiryTime(expiryTime);
|
|
|
+ netflixUserChangeOtherTicketRecordMapper.insert(changeOtherTicketRecord);
|
|
|
+ if (netflixRelationView.getNfCheckId() != null) {
|
|
|
+ netflixUserAccountStatusRecordMapper.update(null, Wrappers.lambdaUpdate(NetflixUserAccountStatusRecord.class)
|
|
|
+ .set(NetflixUserAccountStatusRecord::getDeleted, false)
|
|
|
+ .eq(NetflixUserAccountStatusRecord::getId, netflixRelationView.getNfCheckId()));
|
|
|
+ }
|
|
|
+ //清除车票
|
|
|
+ GroupsRelation clearRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
|
|
|
+ .eq(GroupsRelation::getId, relationId)
|
|
|
+ .in(GroupsRelation::getUserId, userIdList)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (clearRelation != null) {
|
|
|
+ clearService.clearTicket(clearRelation, UserTicketClearedRecord.Source.ticket_replace);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ redisService.del(key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ @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()).op(Operator.InList)
|
|
|
+ .orderBy(GoodsCategorySkuView::getPrice)
|
|
|
+ .build());
|
|
|
+ return goodsCategorySkuViews;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public NetflixRefundInfoResp refundNetflixInfo(Long userId, Long relationId) {
|
|
|
+ //校验奈飞账号状态
|
|
|
+ GroupsRelationView netflixRelationView = checkNetflixErrorStatus(relationId, userId);
|
|
|
+ Date expiryTime = netflixRelationView.getExpiryTime();
|
|
|
+ //小于15
|
|
|
+ Long betweenDay = DateUtil.betweenDay(DateTime.now(), expiryTime, false) + 1;
|
|
|
+ NetflixRefundInfoResp refundInfoResp = new NetflixRefundInfoResp();
|
|
|
+ refundInfoResp.setIsRefund(true);
|
|
|
+ if (betweenDay > 15) {
|
|
|
+ refundInfoResp.setIsRefund(false);
|
|
|
+ }
|
|
|
+ List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
|
|
|
+ OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
|
|
|
+ .eq(OrderDon::getRelationId, relationId)
|
|
|
+ .in(OrderDon::getUserId, userIdList)
|
|
|
+ .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
|
|
|
+ .orderByDesc(OrderDon::getId)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (orderDon == null) {
|
|
|
+ refundInfoResp.setIsRefund(false);
|
|
|
+ }
|
|
|
+ Long skuId = netflixRelationView.getSkuId();
|
|
|
+ GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
|
|
|
+ BigDecimal orderMoney = orderDon == null ? BigDecimal.ZERO : orderDon.getMoney();
|
|
|
+ if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
+ refundInfoResp.setIsRefund(false);
|
|
|
+ }
|
|
|
+ //每天单价
|
|
|
+ BigDecimal dayPrice = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths() * 30), RoundingMode.DOWN);
|
|
|
+ //需要退款金额
|
|
|
+ BigDecimal refundMoney = dayPrice.multiply(BigDecimal.valueOf(betweenDay));
|
|
|
+ refundInfoResp.setPrice(refundMoney);
|
|
|
+ BigDecimal balance = Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO);
|
|
|
+ //超过本身订单金额 不允许退款
|
|
|
+ if (refundMoney.compareTo(orderMoney) > 0) {
|
|
|
+ refundInfoResp.setIsRefund(false);
|
|
|
+ }
|
|
|
+ if (refundMoney.compareTo(orderMoney.add(balance)) > 0) {
|
|
|
+ refundInfoResp.setPrice(orderMoney.add(balance));
|
|
|
+ }
|
|
|
+ refundInfoResp.setRemainDays(betweenDay);
|
|
|
+ return refundInfoResp;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean refundNetflix(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天可退款");
|
|
|
+ }
|
|
|
+ List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
|
|
|
+ OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
|
|
|
+ .eq(OrderDon::getRelationId, relationId)
|
|
|
+ .in(OrderDon::getUserId, userIdList)
|
|
|
+ .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
|
|
|
+ .orderByDesc(OrderDon::getId)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (orderDon == null) {
|
|
|
+ throw BusinessRuntimeException.getInstance("对应车票订单不存在,请联系客服");
|
|
|
+ }
|
|
|
+ Long skuId = netflixRelationView.getSkuId();
|
|
|
+ GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
|
|
|
+ BigDecimal orderMoney = orderDon.getMoney();
|
|
|
+ if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
+ throw BusinessRuntimeException.getInstance("不符合退款条件");
|
|
|
+ }
|
|
|
+ //每天单价
|
|
|
+ BigDecimal dayPrice = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths() * 30), RoundingMode.DOWN);
|
|
|
+ //需要退款金额
|
|
|
+ BigDecimal refundMoney = dayPrice.multiply(BigDecimal.valueOf(betweenDay));
|
|
|
+ if (refundMoney.compareTo(orderMoney) > 0) {
|
|
|
+ throw BusinessRuntimeException.getInstance("不符合退款条件");
|
|
|
+ }
|
|
|
+ //调用第三方接口退款
|
|
|
+ OrderRefundReq refundReq = new OrderRefundReq();
|
|
|
+ refundReq.setRefundMoney(refundMoney);
|
|
|
+ refundReq.setRefundType("money");
|
|
|
+ String outNo = orderRefundService.centerRefund(refundReq, orderDon);
|
|
|
+ orderDon.setStatus(OrderDon.Status.refund);
|
|
|
+ orderDon.setRefundMoney(refundMoney);
|
|
|
+ GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
|
|
|
+ orderRefundService.refundRecord(orderDon, refundMoney, "系统", goodsDon, sku, outNo, orderDon.getType().name(), null);
|
|
|
+ //清除车票
|
|
|
+ GroupsRelation relation = groupsRelationMapper.selectById(relationId);
|
|
|
+ clearService.clearTicket(relation, UserTicketClearedRecord.Source.refund);
|
|
|
+ if (netflixRelationView.getNfCheckId() != null) {
|
|
|
+ netflixUserAccountStatusRecordMapper.update(null, Wrappers.lambdaUpdate(NetflixUserAccountStatusRecord.class)
|
|
|
+ .set(NetflixUserAccountStatusRecord::getDeleted, false)
|
|
|
+ .eq(NetflixUserAccountStatusRecord::getId, netflixRelationView.getNfCheckId()));
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
private DistributePosterGoodsDetailView setGoodsPoster(RenewalView ticket, User user, List<Long> userIds) {
|
|
|
DistributePosterGoodsDetailView distributePosterGoodsDetailView = beanSearcher.searchFirst(DistributePosterGoodsDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
|
|
|
.field(DistributePosterGoodsFrontView::getGoodsId, ticket.getGoodsId()).build());
|
|
|
@@ -1625,4 +1914,118 @@ 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("奈飞车票已过期");
|
|
|
+ }
|
|
|
+ netflixRelationView.setNfCheckId(netflixUseAccountStatusRecord.getId());
|
|
|
+ netflixRelationView.setNfOriOrderId(netflixUseAccountStatusRecord.getOrderId());
|
|
|
+ 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(3)).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;
|
|
|
+ }
|
|
|
}
|