Ver Fonte

add 客服账号续费业绩统计

zoujiajian há 3 anos atrás
pai
commit
a1e5bca4e4
21 ficheiros alterados com 415 adições e 35 exclusões
  1. 2 2
      netflix-dao/src/main/java/com/cyksj/mapper/AccountMapper.java
  2. 21 0
      netflix-dao/src/main/java/com/cyksj/mapper/CustomerServiceRenewOrderRecordMapper.java
  3. 4 0
      netflix-dao/src/main/java/com/cyksj/mapper/GroupsRelationMapper.java
  4. 23 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CustomerServiceRenewOrderRecord.java
  5. 5 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GroupsRelation.java
  6. 6 0
      netflix-dao/src/main/java/com/cyksj/model/excel/ExcelAccountData.java
  7. 18 0
      netflix-dao/src/main/java/com/cyksj/model/request/BatchServiceReq.java
  8. 2 0
      netflix-dao/src/main/java/com/cyksj/model/views/CustomerServiceHandleOrderToMonthView.java
  9. 33 0
      netflix-dao/src/main/java/com/cyksj/model/views/CustomerServiceOrdersDetailView.java
  10. 10 0
      netflix-dao/src/main/java/com/cyksj/model/views/ExpiredAccountDataView.java
  11. 59 0
      netflix-dao/src/main/java/com/cyksj/model/views/ServiceOrdersDetailView.java
  12. 52 0
      netflix-dao/src/main/java/com/cyksj/model/views/ServiceRenewOrdersDetailView.java
  13. 34 4
      netflix-dao/src/main/resources/mapper/AccountMapper.xml
  14. 2 1
      netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml
  15. 2 2
      netflix-service/src/main/java/com/cyksj/service/mange/CmsAccountService.java
  16. 4 4
      netflix-service/src/main/java/com/cyksj/service/mange/account/CmsAccountServiceImpl.java
  17. 2 2
      netflix-service/src/main/java/com/cyksj/service/mange/statistics/StatisticsDataService.java
  18. 4 4
      netflix-service/src/main/java/com/cyksj/service/mange/statistics/impl/StatisticsDataServiceImpl.java
  19. 24 0
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  20. 21 0
      netflix-service/src/main/java/com/cyksj/task/OrderCustomerHandleScheduler.java
  21. 87 16
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

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

@@ -18,11 +18,11 @@ import java.util.List;
  */
 public interface AccountMapper extends BaseMapper<Account> {
 
-	IPage<ExpiredAccountDataView> getExpiredAccountView(@Param("goodsId") Integer goodsId, @Param("account") String account, @Param("renewStatus") Boolean renewStatus, @Param("handleStatus") Boolean handleStatus, @Param("cnAccount") String cnAccount, @Param("usAccount") String usAccount, @Param("userId") Integer userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("now") String now, @Param("page") Page page);
+	IPage<ExpiredAccountDataView> getExpiredAccountView(@Param("isCorpWx") Boolean isCorpWx, @Param("customerService") String customerService, @Param("goodsId") Integer goodsId, @Param("account") String account, @Param("renewStatus") Boolean renewStatus, @Param("handleStatus") Boolean handleStatus, @Param("cnAccount") String cnAccount, @Param("usAccount") String usAccount, @Param("userId") Integer userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("now") String now, @Param("page") Page page);
 
 	List<Account> getNoAppleOneAccount(String appleOne);
 
 	List<OrderDon> getNoAppleOneOrderDon(@Param("skuIds") List<Long> skuIds, @Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate, @Param("noOrderStatus") List<String> noOrderStatus);
 
-	List<ExcelAccountData> getExpiredAccountViewNoPage(@Param("goodsId") Integer goodsId, @Param("account") String account, @Param("renewStatus") Boolean renewStatus, @Param("handleStatus") Boolean handleStatus, @Param("cnAccount") String cnAccount, @Param("usAccount") String usAccount, @Param("userId") Integer userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("now") String now);
+	List<ExcelAccountData> getExpiredAccountViewNoPage(@Param("isCorpWx") Boolean isCorpWx, @Param("customerService") String customerService, @Param("goodsId") Integer goodsId, @Param("account") String account, @Param("renewStatus") Boolean renewStatus, @Param("handleStatus") Boolean handleStatus, @Param("cnAccount") String cnAccount, @Param("usAccount") String usAccount, @Param("userId") Integer userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("now") String now);
 }

