Pārlūkot izejas kodu

fix 用户订单统计;购买实物权益

zoujiajian 3 gadi atpakaļ
vecāks
revīzija
eaf3a076f1
22 mainītis faili ar 510 papildinājumiem un 24 dzēšanām
  1. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/channel/UserPayEquipmentAvailableBenefitsMapper.java
  2. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/channel/UserPayEquipmentReceiveBenefitsRecordMapper.java
  3. 5 0
      netflix-dao/src/main/java/com/cyksj/model/entity/AbstractBackData.java
  4. 10 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonSku.java
  5. 1 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDon.java
  6. 4 0
      netflix-dao/src/main/java/com/cyksj/model/entity/RealGoodsData.java
  7. 4 0
      netflix-dao/src/main/java/com/cyksj/model/entity/StatisticsFashionGoodsData.java
  8. 27 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserPayEquipmentAvailableBenefits.java
  9. 42 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserPayEquipmentReceiveBenefitsRecord.java
  10. 9 1
      netflix-dao/src/main/java/com/cyksj/model/manage/views/UserView.java
  11. 35 1
      netflix-dao/src/main/java/com/cyksj/model/views/BackgroundDataView.java
  12. 36 0
      netflix-dao/src/main/java/com/cyksj/model/views/OrderDonStatisticsView.java
  13. 1 0
      netflix-service/src/main/java/com/cyksj/service/distribute/equipment/impl/EquipmentDistributeFrontServiceImpl.java
  14. 16 1
      netflix-service/src/main/java/com/cyksj/service/distribute/equipment/impl/EquipmentDistributeServiceImpl.java
  15. 1 1
      netflix-service/src/main/java/com/cyksj/service/mange/statistics/StatisticsDataService.java
  16. 65 15
      netflix-service/src/main/java/com/cyksj/service/mange/statistics/impl/StatisticsDataServiceImpl.java
  17. 2 1
      netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java
  18. 22 0
      netflix-service/src/main/java/com/cyksj/service/order/UserRealOrderBenefitsService.java
  19. 27 0
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  20. 174 0
      netflix-service/src/main/java/com/cyksj/service/order/impl/UserRealOrderBenefitsImpl.java
  21. 1 1
      netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/EquipmentController.java
  22. 2 3
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

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

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

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

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

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

