zoujiajian 2 лет назад
Родитель
Сommit
032377e92a
36 измененных файлов с 1135 добавлено и 52 удалено
  1. 5 0
      netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
  2. 3 0
      netflix-dao/src/main/java/com/cyksj/mapper/GoodsDonSkuMapper.java
  3. 19 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonRenewRecordMapper.java
  4. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/renew/RenewUpgradePackageMapper.java
  5. 18 0
      netflix-dao/src/main/java/com/cyksj/model/dto/OriSkuDto.java
  6. 21 0
      netflix-dao/src/main/java/com/cyksj/model/dto/RenewOriOrderSkuDto.java
  7. 20 1
      netflix-dao/src/main/java/com/cyksj/model/entity/ChatgptUser.java
  8. 1 1
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDon.java
  9. 31 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDonRenewRecord.java
  10. 53 0
      netflix-dao/src/main/java/com/cyksj/model/entity/RenewUpgradePackage.java
  11. 9 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonBackView.java
  12. 9 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonSearchView.java
  13. 6 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonView.java
  14. 79 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/RenewUpgradeOrderDonView.java
  15. 1 3
      netflix-dao/src/main/java/com/cyksj/model/manage/views/UpgradeOrderDonBackView.java
  16. 0 5
      netflix-dao/src/main/java/com/cyksj/model/manage/views/UpgradeOrderDonView.java
  17. 5 0
      netflix-dao/src/main/java/com/cyksj/model/views/ChatGptUserView.java
  18. 67 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewUpgradePackageFrontView.java
  19. 91 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewUpgradePackageView.java
  20. 12 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java
  21. 7 0
      netflix-dao/src/main/resources/mapper/GoodsDonSkuMapper.xml
  22. 17 0
      netflix-dao/src/main/resources/mapper/OrderDonRenewRecordMapper.xml
  23. 1 3
      netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java
  24. 8 0
      netflix-service/src/main/java/com/cyksj/service/mange/MirrorUserCleatService.java
  25. 49 0
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  26. 91 4
      netflix-service/src/main/java/com/cyksj/service/mange/impl/MirrorUserCleatServiceImpl.java
  27. 11 0
      netflix-service/src/main/java/com/cyksj/service/mange/renew/RenewUpgradePackageService.java
  28. 19 0
      netflix-service/src/main/java/com/cyksj/service/mange/renew/impl/RenewUpgradePackageServiceImpl.java
  29. 2 0
      netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java
  30. 126 25
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  31. 26 0
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  32. 58 0
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  33. 30 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
  34. 132 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/renew/RenewUpgradePackageController.java
  35. 37 5
      netflix-web/src/main/java/com/cyksj/web/controller/mirror/MirrorController.java
  36. 58 5
      netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

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

@@ -345,4 +345,9 @@ public interface Constant {
 
 	//英文
 	String EN_US = "en_US";
+
+	/**
+	 * 镜像GPT cookie
+	 */
+	String MIRROR_GPT_COOKIE = "nf_ticket_info";
 }

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

@@ -1,6 +1,7 @@
 package com.cyksj.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.dto.OriSkuDto;
 import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.YhShopGoodsSku;
 import org.apache.ibatis.annotations.Param;
@@ -24,4 +25,6 @@ public interface GoodsDonSkuMapper  extends BaseMapper<GoodsDonSku> {
 	List<Long> selectSingleSkuIdsByGoodsId(Long goodsId);
 
 	GoodsDonSku checkAndReturnMinPriceUserOwnsSku(@Param("goodsId") Long goodsId, @Param("dsUserId") Long dsUserId);
+
+	OriSkuDto selectRenewOriSku(Long skuId);
 }

+ 19 - 0
netflix-dao/src/main/java/com/cyksj/mapper/OrderDonRenewRecordMapper.java

@@ -0,0 +1,19 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.OrderDon;
+import com.cyksj.model.entity.OrderDonRenewRecord;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: OrderDonRenewRecordMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/7/19 11:45
+ */
+public interface OrderDonRenewRecordMapper extends BaseMapper<OrderDonRenewRecord> {
+
+	OrderDon getOtherRenewSku(@Param("orderId") Long orderId, @Param("relationId") Long relationId, @Param("userIds") List<Long> userIds);
+}

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.renew;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.RenewUpgradePackage;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: RenewUpgradePackageMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/7/18 16:56
+ */
+public interface RenewUpgradePackageMapper extends BaseMapper<RenewUpgradePackage> {
+}

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/OriSkuDto.java

@@ -0,0 +1,18 @@
+package com.cyksj.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class OriSkuDto {
+	private Long id;
+
+	private String specVal;
+
+	private Integer months;
+
+	private Integer gptLimitNum;
+
+	private Long gptLimitTime;
+}

+ 21 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/RenewOriOrderSkuDto.java

@@ -0,0 +1,21 @@
+package com.cyksj.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: RenewOriOrderSkuDto
+ * 创建者: JavaZou
+ * 创建时间:2024/7/23 15:14
+ */
+@Getter
+@Setter
+public class RenewOriOrderSkuDto {
+	private OriSkuDto oriSku;
+
+	private Date lastExpiryTime;
+
+}

+ 20 - 1
netflix-dao/src/main/java/com/cyksj/model/entity/ChatgptUser.java

@@ -3,6 +3,7 @@ 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.cyksj.model.BaseEntity;
 import com.ejlchina.searcher.bean.SearchBean;
 import lombok.Data;
 
@@ -87,4 +88,22 @@ public class ChatgptUser extends BaseEntity {
      */
     @TableField(updateStrategy = FieldStrategy.IGNORED)
     private Date clearPackageTime;
-}
+
+    /**
+     * 续费升级订单id
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Long renewOrderId;
+
+    /**
+     * 目前续费规格id
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Long renewSkuId;
+
+    /**
+     * 续费升级过期时间
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Date renewExpiryTime;
+}

+ 1 - 1
netflix-dao/src/main/java/com/cyksj/model/entity/OrderDon.java

@@ -72,7 +72,7 @@ public class OrderDon extends BaseEntity implements Serializable {
     private BigDecimal dpMoney;
 
     /**
-     * 主平台订单金额
+     * 主平台订单金额 用于加购订单分销
      */
     private BigDecimal oriMoney;
 

+ 31 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/OrderDonRenewRecord.java

@@ -0,0 +1,31 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: OrderDonRenewRecord
+ * 创建者: JavaZou
+ * 创建时间:2024/7/19 11:45
+ */
+@Getter
+@Setter
+public class OrderDonRenewRecord extends BaseEntity{
+	private Long orderId;
+
+	private Long oriSkuId;
+
+	private Long userId;
+
+	private Long packageId;
+
+	private BigDecimal discount;
+
+	/**
+	 * 是否过期,默认false
+	 */
+	private Boolean isValid;
+}

+ 53 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/RenewUpgradePackage.java

@@ -0,0 +1,53 @@
+package com.cyksj.model.entity;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author zwhui
+ * @date 2024/4/24 14:54
+ */
+@Data
+public class RenewUpgradePackage extends BaseEntity{
+
+    /**
+     * 套餐名称
+     */
+    private String name;
+
+    /**
+     * 商品id
+     */
+    private Long goodsId;
+
+    /**
+     * 商品规格id
+     */
+    private Long skuId;
+
+    /**
+     * 续费升级规格
+     */
+    private String upgradeSkuIds;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 折扣
+     */
+    private BigDecimal discount;
+
+    /**
+     * true 上架 / false 下架
+     */
+    private Boolean status;
+
+    /**
+     * true 存在 / false 删除
+     */
+    private Boolean deleted;
+}

