Преглед на файлове

AI月付账号过期,转移未过期的用户车票

zoujiajian преди 3 години
родител
ревизия
4d8c2fc12a
променени са 28 файла, в които са добавени 667 реда и са изтрити 77 реда
  1. 2 0
      netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
  2. 8 0
      netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java
  3. 5 0
      netflix-dao/src/main/java/com/cyksj/mapper/GoodsDonSkuMapper.java
  4. 12 5
      netflix-dao/src/main/java/com/cyksj/mapper/GroupsMapper.java
  5. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/UserBalanceSourceRecordMapper.java
  6. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/UserRelationChangeErrorRecordMapper.java
  7. 2 3
      netflix-dao/src/main/java/com/cyksj/model/entity/GroupsTrips.java
  8. 35 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserBalanceSourceRecord.java
  9. 46 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserRelationChangeErrorRecord.java
  10. 2 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserTicketClearedRecord.java
  11. 3 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/GroupsRelationView.java
  12. 3 0
      netflix-dao/src/main/java/com/cyksj/model/request/ChangeRelationReq.java
  13. 12 0
      netflix-dao/src/main/resources/mapper/GoodsDonSkuMapper.xml
  14. 81 0
      netflix-dao/src/main/resources/mapper/GroupsMapper.xml
  15. 15 0
      netflix-service/src/main/java/com/cyksj/service/error/UserRelationChangeErrorRecordService.java
  16. 37 0
      netflix-service/src/main/java/com/cyksj/service/error/impl/UserRelationChangeErrorRecordServiceImpl.java
  17. 18 0
      netflix-service/src/main/java/com/cyksj/service/groups/GroupsFuncService.java
  18. 71 0
      netflix-service/src/main/java/com/cyksj/service/groups/impl/GroupFunServiceImpl.java
  19. 5 1
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  20. 1 1
      netflix-service/src/main/java/com/cyksj/service/mange/statistics/impl/StatisticsDataServiceImpl.java
  21. 14 63
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  22. 1 1
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationClearServiceImpl.java
  23. 11 0
      netflix-service/src/main/java/com/cyksj/service/scheduler/SchedulerService.java
  24. 212 0
      netflix-service/src/main/java/com/cyksj/service/scheduler/impl/SchedulerServiceImpl.java
  25. 7 0
      netflix-service/src/main/java/com/cyksj/service/user/UserBenefitsService.java
  26. 25 0
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserBenefitsServiceImpl.java
  27. 12 2
      netflix-service/src/main/java/com/cyksj/task/Scheduler.java
  28. 1 1
      netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

+ 2 - 0
netflix-common/src/main/java/com/cyksj/common/constant/Constant.java

@@ -116,4 +116,6 @@ public interface Constant {
 	List<Long> CHANGE_ACCOUNT_PWD_FILTER_GIDS = List.of(18l, 26l);
 
 	String ZK_MOBILE = "18268325725";
+
+	static List<Long> AI_goodsIds = List.of(18l, 26l);
 }

+ 8 - 0
netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java

@@ -403,6 +403,14 @@ public final class StringUtil {
 		}
 	}
 
+	public static String getErrorMsg(Throwable throwable) {
+		if (throwable == null) {
+			return "ERROR,throwable is NULL!";
+		}
+		String message = throwable.getMessage();
+		return message;
+	}
+
 	/**
 	 * 随即获取length随机字符串
 	 */

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/mapper/GoodsDonSkuMapper.java

@@ -2,10 +2,15 @@ package com.cyksj.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.GoodsDonSku;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * @author chan
  * @date 2022/9/26 6:54 PM
  */
 public interface GoodsDonSkuMapper  extends BaseMapper<GoodsDonSku> {
+
+	List<Long> selectAIMonthSkuIds(@Param("list") List<Long> goodsIds);
 }

+ 12 - 5
netflix-dao/src/main/java/com/cyksj/mapper/GroupsMapper.java

@@ -1,11 +1,14 @@
 package com.cyksj.mapper;
 
+import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.AccountDoubleVerifyRecord;
 import com.cyksj.model.entity.GroupsTrips;