@@ -64,6 +64,11 @@ public abstract class AbstractBackData {
 
 	private Date statisticsDate;
 
+	/**
+	 * 退款金额
+	 */
+	private BigDecimal refundMoney;
+
 	/**
 	 * 创建时间
 	 */

+ 10 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDonSku.java

@@ -74,6 +74,16 @@ public class GoodsDonSku extends BaseEntity {
      */
     private BigDecimal price;
 
+    /**
+     * 是否开启实物车票时长权益
+     */
+    private Boolean isBenefits;
+
+    /**
+     * 权益列表
+     */
+    private String benefitsList;
+
     /**
      * 月数
      */

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

@@ -173,6 +173,7 @@ public class OrderDon extends BaseEntity implements Serializable {
         EX_CODE("exchange_code","兑换码"),
         LOTTERY("lottery","抽奖"),
         EQUIPMENT("equipment", "实物设备分销"),
+        PAY_EQUIPMENT("pay_equipment", "自购设备"),
         ;
         String type;
         String desc;

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

@@ -1,5 +1,6 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -50,5 +51,8 @@ public class RealGoodsData extends BaseEntity{
 	 */
 	private BigDecimal money;
 
+	@TableField(exist = false)
+	private BigDecimal refundMoney;
+
 	private Date statisticsDate;
 }

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

@@ -1,5 +1,6 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -50,5 +51,8 @@ public class StatisticsFashionGoodsData extends BaseEntity{
 	 */
 	private BigDecimal money;
 
+	@TableField(exist = false)
+	private BigDecimal refundMoney;
+
 	private Date statisticsDate;
 }

+ 27 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserPayEquipmentAvailableBenefits.java

@@ -0,0 +1,27 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+/*
+ *项目名: netflix
+ *文件名: UserPayEquipmentAvailableBenefits
+ *创建者: JavaZou
+ *创建时间:2023/3/7 14:58
+ */
+@Getter
+@Setter
+@Accessors(chain = true)
+public class UserPayEquipmentAvailableBenefits extends BaseEntity {
+	private Long userId;
+
+	private Long skuId;
+
+	/**
+	 * 实物订单id
+	 */
+	private Long realOrderId;
+
+	private Boolean deleted;
+}

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

@@ -0,0 +1,42 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+/*
+ *项目名: netflix
+ *文件名: UserPayEquipmentReceiveBenefitsRecord
+ *创建者: JavaZou
+ *创建时间:2023/3/7 14:56
+ */
+@Getter
+@Setter
+@Accessors(chain = true)
+public class UserPayEquipmentReceiveBenefitsRecord extends BaseEntity{
+	private Long userId;
+
+	private Long skuId;
+
+	private Integer months;
+
+	/**
+	 * 座位号
+	 */
+	private Long relationId;
+
+	/**
+	 * 实物订单id
+	 */
+	private Long realOrderId;
+
+	/**
+	 * 未有车票时,生成车票的订单id
+	 */
+	private Long ticketOrderId;
+
+	/**
+	 * 默认1成功,退款后0
+	 */
+	private Integer statusCode;
+}

+ 9 - 1
netflix-dao/src/main/java/com/cyksj/model/manage/views/UserView.java

@@ -16,7 +16,9 @@ import java.util.Date;
 @Getter
 @Setter
 @SearchBean(tables = "user u left join user_distribute_shared usd on usd.user_id = u.id" +
-        " left join user_bind_phone up on up.user_id = u.id")
+        " left join user_bind_phone up on up.user_id = u.id" +
+        " left join channel_popularize cp on cp.id = u.popularize_id" +
+        " left join channel c on c.id = cp.channel_id")
 public class UserView {
 
     /**
@@ -94,6 +96,12 @@ public class UserView {
     @DbField("usd.shared_id")
     private Long sharedId;
 
+    /**
+     * 渠道来源
+     */
+    @DbField("c.name")
+    private String channelName;
+
     /**
      * 创建时间
      */

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

@@ -18,7 +18,12 @@ import java.util.List;
 @Getter
 public class BackgroundDataView {
 	/**
-	 * 总用户数
+	 * 今日访问数
+	 */
+	private Integer activeNumOfUser;
+
+	/**
+	 * 总下单用户数
 	 */
 	private Integer totalNumOfUser;
 
@@ -52,6 +57,35 @@ public class BackgroundDataView {
 	 */
 	private Integer totalExpiredAccountNum;
 
+	/**
+	 * 虚拟订单数
+	 */
+	private Integer virtualNumOfOrder;
+
+	/**
+	 * 虚拟订单金额
+	 */
+	private BigDecimal virtualAccountOfOrder;
+
+	/**
+	 * 实物订单数
+	 */
+	private Integer realGoodsNumOfOrder;
+
+	/**
+	 * 实物订单金额
+	 */
+	private BigDecimal realGoodsAccountOfOrder;
+
+	/**
+	 * 潮玩好物订单数
+	 */
+	private Integer fashionNumOfOrder;
+
+	/**
+	 * 潮玩好物订单金额
+	 */
+	private BigDecimal fashionAccountOfOrder;
 
 
 

+ 36 - 0
netflix-dao/src/main/java/com/cyksj/model/views/OrderDonStatisticsView.java

@@ -0,0 +1,36 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.OrderDon;
+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;
+
+/*
+ *项目名: netflix
+ *文件名: OrderDonStatisticsView
+ *创建者: JavaZou
+ *创建时间:2023/3/7 9:39
+ */
+@Getter
+@Setter
+@SearchBean(tables = " order_don od left join goods_don g on g.id = od.goods_id")
+public class OrderDonStatisticsView {
+	@DbField("od.id")
+	private Long orderId;
+
+	@DbField("g.type")
+	private Long goodsType;
+
+	@DbField("od.status")
+	private OrderDon.Status status;
+
+	@DbField("od.money")
+	private BigDecimal money;
+
+	@DbField("od.created_time")
+	private Date createTime;
+}

+ 1 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/equipment/impl/EquipmentDistributeFrontServiceImpl.java

@@ -59,6 +59,7 @@ public class EquipmentDistributeFrontServiceImpl implements EquipmentDistributeF
 		GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder()
 				.field(GroupsRelationView::getGoodsId, goodsId)
 				.field(GroupsRelationView::getId, relationId)
+				.field(GroupsRelationView::getStatus, GroupsRelation.Status.validity.name())
 				.orderBy(GroupsRelationView::getExpiryTime).asc()
 				.field(GroupsRelationView::getUserId, userId)
 				.build());

+ 16 - 1
netflix-service/src/main/java/com/cyksj/service/distribute/equipment/impl/EquipmentDistributeServiceImpl.java

@@ -183,9 +183,23 @@ public class EquipmentDistributeServiceImpl implements EquipmentDistributeServic
 				.eq(GroupsRelation::getUserId, userId)
 				.eq(GroupsRelation::getId, relationId).eq(GroupsRelation::getStatus, GroupsRelation.Status.validity).last("limit 1"));
 		Date expiryTime = relation.getExpiryTime();
-		if (relation == null || expiryTime == null) {
+		if (relation == null) {
 			return;
 		}
+		if (expiryTime == null) {
+			//未发车直接清除车票
+			groupRelationClearService.clearTicket(relation);
+		} else {
+			DateTime now = DateTime.now();
+			Date finalDate = DateUtil.offset(expiryTime, DateField.MONTH, -months);
+			if (now.isAfter(finalDate)) {
+				//过期 直接清除车票
+				groupRelationClearService.clearTicket(relation);
+			} else {
+				relation.setExpiryTime(finalDate);
+				groupsRelationMapper.updateById(relation);
+			}
+		}
 		DateTime now = DateTime.now();
 		Date finalDate = DateUtil.offset(expiryTime, DateField.MONTH, -months);
 		if (now.isAfter(finalDate)) {
@@ -201,6 +215,7 @@ public class EquipmentDistributeServiceImpl implements EquipmentDistributeServic
 					.set(OrderDon::getStatus, OrderDon.Status.refund));
 		});
 		receiveBenefitsRecord.setRefundOrderId(orderId);
+		receiveBenefitsRecord.setStatusCode(0);
 		equipmentUserReceiveBenefitsRecordMapper.updateById(receiveBenefitsRecord);
 	}
 

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/mange/statistics/StatisticsDataService.java

@@ -15,7 +15,7 @@ import java.util.List;
  *创建时间:2022/10/17 14:43
  */
 public interface StatisticsDataService {
-	Result<BackgroundDataView> getStatisticsByCondition(Long startTime, Long endTime);
+	Result<BackgroundDataView> getStatisticsByCondition(Integer type, Long startTime, Long endTime);
 
 	IPage<ExpiredAccountDataView> getExpiredAccountView(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer uid, Long startTime, Long endTime, Long start, Long limit);
 

+ 65 - 15
netflix-service/src/main/java/com/cyksj/service/mange/statistics/impl/StatisticsDataServiceImpl.java

@@ -18,10 +18,7 @@ import com.cyksj.mapper.manage.statistics.StreamingAccountDataMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.excel.ExcelAccountData;
 import com.cyksj.model.manage.views.GroupsRelationView;
-import com.cyksj.model.views.BackgroundDataView;
-import com.cyksj.model.views.DistributeOrdersView;
-import com.cyksj.model.views.ExpiredAccountDataView;
-import com.cyksj.model.views.GoodsDonSkuView;
+import com.cyksj.model.views.*;
 import com.cyksj.service.mange.CmsAccountService;
 import com.cyksj.service.mange.statistics.StatisticsDataService;
 import com.cyksj.service.order.OrderDonService;
@@ -71,7 +68,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 	private final GroupsMapper groupsMapper;
 
 	@Override
-	public Result<BackgroundDataView> getStatisticsByCondition(Long startTime, Long endTime) {
+	public Result<BackgroundDataView> getStatisticsByCondition(Integer type, Long startTime, Long endTime) {
 		BackgroundDataView backgroundDataView = new BackgroundDataView();
 		Date startDate = null;
 		Date endDate = null;
@@ -83,16 +80,24 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 		}
 		//头部数据
 		headerData(backgroundDataView, startDate, endDate);
-		//appleOne数据
-		getAppleOneDataView(backgroundDataView, startDate, endDate);
-		//流媒体账号
-		getStreamingAccountDataView(backgroundDataView, startDate, endDate);
-		//实物数据
-		getRealGoodsData(backgroundDataView, startDate, endDate);
-		//注册账号数据
-		getRegisterAccountData(backgroundDataView, startDate, endDate);
-		//潮玩好物数据
-		getFashionGoodsData(backgroundDataView, startDate, endDate);
+		switch (type) {
+			case 1:
+				//流媒体账号
+				getStreamingAccountDataView(backgroundDataView, startDate, endDate);
+				break;
+			case 2:
+				//实物数据
+				getRealGoodsData(backgroundDataView, startDate, endDate);
+				break;
+			case 3:
+				//注册账号数据
+				getRegisterAccountData(backgroundDataView, startDate, endDate);
+				break;
+			case 4:
+				//潮玩好物数据
+				getFashionGoodsData(backgroundDataView, startDate, endDate);
+				break;
+		}
 		return GatewayResponse.SUCCESS.newBuilder().toResult(backgroundDataView);
 	}
 
@@ -101,6 +106,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 			List<StatisticsFashionGoodsData> fashionGoodsData = statistics.statisticsFashionGoodsData(startDate, endDate, true);
 			List<StatisticsFashionGoodsData> collect = fashionGoodsData.stream().filter(data -> {
 				if (data.getNumOfUser() != null && data.getNumOfUser() > 0) {
+					data.setRefundMoney(getRefundMoney(data.getGoodsId(), startDate, endDate));
 					data.setMoney(data.getMoney().divide(BigDecimal.valueOf(100)));
 					return true;
 				}
@@ -119,6 +125,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 				if (goodsDonSku != null) {
 					data.setSpecVal(goodsDonSku.getSpecVal());
 				}
+				data.setRefundMoney(getRefundMoney(data.getGoodsId(), startDate, endDate));
 			}));
 			backgroundDataView.setFashionGoodsDataViews(fashionGoodsData);
 		}
