Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/master'

chenbiao 9 mēneši atpakaļ
vecāks
revīzija
1e1b4fd149
58 mainītis faili ar 1281 papildinājumiem un 291 dzēšanām
  1. 2 2
      netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
  2. 2 0
      netflix-dao/src/main/java/com/cyksj/mapper/GroupsRelationMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/NetflixCompensateReceivedRecordMapper.java
  4. 20 0
      netflix-dao/src/main/java/com/cyksj/mapper/UserDistributeRateChangeRecordMapper.java
  5. 4 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeMapper.java
  6. 6 0
      netflix-dao/src/main/java/com/cyksj/mapper/vip/VipGoodsSkuMapper.java
  7. 21 0
      netflix-dao/src/main/java/com/cyksj/model/dto/NetflixRecoverReceivedGptConditionDto.java
  8. 10 0
      netflix-dao/src/main/java/com/cyksj/model/entity/FrontProblemCollectRecord.java
  9. 11 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonSku.java
  10. 31 0
      netflix-dao/src/main/java/com/cyksj/model/entity/NetflixCompensateReceivedRecord.java
  11. 2 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserBlackRecord.java
  12. 27 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeRateChangeRecord.java
  13. 4 0
      netflix-dao/src/main/java/com/cyksj/model/manage/request/ReqGoodsSkuInsert.java
  14. 3 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonBackView.java
  15. 7 0
      netflix-dao/src/main/java/com/cyksj/model/request/DelAccountTripsReq.java
  16. 5 0
      netflix-dao/src/main/java/com/cyksj/model/request/OrderPayRequest.java
  17. 5 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuFrontView.java
  18. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuRenewView.java
  19. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuView.java
  20. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java
  21. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeRateView.java
  22. 2 2
      netflix-dao/src/main/java/com/cyksj/model/views/UserInvoiceChoseOrderViews.java
  23. 5 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserSyncInfoView.java
  24. 2 1
      netflix-dao/src/main/java/com/cyksj/model/views/VipGoodsSkuFrontView.java
  25. 16 0
      netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml
  26. 14 0
      netflix-dao/src/main/resources/mapper/UserDistributeMapper.xml
  27. 24 0
      netflix-dao/src/main/resources/mapper/UserDistributeRateChangeRecordMapper.xml
  28. 24 9
      netflix-service/src/main/java/com/cyksj/service/claude/impl/ClaudeCodeServiceImpl.java
  29. 14 2
      netflix-service/src/main/java/com/cyksj/service/codex/impl/CodexServiceImpl.java
  30. 21 0
      netflix-service/src/main/java/com/cyksj/service/distribute/UserDistributeRateChangeRecordService.java
  31. 110 4
      netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributeServiceImpl.java
  32. 70 0
      netflix-service/src/main/java/com/cyksj/service/distribute/impl/UserDistributeRateChangeRecordServiceImpl.java
  33. 2 0
      netflix-service/src/main/java/com/cyksj/service/mange/CmsAccountService.java
  34. 47 0
      netflix-service/src/main/java/com/cyksj/service/mange/account/CmsAccountServiceImpl.java
  35. 5 5
      netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonSkuServiceImpl.java
  36. 32 0
      netflix-service/src/main/java/com/cyksj/service/mange/group/CmsGroupServiceImpl.java
  37. 7 3
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  38. 3 2
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderCommonServiceImpl.java
  39. 247 184
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  40. 5 8
      netflix-service/src/main/java/com/cyksj/service/order/impl/VipOrderDonServiceImpl.java
  41. 5 0
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  42. 186 27
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  43. 2 1
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java
  44. 12 0
      netflix-service/src/main/java/com/cyksj/service/verify/ApiVerifyService.java
  45. 40 0
      netflix-service/src/main/java/com/cyksj/service/verify/impl/ApiVerifyServiceImpl.java
  46. 12 10
      netflix-service/src/main/java/com/cyksj/service/vip/impl/CmsVipUserServiceImpl.java
  47. 5 2
      netflix-service/src/main/java/com/cyksj/service/vip/impl/VipFrontServiceImpl.java
  48. 3 0
      netflix-web/src/main/java/com/cyksj/web/controller/claude/ClaudeCodeController.java
  49. 3 0
      netflix-web/src/main/java/com/cyksj/web/controller/codex/CodexController.java
  50. 14 0
      netflix-web/src/main/java/com/cyksj/web/controller/cps/CpsDistribtueDataController.java
  51. 22 0
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  52. 12 9
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
  53. 22 5
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java
  54. 25 3
      netflix-web/src/main/java/com/cyksj/web/controller/manage/account/CmsAccountController.java
  55. 23 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java
  56. 11 8
      netflix-web/src/main/java/com/cyksj/web/controller/manage/group/CmsGroupRelationController.java
  57. 30 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java
  58. 19 4
      netflix-web/src/main/java/com/cyksj/web/controller/sys/FrontProblemCollectRecordController.java

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

