zoujiajian пре 11 месеци
родитељ
комит
15a91e7644

+ 16 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GroupsRelation.java

@@ -184,6 +184,22 @@ public class GroupsRelation extends BaseEntity {
     @TableField(exist = false)
     private Boolean isClaudeCodeUpgrade;
 
+    /**
+     * 是否被冻结
+     * 默认false
+     */
+    private Boolean isFrozen;
+
+    /**
+     * 解冻时长
+     */
+    private Date unfrozenTime;
+
+    /**
+     * 冻结保留天数
+     */
+    private Integer reservedDays;
+
 	@AllArgsConstructor
     @Getter
     public enum Status{

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

@@ -164,4 +164,22 @@ public class GroupsRelationView {
     @DbIgnore
     private Long nfOriOrderId;
 
+    /**
+     * 是否被冻结
+     * 默认false
+     */
+    @DbField("gr.is_frozen")
+    private Boolean isFrozen;
+
+    /**
+     * 解冻时长
+     */
+    @DbField("gr.unfrozen_time")
+    private Date unfrozenTime;
+
+    /**
+     * 冻结保留天数
+     */
+    @DbField("gr.reserved_days")
+    private Integer reservedDays;
 }

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/model/response/NetflixRecoverResp.java

@@ -18,4 +18,9 @@ public class NetflixRecoverResp {
 	 * 剩余天数
 	 */
 	private Long remainDays;
+
+	/**
+	 * 是否替换车票成功
+	 */
+	private Boolean isReset = false;
 }

+ 19 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java

@@ -247,6 +247,25 @@ public class RenewalView {
     @DbField("gr.is_vip")
     private Boolean isVip;
 
+    /**
+     * 是否被冻结
+     * 默认false
+     */
+    @DbField("gr.is_frozen")
+    private Boolean isFrozen;
+
+    /**
+     * 解冻时长
+     */
+    @DbField("gr.unfrozen_time")
+    private Date unfrozenTime;
+
+    /**
+     * 冻结保留天数
+     */
+    @DbField("gr.reserved_days")
+    private Integer reservedDays;
+
     @DbIgnore
     private Date payTime;
 

+ 19 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserTicketView.java

@@ -56,6 +56,25 @@ public class UserTicketView {
 	@DbField("gr.is_vip")
 	private Boolean isVip;
 
+	/**
+	 * 是否被冻结
+	 * 默认false
+	 */
+	@DbField("gr.is_frozen")
+	private Boolean isFrozen;
+
+	/**
+	 * 解冻时长
+	 */
+	@DbField("gr.unfrozen_time")
+	private Date unfrozenTime;
+
+	/**
+	 * 冻结保留天数
+	 */
+	@DbField("gr.reserved_days")
+	private Integer reservedDays;
+
 	@DbField("gdk.is_mirror")
 	private Boolean isMirror;
 

+ 21 - 3
netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml

@@ -29,7 +29,10 @@
         gpt_task_id = null,
         recharge_error_info = null,
         bp_verify_code = null,
-        gpt_token = null
+        gpt_token = null,
+        is_frozen = 0,
+        unfrozen_time = null,
+        reserved_days = null
         where id = #{entity.id}
         <if test="expireTime != null">
             and expiry_time = #{expireTime}
@@ -413,7 +416,21 @@
     </select>
 
     <select id="selectUserTickets" resultType="com.cyksj.model.views.UserTicketView">
-        select gr.id as relation_id,gr.user_id,g.id as goods_id,gt.sku_id,g.title,gdk.spec_val,gr.expiry_time,gdk.is_mirror,gdk.gpt_limit_num as gptUserLimitNum,gdk.gpt_limit_time as gptUserLimitTime,gdk.num as skuNum from groups_relation gr left join groups_trips gt on gt.id = gr.groups_id
+        select gr.id as relation_id,
+        gr.user_id,
+        g.id as goods_id,
+        gt.sku_id,
+        g.title,
+        gdk.spec_val,
+        gr.expiry_time,
+        gdk.is_mirror,
+        gdk.gpt_limit_num as gptUserLimitNum,
+        gdk.gpt_limit_time as gptUserLimitTime,
+        gdk.num as skuNum,
+        gr.is_frozen,
+        gr.unfrozen_time,
+        gr.reserved_days
+        from groups_relation gr left join groups_trips gt on gt.id = gr.groups_id
         left join goods_don_sku gdk on gdk.id = gt.sku_id left join goods_don g on g.id = gdk.goods_id
         where gr.user_id in
         <foreach collection="userIds" item="item" open="(" separator="," close=")">
@@ -422,7 +439,8 @@
         and gr.status in ('validity','outside')
         and gr.cmt != 2
         and gr.is_vip = 0
-        and (gr.expiry_time is null or gr.expiry_time > now() or (gdk.is_mirror and gr.expiry_time > DATE_ADD(now(),interval -7 day)))
+        and (gr.expiry_time is null or gr.expiry_time > now() or (gdk.is_mirror and gr.expiry_time >
+        DATE_ADD(now(),interval -7 day)))
         <if test="goodsId != null">
             and g.id = #{goodsId}
         </if>

+ 2 - 0
netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java

@@ -115,4 +115,6 @@ public interface GroupRelationFrontService {
 	List<UserMirrorTicketView> getMirrorTicket(long userId);
 
 	TicketRenewUpgradeView getRenewUpgradeInfo(long userId, Long relationId);
+
+	void netflixSubmitFrozen(ErrorNetflixChangeReq req);
 }

+ 118 - 4
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -238,8 +238,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		if (StrUtil.isNotBlank(account)) {
 			builder.field(RenewalView::getAccount, account).op(Operator.Contain);
 		}
-		//代充剩余次数大于0/未发车/过期时间
-		String conditionSql = String.format("(gr.recharge_remain_num > 0 or gr.expiry_time is null or gr.expiry_time > '%s'", now);
+		//代充剩余次数大于0/未发车/过期时间/冻结时
+		String conditionSql = String.format("(gr.recharge_remain_num > 0 or gr.expiry_time is null or gr.expiry_time > '%s' or gr.is_frozen = true", now);
 		//镜像车票 过期7天后清除
 		//个人店铺和AI店铺 暂不支持过期续费
 		if (cmt == null && StrUtil.isEmpty(customId)) {
@@ -1514,11 +1514,40 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 	}
 
 	@Override
+	@Transactional(rollbackFor = Throwable.class)
 	public NetflixRecoverResp netflixSubmitRecover(ErrorNetflixChangeReq req) {
+		NetflixRecoverResp recoverResp = new NetflixRecoverResp();
 		Long relationId = req.getRelationId();
 		Long userId = req.getUserId();
 		//校验奈飞账号状态
 		GroupsRelationView netflixRelationView = checkNetflixErrorStatus(relationId, userId);
+		if (netflixRelationView.getIsFrozen()) {
+			int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+					.set(GroupsRelation::getIsFrozen, Boolean.FALSE)
+					.eq(GroupsRelation::getId, netflixRelationView.getId())
+					.eq(GroupsRelation::getIsFrozen, Boolean.TRUE));
+			if (update == 0) {
+				throw BusinessRuntimeException.getInstance("申请恢复账号失败,请重试");
+			}
+			try {
+				//获取同规格的车票
+				Long skuId = netflixRelationView.getSkuId();
+				GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
+				GroupsRelation relation = getRelation(null, userId, sku, null);
+				if (relation != null) {
+					Long groupsId = relation.getGroupsId();
+					GroupsTrips groupsTrips = groupsMapper.selectById(groupsId);
+					//已发车
+					if (groupsTrips.getStatus() == GroupsTrips.Status.validity) {
+						resetUserTicket(netflixRelationView, relation);
+						recoverResp.setIsReset(Boolean.TRUE);
+						return recoverResp;
+					}
+				}
+			} catch (Exception e) {
+				throw BusinessRuntimeException.getInstance("申请恢复账号失败,请重试");
+			}
+		}
 		Date expiryTime = netflixRelationView.getExpiryTime();
 		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
 		NetflixUserAccountSubmitRecoverRecord recoverRecord = netflixUserAccountSubmitRecoverRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class)
@@ -1545,13 +1574,58 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		Integer selectCount = netflixUserAccountSubmitRecoverRecordMapper.selectCount(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class)
 				.lt(NetflixUserAccountSubmitRecoverRecord::getCreatedTime, recoverRecord.getCreatedTime())
 				.eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 0));
-		NetflixRecoverResp recoverResp = new NetflixRecoverResp();
 		//往前加100位
 		recoverResp.setIndex(100 + selectCount + 1);
 		recoverResp.setRemainDays(recoverRecord.getRemainDays());
 		return recoverResp;
 	}
 