+ 9 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonBackView.java

@@ -284,4 +284,13 @@ public class OrderDonBackView {
 
 	@DbField("sku.mj_relax_num")
 	private Integer mjRelaxNum;
+
+	@DbIgnore
+	private Date oriPayTime;
+
+	@DbIgnore
+	private String oriSpecVal;
+
+	@DbIgnore
+	private String expiryTime;
 }

+ 9 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonSearchView.java

@@ -64,6 +64,9 @@ public class OrderDonSearchView {
 	@DbField("sku.spec_val")
 	private String specVal;
 
+	@DbField("o.order_type")
+	private Integer orderType;
+
 	@DbField("sku.months")
 	private Integer months;
 
@@ -164,4 +167,10 @@ public class OrderDonSearchView {
 
 	@DbField("sku.is_mirror")
 	private Boolean isMirror;
+
+	/**
+	 * 原先规格
+	 */
+	@DbIgnore
+	private String oriSpecVal;
 }

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonView.java

@@ -158,6 +158,12 @@ public class OrderDonView {
     @DbField("o.yhs_id")
     private Long yhsId;
 
+    @DbField("o.order_type")
+    private Integer orderType;
+
+    @DbIgnore
+    private Boolean isRenewPackage;
+
     @DbIgnore
     private OrderDonWaybill waybill;
 

+ 79 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/views/RenewUpgradeOrderDonView.java

@@ -0,0 +1,79 @@
+package com.cyksj.model.manage.views;
+
+import com.cyksj.model.entity.OrderDon;
+import com.cyksj.model.entity.UpgradeOrderDon;
+import com.ejlchina.searcher.bean.DbField;
+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;
+
+/**
+ * @author chan
+ * @date 2022/9/27 6:56 PM
+ */
+@Getter
+@Setter
+@SearchBean(tables = "order_don_renew_record orr left join order_don o on o.id = orr.order_id" +
+        " left join goods_don g on g.id = o.goods_id" +
+        " left join goods_don_sku sku on o.sku_id = sku.id")
+public class RenewUpgradeOrderDonView {
+
+    @DbField("o.id")
+    private Long id;
+
+    @DbField("o.relation_id")
+    private Long relationId;
+
+    @DbField("o.order_no")
+    private String orderNo;
+
+    @DbField("o.transaction_id")
+    private String transactionId;
+
+    @DbField("g.title")
+    private String title;
+
+    @DbField("sku.spec_val")
+    private String specVal;
+
+    @DbField("g.id")
+    private Long goodsId;
+
+    @DbField("g.logo")
+    private String logo;
+
+
+    @DbField("o.user_id")
+    @JsonIgnore
+    private Long userId;
+
+    @DbField("o.money")
+    private BigDecimal money;
+
+    @DbField("o.refund_money")
+    @JsonIgnore
+    private BigDecimal refundMoney;
+
+    @DbField("o.balance")
+    private BigDecimal balance;
+
+    @DbField("o.refund_desc")
+    private String refundDesc;
+
+    @DbField("o.status")
+    private OrderDon.Status status;
+
+    @DbField("o.type")
+    private UpgradeOrderDon.Type type;
+
+    @DbField("o.created_time")
+    private Date createdTime;
+
+    @DbField("o.pay_time")
+    private Date payTime;
+
+}

+ 1 - 3
netflix-dao/src/main/java/com/cyksj/model/manage/views/UpgradeOrderDonBackView.java

@@ -1,7 +1,6 @@
 package com.cyksj.model.manage.views;
 
-import com.cyksj.model.entity.*;
-import com.cyksj.model.views.GoodsDonSkuView;
+import com.cyksj.model.entity.UpgradeOrderDon;
 import com.ejlchina.searcher.bean.DbField;
 import com.ejlchina.searcher.bean.DbIgnore;
 import com.ejlchina.searcher.bean.SearchBean;
@@ -10,7 +9,6 @@ import lombok.Setter;
 
 import java.math.BigDecimal;
 import java.util.Date;
-import java.util.List;
 
 /*
  *项目名: netflix

+ 0 - 5
netflix-dao/src/main/java/com/cyksj/model/manage/views/UpgradeOrderDonView.java

@@ -1,12 +1,8 @@
 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;
@@ -14,7 +10,6 @@ import lombok.Setter;
 
 import java.math.BigDecimal;
 import java.util.Date;
-import java.util.List;
 
 /**
  * @author chan

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

@@ -70,4 +70,9 @@ public class ChatGptUserView {
      * 目前套餐价格
      */
     private BigDecimal packagePrice;
+
+    /**
+     * 是否是续费升级
+     */
+    private Boolean isRenewPackage;
 }

+ 67 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RenewUpgradePackageFrontView.java

@@ -0,0 +1,67 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: RenewUpgradePackageFrontView
+ * 创建者: JavaZou
+ * 创建时间:2024/7/19 15:19
+ */
+@Getter
+@Setter
+@SearchBean(tables = "renew_upgrade_package rup" +
+		" inner join goods_don g on g.id = rup.goods_id",
+		where = "g.status is true and rup.status is true and rup.deleted is true")
+public class RenewUpgradePackageFrontView {
+	@DbField("rup.id")
+	private Long packageId;
+
+	@DbField("rup.discount")
+	private BigDecimal discount;
+
+	@DbField("rup.goods_id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	private String title;
+
+	@DbField("rup.sku_id")
+	private Long skuId;
+
+	@DbField("rup.upgrade_sku_ids")
+	private String upgradeSkuIds;
+
+	@DbIgnore
+	private List<RenewSkuView> renewSkus;
+
+	@Getter
+	@Setter
+	@SearchBean(tables = "goods_don_sku sku", where = "status is true")
+	public static class RenewSkuView {
+		@DbField("sku.id")
+		private Long skuId;
+
+		@DbField("sku.months")
+		private Integer months;
+
+		@DbField("sku.gpt_limit_num")
+		private Integer gptLimitNum;
+
+		@DbField("sku.gpt_limit_time")
+		private Long gptLimitTime;
+
+		@DbField("sku.spec_val")
+		private String specVal;
+
+		@DbField("sku.price")
+		private BigDecimal price;
+	}
+}

+ 91 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RenewUpgradePackageView.java

@@ -0,0 +1,91 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author zwhui
+ * @date 2024/4/24 15:20
+ */
+@Data
+@SearchBean(tables = "renew_upgrade_package up left join goods_don g on up.goods_id = g.id " +
+        " left join goods_don_sku sku on sku.id = up.sku_id"
+        , where = "up.deleted = true :sku:",
+        orderBy = "up.update_time desc")
+public class RenewUpgradePackageView {
+    @DbField("up.id")
+    private Long id;
+
+    /**
+     * 套餐名称
+     */
+    @DbField("up.name")
+    private String name;
+
+    /**
+     * 商品id
+     */
+    @DbField("up.goods_id")
+    private Long goodsId;
+
+    /**
+     * 商品名称
+     */
+    @DbField("g.title")
+    private String goodsName;
+
+    /**
+     * 商品规格id
+     */
+    @DbField("up.sku_id")
+    private Long skuId;
+
+    @DbField("sku.spec_val")
+    private String specVal;
+
+    /**
+     * 升级规格
+     */
+    @DbField("up.upgrade_sku_ids")
+    private String upgradeSkuIds;
+
+    /**
+     * 商品规格名称
+     */
+    @DbIgnore
+    private String upgradeSpecVal;
+
+
+    /**
+     * 备注
+     */
+    @DbField("up.remark")
+    private String remark;
+
+
+    @DbField("up.discount")
+    private BigDecimal discount;
+
+    /**
+     * true 上架 / false 下架
+     */
+    @DbField("up.status")
+    private Boolean status;
+
+	/**
+	 * true 存在 / false 删除
+	 */
+	@DbField("up.deleted")
+	private Boolean deleted;
+
+	@DbField("up.created_time")
+	private Date createdTime;
+
+	@DbField("up.update_time")
+	private Date updateTime;
+}

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

@@ -260,4 +260,16 @@ public class RenewalView {
 
     @DbIgnore
     private DistributePosterGoodsDetailView posterInfo;
+
+    /**
+     * 是否是续费升级
+     */
+    @DbIgnore
+    private Boolean isRenewPackage;
+
+    /**
+     * 续费升级折扣
+     */
+    @DbIgnore
+    private BigDecimal discount;
 }

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

@@ -48,4 +48,11 @@
             or JSON_CONTAINS(user_owns, '${dsUserId}')
         </if>) order by price limit 1
     </select>
+
+    <select id="selectRenewOriSku" resultType="com.cyksj.model.dto.OriSkuDto">
+        select *
+        from goods_don_sku
+        where id = #{skuId}
+        limit 1
+    </select>
 </mapper>

+ 17 - 0
netflix-dao/src/main/resources/mapper/OrderDonRenewRecordMapper.xml

@@ -0,0 +1,17 @@
+<?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.OrderDonRenewRecordMapper">
+
+
+    <select id="getOtherRenewSku" resultType="com.cyksj.model.entity.OrderDon">
+        select o.* from (select order_id from order_don_renew_record where order_id != #{orderId}
+        and is_valid = 0
+        and user_id in
+        <foreach collection="userIds" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>) orr inner join order_don o on o.id = orr.order_id
+        and o.status not in ('close','noPayment','refund')
+        and o.order_type = 2 and o.relation_id = #{relationId}
+        inner join goods_don_sku sku on sku.id = o.sku_id
+    </select>
+</mapper>

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

@@ -16,14 +16,12 @@ 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.Jsons;
 import com.cyksj.common.util.StringUtil;
 import com.cyksj.mapper.*;
 import com.cyksj.mapper.station.CollegeStudentStationUseTicketRecordMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.request.gpt.ConversationRequest;
 import com.cyksj.model.response.ConversationLimitResponse;
-import com.cyksj.model.views.ChatGptUserConversationRecordHistoryView;
 import com.cyksj.model.views.ChatGptUserView;
 import com.cyksj.model.views.ChatgptCarInfoView;
 import com.cyksj.redis.RedisService;
@@ -31,7 +29,6 @@ import com.cyksj.service.chatgpt.ChatGptAccountService;
 import com.cyksj.service.sys.SysConfigService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.ejlchina.searcher.BeanSearcher;
-import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -848,6 +845,7 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
                     .use(Math.min(chatgptUser.getLimitNum(), getConversationCount(chatgptUser.getUserToken(), chatgptUser.getLimitTime())))
                     .packageId(chatgptUser.getPackageId())
                     .packagePrice(packagePrice)
+                    .isRenewPackage(chatgptUser.getRenewOrderId() != null ? true : false)
                     .build();
         } else {
             throw BusinessRuntimeException.getInstance("您还未购买该车票");

+ 8 - 0
netflix-service/src/main/java/com/cyksj/service/mange/MirrorUserCleatService.java

@@ -1,5 +1,7 @@
 package com.cyksj.service.mange;
 
+import com.cyksj.model.entity.OrderDon;
+
 /**
  * 项目名: yhlxj
  * 文件名: MirrorUserCleatService
@@ -8,4 +10,10 @@ package com.cyksj.service.mange;
  */
 public interface MirrorUserCleatService {
 	void delMirrorUser(Long goodsId, Long relationId);
+
+	/**
+	 * 处理续费升级订单,将镜像车票还原
+	 * @param orderDon
+	 */
+	void handleRenewUpgradeOrders(OrderDon orderDon);
 }

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

@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alipay.api.AlipayClient;
 import com.alipay.api.domain.AlipayTradeRefundModel;
@@ -196,6 +197,8 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
 
     private final MirrorUserCleatService mirrorUserCleatService;
 
+    private final OrderDonRenewRecordMapper orderDonRenewRecordMapper;
+
     private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
     @Override
@@ -371,6 +374,10 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         //修改订单状态
         orderDon.setStatus(OrderDon.Status.refund);
         orderDonMapper.updateById(orderDon);
+        //续费升级订单
+        if (orderDon.getOrderType() == 2 && sku.getIsMirror()) {
+            mirrorUserCleatService.handleRenewUpgradeOrders(orderDon);
+        }
         //提交过工单的订单
         //将用户异常订单关闭
         workOrderMapper.update(null, Wrappers.lambdaUpdate(WorkOrder.class)
@@ -461,9 +468,29 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
                         .lt(UpgradeOrderDon::getNum, orderDon.getNum())
                         .eq(UpgradeOrderDon::getStatus, UpgradeOrderDon.Status.complete)
                         .last("limit 1"));
+                Long renewSkuId = chatgptUser.getRenewSkuId();
+
+                //续费升级
+                GoodsDonSku renewSku = null;
+                if (renewSkuId != null) {
+                    renewSku = goodsDonSkuMapper.selectById(renewSkuId);
+                    gptLimitTime = renewSku.getGptLimitTime();
+                    gptLimitNum = renewSku.getGptLimitNum();
+                }
+
                 if (secondUpgrade != null) {
                     gptLimitTime = secondUpgrade.getTime();
                     gptLimitNum = secondUpgrade.getNum();
+
+                    if (renewSku != null) {
+                        //低级套餐
+                        GoodsDonSku secondSkuUpGrade = goodsDonSkuMapper.selectById(secondUpgrade.getSkuId());
+                        //续费升级套餐更高
+                        if (renewSku.getMonths() >= secondSkuUpGrade.getMonths() && renewSku.getGptLimitNum() >= secondSkuUpGrade.getGptLimitNum() && renewSku.getGptLimitTime() <= secondSkuUpGrade.getGptLimitTime()) {
+                            gptLimitTime = renewSku.getGptLimitTime();
+                            gptLimitNum = renewSku.getGptLimitNum();
+                        }
+                    }
                 }
                 Long packageId = 0l;
                 //降级套餐
@@ -907,6 +934,8 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             giftCardUserRecord.setIsPay(false);
             giftCardUserRecordMapper.updateById(giftCardUserRecord);
         }