@@ -367,7 +367,7 @@ public interface Constant {
 	Long GPT_MIRROR_COMMON_SKU_ID = 426l;
 
 	/**
-	 * 大学生快递站 体验车票标准规格
+	 * 大学生快递站 体验车票标准月付规格
 	 */
 	Long GPT_MIRROR_SKU_ID = 429l;
 
@@ -717,7 +717,7 @@ public interface Constant {
 	/**
 	 * cc api domain
 	 */
-	String CLAUDE_CODE_API_PREFIX = "https://relay.nf.video/";
+	String CLAUDE_CODE_API_PREFIX = "https://cceo.nf.video/";
 
 	String CLAUDE_CODE_HEARD_KEY = "X-Admin-Key";
 

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/mapper/GroupsRelationMapper.java

@@ -85,4 +85,6 @@ public interface GroupsRelationMapper extends BaseMapper<GroupsRelation> {
 	List<UserTicketView> selectUserTickets(@Param("userIds") List<Long> userIds, @Param("goodsId") Long goodsId, @Param("skuId") Long skuId);
 
 	Integer selectCountByGoodsId(@Param("userIds") List<Long> userIdList, @Param("goodsId") Long goodsId, @Param("now") DateTime now);
+
+	Integer updateUserVipSkusExpiryTime(@Param("userIds") List<Long> userIds, @Param("vipSkuIds") List<Long> vipSkuIds, @Param("expiryTime") Date expiryTime);
 }

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.NetflixCompensateReceivedRecord;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: NetflixCompensateReceivedRecordMapper
+ * 创建者: JavaZou
+ * 创建时间:2025/11/4 10:46
+ */
+public interface NetflixCompensateReceivedRecordMapper extends BaseMapper<NetflixCompensateReceivedRecord> {
+}

+ 20 - 0
netflix-dao/src/main/java/com/cyksj/mapper/UserDistributeRateChangeRecordMapper.java

@@ -0,0 +1,20 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserDistribute;
+import com.cyksj.model.entity.UserDistributeRateChangeRecord;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: UserDistributeRateChangeRecordMapper
+ * 创建者: JavaZou
+ * 创建时间:2025/10/29 15:15
+ */
+public interface UserDistributeRateChangeRecordMapper extends BaseMapper<UserDistributeRateChangeRecord> {
+	void batchInsertGoodsRateChangeRecord(@Param("list") List<UserDistribute> list, @Param("goodsId") Long goodsId, @Param("skuId") Long skuId, @Param("changeInfo") String changeInfo, @Param("rate") Integer rate);
+
+	void batchInsertGoodsRateChangeNoSetSkuRecord(@Param("list") List<UserDistribute> list, @Param("goodsId") Long goodsId, @Param("skuId") Long skuId, @Param("changeInfo") String changeInfo);
+}

+ 4 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeMapper.java

@@ -37,4 +37,8 @@ public interface UserDistributeMapper extends BaseMapper<UserDistribute> {
 	DistributeMoneyApply selectRelationBusiness(Long userId);
 
 	CpsOrderDataStatisticsView selectOrderBrokenLineMoney(@Param("cpsUserId") long cpsUserId, @Param("first") String first, @Param("end") String end);
+
+	List<UserDistribute> selectNoSetGoodsRateDistirbutors(Long goodsId);
+
+	List<UserDistribute> selectNoSetGoodsSkuRateDistirbutors(Long skuId);
 }

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/mapper/vip/VipGoodsSkuMapper.java

@@ -2,6 +2,9 @@ package com.cyksj.mapper.vip;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.VipGoodsSku;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
 
 /**
  * 项目名: yhlxj2
@@ -10,4 +13,7 @@ import com.cyksj.model.entity.VipGoodsSku;
  * 创建时间:2025/5/13 11:06
  */
 public interface VipGoodsSkuMapper extends BaseMapper<VipGoodsSku> {
+
+	@Select("select vgs.* from vip_goods_sku vgs inner join goods_don_sku sku on sku.id = vgs.sku_id where sku.status")
+	List<VipGoodsSku> selectUpSkus();
 }

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

@@ -0,0 +1,21 @@
+package com.cyksj.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: NetflixRecoverReceivedGptConditionDto
+ * 创建者: JavaZou
+ * 创建时间:2025/11/4 11:18
+ */
+@Getter
+@Setter
+public class NetflixRecoverReceivedGptConditionDto {
+	/**
+	 * 是否可领取
+	 */
+	private Boolean status;
+
+	private Long nfRelationId;
+}

+ 10 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/FrontProblemCollectRecord.java

@@ -1,5 +1,7 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.ejlchina.searcher.bean.DbIgnore;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -23,4 +25,12 @@ public class FrontProblemCollectRecord extends BaseEntity{
 	 * 操作
 	 */
 	private String handle;
+
+	@DbIgnore
+	@TableField(exist = false)
+	private Long timestamp;
+
+	@DbIgnore
+	@TableField(exist = false)
+	private String sign;
 }

+ 11 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonSku.java

@@ -107,6 +107,12 @@ public class GoodsDonSku extends BaseEntity {
      */
     private BigDecimal price;
 
+    /**
+     * 续费价格
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private BigDecimal renewPrice;
+
     /**
      * 专属用户规格
      */
@@ -313,4 +319,9 @@ public class GoodsDonSku extends BaseEntity {
      */
     @TableField(updateStrategy = FieldStrategy.IGNORED)
     private Integer openaiQuota;
+
+    /**
+     * 是否坐满规格就下架车队 默认false
+     */
+    private Boolean isDown;
 }

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

@@ -0,0 +1,31 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: NetflixCompensateReceivedRecord
+ * 创建者: JavaZou
+ * 创建时间:2025/11/4 10:44
+ * 奈飞补偿领取车票记录
+ */
+@Getter
+@Setter
+public class NetflixCompensateReceivedRecord extends BaseEntity{
+	private Long goodsId;
+
+	private Long skuId;
+
+	/**
+	 * 当时申请恢复的奈飞车票id
+	 */
+	private Long nfRelationId;
+
+	/**
+	 * 车票id
+	 */
+	private Long relationId;
+
+	private Long userId;
+}

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

@@ -23,4 +23,6 @@ public class UserBlackRecord extends BaseEntity{
 	 * 拉黑状态
 	 */
 	private Boolean status;
+
+	private String operator;
 }

+ 27 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeRateChangeRecord.java

@@ -0,0 +1,27 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: UserDistributeRateChangeRecord
+ * 创建者: JavaZou
+ * 创建时间:2025/10/29 15:13
+ */
+@Getter
+@Setter
+public class UserDistributeRateChangeRecord extends BaseEntity{
+	private Long distributeId;
+
+	private Long userId;
+
+	private Long goodsId;
+
+	private Long skuId;
+
+	/**
+	 * 变更记录
+	 */
+	private String changeInfo;
+}

+ 4 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/request/ReqGoodsSkuInsert.java

@@ -68,6 +68,8 @@ public class ReqGoodsSkuInsert {
 
         private BigDecimal price;
 
+        private BigDecimal renewPrice;
+
         /**
          * 专属用户规格
          */
@@ -234,6 +236,8 @@ public class ReqGoodsSkuInsert {
          */
         @TableField(updateStrategy = FieldStrategy.IGNORED)
         private Integer openaiQuota;
+
+        private Boolean isDown;
     }
 
 }

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

@@ -93,6 +93,9 @@ public class OrderDonBackView {
 	@DbField("sku.spec_val")
 	private String specVal;
 
+	@DbField("sku.num")
+	private Integer skuNum;
+
 	@DbField("sku.is_benefits")
 	private Boolean isBenefits;
 

+ 7 - 0
netflix-dao/src/main/java/com/cyksj/model/request/DelAccountTripsReq.java

@@ -23,4 +23,11 @@ public class DelAccountTripsReq {
 	 * 车队ids
 	 */
 	private List<Long> groupsIds;
+
+	/**
+	 * 账号列表
+	 */
+	private List<String> accounts;
+
+	private Integer goodsId;
 }

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/model/request/OrderPayRequest.java

@@ -219,6 +219,11 @@ public class OrderPayRequest {
      */
     private RenewSource renewSource;
 
+    /**
+     * 是否使用续费价格
+     */
+    private Boolean isRenewPrice = false;
+
     @Getter
     public enum RenewSource{
         galaxyCoin("银河币"),

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

@@ -91,6 +91,11 @@ public class GoodsDonSkuFrontView {
 	 */
 	private BigDecimal price = BigDecimal.ZERO;
 
+	/**
+	 * 续费价格
+	 */
+	private BigDecimal renewPrice;
+
 	/**
 	 * 渠道优惠折扣
 	 */

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

@@ -31,6 +31,9 @@ public class GoodsDonSkuRenewView {
 	@DbField("sku.price")
 	private BigDecimal price;
 
+	@DbField("sku.renew_price")
+	private BigDecimal renewPrice;
+
 	@DbField("g.id")
 	private Long goodsId;
 

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

@@ -53,6 +53,9 @@ public class GoodsDonSkuView {
 	@DbField("gdk.price")
 	private BigDecimal money;
 
+	@DbField("gdk.renew_price")
+	private BigDecimal renewPrice;
+
 	@DbField("gd.status")
 	private Boolean goodsDonStatus;
 

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

@@ -59,6 +59,9 @@ public class RenewalView {
     @DbField("sku.price")
     private BigDecimal price;
 
+    @DbField("sku.renew_price")
+    private BigDecimal renewPrice;
+
     @DbField("sku.spec_val")
     private String specVal;
 

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

@@ -26,6 +26,9 @@ public class UserDistributeRateView {
 	@DbField("gc.name")
 	private String categoryName;
 
+	@DbField("g.id")
+	private Long goodsId;
+
 	@DbField("g.title")
 	private String title;
 

+ 2 - 2
netflix-dao/src/main/java/com/cyksj/model/views/UserInvoiceChoseOrderViews.java

@@ -18,7 +18,7 @@ import java.util.Date;
 @Getter
 @Setter
 @SearchBean(tables = " (:order:) o left join user_invoice_order_relate uor on uor.order_id = o.id and uor.type = o.type" +
-		" inner join goods_don g on g.id = o.goods_id and (g.id in (select goods_id from goods_don_category_relate where category = 1) or g.id = 40)" +
+		" inner join goods_don g on g.id = o.goods_id and (g.id in (select goods_id from goods_don_category_relate where category = 1) or g.is_invoice)" +
 		" left join goods_don_sku sku on sku.id = o.sku_id" +
 		" inner join shop_config sc on sc.app_id = o.shop_id",
 		where = " uor.id is null :dc:",
@@ -49,7 +49,7 @@ public class UserInvoiceChoseOrderViews {
 	@DbField("sc.payment")
 	private String zfbPayment;
 
-	@DbField("o.pay_time")
+	@DbField("ifnull(o.pay_time,o.created_time)")
 	private Date payTime;
 
 	@DbField("o.shop_id")

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

@@ -21,6 +21,11 @@ public class UserSyncInfoView {
 	 */
 	private Boolean isVip = false;
 
+	/**
+	 * 是否被拉黑
+	 */
+	private Boolean isBlack = false;
+
 	/**
 	 * 会员开始时间
 	 */

+ 2 - 1
netflix-dao/src/main/java/com/cyksj/model/views/VipGoodsSkuFrontView.java

@@ -16,7 +16,8 @@ import java.math.BigDecimal;
 @Getter
 @Setter
 @SearchBean(tables = "vip_goods_sku vgs left join goods_don g on g.id = vgs.goods_id" +
-		" left join goods_don_sku sku on sku.id = vgs.sku_id")
+		" left join goods_don_sku sku on sku.id = vgs.sku_id",
+		where = "sku.status")
 public class VipGoodsSkuFrontView {
 
 	@DbField("vgs.goods_id")

+ 16 - 0
netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml

@@ -45,6 +45,22 @@
         update groups_relation set expiry_time = DATE_ADD(expiry_time,interval 1 day) where id = #{relationId} and user_id = #{userId}
     </update>
 
+    <update id="updateUserVipSkusExpiryTime">
+        update groups_relation set expiry_time = #{expiryTime},
+        update_time = now()
+        where id in (select * from(
+        select gr.id from groups_relation gr inner join groups_trips gt on gt.id = gr.groups_id
+        where gt.sku_id in
+        <foreach collection="vipSkuIds" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        and gr.user_id in
+        <foreach collection="userIds" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        and is_vip)s)
+    </update>
+
     <select id="getAccountIdsByUserIdOrNickNameOrSubmitAccount" resultType="java.lang.Long">
         select gr.groups_id
         from groups_relation gr,

+ 14 - 0
netflix-dao/src/main/resources/mapper/UserDistributeMapper.xml

@@ -117,4 +117,18 @@
             and curdate &lt; #{end}
         </if>
     </select>
+
+    <select id="selectNoSetGoodsRateDistirbutors" resultType="com.cyksj.model.entity.UserDistribute">
+        select ud.*
+        from (select id,user_id from user_distribute where deleted) ud
+                 left join user_plat_distribute_rate ur on ur.distribute_id = ud.id and ur.goods_id = #{goodsId}
+        where ur.id is null
+    </select>
+
+    <select id="selectNoSetGoodsSkuRateDistirbutors" resultType="com.cyksj.model.entity.UserDistribute">
+        select ud.*
+        from (select id,user_id from user_distribute where deleted) ud
+                 left join user_plat_sku_distribute_rate ur on ur.distribute_id = ud.id and ur.sku_id = #{skuId}
+        where ur.id is null
+    </select>
 </mapper>

+ 24 - 0
netflix-dao/src/main/resources/mapper/UserDistributeRateChangeRecordMapper.xml

@@ -0,0 +1,24 @@
+<?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.UserDistributeRateChangeRecordMapper">
+
+
+    <insert id="batchInsertGoodsRateChangeRecord">
+        insert into
+        user_distribute_rate_change_record(`distribute_id`,`user_id`,`goods_id`,`sku_id`,`change_info`,`created_time`,`update_time`)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.id},#{item.userId},#{goodsId},#{skuId},#{changeInfo},now(),now())
+        </foreach>
+    </insert>
+
+    <insert id="batchInsertGoodsRateChangeNoSetSkuRecord">
+        insert into
+        user_distribute_rate_change_record(`distribute_id`,`user_id`,`goods_id`,`sku_id`,`change_info`,`created_time`,`update_time`)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.id},#{item.userId},#{goodsId},#{skuId},concat(#{changeInfo},(select ifnull(rate,(select rate from business_distribute_default_rate_config where goods_id = #{goodsId} limit 1)) from user_plat_distribute_rate where distribute_id = #{item.id} and goods_id = #{goodsId} limit 1),'%'),now(),now())
+        </foreach>
+    </insert>
+</mapper>

+ 24 - 9
netflix-service/src/main/java/com/cyksj/service/claude/impl/ClaudeCodeServiceImpl.java

@@ -15,10 +15,7 @@ import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.util.Jsons;
 import com.cyksj.common.util.StringUtil;
 import com.cyksj.mapper.*;
-import com.cyksj.mapper.claudecode.ClaudeCodeCreditCardMapper;
-import com.cyksj.mapper.claudecode.ClaudeCodeDayResetRecordMapper;
-import com.cyksj.mapper.claudecode.ClaudeCodeUserCreditCardRecordMapper;
-import com.cyksj.mapper.claudecode.ClaudeCodeUserResetRecordMapper;
+import com.cyksj.mapper.claudecode.*;
 import com.cyksj.mapper.manage.distribute.DistributePointsExchangeMoneyMapper;
 import com.cyksj.mapper.manage.distribute.DistributeWaitingSendPointsMapper;
 import com.cyksj.model.dto.ClaudeCodeDeductDto;
@@ -82,6 +79,8 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 
 	private final OrderDonMapper orderDonMapper;
 
+	private final OrderDonGalaxyCoinRecordMapper orderDonGalaxyCoinRecordMapper;
+
 	private final ClaudeCodeUserResetRecordMapper claudeCodeUserResetRecordMapper;
 
 	private final ClaudeCodeUserCreditCardRecordMapper claudeCodeUserCreditCardRecordMapper;
@@ -106,6 +105,8 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 
 	private final ClaudeCodexApiService claudeCodexApiService;
 
+	private final ClaudeCodeDeductOrderRelateMapper claudeCodeDeductOrderRelateMapper;
+
 	@Override
 	public void generateOrUpdateClaudeCodeUserInfo(Long orderId, Long relationId, Long userId, GoodsDonSku sku, Integer orderType) {
 		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
@@ -389,7 +390,7 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		parmas.put("claude_quota", claudeQuota);
 		//服务类型
 		parmas.put("service_type", "claude");
-		if (sku.getIsCodex()) {
+		if (sku != null && sku.getIsCodex()) {
 			parmas.put("openai_daily_limit", sku.getOpenaiDailyLimit());
 			parmas.put("openai_quota", sku.getOpenaiQuota());
 			//组合
@@ -407,7 +408,7 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 			log.info("用户claude code用户:{}套餐:{}创建或更新失败,info:{}", userId, planName, claudeCodeResp.getMessage());
 		} else {
 			//是否赠送codex
-			if (sku.getIsCodex()) {
+			if (sku != null && sku.getIsCodex()) {
 				CodexUserPackageReq codexPackageReq = CodexUserPackageReq.builder()
 						.userId(userId)
 						.relationId(relationId)
@@ -1070,7 +1071,11 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		ClaudeCodeDeductDto claudeCodeDeductDto = new ClaudeCodeDeductDto();
 		if (renewSkuId != null && renewExpiryTime.compareTo(now) > 0) {
 			OrderDon renewOrderDon = orderDonMapper.selectById(renewOrderId);
-			BigDecimal orderMoney = renewOrderDon.getMoney().add(Optional.ofNullable(renewOrderDon.getBalance()).orElse(BigDecimal.ZERO));
+			BigDecimal orderMoney = renewOrderDon.getMoney().add(Optional.ofNullable(renewOrderDon.getBalance()).orElse(BigDecimal.ZERO)).add(Optional.ofNullable(renewOrderDon.getCouponMoney()).orElse(BigDecimal.ZERO));
+			OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = orderDonGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonGalaxyCoinRecord.class).eq(OrderDonGalaxyCoinRecord::getOrderId, renewOrderDon.getId()).last("limit 1"));
+			if (orderDonGalaxyCoinRecord != null) {
+				orderMoney = orderMoney.add(orderDonGalaxyCoinRecord.getDeductMoney());
+			}
 			GoodsDonSku presentSku = skuMapper.selectById(renewSkuId);
 			if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
 				//存在升级后的0元订单 即兑换码订单 不让抵扣
@@ -1207,10 +1212,12 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 	 * 获取车票可抵扣金额
 	 */
 	public BigDecimal getDeductMoneyFromTicket(Long relationId, List<Long> userIdList, Long skuId, DateTime now, Date relationStartTime, Date relationExpiryTime) {
+		OrderDon oriOrderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus).eq(OrderDon::getOrderType, 1).orderByDesc(OrderDon::getId).last("limit 1"));
 		List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
 				.eq(OrderDon::getRelationId, relationId)
 				.in(OrderDon::getUserId, userIdList)
 				.eq(OrderDon::getSkuId, skuId)
+				.ge(oriOrderDon != null, OrderDon::getCreatedTime, oriOrderDon.getCreatedTime())
 				.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
 				.orderByDesc(OrderDon::getId));
 		//部分退款
@@ -1232,7 +1239,11 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		Integer totalDays = 0;
 		for (OrderDon orderDon : orderDonList) {
 			GoodsDonSku sku = skuMapper.selectById(skuId);
-			BigDecimal thisOrderMoney = orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)).subtract(Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO));
+			BigDecimal thisOrderMoney = orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)).subtract(Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO)).add(Optional.ofNullable(orderDon.getCouponMoney()).orElse(BigDecimal.ZERO));
+			OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = orderDonGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonGalaxyCoinRecord.class).eq(OrderDonGalaxyCoinRecord::getOrderId, orderDon.getId()).last("limit 1"));
+			if (orderDonGalaxyCoinRecord != null) {
+				thisOrderMoney = thisOrderMoney.add(orderDonGalaxyCoinRecord.getDeductMoney());
+			}
 			if (thisOrderMoney.compareTo(BigDecimal.ZERO) == 0) {
 				if (sku.getDays() != null) {
 					relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -sku.getDays());
@@ -1248,6 +1259,10 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 			} else {
 				totalDays += sku.getMonths() * 30;
 			}
+			ClaudeCodeDeductOrderRelate claudeCodeDeductOrderRelate = claudeCodeDeductOrderRelateMapper.selectOne(Wrappers.lambdaQuery(ClaudeCodeDeductOrderRelate.class).eq(ClaudeCodeDeductOrderRelate::getOrderId, orderDon.getId()).last("limit 1"));
+			if (claudeCodeDeductOrderRelate != null) {
+				totalOrderMoney = totalOrderMoney.add(claudeCodeDeductOrderRelate.getDeductMoney());
+			}
 			//原订单数
 			if (orderDonList.size() == 1) {
 				//此次订单过期时间
@@ -1259,7 +1274,7 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 				}
 				//当天购买的按规格原价抵扣
 				if (now.toDateStr().equals(DateUtil.format(relationStartTime, "yyyy-MM-dd")) && (DateUtil.betweenDay(thisOrderExpiryTime, relationExpiryTime, true) == 0)) {
-					return thisOrderMoney;
+					return totalOrderMoney;
 				}
 			}
 		}

+ 14 - 2
netflix-service/src/main/java/com/cyksj/service/codex/impl/CodexServiceImpl.java

@@ -112,6 +112,8 @@ public class CodexServiceImpl implements CodexService {
 
 	private final CouponFontService couponFontService;
 
+	private final OrderDonGalaxyCoinRecordMapper orderDonGalaxyCoinRecordMapper;
+
 	private static final Sequence SEQUENCE = new Sequence(0);
 
 	private final ClaudeCodexApiService claudeCodexApiService;
@@ -475,7 +477,11 @@ public class CodexServiceImpl implements CodexService {
 		//续费规格
 		if (renewSkuId != null && renewExpiryTime.compareTo(now) > 0) {
 			OrderDon renewOrderDon = orderDonMapper.selectById(renewOrderId);
-			BigDecimal orderMoney = renewOrderDon.getMoney().add(Optional.ofNullable(renewOrderDon.getBalance()).orElse(BigDecimal.ZERO));
+			BigDecimal orderMoney = renewOrderDon.getMoney().add(Optional.ofNullable(renewOrderDon.getBalance()).orElse(BigDecimal.ZERO)).add(Optional.ofNullable(renewOrderDon.getCouponMoney()).orElse(BigDecimal.ZERO));
+			OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = orderDonGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonGalaxyCoinRecord.class).eq(OrderDonGalaxyCoinRecord::getOrderId, renewOrderDon.getId()).last("limit 1"));
+			if (orderDonGalaxyCoinRecord != null) {
+				orderMoney = orderMoney.add(orderDonGalaxyCoinRecord.getDeductMoney());
+			}
 			GoodsDonSku presentSku = skuMapper.selectById(renewSkuId);
 			if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
 				orderMoney = presentSku.getPrice();
@@ -861,10 +867,12 @@ public class CodexServiceImpl implements CodexService {
 	 * 获取车票可抵扣金额
 	 */
 	public BigDecimal getDeductMoneyFromTicket(Long relationId, List<Long> userIdList, Long skuId, DateTime now, Date relationStartTime, Date relationExpiryTime) {
+		OrderDon oriOrderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus).eq(OrderDon::getOrderType, 1).orderByDesc(OrderDon::getId).last("limit 1"));
 		List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
 				.eq(OrderDon::getRelationId, relationId)
 				.in(OrderDon::getUserId, userIdList)
 				.eq(OrderDon::getSkuId, skuId)
+				.ge(oriOrderDon != null, OrderDon::getCreatedTime, oriOrderDon.getCreatedTime())
 				.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
 				.orderByDesc(OrderDon::getId));
 		//部分退款
@@ -882,7 +890,11 @@ public class CodexServiceImpl implements CodexService {
 		Integer totalDays = 0;
 		for (OrderDon orderDon : orderDonList) {
 			GoodsDonSku sku = skuMapper.selectById(skuId);
-			BigDecimal thisOrderMoney = orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)).subtract(Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO));
+			BigDecimal thisOrderMoney = orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)).subtract(Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO)).add(Optional.ofNullable(orderDon.getCouponMoney()).orElse(BigDecimal.ZERO));
+			OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = orderDonGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonGalaxyCoinRecord.class).eq(OrderDonGalaxyCoinRecord::getOrderId, orderDon.getId()).last("limit 1"));
+			if (orderDonGalaxyCoinRecord != null) {
+				thisOrderMoney = thisOrderMoney.add(orderDonGalaxyCoinRecord.getDeductMoney());
+			}
 			if (thisOrderMoney.compareTo(BigDecimal.ZERO) == 0) {
 				thisOrderMoney = sku.getPrice();
 			}

+ 21 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/UserDistributeRateChangeRecordService.java

@@ -0,0 +1,21 @@
+package com.cyksj.service.distribute;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.BusinessDistributeDefaultSkuRateConfig;
+import com.cyksj.model.entity.UserDistributeRateChangeRecord;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: UserDistributeRateChangeRecordService
+ * 创建者: JavaZou
+ * 创建时间:2025/10/29 16:16
+ */
+public interface UserDistributeRateChangeRecordService extends IService<UserDistributeRateChangeRecord> {
+	void recordDefaultGoodsRate(Long goodsId, Integer rate);
+
+	void recordDefaultGoodsSkuRate(Long goodsId, Long skuId, Integer rate);
+
+	void recordDefaultGoodsSkuDelRate(List<BusinessDistributeDefaultSkuRateConfig> delLists);
+}

+ 110 - 4
netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributeServiceImpl.java

@@ -11,6 +11,7 @@ import com.cyksj.common.constant.TaskTypeEnum;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.util.Jsons;
 import com.cyksj.mapper.GoodsDonMapper;
+import com.cyksj.mapper.GoodsDonSkuMapper;
 import com.cyksj.mapper.UserDistributeSharedRelateUnbindMapper;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.mapper.manage.coupon.CouponDistributePopularizeMapper;
@@ -26,6 +27,7 @@ import com.cyksj.model.request.UserDistributeReq;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.claude.ClaudeCodeService;
 import com.cyksj.service.distribute.DistributeService;
+import com.cyksj.service.distribute.UserDistributeRateChangeRecordService;
 import com.cyksj.service.market.task.TaskService;
 import com.cyksj.service.relation.GroupRelationFrontService;
 import lombok.RequiredArgsConstructor;