+ 21 - 0
netflix-dao/src/main/java/com/cyksj/mapper/CustomerServiceRenewOrderRecordMapper.java

@@ -0,0 +1,21 @@
+package com.cyksj.mapper;
+
+import cn.hutool.core.date.DateTime;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.CustomerServiceRenewOrderRecord;
+import com.cyksj.model.views.CustomerServiceHandleOrderToMonthView;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: CustomerServiceRenewOrderRecordMapper
+ *创建者: JavaZou
+ *创建时间:2022/12/30 14:33
+ */
+public interface CustomerServiceRenewOrderRecordMapper extends BaseMapper<CustomerServiceRenewOrderRecord> {
+	@Select("select count(*) as numOfOrder,customer_service as renewServiceName from customer_service_renew_order_record where created_time between #{begin} and #{now} group by customer_service order by customer_service")
+	List<CustomerServiceHandleOrderToMonthView> selectCustomerToMonthData(@Param("now") DateTime now, @Param("begin") DateTime begin, @Param("type") Integer type);
+}

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

@@ -3,6 +3,7 @@ package com.cyksj.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.GroupsRelation;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
 
 import java.util.Date;
 import java.util.List;
@@ -18,4 +19,7 @@ public interface GroupsRelationMapper extends BaseMapper<GroupsRelation> {
     Integer updateExpiryTime(@Param("entity") GroupsRelation relation, @Param("expireTime") Date expireTime);
 
 	Long getGroupTripsSkuIdByRelationId(Long relationId);
+
+	@Update("update groups_relation set customer_service = null where id = #{id}")
+	void updateCustomerService(Long id);
 }

+ 23 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CustomerServiceRenewOrderRecord.java

@@ -0,0 +1,23 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: CustomerServiceRenewOrderRecord
+ *创建者: JavaZou
+ *创建时间:2022/12/30 14:32
+ */
+@Getter
+@Setter
+public class CustomerServiceRenewOrderRecord extends BaseEntity{
+	private Long userId;
+
+	private Long orderId;
+
+	/**
+	 * 客服
+	 */
+	private String customerService;
+}

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

