Эх сурвалжийг харах

Merge branch 'distribute_func_b'

zoujiajian 2 жил өмнө
parent
commit
e1cef02741
21 өөрчлөгдсөн 602 нэмэгдсэн , 23 устгасан
  1. 2 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonMapper.java
  2. 4 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/coupon/CouponDistributePopularizeMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeTargetAlertMapper.java
  4. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeTargetAlertRecordMapper.java
  5. 5 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistribute.java
  6. 46 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeTargetAlert.java
  7. 28 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeTargetAlertRecord.java
  8. 17 0
      netflix-dao/src/main/java/com/cyksj/model/request/UserDistributeReq.java
  9. 2 0
      netflix-dao/src/main/java/com/cyksj/model/views/BrokenLineObjView.java
  10. 10 4
      netflix-dao/src/main/java/com/cyksj/model/views/BusinessDistributesMonthlyDataView.java
  11. 50 0
      netflix-dao/src/main/java/com/cyksj/model/views/CouponDistributePopularizeDetailView.java
  12. 1 2
      netflix-dao/src/main/java/com/cyksj/model/views/DistributeOrdersDetailView.java
  13. 42 0
      netflix-dao/src/main/java/com/cyksj/model/views/DistributePlatOrderDonBrokenLineView.java
  14. 12 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeRateDetailView.java
  15. 80 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeTargetAlertView.java
  16. 4 1
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeViews.java
  17. 13 0
      netflix-dao/src/main/resources/mapper/CouponDistributePopularizeMapper.xml
  18. 18 0
      netflix-dao/src/main/resources/mapper/OrderDonMapper.xml
  19. 9 9
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpServiceImpl.java
  20. 131 0
      netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributeServiceImpl.java
  21. 102 7
      netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java

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