@@ -35,10 +37,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
@@ -94,6 +93,14 @@ public class DistributeServiceImpl implements DistributeService {
 
 	private final GroupRelationFrontService groupRelationFrontService;
 
+	private final BusinessDistributeDefaultRateConfigMapper businessDistributeDefaultRateConfigMapper;
+
+	private final BusinessDistributeDefaultSkuRateConfigMapper businessDistributeDefaultSkuRateConfigMapper;
+
+	private final GoodsDonSkuMapper skuMapper;
+
+	private final UserDistributeRateChangeRecordService userDistributeRateChangeRecordService;
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public void insertDistribute(UserDistributeReq userDistributeReq) {
@@ -196,6 +203,7 @@ public class DistributeServiceImpl implements DistributeService {
 		YhShop yhShop = yhShopMapper.selectOne(Wrappers.lambdaQuery(YhShop.class)
 				.eq(YhShop::getUserId, userDistribute.getUserId())
 				.eq(YhShop::getVerifyStatus, YhShop.Status.success).last("limit 1"));
+		List<UserDistributeRateChangeRecord> userDistributeRateChangeRecords = new ArrayList<>();
 		for (UserPlatDistributeRate rate : userDistributeReq.getRates()) {
 			if (rate.getRate() == null) {
 				rate.setRate(0);
@@ -221,6 +229,8 @@ public class DistributeServiceImpl implements DistributeService {
 			rate.setDistributeId(userDistribute.getId());
 			if (rate.getId() == null) {
 				try {
+					//平台比例更变记录
+					recordGoodsRateSaveChange(userDistribute, rate.getGoodsId(), rate.getRate(), goodsDon.getTitle(), userDistributeRateChangeRecords);
 					userPlatDistributeRateMapper.insert(rate);
 				} catch (DuplicateKeyException e) {
 					userPlatDistributeRateMapper.update(null, Wrappers.lambdaUpdate(UserPlatDistributeRate.class)
@@ -246,6 +256,8 @@ public class DistributeServiceImpl implements DistributeService {
 			} else {
 				UserPlatDistributeRate dbPlateRate = userPlatDistributeRateMapper.selectById(rate.getId());
 				if (dbPlateRate == null) {
+					//平台比例更变记录
+					recordGoodsRateSaveChange(userDistribute, rate.getGoodsId(), rate.getRate(), goodsDon.getTitle(), userDistributeRateChangeRecords);
 					continue;
 				}
 				if (dbPlateRate.getRate() != rate.getRate() || dbPlateRate.getSecondRate() != rate.getSecondRate()) {
@@ -257,6 +269,10 @@ public class DistributeServiceImpl implements DistributeService {
 								.eq(YhShopUserPlatDistributeRate::getGoodsId, rate.getGoodsId())
 								.set(YhShopUserPlatDistributeRate::getRate, rate.getRate()));
 					}
+					if (dbPlateRate.getRate() != rate.getRate()) {
+						//变更记录
+						recordGoodsRateChange(userDistribute, goodsDon.getTitle(), rate, userDistributeRateChangeRecords);
+					}
 				}
 			}
 		}
@@ -265,6 +281,10 @@ public class DistributeServiceImpl implements DistributeService {
 		List<UserPlatSkuDistributeRate> skuRates = userDistributeReq.getSkuRates();
 		if (CollUtil.isNotEmpty(skuRates)) {
 			List<Long> skuIds = skuRates.stream().map(UserPlatSkuDistributeRate::getSkuId).collect(Collectors.toList());
+			List<UserPlatSkuDistributeRate> delSkuRateList = userPlatSkuDistributeRateMapper.selectList(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class).eq(UserPlatSkuDistributeRate::getDistributeId,userDistribute.getId()).notIn(UserPlatSkuDistributeRate::getSkuId, skuIds).orderByAsc(UserPlatSkuDistributeRate::getGoodsId));
+			//sku比例更变记录
+			recordSkuRateDelChange(userDistribute, delSkuRateList, userDistributeRateChangeRecords);
+
 			userPlatSkuDistributeRateMapper.delete(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
 					.notIn(UserPlatSkuDistributeRate::getSkuId, skuIds)
 					.eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId()));
@@ -289,20 +309,35 @@ public class DistributeServiceImpl implements DistributeService {
 					checkDistributorAndBusinessRate(skuRate.getRate(), goodsDon.getId(), goodsDon.getTitle());
 				}
 				if (skuRate.getId() != null) {
+					UserPlatSkuDistributeRate dbUserPlatSkuDistributeRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class).eq(UserPlatSkuDistributeRate::getId, skuRate.getId()).last("limit 1"));
 					userPlatSkuDistributeRateMapper.updateById(skuRate);
+					if (dbUserPlatSkuDistributeRate != null && dbUserPlatSkuDistributeRate.getRate() != skuRate.getRate()) {
+						recordSkuRateChange(userDistribute, goodsDon.getTitle(), skuRate, userDistributeRateChangeRecords);
+					}
 					continue;
 				}
 				try {
 					skuRate.setDistributeId(userDistribute.getId());
 					userPlatSkuDistributeRateMapper.insert(skuRate);
+					//不存在 变更
+					recordNoExistsSkuRateChange(skuRate, userDistribute, goodsDon.getTitle(), userDistributeRateChangeRecords);
 				} catch (DuplicateKeyException e) {
 				}
 			}
 		} else {
+			//sku比例更变记录
+			List<UserPlatSkuDistributeRate> delSkuRateList = userPlatSkuDistributeRateMapper.selectList(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class).eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId()).orderByAsc(UserPlatSkuDistributeRate::getGoodsId));
+			recordSkuRateDelChange(userDistribute, delSkuRateList, userDistributeRateChangeRecords);
+
 			userPlatSkuDistributeRateMapper.delete(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
 					.eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId()));
 		}
 		handlerDistributeOtherFunc(userDistribute, userDistributeReq);
+
+		if (CollUtil.isNotEmpty(userDistributeRateChangeRecords)) {
+			userDistributeRateChangeRecords.sort(Comparator.comparing(UserDistributeRateChangeRecord::getGoodsId));
+			userDistributeRateChangeRecordService.saveBatch(userDistributeRateChangeRecords);
+		}
 	}
 
 	/**
@@ -682,4 +717,75 @@ public class DistributeServiceImpl implements DistributeService {
 			couponDistributePopularizeMapper.insert(newPopularizeCode);
 		}
 	}
+
+	private void recordGoodsRateChange(UserDistribute userDistribute, String title, UserPlatDistributeRate rate, List<UserDistributeRateChangeRecord> userDistributeRateChangeRecords) {
+		//记录更变记录
+		UserDistributeRateChangeRecord userDistributeRateChangeRecord = new UserDistributeRateChangeRecord();
+		userDistributeRateChangeRecord.setDistributeId(userDistribute.getId());
+		userDistributeRateChangeRecord.setUserId(userDistribute.getUserId());
+		userDistributeRateChangeRecord.setGoodsId(rate.getGoodsId());
+		String changeInfo = String.format("%s全规格分销比例变为%s%%", title, rate.getRate());
+		userDistributeRateChangeRecord.setChangeInfo(changeInfo);
+		userDistributeRateChangeRecords.add(userDistributeRateChangeRecord);
+	}
+
+
+	private void recordSkuRateChange(UserDistribute userDistribute, String title, UserPlatSkuDistributeRate skuRate, List<UserDistributeRateChangeRecord> userDistributeRateChangeRecords) {
+		//记录更变记录
+		UserDistributeRateChangeRecord userDistributeRateChangeRecord = new UserDistributeRateChangeRecord();
+		userDistributeRateChangeRecord.setDistributeId(userDistribute.getId());
+		userDistributeRateChangeRecord.setUserId(userDistribute.getUserId());
+		userDistributeRateChangeRecord.setGoodsId(skuRate.getGoodsId());
+		userDistributeRateChangeRecord.setSkuId(skuRate.getSkuId());
+		GoodsDonSku sku = skuMapper.selectById(skuRate.getSkuId());
+		String changeInfo = String.format("%s%s规格分销比例变为%s%%", title, sku.getSpecVal(), skuRate.getRate());
+		userDistributeRateChangeRecord.setChangeInfo(changeInfo);
+		userDistributeRateChangeRecords.add(userDistributeRateChangeRecord);
+	}
+
+	private void recordSkuRateDelChange(UserDistribute userDistribute, List<UserPlatSkuDistributeRate> delSkuRateList, List<UserDistributeRateChangeRecord> userDistributeRateChangeRecords) {
+		for (UserPlatSkuDistributeRate userPlatSkuDistributeRate : delSkuRateList) {
+			//记录更变记录
+			UserDistributeRateChangeRecord userDistributeRateChangeRecord = new UserDistributeRateChangeRecord();
+			userDistributeRateChangeRecord.setDistributeId(userDistribute.getId());
+			userDistributeRateChangeRecord.setUserId(userDistribute.getUserId());
+			userDistributeRateChangeRecord.setGoodsId(userPlatSkuDistributeRate.getGoodsId());
+			userDistributeRateChangeRecord.setSkuId(userPlatSkuDistributeRate.getSkuId());
+			GoodsDon goodsDon = goodsDonMapper.selectById(userPlatSkuDistributeRate.getGoodsId());
+			GoodsDonSku sku = skuMapper.selectById(userPlatSkuDistributeRate.getSkuId());
+			UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class).eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId()).eq(UserPlatDistributeRate::getGoodsId, userPlatSkuDistributeRate.getGoodsId()).last("limit 1"));
+			String changeInfo = String.format("%s%s规格分销比例变为%s%%", goodsDon.getTitle(), sku.getSpecVal(), userPlatDistributeRate.getRate());
+			userDistributeRateChangeRecord.setChangeInfo(changeInfo);
+			userDistributeRateChangeRecords.add(userDistributeRateChangeRecord);
+		}
+	}
+
+	private void recordGoodsRateSaveChange(UserDistribute userDistribute, Long goodsId, Integer goodsRate, String title, List<UserDistributeRateChangeRecord> userDistributeRateChangeRecords) {
+		BusinessDistributeDefaultRateConfig businessDistributeDefaultRateConfig = businessDistributeDefaultRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultRateConfig.class).eq(BusinessDistributeDefaultRateConfig::getGoodsId, goodsId).last("limit 1"));
+		if (businessDistributeDefaultRateConfig == null || businessDistributeDefaultRateConfig.getRate() != goodsRate) {
+			//记录更变记录
+			UserDistributeRateChangeRecord userDistributeRateChangeRecord = new UserDistributeRateChangeRecord();
+			userDistributeRateChangeRecord.setDistributeId(userDistribute.getId());
+			userDistributeRateChangeRecord.setUserId(userDistribute.getUserId());
+			userDistributeRateChangeRecord.setGoodsId(goodsId);
+			String changeInfo = String.format("%s全规格分销比例变为%s%%", title, goodsRate);
+			userDistributeRateChangeRecord.setChangeInfo(changeInfo);
+			userDistributeRateChangeRecords.add(userDistributeRateChangeRecord);
+		}
+	}
+
+	private void recordNoExistsSkuRateChange(UserPlatSkuDistributeRate skuRate, UserDistribute userDistribute, String title, List<UserDistributeRateChangeRecord> userDistributeRateChangeRecords) {
+		BusinessDistributeDefaultSkuRateConfig rateConfig = businessDistributeDefaultSkuRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultSkuRateConfig.class).eq(BusinessDistributeDefaultSkuRateConfig::getSkuId, skuRate.getSkuId()).last("limit 1"));
+		if (rateConfig == null || rateConfig.getRate() != skuRate.getRate()) {
+			if (rateConfig == null) {
+				//查看平台默认比例
+				UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class).eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId()).eq(UserPlatDistributeRate::getGoodsId, skuRate.getGoodsId()).last("limit 1"));
+				//相同不记录
+				if (userPlatDistributeRate != null && userPlatDistributeRate.getRate() == skuRate.getRate()) {
+					return;
+				}
+			}
+			recordSkuRateChange(userDistribute, title, skuRate, userDistributeRateChangeRecords);
+		}
+	}
 }

+ 70 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/impl/UserDistributeRateChangeRecordServiceImpl.java

@@ -0,0 +1,70 @@
+package com.cyksj.service.distribute.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.mapper.GoodsDonMapper;
+import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.mapper.UserDistributeRateChangeRecordMapper;
+import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
+import com.cyksj.model.entity.*;
+import com.cyksj.service.distribute.UserDistributeRateChangeRecordService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: UserDistributeRateChangeRecordServiceImpl
+ * 创建者: JavaZou
+ * 创建时间:2025/10/29 16:16
+ */
+@Service
+@RequiredArgsConstructor
+public class UserDistributeRateChangeRecordServiceImpl extends ServiceImpl<UserDistributeRateChangeRecordMapper, UserDistributeRateChangeRecord> implements UserDistributeRateChangeRecordService {
+	private final UserDistributeMapper userDistributeMapper;
+
+	private final UserDistributeRateChangeRecordMapper userDistributeRateChangeRecordMapper;
+
+	private final GoodsDonMapper goodsDonMapper;
+
+	private final GoodsDonSkuMapper skuMapper;
+
+	@Override
+	public void recordDefaultGoodsRate(Long goodsId, Integer rate) {
+		List<UserDistribute> userDistributeList = userDistributeMapper.selectNoSetGoodsRateDistirbutors(goodsId);
+		if (userDistributeList.isEmpty()) {
+			return;
+		}
+		GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
+		String changeInfo = String.format("%s全规格分销比例变为%s%%", goodsDon.getTitle(), rate);
+		userDistributeRateChangeRecordMapper.batchInsertGoodsRateChangeRecord(userDistributeList, goodsId, null, changeInfo, rate);
+	}
+
+	@Override
+	public void recordDefaultGoodsSkuRate(Long goodsId, Long skuId, Integer rate) {
+		List<UserDistribute> userDistributeList = userDistributeMapper.selectNoSetGoodsSkuRateDistirbutors(skuId);
+		if (userDistributeList.isEmpty()) {
+			return;
+		}
+		GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
+		GoodsDonSku sku = skuMapper.selectById(skuId);
+		String changeInfo = String.format("%s%s规格分销比例变为%s%%", goodsDon.getTitle(), sku.getSpecVal(), rate);
+		userDistributeRateChangeRecordMapper.batchInsertGoodsRateChangeRecord(userDistributeList, goodsId, skuId, changeInfo, rate);
+	}
+
+	@Override
+	public void recordDefaultGoodsSkuDelRate(List<BusinessDistributeDefaultSkuRateConfig> delLists) {
+		for (BusinessDistributeDefaultSkuRateConfig skuRateConfig : delLists) {
+			Long skuId = skuRateConfig.getSkuId();
+			List<UserDistribute> userDistributeList = userDistributeMapper.selectNoSetGoodsSkuRateDistirbutors(skuId);
+			if (userDistributeList.isEmpty()) {
+				continue;
+			}
+			Long goodsId = skuRateConfig.getGoodsId();
+			GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
+			GoodsDonSku sku = skuMapper.selectById(skuId);
+			String changeInfo = String.format("%s%s规格分销比例变为", goodsDon.getTitle(), sku.getSpecVal());
+			userDistributeRateChangeRecordMapper.batchInsertGoodsRateChangeNoSetSkuRecord(userDistributeList, goodsId, skuId, changeInfo);
+		}
+	}
+}

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

@@ -60,4 +60,6 @@ public interface CmsAccountService extends IService<Account> {
 	String getAccountEmailCode(Long accountId) throws Exception;
 
 	void batchDeleteAccountTrips(DelAccountTripsReq delAccountTripsReq, long adminId) throws Exception;
+
+	List<String> batchDelAccountTripsByGoodsAccount(DelAccountTripsReq delAccountTripsReq, long adminId) throws Exception;
 }

+ 47 - 0
netflix-service/src/main/java/com/cyksj/service/mange/account/CmsAccountServiceImpl.java

@@ -558,4 +558,51 @@ public class CmsAccountServiceImpl extends ServiceImpl<AccountMapper, Account> i
 			}
 		}
 	}
+
+	@Override
+	public List<String> batchDelAccountTripsByGoodsAccount(DelAccountTripsReq delAccountTripsReq, long adminId) throws Exception {
+		CmsUser cmsUser = cmsUserMapper.selectById(adminId);
+		Integer goodsId = delAccountTripsReq.getGoodsId();
+		List<String> accounts = delAccountTripsReq.getAccounts();
+
+		GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
+		Assert.notNull(goodsDon,"平台不存在");
+
+		List<String> fails = new ArrayList<>();
+
+		if (CollUtil.isNotEmpty(accounts)) {
+			DelAccountRecord delAccountRecord = null;
+			for (String account : accounts) {
+				Account dbAccount = accountMapper.selectOne(Wrappers.lambdaQuery(Account.class).eq(Account::getAccount, account.trim()).eq(Account::getGoodsId, goodsId).last("limit 1"));
+				if (dbAccount == null) {
+					fails.add(account);
+					continue;
+				}
+				GroupsTrips groupsTrips = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
+						.eq(GroupsTrips::getAccountId, dbAccount.getId())
+						.last("limit 1"));
+				if (groupsTrips != null) {
+					Integer selectCount = relationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class)
+							.eq(GroupsRelation::getGroupsId, groupsTrips.getId())
+							.ne(GroupsRelation::getUserId, 0));
+					//车队上存在用户不删除 下个循环
+					if (selectCount > 0) {
+						fails.add(account);
+						continue;
+					}
+					groupsMapper.deleteById(groupsTrips.getId());
+					relationMapper.delete(Wrappers.lambdaQuery(GroupsRelation.class)
+							.eq(GroupsRelation::getGroupsId, groupsTrips.getId()));
+				}
+				delAccountRecord = new DelAccountRecord();
+				if (cmsUser != null) {
+					delAccountRecord.setOperator(cmsUser.getNickname());
+				}
+				delAccountRecord.setAccountInfo(Jsons.toJson(account));
+				delAccountRecordMapper.insert(delAccountRecord);
+				accountMapper.deleteById(dbAccount.getId());
+			}
+		}
+		return fails;
+	}
 }

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

@@ -6,10 +6,7 @@ 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.*;
 import com.cyksj.mapper.shop.YhShopGoodsRateMapper;
 import com.cyksj.mapper.shop.YhShopGoodsSkuMapper;
 import com.cyksj.mapper.shop.YhShopSkuSysTakeDownRecordMapper;
