瀏覽代碼

Merge branch 'master' into dev

# Conflicts:
#	netflix-service/src/main/java/com/cyksj/service/mange/RefreshCacheService.java
#	netflix-service/src/main/java/com/cyksj/service/mange/impl/RefreshCacheServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/user/impl/BadIntentionOpServiceImpl.java
#	netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonCategoryController.java
#	netflix-web/src/main/resources/application-dev.yml
#	netflix-web/src/main/resources/application-prd.yml
#	netflix-web/src/main/resources/application-pre.yml
zoujiajian 2 年之前
父節點
當前提交
759121c066
共有 40 個文件被更改,包括 1236 次插入95 次删除
  1. 3 1
      netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
  2. 17 0
      netflix-dao/src/main/java/com/cyksj/mapper/ChatgptUserTokenPrepareMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/GoodsDonSkuSubsidyMapper.java
  4. 2 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonMapper.java
  5. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonSubsidyRelateMapper.java
  6. 36 0
      netflix-dao/src/main/java/com/cyksj/model/entity/ChatgptUserTokenPrepare.java
  7. 49 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonSkuSubsidy.java
  8. 18 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDonSubsidyRelate.java
  9. 5 0
      netflix-dao/src/main/java/com/cyksj/model/entity/RefundOrderDon.java
  10. 34 0
      netflix-dao/src/main/java/com/cyksj/model/request/ChatGptUserTokenGenerateReq.java
  11. 5 0
      netflix-dao/src/main/java/com/cyksj/model/request/OrderPayRequest.java
  12. 5 0
      netflix-dao/src/main/java/com/cyksj/model/request/OrderRefundReq.java
  13. 37 0
      netflix-dao/src/main/java/com/cyksj/model/views/ChatgptUserTokenPrepareView.java
  14. 29 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyAvailableView.java
  15. 136 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyDetailView.java
  16. 75 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyFrontView.java
  17. 49 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyView.java
  18. 127 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSubsidyDetailView.java
  19. 6 0
      netflix-dao/src/main/java/com/cyksj/model/views/RefundOrderDonView.java
  20. 14 0
      netflix-dao/src/main/resources/mapper/ChatgptUserTokenPrepareMapper.xml
  21. 8 0
      netflix-dao/src/main/resources/mapper/OrderDonMapper.xml
  22. 43 2
      netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java
  23. 14 0
      netflix-service/src/main/java/com/cyksj/service/mange/GoodsDonSkuSubsidyService.java
  24. 11 0
      netflix-service/src/main/java/com/cyksj/service/mange/RefreshCacheService.java
  25. 32 0
      netflix-service/src/main/java/com/cyksj/service/mange/goods/GoodsDonSkuSubsidyServiceImpl.java
  26. 5 5
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  27. 6 0
      netflix-service/src/main/java/com/cyksj/service/mange/impl/RefreshCacheServiceImpl.java
  28. 1 1
      netflix-service/src/main/java/com/cyksj/service/order/OrderRefundService.java
  29. 138 72
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  30. 2 1
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderRefundServiceImpl.java
  31. 1 1
      netflix-service/src/main/java/com/cyksj/service/scheduler/impl/SchedulerServiceImpl.java
  32. 22 9
      netflix-service/src/main/java/com/cyksj/service/user/impl/BadIntentionOpServiceImpl.java
  33. 82 0
      netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java
  34. 1 1
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonCategoryController.java
  35. 1 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonSkuController.java
  36. 94 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/GoodsDonSkuSubsidyController.java
  37. 97 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/mirror/CmsMirrorController.java
  38. 0 0
      netflix-web/src/main/resources/application-dev.yml
  39. 0 0
      netflix-web/src/main/resources/application-prd.yml
  40. 5 2
      netflix-web/src/main/resources/application-pre.yml

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