@@ -64,4 +64,6 @@ public interface OrderDonMapper extends BaseMapper<OrderDon> {
 	BigDecimal getTotalMoney(@Param("startDate") String startDate, @Param("endDate") String endDate);
 
 	BigDecimal getClearRenewOrderMoney(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
+	BrokenLineObjView selectDsPlatBrokenLineMoney(@Param("sharedId") Long sharedId, @Param("first") String first, @Param("end") String end);
 }

+ 4 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/coupon/CouponDistributePopularizeMapper.java

@@ -7,6 +7,8 @@ import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
+import java.util.List;
+
 /*
  *项目名: netflix
  *文件名: CouponDistributePopularizeMapper
@@ -19,4 +21,6 @@ public interface CouponDistributePopularizeMapper extends BaseMapper<CouponDistr
 
 	@Select("select distinct c.* from (select * from coupon_distribute_popularize where distribute_id = #{distributeId} and deleted is true) cp inner join coupon c on c.id = cp.coupon_id and type = 'discount' inner join coupon_sku cs on cs.coupon_id = c.id and cs.sku_id = #{skuId} order by c.discount desc limit 1")
 	Coupon selectDiscountCouponByUserId(@Param("distributeId") Long distributeId, @Param("skuId") Long skuId);
+
+	void batchInsert(@Param("list") List<CouponDistributePopularize> couponRelates);
 }

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

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

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

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

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

@@ -17,6 +17,11 @@ import java.util.Date;
 public class UserDistribute extends BaseEntity{
 	private Long userId;
 
+	/**
+	 * 类型
+	 */
+	private String type;
+
 	/**
 	 * 备注
 	 */

+ 46 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeTargetAlert.java

@@ -0,0 +1,46 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserDistributeTargetAlert
+ * 创建者: JavaZou
+ * 创建时间:2023/11/22 16:08
+ */
+@Getter
+@Setter
+public class UserDistributeTargetAlert extends BaseEntity{
+
+	/**
+	 * 渠道id
+	 */
+	private Long DistributeId;
+
+	/**
+	 * 类型 1总销售额、2销售额正变化、3负变化
+	 */
+	private Integer type;
+
+	/**
+	 * 目标 比例/金额
+	 */
+	private BigDecimal target;
+
+	/**
+	 * 是否开启一周内不提醒 默认false不开启
+	 */
+	private Boolean isWeek;
+
+	/**
+	 * 下周可提醒时间
+	 */
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private Date nextAlertTime;
+}

+ 28 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserDistributeTargetAlertRecord.java

@@ -0,0 +1,28 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserDistributeTargetAlertRecord
+ * 创建者: JavaZou
+ * 创建时间:2023/11/23 16:38
+ */
+@Getter
+@Setter
+public class UserDistributeTargetAlertRecord extends BaseEntity{
+	private Long alertId;
+
+	private Long distributeId;
+
+	private Integer type;
+
+	private BigDecimal target;
+
+	private BigDecimal triggerTarget;
+
+	private Boolean status;
+}

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

@@ -1,5 +1,7 @@
 package com.cyksj.model.request;
 
+import com.cyksj.model.entity.CouponDistributePopularize;
+import com.cyksj.model.entity.UserDistributeTargetAlert;
 import com.cyksj.model.entity.UserPlatDistributeRate;
 import com.cyksj.model.entity.UserPlatSkuDistributeRate;
 import lombok.Getter;
@@ -28,6 +30,11 @@ public class UserDistributeReq {
 	 */
 	private Long businessId;
 
+	/**
+	 * 分类
+	 */
+	private String type;
+
 	private String remark;
 
 	/**
@@ -39,4 +46,14 @@ public class UserDistributeReq {
 	 * 平台规格分销比例
 	 */
 	private List<UserPlatSkuDistributeRate> skuRates;
+
+	/**
+	 * 渠道关联优惠券 列表
+	 */
+	private List<CouponDistributePopularize> couponRelates;
+
+	/**
+	 * 渠道目标额
+	 */
+	private List<UserDistributeTargetAlert> targets;
 }

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

@@ -32,5 +32,7 @@ public class BrokenLineObjView {
 
 	private Map<Long, List<PlatOrderDonBrokenLineView>> goodsData;
 
+	private Map<Long, List<DistributePlatOrderDonBrokenLineView>> dsGoodsData;
+
 	private Map<Long, List<PersonDistributeBrokenLineView>> distributeData;
 }

+ 10 - 4
netflix-dao/src/main/java/com/cyksj/model/views/BusinessDistributesMonthlyDataView.java

@@ -15,12 +15,12 @@ import java.math.BigDecimal;
  */
 @Getter
 @Setter
-@SearchBean(tables = "(select distinct business_id from user_distribute_business_rate ur inner join cms_user cu on cu.id = ur.business_id) ur inner join user_distribute ud on ud.business_id = ur.business_id and ud.deleted is true :time1:" +
+@SearchBean(tables = "(select distinct business_id from user_distribute_business_rate ur inner join cms_user cu on cu.id = ur.business_id) ur left join user_distribute ud on ud.business_id = ur.business_id and ud.deleted is true :time1:" +
 		" left join user_distribute_shared us on us.shared_id = ud.user_id :time2:" +
 		" left join order_don od on od.user_id = us.user_id and od.status not in ('close','refund','noPayment') and od.is_fixed_distribute = 1 :time3:",
-		groupBy = "ud.business_id")
+		groupBy = "ur.business_id")
 public class BusinessDistributesMonthlyDataView {
-	@DbField("ud.business_id")
+	@DbField("ur.business_id")
 	private Long businessId;
 
 	/**
@@ -54,8 +54,14 @@ public class BusinessDistributesMonthlyDataView {
 	private Integer numOfNewUser;
 
 	/**
-	 * 1本月,2历史
+	 * 1本月,2历史,3上个月
 	 */
 	@DbField(":type:")
 	private Integer type;
+
+	/**
+	 * 排序
+	 */
+	@DbField(":sorted:")
+	private Integer sorted;
 }

+ 50 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CouponDistributePopularizeDetailView.java

@@ -0,0 +1,50 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: CouponDistributePopularizeDetailView
+ * 创建者: JavaZou
+ * 创建时间:2023/11/27 12:14
+ */
+@Getter
+@Setter
+@SearchBean(tables = "coupon_distribute_popularize cp inner join coupon c on c.id = cp.coupon_id",
+		where = "cp.deleted is true and cp.is_general is false and c.deleted is true")
+public class CouponDistributePopularizeDetailView {
+	@DbField("cp.id")
+	private Long id;
+
+	@DbField("cp.coupon_id")
+	private Long couponId;
+
+	@DbField("c.name")
+	private String couponName;
+
+	@DbField("c.classification_id")
+	private Long classificationId;
+	/**
+	 * 固定推广者id
+	 */
+	@DbField("cp.distribute_id")
+	private Long distributeId;
+
+	@DbField("cp.user_id")
+	private Long userId;
+
+	/**
+	 * 是否是普通 默认不是
+	 */
+	@DbField("cp.is_general")
+	private Boolean isGeneral;
+
+	/**
+	 * 兑换码
+	 */
+	@DbField("cp.ex_code")
+	private String exCode;
+}

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

@@ -20,8 +20,7 @@ import java.util.Date;
 @Setter
 @SearchBean(tables = "distribute_waiting_send_points dp left join order_don od on od.id = dp.order_id" +
 		" left join user u on u.id = dp.user_id" +
-		" left join goods_don gd on gd.id = od.goods_id",
-		where = "od.is_fixed_distribute is true")
+		" left join goods_don gd on gd.id = od.goods_id")
 public class DistributeOrdersDetailView {
 	@DbField("u.nickname")
 	private String nickname;

+ 42 - 0
netflix-dao/src/main/java/com/cyksj/model/views/DistributePlatOrderDonBrokenLineView.java

@@ -0,0 +1,42 @@
+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;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePlatOrderDonBrokenLineView
+ * 创建者: JavaZou
+ * 创建时间:2023/11/17 18:05
+ */
+@Getter
+@Setter
+@SearchBean(tables = "(select order_id from distribute_waiting_send_points dp :sid:) dp inner join order_don od on od.id = dp.order_id",
+		where = "od.status not in ('noPayment','close','refund')",
+		groupBy = "od.goods_id,date_format(od.created_time,'%Y-%m-%d')")
+public class DistributePlatOrderDonBrokenLineView {
+	@DbField("od.goods_id")
+	private Long goodsId;
+
+	/**
+	 * 平台名称
+	 */
+	@DbField("select title from goods_don where id = od.goods_id")
+	private String goodsTitle;
+
+	/**
+	 * 当前日期订单金额
+	 */
+	@DbField("cast(sum(od.money)/100 as decimal(10,2))")
+	private BigDecimal money;
+
+	/**
+	 * 日期
+	 */
+	@DbField("date_format(od.created_time,'%Y-%m-%d')")
+	private String date;
+}

+ 12 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeRateDetailView.java

@@ -1,5 +1,7 @@
 package com.cyksj.model.views;
 
+import com.cyksj.model.entity.CouponDistributePopularize;
+import com.cyksj.model.entity.UserDistributeTargetAlert;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -17,4 +19,14 @@ public class UserDistributeRateDetailView {
 	private List<UserDistributeView> rates;
 
 	private List<UserSkuDistributeView> skuRates;
+
+	/**
+	 * 渠道关联优惠券 列表
+	 */
+	private List<CouponDistributePopularizeDetailView> couponRelates;
+
+	/**
+	 * 渠道目标额
+	 */
+	private List<UserDistributeTargetAlert> targets;
 }

+ 80 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeTargetAlertView.java

@@ -0,0 +1,80 @@
+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;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserDistributeTargetAlertView
+ * 创建者: JavaZou
+ * 创建时间:2023/11/22 16:35
+ */
+@Getter
+@Setter
+@SearchBean(tables = "user_distribute_target_alert_record ur inner join user_distribute ud on ud.id = ur.distribute_id and ud.deleted is true" +
+		" inner join user u on u.id = ud.user_id" +
+		" left join cms_user cu on cu.id = ud.business_id")
+public class UserDistributeTargetAlertView {
+
+	@DbField("ur.id")
+	private Long id;
+
+	/**
+	 * 用户id
+	 */
+	@DbField("u.id")
+	private Long userId;
+
+	/**
+	 * 用户昵称
+	 */
+	@DbField("u.nickname")
+	private String nickname;
+
+	@DbField("ur.distribute_id")
+	private Long distributeId;
+
+	/**
+	 * 目标类型
+	 */
+	@DbField("ur.type")
+	private Integer type;
+
+	/**
+	 * 目标值
+	 */
+	@DbField("ur.target")
+	private BigDecimal target;
+
+	@DbField("ur.trigger_target")
+	private BigDecimal triggerTarget;
+
+	/**
+	 * 是否跟进
+	 */
+	@DbField("ur.status")
+	private Boolean status;
+
+	/**
+	 * 商务名
+	 */
+	@DbField("cu.nickname")
+	private String businessName;
+
+	/**
+	 * 备注
+	 */
+	@DbField("ud.remark")
+	private String remark;
+
+	/**
+	 * 触发时间
+	 */
+	@DbField("ur.created_time")
+	private Date createdTime;
+}

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

@@ -20,7 +20,7 @@ import java.util.Date;
 @SearchBean(tables = "user_distribute ud left join user_distribute_shared us on ud.user_id = us.shared_id" +
 		" left join order_don od on od.user_id = us.user_id and od.is_fixed_distribute = 1 and od.status not in ('noPayment', 'close') :time:",
 		where = "ud.deleted is true",
-		groupBy = "ud.id,ud.user_id,ud.business_id,ud.remark,ud.created_time,ud.update_time,ud.business_bind_time")
+		groupBy = "ud.id,ud.user_id,ud.business_id,ud.remark,ud.created_time,ud.update_time,ud.business_bind_time,ud.type")
 public class UserDistributeViews {
 
 	@DbField("ud.id")
@@ -41,6 +41,9 @@ public class UserDistributeViews {
 	@DbField("ud.remark")
 	private String remark;
 
+	@DbField("ud.type")
+	private String type;
+
 	@DbField("count(od.id)")
 	private Integer orders;
 

+ 13 - 0
netflix-dao/src/main/resources/mapper/CouponDistributePopularizeMapper.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.cyksj.mapper.manage.coupon.CouponDistributePopularizeMapper">
+
+    <insert id="batchInsert">
+        insert into coupon_distribute_popularize(`coupon_id`,`distribute_id`,`ex_code`,`created_time`,`update_time`)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.couponId},#{item.distributeId},#{item.exCode},now(),now())
+        </foreach>
+    </insert>
+</mapper>

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

@@ -294,4 +294,22 @@
             and o.created_time &lt; #{endDate}
         </if>
     </select>
+
+    <select id="selectDsPlatBrokenLineMoney" resultType="com.cyksj.model.views.BrokenLineObjView">
+        select min(curdate) as firstDate,
+        max(curdate) as lastDate
+        from (select cast(sum(od.money)/100 as decimal(10,2)) as curdateMoney,
+        date_format(od.created_time,'%Y-%m-%d') curdate from (select order_id from distribute_waiting_send_points where
+        shared_id = #{sharedId}) dp inner join order_don od
+        on od.id = dp.order_id
+        where od.status not in ('noPayment','close','refund')
+        group by od.goods_id,date_format(od.created_time,'%Y-%m-%d'))s
+        where 1 = 1
+        <if test="first != null">
+            and curdate >= #{first}
+        </if>
+        <if test="end != null">
+            and curdate &lt; #{end}
+        </if>
+    </select>
 </mapper>

+ 9 - 9
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpServiceImpl.java

@@ -38,7 +38,7 @@ import com.cyksj.service.corp.WxCorpOps;
 import com.cyksj.service.corp.msg.CorpEventActionService;
 import com.cyksj.service.corp.msg.CorpMessageHandler;
 import com.cyksj.service.corp.msg.CorpMessageRouter;
-import com.cyksj.service.mange.coupon.CouponCommonService;
+import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.util.WxCorpUtil;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.param.Operator;
@@ -102,7 +102,7 @@ public class CorpServiceImpl implements CorpService {
 	private CorpUserAuthMapper corpUserAuthMapper;
 
 	@Autowired
-	private CouponCommonService couponCommonService;
+	private UserBindRelationService userBindRelationService;
 
 	@PostConstruct
 	private void init() {
@@ -352,25 +352,25 @@ public class CorpServiceImpl implements CorpService {
 			corpUser.setUserId(user.getId());
 			corpUserMapper.updateById(corpUser);
 		}
+		//关联关系
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(corpUser.getUserId(), null);
 		YHLXUserDetailView view = Optional.ofNullable(beanSearcher.searchFirst(YHLXUserDetailView.class, MapUtils.builder().field(YHLXUserDetailView::getUserId, corpUser.getUserId()).op(Operator.Equal).build())).orElse(new YHLXUserDetailView());
 		if (view.getUserId() != null) {
 			view.setAddress(addressMapper.selectOne(Wrappers.lambdaQuery(Address.class).eq(Address::getUserId, view.getUserId()).eq(Address::getIsDefault, true).last("limit 1")));
 			List<TicketView> ticketViews = beanSearcher.searchAll(TicketView.class, MapUtils.builder()
-					.field(TicketView::getUserId, view.getUserId()).op(Operator.Equal)
-					.field(TicketView::getGrStatus, "validity").op(Operator.Equal)
+					.field(TicketView::getUserId, userIdList).op(Operator.InList)
+					.field(TicketView::getGrStatus, List.of("validity", "outside")).op(Operator.InList)
 					.build());
 			DateTime now = DateTime.now();
 			List<TicketView> tkCollect = ticketViews.stream().filter(tk -> {
-				if ("validity".equals(tk.getGroupsTripStatus())) {
-					if (tk.getExpiryTime() != null && tk.getExpiryTime().before(now)) {
-						return false;
-					}
+				if (tk.getExpiryTime() != null && tk.getExpiryTime().before(now)) {
+					return false;
 				}
 				return true;
 			}).collect(Collectors.toList());
 			view.setTicketViews(tkCollect);
 			List<CorpWxOrderDonView> orderDonViews = beanSearcher.searchAll(CorpWxOrderDonView.class, MapUtils.builder()
-					.field(CorpWxOrderDonView::getUserId, view.getUserId()).op(Operator.Equal)
+					.field(CorpWxOrderDonView::getUserId, userIdList).op(Operator.InList)
 					.build());
 			view.setOrderDonViews(orderDonViews);
 		}

+ 131 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributeServiceImpl.java

@@ -2,6 +2,8 @@ package com.cyksj.service.distribute.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateTime;
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.constant.Constant;
 import com.cyksj.common.constant.TaskTypeEnum;
@@ -24,6 +26,8 @@ import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -65,6 +69,8 @@ public class DistributeServiceImpl implements DistributeService {
 
 	private final UserPlatSkuDistributeRateMapper userPlatSkuDistributeRateMapper;
 
+	private final UserDistributeTargetAlertMapper targetAlertMapper;
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public void insertDistribute(UserDistributeReq userDistributeReq) {
@@ -133,6 +139,13 @@ public class DistributeServiceImpl implements DistributeService {
 				}
 			}
 		}
+		List<CouponDistributePopularize> couponRelates = userDistributeReq.getCouponRelates();
+		handlerDistributeCouponRelate(userDistribute.getId(), couponRelates);
+
+		//渠道目标额配置
+		List<UserDistributeTargetAlert> targets = userDistributeReq.getTargets();
+		handlerDistributeTargetAlert(userDistribute.getId(), targets);
+
 		redisService.del(RedisService.key.USER_DISTRIBUTE_ADD_KEY.getNameFormat(userDistributeReq.getUserId()));
 	}
 
@@ -260,6 +273,11 @@ public class DistributeServiceImpl implements DistributeService {
 				}
 			}
 		}
+		//处理优惠券关联
+		handlerDistributeCouponRelate(userDistribute.getId(), userDistributeReq.getCouponRelates());
+
+		//渠道目标额配置
+		handlerDistributeTargetAlert(userDistribute.getId(), userDistributeReq.getTargets());
 	}
 
 	@Override
@@ -331,4 +349,117 @@ public class DistributeServiceImpl implements DistributeService {
 			}
 		});
 	}
