Explorar o código

Merge branch 'register'

# Conflicts:
#	netflix-dao/src/main/java/com/cyksj/model/entity/RegisterOrderDon.java
#	netflix-dao/src/main/java/com/cyksj/model/views/BackgroundDataView.java
#	netflix-service/src/main/java/com/cyksj/service/register/RegisterOrderDonService.java
#	netflix-service/src/main/java/com/cyksj/service/register/impl/RegisterOrderDonServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/task/Scheduler.java
#	netflix-service/src/main/java/com/cyksj/task/StatisticsDataScheduler.java
#	netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
#	netflix-web/src/main/java/com/cyksj/web/controller/manage/register/CmsRegisterController.java
#	netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java
zoujiajian %!s(int64=3) %!d(string=hai) anos
pai
achega
f9064a4109
Modificáronse 43 ficheiros con 1405 adicións e 60 borrados
  1. 2 0
      netflix-common/src/main/java/com/cyksj/common/constant/TemplateEnum.java
  2. 34 0
      netflix-dao/src/main/java/com/cyksj/mapper/AppleAutoRegisterDataMapper.java
  3. 7 0
      netflix-dao/src/main/java/com/cyksj/mapper/OrderDonMapper.java
  4. 20 0
      netflix-dao/src/main/java/com/cyksj/mapper/RealGoodsInterestUserMapper.java
  5. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/RegisterAccountDataMapper.java
  6. 18 0
      netflix-dao/src/main/java/com/cyksj/mapper/RegisterOrderDonMapper.java
  7. 3 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/statistics/RealGoodsDataMapper.java
  8. 34 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/statistics/StatisticsUserDataMapper.java
  9. 18 10
      netflix-dao/src/main/java/com/cyksj/model/dto/UnifiedOrder.java
  10. 43 0
      netflix-dao/src/main/java/com/cyksj/model/entity/AppleAutoRegisterData.java
  11. 58 0
      netflix-dao/src/main/java/com/cyksj/model/entity/RealGoodsInterestUser.java
  12. 32 0
      netflix-dao/src/main/java/com/cyksj/model/entity/RegisterAccountData.java
  13. 73 1
      netflix-dao/src/main/java/com/cyksj/model/entity/RegisterOrderDon.java
  14. 48 0
      netflix-dao/src/main/java/com/cyksj/model/entity/StatisticsUserData.java
  15. 19 0
      netflix-dao/src/main/java/com/cyksj/model/excel/ExcelAppleIdTemplateData.java
  16. 97 0
      netflix-dao/src/main/java/com/cyksj/model/excel/ExcelRealGoodsUserInterestData.java
  17. 87 0
      netflix-dao/src/main/java/com/cyksj/model/excel/listener/ExcelAppleDataListener.java
  18. 5 0
      netflix-dao/src/main/java/com/cyksj/model/manage/request/RegisterReq.java
  19. 23 0
      netflix-dao/src/main/java/com/cyksj/model/request/UserRealGoodsInterestReq.java
  20. 22 0
      netflix-dao/src/main/java/com/cyksj/model/views/AppleIdCountryOrAreaDataView.java
  21. 21 0
      netflix-dao/src/main/java/com/cyksj/model/views/AppleIdHeadDataView.java
  22. 41 0
      netflix-dao/src/main/java/com/cyksj/model/views/AppleIdRegisterView.java
  23. 7 0
      netflix-dao/src/main/java/com/cyksj/model/views/BackgroundDataView.java
  24. 66 0
      netflix-dao/src/main/java/com/cyksj/model/views/RealGoodsInterestUserView.java
  25. 50 0
      netflix-dao/src/main/java/com/cyksj/model/views/StatisticsUserDataView.java
  26. 40 0
      netflix-dao/src/main/resources/mapper/OrderDonMapper.xml
  27. 27 8
      netflix-dao/src/main/resources/mapper/RealGoodsDataMapper.xml
  28. 4 0
      netflix-service/src/main/java/com/cyksj/common/EnvCommonService.java
  29. 10 0
      netflix-service/src/main/java/com/cyksj/service/mange/statistics/impl/StatisticsDataServiceImpl.java
  30. 7 4
      netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java
  31. 19 0
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  32. 2 0
      netflix-service/src/main/java/com/cyksj/service/register/RegisterOrderDonService.java
  33. 71 7
      netflix-service/src/main/java/com/cyksj/service/register/impl/RegisterOrderDonServiceImpl.java
  34. 33 5
      netflix-service/src/main/java/com/cyksj/service/register/impl/SpotifyServiceImpl.java
  35. 4 2
      netflix-service/src/main/java/com/cyksj/service/wechat/impl/WeChatServiceImpl.java
  36. 59 0
      netflix-service/src/main/java/com/cyksj/task/Scheduler.java
  37. 52 12
      netflix-service/src/main/java/com/cyksj/task/StatisticsDataScheduler.java
  38. 75 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
  39. 2 2
      netflix-web/src/main/java/com/cyksj/web/controller/manage/group/CmsGroupController.java
  40. 74 4
      netflix-web/src/main/java/com/cyksj/web/controller/manage/register/CmsRegisterController.java
  41. 34 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java
  42. 31 5
      netflix-web/src/main/java/com/cyksj/web/controller/register/RegisterController.java
  43. 20 0
      netflix-web/src/main/java/com/cyksj/web/util/EasyExcelUtils.java

+ 2 - 0
netflix-common/src/main/java/com/cyksj/common/constant/TemplateEnum.java