@@ -247,6 +254,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 			List<StreamingAccountData> streamingAccountData = statistics.statisticsStreamingAccountData(startDate, endDate, true);
 			List<StreamingAccountData> collect = streamingAccountData.stream().filter(data -> {
 				if (data.getNumOfUser() != null && data.getNumOfUser() > 0) {
+					data.setRefundMoney(getRefundMoney(data.getGoodsId(), startDate, endDate));
 					data.setMoney(data.getMoney().divide(BigDecimal.valueOf(100)));
 					return true;
 				}
@@ -260,6 +268,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 				if (goodsDon != null) {
 					data.setAccountName(goodsDon.getTitle());
 				}
+				data.setRefundMoney(getRefundMoney(data.getGoodsId(), startDate, endDate));
 			}));
 			backgroundDataView.setStreamAccountDataViews(streamingAccountData);
 		}
@@ -270,6 +279,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 			List<RealGoodsData> realGoodsData = statistics.statisticsRealGoodsData(startDate, endDate, true);
 			List<RealGoodsData> collect = realGoodsData.stream().filter(data ->{
 				if (data.getNumOfUser() != null && data.getNumOfUser() > 0) {
+					data.setRefundMoney(getRefundMoney(data.getGoodsId(), startDate, endDate));
 					data.setMoney(data.getMoney().divide(BigDecimal.valueOf(100)));
 					return true;
 				}
@@ -287,6 +297,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 				if (goodsDonSku != null) {
 					data.setSpecVal(goodsDonSku.getSpecVal());
 				}
+				data.setRefundMoney(getRefundMoney(data.getGoodsId(), startDate, endDate));
 			}));
 			backgroundDataView.setRealGoodsDataViews(realGoodsData);
 		}
