瀏覽代碼

上线测试版本

“lifuquan” 1 年之前
父節點
當前提交
d0ee2f2dbc

+ 1 - 0
doc/需求文档/2024年适配/关于投诉工单日报表2024年适配的需求.md

@@ -46,6 +46,7 @@
     - 排除已退单(re_is_status)状态的工单
     - 统计范围为所有存在归档时间的工单
 2. 处理时长 = 客服受理时间 - 客服受理时间,处理时长超过36小时为超时。
+3. 月底未回单的工单要计入下月工单--所以应该按归档时间计算工单范围
 
 ### 7.4 三率调整
 

+ 40 - 0
src/main/java/com/nokia/tsl_data/dao/AvgDurationMapperV3.java

@@ -0,0 +1,40 @@
+package com.nokia.tsl_data.dao;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+/**
+ * tsl_data.avg_duration_v3 表
+ */
+@Mapper
+public interface AvgDurationMapperV3 {
+
+    /**
+     * 插入上月的平均处理时长
+     */
+    @Insert("with t1 as (select sdd.real_name,kfsn, (extract(epoch from to_timestamp(kf_file_time, 'YYYY-MM-DD HH24:MI:SS'))"
+            + " - extract(epoch from to_timestamp(kd_accept_time, 'YYYY-MM-DD HH24:MI:SS'))) / 3600 as cost_time\n"
+            + "from tsl_data.work_flow_basic_data wfbd, tsl_data.sys_data_dictionary sdd \n" + //
+            " where wfbd.city_id = sdd.nick_code and kf_file_time is not null" +
+            " and re_is_status_id != '06678b79185349b5bf0c24490a978fbb'\n"
+            + "and to_timestamp(wfbd.kf_file_time, 'yyyy-mm-dd hh24:mi:ss') >= to_timestamp(concat(#{month_id}, '01000000'), 'yyyymmddhh24miss') "
+            + " and to_timestamp(wfbd.kf_file_time, 'yyyy-mm-dd hh24:mi:ss') <= " +
+            " (to_timestamp(concat(#{month_id}, '01000000'), 'yyyymmddhh24miss') + interval '1 month'))," +
+            " t2 as (select real_name as city, avg(cost_time) as avg_duration\n" + //
+            " from t1 group by real_name order by real_name), " +
+            " t3 as (select '全省' as city, avg(cost_time) as avg_duration from t1)\n" + //
+            " insert into tsl_data.avg_duration_v3 (month_id, city_name, avg_duration) " +
+            " select #{month_id} as month_id, city as city_name, avg_duration from t2" +
+            " union select #{month_id} as month_id, city as city_name, avg_duration from t3")
+    void insertOldTsDurationForMonth(String monthId);
+
+    /**
+     * 查询历史处理时长
+     */
+    @Select("select city_name, avg_duration from tsl_data.avg_duration_v3 where month_id = #{monthId}")
+    List<Map<String, Object>> selectOldTsDurationForMonth(String monthId);
+}

+ 23 - 28
src/main/java/com/nokia/tsl_data/dao/HighQualityCountMapper.java

