Browse Source

增加了立项材料

lifuquan 1 year ago
parent
commit
737e4cb2d8
30 changed files with 397 additions and 66 deletions
  1. 2 0
      .gitignore
  2. BIN
      doc/数据订阅/能力商店/河北_CEM移网质量投诉明细/河北_CEM移网质量投诉明细_HE_D_MOBILE_COMP.xlsx
  3. 0 0
      doc/数据订阅/能力商店/河北_CEM高品质2日明细/HE_D_HIGH_QUALITY_LIST_DAY_1114200095151828992_20230615.csv
  4. BIN
      doc/数据订阅/能力商店/河北_CEM高品质2日明细/河北客户体验管理高品质日明细.xlsx
  5. BIN
      doc/数据订阅/能力商店/河北_CEM高品质2日统计/河北_CEM高品质2日统计_HE_D_HIGH_QUALITY.xlsx
  6. BIN
      doc/数据订阅/能力商店/河北_用户常驻基站数据/河北_用户常驻基站数据_018_DWA_S_D_RES_USER_RESIDENT_ALL.xlsx
  7. BIN
      doc/立项材料/钉钉群报表自动化(地市需求)/[河北联通]关于投诉工单日报表自动推送增加区县三率的需求.docx
  8. BIN
      doc/立项材料/钉钉群报表自动化(地市需求)/投诉工单日报表增加县区三率的需求.xlsx
  9. BIN
      doc/立项材料/钉钉群报表自动化/[河北联通]关于投诉工单日报表自动推送的需求.docx
  10. BIN
      doc/立项材料/钉钉群报表自动化/投诉工单日报表自动推送需求工作量.xlsx
  11. BIN
      doc/需求文档/输出样本/投诉清单各地市投诉率0322(1).xlsx
  12. BIN
      doc/需求文档/输出样本/投诉清单各地市投诉率20230911.xlsx
  13. BIN
      doc/需求文档/输出样本/投诉清单各地市投诉率20231016.xlsx
  14. 3 2
      src/main/java/com/nokia/tsl_data/config/PropertiesConfig.java
  15. 9 0
      src/main/java/com/nokia/tsl_data/dao/HighQualityDataRepository.java
  16. 9 0
      src/main/java/com/nokia/tsl_data/dao/HighQualityListDayMapper.java
  17. 13 9
      src/main/java/com/nokia/tsl_data/dao/SysDataDictionaryRepository.java
  18. 0 9
      src/main/java/com/nokia/tsl_data/dao/TslMapper.java
  19. 3 3
      src/main/java/com/nokia/tsl_data/dao/WorkFlowDao.java
  20. 78 0
      src/main/java/com/nokia/tsl_data/entity/HighQualityData.java
  21. 22 19
      src/main/java/com/nokia/tsl_data/entity/SysDataDictionary.java
  22. 12 0
      src/main/java/com/nokia/tsl_data/properties/OutputProperties.java
  23. 7 6
      src/main/java/com/nokia/tsl_data/service/CronTaskService.java
  24. 30 0
      src/main/java/com/nokia/tsl_data/service/HighQualityDataService.java
  25. 4 4
      src/main/java/com/nokia/tsl_data/service/MessageService.java
  26. 101 7
      src/main/java/com/nokia/tsl_data/service/TslReportService.java
  27. 5 4
      src/main/resources/logback-spring.xml
  28. 18 0
      src/main/resources/mapper/HighQualityListDayMapper.xml
  29. 73 0
      src/test/java/com/nokia/tsl_data/MainTest.java
  30. 8 3
      src/test/java/com/nokia/tsl_data/TslDataApplicationTest.java

+ 2 - 0
.gitignore

@@ -7,6 +7,8 @@
 **/logs/
 # 上传目录
 **/upload/
+# 输出目录
+**/output/
 
 # vscode
 **/.vscode/

BIN
doc/数据订阅/能力商店/河北_CEM移网质量投诉明细/河北_CEM移网质量投诉明细_HE_D_MOBILE_COMP.xlsx


File diff suppressed because it is too large
+ 0 - 0
doc/数据订阅/能力商店/河北_CEM高品质2日明细/HE_D_HIGH_QUALITY_LIST_DAY_1114200095151828992_20230615.csv