@@ -317,6 +328,13 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 		//已到期主账号
 		List<Account> expiredAccounts = Optional.ofNullable(accountService.list(Wrappers.lambdaQuery(Account.class).le(Account::getExpiryTime, now))).orElse(new ArrayList<>());
 		backgroundDataView.setTotalExpiredAccountNum(expiredAccounts.size());
+		//虚物
+		setGoodsMoneyAndOrder(1, backgroundDataView);
+		//实物
+		setGoodsMoneyAndOrder(2, backgroundDataView);
+		//潮玩
+		setGoodsMoneyAndOrder(3, backgroundDataView);
+
 		//分销金额数据统计
 		distribute(backgroundDataView, startDate, endDate);
 	}
@@ -372,4 +390,36 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 			backgroundDataView.setDistributeVerifyingMoney(BigDecimal.ZERO);
 		}
 	}
+
+	public BigDecimal getRefundMoney(Long goodsId, Date startDate, Date endDate) {
+		Number refundMoneyNumber = beanSearcher.searchSum(OrderDon.class, MapUtils.builder()
+				.field(OrderDon::getGoodsId, goodsId)
+				.field(OrderDon::getStatus, OrderDon.Status.refund.name())
+				.field(OrderDon::getCreatedTime, startDate, endDate).op(Operator.Between)
+				.build(), "refundMoney");
+		BigDecimal refundMoney = BigDecimal.valueOf(refundMoneyNumber.intValue()).divide(BigDecimal.valueOf(100));
+		return refundMoney;
+	}
+
+	public void setGoodsMoneyAndOrder(Integer type, BackgroundDataView backgroundDataView) {
+		List<OrderDonStatisticsView> orderDonStatisticsView = Optional.ofNullable(beanSearcher.searchAll(OrderDonStatisticsView.class,
+				MapUtils.builder().field(OrderDonStatisticsView::getGoodsType, type)
+						.field(OrderDonStatisticsView::getStatus, Constant.noOrderStatus).op(Operator.InList).build())).orElse(new ArrayList<>());
+		Optional<BigDecimal> orderMoneyReduce = orderDonStatisticsView.stream().map(OrderDonStatisticsView::getMoney).reduce(BigDecimal::add);
+		int totalOrder = orderDonStatisticsView.size();
+
+		BigDecimal orderMoney = orderMoneyReduce.isPresent() ? orderMoneyReduce.get().divide(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
+		backgroundDataView.setFashionNumOfOrder(totalOrder);
+		backgroundDataView.setFashionAccountOfOrder(orderMoney);
+		if (type == 1) {
+			backgroundDataView.setVirtualNumOfOrder(totalOrder);
+			backgroundDataView.setVirtualAccountOfOrder(orderMoney);
+		} else if (type == 2) {
+			backgroundDataView.setRealGoodsNumOfOrder(totalOrder);
+			backgroundDataView.setRealGoodsAccountOfOrder(orderMoney);
+		} else if (type == 3) {
+			backgroundDataView.setFashionNumOfOrder(totalOrder);
+			backgroundDataView.setFashionAccountOfOrder(orderMoney);
+		}
+	}
 }

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

