Преглед на файлове

Merge branch 'subsidy_sku_func' into pre

# Conflicts:
#	netflix-dao/src/main/java/com/cyksj/mapper/OrderDonMapper.java
#	netflix-dao/src/main/java/com/cyksj/mapper/UserMapper.java
#	netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeSubRewards.java
#	netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeSubWaiting.java
#	netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeSubDetailView.java
#	netflix-dao/src/main/resources/mapper/OrderDonMapper.xml
#	netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpTagServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/pay/impl/TransferFuncServiceImpl.java
#	netflix-web/src/main/java/com/cyksj/web/controller/cps/CpsBackLoginController.java
zoujiajian преди 2 години
родител
ревизия
72a52dbc4c
променени са 45 файла, в които са добавени 1165 реда и са изтрити 173 реда
  1. 23 0
      netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java
  2. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/GoodsDonSkuSubsidyMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonLocationRelateMapper.java
  4. 9 3
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonMapper.java
  5. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonSubsidyRelateMapper.java
  6. 3 0
      netflix-dao/src/main/java/com/cyksj/mapper/UserMapper.java
  7. 5 0
      netflix-dao/src/main/java/com/cyksj/model/dto/AuthRedirect.java
  8. 2 0
      netflix-dao/src/main/java/com/cyksj/model/dto/CpsAuthDto.java
  9. 36 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonSkuSubsidy.java
  10. 0 4
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDon.java
  11. 24 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDonLocationRelate.java
  12. 18 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDonSubsidyRelate.java
  13. 1 1
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeSubRewards.java
  14. 0 5
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeSubWaiting.java
  15. 5 0
      netflix-dao/src/main/java/com/cyksj/model/request/OrderPayRequest.java
  16. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/CpsApplyMoneyView.java
  17. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/DistributeMoneyApplyView.java
  18. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/DistributePopularizeView.java
  19. 124 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyDetailView.java
  20. 56 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyFrontView.java
  21. 43 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuSubsidyView.java
  22. 125 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSubsidyDetailView.java
  23. 1 1
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeSubDetailView.java
  24. 21 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserInfoView.java
  25. 75 42
      netflix-dao/src/main/resources/mapper/OrderDonMapper.xml
  26. 5 0
      netflix-service/src/main/java/com/cyksj/config/wxlogin/BaseWxOpenPlatConfig.java
  27. 12 0
      netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java
  28. 18 6
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpTagServiceImpl.java
  29. 14 0
      netflix-service/src/main/java/com/cyksj/service/mange/GoodsDonSkuSubsidyService.java
  30. 32 0
      netflix-service/src/main/java/com/cyksj/service/mange/goods/GoodsDonSkuSubsidyServiceImpl.java
  31. 46 0
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  32. 166 87
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  33. 34 17
      netflix-service/src/main/java/com/cyksj/service/pay/impl/TransferFuncServiceImpl.java
  34. 5 0
      netflix-service/src/main/java/com/cyksj/service/user/UserBenefitsService.java
  35. 16 0
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserBenefitsServiceImpl.java
  36. 34 4
      netflix-web/src/main/java/com/cyksj/web/controller/cps/CpsBackLoginController.java
  37. 1 0
      netflix-web/src/main/java/com/cyksj/web/controller/cps/CpsDistribtueDataController.java
  38. 61 0
      netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java
  39. 1 1
      netflix-web/src/main/java/com/cyksj/web/controller/manage/account/CmsAccountController.java
  40. 73 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/GoodsDonSkuSubsidyController.java
  41. 5 0
      netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java
  42. 21 1
      netflix-web/src/main/java/com/cyksj/web/controller/user/DistributePopularizeController.java
  43. 0 0
      netflix-web/src/main/resources/application-dev.yml
  44. 0 0
      netflix-web/src/main/resources/application-prd.yml
  45. 2 1
      netflix-web/src/main/resources/application-pre.yml

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

@@ -532,4 +532,27 @@ public final class StringUtil {
 		sb.append(front).append("****").append(back);
 		return sb.toString();
 	}
+
+	public static String getNewInternalAddressByIp(String ip) {
+		if (StrUtil.isBlank(ip)) {
+			return "unknown";
+		}
+		try {
+			String url = String.format("https://searchplugin.csdn.net/api/v1/ip/get?ip=%s", ip);
+			HttpResponse<String> send = J11HttpC
+					.custom().ofGet().url(url)
+					.send(HttpResponse.BodyHandlers.ofString());
+			String rspStr = send.body();
+			if (StrUtil.isEmpty(rspStr)) {
+				return "unknown";
+			}
+			JSONObject obj = JSONUtil.parseObj(rspStr);
+			JSONObject data = JSONUtil.parseObj(obj.get("data"));
+			String addr = data.getStr("address");
+			return addr;
+		} catch (Exception e) {
+		}
+
+		return "unknown";
+	}
 }

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

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

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.OrderDonLocationRelate;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: OrderDonLocationRelateMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/4/10 15:50
+ */
+public interface OrderDonLocationRelateMapper extends BaseMapper<OrderDonLocationRelate> {
+}

+ 9 - 3
netflix-dao/src/main/java/com/cyksj/mapper/OrderDonMapper.java