+        //校验续费升级规格
+        checkMirrorRenewSku(orderDon);
     }
 
     /**
@@ -1335,4 +1364,24 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         }
         return relation;
     }
+
+    private void checkMirrorRenewSku(OrderDon orderDon) {
+        Long skuId = orderDon.getSkuId();
+        Long orderId = orderDon.getId();
+        OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
+                .eq(OrderDonRenewRecord::getOrderId, orderId)
+                .last("limit 1"));
+        if (orderDonRenewRecord != null) {
+            ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
+                    .eq(ChatgptUser::getRelationId, orderDon.getRelationId())
+                    .last("limit 1"));
+            Long presentRenewSkuId = chatgptUser.getRenewSkuId();
+            //存在不同升级套餐
+            GoodsDonSku presentRenewSku = skuMapper.selectById(presentRenewSkuId);
+            if (!ObjectUtil.equal(presentRenewSkuId, skuId)) {
+                throw BusinessRuntimeException.getInstance("请先退掉用户目前续费升级的{0}规格", presentRenewSku.getSpecVal());
+            }
+        }
+    }
+
 }

+ 91 - 4
netflix-service/src/main/java/com/cyksj/service/mange/impl/MirrorUserCleatServiceImpl.java

@@ -1,15 +1,20 @@
 package com.cyksj.service.mange.impl;
 
+import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.cyksj.mapper.ChatgptUserMapper;
-import com.cyksj.mapper.MidjourneyUserMapper;
-import com.cyksj.model.entity.ChatgptUser;
-import com.cyksj.model.entity.MidjourneyUser;
+import com.cyksj.mapper.*;
+import com.cyksj.model.entity.*;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.mange.MirrorUserCleatService;
+import com.cyksj.service.user.UserBindRelationService;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
 /**
  * 项目名: yhlxj
  * 文件名: MirrorUserCleatServiceImpl
@@ -18,12 +23,26 @@ import org.springframework.stereotype.Service;
  */
 @Service
 @RequiredArgsConstructor
