Sfoglia il codice sorgente

Merge branch 'gpt_upgrade'

# Conflicts:
#	netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonSkuController.java
zoujiajian 2 anni fa
parent
commit
21fd34ffb3
18 ha cambiato i file con 436 aggiunte e 33 eliminazioni
  1. 12 0
      netflix-dao/src/main/java/com/cyksj/model/entity/ChatgptUser.java
  2. 5 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UpgradeOrderDon.java
  3. 18 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UpgradePackage.java
  4. 3 7
      netflix-dao/src/main/java/com/cyksj/model/manage/views/UpgradeOrderDonSearchView.java
  5. 33 0
      netflix-dao/src/main/java/com/cyksj/model/views/ChatGptUserView.java
  6. 30 1
      netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java
  7. 18 0
      netflix-dao/src/main/java/com/cyksj/model/views/UpgradePackageView.java
  8. 35 1
      netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java
  9. 2 0
      netflix-service/src/main/java/com/cyksj/service/mange/CmsGoodsDonSkuService.java
  10. 62 4
      netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonSkuServiceImpl.java
  11. 63 0
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  12. 91 13
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  13. 2 0
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  14. 43 2
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  15. 13 0
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  16. 4 2
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonSkuController.java
  17. 0 2
      netflix-web/src/main/java/com/cyksj/web/controller/manage/upgrade/UpgradePackageController.java
  18. 2 1
      netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

+ 12 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/ChatgptUser.java