@@ -17,6 +17,8 @@ public interface Constant {
 
 	String DEFAULT_NAME = "银河用户";
 
+	String YH_GPT_USER_NAME = "银河录像局";
+
 	List<String> noOrderStatus = List.of("close", "noPayment");
 
 	List<String> noOrderAllStatus = List.of("noPayment", "close", "refund");
@@ -298,5 +300,5 @@ public interface Constant {
 	/**
 	 * 设备客服活码用户分销专用
 	 */
-	Long EP_AC_CODE_ID = 5l;
+	Long EP_AC_CODE_ID = 7l;
 }

+ 17 - 0
netflix-dao/src/main/java/com/cyksj/mapper/ChatgptUserTokenPrepareMapper.java

@@ -0,0 +1,17 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.ChatgptUserTokenPrepare;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: ChatgptUserTokenPrepareMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/4/18 17:58
+ */
+public interface ChatgptUserTokenPrepareMapper extends BaseMapper<ChatgptUserTokenPrepare> {
+	void batchInsert(@Param("list") List<ChatgptUserTokenPrepare> list);
+}

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.GoodsDonSkuSubsidy;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidyMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 12:04
+ */
+public interface GoodsDonSkuSubsidyMapper extends BaseMapper<GoodsDonSkuSubsidy> {
+}

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

@@ -85,4 +85,6 @@ public interface OrderDonMapper extends BaseMapper<OrderDon> {
 	UserOrderDetailView getNumOfTagFansUser(@Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
 	UserOrderDetailView getFansToDayOrdersView(@Param("tagIdStr") String tagIdStr, @Param("date") String date);
+
+	List<Long> getPayGoodsIds(@Param("userIds") List<Long> relationUserIdList);
 }

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

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

+ 36 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/ChatgptUserTokenPrepare.java

@@ -0,0 +1,36 @@
+package com.cyksj.model.entity;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: chatgpt_user_token_papre
+ * 创建者: JavaZou
+ * 创建时间:2024/4/18 17:56
+ */
+@TableName("chatgpt_user_token_prepare")
+@Getter
+@Setter
+@ExcelIgnoreUnannotated
+public class ChatgptUserTokenPrepare extends BaseEntity{
+	private Long skuId;
+
+	private String name;
+
+	@TableField(exist = false)
+	@ExcelProperty("规格")
+	private String skuName;
+
+	private String img;
+
+	@TableField("userToken")
+	@ExcelProperty("用户token")
+	private String userToken;
+
+	private Boolean status;
+}

+ 49 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonSkuSubsidy.java

@@ -0,0 +1,49 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidy
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 11:42
+ * 商品补贴价格
+ */
+@Getter
+@Setter
+public class GoodsDonSkuSubsidy extends BaseEntity {
+	private Long goodsId;
+
+	@NotNull
+	private Long skuId;
+
+	/**
+	 * 补贴价格
+	 */
+	@NotNull
+	@Min(value = 0, message = "补贴价格不能小于0")
+	private BigDecimal price;
+
+	/**
+	 * 图片
+	 */
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private String picture;
+
+	/**
+	 * true 上架
+	 */
+	private Boolean status;
+
+	/**
+	 * true 存在
+	 */
+	private Boolean deleted;
+}

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

@@ -0,0 +1,18 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: OrderDonSubsidyRelate
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 16:26
+ */
+@Getter
+@Setter
+public class OrderDonSubsidyRelate {
+	private Long subsidyId;
+
+	private Long orderId;
+}

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

@@ -60,4 +60,9 @@ public class RefundOrderDon extends BaseEntity{
 	private Boolean isClearBalance;
 
 	private String operator;
+
+	/**
+	 * 聊天记录
+	 */
+	private String chatImg;
 }

+ 34 - 0
netflix-dao/src/main/java/com/cyksj/model/request/ChatGptUserTokenGenerateReq.java

@@ -0,0 +1,34 @@
+package com.cyksj.model.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: ChatGptUserTokenGenerateReq
+ * 创建者: JavaZou
+ * 创建时间:2024/4/18 17:49
+ */
+@Getter
+@Setter
+public class ChatGptUserTokenGenerateReq {
+	/**
+	 * 生成数量
+	 */
+	private Integer num;
+
+	/**
+	 * 名称
+	 */
+	private String name;
+
+	/**
+	 * logo
+	 */
+	private String img;
+
+	/**
+	 * 生成镜像规格
+	 */
+	private Long skuId;
+}

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

@@ -160,4 +160,9 @@ public class OrderPayRequest {
      * 是否设备满减活动优惠
      */
     private Boolean isAcReduce;
+
+    /**
+     * 百亿补贴规格id
+     */
+    private Long subsidyId;
 }

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

@@ -43,4 +43,9 @@ public class OrderRefundReq {
 	private Boolean isOnly;
 
 	private String operator;
+
+	/**
+	 * 聊天记录截图
+	 */
+	private String chatImg;
 }

+ 37 - 0
netflix-dao/src/main/java/com/cyksj/model/views/ChatgptUserTokenPrepareView.java

@@ -0,0 +1,37 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: ChatgptUserTokenPrepareView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/19 10:08
+ */
+@Getter
+@Setter
+@SearchBean(tables = "chatgpt_user_token_prepare cp inner join goods_don_sku sku on cp.sku_id = sku.id")
+public class ChatgptUserTokenPrepareView {
+	@DbField("cp.id")
+	private Long id;
+
+	@DbField("cp.name")
+	private String name;
+
+	@DbField("sku.spec_val")
+	private String skuName;
+
+	@DbField("cp.userToken")
+	private String userToken;
+
+	@DbField("cp.status")
+	private Boolean status;
+
+	@DbField("cp.created_time")
+	private Date createdTime;
+}

+ 29 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyAvailableView.java

@@ -0,0 +1,29 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidyAvailableView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/17 17:27
+ */
+@Getter
+@Setter
+@SearchBean(tables = "(select id,spec_val,price from goods_don_sku where status is true :gid:) sku left join goods_don_sku_subsidy gss on gss.sku_id = sku.id and gss.deleted is true", where = "gss.id is null")
+public class GoodsDonSkuSubsidyAvailableView {
+
+	@DbField("sku.id")
+	private Long skuId;
+
+	@DbField("sku.spec_val")
+	private String specVal;
+
+	@DbField("sku.price")
+	private BigDecimal price;
+}

+ 136 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyDetailView.java

@@ -0,0 +1,136 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidyDetailView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 14:53
+ */
+@Getter
+@Setter
+@SearchBean(tables = "goods_don_sku_subsidy gs inner join goods_don_sku sku on sku.id = gs.sku_id",
+		where = "gs.deleted is true and sku.status is true",
+		orderBy = "sku.sorted asc")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GoodsDonSkuSubsidyDetailView {
+
+	/**
+	 * 规格补贴id
+	 */
+	@DbField("gs.id")
+	private Long subsidyId;
+
+	@DbField("sku.id")
+	private Long id;
+
+	@DbField("sku.goods_id")
+	private Long goodsId;
+
+
+	@DbField("sku.sub_title")
+	private String subTitle;
+
+	/**
+	 * 商品规格 ids
+	 */
+	@DbField("sku.spec_ids")
+	private String specIds;
+
+	/**
+	 * 商品规格 value
+	 */
+	@DbField("sku.spec_val")
+	private String specVal;
+
+	/**
+	 * 商品规格 json
+	 */
+	@DbField("sku.spec_json")
+	private String specJson;
+
+	/**
+	 * 规格说明信息
+	 */
+	@DbField("sku.notify_text")
+	private String notifyText;
+
+	/**
+	 * H5标签
+	 */
+	@DbField("sku.mobile_tags")
+	private String mobileTags;
+
+	/**
+	 * 规格背景图
+	 */
+	@DbField("sku.img")
+	private String img;
+
+	/**
+	 * 规格框提示
+	 */
+	@DbField("sku.small_msg")
+	private String smallMsg;
+
+	/**
+	 * 商品预览图
+	 */
+	@DbField("gs.picture")
+	private String subsidyPicture;
+
+	/**
+	 * 商品预览图
+	 */
+	@DbField("sku.picture")
+	private String picture;
+
+	/**
+	 * 商品详情图
+	 */
+	@DbField("sku.detail")
+	private String detail;
+
+	/**
+	 * 标签
+	 */
+	@DbField("sku.tags")
+	private String tags;
+
+	/**
+	 * 价格
+	 */
+	@DbField("gs.price")
+	private BigDecimal price;
+
+	/**
+	 * 原价
+	 */
+	@DbField("sku.price")
+	private BigDecimal oriPrice;
+
+	/**
+	 * 月数
+	 */
+	@DbField("sku.months")
+	private Integer months;
+
+	/**
+	 * 天数
+	 */
+	@DbField("sku.days")
+	private Integer days;
+
+	/**
+	 * 排序
+	 */
+	@DbField("sku.sorted")
+	private Integer sorted;
+}

+ 75 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyFrontView.java

@@ -0,0 +1,75 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidyFrontView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 14:18
+ */
+@Getter
+@Setter
+@SearchBean(tables = "goods_don_sku_subsidy gs inner join goods_don_sku sku on gs.sku_id = sku.id inner join goods_don g on sku.goods_id = g.id",
+		where = "gs.status is true and gs.deleted is true and sku.status is true and g.deleted is true"
+		, groupBy = "g.id,g.title,g.tags,g.virtual_sold",
+		orderBy = "g.sort_by asc, g.id")
+public class GoodsDonSkuSubsidyFrontView {
+	@DbField("g.id")
+	private Long id;
+
+	/**
+	 * 商品名称
+	 */
+	@DbField("g.title")
+	private String title;
+
+	/**
+	 * 标签
+	 */
+	@DbField("g.tags")
+	private String tags;
+
+	/**
+	 * 缩略图
+	 */
+	@DbField("g.logo")
+	private String logo;
+
+	@DbIgnore
+	private Long skuId;
+
+	/**
+	 * 最低规格价格
+	 */
+	@DbField("min(gs.price)")
+	private BigDecimal price;
+
+	/**
+	 * 商品原价
+	 */
+	@DbIgnore
+	private BigDecimal oriPrice;
+
+	@DbIgnore
+	private String picture;
+
+	@DbIgnore
+	private Integer months;
+
+	@DbIgnore
+	private Integer days;
+
+
+	/**
+	 * 已售
+	 */
+	@DbField("g.virtual_sold")
+	private Integer sold;
+}

+ 49 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyView.java

@@ -0,0 +1,49 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidyView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 12:18
+ */
+@SearchBean(tables = "goods_don_sku_subsidy gs inner join goods_don_sku sku on sku.id = gs.sku_id inner join goods_don g on g.id = sku.goods_id",
+		where = "gs.deleted is true")
+@Getter
+@Setter
+public class GoodsDonSkuSubsidyView {
+
+	@DbField("gs.id")
+	private Long id;
+
+	@DbField("gs.sku_id")
+	private Long skuId;
+
+	@DbField("sku.spec_val")
+	private String specVal;
+
+	@DbField("g.id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	private String title;
+
+	@DbField("gs.price")
+	private BigDecimal price;
+
+	@DbField("gs.picture")
+	private String picture;
+
+	@DbField("gs.status")
+	private Boolean status;
+
+	@DbField("gs.created_time")
+	private Date createdTime;
+}

+ 127 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSubsidyDetailView.java

@@ -0,0 +1,127 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.GoodsDon;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSubsidyDetailView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 14:44
+ */
+@Getter
+@Setter
+@SearchBean(tables = "goods_don_sku_subsidy gs inner join goods_don_sku sku on gs.sku_id = sku.id inner join goods_don g on sku.goods_id = g.id",
+		where = "gs.status is true and gs.deleted is true and sku.status is true and g.deleted is true"
+		, groupBy = "g.id,g.title,g.tags,g.virtual_sold,g.sort_by",
+		orderBy = "g.sort_by asc, g.id")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GoodsDonSubsidyDetailView {
+	@DbField("g.id")
+	private Long id;
+
+	/**
+	 * 商品名称
+	 */
+	@DbField("g.title")
+	private String title;
+
+	/**
+	 * 标签
+	 */
+	@DbField("g.tags")
+	private String tags;
+
+	/**
+	 * 缩略图
+	 */
+	@DbField("g.logo")
+	private String logo;
+
+	/**
+	 * 背景图
+	 */
+	@DbField("g.img")
+	private String img;
+
+	/**
+	 * 视频封面
+	 */
+	@DbField("g.video_cover")
+	private String videoCover;
+
+	@DbField("g.banner")
+	private String banner;
+
+	/**
+	 * 商品搭配图
+	 */
+	@DbField("g.match_img")
+	private String matchImg;
+
+
+	/**
+	 * 是否贴片 false
+	 */
+	@DbField("g.is_patch")
+	private Boolean isPatch;
+
+	/**
+	 * H5标签
+	 */
+	@DbField("g.mobile_tags")
+	private String mobileTags;
+
+	/**
+	 * 类型
+	 */
+	@DbField("g.type")
+	private Integer type;
+
+	@DbField("g.second_type")
+	private Integer secondType;
+
+	@DbField("g.special_type")
+	private GoodsDon.SpecialType specialType;
+
+	/**
+	 * 最低规格价格
+	 */
+	@DbField("min(gs.price)")
+	private BigDecimal price;
+
+	/**
+	 * 已售
+	 */
+	@DbField("g.virtual_sold")
+	private Integer sold;
+
+	@DbField("g.pay_desc")
+	private String payDesc;
+
+	@DbField("g.buy_desc")
+	private String buyDesc;
+
+	@DbField("g.detail")
+	private String detail;
+
+	@DbField("g.video")
+	private String video;
+
+	@DbIgnore
+	private List<GoodsDonSkuSubsidyDetailView> skuList;
+
+	@DbIgnore
+	private GoodsDonSpecFrontView specs;
+
+	@DbIgnore
+	private OrderCommentFrontView comments;
+}

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

@@ -76,6 +76,12 @@ public class RefundOrderDonView {
 	@DbField("rd.operator")
 	private String operator;
 
+	@DbField("rd.refund_desc")
+	private String refundDesc;
+
+	@DbField("rd.chat_img")
+	private String chatImg;
+
 	@DbField("rd.created_time")
 	private Date createTime;
 }

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

@@ -0,0 +1,14 @@
+<?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.ChatgptUserTokenPrepareMapper">
+
+    <insert id="batchInsert">
+        insert into
+        chatgpt_user_token_prepare(`name`,`img`,`userToken`,`sku_id`,`created_time`,`update_time`)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.name},#{item.img},#{item.userToken},#{item.skuId},now(),now())
+        </foreach>
+    </insert>
+</mapper>

+ 8 - 0
netflix-dao/src/main/resources/mapper/OrderDonMapper.xml

@@ -487,4 +487,12 @@
             and date_format(o.created_time, '%Y-%m-%d') = date_format(cu.created_time, '%Y-%m-%d')
             and date_format(o.created_time, '%Y-%m-%d') = #{date}
     </select>
+
+    <select id="getPayGoodsIds" resultType="java.lang.Long">
+        select distinct goods_id from order_don where status not in ('close','noPayment')
+        and user_id in
+        <foreach collection="userIds" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
 </mapper>

+ 43 - 2
netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java

@@ -1,6 +1,7 @@
 package com.cyksj.service.chatgpt.impl;
 
 import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.UUID;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
@@ -89,6 +90,8 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
 
     private final BeanSearcher beanSearcher;
 
+    private final ChatgptUserTokenPrepareMapper chatgptUserTokenPrepareMapper;
+
     @Override
     public String addAccount(Account account) {
         if (isAccountExists(account)) {
@@ -349,6 +352,36 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
         return chatgptUser;
     }
 
+    /**
+     * 创建chatgptUser 无需车队
+     */
+    public ChatgptUser generateChatGptUserUnderPrepare(ChatgptUserTokenPrepare prepare) {
+        ChatgptUser chatgptUser = new ChatgptUser();
+        GoodsDonSku goodsDonSku = skuMapper.selectById(prepare.getSkuId());
+        if (goodsDonSku == null) {
+            throw BusinessRuntimeException.getInstance("车队规格不存在,请联系客服..");
+        }
+        if (goodsDonSku.getIsCar()) {
+            chatgptUser.setIsCar(true);
+            chatgptUser.setLimitNum(goodsDonSku.getGptLimitNum());
+            chatgptUser.setLimitTime(goodsDonSku.getGptLimitTime());
+        }
+        try {
+            chatgptUser.setExpireTime(DateUtil.offsetMonth(DateTime.now(), goodsDonSku.getMonths()));
+            chatgptUser.setIsPlus(1);
+            chatgptUser.setName(prepare.getName());
+            chatgptUser.setImg(prepare.getImg());
+            chatgptUser.setUserToken(prepare.getUserToken());
+            chatgptUserMapper.insert(chatgptUser);
+
+            prepare.setStatus(true);
+            chatgptUserTokenPrepareMapper.updateById(prepare);
+            log.info("用户激活userToken:{}成功", prepare.getUserToken());
+        } catch (DuplicateKeyException e) {
+        }
+        return chatgptUser;
+    }
+
     private void updateChatgptUser(GroupsRelation groupsRelation, User user, ChatgptUser chatgptUser) {
         chatgptUser.setName(user.getNickname());
         chatgptUser.setImg(getWxImg(user.getHeadimgurl(), user));
@@ -567,6 +600,14 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
     @Override
     public ChatgptUser getCarChatGptUserWithToken(String userToken) {
         ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getUserToken, userToken).last(" limit 1"));
+        if (chatgptUser == null) {
+            //是否是用户token预备账号
+            ChatgptUserTokenPrepare chatgptUserTokenPrepare = chatgptUserTokenPrepareMapper.selectOne(Wrappers.lambdaQuery(ChatgptUserTokenPrepare.class)
+                    .eq(ChatgptUserTokenPrepare::getUserToken, userToken).last("limit 1"));
+            if (chatgptUserTokenPrepare != null) {
+                chatgptUser = generateChatGptUserUnderPrepare(chatgptUserTokenPrepare);
+            }
+        }
         if (chatgptUser != null) {
             if(!chatgptUser.getIsCar()){
                 throw BusinessRuntimeException.getInstance("您非车队用户,请购买车队套餐");
@@ -658,7 +699,7 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
         lowestScorecarIds = redisService.zRangeWithScores(RedisService.key.CHATGPT_CAR_SCORES.getName(), 0L, count - 1);
         Map<Object, Double> collect = lowestScorecarIds.stream().collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));
         List<ChatgptSession> chatgptSessions = chatgptSessionMapper.selectList(Wrappers.lambdaQuery(ChatgptSession.class).in(ChatgptSession::getCarId, collect.keySet()));
-        return chatgptSessions.stream().map((chatgptSession) -> buildChatgptCarInfoView(chatgptSession.getCarId(), chatgptSession.getCarName(), chatgptSession.getIsPlus(), collect.get(chatgptSession.getCarId())))
+        return chatgptSessions.stream().map((chatgptSession)-> buildChatgptCarInfoView(chatgptSession.getCarId(),chatgptSession.getCarName(), chatgptSession.getIsPlus(), collect.get(chatgptSession.getCarId())))
                 .sorted(Comparator.comparing(ChatgptCarInfoView::getScore)).collect(Collectors.toCollection(LinkedHashSet::new));
     }
 
@@ -774,7 +815,7 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
         TASK_EXECUTOR.execute(() -> {
             Set<ZSetOperations.TypedTuple<Object>> lowestScorecarIds = redisService.zRangeWithScores(RedisService.key.CHATGPT_CAR_SCORES.getName(), 0L, -1);
             List<Object> collect = lowestScorecarIds.stream().map(ZSetOperations.TypedTuple::getValue).collect(Collectors.toList());
-            List<ChatgptSession> chatgptSessions = chatgptSessionMapper.selectList(Wrappers.lambdaQuery(ChatgptSession.class).notIn(collect.size() > 0, ChatgptSession::getCarId, collect).eq(ChatgptSession::getIsCar, true));
+            List<ChatgptSession> chatgptSessions = chatgptSessionMapper.selectList(Wrappers.lambdaQuery(ChatgptSession.class).notIn(collect.size() > 0, ChatgptSession::getCarId, collect).eq(ChatgptSession::getIsPlus, 1).eq(ChatgptSession::getIsCar, true));
             chatgptSessions.forEach((chatgptSession) -> {
                 if (!redisService.checkValueExistsInZSet(RedisService.key.CHATGPT_CAR_SCORES.getName(), chatgptSession.getCarId())) {
                     redisService.zAdd(RedisService.key.CHATGPT_CAR_SCORES.getName(), 0, chatgptSession.getCarId());

+ 14 - 0
netflix-service/src/main/java/com/cyksj/service/mange/GoodsDonSkuSubsidyService.java

@@ -0,0 +1,14 @@
+package com.cyksj.service.mange;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.GoodsDonSkuSubsidy;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidyService
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 12:13
+ */
+public interface GoodsDonSkuSubsidyService extends IService<GoodsDonSkuSubsidy> {
+	void saveOrUpdateSubsidy(GoodsDonSkuSubsidy goodsDonSkuSubsidy);
+}

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

@@ -8,7 +8,18 @@ package com.cyksj.service.mange;
  */
 public interface RefreshCacheService {
 
+	/**
+	 * 清除官网首页商品缓存
+	 */
 	void refreshYhHomePageCache();
 
+	/**
+	 * 清除首页分类缓存
+	 */
 	void refreshYhHomeCategoryPageCache();
+
+	/**
+	 * 清除补贴商品缓存
+	 */
+	void refreshGoodsSkuSubsidyPageCache();
 }

+ 32 - 0
netflix-service/src/main/java/com/cyksj/service/mange/goods/GoodsDonSkuSubsidyServiceImpl.java

@@ -0,0 +1,32 @@
+package com.cyksj.service.mange.goods;
+
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.mapper.GoodsDonSkuSubsidyMapper;
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.entity.GoodsDonSkuSubsidy;
+import com.cyksj.service.mange.GoodsDonSkuSubsidyService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidyServiceImpl
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 12:14
+ */
+@Service
+@RequiredArgsConstructor
+public class GoodsDonSkuSubsidyServiceImpl extends ServiceImpl<GoodsDonSkuSubsidyMapper, GoodsDonSkuSubsidy> implements GoodsDonSkuSubsidyService {
+	private final GoodsDonSkuMapper goodsDonSkuMapper;
+
+	@Override
+	public void saveOrUpdateSubsidy(GoodsDonSkuSubsidy goodsDonSkuSubsidy) {
+		Long skuId = goodsDonSkuSubsidy.getSkuId();
+		GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
+		Assert.notNull(sku, "选择的规格不存在");
+		goodsDonSkuSubsidy.setGoodsId(goodsDonSkuSubsidy.getGoodsId());
+		this.saveOrUpdate(goodsDonSkuSubsidy);
+	}
+}

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

@@ -345,7 +345,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         String outNo = orderRefundService.centerRefund(refundReq, orderDon);
         orderDon.setRefundDesc(refundReq.getRefundDesc());
         //记录退款信息
-        commonRefund(orderDon, refundReq.getRefundMoney(), refundReq.getOperator(), goodsDon, sku, outNo, refundType, refundReq.getIsOnly(), refundReq.getRefundBalance());
+        commonRefund(orderDon, refundReq.getRefundMoney(), refundReq.getOperator(), goodsDon, sku, outNo, refundType, refundReq.getIsOnly(), refundReq.getRefundBalance(), refundReq.getChatImg());
         //修改订单状态
         orderDon.setStatus(OrderDon.Status.refund);
         orderDonMapper.updateById(orderDon);
@@ -708,9 +708,9 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
     /**
      * 退款后 处理关联
      */
-    public void commonRefund(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType, Boolean isOnly, BigDecimal refundBalance) {
+    public void commonRefund(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType, Boolean isOnly, BigDecimal refundBalance, String chatImg) {
         TASK_POOL.execute(() -> {
-            orderRefundService.refundRecord(orderDon, refundMoney, operator, goodsDon, sku, outNo, refundType);
+            orderRefundService.refundRecord(orderDon, refundMoney, operator, goodsDon, sku, outNo, refundType, chatImg);
             //退款一次
             goodsDonStockService.upStockRelate(null, orderDon.getId(), "refund");
             try {
@@ -725,7 +725,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             }
             //退等比例
             if (isOnly != null && isOnly) {
-	            userBenefitsService.addUserBalance(orderDon.getUserId(), refundBalance, UserBalanceSourceRecord.Source.refund, orderDon.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.refund.getDesc(), true);
+                userBenefitsService.addUserBalance(orderDon.getUserId(), refundBalance, UserBalanceSourceRecord.Source.refund, orderDon.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.refund.getDesc(), true);
                 BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO);
                 orderDon.setRefundBalance(orderDonRefundBalance.add(refundBalance));
             }
@@ -1020,7 +1020,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             orderDonMapper.updateById(orderDon);
         }
 
-        orderRefundService.refundRecord(orderDon, refundMoney, orderRefundReq.getOperator(), goodsDon, sku, outNo, refundType);
+        orderRefundService.refundRecord(orderDon, refundMoney, orderRefundReq.getOperator(), goodsDon, sku, outNo, refundType, null);
     }
 
     @Override

+ 6 - 0
netflix-service/src/main/java/com/cyksj/service/mange/impl/RefreshCacheServiceImpl.java

@@ -29,4 +29,10 @@ public class RefreshCacheServiceImpl implements RefreshCacheService {
 		Set<String> keys = redisService.keys(RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "category" + "*");
 		redisService.del(keys.toArray(String[]::new));
 	}
+
+	@Override
+	public void refreshGoodsSkuSubsidyPageCache() {
+		Set<String> keys = redisService.keys(RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "subsidy" + "*");
+		redisService.del(keys.toArray(String[]::new));
+	}
 }

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/order/OrderRefundService.java

@@ -20,5 +20,5 @@ public interface OrderRefundService {
 	/**
 	 * 退款记录
 	 */
-	void refundRecord(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType);
+	void refundRecord(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType, String chatImg);
 }

+ 138 - 72
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alipay.api.AlipayApiException;
@@ -281,6 +282,10 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final OrderDonLocationRelateMapper orderDonLocationRelateMapper;
 
+	private final GoodsDonSkuSubsidyMapper goodsDonSkuSubsidyMapper;
+
+	private final OrderDonSubsidyRelateMapper orderDonSubsidyRelateMapper;
+
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
 
 	@Transactional(rollbackFor = Throwable.class)
@@ -479,10 +484,16 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		orderDon.setCouponExCode(payRequest.getCouponExCode());
 		//店铺id
 		orderDon.setYhsId(yhsId);
+		//规格补贴id
+		Long subsidyId = payRequest.getSubsidyId();
+		if (subsidyId != null) {
+			//校验百亿补贴规格,并设置参数
+			setSubsidyOrderDonInfo(subsidyId, user, orderDon);
+		}
 		if (relation != null && relation.getStatus() == GroupsRelation.Status.outside) {
 			orderDon.setIsOt(true);
 		}
-		if (orderDon.getYhsId() == 0) {
+		if (orderDon.getYhsId() == 0 && subsidyId == null) {
 			//虚拟商品订单,是否是分销订单
 			setDistributeOrderMark(orderDon, goodsDon.getType(), user.getId());
 		}
@@ -494,77 +505,15 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		}
 		if (sku != null) {
 			//扣除使用优惠券、余额的订单金额
-			deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon.getType(), payRequest.getGcCash(), payRequest.getGcpIds(), payRequest.getIsAcReduce());
+			deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon.getType(), payRequest.getGcCash(), payRequest.getGcpIds(), payRequest.getIsAcReduce(), subsidyId);
 		}
 
 		if (isSpecificPrice && (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0 || orderDon.getMoney().compareTo(specificPrice) != 0)) {
 			throw BusinessRuntimeException.getInstance("专属价格不支持使用其他优惠");
 		}
 		orderDon.setPayDesc(goodsDon.getPayDesc());
-		StringBuilder payTitle = new StringBuilder();
-		payTitle.append(goodsDon.getTitle());
-		if (sku != null) {
-			payTitle.append(sku.getSpecVal());
-		}
-		if (isGiftCardPay.get()) {
-			//礼品卡规格
-			Map<Long, Integer> giftCardPayNumMap = new ConcurrentHashMap<>();
-			giftCards.stream().forEach(data -> {
-				if (data.getNum() <= 0) {
-					return;
-				}
-				giftCardPayNumMap.putIfAbsent(data.getGcId(), data.getNum());
-			});
-			if (giftCardPayNumMap.isEmpty()) {
-				throw BusinessRuntimeException.getInstance("请选择要购买礼品卡的数量");
-			}
-			List<GiftCardGoodsSkuFrontView> giftCardViews = beanSearcher.searchAll(GiftCardGoodsSkuFrontView.class, MapUtils.builder().field(GiftCardGoodsSkuFrontView::getId, giftCardPayNumMap.keySet()).op(Operator.InList).build());
-			if (giftCardViews.size() != giftCards.size()) {
-				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
-			}
-			payTitle.append("购买详情:");
-			BigDecimal gift_card_pay_money = BigDecimal.ZERO;
-			for (GiftCardGoodsSkuFrontView data : giftCardViews) {
-				//礼品卡数量
-				Integer num = giftCardPayNumMap.get(data.getId());
-				data.setGcNum(num);
-				data.setGcShowType(gcPayInfo.getGcShowType());
-				data.setGcImg(gcPayInfo.getGcImg());
-				gift_card_pay_money = gift_card_pay_money.add(data.getPrice().multiply(BigDecimal.valueOf(num)));
-
-				//礼品卡关系
-				if (!payTitle.toString().endsWith("购买详情:")) {
-					payTitle.append(" + ");
-				}
-				String gcDetail;
-				if (data.getGcType() == 1) {
-					gcDetail = String.format("%s张现金卡%s%s", num, Constant.CN_CYS, data.getCash().divide(BigDecimal.valueOf(100)));
-					payTitle.append(gcDetail);
-				} else {
-					gcDetail = String.format("%s张虚拟卡%s%s", num, data.getGcGoodsTitle(), data.getGcSpecVal());
-					payTitle.append(gcDetail);
-				}
-			}
-			gcPayInfo.setGcPayDetail(giftCardViews);
-
-			//调整礼品卡金额
-			if (gift_card_pay_money.compareTo(orderDon.getMoney()) > 0) {
-				orderDon.setMoney(gift_card_pay_money);
-				orderDon.setRealMoney(gift_card_pay_money);
-			}
-		}
-		if (orderDon.getIsDp()) {
-			List<GoodsDonSkuView> dp_skuViewList = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, dpSkuIds).op(Operator.InList).build());
-			if (dp_skuViewList.size() != dpSkuIds.size()) {
-				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新下单");
-			}
-			dp_skuViewList.forEach(dp_SkuView -> {
-				payTitle.append(" + ");
-				payTitle.append(dp_SkuView.getGoodsTitle());
-				payTitle.append(dp_SkuView.getSpecVal());
-			});
-		}
-		orderDon.setPayTitle(payTitle.toString());
+		//设置订单支付商品信息
+		setOrderDonPayTile(isGiftCardPay, gcPayInfo, giftCards, orderDon, goodsDon, sku, dpSkuIds);
 		//下单手机号
 		orderDon.setPhone(orderPhone);
 		this.saveOrUpdate(orderDon);
@@ -647,6 +596,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		}
 		//记录订单ip关联
 		recordOrderDonLocationRelate(orderDon.getId(), payRequest.getIp());
+		//记录补贴订单关联
+		recordOrderDonSubsidyRelate(orderDon.getId(), subsidyId);
 		return orderDon;
 	}
 
@@ -1005,7 +956,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		}
 		orderDon.setRealMoney(orderDon.getMoney());
 		//扣除使用优惠券、余额的订单金额
