Ver código fonte

Merge remote-tracking branch 'origin/master'

zoujiajian 2 anos atrás
pai
commit
6b3550449d
53 arquivos alterados com 939 adições e 318 exclusões
  1. 5 0
      netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
  2. 1 1
      netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java
  3. 18 0
      netflix-dao/src/main/java/com/cyksj/mapper/DistributeGoodsSkuAlertMapper.java
  4. 1 1
      netflix-dao/src/main/java/com/cyksj/mapper/GroupsRelationMapper.java
  5. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeBusinessGeneralRateMapper.java
  6. 2 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeBusinessRateMapper.java
  7. 5 0
      netflix-dao/src/main/java/com/cyksj/mapper/stock/GoodsDonStockRecordMapper.java
  8. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/stock/GoodsSkuStockRelateChangeRecordMapper.java
  9. 18 0
      netflix-dao/src/main/java/com/cyksj/model/entity/DistributeGoodsSkuAlert.java
  10. 4 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonStock.java
  11. 11 1
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonStockRecord.java
  12. 2 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsSkuStockRelate.java
  13. 39 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsSkuStockRelateChangeRecord.java
  14. 7 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GroupsTrips.java
  15. 35 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeBusinessGeneralRate.java
  16. 1 1
      netflix-dao/src/main/java/com/cyksj/model/entity/YhShopUserPlatDistributeRate.java
  17. 4 0
      netflix-dao/src/main/java/com/cyksj/model/excel/ExcelManageAccountData.java
  18. 3 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/AccountView.java
  19. 3 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonBackView.java
  20. 1 1
      netflix-dao/src/main/java/com/cyksj/model/views/BusinessDistributeRateView.java
  21. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/ExchangeCodeView.java
  22. 9 5
      netflix-dao/src/main/java/com/cyksj/model/views/StatisticsStockView.java
  23. 2 2
      netflix-dao/src/main/java/com/cyksj/model/views/UserBusinessDefaultRateConfigView.java
  24. 63 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeBusinessGeneralRateView.java
  25. 1 1
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeBusinessRateRecordView.java
  26. 1 1
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeRateView.java
  27. 1 1
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeView.java
  28. 1 2
      netflix-dao/src/main/java/com/cyksj/model/views/YhShopDistributeBusinessView.java
  29. 1 1
      netflix-dao/src/main/java/com/cyksj/model/views/YhShopUserBusinessDefaultRateConfigView.java
  30. 1 1
      netflix-dao/src/main/java/com/cyksj/model/views/YhShopUserDistributeBusinessRateRecordView.java
  31. 3 2
      netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml
  32. 35 1
      netflix-dao/src/main/resources/mapper/UserDistributeBusinessRateMapper.xml
  33. 1 1
      netflix-service/src/main/java/com/cyksj/redis/RedisService.java
  34. 16 6
      netflix-service/src/main/java/com/cyksj/service/distribute/impl/UserBusinessFrontServiceImpl.java
  35. 5 128
      netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java
  36. 3 2
      netflix-service/src/main/java/com/cyksj/service/mange/CmsOrderDonService.java
  37. 9 0
      netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonSpecServiceImpl.java
  38. 3 2
      netflix-service/src/main/java/com/cyksj/service/mange/group/CmsGroupServiceImpl.java
  39. 62 21
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  40. 11 1
      netflix-service/src/main/java/com/cyksj/service/mange/stock/GoodsDonStockService.java
  41. 168 17
      netflix-service/src/main/java/com/cyksj/service/mange/stock/impl/GoodsDonStockServiceImpl.java
  42. 30 0
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonPostServiceImpl.java
  43. 30 101
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  44. 6 0
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  45. 89 4
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  46. 1 1
      netflix-service/src/main/java/com/cyksj/service/scheduler/impl/SchedulerServiceImpl.java
  47. 1 0
      netflix-service/src/main/java/com/cyksj/service/shop/impl/YhShopDistributeServiceImpl.java
  48. 1 1
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
  49. 117 3
      netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java
  50. 8 4
      netflix-web/src/main/java/com/cyksj/web/controller/manage/group/CmsGroupController.java
  51. 6 4
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java
  52. 45 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/stock/StockController.java
  53. 20 0
      netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

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

@@ -222,4 +222,9 @@ public interface Constant {
 	 * AI 车票额外座位数
 	 */
 	Integer AI_EXTRACT_NUM = 5;
+
+	/**
+	 * 百度回传 过滤平台
+	 */
+	String BAIDU_POST_FILTER_GOODS_KEY = "baidu_post_filter_goods_key";
 }

+ 1 - 1
netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java

@@ -436,7 +436,7 @@ public final class StringUtil {
 		StringBuilder sb = new StringBuilder(length);
 		for (int i = 0; i < length; i++) {
 			int number = RandomUtil.randomInt(baseLength);
-			sb.append(randomStr.charAt(number));
+			sb.append(baseStr.charAt(number));
 		}
 		return sb.toString();
 	}

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/mapper/DistributeGoodsSkuAlertMapper.java

@@ -0,0 +1,18 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.DistributeGoodsSkuAlert;
+import org.apache.ibatis.annotations.Select;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributeGoodsSkuAlertMapper
+ * 创建者: JavaZou
+ * 创建时间:2023/11/8 14:10
+ */
+public interface DistributeGoodsSkuAlertMapper extends BaseMapper<DistributeGoodsSkuAlert> {
+
+	@Select("select count(*) from distribute_goods_sku_alert da inner join goods_don_sku sku on sku.id = da.sku_id and sku.status is true" +
+			" inner join goods_don g on g.id = da.goods_id and g.status is true and g.deleted is true and g.is_distribute is true")
+	Integer selectCountByCondition();
+}

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

@@ -52,7 +52,7 @@ public interface GroupsRelationMapper extends BaseMapper<GroupsRelation> {
 
 	Page<UserRecommendGoodsFrontView> getRecommendGoodsViews(@Param("page") Page<UserRecommendGoodsFrontView> page, @Param("list") List<Long> filter_goods_id, @Param("isPayNf") Boolean isPayNf);
 
-	Long getOutSideGroupsTripsRelationByGoodsId(@Param("skuId") Long skuId, @Param("beginOfDay") DateTime beginOfDay, @Param("extraNum") Integer extraNum, @Param("userId") Long userId);
+	Long getOutSideGroupsTripsRelationByGoodsId(@Param("skuId") Long skuId, @Param("beginOfDay") DateTime beginOfDay, @Param("extraNum") Integer extraNum, @Param("userId") Long userId, @Param("skuNum") Integer skuNum);
 
 	Integer selectAvailableRelation(@Param("skuId") Long skuId, @Param("skuNum") Integer skuNum);
 

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeBusinessGeneralRateMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.distribute;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserDistributeBusinessGeneralRate;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserDistributeBusinessGeneralRateMapper
+ * 创建者: JavaZou
+ * 创建时间:2023/11/8 14:46
+ */
+public interface UserDistributeBusinessGeneralRateMapper extends BaseMapper<UserDistributeBusinessGeneralRate> {
+}

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeBusinessRateMapper.java

@@ -17,4 +17,6 @@ public interface UserDistributeBusinessRateMapper extends BaseMapper<UserDistrib
 	List<Long> selectNoThisGoodsDistribute(Long goodsId);
 
 	void batchInsertDistributePlatRate(@Param("list") List<UserPlatDistributeRate> part);
+
+	void insertOrUpdateBusinessGoodsSkuRate(@Param("list") List<Long> businessIds, @Param("goodsId") Long goodsId, @Param("skuId") Long skuId, @Param("firstOrderRate") Integer firstOrderRate, @Param("renewOrderRate") Integer renewOrderRate);
 }

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/mapper/stock/GoodsDonStockRecordMapper.java

@@ -2,10 +2,15 @@ package com.cyksj.mapper.stock;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.GoodsDonStockRecord;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 
 /**
  * @author chan
  * @date 2022/12/6 4:13 PM
  */
 public interface GoodsDonStockRecordMapper extends BaseMapper<GoodsDonStockRecord> {
+
+	@Select("select * from goods_don_stock_record where stock_id = #{stockId} and type = #{type} and available < num and is_undo is ${isUndo} order by stock_id limit 1")
+	GoodsDonStockRecord selectUndoRecord(@Param("stockId") Long stockId, @Param("isUndo") Boolean isUndo, @Param("type") String type);
 }

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.stock;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.GoodsSkuStockRelateChangeRecord;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: GoodsSkuStockRelateChangeRecordMapper
+ * 创建者: JavaZou
+ * 创建时间:2023/11/2 17:34
+ */
+public interface GoodsSkuStockRelateChangeRecordMapper extends BaseMapper<GoodsSkuStockRelateChangeRecord> {
+}

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

@@ -0,0 +1,18 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributeGoodsSkuAlert
+ * 创建者: JavaZou
+ * 创建时间:2023/11/8 14:08
+ */
+@Getter
+@Setter
+public class DistributeGoodsSkuAlert extends BaseEntity {
+	private Long goodsId;
+
+	private Long skuId;
+}

+ 4 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonStock.java

@@ -33,4 +33,8 @@ public class GoodsDonStock extends BaseEntity {
     @TableField(exist = false)
     private List<GoodsSkuStockRelate> relateList;
 
+    @DbIgnore
+    @TableField(exist = false)
+    private String operator;
+
 }

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