+
+	private void handlerDistributeCouponRelate(Long distributeId, List<CouponDistributePopularize> couponRelates) {
+		Map<Long, CouponDistributePopularize> map = new ConcurrentHashMap<>();
+		couponRelates.forEach(data -> {
+			data.setDistributeId(distributeId);
+			if (data.getCouponId() == null) {
+				throw BusinessRuntimeException.getInstance("优惠券不存在");
+			}
+			Integer exists = couponMapper.selectCount(Wrappers.lambdaQuery(Coupon.class).eq(Coupon::getId, data.getCouponId()).eq(Coupon::getDeleted, 1));
+			if (exists == 0) {
+				throw BusinessRuntimeException.getInstance("id为{}的优惠券不存在", data.getCouponId());
+			}
+			String exCode = data.getExCode();
+			if (StrUtil.isEmpty(exCode)) {
+				throw BusinessRuntimeException.getInstance("优惠码为空");
+			}
+			Integer count = couponDistributePopularizeMapper.selectCount(Wrappers.lambdaQuery(CouponDistributePopularize.class).ne(data.getId() != null, CouponDistributePopularize::getId, data.getId()).eq(CouponDistributePopularize::getDeleted, 1).eq(CouponDistributePopularize::getExCode, exCode));
+			if (count == 0) {
+				count = couponMapper.selectCount(Wrappers.lambdaQuery(Coupon.class).eq(Coupon::getExCode, exCode).eq(Coupon::getDeleted, true));
+			}
+			if (count > 0) {
+				throw BusinessRuntimeException.getInstance("优惠码:{]已存在", exCode);
+			}
+			if (data.getId() != null) {
+				couponDistributePopularizeMapper.updateById(data);
+			} else {
+				couponDistributePopularizeMapper.insert(data);
+			}
+			map.put(data.getId(), data);
+		});
+
+		List<CouponDistributePopularize> dbCouponPopularizes = couponDistributePopularizeMapper.selectList(Wrappers.lambdaQuery(CouponDistributePopularize.class)
+				.eq(CouponDistributePopularize::getDistributeId, distributeId)
+				.eq(CouponDistributePopularize::getDeleted, 1));
+
+		//不存在的删除
+		List<Long> delDbCouponPids = new ArrayList<>();
+		dbCouponPopularizes.forEach(db -> {
+			if (map.get(db.getId()) == null) {
+				delDbCouponPids.add(db.getId());
+			}
+		});
+
+		if (CollUtil.isNotEmpty(delDbCouponPids)) {
+			couponDistributePopularizeMapper.update(null, Wrappers.lambdaUpdate(CouponDistributePopularize.class)
+					.set(CouponDistributePopularize::getDeleted, 0)
+					.in(CouponDistributePopularize::getId, delDbCouponPids)
+					.eq(CouponDistributePopularize::getDeleted, 1));
+		}
+	}
+
+
+	/**
+	 * 渠道目标额 设置
+	 */
+	private void handlerDistributeTargetAlert(Long distributeId, List<UserDistributeTargetAlert> targets) {
+		Map<Long, UserDistributeTargetAlert> map = new ConcurrentHashMap<>();
+		for (UserDistributeTargetAlert targetAlert : targets) {
+			targetAlert.setDistributeId(distributeId);
+			Integer type = targetAlert.getType();
+			BigDecimal target = targetAlert.getTarget();
+			Assert.notNull(type, "请选择对应目标类型");
+			Assert.notNull(target, "请输入对应目标额");
+			if (type < 1 || type > 3) {
+				throw BusinessRuntimeException.getInstance("请选择正确的目标类型");
+			}
+
+			if (target.compareTo(BigDecimal.ZERO) <= 0) {
+				throw BusinessRuntimeException.getInstance("请输入正确的目标额值");
+			}
+
+			if ((type == 2 || type == 3) && target.compareTo(BigDecimal.ZERO) < 0) {
+				throw BusinessRuntimeException.getInstance("请输入正确的变化比例");
+			}
+			Long id = targetAlert.getId();
+
+			try {
+				if (id != null) {
+					UserDistributeTargetAlert dbAlert = targetAlertMapper.selectById(id);
+					if (dbAlert != null) {
+						//目标额 变化 去掉下次提醒时间
+						if (dbAlert.getTarget().compareTo(targetAlert.getTarget()) != 0) {
+							targetAlert.setNextAlertTime(null);
+						}
+						//关闭一周内提醒 去掉下次提醒时间
+						if (!targetAlert.getIsWeek()) {
+							targetAlert.setNextAlertTime(null);
+						}
+						targetAlertMapper.updateById(targetAlert);
+					}
+				} else {
+					targetAlertMapper.insert(targetAlert);
+				}
+				map.put(targetAlert.getId(), targetAlert);
+			} catch (DuplicateKeyException e) {
+			}
+		}
+
+		List<UserDistributeTargetAlert> dbTargetAlert = targetAlertMapper.selectList(Wrappers.lambdaQuery(UserDistributeTargetAlert.class)
+				.eq(UserDistributeTargetAlert::getDistributeId, distributeId));
+
+		//不存在的删除
+		List<Long> delDbTargetAlert = new ArrayList<>();
+		dbTargetAlert.forEach(db -> {
+			if (map.get(db.getId()) == null) {
+				delDbTargetAlert.add(db.getId());
+			}
+		});
+
+		if (CollUtil.isNotEmpty(delDbTargetAlert)) {
+			targetAlertMapper.deleteBatchIds(delDbTargetAlert);
+		}
+	}
 }