@@ -66,7 +66,7 @@ public interface OrderDonMapper extends BaseMapper<OrderDon> {
 
 	BrokenLineObjView selectDsPlatBrokenLineMoney(@Param("sharedId") Long sharedId, @Param("first") String first, @Param("end") String end);
 
-	UserOrderDetailView getTagUserData(@Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("consumeStTime") String consumeStTime, @Param("consumeEtTime") String consumeEtTime);
+	UserOrderDetailView getTagUserOrdersData(@Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("consumeStTime") String consumeStTime, @Param("consumeEtTime") String consumeEtTime);
 
 	Page<UserOrderDetailView> getTagUserDataPage(@Param("page") Page<UserOrderDetailView> page, @Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("consumeStTime") String consumeStTime, @Param("consumeEtTime") String consumeEtTime);
 
@@ -76,9 +76,15 @@ public interface OrderDonMapper extends BaseMapper<OrderDon> {
 
 	String selectMaxRefundGoodsName(@Param("operator") String operator, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
-	BigDecimal selectSubChannelOrderMoney(@Param("sharedId") Long sharedId, @Param("limitTime") Date limitTime);
-
 	OrderDonCustomerServiceRelate selectOrderRelate(Long orderId);
 
+	BigDecimal selectSubChannelOrderMoney(@Param("sharedId") Long sharedId, @Param("invitedTime") Date invitedTime, @Param("limitTime") Date limitTime);
+
 	Page<UserOrderDetailView> getPastRecord(@Param("objectPage") Page<Object> objectPage, @Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("consumeStTime") String consumeStTime, @Param("consumeEtTime") String consumeEtTime);
+
+	UserOrderDetailView getNumOfTagFansUser(@Param("date") String date, @Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime);
+
+	UserOrderDetailView getFansToDayOrdersView(@Param("tagIdStr") String tagIdStr, @Param("date") String date);
+
+	List<Long> getPayGoodsIds(@Param("userIds") List<Long> relationUserIdList);
 }

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

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

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

@@ -70,4 +70,7 @@ public interface UserMapper extends BaseMapper<User> {
 
     @Update("update user set sub_apply_money = sub_apply_money - #{needApplyMoney} where id = #{id} and sub_apply_money >= #{needApplyMoney} and sub_apply_money > 0")
     Integer suUserSubApplyMoney(@Param("id") Long id, @Param("needApplyMoney") BigDecimal needApplyMoney);
+
+    @Update("update user set sub_apply_money = sub_apply_money + #{addApplyMoney} where id = #{id} and sub_apply_money = #{subApplyMoney}")
+    Integer addDistributeSubMoney(@Param("id") Long id, @Param("subApplyMoney") BigDecimal subApplyMoney, @Param("addApplyMoney") BigDecimal addApplyMoney);
 }

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/AuthRedirect.java

@@ -72,4 +72,9 @@ public class AuthRedirect {
      * 店铺自定义id
      */
     private String cd;
+
+    /**
+     * 跳转url
+     */
+    private String url;
 }

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/CpsAuthDto.java

@@ -21,4 +21,6 @@ public class CpsAuthDto {
 	 * 授权标识
 	 */
 	private String authState;
+
+	private String redirectUrl;
 }

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

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

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

@@ -290,10 +290,6 @@ public class OrderDon extends BaseEntity implements Serializable {
      */
     private String phone;
 
-    private String ip;
-
-    private String location;
-
     public enum Status {
         /**
          * 订单状态

+ 24 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/OrderDonLocationRelate.java

@@ -0,0 +1,24 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: OrderDonLocationRelate
+ * 创建者: JavaZou
+ * 创建时间:2024/4/10 15:49
+ */
+@Getter
+@Setter
+public class OrderDonLocationRelate extends BaseEntity{
+	private Long orderId;
+
+	private String ip;
+
+	private String country;
+
+	private String province;
+
+	private String city;
+}

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

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

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

@@ -14,7 +14,7 @@ import java.math.BigDecimal;
  */
 @Getter
 @Setter
-public class UserDistributeSubRewards extends BaseEntity{
+public class UserDistributeSubRewards {
 	private Integer level;
 
 	/**

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

@@ -37,11 +37,6 @@ public class UserDistributeSubWaiting extends BaseEntity {
 
 	private Integer level;
 
-	/**
-	 * 月份
-	 */
-	private Integer months;
-
 	/**
 	 * 锁标识
 	 */

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

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

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

@@ -43,6 +43,9 @@ public class CpsApplyMoneyView {
 	@DbField("dma.type")
 	private DistributeMoneyApply.Type type;
 
+	@DbField("dma.m_type")
+	private DistributeMoneyApply.MType mType;
+
 	@DbField("dma.account")
 	private String account;
 

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

@@ -43,6 +43,9 @@ public class DistributeMoneyApplyView {
 	@DbField("dma.type")
 	private DistributeMoneyApply.Type type;
 
+	@DbField("dma.m_type")
+	private DistributeMoneyApply.MType mType;
+
 	@DbField("dma.account")
 	private String account;
 

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

@@ -30,6 +30,9 @@ public class DistributePopularizeView {
 	 */
 	private BigDecimal gotPoints;
 
+	/**
+	 * 可提现金额
+	 */
 	private BigDecimal gotMoney;
 
 	/**

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

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

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

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

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

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

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

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

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

@@ -32,7 +32,7 @@ public class UserDistributeSubDetailView {
 
 	public String getNextLevelDesc() {
 		if (nextLevel != null) {
-			this.nextLevelDesc = UserDistributeSubRewards.RewardLevel.values()[nextLevel].getMsg();
+			return UserDistributeSubRewards.RewardLevel.values()[nextLevel].getMsg();
 		}
 		if (totalMoney.compareTo(BigDecimal.ZERO) == 0) {
 			return UserDistributeSubRewards.RewardLevel.meteor.getMsg();

+ 21 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserInfoView.java

@@ -0,0 +1,21 @@
+package com.cyksj.model.views;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserInfoView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/8 11:40
+ */
+@Getter
+@Setter
+public class UserInfoView {
+	/**
+	 * 头像
+	 */
+	private String img;
+
+	private String nickname;
+}

+ 75 - 42
netflix-dao/src/main/resources/mapper/OrderDonMapper.xml

@@ -319,61 +319,50 @@
         </if>
     </select>
 
-    <select id="getTagUserData" resultType="com.cyksj.model.views.UserOrderDetailView">
+    <select id="getTagUserOrdersData" resultType="com.cyksj.model.views.UserOrderDetailView">
         select count(if(status != 'refund', 1, NULL)) as numOfOrder,
-               (sum(money) - sum(ifnull(refund_money, 0))) / 100 as orderMoney,
+               cast((sum(money) - sum(ifnull(refund_money, 0))) / 100 as decimal(10,2)) as orderMoney,
                count(if(status != 'refund' and o.goods_id = 15,1,NULL)) as numOfEpOrder,
-               (sum(if(o.goods_id = 15,money,0)) - sum(ifnull(if(o.goods_id = 15,refund_money,0), 0))) / 100 as epOrderMoney,
+              cast((sum(if(o.goods_id = 15,money,0)) - sum(ifnull(if(o.goods_id = 15,refund_money,0), 0))) / 100 as decimal(10,2)) as epOrderMoney,
                count(distinct corpUserId) as numOfUser
         from (select cu.id as corpUserId,
         cu.user_id,
-        s.created_time
+        date_format(s.created_time, '%Y-%m-%d') as joinTime
         from (select relation_id,
         min(ct.created_time) as created_time
         from `corp_user_tag` ct
         where tag_id = #{tagIdStr}
         group by ct.relation_id
         <if test="startTime != null">
-            having min(ct.created_time) >= #{startTime}
+            having date_format(min(ct.created_time), '%Y-%m-%d') >= #{startTime}
         </if>
         <if test="endTime != null">
-            and min(ct.created_time) &lt; #{endTime}
+            and date_format(min(ct.created_time), '%Y-%m-%d') &lt; #{endTime}
         </if>) s
         left join corp_user_follow_relation cufr on cufr.id = s.relation_id
         left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
         left join corp_user cu on cu.id = ca.corp_user_id) s
-        left join order_don o on o.user_id = s.user_id and o.user_id != 0
+        inner join order_don o on o.user_id = s.user_id and o.user_id != 0
         and o.status not in ('close', 'noPayment')
         and o.money > 0
-        and o.created_time > s.created_time
+        and date_format(o.created_time, '%Y-%m-%d') >= joinTime
         <if test="consumeStTime != null">
-            and o.created_time >= #{consumeStTime}
+            and date_format(o.created_time, '%Y-%m-%d') >= #{consumeStTime}
         </if>
         <if test="consumeEtTime != null">
-            and o.created_time &lt; #{consumeEtTime}
+            and date_format(o.created_time, '%Y-%m-%d') &lt; #{consumeEtTime}
         </if>
     </select>
 
     <select id="getTagUserDataPage" resultType="com.cyksj.model.views.UserOrderDetailView">
-        select joinTime                               as `date`,
-               count(DISTINCT corpUserId)             as numOfUser,
-               count(if(status != 'refund', 1, NULL)) as numOfOrder,
-               (ifnull(sum(money), 0) - sum(ifnull(refund_money, 0))) / 100 as orderMoney
-        from (select cu.id as                                corpUserId,
-                     cu.user_id,
-                     date_format(s.created_time, '%Y-%m-%d') joinTime
-              from (select relation_id,
-                           min(ct.created_time) as created_time
+        select joinTime as `date`,
+               count(distinct corp_user_id) as numOfUser
+        from (select cufr.corp_user_id, date_format(s.created_time, '%Y-%m-%d') joinTime
+              from (select relation_id, min(created_time) as created_time
                     from `corp_user_tag` ct
                     where tag_id = #{tagIdStr}
-                    group by ct.relation_id) s
-                       left join corp_user_follow_relation cufr on cufr.id = s.relation_id
-                       left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
-                       left join corp_user cu on cu.id = ca.corp_user_id) s
-                 left join order_don o on o.user_id = s.user_id and o.user_id != 0
-        and o.status not in ('close','noPayment')
-        and date_format(o.created_time, '%Y-%m-%d') = joinTime
-        and o.money > 0
+                    group by relation_id) s
+                       inner join corp_user_follow_relation cufr on cufr.id = s.relation_id) s
         group by joinTime
         order by joinTime desc
     </select>
@@ -443,6 +432,12 @@
         order by count(*) desc limit 1
     </select>
 
+    <select id="selectOrderRelate" resultType="com.cyksj.model.entity.OrderDonCustomerServiceRelate">
+        select cms_user_id, (select nickname from cms_user where id = odr.cms_user_id limit 1) as nickname
+        from order_don_customer_service_relate odr
+        where order_id = #{orderId} limit 1
+    </select>
+
     <select id="selectSubChannelOrderMoney" resultType="java.math.BigDecimal">
         select sum(o.money) - sum(ifnull(o.refund_money, 0))
         from distribute_waiting_send_points dp
@@ -450,19 +445,14 @@
         where dp.shared_id = #{sharedId}
           and o.goods_id != 15
             and o.status not in ('close', 'noPayment')
-        and o.created_time &lt; #{limitTime}
-    </select>
-
-    <select id="selectOrderRelate" resultType="com.cyksj.model.entity.OrderDonCustomerServiceRelate">
-        select cms_user_id, (select nickname from cms_user where id = odr.cms_user_id limit 1) as nickname
-        from order_don_customer_service_relate odr
-        where order_id = #{orderId} limit 1
+        and o.created_time > #{invitedTime}
+          and o.created_time &lt; #{limitTime}
     </select>
 
     <select id="getPastRecord" resultType="com.cyksj.model.views.UserOrderDetailView">
         select date_format(o.created_time,'%Y-%m-%d') as `date`,
         count(if(status != 'refund', 1, NULL)) as numOfOrder,
-        (ifnull(sum(money),0) - sum(ifnull(refund_money, 0))) / 100 as orderMoney
+        cast((ifnull(sum(money),0) - sum(ifnull(refund_money, 0))) / 100 as decimal(10,2)) as orderMoney
         from (select cu.id as corpUserId,
         cu.user_id,
         date_format(s.created_time, '%Y-%m-%d') joinTime
@@ -476,14 +466,57 @@
         left join corp_user cu on cu.id = ca.corp_user_id where cu.user_id != 0)s
         inner join order_don o on o.user_id = s.user_id
         and o.status not in ('close','noPayment')
-        and date_format(o.created_time, '%Y-%m-%d') > joinTime
-        <if test="consumeStTime != null">
-            and o.created_time >= #{consumeStTime}
-        </if>
-        <if test="consumeEtTime != null">
-            and o.created_time &lt; #{consumeEtTime}
-        </if>
+        and date_format(o.created_time, '%Y-%m-%d') >= joinTime
+        and o.money > 0
         group by date_format(o.created_time,'%Y-%m-%d')
         order by date_format(o.created_time,'%Y-%m-%d') desc
     </select>
+
+    <select id="getNumOfTagFansUser" resultType="com.cyksj.model.views.UserOrderDetailView">
+        select count(distinct cufr.corp_user_id) as numOfUser,
+        count(distinct if(cufr.status = 0,cufr.corp_user_id,NULL)) as delNumOfUser
+        from (select relation_id
+        from `corp_user_tag` ct
+        where tag_id = #{tagIdStr}
+        group by relation_id
+        <if test="startTime != null">
+            having min(ct.created_time) >= #{startTime}
+        </if>
+        <if test="endTime != null">
+            and min(ct.created_time) &lt; #{endTime}
+        </if>
+        <if test="date != null">
+            HAVING date_format(min(ct.created_time), '%Y-%m-%d') = #{date}
+        </if>
+        ) s
+        inner join corp_user_follow_relation cufr on cufr.id = s.relation_id
+    </select>
+
+    <select id="getFansToDayOrdersView" resultType="com.cyksj.model.views.UserOrderDetailView">
+        select count(if(status != 'refund', 1, NULL))                                               as numOfOrder,
+               cast((ifnull(sum(money), 0) - sum(ifnull(refund_money, 0))) / 100 as decimal(10, 2)) as orderMoney
+        from (select cu.user_id
+              from (select relation_id
+                    from `corp_user_tag` ct
+                    where tag_id = #{tagIdStr}
+                    group by ct.relation_id
+                    having date_format(min(created_time), '%Y-%m-%d') = #{date}) s
+                       left join corp_user_follow_relation cufr on cufr.id = s.relation_id
+                       left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
+                       left join corp_user cu on cu.id = ca.corp_user_id
+              where cu.user_id != 0) s
+                 left join order_don o
+                           on o.user_id = s.user_id
+                               and o.status not in ('close', 'noPayment')
+                               and date_format(o.created_time, '%Y-%m-%d') = #{date}
+                               and o.money > 0
+    </select>
+
+    <select id="getPayGoodsIds" resultType="java.lang.Long">
+        select distinct goods_id from order_don where status not in ('close','noPayment')
+        where user_id in
+        <foreach collection="userIds" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
 </mapper>

+ 5 - 0
netflix-service/src/main/java/com/cyksj/config/wxlogin/BaseWxOpenPlatConfig.java

@@ -34,6 +34,11 @@ public class BaseWxOpenPlatConfig {
 
 	private String yhShopLoginUrl;
 
+	/**
+	 * 用户官网跳转cps后台地址
+	 */
+	private String cpsWebRedirectUri;
+
 	/**
 	 * 绑定账号回调接口地址
 	 */

+ 12 - 0
netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java

@@ -55,6 +55,8 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
 
     private final UserBindRelationService userBindRelationService;
 
+    private final AccountMapper accountMapper;
+
 
     @Override
     public String addAccount(Account account) {
@@ -212,6 +214,16 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
      */
     private ChatgptUser createChatgptUser(GroupsRelation groupsRelation, GroupsTrips groupsTrips, User user) {
         ChatgptSession chatgptSession = chatgptSessionMapper.selectOne(Wrappers.lambdaQuery(ChatgptSession.class).eq(ChatgptSession::getAccountId, groupsTrips.getAccountId()));
+        if (chatgptSession == null) {
+            Account account = accountMapper.selectById(groupsTrips.getAccountId());
+            //升级为镜像账号
+            String gptRefreshToken = addAccount(account);
+            accountMapper.update(null, Wrappers.lambdaUpdate(Account.class).eq(Account::getId, account.getId()).set(Account::getGptRefreshToken, gptRefreshToken));
+            chatgptSession = chatgptSessionMapper.selectOne(Wrappers.lambdaQuery(ChatgptSession.class).eq(ChatgptSession::getAccountId, groupsTrips.getAccountId()));
+        }
+        if (chatgptSession == null) {
+            throw BusinessRuntimeException.getInstance("账号异常,请联系客服..");
+        }
         ChatgptUser chatgptUser = new ChatgptUser();
         chatgptUser.setExpireTime(groupsRelation.getExpiryTime());
         chatgptUser.setIsPlus(1);

+ 18 - 6
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpTagServiceImpl.java

@@ -423,6 +423,13 @@ public class CorpTagServiceImpl implements CorpTagService {
 	@Override
 	public Page<UserOrderDetailView> getTagUserData(Integer start, Integer limit, String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime) {
 		Page<UserOrderDetailView> fansRecords = orderDonMapper.getTagUserDataPage(new Page<>(start, limit), tagIdStr, startTime, endTime, consumeStTime, consumeEtTime);
+		fansRecords.getRecords().forEach(e->{
+			//查询当日订单数
+			UserOrderDetailView u2 = orderDonMapper.getFansToDayOrdersView(tagIdStr, e.getDate());
+
+			e.setNumOfOrder(u2.getNumOfOrder());
+			e.setOrderMoney(u2.getOrderMoney());
+		});
 		return fansRecords;
 	}
 
@@ -440,12 +447,17 @@ public class CorpTagServiceImpl implements CorpTagService {
 
 	@Override
 	public UserOrderDetailView tagUserHeadData(String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime) {
-		UserOrderDetailView u = orderDonMapper.getTagUserData(tagIdStr, startTime, endTime, consumeStTime, consumeEtTime);
-		//被删除用户数
-		Integer delNumOfUser = corpUserTagMapper.getDelCorpUserNum(tagIdStr, startTime, endTime);
-		u.setDelNumOfUser(delNumOfUser);
+		//被删除用户数,用户数
+		UserOrderDetailView userOrderDetailView = orderDonMapper.getNumOfTagFansUser(null, tagIdStr, startTime, endTime);
+
+		//订单情况
+		UserOrderDetailView headView = orderDonMapper.getTagUserOrdersData(tagIdStr, startTime, endTime, consumeStTime, consumeEtTime);
+
+		headView.setNumOfUser(userOrderDetailView.getNumOfUser());
+		headView.setDelNumOfUser(userOrderDetailView.getDelNumOfUser());
+
 
-		u.setOrderRate(u.getNumOfUser() == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(u.getNumOfEpOrder()).divide(BigDecimal.valueOf(u.getNumOfUser()), 2, RoundingMode.HALF_DOWN));
-		return u;
+		headView.setOrderRate(headView.getNumOfUser() == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(headView.getNumOfEpOrder()).divide(BigDecimal.valueOf(headView.getNumOfUser()), 2, RoundingMode.HALF_DOWN));
+		return headView;
 	}
 }

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

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

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

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

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

@@ -32,6 +32,9 @@ import com.cyksj.mapper.manage.distribute.DistributeWaitingSendPointsMapper;
 import com.cyksj.mapper.manage.distribute.UserDistributeBusinessOrderDonRecordMapper;
 import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
 import com.cyksj.mapper.manage.distribute.equipment.EquipmentUserDistributeTransportBenefitsMapper;
+import com.cyksj.mapper.manage.distribute.sub.UserDistributeSubMapper;
+import com.cyksj.mapper.manage.distribute.sub.UserDistributeSubRewardsMapper;
+import com.cyksj.mapper.manage.distribute.sub.UserDistributeSubWaitingMapper;
 import com.cyksj.mapper.manage.sys.WorkOrderMapper;
 import com.cyksj.mapper.shop.YhShopUserDistributeBusinessOrderDonRecordMapper;
 import com.cyksj.mapper.stock.GoodsSkuStockRelateMapper;
@@ -73,6 +76,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * @author chan
@@ -167,6 +171,12 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
 
     private final ChatgptUserMapper chatgptUserMapper;
 
+    private final UserDistributeSubMapper userDistributeSubMapper;
+
+    private final UserDistributeSubWaitingMapper subWaitingMapper;
+
+    private final UserDistributeSubRewardsMapper userDistributeSubRewardsMapper;
+
     private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
     @Override
@@ -841,9 +851,45 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
                 chatgptUserMapper.delete(Wrappers.lambdaQuery(ChatgptUser.class)
                         .eq(ChatgptUser::getRelationId, orderDon.getRelationId()));
             }
+            //是否是分销订单
+            //处理下级渠道分销提成
+            handleSubRewards(orderDon);
         });
     }
 
+    //处理下级渠道分销提成
+    public void handleSubRewards(OrderDon orderDon) {
+        //是否是分销订单
+        //处理下级渠道分销提成
+        if (orderDon.getIsDistribute()) {
+            UserDistributeSub subRelate = userDistributeSubMapper.getSubRelate(orderDon.getUserId());
+            if (subRelate != null) {
+                List<UserDistributeSubWaiting> subWaitings = subWaitingMapper.selectList(Wrappers.lambdaQuery(UserDistributeSubWaiting.class)
+                        .eq(UserDistributeSubWaiting::getSubUserId, subRelate.getSubUserId())
+                        .eq(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.waiting));
+                if (CollUtil.isNotEmpty(subWaitings)) {
+                    List<UserDistributeSubRewards> userDistributeSubRewards = userDistributeSubRewardsMapper.selectList(null);
+                    Map<Integer, List<UserDistributeSubRewards>> rewardLevelMap = userDistributeSubRewards.stream().collect(Collectors.groupingBy(UserDistributeSubRewards::getLevel));
+                    subWaitings.forEach(wait -> {
+                        List<UserDistributeSubRewards> thisLevelList = rewardLevelMap.get(wait.getLevel());
+                        if (thisLevelList == null) {
+                            return;
+                        }
+                        UserDistributeSubRewards thisLevel = thisLevelList.get(0);
+                        Integer months = thisLevel.getMonths();
+                        BigDecimal subOrderMoney = Optional.ofNullable(orderDonMapper.selectSubChannelOrderMoney(wait.getSubUserId(), subRelate.getCreatedTime(), DateUtil.offsetMonth(subRelate.getCreatedTime(), months))).orElse(BigDecimal.ZERO);
+                        if (subOrderMoney.compareTo(thisLevel.getTargetAmount()) < 0) {
+                            subWaitingMapper.update(null, Wrappers.lambdaUpdate(UserDistributeSubWaiting.class)
+                                    .set(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.close)
+                                    .eq(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.waiting)
+                                    .eq(UserDistributeSubWaiting::getId, wait.getId()));
+                        }
+                    });
+                }
+            }
+        }
+    }
+
     /**
      * 退款 分销提成积分扣除
      */

+ 166 - 87
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alipay.api.AlipayApiException;
@@ -108,6 +109,7 @@ import java.math.RoundingMode;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
 
 /**
  * @author chan
@@ -278,6 +280,12 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final UserDistributeSubWaitingMapper userDistributeSubWaitingMapper;
 
+	private final OrderDonLocationRelateMapper orderDonLocationRelateMapper;
+
+	private final GoodsDonSkuSubsidyMapper goodsDonSkuSubsidyMapper;
+
+	private final OrderDonSubsidyRelateMapper orderDonSubsidyRelateMapper;
+
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
 
 	@Transactional(rollbackFor = Throwable.class)
@@ -369,8 +377,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		/* 生成订单 */
 		String donNo = SEQUENCE.nextId().toString();
 		OrderDon orderDon = new OrderDon();
-		orderDon.setIp(payRequest.getIp());
-		orderDon.setLocation(payRequest.getLocation());
 
 		orderDon.setIsDp(false);
 		if (isNoLogin != null && isNoLogin) {
@@ -499,71 +505,16 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		if (isSpecificPrice && (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0 || orderDon.getMoney().compareTo(specificPrice) != 0)) {
 			throw BusinessRuntimeException.getInstance("专属价格不支持使用其他优惠");
 		}
-		orderDon.setPayDesc(goodsDon.getPayDesc());
-		StringBuilder payTitle = new StringBuilder();
-		payTitle.append(goodsDon.getTitle());
-		if (sku != null) {
-			payTitle.append(sku.getSpecVal());
-		}
-		if (isGiftCardPay.get()) {
-			//礼品卡规格
-			Map<Long, Integer> giftCardPayNumMap = new ConcurrentHashMap<>();
-			giftCards.stream().forEach(data -> {
-				if (data.getNum() <= 0) {
-					return;
-				}
-				giftCardPayNumMap.putIfAbsent(data.getGcId(), data.getNum());
-			});
-			if (giftCardPayNumMap.isEmpty()) {
-				throw BusinessRuntimeException.getInstance("请选择要购买礼品卡的数量");
-			}
-			List<GiftCardGoodsSkuFrontView> giftCardViews = beanSearcher.searchAll(GiftCardGoodsSkuFrontView.class, MapUtils.builder().field(GiftCardGoodsSkuFrontView::getId, giftCardPayNumMap.keySet()).op(Operator.InList).build());
-			if (giftCardViews.size() != giftCards.size()) {
-				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
-			}
-			payTitle.append("购买详情:");
-			BigDecimal gift_card_pay_money = BigDecimal.ZERO;
-			for (GiftCardGoodsSkuFrontView data : giftCardViews) {
-				//礼品卡数量
-				Integer num = giftCardPayNumMap.get(data.getId());
-				data.setGcNum(num);
-				data.setGcShowType(gcPayInfo.getGcShowType());
-				data.setGcImg(gcPayInfo.getGcImg());
-				gift_card_pay_money = gift_card_pay_money.add(data.getPrice().multiply(BigDecimal.valueOf(num)));
 
-				//礼品卡关系
-				if (!payTitle.toString().endsWith("购买详情:")) {
-					payTitle.append(" + ");
-				}
-				String gcDetail;
-				if (data.getGcType() == 1) {
-					gcDetail = String.format("%s张现金卡%s%s", num, Constant.CN_CYS, data.getCash().divide(BigDecimal.valueOf(100)));
-					payTitle.append(gcDetail);
-				} else {
-					gcDetail = String.format("%s张虚拟卡%s%s", num, data.getGcGoodsTitle(), data.getGcSpecVal());
-					payTitle.append(gcDetail);
-				}
-			}
-			gcPayInfo.setGcPayDetail(giftCardViews);
-
-			//调整礼品卡金额
-			if (gift_card_pay_money.compareTo(orderDon.getMoney()) > 0) {
-				orderDon.setMoney(gift_card_pay_money);
-				orderDon.setRealMoney(gift_card_pay_money);
-			}
-		}
-		if (orderDon.getIsDp()) {
-			List<GoodsDonSkuView> dp_skuViewList = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, dpSkuIds).op(Operator.InList).build());
-			if (dp_skuViewList.size() != dpSkuIds.size()) {
-				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新下单");
-			}
-			dp_skuViewList.forEach(dp_SkuView -> {
-				payTitle.append(" + ");
-				payTitle.append(dp_SkuView.getGoodsTitle());
-				payTitle.append(dp_SkuView.getSpecVal());
-			});
+		//规格补贴id
+		Long subsidyId = payRequest.getSubsidyId();
+		if (subsidyId != null) {
+			//校验百亿补贴规格,并设置参数
+			setSubsidyOrderDonInfo(subsidyId, user, orderDon);
 		}
-		orderDon.setPayTitle(payTitle.toString());
+		orderDon.setPayDesc(goodsDon.getPayDesc());
+		//设置订单支付商品信息
+		setOrderDonPayTile(isGiftCardPay, gcPayInfo, giftCards, orderDon, goodsDon, sku, dpSkuIds);
 		//下单手机号
 		orderDon.setPhone(orderPhone);
 		this.saveOrUpdate(orderDon);
@@ -644,6 +595,10 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			informationClickUserRecord.setOrderId(orderDon.getId());
 			informationClickUserRecordMapper.insert(informationClickUserRecord);
 		}
+		//记录订单ip关联
+		recordOrderDonLocationRelate(orderDon.getId(), payRequest.getIp());
+		//记录补贴订单关联
+		recordOrderDonSubsidyRelate(orderDon.getId(), subsidyId);
 		return orderDon;
 	}
 
@@ -976,8 +931,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		/* 生成订单 */
 		String donNo = SEQUENCE.nextId().toString();
 		OrderDon orderDon = new OrderDon();
-		orderDon.setIp(payRequest.getIp());
-		orderDon.setLocation(payRequest.getLocation());
 
 		orderDon.setOrderNo(donNo);
 		orderDon.setOpenId(payOpenId);
@@ -1037,6 +990,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			orderDonMapper.updateById(updateOrder);
 			return updateOrder;
 		}
+		//记录订单ip关联
+		recordOrderDonLocationRelate(orderDon.getId(), payRequest.getIp());
 		return orderDon;
 	}
 
@@ -2639,7 +2594,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class).eq(UserDistributeShared::getUserId, userId).last("limit 1"));
 			if (userDistributeShared != null) {
 				orderDon.setIsDistribute(true);
-				UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, userDistributeShared.getSharedId()));
+				UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, userDistributeShared.getSharedId()).eq(UserDistribute::getDeleted, 1));
 				if (userDistribute != null) {
 					orderDon.setCpsPopularizeId(userDistributeShared.getDsPopularizeId());
 					//是否特殊渠道设备分销用户
@@ -2932,41 +2887,165 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 				//下级渠道用户id
 				Long subUserId = userDistributeSub.getSubUserId();
 
-				UserDistributeSubWaiting userDistributeSubWaiting = userDistributeSubWaitingMapper.selectOne(Wrappers.lambdaQuery(UserDistributeSubWaiting.class)
+				List<Integer> existLevels = userDistributeSubWaitingMapper.selectList(Wrappers.lambdaQuery(UserDistributeSubWaiting.class)
 						.eq(UserDistributeSubWaiting::getUserId, userId)
-						.orderByDesc(UserDistributeSubWaiting::getLevel).last("limit 1"));
-				//小于最大奖励级别
-				if (userDistributeSubWaiting == null || userDistributeSubWaiting.getLevel() < UserDistributeSubRewards.RewardLevel.values().length) {
-					List<UserDistributeSubRewards> userDistributeSubRewards = userDistributeSubRewardsMapper.selectList(Wrappers.lambdaQuery(UserDistributeSubRewards.class)
-							.gt(userDistributeSubWaiting != null, UserDistributeSubRewards::getLevel, userDistributeSubWaiting.getLevel())
-							.orderByAsc(UserDistributeSubRewards::getLevel));
+						.eq(UserDistributeSubWaiting::getSubUserId, subUserId)
+						.in(UserDistributeSubWaiting::getSendStatus, List.of(UserDistributeSubWaiting.Status.waiting, UserDistributeSubWaiting.Status.success))
+						.select(UserDistributeSubWaiting::getLevel).last("limit 1")).stream().map(UserDistributeSubWaiting::getLevel).collect(Collectors.toList());
+				List<UserDistributeSubRewards> userDistributeSubRewards = userDistributeSubRewardsMapper.selectList(Wrappers.lambdaQuery(UserDistributeSubRewards.class)
+						.notIn(CollUtil.isNotEmpty(existLevels), UserDistributeSubRewards::getLevel, existLevels));
 					for (UserDistributeSubRewards userDistributeSubReward : userDistributeSubRewards) {
 						log.info("当前级别:{}对应的目标金额是{}", userDistributeSubReward.getLevel(), userDistributeSubReward.getTargetAmount().divide(BigDecimal.valueOf(100)));
 						Integer rewardLevel = userDistributeSubReward.getLevel();
 						Integer months = userDistributeSubReward.getMonths();
 						BigDecimal targetAmount = userDistributeSubReward.getTargetAmount();
 						//是否达到目标额
-						BigDecimal subOrderMoney = orderDonMapper.selectSubChannelOrderMoney(subUserId, DateUtil.offsetMonth(userDistributeSub.getCreatedTime(), months));
-						if (subOrderMoney != null && subOrderMoney.compareTo(targetAmount) >= 0) {
+						BigDecimal subOrderMoney = Optional.ofNullable(orderDonMapper.selectSubChannelOrderMoney(subUserId, userDistributeSub.getCreatedTime(), DateUtil.offsetMonth(userDistributeSub.getCreatedTime(), months))).orElse(BigDecimal.ZERO);
+						if (subOrderMoney.compareTo(BigDecimal.ZERO) > 0 && subOrderMoney.compareTo(targetAmount) >= 0) {
 							try {
-								//达标 发放提成
-								UserDistributeSubWaiting newSubWaiting = new UserDistributeSubWaiting();
-								newSubWaiting.setMoney(userDistributeSubReward.getMoney());
-								newSubWaiting.setUserId(userId);
-								newSubWaiting.setSubUserId(subUserId);
-								newSubWaiting.setSendStatus(UserDistributeSubWaiting.Status.waiting);
-								newSubWaiting.setSendTime(DateUtil.offsetDay(DateTime.now(), 3));
-								newSubWaiting.setMonths(months);
-								newSubWaiting.setLevel(rewardLevel);
-								userDistributeSubWaitingMapper.insert(newSubWaiting);
+								UserDistributeSubWaiting waiting = Optional.ofNullable(userDistributeSubWaitingMapper.selectOne(Wrappers.lambdaQuery(UserDistributeSubWaiting.class)
+										.eq(UserDistributeSubWaiting::getUserId, userId)
+										.eq(UserDistributeSubWaiting::getSubUserId, subUserId)
+										.eq(UserDistributeSubWaiting::getLevel, rewardLevel)
+										.last("limit 1"))).orElse(new UserDistributeSubWaiting());
+								if (waiting.getId() != null) {
+									if (waiting.getSendStatus() == UserDistributeSubWaiting.Status.close) {
+										userDistributeSubWaitingMapper.update(null, Wrappers.lambdaUpdate(UserDistributeSubWaiting.class)
+												.set(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.waiting)
+												.eq(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.close)
+												.eq(UserDistributeSubWaiting::getId, waiting.getId()));
+									}
+								} else {
+									waiting.setMoney(userDistributeSubReward.getMoney());
+									waiting.setUserId(userId);
+									waiting.setSubUserId(subUserId);
+									waiting.setSendStatus(UserDistributeSubWaiting.Status.waiting);
+									waiting.setSendTime(DateUtil.offsetDay(DateTime.now(), 3));
+									waiting.setLevel(rewardLevel);
+									userDistributeSubWaitingMapper.insert(waiting);
+								}
 								log.info("分销用户:{}下级渠道:{}达到:{}销售额,发送奖励成功", userId, subUserId, UserDistributeSubRewards.RewardLevel.values()[rewardLevel].getMsg());
 							} catch (DuplicateKeyException e) {
 							}
 						}
 					}
+			}
+
+		}
+	}
+
+	private void recordOrderDonLocationRelate(Long orderId, String ip) {
+		OrderDonLocationRelate orderDonLocationRelate = new OrderDonLocationRelate();
+		orderDonLocationRelate.setOrderId(orderId);
+		orderDonLocationRelate.setIp(ip);
+		orderDonLocationRelateMapper.insert(orderDonLocationRelate);
+	}
+
+	private void recordOrderDonSubsidyRelate(Long orderId, Long subsidyId) {
+		if (subsidyId != null) {
+			OrderDonSubsidyRelate orderDonSubsidyRelate = new OrderDonSubsidyRelate();
+			orderDonSubsidyRelate.setSubsidyId(subsidyId);
+			orderDonSubsidyRelate.setOrderId(orderId);
+			orderDonSubsidyRelateMapper.insert(orderDonSubsidyRelate);
+		}
+	}
+
+	/**
+	 * 设置订单支付商品属性
+	 */
+	public void setOrderDonPayTile(AtomicBoolean isGiftCardPay, GiftCardDto gcPayInfo, List<GiftCardPayReq> giftCards, OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku, List<Long> dpSkuIds) {
+		StringBuilder payTitle = new StringBuilder();
+		payTitle.append(goodsDon.getTitle());
+		if (sku != null) {
+			payTitle.append(sku.getSpecVal());
+		}
+		if (isGiftCardPay.get()) {
+			//礼品卡规格
+			Map<Long, Integer> giftCardPayNumMap = new ConcurrentHashMap<>();
+			giftCards.stream().forEach(data -> {
+				if (data.getNum() <= 0) {
+					return;
 				}
+				giftCardPayNumMap.putIfAbsent(data.getGcId(), data.getNum());
+			});
+			if (giftCardPayNumMap.isEmpty()) {
+				throw BusinessRuntimeException.getInstance("请选择要购买礼品卡的数量");
 			}
+			List<GiftCardGoodsSkuFrontView> giftCardViews = beanSearcher.searchAll(GiftCardGoodsSkuFrontView.class, MapUtils.builder().field(GiftCardGoodsSkuFrontView::getId, giftCardPayNumMap.keySet()).op(Operator.InList).build());
+			if (giftCardViews.size() != giftCards.size()) {
+				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
+			}
+			payTitle.append("购买详情:");
+			BigDecimal gift_card_pay_money = BigDecimal.ZERO;
+			for (GiftCardGoodsSkuFrontView data : giftCardViews) {
+				//礼品卡数量
+				Integer num = giftCardPayNumMap.get(data.getId());
+				data.setGcNum(num);
+				data.setGcShowType(gcPayInfo.getGcShowType());
+				data.setGcImg(gcPayInfo.getGcImg());
+				gift_card_pay_money = gift_card_pay_money.add(data.getPrice().multiply(BigDecimal.valueOf(num)));
 
+				//礼品卡关系
+				if (!payTitle.toString().endsWith("购买详情:")) {
+					payTitle.append(" + ");
+				}
+				String gcDetail;
+				if (data.getGcType() == 1) {
+					gcDetail = String.format("%s张现金卡%s%s", num, Constant.CN_CYS, data.getCash().divide(BigDecimal.valueOf(100)));
+					payTitle.append(gcDetail);
+				} else {
+					gcDetail = String.format("%s张虚拟卡%s%s", num, data.getGcGoodsTitle(), data.getGcSpecVal());
+					payTitle.append(gcDetail);
+				}
+			}
+			gcPayInfo.setGcPayDetail(giftCardViews);
+
+			//调整礼品卡金额
+			if (gift_card_pay_money.compareTo(orderDon.getMoney()) > 0) {
+				orderDon.setMoney(gift_card_pay_money);
+				orderDon.setRealMoney(gift_card_pay_money);
+			}
+		}
+		if (orderDon.getIsDp()) {
+			List<GoodsDonSkuView> dp_skuViewList = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, dpSkuIds).op(Operator.InList).build());
+			if (dp_skuViewList.size() != dpSkuIds.size()) {
+				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新下单");
+			}
+			dp_skuViewList.forEach(dp_SkuView -> {
+				payTitle.append(" + ");
+				payTitle.append(dp_SkuView.getGoodsTitle());
+				payTitle.append(dp_SkuView.getSpecVal());
+			});
 		}
