package com.cyksj.service.relation.impl; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.cyksj.common.constant.Constant; import com.cyksj.common.task.GlobalThreadPoolTaskExecutor; import com.cyksj.mapper.*; import com.cyksj.model.entity.*; import com.cyksj.redis.RedisService; import com.cyksj.service.relation.CmsGroupsRelationService; import com.cyksj.service.relation.GroupRelationClearService; import com.cyksj.service.sms.SmsService; import com.cyksj.service.user.UserBindRelationService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * 项目名: yhlxj11111111 * 文件名: CmsGroupsRelationServiceImpl * 创建者: JavaZou * 创建时间:2025/11/11 17:45 */ @Service @RequiredArgsConstructor @Slf4j public class CmsGroupsRelationServiceImpl implements CmsGroupsRelationService { private final NetflixUserAccountSubmitRecoverRecordMapper recoverRecordMapper; private final GroupsRelationMapper groupsRelationMapper; private final RedisService redisService; private final GroupsMapper groupsMapper; private final GoodsDonSkuMapper goodsDonSkuMapper; private final UserBindRelationService userBindRelationService; private final GroupRelationClearService clearService; private final OrderDonMapper orderDonMapper; private final SmsService smsService; private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance(); @Override @Transactional(rollbackFor = Throwable.class) public void recoverAvailableParkingSpace() { List netflixUserAccountSubmitRecoverRecords = recoverRecordMapper.selectList(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class).eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 0)); if (netflixUserAccountSubmitRecoverRecords.isEmpty()) { return; } for (NetflixUserAccountSubmitRecoverRecord recoverRecord : netflixUserAccountSubmitRecoverRecords) { Long recoverRecordId = recoverRecord.getId(); int update = recoverRecordMapper.update(null, Wrappers.lambdaUpdate(NetflixUserAccountSubmitRecoverRecord.class) .set(NetflixUserAccountSubmitRecoverRecord::getStatus, 1) .eq(NetflixUserAccountSubmitRecoverRecord::getId,recoverRecordId) .eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 0)); if (update > 0) { //获取同规格的车票 Long skuId = recoverRecord.getSkuId(); GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId); DateTime newExpiryTime = DateUtil.offsetDay(DateTime.now(), recoverRecord.getRemainDays().intValue()); GroupsRelation newRelation = getRelation(sku, newExpiryTime); if (newRelation == null) { //恢复 待恢复状态 recoverStatusReset(recoverRecordId); continue; } //清除车票 List userIdList; try { userIdList = userBindRelationService.getRelationUserIdList(recoverRecord.getUserId(), null); } catch (Exception e) { userIdList = List.of(recoverRecord.getUserId()); } GroupsRelation oldRelation = groupsRelationMapper.selectOne(Wrappers.lambdaUpdate(GroupsRelation.class).eq(GroupsRelation::getId, recoverRecord.getRelationId()).in(GroupsRelation::getUserId, userIdList).last("limit 1")); if (oldRelation != null) { newRelation.setStartTime(oldRelation.getStartTime()); newRelation.setExpiryTime(newExpiryTime); if (!resetUserTicket(oldRelation, newRelation, userIdList)) { //恢复 待恢复状态 recoverStatusReset(recoverRecordId); } else { recoverRecordMapper.update(null, Wrappers.lambdaUpdate(NetflixUserAccountSubmitRecoverRecord.class) .set(NetflixUserAccountSubmitRecoverRecord::getReplaceRelationId, newRelation.getId()) .eq(NetflixUserAccountSubmitRecoverRecord::getId, recoverRecordId)); try { //发送奈飞恢复短信通知 smsService.sendSmsToRelationUser(recoverRecord.getUserId(), Constant.NETFLIX_ERROR_CHANGE_TICKET_MSG); } catch (Exception e) { } } } } } } public GroupsRelation getRelation(GoodsDonSku sku, DateTime expiryTime) { GroupsRelation relation = null; Integer maxNum = sku.getNum(); GroupsTrips groups = null; if (groups == null) { //寻找差不多过期时间规格的车位 relation = getSimilarExpiredGroupRelation(sku, expiryTime); if (relation == null) { DateTime filterAccountTime = null; groups = groupsMapper.selectTicketGroups(sku.getId(), GroupsTrips.Status.validity, maxNum, null, filterAccountTime); if (groups == null) { return null; } //获取车位 if (relation == null) { //寻找快满编车队进行占座 relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId()); if (relation == null) { Long groupsId = groups.getId(); TASK_EXECUTOR.execute(() -> groupsMapper.updateAvailableNum(groupsId)); return null; } } } } if (groups == null) { groups = groupsMapper.selectById(relation.getGroupsId()); } //车队目前可用停车数 relation.setGroupsAvailParkingNum(groups.getAvailableParkingNum()); relation.setMaxNum(maxNum); return relation; } public GroupsRelation getSimilarExpiredGroupRelation(GoodsDonSku sku, DateTime expiryTime) { Long skuId = sku.getId(); Integer maxNum = sku.getNum(); DateTime minExpiryTime = DateUtil.offsetDay(expiryTime, -5); Long groupsId = groupsRelationMapper.selectSimilarExpiredRelation(skuId, minExpiryTime, maxNum, null); if (groupsId == null) { log.info("暂无相似过期时间车队"); return null; } GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class) .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("获取相似车队的车位relationId:{}", relation.getId()); } return relation; } private Boolean resetUserTicket(GroupsRelation oldRelation, GroupsRelation newRelation, List userIdList) { Long userId = oldRelation.getUserId(); Long oldRelationId = oldRelation.getId(); newRelation.setUserId(userId); //校验座位 int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class) .set(GroupsRelation::getUserId, userId) .eq(GroupsRelation::getUserId, 0) .eq(GroupsRelation::getId, newRelation.getId())); if (update == 0) { return Boolean.FALSE; } groupsMapper.decrAvailableNum(newRelation.getGroupsId()); oldRelation.setNewRelationId(newRelation.getId()); clearService.clearTicket(oldRelation, UserTicketClearedRecord.Source.recover_replace); //恢复状态 newRelation.setStatus(GroupsRelation.Status.validity); groupsRelationMapper.updateById(newRelation); //原订单座位id更新 OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class) .in(OrderDon::getUserId, userIdList) .eq(OrderDon::getRelationId, oldRelationId) .notIn(OrderDon::getStatus, Constant.noOrderStatus) .orderByDesc(OrderDon::getId) .last("limit 1")); if (orderDon != null) { orderDon.setRelationId(newRelation.getId()); orderDonMapper.updateById(orderDon); } return Boolean.TRUE; } public void recoverStatusReset(Long recoverId) { recoverRecordMapper.update(null, Wrappers.lambdaUpdate(NetflixUserAccountSubmitRecoverRecord.class) .set(NetflixUserAccountSubmitRecoverRecord::getStatus, 0) .eq(NetflixUserAccountSubmitRecoverRecord::getId, recoverId) .eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 1)); } }