@@ -16,13 +16,17 @@ import java.util.Date;
 @Getter
 @Setter
 @SearchBean(tables = "goods_don_stock s, goods_don_stock_record r ",
-            where = "s.id = r.stock_id "
+            where = "s.id = r.stock_id and r.is_undo is false"
 )
 public class GoodsDonStockRecord extends BaseEntity{
 
     @DbField("s.id")
     private Long stockId;
 
+    @DbField("r.id")
+    @TableField(exist = false)
+    private Long recordId;
+
     @DbField("s.title")
     @TableField(exist = false)
     private String title;
@@ -61,4 +65,10 @@ public class GoodsDonStockRecord extends BaseEntity{
     @DbField("r.created_time")
     @TableField(exist = false)
     private Date recordCreatedTime;
+
+    /**
+     * 是否撤销 默认否
+     */
+    @DbField("r.is_undo")
+    private Boolean isUndo;
 }

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

@@ -21,4 +21,6 @@ public class GoodsSkuStockRelate extends BaseEntity{
 
     private String skuTitle;
 
+    private String skuJson;
+
 }

+ 39 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GoodsSkuStockRelateChangeRecord.java

@@ -0,0 +1,39 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: GoodsSkuStockRelateChangeRecord
+ * 创建者: JavaZou
+ * 创建时间:2023/11/2 17:32
+ */
+@Getter
+@Setter
+public class GoodsSkuStockRelateChangeRecord extends BaseEntity{
+	private Long stockId;
+
+	private Long goodsId;
+
+	private String goodsTitle;
+
+	private Long skuId;
+
+	private String skuTitle;
+
+	/**
+	 * 统一记录id
+	 */
+	private Long uniformId;
+
+	/**
+	 * 统一记录id
+	 */
+	private String type;
+
+	/**
+	 * 操作人
+	 */
+	private String operator;
+}

+ 7 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GroupsTrips.java

@@ -126,6 +126,13 @@ public class GroupsTrips {
     @TableField(exist = false)
     private Date expiryTime;
 
+    /**
+     * 车队上是否有人
+     */
+    @DbIgnore
+    @TableField(exist = false)
+    private Boolean isExists;
+
     /**
      * 创建时间
      */

+ 35 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeBusinessGeneralRate.java

@@ -0,0 +1,35 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessGeneralRate
+ *创建者: JavaZou
+ *创建时间:2023/11/8 14:45
+ */
+@Getter
+@Setter
+public class UserDistributeBusinessGeneralRate extends BaseEntity {
+
+	/**
+	 * 平台id
+	 */
+	private Long goodsId;
+
+	/**
+	 * 规格id
+	 */
+	private Long skuId;
+
+	/**
+	 * 首单提成比例
+	 */
+	private Integer firstOrderRate;
+
+	/**
+	 * 首单续费提成比例
+	 */
+	private Integer renewOrderRate;
+}

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

@@ -21,7 +21,7 @@ import java.util.Date;
 @Setter
 @SearchBean(tables = "goods_don g left join yh_shop_user_plat_distribute_rate ydr on g.id = ydr.goods_id :uid:" +
 		" left join yh_shop_general_goods_rate ygr on ygr.goods_id = g.id",
-		where = "g.type = 1 and g.status is true and g.deleted is true")
+		where = "g.type = 1 and g.status is true and g.deleted is true and g.is_distribute is true")
 public class YhShopUserPlatDistributeRate {
 	@TableId(value = "id", type = IdType.AUTO)
 	@DbField("ydr.id")

+ 4 - 0
netflix-dao/src/main/java/com/cyksj/model/excel/ExcelManageAccountData.java

@@ -60,6 +60,10 @@ public class ExcelManageAccountData {
 	@ExcelIgnore
 	private Date expiryTime;
 
+	@ExcelProperty("创建时间")
+	@DbField("a.created_time")
+	private Date createdTime;
+
 	@ExcelProperty("首开时间")
 	@DbField("date_format(a.start_time,'%Y/%c/%e')")
 	private String startTimeExcel;

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

@@ -118,6 +118,9 @@ public class AccountView {
     @DbField("gdk.spec_val")
     private String specVal;
 
+    @DbField("a.created_time")
+    private Date createdTime;
+
     //@DbField("select count(ur.id) from user_ticket_cleared_record ur where ur.account_id = a.id and deleted is true and source = 'self' :yesTime:")
     @DbIgnore
     private Integer expiryCount;

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

@@ -116,6 +116,9 @@ public class OrderDonBackView {
 	@DbField("o.refund_money")
 	private BigDecimal refundMoney;
 
+	@DbField("o.refund_balance")
+	private BigDecimal refundBalance;
+
 	@DbField("o.status")
 	private OrderDon.Status status;
 

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

@@ -14,7 +14,7 @@ import lombok.Setter;
 @Getter
 @Setter
 @SearchBean(tables = "goods_don g left join business_distribute_default_rate_config bc on g.id = bc.goods_id",
-		where = "g.deleted is true and g.status is true",
+		where = "g.deleted is true and g.status is true and g.is_distribute is true",
 		orderBy = "g.id")
 public class BusinessDistributeRateView {
 	@DbField("bc.id")

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

@@ -29,6 +29,9 @@ public class ExchangeCodeView {
 	@DbField("ec.goods_id")
 	private Long goodsId;
 
+	@DbField("ec.sku_id")
+	private Long skuId;
+
 	/**
 	 * 平台名称
 	 */

+ 9 - 5
netflix-dao/src/main/java/com/cyksj/model/views/StatisticsStockView.java

@@ -57,11 +57,11 @@ public class StatisticsStockView {
     @ExcelProperty("出库价值")
     private BigDecimal outPrice = BigDecimal.ZERO;
 
-    /**
-     * 不可用总数
-     */
-    @ExcelProperty("不可用总数")
-    private Integer unavailable;
+//    /**
+//     * 不可用总数
+//     */
+//    @ExcelProperty("不可用总数")
+//    private Integer unavailable;
 
     /**
      * 不可用金额
@@ -98,6 +98,10 @@ public class StatisticsStockView {
                 this.outTotal += num;
                 this.outPrice = this.outPrice.add(price);
                 break;
+            case "out":
+                this.outTotal += num;
+                this.outPrice = this.outPrice.add(price);
+                break;
             case "refund":
                 this.refundTotal += num;
                 this.refundPrice = this.refundPrice.add(price);

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

@@ -13,8 +13,8 @@ import lombok.Setter;
  */
 @Getter
 @Setter
-@SearchBean(tables = "user_business_default_rate_config uc left join goods_don g on g.id = uc.goods_id"
-		, where = "g.deleted is true and g.status is true")
+@SearchBean(tables = "goods_don g left join user_business_default_rate_config uc on g.id = uc.goods_id"
+		, where = "g.deleted is true and g.status is true and g.is_distribute is true")
 public class UserBusinessDefaultRateConfigView {
 	@DbField("uc.id")
 	private Long id;

+ 63 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeBusinessGeneralRateView.java

@@ -0,0 +1,63 @@
+package com.cyksj.model.views;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserDistributeBusinessGeneralRateView
+ * 创建者: JavaZou
+ * 创建时间:2023/11/8 14:47
+ */
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessRateRecordView
+ *创建者: JavaZou
+ *创建时间:2023/3/27 15:53
+ */
+@Getter
+@Setter
+@SearchBean(tables = "goods_don g left join goods_don_sku gdk on gdk.goods_id = g.id" +
+		" left join user_distribute_business_general_rate ur on ur.sku_id = gdk.id",
+		where = "g.deleted is true and g.status is true and g.is_distribute is true and gdk.status is true")
+public class UserDistributeBusinessGeneralRateView {
+	@DbField("ur.id")
+	private Long id;
+
+	/**
+	 * 平台id
+	 */
+	@DbField("g.id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	private String goodsName;
+
+	/**
+	 * 规格id
+	 */
+	@DbField("gdk.id")
+	private Long skuId;
+
+	@DbField("gdk.spec_val")
+	private String specVal;
+
+	/**
+	 * 首单提成比例
+	 */
+	@DbField("ifnull(ur.first_order_rate,0)")
+	private Integer firstOrderRate;
+
+	/**
+	 * 首单续费提成比例
+	 */
+	@DbField("ifnull(ur.renew_order_rate,0)")
+	private Integer renewOrderRate;
+
+	@DbField("g.type")
+	private Integer type;
+}
+

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

@@ -16,7 +16,7 @@ import lombok.Setter;
 @Setter
 @SearchBean(tables = "goods_don g left join goods_don_sku gdk on gdk.goods_id = g.id" +
 		" left join user_distribute_business_rate ur on ur.sku_id = gdk.id :business_id:",
-		where = "g.deleted is true and g.status is true")
+		where = "g.deleted is true and g.status is true and g.is_distribute is true and gdk.status is true")
 public class UserDistributeBusinessRateRecordView {
 	@DbField("ur.id")
 	private Long id;

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

@@ -16,7 +16,7 @@ import lombok.Setter;
 @SearchBean(tables = "goods_don g left join goods_don_category_relate gcr on gcr.goods_id = g.id" +
 		" left join goods_don_category gc on gc.id = gcr.category" +
 		" left join user_plat_distribute_rate upr on upr.goods_id = g.id :distribute_id:",
-		where = "g.type = 1 and g.deleted is true and g.status is true and upr.rate > 0")
+		where = "g.type = 1 and g.deleted is true and g.status is true and g.is_distribute is true and upr.rate > 0")
 public class UserDistributeRateView {
 
 	@DbField("gcr.category")

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

@@ -15,7 +15,7 @@ import lombok.Setter;
 @Getter
 @Setter
 @SearchBean(tables = "user_plat_distribute_rate up left join goods_don gd on gd.id = up.goods_id",
-		where = "gd.deleted is true and gd.status is true")
+		where = "gd.deleted is true and gd.status is true and gd.is_distribute is true")
 public class UserDistributeView {
 	@DbField("up.id")
 	private Long id;

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

@@ -16,9 +16,8 @@ import java.math.BigDecimal;
  */
 @Getter
 @Setter
-@SearchBean(tables = "yh_shop ys left join yh_shop_user_distribute_business_order_don_record ubr on ubr.business_id = ys.business_id and :time:" +
+@SearchBean(tables = "(select distinct business_id from yh_shop where business_id != 0) ys left join yh_shop_user_distribute_business_order_don_record ubr on ubr.business_id = ys.business_id and :time:" +
 		" left join cms_user cu on cu.id = ys.business_id",
-		where = "ys.business_id != 0",
 		groupBy = "ys.business_id,cu.nickname,date_format(ubr.order_created_time,'%Y-%m')")
 public class YhShopDistributeBusinessView {
 	@DbField("ys.business_id")

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

@@ -14,7 +14,7 @@ import lombok.Setter;
 @Getter
 @Setter
 @SearchBean(tables = "goods_don g left join yh_shop_user_business_default_rate_config uc on g.id = uc.goods_id"
-		, where = "g.type = 1 and g.deleted is true and g.status is true")
+		, where = "g.type = 1 and g.deleted is true and g.status is true and g.is_distribute is true")
 public class YhShopUserBusinessDefaultRateConfigView {
 	@DbField("uc.id")
 	private Long id;

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

@@ -15,7 +15,7 @@ import lombok.Setter;
 @Setter
 @SearchBean(tables = "goods_don g left join goods_don_sku gdk on gdk.goods_id = g.id" +
 		" left join yh_shop_user_distribute_business_rate ur on ur.sku_id = gdk.id :business_id:",
-		where = "g.type = 1 and g.deleted is true and g.status is true")
+		where = "g.type = 1 and g.deleted is true and g.status is true and g.is_distribute is true")
 public class YhShopUserDistributeBusinessRateRecordView {
 	@DbField("ur.id")
 	private Long id;

+ 3 - 2
netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml

@@ -223,7 +223,7 @@
           and a.expiry_time >= #{beginOfDay}
           and (select count(*)
                from groups_relation gr
-               where gr.status = 'outside'
+               where gr.num > #{skuNum}
                  and gr.groups_id = gt.id
                  and gr.user_id
             != 0)
@@ -277,6 +277,7 @@
                  inner join groups_relation gr on gr.groups_id = gt.id
             and gt.`status` = 'waiting'
             and gt.sku_id = #{skuId}
-            and gr.status = 'validity'
+            and gr.user_id != 0
+            and gr.status in ('validity','outside')
     </select>
 </mapper>

+ 35 - 1
netflix-dao/src/main/resources/mapper/UserDistributeBusinessRateMapper.xml

@@ -10,7 +10,41 @@
             (#{item.distributeId},#{item.goodsId},#{item.rate},#{item.secondRate},now(),now())
         </foreach>
         ON DUPLICATE KEY UPDATE rate = VALUES(rate)
-</insert>
+    </insert>
+
+    <insert id="insertOrUpdateBusinessGoodsSkuRate">
+        insert into user_distribute_business_rate
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            `business_id`,`goods_id`,`sku_id`,
+            <if test="firstOrderRate != null">
+                `first_order_rate`,
+            </if>
+            <if test="renewOrderRate != null">
+                `renew_order_rate`,
+            </if>
+            `created_time`,`update_time`
+        </trim>
+        values
+        <foreach collection="list" item="item" separator=",">
+            (#{item},#{goodsId},#{skuId},
+            <if test="firstOrderRate != null">
+                #{firstOrderRate},
+            </if>
+            <if test="renewOrderRate != null">
+                #{renewOrderRate},
+            </if>
+            now(),now())
+        </foreach>
+        ON DUPLICATE KEY UPDATE
+        <trim suffixOverrides=",">
+            <if test="firstOrderRate != null">
+                first_order_rate = VALUES(first_order_rate),
+            </if>
+            <if test="renewOrderRate != null">
+                renew_order_rate = VALUES(renew_order_rate)
+            </if>
+        </trim>
+    </insert>
 
     <select id="selectNoThisGoodsDistribute" resultType="java.lang.Long">
         select distinct ud.id from user_distribute ud left join user_plat_distribute_rate ur

+ 1 - 1
netflix-service/src/main/java/com/cyksj/redis/RedisService.java

@@ -651,7 +651,7 @@ public class RedisService {
         TASK_RECEIVED_KEY("task_received_key:%s:%s", "领取任务奖励key", 10l),
         CORP_GROUP_CHAT_LIST("corp_group_chat_list:%s", "企业微信客户群列表", 60 * 60 * 24),
         PLUS_GOODS_ADDRESS_KEY("plus_goods_address_key:", "优惠加购实物地址key", 10 * 60l),
-        GROUPS_TRIPS_OUTSIDE_RELATION("groups_trips_outside_relation:key", "额外车位", 30l),
+        GROUPS_TRIPS_OUTSIDE_RELATION("groups_trips_outside_relation:key:%s:%s", "额外车位", 30l),
         DISTRIBUTE_RULE_TIME_KEY("DISTRIBUTE_RULE_TIME_KEY", "渠道规格记录时间key", 5 * 60L),
 
         //巨量广告平台临时存储 callback

+ 16 - 6
netflix-service/src/main/java/com/cyksj/service/distribute/impl/UserBusinessFrontServiceImpl.java

@@ -174,15 +174,25 @@ public class UserBusinessFrontServiceImpl implements UserBusinessFrontService {
 	 */
 	@Override
 	public void taskYhShopDistributeRateBenefits(Long shopUserId, Long businessId, Integer goodsType, OrderDon order, Integer distributeRate) {
-		LambdaQueryWrapper<YhShopUserDistributeBusinessRate> wrapper = Wrappers.lambdaQuery(YhShopUserDistributeBusinessRate.class)
-				.eq(YhShopUserDistributeBusinessRate::getBusinessId, businessId)
-				.eq(YhShopUserDistributeBusinessRate::getGoodsId, order.getGoodsId())
+		LambdaQueryWrapper<UserDistributeBusinessRate> wrapper = Wrappers.lambdaQuery(UserDistributeBusinessRate.class)
+				.eq(UserDistributeBusinessRate::getBusinessId, businessId)
+				.eq(UserDistributeBusinessRate::getGoodsId, order.getGoodsId())
 				.last("limit 1");
-		//虚拟平台
 		if (goodsType == 1) {
-			wrapper.eq(YhShopUserDistributeBusinessRate::getSkuId, order.getSkuId());
+			wrapper.eq(UserDistributeBusinessRate::getSkuId, order.getSkuId());
+		}
+		//和渠道商务用一套提成比例
+		UserDistributeBusinessRate businessRate = userDistributeBusinessRateMapper.selectOne(wrapper);
+		//06-21 奈飞平台商务比例特殊处理
+		UserDistributeSpecial userDistributeSpecial = UserDistributeSpecialMapper.selectOne(Wrappers.lambdaQuery(UserDistributeSpecial.class)
+				.eq(UserDistributeSpecial::getSkuId, order.getSkuId())
+				.eq(UserDistributeSpecial::getSharedId, shopUserId)
+				.eq(UserDistributeSpecial::getBusinessId, businessId)
+				.last("limit 1"));
+		if (userDistributeSpecial != null) {
+			businessRate.setFirstOrderRate(userDistributeSpecial.getFirstRate());
+			businessRate.setRenewOrderRate(userDistributeSpecial.getRenewRate());
 		}
-		YhShopUserDistributeBusinessRate businessRate = yhShopUserDistributeBusinessRateMapper.selectOne(wrapper);
 		if (businessRate != null) {
 			if (order.getOrderType() == 1) {
 				//实物商务分销提成 无首单

+ 5 - 128
netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java

@@ -21,7 +21,6 @@ import com.cyksj.mapper.manage.exchange.ExchangeCodeMapper;
 import com.cyksj.mapper.market.draw.LuckyDrawRecordMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.excel.ExcelExchangeCodeData;
-import com.cyksj.model.manage.views.AccountView;
 import com.cyksj.model.request.ExchangeCodeReq;
 import com.cyksj.model.request.ExchangeCodeTicket;
 import com.cyksj.redis.RedisService;
@@ -30,7 +29,6 @@ import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.relation.GroupsRelationExpiryRecordService;
 import com.cyksj.service.shop.YhShopFrontService;
 import com.ejlchina.searcher.BeanSearcher;
-import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
@@ -360,61 +358,15 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 
 	@Override
 	public GroupsRelation getRelationNoOrder(GoodsDonSku sku, Long userId, Long yhsId) {
-		GroupsRelation relation = null;
 		Integer retryNum = 1;
 		List<Long> errorsRelationIds = new ArrayList<>();
-		relation = getFinalRelation(sku, userId, relation, retryNum, yhsId, errorsRelationIds);
+		GroupsRelation relation = getFinalRelation(sku, userId, retryNum, yhsId, errorsRelationIds);
 		return relation;
 	}
 
-	public GroupsRelation getFinalRelation(GoodsDonSku sku, Long userId, GroupsRelation relation, Integer retryNum, Long yhsId, List<Long> errorsRelationIds) {
-		//寻找差不多过期时间规格的车位
-		relation = groupRelationFrontService.getSimilarExpiredGroupRelation(sku.getId(), sku.getDays(), sku.getMonths(), errorsRelationIds);
-		if (relation == null) {
-			GroupsTrips groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
-					.eq(GroupsTrips::getSkuId, sku.getId())
-					.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
-					.eq(GroupsTrips::getStatus, GroupsTrips.Status.validity)
-					.orderByAsc(GroupsTrips::getAvailableNum));
-			if (groups == null) {
-				//若是ChatGPT Plus 、MidJourney
-				//获取额外的车位
-				relation = getOutSideRelationIfAi(userId, groups, sku);
-				if (relation != null) {
-					groups = groupsMapper.selectById(relation.getGroupsId());
-				}
-				//待发车
-				if (relation == null) {
-					groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
-							.eq(GroupsTrips::getSkuId, sku.getId())
-							.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
-							.eq(GroupsTrips::getStatus, GroupsTrips.Status.waiting)
-							.orderByAsc(GroupsTrips::getAvailableNum));
-				}
-			}
-			if (groups == null) {
-				//新增车位 并关联
-				relation = createNewGroupTripsAndRelation(sku, groups, relation);
-				log.info("无合适规格车队,新增新车队,获取车位relationId:{}", relation.getId());
-			}
-
-			if (relation == null) {
-				//寻找快满编车队进行占座
-				relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
-						.eq(GroupsRelation::getGroupsId, groups.getId())
-						.notIn(errorsRelationIds != null && errorsRelationIds.size() > 0, GroupsRelation::getId, errorsRelationIds)
-						.eq(GroupsRelation::getStatus, "none")
-						.eq(GroupsRelation::getUserId, 0)
-						.orderByAsc(GroupsRelation::getNum)
-						.last("limit 1")
-				);
-				log.info("寻找快满编车队的车位relationId:{}", relation.getId());
-				//如果占位失败 新增车位并关联
-				if (relation == null) {
-					relation = getOutSideRelationIfAi(userId, groups, sku);
-				}
-			}
-		}
+	public GroupsRelation getFinalRelation(GoodsDonSku sku, Long userId, Integer retryNum, Long yhsId, List<Long> errorsRelationIds) {
+		//获取车票车位
+		GroupsRelation relation = groupRelationFrontService.getRelation(null, userId, sku);
 
 		try {
 			//锁定座位
@@ -450,7 +402,7 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 				throw BusinessRuntimeException.getInstance("获取车票异常,请联系客服");
 			}
 			//失败重新给他分配车位
-			getFinalRelation(sku, userId, relation, ++retryNum, yhsId, errorsRelationIds);
+			getFinalRelation(sku, userId, ++retryNum, yhsId, errorsRelationIds);
 		}
 		return relation;
 	}
@@ -475,79 +427,4 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 			}
 		}
 	}
-
-	/**
-	 * 新增新车位并关联车位
-	 */
-	private GroupsRelation createNewGroupTripsAndRelation(GoodsDonSku sku, GroupsTrips groups, GroupsRelation relation) {
-		//通过兑换码兑换车票 新增车位
-		if (groups == null) {
-			groups = new GroupsTrips();
-		}
-		//补充占位
-		if (relation == null) {
-			relation = new GroupsRelation();
-		}
-		groups.setSkuId(sku.getId());
-		groups.setNum(sku.getNum());
-		groups.setAvailableNum(sku.getNum());
-		if (sku.getGoodsId() == 23) {
-			AccountView accountView = beanSearcher.searchFirst(AccountView.class, MapUtils.builder().field(AccountView::getGoodsId, 23).onlySelect(AccountView::getId).build());
-			if (accountView != null) {
-				groups.setAccountId(accountView.getId());
-				groups.setStatus(GroupsTrips.Status.validity);
-				groups.setRemark("已设置唯一账号");
-			}else {
-				groups.setStatus(GroupsTrips.Status.waiting);
-				groups.setRemark("等待设置账号");
-			}
-		} else {
-			groups.setStatus(GroupsTrips.Status.waiting);
-			groups.setRemark("等待设置账号");
-		}
-		groupsMapper.insert(groups);
-		relation.setGroupsId(groups.getId());
-		relation.setNum(1);
-		relation.setStatus(GroupsRelation.Status.none);
-		relation.setGroupsId(groups.getId());
-		groupsRelationMapper.insert(relation);
-		//补充其他占位
-		for (int i = 2; i <= groups.getNum(); i++) {
-			GroupsRelation groupsRelation = new GroupsRelation();
-			groupsRelation.setGroupsId(groups.getId());
-			groupsRelation.setNum(i);
-			groupsRelation.setStatus(GroupsRelation.Status.none);
-			groupsRelationMapper.insert(groupsRelation);
-		}
-		return relation;
-	}
-
-	public GroupsRelation getOutSideRelationIfAi(Long userId, GroupsTrips groups, GoodsDonSku sku) {
-		//若是MidJourney、ChatGPT PLUS每个已满车队 硬塞5个座位
-		//主账号过期时间10天以外
-		GroupsRelation relation = null;
-		if (sku.getNum() > 1 && Constant.AI_goodsIds.contains(sku.getGoodsId())) {
-			DateTime tenExpiry = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), 10);
-			Long groupsId = groupsRelationMapper.getOutSideGroupsTripsRelationByGoodsId(sku.getId(), tenExpiry, 5, userId);
-			if (groupsId != null) {
-				relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
-						.eq(GroupsRelation::getGroupsId, groupsId)
-						.eq(GroupsRelation::getUserId, 0)
-						.eq(GroupsRelation::getStatus, GroupsRelation.Status.outside)
-						.last("limit 1"));
-				if (relation == null) {
-					if (!redisService.setNx(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getName() + groupsId, groupsId, RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getTimeout())) {
-						relation = new GroupsRelation();
-						relation.setStatus(GroupsRelation.Status.outside);
-						relation.setUserId(userId);
-						relation.setGroupsId(groupsId);
-						GroupsRelation maxNumRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsId).orderByDesc(GroupsRelation::getNum).last("limit 1"));
-						relation.setNum(maxNumRelation.getNum() + 1);
-						groupsRelationMapper.insert(relation);
-					}
-				}
-			}
-		}
-		return relation;
-	}
 }

+ 3 - 2
netflix-service/src/main/java/com/cyksj/service/mange/CmsOrderDonService.java

@@ -8,6 +8,7 @@ import com.cyksj.model.request.ChangeRelationReq;
 import com.cyksj.model.request.ClickOutReq;
 import com.cyksj.model.request.OrderRefundReq;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 
@@ -46,11 +47,11 @@ public interface CmsOrderDonService extends IService<OrderDon> {
 	/**
 	 * 退款记录
 	 */
-	void refundRecord(OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType);
+	void refundRecord(OrderDon orderDon, BigDecimal refundMoney, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType);
 
 	/**
 	 *
 	 * @param orderRefundReq
 	 */
-	void refundPriceDiffer(OrderRefundReq orderRefundReq);
+	void refundPriceDiffer(OrderRefundReq orderRefundReq) throws Exception;
 }

+ 9 - 0
netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonSpecServiceImpl.java

@@ -7,9 +7,11 @@ 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.DistributeGoodsSkuAlertMapper;
 import com.cyksj.mapper.GoodsDonMapper;
 import com.cyksj.mapper.GoodsDonSkuMapper;
 import com.cyksj.mapper.GoodsDonSpecMapper;
+import com.cyksj.model.entity.DistributeGoodsSkuAlert;
 import com.cyksj.model.entity.GoodsDon;
 import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.GoodsDonSpec;
@@ -43,6 +45,8 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 
 	private final GoodsDonSkuMapper goodsDonSkuMapper;
 
+	private final DistributeGoodsSkuAlertMapper distributeGoodsSkuAlertMapper;
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public void insertOrUpdateSkuSpec(ReqGoodsSkuInsert insert, Boolean isUpdate) throws Exception {
@@ -254,6 +258,11 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 				}
 			}
 			goodsDonSkuMapper.insert(goodsDonSku);
+
+			DistributeGoodsSkuAlert distributeGoodsSkuAlert = new DistributeGoodsSkuAlert();
+			distributeGoodsSkuAlert.setGoodsId(goods.getId());
+			distributeGoodsSkuAlert.setSkuId(goodsDonSku.getId());
+			distributeGoodsSkuAlertMapper.insert(distributeGoodsSkuAlert);
 		}
 	}
 

+ 3 - 2
netflix-service/src/main/java/com/cyksj/service/mange/group/CmsGroupServiceImpl.java

@@ -376,10 +376,11 @@ public class CmsGroupServiceImpl extends ServiceImpl<GroupsMapper,GroupsTrips> i
         if (Constant.AI_goodsIds.contains(sku.getGoodsId()) && sku.getNum() > 1) {
             Integer extraNum = Constant.AI_EXTRACT_NUM;
             Integer maxNum = skuNum + extraNum;
-            DateTime tenExpiry = DateUtil.offsetDay(DateTime.now(), 10);
+            //主账号有效时间
+            DateTime time = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), 25);
             Integer available = relationMapper.selectAvailableRelation(skuId, skuNum);
             //额外硬塞
-            Integer special_available = relationMapper.selectSpecialGroupsRelationAvailable(skuId, maxNum, skuNum, extraNum, tenExpiry);
+            Integer special_available = relationMapper.selectSpecialGroupsRelationAvailable(skuId, maxNum, skuNum, extraNum, time);
             available += special_available;
             available = getAvailableAfterPreAccount(available, skuId, maxNum, goodsId);
             //待发车已有人员成功上车

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

@@ -316,23 +316,11 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             }
             return;
         }
