Răsfoiți Sursa

日常保存

lifuquan 1 an în urmă
părinte
comite
d78b4878f8
21 a modificat fișierele cu 1740 adăugiri și 41 ștergeri
  1. 26 0
      src/main/java/com/nokia/tsl_data/dao/HighQualityCountMapper.java
  2. 59 0
      src/main/java/com/nokia/tsl_data/dao/MobileComplaintMapper.java
  3. 11 0
      src/main/java/com/nokia/tsl_data/dao/SysDataDictionaryRepository.java
  4. 31 0
      src/main/java/com/nokia/tsl_data/dao/TargetTsRatioMapper.java
  5. 133 0
      src/main/java/com/nokia/tsl_data/dao/TslMapper.java
  6. 23 0
      src/main/java/com/nokia/tsl_data/dao/UserCountMapper.java
  7. 5 0
      src/main/java/com/nokia/tsl_data/dao/UserCountRepository.java
  8. 9 0
      src/main/java/com/nokia/tsl_data/dao/UserResidentRepository.java
  9. 7 3
      src/main/java/com/nokia/tsl_data/entity/UserCount.java
  10. 39 0
      src/main/java/com/nokia/tsl_data/entity/UserResident.java
  11. 35 1
      src/main/java/com/nokia/tsl_data/service/CronTaskService.java
  12. 83 27
      src/main/java/com/nokia/tsl_data/service/DataWarehouseService.java
  13. 72 0
      src/main/java/com/nokia/tsl_data/service/HighQualityCountService.java
  14. 30 0
      src/main/java/com/nokia/tsl_data/service/MessageService.java
  15. 452 0
      src/main/java/com/nokia/tsl_data/service/TslDataService.java
  16. 138 0
      src/main/java/com/nokia/tsl_data/service/UserCountService.java
  17. 107 0
      src/main/java/com/nokia/tsl_data/service/UserResidentWareHouseService.java
  18. 181 0
      src/main/resources/mapper/MobileComplaintMapper.xml
  19. 266 0
      src/main/resources/mapper/TslMapper.xml
  20. 5 10
      src/test/java/com/nokia/tsl_data/MainTest.java
  21. 28 0
      src/test/java/com/nokia/tsl_data/TslDataApplicationTest.java

+ 26 - 0
src/main/java/com/nokia/tsl_data/dao/HighQualityCountMapper.java

@@ -0,0 +1,26 @@
+package com.nokia.tsl_data.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 客户端数据表 高质量统计表
+ * 对应主表 report_auto.he_d_high_quality
+ */
+@Mapper
+public interface HighQualityCountMapper {
+
+    /**
+     * 查询某个日期各个地市的客户端总数(总投诉量(办结量))(所得结果是当月0日到当天的一个累加量)
+     */
+    List<Map<String, Object>> selectTotalComplaintsForDay(String day);
+
+    /**
+     * 查询某个日期各个地市的客户端总数(总投诉量(办结量))(所得结果是当月0日到当天的一个累加量)
+     */
+    List<Map<String, Object>> selectTotalComplaintsForMonthIdAndDay(@Param("monthId") String monthId,
+                                                                    @Param("day") String day);
+}

+ 59 - 0
src/main/java/com/nokia/tsl_data/dao/MobileComplaintMapper.java

@@ -0,0 +1,59 @@
+package com.nokia.tsl_data.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface MobileComplaintMapper {
+    /**
+     * 统计某天入库工单数量
+     */
+    int selectCompCountForDay(String day);
+
+    /**
+     * 超时工单统计
+     */
+    List<Map<String, Object>> selectTimeoutTsCountForDay(String day);
+
+    /**
+     * 处理时长统计
+     */
+    List<Map<String, Object>> selectTsDurationForDay(String day);
+
+    /**
+     * 重复工单
+     */
+    List<Map<String, Object>> selectRepeatTsCountForDay(String day);
+
+    /**
+     * 投诉清单按日按地市计数
+     */
+    List<Map<String, Object>> selectCityTslForMonth(String day);
+
+    /**
+     * 投诉清单全省计数
+     */
+    List<Map<String, Object>> selectAllTslForMonth(String day);
+
+    /**
+     * 投诉清单地市总数
+     */
+    List<Map<String, Object>> selectCityAllForMonth(String day);
+
+    /**
+     * 投诉清单按月计算总数
+     */
+    int selectAllForMonth(String day);
+
+    /**
+     * 删除某天的管理端投诉清单
+     */
+    void deleteMobileCompForDay(String day);
+
+    /**
+     * 插入上月的平均处理时长
+     */
+    void insertOldTsDurationForMonth(String monthId);
+}

+ 11 - 0
src/main/java/com/nokia/tsl_data/dao/SysDataDictionaryRepository.java

@@ -4,6 +4,7 @@ import com.nokia.tsl_data.entity.SysDataDictionary;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -21,4 +22,14 @@ public interface SysDataDictionaryRepository extends JpaRepository<SysDataDictio
         }
         return result;
     }
+
+    // @Query("select t from SysDataDictionary t where t.typeName = 'city'")
+    default List<String> findAllCityName() {
+        List<String> result = new ArrayList<>();
+        List<SysDataDictionary> dictionaries = findByTypeName("city");
+        for (SysDataDictionary dictionary : dictionaries) {
+            result.add(dictionary.getName());
+        }
+        return result;
+    }
 }

+ 31 - 0
src/main/java/com/nokia/tsl_data/dao/TargetTsRatioMapper.java

@@ -0,0 +1,31 @@
+package com.nokia.tsl_data.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface TargetTsRatioMapper {
+    /**
+     * 按月查询管理端目标万投率
+     */
+    @Select("select city_name, management_target_ts_ratio from report_auto.target_ts_ratio where month_id = #{monthId}")
+    List<Map<String, Object>> selectManagementTargetTsRatioForMonth(String monthId);
+
+    /**
+     * 按月查询客户端目标万投率
+     */
+    @Select("select city_name, customer_target_ts_ratio from report_auto.target_ts_ratio where month_id = #{monthId}")
+    List<Map<String, Object>> selectCustomerTargetTsRatioForMonth(String monthId);
+
+    @Select("select city_name, management_target_ts_ratio, customer_target_ts_ratio from report_auto.target_ts_ratio")
+    List<Map<String, Object>> findAll();
+
+    @Update("update report_auto.target_ts_ratio set management_target_ts_ratio = #{value} where month_id = #{monthId} and city_name = #{city}")
+    void updateManagementTargetTsRatio(@Param("monthId") String monthId, @Param("city") String city, @Param("value") double value);
+
+}

+ 133 - 0
src/main/java/com/nokia/tsl_data/dao/TslMapper.java

@@ -0,0 +1,133 @@
+package com.nokia.tsl_data.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface TslMapper {
+    /**
+     * 查询某天的河北_CEM移网质量投诉明细数据量
+     * v1.5废弃
+     */
+    @Deprecated
+    int selectCompCountForDay(String day);
+
+    /**
+     * 查询河北_CEM高品质2日统计数据量
+     */
+    int selectQualityCountForDay(String day);
+
+    /**
+     * 客户端-投诉问题解决满意度
+     * 客户端-投诉问题解决率
+     * 客户端-投诉问题响应率
+     */
+    List<Map<String, Object>> selectClientRatioForDay(String day);
+
+    /**
+     * 查询历史处理时长
+     */
+    List<Map<String, Object>> selectOldTsDurationForMonth(String monthId);
+
+    /**
+     *
+     * @param monthId
+     */
+    @Deprecated
+    void insertOldTsDurationForMonth(String monthId);
+
+    /**
+     * 存入历史处理时长数据
+     *
+     * @param map
+     */
+    void insertOldTsDuration(@Param("map") Map<String, Object> map);
+
+    /**
+     * 处理时长统计
+     *
+     * @param day
+     * @return
+     */
+    @Deprecated
+    List<Map<String, Object>> selectTsDurationForDay(String day);
+
+    /**
+     * 超时工单统计
+     * v1.5废弃
+     */
+    @Deprecated
+    List<Map<String, Object>> selectTimeoutTsCountForDay(String day);
+
+    /**
+     * 重复工单数和比例按截止日期和地市查询
+     * v1.5废弃
+     */
+    @Deprecated
+    List<Map<String, Object>> selectRepeatTsCountForDay(String day);
+
+    /**
+     * 投诉清单按日按地市计数
+     * v1.5废弃
+     */
+    @Deprecated
+    List<Map<String, Object>> selectCityTslForMonth(String day);
+
+    /**
+     * 投诉清单全省计数
+     * v1.5废弃
+     */
+    @Deprecated
+    List<Map<String, Object>> selectAllTslForMonth(String day);
+
+    /**
+     * 投诉清单地市总数
+     * v1.5废弃
+     */
+    @Deprecated
+    List<Map<String, Object>> selectCityAllForMonth(String day);
+
+    /**
+     * 投诉清单按月计算总数
+     * v1.5废弃
+     */
+    @Deprecated
+    int selectAllForMonth(String day);
+
+    /**
+     * 查询用户数
+     */
+    @Deprecated
+    List<Map<String, Object>> selectUserCountForMonth(String monthId);
+
+    /**
+     * 查询期望万投率
+     */
+    @Deprecated
+    List<Map<String, Object>> selectTargetTsRatioForMonth(String monthId);
+
+    /**
+     * 插入用户数
+     */
+    void insertUserCount(@Param("map") Map<String, Object> map);
+
+    /**
+     * 插入目标万投比
+     */
+    void insertTargetTsRatio(@Param("map") Map<String, Object> map);
+
+    /**
+     * 删除某天的客户端数据
+     */
+    void deleteHighQualityForDay(String day);
+
+    /**
+     * 删除某天的管理端投诉清单
+     * v1.5废弃
+     */
+    @Deprecated
+    void deleteMobileCompForDay(String day);
+}