+@Slf4j
 public class MirrorUserCleatServiceImpl implements MirrorUserCleatService {
 	private final ChatgptUserMapper chatgptUserMapper;
 
 	private final MidjourneyUserMapper midjourneyUserMapper;
 
 	private final RedisService redisService;
+
+	private final OrderDonRenewRecordMapper orderDonRenewRecordMapper;
+
+	private final GoodsDonSkuMapper skuMapper;
+
+	private final UserBindRelationService userBindRelationService;
+
+	private final UpgradePackageMapper upgradePackageMapper;
+
+	private final GroupsRelationMapper groupsRelationMapper;
+
+	private final GroupsMapper groupsMapper;
+
 	@Override
 	public void delMirrorUser(Long goodsId, Long relationId) {
 		//gpt镜像
@@ -46,4 +65,72 @@ public class MirrorUserCleatServiceImpl implements MirrorUserCleatService {
 			}
 		}
 	}
+
+	@Override
+	public void handleRenewUpgradeOrders(OrderDon orderDon) {
+		Long orderId = orderDon.getId();
+		OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
+				.eq(OrderDonRenewRecord::getOrderId, orderId)
+				.last("limit 1"));
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(orderDon.getUserId(), null);
+		if (orderDonRenewRecord != null) {
+			ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
+					.eq(ChatgptUser::getRelationId, orderDon.getRelationId())
+					.last("limit 1"));
+			Long presentRenewSkuId = chatgptUser.getRenewSkuId();
+			//存在不同升级套餐
+			GoodsDonSku presentRenewSku = skuMapper.selectById(presentRenewSkuId);
+			GroupsRelation relation = groupsRelationMapper.selectById(orderDon.getRelationId());
+			GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
+			GoodsDonSku finalSku = skuMapper.selectById(groupsTrips.getSkuId());
+			//是否存在其他续费升级
+			OrderDon otherRenewOrderDon = orderDonRenewRecordMapper.getOtherRenewSku(orderDon.getId(), relation.getId(), userIdList);
+			GoodsDonSku otherRenewSku = null;
+			if (otherRenewOrderDon != null) {
+				otherRenewSku = skuMapper.selectById(otherRenewOrderDon.getSkuId());
+			}
+			GoodsDonSku upgradeOrderDonSku = null;
+			Date renewExpiryTime = null;
+			//是否存在套餐升级包
+			Long packageId = chatgptUser.getPackageId();
+			if (packageId != null && packageId != 0) {
+				UpgradePackage upgradePackage = upgradePackageMapper.selectById(chatgptUser.getPackageId());
+				Long upgradeOrderDonSkuId = upgradePackage.getUpgradeSkuId();
+				upgradeOrderDonSku = skuMapper.selectById(upgradeOrderDonSkuId);
+			}
+			//套餐升级
+			if (upgradeOrderDonSku != null) {
+				log.info("续费升级订单退款,relation_id:{}存在套餐升级", orderDon.getUserId());
+				finalSku = upgradeOrderDonSku;
+			}
+			chatgptUser.setRenewSkuId(null);
+			chatgptUser.setRenewOrderId(null);
+			//续费升级
+			if (otherRenewSku != null) {
+				finalSku = otherRenewSku;
+				log.info("续费升级订单退款,relation_id:{}存在次级续费升级订单", orderDon.getUserId());
+				if (upgradeOrderDonSku != null) {
+					//套餐升级高于其他续费升级
+					if (upgradeOrderDonSku.getMonths() >= otherRenewSku.getMonths() && upgradeOrderDonSku.getGptLimitNum() >= otherRenewSku.getGptLimitNum() && upgradeOrderDonSku.getGptLimitTime() <= otherRenewSku.getGptLimitTime()) {
+						log.info("续费升级订单退款,relation_id:{}存在更高级套餐升级", orderDon.getUserId());
+						finalSku = upgradeOrderDonSku;
+					}
+				}
+				Date payTime = Optional.ofNullable(otherRenewOrderDon.getPayTime()).orElse(otherRenewOrderDon.getCreatedTime());
+				renewExpiryTime = DateUtil.offsetMonth(payTime, otherRenewSku.getMonths());
+				chatgptUser.setRenewOrderId(otherRenewOrderDon.getId());
+				chatgptUser.setRenewSkuId(otherRenewOrderDon.getSkuId());
+			}
+			//还原镜像user
+			chatgptUser.setLimitTime(finalSku.getGptLimitTime());
+			chatgptUser.setLimitNum(finalSku.getGptLimitNum());
+			chatgptUser.setRenewExpiryTime(renewExpiryTime);
+			chatgptUserMapper.updateById(chatgptUser);
+			log.info("还原镜像gptuser套餐成功");
+
+			//将续费有效置为过期
+			orderDonRenewRecord.setIsValid(true);
+			orderDonRenewRecordMapper.updateById(orderDonRenewRecord);
+		}
+	}
 }

+ 11 - 0
netflix-service/src/main/java/com/cyksj/service/mange/renew/RenewUpgradePackageService.java

@@ -0,0 +1,11 @@
+package com.cyksj.service.mange.renew;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.RenewUpgradePackage;
+
+/**
+ * @author zwhui
+ * @date 2024/4/24 15:04
+ */
+public interface RenewUpgradePackageService extends IService<RenewUpgradePackage> {
+}

+ 19 - 0
netflix-service/src/main/java/com/cyksj/service/mange/renew/impl/RenewUpgradePackageServiceImpl.java

@@ -0,0 +1,19 @@
+package com.cyksj.service.mange.renew.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.mapper.renew.RenewUpgradePackageMapper;
+import com.cyksj.model.entity.RenewUpgradePackage;
+import com.cyksj.service.mange.renew.RenewUpgradePackageService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zwhui
+ * @date 2024/4/24 15:05
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class RenewUpgradePackageServiceImpl extends ServiceImpl<RenewUpgradePackageMapper, RenewUpgradePackage> implements RenewUpgradePackageService {
+}