@@ -4,7 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.cyksj.dto.Result;
 import com.cyksj.model.dto.AliPayParams;
 import com.cyksj.model.dto.H5JsPayParams;
-import com.cyksj.model.entity.*;
+import com.cyksj.model.entity.OrderDon;
+import com.cyksj.model.entity.RealGoodsInterestUser;
 import com.cyksj.model.manage.views.OrderDonView;
 import com.cyksj.model.request.OrderPayRequest;
 import com.cyksj.model.request.WxOrderRefundReq;

+ 22 - 0
netflix-service/src/main/java/com/cyksj/service/order/UserRealOrderBenefitsService.java

@@ -0,0 +1,22 @@
+package com.cyksj.service.order;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: UserRealOrderBenefitsService
+ *创建者: JavaZou
+ *创建时间:2023/3/7 14:54
+ */
+public interface UserRealOrderBenefitsService {
+
+	/**
+	 * 获取购买实物权益
+	 */
+	void receivePayRealGoodsBenefits(Long userId, Long id, Long id1, List<Long> skuIds);
+
+	/**
+	 * 扣除实物权益
+	 */
+	void deductUserRealGoodsBenefits(Long orderId);
+}

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

@@ -63,6 +63,7 @@ import com.cyksj.service.mange.stock.GoodsDonStockService;
 import com.cyksj.service.market.MarketFrontService;
 import com.cyksj.service.market.task.TaskService;
 import com.cyksj.service.order.OrderDonService;