@@ -48,6 +45,8 @@ public class CmsGoodsDonSkuServiceImpl extends ServiceImpl<GoodsDonSkuMapper,Goo
 
 	private final UpgradePackageMapper upgradePackageMapper;
 
+	private final GoodsDonMapper goodsDonMapper;
+
 	@Override
 	public void handleDiscountPurchaseGoods(GoodsDonSku sku, List<GoodsDiscountPlusPurchaseRelation> discountPlusPurchaseGoods) {
 		Long skuId = sku.getId();
@@ -219,7 +218,8 @@ public class CmsGoodsDonSkuServiceImpl extends ServiceImpl<GoodsDonSkuMapper,Goo
 			throw BusinessRuntimeException.getInstance("优惠加购规格不存在");
 		}
 		if (!sku.getStatus()) {
-			throw BusinessRuntimeException.getInstance("{0}规格未上架", sku.getSpecVal());
+			GoodsDon goodsDon = goodsDonMapper.selectById(sku.getGoodsId());
+			throw BusinessRuntimeException.getInstance("{0}优惠加购规格未上架", goodsDon.getTitle() + sku.getSpecVal());
 		}
 		if (disPrice == null || disPrice.compareTo(BigDecimal.ZERO) <= 0) {
 			throw BusinessRuntimeException.getInstance("请输入正确的优惠加购价格");

+ 32 - 0
netflix-service/src/main/java/com/cyksj/service/mange/group/CmsGroupServiceImpl.java

@@ -15,6 +15,7 @@ import com.cyksj.dto.RedisKey;
 import com.cyksj.mapper.*;
 import com.cyksj.mapper.manage.GroupsTripsAccountReplaceRecordMapper;
 import com.cyksj.mapper.manage.cms.CmsUserMapper;
+import com.cyksj.mapper.manage.cms.SysLogMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.AccountView;
 import com.cyksj.model.manage.views.GroupsRelationView;
@@ -99,6 +100,8 @@ public class CmsGroupServiceImpl extends ServiceImpl<GroupsMapper,GroupsTrips> i
 
     private final GptUserRechargeRecordService gptUserRechargeRecordService;
 
+    private final SysLogMapper sysLogMapper;
+
     private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
 
 
@@ -347,6 +350,22 @@ public class CmsGroupServiceImpl extends ServiceImpl<GroupsMapper,GroupsTrips> i
         if (goodsDon.getId() == Constant.GPT_PLUS_GID && sku.getNum() == 1) {
             setRelationRechargeRemainNumInfo(groupsTrips.getId(), sku.getMonths(), account.getAccount(), account.getPassword());
         }
+
+        //坐满是否下架车队
+        if (sku.getIsDown()) {
+            try {
+                if (groupsTrips.getStatus() == GroupsTrips.Status.validity) {
+                    Integer selectCount = relationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsTrips.getId()).eq(GroupsRelation::getStatus, GroupsTrips.Status.validity));
+                    if (selectCount == sku.getNum()) {
+                        groupsTrips.setStatus(GroupsTrips.Status.down);
+                        groupsMapper.updateById(groupsTrips);
+                        recordSysOpLog(groupsTrips.getId());
+                    }
+                }
+            } catch (Exception e) {
+
+            }
+        }
     }
 
     @Override
@@ -631,4 +650,17 @@ public class CmsGroupServiceImpl extends ServiceImpl<GroupsMapper,GroupsTrips> i
             }
         }
     }
+
+    private void recordSysOpLog(Long groupsId) {
+        try {
+            //添加操作记录
+            SysLog sysLog = new SysLog();
+            sysLog.setModule("过期账号/上下架过期车队");
+            sysLog.setOperateParams(groupsId.toString());
+            sysLog.setOperator("坐满系统下架");
+            sysLogMapper.insert(sysLog);
+        } catch (Exception e) {
+
+        }
+    }
 }

+ 7 - 3
netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java

@@ -749,6 +749,10 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         if (relation.getRechargeStatus() != null) {
             throw BusinessRuntimeException.getInstance("代充账号车票无法更换车票");
         }
+        //冻结中 不允许更换车票
+        if (relation.getIsFrozen()) {
+            throw BusinessRuntimeException.getInstance("用户车票冻结中,无法更换车票");
+        }
         String key = RedisService.key.NETFLIX_CHANGE_TICKET_KEY.getName() + relationId;
         if (!redisService.setNx(key, relationId, RedisService.key.NETFLIX_CHANGE_TICKET_KEY.getTimeout())) {
             throw BusinessRuntimeException.getInstance("正在更换车票中..");
@@ -1056,9 +1060,9 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             } else {
                 endTime = DateUtil.offsetMonth(orderDon.getCreatedTime(), months * num);
             }
-            if (now.isAfter(endTime)) {
-                throw BusinessRuntimeException.getInstance("该订单车票已过期");
-            }
+//            if (now.isAfter(endTime)) {
+//                throw BusinessRuntimeException.getInstance("该订单车票已过期");
+//            }
             if (orderDon.getOrderType() == 1) {
                 //是否有其他付款订单是否过期
                 OrderDon otherOrder = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)

+ 3 - 2
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderCommonServiceImpl.java

@@ -62,7 +62,7 @@ public class OrderCommonServiceImpl implements OrderCommonService {
 					.in(GroupsRelation::getUserId, userIdList)
 					.eq(GroupsRelation::getId, relationId)
 					.in(GroupsRelation::getStatus, List.of(GroupsRelation.Status.validity, GroupsRelation.Status.outside)));
-			Date oriExpiryTime = relation.getExpiryTime();
+			Date oriExpiryTime = null;
 			//车票变更之后
 			if (relation == null || orderDon.getIsChangeTicket()) {
 				UserRenewChangeTicketRecord record = userRenewChangeTicketRecordMapper.selectOne(Wrappers.lambdaQuery(UserRenewChangeTicketRecord.class)
@@ -75,6 +75,7 @@ public class OrderCommonServiceImpl implements OrderCommonService {
 				}
 			}
 			if (relation != null) {
+				oriExpiryTime = relation.getExpiryTime();
 				Boolean isFlag = true;
 				Date expiryTime = relation.getExpiryTime();
 				OrderDon otherOrder = null;
@@ -124,7 +125,7 @@ public class OrderCommonServiceImpl implements OrderCommonService {
 					}
 				}
 				//普通订单 退款直接清除订单
-				if (orderDon.getOrderType() == 1) {
+				if (orderDon.getOrderType() == 1 && relationIds.size() == 1) {
 					isFlag = true;
 				}
 				if (isFlag) {

+ 247 - 184
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -53,6 +53,7 @@ import com.cyksj.mapper.corp.CorpUserMapper;
 import com.cyksj.mapper.corp.CorpUserTagMapper;
 import com.cyksj.mapper.fission.UserMirrorFissionInvertRecordMapper;
 import com.cyksj.mapper.fission.UserMirrorFissionReceiveRecordMapper;
+import com.cyksj.mapper.manage.cms.SysLogMapper;
 import com.cyksj.mapper.manage.coupon.CouponDistributePopularizeMapper;
 import com.cyksj.mapper.manage.coupon.CouponMapper;
 import com.cyksj.mapper.manage.coupon.CouponSkuMapper;
@@ -409,6 +410,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final ClaudeCodeDeductOrderRelateMapper claudeCodeDeductOrderRelateMapper;
 
+	private final SysLogMapper sysLogMapper;
+
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
 
 	@Transactional(rollbackFor = Throwable.class)
@@ -694,7 +697,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		}
 		if (sku != null) {
 			//扣除使用优惠券、余额的订单金额
-			deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon, payRequest.getGcCash(), payRequest.getGcpIds(), payRequest.getIsAcReduce(), subsidyId, sku, payRequest.getGalaxyCoin());
+			deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon, payRequest.getGcCash(), payRequest.getGcpIds(), payRequest.getIsAcReduce(), subsidyId, sku, payRequest.getGalaxyCoin(), null);
 		}
 
 		if (isSpecificPrice && (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0 || orderDon.getMoney().compareTo(specificPrice) != 0)) {
@@ -1267,6 +1270,20 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		if (tripGoodsDonSkuView.getIsMirror() != sku.getIsMirror()) {
 			throw BusinessRuntimeException.getInstance("续费规格错误");
 		}
+		//天卡不支持续费其他规格
+		if (sku.getGoodsId() == Constant.NETFLIX_GID) {
+			if (tripGoodsDonSkuView.getDays() != null && tripGoodsDonSkuView.getSkuId().intValue() != sku.getId().intValue()) {
+				throw BusinessRuntimeException.getInstance("该规格不支持续费");
+			}
+		}
+
+		//cluade code
+		if (goodsDon.getId() == Constant.CLAUDE_CODE_GOODS_ID) {
+			//天卡规格不可续费
+			if (renewSkuId.intValue() == Constant.DISTRIBUTE_CLAUDE_CODE_TRIAL_SKU_ID.intValue()) {
+				throw BusinessRuntimeException.getInstance("不可续费该规格");
+			}
+		}
 
 		if (GroupsTrips.Status.waiting.equals(groupsTrips.getStatus())) {
 			if (!noChekGoodsTemp.contains(goodsDon.getTitle())) {
@@ -1315,7 +1332,17 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		orderDon.setOrderNo(donNo);
 		orderDon.setOpenId(payOpenId);
 		orderDon.setYhsId(yhsId);
-		orderDon.setMoney(sku.getPrice().multiply(BigDecimal.valueOf(payRequest.getNum())));
+		BigDecimal skuPrice = sku.getPrice();
+		BigDecimal renewPrice = null;
+		//使用续费价格
+		if (payRequest.getIsRenewPrice()) {
+			renewPrice = sku.getRenewPrice();
+			//续费价格存在 续费时直接使用
+			if (renewPrice != null && renewPrice.compareTo(BigDecimal.ZERO) > 0) {
+				skuPrice = renewPrice;
+			}
+		}
+		orderDon.setMoney(skuPrice.multiply(BigDecimal.valueOf(payRequest.getNum())));
 		orderDon.setSkuId(renewSkuId);
 		orderDon.setRelationId(relation.getId());
 		//续费订单
@@ -1352,7 +1379,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			orderDon.setMoney(sku.getPrice().multiply(discount));
 		}
 		//扣除使用优惠券、余额的订单金额
-		deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon, payRequest.getGcCash(), payRequest.getGcpIds(), false, null, sku, payRequest.getGalaxyCoin());
+		deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon, payRequest.getGcCash(), payRequest.getGcpIds(), false, null, sku, payRequest.getGalaxyCoin(), renewPrice);
 		this.saveOrUpdate(orderDon);
 
 		Long orderId = orderDon.getId();
@@ -2682,168 +2709,170 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 	/**
 	 * 使用优惠营销 订单金额抵扣
 	 */