+ 2 - 0
netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java

@@ -104,4 +104,6 @@ public interface OrderDonService extends IService<OrderDon> {
     void closeUpgradeOrder(Long orderId, Long userId);
 
     UpgradeOrderDetailView getUpgradeOrderDetail(Long orderId, Long userId);
+
+	OrderDon submitRenewUpgrade(OrderPayRequest payRequest);
 }

+ 126 - 25
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -57,6 +57,7 @@ import com.cyksj.mapper.manage.distribute.sub.UserDistributeSubRewardsMapper;
 import com.cyksj.mapper.manage.distribute.sub.UserDistributeSubWaitingMapper;
 import com.cyksj.mapper.market.task.TaskTypeMapper;
 import com.cyksj.mapper.market.task.UserBindDetailMapper;
+import com.cyksj.mapper.renew.RenewUpgradePackageMapper;
 import com.cyksj.mapper.shop.YhShopGoodsSkuMapper;
 import com.cyksj.model.dto.*;
 import com.cyksj.model.entity.*;
@@ -317,6 +318,10 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper;
 
+	private final RenewUpgradePackageMapper renewUpgradePackageMapper;
+
+	private final OrderDonRenewRecordMapper orderDonRenewRecordMapper;
+
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
 
 	@Transactional(rollbackFor = Throwable.class)
@@ -1444,6 +1449,9 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 					}
 					relation.setExpiryTime(newDate);
 					relation.setStartTime(relation.getStartTime() == null ? new Date() : null);
+
+					//镜像续费升级
+					handleMirrorRenew(sku, order, groupsTrips, relation.getId(), newDate);
 				} else if (GroupsTrips.Status.waiting.equals(groupsTrips.getStatus())) {
 					log.info("车位groupsId:{}未发车,修改订单号orderNo:{}订单为已付款状态:{}", groupsTrips.getId(), order.getOrderNo());
 					order.setStatus(OrderDon.Status.hasPayment);
@@ -1486,31 +1494,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 				}
 			}
 		}
-
-//		//新订单产生 发送模板消息给用户、客服
-//		User user = userMapper.selectById(order.getUserId());
-//		if (user != null) {
-//			THREAD_POOL_TASK_EXECUTOR.execute(() -> {
-//				try {
-//					//发送至用户消息
-//					templateCommonService.newOderSendMsgByType(order, goodsDon, user, user.getOpenId(), false);
-//				} catch (Exception e) {
-//					log.error("向用户发送新订单{}通知消息失败:{}", order.getOrderNo(), e);
-//				}
-//			});
-//		}
-//		THREAD_POOL_TASK_EXECUTOR.execute(() -> {
-//			try {
-//				//发送至客服消息
-//				List<CustomerService> customerServices = customerServiceMapper.selectList(null);
-//				for (CustomerService customerService : customerServices) {
-//					log.info("向客服{}发送新订单消息通知..", customerService.getNickName());
-//					templateCommonService.newOderSendMsgByType(order, goodsDon, user, customerService.getOpenId(), true);
-//				}
-//			} catch (Exception e) {
-//				log.error("向客服发送新订单{}通知消息失败:{}", order.getOrderNo(), e);
-//			}
-//		});
 	}
 
 	/**
@@ -3685,6 +3668,83 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
         return beanSearcher.searchFirst(UpgradeOrderDetailView.class, builder.build());
 	}
 
+
+	@Override
+	public OrderDon submitRenewUpgrade(OrderPayRequest payRequest) {
+		Long packageId = payRequest.getPackageId();
+		Long relationId = payRequest.getRelationId();
+		if (relationId == null) {
+			throw BusinessRuntimeException.getInstance("系统异常");
+		}
+		Long userId = payRequest.getUserId();
+		User user = userMapper.selectById(userId);
+		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 = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
+				.in(OrderDon::getUserId, userIdList)
+				.eq(OrderDon::getRelationId, payRequest.getRelationId())
+				.eq(OrderDon::getStatus, OrderDon.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());
+		GoodsDon goodsDon = goodsDonMapper.selectById(goodsDonSku.getGoodsId());
+		if (!goodsDonSku.getIsMirror()) {
+			throw BusinessRuntimeException.getInstance("系统异常");
+		}
+		Long renewSkuId = payRequest.getSkuId();
+		GoodsDonSku renewSku = goodsDonSkuMapper.selectById(renewSkuId);
+		//校验同规格
+		if (!ObjectUtil.equal(goodsDonSku.getGoodsId(), renewSku.getGoodsId())) {
+			throw BusinessRuntimeException.getInstance("系统异常");
+		}
+
+		OrderDon orderDon = new OrderDon();
+		orderDon.setUserId(userId);
+		orderDon.setGoodsId(goodsDonSku.getGoodsId());
+		orderDon.setRelationId(relationId);
+		orderDon.setSkuId(renewSkuId);
+		//续费订单
+		orderDon.setOrderType(2);
+		RenewUpgradePackage renewUpgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
+				.eq(RenewUpgradePackage::getId, packageId)
+				.eq(RenewUpgradePackage::getStatus, 1)
+				.eq(RenewUpgradePackage::getDeleted, 1));
+		if (renewUpgradePackage == null) {
+			throw BusinessRuntimeException.getInstance("续费升级套餐不存在");
+		}
+		BigDecimal price = renewSku.getPrice();
+		orderDon.setOriMoney(price);
+		orderDon.setRealMoney(price);
+		BigDecimal discountPrice = price.multiply(renewUpgradePackage.getDiscount());
+		orderDon.setMoney(discountPrice);
+
+		StringBuilder payTitle = new StringBuilder();
+		payTitle.append(goodsDon.getTitle()).append(renewSku.getSpecVal());
+		orderDon.setPayTitle(payTitle.toString());
+		String donNo = SEQUENCE.nextId().toString();
+		orderDon.setOrderNo(donNo);
+		orderDon.setStatus(OrderDon.Status.noPayment);
+
+		//虚拟商品订单,是否是分销订单
+		setDistributeOrderMark(orderDon, goodsDon.getType(), user.getId());
+
+		//存在余额
+		deductBalancePayOrderMoney(orderDon, payRequest.getBalance(), user);
+
+		orderDonMapper.insert(orderDon);
+		//记录续费升级的规格
+		recordRenewOrderDon(orderDon, renewUpgradePackage, groupsTrips);
+
+		jobManager.addJob(EXPIRY_TIME, () -> {
+			closeOrder(orderDon.getId(), null);
+		});
+		return orderDon;
+	}
+
 	/**
 	 * 试用车票跳转购买正式车票订单记录
 	 */
@@ -3695,4 +3755,45 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			userTrialTicketJumpPayRecordMapper.insert(userTrialTicketJumpPayRecord);
 		}
 	}
