Sfoglia il codice sorgente

Merge branch 'business'

zoujiajian 3 anni fa
parent
commit
a8e074a682
28 ha cambiato i file con 1047 aggiunte e 15 eliminazioni
  1. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserBusinessDefaultRateConfigMapper.java
  2. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeBusinessOrderDonRecordMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeBusinessRateMapper.java
  4. 31 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserBusinessDefaultRateConfig.java
  5. 5 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistribute.java
  6. 59 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeBusinessOrderDonRecord.java
  7. 42 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeBusinessRate.java
  8. 5 0
      netflix-dao/src/main/java/com/cyksj/model/request/UserDistributeReq.java
  9. 58 0
      netflix-dao/src/main/java/com/cyksj/model/views/BusinessTakeMoneyDetail.java
  10. 39 0
      netflix-dao/src/main/java/com/cyksj/model/views/BusinessTakeMoneyHeadView.java
  11. 52 0
      netflix-dao/src/main/java/com/cyksj/model/views/DistributeBusinessView.java
  12. 3 3
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuView.java
  13. 39 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserBusinessDefaultRateConfigView.java
  14. 61 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeBusinessRateRecordView.java
  15. 30 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeBusinessRateView.java
  16. 8 1
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeViews.java
  17. 1 0
      netflix-service/src/main/java/com/cyksj/redis/RedisService.java
  18. 19 0
      netflix-service/src/main/java/com/cyksj/service/distribute/UserBusinessFrontService.java
  19. 31 5
      netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributeServiceImpl.java
  20. 195 0
      netflix-service/src/main/java/com/cyksj/service/distribute/impl/UserBusinessFrontServiceImpl.java
  21. 16 0
      netflix-service/src/main/java/com/cyksj/service/mange/business/UserBusinessRateService.java
  22. 71 0
      netflix-service/src/main/java/com/cyksj/service/mange/business/impl/UserBusinessRateServiceImpl.java
  23. 14 1
      netflix-service/src/main/java/com/cyksj/service/mange/cms/CmsUserManager.java
  24. 10 0
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  25. 2 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/cms/CmsAdminUserController.java
  26. 199 4
      netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java
  27. 17 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonSkuController.java
  28. 1 1
      netflix-web/src/main/resources/application.yml

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.distribute;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserBusinessDefaultRateConfig;
+
+/*
+ *项目名: netflix
+ *文件名: UserBusinessDefaultRateConfigMapper
+ *创建者: JavaZou
+ *创建时间:2023/3/28 15:44
+ */
+public interface UserBusinessDefaultRateConfigMapper extends BaseMapper<UserBusinessDefaultRateConfig> {
+}

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.distribute;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserDistributeBusinessOrderDonRecord;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessOrderDonRecordMapper
+ *创建者: JavaZou
+ *创建时间:2023/3/23 14:51
+ */
+public interface UserDistributeBusinessOrderDonRecordMapper extends BaseMapper<UserDistributeBusinessOrderDonRecord> {
+}

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.distribute;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserDistributeBusinessRate;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessRateMapper
+ *创建者: JavaZou
+ *创建时间:2023/3/22 18:13
+ */
+public interface UserDistributeBusinessRateMapper extends BaseMapper<UserDistributeBusinessRate> {
+}

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

@@ -0,0 +1,31 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserBusinessDefaultRateConfig
+ *创建者: JavaZou
+ *创建时间:2023/3/28 15:43
+ */
+@Getter
+@Setter
+public class UserBusinessDefaultRateConfig extends BaseEntity{
+	private Long goodsId;
+
+	/**
+	 * 标准配置分销者比例
+	 */
+	private Integer rate;
+
+	/**
+	 * 最高可配置分销者比例
+	 */
+	private Integer maxRate;
+
+	/**
+	 * 超过配置最高分销者比例是否平台承担
+	 */
+	private Boolean isPlatPay;
+}

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

@@ -20,6 +20,11 @@ public class UserDistribute extends BaseEntity{
 	 */
 	private String remark;
 
+	/**
+	 * 商务人员id
+	 */
+	private Long businessId;
+
 	@TableLogic(value = "1", delval = "0")
 	private Boolean deleted;
 }

+ 59 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeBusinessOrderDonRecord.java

@@ -0,0 +1,59 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessOrderDonRecord
+ *创建者: JavaZou
+ *创建时间:2023/3/23 14:47
+ */
+@Getter
+@Setter
+public class UserDistributeBusinessOrderDonRecord extends BaseEntity{
+	/**
+	 * 商务id
+	 */
+	private Long businessId;
+
+	/**
+	 * 分销人id
+	 */
+	private Long sharedId;
+
+	/**
+	 * 产生分销订单用户id
+	 */
+	private Long userId;
+
+	/**
+	 * 首单时 座位id
+	 */
+	private Long preRelationId;
+
+	private Long orderId;
+
+	/**
+	 * 1首单,2续费
+	 */
+	private Integer orderType;
+
+	/**
+	 * 分销比例
+	 */
+	private Integer rate;
+
+	/**
+	 * 提成金额
+	 */
+	private BigDecimal takeMoney;
+
+	/**
+	 * 订单创建时间
+	 */
+	private Date orderCreatedTime;
+}

+ 42 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeBusinessRate.java

@@ -0,0 +1,42 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessRate
+ *创建者: JavaZou
+ *创建时间:2023/3/22 18:11
+ */
+@Getter
+@Setter
+public class UserDistributeBusinessRate extends BaseEntity {
+	/**
+	 * 商务用户id
+	 */
+	@NotNull
+	private Long businessId;
+
+	/**
+	 * 平台id
+	 */
+	private Long goodsId;
+
+	/**
+	 * 规格id
+	 */
+	private Long skuId;
+
+	/**
+	 * 首单提成比例
+	 */
+	private Integer firstOrderRate;
+
+	/**
+	 * 首单续费提成比例
+	 */
+	private Integer renewOrderRate;
+}

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