+import com.cyksj.service.order.UserRealOrderBenefitsService;
 import com.cyksj.service.template.TemplateCommonService;
 import com.cyksj.service.wechat.WeChatService;
 import com.cyksj.task.JobManager;
@@ -176,6 +177,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final EquipmentDistributeService equipmentDistributeService;
 
+	private final UserRealOrderBenefitsService userRealOrderBenefitsService;
+
 	private final CouponDistributePopularizeMapper couponDistributePopularizeMapper;
 
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
@@ -503,6 +506,17 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 				marketFrontService.addSpecificChanceNum(order.getUserId(), order.getId(), order.getGoodsId(), order.getSkuId());
 				if (goodsDon.getType() == 2) {
 					equipmentDistributeService.addDistributeBenefitsChance(order.getUserId(), order.getId());
+					if (sku.getIsBenefits()) {
+						if (StrUtil.isNotEmpty(sku.getBenefitsList())) {
+							try {
+								List<Long> skuIds = Jsons.parseList(sku.getBenefitsList(), Long.class);
+								//自购实物 获取权益
+								userRealOrderBenefitsService.receivePayRealGoodsBenefits(order.getUserId(), order.getId(), goodsDon.getId(), skuIds);
+							} catch (Exception e) {
+
+							}
+						}
+					}
 				}
 				//若该订单使用了规定推广者的兑换码 增加上下级关系
 				if (StrUtil.isNotBlank(order.getCouponExCode())) {
@@ -781,6 +795,17 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 				marketFrontService.addSpecificChanceNum(orderDon.getUserId(), orderDon.getId(), orderDon.getGoodsId(), orderDon.getSkuId());
 				if (goodsDon.getType() == 2) {
 					equipmentDistributeService.addDistributeBenefitsChance(orderDon.getUserId(), orderDon.getId());
+					if (sku.getIsBenefits()) {
+						if (StrUtil.isNotEmpty(sku.getBenefitsList())) {
+							try {
+								List<Long> skuIds = Jsons.parseList(sku.getBenefitsList(), Long.class);
+								//自购实物 获取权益
+								userRealOrderBenefitsService.receivePayRealGoodsBenefits(orderDon.getUserId(), orderDon.getId(), goodsDon.getId(), skuIds);
+							} catch (Exception e) {
+
+							}
+						}
+					}
 				}
 				//若该订单使用了规定推广者的兑换码 增加上下级关系
 				if (StrUtil.isNotBlank(orderDon.getCouponExCode())) {
@@ -920,6 +945,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 					marketFrontService.subSpecificChanceNum(orderDon.getUserId(), orderDon.getId(), orderDon.getGoodsId(), orderDon.getUpdateTime());
 					if (goodsDon.getType() == 2) {
 						equipmentDistributeService.subDistributeBenefitsChance(orderDon.getUserId(), orderDon.getId());
+						//扣除用户自身实物权益
+						userRealOrderBenefitsService.deductUserRealGoodsBenefits(orderDon.getId());
 					}
 				} catch (Exception e) {
 					log.error("zfb减少抽奖机会错误,orderId:{},error:{}", orderDon.getId(), e);

+ 174 - 0
netflix-service/src/main/java/com/cyksj/service/order/impl/UserRealOrderBenefitsImpl.java

@@ -0,0 +1,174 @@
+package com.cyksj.service.order.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.mapper.GroupsRelationMapper;
+import com.cyksj.mapper.OrderDonMapper;
+import com.cyksj.mapper.channel.UserPayEquipmentAvailableBenefitsMapper;
+import com.cyksj.mapper.channel.UserPayEquipmentReceiveBenefitsRecordMapper;
+import com.cyksj.model.entity.*;
+import com.cyksj.model.manage.views.GroupsRelationView;
+import com.cyksj.service.exchange.ExchangeCodeService;
+import com.cyksj.service.order.UserRealOrderBenefitsService;
+import com.cyksj.service.relation.GroupRelationClearService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+/*
+ *项目名: netflix
+ *文件名: UserRealOrderBenefitsImpl
+ *创建者: JavaZou
+ *创建时间:2023/3/7 14:54
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class UserRealOrderBenefitsImpl implements UserRealOrderBenefitsService {
+	private final GroupsRelationMapper groupsRelationMapper;
+
+	private final BeanSearcher beanSearcher;
+
+	private final ExchangeCodeService exchangeCodeService;
+
+	private final GoodsDonSkuMapper goodsDonSkuMapper;
+
+	private final UserPayEquipmentReceiveBenefitsRecordMapper receiveBenefitsRecordMapper;
+
+	private final UserPayEquipmentAvailableBenefitsMapper availableBenefitsMapper;
+
+	private final GroupRelationClearService groupRelationClearService;
+
+	private final OrderDonMapper orderDonMapper;
+
+	@Override
+	public void receivePayRealGoodsBenefits(Long userId, Long orderId, Long goodsId, List<Long> skuIds) {
+		skuIds.forEach(skuId->{
+			GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(skuId);
+			if (goodsDonSku != null) {
+				List<GroupsRelationView> relationViewList = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
+						.field(GroupsRelationView::getGoodsId, goodsId)
+						.field(GroupsRelationView::getSkuId, skuId)
+						.field(GroupsRelationView::getUserId, userId)
+						.field(GroupsRelationView::getStatus, GroupsRelation.Status.validity.name())
+						.build());
+				//是否有该规格车票,若无直接发放车票
+				if (CollUtil.isEmpty(relationViewList)) {
+					//领取权益时,没有车票的用户自动上车,获得对应车票
+					GroupsRelation relation = exchangeCodeService.getGroupTripsTicket(goodsDonSku, userId, null, OrderDon.Type.PAY_EQUIPMENT);
+					saveReceiveBenefitsRecord(userId, skuId, orderId, relation.getOrderId(), relation.getId(), goodsDonSku.getMonths(), 1);
+				} else if (relationViewList.size() == 1) {
+					//若有且只有一张增加时长
+					GroupsRelationView groupsRelationView = relationViewList.get(0);
+					Date expiryTime = groupsRelationView.getExpiryTime();
+					if (expiryTime == null) {
+						throw BusinessRuntimeException.getInstance("该车位暂未发车,请发车后再领取权益");
+					}
+					DateTime updateExpiryTime = DateUtil.offset(expiryTime, DateField.MONTH, goodsDonSku.getMonths());
+					groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+							.eq(GroupsRelation::getId, groupsRelationView.getId())
+							.eq(GroupsRelation::getUserId, userId)
+							.set(GroupsRelation::getExpiryTime, updateExpiryTime));
+					groupsRelationView.setUpdateExpiryTime(updateExpiryTime);
+					saveReceiveBenefitsRecord(userId, skuId, orderId, null, groupsRelationView.getId(), goodsDonSku.getMonths(), 1);
+				}else {
+					//若有该规格多张车票,保存可获取的车票权益 以供用户自行选择
+					saveAvailableBenefits(userId, skuId, orderId);
+				}
+			}
+		});
+	}
+
+	@Override
+	public void deductUserRealGoodsBenefits(Long orderId) {
+		//是否存在该实物订单权益
+		List<UserPayEquipmentReceiveBenefitsRecord> benefitsRecords = Optional.ofNullable(receiveBenefitsRecordMapper.selectList(Wrappers.lambdaQuery(UserPayEquipmentReceiveBenefitsRecord.class)
+				.eq(UserPayEquipmentReceiveBenefitsRecord::getRealOrderId, orderId))).orElse(new ArrayList<>());
+		benefitsRecords.forEach(benefitsRecord -> {
+			//扣除领取的权益
+			Long benefitsRecordId = benefitsRecord.getId();
+			deductReceivedBenefits(benefitsRecord.getUserId(), benefitsRecord.getTicketOrderId(), benefitsRecord.getRelationId(), benefitsRecord.getMonths());
+			benefitsRecord.setStatusCode(0);
+			receiveBenefitsRecordMapper.updateById(benefitsRecord);
+		});
+		//是否存在可领取的实物订单权益
+		//删除其权益
+		availableBenefitsMapper.update(null, Wrappers.lambdaUpdate(UserPayEquipmentAvailableBenefits.class)
+				.set(UserPayEquipmentAvailableBenefits::getDeleted, false)
+				.eq(UserPayEquipmentAvailableBenefits::getRealOrderId, orderId));
+	}
+
+	/**
+	 * 保存获取权益记录
+	 */
+	private void saveReceiveBenefitsRecord(Long userId, Long skuId, Long realOrderId, Long ticketOrderId, Long relationId, Integer months, Integer statusCode) {
+		UserPayEquipmentReceiveBenefitsRecord userPayEquipmentReceiveBenefitsRecord = new UserPayEquipmentReceiveBenefitsRecord()
+				.setUserId(userId)
+				.setSkuId(skuId)
+				.setRealOrderId(realOrderId)
+				.setTicketOrderId(ticketOrderId)
+				.setRelationId(relationId)
+				.setMonths(months)
+				.setStatusCode(statusCode);
+		receiveBenefitsRecordMapper.insert(userPayEquipmentReceiveBenefitsRecord);
+	}
+
+	/**
+	 * 保存用户可获取权益的车票
+	 */
+	public void saveAvailableBenefits(Long userId, Long skuId, Long realOrderId) {
+		UserPayEquipmentAvailableBenefits userPayEquipmentAvailableBenefits = new UserPayEquipmentAvailableBenefits()
+				.setUserId(userId)
+				.setSkuId(skuId)
+				.setRealOrderId(realOrderId);
+		availableBenefitsMapper.insert(userPayEquipmentAvailableBenefits);
+	}
+
+
+	/**
+	 * 扣除用户领取的权益
+	 */
+	private void deductReceivedBenefits(Long userId, Long ticketOrderId, Long relationId, Integer months) {
+		GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+				.eq(GroupsRelation::getUserId, userId)
+				.eq(GroupsRelation::getId, relationId)
+				.eq(GroupsRelation::getStatus, GroupsRelation.Status.validity)
+				.last("limit 1"));
+		Date expiryTime = relation.getExpiryTime();
+		if (relation == null) {
+			return;
+		}
+		if (expiryTime == null) {
+			//未发车直接清除车票
+			groupRelationClearService.clearTicket(relation);
+		} else {
+			DateTime now = DateTime.now();
+			Date finalDate = DateUtil.offset(expiryTime, DateField.MONTH, -months);
+			if (now.isAfter(finalDate)) {
+				//过期 直接清除车票
+				groupRelationClearService.clearTicket(relation);
+			} else {
+				relation.setExpiryTime(finalDate);
+				groupsRelationMapper.updateById(relation);
+			}
+		}
+		Optional.ofNullable(ticketOrderId).ifPresent(selfOrderId -> {
+			orderDonMapper.update(null, Wrappers.lambdaUpdate(OrderDon.class).eq(OrderDon::getId, selfOrderId)
+					.set(OrderDon::getRefundMoney, BigDecimal.ZERO)
+					.set(OrderDon::getStatus, OrderDon.Status.refund));
+		});
+	}
+}

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