-		deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon.getType(), payRequest.getGcCash(), payRequest.getGcpIds(), false);
+		deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon.getType(), payRequest.getGcCash(), payRequest.getGcpIds(), false, null);
 		this.saveOrUpdate(orderDon);
 		if (orderDon.getStatus() == OrderDon.Status.noPayment) {
 			jobManager.addJob(EXPIRY_TIME, () -> {
@@ -2093,13 +2044,13 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 	/**
 	 * 使用优惠营销 订单金额抵扣
 	 */
-	public void deductOrderMoney(OrderDon orderDon, CouponUser couponUser, BigDecimal balance, User user, BigDecimal skuMoney, Integer goodsType, BigDecimal gcCash, List<Long> gcpIds, Boolean isAcReduce) {
+	public void deductOrderMoney(OrderDon orderDon, CouponUser couponUser, BigDecimal balance, User user, BigDecimal skuMoney, Integer goodsType, BigDecimal gcCash, List<Long> gcpIds, Boolean isAcReduce, Long subsidyId) {
 		if (gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0 && couponUser != null) {
 			throw BusinessRuntimeException.getInstance("现金卡不能与其他优惠叠加使用");
 		}
 		BigDecimal first_money = orderDon.getMoney();
 		//礼品卡现金支付 不参与其他优惠
-		if (gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0) {
+		if (subsidyId == null && gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0) {
 			if (CollUtil.isEmpty(gcpIds)) {
 				throw BusinessRuntimeException.getInstance("礼品卡现金支付参数异常");
 			}
@@ -2151,7 +2102,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			return;
 		}
 		//存在优惠券
-		if (couponUser != null) {
+		if (couponUser != null && subsidyId == null) {
 			Long couponId = couponUser.getCouponId();
 			Coupon coupon = couponMapper.getCouponById(couponId);
 			BigDecimal couponMoney = null;
@@ -2191,7 +2142,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			orderDon.setCouponUserId(couponUser.getId());
 		}
 		//特殊渠道推广优惠. 360
-		if (orderDon.getPopularizeId() != null && orderDon.getPopularizeId() != 0L) {
+		if (subsidyId == null && orderDon.getPopularizeId() != null && orderDon.getPopularizeId() != 0L) {
 			String name = channelPopularizeMapper.selectChannelByPid(orderDon.getPopularizeId());
 			//使用了优惠券 不再使用360渠道 折扣
 			if (couponUser == null && goodsType == 1) {
@@ -2813,7 +2764,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		clearUserLockingRelation(groupsRelationMapper.selectById(orderDon.getRelationId()), orderDon);
 
 		//记录退款
-		orderRefundService.refundRecord(orderDon, orderRefundReq.getRefundMoney(), null, goodsDon, sku, outNo, orderDon.getType().getType());
+		orderRefundService.refundRecord(orderDon, orderRefundReq.getRefundMoney(), null, goodsDon, sku, outNo, orderDon.getType().getType(), null);
 		return;
 	}
 
@@ -3008,4 +2959,119 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		orderDonLocationRelate.setIp(ip);
 		orderDonLocationRelateMapper.insert(orderDonLocationRelate);
 	}
+
+	private void recordOrderDonSubsidyRelate(Long orderId, Long subsidyId) {
+		if (subsidyId != null) {
+			OrderDonSubsidyRelate orderDonSubsidyRelate = new OrderDonSubsidyRelate();
+			orderDonSubsidyRelate.setSubsidyId(subsidyId);
+			orderDonSubsidyRelate.setOrderId(orderId);
+			orderDonSubsidyRelateMapper.insert(orderDonSubsidyRelate);
+		}
+	}
+
+	/**
+	 * 设置订单支付商品属性
+	 */
+	public void setOrderDonPayTile(AtomicBoolean isGiftCardPay, GiftCardDto gcPayInfo, List<GiftCardPayReq> giftCards, OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku, List<Long> dpSkuIds) {
+		StringBuilder payTitle = new StringBuilder();
+		payTitle.append(goodsDon.getTitle());
+		if (sku != null) {
+			payTitle.append(sku.getSpecVal());
+		}
+		if (isGiftCardPay.get()) {
+			//礼品卡规格
+			Map<Long, Integer> giftCardPayNumMap = new ConcurrentHashMap<>();
+			giftCards.stream().forEach(data -> {
+				if (data.getNum() <= 0) {
+					return;
+				}
+				giftCardPayNumMap.putIfAbsent(data.getGcId(), data.getNum());
+			});
+			if (giftCardPayNumMap.isEmpty()) {
+				throw BusinessRuntimeException.getInstance("请选择要购买礼品卡的数量");
+			}
+			List<GiftCardGoodsSkuFrontView> giftCardViews = beanSearcher.searchAll(GiftCardGoodsSkuFrontView.class, MapUtils.builder().field(GiftCardGoodsSkuFrontView::getId, giftCardPayNumMap.keySet()).op(Operator.InList).build());
+			if (giftCardViews.size() != giftCards.size()) {
+				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
+			}
+			payTitle.append("购买详情:");
+			BigDecimal gift_card_pay_money = BigDecimal.ZERO;
+			for (GiftCardGoodsSkuFrontView data : giftCardViews) {
+				//礼品卡数量
+				Integer num = giftCardPayNumMap.get(data.getId());
+				data.setGcNum(num);
+				data.setGcShowType(gcPayInfo.getGcShowType());
+				data.setGcImg(gcPayInfo.getGcImg());
+				gift_card_pay_money = gift_card_pay_money.add(data.getPrice().multiply(BigDecimal.valueOf(num)));
+
+				//礼品卡关系
+				if (!payTitle.toString().endsWith("购买详情:")) {
+					payTitle.append(" + ");
+				}
+				String gcDetail;
+				if (data.getGcType() == 1) {
+					gcDetail = String.format("%s张现金卡%s%s", num, Constant.CN_CYS, data.getCash().divide(BigDecimal.valueOf(100)));
+					payTitle.append(gcDetail);
+				} else {
+					gcDetail = String.format("%s张虚拟卡%s%s", num, data.getGcGoodsTitle(), data.getGcSpecVal());
+					payTitle.append(gcDetail);
+				}
+			}
+			gcPayInfo.setGcPayDetail(giftCardViews);
+
+			//调整礼品卡金额
+			if (gift_card_pay_money.compareTo(orderDon.getMoney()) > 0) {
+				orderDon.setMoney(gift_card_pay_money);
+				orderDon.setRealMoney(gift_card_pay_money);
+			}
+		}
+		if (orderDon.getIsDp()) {
+			List<GoodsDonSkuView> dp_skuViewList = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, dpSkuIds).op(Operator.InList).build());
+			if (dp_skuViewList.size() != dpSkuIds.size()) {
+				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新下单");
+			}
+			dp_skuViewList.forEach(dp_SkuView -> {
+				payTitle.append(" + ");
+				payTitle.append(dp_SkuView.getGoodsTitle());
+				payTitle.append(dp_SkuView.getSpecVal());
+			});
+		}
+		orderDon.setPayTitle(payTitle.toString());
+	}
+
+	/**
+	 * 百亿补贴订单
+	 */
+	private void setSubsidyOrderDonInfo(Long subsidyId, User user, OrderDon orderDon) {
+		Assert.notNull(user, "用户不存在");
+		GoodsDonSkuSubsidy goodsDonSkuSubsidy = goodsDonSkuSubsidyMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSkuSubsidy.class)
+				.eq(GoodsDonSkuSubsidy::getId, subsidyId)
+				.eq(GoodsDonSkuSubsidy::getDeleted, 1)
+				.last("limit 1"));
+		if (goodsDonSkuSubsidy == null || !goodsDonSkuSubsidy.getDeleted()) {
+			throw BusinessRuntimeException.getInstance("商品不存在");
+		}
+		if (!goodsDonSkuSubsidy.getStatus()) {
+			throw BusinessRuntimeException.getInstance("规格已下架");
+		}
+		Long skuId = goodsDonSkuSubsidy.getSkuId();
+		Long paySkuId = orderDon.getSkuId();
+		if (!ObjectUtil.equal(skuId, paySkuId)) {
+			throw BusinessRuntimeException.getInstance("规格不存在");
+		}
+		BigDecimal price = goodsDonSkuSubsidy.getPrice();
+		if (price.compareTo(BigDecimal.ZERO) <= 0) {
+			throw BusinessRuntimeException.getInstance("商品价格异常..");
+		}
+		//是否购买过该规格
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(user.getId(), user);
+		Integer selectCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
+				.eq(OrderDon::getSkuId, skuId)
+				.in(OrderDon::getUserId, userIdList)
+				.ne(OrderDon::getStatus, OrderDon.Status.close));
+		if (selectCount > 0) {
+			throw BusinessRuntimeException.getInstance("只可购买一次该补贴规格");
+		}
+		orderDon.setMoney(price);
+	}
 }

+ 2 - 1
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderRefundServiceImpl.java

@@ -84,7 +84,7 @@ public class OrderRefundServiceImpl implements OrderRefundService {
 	}
 
 	@Override
-	public void refundRecord(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType) {
+	public void refundRecord(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType, String chatImg) {
 		RefundOrderDon refund = new RefundOrderDon();
 		refund.setOrderId(orderDon.getId());
 		refund.setOutRefundNo(outRefundNo);
@@ -100,6 +100,7 @@ public class OrderRefundServiceImpl implements OrderRefundService {
 		refund.setRefundMethod(orderDon.getType().name());
 		refund.setGoodsType(goodsDon == null ? 0 : goodsDon.getType());
 		refund.setOperator(operator);
+		refund.setChatImg(chatImg);
 		//退款方式
 		if (StrUtil.isNotBlank(refundType) && refundType.equals(OrderDon.Type.BALANCE.getType())) {
 			refund.setRefundMethod(refundType);

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/scheduler/impl/SchedulerServiceImpl.java

@@ -220,7 +220,7 @@ public class SchedulerServiceImpl implements SchedulerService {
 							if (sku == null) return;
 							skuMap.putIfAbsent(orderDon.getSkuId(), sku);
 						}
-						orderRefundService.refundRecord(orderDon, orderDon.getRefundMoney(), null, goodsDon, sku, StrUtil.EMPTY, "balance");
+						orderRefundService.refundRecord(orderDon, orderDon.getRefundMoney(), null, goodsDon, sku, StrUtil.EMPTY, "balance", null);
 						return;
 					}
 					changeTickerRelation(item_groupsId, relationView, source, relationView.getYhsId());

+ 22 - 9
netflix-service/src/main/java/com/cyksj/service/user/impl/BadIntentionOpServiceImpl.java

@@ -22,9 +22,12 @@ import java.util.Map;
 @Slf4j
 public class BadIntentionOpServiceImpl implements BadIntentionOpService {
 
-    @Value("${smsVerify.apiKey}")
+    @Value("${smsVerify.apikey}")
     String apiKey;
 
+    @Value("${smsVerify.shoppingApikey}")
+    String shoppingApikey;
+
     private final RedisService redisService;
 
     private static final int PHONE_CODE_GET_NUM_DAY_LIMIT = 30;
@@ -41,15 +44,16 @@ public class BadIntentionOpServiceImpl implements BadIntentionOpService {
         }
         if (StringUtils.isBlank(verifyCode)) {
             throw BusinessRuntimeException.getInstance("人机校验不通过");
-        }else {
-            Map<String, Object> parmas = new HashMap<>();
-            parmas.put("api_key", apiKey);
-            parmas.put("response", verifyCode);
-            String post = HttpUtil.post(VERIFY_URL, parmas);
-            JSONObject res = new JSONObject(post);
+        } else {
+            //银河官网
+            JSONObject res = checkVerifyCode(apiKey, verifyCode);
             if (!res.getStr("res").equals("success")) {
-                log.error("手机号:{}验证码校验不通过 res:{}", phone, res);
-                throw BusinessRuntimeException.getInstance("人机校验不通过");
+                //小店域名
+                res = checkVerifyCode(shoppingApikey, verifyCode);
+                if (!res.getStr("res").equals("success")) {
+                    log.error("手机号:{}验证码校验不通过 res:{}", phone, res);
+                    throw BusinessRuntimeException.getInstance("人机校验不通过");
+                }
             }
         }
         String dayKey = RedisService.key.PHONE_CODE_USER_NUM_KEY_DAY.getName() + phone;
@@ -95,4 +99,13 @@ public class BadIntentionOpServiceImpl implements BadIntentionOpService {
             redisService.setNx(RetryTimeKey, 1, RedisService.key.PHONE_CODE_RETRY_TIME_KEY.getTimeout());
         }
     }
+
+    public JSONObject checkVerifyCode(String apiKey, String verifyCode) {
+        Map<String, Object> parmas = new HashMap<>();
+        parmas.put("api_key", apiKey);
+        parmas.put("response", verifyCode);
+        String post = HttpUtil.post(VERIFY_URL, parmas);
+        JSONObject res = new JSONObject(post);
+        return res;
+    }
 }

+ 82 - 0
netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java

@@ -26,6 +26,7 @@ import com.cyksj.redis.RedisService;
 import com.cyksj.service.goods.GoodsDonFrontService;
 import com.cyksj.service.home.ClickRecordFrontService;
 import com.cyksj.service.shop.YhShopFrontService;
+import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.user.UserService;
 import com.cyksj.web.util.StpUserUtil;
 import com.ejlchina.searcher.BeanSearcher;
@@ -78,6 +79,8 @@ public class GoodsDonController {
 
 	private final GoodsDonFrontService goodsDonFrontService;
 
+	private final UserBindRelationService userBindRelationService;
+
 	/**
      * 获取平台商品分类
      */
@@ -1134,4 +1137,83 @@ public class GoodsDonController {
 		}
 		return GatewayResponse.SUCCESS.newBuilder().toResult(list);
 	}
+
+	/**
+	 * 百亿补贴
+	 * 补贴规格列表
+	 */
+	@GetMapping("/get/subsidy")
+	public Result<List<GoodsDonSkuSubsidyFrontView>> getSubsidyGoods() {
+		String key = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "subsidy";
+		Object o = redisService.get(key);
+		if (o == null) {
+			List<GoodsDonSkuSubsidyFrontView> subsidyList = beanSearcher.searchAll(GoodsDonSkuSubsidyFrontView.class, MapUtils.builder().build());
+			subsidyList.forEach(e -> {
+				Optional.ofNullable(beanSearcher.searchFirst(GoodsDonSkuSubsidyDetailView.class, MapUtils.builder().field(GoodsDonSkuSubsidyDetailView::getGoodsId, e.getId()).field(GoodsDonSkuSubsidyDetailView::getPrice, e.getPrice()).build())).ifPresent(sku -> {
+					e.setOriPrice(sku.getOriPrice());
+					e.setMonths(sku.getMonths());
+					e.setDays(sku.getDays());
+					e.setSkuId(sku.getId());
+					e.setPicture(sku.getSubsidyPicture());
+				});
+			});
+			redisService.setNx(key, subsidyList, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
+			o = redisService.get(key);
+		}
+		List<GoodsDonSkuSubsidyFrontView> subsidyList = Jsons.parseList(o, GoodsDonSkuSubsidyFrontView.class);
+		if (CollUtil.isEmpty(subsidyList)) {
+			return GatewayResponse.SUCCESS.newBuilder().toResult(subsidyList);
+		}
+		Long userId = StpUserUtil.getUserIdAfterLogin();
+		if (userId != null) {
+			List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
+			//过滤用户已经购买过平台
+			List<Long> goodsIds = orderDonMapper.getPayGoodsIds(relationUserIdList);
+			if (CollUtil.isNotEmpty(goodsIds)) {
+				subsidyList = subsidyList.stream().filter(data -> !goodsIds.contains(data.getId())).collect(Collectors.toList());
+			}
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult(subsidyList);
+	}
+
+	/**
+	 * 百亿补贴规格详情
+	 */
+	@GetMapping("/get/subsidy/detail/{id}")
+	public Result<GoodsDonSubsidyDetailView> getSubsidyDetailById(@PathVariable Long id) throws Exception {
+		String goodsDetailKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "subsidy:detail:" + id;
+		Object o = redisService.get(goodsDetailKey);
+		GoodsDonSubsidyDetailView subsidyDetail = null;
+		if (o == null) {
+			subsidyDetail = beanSearcher.searchFirst(GoodsDonSubsidyDetailView.class, MapUtils.builder().field(GoodsDonSubsidyDetailView::getId, id).build());
+			if (subsidyDetail == null) {
+				return GatewayResponse.SUCCESS.newBuilder().toResult();
+			}
+
+			subsidyDetail.setSpecs(beanSearcher.searchFirst(GoodsDonSpecFrontView.class, MapUtils.builder().field(GoodsDonSpecFrontView::getGoodsId, subsidyDetail.getId()).build()));
+			MapBuilder builder = MapUtils.builder().field(GoodsDonSkuSubsidyDetailView::getGoodsId, subsidyDetail.getId());
+			subsidyDetail.setSkuList(beanSearcher.searchAll(GoodsDonSkuSubsidyDetailView.class, builder.build()));
+			Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
+					.eq(OrderDon::getGoodsId, subsidyDetail.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
+			subsidyDetail.setSold(sold + subsidyDetail.getSold());
+
+			redisService.setNx(goodsDetailKey, Jsons.toJson(subsidyDetail), RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 60 * RandomUtil.randomInt(10));
+		}
+		if (subsidyDetail == null) {
+			o = redisService.get(goodsDetailKey);
+			subsidyDetail = Jsons.parseObject(o.toString(), GoodsDonSubsidyDetailView.class);
+		}
+
+		return GatewayResponse.SUCCESS.newBuilder().toResult(subsidyDetail);
+	}
+
+	/**
+	 * 可选百亿补贴规格列表
+	 */
+	@GetMapping("/get/available/subsidy/sku/{goodsId}")
+	public Result<List<GoodsDonSkuSubsidyAvailableView>> getAvailableSubsidySku(@PathVariable Long goodsId) {
+		List<GoodsDonSkuSubsidyAvailableView> goodsDonSkuSubsidyAvailableViews = beanSearcher.searchAll(GoodsDonSkuSubsidyAvailableView.class, MapUtils.builder().put("gid", String.format(" and goods_id = %s", goodsId)).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonSkuSubsidyAvailableViews);
+	}
+
 }

+ 1 - 1
netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonCategoryController.java

@@ -164,7 +164,7 @@ public class CmsGoodsDonCategoryController {
 		});
 		if (CollUtil.isNotEmpty(updateList)) {
 			goodsDonCategoryRelateService.updateBatchById(updateList);
-			refreshCacheService.refreshYhHomePageCache();
+			refreshCacheService.refreshYhHomeCategoryPageCache();
 		}
 
 		return GatewayResponse.SUCCESS.newBuilder().toResult();

+ 1 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonSkuController.java

@@ -254,6 +254,7 @@ public class CmsGoodsDonSkuController {
         goodsDonSkuService.update(null, Wrappers.lambdaUpdate(GoodsDonSku.class)
                 .eq(GoodsDonSku::getId, id)
                 .set(GoodsDonSku::getSorted, sorted));
+        refreshCacheService.refreshYhHomePageCache();
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
 }

+ 94 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/GoodsDonSkuSubsidyController.java

@@ -0,0 +1,94 @@
+package com.cyksj.web.controller.manage.goods;
+
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.model.entity.GoodsDonSkuSubsidy;
+import com.cyksj.model.views.GoodsDonSkuSubsidyView;
+import com.cyksj.service.mange.GoodsDonSkuSubsidyService;
+import com.cyksj.service.mange.RefreshCacheService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/** admin/百亿补贴
+ * 项目名: yhlxj2
+ * 文件名: GoodsDonSkuSubsidyController
+ * 创建者: JavaZou
+ * 创建时间:2024/4/11 12:05
+ */
+@Slf4j
+@RequiredArgsConstructor
+@RequestMapping("/manage/goods/sku/subsidy")
+@RestController
+public class GoodsDonSkuSubsidyController {
+	private final GoodsDonSkuSubsidyService goodsDonSkuSubsidyService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
+
+	private final RefreshCacheService refreshCacheService;
+
+	/**
+	 * 新增补贴规格
+	 */
+	@PostMapping("/insert")
+	public Result<String> insertGoodsDonSkuSubsidy(@RequestBody @Validated GoodsDonSkuSubsidy goodsDonSkuSubsidy) {
+		goodsDonSkuSubsidyService.saveOrUpdateSubsidy(goodsDonSkuSubsidy);
+		refreshCacheService.refreshGoodsSkuSubsidyPageCache();
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 更新补贴规格
+	 */
+	@PutMapping("/update")
+	public Result<String> updateGoodsDonSkuSubsidy(@RequestBody @Validated GoodsDonSkuSubsidy goodsDonSkuSubsidy) {
+		goodsDonSkuSubsidyService.saveOrUpdateSubsidy(goodsDonSkuSubsidy);
+		refreshCacheService.refreshGoodsSkuSubsidyPageCache();
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 删除商品补贴价格记录
+	 */
+	@DeleteMapping("/delete/{id}")
+	public Result<String> deleteGoodsDonSkuSubsidy(@PathVariable Long id) {
+		GoodsDonSkuSubsidy byId = goodsDonSkuSubsidyService.getById(id);
+		if (byId != null && byId.getDeleted()) {
+			byId.setDeleted(false);
+			goodsDonSkuSubsidyService.updateById(byId);
+			refreshCacheService.refreshGoodsSkuSubsidyPageCache();
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 上下架补贴规格
+	 */
+	@PutMapping("/status/{id}")
+	public Result<String> updateStatusById(@PathVariable Long id) {
+		GoodsDonSkuSubsidy byId = goodsDonSkuSubsidyService.getById(id);
+		if (byId != null) {
+			byId.setStatus(!byId.getStatus());
+			goodsDonSkuSubsidyService.updateById(byId);
+			refreshCacheService.refreshGoodsSkuSubsidyPageCache();
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 查询商品补贴价格记录 列表
+	 */
+	@GetMapping("/get")
+	public Result<SearchResult<GoodsDonSkuSubsidyView>> getGoodsDonSkuSubsidy() {
+		SearchResult<GoodsDonSkuSubsidyView> search = beanSearcher.search(GoodsDonSkuSubsidyView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+}

+ 97 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/mirror/CmsMirrorController.java

@@ -0,0 +1,97 @@
+package com.cyksj.web.controller.manage.mirror;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.UUID;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.cyksj.common.constant.Constant;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.ChatgptUserTokenPrepareMapper;
+import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.model.entity.ChatgptUserTokenPrepare;
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.request.ChatGptUserTokenGenerateReq;
+import com.cyksj.model.views.ChatgptUserTokenPrepareView;
+import com.cyksj.web.util.EasyExcelUtils;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import com.google.common.collect.Lists;
+import lombok.RequiredArgsConstructor;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: CmsMirrorController
+ * 创建者: JavaZou
+ * 创建时间:2024/4/18 17:45
+ */
+@RestController
+@RequestMapping("/manage/mirror/gpt")
+@RequiredArgsConstructor
+public class CmsMirrorController {
+
+	private final GoodsDonSkuMapper goodsDonSkuMapper;
+
+	private final ChatgptUserTokenPrepareMapper chatgptUserTokenPrepareMapper;
+
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
+
+	/**
+	 * 生成并导出gpt会话
+	 */
+	@GetMapping("/generateAndExport/gpt/session")
+	@Transactional(rollbackFor = Exception.class)
+	public void generateAndExportGptSession(ChatGptUserTokenGenerateReq gptUserTokenGenerateReq, HttpServletResponse response) {
+		Integer num = gptUserTokenGenerateReq.getNum();
+		if (num == null || num <= 0) {
+			throw new IllegalArgumentException("生成数量必须大于0");
+		}
+		Long skuId = gptUserTokenGenerateReq.getSkuId();
+		GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
+		if (sku == null) {
+			throw new IllegalArgumentException("镜像规格不存在");
+		}
+		if (!sku.getIsCar()) {
+			throw new IllegalArgumentException("不是gpt车队规格");
+		}
+		String name = Optional.ofNullable(gptUserTokenGenerateReq.getName()).orElse(Constant.YH_GPT_USER_NAME);
+		String img = Optional.ofNullable(gptUserTokenGenerateReq.getName()).orElse(Constant.DEFAULT_HEAD_IMG);
+		List<ChatgptUserTokenPrepare> prepares = new ArrayList<>(num);
+		ChatgptUserTokenPrepare chatgptUserTokenPrepare = null;
+
+		for (int i = 0; i < num; i++) {
+			chatgptUserTokenPrepare = new ChatgptUserTokenPrepare();
+			chatgptUserTokenPrepare.setUserToken(UUID.randomUUID().toString());
+			chatgptUserTokenPrepare.setName(name);
+			chatgptUserTokenPrepare.setImg(img);
+			chatgptUserTokenPrepare.setSkuId(skuId);
+			chatgptUserTokenPrepare.setSkuName(sku.getSpecVal());
+			prepares.add(chatgptUserTokenPrepare);
+		}
+		if (CollUtil.isNotEmpty(prepares)) {
+			Lists.partition(prepares, 500).forEach(e -> chatgptUserTokenPrepareMapper.batchInsert(e));
+		}
+		EasyExcelUtils.createExcelStreamMutilByEasyExcel(response, ChatgptUserTokenPrepare.class, prepares, "用户token","用户token", ExcelTypeEnum.XLSX, null);
+	}
+
+	/**
+	 * 镜像车队token 列表
+	 */
+	@GetMapping("/get/list")
+	public Result<SearchResult<ChatgptUserTokenPrepareView>> getList() {
+		SearchResult<ChatgptUserTokenPrepareView> search = beanSearcher.search(ChatgptUserTokenPrepareView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.orderBy(ChatgptUserTokenPrepareView::getId).desc()
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+}

文件差異過大導致無法顯示
+ 0 - 0
netflix-web/src/main/resources/application-dev.yml


文件差異過大導致無法顯示
+ 0 - 0
netflix-web/src/main/resources/application-prd.yml


+ 5 - 2
netflix-web/src/main/resources/application-pre.yml

@@ -178,7 +178,10 @@ advertisementwxapp:
   notify: https://xue.niupian.com.cn/8081/api/
 
 chatgpt:
-  domain: "https://gpt.claudeplus.com.cn"
+  domain: "https://gpt.galaxydvd.com"
+  car:
+    domain: "https://car.galaxydvd.com"
 
 smsVerify:
-  apiKey: bc0737b7339ab0f275f954a161fdb313
+  apikey: bc0737b7339ab0f275f954a161fdb313
+  shoppingApikey: 72d4ff765b6c962f35c9a4125100680d

部分文件因文件數量過多而無法顯示