-	public void deductOrderMoney(OrderDon orderDon, CouponUser couponUser, BigDecimal balance, User user, BigDecimal skuMoney, GoodsDon goodsDon, BigDecimal gcCash, List<Long> gcpIds, Boolean isAcReduce, Long subsidyId, GoodsDonSku sku, BigDecimal galaxyCoin) throws Exception {
-		Integer goodsType = goodsDon.getType();
-		if (gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0 && couponUser != null && (balance != null && balance.compareTo(BigDecimal.ZERO) > 0)) {
-			throw BusinessRuntimeException.getInstance("现金卡不能与其他优惠叠加使用");
-		}
-		BigDecimal first_money = orderDon.getMoney();
-		//礼品卡现金支付 不参与其他优惠
-		if (subsidyId == null && gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0) {
-			List<Long> userIdList = userBindRelationService.getRelationUserIdList(user.getId(), user);
-			if (CollUtil.isEmpty(gcpIds)) {
-				throw BusinessRuntimeException.getInstance("礼品卡现金支付参数异常");
-			}
-			BigDecimal money = orderDon.getMoney();
-			if (gcCash.compareTo(money) > 0) {
-				gcCash = money;
-			}
-			List<GiftCardUserRecord> availableGiftCards = giftCardUserRecordService.list(Wrappers.lambdaQuery(GiftCardUserRecord.class)
-					.in(GiftCardUserRecord::getToUserId, userIdList)
-					.in(GiftCardUserRecord::getId, gcpIds)
-					.eq(GiftCardUserRecord::getIsPay, true)
-					.eq(GiftCardUserRecord::getGcType, 1)
-					.gt(GiftCardUserRecord::getRemainCash, 0));
-			if (availableGiftCards.size() != gcpIds.size()) {
-				throw BusinessRuntimeException.getInstance("礼品卡使用异常,请刷新页面重试");
-			}
-			//需要扣除的礼品卡现金
-			BigDecimal deductCash = gcCash;
-			List<GiftCardOrderUseRecord> gcUseRecords = new ArrayList<>();
-			for (GiftCardUserRecord giftCard : availableGiftCards) {
-				if (deductCash.compareTo(BigDecimal.ZERO) <= 0) {
-					break;
-				}
-				BigDecimal remainCash = giftCard.getRemainCash();
-				//扣完
-				if (remainCash.compareTo(deductCash) == 0) {
-					deductGiftCardCash(user.getId(), giftCard.getId(), deductCash, remainCash, gcUseRecords, true);
-					deductCash = BigDecimal.ZERO;
-				} else if (remainCash.compareTo(deductCash) < 0) {
-					deductGiftCardCash(user.getId(), giftCard.getId(), remainCash, remainCash, gcUseRecords, true);
-					deductCash = deductCash.subtract(remainCash);
-				} else if (remainCash.compareTo(deductCash) > 0) {
-					deductGiftCardCash(user.getId(), giftCard.getId(), deductCash, remainCash, gcUseRecords, false);
-					deductCash = BigDecimal.ZERO;
-				}
-			}
-			orderDon.setMoney(orderDon.getMoney().subtract(gcCash));
-			orderDon.setGcCash(gcCash);
-			if (!gcUseRecords.isEmpty()) {
-				orderDon.setGcUseRecords(gcUseRecords);
-			}
-			return;
-		}
-		//针对设备 满减活动优惠 不支持使用优惠券等优惠
-		if (isAcReduce != null && isAcReduce && orderDon.getGoodsId() == 15) {
-			epOrderDonActivityReduce(orderDon);
-			//存在余额
-			deductBalancePayOrderMoney(orderDon, balance, user);
-			return;
-		}
-		//存在优惠券
-		if (couponUser != null && subsidyId == null) {
-			Long couponId = couponUser.getCouponId();
-			Coupon coupon = couponMapper.getCouponById(couponId);
-			BigDecimal couponMoney = null;
-			BigDecimal payMoney = orderDon.getMoney();
-			BigDecimal needDeductMoney = payMoney;
-			if (orderDon.getOriMoney() == null) {
-				orderDon.setOriMoney(payMoney);
-			}
-			if (orderDon.getIsDp() != null && orderDon.getIsDp()) {
-				needDeductMoney = needDeductMoney.subtract(orderDon.getDpMoney());
-			}
-			if (coupon.getType() == Coupon.Type.discount) {
-				couponMoney = needDeductMoney.multiply(BigDecimal.valueOf(1).subtract(coupon.getDiscount()));
-				//需支付金额
-				orderDon.setMoney(payMoney.subtract(couponMoney));
-
-				orderDon.setOriMoney(orderDon.getOriMoney().multiply(coupon.getDiscount()));
-				//记录折扣 用于分销
-				couponUser.setDiscount(coupon.getDiscount());
-				couponUserMapper.updateById(couponUser);
-			} else if (coupon.getType() == Coupon.Type.reduce) {
-				if (goodsType == 2) {
-					if (skuMoney.compareTo(coupon.getReduceCondition()) < 0) {
-						throw BusinessRuntimeException.getInstance(String.format("满%s可用", coupon.getReduceCondition().divide(BigDecimal.valueOf(100))));
+	public void deductOrderMoney(OrderDon orderDon, CouponUser couponUser, BigDecimal balance, User user, BigDecimal skuMoney, GoodsDon goodsDon, BigDecimal gcCash, List<Long> gcpIds, Boolean isAcReduce, Long subsidyId, GoodsDonSku sku, BigDecimal galaxyCoin, BigDecimal renewPrice) throws Exception {
+		//续费规格价格 不允许其他优惠
+		if (renewPrice == null || renewPrice.compareTo(BigDecimal.ZERO) <= 0) {
+			Integer goodsType = goodsDon.getType();
+			if (gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0 && couponUser != null && (balance != null && balance.compareTo(BigDecimal.ZERO) > 0)) {
+				throw BusinessRuntimeException.getInstance("现金卡不能与其他优惠叠加使用");
+			}
+			BigDecimal first_money = orderDon.getMoney();
+			//礼品卡现金支付 不参与其他优惠
+			if (subsidyId == null && gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0) {
+				List<Long> userIdList = userBindRelationService.getRelationUserIdList(user.getId(), user);
+				if (CollUtil.isEmpty(gcpIds)) {
+					throw BusinessRuntimeException.getInstance("礼品卡现金支付参数异常");
+				}
+				BigDecimal money = orderDon.getMoney();
+				if (gcCash.compareTo(money) > 0) {
+					gcCash = money;
+				}
+				List<GiftCardUserRecord> availableGiftCards = giftCardUserRecordService.list(Wrappers.lambdaQuery(GiftCardUserRecord.class)
+						.in(GiftCardUserRecord::getToUserId, userIdList)
+						.in(GiftCardUserRecord::getId, gcpIds)
+						.eq(GiftCardUserRecord::getIsPay, true)
+						.eq(GiftCardUserRecord::getGcType, 1)
+						.gt(GiftCardUserRecord::getRemainCash, 0));
+				if (availableGiftCards.size() != gcpIds.size()) {
+					throw BusinessRuntimeException.getInstance("礼品卡使用异常,请刷新页面重试");
+				}
+				//需要扣除的礼品卡现金
+				BigDecimal deductCash = gcCash;
+				List<GiftCardOrderUseRecord> gcUseRecords = new ArrayList<>();
+				for (GiftCardUserRecord giftCard : availableGiftCards) {
+					if (deductCash.compareTo(BigDecimal.ZERO) <= 0) {
+						break;
+					}
+					BigDecimal remainCash = giftCard.getRemainCash();
+					//扣完
+					if (remainCash.compareTo(deductCash) == 0) {
+						deductGiftCardCash(user.getId(), giftCard.getId(), deductCash, remainCash, gcUseRecords, true);
+						deductCash = BigDecimal.ZERO;
+					} else if (remainCash.compareTo(deductCash) < 0) {
+						deductGiftCardCash(user.getId(), giftCard.getId(), remainCash, remainCash, gcUseRecords, true);
+						deductCash = deductCash.subtract(remainCash);
+					} else if (remainCash.compareTo(deductCash) > 0) {
+						deductGiftCardCash(user.getId(), giftCard.getId(), deductCash, remainCash, gcUseRecords, false);
+						deductCash = BigDecimal.ZERO;
 					}
 				}
-				BigDecimal subtractMoney = payMoney.subtract(coupon.getReduceMoney());
-				orderDon.setMoney(subtractMoney);
-				couponMoney = coupon.getReduceMoney();
-
-				orderDon.setOriMoney(orderDon.getOriMoney().subtract(coupon.getReduceMoney()));
+				orderDon.setMoney(orderDon.getMoney().subtract(gcCash));
+				orderDon.setGcCash(gcCash);
+				if (!gcUseRecords.isEmpty()) {
+					orderDon.setGcUseRecords(gcUseRecords);
+				}
+				return;
 			}
-			if (couponMoney != null && couponMoney.compareTo(first_money) >= 0) {
-				throw BusinessRuntimeException.getInstance("支付金额不能小于优惠金额");
+			//针对设备 满减活动优惠 不支持使用优惠券等优惠
+			if (isAcReduce != null && isAcReduce && orderDon.getGoodsId() == 15) {
+				epOrderDonActivityReduce(orderDon);
+				//存在余额
+				deductBalancePayOrderMoney(orderDon, balance, user);
+				return;
 			}
-			orderDon.setCouponMoney(couponMoney);
-			orderDon.setCouponUserId(couponUser.getId());
-			orderDon.setCouponId(couponUser.getCouponId());
-		}
-		//特殊渠道推广优惠. 360
-		if (subsidyId == null && orderDon.getPopularizeId() != null && orderDon.getPopularizeId() != 0L) {
-			String name = channelPopularizeMapper.selectChannelByPid(orderDon.getPopularizeId());
-			if (StrUtil.isNotBlank(name)) {
-				//使用了优惠券 不再使用360渠道 折扣
-				if (couponUser == null && goodsType == 1) {
-					if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0)) || name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(1))) {
-						String key;
-						if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0))) {
-							//百度渠道 专门优惠链接
-							key = Constant.CHANNEL_BAIDU_DISCOUNT_KEY;
-						} else {
-							//抖音
-							key = Constant.CHANNEL_DY_DISCOUNT_KEY;
+			//存在优惠券
+			if (couponUser != null && subsidyId == null) {
+				Long couponId = couponUser.getCouponId();
+				Coupon coupon = couponMapper.getCouponById(couponId);
+				BigDecimal couponMoney = null;
+				BigDecimal payMoney = orderDon.getMoney();
+				BigDecimal needDeductMoney = payMoney;
+				if (orderDon.getOriMoney() == null) {
+					orderDon.setOriMoney(payMoney);
+				}
+				if (orderDon.getIsDp() != null && orderDon.getIsDp()) {
+					needDeductMoney = needDeductMoney.subtract(orderDon.getDpMoney());
+				}
+				if (coupon.getType() == Coupon.Type.discount) {
+					couponMoney = needDeductMoney.multiply(BigDecimal.valueOf(1).subtract(coupon.getDiscount()));
+					//需支付金额
+					orderDon.setMoney(payMoney.subtract(couponMoney));
+
+					orderDon.setOriMoney(orderDon.getOriMoney().multiply(coupon.getDiscount()));
+					//记录折扣 用于分销
+					couponUser.setDiscount(coupon.getDiscount());
+					couponUserMapper.updateById(couponUser);
+				} else if (coupon.getType() == Coupon.Type.reduce) {
+					if (goodsType == 2) {
+						if (skuMoney.compareTo(coupon.getReduceCondition()) < 0) {
+							throw BusinessRuntimeException.getInstance(String.format("满%s可用", coupon.getReduceCondition().divide(BigDecimal.valueOf(100))));
 						}
-						SysConfig channelNoSignConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
-								.eq(SysConfig::getSysKey, key).last("limit 1"));
-						if (channelNoSignConfig != null) {
-							String sysValue = channelNoSignConfig.getSysValue();
-							if (StrUtil.isNotBlank(sysValue)) {
-								try {
-									ChannelBaiDuDiscountDto baiDuDiscountDto = Jsons.parseObject(sysValue, ChannelBaiDuDiscountDto.class);
-									List<Long> baiduPopularizeIds = baiDuDiscountDto.getPopularizeIds();
-									BigDecimal discount = baiDuDiscountDto.getDiscount();
-									if (CollUtil.isNotEmpty(baiduPopularizeIds) && discount != null && discount.compareTo(BigDecimal.ZERO) > 0) {
-										if (baiduPopularizeIds.contains(orderDon.getPopularizeId())) {
-											BigDecimal discountMoney = orderDon.getMoney().multiply(discount);
-											orderDon.setMoney(discountMoney);
+					}
+					BigDecimal subtractMoney = payMoney.subtract(coupon.getReduceMoney());
+					orderDon.setMoney(subtractMoney);
+					couponMoney = coupon.getReduceMoney();
+
+					orderDon.setOriMoney(orderDon.getOriMoney().subtract(coupon.getReduceMoney()));
+				}
+				if (couponMoney != null && couponMoney.compareTo(first_money) >= 0) {
+					throw BusinessRuntimeException.getInstance("支付金额不能小于优惠金额");
+				}
+				orderDon.setCouponMoney(couponMoney);
+				orderDon.setCouponUserId(couponUser.getId());
+				orderDon.setCouponId(couponUser.getCouponId());
+			}
+			//特殊渠道推广优惠. 360
+			if (subsidyId == null && orderDon.getPopularizeId() != null && orderDon.getPopularizeId() != 0L) {
+				String name = channelPopularizeMapper.selectChannelByPid(orderDon.getPopularizeId());
+				if (StrUtil.isNotBlank(name)) {
+					//使用了优惠券 不再使用360渠道 折扣
+					if (couponUser == null && goodsType == 1) {
+						if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0)) || name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(1))) {
+							String key;
+							if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0))) {
+								//百度渠道 专门优惠链接
+								key = Constant.CHANNEL_BAIDU_DISCOUNT_KEY;
+							} else {
+								//抖音
+								key = Constant.CHANNEL_DY_DISCOUNT_KEY;
+							}
+							SysConfig channelNoSignConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
+									.eq(SysConfig::getSysKey, key).last("limit 1"));
+							if (channelNoSignConfig != null) {
+								String sysValue = channelNoSignConfig.getSysValue();
+								if (StrUtil.isNotBlank(sysValue)) {
+									try {
+										ChannelBaiDuDiscountDto baiDuDiscountDto = Jsons.parseObject(sysValue, ChannelBaiDuDiscountDto.class);
+										List<Long> baiduPopularizeIds = baiDuDiscountDto.getPopularizeIds();
+										BigDecimal discount = baiDuDiscountDto.getDiscount();
+										if (CollUtil.isNotEmpty(baiduPopularizeIds) && discount != null && discount.compareTo(BigDecimal.ZERO) > 0) {
+											if (baiduPopularizeIds.contains(orderDon.getPopularizeId())) {
+												BigDecimal discountMoney = orderDon.getMoney().multiply(discount);
+												orderDon.setMoney(discountMoney);
+											}
 										}
+									} catch (Exception e) {
 									}
-								} catch (Exception e) {
 								}
 							}
-						}
-					} else {
-						SysConfig discountPopularizeConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
-								.eq(SysConfig::getSysKey, Constant.DISCOUNT_POPULARIZE_KEY).last("limit 1"));
-						if (discountPopularizeConfig != null) {
-							String sysValue = discountPopularizeConfig.getSysValue();
-							if (StrUtil.isNotBlank(sysValue)) {
-								if (user == null) {
-									throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
-								}
-								DiscountPopularizeDto discountPopularizeDto = Jsons.parseObject(sysValue, DiscountPopularizeDto.class);
-								List<Long> popularizeIds = discountPopularizeDto.getPopularizeIds();
-								if (CollUtil.isNotEmpty(popularizeIds) && popularizeIds.contains(orderDon.getPopularizeId())) {
-									List<Long> userIdList = userBindRelationService.getRelationUserIdList(user.getId(), user);
-									Integer count = orderDonUserDiscountPopularizeRecordMapper.selectUserPopularzieDiscountRecordByUidAndPid(userIdList, orderDon.getPopularizeId());
-									if (count == 0) {
-										log.info("用户:{}首次使用折扣特殊链接:{} 折扣:{},修改支付金额", user.getId(), orderDon.getPopularizeId(), discountPopularizeDto.getDiscount());
-										BigDecimal discountMoney = orderDon.getMoney().multiply(discountPopularizeDto.getDiscount());
-										orderDon.setMoney(discountMoney);
-
-										//记录用户使用折扣链接
-										orderDon.setDiscountPopularizeRecord(createPopularizeDiscountRecord(orderDon, discountPopularizeDto.getDiscount()));
+						} else {
+							SysConfig discountPopularizeConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
+									.eq(SysConfig::getSysKey, Constant.DISCOUNT_POPULARIZE_KEY).last("limit 1"));
+							if (discountPopularizeConfig != null) {
+								String sysValue = discountPopularizeConfig.getSysValue();
+								if (StrUtil.isNotBlank(sysValue)) {
+									if (user == null) {
+										throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
+									}
+									DiscountPopularizeDto discountPopularizeDto = Jsons.parseObject(sysValue, DiscountPopularizeDto.class);
+									List<Long> popularizeIds = discountPopularizeDto.getPopularizeIds();
+									if (CollUtil.isNotEmpty(popularizeIds) && popularizeIds.contains(orderDon.getPopularizeId())) {
+										List<Long> userIdList = userBindRelationService.getRelationUserIdList(user.getId(), user);
+										Integer count = orderDonUserDiscountPopularizeRecordMapper.selectUserPopularzieDiscountRecordByUidAndPid(userIdList, orderDon.getPopularizeId());
+										if (count == 0) {
+											log.info("用户:{}首次使用折扣特殊链接:{} 折扣:{},修改支付金额", user.getId(), orderDon.getPopularizeId(), discountPopularizeDto.getDiscount());
+											BigDecimal discountMoney = orderDon.getMoney().multiply(discountPopularizeDto.getDiscount());
+											orderDon.setMoney(discountMoney);
+
+											//记录用户使用折扣链接
+											orderDon.setDiscountPopularizeRecord(createPopularizeDiscountRecord(orderDon, discountPopularizeDto.getDiscount()));
+										}
 									}
 								}
 							}
 						}
-					}
-				} else {
-					//360
+					} else {
+						//360
 //					if (Constant.CHANNEL_NAME_360.equals(name)) {
 //						SysConfig sysConfig = sysConfigService.getBaseMapper().selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.CHANNEL_360_DISCOUNT));
 //						if (sysConfig != null) {
@@ -2851,6 +2880,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 //							orderDon.setMoney(discountMoney);
 //						}
 //					}
+					}
 				}
 			}
 		}
@@ -3333,39 +3363,59 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		if (orderDon.getGoodsId() == Constant.CLAUDE_CODE_GOODS_ID) {
 			try {
 				ClaudeCodeDeductOrderRelate claudeCodeDeductOrderRelate = claudeCodeDeductOrderRelateMapper.selectOne(Wrappers.lambdaQuery(ClaudeCodeDeductOrderRelate.class).eq(ClaudeCodeDeductOrderRelate::getOrderId, orderDon.getId()));
-				Long relationId = claudeCodeDeductOrderRelate.getRelationId();
-				//清除旧的cc车票
-				GroupsRelation oldRelation = groupsRelationMapper.selectById(relationId);
-				Long relationUserId = oldRelation.getUserId();
-				groupRelationClearService.clearTicket(oldRelation, UserTicketClearedRecord.Source.cc_deduct);
-				//生成新规格车票
-				Long skuId = orderDon.getSkuId();
-				Long newRelationId = groupRelationFrontService.getTicket(relationUserId, skuId, Boolean.FALSE);
-				GroupsRelation newRelation = groupsRelationMapper.selectById(newRelationId);
-				ClaudeCodeUser claudeCodeUser = claudeCodeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeCodeUser.class).eq(ClaudeCodeUser::getRelationId, relationId).last("limit 1"));
-				//同步用户cc的 车票id
-				if (claudeCodeUser != null) {
-					claudeCodeUser.setRelationId(newRelationId);
-					claudeCodeUser.setRenewSkuId(null);
-					claudeCodeUser.setRenewOrderId(null);
-					claudeCodeUser.setRenewExpiryTime(null);
-					claudeCodeUserMapper.updateById(claudeCodeUser);
-					//同步套餐
-					claudeCodeService.updateClaudeCodeUserPackageInfo(claudeCodeUser, newRelation.getExpiryTime(), sku);
-				}
-				claudeCodeDeductOrderRelate.setNewRelationId(newRelationId);
-				claudeCodeDeductOrderRelateMapper.updateById(claudeCodeDeductOrderRelate);
-				if (claudeCodeDeductOrderRelate.getExtendsDays() != null && claudeCodeDeductOrderRelate.getExtendsDays() > 0) {
-					newRelation.setExpiryTime(DateUtil.offsetDay(newRelation.getExpiryTime(), claudeCodeDeductOrderRelate.getExtendsDays()));
-					groupsRelationMapper.updateById(newRelation);
-				}
-				//将订单车票id同步成新规格车票id
-				orderDon.setRelationId(newRelationId);
-				orderDonMapper.updateById(orderDon);
+				if (claudeCodeDeductOrderRelate != null) {
+					Long relationId = claudeCodeDeductOrderRelate.getRelationId();
+					//清除旧的cc车票
+					GroupsRelation oldRelation = groupsRelationMapper.selectById(relationId);
+					Long relationUserId = oldRelation.getUserId();
+					groupRelationClearService.clearTicket(oldRelation, UserTicketClearedRecord.Source.cc_deduct);
+					//生成新规格车票
+					Long skuId = orderDon.getSkuId();
+					Long newRelationId = groupRelationFrontService.getTicket(relationUserId, skuId, Boolean.FALSE);
+					GroupsRelation newRelation = groupsRelationMapper.selectById(newRelationId);
+					ClaudeCodeUser claudeCodeUser = claudeCodeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeCodeUser.class).eq(ClaudeCodeUser::getRelationId, relationId).last("limit 1"));
+					//同步用户cc的 车票id
+					if (claudeCodeUser != null) {
+						claudeCodeUser.setRelationId(newRelationId);
+						claudeCodeUser.setRenewSkuId(null);
+						claudeCodeUser.setRenewOrderId(null);
+						claudeCodeUser.setRenewExpiryTime(null);
+						claudeCodeUserMapper.updateById(claudeCodeUser);
+						//同步套餐
+						claudeCodeService.updateClaudeCodeUserPackageInfo(claudeCodeUser, newRelation.getExpiryTime(), sku);
+					}
+					claudeCodeDeductOrderRelate.setNewRelationId(newRelationId);
+					claudeCodeDeductOrderRelateMapper.updateById(claudeCodeDeductOrderRelate);
+					if (claudeCodeDeductOrderRelate.getExtendsDays() != null && claudeCodeDeductOrderRelate.getExtendsDays() > 0) {
+						newRelation.setExpiryTime(DateUtil.offsetDay(newRelation.getExpiryTime(), claudeCodeDeductOrderRelate.getExtendsDays()));
+						groupsRelationMapper.updateById(newRelation);
+					}
+					//将订单车票id同步成新规格车票id
+					orderDon.setRelationId(newRelationId);
+					orderDonMapper.updateById(orderDon);
+				}
 			} catch (Exception e) {
 				log.error("订单回调,cc抵扣升级报错:{}", StringUtil.getErrorText(e));
 			}
 		}