@@ -46,6 +46,11 @@ public class GroupsRelation extends BaseEntity {
      */
     private Boolean isHandle;
 
+    /**
+     * 客服
+     */
+    private String customerService;
+
 
     @AllArgsConstructor
     @Getter

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/model/excel/ExcelAccountData.java

@@ -81,4 +81,10 @@ public class ExcelAccountData {
 	 */
 	@ExcelProperty("是否处理过")
 	private Boolean isHandle;
+
+	@ExcelProperty("企业微信")
+	private String isCorpWx;
+
+	@ExcelProperty("客服")
+	private String customerService;
 }

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/request/BatchServiceReq.java

@@ -0,0 +1,18 @@
+package com.cyksj.model.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: BatchServiceReq
+ *创建者: JavaZou
+ *创建时间:2022/12/30 14:43
+ */
+@Getter
+@Setter
+public class BatchServiceReq {
+	private Long relationId;
+
+	private String customerService;
+}

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

@@ -18,6 +18,8 @@ public class CustomerServiceHandleOrderToMonthView {
 
 	private String afterServiceName;
 
+	private String renewServiceName;
+
 	/**
 	 * 订单数量
 	 */

+ 33 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CustomerServiceOrdersDetailView.java

@@ -0,0 +1,33 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.SearchResult;
+import lombok.Getter;
+import lombok.Setter;
+
+
+/*
+ *项目名: netflix
+ *文件名: CustomerServiceOrdersDetailView
+ *创建者: JavaZou
+ *创建时间:2022/12/30 15:05
+ */
+@Getter
+@Setter
+public class CustomerServiceOrdersDetailView {
+	/**
+	 * 总数量
+	 */
+	private Integer orders;
+
+	/**
+	 * Chromecast订单数量
+	 */
+	private Integer AppleTV;
+
+	/**
+	 * Chromecast订单数量
+	 */
+	private Integer Chromecast;
+
+	private SearchResult result;
+}

+ 10 - 0
netflix-dao/src/main/java/com/cyksj/model/views/ExpiredAccountDataView.java

@@ -98,4 +98,14 @@ public class ExpiredAccountDataView {
 	 * 处理状态
 	 */
 	private Boolean status;
+
+	/**
+	 * 是否加入了企业微信 true是
+	 */
+	private Boolean isCorpWx;
+
+	/**
+	 * 客服
+	 */
+	private String customerService;
 }

+ 59 - 0
netflix-dao/src/main/java/com/cyksj/model/views/ServiceOrdersDetailView.java

@@ -0,0 +1,59 @@
+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.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: ServiceOrdersDetail
+ *创建者: JavaZou
+ *创建时间:2022/12/30 15:07
+ */
+@Getter
+@Setter
+@SearchBean(tables = "real_goods_order_handle rh left join order_don od on od.id = rh.order_id" +
+		" left join goods_don_sku gdk on gdk.id = od.sku_id" +
+		" left join goods_don gd on gd.id = gdk.goods_id" +
+		" left join user u on u.id = od.user_id")
+public class ServiceOrdersDetailView {
+	@DbField("gd.id")
+	private Long goodsId;
+
+	@DbField("gd.title")
+	private String goodsName;
+
+	@DbField("gdk.id")
+	private Long skuId;
+
+	@DbField("gdk.spec_val")
+	private String specVal;
+
+	@DbField("od.money")
+	private Long money;
+
+	@DbField("u.nickname")
+	private String nickname;
+
+	@DbField("u.id")
+	private Long userId;
+
+	@DbField("od.status")
+	private OrderDon.Status status;
+
+	@DbField("od.created_time")
+	private Date createdTime;
+
+	@DbField("rh.before_service_name")
+	private String beforeServiceName;
+
+	@DbField("rh.after_service_name")
+	private String afterServiceName;
+
+	@DbField("rh.created_time")
+	private Date recordCreatedTime;
+}

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

@@ -0,0 +1,52 @@
+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.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: ServiceRenewOrdersDetailView
+ *创建者: JavaZou
+ *创建时间:2022/12/30 15:18
+ */
+@Getter
+@Setter
+@SearchBean(tables = "customer_service_renew_order_record cr left join order_don od on od.id = cr.order_id" +
+		" left join goods_don_sku gdk on gdk.id = od.sku_id" +
+		" left join goods_don gd on gd.id = gdk.goods_id" +
+		" left join user u on u.id = od.user_id")
+public class ServiceRenewOrdersDetailView {
+	@DbField("gd.id")
+	private Long goodsId;
+
+	@DbField("gd.title")
+	private String goodsName;
+
+	@DbField("gdk.id")
+	private Long skuId;
+
+	@DbField("gdk.spec_val")
+	private String specVal;
+
+	@DbField("od.money")
+	private Long money;
+
+	@DbField("u.nickname")
+	private String nickname;
+
+	@DbField("u.id")
+	private Long userId;
+
+	@DbField("od.created_time")
+	private Date createdTime;
+
+	@DbField("cr.customer_service")
+	private String customerService;
+
+	@DbField("cr.created_time")
+	private Date recordCreatedTime;
+}

+ 34 - 4
netflix-dao/src/main/resources/mapper/AccountMapper.xml

@@ -17,15 +17,30 @@
                gr.start_time as payTime,
                gr.expiry_time,
                gr.renew_status,
-               gr.is_handle
+               gr.is_handle,
+               gr.customer_service,
+               if(cu.id is null,false,true) as isCorpWx
         from `account` a left join `groups_trips` gt on gt.account_id = a.id
         left join `groups_relation` gr on gr.groups_id = gt.id
         left join `goods_don_sku` gdk on gdk.id = gt.sku_id
         left join `goods_don` gd on gd.id = a.goods_id
         left join `user` u on gr.user_id = u.id
+        left join (select id,unionid from `corp_user` where unionid != '') cu on cu.unionid = u.unionid
         <where>
+            <if test="isCorpWx != null and isCorpWx">
+                cu.id is not null
+            </if>
+            <if test="isCorpWx != null and !isCorpWx">
+                cu.id is null
+            </if>
+            <if test="customerService != null and customerService != '' and customerService != 'waiting'">
+                and gr.customer_service = #{customerService}
+            </if>
+            <if test="customerService == 'waiting'">
+                and gr.customer_service is null
+            </if>
             <if test="goodsId != null">
-                a.goods_id = #{goodsId}
+                and a.goods_id = #{goodsId}
             </if>
             <if test="account != null and account != ''">
                 and a.account like '%${account}%'
@@ -92,15 +107,30 @@
         gr.start_time as payTime,
         gr.expiry_time,
         gr.renew_status,
-        gr.is_handle
+        gr.is_handle,
+        gr.customer_service,
+        if(cu.id is null,'未加入','已加入') as isCorpWx
         from `account` a left join `groups_trips` gt on gt.account_id = a.id
         left join `groups_relation` gr on gr.groups_id = gt.id
         left join `goods_don_sku` gdk on gdk.id = gt.sku_id
         left join `goods_don` gd on gd.id = a.goods_id
         left join `user` u on gr.user_id = u.id
+        left join (select id,unionid from `corp_user` where unionid != '') cu on cu.unionid = u.unionid
         <where>
+            <if test="isCorpWx != null and isCorpWx">
+                cu.id is not null
+            </if>
+            <if test="isCorpWx != null and !isCorpWx">
+                cu.id is null
+            </if>
+            <if test="customerService != null and customerService != '' and customerService != 'waiting'">
+                and gr.customer_service = #{customerService}
+            </if>
+            <if test="customerService == 'waiting'">
+                and gr.customer_service is null
+            </if>
             <if test="goodsId != null">
-                a.goods_id = #{goodsId}
+                and a.goods_id = #{goodsId}
             </if>
             <if test="account != null and account != ''">
                 and a.account like '%${account}%'

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

@@ -10,7 +10,8 @@
             renew_status = #{entity.renewStatus},
             is_handle    = #{entity.isHandle},
             user_id      = #{entity.userId},
-            account = #{entity.account}
+            account = #{entity.account},
+            customer_service = null
         where id = #{entity.id} and expiry_time = #{expireTime}
     </update>
 

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

@@ -15,13 +15,13 @@ import java.util.List;
  * @date 2022/9/27 6:23 PM
  */
 public interface CmsAccountService extends IService<Account> {
-	IPage<ExpiredAccountDataView> getExpiredAccountView(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, String startTime, String endTime, String now, Long offset, Long limit);
+	IPage<ExpiredAccountDataView> getExpiredAccountView(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, String startTime, String endTime, String now, Long offset, Long limit);
 
 	List<Account> getNoAppleOneAccount(String appleOne);
 
 	List<OrderDon> getNoAppleOneOrderDon(List<Long> skuIds, Date yesZeroDate, Date thisZeroDate, List<String> noOrderStatus);
 
-	List<ExcelAccountData> getExpiredAccountViewNoPage(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, String startDate, String endDate, String toString);
+	List<ExcelAccountData> getExpiredAccountViewNoPage(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, String startDate, String endDate, String toString);
 
 	void sendAccountTemplateMsg(Account account) throws Exception;
 }

+ 4 - 4
netflix-service/src/main/java/com/cyksj/service/mange/account/CmsAccountServiceImpl.java

@@ -48,13 +48,13 @@ public class CmsAccountServiceImpl extends ServiceImpl<AccountMapper, Account> i
 	private final UserMapper userMapper;
 
 	@Override
-	public IPage<ExpiredAccountDataView> getExpiredAccountView(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, String startTime, String endTime, String now, Long offset, Long limit) {
-		return accountMapper.getExpiredAccountView(goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startTime, endTime, now, new Page<>(offset, limit));
+	public IPage<ExpiredAccountDataView> getExpiredAccountView(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, String startTime, String endTime, String now, Long offset, Long limit) {
+		return accountMapper.getExpiredAccountView(isCorpWx, customerService, goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startTime, endTime, now, new Page<>(offset, limit));
 	}
 
 	@Override
-	public List<ExcelAccountData> getExpiredAccountViewNoPage(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, String startTime, String endTime, String now) {
-		return accountMapper.getExpiredAccountViewNoPage(goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startTime, endTime, now);
+	public List<ExcelAccountData> getExpiredAccountViewNoPage(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, String startTime, String endTime, String now) {
+		return accountMapper.getExpiredAccountViewNoPage(isCorpWx, customerService, goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startTime, endTime, now);
 	}
 
 	@Override

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

@@ -17,11 +17,11 @@ import java.util.List;
 public interface StatisticsDataService {
 	Result<BackgroundDataView> getStatisticsByCondition(Long startTime, Long endTime);
 
-	IPage<ExpiredAccountDataView> getExpiredAccountView(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer uid, Long startTime, Long endTime, Long start, Long limit);
+	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);
 
 	Result<String> updateRenewStatus(Integer relationId);
 
 	Result<String> updateHandleStatus(Integer relationId);
 
-	List<ExcelAccountData> getExpiredAccountViewNoPage(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime);
+	List<ExcelAccountData> getExpiredAccountViewNoPage(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime);
 }

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

@@ -113,7 +113,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 	}
 
 	@Override
-	public IPage<ExpiredAccountDataView> getExpiredAccountView(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime, Long start, Long limit) {
+	public IPage<ExpiredAccountDataView> getExpiredAccountView(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime, Long start, Long limit) {
 		String startDate = null;
 		String endDate = null;
 		if (startTime != null) {
@@ -122,12 +122,12 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 		if (endTime != null) {
 			endDate = DateTime.of(endTime).toString();
 		}
-		IPage<ExpiredAccountDataView> expiredAccountDataViews = accountService.getExpiredAccountView(goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startDate, endDate, DateTime.now().toString(), start, limit);
+		IPage<ExpiredAccountDataView> expiredAccountDataViews = accountService.getExpiredAccountView(isCorpWx, customerService, goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startDate, endDate, DateTime.now().toString(), start, limit);
 		return expiredAccountDataViews;
 	}
 
 	@Override
-	public List<ExcelAccountData> getExpiredAccountViewNoPage(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime) {
+	public List<ExcelAccountData> getExpiredAccountViewNoPage(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime) {
 		String startDate = null;
 		String endDate = null;
 		if (startTime != null) {
@@ -136,7 +136,7 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 		if (endTime != null) {
 			endDate = DateTime.of(endTime).toString();
 		}
-		List<ExcelAccountData> expiredAccountDataViews = accountService.getExpiredAccountViewNoPage(goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startDate, endDate, DateTime.now().toString());
+		List<ExcelAccountData> expiredAccountDataViews = accountService.getExpiredAccountViewNoPage(isCorpWx, customerService, goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startDate, endDate, DateTime.now().toString());
 		return expiredAccountDataViews;
 	}
 

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

@@ -149,6 +149,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final GoodsDonStockService goodsDonStockService;
 
+	private final CustomerServiceRenewOrderRecordMapper customerServiceRenewOrderRecordMapper;
+
 	@Transactional(rollbackFor = Throwable.class)
 	@Override
 	public OrderDon submit(OrderPayRequest payRequest) throws Exception {
@@ -423,6 +425,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			//无车队,新增车队
 			checkNoGroupsTripsAndSendMsg(sku, order);
 		}
+		//客服续费订单
+		handleServiceRenewOrder(order);
 	}
 
     @Override
@@ -709,6 +713,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			//无车队,新增车队
 			checkNoGroupsTripsAndSendMsg(sku, orderDon);
 		}
+		//客服续费订单
+		handleServiceRenewOrder(orderDon);
 	}
 
 	@Override
@@ -1384,4 +1390,22 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		}
 		return relation;
 	}
+
+	public void handleServiceRenewOrder(OrderDon orderDon) {
+		//续费订单
+		if (orderDon.getOrderType() == 2) {
+			Long relationId = orderDon.getRelationId();
+			GroupsRelation relation = groupsRelationMapper.selectById(relationId);
+			if (StrUtil.isNotBlank(relation.getCustomerService())) {
+				//记录客服续费订单业绩
+				CustomerServiceRenewOrderRecord renewOrderRecord = new CustomerServiceRenewOrderRecord();
+				renewOrderRecord.setUserId(orderDon.getUserId());
+				renewOrderRecord.setOrderId(orderDon.getId());
+				renewOrderRecord.setCustomerService(relation.getCustomerService());
+				customerServiceRenewOrderRecordMapper.insert(renewOrderRecord);
+
+				groupsRelationMapper.updateCustomerService(relation.getId());
+			}
+		}
+	}
 }