+		orderDon.setPayTitle(payTitle.toString());
+	}
+
+	/**
+	 * 百亿补贴订单
+	 */
+	private void setSubsidyOrderDonInfo(Long subsidyId, User user, OrderDon orderDon) {
+		Assert.notNull(user, "用户不存在");
+		GoodsDonSkuSubsidy goodsDonSkuSubsidy = goodsDonSkuSubsidyMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSkuSubsidy.class)
+				.eq(GoodsDonSkuSubsidy::getId, subsidyId)
+				.eq(GoodsDonSkuSubsidy::getDeleted, 1)
+				.last("limit 1"));
+		Assert.notNull(goodsDonSkuSubsidy, "商品不存在");
+		Long skuId = goodsDonSkuSubsidy.getSkuId();
+		Long paySkuId = orderDon.getSkuId();
+		if (ObjectUtil.equal(skuId, paySkuId)) {
+			throw BusinessRuntimeException.getInstance("规格不存在");
+		}
+		BigDecimal price = goodsDonSkuSubsidy.getPrice();
+		if (price.compareTo(BigDecimal.ZERO) <= 0) {
+			throw BusinessRuntimeException.getInstance("商品价格异常..");
+		}
+		//是否购买过该规格
+		Integer selectCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
+				.eq(OrderDon::getSkuId, skuId)
+				.ne(OrderDon::getStatus, OrderDon.Status.close));
+		if (selectCount > 0) {
+			throw BusinessRuntimeException.getInstance("只可购买一次该补贴规格");
+		}
+		orderDon.setMoney(price);
 	}
 }

