| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- package com.cyksj.service.scheduler.impl;
- import cn.hutool.core.date.DateTime;
- import cn.hutool.core.date.DateUnit;
- import cn.hutool.core.date.DateUtil;
- import cn.hutool.core.util.StrUtil;
- import com.baomidou.mybatisplus.core.toolkit.Wrappers;
- import com.cyksj.common.constant.Constant;
- import com.cyksj.common.util.StringUtil;
- import com.cyksj.dto.RedisKey;
- import com.cyksj.mapper.*;
- import com.cyksj.model.entity.*;
- import com.cyksj.model.manage.views.GroupsRelationView;
- import com.cyksj.model.request.ChangeRelationReq;
- import com.cyksj.redis.RedisService;
- import com.cyksj.service.error.UserRelationChangeErrorRecordService;
- import com.cyksj.service.groups.GroupsFuncService;
- import com.cyksj.service.mange.CmsOrderDonService;
- import com.cyksj.service.relation.GroupRelationClearService;
- import com.cyksj.service.scheduler.SchedulerService;
- import com.cyksj.service.user.UserBenefitsService;
- import com.ejlchina.searcher.BeanSearcher;
- import com.ejlchina.searcher.param.Operator;
- import com.ejlchina.searcher.util.MapUtils;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.util.Date;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- /*
- *项目名: netflix
- *文件名: SchedulerServiceImpl
- *创建者: JavaZou
- *创建时间:2023/6/8 16:48
- */
- @Service
- @RequiredArgsConstructor
- @Slf4j
- public class SchedulerServiceImpl implements SchedulerService {
- private final GoodsDonSkuMapper skuMapper;
- private final GroupsMapper groupsMapper;
- private final BeanSearcher beanSearcher;
- private final OrderDonMapper orderDonMapper;
- private final GroupsRelationMapper groupsRelationMapper;
- private final GroupRelationClearService groupRelationClearService;
- private final UserBenefitsService userBenefitsService;
- private final GroupsFuncService groupsFuncService;
- private final CmsOrderDonService cmsOrderDonService;
- private final UserRelationChangeErrorRecordService changeErrorRecordService;
- private final UserRelationChangeErrorRecordMapper userRelationChangeErrorRecordMapper;
- private final GoodsDonMapper goodsDonMapper;
- private final RedisService redisService;
- @Override
- public void transExpiryAccountValidRelation() {
- DateTime now = new DateTime();
- DateTime nextBeginDay = DateUtil.offsetDay(DateUtil.beginOfDay(now), 1);
- //针对AI类 CHAT PLUS、MidJourney 月付
- List<Long> aiSkuIds = skuMapper.selectAIMonthSkuIds(Constant.AI_goodsIds);
- List<GroupsTrips> expiryAccountGroups = groupsMapper.getExpiryAccountGroups(nextBeginDay, aiSkuIds);
- expiryAccountGroups.forEach(expiry_groups -> {
- if (expiry_groups.getStatus() != GroupsTrips.Status.down) {
- expiry_groups.setStatus(GroupsTrips.Status.down);
- groupsMapper.updateById(expiry_groups);
- }
- Long g_groupsId = expiry_groups.getId();
- Date a_expiryTime = expiry_groups.getExpiryTime();
- //未过期用户 只分配有效的用户车票 outside状态过滤
- List<GroupsRelationView> groupsRelations = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
- .field(GroupsRelationView::getGroupsId, g_groupsId)
- .field(GroupsRelationView::getStatus, GroupsRelation.Status.validity.name())
- .field(GroupsRelationView::getExpiryTime, nextBeginDay).op(Operator.GreaterEqual)
- .build());
- reAssign(g_groupsId, now, groupsRelations);
- });
- }
- @Override
- public void assignUserGroupsRelation(Long groupsId) {
- GroupsTrips groupsTrips = groupsMapper.selectById(groupsId);
- if (groupsTrips == null || groupsTrips.getAccountId() == null) return;
- String key = RedisKey.DISABLE_ACCOUNT_ASSIGN + groupsId;
- if (!redisService.setNx(key, groupsId, 60 * 3l)) {
- return;
- }
- if (groupsTrips.getStatus() != GroupsTrips.Status.down) {
- groupsTrips.setStatus(GroupsTrips.Status.down);
- groupsMapper.updateById(groupsTrips);
- }
- DateTime now = DateTime.now();
- //迁移用户
- List<GroupsRelationView> groupsRelations = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
- .field(GroupsRelationView::getGroupsId, groupsId)
- .field(GroupsRelationView::getStatus, List.of(GroupsRelation.Status.validity.name(), GroupsRelation.Status.outside.name())).op(Operator.InList)
- .field(GroupsRelationView::getExpiryTime, now).op(Operator.GreaterEqual)
- .build());
- reAssign(groupsId, now, groupsRelations);
- redisService.del(key);
- }
- /**
- * 重新分配车位
- */
- public void reAssign(Long g_groupsId, DateTime now, List<GroupsRelationView> groupsRelations) {
- log.info("迁移groupsId:{}未过期用户数量:{}", g_groupsId, groupsRelations.size());
- Map<Long, GoodsDon> goodsMap = new ConcurrentHashMap<>();
- Map<Long, GoodsDonSku> skuMap = new ConcurrentHashMap<>();
- groupsRelations.forEach(relationView -> {
- Long change_relationId = relationView.getId();
- Long userId = relationView.getUserId();
- UserRelationChangeErrorRecord exists = userRelationChangeErrorRecordMapper.selectOne(Wrappers.lambdaQuery(UserRelationChangeErrorRecord.class)
- .eq(UserRelationChangeErrorRecord::getRelationId, change_relationId)
- .eq(UserRelationChangeErrorRecord::getUserId, userId)
- .eq(UserRelationChangeErrorRecord::getDeleted, true)
- .last("limit 1"));
- if (exists != null) {
- log.info("存在userId:{}无法转移的车票relationId:{}", userId, change_relationId);
- return;
- }
- Date expiryTime = relationView.getExpiryTime();
- Long skuId = relationView.getSkuId();
- //仅针对chatGPT
- if (relationView.getGoodsId() == 18) {
- Long bet_day = DateUtil.between(now, expiryTime, DateUnit.DAY);
- //10天以内
- if (bet_day <= 10) {
- //分配到过期账号5天内误差的相同规格车队里
- DateTime five_day = DateUtil.offsetDay(expiryTime, 5);
- Long item_groupsId = groupsMapper.selectSameSpecItemGroupsByTime(g_groupsId, skuId, expiryTime, five_day, false);
- if (item_groupsId == null) {
- //无对应车队 退款
- //退款至余额
- OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
- .eq(OrderDon::getRelationId, change_relationId)
- .eq(OrderDon::getUserId, userId)
- .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
- .orderByDesc(OrderDon::getId)
- .last("limit 1"));
- if (orderDon == null) {
- //更换过车票
- orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
- .eq(OrderDon::getSkuId, skuId)
- .eq(OrderDon::getUserId, userId)
- .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
- .orderByDesc(OrderDon::getId)
- .last("limit 1"));
- }
- if (orderDon == null) {
- log.error("用户userId:{}的车票relationId:{}账号过期后转移错误", userId, change_relationId);
- changeErrorRecordService.changeTicketErrorRecord(relationView, UserRelationChangeErrorRecord.Source.change);
- return;
- }
- //清除车票
- GroupsRelation relation = groupsRelationMapper.selectById(change_relationId);
- groupRelationClearService.clearTicket(relation, UserTicketClearedRecord.Source.timing_change_ticket);
- //退款至余额
- //实付金额 + 余额
- BigDecimal money = orderDon.getMoney().add(orderDon.getBalance());
- //当月天数
- Date payTime = orderDon.getPayTime();
- if (payTime == null) {
- payTime = orderDon.getCreatedTime();
- }
- if (money.compareTo(BigDecimal.ZERO) == 0) {
- GoodsDonSku sku = skuMapper.selectById(skuId);
- if (sku != null) {
- money = sku.getPrice();
- }
- }
- int dayNum = DateUtil.dayOfMonth(DateUtil.endOfMonth(payTime));
- BigDecimal re_balance = money.divide(BigDecimal.valueOf(dayNum), 0, RoundingMode.DOWN).multiply(BigDecimal.valueOf(bet_day));
- if (re_balance.compareTo(BigDecimal.ZERO) <= 0) {
- log.info("user_id:{},relationId:{}返回余额为0", userId, change_relationId);
- return;
- }
- userBenefitsService.addUserBalance(userId, re_balance);
- log.info("车票未到期清除,退款至用户user_id:{}余额:{}成功", userId, re_balance);
- userBenefitsService.recordBalanceBySource(userId, re_balance, UserBalanceSourceRecord.Source.clear_valid);
- //修改订单状态 为退款
- orderDon.setStatus(OrderDon.Status.refund);
- orderDon.setRefundBalance(re_balance);
- orderDon.setRefundMoney(BigDecimal.ZERO);
- orderDonMapper.updateById(orderDon);
- GoodsDon goodsDon = goodsMap.get(relationView.getGoodsId());
- if (goodsDon == null) {
- goodsDon = goodsDonMapper.selectById(relationView.getGoodsId());
- if (goodsDon == null) return;
- goodsMap.putIfAbsent(relationView.getGoodsId(), goodsDon);
- }
- GoodsDonSku sku = skuMap.get(orderDon.getSkuId());
- if (sku == null) {
- sku = skuMapper.selectById(orderDon.getSkuId());
- if (sku == null) return;
- skuMap.putIfAbsent(orderDon.getSkuId(), sku);
- }
- cmsOrderDonService.refundRecord(orderDon, goodsDon, sku, StrUtil.EMPTY, "balance");
- return;
- }
- changeTickerRelation(item_groupsId, relationView, UserTicketClearedRecord.Source.timing_change_ticket);
- return;
- }
- //大于10天
- //分配到过期账号10天内误差的相同规格车队里
- DateTime ten_day = DateUtil.offsetDay(expiryTime, 10);
- Long item_groupsId = groupsMapper.selectSameSpecItemGroupsByTime(g_groupsId, skuId, expiryTime, ten_day, true);
- if (item_groupsId == null) {
- //无对应车队 生成空车队
- //寻找空车队
- item_groupsId = groupsMapper.selectSameSpecEmptyGroups(skuId);
- if (item_groupsId == null) {
- //新增空车队
- GoodsDonSku sku = skuMapper.selectById(skuId);
- GroupsRelation new_relation = groupsFuncService.createNewGroupsTrips(sku);
- item_groupsId = new_relation.getGroupsId();
- }
- //新车队
- changeTickerRelation(item_groupsId, relationView, UserTicketClearedRecord.Source.new_groups_ticket);
- return;
- }
- changeTickerRelation(item_groupsId, relationView, UserTicketClearedRecord.Source.timing_change_ticket);
- return;
- }
- if (relationView.getGoodsId() == 26) {
- //移入合适车队
- Long item_groupsId = groupsMapper.selectMidJourneySameSpecItemGroups(g_groupsId, skuId, expiryTime);
- if (item_groupsId == null) {
- //midJourney 无合适车队
- log.error("midJourney账号过期groupsId:{},用户车票relation_id:{}", g_groupsId, change_relationId);
- changeErrorRecordService.changeTicketErrorRecord(relationView, UserRelationChangeErrorRecord.Source.change);
- return;
- }
- changeTickerRelation(item_groupsId, relationView, UserTicketClearedRecord.Source.timing_change_ticket);
- }
- });
- }
- public void changeTickerRelation(Long item_groupsId, GroupsRelationView relationView, UserTicketClearedRecord.Source source) {
- Long change_relationId = relationView.getId();
- try {
- ChangeRelationReq req = new ChangeRelationReq();
- req.setGroupsId(item_groupsId);
- req.setRelationId(change_relationId);
- req.setSource(source);
- cmsOrderDonService.changeRelation(req);
- } catch (Exception e) {
- log.error("更换用户relationId:{}错误:{}", change_relationId, StringUtil.getErrorText(e));
- relationView.setErrorMsg(StringUtil.getErrorMsg(e));
- changeErrorRecordService.changeTicketErrorRecord(relationView, UserRelationChangeErrorRecord.Source.change);
- }
- }
- }
|