+ 23 - 0
src/main/java/com/nokia/tsl_data/dao/UserCountMapper.java

@@ -0,0 +1,23 @@
+package com.nokia.tsl_data.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface UserCountMapper {
+
+    /**
+     * 按月查询管理端用户数
+     */
+    @Select("select city_name, management_user_count from report_auto.user_count where month_id = #{monthId}")
+    List<Map<String, Object>> selectMangementUserCountForMonth(String monthId);
+
+    /**
+     * 按月查询客户端用户数
+     */
+    @Select("select city_name, customer_user_count from report_auto.user_count where month_id = #{monthId}")
+    List<Map<String, Object>> selectCustomerUserCountForMonth(String monthId);
+}

+ 5 - 0
src/main/java/com/nokia/tsl_data/dao/UserCountRepository.java

@@ -2,8 +2,13 @@ package com.nokia.tsl_data.dao;
 
 import com.nokia.tsl_data.entity.UserCount;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
 @Repository
 public interface UserCountRepository extends JpaRepository<UserCount, Long> {
+
+    @Query("select e from UserCount e where e.monthId = :month and e.cityName = :city")
+    UserCount findByMonthAndCity(@Param("month") String month, @Param("city") String city);
 }

+ 9 - 0
src/main/java/com/nokia/tsl_data/dao/UserResidentRepository.java

@@ -0,0 +1,9 @@
+package com.nokia.tsl_data.dao;
+
+import com.nokia.tsl_data.entity.UserResident;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface UserResidentRepository extends JpaRepository<UserResident, Long> {
+}

+ 7 - 3
src/main/java/com/nokia/tsl_data/entity/UserCount.java

@@ -1,6 +1,7 @@
 package com.nokia.tsl_data.entity;
 
 import lombok.Data;
+import lombok.experimental.Accessors;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@@ -10,18 +11,21 @@ import java.time.Instant;
 
 @Data
 @Entity
+@Accessors(chain = true)
 @EntityListeners(AuditingEntityListener.class)