@@ -1,5 +1,6 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.ejlchina.searcher.bean.SearchBean;
@@ -75,4 +76,15 @@ public class ChatgptUser extends BaseEntity {
      * 是否为车队
      */
     private Boolean isCar;
+
+    /**
+     * 目前套餐包id
+     */
+    private Long packageId;
+
+    /**
+     * 清洗套餐包时间
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Date clearPackageTime;
 }

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UpgradeOrderDon.java

@@ -45,6 +45,11 @@ public class UpgradeOrderDon extends BaseEntity {
 
     private String transactionId;
 
+    /**
+     * 时间
+     * */
+    private Long time;
+
     private Integer num;
 
     private BigDecimal price;

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UpgradePackage.java

@@ -1,5 +1,7 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -26,11 +28,27 @@ public class UpgradePackage extends BaseEntity{
      */
     private String skuIds;
 
+    /**
+     * 升级规格
+     */
+    private Long upgradeSkuId;
+
+    /**
+     * gpt类型,0.车票套餐
+     */
+    private Integer gptType;
+
     /**
      * 套餐价格
      */
     private BigDecimal price;
 
+    /**
+     * 时间限制
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Long time;
+
     /**
      * 数量
      */

+ 3 - 7
netflix-dao/src/main/java/com/cyksj/model/manage/views/UpgradeOrderDonSearchView.java

@@ -1,20 +1,13 @@
 package com.cyksj.model.manage.views;
 
-import com.cyksj.model.entity.GoodsDon;
-import com.cyksj.model.entity.OrderDon;
-import com.cyksj.model.entity.OrderDonWaybill;
 import com.cyksj.model.entity.UpgradeOrderDon;
-import com.cyksj.model.views.GoodsDonSkuView;
 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;
-import java.util.List;
 
 /*
  *项目名: netflix
@@ -40,6 +33,9 @@ public class UpgradeOrderDonSearchView {
 	@DbField("up.num")
 	private Integer num;
 
+	@DbField("g.id")
+	private Long goodsId;
+
 	@DbField("g.title")
 	private String title;
 

+ 33 - 0
netflix-dao/src/main/java/com/cyksj/model/views/ChatGptUserView.java

@@ -3,6 +3,7 @@ package com.cyksj.model.views;
 import lombok.Builder;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -37,4 +38,36 @@ public class ChatGptUserView {
      * 使用次数
      */
     private Long use;
+
+    /**
+     * 是否可升级套餐
+     */
+    private Boolean upgrade;
+
+    /**
+     * 原订单id
+     */
+    private Long orderId;
+
+    private Long goodsId;
+
+    /**
+     * 规格
+     */
+    private Long skuId;
+
+    /**
+     * 月份
+     */
+    private Integer months;
+
+    /**
+     * 目前套餐id
+     */
+    private Long packageId;
+
+    /**
+     * 目前套餐价格
+     */
+    private BigDecimal packagePrice;
 }

+ 30 - 1
netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java

@@ -97,7 +97,6 @@ public class RenewalView {
     private Long userId;
 
     @DbField("gr.expiry_time")
-    @JsonIgnore
     private Date expiryTime;
 
     @DbIgnore
@@ -222,4 +221,34 @@ public class RenewalView {
      */
     @DbIgnore
     private Integer mjUserRelaxNum;
+
+    /**
+     * gpt 用户镜像限制次数
+     */
+    @DbIgnore
+    private Integer gptUserLimitNum;
+
+    /**
+     * gpt 用户镜像限制时间
+     */
+    @DbIgnore
+    private Long gptUserLimitTime;
+
+    @DbIgnore
+    private Long use;
+
+    /**
+     * 是否可升级套餐 (标准,专业)
+     */
+    @DbIgnore
+    private Boolean upgrade;
+
+    @DbIgnore
+    private Long packageId;
+
+    /**
+     * 目前已升级套餐价格
+     */
+    @DbIgnore
+    private BigDecimal packagePrice;
 }

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

@@ -42,6 +42,18 @@ public class UpgradePackageView {
     @DbField("up.sku_ids")
     private String skuIds;
 
+    /**
+     * 升级规格
+     */
+    @DbField("up.upgrade_sku_id")
+    private Long upgradeSkuId;
+
+    /**
+     * gpt类型,0.车票套餐
+     */
+    @DbField("up.gpt_type")
+    private Integer gptType;
+
     /**
      * 商品规格名称
      */
@@ -54,6 +66,12 @@ public class UpgradePackageView {
     @DbField("up.price")
     private BigDecimal price;
 
+    /**
+     * 小时
+     */
+    @DbField("up.time")
+    private Integer time;
+
     /**
      * 数量
      */

+ 35 - 1
netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java

@@ -12,6 +12,7 @@ import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.common.util.StringUtil;
@@ -99,6 +100,10 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
 
     private final CollegeStudentStationUseTicketRecordMapper collegeStudentStationUseTicketRecordMapper;
 
+    private final UpgradePackageMapper upgradePackageMapper;
+
+    private final OrderDonMapper orderDonMapper;
+
     @Override
     public String addAccount(Account account) {
         if (isAccountExists(account)) {
@@ -814,12 +819,41 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
             GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
             GoodsDonSku goodsDonSku = skuMapper.selectById(groupsTrips.getSkuId());
             ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, relationId));
+
+            Integer count = upgradePackageMapper.selectCount(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + groupsTrips.getSkuId() + "\"')")
+                    .gt(UpgradePackage::getNum, chatgptUser.getLimitNum())
+                    .eq(UpgradePackage::getStatus, Boolean.TRUE)
+                    .eq(UpgradePackage::getGptType, 0)
+                    .eq(UpgradePackage::getDeleted, Boolean.TRUE));
+            Boolean upgrade = count > 0 ? true : false;
+            OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
+                    .eq(OrderDon::getRelationId, relationId)
+                    .eq(OrderDon::getUserId, groupsRelation.getUserId())
+                    .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
+                    .orderByDesc(OrderDon::getId)
+                    .last("limit 1"));
+            Long orderId = null;
+            if (orderDon != null) {
+                orderId = orderDon.getId();
+            }
+            BigDecimal packagePrice = null;
+            if (chatgptUser.getPackageId() != 0) {
+                UpgradePackage upgradePackage = upgradePackageMapper.selectById(chatgptUser.getPackageId());
+                packagePrice = upgradePackage.getPrice();
+            }
             return ChatGptUserView.builder()
                     .skuName(goodsDonSku.getSubTitle())
                     .expireTime(chatgptUser.getExpireTime())
                     .limitNum(chatgptUser.getLimitNum())
                     .limitTime(chatgptUser.getLimitTime())
-                    .use(Math.min(chatgptUser.getLimitNum(),getConversationCount(chatgptUser.getUserToken(), chatgptUser.getLimitTime())))
+                    .upgrade(upgrade)
+                    .orderId(orderId)
+                    .goodsId(goodsDonSku.getGoodsId())
+                    .skuId(goodsDonSku.getId())
+                    .months(goodsDonSku.getMonths())
+                    .use(Math.min(chatgptUser.getLimitNum(), getConversationCount(chatgptUser.getUserToken(), chatgptUser.getLimitTime())))
+                    .packageId(chatgptUser.getPackageId())
+                    .packagePrice(packagePrice)
                     .build();
         } else {
             throw BusinessRuntimeException.getInstance("您还未购买该车票");

+ 2 - 0
netflix-service/src/main/java/com/cyksj/service/mange/CmsGoodsDonSkuService.java

@@ -17,4 +17,6 @@ public interface CmsGoodsDonSkuService extends IService<GoodsDonSku> {
 	void updateMirrorCarUserNum(GoodsDonSku sku);
 
 	void setBelowPriceShopSkuDown(Long skuId, BigDecimal newPrice);
+
+	void handleGptPackageSku(GoodsDonSku dbSku, GoodsDonSku sku) throws Exception;
 }

+ 62 - 4
netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonSkuServiceImpl.java

@@ -5,16 +5,15 @@ import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
 import com.cyksj.mapper.ChatgptUserMapper;
 import com.cyksj.mapper.GoodsDiscountPlusPurchaseRelationMapper;
 import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.mapper.UpgradePackageMapper;
 import com.cyksj.mapper.shop.YhShopGoodsRateMapper;
 import com.cyksj.mapper.shop.YhShopGoodsSkuMapper;
 import com.cyksj.mapper.shop.YhShopSkuSysTakeDownRecordMapper;
-import com.cyksj.model.entity.GoodsDiscountPlusPurchaseRelation;
-import com.cyksj.model.entity.GoodsDonSku;
-import com.cyksj.model.entity.YhShopGoodsRate;
-import com.cyksj.model.entity.YhShopGoodsSku;
+import com.cyksj.model.entity.*;
 import com.cyksj.service.mange.CmsGoodsDonSkuService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -47,6 +46,8 @@ public class CmsGoodsDonSkuServiceImpl extends ServiceImpl<GoodsDonSkuMapper,Goo
 
 	private final YhShopSkuSysTakeDownRecordMapper yhShopSkuSysTakeDownRecordMapper;
 
+	private final UpgradePackageMapper upgradePackageMapper;
+
 	@Override
 	public void handleDiscountPurchaseGoods(GoodsDonSku sku, List<GoodsDiscountPlusPurchaseRelation> discountPlusPurchaseGoods) {
 		Long skuId = sku.getId();
@@ -146,6 +147,63 @@ public class CmsGoodsDonSkuServiceImpl extends ServiceImpl<GoodsDonSkuMapper,Goo
 		}
 	}
 
+	@Override
+	public void handleGptPackageSku(GoodsDonSku dbSku, GoodsDonSku sku) throws Exception {
+		Long gptLimitTime = dbSku.getGptLimitTime();
+		Integer gptLimitNum = dbSku.getGptLimitNum();
+		BigDecimal price = dbSku.getPrice();
+		BigDecimal newPrice = sku.getPrice();
+		//GPT镜像套餐包关联
+		if (sku.getGoodsId() == 18 && sku.getIsMirror()) {
+			//同步升级规格的价格
+			if (gptLimitNum != sku.getGptLimitNum() || gptLimitTime != sku.getGptLimitTime() || price.compareTo(newPrice) != 0) {
+				if (price.compareTo(newPrice) != 0) {
+					//本身是需升级的规格 同步套餐价格
+					UpgradePackage upgradePackageSelfBind = upgradePackageMapper.selectOne(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + sku.getId() + "\"')")
+							.eq(UpgradePackage::getStatus, Boolean.TRUE)
+							.eq(UpgradePackage::getGptType, 0)
+							.eq(UpgradePackage::getDeleted, Boolean.TRUE)
+							.last("limit 1"));
+					if (upgradePackageSelfBind != null) {
+						Long upgradeSkuId = upgradePackageSelfBind.getUpgradeSkuId();
+						GoodsDonSku upgradeSku = skuMapper.selectById(upgradeSkuId);
+						if (upgradeSku != null && upgradeSku.getPrice().compareTo(sku.getPrice()) > 0) {
+							upgradePackageSelfBind.setPrice(upgradeSku.getPrice().subtract(sku.getPrice()));
+							upgradePackageMapper.updateById(upgradePackageSelfBind);
+						}
+					}
+				}
+
+				//被绑定升级套餐
+				List<UpgradePackage> toUpgradePackages = upgradePackageMapper.selectList(Wrappers.lambdaQuery(UpgradePackage.class)
+						.eq(UpgradePackage::getUpgradeSkuId, sku.getId()));
+				if (CollUtil.isNotEmpty(toUpgradePackages)) {
+					toUpgradePackages.forEach(toUpgradePackage->{
+						if (price.compareTo(sku.getPrice()) != 0) {
+							Long skuId = null;
+							try {
+								skuId = Jsons.parseList(toUpgradePackage.getSkuIds(), Long.class).get(0);
+								//需升级的规格
+								GoodsDonSku oriSku = skuMapper.selectById(skuId);
+								if (oriSku == null) {
+									return;
+								}
+								BigDecimal differ = sku.getPrice().subtract(oriSku.getPrice());
+								if (differ.compareTo(BigDecimal.ZERO) > 0) {
+									toUpgradePackage.setPrice(differ);
+								}
+							} catch (Exception e) {
+							}
+						}
+						toUpgradePackage.setTime(sku.getGptLimitTime());
+						toUpgradePackage.setNum(sku.getGptLimitNum());
+						upgradePackageMapper.updateById(toUpgradePackage);
+					});
+				}
+			}
+		}
+	}
+
 	public void checkPurchaseParamsAndSaveOrUpdate(Long goodsId, Long skuId, GoodsDiscountPlusPurchaseRelation discountGoods) {
 		Long disSid = discountGoods.getDisSid();
 		if (disSid == null) {

+ 63 - 0
netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java

@@ -61,6 +61,7 @@ import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.relation.GroupsRelationExpiryRecordService;
 import com.cyksj.service.shop.YhShopDistributeService;
 import com.cyksj.service.user.UserBenefitsService;
+import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.wechat.WeChatService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.util.MapUtils;
@@ -183,6 +184,10 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
 
     private final MidjourneyUserMapper midjourneyUserMapper;
 
+    private final GroupsRelationMapper groupsRelationMapper;
+
+    private final UserBindRelationService userBindRelationService;
+
     private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
     @Override
@@ -384,6 +389,23 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             upgradeOrderDonMapper.updateById(orderDon);
             return;
         }
+        Long userId = orderDon.getUserId();
+        List<Long> userIdList = null;
+        //检验gpt套餐
+        if (upgradePackage.getGoodsId() == 18) {
+            userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+            //是否有更高级的套餐
+            UpgradeOrderDon more = upgradeOrderDonMapper.selectOne(Wrappers.lambdaQuery(UpgradeOrderDon.class)
+                    .in(UpgradeOrderDon::getUserId, userIdList)
+                    .eq(UpgradeOrderDon::getRelationId, orderDon.getRelationId())
+                    .gt(UpgradeOrderDon::getNum, orderDon.getNum())
+                    .eq(UpgradeOrderDon::getStatus, UpgradeOrderDon.Status.complete)
+                    .last("limit 1"));
+            if (more != null) {
+                throw BusinessRuntimeException.getInstance("请先退掉其更高级套餐");
+            }
+        }
+
         //调用第三方接口退款
         String outNo = orderRefundService.centerUpgradeRefund(refundReq, orderDon);
         orderDon.setRefundDesc(refundReq.getRefundDesc());
@@ -408,6 +430,47 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
                 }
             }
         }
