zoujiajian преди 1 година
родител
ревизия
24b29663a3

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

@@ -22,6 +22,9 @@ public class GoodsDonSkuRenewView {
 	@DbField("sku.id")
 	private Long skuId;
 
+	@DbField("sku.sub_title")
+	private String subTitle;
+
 	@DbField("sku.spec_val")
 	private String specVal;
 

+ 83 - 0
netflix-dao/src/main/java/com/cyksj/model/views/TicketRenewUpgradeView.java

@@ -0,0 +1,83 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: TicketRenewUpgradeView
+ * 创建者: JavaZou
+ * 创建时间:2025/7/25 18:11
+ */
+@Getter
+@Setter
+public class TicketRenewUpgradeView {
+
+	/**
+	 * gpt 用户镜像限制次数
+	 */
+	@DbIgnore
+	private Integer gptUserLimitNum;
+
+	/**
+	 * gpt 用户镜像限制时间
+	 */
+	@DbIgnore
+	private Long gptUserLimitTime;
+
+	/**
+	 * luma 用户次数
+	 */
+	@DbIgnore
+	private Integer lumaUserNum;
+
+	/**
+	 * deepseek限制次数
+	 */
+	@DbIgnore
+	private Integer userDsLimitNum;
+
+	/**
+	 * deepseek限制时间
+	 */
+	@DbIgnore
+	private Long userDsLimitTime;
+
+	/**
+	 * 其他模型限制次数
+	 */
+	@DbIgnore
+	private Integer userOtherLimitNum;
+
+	/**
+	 * 其他模型限制时间
+	 */
+	@DbIgnore
+	private Long userOtherLimitTime;
+
+	/**
+	 * 是否是续费升级
+	 */
+	@DbIgnore
+	private Boolean isRenewPackage;
+
+	/**
+	 * 是否可升级套餐 (标准,专业)
+	 */
+	@DbIgnore
+	private Boolean upgrade;
+
+	@DbIgnore
+	private Long packageId;
+
+	/**
+	 * 目前已升级套餐价格
+	 */
+	@DbIgnore
+	private BigDecimal packagePrice;
+
+	private GoodsDonSkuRenewView renewSku;
+}

+ 324 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserMirrorTicketView.java

@@ -0,0 +1,324 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: UserMirrorTicketView
+ * 创建者: JavaZou
+ * 创建时间:2025/7/25 16:11
+ */
+@SearchBean(tables = "groups_relation gr left join groups_trips gt on gt.id = gr.groups_id " +
+		"left join goods_don_sku sku on gt.sku_id = sku.id " +
+		"left join goods_don g on g.id = sku.goods_id "
+)
+@Getter
+@Setter
+public class UserMirrorTicketView {
+	@DbField("g.id")
+	private Long goodsId;
+
+	@DbField("sku.id")
+	private Long skuId;
+
+	@DbField("g.status")
+	private Boolean goodsStatus;
+
+	@DbField("sku.status")
+	private Boolean skuStatus;
+
+	@DbField("sku.months")
+	private Integer months;
+
+	@DbField("sku.days")
+	private Integer days;
+
+	@DbField("sku.num")
+	private Integer skuNum;
+
+	@DbField("sku.sub_title")
+	private String subTitle;
+
+	@DbField("sku.spec_val")
+	private String specVal;
+
+	@DbField("gr.id")
+	private Long relationId;
+
+	@DbField("gr.num")
+	private Integer num;
+
+	@DbField("gr.groups_id")
+	private Long groupId;
+
+	@DbField("g.title")
+	private String title;
+
+	@DbField("g.logo")
+	private String logo;
+
+	@DbField("g.img")
+	private String img;
+
+	@DbField("gt.status")
+	private String groupsStatus;
+
+	@DbField("gr.user_id")
+	@JsonIgnore
+	private Long userId;
+
+	@DbField("gr.start_time")
+	private Date startTime;
+
+	@DbField("gr.expiry_time")
+	private Date expiryTime;
+
+	@DbIgnore
+	private Long total;
+
+	@DbIgnore
+	private String expiryTimeStr;
+
+	@DbField("gr.status")
+	private String status;
+
+	/**
+	 * 店铺id
+	 */
+	@DbField("gr.yhs_id")
+	private Long yhsId;
+
+	/**
+	 * 店铺类型
+	 * 0无 1.普通店铺 2.镜像店铺
+	 */
+	@DbField("gr.cmt")
+	private Integer cmt;
+
+	/**
+	 * 车票获取类型 默认1购买,2.体验 3.镜像裂变
+	 */
+	@DbField("gr.aq_type")
+	private Integer aqType;
+
+	/**
+	 * 是否是VIP
+	 */
+	@DbField("gr.is_vip")
+	private Boolean isVip;
+
+	@DbIgnore
+	private Date payTime;
+
+	@DbIgnore
+	private String remainDays;
+
+	@DbField("sku.price")
+	private BigDecimal price;
+
+	/**
+	 * 是否为镜像服务
+	 */
+	@DbField("sku.is_mirror")
+	private Boolean isMirror;
+
+	/**
+	 * 是否为镜像车队服务
+	 */
+	@DbField("sku.is_car")
+	private Boolean isCar;
+
+
+	/**
+	 * mj fast次数
+	 */
+	@DbField("sku.mj_fast_num")
+	private Integer mjFastNum;
+
+
+	/**
+	 * mj relax次数
+	 */
+	@DbField("sku.mj_relax_num")
+	private Integer mjRelaxNum;
+
+	/**
+	 * 镜像限制次数
+	 */
+	@DbField("sku.gpt_limit_num")
+	private Integer gptLimitNum;
+
+	/**
+	 * luma 次数
+	 */
+	@DbField("sku.luma_num")
+	private Integer lumaNUm;
+
+	/**
+	 * deepseek限制次数
+	 */
+	@DbField("sku.ds_limit_num")
+	private Integer dsLimitNum;
+
+	/**
+	 * deepseek限制时间
+	 */
+	@DbField("sku.ds_limit_time")
+	private Long dsLimitTime;
+
+	/**
+	 * 其他模型限制次数
+	 */
+	@DbField("sku.other_limit_num")
+	private Integer otherLimitNum;
+
+	/**
+	 * 其他模型限制时间
+	 */
+	@DbField("sku.other_limit_time")
+	private Long otherLimitTime;
+
+	/**
+	 * mj 套餐包最低单价
+	 */
+	@DbIgnore
+	private BigDecimal mjPackagePrice;
+
+	/**
+	 * luma 套餐包最低单价
+	 */
+	@DbIgnore
+	private BigDecimal lumaPackagePrice;
+
+	/**
+	 * 用户 mj fast次数
+	 */
+	@DbIgnore
+	private Integer mjUserFastNum;
+
+	/**
+	 * 用户 mj 加量包次数
+	 */
+	@DbIgnore
+	private Integer mjUserUpgradeNum;
+
+
+	/**
+	 * 用户 mj relax次数
+	 */
+	@DbIgnore
+	private Integer mjUserRelaxNum;
+
+	/**
+	 * gpt 用户镜像限制次数
+	 */
+	@DbIgnore
+	private Integer gptUserLimitNum;
+
+	/**
+	 * gpt 用户镜像限制时间
+	 */
+	@DbIgnore
+	private Long gptUserLimitTime;
+
+	/**
+	 * luma 用户次数
+	 */
+	@DbIgnore
+	private Integer lumaUserNum;
+
+	/**
+	 * deepseek限制次数
+	 */
+	@DbIgnore
+	private Integer userDsLimitNum;
+
+	/**
+	 * deepseek限制时间
+	 */
+	@DbIgnore
+	private Long userDsLimitTime;
+
+	/**
+	 * 其他模型限制次数
+	 */
+	@DbIgnore
+	private Integer userOtherLimitNum;
+
+	/**
+	 * 其他模型限制时间
+	 */
+	@DbIgnore
+	private Long userOtherLimitTime;
+
+	/**
+	 * 镜像token
+	 */
+	@DbIgnore
+	private String userToken;
+
+	@DbIgnore
+	private Long use;
+
+	/**
+	 * 是否可升级套餐 (标准,专业)
+	 */
+	@DbIgnore
+	private Boolean upgrade;
+
+	@DbIgnore
+	private Long packageId;
+
+	/**
+	 * 目前已升级套餐价格
+	 */
+	@DbIgnore
+	private BigDecimal packagePrice;
+
+	@DbIgnore
+	private DistributePosterGoodsDetailView posterInfo;
+
+	/**
+	 * 是否是续费升级
+	 */
+	@DbIgnore
+	private Boolean isRenewPackage;
+
+	/**
+	 * 续费升级规格id
+	 */
+	@DbIgnore
+	private Long renewSkuId;
+
+	/**
+	 * 续费升级目前规格
+	 */
+	@DbIgnore
+	private GoodsDonSkuRenewView renewSku;
+
+	/**
+	 * 续费升级折扣
+	 */
+	@DbIgnore
+	private BigDecimal discount;
+
+	/**
+	 * gpt模式 0旧版 1新版
+	 */
+	@DbIgnore
+	private Integer model;
+
+	/**
+	 * 订单id
+	 */
+	@DbIgnore
+	private Long orderId;
+}

+ 5 - 3
netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java

@@ -11,9 +11,7 @@ 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.GoodsCategorySkuView;
-import com.cyksj.model.views.RenewalView;
-import com.cyksj.model.views.UserRecommendGoodsFrontView;
+import com.cyksj.model.views.*;
 import com.ejlchina.searcher.SearchResult;
 
 import java.util.List;
@@ -113,4 +111,8 @@ public interface GroupRelationFrontService {
 	Boolean refundNetflix(ErrorNetflixChangeReq req) throws Exception;
 
 	NetflixRefundInfoResp refundNetflixInfo(Long userId, Long relationId);
+
+	List<UserMirrorTicketView> getMirrorTicket(long userId);
+
+	TicketRenewUpgradeView getRenewUpgradeInfo(long userId, Long relationId);
 }

+ 173 - 0
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -202,6 +202,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final UserBenefitsService userBenefitsService;
 
+	private final ChatgptUserMapper chatgptUserMapper;
+
 	@Override
 	public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account, String orderNo, Integer cmt) {
 		User u = userMapper.selectById(userId);
@@ -1772,6 +1774,144 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		return true;
 	}
 