+
+	/**
+	 * 记录续费升级的规格
+	 */
+	private void recordRenewOrderDon(OrderDon orderDon, RenewUpgradePackage renewUpgradePackage, GroupsTrips groupsTrips) {
+		OrderDonRenewRecord orderDonRenewRecord = new OrderDonRenewRecord();
+		orderDonRenewRecord.setOrderId(orderDon.getId());
+		orderDonRenewRecord.setUserId(orderDon.getUserId());
+		orderDonRenewRecord.setPackageId(renewUpgradePackage.getId());
+		orderDonRenewRecord.setDiscount(renewUpgradePackage.getDiscount());
+		orderDonRenewRecord.setOriSkuId(groupsTrips.getSkuId());
+		orderDonRenewRecordMapper.insert(orderDonRenewRecord);
+	}
+
+	//镜像续费升级
+	private void handleMirrorRenew(GoodsDonSku sku, OrderDon order, GroupsTrips groupsTrips, Long relationId, Date newDate) {
+		if (sku.getIsMirror() && order.getOrderType() == 2) {
+			OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
+					.eq(OrderDonRenewRecord::getOrderId, order.getId())
+					.last("limit 1"));
+			if (orderDonRenewRecord != null) {
+				orderDonRenewRecordMapper.updateById(orderDonRenewRecord);
+				//同规格续费无需更新
+				if (!ObjectUtil.equal(groupsTrips.getSkuId(), order.getSkuId())) {
+					//升级gptUser次数
+					ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
+							.eq(ChatgptUser::getRelationId, relationId)
+							.last("limit 1"));
+					if (chatgptUser != null) {
+						chatgptUser.setLimitTime(sku.getGptLimitTime());
+						chatgptUser.setLimitNum(sku.getGptLimitNum());
+						//记录续费升级过期的时间
+						chatgptUser.setRenewExpiryTime(newDate);
+						chatgptUser.setRenewOrderId(order.getId());
+						chatgptUser.setRenewSkuId(order.getSkuId());
+						chatgptUserMapper.updateById(chatgptUser);
+					}
+				}
+			}
+		}
+	}
 }

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

@@ -25,6 +25,7 @@ import com.cyksj.mapper.manage.distribute.DistributeGeneralSkuRateMapper;
 import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
 import com.cyksj.mapper.manage.distribute.UserPlatDistributeRateMapper;
 import com.cyksj.mapper.manage.distribute.UserPlatSkuDistributeRateMapper;
+import com.cyksj.mapper.renew.RenewUpgradePackageMapper;
 import com.cyksj.mapper.sys.SysEmailMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.request.SpecialGoodsTicketReq;
@@ -142,6 +143,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper;
 
+	private final RenewUpgradePackageMapper renewUpgradePackageMapper;
+
 	@Override
 	public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account) {
 		User u = userMapper.selectById(userId);
@@ -297,6 +300,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 					UpgradePackage upgradePackage = upgradePackageMapper.selectById(userInfo.getPackageId());
 					ticket.setPackagePrice(upgradePackage.getPrice());
 				}
+				ticket.setIsRenewPackage(userInfo.getIsRenewPackage());
 			}
 			List<GroupsRelationUserView> relationUserViews = groupsRelationMapper.getUserRelationUserViews(ticket.getGroupId(), ticket.getRelationId(), ticket.getUserId(), List.of(GroupsRelation.Status.validity, GroupsRelation.Status.outside));
 			ticket.setRelationViews(relationUserViews);
@@ -313,6 +317,9 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 			ticket.setQa(qaId > 0 ? true : false);
 			//是否存在海报
 			ticket.setPosterInfo(setGoodsPoster(ticket, u));
+
+			//续费升级折扣
+			setRenewDiscount(ticket);
 		});
 		userLoginRecordService.saveUserLoginDayRecord(userId);
 		return list;
@@ -598,6 +605,9 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	@Override
 	public void adjustGroupsParkingTime(Long relationId, GoodsDonSku sku) {
+		if (sku == null) {
+			return;
+		}
 		Long skuId = sku.getId();
 		//更新GPT Plus10人、4人月付车队状态 待优化
 		if (skuId == 161l || skuId == 178l || skuId == 422l || skuId == 423l) {
@@ -978,4 +988,20 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		return distributePosterGoodsDetailView;
 	}
 
+	private void setRenewDiscount(RenewalView ticket) {
+		if (ticket.getIsMirror()) {
+			RenewUpgradePackage renewUpgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
+					.eq(RenewUpgradePackage::getGoodsId, ticket.getGoodsId())
+					.eq(RenewUpgradePackage::getStatus, 1)
+					.eq(RenewUpgradePackage::getDeleted, 1)
+					.eq(RenewUpgradePackage::getSkuId, ticket.getSkuId())
+					.orderByAsc(RenewUpgradePackage::getDiscount)
+					.last("limit 1")
+					.select(RenewUpgradePackage::getId, RenewUpgradePackage::getDiscount));
+			if (renewUpgradePackage != null) {
+				ticket.setDiscount(renewUpgradePackage.getDiscount());
+			}
+		}
+	}
+
 }

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

@@ -47,6 +47,7 @@ import com.cyksj.service.user.UserService;
 import com.cyksj.web.util.StpUserUtil;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.operator.LessEqual;
 import com.ejlchina.searcher.param.Operator;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
@@ -60,6 +61,8 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 
 /**
@@ -126,6 +129,10 @@ public class GroupRelationController {
 
     private final GroupsRelationNetflixService groupsRelationNetflixService;
 
+    private final ChatgptUserMapper chatgptUserMapper;
+
+    private final UpgradeOrderDonMapper upgradeOrderDonMapper;
+
     private final static Sequence SEQUENCE = new Sequence(0);
 
     @RequestMapping("/get/renewal")
@@ -874,4 +881,55 @@ public class GroupRelationController {
     public Result<Integer> getPinStatus(@PathVariable String taskId) throws Exception {
         return GatewayResponse.SUCCESS.newBuilder().toResult(groupsRelationNetflixService.getPinStatus(taskId));
     }
+
+    /**
+     * 可选 续费升级车票
+     */
+    @GetMapping("/get/renew/skus/{relationId}/{skuId}")
+    public Result<List<RenewUpgradePackageFrontView>> getRenewSkus(@PathVariable Long relationId, @PathVariable Long skuId) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+        ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
+                .eq(ChatgptUser::getRelationId, relationId));
+        if (chatgptUser == null) return GatewayResponse.SUCCESS.newBuilder().toResult();
+        //目前续费升级的规格
+        Long renewSkuId = chatgptUser.getRenewSkuId();
+        GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
+        AtomicInteger minMonths = new AtomicInteger(sku.getMonths());
+        AtomicInteger minNum = new AtomicInteger(chatgptUser.getLimitNum());
+        AtomicLong minTime = new AtomicLong(chatgptUser.getLimitTime());
+        if (renewSkuId != null) {
+            GoodsDonSku presentRenew = goodsDonSkuMapper.selectById(renewSkuId);
+            minMonths.set(presentRenew.getMonths());
+        }
+        if (chatgptUser.getPackageId() != 0) {
+            Long packageId = chatgptUser.getPackageId();
+            UpgradeOrderDon upgradeOrderDon = upgradeOrderDonMapper.selectOne(Wrappers.lambdaQuery(UpgradeOrderDon.class)
+                    .eq(UpgradeOrderDon::getPackageId, packageId)
+                    .eq(UpgradeOrderDon::getRelationId, relationId)
+                    .in(UpgradeOrderDon::getUserId, userIdList)
+                    .last("limit 1"));
+            Long upgradeOrderDonSkuId = upgradeOrderDon.getSkuId();
+            GoodsDonSku upgradeSku = goodsDonSkuMapper.selectById(upgradeOrderDonSkuId);
+            if (upgradeSku != null) {
+                if (upgradeSku.getMonths() > minMonths.get()) {
+                    minMonths.set(upgradeSku.getMonths());
+                }
+            }
+        }
+        List<RenewUpgradePackageFrontView> renewUpgradePackageFrontViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.class, MapUtils.builder().field(RenewUpgradePackageFrontView::getSkuId, skuId).build());
+        renewUpgradePackageFrontViews.forEach(renew -> {
+            try {
+                List<RenewUpgradePackageFrontView.RenewSkuView> renewSkuViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.RenewSkuView.class, MapUtils.builder()
+                        .field(RenewUpgradePackageFrontView.RenewSkuView::getMonths, minMonths.get()).op(Operator.GreaterThan)
+                        .field(RenewUpgradePackageFrontView.RenewSkuView::getGptLimitNum, minNum.get()).op(Operator.GreaterEqual)
+                        .field(RenewUpgradePackageFrontView.RenewSkuView::getGptLimitTime, minTime.get()).op(LessEqual.class)
+                        .field(RenewUpgradePackageFrontView.RenewSkuView::getSkuId, Jsons.parseList(renew.getUpgradeSkuIds(), Long.class)).op(Operator.InList)
+                        .build());
+                renew.setRenewSkus(renewSkuViews);
+            } catch (Exception e) {
+            }
+        });
+        return GatewayResponse.SUCCESS.newBuilder().toResult(renewUpgradePackageFrontViews);
+    }
 }