+
+		if (orderDon.getOrderType() == 1 && sku.getIsDown()) {
+			try {
+				GroupsRelation relation = groupsRelationMapper.selectById(orderDon.getRelationId());
+				Long groupsId = relation.getGroupsId();
+				GroupsTrips groupsTrips = groupsMapper.selectById(groupsId);
+				if (groupsTrips.getStatus() == GroupsTrips.Status.validity) {
+					Integer selectCount = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsId).eq(GroupsRelation::getStatus, GroupsTrips.Status.validity));
+					if (selectCount == sku.getNum()) {
+						groupsTrips.setStatus(GroupsTrips.Status.down);
+						groupsMapper.updateById(groupsTrips);
+						recordSysOpLog(groupsTrips.getId());
+					}
+				}
+			} catch (Exception e) {
+
+			}
+		}
 	}
 
 	private void handleUserMirrorSHopOrderDon(OrderDon orderDon) throws Exception {
@@ -4665,9 +4715,9 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
 		GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(groupsTrips.getSkuId());
 		GoodsDon goodsDon = goodsDonMapper.selectById(goodsDonSku.getGoodsId());
-		if (!goodsDonSku.getIsMirror()) {
-			throw BusinessRuntimeException.getInstance("系统异常");
-		}
+//		if (!goodsDonSku.getIsMirror()) {
+//			throw BusinessRuntimeException.getInstance("系统异常");
+//		}
 		Long renewSkuId = payRequest.getSkuId();
 		GoodsDonSku renewSku = goodsDonSkuMapper.selectById(renewSkuId);
 		//校验同规格
@@ -5611,4 +5661,17 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		claudeCodeDeductOrderRelate.setExtendsDays(extendsDays);
 		claudeCodeDeductOrderRelateMapper.insert(claudeCodeDeductOrderRelate);
 	}
+
+	private void recordSysOpLog(Long groupsId) {
+		try {
+			//添加操作记录
+			SysLog sysLog = new SysLog();
+			sysLog.setModule("过期账号/上下架过期车队");
+			sysLog.setOperateParams(groupsId.toString());
+			sysLog.setOperator("坐满系统下架");
+			sysLogMapper.insert(sysLog);
+		} catch (Exception e) {
+
+		}
+	}
 }

+ 5 - 8
netflix-service/src/main/java/com/cyksj/service/order/impl/VipOrderDonServiceImpl.java

@@ -497,7 +497,7 @@ public class VipOrderDonServiceImpl extends ServiceImpl<VipOrderDonMapper, VipOr
 			} catch (Exception e) {
 			}
 		}
-		List<VipGoodsSku> skus = vipGoodsSkuMapper.selectList(null);
+		List<VipGoodsSku> skus = vipGoodsSkuMapper.selectUpSkus();
 		List<Long> deductSkuIds = null;
 		if (CollUtil.isNotEmpty(deductRelationIds)) {
 			List<GroupsRelationView> groupsRelationViews = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
@@ -684,7 +684,7 @@ public class VipOrderDonServiceImpl extends ServiceImpl<VipOrderDonMapper, VipOr
 	 * 设置会员车票同一过期时间
 	 */
 	private void setTicketToVipExpiryTime(List<Long> userIds, Long vipUserId, Date expiryTime) {
-		List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
+		List<Long> vipSkuIds = vipGoodsSkuMapper.selectUpSkus().stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
 		List<Long> selfSkuIds = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
 				.field(GroupsRelationView::getUserId, userIds).op(Operator.InList)
 				.field(GroupsRelationView::getSkuId, vipSkuIds).op(Operator.InList)
@@ -699,12 +699,9 @@ public class VipOrderDonServiceImpl extends ServiceImpl<VipOrderDonMapper, VipOr
 				}
 			});
 		}
-		relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
-				.set(GroupsRelation::getExpiryTime, expiryTime)
-				.set(GroupsRelation::getUpdateTime, DateTime.now())
-				.in(GroupsRelation::getUserId, userIds)
-				.eq(GroupsRelation::getStatus, GroupsRelation.Status.validity)
-				.eq(GroupsRelation::getIsVip, Boolean.TRUE));
+		//更新会员车票
+		Integer update = relationMapper.updateUserVipSkusExpiryTime(userIds, vipSkuIds, expiryTime);
+		log.info("uid;{}镜像会员续费,更新会员{}张车票时长成功", vipUserId, update);
 	}
 
 	private BigDecimal getVipMoney(Integer num) {

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

@@ -1,6 +1,7 @@
 package com.cyksj.service.relation;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.cyksj.model.dto.NetflixRecoverReceivedGptConditionDto;
 import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.GroupsRelation;
 import com.cyksj.model.entity.NetflixUserAccountStatusRecord;
@@ -119,4 +120,8 @@ public interface GroupRelationFrontService {
 	void netflixSubmitFrozen(ErrorNetflixChangeReq req);
 
 	String getSoraCode(Long userId, Long relationId);
+
+	NetflixRecoverReceivedGptConditionDto netflixGptMirrorCondition(long userId);
+
+	void netflixRecoverGetGptMirror(long userId);
 }

+ 186 - 27
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -31,6 +31,7 @@ import com.cyksj.mapper.sys.SysEmailMapper;
 import com.cyksj.mapper.vip.VipGoodsSkuMapper;
 import com.cyksj.mapper.vip.VipUserMapper;
 import com.cyksj.model.dto.ErrorNetflixChangeOtherSkuTicketDto;
+import com.cyksj.model.dto.NetflixRecoverReceivedGptConditionDto;
 import com.cyksj.model.dto.TicketChangeDto;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.AccountView;
@@ -230,6 +231,10 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final ClaudeUserMapper claudeUserMapper;
 
+	private final UserRenewChangeTicketRecordMapper userRenewChangeTicketRecordMapper;
+
+	private final NetflixCompensateReceivedRecordMapper netflixCompensateReceivedRecordMapper;
+
 	@Override
 	public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account, String orderNo, Integer cmt) {
 		User u = userMapper.selectById(userId);
@@ -299,7 +304,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				} catch (Exception e) {
 				}
 			}
-			List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
+			List<Long> vipSkuIds = vipGoodsSkuMapper.selectUpSkus().stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
 			Set<Long> vipGoodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
 					.in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet());
 			Integer vipUserCount = vipUserMapper.selectCount(Wrappers.lambdaQuery(VipUser.class)
@@ -374,6 +379,31 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 						.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
 						.orderByDesc(OrderDon::getId)
 						.last("limit 1"));
+				Long zhSkuId = ticket.getSkuId();
+				if (orderDon == null) {
+					if (ticket.getGoodsId() == Constant.NETFLIX_GID) {
+						//续费更换过车票
+						UserRenewChangeTicketRecord record = userRenewChangeTicketRecordMapper.selectOne(Wrappers.lambdaQuery(UserRenewChangeTicketRecord.class)
+								.in(UserRenewChangeTicketRecord::getUserId, userIds)
+								.eq(UserRenewChangeTicketRecord::getAfterRelationId, ticket.getRelationId())
+								.orderByDesc(UserRenewChangeTicketRecord::getId).last("limit 1"));
+						if (record != null) {
+							Long preRelationId = record.getPreRelationId();
+							orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
+									.eq(OrderDon::getRelationId, preRelationId)
+									.in(OrderDon::getUserId, userIds)
+									.eq(OrderDon::getOrderType, 1)
+									.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
+									.orderByDesc(OrderDon::getId)
+									.last("limit 1"));
+							if (orderDon != null) {
+								zhSkuId = orderDon.getSkuId();
+								GoodsDonSku sku = goodsDonSkuMapper.selectById(zhSkuId);
+								ticket.setSpecVal(sku.getSpecVal());
+							}
+						}
+					}
+				}
 				if (orderDon != null) {
 					ticket.setOrderNo(orderDon.getOrderNo());
 					ticket.setOrderId(orderDon.getId());
@@ -385,7 +415,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 					}
 				}
 				if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
-					String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(ticket.getSkuId(), lang);
+					String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(zhSkuId, lang);
 					if (StrUtil.isNotBlank(languageSpecVal)) {
 						ticket.setSpecVal(languageSpecVal);
 					}
@@ -649,10 +679,10 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				if (relation == null) {
 					//TODO 如果没指定座位,等待逻辑确认
 					DateTime filterAccountTime = null;
-					//奈飞过滤6月23号之前的车队
-					if (sku.getGoodsId() == Constant.NETFLIX_GID) {
-						filterAccountTime = DateUtil.parse("2025-06-23");
-					}
+//					//奈飞过滤6月23号之前的车队
+//					if (sku.getGoodsId() == Constant.NETFLIX_GID) {
+//						filterAccountTime = DateUtil.parse("2025-06-23");
+//					}
 					groups = groupsMapper.selectTicketGroups(sku.getId(), GroupsTrips.Status.validity, maxNum, ip, filterAccountTime);
 
 					if (groups == null) {
@@ -915,6 +945,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				.field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList)
 				.field(RenewalView::getAqType, 1)
 				.field(RenewalView::getIsVip, Boolean.TRUE)
+				.field(RenewalView::getMonths, 300).op(Operator.LessThan)
 				.orderBy(RenewalView::getExpiryTime).asc()
 				.build());
 		if (list.size() > 5) {
@@ -1303,7 +1334,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				state = 3;
 			}
 			//如果账号下架了 直接失败
-			if (StrUtil.equals(GroupsTrips.Status.down.name(), renewalView.getGroupsStatus()) && renewalView.getSkuNum() > 1) {
+			if (renewalView.getDays() == null && StrUtil.equals(GroupsTrips.Status.down.name(), renewalView.getGroupsStatus()) && renewalView.getSkuNum() > 1) {
 				state = 3;
 			}
 		}
@@ -1362,7 +1393,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 			//车队是否已下架
 			GroupsRelation relation = groupsRelationMapper.selectById(relationId);
 			GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
-			if (groupsTrips != null && groupsTrips.getStatus() == GroupsTrips.Status.down) {
+			GoodsDonSku sku = goodsDonSkuMapper.selectById(groupsTrips.getSkuId());
+			if (groupsTrips != null && sku.getDays() == null && groupsTrips.getStatus() == GroupsTrips.Status.down) {
 				state = 3;
 				//下架 异常
 				if (netflixUseAccountStatusRecord != null) {
@@ -1861,19 +1893,24 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		Long skuId = netflixRelationView.getSkuId();
 		GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
 		BigDecimal orderMoney = orderDon == null ? BigDecimal.ZERO : orderDon.getMoney();
-		if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
+		BigDecimal balance = orderDon == null ? BigDecimal.ZERO : Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO);
+		if (orderMoney.add(balance).compareTo(BigDecimal.ZERO) == 0) {
 			refundInfoResp.setIsRefund(false);
 		}
 		//每天单价
-		BigDecimal dayPrice = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths() * 30), RoundingMode.DOWN);
+		BigDecimal dayPrice;
+		if (sku.getDays() != null) {
+			dayPrice = orderMoney.add(balance).divide(BigDecimal.valueOf(sku.getDays()), RoundingMode.DOWN);
+		} else {
+			dayPrice = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths() * 30), RoundingMode.DOWN);
+		}
 		//需要退款金额
 		BigDecimal refundMoney = dayPrice.multiply(BigDecimal.valueOf(betweenDay));
 		refundInfoResp.setPrice(refundMoney);
-		BigDecimal balance = orderDon == null ? BigDecimal.ZERO : Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO);
-		//超过本身订单金额 不允许退款
-		if (refundMoney.compareTo(orderMoney) > 0) {
-			refundInfoResp.setIsRefund(false);
-		}
+//		//超过本身订单金额 不允许退款
+//		if (refundMoney.compareTo(orderMoney) > 0) {
+//			refundInfoResp.setIsRefund(false);
+//		}
 		if (refundMoney.compareTo(orderMoney.add(balance)) > 0) {
 			refundInfoResp.setPrice(orderMoney.add(balance));
 		}
@@ -1906,26 +1943,52 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		Long skuId = netflixRelationView.getSkuId();
 		GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
 		BigDecimal orderMoney = orderDon.getMoney();
-		if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
+		BigDecimal balance = orderDon == null ? BigDecimal.ZERO : Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO);
+		if (orderMoney.add(balance).compareTo(BigDecimal.ZERO) == 0) {
 			throw BusinessRuntimeException.getInstance("不符合退款条件");
 		}
 		//每天单价
-		BigDecimal dayPrice = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths() * 30), RoundingMode.DOWN);
+		BigDecimal dayPrice;
+		if (sku.getDays() != null) {
+			dayPrice = orderMoney.add(balance).divide(BigDecimal.valueOf(sku.getDays()), RoundingMode.DOWN);
+		} else {
+			dayPrice = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths() * 30), RoundingMode.DOWN);
+		}
 		//需要退款金额
-		BigDecimal refundMoney = dayPrice.multiply(BigDecimal.valueOf(betweenDay));
-		if (refundMoney.compareTo(orderMoney) > 0) {
-			throw BusinessRuntimeException.getInstance("不符合退款条件");
+		BigDecimal totalRefundMoney = dayPrice.multiply(BigDecimal.valueOf(betweenDay));
+		BigDecimal refundMoney = totalRefundMoney;
+		BigDecimal refundBalance = BigDecimal.ZERO;
+		if (totalRefundMoney.compareTo(orderMoney) > 0) {
+			refundMoney = orderMoney;
+			refundBalance = totalRefundMoney.subtract(orderMoney);
+		}
+		String outNo = StrUtil.EMPTY;
+		if (refundMoney.compareTo(BigDecimal.ZERO) > 0) {
+			//调用第三方接口退款
+			OrderRefundReq refundReq = new OrderRefundReq();
+			refundReq.setRefundMoney(refundMoney);
+			refundReq.setRefundType("money");
+			outNo = orderRefundService.centerRefund(refundReq, orderDon);
+			orderDon.setRefundMoney(refundMoney);
 		}
-		//调用第三方接口退款
-		OrderRefundReq refundReq = new OrderRefundReq();
-		refundReq.setRefundMoney(refundMoney);
-		refundReq.setRefundType("money");
-		String outNo = orderRefundService.centerRefund(refundReq, orderDon);
 		orderDon.setStatus(OrderDon.Status.refund);
-		orderDon.setRefundMoney(refundMoney);
+		if (refundBalance.compareTo(BigDecimal.ZERO) > 0) {
+			orderDon.setRefundBalance(refundBalance);
+		}
 		GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
 		orderDonMapper.updateById(orderDon);
-		orderRefundService.refundRecord(orderDon, refundMoney, null, "系统", goodsDon, sku, outNo, orderDon.getType().name(), null);
+		if (refundBalance.compareTo(BigDecimal.ZERO) > 0) {
+			userBenefitsService.addUserBalance(orderDon.getUserId(), refundBalance, UserBalanceSourceRecord.Source.refund, null, orderDon.getId(), goodsDon.getTitle() + sku.getSpecVal() + UserBalanceSourceRecord.Source.refund.getDesc(), true);
+		}
+		String refundType;
+		if (refundMoney.compareTo(BigDecimal.ZERO) > 0 && refundBalance.compareTo(BigDecimal.ZERO) > 0) {
+			refundType = "bxj";
+		} else if (refundMoney.compareTo(BigDecimal.ZERO) == 0 && refundBalance.compareTo(BigDecimal.ZERO) > 0) {
+			refundType = "balance";
+		} else {
+			refundType = orderDon.getType().name();
+		}
+		orderRefundService.refundRecord(orderDon, refundMoney, refundBalance, "系统", goodsDon, sku, outNo, refundType, null);
 		//清除车票
 		GroupsRelation relation = groupsRelationMapper.selectById(relationId);
 		clearService.clearTicket(relation, UserTicketClearedRecord.Source.refund);
@@ -2220,6 +2283,102 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		return soraCode.getCode();
 	}
 