+ 34 - 17
netflix-service/src/main/java/com/cyksj/service/pay/impl/TransferFuncServiceImpl.java

@@ -299,27 +299,39 @@ public class TransferFuncServiceImpl implements TransferFuncService {
 			distributeMoneyApply = userDistributeMapper.selectRelationBusiness(userId);
 			isTakeAll = true;
 		}
-		BigDecimal userPoints = user.getPoints();
-		DistributePointsExchangeMoney distributePointsExchangeMoney = distributePointsExchangeMoneyMapper.selectOne(Wrappers.lambdaQuery(DistributePointsExchangeMoney.class).orderByDesc(DistributePointsExchangeMoney::getPoints).last("limit 1"));
-		BigDecimal minPoints = BigDecimal.valueOf(distributePointsExchangeMoney.getMinPoints());
-		BigDecimal ratePoints = BigDecimal.valueOf(distributePointsExchangeMoney.getPoints());
-		BigDecimal minMoney = distributePointsExchangeMoney.getMoney();
-		if (userPoints.compareTo(minPoints) < 0) {
-			throw BusinessRuntimeException.getInstance("您当前积分未达到积分门槛,无法提现");
-		}
 //		//今日是否已提现
 //		DistributeMoneyApply apply = distributeMoneyApplyMapper.selectOne(Wrappers.lambdaQuery(DistributeMoneyApply.class).eq(DistributeMoneyApply::getUserId, userId).between(DistributeMoneyApply::getCreatedTime, DateUtil.beginOfDay(DateTime.now()), DateUtil.endOfDay(DateTime.now())).last("limit 1"));
 //		if (apply != null) {
 //			throw BusinessRuntimeException.getInstance("今日已提现,请明日再进行操作");
 //		}