@@ -18,6 +18,8 @@ public enum TemplateEnum {
 	NEW_ORDER_PRD_TEMPLATE("新订单通知正式环境模板", "T88yYYsfhBIKALWGmGTY2ZJGWHx91pcAtinoRGZ0krw", " "),
 	EMPTY_ENV_TEMPLATE("空车位通知测试环境模板", "ArZr9oCJYelqCfn0pU7RQqRbRIWuyRNaU7N_Oo6p2vM", " "),
 	EMPTY_PRD_TEMPLATE("正式环境空车位通知模板", "T88yYYsfhBIKALWGmGTY2ZJGWHx91pcAtinoRGZ0krw", " "),
+	SPOTIFY_ENV_TEMPLATE("Spotify注册测试环境模板", "gsGFRefPlGKfvNoqB5Vd43ZOsmCsZNsH4UDWefWG0sg", " "),
+	SPOTIFY_PRD_TEMPLATE("Spotify注册正式环境模板", "VPQ3cYd_OMYpyHzyaa1X5oOeWh9ZcgwZlrBw_cGqEIA", " "),
 
 	;
 	private String desc;

+ 34 - 0
netflix-dao/src/main/java/com/cyksj/mapper/AppleAutoRegisterDataMapper.java

@@ -0,0 +1,34 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.AppleAutoRegisterData;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.Date;
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: AppleAutoRegisterDataMapper
+ *创建者: JavaZou
+ *创建时间:2022/11/22 16:15
+ */
+public interface AppleAutoRegisterDataMapper extends BaseMapper<AppleAutoRegisterData> {
+	@Select("select count(*)" +
+			" from apple_auto_register_data" +
+			" where status is false and country_or_area = #{countryOrArea}")
+	Integer selectAreaDataView(AppleAutoRegisterData.CountryOrArea countryOrArea);
+
+	@Select("select ad.id from apple_auto_register_data ad left join register_order_don rd on rd.id = ad.order_id" +
+			" where ad.user_id = #{userId} and ad.status = true" +
+			" and ad.country_or_area = #{countryOrArea}" +
+			" and rd.status = 'noPayment'")
+	Integer checkNoPayOrder(@Param("userId") long userId, @Param("countryOrArea") AppleAutoRegisterData.CountryOrArea countryOrArea);
+
+	@Select("select rd.id from apple_auto_register_data ad inner join register_order_don rd on rd.id = ad.order_id" +
+			" where ad.status = true" +
+			" and ad.user_id != 0" +
+			" and rd.status = 'noPayment' and rd.created_time <= #{newDate}")
+	List<Long> getAllNoPayOrders(Date newDate);
+}

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

@@ -2,6 +2,7 @@ package com.cyksj.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.OrderDon;
+import com.cyksj.model.entity.RealGoodsInterestUser;
 import com.cyksj.model.excel.ExcelOrderDonInfo;
 import org.apache.ibatis.annotations.Param;
 
@@ -18,4 +19,10 @@ public interface OrderDonMapper extends BaseMapper<OrderDon> {
     List<ExcelOrderDonInfo> exportOrderInfo(@Param("promotionId") Long promotionId, @Param("start") String start, @Param("end") String end);
 
     List<OrderDon> getAppleOneOrderDons(@Param("appleOne") String appleOne, @Param("skuIds") List<Long> skuIds, @Param("goodsIds") List<Long> goodsIds, @Param("noOrderStatus") List<String> noOrderStatus, @Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+
+	List<RealGoodsInterestUser> selectNoPaymentRealGoods();
+
+	Integer updateHasPaymentInterestRealGoods();
+
+	void updateHasPaymentInterestRealGoodsPayTime();
 }

+ 20 - 0
netflix-dao/src/main/java/com/cyksj/mapper/RealGoodsInterestUserMapper.java

@@ -0,0 +1,20 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.RealGoodsInterestUser;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: RealGoodsInterestUserMapper
+ *创建者: JavaZou
+ *创建时间:2022/11/25 14:41
+ */
+public interface RealGoodsInterestUserMapper extends BaseMapper<RealGoodsInterestUser> {
+
+	@Update("update real_goods_interest_user set sku_id = #{skuId},order_id = #{orderId},order_created_time = #{orderCreatedTime} where id = #{id}")
+	void updateData(@Param("id") Long id, @Param("skuId") Long skuId, @Param("orderCreatedTime") Date orderCreatedTime, @Param("orderId") Long orderId);
+}

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.RegisterAccountData;
+
+/*
+ *项目名: netflix
+ *文件名: RegisterAccountDataMapper
+ *创建者: JavaZou
+ *创建时间:2022/11/24 13:32
+ */
+public interface RegisterAccountDataMapper extends BaseMapper<RegisterAccountData> {
+}

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/mapper/RegisterOrderDonMapper.java

@@ -1,11 +1,29 @@
 package com.cyksj.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.RegisterAccountData;
 import com.cyksj.model.entity.RegisterOrderDon;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.Date;
 
 /**
  * @author chan
  * @date 2022/11/7 2:38 PM
  */
 public interface RegisterOrderDonMapper extends BaseMapper<RegisterOrderDon> {
+
+	@Select("select platform,count(distinct user_id) as numOfUser," +
+			"count(user_id) as numOfOrder,sum(money) as money" +
+			" from register_order_don" +
+			" where created_time between #{yesZeroDate} and #{thisZeroDate} and status != 'noPayment' and platform = #{platform}" +
+			" group by platform")
+	RegisterAccountData registerAccountDataEveryDay(@Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate, @Param("platform") String platform);
+
+	@Select("select count(user_id) as 'numOfRefundOrder',"+
+			"sum(money) as 'refundMoney'" +
+			" from register_order_don" +
+			" where created_time between #{yesZeroDate} and #{thisZeroDate} and status = 'refund' and platform = #{platform}")
+	RegisterAccountData selectRefundOrderDetail(@Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate, @Param("platform") String platform);
 }

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/statistics/RealGoodsDataMapper.java

@@ -2,6 +2,7 @@ package com.cyksj.mapper.manage.statistics;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.RealGoodsData;
+import com.cyksj.model.entity.RegisterAccountData;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.Date;
@@ -15,4 +16,6 @@ import java.util.List;
  */
 public interface RealGoodsDataMapper extends BaseMapper<RealGoodsData> {
 	List<RealGoodsData> statisticsRealGoodsData(@Param("startDate") Date startDate, @Param("endDate") Date endDate);
+
+	List<RegisterAccountData> statisticsRegisterAccountData(@Param("startDate") Date startDate, @Param("endDate") Date endDate);
 }

+ 34 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/statistics/StatisticsUserDataMapper.java

@@ -0,0 +1,34 @@
+package com.cyksj.mapper.manage.statistics;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.StatisticsUserData;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: StatisticsUserDataMapper
+ *创建者: JavaZou
+ *创建时间:2022/11/24 16:21
+ */
+public interface StatisticsUserDataMapper extends BaseMapper<StatisticsUserData> {
+	@Select("select count(distinct unionid) from user where created_time between #{yesZeroDate} and #{thisZeroDate} and unionid != ''")
+	Integer getNumOfNewUser(@Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+
+	@Select("select count(distinct unionid) from user where update_time between #{yesZeroDate} and #{thisZeroDate} and unionid != ''")
+	Integer getNumOfActiveUser(@Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+
+	@Select("select count(distinct unionid) from user where unionid != ''")
+	Integer getWxTotalOfUser();
+
+	@Select("select count(*) from user where login_phone != ''")
+	Integer getPcTotalOfUser();
+
+	@Select("select count(*) from user where created_time between #{yesZeroDate} and #{thisZeroDate} and login_phone != ''")
+	Integer getPcNumOfNewUser(@Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+
+	@Select("select count(*) from user where update_time between #{yesZeroDate} and #{thisZeroDate} and login_phone != ''")
+	Integer getPcNumOfActiveUser(@Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+}

+ 18 - 10
netflix-dao/src/main/java/com/cyksj/model/dto/UnifiedOrder.java

@@ -117,7 +117,8 @@ public class UnifiedOrder {
     private String sceneInfo;
 
     public String println(String shopKey) {
-        return "appid=" + this.appid +
+        StringBuilder sb = new StringBuilder();
+        sb.append("appid=" + this.appid +
                 "&attach=" + this.attach +
                 "&body=" + this.body +
                 "&mch_id=" + this.mchId +
@@ -125,11 +126,14 @@ public class UnifiedOrder {
                 "&notify_url=" + this.notifyUrl +
                 "&openid=" + this.openid +
                 "&out_trade_no=" + this.outTradeNo +
-                "&spbill_create_ip=" + this.spbillCreateIp +
-                "&time_expire=" + this.timeExpire +
-                "&total_fee=" + totalFee +
+                "&spbill_create_ip=" + this.spbillCreateIp);
+        if (this.timeExpire != null) {
+            sb.append("&time_expire=" + this.timeExpire);
+        }
+        sb.append("&total_fee=" + totalFee +
                 "&trade_type=JSAPI" +
-                "&key=" + shopKey;
+                "&key=" + shopKey);
+        return sb.toString();
     }
 
     public String H5Println(String shopKey) {
@@ -148,18 +152,22 @@ public class UnifiedOrder {
     }
 
     public String nativePrintln(String shopKey) {
-        return "appid=" + this.appid +
+        StringBuilder sb = new StringBuilder();
+        sb.append("appid=" + this.appid +
                 "&attach=" + this.attach +
                 "&body=" + this.body +
                 "&mch_id=" + this.mchId +
                 "&nonce_str=" + this.nonceStr +
                 "&notify_url=" + this.notifyUrl +
                 "&out_trade_no=" + this.outTradeNo +
-                "&spbill_create_ip=" + this.spbillCreateIp +
-                "&time_expire=" + this.timeExpire +
-                "&total_fee=" + totalFee +
+                "&spbill_create_ip=" + this.spbillCreateIp);
+        if (this.timeExpire != null) {
+            sb.append("&time_expire=" + this.timeExpire);
+        }
+        sb.append("&total_fee=" + totalFee +
                 "&trade_type=NATIVE" +
-                "&key=" + shopKey;
+                "&key=" + shopKey);
+        return sb.toString();
     }
 
     public String getPrintln(String tradeType, String shopKey) {

+ 43 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/AppleAutoRegisterData.java

@@ -0,0 +1,43 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: AppleAutoRegisterData
+ *创建者: JavaZou
+ *创建时间:2022/11/22 16:16
+ */
+@Getter
+@Setter
+public class AppleAutoRegisterData extends BaseEntity{
+	private String applePwdId;
+
+	private CountryOrArea countryOrArea;
+
+	/**
+	 * 使用状态
+	 */
+	private Boolean status;
+
+	private Long userId;
+
+	private Long orderId;
+
+	private String remark;
+
+	@Getter
+	public enum CountryOrArea {
+		CN_TaiWan("中国台湾"),
+		CN_HongKong("中国香港"),
+		US("美国"),
+		JAPAN("日本"),
+		;
+		String desc;
+
+		CountryOrArea(String desc) {
+			this.desc = desc;
+		}
+	}
+}

+ 58 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/RealGoodsInterestUser.java

@@ -0,0 +1,58 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: RealGoodsInterestUser
+ *创建者: JavaZou
+ *创建时间:2022/11/25 13:57
+ */
+@Getter
+@Setter
+public class RealGoodsInterestUser extends BaseEntity{
+	private Long userId;
+
+	private Long orderId;
+
+	private String remark;
+
+	private Long goodsId;
+
+	private Long skuId;
+
+	@TableField(exist = false)
+	private BigDecimal money;
+
+	@TableField(exist = false)
+	private String groupBy;
+
+	/**
+	 * 意向
+	 */
+	private Status interestStatus;
+
+	/**
+	 * 订单创建时间
+	 */
+	private Date orderCreatedTime;
+
+	@Getter
+	public enum Status{
+		notContacted("未联系"),
+		interest("有意向"),
+		notInterest("无意向"),
+		hasPayment("已购买"),
+		;
+		String desc;
+
+		Status(String desc) {
+			this.desc = desc;
+		}
+	}
+}

+ 32 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/RegisterAccountData.java

@@ -0,0 +1,32 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: RegisterAccountData
+ *创建者: JavaZou
+ *创建时间:2022/11/24 12:17
+ */
+@Getter
+@Setter
+public class RegisterAccountData extends BaseEntity{
+	private String platform;
+
+	private Integer numOfUser;
+
+
+	private Integer numOfOrder;
+
+	private BigDecimal money;
+
+	private Integer numOfRefundOrder;
+
+	private BigDecimal refundMoney;
+
+	private Date statisticsDate;
+}

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

@@ -1,5 +1,11 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -12,32 +18,51 @@ import java.util.Date;
  */
 @Getter
 @Setter
-public class RegisterOrderDon extends BaseEntity{
+@SearchBean(tables = "register_order_don rd left join apple_auto_register_data ad on ad.order_id = rd.id" +
+        " left join user u on rd.user_id = u.id")
+public class RegisterOrderDon{
 
+    @TableId(value = "id",type = IdType.AUTO)
+    @DbField("rd.id")
+    private Long id;
+
+    @DbField("rd.platform")
     private String platform;
 
+    @DbField("rd.nickname")
     private String nickname;
 
+    @DbField("rd.username")
     private String username;
 
+    @DbField("rd.password")
     private String password;
 
+    @DbField("rd.email")
     private String email;
 
+    @DbField("rd.birth_year")
     private String birthYear;
 
+    @DbField("rd.birth_month")
     private String birthMonth;
 
+    @DbField("rd.birth_day")
     private String birthDay;
 
+    @DbField("rd.gender")
     private String gender;
 
+    @DbField("rd.phone")
     private String phone;
 
+    @DbField("rd.country")
     private String country;
 
+    @DbField("rd.order_no")
     private String orderNo;
 
+    @DbField("money")
     private BigDecimal money;
 
     /**
@@ -47,25 +72,72 @@ public class RegisterOrderDon extends BaseEntity{
 
 
     /** 用户id */
+    @DbField("rd.user_id")
     private Long userId ;
 
+    /**
+     * 用户昵称
+     */
+    @DbField("u.nickname")
+    @TableField(exist = false)
+    private String userNickname;
+
     /**
      * openId
      */
+    @DbField("rd.open_id")
     private String openId;
 
     /** 支付状态 */
+    @DbField("rd.status")
     private Status status ;
 
     /**
      * 支付时间
      */
+    @DbField("rd.pay_time")
     private Date payTime;
 
+    @DbField("rd.is_free")
     private Boolean isFree;
 
+    @DbField("rd.error_msg")
     private String errorMsg;
 
+    @DbField("ad.id")
+    @TableField(exist = false)
+    private Long appleAutoId;
+
+    @DbField("if(ad.id is null,false,true)")
+    @TableField(exist = false)
+    private Boolean appleIsAutoType;
+
+    @DbField("ad.apple_pwd_id")
+    @TableField(exist = false)
+    private String applePwdId;
+
+    @DbField("ad.country_or_area")
+    @TableField(exist = false)
+    private AppleAutoRegisterData.CountryOrArea countryOrArea;
+
+    @DbField("ad.remark")
+    @TableField(exist = false)
+    private String remark;
+
+    /**
+     * 创建时间
+     */
+    @DbField("rd.created_time")
+    @TableField(fill = FieldFill.INSERT)
+    private Date createdTime;
+
+    /**
+     * 修改时间
+     */
+    @DbField("rd.update_time")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateTime;
+
     public enum Status {
         /**
          * 订单状态

+ 48 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/StatisticsUserData.java

@@ -0,0 +1,48 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: StatisticsUserData
+ *创建者: JavaZou
+ *创建时间:2022/11/24 16:04
+ */
+@Getter
+@Setter
+public class StatisticsUserData extends BaseEntity{
+	/**
+	 * 总用户数
+	 */
+	private Integer numOfUser;
+
+	/**
+	 * 新用户
+	 */
+	private Integer numOfNewUser;
+
+	/**
+	 * 活跃用户
+	 */
+	private Integer numOfActiveUser;
+
+	/**
+	 * pc端总用户数
+	 */
+	private Integer pcNumOfUser;
+
+	/**
+	 * pc端新用户
+	 */
+	private Integer pcNumOfNewUser;
+
+	/**
+	 * 实时pc端活跃用户
+	 */
+	private Integer pcNumOfActiveUser;
+
+	private Date statisticsDate;
+}

+ 19 - 0
netflix-dao/src/main/java/com/cyksj/model/excel/ExcelAppleIdTemplateData.java

@@ -0,0 +1,19 @@
+package com.cyksj.model.excel;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: ExcelAppleIdTempalteData
+ *创建者: JavaZou
+ *创建时间:2022/11/22 15:37
+ */
+@Getter
+@Setter
+public class ExcelAppleIdTemplateData {
+
+	@ExcelProperty(value = "Apple ID/密码",index = 0)
+	private String applePwdId;
+}

+ 97 - 0
netflix-dao/src/main/java/com/cyksj/model/excel/ExcelRealGoodsUserInterestData.java

@@ -0,0 +1,97 @@
+package com.cyksj.model.excel;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.cyksj.model.entity.RealGoodsInterestUser;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: ExcelRealGoodsUserInterestData
+ *创建者: JavaZou
+ *创建时间:2022/11/25 15:41
+ */
+@Getter
+@Setter
+@SearchBean(tables = "real_goods_interest_user ru " +
+		" left join goods_don_sku gdk on gdk.id = ru.sku_id" +
+		" left join user u on u.id = ru.user_id" +
+		" left join goods_don gd on gd.id = gdk.goods_id" +
+		" left join order_don_transport ot on ot.order_id = ru.order_id")
+public class ExcelRealGoodsUserInterestData {
+
+	@DbField("ru.id")
+	@ExcelIgnore
+	private Long id;
+
+	@DbField("ru.id")
+	@ExcelProperty("用户ID")
+	private Long userId;
+
+	@DbField("ru.goods_id")
+	@ExcelIgnore
+	private Long goodsId;
+
+	@DbField("ru.sku_id")
+	@ExcelIgnore
+	private Long skuId;
+
+	@DbField("ru.order_id")
+	@ExcelIgnore
+	private Long orderId;
+
+	@DbField("u.nickname")
+	@ExcelProperty("用户名称")
+	private String nickname;
+
+	@DbField("ru.order_created_time")
+	@ExcelProperty("创建时间")
+	private Date orderCreatedTime;
+
+	@DbField("ru.pay_time")
+	@ExcelProperty("购买时间")
+	private Date payTime;
+
+	@DbField("gd.title")
+	@ExcelProperty("意向商品")
+	private String goodsTitle;
+
+	@DbField("gdk.spec_val")
+	@ExcelProperty("规格")
+	private String specVal;
+
+	@DbField("cast(gdk.price/100 as decimal(10,0))")
+	@ExcelProperty("金额")
+	private BigDecimal money;
+
+	@DbField("ot.receiver")
+	@ExcelProperty("姓名")
+	private String receiver;
+
+	@DbField("ot.phone")
+	@ExcelProperty("手机号")
+	private String phone;
+
+	@DbField("concat(ot.province,ot.city,ot.district,ot.address)")
+	@ExcelProperty("地址")
+	private String address;
+
+	@DbField("ru.interest_status")
+	@ExcelIgnore
+	private RealGoodsInterestUser.Status interestStatus;
+
+	@DbIgnore
+	@ExcelProperty("意向")
+	private String cnInterestStatus;
+
+	public String getCnInterestStatus() {
+		return interestStatus.getDesc();
+	}
+}

+ 87 - 0
netflix-dao/src/main/java/com/cyksj/model/excel/listener/ExcelAppleDataListener.java

@@ -0,0 +1,87 @@
+package com.cyksj.model.excel.listener;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.mapper.AppleAutoRegisterDataMapper;
+import com.cyksj.model.entity.AppleAutoRegisterData;
+import com.cyksj.model.excel.ExcelAppleIdTemplateData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.DuplicateKeyException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: ExcelAppleDataListener
+ *创建者: JavaZou
+ *创建时间:2022/11/22 15:48
+ */
+public class ExcelAppleDataListener extends AnalysisEventListener<ExcelAppleIdTemplateData> {
+	private static final Logger LOGGER = LoggerFactory.getLogger(ExcelAppleDataListener.class);
+
+	private AppleAutoRegisterDataMapper appleAutoRegisterDataMapper;
+
+	private String countryOrArea;
+
+	private String remark;
+
+	public ExcelAppleDataListener() {
+	}
+
+	public ExcelAppleDataListener(AppleAutoRegisterDataMapper appleAutoRegisterDataMapper, String countryOrArea, String remark) {
+		this.appleAutoRegisterDataMapper = appleAutoRegisterDataMapper;
+		this.countryOrArea = countryOrArea;
+		this.remark = remark;
+	}
+
+	private List<ExcelAppleIdTemplateData> list = new ArrayList<>();
+
+	private static final int BATCH_COUNT = 100;
+
+	@Override
+	public void invoke(ExcelAppleIdTemplateData data, AnalysisContext analysisContext) {
+		LOGGER.info("解析到一条数据:{}", data);
+		if (StrUtil.hasEmpty(data.getApplePwdId())) {
+			throw new BusinessRuntimeException("表格缺少必填参数,请重新确认");
+		}
+		list.add(data);
+		// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
+		if (list.size() >= BATCH_COUNT) {
+			saveData();
+			// 存储完成清理 list
+			list.clear();
+		}
+	}
+
+	@Override
+	public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+		// 这里也要保存数据,确保最后遗留的数据也存储到数据库
+		saveData();
+		list.clear();
+		LOGGER.info("所有数据解析完成!");
+	}
+
+
+	private void saveData() {
+		for (ExcelAppleIdTemplateData data : list) {
+			AppleAutoRegisterData appleAutoRegisterData = new AppleAutoRegisterData();
+			BeanUtil.copyProperties(data, appleAutoRegisterData);
+			AppleAutoRegisterData.CountryOrArea countryOrArea = AppleAutoRegisterData.CountryOrArea.valueOf(this.countryOrArea);
+			if (countryOrArea == null) {
+				throw BusinessRuntimeException.getInstance("该国家或区域不存在");
+			}
+			appleAutoRegisterData.setCountryOrArea(countryOrArea);
+			appleAutoRegisterData.setRemark(remark);
+			try {
+				appleAutoRegisterDataMapper.insert(appleAutoRegisterData);
+			} catch (DuplicateKeyException e) {
+				LOGGER.info("重复Apple ID:{}记录!", data.getApplePwdId());
+			}
+		}
+	}
+}

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

@@ -1,5 +1,6 @@
 package com.cyksj.model.manage.request;
 
+import com.cyksj.model.entity.AppleAutoRegisterData;
 import lombok.Data;
 
 /**
@@ -39,4 +40,8 @@ public class RegisterReq {
     private String phone;
 
     private String nickname;
+
+    private String appleRegisterType;
+
+    private AppleAutoRegisterData.CountryOrArea countryOrArea;
 }

+ 23 - 0
netflix-dao/src/main/java/com/cyksj/model/request/UserRealGoodsInterestReq.java

@@ -0,0 +1,23 @@
+package com.cyksj.model.request;
+
+import com.cyksj.model.entity.RealGoodsInterestUser;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserRealGoodsInterestReq
+ *创建者: JavaZou
+ *创建时间:2022/11/25 15:33
+ */
+@Getter
+@Setter
+public class UserRealGoodsInterestReq {
+	@NonNull
+	private Long id;
+
+	private RealGoodsInterestUser.Status status;
+
+	private String remark;
+}

+ 22 - 0
netflix-dao/src/main/java/com/cyksj/model/views/AppleIdCountryOrAreaDataView.java

@@ -0,0 +1,22 @@
+package com.cyksj.model.views;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: AppleIdHeadDataView
+ *创建者: JavaZou
+ *创建时间:2022/11/22 17:02
+ */
+@Getter
+@Setter
+public class AppleIdCountryOrAreaDataView {
+	private Integer taiWanAvaNum;
+
+	private Integer hongKongAvaNum;
+
+	private Integer usAvaNum;
+
+	private Integer japanAvaNum;
+}

+ 21 - 0
netflix-dao/src/main/java/com/cyksj/model/views/AppleIdHeadDataView.java

@@ -0,0 +1,21 @@
+package com.cyksj.model.views;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: AppleIdHeadDataView
+ *创建者: JavaZou
+ *创建时间:2022/11/22 17:11
+ */
+@Getter
+@Setter
+public class AppleIdHeadDataView {
+
+	private Integer avaAppleIdNum;
+
+	private Integer usedAppleIdNum;
+
+	private AppleIdCountryOrAreaDataView areaDataView;
+}

+ 41 - 0
netflix-dao/src/main/java/com/cyksj/model/views/AppleIdRegisterView.java

@@ -0,0 +1,41 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.AppleAutoRegisterData;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: AppleIdRegisterView
+ *创建者: JavaZou
+ *创建时间:2022/11/22 16:54
+ */
+@Getter
+@Setter
+@SearchBean(tables = "apple_auto_register_data ar left join user u on u.id = ar.user_id")
+public class AppleIdRegisterView {
+	@DbField("ar.id")
+	private Long id;
+
+	@DbField("ar.apple_pwd_id")
+	private String applePwdId;
+
+	@DbField("ar.country_or_area")
+	private AppleAutoRegisterData.CountryOrArea countryOrArea;
+
+	@DbField("ar.status")
+	private Boolean status;
+
+	@DbField("u.id")
+	private Long userId;
+
+	@DbField("u.nickname")
+	private String nickname;
+
+	@DbField("ar.created_time")
+	private Date createdTime;
+}

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

@@ -2,6 +2,7 @@ package com.cyksj.model.views;
 
 import com.cyksj.model.entity.AppleOneData;
 import com.cyksj.model.entity.RealGoodsData;
+import com.cyksj.model.entity.RegisterAccountData;
 import com.cyksj.model.entity.StreamingAccountData;
 import lombok.Getter;
 import lombok.Setter;
@@ -120,4 +121,10 @@ public class BackgroundDataView {
 	 * 实物数据
 	 */
 	private List<RealGoodsData> realGoodsDataViews;
+
+	/**
+	 * 注册账号数据
+	 */
+	private List<RegisterAccountData> registerAccountDataViews;
+
 }

+ 66 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RealGoodsInterestUserView.java

@@ -0,0 +1,66 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.RealGoodsInterestUser;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: RealGoodsInterestUserView
+ *创建者: JavaZou
+ *创建时间:2022/11/25 14:53
+ */
+@Getter
+@Setter
+@SearchBean(tables = "real_goods_interest_user ru " +
+		" left join goods_don_sku gdk on gdk.id = ru.sku_id" +
+		" left join user u on u.id = ru.user_id" +
+		" left join goods_don gd on gd.id = gdk.goods_id")
+public class RealGoodsInterestUserView {
+	@DbField("ru.id")
+	private Long id;
+
+	@DbField("ru.order_id")
+	private Long orderId;
+
+	@DbField("ru.goods_id")
+	private Long goodsId;
+
+	@DbField("ru.sku_id")
+	private Long skuId;
+
+	@DbField("ru.user_id")
+	private Long userId;
+
+	@DbField("u.nickname")
+	private String nickname;
+
+	@DbField("ru.order_created_time")
+	private Date orderCreatedTime;
+
+	@DbField("ru.pay_time")
+	private Date payTime;
+
+	@DbField("gd.logo")
+	private String logo;
+
+	@DbField("gd.title")
+	private String goodsTitle;
+
+	@DbField("gdk.spec_val")
+	private String specVal;
+
+	@DbField("gdk.price")
+	private BigDecimal money;
+
+	@DbField("ru.remark")
+	private String remark;
+
+	@DbField("ru.interest_status")
+	private RealGoodsInterestUser.Status interestStatus;
+}

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

@@ -0,0 +1,50 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.StatisticsUserData;
+import com.ejlchina.searcher.SearchResult;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: StatisticsUserDataView
+ *创建者: JavaZou
+ *创建时间:2022/11/24 17:49
+ */
+@Getter
+@Setter
+public class StatisticsUserDataView {
+	private Integer totalOfUser;
+
+	/**
+	 * 公众号用户数
+	 */
+	private Integer numOfUser;
+
+	/**
+	 * pc端用户数
+	 */
+	private Integer pcNumOfUser;
+
+	/**
+	 * 实时新用户
+	 */
+	private Integer numOfNewUser;
+
+	/**
+	 * 实时活跃用户
+	 */
+	private Integer numOfActiveUser;
+
+	/**
+	 * pc端新用户
+	 */
+	private Integer pcNumOfNewUser;
+
+	/**
+	 * 实时pc端活跃用户
+	 */
+	private Integer pcNumOfActiveUser;
+
+	SearchResult<StatisticsUserData> userData;
+}

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

@@ -2,6 +2,25 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.cyksj.mapper.OrderDonMapper">
 
+    <update id="updateHasPaymentInterestRealGoods">
+        update real_goods_interest_user
+        set interest_status = 'hasPayment'
+        where id in (select id
+                     from (select distinct ru.id
+                           from `real_goods_interest_user` ru
+                                    left join `order_don` od on od.user_id = ru.user_id and od.goods_id = ru.goods_id
+                           where od.status not in ('close', 'noPayment')
+                             and ru.interest_status != 'hasPayment') s)
+    </update>
+
+    <update id="updateHasPaymentInterestRealGoodsPayTime">
+        update real_goods_interest_user ru
+        set ru.pay_time= (select if(pay_time is null,created_time,pay_time) from `order_don` od where od.user_id = ru.user_id and od.goods_id = ru.goods_id order by money desc limit 1),
+            ru.sku_id = (select sku_id from `order_don` od where od.user_id = ru.user_id and od.goods_id = ru.goods_id order by money desc limit 1)
+        where interest_status = 'hasPayment'
+          and pay_time is null
+    </update>
+
 
     <select id="exportOrderInfo" resultType="com.cyksj.model.excel.ExcelOrderDonInfo">
         SELECT o.order_no, o.real_name ,o.price,o.phone,o.source,o.pay_time ,u1.nickname as sharedName,u2.nickname as nickName
@@ -39,4 +58,25 @@
         </foreach>
         where g.title = #{appleOne} and gr.status = 'validity'
     </select>
+
+    <select id="selectNoPaymentRealGoods" resultType="com.cyksj.model.entity.RealGoodsInterestUser">
+        select s.*
+        from (select od.id                     as orderId,
+                     od.user_id,
+                     gd.id                     as goods_id,
+                     od.sku_id,
+                     od.money,
+                     concat(od.user_id, gd.id) as groupBy,
+                     od.created_time           as orderCreatedTime
+              from `order_don` od
+                       left join `goods_don` gd on gd.id = od.goods_id
+                       left join `real_goods_interest_user` ru on ru.user_id = od.user_id
+                  and ru.goods_id = od.goods_id
+              where gd.type = 2
+                and od.status = 'close'
+                and ru.id is null
+              group by od.id, od.user_id, gd.id, od.sku_id, od.money, od.created_time) s
+        where not EXISTS(
+                select id from `order_don` where user_id = s.user_id and goods_id = s.goods_id and status !='close')
+    </select>
 </mapper>

+ 27 - 8
netflix-dao/src/main/resources/mapper/RealGoodsDataMapper.xml

@@ -4,13 +4,13 @@
 <mapper namespace="com.cyksj.mapper.manage.statistics.RealGoodsDataMapper">
 
     <select id="statisticsRealGoodsData" resultType="com.cyksj.model.entity.RealGoodsData">
-        select goods_id,
-               sku_id,
-               max(goods_title) as goods_title,
-               max(spec_val) as spec_val,
-               sum(num_of_user) as num_of_user,
-               sum(num_of_order) as num_of_order,
-               cast(sum(money)/100 as decimal(20,2)) as money
+        select * from (select goods_id,
+        sku_id,
+        max(goods_title) as goods_title,
+        max(spec_val) as spec_val,
+        sum(num_of_user) as num_of_user,
+        sum(num_of_order) as num_of_order,
+        cast(sum(money)/100 as decimal(20,2)) as money
         from real_goods_data
         <where>
             <if test="startDate != null">
@@ -20,6 +20,25 @@
                 and statistics_date &lt; #{endDate}
             </if>
         </where>
-        group by goods_id,sku_id
+        group by goods_id,sku_id)s where s.num_of_user > 0 and num_of_order > 0 and money > 0
+    </select>
+
+    <select id="statisticsRegisterAccountData" resultType="com.cyksj.model.entity.RegisterAccountData">
+        select platform,
+        sum(num_of_user) as numOfUser,
+        sum(num_of_order) as numOfOrder,
+        cast(sum(money)/100 as decimal(20,2)) as money,
+        sum(num_of_refund_order) as numOfRefundOrder,
+        cast(sum(refund_money)/100 as decimal(20,2)) as refundMoney
+        from register_account_data
+        <where>
+            <if test="startDate != null">
+                statistics_date >= #{startDate}
+            </if>
+            <if test="endDate != null">
+                and statistics_date &lt; #{endDate}
+            </if>
+        </where>
+        group by platform
     </select>
 </mapper>

+ 4 - 0
netflix-service/src/main/java/com/cyksj/common/EnvCommonService.java

@@ -27,4 +27,8 @@ public class EnvCommonService {
 	public String getHost() {
 		return domain;
 	}
+
+	public String getDomain() {
+		return this.getHost().substring(0, this.getHost().indexOf("8081"));
+	}
 }

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

@@ -83,9 +83,19 @@ public class StatisticsDataServiceImpl implements StatisticsDataService {
 		getStreamingAccountDataView(backgroundDataView, startDate, endDate);
 		//实物数据
 		getRealGoodsData(backgroundDataView, startDate, endDate);
+		//注册账号数据
+		getRegisterAccountData(backgroundDataView, startDate, endDate);
 		return GatewayResponse.SUCCESS.newBuilder().toResult(backgroundDataView);
 	}
 
+	/**
+	 * 注册账号数据
+	 */
+	private void getRegisterAccountData(BackgroundDataView backgroundDataView, Date startDate, Date endDate) {
+		List<RegisterAccountData> registerAccountData = realGoodsDataMapper.statisticsRegisterAccountData(startDate, endDate);
+		backgroundDataView.setRegisterAccountDataViews(registerAccountData);
+	}
+
 	@Override
 	public IPage<ExpiredAccountDataView> getExpiredAccountView(Integer goodsId, String account, Boolean renewStatus, Boolean handleStatus, String cnAccount, String usAccount, Integer userId, Long startTime, Long endTime, Long start, Long limit) {
 		String startDate = null;

+ 7 - 4
netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java

@@ -4,10 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.cyksj.dto.Result;
 import com.cyksj.model.dto.AliPayParams;
 import com.cyksj.model.dto.H5JsPayParams;
-import com.cyksj.model.entity.GoodsDon;
-import com.cyksj.model.entity.GoodsDonSku;
-import com.cyksj.model.entity.OrderDon;
-import com.cyksj.model.entity.User;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.OrderDonView;
 import com.cyksj.model.request.OrderPayRequest;
 import com.cyksj.model.request.WxOrderRefundReq;
@@ -80,4 +77,10 @@ public interface OrderDonService extends IService<OrderDon> {
      * 发送新订单模板消息
      */
 	void newOderSendMsgByType(OrderDon order, GoodsDon goodsDon, GoodsDonSku sku, User user,String toPeople) throws Exception;
+
+    List<RealGoodsInterestUser> selectNoPaymentRealGoods();
+
+    Integer updateHasPaymentInterestRealGoods();
+
+    void updateHasPaymentInterestRealGoodsPayTime();
 }

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

@@ -379,6 +379,21 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
         weChatService.sendTemplateMessage(weChatService.getAccessToken(), Jsons.toJson(templateMessage));
     }
 
+	@Override
+	public List<RealGoodsInterestUser> selectNoPaymentRealGoods() {
+		return orderDonMapper.selectNoPaymentRealGoods();
+	}
+
+	@Override
+	public Integer updateHasPaymentInterestRealGoods() {
+		return orderDonMapper.updateHasPaymentInterestRealGoods();
+	}
+
+	@Override
+	public void updateHasPaymentInterestRealGoodsPayTime() {
+		orderDonMapper.updateHasPaymentInterestRealGoodsPayTime();
+	}
+
 	@Transactional(rollbackFor = Throwable.class)
 	@Override
 	public void closeOrder(Long orderId) {
@@ -908,6 +923,10 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		String body = Codec.DoBase64.custom()
 				.setData(Jsons.toJson(attach)).encodeAsText();
 		OrderDon orderDon = orderDonMapper.selectById(orderId);
+		if (orderDon.getType() != OrderDon.Type.ALI_PAY) {
+			orderDon.setType(OrderDon.Type.ALI_PAY);
+			orderDonMapper.updateById(orderDon);
+		}
 		GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
 		GoodsDon goodsDon = goodsDonMapper.selectById(goodsDonSku.getGoodsId());
 		if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode)) {

+ 2 - 0
netflix-service/src/main/java/com/cyksj/service/register/RegisterOrderDonService.java

@@ -26,4 +26,6 @@ public interface RegisterOrderDonService extends IService<RegisterOrderDon> {
     Result<String> wxRefund(WxOrderRefundReq wxOrderRefundReq) throws Exception;
 
     void wxRefundNotify(Map<String, String> map) throws Exception;
+
+    void updateAppleAutoStatus(Long orderId);
 }

+ 71 - 7
netflix-service/src/main/java/com/cyksj/service/register/impl/RegisterOrderDonServiceImpl.java

@@ -12,14 +12,13 @@ import com.cyksj.common.util.Jsons;
 import com.cyksj.common.util.Xmls;
 import com.cyksj.config.WeChatConfig;
 import com.cyksj.dto.RedisKey;
+import com.cyksj.mapper.AppleAutoRegisterDataMapper;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.RegisterOrderDonMapper;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.model.dto.H5JsPayParams;
-import com.cyksj.model.entity.RegisterOrderDon;
-import com.cyksj.model.entity.SysConfig;
-import com.cyksj.model.entity.User;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.request.RegisterReq;
 import com.cyksj.model.request.OrderAttach;
 import com.cyksj.model.request.WxOrderRefundReq;
@@ -28,6 +27,7 @@ import com.cyksj.service.register.RegisterOrderDonService;
 import com.cyksj.service.register.SpotifyService;
 import com.cyksj.service.sys.SysConfigService;
 import com.cyksj.service.wechat.WeChatService;
+import com.cyksj.task.JobManager;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -62,6 +62,14 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
 
     private final UserMapper userMapper;
 
+    private final AppleAutoRegisterDataMapper appleAutoRegisterDataMapper;
+
+    private final JobManager jobManager;
+
+    private final RegisterOrderDonMapper registerOrderDonMapper;
+
+    private static final Long EXPIRY_TIME = 1000 * 60 * 5L;
+
     /**
      * 判断是否免费
      * @author chan
@@ -98,7 +106,6 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
         BeanUtil.copyProperties(req,orderDon);
         SysConfig register_price = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "register_price").last("limit 1"));
         Map<String, Integer> map = Jsons.toMap(register_price.getSysValue());
-
         orderDon.setOrderNo(SEQUENCE.nextId() + "");
         orderDon.setUserId(userId);
         orderDon.setOpenId(user.getOpenId());
@@ -106,15 +113,68 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
         orderDon.setMoney(isFree ? BigDecimal.ZERO : BigDecimal.valueOf(map.get(req.getPlatform())));
         orderDon.setStatus(isFree ? RegisterOrderDon.Status.hasPayment : RegisterOrderDon.Status.noPayment);
         save(orderDon);
-
+        //apple
+        handleAppleIdAuto(userId, req, orderDon);
         return orderDon;
     }
 
+    /**
+     *  Apple ID自动注册
+     */
+    private void handleAppleIdAuto(long userId, RegisterReq req, RegisterOrderDon orderDon) {
+        if ("apple".equals(req.getPlatform()) && "auto".equals(req.getAppleRegisterType())) {
+            //是否有未支付的国家或区域的订单
+            Integer exists = appleAutoRegisterDataMapper.checkNoPayOrder(userId, req.getCountryOrArea());
+            if (exists != null) {
+                throw BusinessRuntimeException.getInstance(String.format("您有%s随机生成Apple ID未支付的订单", req.getCountryOrArea().getDesc()));
+            }
+            if (req.getCountryOrArea() == null) {
+                throw BusinessRuntimeException.getInstance("请选择对应的国家或地区");
+            }
+            //查看是否有空余账号
+            AppleAutoRegisterData appleAutoRegisterData = appleAutoRegisterDataMapper.selectOne(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getCountryOrArea, req.getCountryOrArea()).eq(AppleAutoRegisterData::getStatus, false).select(AppleAutoRegisterData::getId).last("limit 1"));
+            if (appleAutoRegisterData == null) {
+                throw BusinessRuntimeException.getInstance("自动生成Apple ID库存不足");
+            }
+            appleAutoRegisterData.setUserId(userId);
+            appleAutoRegisterData.setStatus(true);
+            appleAutoRegisterData.setOrderId(orderDon.getId());
+            int update = appleAutoRegisterDataMapper.update(appleAutoRegisterData, Wrappers.lambdaUpdate(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getStatus, false).eq(AppleAutoRegisterData::getId, appleAutoRegisterData.getId()));
+            if (update != 1) {
+                throw BusinessRuntimeException.getInstance("系统异常,请重新操作");
+            }
+            jobManager.addJob(EXPIRY_TIME, () -> {
+                updateAppleAutoStatus(orderDon.getId());
+            });
+        }
+    }
+
+    @Override
+    public void updateAppleAutoStatus(Long orderId) {
+        log.info("校验appleID自动注册订单 orderId:{}", orderId);
+        RegisterOrderDon registerOrderDon = this.getById(orderId);
+        if (registerOrderDon != null && RegisterOrderDon.Status.noPayment == registerOrderDon.getStatus()) {
+            AppleAutoRegisterData appleAutoRegisterData = appleAutoRegisterDataMapper.selectOne(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getOrderId, orderId).last("limit 1"));
+            if (appleAutoRegisterData != null) {
+                appleAutoRegisterData.setStatus(false);
+                appleAutoRegisterData.setUserId(0l);
+                appleAutoRegisterData.setOrderId(0l);
+                appleAutoRegisterDataMapper.updateById(appleAutoRegisterData);
+                //订单关闭
+                registerOrderDon.setStatus(RegisterOrderDon.Status.close);
+                registerOrderDonMapper.updateById(registerOrderDon);
+                log.info("未支付appleID自动注册订单:{},修改appleID使用状态", orderId);
+            }
+        }
+    }
+
     @Override
     public H5JsPayParams pay(Long orderId) throws Exception {
         log.info("注册 账号调起微信支付[start] orderId:{}", orderId);
         RegisterOrderDon orderDon = this.getById(orderId);
-
+        if (orderDon.getStatus() == RegisterOrderDon.Status.close) {
+            throw BusinessRuntimeException.getInstance("订单已关闭");
+        }
         OrderAttach attach = new OrderAttach();
         attach.setO(orderDon.getId());
 
@@ -130,7 +190,7 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
                 toWechatAttach,
                 "注册服务",
                 "JSAPI",
-                orderDon.getCreatedTime()
+                null
         );
 
         log.info("微信支付成功[end]");
@@ -174,6 +234,10 @@ public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMap
         // 更改订单状态
         order.setTransactionId(transactionId);
         order.setStatus(RegisterOrderDon.Status.hasPayment);
+        AppleAutoRegisterData appleAutoRegisterData = appleAutoRegisterDataMapper.selectOne(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getOrderId, order.getId()).eq(AppleAutoRegisterData::getStatus, true));
+        if (appleAutoRegisterData != null) {
+            order.setStatus(RegisterOrderDon.Status.complete);
+        }
 
         order.setPayTime(DateUtil.parse(map.get("time_end"), "yyyyMMddHHmmss"));
 

+ 33 - 5
netflix-service/src/main/java/com/cyksj/service/register/impl/SpotifyServiceImpl.java

@@ -1,27 +1,29 @@
 package com.cyksj.service.register.impl;
 
-import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.http.Method;
-import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.cyksj.common.EnvCommonService;
+import com.cyksj.common.constant.TemplateEnum;
+import com.cyksj.common.util.Jsons;
 import com.cyksj.dto.RedisKey;
-import com.cyksj.dto.Result;
-import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.ProxysMapper;
 import com.cyksj.mapper.RegisterOrderDonMapper;
+import com.cyksj.model.dto.WxMpTemplateData;
+import com.cyksj.model.dto.WxMpTemplateMessage;
 import com.cyksj.model.entity.Proxys;
 import com.cyksj.model.entity.RegisterOrderDon;
-import com.cyksj.model.entity.SpotifyRegister;
 import com.cyksj.model.response.ProxyInfo;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.register.SpotifyService;
+import com.cyksj.service.wechat.WeChatService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -47,6 +49,10 @@ public class SpotifyServiceImpl implements SpotifyService {
 
     private final RedisService redisService;
 
+    private final EnvCommonService envCommonService;
+
+    private final WeChatService weChatService;
+
     private static final List<String> User_Agent_LIST =  List.of(
             "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
             "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
@@ -202,6 +208,8 @@ public class SpotifyServiceImpl implements SpotifyService {
                         registerOrderDon.setStatus(RegisterOrderDon.Status.complete);
                         registerOrderDonMapper.updateById(registerOrderDon);
                         regFlag = true;
+                        //注册成功发放模板消息
+                        spotifyTemplateMsg(registerOrderDon, String.format("%s%s", envCommonService.getDomain(), "yinhe/web/sign/list"), true);
                         break;
                     } else {
                         if (errors != null && !errors.isEmpty()) {
@@ -213,6 +221,8 @@ public class SpotifyServiceImpl implements SpotifyService {
                             registerOrderDon.setStatus(RegisterOrderDon.Status.error);
                             registerOrderDonMapper.updateById(registerOrderDon);
                             regFlag = true;
+                            //注册失败发放模板消息
+                            spotifyTemplateMsg(registerOrderDon, String.format("%s%s", envCommonService.getDomain(), "yinhe/web/sign/list"), false);
                             break;
                         }
                     }
@@ -233,5 +243,23 @@ public class SpotifyServiceImpl implements SpotifyService {
         }
     }
 
+    private void spotifyTemplateMsg(RegisterOrderDon registerOrderDon, String url, Boolean isSuccess) throws Exception {
+        TemplateEnum templateEnum = null;
+        if (EnvCommonService.active.equals(envCommonService.getEnv())) {
+            templateEnum = TemplateEnum.SPOTIFY_ENV_TEMPLATE;
+        }else {
+            templateEnum = TemplateEnum.SPOTIFY_PRD_TEMPLATE;
+        }
+        WxMpTemplateMessage templateMessage = new WxMpTemplateMessage()
+                .setToUser(registerOrderDon.getOpenId())
+                .setTemplateId(templateEnum.getTemplateId())
+                .setUrl(url);
+        WxMpTemplateMessage.TemplateData data = templateMessage.getData();
+        data.setFirst(new WxMpTemplateData(isSuccess ? "Spotify账号已注册成功" : "Spotify账号注册失败,请修改后重新提交"));
+        data.setKeyword1(new WxMpTemplateData(registerOrderDon.getPhone()));
+        data.setKeyword2(new WxMpTemplateData(DateUtil.format(registerOrderDon.getCreatedTime(), "yyyy-MM-dd HH:mm:ss")));
+        weChatService.sendTemplateMessage(weChatService.getAccessToken(), Jsons.toJson(templateMessage));
+    }
+
 
 }

+ 4 - 2
netflix-service/src/main/java/com/cyksj/service/wechat/impl/WeChatServiceImpl.java

@@ -197,11 +197,13 @@ public class WeChatServiceImpl implements WeChatService {
                 .setNonceStr("chan.123")
                 .setNotifyUrl(notifyUrl)
                 .setOutTradeNo(outTradeNo)
-                //5分钟过期
-                .setTimeExpire(DateUtil.format(DateUtil.offsetMinute(expireTime, 5), "yyyyMMddHHmmss"))
                 .setSpbillCreateIp("127.0.0.1")
                 .setTotalFee(totalFee)
                 .setTradeType(tradeType);
+        if (expireTime != null) {
+            //5分钟过期
+            order.setTimeExpire(DateUtil.format(DateUtil.offsetMinute(expireTime, 5), "yyyyMMddHHmmss"));
+        }
         if (!"NATIVE".equals(tradeType)) {
             order.setOpenid(openid);
         }

+ 59 - 0
netflix-service/src/main/java/com/cyksj/task/Scheduler.java

@@ -14,10 +14,12 @@ import com.cyksj.model.dto.WxMpTemplateMessage;
 import com.cyksj.model.entity.*;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.order.OrderDonService;
+import com.cyksj.service.register.RegisterOrderDonService;
 import com.cyksj.service.register.SpotifyService;
 import com.cyksj.service.wechat.WeChatService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -26,6 +28,8 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Optional;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static com.cyksj.common.constant.WeChatTemplateConst.EXPIRY_TEMPLATE;
 
@@ -62,6 +66,12 @@ public class Scheduler {
 
         private final DistributeWaitingSendPointsMapper distributeWaitingSendPointsMapper;
 
+        private final RegisterOrderDonService registerOrderDonService;
+
+        private final AppleAutoRegisterDataMapper appleAutoRegisterDataMapper;
+
+        private final RealGoodsInterestUserMapper realGoodsInterestUserMapper;
+
 
     /**
      * 每5分钟清理过期账号
@@ -238,4 +248,53 @@ public class Scheduler {
             }
         });
     }
+
+    /**
+     * 定时更新未支付AppleID自动注册订单
+     */
+    @Scheduled(cron = "0 0/5 * * * ?")
+    public void updateAppleAutoStatus() {
+        //获取为支付订单
+        DateTime now = new DateTime();
+        Date newDate = DateUtil.offset(now, DateField.MINUTE, -5);
+        List<Long> orderDons = appleAutoRegisterDataMapper.getAllNoPayOrders(newDate);
+        log.info("定时更新未支付AppleID自动注册订单 订单数:{}",orderDons.size());
+        orderDons.forEach((orderId)->{
+            registerOrderDonService.updateAppleAutoStatus(orderId);
+        });
+    }
+
+    /**
+     * 实物订单意愿数据
+     */
+    @Scheduled(cron = "0 0/5 * * * ?")
+    public void realGoodsInterestUser() {
+        Optional.ofNullable(orderDonService.selectNoPaymentRealGoods()).ifPresent(list -> {
+                    if (list.size() > 0) {
+                        Map<String, List<RealGoodsInterestUser>> collect = list.stream().collect(Collectors.groupingBy(RealGoodsInterestUser::getGroupBy));
+                        log.info("实物订单意愿数据同步开始");
+                        collect.forEach((k, data) -> {
+                            RealGoodsInterestUser realGoodsInterestUser = null;
+                            if (data.size() == 0) {
+                                realGoodsInterestUser = data.get(0);
+                            } else {
+                                List<RealGoodsInterestUser> high = data.stream().sorted(Comparator.comparing(RealGoodsInterestUser::getMoney).thenComparing(RealGoodsInterestUser::getOrderCreatedTime).reversed()).collect(Collectors.toList());
+                                realGoodsInterestUser = high.get(0);
+                            }
+                            try {
+                                realGoodsInterestUserMapper.insert(realGoodsInterestUser);
+                            } catch (DuplicateKeyException e) {
+                                log.info("重复插入用户相同实物商品记录");
+                            }
+                        });
+                        log.info("实物订单意愿数据同步结束");
+                    }
+                }
+        );
+        Integer update = orderDonService.updateHasPaymentInterestRealGoods();
+        orderDonService.updateHasPaymentInterestRealGoodsPayTime();
+        if (update > 0) {
+            log.info("更新用户记录:{}已购买实物意愿商品状态成功", update);
+        }
+    }
 }

+ 52 - 12
netflix-service/src/main/java/com/cyksj/task/StatisticsDataScheduler.java

@@ -6,8 +6,11 @@ import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.mapper.GoodsDonMapper;
+import com.cyksj.mapper.RegisterAccountDataMapper;
+import com.cyksj.mapper.RegisterOrderDonMapper;
 import com.cyksj.mapper.manage.statistics.AppleOneDataMapper;
 import com.cyksj.mapper.manage.statistics.RealGoodsDataMapper;
+import com.cyksj.mapper.manage.statistics.StatisticsUserDataMapper;
 import com.cyksj.mapper.manage.statistics.StreamingAccountDataMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.service.mange.CmsAccountService;
@@ -50,13 +53,21 @@ public class StatisticsDataScheduler {
 	public static List<String> noOrderStatus = List.of("close", "noPayment");
 
 	public static List<String> payType = List.of("月", "季", "年");
-	
+
+	private final static List<String> registerAccount = List.of("apple", "spotify", "google");
+
 	private static Long DAY_MILLS = 86400000l;
 
 	private final GoodsDonMapper goodsDonMapper;
 
 	private final RealGoodsDataMapper realGoodsDataMapper;
 
+	private final RegisterOrderDonMapper registerOrderDonMapper;
+
+	private final RegisterAccountDataMapper registerAccountDataMapper;
+
+	private final StatisticsUserDataMapper statisticsUserDataMapper;
+
 	/**
 	 * 后台数据统计 定时器
 	 */
@@ -69,8 +80,47 @@ public class StatisticsDataScheduler {
 		//统计流媒体账号数据
 		TASK_POOL.execute(() -> statisticsStreamingAccountData(yesZeroDate, thisZeroDate));
 		//统计实物数据
-		statisticsRealGoodsData(yesZeroDate, thisZeroDate);
+		TASK_POOL.execute(()->statisticsRealGoodsData(yesZeroDate, thisZeroDate));
+		//注册账号数据
+		TASK_POOL.execute(() -> statisticsRegisterAccountData(yesZeroDate, thisZeroDate));
+		//用户数据统计
+		statisticsUserData(yesZeroDate, thisZeroDate);
+
+	}
+
+	/**
+	 * 用户数据统计
+	 */
+	private void statisticsUserData(Date yesZeroDate, Date thisZeroDate) {
+		StatisticsUserData yesData = statisticsUserDataMapper.selectOne(Wrappers.lambdaQuery(StatisticsUserData.class).orderByDesc(StatisticsUserData::getId).select(StatisticsUserData::getNumOfUser, StatisticsUserData::getPcNumOfUser).last("limit 1"));
+		Integer yesNumOfUser = yesData == null ? 0 : yesData.getNumOfUser();
+		Integer yesPcNumOfUser = yesData == null ? 0 : yesData.getPcNumOfUser();
+		StatisticsUserData statisticsUserData = new StatisticsUserData();
+		statisticsUserData.setNumOfNewUser(statisticsUserDataMapper.getNumOfNewUser(yesZeroDate, thisZeroDate));
+		statisticsUserData.setNumOfActiveUser(statisticsUserDataMapper.getNumOfActiveUser(yesZeroDate, thisZeroDate));
+		statisticsUserData.setNumOfUser(yesNumOfUser + statisticsUserData.getNumOfNewUser());
+
+		statisticsUserData.setPcNumOfNewUser(statisticsUserDataMapper.getPcNumOfNewUser(yesZeroDate, thisZeroDate));
+		statisticsUserData.setPcNumOfActiveUser(statisticsUserDataMapper.getPcNumOfActiveUser(yesZeroDate, thisZeroDate));
+		statisticsUserData.setPcNumOfUser(yesPcNumOfUser + statisticsUserData.getPcNumOfNewUser());
 
+		statisticsUserData.setStatisticsDate(yesZeroDate);
+		statisticsUserDataMapper.insert(statisticsUserData);
+	}
+
+	/**
+	 * 注册账号数据
+	 */
+	private void statisticsRegisterAccountData(Date yesZeroDate, Date thisZeroDate) {
+		registerAccount.forEach(platform->{
+			RegisterAccountData entity = Optional.ofNullable(registerOrderDonMapper.registerAccountDataEveryDay(yesZeroDate, thisZeroDate, platform)).orElse(new RegisterAccountData());
+			entity.setPlatform(platform);
+			RegisterAccountData dto = Optional.ofNullable(registerOrderDonMapper.selectRefundOrderDetail(yesZeroDate, thisZeroDate, platform)).orElse(new RegisterAccountData());
+			entity.setNumOfRefundOrder(dto.getNumOfRefundOrder());
+			entity.setRefundMoney(dto.getRefundMoney());
+			entity.setStatisticsDate(yesZeroDate);
+			registerAccountDataMapper.insert(entity);
+		});
 	}
 
 	/**
@@ -123,12 +173,6 @@ public class StatisticsDataScheduler {
 			if (money.isPresent()) {
 				appleOne.setMoney(money.get());
 			} else appleOne.setMoney(BigDecimal.ZERO);
-
-			List<OrderDon> distributeOrders = Optional.ofNullable(orderDons.stream().filter(ord -> ord.getIsDistribute()).collect(Collectors.toList())).orElse(new ArrayList<>());
-			appleOne.setNumOfDistributeOrder(distributeOrders.size());
-			Optional<BigDecimal> distributeMoney = distributeOrders.stream().map(OrderDon::getMoney).reduce(BigDecimal::add);
-			appleOne.setDistributeOrderMoney(distributeMoney.isPresent() ? distributeMoney.get() : BigDecimal.ZERO);
-
 			getNumOfOrderByPayType(orderDons, appleOne);
 		}
 		appleOneSave.add(appleOne);
@@ -219,10 +263,6 @@ public class StatisticsDataScheduler {
 			}
 			//金额
 			streamingAccountData.setMoney(totalMoney);
-			List<OrderDon> distributeOrders = Optional.ofNullable(orderDons.stream().filter(ord -> ord.getIsDistribute()).collect(Collectors.toList())).orElse(new ArrayList<>());
-			streamingAccountData.setNumOfDistributeOrder(distributeOrders.size());
-			Optional<BigDecimal> distributeMoney = distributeOrders.stream().map(OrderDon::getMoney).reduce(BigDecimal::add);
-			streamingAccountData.setDistributeOrderMoney(distributeMoney.isPresent() ? distributeMoney.get() : BigDecimal.ZERO);
 		}
 		dataSave.add(streamingAccountData);
 	}

+ 75 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java

@@ -1,23 +1,34 @@
 package com.cyksj.web.controller.manage;
 
+import com.alibaba.excel.support.ExcelTypeEnum;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.RealGoodsInterestUserMapper;
 import com.cyksj.model.entity.OrderDon;
 import com.cyksj.model.entity.OrderDonWaybill;
+import com.cyksj.model.entity.RealGoodsInterestUser;
+import com.cyksj.model.excel.ExcelRealGoodsUserInterestData;
 import com.cyksj.model.manage.request.ReqSetLogisticsPost;
 import com.cyksj.model.manage.views.OrderDonView;
+import com.cyksj.model.request.UserRealGoodsInterestReq;
+import com.cyksj.model.views.RealGoodsInterestUserView;
 import com.cyksj.model.views.OrderDonTransportView;
 import com.cyksj.service.mange.CmsOrderDonService;
 import com.cyksj.service.user.UserService;
+import com.cyksj.web.util.EasyExcelUtils;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapBuilder;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.util.List;
 
 /**
  * @author chan
@@ -38,6 +49,8 @@ public class CmsOrderController {
 
     private final BeanSearcher beanSearcher;
 
+    private final RealGoodsInterestUserMapper realGoodsInterestUserMapper;
+
 
     @GetMapping("/get")
     public Result<SearchResult<OrderDonView>> get(){
@@ -65,4 +78,66 @@ public class CmsOrderController {
         return GatewayResponse.SUCCESS.newBuilder().toResult(orderDonWaybill);
     }
 
+    /**
+     * 用户购买实物商品意愿列表
+     */
+    @GetMapping("/get/realGooods/interest/users")
+    public Result<SearchResult<RealGoodsInterestUserView>> getInterestUserList(RealGoodsInterestUser.Status interestStatus,HttpServletRequest request) {
+        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+        if (interestStatus == null) {
+            builder.field(RealGoodsInterestUserView::getInterestStatus, "hasPayment").op(Operator.NotEqual);
+        }
+        SearchResult<RealGoodsInterestUserView> search = beanSearcher.search(RealGoodsInterestUserView.class, builder.build());
+        search.getDataList().forEach(data->{
+            Long goodsId = data.getGoodsId();
+            OrderDon order = cmsOrderDonService.getOne(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getUserId, data.getUserId()).eq(OrderDon::getGoodsId, goodsId).ne(OrderDon::getId, data.getId()).gt(OrderDon::getMoney, data.getMoney()).eq(OrderDon::getStatus, "close").last("limit 1"));
+            if (order != null) {
+                data.setOrderId(order.getId());
+                data.setSkuId(order.getSkuId());
+                data.setMoney(order.getMoney());
+                data.setOrderCreatedTime(order.getCreatedTime());
+                realGoodsInterestUserMapper.updateData(data.getId(), data.getSkuId(), data.getOrderCreatedTime(), data.getOrderId());
+            }
+        });
+        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+    }
+
+    /**
+     * 修改购买意愿记录
+     */
+    @PutMapping("/put/interest")
+    public Result<String> updateInterest(@RequestBody @Validated UserRealGoodsInterestReq req) {
+        RealGoodsInterestUser realGoodsInterestUser = realGoodsInterestUserMapper.selectById(req.getId());
+        if (realGoodsInterestUser != null) {
+            if (req.getStatus() != null) {
+                realGoodsInterestUser.setInterestStatus(req.getStatus());
+            }
+            if (req.getRemark() != null) {
+                realGoodsInterestUser.setRemark(req.getRemark());
+            }
+            realGoodsInterestUserMapper.updateById(realGoodsInterestUser);
+        }
+        return GatewayResponse.SUCCESS.newBuilder().toResult("修改成功");
+    }
+
+    /**
+     * 导出用户意愿列表
+     */
+    @GetMapping("/export/interest")
+    public void exportInterest(HttpServletRequest request, HttpServletResponse response) {
+        List<ExcelRealGoodsUserInterestData> excelRealGoodsUserInterestData = beanSearcher.searchAll(ExcelRealGoodsUserInterestData.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+        excelRealGoodsUserInterestData.forEach(data -> {
+            Long goodsId = data.getGoodsId();
+            OrderDon order = cmsOrderDonService.getOne(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getUserId, data.getUserId()).eq(OrderDon::getGoodsId, goodsId).ne(OrderDon::getId, data.getId()).gt(OrderDon::getMoney, data.getMoney()).eq(OrderDon::getStatus, "close").last("limit 1"));
+            if (order != null) {
+                data.setOrderId(order.getId());
+                data.setSkuId(order.getSkuId());
+                data.setMoney(order.getMoney());
+                data.setOrderCreatedTime(order.getCreatedTime());
+                realGoodsInterestUserMapper.updateData(data.getId(), data.getSkuId(), data.getOrderCreatedTime(), data.getOrderId());
+            }
+        });
+        EasyExcelUtils.createExcelStreamMutilByEasyExcel(response, ExcelRealGoodsUserInterestData.class, excelRealGoodsUserInterestData, "用户意愿列表", "用户意愿列表", ExcelTypeEnum.XLSX, null);
+    }
+
 }

+ 2 - 2
netflix-web/src/main/java/com/cyksj/web/controller/manage/group/CmsGroupController.java

@@ -1,13 +1,12 @@
 package com.cyksj.web.controller.manage.group;
 
+import com.cyksj.common.annotation.NoSubmit;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.model.entity.Account;
-import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.GroupsTrips;
-import com.cyksj.model.manage.views.AccountView;
 import com.cyksj.service.mange.CmsAccountService;
 import com.cyksj.service.mange.CmsGoodsDonSkuService;
 import com.cyksj.service.mange.CmsGroupService;
@@ -67,6 +66,7 @@ public class CmsGroupController {
     }
 
     @PostMapping("/post")
+    @NoSubmit
     public Result<GroupsTrips> add(@RequestBody GroupsTrips groups){
 
         GroupsTrips groupsTrips = groupService.issuance(groups);

+ 74 - 4
netflix-web/src/main/java/com/cyksj/web/controller/manage/register/CmsRegisterController.java

@@ -1,26 +1,38 @@
 package com.cyksj.web.controller.manage.register;
 
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import cn.hutool.core.util.StrUtil;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.util.IoKit;
 import com.cyksj.common.util.Xmls;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.AppleAutoRegisterDataMapper;
+import com.cyksj.model.entity.AppleAutoRegisterData;
 import com.cyksj.model.entity.RegisterOrderDon;
+import com.cyksj.model.excel.ExcelAppleIdTemplateData;
+import com.cyksj.model.excel.listener.ExcelAppleDataListener;
+import com.cyksj.model.views.AppleIdCountryOrAreaDataView;
+import com.cyksj.model.views.AppleIdHeadDataView;
+import com.cyksj.model.views.AppleIdRegisterView;
 import com.cyksj.model.request.WxOrderRefundReq;
 import com.cyksj.service.register.RegisterOrderDonService;
+import com.cyksj.web.util.EasyExcelUtils;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapBuilder;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.OutputStream;
-import java.util.Map;
 
 /**
  * @author chan
@@ -38,9 +50,25 @@ public class CmsRegisterController {
 
     private final HttpServletRequest request;
 
+    private final AppleAutoRegisterDataMapper appleAutoRegisterDataMapper;
+
     @GetMapping("/get")
-    public Result<SearchResult<RegisterOrderDon>> get(){
-        SearchResult<RegisterOrderDon> search = beanSearcher.search(RegisterOrderDon.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+    public Result<SearchResult<RegisterOrderDon>> get(Boolean appleIsAutoType) {
+        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+        if (appleIsAutoType != null) {
+            if (appleIsAutoType) {
+                builder.field(RegisterOrderDon::getAppleAutoId).op(Operator.NotNull);
+            }else {
+                builder.field(RegisterOrderDon::getAppleAutoId).op(Operator.IsNull);
+            }
+        }
+        SearchResult<RegisterOrderDon> search = beanSearcher.search(RegisterOrderDon.class, builder.build());
+        search.getDataList().forEach(data->{
+            if (data.getAppleIsAutoType()) {
+                data.setCountry(data.getCountryOrArea().getDesc());
+                data.setEmail(data.getApplePwdId());
+            }
+        });
         return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
 
@@ -50,7 +78,49 @@ public class CmsRegisterController {
         return GatewayResponse.SUCCESS.newBuilder().toResult(registerOrderDon);
     }
 
+    /**
+     * 下载apple id 导入模板
+     */
+    @GetMapping("/get/appleId/template")
+    public void appleIdTemplate(HttpServletResponse response) {
+        EasyExcelUtils.createTemplateExcel(response, ExcelAppleIdTemplateData.class, "导入模板", "导入模板", ExcelTypeEnum.XLSX, null);
+    }
+
+    /**
+     * 导入apple Id注册数据
+     */
+    @PostMapping("/export/appleId/data")
+    public Result<String> exportRegisterAppleData(MultipartFile file, String remark, String countryOrArea) throws Exception {
+        EasyExcel.read(file.getInputStream(), ExcelAppleIdTemplateData.class, new ExcelAppleDataListener(appleAutoRegisterDataMapper, countryOrArea, remark)).sheet().doRead();
+        return GatewayResponse.SUCCESS.newBuilder().toResult("导入数据成功");
+    }
+
+    /**
+     * apple ID注册数据列表
+     */
+    @GetMapping("/get/appleId/list")
+    public Result<SearchResult<AppleIdRegisterView>> getAppleIdList(HttpServletRequest request) {
+        return GatewayResponse.SUCCESS.newBuilder().toResult(beanSearcher.search(AppleIdRegisterView.class, MapUtils.flatBuilder(request.getParameterMap()).build()));
+    }
 
+    /**
+     * apple ID头部数据
+     */
+    @GetMapping("/get/appleId/head")
+    public Result<AppleIdHeadDataView> getAppleIdHeadDataView() {
+        AppleIdCountryOrAreaDataView appleIdCountryOrAreaDataView = new AppleIdCountryOrAreaDataView();
+        appleIdCountryOrAreaDataView.setJapanAvaNum(appleAutoRegisterDataMapper.selectAreaDataView(AppleAutoRegisterData.CountryOrArea.JAPAN));
+        appleIdCountryOrAreaDataView.setHongKongAvaNum(appleAutoRegisterDataMapper.selectAreaDataView(AppleAutoRegisterData.CountryOrArea.CN_HongKong));
+        appleIdCountryOrAreaDataView.setUsAvaNum(appleAutoRegisterDataMapper.selectAreaDataView(AppleAutoRegisterData.CountryOrArea.US));
+        appleIdCountryOrAreaDataView.setTaiWanAvaNum(appleAutoRegisterDataMapper.selectAreaDataView(AppleAutoRegisterData.CountryOrArea.CN_TaiWan));
+        AppleIdHeadDataView appleIdHeadDataView = new AppleIdHeadDataView();
+        appleIdHeadDataView.setAreaDataView(appleIdCountryOrAreaDataView);
+        Integer avaAppleIdNum = appleAutoRegisterDataMapper.selectCount(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getStatus, false));
+        appleIdHeadDataView.setAvaAppleIdNum(avaAppleIdNum);
+        Integer usedAppleIdNum = appleAutoRegisterDataMapper.selectCount(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getStatus, true));
+        appleIdHeadDataView.setUsedAppleIdNum(usedAppleIdNum);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(appleIdHeadDataView);
+    }
     /**
      * 微信订单退款
      */

+ 34 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -1,10 +1,15 @@
 package com.cyksj.web.controller.manage.statistics;
 
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.manage.statistics.StatisticsUserDataMapper;
+import com.cyksj.model.entity.StatisticsUserData;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.manage.statistics.IncrExpiryTimeRecordMapper;
 import com.cyksj.model.entity.GroupsRelation;
@@ -12,10 +17,13 @@ import com.cyksj.model.entity.IncrExpiryTimeRecord;
 import com.cyksj.model.request.RenewTimeUpReq;
 import com.cyksj.model.views.BackgroundDataView;
 import com.cyksj.model.views.ExpiredAccountDataView;
+import com.cyksj.model.views.StatisticsUserDataView;
 import com.cyksj.service.mange.statistics.StatisticsDataService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.util.MapUtils;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -43,6 +51,10 @@ public class StatisticsDataController {
 
 	private final BeanSearcher beanSearcher;
 
+	private final UserMapper userMapper;
+
+	private final StatisticsUserDataMapper statisticsUserDataMapper;
+
 	/**
 	 * 查询统计数据
 	 */
@@ -119,4 +131,26 @@ public class StatisticsDataController {
 	public Result<SearchResult<IncrExpiryTimeRecord>> getOpRecord(HttpServletRequest request) {
 		return GatewayResponse.SUCCESS.newBuilder().toResult(beanSearcher.search(IncrExpiryTimeRecord.class, MapUtils.flatBuilder(request.getParameterMap()).build()));
 	}
+
+	/**
+	 * 总用户数列表
+	 */
+	@GetMapping("/get/user/data")
+	public Result<StatisticsUserDataView> getUserData(HttpServletRequest request) {
+		StatisticsUserDataView statisticsUserDataView = new StatisticsUserDataView();
+		DateTime now = DateTime.now();
+		DateTime thisZero = DateUtil.beginOfDay(now);
+		DateTime thisEnd = DateUtil.endOfDay(now);
+		Integer wxUserNum = statisticsUserDataMapper.getWxTotalOfUser();
+		Integer pcUserNum = statisticsUserDataMapper.getPcTotalOfUser();
+		statisticsUserDataView.setTotalOfUser(wxUserNum + pcUserNum);
+		statisticsUserDataView.setNumOfUser(wxUserNum);
+		statisticsUserDataView.setPcNumOfUser(pcUserNum);
+		statisticsUserDataView.setNumOfNewUser(statisticsUserDataMapper.getNumOfNewUser(thisZero, thisEnd));
+		statisticsUserDataView.setPcNumOfNewUser(statisticsUserDataMapper.getPcNumOfNewUser(thisZero, thisEnd));
+		statisticsUserDataView.setNumOfActiveUser(statisticsUserDataMapper.getNumOfActiveUser(thisZero, thisEnd));
+		statisticsUserDataView.setPcNumOfActiveUser(statisticsUserDataMapper.getPcNumOfActiveUser(thisZero, thisEnd));
+		statisticsUserDataView.setUserData(beanSearcher.search(StatisticsUserData.class, MapUtils.flatBuilder(request.getParameterMap()).build()));
+		return GatewayResponse.SUCCESS.newBuilder().toResult(statisticsUserDataView);
+	}
 }

+ 31 - 5
netflix-web/src/main/java/com/cyksj/web/controller/register/RegisterController.java

@@ -5,16 +5,17 @@ import com.cyksj.common.util.IoKit;
 import com.cyksj.common.util.Xmls;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.AppleAutoRegisterDataMapper;
 import com.cyksj.model.dto.H5JsPayParams;
-import com.cyksj.model.dto.H5PayParams;
+import com.cyksj.model.entity.AppleAutoRegisterData;
 import com.cyksj.model.entity.RegisterOrderDon;
 import com.cyksj.model.manage.request.RegisterReq;
-import com.cyksj.redis.RedisService;
+import com.cyksj.model.views.AppleIdCountryOrAreaDataView;
 import com.cyksj.service.register.RegisterOrderDonService;
-import com.cyksj.service.register.SpotifyService;
 import com.cyksj.web.util.StpUserUtil;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.param.Operator;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -42,6 +43,8 @@ public class RegisterController {
 
     private final HttpServletRequest request;
 
+    private final AppleAutoRegisterDataMapper appleAutoRegisterDataMapper;
+
     @PostMapping
     public Result<RegisterOrderDon> register(@RequestBody RegisterReq req) throws Exception {
         long userId = StpUserUtil.getLoginIdAsLong();
@@ -110,11 +113,34 @@ public class RegisterController {
     public Result<SearchResult<RegisterOrderDon>> get(){
         long userId = StpUserUtil.getLoginIdAsLong();
         SearchResult<RegisterOrderDon> search = beanSearcher.search(RegisterOrderDon.class, MapUtils.flatBuilder(request.getParameterMap())
-                .field(RegisterOrderDon::getUserId,userId)
+                .field(RegisterOrderDon::getUserId,userId).op(Operator.Equal)
                 .build());
+        search.getDataList().forEach(data->{
+            if (data.getAppleIsAutoType() && (data.getStatus() == RegisterOrderDon.Status.noPayment || data.getStatus() == RegisterOrderDon.Status.close)) {
+                data.setApplePwdId(null);
+                data.setCountryOrArea(null);
+                data.setRemark(null);
+            }
+        });
         return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
 
+    @GetMapping("/get/appleId/area/detail")
+    public Result<AppleIdCountryOrAreaDataView> getAppleIdCountryOrAreaData() {
+        AppleIdCountryOrAreaDataView appleIdCountryOrAreaDataView = new AppleIdCountryOrAreaDataView();
+        appleIdCountryOrAreaDataView.setJapanAvaNum(appleAutoRegisterDataMapper.selectAreaDataView(AppleAutoRegisterData.CountryOrArea.JAPAN));
+        appleIdCountryOrAreaDataView.setHongKongAvaNum(appleAutoRegisterDataMapper.selectAreaDataView(AppleAutoRegisterData.CountryOrArea.CN_HongKong));
+        appleIdCountryOrAreaDataView.setUsAvaNum(appleAutoRegisterDataMapper.selectAreaDataView(AppleAutoRegisterData.CountryOrArea.US));
+        appleIdCountryOrAreaDataView.setTaiWanAvaNum(appleAutoRegisterDataMapper.selectAreaDataView(AppleAutoRegisterData.CountryOrArea.CN_TaiWan));
+        return GatewayResponse.SUCCESS.newBuilder().toResult(appleIdCountryOrAreaDataView);
+    }
 
-
+    /**
+     * 取消appleId订单
+     */
+    @PutMapping("/cancel/order/{orderId}")
+    public Result<String> cancelOrder(@PathVariable Long orderId) {
+        registerOrderDonService.updateAppleAutoStatus(orderId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult("取消订单成功");
+    }
 }

+ 20 - 0
netflix-web/src/main/java/com/cyksj/web/util/EasyExcelUtils.java

@@ -129,6 +129,26 @@ public class EasyExcelUtils {
 		}
 	}
 
+	/**
+	 * 获取模板 Excel
+	 */
+	public static void createTemplateExcel(HttpServletResponse response, Class tClass, String sheetName, String fileName, ExcelTypeEnum type, String charset) {
+		final String methodName = "createTemplateExcel";
+		LOGGER.info("{},excel导出开始[end]",methodName);
+		try {
+			response.setContentType("application/x-download");
+			response.setContentType("application/vnd.ms-excel");
+			response.setCharacterEncoding("utf-8");
+			response.setHeader("Content-disposition",
+					"attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO-8859-1")+ type.getValue());
+
+			EasyExcel.write(response.getOutputStream(), tClass).sheet(sheetName).doWrite(null);
+			LOGGER.info("{},excel导出结束[end]",methodName);
+		} catch (IOException e) {
+			LOGGER.warn("{},excel导出 异常:{}",methodName,e.getMessage());
+		}
+	}
+
 
 
 	/**