+import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -20,14 +23,18 @@ public interface GroupsMapper extends BaseMapper<GroupsTrips> {
     int incrAvailableNum(Long groupId);
 
     @Select("select count(*) from groups_trips where sku_id = #{skuId} and num = available_num")
-	Integer selectEmptyNetfilxTrips(Long skuId);
+	Integer selectEmptyNetflixTrips(Long skuId);
 
-	@Select("select gt.* from (select a.account,t.account_id,t.id as groups_id,t.sku_id,t.num from account a inner join groups_trips t on a.id = t.account_id where t.sku_id in (select id from goods_don_sku where goods_id = #{goodsId} and status is true) and t.num > 1 and a.api_secret = '') gt" +
-			" where gt.num = (select count(*) from groups_relation gr where gr.groups_id = gt.groups_id and gr.`status` = 'validity')" +
-			" and not EXISTS (select account_id from account_double_verify_record where account_id = gt.account_id and deleted is true)" +
-			" and DATE_SUB(now(),INTERVAL 3 day) >= (select max(update_time) from groups_relation gr where gr.groups_id = gt.groups_id and gr.`status` = 'validity')")
 	List<AccountDoubleVerifyRecord> selectGPTDoubleVerifyTrips(Long goodsId);
 
 	@Update("update groups_trips set available_num = (select count(*) from groups_relation where groups_id = #{groupsId} and status = 'none') where id = #{groupsId}")
 	Integer updateAvailableNum(Long groupsId);
+
+	List<GroupsTrips> getExpiryAccountGroups(@Param("nextBeginDay") DateTime nextBeginDay, @Param("list") List<Long> aiSkuIds);
+
+	Long selectSameSpecItemGroupsByTime(@Param("groupsId") Long groupsId, @Param("skuId") Long skuId, @Param("expiryTime") Date expiryTime, @Param("betDay") DateTime betDay, @Param("isOverTen") Boolean isOverTen);
+
+	Long selectSameSpecEmptyGroups(Long skuId);
+
+	Long selectMidJourneySameSpecItemGroups(@Param("groupsId") Long groupsId, @Param("skuId") Long skuId, @Param("expiryTime") Date expiryTime);
 }

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/UserBalanceSourceRecordMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserBalanceSourceRecord;
+
+/*
+ *项目名: netflix
+ *文件名: UserBalanceSourceRecordMapper
+ *创建者: JavaZou
+ *创建时间:2023/6/9 12:31
+ */
+public interface UserBalanceSourceRecordMapper extends BaseMapper<UserBalanceSourceRecord> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/UserRelationChangeErrorRecordMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserRelationChangeErrorRecord;
+
+/*
+ *项目名: netflix
+ *文件名: UserRelationChangeErrorRecordMapper
+ *创建者: JavaZou
+ *创建时间:2023/6/9 10:27
+ */
+public interface UserRelationChangeErrorRecordMapper extends BaseMapper<UserRelationChangeErrorRecord> {
+}

+ 2 - 3
netflix-dao/src/main/java/com/cyksj/model/entity/GroupsTrips.java