BIN
doc/数据订阅/能力商店/河北_CEM高品质2日明细/河北客户体验管理高品质日明细.xlsx


BIN
doc/数据订阅/能力商店/河北_CEM高品质2日统计/河北_CEM高品质2日统计_HE_D_HIGH_QUALITY.xlsx


BIN
doc/数据订阅/能力商店/河北_用户常驻基站数据/河北_用户常驻基站数据_018_DWA_S_D_RES_USER_RESIDENT_ALL.xlsx


BIN
doc/立项材料/钉钉群报表自动化(地市需求)/[河北联通]关于投诉工单日报表自动推送增加区县三率的需求.docx


BIN
doc/立项材料/钉钉群报表自动化(地市需求)/投诉工单日报表增加县区三率的需求.xlsx


BIN
doc/立项材料/钉钉群报表自动化/[河北联通]关于投诉工单日报表自动推送的需求.docx


BIN
doc/立项材料/钉钉群报表自动化/投诉工单日报表自动推送需求工作量.xlsx


BIN
doc/需求文档/输出样本/投诉清单各地市投诉率0322(1).xlsx


BIN
doc/需求文档/输出样本/投诉清单各地市投诉率20230911.xlsx


BIN
doc/需求文档/输出样本/投诉清单各地市投诉率20231016.xlsx


+ 3 - 2
src/main/java/com/nokia/tsl_data/config/PropertiesAutoConfig.java → src/main/java/com/nokia/tsl_data/config/PropertiesConfig.java

@@ -1,10 +1,11 @@
 package com.nokia.tsl_data.config;
 
 import com.nokia.tsl_data.properties.DataWarehouseProperties;
