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

Merge branch 'master' into dev

# Conflicts:
#	netflix-dao/src/main/java/com/cyksj/mapper/OrderDonMapper.java
#	netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpUserTagMapper.java
#	netflix-dao/src/main/java/com/cyksj/model/entity/CorpCustomerAcquisitionLinkPopularize.java
#	netflix-dao/src/main/resources/mapper/CorpUserTagMapper.xml
#	netflix-dao/src/main/resources/mapper/OrderDonMapper.xml
#	netflix-service/src/main/java/com/cyksj/redis/RedisService.java
#	netflix-service/src/main/java/com/cyksj/service/chatgpt/ChatGptAccountService.java
#	netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpEventActionServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
#	netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/WxCorpController.java
#	netflix-web/src/main/java/com/cyksj/web/controller/mirror/MirrorController.java
zoujiajian 2 жил өмнө
parent
commit
80ef32d083
57 өөрчлөгдсөн 783 нэмэгдсэн , 221 устгасан
  1. 23 0
      netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java
  2. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonCustomerServiceRelateMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonLocationRelateMapper.java
  4. 13 2
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonMapper.java
  5. 3 4
      netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpUserTagMapper.java
  6. 6 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/statistics/StatisticsExportMapper.java
  7. 1 1
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpCustomerAcquisitionLinkPopularize.java
  8. 0 2
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpFollowActiveCode.java
  9. 2 0
      netflix-dao/src/main/java/com/cyksj/model/entity/ExchangeCode.java
  10. 0 4
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDon.java
  11. 28 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDonCustomerServiceRelate.java
  12. 24 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDonLocationRelate.java
  13. 27 0
      netflix-dao/src/main/java/com/cyksj/model/excel/ExcelMonthOrderData.java
  14. 14 0
      netflix-dao/src/main/java/com/cyksj/model/manage/request/ReqGoodsSkuInsert.java
  15. 3 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/CorpMsgAuditUserView.java
  16. 12 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonBackView.java
  17. 2 0
      netflix-dao/src/main/java/com/cyksj/model/request/ExchangeCodeReq.java
  18. 1 0
      netflix-dao/src/main/java/com/cyksj/model/request/LoginReq.java
  19. 0 3
      netflix-dao/src/main/java/com/cyksj/model/views/CorpFollowActiveCodeView.java
  20. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/ExchangeCodeView.java
  21. 31 0
      netflix-dao/src/main/java/com/cyksj/model/views/OrderCustomerServiceDataView.java
  22. 7 0
      netflix-dao/src/main/java/com/cyksj/model/views/RefundOrderDonServiceDataView.java
  23. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java
  24. 9 1
      netflix-dao/src/main/java/com/cyksj/model/views/UserOrderDetailView.java
  25. 19 18
      netflix-dao/src/main/resources/mapper/CorpUserTagMapper.xml
  26. 112 58
      netflix-dao/src/main/resources/mapper/OrderDonMapper.xml
  27. 65 0
      netflix-dao/src/main/resources/mapper/StatisticsExportMapper.xml
  28. 3 0
      netflix-service/src/main/java/com/cyksj/redis/RedisService.java
  29. 1 1
      netflix-service/src/main/java/com/cyksj/service/chatgpt/ChatGptAccountService.java
  30. 13 9
      netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java
  31. 5 1
      netflix-service/src/main/java/com/cyksj/service/corp/CorpTagService.java
  32. 52 26
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpEventActionServiceImpl.java
  33. 0 3
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpFollowServiceImpl.java
  34. 30 15
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpTagServiceImpl.java
  35. 1 0
      netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java
  36. 1 1
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  37. 34 0
      netflix-service/src/main/java/com/cyksj/service/mange/statistics/impl/StatisticsDataServiceImpl.java
  38. 19 6
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  39. 1 1
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  40. 22 13
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  41. 1 1
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupsRelationExpiryRecordServiceImpl.java
  42. 4 0
      netflix-service/src/main/java/com/cyksj/service/user/BadIntentionOpService.java
  43. 2 1
      netflix-service/src/main/java/com/cyksj/service/user/UserService.java
  44. 28 0
      netflix-service/src/main/java/com/cyksj/service/user/impl/BadIntentionOpServiceImpl.java
  45. 8 5
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java
  46. 4 2
      netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java
  47. 3 3
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  48. 39 2
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
  49. 0 4
      netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/CmsCorpFollowActiveCodeController.java
  50. 25 6
      netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/CorpTagController.java
  51. 9 7
      netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/WxCorpController.java
  52. 3 1
      netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java
  53. 8 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/exchange/ExchangeCodeController.java
  54. 20 10
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java
  55. 3 5
      netflix-web/src/main/java/com/cyksj/web/controller/mirror/MirrorController.java
  56. 8 3
      netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java
  57. 2 2
      netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

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

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

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

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

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

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

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

@@ -3,6 +3,7 @@ package com.cyksj.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cyksj.model.entity.OrderDon;
+import com.cyksj.model.entity.OrderDonCustomerServiceRelate;
 import com.cyksj.model.entity.RealGoodsInterestUser;
 import com.cyksj.model.excel.ExcelOrderDonInfo;
 import com.cyksj.model.views.*;