@@ -22,6 +22,11 @@ public class UserDistributeReq {
 	@NotNull(message = "请添加用户")
 	private Long userId;
 
+	/**
+	 * 商务人员id
+	 */
+	private Long businessId;
+
 	private String remark;
 
 	/**

+ 58 - 0
netflix-dao/src/main/java/com/cyksj/model/views/BusinessTakeMoneyDetail.java

@@ -0,0 +1,58 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: BusinessTakeMoneyDetail
+ *创建者: JavaZou
+ *创建时间:2023/3/27 10:47
+ */
+@Getter
+@Setter
+@SearchBean(tables = "user_distribute_business_order_don_record ubr",
+		where = ":time:"
+		, groupBy = "ubr.shared_id,ubr.business_id")
+public class BusinessTakeMoneyDetail {
+
+	@DbField("ubr.shared_id")
+	private Long userId;
+
+	@DbIgnore
+	private String nickname;
+
+	@DbIgnore
+	private Date createdTime;
+
+	@DbField("ubr.business_id")
+	private Long businessId;
+
+	@DbIgnore
+	private String businessName;
+
+	@DbField("count(distinct ubr.user_id)")
+	private Integer distributeNum;
+
+	@DbField("count(if(ubr.order_type = 1,1,NULL))")
+	private Integer numOfFirstOrderThisMonth;
+
+	@DbField("cast(sum(if(ubr.order_type = 1,ubr.take_money,0))/100 as decimal(10,2))")
+	private BigDecimal moneyOfFirstOrderThisMonth;
+
+	@DbField("count(if(ubr.order_type = 2,1,NULL))")
+	private Integer numOfRenewOrderThisMonth;
+
+	@DbField("cast(sum(if(ubr.order_type = 2,ubr.take_money,0))/100 as decimal(10,2))")
+	private BigDecimal moneyOfRenewOrderThisMonth;
+
+	@DbField("cast(sum(ubr.take_money)/100 as decimal(10,2))")
+	private BigDecimal takeMoney;
+
+}

+ 39 - 0
netflix-dao/src/main/java/com/cyksj/model/views/BusinessTakeMoneyHeadView.java

@@ -0,0 +1,39 @@
+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;
+
+/*
+ *项目名: netflix
+ *文件名: BusinessTakeMoneyHeadView
+ *创建者: JavaZou
+ *创建时间:2023/3/27 14:02
+ */
+@Getter
+@Setter
+@SearchBean(tables = "user_distribute_business_order_don_record ubr",
+		where = ":time:"
+		, groupBy = "ubr.business_id")
+public class BusinessTakeMoneyHeadView {
+	@DbField("ubr.business_id")
+	private Long businessId;
+
+	@DbField("count(if(ubr.order_type = 1,1,NULL))")
+	private Integer numOfFirstOrder;
+
+	@DbField("cast(sum(if(ubr.order_type = 1,ubr.take_money,0))/100 as decimal(10,2))")
+	private BigDecimal moneyOfFirstOrder;
+
+	@DbField("count(if(ubr.order_type = 2,1,NULL))")
+	private Integer numOfRenewOrder;
+
+	@DbField("cast(sum(if(ubr.order_type = 2,ubr.take_money,0))/100 as decimal(10,2))")
+	private BigDecimal moneyOfRenewOrder;
+
+	@DbField("cast(sum(ubr.take_money)/100 as decimal(10,2))")
+	private BigDecimal takeMoney;
+}

+ 52 - 0
netflix-dao/src/main/java/com/cyksj/model/views/DistributeBusinessView.java

@@ -0,0 +1,52 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/*
+ *项目名: netflix
+ *文件名: DistributeBusinessView
+ *创建者: JavaZou
+ *创建时间:2023/3/22 18:00
+ */
+@Getter
+@Setter
+@SearchBean(tables = "(select distinct business_id from user_distribute_business_rate) ur left join user_distribute_business_order_don_record ubr on ubr.business_id = ur.business_id" +
+		" left join cms_user cu on cu.id = ur.business_id",
+		groupBy = "ur.business_id,cu.nickname,date_format(ubr.order_created_time,'%Y-%m')")
+public class DistributeBusinessView {
+	@DbField("ur.business_id")
+	private Long businessId;
+
+	@DbField("cu.nickname")
+	private String businessName;
+
+	/**
+	 * 关联人数
+	 */
+	@DbIgnore
+	private Integer numOfRelation;
+
+	@DbField("count(if(ubr.order_type = 1,1,NULL))")
+	private Integer numOfFirstOrderThisMonth;
+
+	@DbField("cast(sum(if(ubr.order_type = 1,ubr.take_money,0))/100 as decimal(10,2))")
+	private BigDecimal moneyOfFirstOrderThisMonth;
+
+	@DbField("count(if(ubr.order_type = 2,1,NULL))")
+	private Integer numOfRenewOrderThisMonth;
+
+	@DbField("cast(sum(if(ubr.order_type = 2,ubr.take_money,0))/100 as decimal(10,2))")
+	private BigDecimal moneyOfRenewOrderThisMonth;
+
+	@DbField("cast(sum(ubr.take_money)/100 as decimal(10,2))")
+	private BigDecimal takeMoney;
+
+	@DbField("date_format(ubr.order_created_time,'%Y-%m')")
+	private String monthDate;
+}

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

@@ -26,9 +26,6 @@ public class GoodsDonSkuView {
 	@DbField("gd.title")
 	private String goodsTitle;
 
-	@DbField("gd.type")
-	private Integer goodsDonType;
-
 	@DbField("gd.type")
 	private Integer type;
 
@@ -47,6 +44,9 @@ public class GoodsDonSkuView {
 	@DbField("gd.status")
 	private Boolean goodsDonStatus;
 
+	@DbField("gd.deleted")
+	private Boolean goodsDonDeleted;
+
 	@DbField("gdk.status")
 	private Boolean goodsDonSkuStatus;
 }

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

@@ -0,0 +1,39 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserBusinessDefaultRateConfigView
+ *创建者: JavaZou
+ *创建时间:2023/3/28 17:25
+ */
+@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")
+public class UserBusinessDefaultRateConfigView {
+	@DbField("uc.id")
+	private Long id;
+
+	@DbField("uc.goods_id")
+	private Long goodsId;
+
+	@DbField("g.type")
+	private Integer type;
+
+	@DbField("g.title")
+	private String goodsName;
+
+	@DbField("uc.rate")
+	private Integer rate;
+
+	@DbField("uc.max_rate")
+	private Integer maxRate;
+
+	@DbField("uc.is_plat_pay")
+	private Boolean isPlatPay;
+}

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

@@ -0,0 +1,61 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessRateRecordView
+ *创建者: JavaZou
+ *创建时间:2023/3/27 15:53
+ */
+@Getter
+@Setter
+@SearchBean(tables = "user_distribute_business_rate ur left join goods_don g on g.id = ur.goods_id" +
+		" left join goods_don_sku gdk on gdk.id = ur.sku_id",
+		where = "g.deleted is true")
+public class UserDistributeBusinessRateRecordView {
+	@DbField("ur.id")
+	private Long id;
+
+	/**
+	 * 商务用户id
+	 */
+	@NotNull
+	@DbField("ur.business_id")
+	private Long businessId;
+
+	/**
+	 * 平台id
+	 */
+	@DbField("ur.goods_id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	private String goodsName;
+
+	/**
+	 * 规格id
+	 */
+	@DbField("ur.sku_id")
+	private Long skuId;
+
+	@DbField("gdk.spec_val")
+	private String specVal;
+
+	/**
+	 * 首单提成比例
+	 */
+	@DbField("ur.first_order_rate")
+	private Integer firstOrderRate;
+
+	/**
+	 * 首单续费提成比例
+	 */
+	@DbField("ur.renew_order_rate")
+	private Integer renewOrderRate;
+}

+ 30 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeBusinessRateView.java

@@ -0,0 +1,30 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessRateView
+ *创建者: JavaZou
+ *创建时间:2023/3/23 14:24
+ */
+@Getter
+@Setter
+@SearchBean(tables = "user_distribute ud left join user_distribute_business_rate ubr on ubr.business_id = ud.business_id"
+		, where = "ud.deleted is true")
+public class UserDistributeBusinessRateView {
+	@DbField("ud.user_id")
+	private Long sharedId;
+
+	@DbField("ud.business_id")
+	private Long businessId;
+
+	@DbField("ubr.first_order_rate")
+	private Integer firstOrderRate;
+
+	@DbField("ubr.renew_order_rate")
+	private Integer renewOrderRate;
+}

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

@@ -18,7 +18,8 @@ import java.util.Date;
  */
 @Getter
 @Setter
-@SearchBean(tables = "user_distribute ud left join user u on u.id = ud.user_id",
+@SearchBean(tables = "user_distribute ud left join user u on u.id = ud.user_id" +
+		" left join cms_user cu on cu.id = ud.business_id",
 where = "ud.deleted is true and u.id is not null")
 public class UserDistributeViews {
 
@@ -28,6 +29,12 @@ public class UserDistributeViews {
 	@DbField("ud.user_id")
 	private Long userId;
 
+	@DbField("ud.business_id")
+	private Long businessId;
+
+	@DbField("cu.nickname")
+	private String businessName;
+
 	@DbField("u.nickname")
 	private String nickname;
 

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

@@ -600,6 +600,7 @@ public class RedisService {
         CMS_USER_ROLE_KEY("cms:user:role:%s:", "user角色缓存前缀", 60 * 60 * 24L * 7),
         CMS_USER_PERMISSION_KEY("cms:user:permission:%s:", "user权限缓存前缀", 60 * 60 * 24L * 7),
         REPEAT_USER_KEY("repeat_user_key:%s:", "重复用户插入key", 60l),
+        BUSINESS_FIRST_ORDER_USER_KEY("business_first_order_user_key:%s:", "商务分销首单提成key", 60l),
         ;
 
         private String name;

+ 19 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/UserBusinessFrontService.java

@@ -0,0 +1,19 @@
+package com.cyksj.service.distribute;
+
+import com.cyksj.model.entity.OrderDon;
+
+/*
+ *项目名: netflix
+ *文件名: UserBusinessFrontService
+ *创建者: JavaZou
+ *创建时间:2023/3/23 14:19
+ */
+public interface UserBusinessFrontService {
+	/**
+	 * @param sharedId   分销人id
+	 * @param businessId 商务id
+	 * @param order      订单
+	 * @param distributeRate      平台分销比例
+	 */
+	void taskDistributeRateBenefits(Long sharedId, Long businessId, OrderDon order, Integer distributeRate);
+}

+ 31 - 5
netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributeServiceImpl.java

@@ -4,9 +4,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.constant.TaskTypeEnum;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.mapper.GoodsDonMapper;
-import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
-import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
-import com.cyksj.mapper.manage.distribute.UserPlatDistributeRateMapper;
+import com.cyksj.mapper.manage.distribute.*;
 import com.cyksj.mapper.market.task.TaskTypeMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.request.UserDistributeReq;
@@ -18,6 +16,8 @@ import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Optional;
+
 /*
  *项目名: netflix
  *文件名: DistributeServiceImpl
@@ -40,6 +40,8 @@ public class DistributeServiceImpl implements DistributeService {
 
 	private final UserDistributeSharedMapper userDistributeSharedMapper;
 
+	private final UserBusinessDefaultRateConfigMapper defaultRateConfigMapper;
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public void insertDistribute(UserDistributeReq userDistributeReq) {
@@ -50,16 +52,21 @@ public class DistributeServiceImpl implements DistributeService {
 		UserDistribute userDistribute = new UserDistribute();
 		userDistribute.setUserId(userDistributeReq.getUserId());
 		userDistribute.setRemark(userDistributeReq.getRemark());
+		userDistribute.setBusinessId(userDistributeReq.getBusinessId());
 		userDistributeMapper.insert(userDistribute);
-
+		Long businessId = userDistributeReq.getBusinessId();
 		for (UserPlatDistributeRate rate : userDistributeReq.getRates()) {
-			if (rate.getRate() <0 || rate.getRate() > 100) {
+			if (rate.getRate() < 0 || rate.getRate() > 100) {
 				throw new BusinessRuntimeException("比例错误");
 			}
 			GoodsDon goodsDon = goodsDonMapper.selectById(rate.getGoodsId());
 			if (goodsDon == null || !goodsDon.getDeleted() || goodsDon.getType() == 3) {
 				throw new BusinessRuntimeException("平台错误");
 			}
+			//分销者虚物分销比例且配置商务
+			if (businessId != null && goodsDon.getType() == 1) {
+				checkDistributorAndBusinessRate(rate.getRate(), goodsDon.getId(), goodsDon.getTitle());
+			}
 			rate.setDistributeId(userDistribute.getId());
 			userPlatDistributeRateMapper.insert(rate);
 		}
@@ -74,6 +81,10 @@ public class DistributeServiceImpl implements DistributeService {
 		UserDistribute userDistribute = new UserDistribute();
 		userDistribute.setId(userDistributeReq.getId());
 		userDistribute.setRemark(userDistributeReq.getRemark());
+		if (userDistributeReq.getBusinessId() == null) {
+			userDistribute.setBusinessId(0l);
+		} else userDistribute.setBusinessId(userDistributeReq.getBusinessId());
+		Long businessId = userDistributeReq.getBusinessId();
 		userDistributeMapper.updateById(userDistribute);
 		for (UserPlatDistributeRate rate : userDistributeReq.getRates()) {
 			if (rate.getRate() < 0 || rate.getRate() > 100) {
@@ -87,6 +98,10 @@ public class DistributeServiceImpl implements DistributeService {
 			if (goodsDon == null || !goodsDon.getDeleted() || goodsDon.getType() == 3) {
 				throw new BusinessRuntimeException("平台错误");
 			}
+			//分销者虚物分销比例且配置商务
+			if (businessId != null && goodsDon.getType() == 1) {
+				checkDistributorAndBusinessRate(rate.getRate(), goodsDon.getId(), goodsDon.getTitle());
+			}
 			rate.setDistributeId(userDistribute.getId());
 			if (rate.getId() == null) {
 				try {
@@ -115,4 +130,15 @@ public class DistributeServiceImpl implements DistributeService {
 			log.info("分销被邀请人重复插入");
 		}
 	}
+
+	public void checkDistributorAndBusinessRate(Integer distributeGoodsRate, Long goodsId, String goodsName) {
+		UserBusinessDefaultRateConfig defaultGoodsRateConfig = defaultRateConfigMapper.selectOne(Wrappers.lambdaQuery(UserBusinessDefaultRateConfig.class)
+				.eq(UserBusinessDefaultRateConfig::getGoodsId, goodsId)
+				.last("limit 1"));
+		Optional.ofNullable(defaultGoodsRateConfig).ifPresent(config -> {
+			if (distributeGoodsRate > config.getMaxRate()) {
+				throw BusinessRuntimeException.getInstance(String.format("该%s平台最高可配置分销比例为%s", goodsName, config.getMaxRate()));
+			}
+		});
+	}
 }

+ 195 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/impl/UserBusinessFrontServiceImpl.java

@@ -0,0 +1,195 @@
+package com.cyksj.service.distribute.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
+import com.cyksj.mapper.OrderDonMapper;
+import com.cyksj.mapper.UserRenewChangeTicketRecordMapper;
+import com.cyksj.mapper.manage.distribute.UserBusinessDefaultRateConfigMapper;
+import com.cyksj.mapper.manage.distribute.UserDistributeBusinessOrderDonRecordMapper;
+import com.cyksj.mapper.manage.distribute.UserDistributeBusinessRateMapper;
+import com.cyksj.model.entity.*;
+import com.cyksj.redis.RedisService;
+import com.cyksj.service.distribute.UserBusinessFrontService;
+import com.ejlchina.searcher.BeanSearcher;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+
+/*
+ *项目名: netflix
+ *文件名: UserBusinessFrontServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/3/23 14:20
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class UserBusinessFrontServiceImpl implements UserBusinessFrontService {
+	private final BeanSearcher beanSearcher;
+
+	private final UserDistributeBusinessRateMapper userDistributeBusinessRateMapper;
+
+	private final OrderDonMapper orderDonMapper;
+
+	private final UserDistributeBusinessOrderDonRecordMapper businessOrderDonRecordMapper;
+
+	private final UserRenewChangeTicketRecordMapper renewChangeTicketRecordMapper;
+
+	private final RedisService redisService;
+
+	private final UserBusinessDefaultRateConfigMapper defaultRateConfigMapper;
+
+	@Override
+	public void taskDistributeRateBenefits(Long sharedId, Long businessId, OrderDon order, Integer distributeRate) {
+		UserDistributeBusinessRate businessRate = userDistributeBusinessRateMapper.selectOne(Wrappers.lambdaQuery(UserDistributeBusinessRate.class)
+				.eq(UserDistributeBusinessRate::getBusinessId, businessId)
+				.eq(UserDistributeBusinessRate::getGoodsId, order.getGoodsId())
+				.eq(UserDistributeBusinessRate::getSkuId, order.getSkuId()).last("limit 1"));
+		if (businessRate != null) {
+			//首单
+			if (order.getOrderType() == 1) {
+				log.info("商务首单orderId:{}分销分配提成开始", order.getId());
+				//用户之前是否下过单
+				Integer count = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
+						.eq(OrderDon::getUserId, order.getUserId())
+						.ne(OrderDon::getId, order.getId()).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
+				if (count == 0) {
+					//是否享受过该用户带来的首单 提成
+					UserDistributeBusinessOrderDonRecord record = businessOrderDonRecordMapper.selectOne(Wrappers.lambdaQuery(UserDistributeBusinessOrderDonRecord.class)
+							.eq(UserDistributeBusinessOrderDonRecord::getBusinessId, businessId)
+							.eq(UserDistributeBusinessOrderDonRecord::getUserId, order.getUserId())
+							.eq(UserDistributeBusinessOrderDonRecord::getOrderType, 1)
+							.last("limit 1"));
+					if (record == null) {
+						try {
+							boolean isSuccess = redisService.setNx(RedisService.key.BUSINESS_FIRST_ORDER_USER_KEY.getNameFormat(order.getUserId()), businessId, RedisService.key.BUSINESS_FIRST_ORDER_USER_KEY.getTimeout());
+							if (isSuccess) {
+								//首单虚物规格 提成
+								record = saveBusinessTakeMoneyRecord(order, businessId, sharedId, businessRate.getFirstOrderRate(), null, distributeRate);
+								if (record == null) {
+									return;
+								}
+								businessOrderDonRecordMapper.insert(record);
+								log.info("开始给商务人员:{}分配分销人:{}分销的用户:{}首单:{}提成", businessId, sharedId, order.getUserId(), order.getId());
+							}
+						} catch (DuplicateKeyException e) {
+							log.error("商务:{}重复获取分销人:{}分销的用户:{}首单:{}提成", businessId, businessId, order.getUserId(), order.getId());
+						}
+					}
+				}
+			}
+			//续费
+			if (order.getOrderType() == 2) {
+				log.info("商务首单续费分销分配提成开始");
+				//是否享受过该用户首单 提成
+				UserDistributeBusinessOrderDonRecord record = businessOrderDonRecordMapper.selectOne(Wrappers.lambdaQuery(UserDistributeBusinessOrderDonRecord.class)
+						.eq(UserDistributeBusinessOrderDonRecord::getBusinessId, businessId)
+						.eq(UserDistributeBusinessOrderDonRecord::getUserId, order.getUserId())
+						.eq(UserDistributeBusinessOrderDonRecord::getOrderType, 1).last("limit 1"));
+				if (record != null) {
+					log.info("开始给商务人员:{}分配用户:{}首单续费提成", businessId, order.getUserId());
+					//是否更换过车票规格座位号
+					Long preRelationId = record.getPreRelationId();
+					Long relationId = order.getRelationId();
+					if (relationId.equals(preRelationId)) {
+						try {
+							//分配首单续费提成
+							record = saveBusinessTakeMoneyRecord(order, businessId, sharedId, null, businessRate.getRenewOrderRate(), distributeRate);
+							if (record == null) {
+								return;
+							}
+							businessOrderDonRecordMapper.insert(record);
+							log.info("开始给商务人员:{}分配分销人:{}分销的用户:{}续费首单:{}提成", businessId, sharedId, order.getUserId(), order.getId());
+						} catch (DuplicateKeyException e) {
+							log.error("商务:{}重复获取分销人:{}分销的用户:{}续费首单:{}提成", businessId, businessId, order.getUserId(), order.getId());
+						}
+					} else {
+						UserRenewChangeTicketRecord renewChangeTicketRecord = renewChangeTicketRecordMapper.selectOne(Wrappers.lambdaQuery(UserRenewChangeTicketRecord.class)
+								.eq(UserRenewChangeTicketRecord::getUserId, order.getUserId())
+								.eq(UserRenewChangeTicketRecord::getAfterRelationId, relationId)
+								.last("limit 1"));
+						if (renewChangeTicketRecord != null && renewChangeTicketRecord.getPreRelationId().equals(preRelationId)) {
+							try {
+								//分配首单续费更换车位后提成
+								record = saveBusinessTakeMoneyRecord(order, businessId, sharedId, null, businessRate.getRenewOrderRate(), distributeRate);
+								if (record == null) {
+									return;
+								}
+								businessOrderDonRecordMapper.insert(record);
+								log.info("开始给商务人员:{}分配分销人:{}分销的用户:{}续费首单:{}更换后车位提成", businessId, sharedId, order.getUserId(), order.getId());
+							} catch (DuplicateKeyException e) {
+								log.error("商务:{}重复获取分销人:{}分销的用户:{}续费首单:{}更换后车位提成", businessId, businessId, order.getUserId(), order.getId());
+							}
+						}
+					}
+
+				}
+			}
+		}
+	}
+
+
+	/**
+	 * 保存商务分配提成记录
+	 */
+	public UserDistributeBusinessOrderDonRecord saveBusinessTakeMoneyRecord(OrderDon order, Long businessId, Long sharedId, Integer firstOrderRate, Integer renewOrderRate, Integer distributeRate) {
+		UserBusinessDefaultRateConfig defaultGoodsRateConfig = defaultRateConfigMapper.selectOne(Wrappers.lambdaQuery(UserBusinessDefaultRateConfig.class)
+				.eq(UserBusinessDefaultRateConfig::getGoodsId, order.getGoodsId()).last("limit 1"));
+		if (defaultGoodsRateConfig == null) {
+			log.info("系统默认商务分销配置未配置,businessId:{},orderId:{}", businessId, order.getId());
+			return null;
+		}
+		UserDistributeBusinessOrderDonRecord record = new UserDistributeBusinessOrderDonRecord();
+		record.setBusinessId(businessId);
+		record.setUserId(order.getUserId());
+		record.setSharedId(sharedId);
+		record.setOrderType(order.getOrderType());
+		record.setOrderCreatedTime(order.getCreatedTime());
+		record.setOrderId(order.getId());
+		record.setPreRelationId(order.getRelationId());
+		//是否超过默认配置平台比例
+		Integer defaultGoodsRate = defaultGoodsRateConfig.getRate();
+		//首单提成比例
+		BigDecimal orderMoney = order.getMoney();
+		BigDecimal takeMoney = BigDecimal.ZERO;
+		if (firstOrderRate != null) {
+			if (distributeRate > defaultGoodsRate) {
+				if (defaultGoodsRateConfig.getIsPlatPay()) {
+					log.info("首单,平台承担商务businessId:{}配置分销者sharedId:{}超过平台goodsId:{}标准分销比例:{}", businessId, sharedId, order.getGoodsId(), defaultGoodsRate);
+				} else {
+					firstOrderRate -= distributeRate - defaultGoodsRate;
+					log.info("商务businessId:{}配置分销者sharedId:{}比例超过标准比例,可获取首单提成比例为:{}", businessId, sharedId, firstOrderRate);
+					if (firstOrderRate <= 0) {
+						log.info("商务businessId:{}获得分销者sharedId:{}首单提成比例不大于0", businessId, sharedId);
+						return null;
+					}
+				}
+			}
+			record.setRate(firstOrderRate);
+			BigDecimal firstRate = BigDecimal.valueOf(firstOrderRate).divide(BigDecimal.valueOf(100));
+			takeMoney = orderMoney.multiply(firstRate);
+		}
+		if (renewOrderRate != null) {
+			if (distributeRate > defaultGoodsRate) {
+				if (defaultGoodsRateConfig.getIsPlatPay()) {
+					log.info("首单续费,平台承担商务businessId:{}配置分销者sharedId:{}超过平台goodsId:{}标准分销比例:{}", businessId, sharedId, order.getGoodsId(), defaultGoodsRate);
+				} else {
+					renewOrderRate -= distributeRate - defaultGoodsRate;
+					log.info("商务businessId:{}配置分销者sharedId:{}比例超过标准比例,可获取首单续费提成比例为:{}", businessId, sharedId, renewOrderRate);
+					if (renewOrderRate <= 0) {
+						log.info("商务businessId:{}获得分销者sharedId:{}首单续费提成比例不大于0", businessId, sharedId);
+						return null;
+					}
+				}
+			}
+			record.setRate(renewOrderRate);
+			BigDecimal renewRate = BigDecimal.valueOf(renewOrderRate).divide(BigDecimal.valueOf(100));
+			takeMoney = orderMoney.multiply(renewRate);
+		}
+		record.setTakeMoney(takeMoney);
+		return record;
+	}
+}

+ 16 - 0
netflix-service/src/main/java/com/cyksj/service/mange/business/UserBusinessRateService.java

@@ -0,0 +1,16 @@
+package com.cyksj.service.mange.business;
+
+/*
+ *项目名: netflix
+ *文件名: UserBusinessRateService
+ *创建者: JavaZou
+ *创建时间:2023/3/23 14:02
+ */
+public interface UserBusinessRateService {
+	/**
+	 * 若无配置商务人员比例,保存商务人员比例
+	 */
+	void saveBusinessRate(Long businessId);
+
+	Boolean isBusiness(Long businessId);
+}

+ 71 - 0
netflix-service/src/main/java/com/cyksj/service/mange/business/impl/UserBusinessRateServiceImpl.java

@@ -0,0 +1,71 @@
+package com.cyksj.service.mange.business.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.mapper.manage.distribute.UserDistributeBusinessRateMapper;
+import com.cyksj.model.entity.UserDistributeBusinessRate;
+import com.cyksj.model.views.CmsUserVO;
+import com.cyksj.model.views.GoodsDonSkuView;
+import com.cyksj.service.mange.business.UserBusinessRateService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: UserBusinessRateServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/3/23 14:02
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class UserBusinessRateServiceImpl implements UserBusinessRateService {
+	private final UserDistributeBusinessRateMapper userDistributeBusinessRateMapper;
+
+	private final BeanSearcher beanSearcher;
+
+	@Override
+	public void saveBusinessRate(Long businessId) {
+		if (businessId != null) {
+			List<GoodsDonSkuView> goodsDonSkuList = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getType, 1)
+					.field(GoodsDonSkuView::getGoodsDonDeleted, true)
+					.field(GoodsDonSkuView::getSkuId).op(Operator.NotNull)
+					.build());
+			goodsDonSkuList.forEach(goodsDonSku -> {
+				Long goodsId = goodsDonSku.getGoodsId();
+				Long skuId = goodsDonSku.getSkuId();
+				UserDistributeBusinessRate businessRate = userDistributeBusinessRateMapper.selectOne(Wrappers.lambdaQuery(UserDistributeBusinessRate.class)
+						.eq(UserDistributeBusinessRate::getGoodsId, goodsId)
+						.eq(UserDistributeBusinessRate::getSkuId, skuId)
+						.eq(UserDistributeBusinessRate::getBusinessId, businessId).last("limit 1"));
+				if (businessRate == null) {
+					try {
+						businessRate = new UserDistributeBusinessRate();
+						businessRate.setBusinessId(businessId);
+						businessRate.setGoodsId(goodsId);
+						businessRate.setSkuId(skuId);
+						userDistributeBusinessRateMapper.insert(businessRate);
+					} catch (DuplicateKeyException e) {
+
+					}
+				}
+			});
+		}
+	}
+
+	@Override
+	public Boolean isBusiness(Long businessId) {
+		//是否是商务人员
+		CmsUserVO isBusiness = beanSearcher.searchFirst(CmsUserVO.class, MapUtils.builder().field(CmsUserVO::getId, businessId).field(CmsUserVO::getRoleNames, "商务").op(Operator.Contain).build());
+		if (isBusiness != null) {
+			return true;
+		}
+		return false;
+	}
+}

+ 14 - 1
netflix-service/src/main/java/com/cyksj/service/mange/cms/CmsUserManager.java

@@ -2,14 +2,17 @@ package com.cyksj.service.mange.cms;
 
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.mapper.manage.cms.CmsMenuMapper;
 import com.cyksj.mapper.manage.cms.CmsRoleMapper;
 import com.cyksj.mapper.manage.cms.CmsUserMapper;
 import com.cyksj.mapper.manage.cms.CmsUserRoleMapper;
+import com.cyksj.mapper.manage.distribute.UserDistributeBusinessRateMapper;
 import com.cyksj.model.entity.CmsMenu;
 import com.cyksj.model.entity.CmsRole;
 import com.cyksj.model.entity.CmsUser;
 import com.cyksj.model.entity.CmsUserRole;
+import com.cyksj.service.mange.business.UserBusinessRateService;
 import com.cyksj.service.mange.cms.manager.service.CacheService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -41,6 +44,12 @@ public class CmsUserManager {
 
 	private final CmsUserRoleMapper cmsUserRoleMapper;
 
+	private final UserDistributeBusinessRateMapper userDistributeBusinessRateMapper;
+
+	private final UserBusinessRateService userBusinessRateService;
+
+	private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
+
 	public CmsUser getUser(Long account) {
 		return selectCacheByTemplate(() -> cacheService.getUserCache(account), () -> cmsUserMapper.selectById(account));
 	}
@@ -99,7 +108,11 @@ public class CmsUserManager {
 	}
 
 	public void saveUserRoleRelation(Long userId, String roleIds) {
-		Arrays.stream(roleIds.split(",")).collect(Collectors.toSet()).forEach(roleId->{
+		Arrays.stream(roleIds.split(",")).collect(Collectors.toSet()).forEach(roleId -> {
+			CmsRole cmsRole = cmsRoleMapper.selectById(roleId);
+			if (cmsRole != null && cmsRole.getRoleName().contains("商务")) {
+				TASK_EXECUTOR.execute(() -> userBusinessRateService.saveBusinessRate(userId));
+			}
 			cmsUserRoleMapper.insert(new CmsUserRole(userId, Long.valueOf(roleId)));
 		});
 	}

+ 10 - 0
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -58,6 +58,7 @@ import com.cyksj.model.views.CouponUserView;
 import com.cyksj.model.views.GoodsDonSkuView;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.coupon.CouponFontService;
+import com.cyksj.service.distribute.UserBusinessFrontService;
 import com.cyksj.service.distribute.equipment.EquipmentDistributeService;
 import com.cyksj.service.exchange.ExchangeCodeService;
 import com.cyksj.service.mange.stock.GoodsDonStockService;
@@ -192,6 +193,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final SysConfigService sysConfigService;
 
+	private final UserBusinessFrontService userBusinessFrontService;
+
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
 
 	@Transactional(rollbackFor = Throwable.class)
@@ -1495,6 +1498,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		BigDecimal orderMoney = order.getMoney();
 		BigDecimal points = null;
 		BigDecimal returnMoney = null;
+		Long businessId = null;
 		UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class).eq(UserDistributeShared::getUserId, order.getUserId()).last("limit 1"));
 		if (userDistributeShared != null) {
 			distributeWaitingSendPoints.setSharedId(userDistributeShared.getSharedId());
@@ -1532,6 +1536,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 						returnMoney = orderMoney.multiply(BigDecimal.valueOf(rate)).divide(BigDecimal.valueOf(100));
 					}
 				}else {
+					businessId = userDistribute.getBusinessId();
 					//固定推广分销
 					UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class)
 							.eq(UserPlatDistributeRate::getGoodsId, order.getGoodsId())
@@ -1561,6 +1566,11 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 					distributeWaitingSendPoints.setSendStatus(DistributeWaitingSendPoints.Status.waiting);
 					distributeWaitingSendPoints.setSendTime(DateUtil.offsetDay(order.getPayTime(), 3));
 					distributeWaitingSendPointsMapper.insert(distributeWaitingSendPoints);
+					//暂定虚物 商务可首单提成
+					if (businessId != null && goodsDon.getType() == 1) {
+						//给商务人员 分配提成权益
+						userBusinessFrontService.taskDistributeRateBenefits(userDistributeShared.getSharedId(), businessId, order, rate);
+					}
 				}
 			}
 		}

+ 2 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/cms/CmsAdminUserController.java

@@ -34,6 +34,7 @@ import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.dao.DuplicateKeyException;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -86,6 +87,7 @@ public class CmsAdminUserController {
 
 	@PostMapping("/post")
 	@Log(module = "用户管理/新增用户", businessType = BusinessType.POST, isSaveRequestData = true)
+	@Transactional(rollbackFor = Throwable.class)
 	public Result<String> saveAdmin(@RequestBody @Validated CmsUserReq cmsUserReq) throws Exception {
 		Long adminId = StpUtil.getLoginIdAsLong();
 		CmsUser exist = cmsUserMapper.selectById(adminId);

+ 199 - 4
netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java

@@ -1,32 +1,39 @@
 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.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.annotation.Log;
 import com.cyksj.common.constant.Constant;
 import com.cyksj.common.exception.BusinessRuntimeException;
+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.GoodsDonMapper;
 import com.cyksj.mapper.GoodsDonSkuMapper;
 import com.cyksj.mapper.UserMapper;
-import com.cyksj.mapper.manage.distribute.DistributeMoneyApplyMapper;
-import com.cyksj.mapper.manage.distribute.DistributePointsExchangeMoneyMapper;
-import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
+import com.cyksj.mapper.manage.cms.CmsUserMapper;
+import com.cyksj.mapper.manage.distribute.*;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.request.DistributeApplyMoneyReq;
 import com.cyksj.model.request.UserDistributeReq;
 import com.cyksj.model.views.*;
 import com.cyksj.service.distribute.DistributeService;
+import com.cyksj.service.mange.business.UserBusinessRateService;
 import com.cyksj.service.mange.statistics.StatisticsDataService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapBuilder;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -68,13 +75,28 @@ public class DistributeController {
 
 	private final StatisticsDataService statisticsDataService;
 
+	private final UserBusinessRateService userBusinessRateService;
+
+	private final UserDistributeBusinessRateMapper userDistributeBusinessRateMapper;
+
+	private final HttpServletRequest request;
+
+	private final CmsUserMapper cmsUserMapper;
+
+	private final UserBusinessDefaultRateConfigMapper defaultRateConfigMapper;
+
 	/**
 	 * 添加固定推广者
 	 */
 	@PostMapping
+	@SaCheckPermission("distribute:add")
 	@Log(module = "分销管理/增加推广者", businessType = BusinessType.POST, isSaveRequestData = true)
+	@Transactional(rollbackFor = Throwable.class)
 	public Result<String> saveDistributes(@RequestBody @NotNull UserDistributeReq userDistributeReq) {
 		distributeService.insertDistribute(userDistributeReq);
+		Long businessId = userDistributeReq.getBusinessId();
+		//保存商务人员提成比例
+		userBusinessRateService.saveBusinessRate(businessId);
 		return GatewayResponse.SUCCESS.newBuilder().toResult("添加成功");
 	}
 
@@ -82,6 +104,7 @@ public class DistributeController {
 	 * 删除固定推广者
 	 */
 	@DeleteMapping("/del/{id}")
+	@SaCheckPermission("distribute:delete")
 	@Log(module = "分销管理/删除推广者", businessType = BusinessType.DELETE, isSaveRequestData = true)
 	public Result<String> deleteDistributesById(@PathVariable Long id) {
 		if (id == null || id < 1) {
@@ -95,6 +118,7 @@ public class DistributeController {
 	 * 推广者编辑
 	 */
 	@PutMapping
+	@SaCheckPermission("distribute:update")
 	@Log(module = "分销管理/编辑推广者", businessType = BusinessType.PUT, isSaveRequestData = true)
 	public Result<String> editDistribute(@RequestBody UserDistributeReq userDistributeReq) {
 		distributeService.editDistribute(userDistributeReq);
@@ -117,7 +141,13 @@ public class DistributeController {
 	 */
 	@GetMapping
 	public Result<SearchResult<UserDistributeViews>> distributeList(HttpServletRequest request) {
-		SearchResult<UserDistributeViews> search = beanSearcher.search(UserDistributeViews.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		long adminId = StpUtil.getLoginIdAsLong();
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+		//是否是商务人员
+		if (userBusinessRateService.isBusiness(adminId)) {
+			builder.field(UserDistributeViews::getBusinessId, adminId);
+		}
+		SearchResult<UserDistributeViews> search = beanSearcher.search(UserDistributeViews.class, builder.build());
 		DistributePointsExchangeMoney pointsMoneyRate = distributePointsExchangeMoneyMapper.selectOne(null);
 		Optional.ofNullable(search.getDataList()).ifPresent(list -> list.forEach(view -> {
 			BigDecimal num = view.getPoints().divide(BigDecimal.valueOf(pointsMoneyRate.getPoints()), RoundingMode.DOWN);
@@ -226,6 +256,7 @@ public class DistributeController {
 	 * 提现列表
 	 */
 	@GetMapping("/get/applyMoney/list")
+	@SaCheckPermission("distribute:applyView")
 	public Result<SearchResult<DistributeMoneyApplyView>> applyMoneyList(HttpServletRequest request) {
 		SearchResult<DistributeMoneyApplyView> search = beanSearcher.search(DistributeMoneyApplyView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
 		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
@@ -324,4 +355,168 @@ public class DistributeController {
 				.build());
 		return GatewayResponse.SUCCESS.newBuilder().toResult(number.intValue());
 	}
+
+	/**
+	 * 绑定固定分销者的商务人员详情
+	 */
+	@GetMapping("/get/business/list")
+	public Result<SearchResult<DistributeBusinessView>> getDistributeBusinessView() {
+		long adminId = StpUtil.getLoginIdAsLong();
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+		//是否是商务人员
+		if (userBusinessRateService.isBusiness(adminId)) {
+			builder.field(DistributeBusinessView::getBusinessId, adminId);
+		}
+		SearchResult<DistributeBusinessView> search = beanSearcher.search(DistributeBusinessView.class, builder.build());
+		search.getDataList().forEach(data->{
+			Number numOfRelation = beanSearcher.searchCount(UserDistribute.class, MapUtils.builder().field(UserDistribute::getBusinessId, data.getBusinessId()).field(UserDistribute::getDeleted, true).build());
+			data.setNumOfRelation(numOfRelation.intValue());
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 商务人员提成详情
+	 */
+	@GetMapping("/get/takeMoney/detail")
+	public Result<SearchResult<BusinessTakeMoneyDetail>> getTakeMoneyDetail(String firstMonthDate, String secondMonthDate) {
+		long adminId = StpUtil.getLoginIdAsLong();
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+		//是否是商务人员
+		if (userBusinessRateService.isBusiness(adminId)) {
+			builder.field(BusinessTakeMoneyDetail::getBusinessId, adminId);
+		}
+		String timeSql = StringUtil.EMPTY;
+		if (StrUtil.isNotBlank(firstMonthDate)) {
+			timeSql += String.format("date_format(ubr.order_created_time,'%%Y-%%m') >= '%s'", firstMonthDate);
+		}
+		if (StrUtil.isNotBlank(secondMonthDate)) {
+			timeSql += String.format("and date_format(ubr.order_created_time,'%%Y-%%m') <= '%s'", secondMonthDate);
+		}
+		if (StrUtil.isNotBlank(timeSql)) {
+			builder.put("time", timeSql);
+		}
+		SearchResult<BusinessTakeMoneyDetail> search = beanSearcher.search(BusinessTakeMoneyDetail.class, builder.build());
+		search.getDataList().forEach(data -> {
+			User user = userMapper.selectById(data.getUserId());
+			Optional.ofNullable(user).ifPresent(u -> {
+				data.setNickname(u.getNickname());
+				data.setCreatedTime(u.getCreatedTime());
+			});
+			CmsUser business = cmsUserMapper.selectById(data.getBusinessId());
+			Optional.ofNullable(business).ifPresent(bs -> data.setBusinessName(bs.getNickname()));
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 商务提成head
+	 */
+	@GetMapping("/get/business/headData")
+	public Result<BusinessTakeMoneyHeadView> getTakeMoneyHeadDetail(String firstMonthDate, String secondMonthDate) {
+		long adminId = StpUtil.getLoginIdAsLong();
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+		//是否是商务人员
+		if (userBusinessRateService.isBusiness(adminId)) {
+			builder.field(BusinessTakeMoneyHeadView::getBusinessId, adminId);
+		}
+		String timeSql = StringUtil.EMPTY;
+		if (StrUtil.isNotBlank(firstMonthDate)) {
+			timeSql += String.format("date_format(ubr.order_created_time,'%%Y-%%m') >= '%s'", firstMonthDate);
+		}
+		if (StrUtil.isNotBlank(secondMonthDate)) {
+			timeSql += String.format("and date_format(ubr.order_created_time,'%%Y-%%m') <= '%s'", secondMonthDate);
+		}
+		if (StrUtil.isNotBlank(timeSql)) {
+			builder.put("time", timeSql);
+		}
+		BusinessTakeMoneyHeadView headView = beanSearcher.searchFirst(BusinessTakeMoneyHeadView.class, builder.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(headView);
+	}
+
+	/**
+	 * 查看商务人员提成比例
+	 */
+	@GetMapping("/get/business/rate")
+	public Result<List<UserDistributeBusinessRateRecordView>> getUserDistributeBusinessRateDetail(Long businessId) {
+		List<UserDistributeBusinessRateRecordView> userDistributeBusinessRate = beanSearcher.searchAll(UserDistributeBusinessRateRecordView.class, MapUtils.builder()
+				.field(UserDistributeBusinessRateRecordView::getBusinessId, businessId)
+				.orderBy(UserDistributeBusinessRateRecordView::getGoodsId).asc()
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(userDistributeBusinessRate);
+	}
+
+	/**
+	 * 修改商务人员提成比例
+	 */
+	@PutMapping("/put/business/rate")
+	@Log(module = "分销管理/修改商务人员比例", businessType = BusinessType.PUT, isSaveRequestData = true)
+	public Result<String> updateBusinessRate(@RequestBody @Validated List<UserDistributeBusinessRate> rates) {
+		rates.forEach(userDistributeBusinessRate->{
+			Long rateId = userDistributeBusinessRate.getId();
+			UserDistributeBusinessRate businessRate = Optional.ofNullable(userDistributeBusinessRateMapper.selectById(rateId)).orElse(new UserDistributeBusinessRate());
+			BeanUtil.copyProperties(userDistributeBusinessRate, businessRate);
+			Number number = beanSearcher.searchCount(GoodsDonSkuView.class, MapUtils.builder()
+					.field(GoodsDonSkuView::getGoodsId, userDistributeBusinessRate.getGoodsId())
+					.field(GoodsDonSkuView::getSkuId, userDistributeBusinessRate.getSkuId())
+					.field(GoodsDonSkuView::getGoodsDonDeleted, true)
+					.build());
+			if (number.intValue() == 0) {
+				userDistributeBusinessRateMapper.delete(Wrappers.lambdaQuery(UserDistributeBusinessRate.class)
+						.eq(UserDistributeBusinessRate::getBusinessId, userDistributeBusinessRate.getBusinessId())
+						.eq(UserDistributeBusinessRate::getGoodsId, userDistributeBusinessRate.getGoodsId())
+						.eq(UserDistributeBusinessRate::getSkuId, userDistributeBusinessRate.getSkuId()));
+				return;
+			}
+			if (businessRate.getId() == null) {
+				try {
+					userDistributeBusinessRateMapper.insert(businessRate);
+				} catch (DuplicateKeyException e) {
+				}
+			} else {
+				userDistributeBusinessRateMapper.updateById(businessRate);
+			}
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult("修改比例成功");
+	}
+
+	/**
+	 * 商务默认分配平台比例
+	 */
+	@GetMapping("/get/defaultRateConfig")
+	public Result<List<UserBusinessDefaultRateConfigView>> getDefaultRateConfig() {
+		List<UserBusinessDefaultRateConfigView> search = beanSearcher.searchAll(UserBusinessDefaultRateConfigView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 编辑商务默认平台比例
+	 */
+	@PutMapping("/update/business/defaultRate")
+	public Result<String> updateBusinessDefaultRate(@RequestBody List<UserBusinessDefaultRateConfig> configs) {
+		configs.forEach(rateConfig->{
+			Long rateConfigId = rateConfig.getId();
+			UserBusinessDefaultRateConfig config = Optional.ofNullable(defaultRateConfigMapper.selectById(rateConfigId)).orElse(new UserBusinessDefaultRateConfig());
+			BeanUtil.copyProperties(rateConfig, config);
+			Number number = beanSearcher.searchCount(GoodsDonSkuView.class, MapUtils.builder()
+					.field(GoodsDonSkuView::getGoodsId, rateConfig.getGoodsId())
+					.field(GoodsDonSkuView::getGoodsDonDeleted, true)
+					.build());
+			if (number.intValue() == 0) {
+				defaultRateConfigMapper.delete(Wrappers.lambdaQuery(UserBusinessDefaultRateConfig.class)
+						.eq(UserBusinessDefaultRateConfig::getGoodsId, rateConfig.getGoodsId()));
+				return;
+			}
+			if (rateConfig.getId() == null) {
+				try {
+					defaultRateConfigMapper.insert(config);
+					return;
+				} catch (DuplicateKeyException e) {
+
+				}
+			}
+			defaultRateConfigMapper.updateById(config);
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
 }

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

@@ -13,9 +13,12 @@ import com.cyksj.model.entity.GoodsDonSpec;
 import com.cyksj.model.manage.request.ReqGoodsSkuInsert;
 import com.cyksj.model.manage.request.ReqGoodsSkuSpec;
 import com.cyksj.model.manage.request.ReqGoodsSpecSingle;
+import com.cyksj.model.views.GoodsDonSkuView;
 import com.cyksj.service.mange.CmsGoodsDonService;
 import com.cyksj.service.mange.CmsGoodsDonSkuService;
 import com.cyksj.service.mange.CmsGoodsDonSpecService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.util.MapUtils;
 import com.fasterxml.jackson.databind.JavaType;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -24,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.*;
 
 /**
@@ -43,6 +47,10 @@ public class CmsGoodsDonSkuController {
 
     private final CmsGoodsDonSkuService goodsDonSkuService;
 
+    private final BeanSearcher beanSearcher;
+
+    private final HttpServletRequest request;
+
 
     /**
      * 新增 商品spec & sku
@@ -235,4 +243,13 @@ public class CmsGoodsDonSkuController {
         goodsDonSkuService.removeById(skuId);
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
+
+    /**
+     * 获取平台规格列表
+     */
+    @GetMapping("/get/list")
+    public Result<List<GoodsDonSkuView>> getGoodsSkuList() {
+        List<GoodsDonSkuView> skuViewList = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(skuViewList);
+    }
 }

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

@@ -1 +1 @@
-spring:
  profiles:
    active:
      - ${activeProfile}
    
+spring:
  profiles:
    active:
      - ${activeProfile}