+	private void resetUserTicket(GroupsRelationView oldRelation, GroupsRelation newRelation) {
+		Long userId = oldRelation.getUserId();
+		Long oldRelationId = oldRelation.getId();
+		//清除车票
+		List<Long> userIdList;
+		try {
+			userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		} catch (Exception e) {
+			userIdList = List.of(userId);
+		}
+		GroupsRelation clearRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+				.eq(GroupsRelation::getId, oldRelationId)
+				.in(GroupsRelation::getUserId, userIdList)
+				.last("limit 1"));
+		if (clearRelation != null) {
+			clearRelation.setNewRelationId(newRelation.getId());
+			clearService.clearTicket(clearRelation, UserTicketClearedRecord.Source.ticket_replace);
+		}
+		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) {
+			throw BusinessRuntimeException.getInstance("申请恢复账号失败,请重试");
+		}
+		//恢复状态
+		newRelation.setStartTime(oldRelation.getStartTime());
+		newRelation.setExpiryTime(DateUtil.offsetDay(DateTime.now(), oldRelation.getReservedDays()));
+		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);
+		}
+	}
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public void errorNetflixSubmitChangeOtherTicket(ErrorNetflixChangeReq req) throws Exception {
@@ -1957,6 +2031,35 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		return ticketRenewUpgradeView;
 	}
 