+	@Override
+	public List<UserMirrorTicketView> getMirrorTicket(long userId) {
+		User u = userMapper.selectById(userId);
+		if (u == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
+		if (u.getIsBlack()) {
+			return null;
+		}
+		List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, u);
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+		DateTime now = DateTime.now();
+		String lang = request.getHeader("lang");
+		List<UserMirrorTicketView> list = beanSearcher.searchAll(UserMirrorTicketView.class, builder
+				.field(UserMirrorTicketView::getUserId, userIds).op(Operator.InList)
+				.field(UserMirrorTicketView::getIsMirror, Boolean.TRUE)
+				//过期7天内的镜像车票都展示
+				.field(UserMirrorTicketView::getExpiryTime, DateUtil.offsetDay(now, -7)).op(Operator.GreaterThan)
+				.orderBy(RenewalView::getExpiryTime).asc()
+				.build());
+		list.forEach(ticket -> {
+			if (ticket.getExpiryTime() != null) {
+				String remainDays = DateUtil.formatBetween(now, ticket.getExpiryTime(), BetweenFormater.Level.DAY);
+				if ("0天".equals(remainDays)) {
+					remainDays = "小于1天";
+				} else {
+					//当天也算
+					int days = Integer.parseInt(remainDays.substring(0, remainDays.indexOf("天")));
+					remainDays = days + 1 + "天";
+				}
+				ticket.setRemainDays(remainDays);
+				ticket.setTotal(DateUtil.betweenDay(ticket.getStartTime(), ticket.getExpiryTime(), false) + 1);
+			}
+			if (ticket.getExpiryTime() != null) {
+				ticket.setExpiryTimeStr(DateUtil.format(ticket.getExpiryTime(), "yyyy-MM-dd"));
+			}
+			//续费升级折扣
+			BigDecimal renewDiscount = getRenewDiscount(ticket.getGoodsId(), ticket.getSkuId(), ticket.getIsMirror(), ticket.getSkuNum());
+			ticket.setDiscount(renewDiscount);
+			setAIZoneMirrorTicketInfo(ticket);
+
+			if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+				String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(ticket.getSkuId(), lang);
+				if (StrUtil.isNotBlank(languageSpecVal)) {
+					ticket.setSpecVal(languageSpecVal);
+				}
+			}
+
+			OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
+					.eq(OrderDon::getRelationId, ticket.getRelationId())
+					.eq(OrderDon::getUserId, ticket.getUserId())
+					.eq(OrderDon::getOrderType, 1)
+					.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
+					.orderByDesc(OrderDon::getId)
+					.last("limit 1"));
+			if (orderDon != null) {
+				ticket.setOrderId(orderDon.getId());
+			}
+		});
+		userLoginRecordService.saveUserLoginDayRecord(userId);
+		return list;
+	}
+
+	@Override
+	public TicketRenewUpgradeView getRenewUpgradeInfo(long userId, Long relationId) {
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder()
+				.field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
+				.field(GroupsRelationView::getId, relationId)
+				.field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
+				.build());
+		TicketRenewUpgradeView ticketRenewUpgradeView = new TicketRenewUpgradeView();
+		if (groupsRelationView != null) {
+			String lang = request.getHeader("lang");
+			//clause pro
+			if (groupsRelationView.getGoodsId() == 75l) {
+				try {
+					ClaudeUserView userInfo = claudeService.getUserInfo(groupsRelationView.getUserId(), groupsRelationView.getId());
+					Long renewSkuId = userInfo.getRenewSkuId();
+					if (renewSkuId != null) {
+						GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, renewSkuId).build());
+						ticketRenewUpgradeView.setRenewSku(renewSku);
+					}
+					ticketRenewUpgradeView.setGptUserLimitNum(userInfo.getLimitNum());
+					ticketRenewUpgradeView.setGptUserLimitTime(userInfo.getLimitTime());
+				} catch (Exception e) {
+				}
+			}
+
+			if (groupsRelationView.getGoodsId() == 18) {
+				try {
+					//gpt用户镜像
+					ChatGptUserView userInfo = chatGptAccountService.getUserInfo(groupsRelationView.getUserId(), groupsRelationView.getId());
+					Integer count = upgradePackageMapper.selectCount(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + groupsRelationView.getSkuId() + "\"')")
+							.gt(UpgradePackage::getNum, userInfo.getLimitNum())
+							.eq(UpgradePackage::getStatus, Boolean.TRUE)
+							.eq(UpgradePackage::getGptType, 0)
+							.eq(UpgradePackage::getDeleted, Boolean.TRUE));
+					ticketRenewUpgradeView.setUpgrade(count > 0 ? true : false);
+					ticketRenewUpgradeView.setPackageId(userInfo.getPackageId());
+					ticketRenewUpgradeView.setGptUserLimitNum(userInfo.getLimitNum());
+					ticketRenewUpgradeView.setGptUserLimitTime(userInfo.getLimitTime());
+					ticketRenewUpgradeView.setUserDsLimitNum(userInfo.getDsLimitNum());
+					ticketRenewUpgradeView.setUserDsLimitTime(userInfo.getDsLimitTime());
+					ticketRenewUpgradeView.setUserOtherLimitNum(userInfo.getOtherLimitNum());
+					ticketRenewUpgradeView.setUserOtherLimitTime(userInfo.getOtherLimitTime());
+					if (userInfo.getPackageId() != 0) {
+						UpgradePackage upgradePackage = upgradePackageMapper.selectById(userInfo.getPackageId());
+						ticketRenewUpgradeView.setPackagePrice(upgradePackage.getPrice());
+						Long upgradeOrderDonSkuId = upgradePackage.getUpgradeSkuId();
+						GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, upgradeOrderDonSkuId).build());
+						renewSku.setPackageId(userInfo.getPackageId());
+						ticketRenewUpgradeView.setRenewSku(renewSku);
+					}
+					ticketRenewUpgradeView.setIsRenewPackage(userInfo.getIsRenewPackage());
+					Long renewSkuId = userInfo.getRenewSkuId();
+					if (renewSkuId != null) {
+						GoodsDonSkuRenewView upgradeSkuRenewView = ticketRenewUpgradeView.getRenewSku();
+						GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, renewSkuId).build());
+						//续费升级是更高级规格
+						if (upgradeSkuRenewView == null || (renewSku.getGptUserLimitNum() >= upgradeSkuRenewView.getGptUserLimitNum() && renewSku.getMonths() >= userInfo.getMonths())) {
+							Optional.ofNullable(orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
+									.eq(OrderDonRenewRecord::getOrderId, userInfo.getRenewOrderId())
+									.last("limit 1"))).ifPresent(e -> renewSku.setOriginalOrderId(e.getOrderId()));
+							if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+								String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(renewSku.getSkuId(), lang);
+								if (StrUtil.isNotBlank(languageSpecVal)) {
+									renewSku.setSpecVal(languageSpecVal);
+								}
+							}
+							ticketRenewUpgradeView.setRenewSku(renewSku);
+						}
+					}
+				} catch (Exception e) {
+				}
+			}
+		}
+		return ticketRenewUpgradeView;
+	}
+
 	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());