@@ -53,7 +53,7 @@ public class EquipmentController {
 	@GetMapping("/get")
 	public Result<SearchResult<EquipmentUserDistributeViews>> getEquipmentDistribute() {
 		SearchResult<EquipmentUserDistributeViews> search = beanSearcher.search(EquipmentUserDistributeViews.class, MapUtils.flatBuilder(request.getParameterMap()).build());
-		search.getDataList().forEach(data->{
+		search.getDataList().forEach(data -> {
 			User user = userMapper.selectById(data.getShareId());
 			Optional.ofNullable(user).ifPresent(u -> data.setNickname(u.getNickname()));
 			data.setRecordNum(equipmentUserChanceRecordMapper.selectCount(Wrappers.lambdaQuery(EquipmentUserChanceRecord.class)

+ 2 - 3
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -83,9 +83,8 @@ public class StatisticsDataController {
 	 * 查询统计数据
 	 */
 	@GetMapping
-	public Result<BackgroundDataView> getStatisticsByCondition(Long startTime, Long endTime) {
-
-		return statisticsDataService.getStatisticsByCondition(startTime, endTime);
+	public Result<BackgroundDataView> getStatisticsByCondition(@RequestParam(defaultValue = "1") Integer type, Long startTime, Long endTime) {
+		return statisticsDataService.getStatisticsByCondition(type, startTime, endTime);
 	}
 
 	/**