+	@Override
+	public NetflixRecoverReceivedGptConditionDto netflixGptMirrorCondition(long userId) {
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		//是否申请过奈飞恢复
+		NetflixUserAccountSubmitRecoverRecord last = netflixUserAccountSubmitRecoverRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class).in(NetflixUserAccountSubmitRecoverRecord::getUserId, userIdList).orderByDesc(NetflixUserAccountSubmitRecoverRecord::getId).last("limit 1"));
+		NetflixRecoverReceivedGptConditionDto receivedGptConditionDto = new NetflixRecoverReceivedGptConditionDto();
+		if (last == null) {
+			receivedGptConditionDto.setStatus(Boolean.FALSE);
+			return receivedGptConditionDto;
+		}
+		//是否存在奈飞车票
+		List<RenewalView> tickets = beanSearcher.searchAll(RenewalView.class, MapUtils.builder()
+				.field(RenewalView::getUserId, userIdList).op(Operator.InList)
+				.field(RenewalView::getGoodsId, Constant.NETFLIX_GID)
+				.field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
+				.onlySelect(RenewalView::getRelationId)
+				.build());
+		if (CollUtil.isEmpty(tickets)) {
+			receivedGptConditionDto.setStatus(Boolean.FALSE);
+			return receivedGptConditionDto;
+		}
+		//多张奈飞车票 不给领取
+		if (tickets.size() > 1) {
+			receivedGptConditionDto.setStatus(Boolean.FALSE);
+			return receivedGptConditionDto;
+		}
+		Long submitRelationId = last.getRelationId();
+		receivedGptConditionDto.setNfRelationId(submitRelationId);
+
+		RenewalView renewalView = tickets.get(0);
+		Long presentRelationId = renewalView.getRelationId();
+		//是否领取过 并且现在是否有效
+		NetflixCompensateReceivedRecord netflixCompensateReceivedRecord = netflixCompensateReceivedRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixCompensateReceivedRecord.class).in(NetflixCompensateReceivedRecord::getUserId, userIdList).orderByDesc(NetflixCompensateReceivedRecord::getId).last("limit 1"));
+		if (netflixCompensateReceivedRecord != null) {
+			//是否 有效
+			Long gptRelationId = netflixCompensateReceivedRecord.getRelationId();
+			Integer expiryCount = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getId, gptRelationId).in(GroupsRelation::getUserId, userIdList).gt(GroupsRelation::getExpiryTime, DateTime.now()));
+			if (expiryCount > 0) {
+				receivedGptConditionDto.setStatus(Boolean.FALSE);
+				return receivedGptConditionDto;
+			}
+			//领取后已过期
+			Long compensateReceivedRecordNfRelationId = netflixCompensateReceivedRecord.getNfRelationId();
+			//是否通过当前车票已经获取过 镜像车票
+			if (compensateReceivedRecordNfRelationId.equals(presentRelationId)) {
+				receivedGptConditionDto.setStatus(Boolean.FALSE);
+				return receivedGptConditionDto;
+			}
+			//恢复中 可获取
+			if (last.getStatus() == 0) {
+				receivedGptConditionDto.setStatus(Boolean.TRUE);
+				return receivedGptConditionDto;
+			}
+			//不是正常恢复 不可获取
+			if (last.getStatus() != 1) {
+				receivedGptConditionDto.setStatus(Boolean.FALSE);
+				return receivedGptConditionDto;
+			}
+
+			Long replaceRelationId = last.getReplaceRelationId();
+			//非同一张车票 存在更换过
+			if (!presentRelationId.equals(replaceRelationId)) {
+				receivedGptConditionDto.setStatus(Boolean.FALSE);
+				return receivedGptConditionDto;
+			}
+
+		}
+		receivedGptConditionDto.setStatus(Boolean.TRUE);
+		return receivedGptConditionDto;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public void netflixRecoverGetGptMirror(long userId) {
+		NetflixRecoverReceivedGptConditionDto receivedGptConditionDto = netflixGptMirrorCondition(userId);
+		if (receivedGptConditionDto.getStatus()) {
+			try {
+				NetflixCompensateReceivedRecord netflixCompensateReceivedRecord = new NetflixCompensateReceivedRecord();
+				netflixCompensateReceivedRecord.setUserId(userId);
+				netflixCompensateReceivedRecord.setNfRelationId(receivedGptConditionDto.getNfRelationId());
+				netflixCompensateReceivedRecord.setGoodsId(Constant.GPT_PLUS_GID);
+				netflixCompensateReceivedRecord.setSkuId(Constant.GPT_MIRROR_SKU_ID);
+				netflixCompensateReceivedRecordMapper.insert(netflixCompensateReceivedRecord);
+
+				Long relationId = this.getTicket(userId, Constant.GPT_MIRROR_SKU_ID, Boolean.FALSE);
+				if (relationId == null) {
+					throw BusinessRuntimeException.getInstance("获取车票失败,请重新领取");
+				}
+				netflixCompensateReceivedRecord.setRelationId(relationId);
+				netflixCompensateReceivedRecordMapper.updateById(netflixCompensateReceivedRecord);
+			} catch (DuplicateKeyException e) {
+
+			}
+		}
+	}
+
 	private DistributePosterGoodsDetailView setGoodsPoster(RenewalView ticket, User user, List<Long> userIds) {
 		DistributePosterGoodsDetailView distributePosterGoodsDetailView = beanSearcher.searchFirst(DistributePosterGoodsDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
 				.field(DistributePosterGoodsFrontView::getGoodsId, ticket.getGoodsId()).build());

+ 2 - 1
netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java

@@ -935,6 +935,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 		}
 		User user = userMapper.selectById(userId);
 		syncInfoView.setGalaxyCoin(user.getGalaxyCoin());
+		syncInfoView.setIsBlack(user.getIsBlack());
 		return syncInfoView;
 	}
 
@@ -978,7 +979,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 			UserBlackRecord userBlackRecord = new UserBlackRecord();
 			userBlackRecord.setOperateUserId(userId);
 			userBlackRecord.setUserId(relateUser.getId());
-			userBlackRecord.setStatus(user.getIsBlack());
+			userBlackRecord.setStatus(relateUser.getIsBlack());
 			blackRecordMapper.insert(userBlackRecord);
 		}
 	}

+ 12 - 0
netflix-service/src/main/java/com/cyksj/service/verify/ApiVerifyService.java

@@ -0,0 +1,12 @@
+package com.cyksj.service.verify;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: ApiVerifyService
+ * 创建者: JavaZou
+ * 创建时间:2025/10/22 18:00
+ */
+public interface ApiVerifyService {
+
+	Boolean verifyApiDo(String params) throws Exception;
+}

+ 40 - 0
netflix-service/src/main/java/com/cyksj/service/verify/impl/ApiVerifyServiceImpl.java