+ 21 - 0
netflix-service/src/main/java/com/cyksj/task/OrderCustomerHandleScheduler.java

@@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
 import com.cyksj.mapper.manage.CustomerServiceEveryMonthDetailMapper;
 import com.cyksj.mapper.manage.StatisticsCustomerServiceEveryMonthMapper;
 import com.cyksj.model.entity.CustomerServiceEveryMonthDetail;
+import com.cyksj.model.entity.CustomerServiceRenewOrderRecord;
 import com.cyksj.model.entity.RealGoodsOrderHandle;
 import com.cyksj.model.entity.StatisticsCustomerServiceEveryMonth;
 import com.ejlchina.searcher.BeanSearcher;
@@ -63,6 +64,14 @@ public class OrderCustomerHandleScheduler {
 		after.forEach((k, v) -> {
 			customerServiceRecord(k, v, 2, statistics.getId());
 		});
+		//续费业绩
+		List<CustomerServiceRenewOrderRecord> customerServiceRecords = beanSearcher.searchAll(CustomerServiceRenewOrderRecord.class, MapUtils.builder()
+				.field(RealGoodsOrderHandle::getCreatedTime, begin, now).op(Operator.Between)
+				.build());
+		Map<String, List<CustomerServiceRenewOrderRecord>> renews = customerServiceRecords.stream().collect(Collectors.groupingBy(CustomerServiceRenewOrderRecord::getCustomerService));
+		renews.forEach((k,v)->{
+			renewServiceOrderRecord(k, v, 3, statistics.getId());
+		});
 	}
 
 