@@ -65,13 +66,23 @@ public interface OrderDonMapper extends BaseMapper<OrderDon> {
 
 	BrokenLineObjView selectDsPlatBrokenLineMoney(@Param("sharedId") Long sharedId, @Param("first") String first, @Param("end") String end);
 
-	UserOrderDetailView getTagUserData(@Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime);
+	UserOrderDetailView getTagUserOrdersData(@Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("consumeStTime") String consumeStTime, @Param("consumeEtTime") String consumeEtTime);
 
-	Page<UserOrderDetailView> getTagUserDataPage(@Param("page") Page<UserOrderDetailView> page, @Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime);
+	Page<UserOrderDetailView> getTagUserDataPage(@Param("page") Page<UserOrderDetailView> page, @Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("consumeStTime") String consumeStTime, @Param("consumeEtTime") String consumeEtTime);
 
 	Page<CorpTagUserOrderDataView> getTagUserTimeOrderData(@Param("page") Page<Object> objectPage, @Param("tagIdStr") String tagIdStr, @Param("toDate") String toDate, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
 	List<RealGoodsSourceData> getRealGoodsSourceData(@Param("isGeneral") Boolean isGeneral, @Param("startDate") String startDate, @Param("endDate") String endDate);
 
+	String selectMaxRefundGoodsName(@Param("operator") String operator, @Param("startTime") String startTime, @Param("endTime") String endTime);
+
+	OrderDonCustomerServiceRelate selectOrderRelate(Long orderId);
+
 	BigDecimal selectSubChannelOrderMoney(@Param("sharedId") Long sharedId, @Param("invitedTime") Date invitedTime, @Param("limitTime") Date limitTime);
+
+	Page<UserOrderDetailView> getPastRecord(@Param("objectPage") Page<Object> objectPage, @Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("consumeStTime") String consumeStTime, @Param("consumeEtTime") String consumeEtTime);
+
+	UserOrderDetailView getNumOfTagFansUser(@Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime);
+
+	UserOrderDetailView getFansToDayOrdersView(@Param("tagIdStr") String tagIdStr, @Param("date") String date);
 }

+ 3 - 4
netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpUserTagMapper.java

@@ -7,7 +7,6 @@ import com.cyksj.model.excel.CorpUserTagExcelData;
 import com.cyksj.model.views.CorpUserIntentionView;
 import com.cyksj.model.views.CorpUserView;
 import com.cyksj.model.views.UserIntentionPieView;
-import com.cyksj.model.views.UserOrderDetailView;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -22,11 +21,11 @@ public interface CorpUserTagMapper extends BaseMapper<CorpUserTag> {
 
 	List<CorpUserTagExcelData> exportUserTagDetail(@Param("tagIds") String[] tagIds, @Param("groupIds") String[] groupIds, @Param("wxCorpId") Long wxCorpId);
 
-	UserOrderDetailView countTagUser(@Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("thisDate") String thisDate);
+	Integer getDelCorpUserNum(@Param("tagIdStr") String tagIdStr, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
 	List<Long> getTagIdByCorpUserId(Long corpUserId);
 
-	UserIntentionPieView getUserIntentionPie(@Param("tagIdStr") String tagId, @Param("thisDate") String date);
+	List<UserIntentionPieView> getUserIntentionPie(@Param("tagIdStr") String tagId, @Param("thisDate") String date);
 
-	Page<CorpUserIntentionView> getCorpUserIntentionView(@Param("page") Page<CorpUserIntentionView> page, @Param("userId") Long userId, @Param("nickname") String nickname, @Param("tagIdStr") String tagId, @Param("thisDate") String date);
+	Page<CorpUserIntentionView> getCorpUserIntentionView(@Param("page") Page<CorpUserIntentionView> page, @Param("userId") Long userId, @Param("nickname") String nickname, @Param("tagIdStr") String tagId, @Param("thisDate") String date, @Param("intention") Integer intention);
 }

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/statistics/StatisticsExportMapper.java

@@ -76,4 +76,10 @@ public interface StatisticsExportMapper{
 	List<MonthlyUserOrderDetailDto> getMonthlyUserOrderDetail(@Param("thisMonth") DateTime thisMonth, @Param("nextMonth") DateTime nextMonth);
 
 	Map<String, Long> getEpOrderNumsGroupSource(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
+	Integer getOverPayByGoodsId(@Param("goodsId") Long goodsId, @Param("skuIds") List<Long> skuIds, @Param("lastMonth") String lastMonth, @Param("thisMonth") DateTime thisMonth, @Param("nextMonth") DateTime nextMonth);
+
+	Integer getYearNumOfRenewalsByGoodsId(@Param("goodsId") Long goodsId, @Param("lastElevMonth") String lastElevMonth, @Param("lastYearMonth") String lastYearMonth);
+
+	Integer getActualNumberOfRenewalsByGoodsId(@Param("goodsId") Long goodsId, @Param("lastElevMonth") String lastElevMonth, @Param("lastYearMonth") String lastYearMonth);
 }

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

@@ -36,7 +36,7 @@ public class CorpCustomerAcquisitionLinkPopularize extends BaseEntity {
     private Long time;
 
     /**
-     * 类型为 加粉,是否要延期回传
+     * 是否记录回传
      */
     private Boolean delayedPost;
 

+ 0 - 2
netflix-dao/src/main/java/com/cyksj/model/entity/CorpFollowActiveCode.java

@@ -77,7 +77,5 @@ public class CorpFollowActiveCode extends BaseEntity{
 	 */
 	private String operator;
 
-	private String couponIds;
-
 	private Boolean deleted;
 }

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/ExchangeCode.java

@@ -45,4 +45,6 @@ public class ExchangeCode extends BaseEntity{
 	 * 0平台 1抽奖
 	 */
 	private Integer type;
+
+	private String operator;
 }

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

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

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

@@ -0,0 +1,28 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: OrderDonCustomerServiceRelate
+ * 创建者: JavaZou
+ * 创建时间:2024/4/1 15:37
+ */
+@Getter
+@Setter
+public class OrderDonCustomerServiceRelate extends BaseEntity{
+	@NotNull
+	private Long orderId;
+
+	@NotNull
+	private Long cmsUserId;
+
+	@DbIgnore
+	@TableField(exist = false)
+	private String nickname;
+}

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

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

+ 27 - 0
netflix-dao/src/main/java/com/cyksj/model/excel/ExcelMonthOrderData.java

@@ -29,6 +29,9 @@ public class ExcelMonthOrderData {
 	@ExcelProperty({"品类数据类", "奈飞续费数据", "D.非当月到期,但续费的用户数"})
 	private Integer monthNfNoExRenewNumOfUser;
 
+	@ExcelProperty({"品类数据类", "奈飞续费数据", "E.超期购买"})
+	private Integer overNfPayNumOfUser;
+
 	@ExcelProperty({"品类数据类", "AI类续费(gptplus月付)", "A.月付当月到期的所有用户数"})
 	private Integer monthAiGptExNumOfUser;
 
@@ -41,6 +44,9 @@ public class ExcelMonthOrderData {
 	@ExcelProperty({"品类数据类", "AI类续费(gptplus月付)", "D.非当月到期,但续费的用户数"})
 	private Integer monthAiGptNoExRenewNumOfUser;
 
+	@ExcelProperty({"品类数据类", "AI类续费(gptplus月付)", "E.超期购买"})
+	private Integer overGptPayNumOfUser;
+
 	@ExcelProperty({"品类数据类", "AI类续费(midjourney月付)", "A.月付当月到期的所有用户数"})
 	private Integer monthAiMidExNumOfUser;
 
@@ -53,6 +59,9 @@ public class ExcelMonthOrderData {
 	@ExcelProperty({"品类数据类", "AI类续费(midjourney月付)", "D.非当月到期,但续费的用户数"})
 	private Integer monthAiMidNoExRenewNumOfUser;
 
+	@ExcelProperty({"品类数据类", "AI类续费(midjourney月付)", "E.超期购买"})
+	private Integer overMidPayNumOfUser;
+
 	@ExcelProperty({"品类数据类", "流媒类复购数据", "A.购买流媒体类产品为首单的当月新用户"})
 	private Integer monthStreamingNewNumOfUser;
 
@@ -71,6 +80,24 @@ public class ExcelMonthOrderData {
 	@ExcelProperty({"品类数据类", "AI类复购数据", "C.A用户中购买第二单流媒体产品的用户数"})
 	private Integer monthAiNewPayStreamingNumOfUser;
 
+	@ExcelProperty({"品类数据类", "油管年付", "A.应续费人数"})
+	private Integer youtubeNumOfRenewals;
+
+	@ExcelProperty({"品类数据类", "油管年付", "B.实际续费人数"})
+	private Integer youtubeActualNumberOfRenewals;
+
+	@ExcelProperty({"品类数据类", "声破天年付", "A.应续费人数"})
+	private Integer spotifyNumOfRenewals;
+
+	@ExcelProperty({"品类数据类", "声破天年付", "B.实际续费人数"})
+	private Integer spotifyActualNumberOfRenewals;
+
+	@ExcelProperty({"品类数据类", "迪士尼年付", "A.应续费人数"})
+	private Integer disneyNumOfRenewals;
+
+	@ExcelProperty({"品类数据类", "迪士尼年付", "B.实际续费人数"})
+	private Integer disneyActualNumberOfRenewals;
+
 	@ExcelProperty({"用户维度", "当月新用户", "订单量"})
 	private Integer monthlyNewUserOrders;
 

+ 14 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/request/ReqGoodsSkuInsert.java

@@ -136,6 +136,20 @@ public class ReqGoodsSkuInsert {
          */
         private Integer sorted;
 
+        /**
+         * 是否是车队形式
+         */
+        private Boolean isCar;
+
+        /**
+         * 限制次数
+         */
+        private int gptLimitNum;
+
+        /**
+         * 限制时间
+         */
+        private int gptLimitTime;
     }
 
 }

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

@@ -30,6 +30,9 @@ public class CorpMsgAuditUserView {
     @DbField("cu.external_userid")
     private String externalUserid;
 
+    @DbField("c.user_id")
+    private Long userId;
+
     /**
      * 外部联系人头像,代开发自建应用需要管理员授权才可以获取,第三方不可获取,上游企业不可获取下游企业客户该字段
      */

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

@@ -262,4 +262,16 @@ public class OrderDonBackView {
 
 	@DbIgnore
 	private List<GoodsDonSkuView> benefitsViews;
+
+	/**
+	 * 客服id
+	 */
+	@DbIgnore
+	private Long cmsUserId;
+
+	/**
+	 * 客服名
+	 */
+	@DbIgnore
+	private String serviceName;
 }

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/request/ExchangeCodeReq.java

@@ -31,4 +31,6 @@ public class ExchangeCodeReq {
 	 * 0平台 1抽奖
 	 */
 	private Integer type;
+
+	private String operator;
 }

+ 1 - 0
netflix-dao/src/main/java/com/cyksj/model/request/LoginReq.java

@@ -1,5 +1,6 @@
 package com.cyksj.model.request;
 
+import cn.hutool.http.server.HttpServerRequest;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;

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

@@ -78,9 +78,6 @@ public class CorpFollowActiveCodeView {
 	@DbField("cfa.operator")
 	private String operator;
 
-	@DbField("cfa.coupon_id")
-	private Long couponId;
-
 	/**
 	 * 优惠券名
 	 */

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

@@ -62,6 +62,9 @@ public class ExchangeCodeView {
 	@DbField("ec.user_id")
 	private Long userId;
 
+	@DbField("ec.operator")
+	private String operator;
+
 	/**
 	 * 用户昵称
 	 */

+ 31 - 0
netflix-dao/src/main/java/com/cyksj/model/views/OrderCustomerServiceDataView.java

@@ -0,0 +1,31 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: OrderCustomerServiceDataView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/1 15:30
+ */
+@Getter
+@Setter
+@SearchBean(tables = "order_don_customer_service_relate odr inner join order_don od on odr.order_id = od.id and od.status not in ('close','noPayment','refund')" +
+		" inner join cms_user cu on cu.id = odr.cms_user_id",
+		groupBy = "odr.cms_user_id,od.goods_id")
+public class OrderCustomerServiceDataView {
+	@DbField("count(*)")
+	private Integer orders;
+
+	@DbField("odr.cms_user_id")
+	private Long cmsUserId;
+
+	@DbField("any_value(cu.nickname)")
+	private String nickname;
+
+	@DbField("select title from goods_don where id = od.goods_id limit 1")
+	private String goodsName;
+}

+ 7 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RefundOrderDonServiceDataView.java

@@ -1,6 +1,7 @@
 package com.cyksj.model.views;
 
 import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
 import com.ejlchina.searcher.bean.SearchBean;
 import lombok.Getter;
 import lombok.Setter;
@@ -27,4 +28,10 @@ public class RefundOrderDonServiceDataView {
 
 	@DbField("sum(rd.refund_fee)/100")
 	private BigDecimal refundMoney;
+
+	/**
+	 * 退款最多的产品
+	 */
+	@DbIgnore
+	private String goodsName;
 }

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

@@ -32,6 +32,9 @@ public class RenewalView {
     @DbField("sku.id")
     private Long skuId;
 
+    @DbField("sku.status")
+    private Boolean skuStatus;
+
     @DbField("sku.months")
     private Integer months;
 

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

@@ -31,5 +31,13 @@ public class UserOrderDetailView {
 
 	private String date;
 
-	Page<UserOrderDetailView> records;
+	/**
+	 * 进粉记录
+	 */
+	Page<UserOrderDetailView> fansRecords;
+
+	/**
+	 * 往期标签用户订单记录
+	 */
+	Page<UserOrderDetailView> pastRecords;
 }

+ 19 - 18
netflix-dao/src/main/resources/mapper/CorpUserTagMapper.xml

@@ -61,9 +61,8 @@
         group by cu.id, cu.unionid)s order by s.tagTime desc, s.userId asc
     </select>
 
-    <select id="countTagUser" resultType="com.cyksj.model.views.UserOrderDetailView">
-        select count(distinct ca.corp_user_id) as numOfUser,
-        count(distinct if(cufr.status = 0,ca.corp_user_id,NULL)) as delNumOfUser
+    <select id="getDelCorpUserNum" resultType="java.lang.Integer">
+        select count(distinct if(cufr.status = 0,ca.corp_user_id,NULL)) as delNumOfUser
         from (select relation_id
         from `corp_user_tag` ct
         where tag_id = #{tagIdStr}
@@ -72,9 +71,6 @@
         </if>
         <if test="endTime != null">
             and ct.created_time &lt; #{endTime}
-        </if>
-        <if test="thisDate != null">
-            and date_format(ct.created_time,'%Y-%m-%d') = #{thisDate}
         </if>) s
         left join corp_user_follow_relation cufr on cufr.id = s.relation_id
         left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
@@ -94,27 +90,29 @@
         from (select relation_id
         from `corp_user_tag` ct
         where tag_id = #{tagIdStr}
+        group by relation_id
         <if test="thisDate != null">
-            and date_format(ct.created_time,'%Y-%m-%d') = #{thisDate}
+            having date_format(min(ct.created_time),'%Y-%m-%d') = #{thisDate}
         </if>) s
         left join corp_user_follow_relation cufr on cufr.id = s.relation_id
         left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
-        inner join corp_customer_acquistion_callback ccc on ccc.corp_user_id = ca.corp_user_id
+        left join corp_user cu on cu.id = ca.corp_user_id
+        inner join corp_customer_acquistion_callback ccc on ccc.union_id = cu.unionid
         group by ccc.intention
     </select>
 
     <select id="getCorpUserIntentionView" resultType="com.cyksj.model.views.CorpUserIntentionView">
-        select cu.user_id,cu.name,cu.created_time,ccc.id as intentionId,ccc.intention
-        from (select relation_id
-        from `corp_user_tag` ct
-        where tag_id = #{tagIdStr}
+        select cu.user_id,cu.name as nickname,cu.created_time,ccc.id as intentionId,ccc.intention
+        from (select distinct cu.*
+        from (select DISTINCT relation_id from corp_user_tag where tag_id = #{tagIdStr}) ct
+        inner join corp_user_follow_relation cufr on cufr.id = ct.relation_id
+        inner join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
+        inner join corp_user cu on cu.id = ca.corp_user_id
         <if test="thisDate != null">
-            and date_format(ct.created_time,'%Y-%m-%d') = #{thisDate}
-        </if>) s
-        left join corp_user_follow_relation cufr on cufr.id = s.relation_id
-        left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
-        inner join corp_customer_acquistion_callback ccc on ccc.corp_user_id = ca.corp_user_id
-        left join corp_user cu on cu.id = ca.corp_user_id
+            where date_format(cu.created_time,'%Y-%m-%d') = #{thisDate}
+        </if>
+        ) cu
+        left join corp_customer_acquistion_callback ccc on ccc.union_id = cu.unionid
         <where>
             <if test="userId != null">
                 cu.user_id = #{userId}
@@ -122,6 +120,9 @@
             <if test="userId != null">
                 and cu.name like concat('%',#{userName},'%')
             </if>
+            <if test="intention != null">
+                and ccc.intention = #{intention}
+            </if>
         </where>
     </select>
 </mapper>

+ 112 - 58
netflix-dao/src/main/resources/mapper/OrderDonMapper.xml

@@ -319,57 +319,45 @@
         </if>
     </select>
 
-    <select id="getTagUserData" resultType="com.cyksj.model.views.UserOrderDetailView">
-        select count(if(status != 'refund', 1, NULL)) as numOfOrder, (sum(money) - sum(ifnull(refund_money, 0))) / 100
-        as orderMoney,
+    <select id="getTagUserOrdersData" resultType="com.cyksj.model.views.UserOrderDetailView">
+        select count(if(status != 'refund', 1, NULL)) as numOfOrder,
+        cast((sum(money) - sum(ifnull(refund_money, 0))) / 100 as decimal(10,2)) as orderMoney,
         count(if(status != 'refund' and o.goods_id = 15,1,NULL)) as numOfEpOrder,
-        (sum(if(o.goods_id = 15,money,0)) - sum(ifnull(if(o.goods_id = 15,refund_money,0), 0))) / 100 as epOrderMoney
-        from (select cu.user_id
-        from (select relation_id
-        from `corp_user_tag` ct
-        where tag_id = #{tagIdStr}
+        cast((sum(if(o.goods_id = 15,money,0)) - sum(ifnull(if(o.goods_id = 15,refund_money,0), 0))) / 100 as
+        decimal(10,2)) as epOrderMoney
+        from (select distinct cu.user_id,cu.created_time from (select DISTINCT relation_id from corp_user_tag where tag_id = #{tagIdStr})
+        ct inner join corp_user_follow_relation cufr on cufr.id = ct.relation_id
+        inner join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
+        inner join corp_user cu on cu.id = ca.corp_user_id
+        where cu.user_id != 0
         <if test="startTime != null">
-            and ct.created_time >= #{startTime}
+            and cu.created_time >= #{startTime}
         </if>
         <if test="endTime != null">
-            and ct.created_time &lt; #{endTime}
-        </if>) s
-        left join corp_user_follow_relation cufr on cufr.id = s.relation_id
-        left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
-        left join corp_user cu on cu.id = ca.corp_user_id where cu.user_id != 0) s inner join order_don o on o.user_id =
-        s.user_id
-        and o.status not in ('close', 'noPayment')
-        and o.money > 0
-        and o.money > ifnull(o.refund_money,0)
-        <if test="startTime != null">
-            and o.created_time >= #{startTime}
+            and cu.created_time &lt; #{endTime}
+        </if>)
+        cu inner join order_don o on o.user_id = cu.user_id
+        and o.`status` not in ('close','noPayment')
+        AND o.money > 0
+        and o.created_time > cu.created_time
+        <if test="consumeStTime != null">
+            and o.created_time >= #{consumeStTime}
+        </if>
+        <if test="consumeEtTime != null">
+            and o.created_time &lt; #{consumeEtTime}
         </if>
     </select>
 
     <select id="getTagUserDataPage" resultType="com.cyksj.model.views.UserOrderDetailView">
-        select count(if(status != 'refund', 1, NULL)) as numOfOrder, (sum(money) - sum(ifnull(refund_money, 0))) / 100
-        as orderMoney,date_format(o.created_time,'%Y-%m-%d') as date from (select cu.user_id
-        from (select relation_id
-        from `corp_user_tag` ct
-        where tag_id = #{tagIdStr}
-        <if test="startTime != null">
-            and ct.created_time >= #{startTime}
-        </if>
-        <if test="endTime != null">
-            and ct.created_time &lt; #{endTime}
-        </if>) s
-        left join corp_user_follow_relation cufr on cufr.id = s.relation_id
-        left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
-        left join corp_user cu on cu.id = ca.corp_user_id where cu.user_id != 0) s inner join order_don o on o.user_id =
-        s.user_id
-        and o.status not in ('close', 'noPayment')
-        and o.money > 0
-        and o.money > ifnull(o.refund_money,0)
-        <if test="startTime != null">
-            and o.created_time >= #{startTime}
-        </if>
-        group by date_format(o.created_time,'%Y-%m-%d')
-        order by date_format(o.created_time,'%Y-%m-%d') desc
+        select date_format(cu.created_time, '%Y-%m-%d') as `date`,
+               count(distinct cu.id)                    as numOfUser
+        from (select distinct cu.id, cu.user_id, cu.created_time
+              from (select DISTINCT relation_id from corp_user_tag where tag_id = #{tagIdStr}) ct
+                       inner join corp_user_follow_relation cufr on cufr.id = ct.relation_id
+                       inner join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
+                       inner join corp_user cu on cu.id = ca.corp_user_id) cu
+        group by date_format(cu.created_time, '%Y-%m-%d')
+        order by date_format(cu.created_time, '%Y-%m-%d') desc
     </select>
 
     <select id="getTagUserTimeOrderData" resultType="com.cyksj.model.views.CorpTagUserOrderDataView">
@@ -377,22 +365,14 @@
         (select nickname from user u where u.id = o.user_id limit 1),
         o.order_no,o.goods_id,g.title,o.sku_id,sku.spec_val,
         o.money/100 as money,o.created_time
-        from (select
-        cu.user_id
-        from (select relation_id
-        from `corp_user_tag` ct
-        where tag_id = #{tagIdStr}
-        <if test="startTime != null">
-            and ct.created_time >= #{startTime}
-        </if>
-        <if test="endTime != null">
-            and ct.created_time &lt; #{endTime}
-        </if>) s
-        left join corp_user_follow_relation cufr on cufr.id = s.relation_id
-        left join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
-        left join corp_user cu on cu.id = ca.corp_user_id where cu.user_id != 0) s inner join order_don o on o.user_id =
-        s.user_id
+        from (select distinct cu.user_id, date_format(cu.created_time, '%Y-%m-%d') joinTime
+        from (select DISTINCT relation_id from corp_user_tag where tag_id = #{tagIdStr}) ct
+        inner join corp_user_follow_relation cufr on cufr.id = ct.relation_id
+        inner join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
+        inner join corp_user cu on cu.id = ca.corp_user_id
+        where cu.user_id != 0) cu inner join order_don o on o.user_id = cu.user_id
         and o.status not in ('close', 'noPayment','refund')
+        and date_format(o.created_time, '%Y-%m-%d') = joinTime
         and o.money > 0
         <if test="toDate != null and toDate != ''">
             and date_format(o.created_time,'%Y-%m-%d') = #{toDate}
@@ -423,6 +403,28 @@
         group by o.label_source
     </select>
 
+    <select id="selectMaxRefundGoodsName" resultType="java.lang.String">
+        select (select title from goods_don where id = o.goods_id limit 1)
+        from (select distinct order_id from refund_order_don where operator = #{operator}
+        and refund_method not in ('EX_CODE'
+        , 'balance')) rd inner join order_don o
+        on o.id = rd.order_id
+        <if test="startTime != null">
+            and o.created_time >= #{startTime}
+        </if>
+        <if test="endTime != null">
+            and o.created_time &lt; #{endTime}
+        </if>
+        group by o.goods_id
+        order by count(*) desc limit 1
+    </select>
+
+    <select id="selectOrderRelate" resultType="com.cyksj.model.entity.OrderDonCustomerServiceRelate">
+        select cms_user_id, (select nickname from cms_user where id = odr.cms_user_id limit 1) as nickname
+        from order_don_customer_service_relate odr
+        where order_id = #{orderId} limit 1
+    </select>
+
     <select id="selectSubChannelOrderMoney" resultType="java.math.BigDecimal">
         select sum(o.money) - sum(ifnull(o.refund_money, 0))
         from distribute_waiting_send_points dp
@@ -433,4 +435,56 @@
         and o.created_time > #{invitedTime}
           and o.created_time &lt; #{limitTime}
     </select>
+
+    <select id="getPastRecord" resultType="com.cyksj.model.views.UserOrderDetailView">
+        select date_format(o.created_time, '%Y-%m-%d')                                              as `date`,
+               count(if(status != 'refund', 1, NULL))                                               as numOfOrder,
+               cast((ifnull(sum(money), 0) - sum(ifnull(refund_money, 0))) / 100 as decimal(10, 2)) as orderMoney
+        from (select distinct cu.user_id, cu.created_time
+              from (select DISTINCT relation_id from corp_user_tag where tag_id = #{tagIdStr}) ct
+                       inner join corp_user_follow_relation cufr on cufr.id = ct.relation_id
+                       inner join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
+                       inner join corp_user cu on cu.id = ca.corp_user_id
+              where cu.user_id != 0) cu
+                 inner join order_don o
+                            on o.user_id = cu.user_id
+                                and o.`status` not in ('close', 'noPayment')
+                                AND money > 0
+                                and o.created_time > cu.created_time
+        group by date_format(o.created_time, '%Y-%m-%d')
+        order by date_format(o.created_time, '%Y-%m-%d') desc
+    </select>
+
+    <select id="getNumOfTagFansUser" resultType="com.cyksj.model.views.UserOrderDetailView">
+        select count(distinct cu.id) as numOfUser,
+        count(distinct if(cufr.status = 0,cu.id,NULL)) as delNumOfUser
+        from (select distinct relation_id from `corp_user_tag` where tag_id = #{tagIdStr}) s
+        inner join corp_user_follow_relation cufr on cufr.id = s.relation_id
+        inner join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
+        inner join corp_user cu on cu.id = ca.corp_user_id
+        <where>
+            <if test="startTime != null">
+                cu.created_time >= #{startTime}
+            </if>
+            <if test="endTime != null">
+                and cu.created_time &lt; #{endTime}
+            </if>
+        </where>
+    </select>
+
+    <select id="getFansToDayOrdersView" resultType="com.cyksj.model.views.UserOrderDetailView">
+        select count(if(status != 'refund', 1, NULL))                                               as numOfOrder,
+               cast((ifnull(sum(money), 0) - sum(ifnull(refund_money, 0))) / 100 as decimal(10, 2)) as orderMoney
+        from (select distinct cu.user_id, cu.created_time
+              from (select DISTINCT relation_id from corp_user_tag where tag_id = #{tagIdStr}) ct
+                       inner join corp_user_follow_relation cufr on cufr.id = ct.relation_id
+                       inner join corp_user_auth ca on ca.external_userid = cufr.corp_user_id
+                       inner join corp_user cu on cu.id = ca.corp_user_id
+              where cu.user_id != 0) cu
+                 inner join order_don o on o.user_id = cu.user_id
+            and o.`status` not in ('close', 'noPayment')
+            AND money > 0
+            and date_format(o.created_time, '%Y-%m-%d') = date_format(cu.created_time, '%Y-%m-%d')
+            and date_format(o.created_time, '%Y-%m-%d') = #{date}
+    </select>
 </mapper>

+ 65 - 0
netflix-dao/src/main/resources/mapper/StatisticsExportMapper.xml

@@ -529,4 +529,69 @@
         </if>
         group by DATE_FORMAT(created_time, '%Y-%m')
     </select>
+
+    <select id="getOverPayByGoodsId" resultType="java.lang.Integer">
+        select count(DISTINCT user_id)
+        from order_don o
+        where created_time &lt; #{lastMonth}
+        <if test="goodsId !=null">
+            and goods_id = #{goodsId}
+        </if>
+        <if test="skuIds!=null">
+            and sku_id in
+            <foreach collection="skuIds" item="item" open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        and `status` not in ('close', 'noPayment', 'refund')
+        and NOT EXISTS (select 1
+        from order_don
+        where created_time BETWEEN #{lastMonth} and #{thisMonth}
+        and `status` not in ('close', 'noPayment', 'refund')
+        AND user_id = o.user_id
+        <if test="goodsId !=null">
+            and goods_id = #{goodsId}
+        </if>
+        <if test="skuIds!=null">
+            and sku_id in
+            <foreach collection="skuIds" item="item" open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        )
+        and EXISTS (select 1
+        from order_don
+        where created_time BETWEEN #{thisMonth} and #{nextMonth}
+        and `status` not in ('close', 'noPayment', 'refund')
+        and user_id = o.user_id
+        <if test="goodsId !=null">
+            and goods_id = #{goodsId}
+        </if>
+        <if test="skuIds!=null">
+            and sku_id in
+            <foreach collection="skuIds" item="item" open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        )
+    </select>
+
+    <select id="getYearNumOfRenewalsByGoodsId" resultType="java.lang.Integer">
+        select count(distinct user_id)
+        from order_don
+        where created_time BETWEEN #{lastYearMonth} and #{lastElevMonth}
+          and `status` not in ('close', 'noPayment', 'refund')
+          and goods_id = #{goodsId}
+    </select>
+
+    <select id="getActualNumberOfRenewalsByGoodsId" resultType="java.lang.Integer">
+        select count(distinct user_id)
+        from order_don o
+        where created_time BETWEEN #{lastYearMonth} and #{lastElevMonth}
+          and `status` not in ('close', 'noPayment', 'refund')
+          and goods_id = #{goodsId}
+        and exists (select 1 from order_don where created_time > #{lastElevMonth}
+            and `status` not in ('close', 'noPayment', 'refund')
+            and goods_id = #{goodsId} and user_id = o.user_id limit 1)
+    </select>
 </mapper>

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

@@ -756,6 +756,8 @@ public class RedisService {
         PHONE_CODE_KEY("phone_code_key:", "短信验证码", 60 * 3),
         PHONE_CODE_USER_NUM_KEY_DAY("phone_code_user_num_key:", "近一天获取验证码次数", 60 * 60 * 24l),
         PHONE_CODE_BALCK_KEY("phone_code_balck_key:", "手机黑名单", -1l),
+        PHONE_CODE_RETRY_TIME_KEY("phone_code_retry_time_key:", "手机登录重试key", 60 * 3),
+        BALCK_USER_IP_KEY("balck_user_ip_key:", "拉黑用户ip", 60 * 60 * 24),
         LOTTERY_KEY("lottery_key:%s", "抽奖key", 60 * 60 * 24l),
         TASK_TIME_LIMIT_KEY("task_time_limit:%s", "一次性任务key", 30),
         WX_GZH_QRCODE_LOGIN("wx_gzh_qrcode_login:%s", "微信公众号扫码登录key", 60),
@@ -816,6 +818,7 @@ public class RedisService {
         WX_INDENT_BIND_KEY("wx_indent_bind:key:", "微信身份授权绑定key", 60 * 60 * 24),
         EQUIPMENT_USER_SERVICE_RECORD("equipment_user_service_record:", "用户设备客服获取记录key", 60 * 60 * 24),
         INFORMATION_KEY("information_key:", "文章", 30 * 60L),
+        CLOSE_ORDER_TIME_KEY("close_order_time_key:", "关闭订单key", 3 * 60),
         CHATGPT_CONVERSATION_LIMIT("chatgpt:conversation:limit:", "chatGpt 对话限制", 3 * 60 * 60L),
 
         CHATGPT_CAR_CONVERSATION_LIMIT("chatgpt:conversation:car:", "chatGpt 车队对话数量", 3 * 60 * 60L),

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/chatgpt/ChatGptAccountService.java

@@ -59,7 +59,7 @@ public interface ChatGptAccountService {
     /**
      * oai 触发车队限制
      */
-    void carLimited(String carId, String userToken, Integer expTime);
+    void carLimited(String carId, String userToken, Long expTime);
 
     /**
      * 获取GPT session

+ 13 - 9
netflix-service/src/main/java/com/cyksj/service/chatgpt/impl/ChatGptAccountServiceImpl.java

@@ -30,6 +30,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.data.redis.core.ZSetOperations;
 import org.springframework.stereotype.Service;
 
@@ -320,13 +321,16 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
             chatgptUser.setLimitNum(goodsDonSku.getGptLimitNum());
             chatgptUser.setLimitTime(goodsDonSku.getGptLimitTime());
         }
-        chatgptUser.setExpireTime(groupsRelation.getExpiryTime());
-        chatgptUser.setIsPlus(1);
-        chatgptUser.setName(user.getNickname());
-        chatgptUser.setImg(getWxImg(user.getHeadimgurl(), user));
-        chatgptUser.setRelationId(groupsRelation.getId());
-        chatgptUser.setUserToken(UUID.randomUUID().toString());
-        chatgptUserMapper.insert(chatgptUser);
+        try {
+            chatgptUser.setExpireTime(groupsRelation.getExpiryTime());
+            chatgptUser.setIsPlus(1);
+            chatgptUser.setName(user.getNickname());
+            chatgptUser.setImg(getWxImg(user.getHeadimgurl(), user));
+            chatgptUser.setRelationId(groupsRelation.getId());
+            chatgptUser.setUserToken(UUID.randomUUID().toString());
+            chatgptUserMapper.insert(chatgptUser);
+        } catch (DuplicateKeyException e) {
+        }
         return chatgptUser;
     }
 
@@ -733,7 +737,7 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
     }
 
     @Override
-    public void carLimited(String carId, String userToken, Integer expTime) {
+    public void carLimited(String carId, String userToken, Long expTime) {
         if(carId == null){
             if (StringUtils.isNotBlank(userToken)) {
                 ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getUserToken, userToken));
@@ -745,7 +749,7 @@ public class ChatGptAccountServiceImpl implements ChatGptAccountService {
                 }
             }
         }
-        redisService.set("chatgpt:clears_in:" + carId, expTime);
+        redisService.set("chatgpt:clears_in:" + carId, expTime, expTime);
     }
 
     @PostConstruct

+ 5 - 1
netflix-service/src/main/java/com/cyksj/service/corp/CorpTagService.java

@@ -45,7 +45,11 @@ public interface CorpTagService {
 	 */
 	CorpTagGroupView addGroup(CorpTagGroupView tagGroup) throws Exception;
 
-	UserOrderDetailView getTagUserData(Integer start, Integer limit, String tagIdStr, String startTime, String endTime);
+	Page<UserOrderDetailView>  getTagUserData(Integer start, Integer limit, String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime);
 
 	Page<CorpTagUserOrderDataView> getTagUserTimeOrderData(Integer start, Integer limit, String tagIdStr, String toDate, String startTime, String endTime);
+
+	Page<UserOrderDetailView> getTagUserPastRecord(Integer start, Integer limit, String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime);
+
+	UserOrderDetailView tagUserHeadData(String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime);
 }

+ 52 - 26
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpEventActionServiceImpl.java

@@ -591,10 +591,17 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 		relation.setWxCorpId(wxCorpId);
 		if (relation.getId() == null) relationMapper.insert(relation);
 		else relationMapper.updateById(relation);
-		corpUserTagMapper.delete(Wrappers.lambdaQuery(CorpUserTag.class).eq(CorpUserTag::getRelationId, relation.getId()));
 
+		List<CorpUserTag> corpUserTags = Optional.ofNullable(corpUserTagMapper.selectList(Wrappers.lambdaQuery(CorpUserTag.class)
+				.eq(CorpUserTag::getRelationId, relation.getId()))).orElse(new ArrayList<>());
+		List<String> exists_tagIds = corpUserTags.stream().map(CorpUserTag::getTagId).collect(Collectors.toList());
 		//存储用户标签
 		Stream.of(followedUser.getTags()).forEach((tag) -> {
+			//相同标签
+			if (CollUtil.isNotEmpty(exists_tagIds) && exists_tagIds.contains(tag.getTagId())) {
+				exists_tagIds.remove(tag.getTagId());
+				return;
+			}
 			CorpUserTag corpUserTag = new CorpUserTag();
 			corpUserTag.setRelationId(relation.getId());
 			corpUserTag.setGroupName(tag.getGroupName());
@@ -603,6 +610,14 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 			corpUserTag.setType(tag.getType());
 			corpUserTagMapper.insert(corpUserTag);
 		});
+
+		//存在被删除的标签
+		if (CollUtil.isNotEmpty(exists_tagIds)) {
+			corpUserTagMapper.delete(Wrappers.lambdaQuery(CorpUserTag.class)
+					.in(CorpUserTag::getTagId, exists_tagIds)
+					.eq(CorpUserTag::getRelationId, relation.getId()));
+		}
+
 		//同步企业微信 银河用户id
 		Optional.ofNullable(corpUserMapper.setCorpUserUserId(relation.getCorpUserId()))
 				.ifPresent(corpUser -> {
@@ -721,6 +736,7 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 		String state = message.getState();
 		CorpFollowActiveCode corpFollowActiveCode = null;
 		AtomicBoolean isSendWelcomeMsg = new AtomicBoolean(false);
+		CorpWelcomeTemplate corpWelcomeTemplate = null;
 		if (StrUtil.isNotBlank(state) && state.contains(Constant.AC_CODE_KEY)) {
 			//查找对应的活动活码 记录
 			String acIdStr = StrUtil.subAfter(state, StrUtil.C_COLON, true);
@@ -733,7 +749,7 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 					}
 					//欢迎语模板id
 					Long msgId = corpFollowActiveCode.getMsgId();
-					sendWelcomeMsg(msgId, message);
+					corpWelcomeTemplate = sendWelcomeMsg(msgId, message);
 					isSendWelcomeMsg.set(true);
 					try {
 						//对客户进行标记
@@ -802,10 +818,17 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 				isJoinFixedCustomer(user.getId(), message.getUserId());
 
 				//活码 优惠券发送
-				if (corpFollowActiveCode != null && StrUtil.isNotBlank(corpFollowActiveCode.getCouponIds())) {
+				if (corpFollowActiveCode != null && corpFollowActiveCode.getMsgId() != 0) {
+					Long msgId = corpFollowActiveCode.getMsgId();
+					if (corpWelcomeTemplate == null) {
+						corpWelcomeTemplate = corpWelcomeTemplateMapper.selectById(msgId);
+					}
+					String couponIdsStr = corpWelcomeTemplate != null ? corpWelcomeTemplate.getCouponIds() : null;
 					try {
-						List<Long> couponIds = Jsons.parseList(corpFollowActiveCode.getCouponIds(), Long.class);
-						couponIds.forEach(couponId -> couponCommonService.sendCouponToUser(user.getId(), couponId, 0l, 0l, 0l, CouponUser.Channel.corp_active_code));
+						if (StrUtil.isNotBlank(couponIdsStr)) {
+							List<Long> couponIds = Jsons.parseList(couponIdsStr, Long.class);
+							couponIds.forEach(couponId -> couponCommonService.sendCouponToUser(user.getId(), couponId, 0l, 0l, 0l, CouponUser.Channel.corp_active_code));
+						}
 					} catch (Exception e) {
 					}
 				}
@@ -841,16 +864,16 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 
 		//若没找到规则的欢迎语 发送默认欢迎语
 		if (StrUtil.isNotEmpty(message.getWelcomeCode()) && !isSendWelcomeMsg.get()) {
-			CorpWelcomeTemplate corpWelcomeTemplate = corpWelcomeTemplateMapper.selectOne(Wrappers.lambdaQuery(CorpWelcomeTemplate.class)
+			CorpWelcomeTemplate serviceWelcomeTemplate = corpWelcomeTemplateMapper.selectOne(Wrappers.lambdaQuery(CorpWelcomeTemplate.class)
 					.eq(CorpWelcomeTemplate::getType, 0)
 					.eq(CorpWelcomeTemplate::getDeleted, 1)
 					.last("limit 1"));
-			if (corpWelcomeTemplate == null) {
+			if (serviceWelcomeTemplate == null) {
 				log.info("===========未找到自然流量默认欢迎语===========");
 			}
-			if (corpWelcomeTemplate != null) {
+			if (serviceWelcomeTemplate != null) {
 				log.info("===========找到自然流量默认欢迎语记录===========");
-				senCorpWelcomeMsg(message, corpWelcomeTemplate.getText(), corpWelcomeTemplate.getAttachmentsStr());
+				senCorpWelcomeMsg(message, serviceWelcomeTemplate.getText(), serviceWelcomeTemplate.getAttachmentsStr());
 			}
 		}
 		return corpUser;
@@ -1100,21 +1123,7 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 					//如果为加粉则直接回传
 					if (corpCustomerAcquisitionLinkPopularize.getType() == 1) {
 						//如果需要延后主动回传的做持久化.
-						if(corpCustomerAcquisitionLinkPopularize.getDelayedPost()){
-							CorpCustomerAcquistionCallback corpCustomerAcquistionCallback =
-									corpCustomerAcquistionCallbackMapper.selectOne(Wrappers.lambdaQuery(CorpCustomerAcquistionCallback.class).eq(CorpCustomerAcquistionCallback::getCallback, callback).eq(CorpCustomerAcquistionCallback::getUnionId, unionId));
-							if(corpCustomerAcquistionCallback == null){
-								corpCustomerAcquistionCallback = new CorpCustomerAcquistionCallback();
-							}
-							corpCustomerAcquistionCallback.setCallback(callback);
-							corpCustomerAcquistionCallback.setEvent(corpCustomerAcquistionCallback.getEvent());
-							corpCustomerAcquistionCallback.setUnionId(unionId);
-							if(corpCustomerAcquistionCallback.getId() != null){
-								corpCustomerAcquistionCallbackMapper.updateById(corpCustomerAcquistionCallback);
-							}else {
-								corpCustomerAcquistionCallbackMapper.insert(corpCustomerAcquistionCallback);
-							}
-						}else {
+						if(!corpCustomerAcquisitionLinkPopularize.getDelayedPost()){
 							postData(callback, corpCustomerAcquisitionLinkPopularize.getEvent());
 						}
 					}else {
@@ -1126,6 +1135,22 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 						//深度回传.
 						redisService.set(String.format(RedisService.key.CORP_CUSTOMER_ACQUISTION_UNIONID_CLICKID.getName(),unionId), json, corpCustomerAcquisitionLinkPopularize.getTime() * 60 * 60);
 					}
+
+					if(corpCustomerAcquisitionLinkPopularize.getDelayedPost()){
+						CorpCustomerAcquistionCallback corpCustomerAcquistionCallback =
+								corpCustomerAcquistionCallbackMapper.selectOne(Wrappers.lambdaQuery(CorpCustomerAcquistionCallback.class).eq(CorpCustomerAcquistionCallback::getCallback, callback).eq(CorpCustomerAcquistionCallback::getUnionId, unionId));
+						if(corpCustomerAcquistionCallback == null){
+							corpCustomerAcquistionCallback = new CorpCustomerAcquistionCallback();
+						}
+						corpCustomerAcquistionCallback.setCallback(callback);
+						corpCustomerAcquistionCallback.setEvent(corpCustomerAcquisitionLinkPopularize.getEvent());
+						corpCustomerAcquistionCallback.setUnionId(unionId);
+						if(corpCustomerAcquistionCallback.getId() != null){
+							corpCustomerAcquistionCallbackMapper.updateById(corpCustomerAcquistionCallback);
+						}else {
+							corpCustomerAcquistionCallbackMapper.insert(corpCustomerAcquistionCallback);
+						}
+					}
 				}
 			}
 		}
@@ -1149,9 +1174,9 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 	 * @param msgId 模板id
 	 * @param message
 	 */
-	public void sendWelcomeMsg(Long msgId, CorpXmlMessage message) {
+	public CorpWelcomeTemplate sendWelcomeMsg(Long msgId, CorpXmlMessage message) {
 		if (StrUtil.isEmpty(message.getWelcomeCode())) {
-			return;
+			return null;
 		}
 		CorpWelcomeTemplate corpWelcomeTemplate = corpWelcomeTemplateMapper.selectById(msgId);
 		if (corpWelcomeTemplate != null) {
@@ -1164,5 +1189,6 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 				});
 			}
 		}
+		return corpWelcomeTemplate;
 	}
 }

+ 0 - 3
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpFollowServiceImpl.java

@@ -156,9 +156,6 @@ public class CorpFollowServiceImpl implements CorpFollowService {
 		} else if (isUpdateAcCode) {
 			corpFollowDynamicConfigService.updateCorpFollowActiveCode(dbActiveCode.getMarkTag(), activeCode.getMarkTag());
 		}
-		if (StrUtil.isEmpty(activeCode.getCouponIds())) {
-			activeCode.setCouponIds(null);
-		}
 		if (activeCode.getMsgId() == null) {
 			activeCode.setMsgId(0l);
 		}

+ 30 - 15
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpTagServiceImpl.java

@@ -421,23 +421,22 @@ public class CorpTagServiceImpl implements CorpTagService {
 	}
 
 	@Override
-	public UserOrderDetailView getTagUserData(Integer start, Integer limit, String tagIdStr, String startTime, String endTime) {
-		UserOrderDetailView u = orderDonMapper.getTagUserData(tagIdStr, startTime, endTime);
-
-		UserOrderDetailView u2 = corpUserTagMapper.countTagUser(tagIdStr, startTime, endTime,null);
-
-		u.setNumOfUser(u2.getNumOfUser());
-		u.setDelNumOfUser(u2.getDelNumOfUser());
-		u.setOrderRate(u.getNumOfUser() == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(u.getNumOfEpOrder()).divide(BigDecimal.valueOf(u.getNumOfUser()), 2, RoundingMode.HALF_DOWN));
-		Page<UserOrderDetailView> records = orderDonMapper.getTagUserDataPage(new Page<>(start, limit), tagIdStr, startTime, endTime);
-		records.getRecords().forEach(e->{
-			String date = e.getDate();
-			UserOrderDetailView userOrderDetailView = corpUserTagMapper.countTagUser(tagIdStr, null, null, date);
-			e.setNumOfUser(userOrderDetailView.getNumOfUser());
+	public Page<UserOrderDetailView> getTagUserData(Integer start, Integer limit, String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime) {
+		Page<UserOrderDetailView> fansRecords = orderDonMapper.getTagUserDataPage(new Page<>(start, limit), tagIdStr, startTime, endTime, consumeStTime, consumeEtTime);
+		fansRecords.getRecords().forEach(e->{
+			//查询当日订单数
+			UserOrderDetailView u2 = orderDonMapper.getFansToDayOrdersView(tagIdStr, e.getDate());
+
+			e.setNumOfOrder(u2.getNumOfOrder());
+			e.setOrderMoney(u2.getOrderMoney());
 		});
+		return fansRecords;
+	}
 
-		u.setRecords(records);
-		return u;
+	@Override
+	public Page<UserOrderDetailView>  getTagUserPastRecord(Integer start, Integer limit, String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime) {
+		Page<UserOrderDetailView> pastRecords = orderDonMapper.getPastRecord(new Page<>(start, limit), tagIdStr, startTime, endTime, consumeStTime, consumeEtTime);
+		return pastRecords;
 	}
 
 	@Override
@@ -445,4 +444,20 @@ public class CorpTagServiceImpl implements CorpTagService {
 		Page<CorpTagUserOrderDataView> records = orderDonMapper.getTagUserTimeOrderData(new Page<>(start, limit), tagIdStr, toDate, startTime, endTime);
 		return records;
 	}
+
+	@Override
+	public UserOrderDetailView tagUserHeadData(String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime) {
+		//被删除用户数,用户数
+		UserOrderDetailView userOrderDetailView = orderDonMapper.getNumOfTagFansUser(tagIdStr, startTime, endTime);
+
+		//订单情况
+		UserOrderDetailView headView = orderDonMapper.getTagUserOrdersData(tagIdStr, startTime, endTime, consumeStTime, consumeEtTime);
+
+		headView.setNumOfUser(userOrderDetailView.getNumOfUser());
+		headView.setDelNumOfUser(userOrderDetailView.getDelNumOfUser());
+
+
+		headView.setOrderRate(headView.getNumOfUser() == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(headView.getNumOfEpOrder()).divide(BigDecimal.valueOf(headView.getNumOfUser()), 2, RoundingMode.HALF_DOWN));
+		return headView;
+	}
 }

+ 1 - 0
netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java

@@ -114,6 +114,7 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 			exchangeCode.setCode(sb.toString());
 			exchangeCode.setUseStatus(false);
 			exchangeCode.setType(exchangeCodeReq.getType());
+			exchangeCode.setOperator(exchangeCodeReq.getOperator());
 			exchangeCodeMapper.insert(exchangeCode);
 			ExcelExchangeCodeData excelExchangeCodeData = new ExcelExchangeCodeData();
 			BeanUtils.copyProperties(exchangeCode, excelExchangeCodeData);

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

@@ -877,7 +877,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
                         }
                         UserDistributeSubRewards thisLevel = thisLevelList.get(0);
                         Integer months = thisLevel.getMonths();
-                        BigDecimal subOrderMoney = orderDonMapper.selectSubChannelOrderMoney(wait.getSubUserId(), subRelate.getCreatedTime(), DateUtil.offsetMonth(subRelate.getCreatedTime(), months));
+                        BigDecimal subOrderMoney = Optional.ofNullable(orderDonMapper.selectSubChannelOrderMoney(wait.getSubUserId(), subRelate.getCreatedTime(), DateUtil.offsetMonth(subRelate.getCreatedTime(), months))).orElse(BigDecimal.ZERO);
                         if (subOrderMoney.compareTo(thisLevel.getTargetAmount()) < 0) {
                             subWaitingMapper.update(null, Wrappers.lambdaUpdate(UserDistributeSubWaiting.class)
                                     .set(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.close)

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

@@ -559,6 +559,8 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 	private void exportBusinessMonthlyData(List<ExcelSheetAndData> excelSheetDataList, Long startTime, Long endTime) {
 		//月付、季付、年付
 		Long nf_goodsId = 1l;
+		Long gpt_goodsId = 18l;
+		Long mj_goodsId = 26l;
 		DateTime thisMonth = DateTime.of(startTime);
 		DateTime nextMonth = DateUtil.offsetMonth(thisMonth, 1);
 		String lastMonth = DateUtil.offsetMonth(thisMonth, -1).toDateStr();
@@ -581,6 +583,9 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 		Integer monthNfRenewNumOfUser = statisticsExportMapper.getMonthNfRenewNumOfUser(nf_goodsId, thisMonth, nextMonth);
 		Integer monthNfNoExRenewNumOfUser = monthNfRenewNumOfUser - monthNfExRenewNumOfUser;
 
+		//奈飞超期购买 中间隔断一个月购买的用户数
+		Integer overNfPayNumOfUser = statisticsExportMapper.getOverPayByGoodsId(nf_goodsId, null, lastMonth, thisMonth, nextMonth);
+
 		//Ai Gpt月付
 		List<Long> gptMonthSkuId = statisticsExportMapper.getAiMonthPlus(18l);
 		//Ai类gptplus当月到期用户数
@@ -593,6 +598,8 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 		Integer monthAiGptRenewNumOfUser = statisticsExportMapper.getMonthAiRenewNumOfUser(gptMonthSkuId, thisMonth, nextMonth);
 		//非当月 续费人数
 		Integer monthAiGptNoExRenewNumOfUser = monthAiGptRenewNumOfUser - monthAiGptExRenewNumOfUser;
+		//超期购买 中间隔断一个月购买的用户数
+		Integer overGptPayNumOfUser = statisticsExportMapper.getOverPayByGoodsId(null, gptMonthSkuId, lastMonth, thisMonth, nextMonth);
 
 		//Ai midjourney 月付
 		List<Long> midJourneyMonthSkuId = statisticsExportMapper.getAiMonthPlus(26l);
@@ -605,6 +612,24 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 		Integer monthAiMidRenewNumOfUser = statisticsExportMapper.getMonthAiRenewNumOfUser(midJourneyMonthSkuId, thisMonth, nextMonth);
 		//非当月 midjourney续费人数
 		Integer monthAiMidNoExRenewNumOfUser = monthAiMidRenewNumOfUser - monthAiMidExRenewNumOfUser;
+		//超期购买 中间隔断一个月购买的用户数
+		Integer overMjPayNumOfUser = statisticsExportMapper.getOverPayByGoodsId(null, midJourneyMonthSkuId, lastMonth, thisMonth, nextMonth);
+
+		//油管年付
+		Long ybGoodsId = 5l;
+		Integer youtubeNumOfRenewals = statisticsExportMapper.getYearNumOfRenewalsByGoodsId(ybGoodsId, lastElevMonth, lastYearMonth);
+		//实际续费人数
+		Integer youtubeActualNumberOfRenewals = statisticsExportMapper.getActualNumberOfRenewalsByGoodsId(ybGoodsId, lastElevMonth, lastYearMonth);
+		//声破天 续费数据
+		Long spGoodsId = 4l;
+		Integer spotifyNumOfRenewals = statisticsExportMapper.getYearNumOfRenewalsByGoodsId(spGoodsId, lastElevMonth, lastYearMonth);
+		//实际续费人数
+		Integer spotifyActualNumberOfRenewals = statisticsExportMapper.getActualNumberOfRenewalsByGoodsId(spGoodsId, lastElevMonth, lastYearMonth);
+		//迪士尼年付
+		Long dsGoodsId = 3l;
+		Integer disneyNumOfRenewals = statisticsExportMapper.getYearNumOfRenewalsByGoodsId(dsGoodsId, lastElevMonth, lastYearMonth);
+		//实际续费人数
+		Integer disneyActualNumberOfRenewals = statisticsExportMapper.getActualNumberOfRenewalsByGoodsId(dsGoodsId, lastElevMonth, lastYearMonth);
 
 		//流媒体当月首单
 		Integer monthStreamingNewNumOfUser = statisticsExportMapper.getMonthStreamingNewNumOfUser(thisMonth, nextMonth);
@@ -659,14 +684,17 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 				.setMonthNfExRenewNumOfUser(monthNfExRenewNumOfUser)
 				.setMonthNfExRePayNumOfUser(monthNfExRePayNumOfUser)
 				.setMonthNfNoExRenewNumOfUser(monthNfNoExRenewNumOfUser)
+				.setOverNfPayNumOfUser(overNfPayNumOfUser)
 				.setMonthAiGptExNumOfUser(monthAiGptExNumOfUser)
 				.setMonthAiGptExRenewNumOfUser(monthAiGptExRenewNumOfUser)
 				.setMonthAiGptExRePayNumOfUser(monthAiGptExRePayNumOfUser)
 				.setMonthAiGptNoExRenewNumOfUser(monthAiGptNoExRenewNumOfUser)
+				.setOverGptPayNumOfUser(overGptPayNumOfUser)
 				.setMonthAiMidExNumOfUser(monthAiMidExNumOfUser)
 				.setMonthAiMidExRenewNumOfUser(monthAiMidExRenewNumOfUser)
 				.setMonthAiMidExRePayNumOfUser(monthAiMidExRePayNumOfUser)
 				.setMonthAiMidNoExRenewNumOfUser(monthAiMidNoExRenewNumOfUser)
+				.setOverMidPayNumOfUser(overMjPayNumOfUser)
 				.setMonthStreamingNewNumOfUser(monthStreamingNewNumOfUser)
 				.setMonthStreamingNewPayOtherNumOfUser(monthStreamingNewPayOtherNumOfUser)
 				.setMonthStreamingNewPayAiNumOfUser(monthStreamingNewPayAiNumOfUser)
@@ -677,6 +705,12 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 				.setMonthlyNewUserOrdersMoney(monthlyNewUserOrdersMoney)
 				.setMonthlyBeforeUserOrders(monthlyBeforeUserOrders)
 				.setMonthlyBeforeUserOrdersMoney(monthlyBeforeUserOrdersMoney)
+				.setYoutubeNumOfRenewals(youtubeNumOfRenewals)
+				.setYoutubeActualNumberOfRenewals(youtubeActualNumberOfRenewals)
+				.setSpotifyNumOfRenewals(spotifyNumOfRenewals)
+				.setSpotifyActualNumberOfRenewals(spotifyActualNumberOfRenewals)
+				.setDisneyNumOfRenewals(disneyNumOfRenewals)
+				.setDisneyActualNumberOfRenewals(disneyActualNumberOfRenewals)
 				;
 //				.setNfTicketNumOfUser(nfTicketNumOfUser)
 //				.setAiTicketNumOfUser(aiTicketNumOfUser)

+ 19 - 6
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -279,6 +279,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final UserDistributeSubWaitingMapper userDistributeSubWaitingMapper;
 
+	private final OrderDonLocationRelateMapper orderDonLocationRelateMapper;
+
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
 
 	@Transactional(rollbackFor = Throwable.class)
@@ -370,8 +372,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		/* 生成订单 */
 		String donNo = SEQUENCE.nextId().toString();
 		OrderDon orderDon = new OrderDon();
-		orderDon.setIp(payRequest.getIp());
-		orderDon.setLocation(payRequest.getLocation());
 
 		orderDon.setIsDp(false);
 		if (isNoLogin != null && isNoLogin) {
@@ -645,6 +645,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			informationClickUserRecord.setOrderId(orderDon.getId());
 			informationClickUserRecordMapper.insert(informationClickUserRecord);
 		}
+		//记录订单ip关联
+		recordOrderDonLocationRelate(orderDon.getId(), payRequest.getIp());
 		return orderDon;
 	}
 
@@ -816,6 +818,10 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 	@Transactional(rollbackFor = Throwable.class)
 	@Override
 	public void closeOrder(Long orderId, Long userId) {
+		String orderCloseKey = RedisService.key.CLOSE_ORDER_TIME_KEY.getName() + orderId;
+		if (!redisService.setNx(orderCloseKey, orderId, RedisService.key.CLOSE_ORDER_TIME_KEY.getTimeout())) {
+			throw BusinessRuntimeException.getInstance("订单正在关闭中..");
+		}
 		//关闭订单逻辑
 		OrderDon orderDon = getById(orderId);
 		if (orderDon == null) {
@@ -973,8 +979,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		/* 生成订单 */
 		String donNo = SEQUENCE.nextId().toString();
 		OrderDon orderDon = new OrderDon();
-		orderDon.setIp(payRequest.getIp());
-		orderDon.setLocation(payRequest.getLocation());
 
 		orderDon.setOrderNo(donNo);
 		orderDon.setOpenId(payOpenId);
@@ -1034,6 +1038,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			orderDonMapper.updateById(updateOrder);
 			return updateOrder;
 		}
+		//记录订单ip关联
+		recordOrderDonLocationRelate(orderDon.getId(), payRequest.getIp());
 		return orderDon;
 	}
 
@@ -2942,8 +2948,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 						Integer months = userDistributeSubReward.getMonths();
 						BigDecimal targetAmount = userDistributeSubReward.getTargetAmount();
 						//是否达到目标额
-						BigDecimal subOrderMoney = orderDonMapper.selectSubChannelOrderMoney(subUserId, userDistributeSub.getCreatedTime(), DateUtil.offsetMonth(userDistributeSub.getCreatedTime(), months));
-						if (subOrderMoney != null && subOrderMoney.compareTo(targetAmount) >= 0) {
+						BigDecimal subOrderMoney = Optional.ofNullable(orderDonMapper.selectSubChannelOrderMoney(subUserId, userDistributeSub.getCreatedTime(), DateUtil.offsetMonth(userDistributeSub.getCreatedTime(), months))).orElse(BigDecimal.ZERO);
+						if (subOrderMoney.compareTo(BigDecimal.ZERO) > 0 && subOrderMoney.compareTo(targetAmount) >= 0) {
 							try {
 								UserDistributeSubWaiting waiting = Optional.ofNullable(userDistributeSubWaitingMapper.selectOne(Wrappers.lambdaQuery(UserDistributeSubWaiting.class)
 										.eq(UserDistributeSubWaiting::getUserId, userId)
@@ -2975,4 +2981,11 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 		}
 	}
+
+	private void recordOrderDonLocationRelate(Long orderId, String ip) {
+		OrderDonLocationRelate orderDonLocationRelate = new OrderDonLocationRelate();
+		orderDonLocationRelate.setOrderId(orderId);
+		orderDonLocationRelate.setIp(ip);
+		orderDonLocationRelateMapper.insert(orderDonLocationRelate);
+	}
 }

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java

@@ -37,7 +37,7 @@ public interface GroupRelationFrontService {
 	/**
 	 * 获取车票账号登录 验证码
 	 */
-	String getAiVerifyCode(Long userId, Long relationId) throws Exception;
+	String getAiVerifyCode(Long userId, Long relationId, Integer type) throws Exception;
 
 
 	void checkGroupsAvailParkingNum(Long skuId, Long groupsId, Integer availableParkingNum, Integer maxNum);

+ 22 - 13
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -441,7 +441,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 	}
 
 	@Override
-	public String getAiVerifyCode(Long userId, Long relationId) throws Exception {
+	public String getAiVerifyCode(Long userId, Long relationId, Integer type) throws Exception {
 		List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
 		RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder().field(RenewalView::getUserId, relationUserIdList).op(Operator.InList)
 				.field(RenewalView::getRelationId, relationId).build());
@@ -465,7 +465,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 			throw BusinessRuntimeException.getInstance("获取账号验证码异常,请联系客服...");
 		}
 		String url = "http://yinhelx.com/api/controller.php";
-		Map<String,Object> params = new HashMap<>();
+		Map<String, Object> params = new HashMap<>();
 
 		params.put("imap_key", "imap_56568niua@@");
 		params.put("fun", "imap_read");
@@ -482,7 +482,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		if (execute.getStatus() != HttpStatus.HTTP_OK) {
 			throw BusinessRuntimeException.getInstance("获取验证码异常,请联系客服...");
 		}
-		String code = getDifferentGoodsCode(renewalView.getGoodsId(), execute.body());
+		String code = getDifferentGoodsCode(renewalView.getGoodsId(), execute.body(), type);
 		GroupsRelationLoginCodeRecord record = new GroupsRelationLoginCodeRecord();
 		record.setUserId(userId);
 		record.setRelationId(relationId);
@@ -591,7 +591,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		UserFuncProperty userFuncProperty = userFuncPropertyMapper.selectOne(Wrappers.lambdaQuery(UserFuncProperty.class).eq(UserFuncProperty::getUserId, userId).last("limit 1"));
 		//默认0次
 		int num = 0;
-		//有安全码 不可查看验证码
+		//有安全码查看次数 置为0
 		if (isHasVerifyCode) {
 			return num;
 		}
@@ -604,20 +604,29 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		return num;
 	}
 
-	public String getDifferentGoodsCode(Long goodsId, String body) {
+	public String getDifferentGoodsCode(Long goodsId, String body, Integer type) {
 		String code = null;
 		//奈飞
 		if (goodsId == 1) {
-			String urlPref = "https://www.netflix.com/account/update-primary-location";
-			code = StrUtil.subBetween(body, "[" + urlPref, "]");
-			if (StrUtil.isEmpty(code)) {
-				urlPref = "https://www.netflix.com/account/travel/verify";
+			if (body.contains("輸入此代碼登入")) {
+				code = StrUtil.subBetween(body, "輸入此代碼登入", "請在裝置上輸入上");
+			} else {
+				String urlPref = "https://www.netflix.com/account/update-primary-location";
 				code = StrUtil.subBetween(body, "[" + urlPref, "]");
 				if (StrUtil.isEmpty(code)) {
-					throw BusinessRuntimeException.getInstance("获取认证链接失败,请重新获取");
+					urlPref = "https://www.netflix.com/account/travel/verify";
+					code = StrUtil.subBetween(body, "[" + urlPref, "]");
+					if (StrUtil.isEmpty(code) && type == null) {
+						throw BusinessRuntimeException.getInstance("获取认证链接失败,请重新获取");
+					}
 				}
+				if (StrUtil.isNotBlank(code)) {
+					return urlPref + code;
+				}
+			}
+			if (type != null && type == 1) {
+				throw BusinessRuntimeException.getInstance("查询失败,请检查是否发送了登陆码..");
 			}
-			return urlPref + code;
 		}
 		//迪士尼
 		if (goodsId == 3) {
@@ -634,14 +643,14 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		code = getVerifyCode(code);
 		if (!Validator.isNumber(code)) {
 			log.error("获取账号验证码失败:{}", StrUtil.subSufByLength(code, 512));
-			throw BusinessRuntimeException.getInstance("获取验证码失败,请重新获取...");
+			throw BusinessRuntimeException.getInstance("获取验证码失败,请重新获取..");
 		}
 		return code.trim();
 	}
 
 	public String getVerifyCode(String code) {
 		if (StrUtil.isNotEmpty(code)) {
-			Pattern pattern = Pattern.compile("\\d{6}");
+			Pattern pattern = Pattern.compile("\\d{4,}");
 			Matcher matcher = pattern.matcher(code);
 			while (matcher.find()) {
 				return matcher.group();

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupsRelationExpiryRecordServiceImpl.java

@@ -52,7 +52,7 @@ public class GroupsRelationExpiryRecordServiceImpl extends ServiceImpl<GroupsRel
 				this.saveOrUpdateBatch(groupsRelationExpiryRecords);
 			}
 		}
-		if (groupsRelationExpiryRecord != null) {
+		if (groupsRelationExpiryRecord != null) { 
 			groupsRelationExpiryRecord.setReBuyGoodsId(goodsDon.getId());
 			groupsRelationExpiryRecord.setReBuyGoodsTitle(goodsDon.getTitle());
 			groupsRelationExpiryRecord.setReBuySkuId(sku.getId());

+ 4 - 0
netflix-service/src/main/java/com/cyksj/service/user/BadIntentionOpService.java

@@ -1,5 +1,9 @@
 package com.cyksj.service.user;
 
+import javax.servlet.http.HttpServletRequest;
+
 public interface BadIntentionOpService {
     void checkHandleBadUserOp(String phone);
+
+    void isBadOpLoginPhone(HttpServletRequest request, String phone);
 }

+ 2 - 1
netflix-service/src/main/java/com/cyksj/service/user/UserService.java

@@ -8,6 +8,7 @@ import com.cyksj.model.entity.User;
 import com.cyksj.model.entity.WxSyncLog;
 import com.cyksj.model.request.LoginReq;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 /**
@@ -44,7 +45,7 @@ public interface UserService extends IService<User> {
 	/**
 	 * 验证码登录
 	 */
-	User webLogin(LoginReq loginReq) throws Exception;
+	User webLogin(LoginReq loginReq, HttpServletRequest request) throws Exception;
 
 	String bindWxAccountRedirect(String code, String state) throws Exception;
 

+ 28 - 0
netflix-service/src/main/java/com/cyksj/service/user/impl/BadIntentionOpServiceImpl.java

@@ -1,12 +1,16 @@
 package com.cyksj.service.user.impl;
 
+import cn.hutool.extra.servlet.ServletUtil;
 import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.StringUtil;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.user.BadIntentionOpService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import javax.servlet.http.HttpServletRequest;
+
 @Service
 @RequiredArgsConstructor
 @Slf4j
@@ -16,6 +20,8 @@ public class BadIntentionOpServiceImpl implements BadIntentionOpService {
     private static final int PHONE_CODE_GET_NUM_DAY_LIMIT = 30;
     private static final int PHONE_CODE_GET_NUM_DAY_MAX_BLACK = 50;
 
+    private static final int PHONE_LOGIN_CODE_RETRY = 10;
+
     @Override
     public void checkHandleBadUserOp(String phone) {
         if ("13662979985".equals(phone)) {
@@ -40,4 +46,26 @@ public class BadIntentionOpServiceImpl implements BadIntentionOpService {
         }
         redisService.set(dayKey, 1, RedisService.key.PHONE_CODE_USER_NUM_KEY_DAY.getTimeout());
     }
+
+    @Override
+    public void isBadOpLoginPhone(HttpServletRequest request, String phone) {
+        String ip = StringUtil.getInternalAddressByIP(ServletUtil.getClientIP(request));
+        String blackIpKey = RedisService.key.BALCK_USER_IP_KEY + ip;
+        if (redisService.hasKey(blackIpKey)) {
+            throw BusinessRuntimeException.getInstance("检测到您操作异常,请联系客服");
+        }
+        String RetryTimeKey = RedisService.key.PHONE_CODE_RETRY_TIME_KEY.getName() + phone;
+        if (redisService.hasKey(RetryTimeKey)) {
+            int i = Integer.parseInt(redisService.get(RetryTimeKey).toString());
+            if (i >= PHONE_LOGIN_CODE_RETRY) {
+                //锁住他的ip
+                redisService.setNx(blackIpKey, ip, RedisService.key.BALCK_USER_IP_KEY.getTimeout());
+                throw BusinessRuntimeException.getInstance("检测到您操作异常,请联系客服");
+            } else {
+                redisService.incr(RetryTimeKey, 1l);
+            }
+        } else {
+            redisService.setNx(RetryTimeKey, 1, RedisService.key.PHONE_CODE_RETRY_TIME_KEY.getTimeout());
+        }
+    }
 }

+ 8 - 5
netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java

@@ -36,6 +36,7 @@ import com.cyksj.service.mange.coupon.CouponCommonService;
 import com.cyksj.service.market.task.BindTaskService;
 import com.cyksj.service.shop.YhShopDistributeService;
 import com.cyksj.service.sys.SysConfigService;
+import com.cyksj.service.user.BadIntentionOpService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.user.UserLoginRecordService;
 import com.cyksj.service.user.UserService;
@@ -50,6 +51,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -117,8 +119,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 
 	private final UserDistributeSharedMapper userDistributeSharedMapper;
 
-	private final UserCertRecordMapper userCertRecordMapper;
-
+	private final BadIntentionOpService badIntentionOpService;
 	private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
 	@Override
@@ -370,9 +371,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 	}
 
 	@Override
-	public User webLogin(LoginReq loginReq) throws Exception {
+	public User webLogin(LoginReq loginReq, HttpServletRequest request) throws Exception {
 		LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class).last("limit 1");
-		if (loginReq.getType() == null || loginReq.getType() < 1 && loginReq.getType() > 2) {
+		if (loginReq.getType() == null || loginReq.getType() < 1 || loginReq.getType() > 3) {
 			throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新操作");
 		}
 		if (loginReq.getType() == 1) {
@@ -391,6 +392,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 				throw BusinessRuntimeException.getInstance("手机验证码已失效,请重新获取");
 			}
 			if (!StrUtil.equals(loginReq.getCode(), phoneCode.getCode())) {
+				//是否是恶意用户
+				badIntentionOpService.isBadOpLoginPhone(request, loginReq.getPhone());
 				throw BusinessRuntimeException.getInstance("手机验证码错误,请重新输入");
 			}
 			wrapper.eq(User::getLoginPhone, loginReq.getPhone());
@@ -409,7 +412,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 			redisService.del(RedisService.key.EMAIL_CODE_KEY.getNameFormat(loginReq.getEmail()));
 			wrapper.eq(User::getEmail, loginReq.getEmail());
 		}
-		if (loginReq.getType() == 3){
+		if (loginReq.getType() == 3) {
 			wrapper.eq(User::getEmail, loginReq.getEmail());
 		}
 		//保存用户信息

+ 4 - 2
netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java

@@ -224,7 +224,8 @@ public class GoodsDonController {
 		    Result<List<YhShopGoodsFrontView>> shopGoods = getShopGoods(yhShopFrontService.getYhsIdByCustomId(customId));
 		    return shopGoods;
 	    }
-	    List<Long> filter_goodsIds = getFilterGoodsIds();
+	    //List<Long> filter_goodsIds = getFilterGoodsIds();
+	    List<Long> filter_goodsIds = null;
 	    String pcCacheKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "PC";
 	    if (CollUtil.isNotEmpty(filter_goodsIds)) {
 		    pcCacheKey += ":hz-ip";
@@ -268,7 +269,8 @@ public class GoodsDonController {
 		    Result<List<YhShopGoodsFrontView>> shopGoods = getShopGoods(yhShopFrontService.getYhsIdByCustomId(customId));
 		    return shopGoods;
 	    }
-	    List<Long> filter_goodsIds = getFilterGoodsIds();
+	    //List<Long> filter_goodsIds = getFilterGoodsIds();
+		List<Long> filter_goodsIds = null;
 	    String h5CacheKey = RedisService.key.YH_HOME_PAGHE_CACHE.getEnvName() + "H5";
 	    if (CollUtil.isNotEmpty(filter_goodsIds)) {
 		    h5CacheKey += ":hz-ip";

+ 3 - 3
netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java

@@ -214,7 +214,7 @@ public class GroupRelationController {
         viewRecord.setUserId(userId);
         viewRecord.setRelationId(relationId);
         viewRecord.setSkuId(groupsRelationView.getSkuId());
-        viewRecord.setOperateLocation(StringUtil.getRealAddressByIP(ServletUtil.getClientIP(request)));
+        viewRecord.setOperateLocation(ServletUtil.getClientIP(request));
         viewRecord.setAccount(groupsRelationView.getTripsAccount());
         viewRecord.setPassword(groupsRelationView.getTripsPassword());
         ticketPwdViewRecordMapper.insert(viewRecord);
@@ -591,9 +591,9 @@ public class GroupRelationController {
      * 读取车票账号登录验证码
      */
     @GetMapping("/get/verifyCode/{relationId}")
-    public Result<String> getAiVerifyCode(@PathVariable Long relationId) throws Exception {
+    public Result<String> getAiVerifyCode(@PathVariable Long relationId, Integer type) throws Exception {
         long userId = StpUserUtil.getLoginIdAsLong();
-        return GatewayResponse.SUCCESS.newBuilder().toResult(groupRelationFrontService.getAiVerifyCode(userId, relationId));
+        return GatewayResponse.SUCCESS.newBuilder().toResult(groupRelationFrontService.getAiVerifyCode(userId, relationId, type));
     }
 
     /**

+ 39 - 2
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java

@@ -49,6 +49,7 @@ import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -103,6 +104,10 @@ public class CmsOrderController {
 
 	private final UserMapper userMapper;
 
+	private final OrderDonMapper orderDonMapper;
+
+	private final OrderDonCustomerServiceRelateMapper orderDonCustomerServiceRelateMapper;
+
 
 	@GetMapping("/get")
 	@SaCheckPermission("order:view")
@@ -208,6 +213,13 @@ public class CmsOrderController {
 				data.setRegister(StrUtil.isNotEmpty(user.getUnionid()) ? "wechat" : StrUtil.isNotEmpty(user.getLoginPhone()) ? "phone" : "email");
 
 			}
+			if (data.getGoodsDonType() != null && data.getGoodsDonType() == 1) {
+				//获取订单关联客服
+				Optional.ofNullable(orderDonMapper.selectOrderRelate(data.getId())).ifPresent(e -> {
+					data.setCmsUserId(e.getCmsUserId());
+					data.setNickname(e.getNickname());
+				});
+			}
 		});
 		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
 	}
@@ -751,10 +763,10 @@ public class CmsOrderController {
 	public Result<SearchResult<RefundOrderDonServiceDataView>> getRefundOrderData(String startTime, String endTime, String operator) {
 		String time = StrUtil.EMPTY;
 		if (StrUtil.isNotBlank(startTime)) {
-			time += String.format(" and rd.created_time >= '%s'", startTime);
+			time += String.format(" and o.created_time >= '%s'", startTime);
 		}
 		if (StrUtil.isNotBlank(endTime)) {
-			time += String.format(" and rd.created_time < '%s'", endTime);
+			time += String.format(" and o.created_time < '%s'", endTime);
 		}
 		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
 		if (StrUtil.isNotBlank(time)) {
@@ -768,7 +780,32 @@ public class CmsOrderController {
 			}
 		}
 		SearchResult<RefundOrderDonServiceDataView> search = beanSearcher.search(RefundOrderDonServiceDataView.class, builder.build());
+		search.getDataList().forEach(e->{
+			String goodsName = orderDonMapper.selectMaxRefundGoodsName(e.getOperator(), startTime, endTime);
+			e.setGoodsName(goodsName);
+		});
 		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
 	}
 
+	/**
+	 * 设置订单客服
+	 */
+	@PutMapping("/set/service")
+	public Result<String> setOrderCustomerService(@RequestBody OrderDonCustomerServiceRelate relate) {
+		OrderDonCustomerServiceRelate orderDonCustomerServiceRelate = orderDonCustomerServiceRelateMapper.selectOne(Wrappers.lambdaQuery(OrderDonCustomerServiceRelate.class)
+				.eq(OrderDonCustomerServiceRelate::getOrderId, relate.getOrderId()).last("limit 1"));
+		if (orderDonCustomerServiceRelate != null) {
+			relate.setId(orderDonCustomerServiceRelate.getId());
+		}
+		try {
+			if (relate.getId() == null) {
+				orderDonCustomerServiceRelateMapper.insert(relate);
+			} else {
+				orderDonCustomerServiceRelateMapper.updateById(relate);
+
+			}
+		} catch (DuplicateKeyException e) {
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
 }

+ 0 - 4
netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/CmsCorpFollowActiveCodeController.java

@@ -37,7 +37,6 @@ import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 
 /** admin/企业微信/客服活码
@@ -144,9 +143,6 @@ public class CmsCorpFollowActiveCodeController {
 	public Result<SearchResult<CorpFollowActiveCodeView>> getActiveCodeList() {
 		SearchResult<CorpFollowActiveCodeView> search = beanSearcher.search(CorpFollowActiveCodeView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
 		search.getDataList().forEach(data -> {
-			if (data.getCouponId() > 0) {
-				Optional.ofNullable(couponMapper.selectById(data.getCouponId())).ifPresent(c -> data.setCouponName(c.getName()));
-			}
 			Integer numOfUser = corpUserMapper.selectCount(Wrappers.lambdaQuery(CorpUser.class)
 					.eq(CorpUser::getAcId, data.getId()));
 			data.setNumOfUser(numOfUser);

+ 25 - 6
netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/CorpTagController.java

@@ -170,17 +170,36 @@ public class CorpTagController {
 	}
 
 	/**
-	 * 通过标签 查找对应用户订单数据
+	 * 按照标签时间,消费时间 查看用户总览
 	 */
-	@GetMapping("/get/tagUser/data")
-	public Result<UserOrderDetailView> getTagUserData(@RequestParam(defaultValue = "1") Integer start, @RequestParam(defaultValue = "10") Integer limit, @RequestParam(required = true) String tagIdStr, String startTime, String endTime) {
+	@GetMapping("/get/tagUser/headData")
+	public Result<UserOrderDetailView> tagUserHeadData(@RequestParam(required = true) String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime) {
 		Assert.notEmpty(tagIdStr, "请输入对应标签");
-		UserOrderDetailView userOrderDetailView = corpTagService.getTagUserData(start, limit, tagIdStr, startTime, endTime);
-		return GatewayResponse.SUCCESS.newBuilder().toResult(userOrderDetailView);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(corpTagService.tagUserHeadData(tagIdStr,startTime,endTime,consumeStTime,consumeEtTime));
 	}
 
 	/**
-	 * 标签用户订单详情
+	 * 通过标签 查找进粉订单记录
+	 */
+	@GetMapping("/get/tagUser/fansData")
+	public Result<Page<UserOrderDetailView> > getTagUserData(@RequestParam(defaultValue = "1") Integer start, @RequestParam(defaultValue = "10") Integer limit, @RequestParam(required = true) String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime) {
+		Assert.notEmpty(tagIdStr, "请输入对应标签");
+		Page<UserOrderDetailView>  page = corpTagService.getTagUserData(start, limit, tagIdStr, startTime, endTime, consumeStTime, consumeEtTime);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(page);
+	}
+
+	/**
+	 * 通过标签 查找标签用户历史订单记录
+	 */
+	@GetMapping("/get/tagUser/pastData")
+	public Result<Page<UserOrderDetailView>> getTagUserPastRecord(@RequestParam(defaultValue = "1") Integer start, @RequestParam(defaultValue = "10") Integer limit, @RequestParam(required = true) String tagIdStr, String startTime, String endTime, String consumeStTime, String consumeEtTime) {
+		Assert.notEmpty(tagIdStr, "请输入对应标签");
+		Page<UserOrderDetailView> page = corpTagService.getTagUserPastRecord(start, limit, tagIdStr, startTime, endTime, consumeStTime, consumeEtTime);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(page);
+	}
+
+	/**
+	 * 当日进粉户订单详情
 	 */
 	@GetMapping("/get/tagUser/time/orderData")
 	public Result<Page<CorpTagUserOrderDataView>> getTagUserTimeOrderData(@RequestParam(defaultValue = "1") Integer start, @RequestParam(defaultValue = "10") Integer limit, @RequestParam(required = true) String tagIdStr, String toDate, String startTime, String endTime) {

+ 9 - 7
netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/WxCorpController.java

@@ -324,9 +324,11 @@ public class WxCorpController {
 			if (user != null && StrUtil.isNotBlank(user.getUnionid())) {
 				builder.field(CorpCustomerAcquistionCallback::getUnionId, user.getUnionid());
 			}
+
+			CorpCustomerAcquistionCallback corpCustomerAcquistionCallback = beanSearcher.searchFirst(CorpCustomerAcquistionCallback.class, builder.build());
+			return GatewayResponse.SUCCESS.newBuilder().toResult(corpCustomerAcquistionCallback);
 		}
-		CorpCustomerAcquistionCallback corpCustomerAcquistionCallback = beanSearcher.searchFirst(CorpCustomerAcquistionCallback.class, builder.build());
-		return GatewayResponse.SUCCESS.newBuilder().toResult(corpCustomerAcquistionCallback);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
 
 	/**
@@ -357,17 +359,17 @@ public class WxCorpController {
 	 * 用户意愿饼图
 	 */
 	@GetMapping("/get/user/intention/pie")
-	public Result<UserIntentionPieView> getUserIntentionPie(String tagId, String date) {
-		UserIntentionPieView userIntentionPieView = corpUserTagMapper.getUserIntentionPie(tagId, date);
-		return GatewayResponse.SUCCESS.newBuilder().toResult(userIntentionPieView);
+	public Result<List<UserIntentionPieView>> getUserIntentionPie(String tagId, String date) {
+		List<UserIntentionPieView> userIntentionPieViews = corpUserTagMapper.getUserIntentionPie(tagId, date);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(userIntentionPieViews);
 	}
 
 	/**
 	 * 标签用户列表
 	 */
 	@GetMapping("/get/tag/user/list")
-	public Result<Page<CorpUserIntentionView>> getCorpUserIntentionView(Long userId, String nickname, String tagId, String date, @RequestParam(defaultValue = "1") Integer start, @RequestParam(defaultValue = "10") Integer limit) {
-		Page<CorpUserIntentionView> page = corpUserTagMapper.getCorpUserIntentionView(new Page<>(start, limit), userId, nickname, tagId, date);
+	public Result<Page<CorpUserIntentionView>> getCorpUserIntentionView(Long userId, String nickname, String tagId, String date, Integer intention, @RequestParam(defaultValue = "1") Integer start, @RequestParam(defaultValue = "10") Integer limit) {
+		Page<CorpUserIntentionView> page = corpUserTagMapper.getCorpUserIntentionView(new Page<>(start, limit), userId, nickname, tagId, date, intention);
 		return GatewayResponse.SUCCESS.newBuilder().toResult(page);
 	}
 }

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

@@ -278,7 +278,9 @@ public class DistributeController {
 		}
 		if (StrUtil.isNotBlank(nickname)) {
 			List<Long> userIds = userMapper.selectListByNickname(nickname);
-			builder.field(UserDistributeViews::getUserId, userIds).op(Operator.InList);
+			if (CollUtil.isNotEmpty(userIds)) {
+				builder.field(UserDistributeViews::getUserId, userIds).op(Operator.InList);
+			}
 		}
 		String timeSql = StrUtil.EMPTY;
 		if (StrUtil.isNotBlank(startTime)) {

+ 8 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/exchange/ExchangeCodeController.java

@@ -1,6 +1,7 @@
 package com.cyksj.web.controller.manage.exchange;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.excel.support.ExcelTypeEnum;
 import com.cyksj.common.annotation.Log;
@@ -8,6 +9,8 @@ import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.manage.cms.CmsUserMapper;
+import com.cyksj.model.entity.CmsUser;
 import com.cyksj.model.excel.ExcelExchangeCodeData;
 import com.cyksj.model.request.ExchangeCodeReq;
 import com.cyksj.model.views.ExchangeCodeView;
@@ -42,6 +45,8 @@ public class ExchangeCodeController {
 
 	private final ExchangeCodeService exchangeCodeService;
 
+	private final CmsUserMapper cmsUserMapper;
+
 	/**
 	 * 生成兑换码 并导出
 	 */
@@ -52,6 +57,9 @@ public class ExchangeCodeController {
 		if (ObjectUtil.hasEmpty(exchangeCodeReq.getGoodsId(), exchangeCodeReq.getSkuId(), exchangeCodeReq.getNumber())) {
 			throw BusinessRuntimeException.getInstance("必填项为空");
 		}
+		long adminId = StpUtil.getLoginIdAsLong();
+		CmsUser cmsUser = cmsUserMapper.selectById(adminId);
+		exchangeCodeReq.setOperator(cmsUser.getNickname());
 		List<ExcelExchangeCodeData> data =  exchangeCodeService.createExchangeCode(exchangeCodeReq);
 		EasyExcelUtils.createExcelStreamMutilByEasyExcel(response, ExcelExchangeCodeData.class, data, "银河兑换码","银河兑换码", ExcelTypeEnum.XLSX, null);
 	}

+ 20 - 10
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -355,11 +355,11 @@ public class StatisticsDataController {
 	}
 
 	@GetMapping("/get/stock")
-	public Result<List<StatisticsStockView>> getStock(HttpServletRequest request, @RequestParam(defaultValue = "0") Long startTime,@RequestParam(defaultValue = "0") Long endTime){
+	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());
 		List<StatisticsStockView> res = new ArrayList<>(goodsDonStocks.size() + 1);
 
-		goodsDonStocks.forEach((stock)->{
+		goodsDonStocks.forEach((stock) -> {
 			List<GoodsDonStockRecord> goodsDonStockRecords = stockRecordMapper.selectList(Wrappers.lambdaQuery(GoodsDonStockRecord.class)
 					.eq(GoodsDonStockRecord::getStockId, stock.getId())
 					.eq(GoodsDonStockRecord::getIsUndo, false)
@@ -378,11 +378,11 @@ public class StatisticsDataController {
 			}
 //			statisticsStockView.setUnavailable(stock.getUnavailable());
 			statisticsStockView.setTitle(stock.getTitle());
-			typeRecordsMap.forEach((type,records)->{
+			typeRecordsMap.forEach((type, records) -> {
 				int sum = records.stream().mapToInt(GoodsDonStockRecord::getNum).sum();
 				BigDecimal price = records.stream().map((record) -> record.getPrice().multiply(BigDecimal.valueOf(record.getNum())))
 						.reduce(BigDecimal.ZERO, BigDecimal::add);
-				statisticsStockView.setTotalWithPrice(type,sum,price);
+				statisticsStockView.setTotalWithPrice(type, sum, price);
 			});
 			res.add(statisticsStockView);
 		});
@@ -391,11 +391,11 @@ public class StatisticsDataController {
 	}
 
 	@GetMapping("/export/stock")
-	public void exportStock(HttpServletRequest request, HttpServletResponse response, @RequestParam(defaultValue = "0") Long startTime,@RequestParam(defaultValue = "0") Long endTime){
+	public void exportStock(HttpServletRequest request, HttpServletResponse response, @RequestParam(defaultValue = "0") Long startTime, @RequestParam(defaultValue = "0") Long endTime) {
 		List<GoodsDonStock> goodsDonStocks = beanSearcher.searchAll(GoodsDonStock.class, MapUtils.flatBuilder(request.getParameterMap()).build());
 		List<StatisticsStockView> res = new ArrayList<>(goodsDonStocks.size() + 1);
 
-		goodsDonStocks.forEach((stock)->{
+		goodsDonStocks.forEach((stock) -> {
 			List<GoodsDonStockRecord> goodsDonStockRecords = stockRecordMapper.selectList(Wrappers.lambdaQuery(GoodsDonStockRecord.class)
 					.eq(GoodsDonStockRecord::getStockId, stock.getId())
 					.eq(GoodsDonStockRecord::getIsUndo, false)
@@ -408,17 +408,17 @@ public class StatisticsDataController {
 			if (put != null) {
 				int sum = put.stream().mapToInt(GoodsDonStockRecord::getAvailable).sum();
 				BigDecimal price = put.stream().map((record) -> record.getPrice().multiply(BigDecimal.valueOf(record.getAvailable())))
-						.reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_EVEN);
+						.reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN);
 				statisticsStockView.setThenTotal(sum);
 				statisticsStockView.setThenPrice(price);
 			}
 //			statisticsStockView.setUnavailable(stock.getUnavailable());
 			statisticsStockView.setTitle(stock.getTitle());
-			typeRecordsMap.forEach((type,records)->{
+			typeRecordsMap.forEach((type, records) -> {
 				int sum = records.stream().mapToInt(GoodsDonStockRecord::getNum).sum();
 				BigDecimal price = records.stream().map((record) -> record.getPrice().multiply(BigDecimal.valueOf(record.getNum())))
-						.reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_EVEN);
-				statisticsStockView.setTotalWithPrice(type,sum,price);
+						.reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN);
+				statisticsStockView.setTotalWithPrice(type, sum, price);
 			});
 			res.add(statisticsStockView);
 		});
@@ -496,6 +496,7 @@ public class StatisticsDataController {
 
 	/**
 	 * 渠道后台数据统计折线图
+	 *
 	 * @return
 	 */
 	@GetMapping("/get/channelStatistics/brokenLine")
@@ -602,4 +603,13 @@ public class StatisticsDataController {
 		});
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
+
+	/**
+	 * 虚拟商品订单客服数据统计
+	 */
+	@GetMapping("/get/order/service/data")
+	public Result<SearchResult<OrderCustomerServiceDataView>> getOrderServiceData() {
+		SearchResult<OrderCustomerServiceDataView> search = beanSearcher.search(OrderCustomerServiceDataView.class, MapUtils.builder().build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
 }

+ 3 - 5
netflix-web/src/main/java/com/cyksj/web/controller/mirror/MirrorController.java

@@ -1,7 +1,6 @@
 package com.cyksj.web.controller.mirror;
 
 import cn.hutool.json.JSONObject;
-import com.baomidou.mybatisplus.extension.api.R;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.common.util.IoKit;
@@ -61,10 +60,9 @@ public class MirrorController {
      * @param relationId 车票id
      */
     @GetMapping("/chatGptMirror/{relationId}")
-    public void chatGptMirror(@PathVariable Long relationId) throws IOException {
+    public Result<String> chatGptMirror(@PathVariable Long relationId) throws IOException {
         Long userId = StpUserUtil.getLoginIdAsLong();
-
-        response.sendRedirect(chatGptAccountService.getLoginUrl(userId, relationId));
+        return GatewayResponse.SUCCESS.newBuilder().toResult(chatGptAccountService.getLoginUrl(userId, relationId));
     }
 
     /**
@@ -221,7 +219,7 @@ public class MirrorController {
      * oai触发车队限制
      */
     @GetMapping("/gpt/car/limited")
-    public Result<String> carLimited(String carId, Integer expTime) {
+    public Result<String> carLimited(String carId, Long expTime) {
         String authorization = request.getHeader("Authorization");
         String userToken = "";
         if(StringUtils.isNotBlank(authorization)){

+ 8 - 3
netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

@@ -136,9 +136,9 @@ public class OrderController {
         log.info("{}[start] params:{}", methodName, payRequest);
 
         String ip = ServletUtil.getClientIP(request);
-        if (StringUtil.getInternalAddressByIP(ip).contains("柬埔寨")) {
-            throw BusinessRuntimeException.getInstance("系统异常");
-        }
+//        if (StringUtil.getInternalAddressByIP(ip).contains("柬埔寨")) {
+//            throw BusinessRuntimeException.getInstance("系统异常");
+//        }
         payRequest.setIp(ip);
 
         OrderDon orderDon = orderDonService.submit(payRequest);
@@ -489,6 +489,11 @@ public class OrderController {
         UserBindDetail userBindDetail = userBindDetailMapper.selectOne(Wrappers.lambdaQuery(UserBindDetail.class)
                 .eq(StrUtil.isNotEmpty(user.getOpenId()), UserBindDetail::getUserId, userId)
                 .eq(StrUtil.isNotEmpty(user.getEmail()), UserBindDetail::getEmailUserId, userId).last("limit 1"));
+        //台湾ip
+        String address = StringUtil.getNewInternalAddressByIp(ServletUtil.getClientIP(request));
+        if (address.contains("台湾") || !address.contains("中国")) {
+            return GatewayResponse.SUCCESS.newBuilder().toResult(true);
+        }
         if (userBindDetail == null || StrUtil.isEmpty(userBindDetail.getPhone())) {
             return GatewayResponse.SUCCESS.newBuilder().toResult(false);
         }

+ 2 - 2
netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

@@ -442,7 +442,7 @@ public class AuthorizationController {
     @PostMapping("/login/phone")
     @NoSubmit
     public Result<UserAuthLoginResp> loginByPhone(@RequestBody LoginReq loginReq) throws Exception {
-        User user = userService.webLogin(loginReq);
+        User user = userService.webLogin(loginReq, request);
         Optional.ofNullable(user.getIsBlack())
                 .ifPresent(black -> {
                     if (black) {
@@ -517,7 +517,7 @@ public class AuthorizationController {
         loginReq.setType(3);
         loginReq.setEmail(googleLoginRep.getEmail());
         loginReq.setSubject(googleLoginRep.getSubject());
-        User user = userService.webLogin(loginReq);
+        User user = userService.webLogin(loginReq, request);
 
         Optional.ofNullable(user.getIsBlack())
                 .ifPresent(black -> {