@@ -0,0 +1,40 @@
+package com.cyksj.service.verify.impl;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.common.util.SignatureUtils;
+import com.cyksj.service.verify.ApiVerifyService;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: ApiVerifyServiceImpl
+ * 创建者: JavaZou
+ * 创建时间:2025/10/22 18:01
+ */
+@Service
+public class ApiVerifyServiceImpl implements ApiVerifyService {
+	public static final String SIGN_SECRET = "xmR7XvKbPeShVmYq3t5w9z$C&FHx@McQ";
+
+	@Override
+	public Boolean verifyApiDo(String params) throws Exception {
+		JSONObject jsonObject = Jsons.parseObject(params, JSONObject.class);
+		String sign = jsonObject.getStr("sign");
+		if (StrUtil.isEmpty(sign)) {
+			return Boolean.FALSE;
+		}
+		Long timestamp = jsonObject.getLong("timestamp");
+		//1s内
+		if (timestamp == null || System.currentTimeMillis() - timestamp > 1000) {
+			return Boolean.FALSE;
+		}
+		String bsign = SignatureUtils.generateSignature(Map.of("timestamp", timestamp.toString()), SIGN_SECRET);
+		if (!StrUtil.equals(bsign, sign)) {
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+}

+ 12 - 10
netflix-service/src/main/java/com/cyksj/service/vip/impl/CmsVipUserServiceImpl.java

@@ -16,9 +16,11 @@ import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.vip.CmsVipUserService;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 项目名: yhlxj2
@@ -28,6 +30,7 @@ import java.util.List;
  */
 @Service
 @RequiredArgsConstructor
+@Slf4j
 public class CmsVipUserServiceImpl implements CmsVipUserService {
 	private final VipUserMapper vipUserMapper;
 
@@ -69,16 +72,16 @@ public class CmsVipUserServiceImpl implements CmsVipUserService {
 			vipUserMapper.updateById(vipUser);
 		}
 		//发送车票
-		List<VipGoodsSku> skus = vipGoodsSkuMapper.selectList(null);
+		List<VipGoodsSku> skus = vipGoodsSkuMapper.selectUpSkus();
 		for (VipGoodsSku sku : skus) {
 			//未有抵扣 直接发送会员车票
 			groupRelationFrontService.getTicket(userId, sku.getSkuId(), Boolean.TRUE);
 		}
 		//同步时间
-		groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
-				.set(GroupsRelation::getExpiryTime, vipUser.getExpiryTime())
-				.in(GroupsRelation::getUserId, userIdList)
-				.eq(GroupsRelation::getIsVip, Boolean.TRUE));
+		List<Long> vipSkuIds = skus.stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
+		Integer update = groupsRelationMapper.updateUserVipSkusExpiryTime(userIdList, vipSkuIds, vipUser.getExpiryTime());
+		log.info("后台开通uid;{}镜像会员,更新会员{}张车票时长成功", vipUser.getUserId(), update);
+
 		//操作记录
 		VipUserOperateLog vipUserOperateLog = new VipUserOperateLog();
 		vipUserOperateLog.setUserId(userId);
@@ -102,11 +105,10 @@ public class CmsVipUserServiceImpl implements CmsVipUserService {
 		vipUser.setExpiryTime(DateUtil.offsetDay(vipUser.getExpiryTime(), days));
 		vipUserMapper.updateById(vipUser);
 
-		//同步时间
-		groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
-				.set(GroupsRelation::getExpiryTime, vipUser.getExpiryTime())
-				.in(GroupsRelation::getUserId, userIdList)
-				.eq(GroupsRelation::getIsVip, Boolean.TRUE));
+		//更新会员车票
+		List<Long> vipSkuIds = vipGoodsSkuMapper.selectUpSkus().stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
+		Integer update = groupsRelationMapper.updateUserVipSkusExpiryTime(userIdList, vipSkuIds, vipUser.getExpiryTime());
+		log.info("后台uid;{}镜像会员延长或扣除,更新会员{}张车票时长成功", vipUser.getUserId(), update);
 
 		//操作记录
 		VipUserOperateLog vipUserOperateLog = new VipUserOperateLog();

+ 5 - 2
netflix-service/src/main/java/com/cyksj/service/vip/impl/VipFrontServiceImpl.java

@@ -16,6 +16,7 @@ import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.GroupsRelationView;
 import com.cyksj.model.response.VipUserPageResp;
 import com.cyksj.model.views.RenewalView;
+import com.cyksj.model.views.VipGoodsSkuFrontView;
 import com.cyksj.service.chatgpt.ChatGptAccountService;
 import com.cyksj.service.claude.ClaudeService;
 import com.cyksj.service.user.UserBindRelationService;
@@ -86,7 +87,7 @@ public class VipFrontServiceImpl implements VipFrontService {
 		//可抵扣价格
 		BigDecimal deductMoney = BigDecimal.ZERO;
 		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
-		List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
+		List<Long> vipSkuIds = beanSearcher.searchAll(VipGoodsSkuFrontView.class, MapUtils.builder().build()).stream().map(VipGoodsSkuFrontView::getSkuId).collect(Collectors.toList());
 		//可有抵扣车票
 		DateTime now = DateTime.now();
 		//会员规格
@@ -115,7 +116,7 @@ public class VipFrontServiceImpl implements VipFrontService {
 	@Override
 	public VipDeductDto checkAndGetOrderDeductMoney(Long userId, Integer months) {
 		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
-		List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
+		List<Long> vipSkuIds = vipGoodsSkuMapper.selectUpSkus().stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
 		//会员规格
 		Set<Long> goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
 				.in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet());
@@ -358,10 +359,12 @@ public class VipFrontServiceImpl implements VipFrontService {
 	 * 获取车票可抵扣金额
 	 */
 	public BigDecimal getDeductMoneyFromTicket(Long relationId, List<Long> userIdList, Long skuId, DateTime now, Date relationStartTime, Date relationExpiryTime) {
+		OrderDon oriOrderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus).eq(OrderDon::getOrderType, 1).orderByDesc(OrderDon::getId).last("limit 1"));
 		List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
 				.eq(OrderDon::getRelationId, relationId)
 				.in(OrderDon::getUserId, userIdList)
 				.eq(OrderDon::getSkuId, skuId)
+				.ge(oriOrderDon != null, OrderDon::getCreatedTime, oriOrderDon.getCreatedTime())
 				.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
 				.orderByDesc(OrderDon::getId));
 		//部分退款

+ 3 - 0
netflix-web/src/main/java/com/cyksj/web/controller/claude/ClaudeCodeController.java

@@ -209,6 +209,9 @@ public class ClaudeCodeController {
 				GroupsRelation relation = relationMapper.selectById(user.getRelationId());
 				GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
 				Long skuId = groupsTrips.getSkuId();
+				if (user.getRenewSkuId() != null && user.getRenewSkuId() > 0) {
+					skuId = user.getRenewSkuId();
+				}
 				List<RenewUpgradePackageFrontView> renewUpgradePackageFrontViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.class, MapUtils.builder().field(RenewUpgradePackageFrontView::getSkuId, skuId).build());
 				renewUpgradePackageFrontViews.forEach(renew -> {
 					try {

+ 3 - 0
netflix-web/src/main/java/com/cyksj/web/controller/codex/CodexController.java

@@ -195,6 +195,9 @@ public class CodexController {
                 GroupsRelation relation = relationMapper.selectById(user.getRelationId());
                 GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
                 Long skuId = groupsTrips.getSkuId();
+                if (user.getRenewSkuId() != null && user.getRenewSkuId() > 0) {
+                    skuId = user.getRenewSkuId();
+                }
                 List<RenewUpgradePackageFrontView> renewUpgradePackageFrontViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.class, MapUtils.builder().field(RenewUpgradePackageFrontView::getSkuId, skuId).build());
                 renewUpgradePackageFrontViews.forEach(renew -> {
                     try {

+ 14 - 0
netflix-web/src/main/java/com/cyksj/web/controller/cps/CpsDistribtueDataController.java

@@ -103,6 +103,20 @@ public class CpsDistribtueDataController {
 		return GatewayResponse.SUCCESS.newBuilder().toResult(detailView);
 	}
 
+	/**
+	 * 比例变更记录
+	 */
+	@GetMapping("/get/rate/record")
+	public Result<SearchResult<UserDistributeRateChangeRecord>> getRateRecord() {
+		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
+		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
+				.eq(UserDistribute::getUserId, cpsUserId)
+				.eq(UserDistribute::getDeleted, 1)
+				.last("limit 1"));
+		SearchResult<UserDistributeRateChangeRecord> search = beanSearcher.search(UserDistributeRateChangeRecord.class, MapUtils.flatBuilder(request.getParameterMap()).field(UserDistributeRateChangeRecord::getDistributeId, userDistribute.getId()).onlySelect(UserDistributeRateChangeRecord::getChangeInfo, UserDistributeRateChangeRecord::getCreatedTime).orderBy(UserDistributeRateChangeRecord::getId).desc().build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
 	/**
 	 * 待入账数据统计
 	 */

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

@@ -29,6 +29,7 @@ import com.cyksj.mapper.manage.form.QuestionnairePromotionMapper;
 import com.cyksj.mapper.shop.YhShopMapper;
 import com.cyksj.model.dto.DoubleVerifyDto;
 import com.cyksj.model.dto.GalaxyCoinPayConfigDto;
+import com.cyksj.model.dto.NetflixRecoverReceivedGptConditionDto;
 import com.cyksj.model.dto.QuestionnaireView;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.AccountView;
@@ -1548,4 +1549,25 @@ public class GroupRelationController {
         String soraCode = groupRelationFrontService.getSoraCode(userId, relationId);
         return GatewayResponse.SUCCESS.newBuilder().toResult(soraCode);
     }
+
+    /**
+     * 奈飞补偿
+     * 用户可领取GPT镜像标准月付情况
+     */
+    @GetMapping("/netflix/gptMirror/condition")
+    public Result<Boolean> netflixGptMirrorCondition() {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        NetflixRecoverReceivedGptConditionDto conditionDto = groupRelationFrontService.netflixGptMirrorCondition(userId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(conditionDto.getStatus());
+    }
+
+    /**
+     * 奈飞申请恢复过的用户 领取GPT镜像标准月付
+     */
+    @GetMapping("/netflix/recover/get/gptMirror")
+    public Result<String> netflixRecoverGetGptMirror() {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        groupRelationFrontService.netflixRecoverGetGptMirror(userId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
 }

+ 12 - 9
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java

@@ -630,17 +630,20 @@ public class CmsOrderController {
 					relation.setOperator(cmsUser.getNickname());
 				}
 				relation.setSendTime(DateTime.now());
-				relation.setStartTime(DateTime.now());
-				GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId());
-				DateTime expiryTime;
-				if (sku.getDays() != null && sku.getDays() > 0) {
-					expiryTime = DateUtil.offsetDay(relation.getStartTime(), sku.getDays());
-				} else {
-					expiryTime = DateUtil.offsetMonth(relation.getStartTime(), sku.getMonths());
+
+				//设置车票时间
+				if (relation.getStartTime() == null) {
+					relation.setStartTime(DateTime.now());
+					GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId());
+					DateTime expiryTime;
+					if (sku.getDays() != null && sku.getDays() > 0) {
+						expiryTime = DateUtil.offsetDay(relation.getStartTime(), sku.getDays());
+					} else {
+						expiryTime = DateUtil.offsetMonth(relation.getStartTime(), sku.getMonths());
+					}
+					relation.setExpiryTime(expiryTime);
 				}
-				relation.setExpiryTime(expiryTime);
 				relationMapper.updateById(relation);
-
 				//GPT代充
 				if (orderDon.getGoodsId() == Constant.GPT_RECHARGE_GOODS_ID) {
 					//扣除次数

+ 22 - 5
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java

@@ -94,6 +94,8 @@ public class CmsUserController{
 
     private final CmsVipUserService cmsVipUserService;
 
+    private final UserBlackRecordMapper blackRecordMapper;
+
     private final List<Long> no_blacks_userIds = List.of(375274l, 545599l, 523937l, 507498l, 604146l, 613437l, 651728l, 614100l, 604148l);
 
     @GetMapping("/get")
@@ -195,11 +197,13 @@ public class CmsUserController{
         if (no_blacks_userIds.contains(id)) {
             throw BusinessRuntimeException.getInstance("张凯已处理");
         }
+        long adminId = StpUtil.getLoginIdAsLong();
         User user = userMapper.selectById(id);
+        CmsUser cmsUser = cmsUserMapper.selectById(adminId);
         Optional.ofNullable(user).ifPresent(u -> {
-            u.setIsBlack(!u.getIsBlack());
-            if (u.getIsBlack()) {
-                List<Long> userIds = userBindRelationService.getRelationUserIdList(id, user);
+            Boolean isBlack = !u.getIsBlack();
+            List<Long> userIds = userBindRelationService.getRelationUserIdList(id, user);
+            if (isBlack) {
                 List<RenewalView> groupsRelations = beanSearcher.searchAll(RenewalView.class, MapUtils.builder()
                         .field(RenewalView::getUserId, 0).op(Operator.GreaterThan)
                         .field(RenewalView::getUserId, userIds).op(Operator.InList)
@@ -220,11 +224,24 @@ public class CmsUserController{
                     vipUserMapper.updateById(vipUser);
                 });
             }
-            userMapper.updateById(u);
+            List<User> users = userMapper.selectBatchIds(userIds);
+
+            for (User relateUser : users) {
+                relateUser.setIsBlack(isBlack);
+                userMapper.updateById(relateUser);
+
+                //用户拉黑记录
+                UserBlackRecord userBlackRecord = new UserBlackRecord();
+                userBlackRecord.setUserId(relateUser.getId());
+                userBlackRecord.setStatus(relateUser.getIsBlack());
+                if (cmsUser != null) {
+                    userBlackRecord.setOperator(cmsUser.getNickname());
+                }
+                blackRecordMapper.insert(userBlackRecord);
+            }
         });
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
-
     /**
      * 修改用户查看验证码次数
      */

+ 25 - 3
netflix-web/src/main/java/com/cyksj/web/controller/manage/account/CmsAccountController.java

@@ -124,6 +124,8 @@ public class CmsAccountController {
 
 	private final OrderDonMapper orderDonMapper;
 
+	private final DelAccountRecordMapper delAccountRecordMapper;
+
 	@GetMapping("/get")
 	@SaCheckPermission("account:view")
 	public Result<SearchResult<AccountView>> get(String title, Long userId, String showId, String nickName, String submitAccount, String expiryStartTime, String expiryEndTime, Boolean expiredAll, Boolean existsExpired, Boolean existsExpiredToday, Integer noChangeMonths, Boolean isMjMirror, String orderNo, Boolean isEmpty) {
@@ -775,13 +777,23 @@ public class CmsAccountController {
 	@DeleteMapping("/delete/{id}")
 	@SaCheckPermission("account:delete")
 	@Log(module = "平台管理/删除账号", businessType = BusinessType.DELETE, isSaveRequestData = true)
-	public Result<String> update(@PathVariable Long id){
-	    //是否关联了车队
+	public Result<String> update(@PathVariable Long id) throws Exception {
+		long adminId = StpUtil.getLoginIdAsLong();
+		//是否关联了车队
 	    Integer count = groupsMapper.selectCount(Wrappers.lambdaQuery(GroupsTrips.class).eq(GroupsTrips::getAccountId, id));
 	    if (count > 0) {
 		    throw BusinessRuntimeException.getInstance("已经发布账号,必须先删除车队才可删除账号");
 	    }
-        accountService.removeById(id);
+		Account account = accountService.getById(id);
+		accountService.removeById(id);
+
+		DelAccountRecord delAccountRecord = new DelAccountRecord();
+		CmsUser cmsUser = cmsUserMapper.selectById(adminId);
+		if (cmsUser != null) {
+			delAccountRecord.setOperator(cmsUser.getNickname());
+		}
+		delAccountRecord.setAccountInfo(Jsons.toJson(account));
+		delAccountRecordMapper.insert(delAccountRecord);
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
 
@@ -795,6 +807,16 @@ public class CmsAccountController {
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
 
+	/**
+	 * 导入账号 批量删除
+	 */
+	@DeleteMapping("/batch/delete/goods/accountTrips")
+	public Result<List<String>> batchDelAccountTripsByGoodsAccount(@RequestBody DelAccountTripsReq delAccountTripsReq) throws Exception {
+		long adminId = StpUtil.getLoginIdAsLong();
+		List<String> fails = accountService.batchDelAccountTripsByGoodsAccount(delAccountTripsReq, adminId);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(fails);
+	}
+
     @PutMapping("/update/expiryTime")
     @SaCheckPermission("account:addExpiryTime")
     public Result<String> updateExpiryTime(@RequestBody ReqAccountIncrExpiryTime incrExpiryTime){

+ 23 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java

@@ -30,6 +30,7 @@ import com.cyksj.model.request.UserDistributeReq;
 import com.cyksj.model.views.*;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.distribute.DistributeService;
+import com.cyksj.service.distribute.UserDistributeRateChangeRecordService;
 import com.cyksj.service.distribute.UserDistributeReturnMoneyDetailService;
 import com.cyksj.service.mange.business.UserBusinessRateService;
 import com.cyksj.service.mange.statistics.StatisticsDataService;
@@ -127,6 +128,9 @@ public class DistributeController {
 	private final UserDistributeSubMapper userDistributeSubMapper;
 
 	private final UserDistributeReturnMoneyDetailService userDistributeReturnMoneyDetailService;
+
+	private final UserDistributeRateChangeRecordService changeRecordService;
+
 	/**
 	 * 添加固定推广者
 	 */
@@ -828,11 +832,18 @@ public class DistributeController {
 				if (id == null) {
 					try {
 						businessDefaultRateConfigMapper.insert(config);
+						//默认平台比例变更记录
+						changeRecordService.recordDefaultGoodsRate(config.getGoodsId(), config.getRate());
 						alertGoodsId.add(config.getGoodsId());
 					} catch (DuplicateKeyException e) {
 					}
 				} else {
+					BusinessDistributeDefaultRateConfig dbConfig = businessDefaultRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultRateConfig.class).eq(BusinessDistributeDefaultRateConfig::getId, config.getId()).last("limit 1"));
 					businessDefaultRateConfigMapper.updateById(config);
+					if (dbConfig != null && dbConfig.getRate() != config.getRate()) {
+						//默认平台比例变更记录
+						changeRecordService.recordDefaultGoodsRate(config.getGoodsId(), config.getRate());
+					}
 				}
 			});
 		}
@@ -841,6 +852,10 @@ public class DistributeController {
 		if (CollUtil.isNotEmpty(skuRates)) {
 			List<Long> collect = skuRates.stream().map(BusinessDistributeDefaultSkuRateConfig::getSkuId).collect(Collectors.toList());
 			if (CollUtil.isNotEmpty(collect)) {
+				List<BusinessDistributeDefaultSkuRateConfig> businessDistributeDefaultSkuRateConfigs = businessDistributeDefaultSkuRateConfigMapper.selectList(Wrappers.lambdaQuery(BusinessDistributeDefaultSkuRateConfig.class).notIn(BusinessDistributeDefaultSkuRateConfig::getSkuId, collect));
+				//默认平台规格比例变更记录
+				changeRecordService.recordDefaultGoodsSkuDelRate(businessDistributeDefaultSkuRateConfigs);
+
 				businessDistributeDefaultSkuRateConfigMapper.delete(Wrappers.lambdaQuery(BusinessDistributeDefaultSkuRateConfig.class)
 						.notIn(BusinessDistributeDefaultSkuRateConfig::getSkuId, collect));
 			}
@@ -855,11 +870,19 @@ public class DistributeController {
 				if (config.getId() == null) {
 					try {
 						businessDistributeDefaultSkuRateConfigMapper.insert(config);
+						//默认平台规格比例变更记录
+						changeRecordService.recordDefaultGoodsSkuRate(config.getGoodsId(), config.getSkuId(), config.getRate());
+						//默认平台规格比例变更记录
 						alertGoodsId.add(config.getGoodsId());
 					} catch (DuplicateKeyException e) {
 					}
 				} else {
+					BusinessDistributeDefaultSkuRateConfig dbConfig = businessDistributeDefaultSkuRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultSkuRateConfig.class).eq(BusinessDistributeDefaultSkuRateConfig::getId, config.getId()).last("limit 1"));
 					businessDistributeDefaultSkuRateConfigMapper.updateById(config);
+					if (dbConfig != null && dbConfig.getRate() != config.getRate()) {
+						//默认平台比例变更记录
+						changeRecordService.recordDefaultGoodsSkuRate(config.getGoodsId(), config.getSkuId(), config.getRate());
+					}
 				}
 			});
 		}

+ 11 - 8
netflix-web/src/main/java/com/cyksj/web/controller/manage/group/CmsGroupRelationController.java

@@ -250,15 +250,18 @@ public class CmsGroupRelationController {
 
             orderDonMapper.updateById(orderDon);
 
-            relation.setStartTime(DateTime.now());
-            GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
-            DateTime expiryTime;
-            if (sku.getDays() != null && sku.getDays() > 0) {
-                expiryTime = DateUtil.offsetDay(relation.getStartTime(), sku.getDays());
-            } else {
-                expiryTime = DateUtil.offsetMonth(relation.getStartTime(), sku.getMonths());
+            //设置车票时间
+            if (relation.getStartTime() == null) {
+                relation.setStartTime(DateTime.now());
+                GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
+                DateTime expiryTime;
+                if (sku.getDays() != null && sku.getDays() > 0) {
+                    expiryTime = DateUtil.offsetDay(relation.getStartTime(), sku.getDays());
+                } else {
+                    expiryTime = DateUtil.offsetMonth(relation.getStartTime(), sku.getMonths());
+                }
+                relation.setExpiryTime(expiryTime);
             }
-            relation.setExpiryTime(expiryTime);
         }
         groupsRelationMapper.updateById(relation);
         //GPT代充

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

@@ -31,6 +31,8 @@ import com.cyksj.model.request.BatchServiceReq;
 import com.cyksj.model.request.RedBookReq;
 import com.cyksj.model.request.RenewTimeUpReq;
 import com.cyksj.model.views.*;
+import com.cyksj.service.claude.ClaudeCodeService;
+import com.cyksj.service.codex.CodexService;
 import com.cyksj.service.mange.statistics.StatisticsDataService;
 import com.cyksj.service.relation.GroupRelationClearService;
 import com.cyksj.web.util.EasyExcelUtils;
@@ -97,6 +99,18 @@ public class StatisticsDataController {
 
 	private final HttpServletRequest request;
 
+	private final GroupsMapper groupsMapper;
+
+	private final GoodsDonSkuMapper goodsDonSkuMapper;
+
+	private final CodexUserMapper codexUserMapper;
+
+	private final CodexService codexService;
+
+	private final ClaudeCodeService claudeCodeService;
+
+	private final ClaudeCodeUserMapper claudeCodeUserMapper;
+
 	/**
 	 * 查询头部统计数据
 	 */
@@ -248,6 +262,22 @@ public class StatisticsDataController {
 		//清除车票
 		if (relation.getExpiryTime().before(DateTime.now())) {
 			clearService.clearTicket(relation, UserTicketClearedRecord.Source.manual);
+		} else {
+			Long groupsId = relation.getGroupsId();
+			GroupsTrips groupsTrips = groupsMapper.selectById(groupsId);
+			Long skuId = groupsTrips.getSkuId();
+			GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
+			if (sku.getGoodsId() == Constant.CODEX_GOODS_ID) {
+				CodexUser codexUser = codexUserMapper.selectOne(Wrappers.lambdaQuery(CodexUser.class).eq(CodexUser::getRelationId, relation.getId()).last("limit 1"));
+				if (codexUser != null) {
+					codexService.updateCodexUserPackageInfo(codexUser, relation.getExpiryTime(), null);
+				}
+			} else if (sku.getGoodsId() == Constant.CLAUDE_CODE_GOODS_ID) {
+				ClaudeCodeUser claudeCodeUser = claudeCodeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeCodeUser.class).eq(ClaudeCodeUser::getRelationId, relation.getId()).last("limit 1"));
+				if (claudeCodeUser != null) {
+					claudeCodeService.updateClaudeCodeUserPackageInfo(claudeCodeUser, relation.getExpiryTime(), null);
+				}
+			}
 		}
 		return GatewayResponse.SUCCESS.newBuilder().toResult("增加车票有效期成功");
 	}

+ 19 - 4
netflix-web/src/main/java/com/cyksj/web/controller/sys/FrontProblemCollectRecordController.java

@@ -1,10 +1,13 @@
 package com.cyksj.web.controller.sys;
 
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.util.Jsons;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.manage.sys.FrontProblemCollectRecordMapper;
 import com.cyksj.model.entity.FrontProblemCollectRecord;
+import com.cyksj.service.verify.ApiVerifyService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.util.MapUtils;
@@ -29,8 +32,14 @@ public class FrontProblemCollectRecordController {
 
 	private final BeanSearcher beanSearcher;
 
-	@PostMapping
-	public Result saveProblem(@RequestBody FrontProblemCollectRecord record) {
+	private final ApiVerifyService apiVerifyService;
+
+	@PostMapping("/save")
+	public Result saveProblem(@RequestBody FrontProblemCollectRecord record) throws Exception {
+		Boolean b = apiVerifyService.verifyApiDo(Jsons.toJson(record));
+		if (!b) {
+			return GatewayResponse.SUCCESS.newBuilder().toResult();
+		}
 		String errorMsg = record.getErrorMsg();
 		String track = record.getTrack();
 		String handle = record.getHandle();
@@ -48,7 +57,13 @@ public class FrontProblemCollectRecordController {
 			isFlag = true;
 		}
 		if (isFlag) {
-			recordMapper.insert(record);
+			Integer selectCount = 0;
+			if (StrUtil.isNotBlank(record.getErrorMsg())) {
+				selectCount = recordMapper.selectCount(Wrappers.lambdaQuery(FrontProblemCollectRecord.class).eq(FrontProblemCollectRecord::getErrorMsg, record.getErrorMsg()));
+			}
+			if (selectCount == 0) {
+				recordMapper.insert(record);
+			}
 		}
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
@@ -56,7 +71,7 @@ public class FrontProblemCollectRecordController {
 	/**
 	 * 列表
 	 */
-	@GetMapping
+	@GetMapping("/get/list")
 	public Result<SearchResult<FrontProblemCollectRecord>> getRecords() {
 		SearchResult<FrontProblemCollectRecord> search = beanSearcher.search(FrontProblemCollectRecord.class, MapUtils.flatBuilder(request.getParameterMap()).build());
 		return GatewayResponse.SUCCESS.newBuilder().toResult(search);