@@ -78,4 +87,16 @@ public class OrderCustomerHandleScheduler {
 			detailMapper.insert(record);
 		}
 	}
+
+	public void renewServiceOrderRecord(String serviceName, List<CustomerServiceRenewOrderRecord> renewOrderRecords, Integer type, Long statisticsId) {
+		if (StrUtil.isNotBlank(serviceName)) {
+			CustomerServiceEveryMonthDetail record = new CustomerServiceEveryMonthDetail();
+			record.setType(type);
+			record.setCustomerServiceName(serviceName);
+			record.setStatisticsId(statisticsId);
+			record.setNumOfOrder(renewOrderRecords.size());
+			record.setMoney(BigDecimal.ZERO);
+			detailMapper.insert(record);
+		}
+	}
 }

+ 87 - 16
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -2,44 +2,47 @@ package com.cyksj.web.controller.manage.statistics;
 
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.excel.support.ExcelTypeEnum;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.mapper.stock.GoodsDonStockRecordMapper;
-import com.cyksj.model.entity.*;
-import com.cyksj.model.excel.ExcelAccountData;
-import com.cyksj.model.views.BackgroundDataView;
-import com.cyksj.model.views.ExpiredAccountDataView;
+import com.cyksj.mapper.CustomerServiceRenewOrderRecordMapper;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.mapper.manage.CustomerServiceEveryMonthDetailMapper;
 import com.cyksj.mapper.manage.RealGoodsOrderHandleMapper;
 import com.cyksj.mapper.manage.statistics.IncrExpiryTimeRecordMapper;
 import com.cyksj.mapper.manage.statistics.StatisticsUserDataMapper;