@@ -119,9 +119,8 @@ public class GroupsTrips {
     @TableField(exist = false)
     private String verifyCodes;
 
-    @DbField("gt.created_time")
-    @TableField(exist = false)
-    private Date createTime;
+    @DbField("gt.renewal_time")
+    private Date renewalTime;
 
     @DbField("a.expiry_time")
     @TableField(exist = false)

+ 35 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserBalanceSourceRecord.java

@@ -0,0 +1,35 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/*
+ *项目名: netflix
+ *文件名: UserBalanceSourceRecord
+ *创建者: JavaZou
+ *创建时间:2023/6/9 12:29
+ */
+@Getter
+@Setter
+public class UserBalanceSourceRecord extends BaseEntity{
+	private Long userId;
+
+	private BigDecimal balance;
+
+	private Source source;
+
+	@Getter
+	public enum Source {
+		refund("订单退款"),
+		clear_valid("车票未到期清除")
+		;
+		String desc;
+
+		Source(String desc) {
+			this.desc = desc;
+		}
+	}
+}
+

+ 46 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserRelationChangeErrorRecord.java

@@ -0,0 +1,46 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: UserRelationChangeErrorRecord
+ *创建者: JavaZou
+ *创建时间:2023/6/9 10:25
+ */
+@Getter
+@Setter
+public class UserRelationChangeErrorRecord extends BaseEntity{
+	private Long userId;
+
+	private Long skuId;
+
+	private Long groupsId;
+
+	private Long relationId;
+
+	private Date startTime;
+
+	private Date expiryTime;
+
+	private Source source;
+
+	private String errorMsg;
+
+	private Boolean deleted;
+
+	@Getter
+	public enum Source {
+		change("账号过期,更换车票"),
+		;
+		String desc;
+
+		Source(String desc) {
+			this.desc = desc;
+		}
+	}
+
+}

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserTicketClearedRecord.java

@@ -47,6 +47,8 @@ public class UserTicketClearedRecord extends BaseEntity{
 		specific("抽奖"),
 		black("拉黑"),
 		change_ticket("更换车票"),
+		timing_change_ticket("定时更换车票"),
+		new_groups_ticket("新空车队车票"),
 		;
 		String desc;
 

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/views/GroupsRelationView.java

@@ -127,4 +127,7 @@ public class GroupsRelationView {
     @DbIgnore
     private Date updateExpiryTime;
 
+    @DbIgnore
+    private String errorMsg;
+
 }

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/request/ChangeRelationReq.java

@@ -1,5 +1,6 @@
 package com.cyksj.model.request;
 
+import com.cyksj.model.entity.UserTicketClearedRecord;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -20,4 +21,6 @@ public class ChangeRelationReq {
 
 	@NotNull(message = "新车队id为空")
 	private Long groupsId;
+
+	private UserTicketClearedRecord.Source source;
 }

+ 12 - 0
netflix-dao/src/main/resources/mapper/GoodsDonSkuMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.cyksj.mapper.GoodsDonSkuMapper">
+
+    <select id="selectAIMonthSkuIds" resultType="java.lang.Long">
+        select id from goods_don_sku where goods_id in
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        and `months` = 1
+    </select>
+</mapper>

+ 81 - 0
netflix-dao/src/main/resources/mapper/GroupsMapper.xml

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.cyksj.mapper.GroupsMapper">
+
+    <select id="selectGPTDoubleVerifyTrips" resultType="com.cyksj.model.entity.AccountDoubleVerifyRecord">
+        select gt.*
+        from (select a.account, t.account_id, t.id as groups_id, t.sku_id, t.num
+              from account a
+                       inner join groups_trips t on a.id = t.account_id
+              where t.sku_id in (select id from goods_don_sku where goods_id = #{goodsId} and status is true)
+                and t.num > 1
+                and a.api_secret = '') gt
+        where gt.num =
+              (select count(*) from groups_relation gr where gr.groups_id = gt.groups_id and gr.`status` = 'validity')
+          and not EXISTS(select account_id
+                         from account_double_verify_record
+                         where account_id = gt.account_id
+                           and deleted is true)
+          and DATE_SUB(now(), INTERVAL 3 day) >= (select max(update_time)
+                                                  from groups_relation gr
+                                                  where gr.groups_id = gt.groups_id
+                                                    and gr.`status` = 'validity')
+    </select>
+
+    <select id="getExpiryAccountGroups" resultType="com.cyksj.model.entity.GroupsTrips">
+        select gt.id,
+               gt.status,
+               a.expiry_time
+        from `groups_trips` gt inner join account a on a.id = gt.account_id
+        where gt.sku_id in
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        and gt.num != available_num
+        and a.expiry_time &lt; #{nextBeginDay}
+        and gt.num > 1
+    </select>
+
+    <select id="selectSameSpecItemGroupsByTime" resultType="java.lang.Long">
+        select gt.id
+        from `groups_trips` gt
+        inner join account a on a.id = gt.account_id
+        where gt.id != #{groupsId}
+        and gt.sku_id = #{skuId}
+        and gt.status = 'validity'
+        and a.expiry_time >= #{expiryTime}
+        and a.expiry_time &lt;= #{betDay}
+        and (select count(*) from groups_relation gr where gr.status ='outside' and gr.groups_id = gt.id and
+        gr.user_id = 0) &lt;=
+        <choose>
+            <when test="isOverTen">
+                10
+            </when>
+            <otherwise>
+                5
+            </otherwise>
+        </choose>
+        order by gt.available_num asc limit 1
+    </select>
+
+    <select id="selectSameSpecEmptyGroups" resultType="java.lang.Long">
+        select id
+        from `groups_trips`
+        where status = 'waiting'
+          and available_num > 0
+          and sku_id = #{skuId}
+        order by available_num asc limit 1
+    </select>
+
+    <select id="selectMidJourneySameSpecItemGroups" resultType="java.lang.Long">
+        select gt.id
+        from `groups_trips` gt
+                 inner join account a on a.id = gt.account_id
+        where gt.id != #{groupsId}
+          and gt.sku_id = #{skuId}
+          and gt.status = 'validity'
+          and a.expiry_time >= #{expiryTime}
+          and gt.available_num > 0
+        order by gt.available_num asc limit 1
+    </select>
+</mapper>

+ 15 - 0
netflix-service/src/main/java/com/cyksj/service/error/UserRelationChangeErrorRecordService.java

@@ -0,0 +1,15 @@
+package com.cyksj.service.error;
+
+import com.cyksj.model.entity.UserRelationChangeErrorRecord;
+import com.cyksj.model.manage.views.GroupsRelationView;
+
+/*
+ *项目名: netflix
+ *文件名: UserRelationChangeErrorRecordService
+ *创建者: JavaZou
+ *创建时间:2023/6/9 10:28
+ */
+public interface UserRelationChangeErrorRecordService {
+
+	void changeTicketErrorRecord(GroupsRelationView relationView, UserRelationChangeErrorRecord.Source source);
+}

+ 37 - 0
netflix-service/src/main/java/com/cyksj/service/error/impl/UserRelationChangeErrorRecordServiceImpl.java

@@ -0,0 +1,37 @@
+package com.cyksj.service.error.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.cyksj.mapper.UserRelationChangeErrorRecordMapper;
+import com.cyksj.model.entity.UserRelationChangeErrorRecord;
+import com.cyksj.model.manage.views.GroupsRelationView;
+import com.cyksj.service.error.UserRelationChangeErrorRecordService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/*
+ *项目名: netflix
+ *文件名: UserRelationChangeErrorRecordServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/6/9 10:28
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class UserRelationChangeErrorRecordServiceImpl implements UserRelationChangeErrorRecordService {
+
+	private final UserRelationChangeErrorRecordMapper userRelationChangeErrorRecordMapper;
+
+	@Override
+	public void changeTicketErrorRecord(GroupsRelationView relationView, UserRelationChangeErrorRecord.Source source) {
+		UserRelationChangeErrorRecord userRelationChangeErrorRecord = new UserRelationChangeErrorRecord();
+		BeanUtil.copyProperties(relationView, userRelationChangeErrorRecord);
+		userRelationChangeErrorRecord.setSource(source);
+		userRelationChangeErrorRecord.setRelationId(relationView.getId());
+		if (StrUtil.isNotEmpty(userRelationChangeErrorRecord.getErrorMsg()) && userRelationChangeErrorRecord.getErrorMsg().length() > 1000) {
+			userRelationChangeErrorRecord.setErrorMsg(StrUtil.subSufByLength(userRelationChangeErrorRecord.getErrorMsg(), 512));
+		}
+		userRelationChangeErrorRecordMapper.insert(userRelationChangeErrorRecord);
+	}
+}

+ 18 - 0
netflix-service/src/main/java/com/cyksj/service/groups/GroupsFuncService.java

@@ -0,0 +1,18 @@
+package com.cyksj.service.groups;
+
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.entity.GroupsRelation;
+
+/*
+ *项目名: netflix
+ *文件名: GroupsFuncService
+ *创建者: JavaZou
+ *创建时间:2023/6/8 16:34
+ */
+public interface GroupsFuncService {
+
+	/**
+	 * 新增空车队
+	 */
+	GroupsRelation createNewGroupsTrips(GoodsDonSku sku);
+}

+ 71 - 0
netflix-service/src/main/java/com/cyksj/service/groups/impl/GroupFunServiceImpl.java

@@ -0,0 +1,71 @@
+package com.cyksj.service.groups.impl;
+
+import com.cyksj.mapper.GroupsMapper;
+import com.cyksj.mapper.GroupsRelationMapper;
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.entity.GroupsRelation;
+import com.cyksj.model.entity.GroupsTrips;
+import com.cyksj.model.manage.views.AccountView;
+import com.cyksj.service.groups.GroupsFuncService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/*
+ *项目名: netflix
+ *文件名: GroupFunServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/6/8 16:34
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class GroupFunServiceImpl implements GroupsFuncService {
+
+	private final BeanSearcher beanSearcher;
+
+	private final GroupsMapper groupsMapper;
+
+	private final GroupsRelationMapper groupsRelationMapper;
+
+	@Override
+	public GroupsRelation createNewGroupsTrips(GoodsDonSku sku) {
+		//新增车次
+		GroupsTrips groups = new GroupsTrips();
+		groups.setSkuId(sku.getId());
+		groups.setNum(sku.getNum());
+		groups.setAvailableNum(sku.getNum());
+		if (sku.getGoodsId() == 23) {
+			AccountView accountView = beanSearcher.searchFirst(AccountView.class, MapUtils.builder().field(AccountView::getGoodsId, 23).onlySelect(AccountView::getId).build());
+			if (accountView != null) {
+				groups.setAccountId(accountView.getId());
+				groups.setStatus(GroupsTrips.Status.validity);
+				groups.setRemark("已设置唯一账号");
+			} else {
+				groups.setStatus(GroupsTrips.Status.waiting);
+				groups.setRemark("等待设置账号");
+			}
+		} else {
+			groups.setStatus(GroupsTrips.Status.waiting);
+			groups.setRemark("等待设置账号");
+		}
+		groupsMapper.insert(groups);
+		GroupsRelation relation = new GroupsRelation();
+		relation.setGroupsId(groups.getId());
+		relation.setNum(1);
+		relation.setStatus(GroupsRelation.Status.none);
+		relation.setGroupsId(groups.getId());
+		groupsRelationMapper.insert(relation);
+
+		for (int i = 2; i <= groups.getNum(); i++) {
+			GroupsRelation groupsRelation = new GroupsRelation();
+			groupsRelation.setGroupsId(groups.getId());
+			groupsRelation.setNum(i);
+			groupsRelation.setStatus(GroupsRelation.Status.none);
+			groupsRelationMapper.insert(groupsRelation);
+		}
+		return relation;
+	}
+}

+ 5 - 1
netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java

@@ -304,6 +304,8 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
     public void changeRelation(ChangeRelationReq req) {
         Long relationId = req.getRelationId();
         Long groupId = req.getGroupsId();
+        UserTicketClearedRecord.Source source = req.getSource();
+        if (source == null) source = UserTicketClearedRecord.Source.change_ticket;
         GroupsRelation relation = relationMapper.selectById(relationId);
         Assert.notNull(relation, "车票已不存在");
         Long userId = relation.getUserId();
@@ -345,7 +347,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
 
         //清除原先车票
         relation.setNewRelationId(newRelation.getId());
-        relationClearService.clearTicket(relation, UserTicketClearedRecord.Source.change_ticket);
+        relationClearService.clearTicket(relation, source);
 
         if ((newRelation.getStartTime() == null || newRelation.getExpiryTime() == null)) {
             List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getUserId, userId).eq(OrderDon::getRelationId, relationId).eq(OrderDon::getStatus, OrderDon.Status.hasPayment));
@@ -524,6 +526,8 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             if (OrderDon.Type.BALANCE.getType().equals(refundType)) {
                 if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
                     userBenefitsService.addUserBalance(orderDon.getUserId(), orderDon.getRefundBalance());
+                    //退款余额时,记录
+                    userBenefitsService.recordBalanceBySource(orderDon.getUserId(), orderDon.getRefundBalance(), UserBalanceSourceRecord.Source.clear_valid);
                 }
             } else {
                 //余额退款不需要扣除积分

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/mange/statistics/impl/StatisticsDataServiceImpl.java

@@ -206,7 +206,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 				.build()).intValue();
 		backgroundDataView.setNumOfMonthEmptyRelationNetflix(numOfMonthEmptyRelationNetflix);
 
-		Integer numOfMonthEmptyTripsNetflix = groupsMapper.selectEmptyNetfilxTrips(skuId);
+		Integer numOfMonthEmptyTripsNetflix = groupsMapper.selectEmptyNetflixTrips(skuId);
 		backgroundDataView.setNumOfMonthEmptyTripsNetflix(numOfMonthEmptyTripsNetflix);
 		Number number = beanSearcher.searchCount(OrderDonView.class, MapUtils.builder().field(OrderDonView::getType, Constant.realGoodsType).op(Operator.InList)
 				.field(OrderDonView::getStatus, OrderDon.Status.hasPayment.name())

+ 14 - 63
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -50,7 +50,6 @@ import com.cyksj.model.dto.CouponPopularizeDto;
 import com.cyksj.model.dto.H5JsPayParams;
 import com.cyksj.model.entity.Address;
 import com.cyksj.model.entity.*;
-import com.cyksj.model.manage.views.AccountView;
 import com.cyksj.model.manage.views.GroupsRelationView;
 import com.cyksj.model.manage.views.OrderDonView;
 import com.cyksj.model.request.OrderAttach;
@@ -64,12 +63,11 @@ import com.cyksj.service.coupon.CouponFontService;
 import com.cyksj.service.distribute.UserBusinessFrontService;
 import com.cyksj.service.distribute.equipment.EquipmentDistributeService;
 import com.cyksj.service.exchange.ExchangeCodeService;
-import com.cyksj.service.mange.stock.GoodsDonStockService;
+import com.cyksj.service.groups.GroupsFuncService;
 import com.cyksj.service.market.MarketFrontService;
 import com.cyksj.service.market.task.TaskService;
 import com.cyksj.service.order.OrderCommonService;
 import com.cyksj.service.order.OrderDonService;
-import com.cyksj.service.order.UserRealOrderBenefitsService;
 import com.cyksj.service.relation.GroupRelationClearService;
 import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.sys.SysConfigService;
@@ -145,10 +143,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
-	private final CustomerServiceMapper customerServiceMapper;
-
-	private final RefundOrderDonMapper refundOrderDonMapper;
-
 	private final UserDistributeSharedMapper userDistributeSharedMapper;
 
 	private final DistributeWaitingSendPointsMapper distributeWaitingSendPointsMapper;
@@ -169,8 +163,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final ShopConfigMapper shopConfigMapper;
 
-	private final GoodsDonStockService goodsDonStockService;
-
 	private final TaskService taskService;
 
 	private final TaskTypeMapper taskTypeMapper;
@@ -185,8 +177,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final EquipmentDistributeService equipmentDistributeService;
 
-	private final UserRealOrderBenefitsService userRealOrderBenefitsService;
-
 	private final CouponDistributePopularizeMapper couponDistributePopularizeMapper;
 
 	private final GroupRelationFrontService groupRelationFrontService;
@@ -207,6 +197,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final UserBenefitsService userBenefitsService;
 
+	private final GroupsFuncService groupsFuncService;
+
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
 
 	@Transactional(rollbackFor = Throwable.class)
@@ -1383,61 +1375,20 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		if (groups == null) {
 			//新增空车队发送模板消息
 			TASK_POOL.execute(() -> {
-				createNewGroupsTrips(sku);
-				try {
-					List<CustomerService> customerServices = customerServiceMapper.selectList(null);
-					for (CustomerService customerService : customerServices) {
-						log.info("发送客服{}空车位通知消息", customerService.getNickName());
-						templateCommonService.emptySendMsgNotify(order, customerService.getOpenId());
-					}
-				} catch (Exception e) {
-					log.error("发送{}空车位模板消息至客服失败:{}", order.getGoodsId(), e);
-				}
+				groupsFuncService.createNewGroupsTrips(sku);
+//				try {
+//					List<CustomerService> customerServices = customerServiceMapper.selectList(null);
+//					for (CustomerService customerService : customerServices) {
+//						log.info("发送客服{}空车位通知消息", customerService.getNickName());
+//						templateCommonService.emptySendMsgNotify(order, customerService.getOpenId());
+//					}
+//				} catch (Exception e) {
+//					log.error("发送{}空车位模板消息至客服失败:{}", order.getGoodsId(), e);
+//				}
 			});
 		}
 	}
 
-	/**
-	 * 新增空车队
-	 */
-	private GroupsRelation createNewGroupsTrips(GoodsDonSku sku) {
-		//新增车次
-		GroupsTrips groups = new GroupsTrips();
-		groups.setSkuId(sku.getId());
-		groups.setNum(sku.getNum());
-		groups.setAvailableNum(sku.getNum());
-		if (sku.getGoodsId() == 23) {
-			AccountView accountView = beanSearcher.searchFirst(AccountView.class, MapUtils.builder().field(AccountView::getGoodsId, 23).onlySelect(AccountView::getId).build());
-			if (accountView != null) {
-				groups.setAccountId(accountView.getId());
-				groups.setStatus(GroupsTrips.Status.validity);
-				groups.setRemark("已设置唯一账号");
-			} else {
-				groups.setStatus(GroupsTrips.Status.waiting);
-				groups.setRemark("等待设置账号");
-			}
-		} else {
-			groups.setStatus(GroupsTrips.Status.waiting);
-			groups.setRemark("等待设置账号");
-		}
-		groupsMapper.insert(groups);
-		GroupsRelation relation = new GroupsRelation();
-		relation.setGroupsId(groups.getId());
-		relation.setNum(1);
-		relation.setStatus(GroupsRelation.Status.none);
-		relation.setGroupsId(groups.getId());
-		groupsRelationMapper.insert(relation);
-
-		for (int i = 2; i <= groups.getNum(); i++) {
-			GroupsRelation groupsRelation = new GroupsRelation();
-			groupsRelation.setGroupsId(groups.getId());
-			groupsRelation.setNum(i);
-			groupsRelation.setStatus(GroupsRelation.Status.none);
-			groupsRelationMapper.insert(groupsRelation);
-		}
-		return relation;
-	}
-
 	public void handleServiceRenewOrder(OrderDon orderDon) {
 		//续费订单
 		if (orderDon.getOrderType() == 2) {
@@ -1790,7 +1741,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 						.orderByAsc(GroupsTrips::getAvailableNum);
 				GroupsTrips groups = groupsMapper.selectOne(queryWrapper);
 				if (groups == null) {
-					relation = createNewGroupsTrips(sku);
+					relation = groupsFuncService.createNewGroupsTrips(sku);
 				} else {
 					//寻找快满编车队进行占座
 					relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId());

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationClearServiceImpl.java

@@ -94,7 +94,7 @@ public class GroupRelationClearServiceImpl implements GroupRelationClearService
 				userTicketClearedRecord.setStartTime(startTime);
 				userTicketClearedRecord.setExpiryTime(expireTime);
 				userTicketClearedRecord.setNewRelationId(newRelationId);
-				if (source == UserTicketClearedRecord.Source.change_ticket) {
+				if (source != UserTicketClearedRecord.Source.self) {
 					userTicketClearedRecord.setDeleted(false);
 				}
 				userTicketClearedRecordMapper.insert(userTicketClearedRecord);

+ 11 - 0
netflix-service/src/main/java/com/cyksj/service/scheduler/SchedulerService.java

@@ -0,0 +1,11 @@
+package com.cyksj.service.scheduler;
+
+/*
+ *项目名: netflix
+ *文件名: SchedulerService
+ *创建者: JavaZou
+ *创建时间:2023/6/8 16:47
+ */
+public interface SchedulerService {
+	void transExpiryAccountValidRelation();
+}

+ 212 - 0
netflix-service/src/main/java/com/cyksj/service/scheduler/impl/SchedulerServiceImpl.java

@@ -0,0 +1,212 @@
+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 com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
+import com.cyksj.common.util.StringUtil;
+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.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;
+
+/*
+ *项目名: 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;
+
+	@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());
+			log.info("迁移groupsId:{}未过期用户数量:{}", g_groupsId, groupsRelations.size());
+			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);
+							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);
+		}
+	}
+}

+ 7 - 0
netflix-service/src/main/java/com/cyksj/service/user/UserBenefitsService.java

@@ -1,5 +1,7 @@
 package com.cyksj.service.user;
 
+import com.cyksj.model.entity.UserBalanceSourceRecord;
+
 import java.math.BigDecimal;
 
 /*
@@ -30,4 +32,9 @@ public interface UserBenefitsService {
 	 * 扣除用户余额
 	 */
 	void deductUserBalance(Long userId, BigDecimal subBalance);
+
+	/**
+	 * 记录用于余额来源
+	 */
+	void recordBalanceBySource(Long userId, BigDecimal balance, UserBalanceSourceRecord.Source source);
 }

+ 25 - 0
netflix-service/src/main/java/com/cyksj/service/user/impl/UserBenefitsServiceImpl.java

@@ -1,9 +1,11 @@
 package com.cyksj.service.user.impl;
 
 import com.cyksj.mapper.DistributeOrdersDeductPointsRecordMapper;
+import com.cyksj.mapper.UserBalanceSourceRecordMapper;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.model.entity.DistributeOrdersDeductPointsRecord;
 import com.cyksj.model.entity.User;
+import com.cyksj.model.entity.UserBalanceSourceRecord;
 import com.cyksj.service.user.UserBenefitsService;
 import lombok.RequiredArgsConstructor;
 import org.springframework.dao.DuplicateKeyException;
@@ -24,8 +26,13 @@ public class UserBenefitsServiceImpl implements UserBenefitsService {
 
 	private final DistributeOrdersDeductPointsRecordMapper distributeOrdersDeductPointsRecordMapper;
 
+	private final UserBalanceSourceRecordMapper userBalanceSourceRecordMapper;
+
 	@Override
 	public void deductDistributePoints(Long orderId, Long userId, BigDecimal deductPoints) {
+		if (deductPoints.compareTo(BigDecimal.ZERO) <= 0) {
+			return;
+		}
 		while (true) {
 			User user = userMapper.selectById(userId);
 			if (user == null) break;
@@ -41,6 +48,9 @@ public class UserBenefitsServiceImpl implements UserBenefitsService {
 
 	@Override
 	public void addDistributePoints(Long userId, BigDecimal addPoints) {
+		if (addPoints.compareTo(BigDecimal.ZERO) <= 0) {
+			return;
+		}
 		while (true) {
 			User user = userMapper.selectById(userId);
 			if (user == null) break;
@@ -52,6 +62,9 @@ public class UserBenefitsServiceImpl implements UserBenefitsService {
 
 	@Override
 	public void addUserBalance(Long userId, BigDecimal addBalance) {
+		if (addBalance.compareTo(BigDecimal.ZERO) <= 0) {
+			return;
+		}
 		while (true) {
 			User user = userMapper.selectById(userId);
 			if (user == null) break;
@@ -63,6 +76,9 @@ public class UserBenefitsServiceImpl implements UserBenefitsService {
 
 	@Override
 	public void deductUserBalance(Long userId, BigDecimal subBalance) {
+		if (subBalance.compareTo(BigDecimal.ZERO) <= 0) {
+			return;
+		}
 		while (true) {
 			User user = userMapper.selectById(userId);
 			if (user == null) break;
@@ -83,4 +99,13 @@ public class UserBenefitsServiceImpl implements UserBenefitsService {
 
 		}
 	}
+
+	@Override
+	public void recordBalanceBySource(Long userId, BigDecimal balance, UserBalanceSourceRecord.Source source) {
+		UserBalanceSourceRecord userBalanceSourceRecord = new UserBalanceSourceRecord();
+		userBalanceSourceRecord.setUserId(userId);
+		userBalanceSourceRecord.setBalance(balance);
+		userBalanceSourceRecord.setSource(UserBalanceSourceRecord.Source.clear_valid);
+		userBalanceSourceRecordMapper.insert(userBalanceSourceRecord);
+	}
 }

+ 12 - 2
netflix-service/src/main/java/com/cyksj/task/Scheduler.java

@@ -28,6 +28,7 @@ import com.cyksj.service.order.OrderDonService;
 import com.cyksj.service.register.RegisterOrderDonService;
 import com.cyksj.service.register.SpotifyService;
 import com.cyksj.service.relation.GroupRelationClearService;
+import com.cyksj.service.scheduler.SchedulerService;
 import com.cyksj.service.sms.SmsService;
 import com.cyksj.service.user.UserBenefitsService;
 import com.ejlchina.searcher.BeanSearcher;
@@ -98,8 +99,9 @@ public class Scheduler {
 
 	    private final UserBenefitsService userBenefitsService;
 
-	    private final static List<Long> filter_skuIds = List.of(177l);
+	    private final SchedulerService schedulerService;
 
+	    private final static List<Long> filter_skuIds = List.of(177l);
 
     /**
      * 每5分钟清理过期账号
@@ -129,6 +131,14 @@ public class Scheduler {
 		expiryGPTListToday.forEach(relation -> groupRelationClearService.clearTicket(relation, UserTicketClearedRecord.Source.self));
 	}
 
+	/**
+	 * 每日过期主账号 迁移该账号对应车队的未过期用户车票
+	 */
+	@Scheduled(cron = "0 30 0 * * ?")
+	public void expiryAccountTrans() {
+		schedulerService.transExpiryAccountValidRelation();
+	}
+
 	@Scheduled(cron = "0 0 9 * * ?")
 	public void expiryWxMsg() throws Exception {
 		if (envCommonService.isPrdEnv()) {
@@ -475,7 +485,7 @@ public class Scheduler {
 		DateTime nextDay = DateUtil.offsetDay(DateUtil.beginOfDay(now), 3);
 		List<CloseGroupsTripsView> closeGroupsTripsViews = Optional.ofNullable(beanSearcher.searchAll(CloseGroupsTripsView.class, MapUtils.builder()
 				.field(CloseGroupsTripsView::getExpiryTime, nextDay).op(Operator.LessThan)
-				.field(CloseGroupsTripsView::getGoodsId, List.of(18, 26)).op(Operator.InList)
+				.field(CloseGroupsTripsView::getGoodsId, Constant.AI_goodsIds).op(Operator.InList)
 				.field(CloseGroupsTripsView::getGroupsId).op(Operator.NotNull)
 				.field(CloseGroupsTripsView::getGroupsStatus, GroupsTrips.Status.down.name()).op(Operator.NotEqual)
 				.build())).orElse(new ArrayList<>());

+ 1 - 1
netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

@@ -15,8 +15,8 @@ import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.GroupsRelationView;
 import com.cyksj.model.request.ExchangeCodeTicket;
 import com.cyksj.model.request.ReceiveBenefitsReq;
-import com.cyksj.model.request.WorkOrderReq;
 import com.cyksj.model.request.UserReq;
+import com.cyksj.model.request.WorkOrderReq;
 import com.cyksj.model.views.RenewalView;
 import com.cyksj.model.views.UserAvailableGoodsTicketView;
 import com.cyksj.model.views.UserPersonalView;