+
+        //扣除gpt套餐升级
+        if (upgradePackage.getGoodsId() == 18) {
+            ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, orderDon.getRelationId()));
+            if (chatgptUser != null) {
+                GroupsRelation relation = groupsRelationMapper.selectById(chatgptUser.getRelationId());
+                GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
+                GoodsDonSku sku = skuMapper.selectById(groupsTrips.getSkuId());
+
+                //原先sku的套餐
+                Long gptLimitTime = sku.getGptLimitTime();
+                Integer gptLimitNum = sku.getGptLimitNum();
+
+                //次等套餐的规格
+                UpgradeOrderDon secondUpgrade = upgradeOrderDonMapper.selectOne(Wrappers.lambdaQuery(UpgradeOrderDon.class)
+                        .in(UpgradeOrderDon::getUserId, userIdList)
+                        .eq(UpgradeOrderDon::getRelationId, orderDon.getRelationId())
+                        .lt(UpgradeOrderDon::getNum, orderDon.getNum())
+                        .eq(UpgradeOrderDon::getStatus, UpgradeOrderDon.Status.complete)
+                        .last("limit 1"));
+                if (secondUpgrade != null) {
+                    gptLimitTime = secondUpgrade.getTime();
+                    gptLimitNum = secondUpgrade.getNum();
+                }
+                Long packageId = 0l;
+                //降级套餐
+                if (secondUpgrade != null) {
+                    packageId = secondUpgrade.getPackageId();
+                }
+                int update = chatgptUserMapper.update(null, Wrappers.lambdaUpdate(ChatgptUser.class)
+                        .set(ChatgptUser::getLimitTime, gptLimitTime)
+                        .set(ChatgptUser::getLimitNum, gptLimitNum)
+                        .set(ChatgptUser::getPackageId, packageId)
+                        //无次等套餐 不需要清除套餐时间
+                        .set(secondUpgrade == null, ChatgptUser::getClearPackageTime, null)
+                        .eq(ChatgptUser::getId, chatgptUser.getId()));
+                if (update == 0) {
+                    log.info("chatgptUser 升级套餐包增值失败 id:{},orderId:{}", chatgptUser.getId(), orderDon.getId());
+                }
+            }
+        }
     }
 
     /**

+ 91 - 13
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -3,6 +3,7 @@ package com.cyksj.service.order.impl;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
@@ -303,6 +304,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final MidjourneyUserMapper midjourneyUserMapper;
 
+	private final ChatgptUserMapper chatgptUserMapper;
+
 	private final DistributeExtraRebateService distributeExtraRebateService;
 
 	private final UserTrialTicketJumpPayRecordMapper userTrialTicketJumpPayRecordMapper;
@@ -3205,13 +3208,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 	public UpgradeOrderDon submitUpgrade(OrderPayRequest payRequest) {
 		User user = null;
 		Long userId = payRequest.getUserId();
-		if (userId != null) {
-			int noPayCount = upgradeOrderDonMapper.selectCount(Wrappers.lambdaQuery(UpgradeOrderDon.class).eq(UpgradeOrderDon::getUserId, userId).eq(UpgradeOrderDon::getPackageId, payRequest.getPackageId())
-					.eq(UpgradeOrderDon::getStatus, UpgradeOrderDon.Status.noPayment.toString()));
-			if (noPayCount > 0) {
-				throw new BusinessRuntimeException("您有未支付订单.");
-			}
-		}
 		String orderPhone = payRequest.getPhone();
 		if (StrUtil.isNotBlank(orderPhone)) {
 			user = saveOrGetOrderPhoneUser(payRequest);
@@ -3226,6 +3222,14 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			if (user == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
 			if (user.getIsBlack()) throw BusinessRuntimeException.getInstance("系统检测操作异常,请稍后再试");
 		}
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, user);
+		int noPayCount = upgradeOrderDonMapper.selectCount(Wrappers.lambdaQuery(UpgradeOrderDon.class)
+				.in(UpgradeOrderDon::getUserId, userIdList)
+				.eq(UpgradeOrderDon::getRelationId, payRequest.getRelationId())
+				.eq(UpgradeOrderDon::getStatus, UpgradeOrderDon.Status.noPayment.toString()));
+		if (noPayCount > 0) {
+			throw new BusinessRuntimeException("您有未支付订单.");
+		}
 		GroupsRelation groupsRelation = getGroupsRelation(payRequest.getUserId(), payRequest.getRelationId());
 		GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
 		GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(groupsTrips.getSkuId());
@@ -3238,14 +3242,66 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			if (upgradePackage.getPrice() == null || upgradePackage.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
 				throw BusinessRuntimeException.getInstance("下单商品价格异常");
 			}
-			if (payRequest.getDonMoney().compareTo(upgradePackage.getPrice()) < 0) {
-				log.info("套餐包:{}支付金额:{}异常,调整用户userId:{}支付金额为:{}", upgradePackage.getName(), payRequest.getDonMoney(), user.getId(), upgradePackage.getPrice());
-				payRequest.setDonMoney(upgradePackage.getPrice());
+			if (goodsDonSku.getGoodsId() == 18) {
+				ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, payRequest.getRelationId()));
+				if (chatgptUser == null) {
+					throw BusinessRuntimeException.getInstance("车票未激活gpt账号,请先激活");
+				}
+				Date expiryTime = groupsRelation.getExpiryTime();
+				//剩余多少天
+				DateTime now = DateTime.now();
+				long remainDay = DateUtil.between(now, expiryTime, DateUnit.DAY) + 1;
+				if (remainDay <= 0) {
+					throw BusinessRuntimeException.getInstance("车票已过期");
+				}
+				Long upgradeSkuId = upgradePackage.getUpgradeSkuId();
+				GoodsDonSku upgradeSku = goodsDonSkuMapper.selectById(upgradeSkuId);
+				Integer upgradeSkuGptLimitNum = upgradeSku.getGptLimitNum();
+				if (upgradeSkuGptLimitNum <= chatgptUser.getLimitNum()) {
+					throw BusinessRuntimeException.getInstance("您已升级该套餐");
+				}
+				//两者之间的差价
+				BigDecimal differPrice = upgradeSku.getPrice().subtract(goodsDonSku.getPrice());
+				Long userUpgradePackageId = chatgptUser.getPackageId();
+				//已升级的套餐包
+				if (userUpgradePackageId != 0) {
+					UpgradePackage hasUpgradePackage = upgradePackageMapper.selectById(userUpgradePackageId);
+					BigDecimal thisPackagePrice = hasUpgradePackage.getPrice();
+					differPrice = upgradePackage.getPrice().subtract(thisPackagePrice);
+				}
+
+				if (differPrice.compareTo(BigDecimal.ZERO) < 0) {
+					throw BusinessRuntimeException.getInstance("车票套餐升级错误,请联系客服");
+				}
+
+				//自然月差价
+				DateTime offset = DateUtil.offsetMonth(now, goodsDonSku.getMonths());
+				long totalDays = DateUtil.between(now, offset, DateUnit.DAY) + 1;
+				//待支付价格
+				//每日单价
+				BigDecimal singlePrice = differPrice.divide(BigDecimal.valueOf(totalDays), 0, RoundingMode.HALF_UP);
+
+				BigDecimal payUpgradePackagePrice = singlePrice.multiply(BigDecimal.valueOf(remainDay));
+				//车票当日买 当天升级 用套餐包原价
+				if (totalDays == remainDay) {
+					payUpgradePackagePrice = differPrice;
+				}
+				if (payRequest.getDonMoney().compareTo(payUpgradePackagePrice) < 0) {
+					payRequest.setDonMoney(payUpgradePackagePrice);
+				}
 			}
-			MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, payRequest.getRelationId()));
-			if (midjourneyUser == null){
-				throw BusinessRuntimeException.getInstance("车票未激活Midjourney账号,请先激活");
+
+			if (goodsDonSku.getGoodsId() == 26) {
+				if (payRequest.getDonMoney().compareTo(upgradePackage.getPrice()) < 0) {
+					log.info("套餐包:{}支付金额:{}异常,调整用户userId:{}支付金额为:{}", upgradePackage.getName(), payRequest.getDonMoney(), user.getId(), upgradePackage.getPrice());
+					payRequest.setDonMoney(upgradePackage.getPrice());
+				}
+				MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, payRequest.getRelationId()));
+				if (midjourneyUser == null){
+					throw BusinessRuntimeException.getInstance("车票未激活Midjourney账号,请先激活");
+				}
 			}
+
 			String donNo = SEQUENCE.nextId().toString();
 			UpgradeOrderDon upgradeOrderDon = new UpgradeOrderDon();
 			upgradeOrderDon.setOrderNo(donNo);
@@ -3255,6 +3311,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			upgradeOrderDon.setPackageId(payRequest.getPackageId());
 			upgradeOrderDon.setPrice(upgradePackage.getPrice());
 			upgradeOrderDon.setNum(upgradePackage.getNum());
+			upgradeOrderDon.setTime(upgradePackage.getTime());
 			upgradeOrderDon.setGoodsId(goodsDonSku.getGoodsId());
 			upgradeOrderDon.setSkuId(goodsDonSku.getId());
 			upgradeOrderDon.setMoney(payRequest.getDonMoney());
@@ -3419,6 +3476,27 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 				}
 			}
 		}
+
+		//gpt 升级套餐
+		if (upgradePackage.getGoodsId() == 18) {
+			ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, orderDon.getRelationId()));
+			if (chatgptUser != null) {
+				Long time = upgradePackage.getTime();
+				Integer num = upgradePackage.getNum();
+				//下次清洗用户套餐包时间 避免续费时间修改
+				Date clearPackageTime = chatgptUser.getExpireTime();
+
+				int update = chatgptUserMapper.update(null, Wrappers.lambdaUpdate(ChatgptUser.class)
+						.set(ChatgptUser::getLimitTime, time)
+						.set(ChatgptUser::getLimitNum, num)
+						.set(ChatgptUser::getPackageId, orderDon.getPackageId())
+						.set(ChatgptUser::getClearPackageTime, clearPackageTime)
+						.eq(ChatgptUser::getId, chatgptUser.getId()));
+				if (update == 0) {
+					log.info("chatgptUser 升级套餐包增值失败 id:{},orderId:{}", chatgptUser.getId(), orderDon.getId());
+				}
+			}
+		}
 	}
 
 

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

@@ -57,4 +57,6 @@ public interface GroupRelationFrontService {
 	List<RenewalView> getExpiryRenewalNotify(Long userId);
 
 	void getCollegeStudentUserGptTicket(Long userId);
+
+	RenewalView getTicketDetail(long userId, Long relationId);
 }

+ 43 - 2
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -26,6 +26,7 @@ import com.cyksj.model.entity.*;
 import com.cyksj.model.request.SpecialGoodsTicketReq;
 import com.cyksj.model.views.*;
 import com.cyksj.redis.RedisService;
+import com.cyksj.service.chatgpt.ChatGptAccountService;
 import com.cyksj.service.chatgpt.ChatGptAuthService;
 import com.cyksj.service.groups.GroupsFuncService;
 import com.cyksj.service.mail.CuiQiuMailService;
@@ -114,6 +115,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final MidjourneyAccountService midjourneyAccountService;
 
+	private final ChatGptAccountService chatGptAccountService;
+
 	//脆球邮箱后缀
 	private final static String CUI_QIU_EMAIL_SUFFIX = "@kindvd.com";
 	private final UpgradePackageMapper upgradePackageMapper;
@@ -138,7 +141,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				.field(RenewalView::getUserId, 0).op(Operator.GreaterThan)
 				.field(RenewalView::getUserId, userIds).op(Operator.InList)
 				//.field(RenewalView::getYhsId, yhsId)
-				.field("condition", String.format("(gr.expiry_time is null or gr.expiry_time > '%s')", now))
+				.put("condition", String.format("(gr.expiry_time is null or gr.expiry_time > '%s')", now))
 				.field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList)
 				.orderBy(RenewalView::getExpiryTime).asc()
 				.build());
@@ -238,7 +241,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				ticket.setPayTime(payTime);
 			}
 			if (ticket.getGoodsId() == 26 && ticket.getIsMirror()){
-				List<UpgradePackage> upgradePackages = upgradePackageMapper.selectList(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\""+ticket.getSkuId()+"\"')").eq(UpgradePackage::getStatus, Boolean.TRUE));
+				List<UpgradePackage> upgradePackages = upgradePackageMapper.selectList(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + ticket.getSkuId() + "\"')").eq(UpgradePackage::getStatus, Boolean.TRUE).eq(UpgradePackage::getDeleted, Boolean.TRUE));
 				if (CollectionUtil.isNotEmpty(upgradePackages)){
 					upgradePackages.stream().map(e -> e.getPrice().divide(BigDecimal.valueOf(e.getNum()), 2, RoundingMode.HALF_UP)).min(BigDecimal::compareTo).ifPresent(ticket::setMjPackagePrice);
 				}
@@ -258,6 +261,24 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				} catch (Exception e) {
 				}
 			}
+			if (ticket.getGoodsId() == 18 && ticket.getIsMirror() && ticket.getExpiryTime() != null) {
+				//gpt用户镜像
+				ChatGptUserView userInfo = chatGptAccountService.getUserInfo(userId, ticket.getRelationId());
+				ticket.setGptUserLimitNum(userInfo.getLimitNum());
+				ticket.setGptUserLimitTime(userInfo.getLimitTime());
+				ticket.setUse(userInfo.getUse());
+				Integer count = upgradePackageMapper.selectCount(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + ticket.getSkuId() + "\"')")
+						.gt(UpgradePackage::getNum, userInfo.getLimitNum())
+						.eq(UpgradePackage::getStatus, Boolean.TRUE)
+						.eq(UpgradePackage::getGptType, 0)
+						.eq(UpgradePackage::getDeleted, Boolean.TRUE));
+				ticket.setUpgrade(count > 0 ? true : false);
+				ticket.setPackageId(userInfo.getPackageId());
+				if (userInfo.getPackageId() != 0) {
+					UpgradePackage upgradePackage = upgradePackageMapper.selectById(userInfo.getPackageId());
+					ticket.setPackagePrice(upgradePackage.getPrice());
+				}
+			}
 			List<GroupsRelationUserView> relationUserViews = groupsRelationMapper.getUserRelationUserViews(ticket.getGroupId(), ticket.getRelationId(), ticket.getUserId(), List.of(GroupsRelation.Status.validity, GroupsRelation.Status.outside));
 			ticket.setRelationViews(relationUserViews);
 			if (ticket.getExpiryTime() != null) {
@@ -801,4 +822,24 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 			log.error("发送用户GPT镜像体验失败:{}", StringUtil.getErrorText(e));
 		}
 	}
+
+	@Override
+	public RenewalView getTicketDetail(long userId, Long relationId) {
+		User u = userMapper.selectById(userId);
+		List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, u);
+		MapBuilder builder = MapUtils.builder();
+		RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, builder
+				.field(RenewalView::getRelationId, relationId)
+				.field(RenewalView::getUserId, 0).op(Operator.GreaterThan)
+				.field(RenewalView::getUserId, userIds).op(Operator.InList)
+				.field("condition", String.format("(gr.expiry_time is null or gr.expiry_time > '%s')", DateTime.now()))
+				.field(RenewalView::getStatus, List.of("validity", "outside")).op(Operator.InList)
+				.orderBy(RenewalView::getExpiryTime).asc()
+				.onlySelect(RenewalView::getRelationId, RenewalView::getExpiryTime, RenewalView::getTitle, RenewalView::getSpecVal, RenewalView::getGoodsId, RenewalView::getSkuId, RenewalView::getSkuNum, RenewalView::getSkuStatus, RenewalView::getGoodsStatus)
+				.build());
+		if (renewalView != null) {
+			renewalView.setExpiryTimeStr(DateUtil.format(renewalView.getExpiryTime(), "yyyy-MM-dd"));
+		}
+		return renewalView;
+	}
 }

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

@@ -774,4 +774,17 @@ public class GroupRelationController {
         List<RenewalView> expiryRenewals = groupRelationFrontService.getExpiryRenewalNotify(userId);
         return GatewayResponse.SUCCESS.newBuilder().toResult(expiryRenewals);
     }
+
+    /**
+     * 车票详情
+     */
+    @GetMapping("/get/detail")
+    public Result<RenewalView> getTicketDetail(Long relationId) {
+        if (relationId == null) {
+            return GatewayResponse.SUCCESS.newBuilder().toResult();
+        }
+        long userId = StpUserUtil.getLoginIdAsLong();
+        RenewalView ticketDetail = groupRelationFrontService.getTicketDetail(userId, relationId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(ticketDetail);
+    }
 }