+import com.nokia.tsl_data.properties.OutputProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
-@EnableConfigurationProperties(DataWarehouseProperties.class)
-public class PropertiesAutoConfig {
+@EnableConfigurationProperties({DataWarehouseProperties.class, OutputProperties.class})
+public class PropertiesConfig {
 }

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

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

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

@@ -1,6 +1,8 @@
 package com.nokia.tsl_data.dao;
 
+import com.nokia.tsl_data.entity.HighQualityData;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.ResultMap;
 import org.apache.ibatis.annotations.Select;
 
 import java.util.List;
@@ -10,4 +12,11 @@ public interface HighQualityListDayMapper {
 
     @Select("select sheet_no from tsl_data.high_quality_list_day")
     List<String> findOrderOf(String day);
+
+    @ResultMap("highQualityDataResultMap")
+    @Select("select concat(month_id, day_id) as day_id, sheet_no, cp_satisfaction, cp_is_ok,"
+            + " cp_timely_contact, cp_timely_contact, area_id, area_name, city_id, city_name"
+            + " from tsl_data.high_quality_list_day "
+            + "where month_id = substring(#{day} from 1 for 6) and day_id = substring(#{day} from 7 for 2)")
+    List<HighQualityData> findHighQualityDataOfDay(String day);
 }

+ 13 - 9
src/main/java/com/nokia/tsl_data/dao/SysDataDictionaryRepository.java

@@ -12,22 +12,26 @@ import java.util.Set;
 @Repository
 public interface SysDataDictionaryRepository extends JpaRepository<SysDataDictionary, Long> {
 
-    List<SysDataDictionary> findByTypeName(String typeName);
+    List<SysDataDictionary> findByTypeOrderByOrd(String type);
 
-    default Set<String> findAllServTypeNames() {
-        Set<String> result = new HashSet<>();
-        List<SysDataDictionary> dictionaries = findByTypeName("serv_type_name");
+    SysDataDictionary findByRealNameAndType(String realName, String type);
+    SysDataDictionary findByNickNameAndType(String nickName, String type);
+    SysDataDictionary findByNickCodeAndType(String nickCode, String type);
+
+    default List<String> findAllCityName() {
+        List<String> result = new ArrayList<>();
+        List<SysDataDictionary> dictionaries = findByTypeOrderByOrd("work_flow_city");
         for (SysDataDictionary dictionary : dictionaries) {
-            result.add(dictionary.getName());
+            result.add(dictionary.getRealName());
         }
         return result;
     }
 
-    default List<String> findAllCityName() {
-        List<String> result = new ArrayList<>();
-        List<SysDataDictionary> dictionaries = findByTypeName("city");
+    default Set<String> findAllServTypeNames() {
+        Set<String> result = new HashSet<>();
+        List<SysDataDictionary> dictionaries = findByTypeOrderByOrd("serv_type_name");
         for (SysDataDictionary dictionary : dictionaries) {
-            result.add(dictionary.getName());
+            result.add(dictionary.getRealName());
         }
         return result;
     }

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

@@ -32,25 +32,16 @@ public interface TslMapper {
      */
     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);

+ 3 - 3
src/main/java/com/nokia/tsl_data/dao/WorkFlowDao.java

@@ -67,9 +67,9 @@ public class WorkFlowDao {
         @Override
         public SysDataDictionary mapRow(ResultSet rs, int rowNum) throws SQLException {
             SysDataDictionary sysDataDictionary = new SysDataDictionary();
-            sysDataDictionary.setWorkFlowId(rs.getString("id"));
-            sysDataDictionary.setWorkFlowTypeCode(rs.getString("type_code"));
-            sysDataDictionary.setWorkFlowName(rs.getString("name"));
+            sysDataDictionary.setType("work_flow_"+rs.getString("type_code"));
+            sysDataDictionary.setNickCode(rs.getString("id"));
+            sysDataDictionary.setNickName(rs.getString("name"));
             return sysDataDictionary;
         }
     }

+ 78 - 0
src/main/java/com/nokia/tsl_data/entity/HighQualityData.java

@@ -0,0 +1,78 @@
+package com.nokia.tsl_data.entity;
+
+import lombok.Data;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.time.Instant;
+
+@Data
+@Entity
+@EntityListeners(AuditingEntityListener.class)
+@Table(name = "high_quality_data", schema = "tsl_data")
+public class HighQualityData {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    // 账期
+    @Column(name = "day_id", columnDefinition = "varchar(8)", nullable = false)
+    private String dayId;
+
+    // 工单号
+    @Column(name = "sheet_no", columnDefinition = "varchar(50)", nullable = false, unique = true)
+    private String sheetNo;
+
+    // 测评-满意度
+    @Column(name = "cp_satisfaction", columnDefinition = "varchar(50)")
+    private String cpSatisfaction;
+
+    // 测评-解决情况
+    @Column(name = "cp_is_ok", columnDefinition = "varchar(50)")
+    private String cpIsOk;
+
+    // 测评-响应情况
+    @Column(name = "cp_timely_contact", columnDefinition = "varchar(50)")
+    private String cpTimelyContact;
+
+    // 未回访标识 已回访/未回访
+    @Column(name = "no_visit_tag", columnDefinition = "varchar(50)")
+    private String noVisitTag;
+
+    // 地市编码
+    @Column(name = "area_id", columnDefinition = "varchar(50)")
+    private String areaId;
+
+    // 地市名
+    @Column(name = "area_name", columnDefinition = "varchar(50)")
+    private String areaName;
+
+    // 区县编码
+    @Column(name = "city_id", columnDefinition = "varchar(50)")
+    private String cityId;
+
+    // 区县名
+    @Column(name = "city_name", columnDefinition = "varchar(50)")
+    private String cityName;
+
+    // 最后确认的地市
+    @Column(name = "checked_city", columnDefinition = "varchar(50)")
+    private String checkedCity;
+
+    // 最后确认的区县
+    @Column(name = "checked_region", columnDefinition = "varchar(50)")
+    private String checkedRegion;
+
+    // 确认区县的原因
+    @Column(name = "checked_region_reason", columnDefinition = "varchar(50)")
+    private String checkedRegionReason;
+
+    @CreatedDate
+    private Instant createDate;
+
+    @LastModifiedDate
+    private Instant lastUpdateDate;
+}

+ 22 - 19
src/main/java/com/nokia/tsl_data/entity/SysDataDictionary.java

@@ -13,34 +13,37 @@ import java.time.Instant;
 @EntityListeners(AuditingEntityListener.class)
 @Table(name = "sys_data_dictionary", schema = "tsl_data")
 public class SysDataDictionary {
-
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
-    // 工作流id
-    @Column(name = "work_flow_id", columnDefinition = "varchar(50)")
-    private String workFlowId;
+    // 类型名
+    @Column(name = "type", columnDefinition = "varchar(50)")
+    private String type;
+
+    // 真实码
+    @Column(name = "real_code", columnDefinition = "varchar(50)")
+    private String realCode;
 
-    // 工作流类型
-    @Column(name = "work_flow_type_code", columnDefinition = "varchar(50)")
-    private String workFlowTypeCode;
+    // 真实名
+    @Column(name = "real_name", columnDefinition = "varchar(100)")
+    private String realName;
 
-    // 工作流命名
-    @Column(name = "work_flow_name", columnDefinition = "varchar(100)")
-    private String workFlowName;
+    // 其他码
+    @Column(name = "nick_code", columnDefinition = "varchar(50)")
+    private String nickCode;
 
-    // 类型
-    @Column(name = "type_name", columnDefinition = "varchar(50)")
-    private String typeName;
+    // 其他
+    @Column(name = "nick_name", columnDefinition = "varchar(100)")
+    private String nickName;
 
-    // 命名
-    @Column(name = "name", columnDefinition = "varchar(100)")
-    private String name;
+    // 用于排序
+    @Column(name = "ord", columnDefinition = "int4")
+    private Integer ord;
 
-    // 码
-    @Column(name = "code", columnDefinition = "varchar(50)")
-    private String code;
+    @OneToOne
+    @JoinColumn(name = "parent_id", referencedColumnName = "id")
+    private SysDataDictionary parent;
 
     @CreatedDate
     private Instant createDate;

+ 12 - 0
src/main/java/com/nokia/tsl_data/properties/OutputProperties.java

@@ -0,0 +1,12 @@
+package com.nokia.tsl_data.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Data
+@ConfigurationProperties(prefix = "tsl.output")
+public class OutputProperties {
+
+    private String outputPath = "./output";
+    private String outputFileNamePrefix = "投诉清单各地市投诉率";
+}

+ 7 - 6
src/main/java/com/nokia/tsl_data/service/CronTaskService.java

@@ -21,23 +21,24 @@ import java.util.List;
 @Service
 public class CronTaskService {
 
+    private final TslDataDao tslDataDao;
+    private final TaskRecordRepository taskRecordRepository;
     private final WorkFlowService workFlowService;
     private final DataWarehouseService dataWarehouseService;
     private final MessageService messageService;
-    private final TslDataDao tslDataDao;
-    private final TaskRecordRepository taskRecordRepository;
+    private final TslReportService tslReportService;
 
-    public CronTaskService(WorkFlowService workFlowService, DataWarehouseService dataWarehouseService, MessageService messageService, TslDataDao tslDataDao, TaskRecordRepository taskRecordRepository) {
+    public CronTaskService(WorkFlowService workFlowService, DataWarehouseService dataWarehouseService, MessageService messageService, TslDataDao tslDataDao, TaskRecordRepository taskRecordRepository, TslReportService tslReportService) {
         this.workFlowService = workFlowService;
         this.dataWarehouseService = dataWarehouseService;
         this.messageService = messageService;
         this.tslDataDao = tslDataDao;
         this.taskRecordRepository = taskRecordRepository;
+        this.tslReportService = tslReportService;
     }
 
     /**
      * 日报表
-     * TODO
      */
     public void dailyReport() {
         // 当天时间
@@ -51,9 +52,9 @@ public class CronTaskService {
             dataWarehouseService.warehouseHighQualityListDay(day);
             dataWarehouseService.warehouseMobileComplaintDay(day);
             // 生成表
-            // TODO 生成表
+            tslReportService.generateReport(day);
             // 截图
-            // TODO 截图
+            tslReportService.screenShot(day);
         } catch (Exception e) {
             log.error("定时任务出错--{}", e.getMessage());
             e.printStackTrace();

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

@@ -0,0 +1,30 @@
+package com.nokia.tsl_data.service;
+
+import com.nokia.tsl_data.dao.HighQualityDataRepository;
+import org.springframework.stereotype.Service;
+
+/**
+ * 根据高质量明细表生产数据
+ */
+@Service
+public class HighQualityDataService {
+
+    private final HighQualityDataRepository highQualityDataRepository;
+
+    public HighQualityDataService(HighQualityDataRepository highQualityDataRepository) {
+        this.highQualityDataRepository = highQualityDataRepository;
+    }
+
+    /**
+     * 根据商定的算法生成数据
+     */
+    public void generateHighQualityData(String day) {
+        // 1. 获取数据
+
+        // 2. 从 WorkFlowBasicData 更新地市/区县信息
+
+        // 3. 补充数据
+
+        // 4. 仍无数据的配置默认值
+    }
+}

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

@@ -7,8 +7,8 @@ import org.springframework.stereotype.Service;
 public class MessageService {
 
     private final PushMessageService pushMessageService;
-    private final String openConversationId = "";
-    private final String prefix = "";
+    private final String accessToken = "b2f1424d6119affaacab614b184f043fcd2c73db2651bb86eff29992d66820bf";
+    private final String prefix = "CUC:";
 
     public MessageService(PushMessageService pushMessageService) {
         this.pushMessageService = pushMessageService;
@@ -17,7 +17,7 @@ public class MessageService {
 
     public void error(String errorMessage) {
         pushMessageService.sendMarkdownMessage(
-                openConversationId,
+                accessToken,
                 prefix,
                 String.format("<font color=#FF0000>%s</font>", errorMessage),
                 "ERROR"
@@ -25,6 +25,6 @@ public class MessageService {
     }
 
     public void info(String infoMessage) {
-        pushMessageService.sendTextMessage(openConversationId, prefix, infoMessage);
+        pushMessageService.sendTextMessage(accessToken, prefix, infoMessage);
     }
 }

+ 101 - 7
src/main/java/com/nokia/tsl_data/service/TslReportService.java

@@ -1,15 +1,26 @@
 package com.nokia.tsl_data.service;
 
+import com.nokia.common.io.excel.entity.CellRect;
+import com.nokia.common.io.excel.poi.PoiUtil;
+import com.nokia.tsl_data.dao.MobileComplaintMapper;
 import com.nokia.tsl_data.dao.SysDataDictionaryRepository;
+import com.nokia.tsl_data.dao.TslMapper;
+import com.nokia.tsl_data.properties.OutputProperties;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.RegionUtil;
 import org.apache.poi.xssf.usermodel.*;
 import org.springframework.stereotype.Service;
 
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.file.Paths;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -28,21 +39,103 @@ import java.util.Map;
 public class TslReportService {
 
     private final TslDataService tslDataService;
+    private final OutputProperties outputProperties;
+    private final TslMapper tslMapper;
+    private final MobileComplaintMapper mobileComplaintMapper;
     private final SysDataDictionaryRepository sysDataDictionaryRepository;
 
     private XSSFWorkbook workbook = null;
 
     private static final DateFormat DAY_FORMAT = new SimpleDateFormat("yyyyMMdd");
 
-    public TslReportService(TslDataService tslDataService, SysDataDictionaryRepository sysDataDictionaryRepository) {
+    public TslReportService(TslDataService tslDataService, OutputProperties outputProperties, TslMapper tslMapper, MobileComplaintMapper mobileComplaintMapper, SysDataDictionaryRepository sysDataDictionaryRepository) {
         this.tslDataService = tslDataService;
+        this.outputProperties = outputProperties;
+        this.tslMapper = tslMapper;
+        this.mobileComplaintMapper = mobileComplaintMapper;
         this.sysDataDictionaryRepository = sysDataDictionaryRepository;
     }
 
+    /**
+     * 截图任务
+     */
+    public void screenShot(String day) {
+        String fileName = outputProperties.getOutputFileNamePrefix() + day + ".xlsx";
+        File file = Paths.get(outputProperties.getOutputPath(), day, fileName).toFile();
+        if (!file.exists()) {
+            throw new RuntimeException(String.format("无法截图,文件%s不存在", file.getAbsolutePath()));
+        }
+        try (Workbook workbook = WorkbookFactory.create(file);) {
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
+            int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
+            BufferedImage screenShot;
+            // 截图1
+            String area = "A1:" + CellRect.getColumnName(dayOfMonth + 7) + "15";
+            screenShot = PoiUtil.screenShot(workbook.getSheet("管理端-移网质量类"), area, "微软雅黑");
+            ImageIO.write(screenShot, "png", Paths.get(outputProperties.getOutputPath(), day, day + "-1-投诉率.png").toFile());
+
+            // 新截图
+            String area2 = "A1:" + CellRect.getColumnName(dayOfMonth + 7) + "15";
+            screenShot = PoiUtil.screenShot(workbook.getSheet("客户端-战略考核"), area2, "微软雅黑");
+            ImageIO.write(screenShot, "png", Paths.get(outputProperties.getOutputPath(), day, day + "-2-客户端-战略考核.png").toFile());
+
+            // 截图2
+            if (!day.endsWith("01")) {
+                screenShot = PoiUtil.screenShot(workbook.getSheet("管理端-重复投诉率"), "A1:G16", "微软雅黑");
+                ImageIO.write(screenShot, "png", Paths.get(outputProperties.getOutputPath(), day, day + "-3-重复投诉率.png").toFile());
+            }
+
+            // 截图3 4
+            Sheet sheet = workbook.getSheet("投诉处理时长、超时工单概况");
+            screenShot = PoiUtil.screenShot(sheet, "A1:D15", "微软雅黑");
+            ImageIO.write(screenShot, "png", Paths.get(outputProperties.getOutputPath(), day, day + "-4-超时工单.png").toFile());
+            screenShot = PoiUtil.screenShot(sheet, "G1:J14", "微软雅黑");
+            ImageIO.write(screenShot, "png", Paths.get(outputProperties.getOutputPath(), day, day + "-5-处理时长.png").toFile());
+
+            // 截图5
+            screenShot = PoiUtil.screenShot(workbook.getSheet("客户端-投诉问题解决满意度"), "A1:D15", "微软雅黑");
+            ImageIO.write(screenShot, "png", Paths.get(outputProperties.getOutputPath(), day, day + "-6-满意率.png").toFile());
+
+            // 截图6
+            screenShot = PoiUtil.screenShot(workbook.getSheet("客户端-投诉问题解决率"), "A1:D15", "微软雅黑");
+            ImageIO.write(screenShot, "png", Paths.get(outputProperties.getOutputPath(), day, day + "-7-解决率.png").toFile());
+
+            // 截图7
+            screenShot = PoiUtil.screenShot(workbook.getSheet("客户端-投诉问题响应率"), "A1:D15", "微软雅黑");
+            ImageIO.write(screenShot, "png", Paths.get(outputProperties.getOutputPath(), day, day + "-8-响应率.png").toFile());
+        } catch (EncryptedDocumentException | IOException | ParseException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    /**
+     * 生成报表
+     */
+    public void generateReport(String day) {
+        String fileName = outputProperties.getOutputFileNamePrefix() + day + ".xlsx";
+        File file = Paths.get(outputProperties.getOutputPath(), day).toFile();
+        if (!file.exists()) {
+            boolean mkdirs = file.mkdirs();
+            System.out.println(mkdirs);
+        }
+        String dayId = day.substring(0, 4) + "-" + day.substring(4, 6) + "-" + day.substring(6);
+        int qualityCountForDay = tslMapper.selectQualityCountForDay(dayId);
+        if (qualityCountForDay == 0) {
+            throw new RuntimeException("he_d_high_quality表缺少数据");
+        }
+        int compCountForDay = mobileComplaintMapper.selectCompCountForDay(day);
+        if (compCountForDay == 0) {
+            throw new RuntimeException("he_d_mobile_comp表缺少数据");
+        }
+        workbookToFile(day, Paths.get(file.getAbsolutePath(), fileName).toFile());
+    }
+
     /**
      * 写入workbook
      */
-    public void workbookToFile(String day, String path) {
+    private void workbookToFile(String day, File file) {
         // 每次需要重置workbook
         workbook = new XSSFWorkbook();
         // 按照顺序写入各个sheet
@@ -56,11 +149,12 @@ public class TslReportService {
         getSheet3(day);
         // 客户端-投诉问题解决满意度 客户端-投诉问题解决率 客户端-投诉问题响应率
         getSheet4_6(day);
-        try (OutputStream outputStream = new FileOutputStream(path)) {
+        try (OutputStream outputStream = new FileOutputStream(file)) {
             workbook.write(outputStream);
             workbook.close();
             workbook = null;
         } catch (Exception e) {
+            e.printStackTrace();
             log.error("写入失败。。。" + e.getMessage());
         }
     }
@@ -960,7 +1054,7 @@ public class TslReportService {
     private void setConditionalFormatting(Sheet sheet, CellRangeAddress rangeAddress) {
         SheetConditionalFormatting conditionalFormatting = sheet.getSheetConditionalFormatting();
         ConditionalFormattingRule rule = conditionalFormatting.createConditionalFormattingColorScaleRule();
-        XSSFColor[] colors = new XSSFColor[] {
+        XSSFColor[] colors = new XSSFColor[]{
                 new XSSFColor(), new XSSFColor(), new XSSFColor()
         };
         colors[0].setARGBHex("FF63BE7B");
@@ -969,7 +1063,7 @@ public class TslReportService {
 
         rule.getColorScaleFormatting().setColors(colors);
 
-        CellRangeAddress[] cellRangeAddresses = new CellRangeAddress[] {
+        CellRangeAddress[] cellRangeAddresses = new CellRangeAddress[]{
                 rangeAddress
         };
 
@@ -983,7 +1077,7 @@ public class TslReportService {
     private void setConditionalFormatting2(Sheet sheet, CellRangeAddress rangeAddress) {
         SheetConditionalFormatting conditionalFormatting = sheet.getSheetConditionalFormatting();
         ConditionalFormattingRule rule = conditionalFormatting.createConditionalFormattingColorScaleRule();
-        XSSFColor[] colors = new XSSFColor[] {
+        XSSFColor[] colors = new XSSFColor[]{
                 new XSSFColor(), new XSSFColor(), new XSSFColor()
         };
         colors[0].setARGBHex("FFF8696B");
@@ -992,7 +1086,7 @@ public class TslReportService {
 
         rule.getColorScaleFormatting().setColors(colors);
 
-        CellRangeAddress[] cellRangeAddresses = new CellRangeAddress[] {
+        CellRangeAddress[] cellRangeAddresses = new CellRangeAddress[]{
                 rangeAddress
         };
 

+ 5 - 4
src/main/resources/logback-spring.xml

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
     <property name="PATH" value="./log"/>
+    <property name="APP_NAME" value="tal-data" />
     <!-- 用于在console输出日志 -->
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
         <encoder>
@@ -11,10 +12,10 @@
     </appender>
     <!-- 用于写入日志文件 -->
     <appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${PATH}/lfq-n100-trace.log</file>
+        <file>${PATH}/${APP_NAME}-trace.log</file>
         <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
             <!-- 每天切换日志文件 -->
-            <fileNamePattern>${PATH}/tsl_data_trace.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <fileNamePattern>${PATH}/${APP_NAME}-trace.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
             <!-- 单个文件最大值,超过会切换新的日志文件,此配置最大不超过20GB -->
             <maxFileSize>100MB</maxFileSize>
             <!-- 最多保存60天日志 -->
@@ -29,10 +30,10 @@
     </appender>
     <!-- 错误日志写入文件 -->
     <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${PATH}/tsl_data_error.log</file>
+        <file>${PATH}/${APP_NAME}-error.log</file>
         <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
             <!-- 每天切换日志文件 -->
-            <fileNamePattern>${PATH}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <fileNamePattern>${PATH}/${APP_NAME}-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
             <!-- 单个文件最大值,超过会切换新的日志文件,此配置最大不超过20GB -->
             <maxFileSize>100MB</maxFileSize>
             <!-- 最多保存60天日志 -->

+ 18 - 0
src/main/resources/mapper/HighQualityListDayMapper.xml

@@ -0,0 +1,18 @@
+<?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.HighQualityListDayMapper">
+
+    <resultMap id="highQualityDataResultMap" type="com.nokia.tsl_data.entity.HighQualityData">
+        <result property="dayId" column="day_id" />
+        <result property="sheetNo" column="sheet_no" />
+        <result property="cpSatisfaction" column="cp_satisfaction" />
+        <result property="cpIsOk" column="cp_is_ok" />
+        <result property="cpTimelyContact" column="cp_timely_contact" />
+        <result property="noVisitTag" column="cp_timely_contact" />
+        <result property="areaId" column="area_id" />
+        <result property="areaName" column="area_name" />
+        <result property="cityId" column="city_id" />
+        <result property="cityName" column="city_name" />
+    </resultMap>
+</mapper>

+ 73 - 0
src/test/java/com/nokia/tsl_data/MainTest.java

@@ -0,0 +1,73 @@
+package com.nokia.tsl_data;
+
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVPrinter;
+import org.apache.commons.csv.CSVRecord;
+import org.junit.jupiter.api.Test;
+
+import java.io.*;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MainTest {
+
+    @Test
+    void test() throws IOException {
+        String path1 = "D:\\src\\20231023\\移网网络体验明细_202310230930.csv";
+        String path2 = "D:\\src\\20231023\\customerservice_firstline_log_202310231617.csv";
+        String out = "D:\\src\\20231023\\移网网络体验明细_202310230930--.csv";
+
+        DateFormat dateFormat1 = new SimpleDateFormat("yyyy/M/d HH:mm");
+        DateFormat dateFormat2 = new SimpleDateFormat("yyyyMMdd==");
+
+        CSVFormat csvFormat = CSVFormat.DEFAULT.builder().setHeader().build();
+
+        CSVParser parse1 = csvFormat.parse(new InputStreamReader(new FileInputStream(path1), "gbk"));
+        CSVParser parse2 = csvFormat.parse(new InputStreamReader(new FileInputStream(path2), "gbk"));
+        parse2.getHeaderMap().forEach((k, v) -> {
+            System.out.println(k + "===" + v);
+        });
+
+        // 存储2表对应关系
+        Map<String, CSVRecord> map2 = new HashMap<>();
+
+        for (CSVRecord record : parse2.getRecords()) {
+            try {
+                String key = record.get(78).substring(0, 8) + "==" + record.get(0);
+                map2.put(key, record);
+            } catch (Exception e) {
+                System.out.println("=============" + record.get(78));
+            }
+        }
+        System.out.println(parse2.getRecords().size() + "==============================");
+
+        List<String> outHeader = new ArrayList<>();
+        outHeader.addAll(parse1.getHeaderNames());
+        outHeader.addAll(parse2.getHeaderNames());
+
+        CSVPrinter printer = CSVFormat.DEFAULT.builder().setHeader(outHeader.toArray(new String[0])).build().print(new OutputStreamWriter(new FileOutputStream(out), "gbk"));
+        parse1.forEach(record -> {
+            try {
+                String key = dateFormat2.format(dateFormat1.parse(record.get(2))) + record.get(3);
+                for (String s : record) {
+                    printer.print(s);
+                }
+                CSVRecord record1 = map2.get(key);
+                if (record1 != null) {
+                    for (String s : record1) {
+                        printer.print(s);
+                    }
+                }
+                printer.println();
+            } catch (ParseException | IOException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+}

+ 8 - 3
src/test/java/com/nokia/tsl_data/TslDataApplicationTest.java

@@ -1,6 +1,7 @@
 package com.nokia.tsl_data;
 
-import com.nokia.tsl_data.service.TslReportService;
+import com.nokia.tsl_data.dao.HighQualityListDayMapper;
+import com.nokia.tsl_data.entity.HighQualityData;
 import com.nokia.tsl_data.service.UserCountService;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -10,6 +11,7 @@ import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.List;
 
 @SpringBootTest
 class TslDataApplicationTest {
@@ -46,10 +48,13 @@ class TslDataApplicationTest {
     }
 
     @Autowired
-    private TslReportService tslReportService;
+    private HighQualityListDayMapper highQualityListDayMapper;
 
     @Test
     void test() {
-        tslReportService.workbookToFile("20231014", "D:/src/123");
+        List<HighQualityData> highQualityDataOfDay = highQualityListDayMapper.findHighQualityDataOfDay("20231014");
+        for (HighQualityData highQualityData : highQualityDataOfDay) {
+            System.out.println(highQualityData);
+        }
     }
 }

Some files were not shown because too many files changed in this diff