+ 30 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java

@@ -28,6 +28,8 @@ import com.cyksj.mapper.manage.RealGoodsOrderHandleMapper;
 import com.cyksj.mapper.manage.cms.CmsUserMapper;
 import com.cyksj.mapper.manage.coupon.CouponMapper;
 import com.cyksj.mapper.shop.YhShopMapper;
+import com.cyksj.model.dto.OriSkuDto;
+import com.cyksj.model.dto.RenewOriOrderSkuDto;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.excel.*;
 import com.cyksj.model.manage.request.ReqSetLogisticsPost;
@@ -114,6 +116,8 @@ public class CmsOrderController {
 
 	private final UserBindRelationService userBindRelationService;
 
+	private final OrderDonRenewRecordMapper orderDonRenewRecordMapper;
+
 
 	@GetMapping("/get")
 	@SaCheckPermission("order:view")
@@ -1058,4 +1062,30 @@ public class CmsOrderController {
 				.build());
 		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
 	}
+
+	/**
+	 * 续费升级订单详情
+	 */
+	@GetMapping("/renew/orders/detail")
+	public Result<RenewOriOrderSkuDto> getRenewOrdersDetail(Long orderId) {
+		OrderDon orderDon = orderDonMapper.selectById(orderId);
+		if (orderDon.getOrderType() == 2) {
+			OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
+					.eq(OrderDonRenewRecord::getOrderId, orderDon.getId())
+					.last("limit 1"));
+			if (orderDonRenewRecord != null) {
+				GroupsRelation relation = relationMapper.selectById(orderDon.getRelationId());
+				GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId());
+				Date expiryTime = relation.getExpiryTime();
+				DateTime lastExpiryTIme = DateUtil.offsetMonth(expiryTime, -sku.getMonths());
+
+				RenewOriOrderSkuDto renewOriOrderSkuDto = new RenewOriOrderSkuDto();
+				OriSkuDto oriSku = skuMapper.selectRenewOriSku(orderDonRenewRecord.getOriSkuId());
+				renewOriOrderSkuDto.setOriSku(oriSku);
+				renewOriOrderSkuDto.setLastExpiryTime(lastExpiryTIme);
+				return GatewayResponse.SUCCESS.newBuilder().toResult(renewOriOrderSkuDto);
+			}
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
 }

+ 132 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/renew/RenewUpgradePackageController.java