+ 102 - 7
netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java

@@ -16,10 +16,7 @@ import com.cyksj.common.util.StringUtil;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.mapper.DistributeGoodsSkuAlertMapper;
-import com.cyksj.mapper.GoodsDonMapper;
-import com.cyksj.mapper.GoodsDonSkuMapper;
-import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.*;
 import com.cyksj.mapper.manage.cms.CmsUserMapper;
 import com.cyksj.mapper.manage.coupon.CouponDistributePopularizeMapper;
 import com.cyksj.mapper.manage.distribute.*;
@@ -54,7 +51,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
-/*
+/** 分销管理
  *项目名: netflix
  *文件名: DistributeController
  *创建者: JavaZou
@@ -112,6 +109,12 @@ public class DistributeController {
 
 	private final UserDistributeBusinessGeneralRateMapper businessGeneralRateMapper;
 
+	private final OrderDonMapper orderDonMapper;
+
+	private final UserDistributeTargetAlertMapper targetAlertMapper;
+
+	private final UserDistributeTargetAlertRecordMapper targetAlertRecordMapper;
+
 	/**
 	 * 添加固定推广者
 	 */
@@ -172,9 +175,46 @@ public class DistributeController {
 				.orderBy(UserSkuDistributeView::getGoodsId).asc()
 				.build());
 		rateDetailView.setSkuRates(skuRates);