-        OrderDon.Type type = orderDon.getType();
-        String outNo = StrUtil.EMPTY;
-        if (type == OrderDon.Type.WeChat && !refundType.equals(OrderDon.Type.BALANCE.getType())) {
-            outNo = wxRefund(refundReq, orderDon);
-        }
-        if (type == OrderDon.Type.ALI_PAY && !refundType.equals(OrderDon.Type.BALANCE.getType())) {
-            outNo = zfbRefund(refundReq, orderDon);
-        }
-        if (type == OrderDon.Type.PAYPAL && !refundType.equals(OrderDon.Type.BALANCE.getType())) {
-            payPalService.refund(refundReq, orderDon);
-        }
-        if (type == OrderDon.Type.STRIPE && !refundType.equals(OrderDon.Type.BALANCE.getType())) {
-            stripeService.refund(refundReq, orderDon);
-        }
+        //调用第三方接口退款
+        String outNo = centerRefund(refundReq, orderDon);
         orderDon.setRefundDesc(refundReq.getRefundDesc());
         //记录退款信息
-        commonRefund(orderDon, goodsDon, sku, outNo, refundType);
+	    commonRefund(orderDon, refundReq.getRefundMoney(), goodsDon, sku, outNo, refundType);
         //修改订单状态
         orderDon.setStatus(OrderDon.Status.refund);
         orderDonMapper.updateById(orderDon);