-@Table(name = "user_count", schema = "tsl_data")
+@Table(name = "user_count", schema = "tsl_data", indexes = {
+        @Index(name = "month_city_unique", columnList = "month_id, city_name", unique = true)
+})
 public class UserCount {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
-    @Column(name = "month_id", columnDefinition = "varchar(8)", nullable = false)
+    @Column(name = "month_id", columnDefinition = "varchar(6)", nullable = false)
     private String monthId;
 
-    @Column(name = "city_name", columnDefinition = "varchar(50)", nullable = false)
+    @Column(name = "city_name", columnDefinition = "varchar(10)", nullable = false)
     private String cityName;
 
     // 管理端用户数统计

+ 39 - 0
src/main/java/com/nokia/tsl_data/entity/UserResident.java

@@ -0,0 +1,39 @@
+package com.nokia.tsl_data.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.sql.Date;
+
+/**
+ * 用户常驻小区
+ */
+@Data
+@Entity
+@Table(name = "user_resident", schema = "public")
+public class UserResident {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(name = "month_id", columnDefinition = "text", nullable = false)
+    private String monthId;
+
+    @Column(name = "day_id", columnDefinition = "text", nullable = false)
+    private String dayId;
+
+    @Column(name = "area_no", columnDefinition = "text", nullable = false)
+    private String areaNo;
+
+    @Column(name = "device_number", columnDefinition = "text", nullable = false)
+    private String deviceNumber;
+
+    @Column(name = "lac", columnDefinition = "text", nullable = true)
+    private String lac;
+
+    @Column(name = "ci", columnDefinition = "text", nullable = true)
+    private String ci;
+
+    @Column(name = "last_modify", columnDefinition = "timestamp default now()", nullable = true)
+    private Date lastModify;
+}

+ 35 - 1
src/main/java/com/nokia/tsl_data/service/CronTaskService.java

@@ -6,27 +6,61 @@ import com.nokia.common.basic.DateUtil;
 import com.nokia.tsl_data.dao.TaskRecordRepository;
 import com.nokia.tsl_data.dao.TslDataDao;
 import com.nokia.tsl_data.entity.TaskRecord;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import java.text.SimpleDateFormat;
 import java.time.Instant;
+import java.util.Date;
 import java.util.List;
 
 /**
  * 定时任务
  */
+@Slf4j
 @Service
 public class CronTaskService {
 
     private final WorkFlowService workFlowService;
+    private final DataWarehouseService dataWarehouseService;
+    private final MessageService messageService;
     private final TslDataDao tslDataDao;
     private final TaskRecordRepository taskRecordRepository;
 
-    public CronTaskService(WorkFlowService workFlowService, TslDataDao tslDataDao, TaskRecordRepository taskRecordRepository) {
+    public CronTaskService(WorkFlowService workFlowService, DataWarehouseService dataWarehouseService, MessageService messageService, TslDataDao tslDataDao, TaskRecordRepository taskRecordRepository) {
         this.workFlowService = workFlowService;
+        this.dataWarehouseService = dataWarehouseService;
+        this.messageService = messageService;
         this.tslDataDao = tslDataDao;
         this.taskRecordRepository = taskRecordRepository;
     }
 
+    /**
+     * 日报表
+     * TODO
+     */
+    public void dailyReport() {
+        // 当天时间
+        String day = new SimpleDateFormat("yyyyMMdd")
+                .format(new Date(System.currentTimeMillis() - 1000L * 3600 * 24));
+        try {
+            // 检查数据源
+            dataWarehouseService.checkSourceAndDelayIfNotOK(day);
+            // 入库数据
+            dataWarehouseService.warehouseHighQualityCountDay(day);
+            dataWarehouseService.warehouseHighQualityListDay(day);
+            dataWarehouseService.warehouseMobileComplaintDay(day);
+            // 生成表
+            // TODO 生成表
+            // 截图
+            // TODO 截图
+        } catch (Exception e) {
+            log.error("定时任务出错--{}", e.getMessage());
+            e.printStackTrace();
+            messageService.error("定时任务出错--" + e.getMessage());
+        }
+    }
+
     /**
      * 从工单系统定时更新数据
      * 调度周期每小时

+ 83 - 27
src/main/java/com/nokia/tsl_data/service/DataWarehouseService.java

@@ -1,5 +1,7 @@
 package com.nokia.tsl_data.service;
 
+import com.nokia.common.codec.MD5Util;
+import com.nokia.common.io.TextUtil;
 import com.nokia.tsl_data.dao.SysDataDictionaryRepository;
 import com.nokia.tsl_data.dao.TslDataDao;
 import com.nokia.tsl_data.properties.DataWarehouseProperties;
@@ -11,7 +13,6 @@ import org.springframework.stereotype.Service;
 
 import java.io.*;
 import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
@@ -24,37 +25,106 @@ public class DataWarehouseService {
     private final TslDataDao tslDataDao;
     private final SysDataDictionaryRepository sysDataDictionaryRepository;
     private final DataWarehouseProperties dataWarehouseProperties;
+    private final MessageService messageService;
+    // 重试等待时间
+    private final Long delayForRetry = 1800L;
 
-    public DataWarehouseService(TslDataDao tslDataDao, SysDataDictionaryRepository sysDataDictionaryRepository, DataWarehouseProperties dataWarehouseProperties) {
+    public DataWarehouseService(TslDataDao tslDataDao, SysDataDictionaryRepository sysDataDictionaryRepository, DataWarehouseProperties dataWarehouseProperties, MessageService messageService) {
         this.tslDataDao = tslDataDao;
         this.sysDataDictionaryRepository = sysDataDictionaryRepository;
         this.dataWarehouseProperties = dataWarehouseProperties;
+        this.messageService = messageService;
     }
 
-    // TODO
-    public void checkSource(String day) {
+    public void checkSourceAndDelayIfNotOK(String day) {
+        boolean flag = false;
+        do {
+            String result = checkSource(day);
+            if (result.length() == 0) {
+                // 数据源正常
+                flag = true;
+            } else {
+                // 数据源存在异常
+                messageService.error(result);
+                // 等待一段时间后再次检查
+                try {
+                    Thread.sleep(1000L * delayForRetry);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException("检查数据源等待中被中断... " + e.getMessage());
+                }
+            }
+        } while (!flag);
+    }
 
+    public String checkSource(String day) {
+        StringBuffer stringBuffer = new StringBuffer();
+        // 河北_CEM移网质量投诉明细
+        File mobileComplaintDayFile = getMobileComplaintDayFile(day);
+        if (!mobileComplaintDayFile.exists()) {
+            stringBuffer.append("河北_CEM移网质量投诉明细_HE_D_MOBILE_COMP表账期 ").append(day).append(" 数据未到达");
+        }
+        if (!checkMD5(mobileComplaintDayFile)) {
+            stringBuffer.append("河北_CEM移网质量投诉明细_HE_D_MOBILE_COMP表账期 ").append(day).append(" MD5验证未通过");
+        }
+        // 河北_CEM高品质2日明细
+        File highQualityListDayFile = getHighQualityListDayFile(day);
+        if (!highQualityListDayFile.exists()) {
+            stringBuffer.append("河北_CEM高品质2日明细_HE_D_HIGH_QUALITY_LIST表账期 ").append(day).append(" 数据未到达");
+        }
+        if (!checkMD5(highQualityListDayFile)) {
+            stringBuffer.append("河北_CEM高品质2日明细_HE_D_HIGH_QUALITY_LIST表账期 ").append(day).append(" MD5验证未通过");
+        }
+        // 河北_CEM高品质2日统计
+        File highQualityCountDayFile = getHighQualityCountDayFile(day);
+        if (!highQualityCountDayFile.exists()) {
+            stringBuffer.append("河北_CEM高品质2日统计_HE_D_HIGH_QUALITY_COUNT表账期 ").append(day).append(" 数据未到达");
+        }
+        if (!checkMD5(highQualityCountDayFile)) {
+            stringBuffer.append("河北_CEM高品质2日统计_HE_D_HIGH_QUALITY_COUNT表账期 ").append(day).append(" MD5验证未通过");
+        }
+        return stringBuffer.toString();
     }
 
-    // TODO
-    private boolean checkHighQualityListDay(String day) {
+    private File getMobileComplaintDayFile(String day) {
+        String fileName = dataWarehouseProperties.getPrefixOfMobileComplaint() + day + ".csv";
+        return Paths.get(dataWarehouseProperties.getDirOfMobileComplaint(), fileName).toFile();
+    }
+
+    private File getHighQualityListDayFile(String day) {
         String fileName = dataWarehouseProperties.getPrefixOfHighQualityListDay() + day + ".csv";
-        Path path = Paths.get(dataWarehouseProperties.getDirOfHighQualityListDay(), fileName);
-        return path.toFile().exists();
+        return Paths.get(dataWarehouseProperties.getDirOfHighQualityListDay(), fileName).toFile();
     }
 
+    private File getHighQualityCountDayFile(String day) {
+        String fileName = dataWarehouseProperties.getPrefixOfHighQualityCountDay() + day + ".csv";
+        return Paths.get(dataWarehouseProperties.getDirOfHighQualityListDay(), fileName).toFile();
+    }
+
+    /**
+     * 验证文件的MD5
+     */
+    private boolean checkMD5(File file) {
+        String md5String = TextUtil.readLinesWithUTF8(file.getAbsolutePath() + ".MD5").get(0);
+        String md5OfFile = MD5Util.MD5OfFile(file);
+        return md5String.equals(md5OfFile);
+    }
 
     public void warehouseHighQualityListDay(String day) {
-        String fileName = dataWarehouseProperties.getPrefixOfHighQualityListDay() + day + ".csv";
-        Path path = Paths.get(dataWarehouseProperties.getDirOfHighQualityListDay(), fileName);
-        warehouseHighQualityListDay(path.toFile());
-        log.info("河北_CEM高质量2日明细数据入库成功: {}...", day);
+        warehouseHighQualityListDay(getHighQualityListDayFile(day));
+    }
+
+    public void warehouseMobileComplaintDay(String day) {
+        warehouseMobileComplaintDay(getMobileComplaintDayFile(day));
+    }
+
+    public void warehouseHighQualityCountDay(String day) {
+        warehouseHighQualityCountDay(getHighQualityCountDayFile(day));
     }
 
     /**
      * 入库 河北高质量2日明细数据
      */
-    public void warehouseHighQualityListDay(File file) {
+    private void warehouseHighQualityListDay(File file) {
         try (Reader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
             // SOH作为分割符
             char delimiter = 1;
@@ -85,13 +155,6 @@ public class DataWarehouseService {
         }
     }
 
-    public void warehouseMobileComplaintDay(String day) {
-        String fileName = dataWarehouseProperties.getPrefixOfMobileComplaint() + day + ".csv";
-        Path path = Paths.get(dataWarehouseProperties.getDirOfMobileComplaint(), fileName);
-        warehouseMobileComplaintDay(path.toFile());
-        log.info("河北_CEM移网质量投诉明细数据入库成功: {}...", day);
-    }
-
     /**
      * 入库 河北_CEM移网质量投诉明细
      */
@@ -121,13 +184,6 @@ public class DataWarehouseService {
         }
     }
 
-    public void warehouseHighQualityCountDay(String day) {
-        String fileName = dataWarehouseProperties.getPrefixOfHighQualityCountDay() + day + ".csv";
-        Path path = Paths.get(dataWarehouseProperties.getDirOfHighQualityCountDay(), fileName);
-        warehouseHighQualityCountDay(path.toFile());
-        log.info("河北_CEM高品质2日统计数据入库成功: {}...", day);
-    }
-
     /**
      * 入库 河北_CEM高品质2日统计
      */

+ 72 - 0
src/main/java/com/nokia/tsl_data/service/HighQualityCountService.java

@@ -0,0 +1,72 @@
+package com.nokia.tsl_data.service;
+
+import com.nokia.tsl_data.dao.HighQualityCountMapper;
+import com.nokia.tsl_data.dao.SysDataDictionaryRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 处理客户端统计数据
+ */
+@Service
+public class HighQualityCountService {
+
+    private final HighQualityCountMapper highQualityCountDao;
+    private final SysDataDictionaryRepository sysDataDictionaryRepository;
+
+    public HighQualityCountService(HighQualityCountMapper highQualityCountDao, SysDataDictionaryRepository sysDataDictionaryRepository) {
+        this.highQualityCountDao = highQualityCountDao;
+        this.sysDataDictionaryRepository = sysDataDictionaryRepository;
+    }
+
+    /**
+     * 根据日期查询当月从1日起每天每个地市的客户端统计数据
+     */
+    public Map<String, int[]> getComplaintsForDay(String day) {
+        // 预处理时间
+        String monthId = day.substring(0, 6);
+        int dayIndex = Integer.parseInt(day.substring(6));
+
+        List<String> allCityName = sysDataDictionaryRepository.findAllCityName();
+        Map<String, int[]> result = new HashMap<>();
+        // 每个地市一个数组,数组保存dayIndex天数据
+        for (String areaName : allCityName) {
+            result.put(areaName, new int[dayIndex + 1]);
+        }
+        // 全省
+        result.put("全省", new int[dayIndex + 1]);
+        for (int i = 1; i <= dayIndex; i++) {
+            // 拼接一个表示天的字符串,天如果小于10要补0
+            String newDay = i >= 10 ? monthId + i : monthId + "0" + i;
+            // 这里有一个查询操作
+            List<Map<String, Object>> totalComplaintsForDay = highQualityCountDao
+                    .selectTotalComplaintsForDay(newDay);
+            int provinceAll = 0;
+            for (Map<String, Object> map : totalComplaintsForDay) {
+                String city = map.get("businoareaname").toString();
+                // 这里雄安新区需要特殊处理一下
+                city = city.equals("雄安新区") ? "雄安" : city;
+                int[] arr = result.get(city);
+                arr[i - 1] = Integer.parseInt(map.get("total_complaints").toString());
+                provinceAll += arr[i - 1];
+                if (i == dayIndex) {
+                    arr[dayIndex] = arr[dayIndex - 1];
+                }
+            }
+            result.get("全省")[i - 1] = provinceAll;
+            if (i == dayIndex) {
+                result.get("全省")[dayIndex] = provinceAll;
+            }
+        }
+        // 以上得到的result是每天累加,需要计算一下每天的增量
+        for (int[] arr : result.values()) {
+            for (int i = dayIndex - 1; i >= 1; i--) {
+                arr[i] = arr[i] - arr[i - 1];
+            }
+        }
+        return result;
+    }
+}

+ 30 - 0
src/main/java/com/nokia/tsl_data/service/MessageService.java

@@ -0,0 +1,30 @@
+package com.nokia.tsl_data.service;
+
+import com.nokia.pushmessage.service.PushMessageService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class MessageService {
+
+    private final PushMessageService pushMessageService;
+    private final String openConversationId = "";
+    private final String prefix = "";
+
+    public MessageService(PushMessageService pushMessageService) {
+        this.pushMessageService = pushMessageService;
+    }
+
+
+    public void error(String errorMessage) {
+        pushMessageService.sendMarkdownMessage(
+                openConversationId,
+                prefix,
+                String.format("<font color=#FF0000>%s</font>", errorMessage),
+                "ERROR"
+        );
+    }
+
+    public void info(String infoMessage) {
+        pushMessageService.sendTextMessage(openConversationId, prefix, infoMessage);
+    }
+}

+ 452 - 0
src/main/java/com/nokia/tsl_data/service/TslDataService.java

@@ -1,7 +1,459 @@
 package com.nokia.tsl_data.service;
 
+import com.nokia.tsl_data.dao.MobileComplaintMapper;
+import com.nokia.tsl_data.dao.SysDataDictionaryRepository;
+import com.nokia.tsl_data.dao.TargetTsRatioMapper;
+import com.nokia.tsl_data.dao.TslMapper;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * 计算输出到文件的数据
+ */
 @Service
 public class TslDataService {
+
+    private final TslMapper tslMapper;
+    private final MobileComplaintMapper mobileComplaintMapper;
+    private final SysDataDictionaryRepository sysDataDictionaryRepository;
+    private final TargetTsRatioMapper targetTsRatioMapper;
+    private final HighQualityCountService highQualityCountService;
+    private final UserCountService userCountService;
+
+    @Value("${tslTask.compliance.satisfied:0.92}")
+    private double satisfiedCompliance;
+    @Value("${tslTask.compliance.resolution:0.85}")
+    private double resolutionCompliance;
+    @Value("${tslTask.compliance.response:0.99}")
+    private double responseCompliance;
+
+    public TslDataService(TslMapper tslMapper, MobileComplaintMapper mobileComplaintMapper, SysDataDictionaryRepository sysDataDictionaryRepository, TargetTsRatioMapper targetTsRatioMapper, HighQualityCountService highQualityCountService, UserCountService userCountService) {
+        this.tslMapper = tslMapper;
+        this.mobileComplaintMapper = mobileComplaintMapper;
+        this.sysDataDictionaryRepository = sysDataDictionaryRepository;
+        this.targetTsRatioMapper = targetTsRatioMapper;
+        this.highQualityCountService = highQualityCountService;
+        this.userCountService = userCountService;
+    }
+
+    /**
+     * 客户端-投诉问题解决满意度
+     * 客户端-投诉问题解决率
+     * 客户端-投诉问题响应率
+     */
+    public List<List<List<Object>>> getSheet4_6Data(String day) {
+        String realDay = day.substring(0, 4) + "-" + day.substring(4, 6) + "-" + day.substring(6);
+        List<Map<String, Object>> data = tslMapper.selectClientRatioForDay(realDay);
+        Map<String, Map<String, Object>> dataMap = new HashMap<>();
+        for (Map<String, Object> map : data) {
+            String key = (String) map.get("businoareaname");
+            if (key.equals("雄安新区")) {
+                dataMap.put("雄安", map);
+            }
+            dataMap.put(key, map);
+        }
+        List<List<List<Object>>> result = new ArrayList<>(3);
+        List<List<Object>> list0;
+        List<Object> list1;
+
+        // 满意度
+        list0 = new ArrayList<>();
+        result.add(list0);
+        // 地市满意度
+        for (String area : sysDataDictionaryRepository.findAllCityName()) {
+            list1 = new ArrayList<>(4);
+            list0.add(list1);
+            // 地市
+            list1.add(0, area);
+            // 满意率
+            list1.add(1, dataMap.get(area).get("complaint_satisfied"));
+            // 达标值
+            list1.add(2, satisfiedCompliance);
+            // 差距
+            list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
+        }
+        // 逆序排序
+        list0.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
+        // 全省满意度
+        list1 = new ArrayList<>(4);
+        list0.add(list1);
+        // 地市
+        list1.add(0, "全省");
+        // 满意率
+        list1.add(1, dataMap.get("全省").get("complaint_satisfied"));
+        // 达标值
+        list1.add(2, satisfiedCompliance);
+        // 差距
+        list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
+
+        // 解决率
+        list0 = new ArrayList<>();
+        result.add(list0);
+        // 地市解决率
+        for (String area : sysDataDictionaryRepository.findAllCityName()) {
+            list1 = new ArrayList<>(4);
+            list0.add(list1);
+            // 地市
+            list1.add(0, area);
+            // 解决率
+            list1.add(1, dataMap.get(area).get("complaint_resolution"));
+            // 达标值
+            list1.add(2, resolutionCompliance);
+            // 差距
+            list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
+        }
+        // 逆序排序
+        list0.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
+        // 全省解决率
+        list1 = new ArrayList<>(4);
+        list0.add(list1);
+        // 地市
+        list1.add(0, "全省");
+        // 解决率
+        list1.add(1, dataMap.get("全省").get("complaint_resolution"));
+        // 达标值
+        list1.add(2, resolutionCompliance);
+        // 差距
+        list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
+
+        // 响应率
+        list0 = new ArrayList<>();
+        result.add(list0);
+        for (String area : sysDataDictionaryRepository.findAllCityName()) {
+            list1 = new ArrayList<>(4);
+            list0.add(list1);
+            // 地市
+            list1.add(0, area);
+            // 解决率
+            list1.add(1, dataMap.get(area).get("complaint_response"));
+            // 达标值
+            list1.add(2, responseCompliance);
+            // 差距
+            list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
+        }
+        // 逆序排序
+        list0.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
+        list1 = new ArrayList<>(4);
+        list0.add(list1);
+        list1.add(0, "全省");
+        // 相应
+        list1.add(1, dataMap.get("全省").get("complaint_response"));
+        // 达标值
+        list1.add(2, responseCompliance);
+        // 差距
+        list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
+
+        return result;
+    }
+
+    /**
+     * 超时工单情况
+     */
+    public List<List<Object>> getSheet3Data1(String day) {
+        List<Map<String, Object>> data = mobileComplaintMapper.selectTimeoutTsCountForDay(day);
+        Map<String, Map<String, Object>> dayMap = new HashMap<>();
+        for (Map<String, Object> map : data) {
+            dayMap.put((String) map.get("compl_area_local"), map);
+        }
+        List<List<Object>> result = new ArrayList<>();
+        // 各地市数据
+        for (String area : sysDataDictionaryRepository.findAllCityName()) {
+            // 地市 工单数 超时工单数 超时工单占比
+            List<Object> list = new ArrayList<>(4);
+            result.add(list);
+
+            list.add(0, area);
+            // 获取该地市的数据--可能为null
+            Map<String, Object> map = dayMap.get(area);
+            if (map == null) {
+                list.add(1, 0L);
+                list.add(2, 0L);
+                list.add(3, 0.0);
+            } else {
+                list.add(1, map.get("total_num"));
+                list.add(2, map.get("timeout_num"));
+                list.add(3, map.get("timeout_ratio"));
+            }
+        }
+        // 逆序排序
+        result.sort((o1, o2) -> {
+            return Double.compare((double) o2.get(3), (double) o1.get(3));
+        });
+        // 全省数据
+        List<Object> list = new ArrayList<>();
+        result.add(list);
+        // 地市
+        list.add(0, "全省");
+        // 工单数
+        list.add(1, dayMap.get("全省").get("total_num"));
+        // 超时工单数
+        list.add(2, dayMap.get("全省").get("timeout_num"));
+        // 超时工单占比
+        list.add(3, dayMap.get("全省").get("timeout_ratio"));
+        return result;
+    }
+
+    /**
+     * 平均处理时长
+     */
+    public List<List<Object>> getSheet3Data2(String day) {
+        Calendar calendar = Calendar.getInstance(Locale.CHINA);
+        try {
+            calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        // 获取上个月的时间
+        calendar.add(Calendar.MONTH, -1);
+        String oldMonthId = new SimpleDateFormat("yyyyMM").format(calendar.getTime());
+        List<Map<String, Object>> oldData = tslMapper.selectOldTsDurationForMonth(oldMonthId);
+        // 如果上月的平均处理时长数据不存在,需要插入
+        if (oldData.size() == 0) {
+            mobileComplaintMapper.insertOldTsDurationForMonth(oldMonthId);
+            oldData = tslMapper.selectOldTsDurationForMonth(oldMonthId);
+        }
+        List<Map<String, Object>> dayData = mobileComplaintMapper.selectTsDurationForDay(day);
+        // 转化格式方便读取
+        Map<String, Map<String, Object>> dayMap = new HashMap<>();
+        Map<String, Map<String, Object>> preMap = new HashMap<>();
+        for (Map<String, Object> map : dayData) {
+            dayMap.put((String) map.get("compl_area_local"), map);
+        }
+        for (Map<String, Object> map : oldData) {
+            preMap.put((String) map.get("city_name"), map);
+        }
+        List<List<Object>> result = new ArrayList<>();
+        // 各地市数据
+        for (String area : sysDataDictionaryRepository.findAllCityName()) {
+            // 地市 上月平均处理时长 当月平均处理时长 涨幅
+            List<Object> list = new ArrayList<>(4);
+            result.add(list);
+            list.add(0, area);
+            list.add(1, preMap.get(area).get("avg_duration"));
+            Map<String, Object> map = dayMap.get(area);
+            if (map == null) {
+                list.add(2, 0.0);
+                list.add(3, 0.0);
+            } else {
+                list.add(2, dayMap.get(area).get("avg_duration"));
+                list.add(3, ((double) list.get(2)) - (double) list.get(1));
+            }
+        }
+        // 逆序排序
+        result.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
+        return result;
+    }
+
+    /**
+     * 管理端-重复投诉率
+     */
+    public List<List<Object>> getSheet2Data(String day) {
+        // 从数据库
+        List<Map<String, Object>> dayData = mobileComplaintMapper.selectRepeatTsCountForDay(day);
+        List<Map<String, Object>> preDayData = dayData;
+        if (!day.endsWith("01")) {
+            String preDay = String.valueOf(Integer.parseInt(day) - 1);
+            preDayData = mobileComplaintMapper.selectRepeatTsCountForDay(preDay);
+        }
+        // 转化格式方便读取
+        Map<String, Map<String, Object>> dayMap = new HashMap<>();
+        Map<String, Map<String, Object>> preMap = new HashMap<>();
+        for (Map<String, Object> map : dayData) {
+            dayMap.put((String) map.get("compl_area_local"), map);
+        }
+        for (Map<String, Object> map : preDayData) {
+            preMap.put((String) map.get("compl_area_local"), map);
+        }
+        List<List<Object>> result = new ArrayList<>();
+        // 各地市数据
+        for (String area : sysDataDictionaryRepository.findAllCityName()) {
+            List<Object> list = new ArrayList<>(7);
+            result.add(list);
+            list.add(0, area);
+            // 重复投诉工单数
+            list.add(1, preMap.get(area).get("repeat_num"));
+            list.add(2, dayMap.get(area).get("repeat_num"));
+            // 重复投诉率
+            list.add(3, preMap.get(area).get("repeat_ratio"));
+            list.add(4, dayMap.get(area).get("repeat_ratio"));
+            // 增量
+            list.add(5, ((double) list.get(2)) - ((double) list.get(1)));
+            list.add(6, ((double) list.get(4)) - ((double) list.get(3)));
+        }
+        // 排序--逆序
+        result.sort((o1, o2) -> {
+            return Double.compare((double) o2.get(6), (double) o1.get(6));
+        });
+        // 全省数据
+        List<Object> list = new ArrayList<>(7);
+        result.add(list);
+        list.add(0, "全省");
+        // 重复投诉工单数
+        list.add(1, preMap.get("全省").get("repeat_num"));
+        list.add(2, dayMap.get("全省").get("repeat_num"));
+        // 重复投诉率
+        list.add(3, preMap.get("全省").get("repeat_ratio"));
+        list.add(4, dayMap.get("全省").get("repeat_ratio"));
+        // 增量
+        list.add(5, ((double) list.get(2)) - ((double) list.get(1)));
+        list.add(6, ((double) list.get(4)) - ((double) list.get(3)));
+        return result;
+    }
+
+    /**
+     * 客户端-战略考核
+     */
+    public Map<String, List<Object>> getSheet1_1Data(String day) {
+        // 各地市和全省数据
+        Map<String, int[]> complaintsForDay = highQualityCountService.getComplaintsForDay(day);
+        Map<String, List<Object>> result = new HashMap<>();
+        // int dayIndex = Integer.parseInt(day.substring(6, 8));
+        // 写入各地市数据
+        for (String area : sysDataDictionaryRepository.findAllCityName()) {
+            List<Object> list = new ArrayList<>();
+            int[] js = complaintsForDay.get(area);
+            for (int i = 0; i < js.length; i++) {
+                list.add(js[i]);
+            }
+            result.put(area, list);
+        }
+        // 写入全省数据
+        result.put("全省", new ArrayList<>());
+        int[] js = complaintsForDay.get("全省");
+        for (int i = 0; i < js.length; i++) {
+            result.get("全省").add(js[i]);
+        }
+        // 客户端用户数
+        Map<String, Double> customerUserCount = userCountService.getCustomerUserCountForMonth(day.substring(0, 6));
+        for (Entry<String, List<Object>> entry : result.entrySet()) {
+            entry.getValue().add(customerUserCount.get(entry.getKey()));
+        }
+
+        // 获取当前月
+        Calendar calendar = Calendar.getInstance(Locale.CHINA);
+        try {
+            calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        int actualMaximumDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
+        // 万投率和本月预测
+        for (Entry<String, List<Object>> entry : result.entrySet()) {
+            List<Object> list = entry.getValue();
+            int size = list.size();
+            // 计算万投率
+            double wtl = Double.parseDouble(list.get(size - 2).toString())
+                    / Double.parseDouble(list.get(size - 1).toString());
+            list.add(wtl);
+            // 计算预测万投率
+            double ycwtl = wtl * actualMaximumDayOfMonth / dayOfMonth;
+            list.add(ycwtl);
+        }
+
+        // 期望万投率--从数据库取出来是一个字符串
+        // 客户端目标投诉率
+        List<Map<String, Object>> targetTsRatio = targetTsRatioMapper
+                .selectCustomerTargetTsRatioForMonth(day.substring(0, 6));
+        for (Map<String, Object> map : targetTsRatio) {
+            result.get(map.get("city_name")).add(Double.parseDouble(map.get("customer_target_ts_ratio").toString()));
+        }
+
+        // 与目标差距
+        for (Entry<String, List<Object>> entry : result.entrySet()) {
+            List<Object> list = entry.getValue();
+            int size = list.size();
+            double cj = ((double) list.get(size - 2)) - ((double) list.get(size - 1));
+            list.add(cj);
+        }
+
+        return result;
+    }
+
+    /**
+     * 管理端-移网质量类
+     */
+    public Map<String, List<Object>> getSheet1Data(String day) {
+        // 获取当前月
+        Calendar calendar = Calendar.getInstance(Locale.CHINA);
+        try {
+            calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        int actualMaximumDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
+        // monthId
+        String monthId = new SimpleDateFormat("yyyyMM").format(calendar.getTime());
+
+        List<Map<String, Object>> cityTslforMonth = mobileComplaintMapper.selectCityTslForMonth(day);
+        List<Map<String, Object>> allTslforMonth = mobileComplaintMapper.selectAllTslForMonth(day);
+        List<Map<String, Object>> cityAllforMonth = mobileComplaintMapper.selectCityAllForMonth(day);
+        int total = mobileComplaintMapper.selectAllForMonth(day);
+
+        int dayIndex = Integer.parseInt(day.substring(6, 8));
+        Map<String, List<Object>> result = new HashMap<>();
+        for (String area : sysDataDictionaryRepository.findAllCityName()) {
+            List<Object> list = new ArrayList<>();
+            // 需要初始化一下
+            for (int i = 0; i < dayIndex; i++) {
+                list.add(0);
+            }
+            result.put(area, list);
+        }
+        result.put("全省", new ArrayList<>());
+
+        // 各地市每日投诉量
+        for (Map<String, Object> map : cityTslforMonth) {
+            int dayId = Integer.parseInt(map.get("day_id").toString());
+            result.get(map.get("compl_area_local")).set(dayId - 1, map.get("num"));
+        }
+        // 全省每日投诉量
+        for (Map<String, Object> map : allTslforMonth) {
+            result.get("全省").add(map.get("num"));
+        }
+        // 各地市投诉总量
+        for (Map<String, Object> map : cityAllforMonth) {
+            result.get(map.get("compl_area_local")).add(map.get("num"));
+        }
+        // 全省总量
+        result.get("全省").add(total);
+        // 当月管理端用户数
+        Map<String, Double> userCount = userCountService.getManagementUserCountForMonth(monthId);
+        for (Entry<String, List<Object>> entry : result.entrySet()) {
+            entry.getValue().add(userCount.get(entry.getKey()));
+        }
+        // 万投率和本月预测
+        for (Entry<String, List<Object>> entry : result.entrySet()) {
+            List<Object> list = entry.getValue();
+            int size = list.size();
+            // 计算万投率
+            double wtl = Double.parseDouble(list.get(size - 2).toString())
+                    / Double.parseDouble(list.get(size - 1).toString());
+            list.add(wtl);
+            // 计算预测万投率
+            double ycwtl = wtl * actualMaximumDayOfMonth / dayOfMonth;
+            list.add(ycwtl);
+        }
+        // 期望万投率--从数据库取出来是一个字符串
+        // 服务端目标投诉率
+        List<Map<String, Object>> targetTsRatio = targetTsRatioMapper.selectManagementTargetTsRatioForMonth(monthId);
+        for (Map<String, Object> map : targetTsRatio) {
+            result.get(map.get("city_name")).add(Double.parseDouble(map.get("management_target_ts_ratio").toString()));
+        }
+        // 与目标差距
+        for (Entry<String, List<Object>> entry : result.entrySet()) {
+            List<Object> list = entry.getValue();
+            int size = list.size();
+            double cj = ((double) list.get(size - 2)) - ((double) list.get(size - 1));
+            list.add(cj);
+        }
+
+        return result;
+    }
 }

+ 138 - 0
src/main/java/com/nokia/tsl_data/service/UserCountService.java

@@ -0,0 +1,138 @@
+package com.nokia.tsl_data.service;
+
+import com.nokia.tsl_data.dao.UserCountMapper;
+import com.nokia.tsl_data.dao.UserCountRepository;
+import com.nokia.tsl_data.entity.UserCount;
+import org.springframework.stereotype.Service;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class UserCountService {
+
+    private final UserCountRepository userCountRepository;
+    private final UserCountMapper userCountMapper;
+
+    private final DateFormat dateFormat = new SimpleDateFormat("yyyyMM");
+
+    public UserCountService(UserCountRepository userCountRepository, UserCountMapper userCountMapper) {
+        this.userCountRepository = userCountRepository;
+        this.userCountMapper = userCountMapper;
+    }
+
+    /**
+     * 读取管理端用户数如果当前月份没有数据就读上一个月
+     * 递归方式,最多递归2层
+     */
+    public Map<String, Double> getManagementUserCountForMonth(String monthId) {
+        List<Map<String, Object>> managementUserCountForMonth = getManagementUserCountForMonth(monthId, 2);
+        Map<String, Double> result = new HashMap<>();
+        for (Map<String, Object> map : managementUserCountForMonth) {
+            result.put(map.get("city_name").toString(),
+                    Double.parseDouble(map.get("management_user_count").toString()));
+        }
+        return result;
+    }
+
+    /**
+     * 递归实现getangementUserCountForMonth
+     */
+    private List<Map<String, Object>> getManagementUserCountForMonth(String monthId, int stackLayerCount) {
+        List<Map<String, Object>> result = userCountMapper.selectMangementUserCountForMonth(monthId);
+        if (stackLayerCount != 0) {
+            stackLayerCount -= 1;
+            if (result == null || result.size() == 0) {
+                LocalDate localDate = LocalDate.parse(monthId + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
+                localDate = localDate.plusMonths(-1L);
+                String newMonthId = DateTimeFormatter.ofPattern("yyyyMM").format(localDate);
+                return getManagementUserCountForMonth(newMonthId, stackLayerCount);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 读取客户端用户数如果当前月份没有数据就读上一个月
+     * 递归方式,最多递归2层
+     */
+    public Map<String, Double> getCustomerUserCountForMonth(String monthId) {
+        List<Map<String, Object>> mangementUserCountForMonth = getCustomerUserCountForMonth(monthId, 2);
+        Map<String, Double> result = new HashMap<>();
+        for (Map<String, Object> map : mangementUserCountForMonth) {
+            result.put(map.get("city_name").toString(),
+                    Double.parseDouble(map.get("customer_user_count").toString()));
+        }
+        return result;
+    }
+
+    /**
+     * 递归实现getangementUserCountForMonth
+     */
+    private List<Map<String, Object>> getCustomerUserCountForMonth(String monthId, int stackLayerCount) {
+        List<Map<String, Object>> result = userCountMapper.selectCustomerUserCountForMonth(monthId);
+        if (stackLayerCount != 0) {
+            stackLayerCount -= 1;
+            if (result == null || result.size() == 0) {
+                LocalDate localDate = LocalDate.parse(monthId + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
+                localDate = localDate.plusMonths(-1L);
+                String newMonthId = DateTimeFormatter.ofPattern("yyyyMM").format(localDate);
+                return getCustomerUserCountForMonth(newMonthId, stackLayerCount);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 更新管理端用户数据 用户数单位是万人
+     * 如果当月数据存在,直接进行更新;如果当月数据不存在,则首先查找上月数据,如果上月数据存在,则在上月数据基础上更新,否则初始化用户数为0.0
+     */
+    public void updateManagementUserCount(String month, String city, double managementUserCount) {
+        UserCount userCount = getCustomerUserToUpdate(month, city);
+        userCount.setCityName(city).setMonthId(month).setManagementUserCount(managementUserCount);
+        // 保存数据
+        userCountRepository.save(userCount);
+    }
+
+    /**
+     * 更新客户端用户数据 用户数单位是万人
+     * 如果当月数据存在,直接进行更新;如果当月数据不存在,则首先查找上月数据,如果上月数据存在,则在上月数据基础上更新,否则初始化用户数为0.0
+     */
+    public void updateCustomerUserCount(String month, String city, double customerUserCount) {
+        UserCount userCount = getCustomerUserToUpdate(month, city);
+        userCount.setCityName(city).setMonthId(month).setCustomerUserCount(customerUserCount);
+        userCountRepository.save(userCount);
+    }
+
+    /**
+     * 获取要更新的UserCount
+     * 如果当月数据存在,直接进行返回;如果当月数据不存在,则首先查找上月数据,如果上月数据存在,则在返回上月数据,否则返回初始化用户数为0.0的新对象
+     */
+    private UserCount getCustomerUserToUpdate(String month, String city) {
+        UserCount userCount = userCountRepository.findByMonthAndCity(month, city);
+        if (userCount == null) {
+            // 计算上个月monthId
+            Calendar calendar = Calendar.getInstance();
+            calendar.set(Calendar.MONTH, Integer.parseInt(month.substring(4)) - 1);
+            calendar.add(Calendar.MONTH, -1);
+            String lastMonth = dateFormat.format(calendar.getTime());
+            // 获取上个月的数据
+            userCount = userCountRepository.findByMonthAndCity(lastMonth, city);
+            if (userCount != null) {
+                // 重置id为空,避免保存时覆盖上月数据
+                userCount.setId(null);
+            } else {
+                // 如果上个月也为空,则初始化
+                userCount = new UserCount().setMonthId(month).setCityName(city).setCustomerUserCount(0.0)
+                        .setManagementUserCount(0.0);
+            }
+        }
+        return userCount;
+    }
+}

+ 107 - 0
src/main/java/com/nokia/tsl_data/service/UserResidentWareHouseService.java

@@ -0,0 +1,107 @@
+package com.nokia.tsl_data.service;
+
+import com.nokia.tsl_data.dao.UserResidentRepository;
+import com.nokia.tsl_data.entity.UserResident;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+/**
+ * 入库用户常驻基站数据
+ * 
+ * 入库逻辑,每次清空原数据,导入新数据
+ */
+@Slf4j
+@Service
+public class UserResidentWareHouseService {
+
+    @Value("${tsl_data.user_resident.source_path:/data/nenglishangdian/}")
+    private String sourcePath;
+
+    @Value("${tsl_data.user_resident.prefix:aaa}")
+    private String fileNamePrefix;
+
+    @Value("${tsl_data.user_resident.suffix:aaa}")
+    private String suffix;
+
+    private final MessageService messageService;
+    private final UserResidentRepository userResidentJpaDao;
+
+    private final int batchSize = 65536;
+
+    public UserResidentWareHouseService(MessageService messageService, UserResidentRepository userResidentJpaDao) {
+        this.messageService = messageService;
+        this.userResidentJpaDao = userResidentJpaDao;
+    }
+
+    /**
+     * 检查源文件是否存在
+     */
+    public boolean sourceFileExist(String day) {
+        Path path = Paths.get(sourcePath, fileNamePrefix + day + suffix);
+        return Files.exists(path, LinkOption.NOFOLLOW_LINKS);
+    }
+
+    public void wareHouse(String day) {
+        Path path = Paths.get(sourcePath, fileNamePrefix + day + suffix);
+        CSVFormat csvFormat = CSVFormat.DEFAULT.builder()
+                .setDelimiter("||")
+                .setIgnoreHeaderCase(false)
+                .setQuote(null)
+                .build();
+        List<UserResident> batchTemp = new ArrayList<>(1024);
+        // 采用流式方式读取csv文件
+        try (Stream<String> lines = Files.lines(path)) {
+            lines.map(line -> {
+                try {
+                    return CSVParser.parse(line, csvFormat);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    return null;
+                }
+            }).filter(Objects::nonNull).flatMap(records -> {
+                Stream.Builder<CSVRecord> builder = Stream.builder();
+                try {
+                    for (CSVRecord record : records) {
+                        builder.add(record);
+                    }
+                    return builder.build();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return null;
+                }
+            }).forEach(record -> {
+                UserResident userResident = new UserResident();
+                userResident.setMonthId(record.get(0));
+                userResident.setDayId(record.get(1));
+                userResident.setAreaNo(record.get(2));
+                userResident.setDeviceNumber(record.get(3));
+                userResident.setLac(record.get(9));
+                userResident.setCi(record.get(10));
+                batchTemp.add(userResident);
+                if (batchTemp.size() >= batchSize) {
+                    userResidentJpaDao.saveAllAndFlush(batchTemp);
+                    batchTemp.clear();
+                    log.info("batch=====");
+                }
+            });
+        } catch (IOException e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+            messageService.error(e.getMessage());
+        }
+    }
+}

+ 181 - 0
src/main/resources/mapper/MobileComplaintMapper.xml

@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.nokia.tsl_data.dao.MobileComplaintMapper">
+
+    <select id="selectCompCountForDay" resultType="int"> select count(1)
+                                                         from report_auto.he_d_mobile_comp_new
+                                                         where month_id = substring(#{day} from 1 for 6)
+                                                           and day_id
+                                                             = substring(#{day} from 7 for 2) </select>
+
+    <!-- 从现有数据获取上月处理时长(按上月最后一天处理)并插入数据表 -->
+    <insert id="insertOldTsDurationForMonth">with t1 as (select compl_area_local,
+                                                                case
+                                                                    when
+                                                                        proce_time != '' then (extract('epoch' from
+                                                                                                       to_timestamp(
+                                                                                                               proce_time, 'YYYY-MM-DD
+        HH24:MI:SS')) - extract('epoch' from to_timestamp(accept_time, 'YYYY-MM-DD
+        HH24:MI:SS'))) / 3600
+                                                                    when is_online_complete = '是' then 0
+                                                                    else (extract('epoch' from
+                                                                                  to_timestamp(end_time, 'YYYY-MM-DD HH24:MI:SS')) -
+                                                                          extract('epoch' from
+                                                                                  to_timestamp(accept_time, 'YYYY-MM-DD HH24:MI:SS'))) /
+                                                                         3600 end as duration
+                                                         from report_auto.he_d_mobile_comp_new hdmc
+                                                         where month_id = #{month_id}
+                                                           and day_id::float8 =
+                                                               extract('day' from
+                                                                       to_timestamp(#{month_id}, 'YYYYMM') + interval '1 month' -
+                                                                       interval '1
+        day'))
+                                             insert
+                                             into report_auto.avg_duration (month_id, city_name, avg_duration)
+                                             select #{month_id}      as month_id,
+                                                    compl_area_local as city_name,
+                                                    avg(duration)    as avg_duration
+                                             from t1
+                                             group by compl_area_local </insert>
+
+    <select id="selectTsDurationForDay" resultType="Map"> with t1 as (select compl_area_local,
+                                                                             case
+                                                                                 when proce_time != '' then
+                                                                                         (extract('epoch' from
+                                                                                                  to_timestamp(
+                                                                                                          proce_time, 'YYYY-MM-DD
+        HH24:MI:SS')) - extract('epoch' from to_timestamp(accept_time, 'YYYY-MM-DD
+        HH24:MI:SS'))) / 3600
+                                                                                 when is_online_complete = '是' then 0
+                                                                                 else (extract('epoch' from
+                                                                                               to_timestamp(end_time, 'YYYY-MM-DD HH24:MI:SS')) -
+                                                                                       extract('epoch' from
+                                                                                               to_timestamp(accept_time, 'YYYY-MM-DD HH24:MI:SS'))) /
+                                                                                      3600 end as duration
+                                                                      from report_auto.he_d_mobile_comp_new hdmc
+                                                                      where month_id = substring(#{day} from 1 for 6)
+                                                                        and day_id = substring(#{day} from 7 for 2))
+                                                          select compl_area_local,
+                                                                 avg(duration) as
+                                                                     avg_duration
+                                                          from t1
+                                                          group by compl_area_local </select>
+
+    <select id="selectTimeoutTsCountForDay" resultType="Map">with t1 as (select compl_area_local,
+                                                                                is_timeout
+                                                                         from report_auto.he_d_mobile_comp_new hdmc
+                                                                         where month_id = substring(#{day} from
+                                                                                                    1 for 6)
+                                                                           and day_id = substring(#{day} from 7 for 2)),
+                                                                  t2 as (select '全省'     as
+                                                                                            compl_area_local,
+                                                                                count(1) as total_num
+                                                                         from t1),
+                                                                  t3 as (select compl_area_local,
+                                                                                count(1)
+                                                                                    as total_num
+                                                                         from t1
+                                                                         group by compl_area_local),
+                                                                  t4 as (select *
+                                                                         from t2
+                                                                         union
+                                                                         select *
+                                                                         from t3),
+                                                                  t5 as (select compl_area_local from t1 where is_timeout = '是'),
+                                                                  t7 as (select '全省'     as
+                                                                                            compl_area_local,
+                                                                                count(1) as timeout_num
+                                                                         from t5),
+                                                                  t8 as (select compl_area_local,
+                                                                                count(1)
+                                                                                    as timeout_num
+                                                                         from t5
+                                                                         group by compl_area_local),
+                                                                  t9 as (select *
+                                                                         from t7
+                                                                         union
+                                                                         select *
+                                                                         from t8)
+                                                             select t4.compl_area_local,
+                                                                    t4.total_num,
+                                                                    t9.timeout_num,
+                                                                    t9.timeout_num /
+                                                                    t4.total_num::float8 as timeout_ratio
+                                                             from t4,
+                                                                  t9
+                                                             where t4.compl_area_local =
+                                                                   t9.compl_area_local</select>
+
+    <select id="selectRepeatTsCountForDay" resultType="Map"> with t1 as (select compl_area_local,
+                                                                                busi_no
+                                                                         from report_auto.he_d_mobile_comp_new hdmc
+                                                                         where month_id = substring(#{day} from 1
+                                                                                                    for 6)
+                                                                           and day_id = substring(#{day} from 7 for 2)),
+                                                                  t2 as (select distinct * from t1),
+                                                                  t3
+                                                                      as (select compl_area_local, count(1) as total_num
+                                                                          from t1
+                                                                          group by compl_area_local),
+                                                                  t4 as
+                                                                      (select compl_area_local, count(1) as distinct_num
+                                                                       from t2
+                                                                       group by compl_area_local),
+                                                                  t5 as
+                                                                      (select t3.compl_area_local,
+                                                                              t3.total_num,
+                                                                              t3.total_num - t4.distinct_num::float8                  as
+                                                                                                                                         repeat_num,
+                                                                              (t3.total_num - t4.distinct_num) / t3.total_num::float8 as repeat_ratio
+                                                                       from T3,
+                                                                            t4
+                                                                       where t3.compl_area_local = t4.compl_area_local)
+                                                             select '全省'                         as compl_area_local,
+                                                                    sum(total_num)               as total_num,
+                                                                    sum(repeat_num)              as repeat_num,
+                                                                    sum(repeat_num)
+                                                                        / sum(total_num)::float8 as repeat_ratio
+                                                             from t5
+                                                             union
+                                                             select *
+                                                             from t5 </select>
+
+    <select id="selectCityTslForMonth" resultType="Map"> select compl_area_local,
+                                                                substring(acct_date from 7 for 2) as day_id,
+                                                                count(1)                          as num
+                                                         from report_auto.he_d_mobile_comp_new hdmc
+                                                         where month_id = substring(#{day} from 1 for 6)
+                                                           and day_id = substring(#{day} from 7 for 2)
+                                                         group by compl_area_local,
+                                                                  substring(acct_date from
+                                                                            7 for 2)
+                                                         order by compl_area_local, substring(acct_date from 7 for 2) </select>
+
+    <select id="selectAllTslForMonth" resultType="Map"> select substring(acct_date from 7 for 2) as
+                                                                                                    day_id,
+                                                               count(1)                          as num
+                                                        from report_auto.he_d_mobile_comp_new hdmc
+                                                        where month_id =
+                                                              substring(#{day} from 1 for 6)
+                                                          and day_id = substring(#{day} from 7 for 2)
+                                                        group by substring(acct_date from 7 for 2)
+                                                        order by substring(acct_date from 7 for 2) </select>
+
+    <select id="selectCityAllForMonth" resultType="Map">select compl_area_local, count(1) as num
+                                                        from report_auto.he_d_mobile_comp_new hdmc
+                                                        where month_id = substring(#{day} from 1 for 6)
+                                                          and day_id = substring(#{day} from 7 for 2)
+                                                        group by compl_area_local
+                                                        order by compl_area_local </select>
+
+    <select id="selectAllForMonth" resultType="int">select count(1) as num
+                                                    from report_auto.he_d_mobile_comp_new hdmc
+                                                    where month_id = substring(#{day} from 1 for 6)
+                                                      and day_id = substring(#{day} from 7 for 2)</select>
+
+    <delete id="deleteMobileCompForDay" parameterType="string">delete
+                                                               from report_auto.he_d_mobile_comp_new hdmc
+                                                               where month_id = substring(#{day} from 1 for 6)
+                                                                 and day_id = substring(#{day} from 7 for 2)</delete>
+</mapper>

+ 266 - 0
src/main/resources/mapper/TslMapper.xml

@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.nokia.tsl_data.dao.TslMapper">
+
+    <!-- V1.5废弃 -->
+    <select id="selectCompCountForDay" resultType="int"> select count(1)
+                                                         from report_auto.he_d_mobile_comp
+                                                         where acct_date = #{day} </select>
+
+    <select id="selectQualityCountForDay" resultType="int"> select count(1)
+                                                            from report_auto.he_d_high_quality
+                                                            where acct_date = #{day} </select>
+
+    <!-- 满意率 -->
+    <select id="selectClientRatioForDay" resultType="Map">with t1 as (select businoareaname,
+                                                                             complaint_satisfied_list::float8,
+                                                                             complaint_satisfied_count::float8,
+                                                                             complaint_resolution_list::float8,
+                                                                             complaint_resolution_count::float8,
+                                                                             complaint_response_list::float8,
+                                                                             complaint_response_count::float8,
+                                                                             complaint::float8
+                                                                      from report_auto.he_d_high_quality hdhq
+                                                                      where acct_date = #{day}
+                                                                        and profes_dep = '网络质量'
+                                                                        and big_type_name = '移网网络体验'
+                                                                        and small_type_name = '--')
+                                                          select '全省'                                       as businoareaname,
+                                                                 sum(complaint_satisfied_list) /
+                                                                 sum(complaint_satisfied_count + complaint) as
+                                                                                                               complaint_satisfied,
+                                                                 sum(complaint_resolution_list) /
+                                                                 sum(complaint_resolution_count +
+                                                                     complaint)                             as complaint_resolution,
+                                                                 sum(complaint_response_list) /
+                                                                 sum(complaint_response_count + complaint)  as complaint_response
+                                                          from t1
+                                                          union
+                                                          select businoareaname,
+                                                                 case
+                                                                     when (complaint_satisfied_count + complaint) = 0
+                                                                         then 0
+                                                                     else
+                                                                         complaint_satisfied_list / (complaint_satisfied_count + complaint) end   as
+                                                                                                                                                     complaint_satisfied,
+                                                                 case
+                                                                     when (complaint_resolution_count + complaint) = 0
+                                                                         then 0
+                                                                     else
+                                                                         complaint_resolution_list / (complaint_resolution_count + complaint) end as
+                                                                                                                                                     complaint_resolution,
+                                                                 case
+                                                                     when (complaint_response_count + complaint) = 0
+                                                                         then 0
+                                                                     else
+                                                                         complaint_response_list / (complaint_response_count + complaint) end     as complaint_response
+                                                          from t1</select>
+
+    <select id="selectOldTsDurationForMonth" resultType="Map"> select city_name, avg_duration
+                                                               from report_auto.avg_duration
+                                                               where month_id = #{monthId} </select>
+
+    <!-- V1.5废弃 -->
+    <!-- 从现有数据获取上月处理时长并插入数据表 -->
+    <insert id="insertOldTsDurationForMonth">with t1 as (select compl_area_local,
+                                                                case
+                                                                    when
+                                                                        proce_time != '' then (extract('epoch' from
+                                                                                                       to_timestamp(
+                                                                                                               proce_time, 'YYYY-MM-DD
+        HH24:MI:SS')) - extract('epoch' from to_timestamp(accept_time, 'YYYY-MM-DD
+        HH24:MI:SS'))) / 3600
+                                                                    when is_online_complete = '是' then 0
+                                                                    else (extract('epoch' from
+                                                                                  to_timestamp(end_time, 'YYYY-MM-DD HH24:MI:SS')) -
+                                                                          extract('epoch' from
+                                                                                  to_timestamp(accept_time, 'YYYY-MM-DD HH24:MI:SS'))) /
+                                                                         3600 end as duration
+                                                         from report_auto.he_d_mobile_comp hdmc
+                                                         where month_id = #{month_id}
+                                                           and day_id::float8 &lt;=
+                                                               extract('day' from
+                                                                       to_timestamp(#{month_id}, 'YYYYMM') + interval '1 month' -
+                                                                       interval '1
+        day'))
+                                             insert
+                                             into report_auto.avg_duration (month_id, city_name, avg_duration)
+                                             select #{month_id}      as month_id,
+                                                    compl_area_local as city_name,
+                                                    avg(duration)    as avg_duration
+                                             from t1
+                                             group by compl_area_local </insert>
+
+    <insert id="insertOldTsDuration" parameterType="Map"> INSERT INTO report_auto.avg_duration
+                                                              (month_id, city_name, avg_duration)
+                                                          VALUES (#{map.month_id}, #{map.city_name},
+                                                                  #{map.avg_duration}); </insert>
+
+    <!-- V1.5废弃 -->
+    <select id="selectTsDurationForDay" resultType="Map"> with t1 as (select compl_area_local,
+                                                                             case
+                                                                                 when proce_time != '' then
+                                                                                         (extract('epoch' from
+                                                                                                  to_timestamp(
+                                                                                                          proce_time, 'YYYY-MM-DD
+        HH24:MI:SS')) - extract('epoch' from to_timestamp(accept_time, 'YYYY-MM-DD
+        HH24:MI:SS'))) / 3600
+                                                                                 when is_online_complete = '是' then 0
+                                                                                 else (extract('epoch' from
+                                                                                               to_timestamp(end_time, 'YYYY-MM-DD HH24:MI:SS')) -
+                                                                                       extract('epoch' from
+                                                                                               to_timestamp(accept_time, 'YYYY-MM-DD HH24:MI:SS'))) /
+                                                                                      3600 end as duration
+                                                                      from report_auto.he_d_mobile_comp hdmc
+                                                                      where month_id = substring(#{day} from 1 for 6)
+                                                                        and day_id
+                                                                          &lt;= substring(#{day} from 7 for 2))
+                                                          select compl_area_local, avg(duration) as avg_duration
+                                                          from t1
+                                                          group by compl_area_local </select>
+
+    <!-- V1.5废弃 -->
+    <select id="selectTimeoutTsCountForDay" resultType="Map">with t1 as (select compl_area_local,
+                                                                                is_timeout
+                                                                         from report_auto.he_d_mobile_comp hdmc
+                                                                         where month_id = substring(#{day} from 1
+                                                                                                    for 6)
+                                                                           and day_id &lt;= substring(#{day} from 7 for 2)),
+                                                                  t2 as (select '全省'     as
+                                                                                            compl_area_local,
+                                                                                count(1) as total_num
+                                                                         from t1),
+                                                                  t3 as (select compl_area_local,
+                                                                                count(1)
+                                                                                    as total_num
+                                                                         from t1
+                                                                         group by compl_area_local),
+                                                                  t4 as (select *
+                                                                         from t2
+                                                                         union
+                                                                         select *
+                                                                         from t3),
+                                                                  t5 as (select compl_area_local from t1 where is_timeout = '是'),
+                                                                  t7 as (select '全省'     as
+                                                                                            compl_area_local,
+                                                                                count(1) as timeout_num
+                                                                         from t5),
+                                                                  t8 as (select compl_area_local,
+                                                                                count(1)
+                                                                                    as timeout_num
+                                                                         from t5
+                                                                         group by compl_area_local),
+                                                                  t9 as (select *
+                                                                         from t7
+                                                                         union
+                                                                         select *
+                                                                         from t8)
+                                                             select t4.compl_area_local,
+                                                                    t4.total_num,
+                                                                    t9.timeout_num,
+                                                                    t9.timeout_num /
+                                                                    t4.total_num::float8 as timeout_ratio
+                                                             from t4,
+                                                                  t9
+                                                             where t4.compl_area_local =
+                                                                   t9.compl_area_local</select>
+
+    <!-- V1.5废弃 -->
+    <select id="selectRepeatTsCountForDay" resultType="Map"> with t1 as (select compl_area_local,
+                                                                                busi_no
+                                                                         from report_auto.he_d_mobile_comp hdmc
+                                                                         where month_id = substring(#{day} from 1 for
+                                                                                                    6)
+                                                                           and day_id &lt;= substring(#{day} from 7 for 2)),
+                                                                  t2 as (select distinct * from t1),
+                                                                  t3
+                                                                      as (select compl_area_local, count(1) as total_num
+                                                                          from t1
+                                                                          group by compl_area_local),
+                                                                  t4 as
+                                                                      (select compl_area_local, count(1) as distinct_num
+                                                                       from t2
+                                                                       group by compl_area_local),
+                                                                  t5 as
+                                                                      (select t3.compl_area_local,
+                                                                              t3.total_num,
+                                                                              t3.total_num - t4.distinct_num::float8                  as
+                                                                                                                                         repeat_num,
+                                                                              (t3.total_num - t4.distinct_num) / t3.total_num::float8 as repeat_ratio
+                                                                       from T3,
+                                                                            t4
+                                                                       where t3.compl_area_local = t4.compl_area_local)
+                                                             select '全省'                         as compl_area_local,
+                                                                    sum(total_num)               as total_num,
+                                                                    sum(repeat_num)              as repeat_num,
+                                                                    sum(repeat_num)
+                                                                        / sum(total_num)::float8 as repeat_ratio
+                                                             from t5
+                                                             union
+                                                             select *
+                                                             from t5 </select>
+
+    <!-- V1.5废弃 -->
+    <select id="selectCityTslForMonth" resultType="Map"> select compl_area_local,
+                                                                day_id,
+                                                                count(1)
+                                                                    as num
+                                                         from report_auto.he_d_mobile_comp hdmc
+                                                         where month_id = substring(#{day} from 1 for
+                                                                                    6)
+                                                           and day_id &lt;= substring(#{day} from 7 for 2)
+                                                         group by compl_area_local, day_id
+                                                         order by compl_area_local, day_id </select>
+
+    <!-- V1.5废弃 -->
+    <select id="selectAllTslForMonth" resultType="Map"> select day_id, count(1) as num
+                                                        from report_auto.he_d_mobile_comp hdmc
+                                                        where month_id = substring(#{day} from 1 for 6)
+                                                          and day_id
+                                                            &lt;= substring(#{day} from 7 for 2)
+                                                        group by day_id
+                                                        order by day_id </select>
+
+    <!-- V1.5废弃 -->
+    <select id="selectCityAllForMonth" resultType="Map">select compl_area_local, count(1) as num
+                                                        from report_auto.he_d_mobile_comp hdmc
+                                                        where month_id = substring(#{day} from 1 for 6)
+                                                          and day_id &lt;= substring(#{day} from 7 for 2)
+                                                        group by compl_area_local
+                                                        order by compl_area_local </select>
+
+    <!-- V1.5废弃 -->
+    <select id="selectAllForMonth" resultType="int">select count(1) as num
+                                                    from report_auto.he_d_mobile_comp hdmc
+                                                    where month_id = substring(#{day} from 1 for 6)
+                                                      and day_id
+                                                        &lt;= substring(#{day} from 7 for 2)</select>
+
+    <select id="selectUserCountForMonth" resultType="Map">select city_name, user_count
+                                                          from report_auto.user_count
+                                                          where month_id = #{monthId}</select>
+
+    <select id="selectTargetTsRatioForMonth" resultType="Map">select city_name, target_ts_ratio
+                                                              from report_auto.target_ts_ratio
+                                                              where month_id = #{monthId}</select>
+
+    <insert id="insertUserCount" parameterType="map"> INSERT INTO report_auto.user_count (month_id,
+                                                                                          city_name, user_count)
+                                                      VALUES (#{map.monthId}, #{map.cityName}, #{map.userCount})</insert>
+
+    <insert id="insertTargetTsRatio" parameterType="map">INSERT INTO report_auto.target_ts_ratio
+                                                             (month_id, city_name, target_ts_ratio)
+                                                         VALUES (#{map.monthId}, #{map.cityName},
+                                                                 #{map.targetTsRatio}); </insert>
+
+    <delete id="deleteHighQualityForDay" parameterType="string">delete
+                                                                from report_auto.he_d_high_quality hdhq
+                                                                where acct_date = #{day}</delete>
+
+    <!-- V1.5废弃 -->
+    <delete id="deleteMobileCompForDay" parameterType="string">delete
+                                                               from report_auto.he_d_mobile_comp hdmc
+                                                               where acct_date = #{day}</delete>
+
+</mapper>

+ 5 - 10
src/test/java/com/nokia/tsl_data/MainTest.java

@@ -2,20 +2,15 @@ package com.nokia.tsl_data;
 
 import org.junit.jupiter.api.Test;
 
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import java.time.temporal.TemporalAccessor;
+import java.io.File;
 
 public class MainTest {
 
     @Test
     void test() {
-        // DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("Asia/Shanghai"));
-        Instant now = Instant.now();
-        System.out.println(formatter.format(now));
-        TemporalAccessor parse = formatter.parse("2023-10-13 14:47:37");
-        System.out.println(Instant.from(parse));
+        File file = new File("C:\\Users\\lfq\\Desktop\\新建文件夹\\HE_D_HIGH_QUALITY_LIST_DAY_1114200095151828992_20231009.csv");
+        System.out.println(file.exists());
+        File file2 = new File(file.getAbsolutePath()+".MD5");
+        System.out.println("==========="+file2.exists());
     }
 }

+ 28 - 0
src/test/java/com/nokia/tsl_data/TslDataApplicationTest.java

@@ -9,10 +9,15 @@ import com.nokia.tsl_data.dao.TslDataDao;
 import com.nokia.tsl_data.entity.SysDataDictionary;
 import com.nokia.tsl_data.service.CronTaskService;
 import com.nokia.tsl_data.service.DataWarehouseService;
+import com.nokia.tsl_data.service.UserCountService;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.List;
 
 @SpringBootTest
@@ -62,4 +67,27 @@ class TslDataApplicationTest {
         String prefix = "CUC:";
         pushMessageService.sendMarkdownMessage(accessToken, prefix, "abc");
     }
+
+    @Autowired
+    private UserCountService userCountService;
+
+    /**
+     * 更新管理端用户数
+     */
+    @Test
+    void test1() throws IOException {
+        String path = "D:/src/管理端用户数.txt";
+        Files.lines(Paths.get(path), Charset.forName("utf-8"))
+                .forEach(line -> {
+                    String[] split = line.split("\t");
+                    System.out.println(split[0] + Double.parseDouble(split[2]));
+                    userCountService.updateCustomerUserCount("202310", split[0], Double.parseDouble(split[2]));
+                });
+    }
+
+    @Test
+    void test4() {
+        List<String> allCityName = sysDataDictionaryRepository.findAllCityName();
+        System.out.println(allCityName);
+    }
 }