@@ -1836,6 +1976,24 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		}
 	}
 
+	private BigDecimal getRenewDiscount(Long goodsId, Long skuId, Boolean isMirror, Integer skuNum) {
+		//镜像或者独立规格
+		if (isMirror || (skuNum != null && skuNum == 1)) {
+			RenewUpgradePackage renewUpgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
+					.eq(RenewUpgradePackage::getGoodsId, goodsId)
+					.eq(RenewUpgradePackage::getStatus, 1)
+					.eq(RenewUpgradePackage::getDeleted, 1)
+					.eq(RenewUpgradePackage::getSkuId, skuId)
+					.orderByAsc(RenewUpgradePackage::getDiscount)
+					.last("limit 1")
+					.select(RenewUpgradePackage::getId, RenewUpgradePackage::getDiscount));
+			if (renewUpgradePackage != null) {
+				return renewUpgradePackage.getDiscount();
+			}
+		}
+		return null;
+	}
+
 	private void setMirrorTicketInfo(RenewalView ticket) {
 		//设置MJ镜像信息
 		setMjMirrorInfo(ticket);
@@ -2113,4 +2271,19 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		orderDonMapper.insert(orderDon);
 		return orderDon;
 	}
+
+	private void setAIZoneMirrorTicketInfo(UserMirrorTicketView ticket) {
+		setAIZoneGptMirrorInfo(ticket);
+	}
+
+	private void setAIZoneGptMirrorInfo(UserMirrorTicketView ticket) {
+		if (ticket.getGoodsId() != null && ticket.getGoodsId() == Constant.GPT_PLUS_GID) {
+			ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
+					.eq(ChatgptUser::getRelationId, ticket.getRelationId())
+					.last("limit 1"));
+			if (chatgptUser != null) {
+				ticket.setModel(chatgptUser.getModel());
+			}
+		}
+	}
 }

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

@@ -1292,4 +1292,24 @@ public class GroupRelationController {
         Boolean flag = groupRelationFrontService.getMirrorPopups(userId);
         return GatewayResponse.SUCCESS.newBuilder().toResult(flag);
     }
+
+    /**
+     * 镜像车票列表
+     */
+    @GetMapping("/get/mirror/ticket")
+    public Result<List<UserMirrorTicketView>> getMirrorTicket() {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        List<UserMirrorTicketView> list = groupRelationFrontService.getMirrorTicket(userId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(list);
+    }
+
+    /**
+     * 镜像车票续费升级信息
+     */
+    @GetMapping("/get/renewInfo")
+    public Result<TicketRenewUpgradeView> getRenewUpgradeInfo(Long relationId) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        TicketRenewUpgradeView renewView = groupRelationFrontService.getRenewUpgradeInfo(userId, relationId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(renewView);
+    }
 }