+	@Override
+	public void netflixSubmitFrozen(ErrorNetflixChangeReq req) {
+		Long relationId = req.getRelationId();
+		Long userId = req.getUserId();
+		//校验奈飞账号状态
+		GroupsRelationView netflixRelationView = checkNetflixErrorStatus(relationId, userId);
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		Integer recoverCount = netflixUserAccountSubmitRecoverRecordMapper.selectCount(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class)
+				.eq(NetflixUserAccountSubmitRecoverRecord::getRelationId, relationId)
+				.in(NetflixUserAccountSubmitRecoverRecord::getUserId, userIdList)
+				.eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 0));
+		if (recoverCount > 0) {
+			throw BusinessRuntimeException.getInstance("你已申请恢复账号,无法再申请冻结");
+		}
+		if (netflixRelationView.getIsFrozen()) {
+			throw BusinessRuntimeException.getInstance("你已申请冻结,无法再申请冻结");
+		}
+		Date expiryTime = netflixRelationView.getExpiryTime();
+		//保留天数
+		Long betweenDay = DateUtil.betweenDay(DateTime.now(), expiryTime, false) + 1;
+		groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+				.set(GroupsRelation::getIsFrozen, Boolean.TRUE)
+				//冻结2个月
+				.set(GroupsRelation::getUnfrozenTime, DateUtil.offsetMonth(DateTime.now(), 2))
+				.set(GroupsRelation::getReservedDays, betweenDay)
+				.eq(GroupsRelation::getId, netflixRelationView.getId())
+				.eq(GroupsRelation::getUserId, netflixRelationView.getUserId()));
+	}
+
 	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());
@@ -2228,11 +2331,22 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				.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("奈飞车票已过期");
 		}
+		if (netflixRelationView != null) {
+			if (netflixRelationView.getIsFrozen() && netflixRelationView.getUnfrozenTime().after(DateTime.now())) {
+				throw BusinessRuntimeException.getInstance("冻结未结束");
+			}
+			if (netflixRelationView.getIsFrozen()) {
+				//重新设置车票时长
+				netflixRelationView.setExpiryTime(DateUtil.offsetDay(DateTime.now(), netflixRelationView.getReservedDays()));
+			}
+			if (netflixRelationView.getExpiryTime().before(DateTime.now())) {
+				throw BusinessRuntimeException.getInstance("奈飞车票已过期");
+			}
+		}
 		netflixRelationView.setNfCheckId(netflixUseAccountStatusRecord.getId());
 		netflixRelationView.setNfOriOrderId(netflixUseAccountStatusRecord.getOrderId());
 		return netflixRelationView;

+ 12 - 0
netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java

@@ -1288,6 +1288,18 @@ public class GroupRelationController {
         return GatewayResponse.SUCCESS.newBuilder().toResult(recoverResp);
     }
 
+    /**
+     * 奈飞申请冻结
+     */
+    @PostMapping("/netflix/submit/frozen")
+    public Result<String> netflixSubmitFrozen(@RequestBody ErrorNetflixChangeReq req) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        req.setUserId(userId);
+        groupRelationFrontService.netflixSubmitFrozen(req);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+
     /**
      * 奈飞更换其他车票
      */

+ 8 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -32,6 +32,7 @@ import com.cyksj.model.request.RedBookReq;
 import com.cyksj.model.request.RenewTimeUpReq;
 import com.cyksj.model.views.*;
 import com.cyksj.service.mange.statistics.StatisticsDataService;
+import com.cyksj.service.relation.GroupRelationClearService;
 import com.cyksj.web.util.EasyExcelUtils;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
@@ -92,6 +93,8 @@ public class StatisticsDataController {
 
 	private final CmsUserMapper cmsUserMapper;
 
+	private final GroupRelationClearService clearService;
+
 	private final HttpServletRequest request;
 
 	/**
@@ -238,6 +241,11 @@ public class StatisticsDataController {
 		incrExpiryTimeRecord.setRelationId(relation.getId());
 		Optional.ofNullable(cmsUserMapper.selectById(adminId)).ifPresent(admin -> incrExpiryTimeRecord.setOperator(admin.getNickname()));
 		incrExpiryTimeRecordMapper.insert(incrExpiryTimeRecord);
+
+		//清除车票
+		if (relation.getExpiryTime().before(DateTime.now())) {
+			clearService.clearTicket(relation, UserTicketClearedRecord.Source.manual);
+		}
 		return GatewayResponse.SUCCESS.newBuilder().toResult("增加车票有效期成功");
 	}