@@ -0,0 +1,132 @@
+package com.cyksj.web.controller.manage.renew;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.annotation.Log;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.BusinessType;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.entity.RenewUpgradePackage;
+import com.cyksj.model.views.RenewUpgradePackageView;
+import com.cyksj.service.mange.renew.RenewUpgradePackageService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: RenewUpgradePackageController
+ * 创建者: JavaZou
+ * 创建时间:2024/7/18 16:59
+ */
+@Slf4j
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/manage/renew/upgrade")
+public class RenewUpgradePackageController {
+	private final RenewUpgradePackageService renewUpgradePackageService;
+
+	private final HttpServletRequest request;
+
+	private final BeanSearcher beanSearcher;
+
+	private final GoodsDonSkuMapper goodsDonSkuMapper;
+
+	/**
+	 * 新增套餐
+	 */
+	@PostMapping
+	@SaCheckPermission("upgrade:add")
+	@Log(module = "套餐管理/新增套餐", businessType = BusinessType.POST, isSaveRequestData = true)
+	public Result<String> post(@RequestBody RenewUpgradePackage upgradePackage){
+		log.info("新增套餐:{}", upgradePackage);
+		renewUpgradePackageService.save(upgradePackage);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 修改套餐
+	 */
+	@PutMapping
+	@SaCheckPermission("upgrade:edit")
+	@Log(module = "套餐管理/修改套餐", businessType = BusinessType.PUT, isSaveRequestData = true)
+	public Result<String> put(@RequestBody RenewUpgradePackage upgradePackage){
+		log.info("修改套餐:{}", upgradePackage);
+		renewUpgradePackageService.updateById(upgradePackage);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 删除套餐
+	 */
+	@DeleteMapping("/{id}")
+	@SaCheckPermission("upgrade:delete")
+	@Log(module = "套餐管理/删除套餐", businessType = BusinessType.DELETE, isSaveRequestData = true)
+	public Result<String> delete(@PathVariable Long id){
+		log.info("删除套餐:{}", id);
+		RenewUpgradePackage byId = renewUpgradePackageService.getById(id);
+		if (byId == null){
+			throw BusinessRuntimeException.getInstance("套餐不存在");
+		}
+		byId.setDeleted(false);
+		renewUpgradePackageService.updateById(byId);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 上下架套餐
+	 */
+	@PutMapping("/put/status/{id}")
+	@SaCheckPermission("upgrade:putStatus")
+	@Log(module = "套餐管理/上下架套餐", businessType = BusinessType.PUT, isSaveRequestData = true)
+	public Result<Boolean> putStatus(@PathVariable Long id){
+		log.info("上下架套餐:{}", id);
+		RenewUpgradePackage byId = renewUpgradePackageService.getById(id);
+		if (byId == null){
+			throw BusinessRuntimeException.getInstance("套餐不存在");
+		}
+		byId.setStatus(!byId.getStatus());
+		renewUpgradePackageService.updateById(byId);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(byId.getStatus());
+	}
+
+	/**
+	 * 获取套餐
+	 */
+	@GetMapping("/{id}")
+	public Result<RenewUpgradePackage> get(@PathVariable Long id){
+		log.info("获取套餐:{}", id);
+		RenewUpgradePackage byId = renewUpgradePackageService.getById(id);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(byId);
+	}
+
+	/**
+	 * 获取套餐列表
+	 */
+	@GetMapping
+	public Result<SearchResult<RenewUpgradePackageView>> list(Long skuId) {
+		log.info("获取套餐列表");
+		Map<String, Object> build = MapUtils.flatBuilder(request.getParameterMap()).build();
+		SearchResult<RenewUpgradePackageView> search = beanSearcher.search(RenewUpgradePackageView.class, build);
+		search.getDataList().forEach(upgradePackageView -> {
+			try {
+				String specVal = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class).in(GoodsDonSku::getId, Jsons.parseList(upgradePackageView.getUpgradeSkuIds(), Long.class))).stream().map(GoodsDonSku::getSpecVal).collect(Collectors.joining(","));
+				upgradePackageView.setUpgradeSpecVal(specVal);
+			} catch (Exception e) {
+				throw BusinessRuntimeException.getInstance("获取套餐规格失败");
+			}
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+}

+ 37 - 5
netflix-web/src/main/java/com/cyksj/web/controller/mirror/MirrorController.java

@@ -1,14 +1,16 @@
 package com.cyksj.web.controller.mirror;
 
 import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.EnvCommonService;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.model.entity.ChatgptSession;
-import com.cyksj.model.entity.ChatgptUser;
-import com.cyksj.model.entity.MidjourneyUser;
+import com.cyksj.mapper.GroupsMapper;
+import com.cyksj.mapper.GroupsRelationMapper;
+import com.cyksj.mapper.renew.RenewUpgradePackageMapper;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.request.gpt.ConversationRequest;
 import com.cyksj.model.response.ConversationLimitResponse;
 import com.cyksj.model.views.ChatGptUserConversationRecordHistoryView;
@@ -37,7 +39,6 @@ import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.List;
-import java.util.Set;
 
 /**
  * /server/镜像服务
@@ -71,6 +72,12 @@ public class MirrorController {
     @Value("${midjourney.drawUrl}")
     private String midjourneyDrawUrl;
 
+    private final RenewUpgradePackageMapper renewUpgradePackageMapper;
+
+    private final GroupsRelationMapper relationMapper;
+
+    private final GroupsMapper groupsMapper;
+
 
     /**
      * GPT车票跳转登录
@@ -102,7 +109,7 @@ public class MirrorController {
             ChatgptSession session = chatGptAccountService.checkSession(carId);
             if (session.getIsCar()) {
                 log.info("用户:{}通过userToken:{}访问镜像车队carId:{}成功", user.getName(), userToken, carId);
-                return GatewayResponse.SUCCESS.newBuilder().setMsg("登陆成功").setCode(1).toResult();
+                return GatewayResponse.SUCCESS.newBuilder().setMsg("登陆成功").setCode(1).toResult(user.getRelationId().toString());
             }
         } catch (Exception e) {
             log.error("服务器错误", e);
@@ -355,4 +362,29 @@ public class MirrorController {
         response.addCookie(cookie);
         response.sendRedirect(midjourneyDrawUrl);
     }
+
+    /**
+     * gpt续费广告弹窗
+     */
+    @GetMapping("/get/gpt/renew/discount")
+    public Result<RenewUpgradePackage> getGptRenewDiscount(Long relationId) {
+        if (relationId != null) {
+            GroupsRelation relation = relationMapper.selectById(relationId);
+            if (relation != null) {
+                GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
+                if (groupsTrips != null) {
+                    RenewUpgradePackage renewUpgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
+                            .eq(RenewUpgradePackage::getGoodsId, 18)
+                            .eq(RenewUpgradePackage::getStatus, 1)
+                            .eq(RenewUpgradePackage::getDeleted, 1)
+                            .eq(RenewUpgradePackage::getSkuId, groupsTrips.getSkuId())
+                            .orderByAsc(RenewUpgradePackage::getDiscount)
+                            .last("limit 1")
+                            .select(RenewUpgradePackage::getId, RenewUpgradePackage::getDiscount));
+                    return GatewayResponse.SUCCESS.newBuilder().toResult(renewUpgradePackage);
+                }
+            }
+        }
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
 }

+ 58 - 5
netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

@@ -20,6 +20,7 @@ import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayApiCode;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.mapper.OrderDonRenewRecordMapper;
 import com.cyksj.mapper.OrderDonWaybillMapper;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.mapper.channel.UserPayEquipmentAvailableBenefitsMapper;
@@ -68,10 +69,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -128,6 +126,9 @@ public class OrderController {
     @Autowired
     private GoodsDonSkuMapper skuMapper;
 
+    @Autowired
+    private OrderDonRenewRecordMapper orderDonRenewRecordMapper;
+
     /**
      * 支付
      * @author chan
@@ -477,7 +478,15 @@ public class OrderController {
                     }
                 }
             }
-            data.setWaybill(waybillMapper.selectOne(Wrappers.lambdaQuery(OrderDonWaybill.class).eq(OrderDonWaybill::getOrderId, data.getId()).last("limit 1")));
+            if (data.getRelationId() == 0) {
+                data.setWaybill(waybillMapper.selectOne(Wrappers.lambdaQuery(OrderDonWaybill.class).eq(OrderDonWaybill::getOrderId, data.getId()).last("limit 1")));
+            }
+            if (data.getOrderType() == 2) {
+                OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
+                        .eq(OrderDonRenewRecord::getOrderId, data.getId())
+                        .last("limit 1"));
+                data.setIsRenewPackage(orderDonRenewRecord != null ? true : false);
+            }
         });
         return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
@@ -516,6 +525,15 @@ public class OrderController {
         if (orderDonView == null) {
             throw BusinessRuntimeException.getInstance("订单不存在");
         }
+        if (orderDonView.getIsMirror() && orderDonView.getOrderType() == 2) {
+            Optional.ofNullable(orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
+                            .eq(OrderDonRenewRecord::getOrderId, orderId)
+                            .last("limit 1")))
+                    .ifPresent(renew -> {
+                        GoodsDonSku sku = skuMapper.selectById(renew.getOriSkuId());
+                        orderDonView.setOriSpecVal(sku.getSpecVal());
+                    });
+        }
         return GatewayResponse.SUCCESS.newBuilder().toResult(orderDonView);
     }
 
@@ -809,4 +827,39 @@ public class OrderController {
         }
         return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
+
+    /**
+     * 续费升级提交支付
+     */
+    @PostMapping("/post/renew/upgrade/submit")
+    public Result<OrderDon> submitRenewUpgrade(@Validated @RequestBody OrderPayRequest payRequest) throws Exception {
+        final String methodName = "续费升级吊起支付";
+        //无需免登录
+        Long userId = StpUserUtil.getLoginIdAsLong();
+        payRequest.setUserId(userId);
+        log.info("{}[start] params:{}", methodName, payRequest);
+
+        String ip = ServletUtil.getClientIP(request);
+
+        payRequest.setIp(ip);
+
+        OrderDon orderDon = orderDonService.submitRenewUpgrade(payRequest);
+
+        return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon);
+    }
+
+    /**
+     * 获取续费套餐订单列表
+     */
+    @GetMapping("/renew/get")
+    public Result<SearchResult<RenewUpgradeOrderDonView>> listRenewOrders(){
+        long userId = StpUserUtil.getLoginIdAsLong();
+        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+        List<Long> userIds = UserBindRelationService.getRelationUserIdList(userId, null);
+        SearchResult<RenewUpgradeOrderDonView> search = beanSearcher.search(RenewUpgradeOrderDonView.class, builder
+                .field(UpgradeOrderDonView::getUserId, userIds).op(Operator.InList)
+                .orderBy(UpgradeOrderDonView::getId).desc()
+                .build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+    }
 }