@@ -602,6 +590,8 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         if (orderDon == null) {
             throw BusinessRuntimeException.getInstance("订单不存在");
         }
+        BigDecimal orderDonRefundMoney = Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO);
+        BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO);
         String refundType = refundReq.getRefundType();
         if (orderDon.getType() == OrderDon.Type.BALANCE && !OrderDon.Type.BALANCE.getType().equals(refundType)) {
             throw BusinessRuntimeException.getInstance("余额支付的订单不支持金额退款");
@@ -647,6 +637,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         //余额退款
         if (OrderDon.Type.BALANCE.getType().equals(refundType)) {
             BigDecimal balance = orderDon.getBalance();
+            refundMoney = orderDonRefundBalance.add(refundMoney);
             if (OrderDon.Type.BALANCE == orderDon.getType() && refundMoney.compareTo(balance) > 0) {
                 throw BusinessRuntimeException.getInstance("退款余额大于订单支付余额");
             }
@@ -657,6 +648,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             orderDon.setRefundMoney(BigDecimal.ZERO);
         } else {
             //退金额
+            refundMoney = orderDonRefundMoney.add(refundMoney);
             if (refundMoney.compareTo(money) > 0) {
                 throw BusinessRuntimeException.getInstance("退款金额大于订单支付金额");
             }
@@ -684,9 +676,9 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
     /**
      * 退款后 处理关联
      */
-    public void commonRefund(OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType) {
+    public void commonRefund(OrderDon orderDon, BigDecimal refundMoney, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType) {
         TASK_POOL.execute(() -> {
-            refundRecord(orderDon, goodsDon, sku, outNo, refundType);
+            refundRecord(orderDon, refundMoney, goodsDon, sku, outNo, refundType);
             //退款一次
             goodsDonStockService.upStockRelate(null, orderDon.getId(), "refund");
             try {
@@ -893,14 +885,14 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
      * 记录退款信息
      */
     @Override
-    public void refundRecord(OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType) {
+    public void refundRecord(OrderDon orderDon, BigDecimal refundMoney, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType) {
         RefundOrderDon refund = new RefundOrderDon();
         refund.setOrderId(orderDon.getId());
         refund.setOutRefundNo(outRefundNo);
         refund.setTotalFee(orderDon.getMoney());
         refund.setRefundDesc(orderDon.getRefundDesc());
         //退款金额
-        refund.setRefundFee(orderDon.getRefundMoney());
+        refund.setRefundFee(refundMoney);
         refund.setUserId(orderDon.getUserId());
         refund.setGoodsId(orderDon.getGoodsId());
         refund.setGoodsTitle(goodsDon == null ? null : goodsDon.getTitle());
@@ -917,7 +909,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
     }
 
     @Override
-    public void refundPriceDiffer(OrderRefundReq orderRefundReq) {
+    public void refundPriceDiffer(OrderRefundReq orderRefundReq) throws Exception {
         Long orderId = orderRefundReq.getOrderId();
         OrderDon orderDon = orderDonMapper.selectById(orderId);
         if (orderDon == null) {
@@ -929,11 +921,42 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         if (Constant.noOrderAllStatus.contains(orderDon.getStatus().name())) {
             throw BusinessRuntimeException.getInstance("订单不是已支付状态");
         }
-        BigDecimal refundBalance = orderRefundReq.getRefundBalance();
+        //默认补差价余额
+        String refundType = Optional.ofNullable(orderRefundReq.getRefundType()).orElse("balance");
+        BigDecimal refundMoney = orderRefundReq.getRefundMoney();
+        BigDecimal orderRefundMoney = Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO);
+        BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO);
+        if (refundMoney.add(orderRefundMoney).add(orderDonRefundBalance).compareTo(orderDon.getRealMoney()) >= 0) {
+            throw BusinessRuntimeException.getInstance("补差价已达到该订单付款金额");
+        }
+        if ("money".equals(refundType)) {
+            if (refundMoney == null || refundMoney.compareTo(BigDecimal.ZERO) <= 0) {
+                throw BusinessRuntimeException.getInstance("请输入正确的差价金额");
+            }
+            if (refundMoney.compareTo(orderDon.getMoney()) >= 0) {
+                throw BusinessRuntimeException.getInstance("补差价金额应不大于订单金额");
+            }
+            //退款
+            String outNo = centerRefund(orderRefundReq, orderDon);
+            orderDon.setRefundMoney(orderRefundMoney.add(refundMoney));
+            orderDonMapper.updateById(orderDon);
+
+            GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
+            GoodsDonSku sku = null;
+            if (orderDon.getSkuId() != null) {
+                sku = skuMapper.selectById(orderDon.getSkuId());
+            }
+            orderDon.setRefundDesc("补差价");
+            refundRecord(orderDon, refundMoney, goodsDon, sku, outNo, refundType);
+            return;
+        }
+        BigDecimal refundBalance = refundMoney;
         if (refundBalance == null || refundBalance.compareTo(BigDecimal.ZERO) <= 0 || refundBalance.compareTo(orderDon.getMoney()) > 0) {
             throw BusinessRuntimeException.getInstance("请输入正确的差价金额");
         }
         userBenefitsService.addUserBalance(orderDon.getUserId(), refundBalance, UserBalanceSourceRecord.Source.price_differ, orderDon.getYhsId());
+        orderDon.setRefundBalance(orderDonRefundBalance.add(refundBalance));
+        orderDonMapper.updateById(orderDon);
     }
 
     /**
@@ -981,4 +1004,22 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         }
         return relation;
     }
+
+	public String centerRefund(OrderRefundReq refundReq, OrderDon orderDon) throws Exception {
+		OrderDon.Type type = orderDon.getType();
+		String refundType = refundReq.getRefundType();
+		if (type == OrderDon.Type.WeChat && !refundType.equals(OrderDon.Type.BALANCE.getType())) {
+			return wxRefund(refundReq, orderDon);
+		}
+		if (type == OrderDon.Type.ALI_PAY && !refundType.equals(OrderDon.Type.BALANCE.getType())) {
+			return zfbRefund(refundReq, orderDon);
+		}
+		if (type == OrderDon.Type.PAYPAL && !refundType.equals(OrderDon.Type.BALANCE.getType())) {
+			payPalService.refund(refundReq, orderDon);
+		}
+		if (type == OrderDon.Type.STRIPE && !refundType.equals(OrderDon.Type.BALANCE.getType())) {
+			stripeService.refund(refundReq, orderDon);
+		}
+		return StrUtil.EMPTY;
+	}
 }

+ 11 - 1
netflix-service/src/main/java/com/cyksj/service/mange/stock/GoodsDonStockService.java

@@ -1,6 +1,5 @@
 package com.cyksj.service.mange.stock;
 
-import com.baomidou.mybatisplus.extension.service.IService;
 import com.cyksj.model.entity.GoodsDonStock;
 import com.cyksj.model.entity.GoodsDonStockRecord;
 import com.cyksj.model.request.StockUpReq;
@@ -47,4 +46,15 @@ public interface GoodsDonStockService {
      * 删除库存
      */
     void del(Long stockId);
+
+    /**
+     * 更换库存绑定商品信息
+     */
+    void updateBindGoods(GoodsDonStock stock);
+
+    /**
+     * 撤销库存变更回滚
+     */
+    void undoChange(Long recordId);
+
 }

+ 168 - 17
netflix-service/src/main/java/com/cyksj/service/mange/stock/impl/GoodsDonStockServiceImpl.java

@@ -1,18 +1,13 @@
 package com.cyksj.service.mange.stock.impl;
 
 import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.math.MathUtil;
-import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
-import com.cyksj.mapper.stock.GoodsDonStockMapper;
-import com.cyksj.mapper.stock.GoodsDonStockRecordMapper;
-import com.cyksj.mapper.stock.GoodsSkuStockRelateMapper;
-import com.cyksj.mapper.stock.OrderDonStockMapper;
-import com.cyksj.model.entity.GoodsDonStock;
-import com.cyksj.model.entity.GoodsDonStockRecord;
-import com.cyksj.model.entity.GoodsSkuStockRelate;
-import com.cyksj.model.entity.OrderDonStock;
+import com.cyksj.common.snowflake.Sequence;
+import com.cyksj.mapper.stock.*;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.request.StockUpReq;
 import com.cyksj.service.mange.stock.GoodsDonStockService;
 import lombok.RequiredArgsConstructor;
@@ -20,9 +15,10 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * @author chan
@@ -41,6 +37,12 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
 
     private final GoodsSkuStockRelateMapper skuStockRelateMapper;
 
+    private final GoodsSkuStockRelateChangeRecordMapper relateChangeRecordMapper;
+
+    private static final Sequence SEQUENCE = new Sequence(0);
+
+    private final List<String> ADD_OPERATE = List.of("put", "refund");
+
     @Transactional(rollbackFor = Throwable.class)
     @Override
     public void upStockRelate(Long stockId, Long orderId, String status) {
@@ -52,6 +54,10 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
                 orderDonStock.setStatus("refund");
                 orderDonStockMapper.updateById(orderDonStock);
                 GoodsDonStockRecord putRecord = stockRecordMapper.selectById(orderDonStock.getRecordId());
+                //发货库存操作已撤销
+                if (putRecord.getIsUndo()) {
+                    return;
+                }
 
                 GoodsDonStock stock = stockMapper.selectById(putRecord.getStockId());
                 //新增库存记录
@@ -81,6 +87,7 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
                     .eq(GoodsDonStockRecord::getStockId, stockId)
                     .eq(GoodsDonStockRecord::getType, "put")
                     .gt(GoodsDonStockRecord::getAvailable, 0)
+                    .eq(GoodsDonStockRecord::getIsUndo, false)
                     .orderByAsc(GoodsDonStockRecord::getCreatedTime)
                     .last(" limit 1")
             );
@@ -98,7 +105,7 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
             GoodsDonStock stock = stockMapper.selectById(putRecord.getStockId());
             //新增库存记录
             GoodsDonStockRecord record = new GoodsDonStockRecord();
-            record.setNum(-1);
+            record.setNum(1);
             record.setStockId(stockId);
             record.setThenTotal(stock.getTotal());
             record.setType("transport");
@@ -145,12 +152,13 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
         GoodsDonStock goodsDonStock = stockMapper.selectById(stock.getId());
         GoodsDonStockRecord putRecord = stockRecordMapper.selectOne(
                 Wrappers.lambdaQuery(GoodsDonStockRecord.class)
-                        .eq(GoodsDonStockRecord::getStockId,stock.getId())
-                        .eq(GoodsDonStockRecord::getType,"put")
-                        .gt(GoodsDonStockRecord::getAvailable,0)
+                        .eq(GoodsDonStockRecord::getStockId, stock.getId())
+                        .eq(GoodsDonStockRecord::getType, "put")
+                        .gt(GoodsDonStockRecord::getAvailable, 0)
+                        .eq(GoodsDonStockRecord::getIsUndo, false)
                         .orderByAsc(GoodsDonStockRecord::getId)
                         .last(" limit 1")
-                );
+        );
         if(putRecord == null){
             throw BusinessRuntimeException.getInstance("没有库存>0的批次");
         }
@@ -256,4 +264,147 @@ public class GoodsDonStockServiceImpl implements GoodsDonStockService {
         stockMapper.deleteById(stockId);
         skuStockRelateMapper.delete(Wrappers.lambdaQuery(GoodsSkuStockRelate.class).eq(GoodsSkuStockRelate::getStockId,stockId));
     }
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class)
+    public void updateBindGoods(GoodsDonStock stock) {
+        GoodsDonStock dbStock = stockMapper.selectById(stock.getId());
+        if (dbStock == null) {
+            throw BusinessRuntimeException.getInstance("库存不存在");
+        }
+        if (StrUtil.isNotBlank(stock.getTitle())) {
+            dbStock.setTitle(stock.getTitle());
+            stockMapper.updateById(dbStock);
+        }
+        List<GoodsSkuStockRelate> dbStockRelateList = skuStockRelateMapper.selectList(Wrappers.lambdaQuery(GoodsSkuStockRelate.class)
+                .eq(GoodsSkuStockRelate::getStockId, stock.getId()));
+
+        Map<Long, List<GoodsSkuStockRelate>> dbSkuMap = dbStockRelateList.stream().collect(Collectors.groupingBy(GoodsSkuStockRelate::getSkuId));
+
+        List<GoodsSkuStockRelate> relateList = stock.getRelateList();
+        Map<Long, List<GoodsSkuStockRelate>> skuMap = relateList.stream().collect(Collectors.groupingBy(GoodsSkuStockRelate::getSkuId));
+
+        List<GoodsSkuStockRelate> insertList = new ArrayList<>();
+        List<GoodsSkuStockRelate> deleteList = new ArrayList<>();
+
+        //目前的
+        relateList.forEach(relate->{
+            List<GoodsSkuStockRelate> stockRelates = dbSkuMap.get(relate.getSkuId());
+            if (CollUtil.isEmpty(stockRelates)) {
+                insertList.add(relate);
+            }
+        });
+
+        dbStockRelateList.forEach(data -> {
+            List<GoodsSkuStockRelate> stockRelates = skuMap.get(data.getSkuId());
+            if (CollUtil.isEmpty(stockRelates)) {
+                deleteList.add(data);
+            }
+        });
+
+        Long uniformId = SEQUENCE.nextId();
+        String operator = stock.getOperator();
+
+        insertList.forEach(insert->{
+            insert.setStockId(stock.getId());
+            skuStockRelateMapper.insert(insert);
+
+            saveChangeRelateRecord(insert, "insert", uniformId, operator);
+        });
+
+        List<Long> deleteRelateIds = new ArrayList<>();
+        deleteList.forEach(delete->{
+            saveChangeRelateRecord(delete, "delete", uniformId, operator);
+
+            deleteRelateIds.add(delete.getId());
+        });
+
+        if (CollUtil.isNotEmpty(deleteRelateIds)) {
+            skuStockRelateMapper.deleteBatchIds(deleteRelateIds);
+        }
+    }
+
+    public void saveChangeRelateRecord(GoodsSkuStockRelate skuStockRelate, String type, Long uniformId, String operator) {
+        GoodsSkuStockRelateChangeRecord changeRecord = new GoodsSkuStockRelateChangeRecord();
+        BeanUtil.copyProperties(skuStockRelate, changeRecord);
+        changeRecord.setType(type);
+        changeRecord.setUniformId(uniformId);
+        changeRecord.setOperator(operator);
+        relateChangeRecordMapper.insert(changeRecord);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class)
+    public void undoChange(Long recordId) {
+        GoodsDonStockRecord goodsDonStockRecord = stockRecordMapper.selectById(recordId);
+        if (goodsDonStockRecord == null) {
+            throw BusinessRuntimeException.getInstance("该库存变更记录不存在");
+        }
+        //撤销
+        Long stockId = goodsDonStockRecord.getStockId();
+        //目前可用
+        Integer num = goodsDonStockRecord.getAvailable();
+        String type = goodsDonStockRecord.getType();
+        //扣减库存回滚操作 数量为正时 置为负数
+        if (!ADD_OPERATE.contains(type)) {
+            //回滚扣除操作时
+            num = goodsDonStockRecord.getNum();
+            if (num > 0) {
+                num = -num;
+            }
+        }
+        handleUndoChange(type, goodsDonStockRecord.getId(), stockId, num);
+    }
+
+    /**
+     * @param stockRecordId 库存存储记录id
+     * @param stockId       库存id
+     * @param num           库存数量
+     */
+    public void handleUndoChange(String type, Long stockRecordId, Long stockId, Integer num) {
+        GoodsDonStock goodsDonStock = stockMapper.selectById(stockId);
+        if (ADD_OPERATE.contains(type) && goodsDonStock.getTotal() <= 0) {
+            throw BusinessRuntimeException.getInstance("当前商品库存为0,不可撤销该增加库存操作");
+        }
+        int update = stockRecordMapper.update(null, Wrappers.lambdaUpdate(GoodsDonStockRecord.class)
+                .set(GoodsDonStockRecord::getIsUndo, true)
+                .set(num > 0, GoodsDonStockRecord::getAvailable, 0)
+                .eq(GoodsDonStockRecord::getId, stockRecordId)
+                .eq(GoodsDonStockRecord::getIsUndo, false));
+
+        if (update > 0) {
+            //回滚扣减库存操作
+            if (num < 0) {
+                String recordType = "put";
+                Boolean isUndo = false;
+                GoodsDonStockRecord record = stockRecordMapper.selectUndoRecord(stockId, isUndo, recordType);
+                if (record == null) {
+                    isUndo = true;
+                    record = stockRecordMapper.selectUndoRecord(stockId, isUndo, recordType);
+                }
+                if (record != null) {
+                    Integer available = record.getAvailable();
+                    //回滚新增库存的时候的可用数
+                    update = stockRecordMapper.update(null, Wrappers.lambdaUpdate(GoodsDonStockRecord.class)
+                            .set(GoodsDonStockRecord::getAvailable, available - num)
+                            .set(GoodsDonStockRecord::getIsUndo, false)
+                            .eq(GoodsDonStockRecord::getId, record.getId())
+                            .eq(GoodsDonStockRecord::getAvailable, available));
+                    if (update == 0) {
+                        throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
+                    }
+                }
+            }
+
+            //恢复对应储存的库存
+            update = stockMapper.update(null, Wrappers.lambdaUpdate(GoodsDonStock.class)
+                    .set(GoodsDonStock::getTotal, goodsDonStock.getTotal() - num)
+                    .set(GoodsDonStock::getStock, goodsDonStock.getStock() - num)
+                    .eq(GoodsDonStock::getId, stockId)
+                    .eq(GoodsDonStock::getTotal, goodsDonStock.getTotal()));
+            if (update == 0) {
+                throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
+            }
+        }
+    }
 }

+ 30 - 0
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonPostServiceImpl.java

@@ -1,25 +1,40 @@
 package com.cyksj.service.order.impl;
 
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.common.constant.Constant;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.mapper.OrderDonMapper;
+import com.cyksj.mapper.SysConfigMapper;
 import com.cyksj.mapper.order.OrderDonPostMapper;
+import com.cyksj.model.entity.OrderDon;
 import com.cyksj.model.entity.OrderDonPost;
+import com.cyksj.model.entity.SysConfig;
 import com.cyksj.service.order.OrderDonPostService;
 import com.cyksj.service.order.post.AbstractPostDataService;
 import com.cyksj.service.order.post.PostDataFactory;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 
+import java.util.List;
+
 /**
  * @author chan
  * @date 2023/5/16 11:05 AM
  */
 @Service
 @Slf4j
+@RequiredArgsConstructor
 public class OrderDonPostServiceImpl extends ServiceImpl<OrderDonPostMapper, OrderDonPost> implements OrderDonPostService {
 
+    private final OrderDonMapper orderDonMapper;
+
+    private final SysConfigMapper sysConfigMapper;
+
     @Override
     public void postData(Long orderId) throws Exception {
         OrderDonPost orderPost = this.getOne(Wrappers.lambdaQuery(OrderDonPost.class).eq(OrderDonPost::getOrderId, orderId).eq(OrderDonPost::getStatus, Boolean.FALSE));
@@ -27,6 +42,21 @@ public class OrderDonPostServiceImpl extends ServiceImpl<OrderDonPostMapper, Ord
             log.info("post 数据 不了存在 id:{}", orderId);
             return;
         }
+        if (orderPost.getType() == OrderDonPost.Type.BaiDu) {
+            SysConfig baiduFilterConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
+                    .eq(SysConfig::getSysKey, Constant.BAIDU_POST_FILTER_GOODS_KEY).last("limit 1"));
+            if (baiduFilterConfig != null) {
+                String sysValue = baiduFilterConfig.getSysValue();
+                if (StrUtil.isNotBlank(sysValue)) {
+                    List<Long> baiduFilterGoods = Jsons.parseList(sysValue, Long.class);
+                    OrderDon orderDon = orderDonMapper.selectById(orderId);
+                    if (baiduFilterGoods.contains(orderDon.getGoodsId())) {
+                        log.info("baidu 不回传该商品. 该订单商品id:{}", orderDon.getGoodsId());
+                        return;
+                    }
+                }
+            }
+        }
         post(orderId, orderPost);
     }
 

+ 30 - 101
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -105,9 +105,6 @@ import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_ALREADY_BE_USER;
-import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_NOT_FIND;
-
 /**
  * @author chan
  * @date 2021/10/11 下午4:08
@@ -1370,6 +1367,12 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		BigDecimal points = null;
 		BigDecimal returnMoney = null;
 		Long businessId = null;
+		//普通分销
+		GoodsDon goodsDon = goodsDonMapper.selectById(order.getGoodsId());
+		if (goodsDon == null || !goodsDon.getIsDistribute()) {
+			log.info("分销订单orderId:{}对应平台goodsId:{}不存在或已不参与分成比例", order.getId(), order.getGoodsId());
+			return;
+		}
 		UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class).eq(UserDistributeShared::getUserId, order.getUserId()).last("limit 1"));
 		if (userDistributeShared != null) {
 			distributeWaitingSendPoints.setSharedId(userDistributeShared.getSharedId());
@@ -1378,34 +1381,30 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 				log.info("分销兑换积分比例未配置");
 			} else {
 				UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, userDistributeShared.getSharedId()).eq(UserDistribute::getDeleted, true).last("limit 1"));
-				//普通分销
-				GoodsDon goodsDon = goodsDonMapper.selectById(order.getGoodsId());
 				//分销比例
 				Integer rate = 0;
 				if (userDistribute == null) {
-					if (goodsDon != null) {
-						//普通分销者 是否享受过该用户的首单分销
-						DistributeWaitingSendPoints isReceived = distributeWaitingSendPointsMapper.selectOne(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class)
-								.eq(DistributeWaitingSendPoints::getSharedId, userDistributeShared.getSharedId())
-								.eq(DistributeWaitingSendPoints::getUserId, order.getUserId())
-								.in(DistributeWaitingSendPoints::getSendStatus, List.of(DistributeWaitingSendPoints.Status.waiting.name(), DistributeWaitingSendPoints.Status.success.name()))
-								.last("limit 1"));
-						if (isReceived != null) {
-							return;
-						}
-						rate = goodsDon.getRate();
-						//实物分销比例
-						if (goodsDon.getType() == 2) {
-							GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(order.getSkuId());
-							if (goodsDonSku != null) {
-								//不包含套餐权益
-								if (!goodsDonSku.getIsBenefits()) {
-									rate = goodsDon.getSecondRate();
-								}
+					//普通分销者 是否享受过该用户的首单分销
+					DistributeWaitingSendPoints isReceived = distributeWaitingSendPointsMapper.selectOne(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class)
+							.eq(DistributeWaitingSendPoints::getSharedId, userDistributeShared.getSharedId())
+							.eq(DistributeWaitingSendPoints::getUserId, order.getUserId())
+							.in(DistributeWaitingSendPoints::getSendStatus, List.of(DistributeWaitingSendPoints.Status.waiting.name(), DistributeWaitingSendPoints.Status.success.name()))
+							.last("limit 1"));
+					if (isReceived != null) {
+						return;
+					}
+					rate = goodsDon.getRate();
+					//实物分销比例
+					if (goodsDon.getType() == 2) {
+						GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(order.getSkuId());
+						if (goodsDonSku != null) {
+							//不包含套餐权益
+							if (!goodsDonSku.getIsBenefits()) {
+								rate = goodsDon.getSecondRate();
 							}
 						}
-						returnMoney = orderMoney.multiply(BigDecimal.valueOf(rate)).divide(BigDecimal.valueOf(100));
 					}
+					returnMoney = orderMoney.multiply(BigDecimal.valueOf(rate)).divide(BigDecimal.valueOf(100));
 				} else {
 					businessId = userDistribute.getBusinessId();
 					//固定推广分销
@@ -1905,81 +1904,11 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 	 * yshId 店铺id
 	 */
 	public GroupsRelation getRelation(OrderPayRequest payRequest, GoodsDonSku sku, Long yhsId) {
-		GroupsRelation relation;
 		Long payRelationId = payRequest.getRelationId();
 		Boolean isLoginPopularize = payRequest.getIsLoginPopularize();
 		Long userId = payRequest.getUserId();
-		//锁定座位
-		if (payRelationId != null && payRelationId > 0) {
-			relation = groupsRelationMapper.selectById(payRelationId);
-			if (relation == null) {
-				throw new BusinessRuntimeException(GROUP_INDEX_NOT_FIND.getCode(), GROUP_INDEX_NOT_FIND.getMsg());
-			}
-			if (relation.getUserId() != null && relation.getUserId() > 0L) {
-				throw new BusinessRuntimeException(GROUP_INDEX_ALREADY_BE_USER.getCode(), GROUP_INDEX_ALREADY_BE_USER.getMsg());
-			}
-
-		} else {
-			//寻找差不多过期时间规格的车位
-			relation = groupRelationFrontService.getSimilarExpiredGroupRelation(sku.getId(), sku.getDays(), sku.getMonths(), null);
-			if (relation == null) {
-				//TODO 如果没指定座位,等待逻辑确认
-				GroupsTrips groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
-						.eq(GroupsTrips::getSkuId, sku.getId())
-						.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
-						.eq(GroupsTrips::getStatus, GroupsTrips.Status.validity)
-						.orderByAsc(GroupsTrips::getAvailableNum));
-				if (groups == null) {
-					//若是MidJourney、ChatGPT PLUS每个已满车队 硬塞5个座位
-					//主账号过期时间10天以外
-					if (sku.getNum() > 1 && Constant.AI_goodsIds.contains(sku.getGoodsId())) {
-						DateTime tenExpiry = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), 10);
-						//不塞存在该用户的车队
-						Long groupsId = groupsRelationMapper.getOutSideGroupsTripsRelationByGoodsId(sku.getId(), tenExpiry, 5, userId);
-						if (groupsId != null) {
-							relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
-									.eq(GroupsRelation::getGroupsId, groupsId)
-									.eq(GroupsRelation::getUserId, 0)
-									.eq(GroupsRelation::getStatus, GroupsRelation.Status.outside)
-									.last("limit 1"));
-							if (relation == null) {
-								if (redisService.setNx(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getName() + groupsId, groupsId, RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getTimeout())) {
-									relation = new GroupsRelation();
-									relation.setStatus(GroupsRelation.Status.outside);
-									relation.setUserId(userId);
-									relation.setGroupsId(groupsId);
-									GroupsRelation maxNumRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsId).orderByDesc(GroupsRelation::getNum).last("limit 1"));
-									relation.setNum(maxNumRelation.getNum() + 1);
-									groupsRelationMapper.insert(relation);
-									redisService.del(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getName() + groupsId);
-								}
-							}
-							groups = groupsMapper.selectById(groupsId);
-						}
-					}
-					if (relation == null) {
-						//待发车
-						groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
-								.eq(GroupsTrips::getSkuId, sku.getId())
-								.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
-								.eq(GroupsTrips::getStatus, GroupsTrips.Status.waiting)
-								.orderByAsc(GroupsTrips::getAvailableNum));
-					}
-				}
-
-				if (groups == null) {
-					relation = groupsFuncService.createNewGroupsTrips(sku);
-				}
-
-				if (relation == null) {
-					//寻找快满编车队进行占座
-					relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId());
-					if (relation == null) {
-						throw new BusinessRuntimeException(GROUP_INDEX_NOT_FIND.getCode(), GROUP_INDEX_NOT_FIND.getMsg());
-					}
-				}
-			}
-		}
+		//获取车票车位
+		GroupsRelation relation = groupRelationFrontService.getRelation(payRelationId, userId, sku);
 
 		//锁定座位
 		setRelation(relation.getId(), relation.getGroupsId(), userId, sku.getGoodsId(), isLoginPopularize, relation.getStatus());