@@ -24,16 +24,13 @@ public interface HighQualityCountMapper {
         /**
          * 查询客户端地市响应率数据 参数day_id 20231105
          */
-        @Select("select businoareaname                                                                           as city,\n"
-                        +
-                        "       complaint_response_list::float8                                                          as numerator,\n"
-                        +
-                        "       complaint_response_count::float8 + complaint::float8                                     as denominator,\n"
-                        +
-                        "       complaint_response_list::float8 / (complaint_response_count::float8 + complaint::float8) as rate\n"
-                        +
-                        "from tsl_data.high_quality_count_day\n" +
-                        "where month_id = substring(#{day_id} from 1 for 6)\n" +
+        @Select("select businoareaname as city,\n" +
+                        " complaint_response_list::float8 as numerator,\n" +
+                        " complaint_response_count::float8 + complaint::float8 as denominator,\n" +
+                        " case when complaint_response_count::float8 + complaint::float8 = 0 then 1 else " +
+                        " complaint_response_list::float8 / (complaint_response_count::float8 + complaint::float8) end as rate "
+                        + " from tsl_data.high_quality_count_day\n" +
+                        " where month_id = substring(#{day_id} from 1 for 6)\n" +
                         "  and day_id = substring(#{day_id} from 7 for 2)\n" +
                         "  and profes_dep = '网络质量'\n" +
                         "  and big_type_name = '移网网络体验'\n" +
@@ -43,15 +40,12 @@ public interface HighQualityCountMapper {
         /**
          * 查询客户端地市解决率 参数day_id 20231105
          */
-        @Select("select businoareaname                                                                               as city,\n"
-                        +
-                        "       complaint_resolution_list::float8                                                            as numerator,\n"
-                        +
-                        "       complaint_resolution_count::float8 + complaint::float8                                       as denominator,\n"
-                        +
-                        "       complaint_resolution_list::float8 / (complaint_resolution_count::float8 + complaint::float8) as rate\n"
-                        +
-                        "from tsl_data.high_quality_count_day\n" +
+        @Select("select businoareaname as city,\n" +
+                        " complaint_resolution_list::float8 as numerator,\n" +
+                        " complaint_resolution_count::float8 + complaint::float8 as denominator,\n" +
+                        " case when complaint_resolution_count::float8 + complaint::float8 = 0 then 1 else " +
+                        " complaint_resolution_list::float8 / (complaint_resolution_count::float8 + complaint::float8) end as rate "
+                        + "from tsl_data.high_quality_count_day\n" +
                         "where month_id = substring(#{day_id} from 1 for 6)\n" +
                         "  and day_id = substring(#{day_id} from 7 for 2)\n" +
                         "  and profes_dep = '网络质量'\n" +
@@ -62,12 +56,13 @@ public interface HighQualityCountMapper {
         /**
          * 查询客户端地市满意度 参数day_id 20231105
          */
-        @Select("select businoareaname                                                                             as city,\n"
-                        + " complaint_satisfied_list::float8                                                           as numerator,\n"
-                        + " complaint_satisfied_count::float8 + complaint::float8                                      as denominator,\n"
-                        + " complaint_satisfied_list::float8 / (complaint_satisfied_count::float8 + complaint::float8) as rate\n"
-                        + "from tsl_data.high_quality_count_day\n" +
-                        "where month_id = substring(#{day_id} from 1 for 6)\n" +
+        @Select("select businoareaname as city,\n"
+                        + " complaint_satisfied_list::float8 as numerator,\n"
+                        + " complaint_satisfied_count::float8 + complaint::float8 as denominator,\n"
+                        + " case when complaint_satisfied_count::float8 + complaint::float8 = 0 then 1 else" +
+                        " complaint_satisfied_list::float8 / (complaint_satisfied_count::float8 + complaint::float8) end as rate "
+                        + " from tsl_data.high_quality_count_day\n" +
+                        " where month_id = substring(#{day_id} from 1 for 6)\n" +
                         "  and day_id = substring(#{day_id} from 7 for 2)\n" +
                         "  and profes_dep = '网络质量'\n" +
                         "  and big_type_name = '移网网络体验'\n" +
@@ -86,11 +81,11 @@ public interface HighQualityCountMapper {
                         + " 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 " +
+                        "case when (complaint_satisfied_count + complaint) = 0 then 1 " +
                         "  else complaint_satisfied_list / (complaint_satisfied_count + complaint) end as complaint_satisfied, "
-                        + "case when (complaint_resolution_count + complaint) = 0 then 0 " +
+                        + "case when (complaint_resolution_count + complaint) = 0 then 1 " +
                         "  else complaint_resolution_list / (complaint_resolution_count + complaint) end as complaint_resolution, "
-                        + "case when (complaint_response_count + complaint) = 0 then 0 " +
+                        + "case when (complaint_response_count + complaint) = 0 then 1 " +
                         "  else complaint_response_list / (complaint_response_count + complaint) end     as complaint_response from t1")
         List<Map<String, Object>> selectClientRatioForDay(String day);
 

+ 12 - 8
src/main/java/com/nokia/tsl_data/dao/WorkFlowBasicDataMapper.java

@@ -19,9 +19,10 @@ public interface WorkFlowBasicDataMapper {
                         + "from tsl_data.work_flow_basic_data wfbd, tsl_data.sys_data_dictionary sdd \n" + //
                         "where kf_file_time is not null and re_is_status_id != '06678b79185349b5bf0c24490a978fbb'\n" + //
                         "and wfbd.city_id = sdd.nick_code and" +
-                        " to_timestamp(kd_accept_time, 'yyyy-mm-dd hh24:mi:ss') >= #{start}"
-                        + " and to_timestamp(kd_accept_time, 'yyyy-mm-dd hh24:mi:ss') <= #{end})," +
-                        "t2 as (select '全省' as city, count(1) as total_num, count(is_timeout or null) as timeout_num, " +
+                        " to_timestamp(kf_file_time, 'yyyy-mm-dd hh24:mi:ss') >= #{start}"
+                        + " and to_timestamp(kf_file_time, 'yyyy-mm-dd hh24:mi:ss') <= #{end})," +
+                        "t2 as (select '全省' as city, count(1) as total_num, count(is_timeout or null) as timeout_num, "
+                        +
                         " count(is_timeout or null)::float8 / count(1) as timeout_ratio from t1),"
                         + " t3 as (select city, count(1) as total_num, count(is_timeout or null) as timeout_num, " +
                         " count(is_timeout or null)::float8 / count(1) as timeout_ratio from t1 group by city) " +
@@ -34,10 +35,13 @@ public interface WorkFlowBasicDataMapper {
         @Select("with t1 as (select sdd.real_name,kfsn, (extract(epoch from to_timestamp(kf_file_time, 'YYYY-MM-DD HH24:MI:SS'))"
                         + " - extract(epoch from to_timestamp(kd_accept_time, 'YYYY-MM-DD HH24:MI:SS'))) / 3600 as cost_time\n"
                         + "from tsl_data.work_flow_basic_data wfbd, tsl_data.sys_data_dictionary sdd \n" + //
-                        "where wfbd.city_id = sdd.nick_code and kf_file_time is not null and re_is_status_id != '06678b79185349b5bf0c24490a978fbb'\n"
-                        + "and to_timestamp(wfbd.kd_accept_time, 'yyyy-mm-dd hh24:mi:ss') >= #{start}" +
-                        " and to_timestamp(wfbd.kd_accept_time, 'yyyy-mm-dd hh24:mi:ss') <= #{end})"
-                        + "select real_name as city, avg(cost_time) as avg_duration\n" + //
-                        "from t1 group by real_name order by real_name")
+                        " where wfbd.city_id = sdd.nick_code and kf_file_time is not null" +
+                        " and re_is_status_id != '06678b79185349b5bf0c24490a978fbb'\n"
+                        + "and to_timestamp(wfbd.kf_file_time, 'yyyy-mm-dd hh24:mi:ss') >= #{start}" +
+                        " and to_timestamp(wfbd.kf_file_time, 'yyyy-mm-dd hh24:mi:ss') <= #{end})," +
+                        " t2 as (select real_name as city, avg(cost_time) as avg_duration\n" + //
+                        " from t1 group by real_name order by real_name), " +
+                        " t3 as (select '全省' as city, avg(cost_time) as avg_duration from t1)\n" + //
+                        " select * from t2 union select * from t3")
         List<Map<String, Object>> selectTsDurationForDay(@Param("start") Date start, @Param("end") Date end);
 }

+ 114 - 7
src/main/java/com/nokia/tsl_data/service/HighQualityCountService.java

@@ -3,9 +3,12 @@ package com.nokia.tsl_data.service;
 import com.nokia.tsl_data.dao.HighQualityCountMapper;
 import com.nokia.tsl_data.dao.SysDataDictionaryRepository;
 import com.nokia.tsl_data.properties.CustomerRateTargetProperties;
+
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -16,14 +19,118 @@ import java.util.Map;
 @Service
 public class HighQualityCountService {
 
-    private final HighQualityCountMapper highQualityCountMapper;
-    private final SysDataDictionaryRepository sysDataDictionaryRepository;
-    private final CustomerRateTargetProperties customerRateTargetProperties;
+    @Autowired
+    private HighQualityCountMapper highQualityCountMapper;
+    @Autowired
+    private SysDataDictionaryRepository sysDataDictionaryRepository;
+    @Autowired
+    private CustomerRateTargetProperties customerRateTargetProperties;
 
-    public HighQualityCountService(HighQualityCountMapper highQualityCountMapper, SysDataDictionaryRepository sysDataDictionaryRepository, CustomerRateTargetProperties customerRateTargetProperties) {
-        this.highQualityCountMapper = highQualityCountMapper;
-        this.sysDataDictionaryRepository = sysDataDictionaryRepository;
-        this.customerRateTargetProperties = customerRateTargetProperties;
+    public List<List<Object>> getThreeRateOfCityV3(String day) {
+        List<List<Object>> result = new ArrayList<>();
+        // 各地市
+        for (String cityName : sysDataDictionaryRepository.findAllCityName()) {
+            List<Object> list = new ArrayList<>();
+            list.add(cityName);
+            result.add(list);
+        }
+        // 顺序是 满意率 解决率 响应率
+        Map<String, Double[]> map = generateThreeRateOfCityV3(day);
+        result.forEach(list -> {
+            Double[] arr = map.get(list.get(0).toString());
+            list.add(arr[0]);
+            list.add(arr[1]);
+            list.add(arr[2]);
+            // 移网综合投诉评价“三率”=响应率*0.1+解决率*0.4+满意率*0.5
+            double rate = arr[2] * 0.1 + arr[1] * 0.4 + arr[0] * 0.5;
+            list.add(rate);
+            list.add(0.92d);
+            list.add(0.92d - rate);
+        });
+        // 逆序排序
+        result.sort((o1, o2) -> Double.compare((double) o2.get(6), (double) o1.get(6)));
+        // 全省
+        Double[] allCity = map.get("全省");
+        double rate = allCity[2] * 0.1 + allCity[1] * 0.4 + allCity[0] * 0.5;
+        result.add(new ArrayList<Object>() {
+            {
+                add("全省");
+                add(allCity[0]);
+                add(allCity[1]);
+                add(allCity[2]);
+                add(rate);
+                add(0.92d);
+                add(0.92d - rate);
+            }
+        });
+        return result;
+    }
+
+    /**
+     * 客户端地市满意度 客户端地市解决率 客户端地市响应率
+     */
+    public Map<String, Double[]> generateThreeRateOfCityV3(String day) {
+        // 顺序是 满意率 解决率 响应率
+        Map<String, Double[]> result = new HashMap<>();
+        for (String cityName : sysDataDictionaryRepository.findAllCityName()) {
+            Double[] arr = new Double[6];
+            Arrays.fill(arr, 1.0d);
+            result.put(cityName, arr);
+        }
+        Double[] allCity = new Double[3];
+        result.put("全省", allCity);
+        double numerator = 0, denominator = 0;
+        // 客户端地市满意率
+        List<Map<String, Object>> satisfiedOfCity = highQualityCountMapper.selectSatisfiedOfCity(day);
+        for (Map<String, Object> map : satisfiedOfCity) {
+            String key = (String) map.get("city");
+            Double[] arr;
+            if (key.equals("雄安新区")) {
+                arr = result.get("雄安");
+            } else {
+                arr = result.get(key);
+            }
+            arr[0] = (double) map.get("rate");
+            numerator += (double) map.get("numerator");
+            denominator += (double) map.get("denominator");
+        }
+        allCity[0] = numerator / denominator;
+        // 客户端地市解决率
+        numerator = 0;
+        denominator = 0;
+        List<Map<String, Object>> resolutionOfCity = highQualityCountMapper.selectResolutionOfCity(day);
+        for (Map<String, Object> map : resolutionOfCity) {
+            String key = (String) map.get("city");
+            Double[] arr;
+            if (key.equals("雄安新区")) {
+                arr = result.get("雄安");
+            } else {
+                arr = result.get(key);
+            }
+            arr[1] = (double) map.get("rate");
+            numerator += (double) map.get("numerator");
+            denominator += (double) map.get("denominator");
+        }
+        allCity[1] = numerator / denominator;
+        // 客户端地市响应率
+        numerator = 0;
+        denominator = 0;
+        List<Map<String, Object>> responseOfCity = highQualityCountMapper.selectResponseOfCity(day);
+        for (Map<String, Object> map : responseOfCity) {
+            String key = (String) map.get("city");
+            Double[] arr;
+            if (key.equals("雄安新区")) {
+                arr = result.get("雄安");
+            } else {
+                arr = result.get(key);
+            }
+            arr[2] = (double) map.get("rate");
+            numerator += (double) map.get("numerator");
+            denominator += (double) map.get("denominator");
+        }
+        allCity[2] = numerator / denominator;
+
+        return result;
     }
 
     /**

+ 52 - 142
src/main/java/com/nokia/tsl_data/service/ReportServiceV3.java

@@ -52,6 +52,8 @@ public class ReportServiceV3 {
     @Autowired
     private SysDataDictionaryRepository sysDataDictionaryRepository;
     @Autowired
+    private HighQualityCountService highQualityCountService;
+    @Autowired
     private ManagementDetailService managementDetailService;
     @Autowired
     private WorkFlowService workFlowService;
@@ -71,39 +73,35 @@ public class ReportServiceV3 {
             int dayOfMonth = Integer.parseInt(day.substring(6, 8));
             BufferedImage screenShot;
             Sheet sheet;
+            String area;
             // 截图 管理端-移网感知类
             sheet = workbook.getSheet("管理端-移网感知类");
             if (sheet != null) {
-                String area = "A1:" + CellRect.getColumnName(dayOfMonth + 7) + "15";
+                area = "A1:" + CellRect.getColumnName(dayOfMonth + 7) + "15";
                 screenShot = PoiUtil.screenShot(sheet, area, "微软雅黑");
                 ImageIO.write(screenShot, "png",
-                        Paths.get(file.getParentFile().getAbsolutePath(), day + "-1-投诉率.png").toFile());
+                        Paths.get(file.getParentFile().getAbsolutePath(), "管理端-移网感知类" + day + ".png").toFile());
             }
             // 截图 服请
             // 截图 重复投诉 超时工单
-            // 截图 三率
-            String area = "A1:D15";
-            sheet = workbook.getSheet("客户端-投诉问题解决满意度");
+            sheet = workbook.getSheet("投诉处理时长、超时工单概况");
             if (sheet != null) {
+                area = "A1:D15";
                 screenShot = PoiUtil.screenShot(sheet, area, "微软雅黑");
                 ImageIO.write(screenShot, "png",
-                        Paths.get(file.getParentFile().getAbsolutePath(), day + "-5-满意度.png").toFile());
-            }
-            sheet = workbook.getSheet("客户端-投诉问题解决率");
-            if (sheet != null) {
-                if (sheet != null) {
-                    screenShot = PoiUtil.screenShot(sheet, area, "微软雅黑");
-                    ImageIO.write(screenShot, "png",
-                            Paths.get(file.getParentFile().getAbsolutePath(), day + "-6-解决率.png").toFile());
-                }
+                        Paths.get(file.getParentFile().getAbsolutePath(), "超时工单概况" + day + ".png").toFile());
+                area = "G1:J14";
+                screenShot = PoiUtil.screenShot(sheet, area, "微软雅黑");
+                ImageIO.write(screenShot, "png",
+                        Paths.get(file.getParentFile().getAbsolutePath(), "投诉处理时长" + day + ".png").toFile());
             }
-            sheet = workbook.getSheet("客户端-投诉问题响应率");
+            // 截图 移网综合投诉评价
+            sheet = workbook.getSheet("移网综合投诉评价");
             if (sheet != null) {
-                if (sheet != null) {
-                    screenShot = PoiUtil.screenShot(sheet, area, "微软雅黑");
-                    ImageIO.write(screenShot, "png",
-                            Paths.get(file.getParentFile().getAbsolutePath(), day + "-7-响应率.png").toFile());
-                }
+                area = "A1:G15";
+                screenShot = PoiUtil.screenShot(sheet, area, "微软雅黑");
+                ImageIO.write(screenShot, "png",
+                        Paths.get(file.getParentFile().getAbsolutePath(), "移网综合投诉评价" + day + ".png").toFile());
             }
         } catch (EncryptedDocumentException | IOException e) {
             e.printStackTrace();
@@ -123,12 +121,11 @@ public class ReportServiceV3 {
         log.info("帐期 {} 管理端-移网感知类 sheet写入成功", day);
         // 1.2 写入 服请情况
         // 1.3 写入 投诉处理时长、超时工单概况
-        // TODO
         writeSheet3(workbookWrapper, day);
         log.info("帐期 {} 投诉处理时长、超时工单概况 sheet写入成功", day);
         // 1.4 写入三率
         tslDataService.checkStatDayCount(day);
-        writeSheet4_6(workbookWrapper, day);
+        writeSheet4(workbookWrapper, day);
         log.info("帐期 {} 客户端-三率 sheet写入成功", day);
         // 2. 写入到本地文件
         try (OutputStream outputStream = new FileOutputStream(file)) {
@@ -143,12 +140,10 @@ public class ReportServiceV3 {
     }
 
     /**
-     * 客户端-投诉问题解决满意度
-     * 客户端-投诉问题解决率
-     * 客户端-投诉问题响应率
+     * 移网综合投诉评价
      */
-    private void writeSheet4_6(XSSFWorkbookWrapper workbookWrapper, String day) {
-        List<List<List<Object>>> sheet4_6Data = tslDataService.getSheet4_6Data(day);
+    private void writeSheet4(XSSFWorkbookWrapper workbookWrapper, String day) {
+        List<List<Object>> data = highQualityCountService.getThreeRateOfCityV3(day);
         // 计算时间常数
         Calendar calendar = Calendar.getInstance(Locale.CHINA);
         try {
@@ -157,19 +152,15 @@ public class ReportServiceV3 {
             log.error("时间字符串解析失败--{}", day);
         }
         int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
-        Sheet sheet4 = workbookWrapper.getWorkbook().createSheet("客户端-投诉问题解决满意度");
-        Sheet sheet5 = workbookWrapper.getWorkbook().createSheet("客户端-投诉问题解决率");
-        Sheet sheet6 = workbookWrapper.getWorkbook().createSheet("客户端-投诉问题响应率");
+        Sheet sheet4 = workbookWrapper.getWorkbook().createSheet("移网综合投诉评价");
         Row row;
         Cell cell;
-
-        // 客户端-投诉问题解决满意度 第一行
         row = sheet4.createRow(0);
         cell = row.createCell(0);
-        cell.setCellValue(String.format("投诉问题解决满意率(1-%s)", dayOfMonth));
+        cell.setCellValue(String.format("移网综合投诉评价(1-%s)", dayOfMonth));
         cell.setCellStyle(workbookWrapper.getCellStyle3());
         // 合并单元格 A1 - D1
-        PoiUtil.addMergedRegion(sheet4, 0, 0, 0, 3);
+        PoiUtil.addMergedRegion(sheet4, 0, 0, 0, 6);
         // 客户端-投诉问题解决满意度 第二行
         row = sheet4.createRow(1);
         cell = row.createCell(0);
@@ -179,144 +170,63 @@ public class ReportServiceV3 {
         cell.setCellValue("满意率");
         cell.setCellStyle(workbookWrapper.getCellStyle3());
         cell = row.createCell(2);
-        cell.setCellValue("达标值");
+        cell.setCellValue("解决率");
         cell.setCellStyle(workbookWrapper.getCellStyle3());
         cell = row.createCell(3);
-        cell.setCellValue("与达标值差距");
-        cell.setCellStyle(workbookWrapper.getCellStyle3());
-        int rowNum = 2;
-        for (List<Object> list : sheet4_6Data.get(0)) {
-            row = sheet4.createRow(rowNum++);
-            // 地市
-            cell = row.createCell(0);
-            cell.setCellValue(list.get(0).toString());
-            cell.setCellStyle(workbookWrapper.getCellStyle1());
-            // 投诉问题解决满意率
-            cell = row.createCell(1);
-            cell.setCellValue(((double) list.get(1)));
-            cell.setCellStyle(workbookWrapper.getCellStyle2());
-            // 达标值
-            cell = row.createCell(2);
-            cell.setCellValue((double) list.get(2));
-            cell.setCellStyle(workbookWrapper.getCellStyle2());
-            // 与达标值差距
-            cell = row.createCell(3);
-            cell.setCellValue(((double) list.get(3)));
-            cell.setCellStyle(workbookWrapper.getCellStyle2());
-        }
-        // 设置条件格式D3-D14
-        PoiUtil.setConditionalFormattingRedToGreen(sheet4, 2, 13, 3, 3);
-        // 设置列宽 2048 1304 2048 2304
-        for (int i = 0; i < 4; i++) {
-            sheet4.setColumnWidth(i, 2848);
-        }
-        // 设置行高 15.0 15.0...
-        for (int i = 0; i < 15; i++) {
-            sheet4.getRow(i).setHeightInPoints(15.0F);
-        }
-
-        // 客户端-投诉问题解决率
-        row = sheet5.createRow(0);
-        cell = row.createCell(0);
-        cell.setCellValue(String.format("投诉问题解决率(1-%s)", dayOfMonth));
-        cell.setCellStyle(workbookWrapper.getCellStyle3());
-        // 合并单元格 A1 - D1
-        PoiUtil.addMergedRegion(sheet5, 0, 0, 0, 3);
-        // 客户端-投诉问题解决率 第二行
-        row = sheet5.createRow(1);
-        cell = row.createCell(0);
-        cell.setCellValue("地市");
+        cell.setCellValue("响应率");
         cell.setCellStyle(workbookWrapper.getCellStyle3());
-        cell = row.createCell(1);
-        cell.setCellValue("解决率");
+        cell = row.createCell(4);
+        cell.setCellValue("综合评价");
         cell.setCellStyle(workbookWrapper.getCellStyle3());
-        cell = row.createCell(2);
+        cell = row.createCell(5);
         cell.setCellValue("达标值");
         cell.setCellStyle(workbookWrapper.getCellStyle3());
-        cell = row.createCell(3);
+        cell = row.createCell(6);
         cell.setCellValue("与达标值差距");
         cell.setCellStyle(workbookWrapper.getCellStyle3());
-        rowNum = 2;
-        for (List<Object> list : sheet4_6Data.get(1)) {
-            row = sheet5.createRow(rowNum++);
+        // 写入各地市数据
+        int rowNum = 2;
+        for (List<Object> list : data) {
+            row = sheet4.createRow(rowNum++);
             // 地市
             cell = row.createCell(0);
             cell.setCellValue(list.get(0).toString());
             cell.setCellStyle(workbookWrapper.getCellStyle1());
-            // 投诉问题解决
+            // 满意率
             cell = row.createCell(1);
-            cell.setCellValue(((double) list.get(1)));
+            cell.setCellValue((double) list.get(1));
             cell.setCellStyle(workbookWrapper.getCellStyle2());
-            // 达标值
+            // 解决率
             cell = row.createCell(2);
             cell.setCellValue((double) list.get(2));
             cell.setCellStyle(workbookWrapper.getCellStyle2());
-            // 与达标值差距
+            // 相应率
             cell = row.createCell(3);
-            cell.setCellValue(((double) list.get(3)));
+            cell.setCellValue((double) list.get(3));
             cell.setCellStyle(workbookWrapper.getCellStyle2());
-        }
-        // 设置条件格式D3-D14
-        PoiUtil.setConditionalFormattingRedToGreen(sheet5, 2, 13, 3, 3);
-        // 设置列宽 2048 1304 2048 2304
-        for (int i = 0; i < 4; i++) {
-            sheet5.setColumnWidth(i, 2848);
-        }
-        // 设置行高 15.0 15.0...
-        for (int i = 0; i < 15; i++) {
-            sheet5.getRow(i).setHeightInPoints(15.0F);
-        }
-
-        // 客户端-投诉问题响应率
-        row = sheet6.createRow(0);
-        cell = row.createCell(0);
-        cell.setCellValue(String.format("投诉问题响应率(1-%s)", dayOfMonth));
-        cell.setCellStyle(workbookWrapper.getCellStyle3());
-        // 合并单元格 A1 - D1
-        PoiUtil.addMergedRegion(sheet6, 0, 0, 0, 3);
-        // 客户端-投诉问题响应率 第二行
-        row = sheet6.createRow(1);
-        cell = row.createCell(0);
-        cell.setCellValue("地市");
-        cell.setCellStyle(workbookWrapper.getCellStyle3());
-        cell = row.createCell(1);
-        cell.setCellValue("响应率");
-        cell.setCellStyle(workbookWrapper.getCellStyle3());
-        cell = row.createCell(2);
-        cell.setCellValue("达标值");
-        cell.setCellStyle(workbookWrapper.getCellStyle3());
-        cell = row.createCell(3);
-        cell.setCellValue("与达标值差距");
-        cell.setCellStyle(workbookWrapper.getCellStyle3());
-        rowNum = 2;
-        for (List<Object> list : sheet4_6Data.get(2)) {
-            row = sheet6.createRow(rowNum++);
-            // 地市
-            cell = row.createCell(0);
-            cell.setCellValue(list.get(0).toString());
-            cell.setCellStyle(workbookWrapper.getCellStyle1());
-            // 投诉问题解决率
-            cell = row.createCell(1);
-            cell.setCellValue(((double) list.get(1)));
+            // 综合评价
+            cell = row.createCell(4);
+            // 移网综合投诉评价“三率”=响应率*0.1+解决率*0.4+满意率*0.5
+            cell.setCellValue((double) list.get(4));
             cell.setCellStyle(workbookWrapper.getCellStyle2());
             // 达标值
-            cell = row.createCell(2);
-            cell.setCellValue((double) list.get(2));
+            cell = row.createCell(5);
+            cell.setCellValue((double) list.get(5));
             cell.setCellStyle(workbookWrapper.getCellStyle2());
             // 与达标值差距
-            cell = row.createCell(3);
-            cell.setCellValue(((double) list.get(3)));
+            cell = row.createCell(6);
+            cell.setCellValue((double) list.get(6));
             cell.setCellStyle(workbookWrapper.getCellStyle2());
         }
         // 设置条件格式D3-D14
-        PoiUtil.setConditionalFormattingRedToGreen(sheet6, 2, 13, 3, 3);
+        PoiUtil.setConditionalFormattingGreenToRed(sheet4, 2, 13, 6, 6);
         // 设置列宽 2048 1304 2048 2304
-        for (int i = 0; i < 4; i++) {
-            sheet6.setColumnWidth(i, 2848);
+        for (int i = 0; i < 7; i++) {
+            sheet4.setColumnWidth(i, 2848);
         }
         // 设置行高 15.0 15.0...
         for (int i = 0; i < 15; i++) {
-            sheet6.getRow(i).setHeightInPoints(15.0F);
+            sheet4.getRow(i).setHeightInPoints(15.0F);
         }
     }
 

+ 18 - 5
src/main/java/com/nokia/tsl_data/service/WorkFlowService.java

@@ -1,7 +1,7 @@
 package com.nokia.tsl_data.service;
 
 import com.alibaba.fastjson2.JSONObject;
-import com.nokia.tsl_data.dao.AvgDurationMapper;
+import com.nokia.tsl_data.dao.AvgDurationMapperV3;
 import com.nokia.tsl_data.dao.SysDataDictionaryRepository;
 import com.nokia.tsl_data.dao.TslDataDao;
 import com.nokia.tsl_data.dao.WorkFlowBasicDataMapper;
@@ -43,7 +43,7 @@ public class WorkFlowService {
     @Autowired
     private SysDataDictionaryRepository sysDataDictionaryRepository;
     @Autowired
-    private AvgDurationMapper avgDurationMapper;
+    private AvgDurationMapperV3 avgDurationMapperV3;
 
     private final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
             .withZone(ZoneId.of("Asia/Shanghai"));
@@ -147,11 +147,11 @@ public class WorkFlowService {
         // 获取上个月的时间
         calendar.add(Calendar.MONTH, -1);
         String oldMonthId = new SimpleDateFormat("yyyyMM").format(calendar.getTime());
-        List<Map<String, Object>> oldData = avgDurationMapper.selectOldTsDurationForMonth(oldMonthId);
+        List<Map<String, Object>> oldData = avgDurationMapperV3.selectOldTsDurationForMonth(oldMonthId);
         // 如果上月的平均处理时长数据不存在,需要插入
         if (oldData.size() == 0) {
-            avgDurationMapper.insertOldTsDurationForMonth(oldMonthId);
-            oldData = avgDurationMapper.selectOldTsDurationForMonth(oldMonthId);
+            avgDurationMapperV3.insertOldTsDurationForMonth(oldMonthId);
+            oldData = avgDurationMapperV3.selectOldTsDurationForMonth(oldMonthId);
         }
         // 这里输入的参数格式应为 2014-01-01 00:00:00
         SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyyMMddHHmmss");
@@ -192,6 +192,19 @@ public class WorkFlowService {
         }
         // 逆序排序
         result.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
+        // 全省数据
+        List<Object> allCity = new ArrayList<>(4);
+        result.add(allCity);
+        allCity.add("全省");
+        allCity.add(preMap.get("全省").get("avg_duration"));
+        Map<String, Object> map = dayMap.get("全省");
+        if (map == null) {
+            allCity.add(0.0);
+            allCity.add(0.0);
+        } else {
+            allCity.add(dayMap.get("全省").get("avg_duration"));
+            allCity.add((double) allCity.get(2) - (double) allCity.get(1));
+        }
         return result;
     }
 }

+ 1 - 1
src/main/java/com/nokia/tsl_data/util/excel/PoiUtil.java

@@ -442,7 +442,7 @@ public class PoiUtil {
      */
     public static void setConditionalFormattingRedToGreen(Sheet sheet, int firstRow, int lastRow, int firstCol,
             int lastCol) {
-        String[] colorStringArray = new String[] { "FF63BE7B", "FFFFEB84", "FFF8696B" };
+        String[] colorStringArray = new String[] { "FFF8696B", "FFFFEB84", "FF63BE7B" };
         setConditionalFormatting(sheet, firstRow, lastRow, firstCol, lastCol, colorStringArray);
     }
 

+ 7 - 1
src/main/java/com/nokia/tsl_data/util/excel/entity/ThreeColorGradient.java

@@ -24,7 +24,13 @@ public class ThreeColorGradient {
      * 根据输入值返回一个颜色
      */
     public Color getColor(double d) {
-        if ((d >= startValue && d < middleValue) || (d <= startValue && d > middleValue)) {
+        if (d == startValue) {
+            return startColor;
+        } else if (d == endValue) {
+            return endColor;
+        } else if (d == middleValue) {
+            return middleColor;
+        } else if ((d > startValue && d < middleValue) || (d < startValue && d > middleValue)) {
             // 值在中位数和satartValue之间,计算起始颜色和中间颜色之间的渐进色
             double t = middleValue == startValue ? 0 : (d - startValue) / (middleValue - startValue);
             double red = (1 - t) * startColor.getRed() + t * middleColor.getRed();

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

@@ -1,9 +1,11 @@
 package com.nokia.tsl_data;
 
+import java.util.Date;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 
+import com.nokia.tsl_data.dao.WorkFlowBasicDataMapper;
 import com.nokia.tsl_data.service.TaskService;
 
 @SpringBootTest
@@ -16,4 +18,12 @@ class TslDataApplicationTest {
     void test() {
         taskService.generateReportV3("20240101");
     }
+
+    @Autowired
+    private WorkFlowBasicDataMapper workFlowBasicDataMapper;
+
+    @Test
+    void test1() {
+        workFlowBasicDataMapper.selectTsDurationForDay(new Date(), new Date());
+    }
 }