+
+		List<CouponDistributePopularizeDetailView> distributePopularizes = beanSearcher.searchAll(CouponDistributePopularizeDetailView.class, MapUtils.builder()
+				.field(CouponDistributePopularizeDetailView::getDistributeId, id)
+				.build());
+		rateDetailView.setCouponRelates(distributePopularizes);
+
+		List<UserDistributeTargetAlert> targets = targetAlertMapper.selectList(Wrappers.lambdaQuery(UserDistributeTargetAlert.class)
+				.eq(UserDistributeTargetAlert::getDistributeId, id));
+		rateDetailView.setTargets(targets);
 		return GatewayResponse.SUCCESS.newBuilder().toResult(rateDetailView);
 	}
 
+	/**
+	 * 固定渠道平台分销详情 趋势图
+	 */
+	@GetMapping("/get/distribute/plat/brokenLine/{sharedId}")
+	public Result<BrokenLineObjView> getDsPlatBrokenLine(@PathVariable Long sharedId, Long firstDate, Long lastDate) {
+		String first = null;
+		String end = null;
+		if (firstDate != null) {
+			first = DateUtil.format(DateTime.of(firstDate), "yyyy-MM-dd");
+		}
+		if (lastDate != null) {
+			end = DateUtil.format(DateTime.of(lastDate), "yyyy-MM-dd");
+		}
+		BrokenLineObjView brokenLineObjView = Optional.ofNullable(orderDonMapper.selectDsPlatBrokenLineMoney(sharedId, first, end))
+				.orElse(new BrokenLineObjView());
+
+		if (brokenLineObjView != null) {
+			List<DistributePlatOrderDonBrokenLineView> views = beanSearcher.searchAll(DistributePlatOrderDonBrokenLineView.class, MapUtils.builder()
+					.field(DistributePlatOrderDonBrokenLineView::getDate, first, end).op(Operator.Between)
+					.put("sid", String.format("where shared_id = %s", sharedId))
+					.orderBy(DistributePlatOrderDonBrokenLineView::getDate).asc()
+					.build());
+			Map<Long, List<DistributePlatOrderDonBrokenLineView>> goodsMap = views.stream().collect(Collectors.groupingBy(DistributePlatOrderDonBrokenLineView::getGoodsId));
+			brokenLineObjView.setDsGoodsData(goodsMap);
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult(brokenLineObjView);
+	}
+
 	/**
 	 * 固定推广者列表
 	 */
@@ -907,7 +947,7 @@ public class DistributeController {
 		if (isBusiness) {
 			builder.field(BusinessDistributesMonthlyDataView::getBusinessId, adminId);
 		}
-		builder.put("n", "(select nickname from cms_user where id = ud.business_id limit 1)");
+		builder.put("n", "(select nickname from cms_user where id = ur.business_id limit 1)");
 		//当月渠道本月数据
 		String time1Sql = StrUtil.EMPTY;
 		String time2Sql = StrUtil.EMPTY;
@@ -932,6 +972,7 @@ public class DistributeController {
 			builder.put("time3", time3Sql);
 		}
 		builder.put("type", 1);
+		builder.put("sorted", 0);
 		List<BusinessDistributesMonthlyDataView> search = beanSearcher.searchAll(BusinessDistributesMonthlyDataView.class, builder.build());
 		//历史渠道 当月数据
 		time1Sql = StrUtil.EMPTY;
@@ -956,9 +997,39 @@ public class DistributeController {
 			builder.put("time3", time3Sql);
 		}
 		builder.put("type", 2);
+		builder.put("sorted", 99);
+
 		List<BusinessDistributesMonthlyDataView> search2 = beanSearcher.searchAll(BusinessDistributesMonthlyDataView.class, builder.build());
+
+		time1Sql = StrUtil.EMPTY;
+		time2Sql = StrUtil.EMPTY;
+		time3Sql = StrUtil.EMPTY;
+		if (StrUtil.isNotBlank(firstMonthDate)) {
+			time1Sql += String.format(" and ud.business_bind_time between '%s' and '%s'", DateUtil.offsetMonth(DateUtil.parse(firstMonthDate, "yyyy-MM-dd"), -1), firstMonthDate);
+			time2Sql += String.format(" and us.created_time >= '%s'", firstMonthDate);
+			time3Sql += String.format(" and od.created_time >= '%s'", firstMonthDate);
+		}
+		if (StrUtil.isNotBlank(secondMonthDate)) {
+			time2Sql += String.format(" and us.created_time < '%s'", secondMonthDate);
+			time3Sql += String.format(" and od.created_time < '%s'", secondMonthDate);
+		}
+		if (StrUtil.isNotBlank(time1Sql)) {
+			builder.put("time1", time1Sql);
+		}
+		if (StrUtil.isNotBlank(time2Sql)) {
+			builder.put("time2", time2Sql);
+		}
+		if (StrUtil.isNotBlank(time3Sql)) {
+			builder.put("time3", time3Sql);
+		}
+		builder.put("type", 3);
+		builder.put("sorted", 1);
+		//上个月渠道在本月历史数据
+		List<BusinessDistributesMonthlyDataView> search3 = beanSearcher.searchAll(BusinessDistributesMonthlyDataView.class, builder.build());
+
 		Collection<BusinessDistributesMonthlyDataView> businessDistributesDataViews = CollUtil.addAll(search, search2);
-		List<BusinessDistributesMonthlyDataView> collect = businessDistributesDataViews.stream().sorted(Comparator.comparing(BusinessDistributesMonthlyDataView::getBusinessId).thenComparing(BusinessDistributesMonthlyDataView::getType)).collect(Collectors.toList());
+		businessDistributesDataViews = CollUtil.addAll(businessDistributesDataViews, search3);
+		List<BusinessDistributesMonthlyDataView> collect = businessDistributesDataViews.stream().sorted(Comparator.comparing(BusinessDistributesMonthlyDataView::getBusinessId).thenComparing(BusinessDistributesMonthlyDataView::getSorted)).collect(Collectors.toList());
 		return GatewayResponse.SUCCESS.newBuilder().toResult(collect);
 	}
 
@@ -1049,4 +1120,28 @@ public class DistributeController {
 		Integer count = distributeGoodsSkuAlertMapper.selectCountByCondition();
 		return GatewayResponse.SUCCESS.newBuilder().toResult(count > 0 ? true : false);
 	}
+
+	/**
+	 * 渠道预警列表
+	 */
+	@GetMapping("/get/target/alert/list")
+	public Result<SearchResult<UserDistributeTargetAlertView>> getTargetAlertList() {
+		SearchResult<UserDistributeTargetAlertView> search = beanSearcher.search(UserDistributeTargetAlertView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.orderBy(UserDistributeTargetAlertView::getId).desc()
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 跟进渠道预警
+	 */
+	@PutMapping("/update/target/alert/status/{id}")
+	public Result<String> updateTargetAlertStatus(@PathVariable Long id) {
+		UserDistributeTargetAlertRecord record = targetAlertRecordMapper.selectById(id);
+		if (record != null && !record.getStatus()) {
+			record.setStatus(true);
+			targetAlertRecordMapper.updateById(record);
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
 }