-		BigDecimal num = userPoints.divide(ratePoints, 0, RoundingMode.DOWN);
-		BigDecimal needApplyMoney = num.multiply(minMoney);
-		BigDecimal needSubPoints = num.multiply(ratePoints);
-		BigDecimal fourHundred = BigDecimal.valueOf(4 * 100 * 100);
-		if (isTakeAll == null || !isTakeAll) {
-			if (needApplyMoney.compareTo(fourHundred) > 0) {
-				needApplyMoney = fourHundred;
-				needSubPoints = fourHundred.divide(minMoney).multiply(ratePoints);
+		BigDecimal userPoints = null;
+		BigDecimal needSubPoints = null;
+		BigDecimal needApplyMoney = null;
+		BigDecimal fourHundred = null;
+		if (mType == DistributeMoneyApply.MType.ds) {
+			userPoints = user.getPoints();
+			DistributePointsExchangeMoney distributePointsExchangeMoney = distributePointsExchangeMoneyMapper.selectOne(Wrappers.lambdaQuery(DistributePointsExchangeMoney.class).orderByDesc(DistributePointsExchangeMoney::getPoints).last("limit 1"));
+			BigDecimal minPoints = BigDecimal.valueOf(distributePointsExchangeMoney.getMinPoints());
+			BigDecimal ratePoints = BigDecimal.valueOf(distributePointsExchangeMoney.getPoints());
+			BigDecimal minMoney = distributePointsExchangeMoney.getMoney();
+			if (userPoints.compareTo(minPoints) < 0) {
+				throw BusinessRuntimeException.getInstance("您当前积分未达到积分门槛,无法提现");
+			}
+			BigDecimal num = userPoints.divide(ratePoints, 0, RoundingMode.DOWN);
+			needApplyMoney = num.multiply(minMoney);
+			needSubPoints = num.multiply(ratePoints);
+			fourHundred = BigDecimal.valueOf(4 * 100 * 100);
+			if (isTakeAll == null || !isTakeAll) {
+				if (needApplyMoney.compareTo(fourHundred) > 0) {
+					needApplyMoney = fourHundred;
+					needSubPoints = fourHundred.divide(minMoney).multiply(ratePoints);
+				}
+			}
+		}
+		if (mType == DistributeMoneyApply.MType.sub) {
+			needApplyMoney = user.getSubApplyMoney();
+			if (needApplyMoney.compareTo(BigDecimal.ZERO) <= 0) {
+				throw BusinessRuntimeException.getInstance("您暂无可提现金额..");
 			}
 		}
 		Integer update = 0;
@@ -360,7 +372,12 @@ public class TransferFuncServiceImpl implements TransferFuncService {
 				} else {
 					distributeMoneyApply.setVerifyStatus(DistributeMoneyApply.Status.fail);
 					distributeMoneyApply.setReason(alipayResponse.getSubMsg());
-					userBenefitsService.addDistributePoints(userId, distributeMoneyApply.getPoints());
+					if (mType == DistributeMoneyApply.MType.ds){
+						userBenefitsService.addDistributePoints(userId, distributeMoneyApply.getPoints());
+					}
+					if (mType == DistributeMoneyApply.MType.sub) {
+						userBenefitsService.addDistributeSubMoney(userId, needApplyMoney);
+					}
 					if (StrUtil.equals(alipayResponse.getSubCode(), "SECURITY_CHECK_FAILED")) {
 						return GatewayResponse.FAIL.newBuilder().setMsg("当前支付宝提现人数较多,请稍后再试").toResult();
 					}

+ 5 - 0
netflix-service/src/main/java/com/cyksj/service/user/UserBenefitsService.java

@@ -44,4 +44,9 @@ public interface UserBenefitsService {
 	 * 扣除店铺主用户 提成金额
 	 */
 	void deductYhShopTakeMoney(Long orderId, Long shopUserId, BigDecimal deductMoney);
+
+	/**
+	 * 返回用户邀请奖励提成
+	 */
+	void addDistributeSubMoney(Long userId, BigDecimal needApplyMoney);
 }

+ 16 - 0
netflix-service/src/main/java/com/cyksj/service/user/impl/UserBenefitsServiceImpl.java

@@ -169,6 +169,22 @@ public class UserBenefitsServiceImpl implements UserBenefitsService {
 		}
 	}
 
+	@Override
+	public void addDistributeSubMoney(Long userId, BigDecimal addApplyMoney) {
+		if (addApplyMoney.compareTo(BigDecimal.ZERO) <= 0) {
+			return;
+		}
+		while (true) {
+			User user = userMapper.selectById(userId);
+			if (user == null) break;
+			BigDecimal subApplyMoney = user.getSubApplyMoney();
+			Integer success = userMapper.addDistributeSubMoney(user.getId(), subApplyMoney, addApplyMoney);
+			if (success == 1) {
+				break;
+			}
+		}
+	}
+
 	private void deductYhsMoneyRecord(Long orderId, Long shopUserId, BigDecimal deductMoney) {
 		try {
 			YhShopDistributeOrdersDeductPointsRecord record = new YhShopDistributeOrdersDeductPointsRecord();

+ 34 - 4
netflix-web/src/main/java/com/cyksj/web/controller/cps/CpsBackLoginController.java

@@ -3,6 +3,7 @@ package com.cyksj.web.controller.cps;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.annotation.NoSubmit;
 import com.cyksj.common.constant.Constant;
@@ -26,6 +27,7 @@ import com.cyksj.model.entity.SysConfig;
 import com.cyksj.model.entity.User;
 import com.cyksj.model.entity.UserDistribute;
 import com.cyksj.model.request.LoginReq;
+import com.cyksj.model.views.UserInfoView;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.authorization.AuthorizationService;
 import com.cyksj.service.cps.CpsManageService;
@@ -97,7 +99,7 @@ public class CpsBackLoginController {
 	 * cps后台微信授权登录
 	 */
 	@GetMapping("/wx/authLogin")
-	public Result<CpsAuthDto> wxAuthorize() throws Exception {
+	public Result<CpsAuthDto> wxAuthorize(String redirectUrl) throws Exception {
 		Object authUrlObj = redisService.get(RedisService.key.WX_LOGIN_AUTH_URI.getNameFormat("cps", wxOpenPlatYHLXLoginConfig.getAppId()));
 		if (authUrlObj != null) {
 			CpsAuthDto cpsAuthDto = Jsons.parseObject(authUrlObj.toString(), CpsAuthDto.class);
@@ -108,6 +110,7 @@ public class CpsBackLoginController {
 		String authState = mappingId.toString();
 		redisService.set(authState, authState, 60 * 60 * 24L);
 		AuthRedirect redirect = new AuthRedirect().setMappingId(mappingId);
+		redirect.setUrl(redirectUrl);
 		String state = Codec.DoBase64.custom().setData(Jsons.toJson(redirect)).encodeAsText();
 		String wxAuthUrl = authorizationService.createWxAuthLoginUrl(state, wxOpenPlatYHLXLoginConfig.getAppId(), wxOpenPlatYHLXLoginConfig.getCpsRedirectUri());
 		cpsAuthDto.setAuthUrl(wxAuthUrl);
@@ -136,11 +139,16 @@ public class CpsBackLoginController {
 						.orderByAsc(User::getId)
 						.last("limit 1")));
 		if (user == null) throw BusinessRuntimeException.getInstance("用户信息不存在");
-		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, user.getId()).select(UserDistribute::getId).last("limit 1"));
+		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, user.getId()).eq(UserDistribute::getDeleted, 1).select(UserDistribute::getId).last("limit 1"));
 		if (userDistribute == null) throw BusinessRuntimeException.getInstance("只支持渠道分销用户登录");
-		JSONObject res = new JSONObject();
 		StpCpsManageUser.login(user.getId());
 		String cpsToken = StpCpsManageUser.getTokenValue();
+		String url = re.getUrl();
+		if (StrUtil.isNotBlank(url)) {
+			response.sendRedirect(url.contains("?") ? url + "&t=" + cpsToken : url + "?t=" + cpsToken);
+			return;
+		}
+		JSONObject res = new JSONObject();
 		res.putOpt("satoken-cpsUser", cpsToken);
 		res.putOpt("img", user.getHeadimgurl());
 		res.putOpt("nickname", user.getNickname());
@@ -174,8 +182,30 @@ public class CpsBackLoginController {
 		if (cpsUserAdRecord == null) {
 			SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
 					.eq(SysConfig::getSysKey, key).last("limit 1"));
-			if (sysConfig != null) return GatewayResponse.SUCCESS.newBuilder().toResult(sysConfig.getSysValue());
+			if (sysConfig != null){
+				cpsUserAdRecord = new CpsUserAdRecord();
+				cpsUserAdRecord.setUserId(cpsUserId);
+				cpsUserAdRecord.setSysKey(key);
+				cpsUserAdRecordMapper.insert(cpsUserAdRecord);
+				return GatewayResponse.SUCCESS.newBuilder().toResult(sysConfig.getSysValue());
+			}
 		}
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
+
+	/**
+	 * 获取cps用户基本信息
+	 */
+	@GetMapping("/get/redirect/userInfo")
+	public Result<UserInfoView> getUserInfoView() {
+		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
+		User user = userMapper.selectById(cpsUserId);
+		Assert.notNull(user, "用户不存在");
+		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, user.getId()).eq(UserDistribute::getDeleted, 1).select(UserDistribute::getId).last("limit 1"));
+		Assert.notNull(userDistribute, "只支持渠道分销用户登录");
+		UserInfoView userInfoView = new UserInfoView();
+		userInfoView.setImg(user.getHeadimgurl());
+		userInfoView.setNickname(user.getNickname());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(userInfoView);
+	}
 }

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

@@ -72,6 +72,7 @@ public class CpsDistribtueDataController {
 		Number gotApplyMoney = beanSearcher.searchSum(DistributeMoneyApply.class, MapUtils.builder()
 				.field(DistributeMoneyApply::getUserId, cpsUserId)
 				.field(DistributeMoneyApply::getVerifyStatus, DistributeMoneyApply.Status.success.name())
+				.field(DistributeMoneyApply::getMType, DistributeMoneyApply.MType.ds.name())
 				.build(), "money");
 		Number reMoneyPoints = beanSearcher.searchSum(DistributeWaitingSendPoints.class, MapUtils.builder().field(DistributeWaitingSendPoints::getSharedId, cpsUserId).field(DistributeWaitingSendPoints::getSendStatus, DistributeWaitingSendPoints.Status.success.name()).build(), "points");
 		Number wMoneyPoints = beanSearcher.searchSum(DistributeWaitingSendPoints.class, MapUtils.builder().field(DistributeWaitingSendPoints::getSharedId, cpsUserId).field(DistributeWaitingSendPoints::getSendStatus, DistributeWaitingSendPoints.Status.waiting.name()).build(), "points");

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

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

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

@@ -428,7 +428,7 @@ public class CmsAccountController {
 		    }
 			GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(account.getSkuId());
 			if (goodsDonSku.getIsMirror()) {
-				String gptRefreshToken = chatGptAccountService.addAccount(account);
+				String gptRefreshToken = chatGptAccountService. addAccount(account);
 				accountService.update(null, Wrappers.lambdaUpdate(Account.class).eq(Account::getId, account.getId()).set(Account::getGptRefreshToken,gptRefreshToken ));
 			}
 			groupsTrips.setAvailableParkingNum(availableParkingNum);

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

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

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

@@ -489,6 +489,11 @@ public class OrderController {
         UserBindDetail userBindDetail = userBindDetailMapper.selectOne(Wrappers.lambdaQuery(UserBindDetail.class)
                 .eq(StrUtil.isNotEmpty(user.getOpenId()), UserBindDetail::getUserId, userId)
                 .eq(StrUtil.isNotEmpty(user.getEmail()), UserBindDetail::getEmailUserId, userId).last("limit 1"));
+        //台湾ip
+        String address = StringUtil.getNewInternalAddressByIp(ServletUtil.getClientIP(request));
+        if (address.contains("台湾") || !address.contains("中国")) {
+            return GatewayResponse.SUCCESS.newBuilder().toResult(true);
+        }
         if (userBindDetail == null || StrUtil.isEmpty(userBindDetail.getPhone())) {
             return GatewayResponse.SUCCESS.newBuilder().toResult(false);
         }

+ 21 - 1
netflix-web/src/main/java/com/cyksj/web/controller/user/DistributePopularizeController.java

@@ -10,6 +10,7 @@ import com.cyksj.common.EnvCommonService;
 import com.cyksj.common.annotation.NoSubmit;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.util.ValidatorUtil;
+import com.cyksj.config.wxlogin.WxOpenPlatYHLXLoginConfig;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GoodsDonMapper;
@@ -28,6 +29,7 @@ import com.cyksj.model.views.*;
 import com.cyksj.service.distribute.DistributeService;
 import com.cyksj.service.pay.TransferFuncService;
 import com.cyksj.service.user.UserService;
+import com.cyksj.web.util.StpCpsManageUser;
 import com.cyksj.web.util.StpUserUtil;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
@@ -84,6 +86,8 @@ public class DistributePopularizeController {
 
 	private final CouponMapper couponMapper;
 
+	private final WxOpenPlatYHLXLoginConfig wxOpenPlatYHLXLoginConfig;
+
 	/**
 	 * 推广订单明细
 	 */
@@ -140,7 +144,7 @@ public class DistributePopularizeController {
 		distributePopularizeView.setGotPoints(user.getPoints());
 		Integer orders = userDistributeMapper.count(userId);
 		distributePopularizeView.setDistributeOrders(orders);
-		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, userId).select(UserDistribute::getId).last("limit 1"));
+		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, userId).eq(UserDistribute::getDeleted, 1).select(UserDistribute::getId).last("limit 1"));
 		if (userDistribute != null) {
 			//是否是固定推广者
 			UserDistributeView userDistributeView = beanSearcher.searchFirst(UserDistributeView.class, MapUtils.builder()
@@ -259,6 +263,7 @@ public class DistributePopularizeController {
 	public Result<Boolean> isGeneralDistribute() {
 		Long userId = StpUserUtil.getLoginIdAsLong();
 		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
+				.eq(UserDistribute::getDeleted, 1)
 				.eq(UserDistribute::getUserId, userId));
 		if (userDistribute != null) {
 			return GatewayResponse.SUCCESS.newBuilder().toResult(false);
@@ -309,4 +314,19 @@ public class DistributePopularizeController {
 		distributeService.bindPopularizeCode(userId, code);
 		return GatewayResponse.SUCCESS.newBuilder().toResult("设置成功");
 	}
+
+	/**
+	 * 固定推广登录信息
+	 */
+	@GetMapping("/get/ds/detail")
+	public Result<String> getDistributeDetail() {
+		long userId = StpUserUtil.getLoginIdAsLong();
+		User user = userMapper.selectById(userId);
+		if (user == null) throw BusinessRuntimeException.getInstance("用户信息不存在");
+		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, user.getId()).eq(UserDistribute::getDeleted, 1).select(UserDistribute::getId).last("limit 1"));
+		if (userDistribute == null) throw BusinessRuntimeException.getInstance("只支持渠道分销用户登录");
+		StpCpsManageUser.login(user.getId());
+		String cpsToken = StpCpsManageUser.getTokenValue();
+		return GatewayResponse.SUCCESS.newBuilder().toResult(wxOpenPlatYHLXLoginConfig.getCpsWebRedirectUri() + "?t=" + cpsToken);
+	}
 }

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
netflix-web/src/main/resources/application-dev.yml


Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
netflix-web/src/main/resources/application-prd.yml


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

@@ -138,7 +138,8 @@ wx-login:
   cpsLoginUrl: https://cps.nf.video/yinhe/cps/loginNexte
   yhShopRedirectUri: https://nf.video/8082/api/yhShop/manage/wx/authLogin/baseRedirect
   yhShopLoginUrl: https://shop.liuliangbang.vip/mall/admin/loginNexte
-  baRedirectUrl: https://nf.video/80821/api/applets/market/task/bind/wx/baseRedirect
+  baRedirectUrl: https://nf.video/8082/api/applets/market/task/bind/wx/baseRedirect
+  cpsWebRedirectUri: https://inside.liuliangbang.vip/yinhe/cps/homePage
   remark: 银河录像网页微信登录
 
 wx-shop-login:

Някои файлове не бяха показани, защото твърде много файлове са промени