+ 4 - 2
netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonSkuController.java

@@ -171,9 +171,11 @@ public class CmsGoodsDonSkuController {
         //前后两次价格不同 下架店铺低于这个折扣最低价格
         BigDecimal oldPrice = dbSku.getPrice();
         BigDecimal newPrice = sku.getPrice();
-        //规格变化
-        //下架店铺不在平台设置的价格区间
+        //规格新价 变高
+        //下架店铺低于这个规格价格的品
         goodsDonSkuService.setBelowPriceShopSkuDown(skuId, newPrice);
+        //套餐包关联规格
+        goodsDonSkuService.handleGptPackageSku(dbSku,sku);
         refreshCacheService.refreshYhHomePageCache();
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }

+ 0 - 2
netflix-web/src/main/java/com/cyksj/web/controller/manage/upgrade/UpgradePackageController.java

@@ -1,7 +1,6 @@
 package com.cyksj.web.controller.manage.upgrade;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.hutool.core.map.MapUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.annotation.Log;
 import com.cyksj.common.exception.BusinessRuntimeException;
@@ -16,7 +15,6 @@ import com.cyksj.model.views.UpgradePackageView;
 import com.cyksj.service.mange.upgrade.UpgradePackageService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
-import com.ejlchina.searcher.util.MapBuilder;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;

+ 2 - 1
netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

@@ -183,7 +183,8 @@ public class OrderController {
     @PostMapping("/post/upgrade/submit")
     public Result<UpgradeOrderDon> submitUpgrade(@Validated @RequestBody OrderPayRequest payRequest) throws Exception {
         final String methodName = "套餐吊起支付";
-        Long userId = StpUserUtil.getUserIdAfterLogin();
+        //无需免登录
+        Long userId = StpUserUtil.getLoginIdAsLong();
         payRequest.setUserId(userId);
         log.info("{}[start] params:{}", methodName, payRequest);