@@ -2510,12 +2439,12 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 					if (!userDistributeShared.getIsBind()) {
 						orderDon.setIsDistribute(false);
 					} else {
-						//45天内是否下单成功
+						//45天内是否下单成功 ==>改为30天
 						Date createdTime = userDistributeShared.getCreatedTime();
-						DateTime forty_five = DateUtil.offsetDay(createdTime, 45);
+						DateTime time = DateUtil.offsetDay(createdTime, 30);
 						//在45天内
 						Boolean is_fit = false;
-						boolean before = DateTime.now().isBefore(forty_five);
+						boolean before = DateTime.now().isBefore(time);
 						//超过45天还未下过单
 						//直接不参与后续的 提成
 						if (before) {
@@ -2524,7 +2453,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 							int count = this.count(Wrappers.lambdaQuery(OrderDon.class)
 									.eq(OrderDon::getUserId, userId)
 									.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
-									.le(OrderDon::getCreatedTime, forty_five));
+									.le(OrderDon::getCreatedTime, time));
 							if (count > 0) {
 								is_fit = true;
 							} else {

+ 6 - 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.entity.GoodsDonSku;
 import com.cyksj.model.entity.GroupsRelation;
 import com.cyksj.model.request.SpecialGoodsTicketReq;
 import com.cyksj.model.views.RenewalView;
@@ -27,4 +28,9 @@ public interface GroupRelationFrontService {
 	 * 通过邮件发送课程
 	 */
 	void sendCourseWare(SpecialGoodsTicketReq request) throws Exception;
+
+	/**
+	 * 获取车票座位
+	 */
+	GroupsRelation getRelation(Long payRelationId, Long userId, GoodsDonSku sku);
 }

+ 89 - 4
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -8,18 +8,17 @@ import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.cyksj.common.constant.Constant;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.util.Jsons;
 import com.cyksj.enums.GatewayApiCode;
-import com.cyksj.mapper.GroupsRelationMapper;
-import com.cyksj.mapper.OrderDiscountPlusPurchaseSkuRelationMapper;
-import com.cyksj.mapper.OrderDonMapper;
-import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.*;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.request.SpecialGoodsTicketReq;
 import com.cyksj.model.views.*;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.chatgpt.ChatGptAuthService;
+import com.cyksj.service.groups.GroupsFuncService;
 import com.cyksj.service.mail.MailService;
 import com.cyksj.service.mange.coupon.CouponCommonService;
 import com.cyksj.service.relation.GroupRelationFrontService;
@@ -40,6 +39,9 @@ import java.util.Date;
 import java.util.List;
 import java.util.Optional;
 
+import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_ALREADY_BE_USER;
+import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_NOT_FIND;
+
 /*
  *项目名: netflix
  *文件名: GroupRelationFrontServiceImpl
@@ -60,6 +62,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final GroupsRelationMapper groupsRelationMapper;
 
+	private final GroupsMapper groupsMapper;
+
 	private final ChatGptAuthService chatGptAuthService;
 
 	private final RedisService redisService;
@@ -72,6 +76,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final HttpServletRequest request;
 
+	private final GroupsFuncService groupsFuncService;
+
 	private final OrderDiscountPlusPurchaseSkuRelationMapper orderDiscountPlusPurchaseSkuRelationMapper;
 
 	@Override
@@ -284,4 +290,83 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 			mailService.sendCoursewareByGoodsId(relation.getGoodsId(), relation.getRelationId(), relation.getUserId(), relation.getTitle(), email);
 		}
 	}
+
+	@Override
+	public GroupsRelation getRelation(Long payRelationId, Long userId, GoodsDonSku sku) {
+		GroupsRelation relation = null;
+		if (payRelationId != null && payRelationId > 0) {
+			relation = groupsRelationMapper.selectById(payRelationId);
+			if (relation == null) {
+				throw new BusinessRuntimeException(GROUP_INDEX_NOT_FIND.getCode(), GROUP_INDEX_NOT_FIND.getMsg());
+			}
+			if (relation.getUserId() != null && relation.getUserId() > 0L) {
+				throw new BusinessRuntimeException(GROUP_INDEX_ALREADY_BE_USER.getCode(), GROUP_INDEX_ALREADY_BE_USER.getMsg());
+			}
+
+		} else {
+			GroupsTrips groups = null;
+			//ChatGpt Plus、Midjourney非独立规格 上车先获取硬塞座位 硬塞5个座位
+			//主账号过期时间25天以外
+			if (sku.getNum() > 1 && Constant.AI_goodsIds.contains(sku.getGoodsId())) {
+				DateTime time = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), 25);
+				//不塞存在该用户的车队
+				Long groupsId = groupsRelationMapper.getOutSideGroupsTripsRelationByGoodsId(sku.getId(), time, 5, userId, sku.getNum());
+				if (groupsId != null) {
+					relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+							.eq(GroupsRelation::getGroupsId, groupsId)
+							.eq(GroupsRelation::getUserId, 0)
+							.eq(GroupsRelation::getStatus, GroupsRelation.Status.outside)
+							.last("limit 1"));
+					if (relation == null) {
+						relation = new GroupsRelation();
+						relation.setStatus(GroupsRelation.Status.outside);
+						relation.setUserId(userId);
+						relation.setGroupsId(groupsId);
+						GroupsRelation maxNumRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsId).orderByDesc(GroupsRelation::getNum).last("limit 1"));
+						Integer nextNum = maxNumRelation.getNum() + 1;
+						if (redisService.setNx(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getNameFormat(groupsId, nextNum), nextNum, RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getTimeout())) {
+							relation.setNum(nextNum);
+							groupsRelationMapper.insert(relation);
+						} else {
+							throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
+						}
+					}
+					groups = groupsMapper.selectById(groupsId);
+				}
+			}
+			if (groups == null) {
+				//寻找差不多过期时间规格的车位
+				relation = getSimilarExpiredGroupRelation(sku.getId(), sku.getDays(), sku.getMonths(), null);
+				if (relation == null) {
+					//TODO 如果没指定座位,等待逻辑确认
+					groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
+							.eq(GroupsTrips::getSkuId, sku.getId())
+							.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
+							.eq(GroupsTrips::getStatus, GroupsTrips.Status.validity)
+							.orderByAsc(GroupsTrips::getAvailableNum));
+					if (groups == null) {
+						//待发车
+						groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
+								.eq(GroupsTrips::getSkuId, sku.getId())
+								.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
+								.eq(GroupsTrips::getStatus, GroupsTrips.Status.waiting)
+								.orderByAsc(GroupsTrips::getAvailableNum));
+					}
+					//新增空车队
+					if (groups == null) {
+						relation = groupsFuncService.createNewGroupsTrips(sku);
+					}
+					//获取车位
+					if (relation == null) {
+						//寻找快满编车队进行占座
+						relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId());
+						if (relation == null) {
+							throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
+						}
+					}
+				}
+			}
+		}
+		return relation;
+	}
 }

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

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

+ 1 - 0
netflix-service/src/main/java/com/cyksj/service/shop/impl/YhShopDistributeServiceImpl.java

@@ -61,6 +61,7 @@ public class YhShopDistributeServiceImpl implements YhShopDistributeService {
 				.eq(GoodsDon::getId, order.getGoodsId()).last("limit 1"));
 		if (goodsDon == null || !goodsDon.getIsDistribute()) {
 			log.info("店铺订单orderId:{}对应平台goodsId:{}不存在或已不参与分成比例", order.getId(), order.getGoodsId());
+			return;
 		}
 		Long shopUserId = yhShop.getUserId();
 		YhShopDistributeWaitingSendPoints distributeWaitingSendPoints = new YhShopDistributeWaitingSendPoints();

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

@@ -639,7 +639,7 @@ public class CmsOrderController {
 	 */
 	@PutMapping("/refund/price/differ")
 	@Log(module = "订单管理/订单补差价", businessType = BusinessType.PUT, isSaveRequestData = true)
-	public Result<String> refundPriceDiffer(@RequestBody OrderRefundReq orderRefundReq) {
+	public Result<String> refundPriceDiffer(@RequestBody OrderRefundReq orderRefundReq) throws Exception {
 		cmsOrderDonService.refundPriceDiffer(orderRefundReq);
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}

+ 117 - 3
netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java

@@ -3,8 +3,8 @@ package com.cyksj.web.controller.manage.distribute;
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.date.BetweenFormater;
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.BetweenFormater;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
@@ -16,6 +16,7 @@ import com.cyksj.common.util.StringUtil;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.DistributeGoodsSkuAlertMapper;
 import com.cyksj.mapper.GoodsDonMapper;
 import com.cyksj.mapper.GoodsDonSkuMapper;
 import com.cyksj.mapper.UserMapper;
@@ -50,6 +51,7 @@ import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
 /*
@@ -102,8 +104,12 @@ public class DistributeController {
 
 	private final RedisService redisService;
 
+	private final DistributeGoodsSkuAlertMapper distributeGoodsSkuAlertMapper;
+
 	private final UserDistributeRuleOrderRecordMapper userDistributeRuleOrderRecordMapper;
 
+	private final UserDistributeBusinessGeneralRateMapper businessGeneralRateMapper;
+
 	/**
 	 * 添加固定推广者
 	 */
@@ -239,7 +245,11 @@ public class DistributeController {
 	 */
 	@GetMapping("/get/plat")
 	public Result<List<GoodsDon>> getGoodsDistributeRate() {
-		return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonMapper.selectList(Wrappers.lambdaQuery(GoodsDon.class).in(GoodsDon::getType, Constant.dsGoodsIds).eq(GoodsDon::getDeleted, true).eq(GoodsDon::getStatus, true).orderByAsc(GoodsDon::getType).orderByAsc(GoodsDon::getId).select(GoodsDon::getId, GoodsDon::getType, GoodsDon::getTitle, GoodsDon::getRate, GoodsDon::getSecondRate)));
+		return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonMapper.selectList(Wrappers.lambdaQuery(GoodsDon.class).in(GoodsDon::getType, Constant.dsGoodsIds).eq(GoodsDon::getDeleted, true)
+				.eq(GoodsDon::getStatus, true).orderByAsc(GoodsDon::getType)
+				.eq(GoodsDon::getIsDistribute, true)
+				.orderByAsc(GoodsDon::getId)
+				.select(GoodsDon::getId, GoodsDon::getType, GoodsDon::getTitle, GoodsDon::getRate, GoodsDon::getSecondRate)));
 	}
 
 	/**
@@ -535,6 +545,7 @@ public class DistributeController {
 	@PutMapping("/put/business/rate")
 	@Log(module = "分销管理/修改商务人员比例", businessType = BusinessType.PUT, isSaveRequestData = true)
 	public Result<String> updateBusinessRate(@RequestBody @Validated List<UserDistributeBusinessRate> rates) {
+		List<Long> newDsSkuIds = new ArrayList<>();
 		rates.forEach(userDistributeBusinessRate -> {
 			Long rateId = userDistributeBusinessRate.getId();
 			UserDistributeBusinessRate businessRate = Optional.ofNullable(userDistributeBusinessRateMapper.selectById(rateId)).orElse(new UserDistributeBusinessRate());
@@ -554,12 +565,20 @@ public class DistributeController {
 			if (businessRate.getId() == null) {
 				try {
 					userDistributeBusinessRateMapper.insert(businessRate);
+
+					newDsSkuIds.add(businessRate.getSkuId());
 				} catch (DuplicateKeyException e) {
 				}
 			} else {
 				userDistributeBusinessRateMapper.updateById(businessRate);
 			}
 		});
+
+		if (CollUtil.isNotEmpty(newDsSkuIds)) {
+			//删除存在告警的平台规格
+			distributeGoodsSkuAlertMapper.delete(Wrappers.lambdaQuery(DistributeGoodsSkuAlert.class)
+					.in(DistributeGoodsSkuAlert::getSkuId, newDsSkuIds));
+		}
 		return GatewayResponse.SUCCESS.newBuilder().toResult("修改比例成功");
 	}
 
@@ -651,7 +670,14 @@ public class DistributeController {
 					userPlatDistributeRate.setSecondRate(secondRate);
 					save.add(userPlatDistributeRate);
 				});
-				Lists.partition(save, 100).forEach(part -> userDistributeBusinessRateMapper.batchInsertDistributePlatRate(part));
+				Lists.partition(save, 100).forEach(part -> {
+					List<Long> goodsIds = part.stream().map(UserPlatDistributeRate::getGoodsId).collect(Collectors.toList());
+					//删除存在告警的平台
+					distributeGoodsSkuAlertMapper.delete(Wrappers.lambdaQuery(DistributeGoodsSkuAlert.class)
+							.in(DistributeGoodsSkuAlert::getGoodsId, goodsIds));
+
+					userDistributeBusinessRateMapper.batchInsertDistributePlatRate(part);
+				});
 			}
 			businessDefaultRateConfigMapper.updateById(config);
 		});
@@ -899,4 +925,92 @@ public class DistributeController {
 		List<BusinessDistributesMonthlyDataView> collect = businessDistributesDataViews.stream().sorted(Comparator.comparing(BusinessDistributesMonthlyDataView::getBusinessId).thenComparing(BusinessDistributesMonthlyDataView::getType)).collect(Collectors.toList());
 		return GatewayResponse.SUCCESS.newBuilder().toResult(collect);
 	}
+
+	/**
+	 * 针对商务
+	 * 获取商务 分销平台通用比例
+	 */
+	@GetMapping("/get/business/general/rate")
+	public Result<List<UserDistributeBusinessGeneralRateView>> getBusinessGeneralRate(@RequestParam(defaultValue = "1") Integer type) {
+		List<UserDistributeBusinessGeneralRateView> userDistributeBusinessGeneralRateViews = beanSearcher.searchAll(UserDistributeBusinessGeneralRateView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.field(UserDistributeBusinessGeneralRateView::getType, type).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(userDistributeBusinessGeneralRateViews);
+	}
+
+	/**
+	 * 编辑商务 分销平台通用比例
+	 * 商务的平台规格提成 根据这个改变
+	 */
+	@PutMapping("/put/business/general/rate")
+	@Transactional(rollbackFor = Throwable.class)
+	public Result<String> updateBusinessGeneralRate(@RequestBody List<UserDistributeBusinessGeneralRate> generalRates) {
+		List<CmsUserVO> userVOS = beanSearcher.searchAll(CmsUserVO.class, MapUtils.builder().field(CmsUserVO::getRoleNames, "商务").op(Operator.Contain).build());
+		List<Long> collect = userVOS.stream().map(CmsUserVO::getId).collect(Collectors.toList());
+		final List<Long> businessIds = collect;
+		List<Long> newDsSkuIds = new ArrayList<>();
+		generalRates.forEach(data -> {
+			if (data.getId() == null) {
+				try {
+					//新增
+					UserDistributeBusinessGeneralRate businessGeneralRate = new UserDistributeBusinessGeneralRate();
+					if (data.getGoodsId() == null || data.getSkuId() == null) {
+						throw BusinessRuntimeException.getInstance("缺少必要参数");
+					}
+					businessGeneralRate.setGoodsId(data.getGoodsId());
+					businessGeneralRate.setSkuId(data.getSkuId());
+					Integer firstOrderRate = Optional.ofNullable(data.getFirstOrderRate()).orElse(0);
+					businessGeneralRate.setFirstOrderRate(firstOrderRate);
+					Integer renewOrderRate = Optional.ofNullable(data.getRenewOrderRate()).orElse(0);
+					businessGeneralRate.setRenewOrderRate(renewOrderRate);
+					businessGeneralRateMapper.insert(businessGeneralRate);
+					if (CollUtil.isNotEmpty(businessIds)) {
+						userDistributeBusinessRateMapper.insertOrUpdateBusinessGoodsSkuRate(businessIds, data.getGoodsId(), data.getSkuId(), firstOrderRate, renewOrderRate);
+					}
+					newDsSkuIds.add(data.getSkuId());
+				} catch (DuplicateKeyException e) {
+				}
+				return;
+			}
+			UserDistributeBusinessGeneralRate dbGeneralRate = businessGeneralRateMapper.selectById(data.getId());
+			if (dbGeneralRate != null) {
+				Integer firstOrderRate_new = null;
+				Integer renewOrderRate_new = null;
+				AtomicBoolean is_change = new AtomicBoolean(false);
+				//需要更新首单比例
+				if (data.getFirstOrderRate() != null && dbGeneralRate.getFirstOrderRate() != data.getFirstOrderRate()) {
+					firstOrderRate_new = data.getFirstOrderRate();
+					is_change.set(true);
+				}
+				//需要更新续费比例
+				if (data.getRenewOrderRate() != null && dbGeneralRate.getRenewOrderRate() != data.getRenewOrderRate()) {
+					renewOrderRate_new = data.getRenewOrderRate();
+					is_change.set(true);
+				}
+				if (is_change.get()) {
+					businessGeneralRateMapper.updateById(data);
+					newDsSkuIds.add(data.getSkuId());
+					if (CollUtil.isNotEmpty(businessIds)) {
+						//获取所有商务
+						userDistributeBusinessRateMapper.insertOrUpdateBusinessGoodsSkuRate(businessIds, data.getGoodsId(), data.getSkuId(), firstOrderRate_new, renewOrderRate_new);
+					}
+				}
+			}
+
+			if (CollUtil.isNotEmpty(newDsSkuIds)) {
+				//删除存在告警的平台规格
+				distributeGoodsSkuAlertMapper.delete(Wrappers.lambdaQuery(DistributeGoodsSkuAlert.class)
+						.in(DistributeGoodsSkuAlert::getSkuId, newDsSkuIds));
+			}
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 是否有未配置比例的规格
+	 */
+	@GetMapping("/get/goodsSku/alert")
+	public Result<Boolean> getGoodsSkuAlert() {
+		Integer count = distributeGoodsSkuAlertMapper.selectCountByCondition();
+		return GatewayResponse.SUCCESS.newBuilder().toResult(count > 0 ? true : false);
+	}
 }

+ 8 - 4
netflix-web/src/main/java/com/cyksj/web/controller/manage/group/CmsGroupController.java

@@ -22,10 +22,7 @@ import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GroupsRelationAlertMapper;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.UserMapper;
-import com.cyksj.model.entity.Account;
-import com.cyksj.model.entity.GroupsRelationAlert;
-import com.cyksj.model.entity.GroupsTrips;
-import com.cyksj.model.entity.GroupsTripsAccountReplaceRecord;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.excel.ExcelGroupRelationData;
 import com.cyksj.model.request.AccountGroupsReq;
 import com.cyksj.model.request.ReplaceTripsAccountReq;
@@ -102,6 +99,13 @@ public class CmsGroupController {
                 .field(GroupsTrips::getAccount, StringUtils.isBlank(account) ? null : account).op(Operator.EndWith)
                 .build()
         );
+        search.getDataList().forEach(data->{
+            Number count = beanSearcher.searchCount(GroupsRelation.class, MapUtils.builder()
+                    .field(GroupsRelation::getGroupsId, data.getId())
+                    .field(GroupsRelation::getUserId, 0).op(Operator.NotEqual)
+                    .build());
+            data.setIsExists(count.intValue() > 0 ? true : false);
+        });
         return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
 

+ 6 - 4
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -362,7 +362,8 @@ public class StatisticsDataController {
 		goodsDonStocks.forEach((stock)->{
 			List<GoodsDonStockRecord> goodsDonStockRecords = stockRecordMapper.selectList(Wrappers.lambdaQuery(GoodsDonStockRecord.class)
 					.eq(GoodsDonStockRecord::getStockId, stock.getId())
-					.ge(startTime != 0 , GoodsDonStockRecord::getCreatedTime, DateTime.of(startTime).toString())
+					.eq(GoodsDonStockRecord::getIsUndo, false)
+					.ge(startTime != 0, GoodsDonStockRecord::getCreatedTime, DateTime.of(startTime).toString())
 					.le(endTime != 0, GoodsDonStockRecord::getCreatedTime, DateTime.of(endTime).toString())
 			);
 			Map<String, List<GoodsDonStockRecord>> typeRecordsMap = goodsDonStockRecords.stream().collect(Collectors.groupingBy(GoodsDonStockRecord::getType));
@@ -375,7 +376,7 @@ public class StatisticsDataController {
 				statisticsStockView.setThenTotal(sum);
 				statisticsStockView.setThenPrice(price);
 			}
-			statisticsStockView.setUnavailable(stock.getUnavailable());
+//			statisticsStockView.setUnavailable(stock.getUnavailable());
 			statisticsStockView.setTitle(stock.getTitle());
 			typeRecordsMap.forEach((type,records)->{
 				int sum = records.stream().mapToInt(GoodsDonStockRecord::getNum).sum();
@@ -397,7 +398,8 @@ public class StatisticsDataController {
 		goodsDonStocks.forEach((stock)->{
 			List<GoodsDonStockRecord> goodsDonStockRecords = stockRecordMapper.selectList(Wrappers.lambdaQuery(GoodsDonStockRecord.class)
 					.eq(GoodsDonStockRecord::getStockId, stock.getId())
-					.ge(startTime != 0 , GoodsDonStockRecord::getCreatedTime, DateTime.of(startTime).toString())
+					.eq(GoodsDonStockRecord::getIsUndo, false)
+					.ge(startTime != 0, GoodsDonStockRecord::getCreatedTime, DateTime.of(startTime).toString())
 					.le(endTime != 0, GoodsDonStockRecord::getCreatedTime, DateTime.of(endTime).toString())
 			);
 			Map<String, List<GoodsDonStockRecord>> typeRecordsMap = goodsDonStockRecords.stream().collect(Collectors.groupingBy(GoodsDonStockRecord::getType));
@@ -410,7 +412,7 @@ public class StatisticsDataController {
 				statisticsStockView.setThenTotal(sum);
 				statisticsStockView.setThenPrice(price);
 			}
-			statisticsStockView.setUnavailable(stock.getUnavailable());
+//			statisticsStockView.setUnavailable(stock.getUnavailable());
 			statisticsStockView.setTitle(stock.getTitle());
 			typeRecordsMap.forEach((type,records)->{
 				int sum = records.stream().mapToInt(GoodsDonStockRecord::getNum).sum();

+ 45 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/stock/StockController.java

@@ -1,12 +1,18 @@
 package com.cyksj.web.controller.manage.stock;
 
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.annotation.Log;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.manage.cms.CmsUserMapper;
+import com.cyksj.mapper.stock.GoodsSkuStockRelateMapper;
+import com.cyksj.model.entity.CmsUser;
 import com.cyksj.model.entity.GoodsDonStock;
 import com.cyksj.model.entity.GoodsDonStockRecord;
+import com.cyksj.model.entity.GoodsSkuStockRelate;
 import com.cyksj.model.request.StockUpReq;
 import com.cyksj.service.mange.stock.GoodsDonStockService;
 import com.ejlchina.searcher.BeanSearcher;
@@ -36,9 +42,17 @@ public class StockController {
 
     private final GoodsDonStockService stockService;
 
+    private final CmsUserMapper cmsUserMapper;
+
+    private final GoodsSkuStockRelateMapper skuStockRelateMapper;
+
     @GetMapping
     public Result<SearchResult<GoodsDonStock>> get(){
         SearchResult<GoodsDonStock> search = beanSearcher.search(GoodsDonStock.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+        search.getDataList().forEach(data->{
+            data.setRelateList(skuStockRelateMapper.selectList(Wrappers.lambdaQuery(GoodsSkuStockRelate.class)
+                    .eq(GoodsSkuStockRelate::getStockId, data.getId())));
+        });
         return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
 
@@ -71,10 +85,21 @@ public class StockController {
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
 
+    /**
+     * 撤销库存变动操作
+     */
+    @PutMapping("/undo/change/{recordId}")
+    public Result<String> undoChangeSku(@PathVariable Long recordId) {
+        stockService.undoChange(recordId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+
     /**
      * 编辑不可用
      */
     @PutMapping("/put/unavailable")
+    @Deprecated
     public Result<String> upUnavailable(@RequestBody StockUpReq stock){
         if(StringUtils.isBlank(stock.getRemark())){
             throw BusinessRuntimeException.getInstance("请填写备注");
@@ -87,6 +112,7 @@ public class StockController {
      * 编辑已刷机
      */
     @PutMapping("/put/upgrade")
+    @Deprecated
     public Result<String> upgrade(@RequestBody StockUpReq stock){
         stockService.upgrade(stock);
         return GatewayResponse.SUCCESS.newBuilder().toResult();
@@ -107,6 +133,25 @@ public class StockController {
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
 
+    /**
+     * 编辑库存商品绑定实物商品
+     */
+    @PutMapping("/update/bindGoods")
+    public Result<String> updateBindGoods(@RequestBody GoodsDonStock stock) {
+        long adminId = StpUtil.getLoginIdAsLong();
+        Long id = stock.getId();
+        if (id == null) {
+            throw BusinessRuntimeException.getInstance("库存id不存在");
+        }
+        if (stock.getRelateList().size() == 0) {
+            throw BusinessRuntimeException.getInstance("缺少关联商品");
+        }
+        CmsUser cmsUser = cmsUserMapper.selectById(adminId);
+        stock.setOperator(cmsUser.getNickname());
+        stockService.updateBindGoods(stock);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
     /*
     库存明细
     ------------------------------------------------------------------

+ 20 - 0
netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

@@ -437,6 +437,12 @@ public class AuthorizationController {
     @NoSubmit
     public Result<UserAuthLoginResp> loginByPhone(@RequestBody LoginReq loginReq) throws Exception {
         User user = userService.webLogin(loginReq);
+        Optional.ofNullable(user.getIsBlack())
+                .ifPresent(black -> {
+                    if (black) {
+                        throw BusinessRuntimeException.getInstance("您的账号已被注销...");
+                    }
+                });
         //写回登陆信息
         StpUserUtil.login(user.getId());
         UserAuthLoginResp loginPhoneRep = new UserAuthLoginResp(StpUserUtil.getTokenValue(), user.getShowId(), user.getNickname(), user.getHeadimgurl());
@@ -456,6 +462,13 @@ public class AuthorizationController {
             throw BusinessRuntimeException.getInstance("系统错误,请重新授权");
         }
 
+        Optional.ofNullable(user.getIsBlack())
+                .ifPresent(black -> {
+                    if (black) {
+                        throw BusinessRuntimeException.getInstance("您的账号已被注销...");
+                    }
+                });
+
         //写回登陆信息
         StpUserUtil.login(user.getId());
         response.addHeader("satoken-user", StpUserUtil.getTokenValue());
@@ -491,6 +504,13 @@ public class AuthorizationController {
         loginReq.setEmail(googleLoginRep.getEmail());
         loginReq.setSubject(googleLoginRep.getSubject());
         User user = userService.webLogin(loginReq);
+
+        Optional.ofNullable(user.getIsBlack())
+                .ifPresent(black -> {
+                    if (black) {
+                        throw BusinessRuntimeException.getInstance("您的账号已被注销...");
+                    }
+                });
         //写回登陆信息
         StpUserUtil.login(user.getId());
         UserAuthLoginResp loginPhoneRep = new UserAuthLoginResp(StpUserUtil.getTokenValue(), user.getShowId(), user.getNickname(), user.getHeadimgurl());