+import com.cyksj.mapper.stock.GoodsDonStockRecordMapper;
+import com.cyksj.model.entity.*;
+import com.cyksj.model.excel.ExcelAccountData;
+import com.cyksj.model.request.BatchServiceReq;
 import com.cyksj.model.request.RenewTimeUpReq;
 import com.cyksj.model.views.*;
 import com.cyksj.service.mange.statistics.StatisticsDataService;
-import com.cyksj.web.util.EasyExcelUtils;
 import com.cyksj.task.OrderCustomerHandleScheduler;
+import com.cyksj.web.util.EasyExcelUtils;
 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 org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.*;
-
-import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 /*
@@ -72,6 +75,8 @@ public class StatisticsDataController {
 
 	private final GoodsDonStockRecordMapper stockRecordMapper;
 
+	private final CustomerServiceRenewOrderRecordMapper customerServiceRenewOrderRecordMapper;
+
 	/**
 	 * 查询统计数据
 	 */
@@ -85,16 +90,16 @@ public class StatisticsDataController {
 	 * 有效子账号数列表
 	 */
 	@GetMapping("/expired/account")
-	public Result<IPage<ExpiredAccountDataView>> getExpiredAccountView(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime, @RequestParam(required = false, defaultValue = "1") Long start, @RequestParam(required = false, defaultValue = "10") Long limit) {
-		return GatewayResponse.SUCCESS.newBuilder().toResult(statisticsDataService.getExpiredAccountView(goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startTime, endTime, start, limit));
+	public Result<IPage<ExpiredAccountDataView>> getExpiredAccountView(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime, @RequestParam(required = false, defaultValue = "1") Long start, @RequestParam(required = false, defaultValue = "10") Long limit) {
+		return GatewayResponse.SUCCESS.newBuilder().toResult(statisticsDataService.getExpiredAccountView(isCorpWx, customerService, goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startTime, endTime, start, limit));
 	}
 
 	/**
 	 * 导出有效子账号数
 	 */
 	@GetMapping("/export/account")
-	public void exportAccount(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime, HttpServletResponse response) {
-		List<ExcelAccountData> expiredAccountView = statisticsDataService.getExpiredAccountViewNoPage(goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startTime, endTime);
+	public void exportAccount(Boolean isCorpWx, String customerService, Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime, HttpServletResponse response) {
+		List<ExcelAccountData> expiredAccountView = statisticsDataService.getExpiredAccountViewNoPage(isCorpWx, customerService, goodsId, account, renewStatus, handleStatus, cnAccount, usAccount, userId, startTime, endTime);
 		EasyExcelUtils.createExcelStreamMutilByEasyExcel(response, ExcelAccountData.class, expiredAccountView, "有效子账号", "有效子账号", ExcelTypeEnum.XLSX, null);
 	}
 
@@ -194,11 +199,16 @@ public class StatisticsDataController {
 		DateTime now = DateTime.now();
 		DateTime begin = DateUtil.beginOfMonth(now);
 		String statisticsDate = DateUtil.format(now, "yyyy-MM");
-		List<CustomerServiceHandleOrderToMonthView> toMonthDetail = realGoodsOrderHandleMapper.selectCustomerToMonthData(now, begin, OrderCustomerHandleScheduler.noOrderStatus, type);
 		StatisticsCustomerDataView customerDataView = new StatisticsCustomerDataView();
+		StatisticsCustomerServiceEveryMonthView toMonth = new StatisticsCustomerServiceEveryMonthView();
+		toMonth.setStatisticsData(statisticsDate);
+		List<CustomerServiceHandleOrderToMonthView> toMonthDetail;
+		if (type == 3) {
+			toMonthDetail = customerServiceRenewOrderRecordMapper.selectCustomerToMonthData(now, begin, type);
+		} else {
+			toMonthDetail = realGoodsOrderHandleMapper.selectCustomerToMonthData(now, begin, OrderCustomerHandleScheduler.noOrderStatus, type);
+		}
 		if (!toMonthDetail.isEmpty()) {
-			StatisticsCustomerServiceEveryMonthView toMonth = new StatisticsCustomerServiceEveryMonthView();
-			toMonth.setStatisticsData(statisticsDate);
 			toMonth.setDetails(toMonthDetail);
 			customerDataView.setToMonth(toMonth);
 		}
@@ -210,6 +220,45 @@ public class StatisticsDataController {
 		return GatewayResponse.SUCCESS.newBuilder().toResult(customerDataView);
 	}
 
+	/**
+	 * 客服业绩订单明细
+	 */
+	@GetMapping("/get/service/orders/detail")
+	public Result<CustomerServiceOrdersDetailView> getCustomerData(Integer type, String monthDate, String customerService, HttpServletRequest request) {
+		DateTime month = null;
+		if (StrUtil.isEmpty(monthDate)) {
+			month = DateTime.now();
+		} else {
+			month = DateUtil.parse(monthDate, "yyyy-MM-dd");
+		}
+		DateTime beginOfMonth = DateUtil.beginOfMonth(month);
+		DateTime endOfMonth = DateUtil.endOfMonth(month);
+		CustomerServiceOrdersDetailView view = new CustomerServiceOrdersDetailView();
+		if (type != 3) {
+			MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap())
+					.field(ServiceOrdersDetailView::getRecordCreatedTime, beginOfMonth, endOfMonth).op(Operator.Between);
+			if (type == 1) {
+				builder.field(ServiceOrdersDetailView::getBeforeServiceName, customerService).op(Operator.Equal);
+			} else if (type == 2) {
+				builder.field(ServiceOrdersDetailView::getAfterServiceName, customerService).op(Operator.Equal);
+			}
+			builder.field(ServiceOrdersDetailView::getStatus, OrderCustomerHandleScheduler.noOrderStatus).op(Operator.NotIn);
+			SearchResult<ServiceOrdersDetailView> search = beanSearcher.search(ServiceOrdersDetailView.class, builder.build());
+			Number AppleTV = beanSearcher.searchCount(ServiceOrdersDetailView.class, builder.field(ServiceOrdersDetailView::getSpecVal, "Apple TV").op(Operator.Contain).build());
+			Number Chromecast = beanSearcher.searchCount(ServiceOrdersDetailView.class, builder.field(ServiceOrdersDetailView::getSpecVal, "Chromecast").op(Operator.Contain).build());
+			view.setAppleTV(AppleTV.intValue());
+			view.setChromecast(Chromecast.intValue());
+			view.setOrders(search.getTotalCount().intValue());
+			view.setResult(search);
+		} else {
+			SearchResult<ServiceRenewOrdersDetailView> search = beanSearcher.search(ServiceRenewOrdersDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
+					.field(ServiceRenewOrdersDetailView::getCustomerService, customerService).op(Operator.Equal)
+					.field(ServiceRenewOrdersDetailView::getRecordCreatedTime, beginOfMonth, endOfMonth).op(Operator.Between).build());
+			view.setResult(search);
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult(view);
+	}
+
 	@GetMapping("/get/stock")
 	public Result<List<StatisticsStockView>> getStock(HttpServletRequest request, @RequestParam(defaultValue = "0") Long startTime,@RequestParam(defaultValue = "0") Long endTime){
 		List<GoodsDonStock> goodsDonStocks = beanSearcher.searchAll(GoodsDonStock.class, MapUtils.flatBuilder(request.getParameterMap()).build());
@@ -279,4 +328,26 @@ public class StatisticsDataController {
 		EasyExcelUtils.createExcelStreamMutilByEasyExcel(response, StatisticsStockView.class, res, "库存统计", "库存统计", ExcelTypeEnum.XLSX, null);
 
 	}
+
+	/**
+	 * 批量分配客服
+	 */
+	@PostMapping("/batch/service")
+	public Result<String> batchService(@RequestBody List<BatchServiceReq> batchServices) {
+		batchServices.forEach(service -> {
+			if (StrUtil.isEmpty(service.getCustomerService())) {
+				throw BusinessRuntimeException.getInstance("所分配客服不能为空");
+			}
+			GroupsRelation relation = groupsRelationMapper.selectById(service.getRelationId());
+			if (relation == null) {
+				return;
+			}
+			if (StrUtil.isEmpty(relation.getCustomerService()) && relation.getUserId() != 0
+					&& GroupsRelation.Status.validity == relation.getStatus()) {
+				relation.setCustomerService(service.getCustomerService());
+				groupsRelationMapper.updateById(relation);
+			}
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult("分配客服成功");
+	}
 }