Преглед изворни кода

dingtalk_auto v1.0 和tsl_data v1.1上线版本

lifuquan пре 2 година
родитељ
комит
0d5790b9d4
25 измењених фајлова са 726 додато и 358 уклоњено
  1. 30 4
      dingtalk_auto/pom.xml
  2. 0 58
      dingtalk_auto/src/main/java/com/nokia/common/aspose/AsposeUtil.java
  3. 9 7
      dingtalk_auto/src/main/java/com/nokia/common/dingtalk/DingTalkUtil.java
  4. 88 0
      dingtalk_auto/src/main/java/com/nokia/common/http/R.java
  5. 2 0
      dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/DingTalkAutoApplication.java
  6. 60 0
      dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/config/DingTalkUtilConfig.java
  7. 37 0
      dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/config/TaskRunner.java
  8. 21 0
      dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/config/TaskSchedulerConfig.java
  9. 93 0
      dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/controller/TslTaskConroller.java
  10. 89 0
      dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/service/TslCronTaskService.java
  11. 106 161
      dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/service/TslTaskService.java
  12. 6 0
      dingtalk_auto/src/main/resources/application-dev.properties
  13. 10 12
      dingtalk_auto/src/main/resources/application.properties
  14. 2 37
      dingtalk_auto/src/test/java/com/nokia/dingtalk_auto/service/task/TslTaskServiceTest.java
  15. 1 1
      doc/开发文档/开发文档.md
  16. 2 2
      doc/开发文档/本地环境接口测试.md
  17. 14 3
      doc/开发文档/部署环境接口测试.md
  18. 16 1
      tsl_data/src/main/java/com/nokia/tsl_data/controller/TslTaskConroller.java
  19. 91 44
      tsl_data/src/main/java/com/nokia/tsl_data/service/TslReportService.java
  20. 7 7
      tsl_data/src/main/java/com/nokia/tsl_data/service/TslTaskService.java
  21. 23 3
      tsl_data/src/main/java/com/nokia/tsl_data/service/TslWaraHouseService.java
  22. 8 8
      tsl_data/src/main/resources/application-dev.properties
  23. 1 1
      tsl_data/src/main/resources/application.properties
  24. 8 7
      tsl_data/src/main/resources/mapper/TslDao.xml
  25. 2 2
      tsl_data/src/test/java/com/nokia/tsl_data/TslDataApplicationTest.java

+ 30 - 4
dingtalk_auto/pom.xml

@@ -38,11 +38,17 @@
     </properties>
 
     <dependencies>
-        <!-- aspose-cells 处理excel 非开源 -->
+        <!-- poi -->
         <dependency>
-            <groupId>com.luhuiguo</groupId>
-            <artifactId>aspose-cells</artifactId>
-            <version>22.4</version>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>5.2.3</version>
+        </dependency>
+        <!-- poi 2007 -->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>5.2.3</version>
         </dependency>
         <!--ssh2 -->
         <dependency>
@@ -74,4 +80,24 @@
         </dependency>
     </dependencies>
 
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.6.14</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <classifier>exec</classifier>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
 </project>

+ 0 - 58
dingtalk_auto/src/main/java/com/nokia/common/aspose/AsposeUtil.java

@@ -1,58 +0,0 @@
-package com.nokia.common.aspose;
-
-import java.io.FileOutputStream;
-
-import com.aspose.cells.ImageOrPrintOptions;
-import com.aspose.cells.ImageType;
-import com.aspose.cells.SheetRender;
-import com.aspose.cells.Worksheet;
-
-public class AsposeUtil {
-
-    private static final String[] colNames = new String[] {
-            "A", "B", "C", "D", "E", "F", "G",
-            "H", "I", "J", "K", "L", "M", "N",
-            "O", "P", "Q", "R", "S", "T",
-            "U", "V", "W", "X", "Y", "Z",
-            "AA", "AB", "AC", "AD", "AE", "AF", "AG",
-            "AH", "AI", "AJ", "AK", "AL", "AM", "AN"
-    };
-
-    /**
-     * 截图并保存位png
-     * 
-     * @param imgPath
-     * @param worksheet
-     * @param area
-     * @throws Exception
-     */
-    public static void screenshot(String imgPath, Worksheet worksheet, String area) throws Exception {
-        if (!imgPath.toLowerCase().endsWith(".png")) {
-            imgPath = imgPath + ".png";
-        }
-        // 设置图片数据的边距
-        worksheet.getPageSetup().setPrintArea(area);
-        worksheet.getPageSetup().setLeftMargin(1);
-        worksheet.getPageSetup().setRightMargin(1);
-        worksheet.getPageSetup().setTopMargin(1);
-        worksheet.getPageSetup().setBottomMargin(1);
-        ImageOrPrintOptions options = new ImageOrPrintOptions();
-        options.setCellAutoFit(false);
-        options.setOnePagePerSheet(true);
-        options.setImageType(ImageType.PNG);
-        SheetRender sheetRender = new SheetRender(worksheet, options);
-        for (int i = 0; i < sheetRender.getPageCount(); i++) {
-            sheetRender.toImage(i, new FileOutputStream(imgPath));
-        }
-    }
-
-    /**
-     * 获取列名
-     * 
-     * @param colId
-     * @return
-     */
-    public static String getColName(int colId) {
-        return colNames[colId];
-    }
-}

+ 9 - 7
dingtalk_auto/src/main/java/com/nokia/common/dingtalk/DingTalkUtil.java

@@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.nokia.common.dingtalk.exception.DingTalkApiException;
 
+import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 
 /*
@@ -34,16 +35,17 @@ public class DingTalkUtil {
 
     private final String appKey;
     private final String appSecret;
-    private final String conversationId;
     private final RestTemplate restTemplate;
     private final RedisTemplate<String, Object> redisTemplate;
     private final ObjectMapper objectMapper;
 
-    public DingTalkUtil(String appKey, String appSecret, String conversationId, RestTemplate restTemplate,
+    @Setter
+    private String conversationId;
+
+    public DingTalkUtil(String appKey, String appSecret, RestTemplate restTemplate,
             RedisTemplate<String, Object> redisTemplate, ObjectMapper objectMapper) {
         this.appKey = appKey;
         this.appSecret = appSecret;
-        this.conversationId = conversationId;
         this.restTemplate = restTemplate;
         this.redisTemplate = redisTemplate;
         this.objectMapper = objectMapper;
@@ -253,7 +255,7 @@ public class DingTalkUtil {
      * 优先从redis获取,redis中不存在的情况下从
      */
     public String getApiToken() throws DingTalkApiException {
-        Object token = redisTemplate.opsForValue().get(API_ACCESS_TOKEN_REDIS_KEY);
+        Object token = redisTemplate.opsForValue().get(appKey + API_ACCESS_TOKEN_REDIS_KEY);
         if (token == null) {
             // 调用api获取accessToken
             String url = "https://api.dingtalk.com/v1.0/oauth2/accessToken";
@@ -274,7 +276,7 @@ public class DingTalkUtil {
                     if (node.get("accessToken") != null) {
                         // 添加到缓存,缓存时间比返回的时间短10秒
                         token = node.get("accessToken").asText();
-                        redisTemplate.boundValueOps(API_ACCESS_TOKEN_REDIS_KEY)
+                        redisTemplate.boundValueOps(appKey + API_ACCESS_TOKEN_REDIS_KEY)
                                 .set(token, Duration.ofSeconds(node.get("expireIn").asLong(3600L) - 10L));
                     } else {
                         throw new DingTalkApiException("api返回格式有误--" + responseEntity.getBody());
@@ -294,7 +296,7 @@ public class DingTalkUtil {
      * 获取oapi access token
      */
     public Object getOapiToken() throws DingTalkApiException {
-        Object token = redisTemplate.opsForValue().get(OAPI_ACCESS_TOKEN_REDIS_KEY);
+        Object token = redisTemplate.opsForValue().get(appKey + OAPI_ACCESS_TOKEN_REDIS_KEY);
 
         if (token == null) {
             String url = "https://oapi.dingtalk.com/gettoken?appkey={0}&appsecret={1}";
@@ -308,7 +310,7 @@ public class DingTalkUtil {
                     if (code == 0) {
                         // 添加到缓存
                         token = node.get("access_token").asText();
-                        redisTemplate.boundValueOps(OAPI_ACCESS_TOKEN_REDIS_KEY)
+                        redisTemplate.boundValueOps(appKey + OAPI_ACCESS_TOKEN_REDIS_KEY)
                                 .set(token, Duration.ofSeconds(node.get("expires_in").asLong(3600L) - 10L));
                     } else {
                         throw new DingTalkApiException(node.get("errmsg").asText());

+ 88 - 0
dingtalk_auto/src/main/java/com/nokia/common/http/R.java

@@ -0,0 +1,88 @@
+package com.nokia.common.http;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 返回值的统一包装
+ */
+public class R {
+    private Boolean success;
+    private String message;
+
+    private Map<String, Object> data = new HashMap<>();
+
+    /**
+     * 私有化构造方法,不允许在外部实例化
+     */
+    private R() {
+    }
+
+    /**
+     * 成功的静态方法
+     *
+     * @return R实例
+     */
+    public static R ok() {
+        R r = new R();
+        r.setSuccess(true);
+        r.setMessage("成功");
+        return r;
+    }
+
+    /**
+     * 失败的静态方法
+     *
+     * @return R实例
+     */
+    public static R error() {
+        R r = new R();
+        r.setSuccess(false);
+        r.setMessage("失败");
+        return r;
+    }
+
+    public R success(Boolean success) {
+        this.setSuccess(success);
+        return this;
+    }
+
+    public R message(String message) {
+        this.setMessage(message);
+        return this;
+    }
+
+    public R data(String key, Object value) {
+        this.data.put(key, value);
+        return this;
+    }
+
+    public R data(Map<String, Object> map) {
+        this.setData(map);
+        return this;
+    }
+
+    public Boolean getSuccess() {
+        return success;
+    }
+
+    public void setSuccess(Boolean success) {
+        this.success = success;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Map<String, Object> getData() {
+        return data;
+    }
+
+    public void setData(Map<String, Object> data) {
+        this.data = data;
+    }
+}

+ 2 - 0
dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/DingTalkAutoApplication.java

@@ -2,11 +2,13 @@ package com.nokia.dingtalk_auto;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 /*
  * 程序启动入口
  */
 @SpringBootApplication
+@EnableScheduling
 public class DingTalkAutoApplication {
 
     public static void main(String[] args) {

+ 60 - 0
dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/config/DingTalkUtilConfig.java

@@ -0,0 +1,60 @@
+package com.nokia.dingtalk_auto.config;
+
+import javax.annotation.Resource;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.client.RestTemplate;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nokia.common.dingtalk.DingTalkUtil;
+
+/**
+ * 注入钉钉机器人工具类
+ */
+@Configuration
+public class DingTalkUtilConfig {
+
+    @Resource
+    private RestTemplate restTemplate;
+    @Resource
+    private RedisTemplate<String, Object> redisTemplate;
+    @Resource
+    private ObjectMapper objectMapper;
+
+    @Value("${remind.dingTalk.appKey:dingothmdq6opv6hjrm5}")
+    private String remindAppKey;
+
+    @Value("${remind.dingTalk.appSecret:SeoyAwUnzFIFY4j4CX089HJ0i-pj1BIzByB3AZcnbCQaq94lZvazFpfEGGQwPznc}")
+    private String remindAppSecret;
+
+    @Value("${remind.dingTalk.openConversationId:cidcWmmFwduUTDB3G0vPNOldQ==}")
+    private String remindOpenConversationId;
+
+    @Value("${tslTask.dingTalk.appKey}")
+    private String tslAppKey;
+
+    @Value("${tslTask.dingTalk.appSecret}")
+    private String tslAppSecret;
+
+    @Value("${tslTask.dingTalk.openConversationId}")
+    private String tslOpenConversationId;
+
+    @Bean("remindDingTalkUtil")
+    public DingTalkUtil remindDingTalkUtil() {
+        DingTalkUtil dingTalkUtil = new DingTalkUtil(remindAppKey, remindAppSecret, restTemplate, redisTemplate,
+                objectMapper);
+        dingTalkUtil.setConversationId(remindOpenConversationId);
+        return dingTalkUtil;
+    }
+
+    @Bean("tslTaskDingTalkUtil")
+    public DingTalkUtil tslTaskDingTalkUtil() {
+        DingTalkUtil dingTalkUtil = new DingTalkUtil(tslAppKey, tslAppSecret, restTemplate, redisTemplate,
+                objectMapper);
+        dingTalkUtil.setConversationId(tslOpenConversationId);
+        return dingTalkUtil;
+    }
+}

+ 37 - 0
dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/config/TaskRunner.java

@@ -0,0 +1,37 @@
+package com.nokia.dingtalk_auto.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+import com.nokia.dingtalk_auto.service.TslCronTaskService;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 在项目启动时根据配置启动任务
+ */
+@Slf4j
+@Component
+public class TaskRunner implements CommandLineRunner {
+
+    @Value("${tslTask.isStarted}")
+    private boolean isStarted;
+
+    @Value("${tslTask.cronExpression}")
+    private String cronExpression;
+
+    @Autowired
+    private TslCronTaskService cronTaskService;
+
+    @Override
+    public void run(String... args) throws Exception {
+        cronTaskService.updateCronExpression(cronExpression);
+        if (isStarted) {
+            cronTaskService.startCronTask();
+        }
+        log.info("已启动定时任务");
+    }
+
+}

+ 21 - 0
dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/config/TaskSchedulerConfig.java

@@ -0,0 +1,21 @@
+package com.nokia.dingtalk_auto.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+
+@Configuration
+public class TaskSchedulerConfig {
+    private int poolSize = 1;
+
+    @Bean
+    public ThreadPoolTaskScheduler taskScheduler() {
+        // 使用最常用的ThreadPoolTaskScheduler
+        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
+        // 线程数
+        taskScheduler.setPoolSize(poolSize);
+        taskScheduler.setRemoveOnCancelPolicy(true);
+        taskScheduler.setThreadNamePrefix("taskSchedulerThreadPool-");
+        return taskScheduler;
+    }
+}

+ 93 - 0
dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/controller/TslTaskConroller.java

@@ -0,0 +1,93 @@
+package com.nokia.dingtalk_auto.controller;
+
+import org.springframework.scheduling.support.CronExpression;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.nokia.common.http.R;
+import com.nokia.dingtalk_auto.service.TslCronTaskService;
+import com.nokia.dingtalk_auto.service.TslTaskService;
+
+/**
+ * 投诉率相关数据源入库
+ * 
+ * 1. 支持定时任务状态查询、修改定时任务表达式、启动或停止定时任务
+ * 支持手动重新生成某天的报告或入库
+ */
+@RequestMapping("/tsl/task")
+@RestController
+public class TslTaskConroller {
+
+    private final TslTaskService taskService;
+    private final TslCronTaskService cronTaskService;
+
+    public TslTaskConroller(TslTaskService taskService, TslCronTaskService cronTaskService) {
+        this.taskService = taskService;
+        this.cronTaskService = cronTaskService;
+    }
+
+    @PostMapping("/send")
+    public R send(@RequestBody String day) {
+        try {
+            taskService.runTask(day);
+            return R.ok().message("发送成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.error().message(e.getMessage());
+        }
+    }
+
+    /**
+     * 启动定时任务
+     * 
+     * @return
+     */
+    @PostMapping("/cron/start")
+    public R startCronTask() {
+        cronTaskService.startCronTask();
+        return R.ok().message("任务启动成功");
+    }
+
+    /**
+     * 停止定时任务
+     * 
+     * @return
+     */
+    @PostMapping("/cron/stop")
+    public R stopCronTask() {
+        cronTaskService.stopCronTask();
+        return R.ok().message("任务已停止");
+    }
+
+    /**
+     * 查询定时任务状态
+     * 
+     * @return
+     */
+    @PostMapping("/cron/status")
+    public R getCronTaskStatus() {
+        String cronExpression = cronTaskService.getCronExpression();
+        boolean started = cronTaskService.isStarted();
+        String status = started ? "启动中" : "已停止";
+        return R.ok().message(String.format("任务状态:%s, 定时表达式:%s", status, cronExpression));
+    }
+
+    /**
+     * 修改定时任务定时表达式
+     * 
+     * @return
+     */
+    @PostMapping("/cron/expression")
+    public R updateCronTaskExpression(@RequestBody String cronExpression) {
+        try {
+            CronExpression.parse(cronExpression);
+        } catch (IllegalArgumentException e) {
+            return R.error().message(String.format("输入的表达式有误, 任务状态不变:%s", e.getMessage()));
+        }
+        String oldCronExpression = cronTaskService.getCronExpression();
+        cronTaskService.updateCronExpression(cronExpression);
+        return R.ok().message(String.format("定时表达式更新成功, 新表达式:%s, 原表达式:%s", cronExpression, oldCronExpression));
+    }
+}

+ 89 - 0
dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/service/TslCronTaskService.java

@@ -0,0 +1,89 @@
+package com.nokia.dingtalk_auto.service;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.concurrent.ScheduledFuture;
+
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.scheduling.support.CronTrigger;
+import org.springframework.stereotype.Service;
+
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 定时任务相关逻辑
+ * 
+ * 支持查询任务状态、启动任务、停止任务、修改任务定时表达式
+ */
+@Slf4j
+@Service
+public class TslCronTaskService {
+
+    @Getter
+    private String cronExpression;
+    @Getter
+    private boolean isStarted = false;
+    private ScheduledFuture<?> future = null;
+
+    private final ThreadPoolTaskScheduler taskScheduler;
+    private final TslTaskService tslTaskService;
+
+    public TslCronTaskService(ThreadPoolTaskScheduler taskScheduler, TslTaskService tslTaskService) {
+        this.taskScheduler = taskScheduler;
+        this.tslTaskService = tslTaskService;
+    }
+
+    /**
+     * 启动任务
+     */
+    public void startCronTask() {
+        if (!isStarted) {
+            future = taskScheduler.schedule(new Runnable() {
+
+                @Override
+                public void run() {
+                    // 获取入参 day
+                    String day = new SimpleDateFormat("yyyyMMdd")
+                            .format(new Date(System.currentTimeMillis() - 1000L * 3600 * 24));
+                    try {
+                        tslTaskService.runTask(day);
+                    } catch (Exception e) {
+                        log.error("定时任务出错--{}", e.getMessage());
+                        e.printStackTrace();
+                    }
+                }
+
+            }, new CronTrigger(cronExpression));
+            isStarted = true;
+        }
+    }
+
+    /**
+     * 停止任务
+     */
+    public void stopCronTask() {
+        if (isStarted) {
+            if (future != null) {
+                // 如果有正在执行的任务,需要执行完
+                future.cancel(false);
+            }
+            isStarted = false;
+        }
+    }
+
+    /**
+     * 修改任务定时表达式
+     * 
+     * @param cronExpression
+     */
+    public void updateCronExpression(String newCronExpression) {
+        cronExpression = newCronExpression;
+        if (isStarted) {
+            // 如果任务在启动状态,需要停止任务并重新启动
+            startCronTask();
+            startCronTask();
+        }
+    }
+
+}

+ 106 - 161
dingtalk_auto/src/main/java/com/nokia/dingtalk_auto/service/TslTaskService.java

@@ -8,40 +8,28 @@ import java.util.Calendar;
 import java.util.List;
 import javax.annotation.Resource;
 
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 
-import com.aspose.cells.Cells;
-import com.aspose.cells.Workbook;
-import com.aspose.cells.Worksheet;
-import com.aspose.cells.WorksheetCollection;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jcraft.jsch.JSchException;
 import com.jcraft.jsch.SftpException;
-import com.nokia.common.aspose.AsposeUtil;
 import com.nokia.common.dingtalk.DingTalkUtil;
 import com.nokia.common.dingtalk.exception.DingTalkApiException;
 import com.nokia.common.jsch.SftpUtil;
 
-import lombok.Getter;
-
 /**
  * 向钉钉群发送投诉清单各地市投诉率
  */
 @Service
 public class TslTaskService {
 
-    @Value("${tslTask.dingTalk.appKey:dingothmdq6opv6hjrm5}")
-    private String appKey;
-
-    @Value("${tslTask.dingTalk.appSecret:SeoyAwUnzFIFY4j4CX089HJ0i-pj1BIzByB3AZcnbCQaq94lZvazFpfEGGQwPznc}")
-    private String appSecret;
-
-    @Value("${tslTask.dingTalk.openConversationId:cidcWmmFwduUTDB3G0vPNOldQ==}")
-    private String openConversationId;
-
     @Value("${tslTask.remoteDir:/data/report_auto/output}")
     private String remoteDir;
 
@@ -67,10 +55,10 @@ public class TslTaskService {
     @Resource
     private ObjectMapper objectMapper;
 
-    @Getter
-    private DingTalkUtil dingTalkUtil;
-    @Getter
-    private boolean isDingTalkUtilInited = false;
+    @Resource
+    private DingTalkUtil tslTaskDingTalkUtil;
+    @Resource
+    private DingTalkUtil remindDingTalkUtil;
 
     // 完成指定日期的发送任务
     public void runTask(String day) throws DingTalkApiException, Exception {
@@ -78,43 +66,31 @@ public class TslTaskService {
         download(day);
         // 2. 生成要发送的内容
         String message = getFilesToSend(day);
+        // 5. 发送提醒
+        remindDingTalkUtil.sendMarkdownMsgWithRobot(message);
         // 3. 发送文件
         sendDingTalkMsg(day);
         // 4. 发送消息
-        if (!isDingTalkUtilInited) {
-            initDingTalkUtil();
-        }
-        dingTalkUtil.sendMarkdownMsgWithRobot(message);
+        tslTaskDingTalkUtil.sendMarkdownMsgWithRobot(message);
+        remindDingTalkUtil.sendTextMsgWithRobot("发送成功==" + day);
     }
 
     public void sendDingTalkMsg(String day) throws DingTalkApiException {
-        if (!isDingTalkUtilInited) {
-            initDingTalkUtil();
-        }
         String localPath = localDir + "/" + day;
         File[] files = new File(localPath).listFiles();
         for (File file : files) {
             if (file.getName().toLowerCase().endsWith(".png")) {
-                String mediaId = dingTalkUtil.upload(file.getAbsolutePath(), "image");
-                dingTalkUtil.sendImageMsgWithRobot(mediaId);
-            } else if (file.getName().toLowerCase().endsWith(".xlsx")) {
-                // TODO 需要确认一下仅发送正常文件且只发送1个
-                String mediaId = dingTalkUtil.upload(file.getAbsolutePath(), "file");
-                dingTalkUtil.sendFileMsgWithRobot(mediaId, file.getName());
+                String mediaId = tslTaskDingTalkUtil.upload(file.getAbsolutePath(), "image");
+                tslTaskDingTalkUtil.sendImageMsgWithRobot(mediaId);
+            } else if (file.getName().toLowerCase().equals("投诉清单各地市投诉率" + day + ".xlsx")) {
+                String mediaId = tslTaskDingTalkUtil.upload(file.getAbsolutePath(), "file");
+                tslTaskDingTalkUtil.sendFileMsgWithRobot(mediaId, file.getName());
             }
         }
     }
 
-    public void initDingTalkUtil() {
-        if (!isDingTalkUtilInited) {
-            dingTalkUtil = new DingTalkUtil(appKey, appSecret, openConversationId, restTemplate,
-                    redisTemplate, objectMapper);
-            isDingTalkUtilInited = true;
-        }
-    }
-
     /**
-     * 截图,组织一段话
+     * 组织一段话
      * 
      * @param day
      * @throws Exception
@@ -128,7 +104,7 @@ public class TslTaskService {
         int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
         stringBuffer.append(calendar.get(Calendar.YEAR))
                 .append("年")
-                .append(calendar.get(Calendar.MONTH + 1))
+                .append(calendar.get(Calendar.MONTH) + 1)
                 .append("月截至")
                 .append(dayOfMonth)
                 .append("日移动网投诉情况统计:\n\n管理端-移网质量类:投诉率:<font color=#FF0000>");
@@ -136,127 +112,98 @@ public class TslTaskService {
         if (!file.exists()) {
             throw new Exception(String.format("文件--%s--不存在", localFile));
         }
-        Workbook workbook = new Workbook(localFile);
-        WorksheetCollection worksheets = workbook.getWorksheets();
-        Worksheet worksheet = worksheets.get("管理端-移网质量类");
-        // 截图1
-        String area = "A1:" + AsposeUtil.getColName(dayOfMonth + 7) + "15";
-        AsposeUtil.screenshot(localPath + day + "-1.png", worksheet, area);
-        Cells cells = worksheet.getCells();
-        List<List<Object>> list = new ArrayList<>();
-        for (int i = 2; i < 14; i++) {
-            double value = cells.get(i, dayOfMonth + 6).getDoubleValue();
-            if (value > 0.0) {
+        try (Workbook workbook = WorkbookFactory.create(file)) {
+            Sheet sheet = workbook.getSheet("管理端-移网质量类");
+            Row row;
+            List<List<Object>> list = new ArrayList<>();
+            for (int i = 2; i < 14; i++) {
+                row = sheet.getRow(i);
+                double value = row.getCell(dayOfMonth + 6).getNumericCellValue();
+                if (value > 0.0) {
+                    List<Object> list2 = new ArrayList<>();
+                    list.add(list2);
+                    list2.add(0, value);
+                    list2.add(1, row.getCell(dayOfMonth + 7).getStringCellValue());
+                }
+            }
+            // 排序
+            list.sort((o1, o2) -> Double.compare((double) o2.get(0), (double) o1.get(0)));
+            StringBuffer stringBuffer2 = new StringBuffer();
+            for (int i = 0; i < list.size(); i++) {
+                stringBuffer.append(list.get(i).get(1).toString()).append("、");
+                if (i < 3) {
+                    stringBuffer2.append(list.get(i).get(1).toString()).append("、");
+                }
+            }
+            stringBuffer.deleteCharAt(stringBuffer.length() - 1);
+            stringBuffer2.deleteCharAt(stringBuffer2.length() - 1);
+            stringBuffer.append("</font>未达到目标值,<font color=#FF0000>")
+                    .append(stringBuffer2.toString())
+                    .append("</font>排名靠后");
+
+            // 1号忽略重复投诉率
+            if (day.endsWith("01")) {
+                stringBuffer.append("。\n\n客户端-移网网络体验:投诉问题解决满意率:<font color=#FF0000>");
+            } else {
+                stringBuffer.append(";重复投诉率:<font color=#FF0000>");
+                sheet = workbook.getSheet("管理端-重复投诉率");
+                stringBuffer.append(sheet.getRow(3).getCell(0).getStringCellValue()).append("、")
+                        .append(sheet.getRow(4).getCell(0).getStringCellValue()).append("、")
+                        .append(sheet.getRow(5).getCell(0).getStringCellValue())
+                        .append("</font>增长较快。\n\n客户端-移网网络体验:投诉问题解决满意率:<font color=#FF0000>");
+            }
+
+            sheet = workbook.getSheet("客户端-投诉问题解决满意度");
+            stringBuffer.append(sheet.getRow(13).getCell(0).getStringCellValue()).append("、")
+                    .append(sheet.getRow(12).getCell(0).getStringCellValue()).append("、")
+                    .append(sheet.getRow(11).getCell(0).getStringCellValue())
+                    .append("</font>较低,与达标值差距较大;投诉问题解决率:<font color=#FF0000>");
+
+            sheet = workbook.getSheet("客户端-投诉问题解决率");
+            stringBuffer.append(sheet.getRow(13).getCell(0).getStringCellValue()).append("、")
+                    .append(sheet.getRow(12).getCell(0).getStringCellValue()).append("、")
+                    .append(sheet.getRow(11).getCell(0).getStringCellValue())
+                    .append("</font>较低,与达标值差距较大;投诉问题响应率:<font color=#FF0000>");
+
+            sheet = workbook.getSheet("客户端-投诉问题响应率");
+            stringBuffer.append(sheet.getRow(13).getCell(0).getStringCellValue()).append("、")
+                    .append(sheet.getRow(12).getCell(0).getStringCellValue()).append("、")
+                    .append(sheet.getRow(11).getCell(0).getStringCellValue())
+                    .append("</font>较低,与达标值差距较大。\n\n投诉处理时长、超时工单概况:超时工单:<font color=#FF0000>");
+
+            sheet = workbook.getSheet("投诉处理时长、超时工单概况");
+            stringBuffer.append(sheet.getRow(2).getCell(0).getStringCellValue()).append("、")
+                    .append(sheet.getRow(3).getCell(0).getStringCellValue()).append("、")
+                    .append(sheet.getRow(4).getCell(0).getStringCellValue())
+                    .append("</font>分公司超时工单占比较高,<font color=#FF0000>");
+            list = new ArrayList<>();
+            for (int i = 2; i < 14; i++) {
                 List<Object> list2 = new ArrayList<>();
                 list.add(list2);
-                list2.add(0, value);
-                list2.add(1, cells.get(i, dayOfMonth + 7).getStringValue());
+                list2.add(0, sheet.getRow(i).getCell(2).getNumericCellValue());
+                list2.add(1, sheet.getRow(i).getCell(0).getStringCellValue());
             }
-        }
-        // 排序
-        list.sort((o1, o2) -> Double.compare((double) o2.get(0), (double) o1.get(0)));
-        StringBuffer stringBuffer2 = new StringBuffer();
-        for (int i = 0; i < list.size(); i++) {
-            stringBuffer.append(list.get(i).get(1).toString()).append("、");
-            if (i < 3) {
-                stringBuffer2.append(list.get(i).get(1).toString()).append("、");
+            list.sort((o1, o2) -> Double.compare((double) o2.get(0), (double) o1.get(0)));
+            stringBuffer.append(list.get(0).get(1).toString()).append("、")
+                    .append(list.get(1).get(1).toString()).append("、")
+                    .append(list.get(2).get(1).toString())
+                    .append("</font>超时工单数量较多。平均处理时长:本月相对较长的地市为<font color=#FF0000>");
+
+            list = new ArrayList<>();
+            for (int i = 2; i < 14; i++) {
+                List<Object> list2 = new ArrayList<>();
+                list.add(list2);
+                list2.add(0, sheet.getRow(i).getCell(8).getNumericCellValue());
+                list2.add(1, sheet.getRow(i).getCell(6).getStringCellValue());
             }
+            list.sort((o1, o2) -> Double.compare((double) o2.get(0), (double) o1.get(0)));
+            stringBuffer.append(list.get(0).get(1).toString()).append("、")
+                    .append(list.get(1).get(1).toString()).append("、")
+                    .append(list.get(2).get(1).toString()).append("</font>;与")
+                    .append(sheet.getRow(1).getCell(7).getStringCellValue()).append("比<font color=#FF0000>")
+                    .append(sheet.getRow(2).getCell(6).getStringCellValue()).append("</font>时长增幅较大。");
         }
-        stringBuffer.deleteCharAt(stringBuffer.length() - 1);
-        stringBuffer2.deleteCharAt(stringBuffer2.length() - 1);
-        stringBuffer.append("</font>未达到目标值,<font color=#FF0000>")
-                .append(stringBuffer2.toString())
-                .append("</font>排名靠后");
-
-        // 1号忽略重复投诉率
-        if (day.endsWith("01")) {
-            stringBuffer.append("。\n\n客户端-移网网络体验:投诉问题解决满意率:<font color=#FF0000>");
-        } else {
-            stringBuffer.append(";重复投诉率:<font color=#FF0000>");
-            // 截图2 重复投诉率
-            worksheet = worksheets.get("管理端-重复投诉率");
-            AsposeUtil.screenshot(localPath + day + "-2.png", worksheet, "A1:G16");
-            cells = worksheet.getCells();
-            stringBuffer.append(cells.get(3, 0).getStringValue())
-                    .append("、")
-                    .append(cells.get(4, 0).getStringValue())
-                    .append("、")
-                    .append(cells.get(5, 0).getStringValue())
-                    .append("</font>增长较快。\n\n客户端-移网网络体验:投诉问题解决满意率:<font color=#FF0000>");
-        }
-
-        // 截图5
-        worksheet = worksheets.get("客户端-投诉问题解决满意度");
-        AsposeUtil.screenshot(localPath + day + "-5.png", worksheet, "A1:D15");
-        cells = worksheet.getCells();
-        stringBuffer.append(cells.get(13, 0).getStringValue())
-                .append("、")
-                .append(cells.get(12, 0).getStringValue())
-                .append("、")
-                .append(cells.get(11, 0).getStringValue())
-                .append("</font>较低,与达标值差距较大;投诉问题解决率:<font color=#FF0000>");
 
-        // 截图6
-        worksheet = worksheets.get("客户端-投诉问题解决率");
-        AsposeUtil.screenshot(localPath + day + "-6.png", worksheet, "A1:D15");
-        cells = worksheet.getCells();
-        stringBuffer.append(cells.get(13, 0).getStringValue())
-                .append("、")
-                .append(cells.get(12, 0).getStringValue())
-                .append("、")
-                .append(cells.get(11, 0).getStringValue())
-                .append("</font>较低,与达标值差距较大;投诉问题响应率:<font color=#FF0000>");
-
-        // 截图7
-        worksheet = worksheets.get("客户端-投诉问题响应率");
-        AsposeUtil.screenshot(localPath + day + "-7.png", worksheet, "A1:D15");
-        cells = worksheet.getCells();
-        stringBuffer.append(cells.get(13, 0).getStringValue())
-                .append("、")
-                .append(cells.get(12, 0).getStringValue())
-                .append("、")
-                .append(cells.get(11, 0).getStringValue())
-                .append("</font>较低,与达标值差距较大。\n\n投诉处理时长、超时工单概况:超时工单:<font color=#FF0000>");
-
-        // 截图3 4
-        worksheet = worksheets.get("投诉处理时长、超时工单概况");
-        AsposeUtil.screenshot(localPath + day + "-3.png", worksheet, "A1:D15");
-        AsposeUtil.screenshot(localPath + day + "-4.png", worksheet, "G1:J14");
-        cells = worksheet.getCells();
-        stringBuffer.append(cells.get(2, 0).getStringValue())
-                .append("、")
-                .append(cells.get(3, 0).getStringValue())
-                .append("、")
-                .append(cells.get(4, 0).getStringValue())
-                .append("</font>分公司超时工单占比较高,<font color=#FF0000>");
-        list = new ArrayList<>();
-        for (int i = 2; i < 14; i++) {
-            List<Object> list2 = new ArrayList<>();
-            list.add(list2);
-            list2.add(0, cells.get(i, 2).getDoubleValue());
-            list2.add(1, cells.get(i, 0).getStringValue());
-        }
-        list.sort((o1, o2) -> Double.compare((double) o2.get(0), (double) o1.get(0)));
-        stringBuffer.append(list.get(0).get(1).toString()).append("、")
-                .append(list.get(1).get(1).toString()).append("、")
-                .append(list.get(2).get(1).toString())
-                .append("</font>超时工单数量较多。平均处理时长:本月相对较长的地市为<font color=#FF0000>");
-
-        list = new ArrayList<>();
-        for (int i = 2; i < 14; i++) {
-            List<Object> list2 = new ArrayList<>();
-            list.add(list2);
-            list2.add(0, cells.get(i, 8).getDoubleValue());
-            list2.add(1, cells.get(i, 6).getStringValue());
-        }
-        list.sort((o1, o2) -> Double.compare((double) o2.get(0), (double) o1.get(0)));
-        stringBuffer.append(list.get(0).get(1).toString()).append("、")
-                .append(list.get(1).get(1).toString()).append("、")
-                .append(list.get(2).get(1).toString())
-                .append("</font>;与").append(cells.get(1, 7).getStringValue()).append("比<font color=#FF0000>")
-                .append(cells.get(2, 6).getStringValue()).append("</font>时长增幅较大。");
-
-        workbook.dispose();
         return stringBuffer.toString();
     }
 
@@ -283,9 +230,7 @@ public class TslTaskService {
             sftpUtil.connect();
             List<String> files = sftpUtil.ls(remotePath);
             for (String fileName : files) {
-                if (fileName.endsWith(".xlsx")) {
-                    sftpUtil.get(remotePath + "/" + fileName, localPath + "/" + fileName);
-                }
+                sftpUtil.get(remotePath + "/" + fileName, localPath + "/" + fileName);
             }
         } catch (JSchException | SftpException | IOException e) {
             e.printStackTrace();

+ 6 - 0
dingtalk_auto/src/main/resources/application-dev.properties

@@ -3,6 +3,12 @@
 spring.redis.host=127.0.0.1
 spring.redis.port=6379
 
+# 李福全测试群
 # tslTask.dingTalk.appKey=dingothmdq6opv6hjrm5
 # tslTask.dingTalk.appSecret=SeoyAwUnzFIFY4j4CX089HJ0i-pj1BIzByB3AZcnbCQaq94lZvazFpfEGGQwPznc
 # tslTask.dingTalk.openConversationId=cidcWmmFwduUTDB3G0vPNOldQ==
+
+# 王玉龙测试群
+# tslTask.dingTalk.appKey=dingzj6ozs4wfzxthzen
+# tslTask.dingTalk.appSecret=f5tIy_k8jjIPdwBT0Uns9cSEbP47vTZcqmkAwMnH0cD_GM4cu26Zt18vjRbylBbz
+tslTask.dingTalk.openConversationId=cidlDlGNd6lQ++tNqDI8kX3Xw==

+ 10 - 12
dingtalk_auto/src/main/resources/application.properties

@@ -1,4 +1,4 @@
-spring.profiles.active=dev
+spring.profiles.active=pro
 
 server.port=11111
 
@@ -8,17 +8,15 @@ tslTask.remoteDir=/data/report_auto/output
 tslTask.remoteHost=133.96.94.105
 tslTask.localDir=./download
 
-# 李福全测试群
-# tslTask.dingTalk.appKey=dingothmdq6opv6hjrm5
-# tslTask.dingTalk.appSecret=SeoyAwUnzFIFY4j4CX089HJ0i-pj1BIzByB3AZcnbCQaq94lZvazFpfEGGQwPznc
-# tslTask.dingTalk.openConversationId=cidcWmmFwduUTDB3G0vPNOldQ==
-
-# 王玉龙测试群
-# tslTask.dingTalk.appKey=dingzj6ozs4wfzxthzen
-# tslTask.dingTalk.appSecret=f5tIy_k8jjIPdwBT0Uns9cSEbP47vTZcqmkAwMnH0cD_GM4cu26Zt18vjRbylBbz
-# tslTask.dingTalk.openConversationId=cidlDlGNd6lQ++tNqDI8kX3Xw==
-
 # 河北联通移动网络优化工作群
 tslTask.dingTalk.appKey=dingzj6ozs4wfzxthzen
 tslTask.dingTalk.appSecret=f5tIy_k8jjIPdwBT0Uns9cSEbP47vTZcqmkAwMnH0cD_GM4cu26Zt18vjRbylBbz
-tslTask.dingTalk.openConversationId=cide4nWtey1XgBmy7VFcsu3rA==
+tslTask.dingTalk.openConversationId=cide4nWtey1XgBmy7VFcsu3rA==
+
+# 任务提醒群
+remind.dingTalk.appKey=dingothmdq6opv6hjrm5
+remind.dingTalk.appSecret=SeoyAwUnzFIFY4j4CX089HJ0i-pj1BIzByB3AZcnbCQaq94lZvazFpfEGGQwPznc
+remind.dingTalk.openConversationId=cidcWmmFwduUTDB3G0vPNOldQ==
+
+tslTask.cronExpression=0 0 14 * * *
+tslTask.isStarted=true

+ 2 - 37
dingtalk_auto/src/test/java/com/nokia/dingtalk_auto/service/task/TslTaskServiceTest.java

@@ -1,14 +1,8 @@
 package com.nokia.dingtalk_auto.service.task;
 
-import java.io.File;
-
-import javax.annotation.Resource;
-
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.data.redis.core.RedisTemplate;
-
 import com.nokia.common.dingtalk.exception.DingTalkApiException;
 import com.nokia.dingtalk_auto.service.TslTaskService;
 
@@ -17,39 +11,10 @@ public class TslTaskServiceTest {
     @Autowired
     private TslTaskService tslTaskService;
 
-    @Resource
-    private RedisTemplate<String, Object> redisTemplate;
-
     @Test
     void test() throws Exception, DingTalkApiException {
-        test2("20230501");
+        tslTaskService.runTask("20230502");
+        // tslTaskService.download("20230502");
     }
 
-    void test3(String day) throws Exception {
-        // 1. 下载文件
-        tslTaskService.download(day);
-        // 2. 生成要发送的内容
-        String message = tslTaskService.getFilesToSend(day);
-        System.out.println(message);
-    }
-
-    void test2(String day) throws Exception {
-        // 1. 下载文件
-        tslTaskService.download(day);
-        // 2. 生成要发送的内容
-        String message = tslTaskService.getFilesToSend(day);
-        System.out.println(message);
-        if (!tslTaskService.isDingTalkUtilInited()) {
-            tslTaskService.initDingTalkUtil();
-        }
-        String localPath = "./download/" + day;
-        File[] files = new File(localPath).listFiles();
-        for (File file : files) {
-            if (file.getName().toLowerCase().endsWith(".xlsx")) {
-                String mediaId = tslTaskService.getDingTalkUtil().upload(file.getAbsolutePath(), "file");
-                tslTaskService.getDingTalkUtil().sendFileMsgWithRobot(mediaId, file.getName());
-            }
-        }
-        tslTaskService.getDingTalkUtil().sendMarkdownMsgWithRobot(message);
-    }
 }

+ 1 - 1
doc/开发文档/开发文档.md

@@ -1,6 +1,6 @@
 # 开发文档
 
-nohup java -jar tsl_data-1.0-exec.jar >output.log 2>&1 &
+nohup java -jar tsl_data-1.1-exec.jar >output.log 2>&1 &
 
 ## 钉钉API相关汇总
 

+ 2 - 2
doc/开发文档/tsl_data/本地环境接口测试.md → doc/开发文档/本地环境接口测试.md

@@ -3,10 +3,10 @@
 ## 数据手动入库
 
 ```http
-POST http://127.0.0.1:29100/tsl/task/warahouse/manually HTTP/1.1
+POST http://127.0.0.1:29100/tsl/task/warahouse HTTP/1.1
 Content-Type:application/json
 
-20230425
+20230502
 ```
 
 ## 定时任务

+ 14 - 3
doc/开发文档/tsl_data/部署环境接口测试.md → doc/开发文档/部署环境接口测试.md

@@ -1,6 +1,8 @@
 # 接口测试
 
-nohup java -jar tsl_data-1.0-exec.jar >output.log 2>&1 &
+nohup java -jar tsl_data-1.1-exec.jar >output.log 2>&1 &
+
+nohup java -jar dingtalk_auto-1.0-exec.jar >output.log 2>&1 &
 
 ## 数据手动入库
 
@@ -8,7 +10,7 @@ nohup java -jar tsl_data-1.0-exec.jar >output.log 2>&1 &
 POST http://192.168.10.7:29100/tsl/task/warahouse HTTP/1.1
 Content-Type:application/json
 
-20230427
+20230502
 ```
 
 ## 手动生成报表
@@ -17,7 +19,16 @@ Content-Type:application/json
 POST http://192.168.10.7:29100/tsl/task/report/generate HTTP/1.1
 Content-Type:application/json
 
-20230501
+20230502
+```
+
+## 查询数据
+
+```http
+POST http://192.168.10.7:29100/tsl/task/check/srcfile HTTP/1.1
+Content-Type:application/json
+
+20230502
 ```
 
 ## 定时任务

+ 16 - 1
tsl_data/src/main/java/com/nokia/tsl_data/controller/TslTaskConroller.java

@@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.RestController;
 import com.nokia.common.http.R;
 import com.nokia.tsl_data.service.TslCronTaskService;
 import com.nokia.tsl_data.service.TslTaskService;
+import com.nokia.tsl_data.service.TslWaraHouseService;
 
 /**
  * 投诉率相关数据源入库
@@ -25,10 +26,13 @@ public class TslTaskConroller {
 
     private final TslTaskService taskService;
     private final TslCronTaskService cronTaskService;
+    private final TslWaraHouseService tslWaraHouseService;
 
-    public TslTaskConroller(TslTaskService taskService, TslCronTaskService cronTaskService) {
+    public TslTaskConroller(TslTaskService taskService, TslCronTaskService cronTaskService,
+            TslWaraHouseService tslWaraHouseService) {
         this.taskService = taskService;
         this.cronTaskService = cronTaskService;
+        this.tslWaraHouseService = tslWaraHouseService;
     }
 
     /**
@@ -54,6 +58,16 @@ public class TslTaskConroller {
         }
     }
 
+    @PostMapping("/check/srcfile")
+    public R checkScrFile(@RequestBody String day) {
+        String check = tslWaraHouseService.check(day);
+        if (check.endsWith("数据源正常。")) {
+            return R.ok().message(check);
+        } else {
+            return R.error().message(check);
+        }
+    }
+
     /**
      * 手动生成报告
      * 
@@ -64,6 +78,7 @@ public class TslTaskConroller {
     public R reportGenrateManully(@RequestBody String day) {
         try {
             taskService.reportGenerateTask(day);
+            taskService.screenShotTask(day);
             return R.ok().message("报告生成成功");
         } catch (NullPointerException e) {
             e.printStackTrace();

+ 91 - 44
tsl_data/src/main/java/com/nokia/tsl_data/service/TslReportService.java

@@ -20,6 +20,7 @@ import org.apache.poi.ss.usermodel.HorizontalAlignment;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.RegionUtil;
 import org.apache.poi.xssf.usermodel.XSSFCellStyle;
@@ -86,12 +87,13 @@ public class TslReportService {
         CellRangeAddress rangeAddress;
         XSSFDataFormat dataFormat = getWorkbook().createDataFormat();
         XSSFFont font = getWorkbook().createFont();
-        font.setFontName("等线");
+        font.setFontName("微软雅黑");
         font.setFontHeightInPoints((short) 10);
-        // 基本模式 等线 10号字 带全边框 水平居中
+        // 基本模式 微软雅黑 10号字 带全边框 水平居中
         XSSFCellStyle baseStyle = getWorkbook().createCellStyle();
         baseStyle.setFont(font);
         baseStyle.setAlignment(HorizontalAlignment.CENTER);
+        baseStyle.setVerticalAlignment(VerticalAlignment.CENTER);
         baseStyle.setBorderBottom(BorderStyle.THIN);
         baseStyle.setBorderTop(BorderStyle.THIN);
         baseStyle.setBorderLeft(BorderStyle.THIN);
@@ -101,11 +103,11 @@ public class TslReportService {
         // 样式2 百分比 2位小数
         XSSFCellStyle cellStyle2 = baseStyle.copy();
         cellStyle2.setDataFormat(dataFormat.getFormat("0.00%"));
-        // 样式3 自动换行 背景色FFE7E6E6
+        // 样式3 自动换行 背景色FFE7E6E6 FFAEAAAA
         XSSFCellStyle cellStyle3 = baseStyle.copy();
-        cellStyle3.setWrapText(true);
+        // cellStyle3.setWrapText(true);
         XSSFColor color = new XSSFColor();
-        color.setARGBHex("FFE7E6E6");
+        color.setARGBHex("FFAEAAAA");
         cellStyle3.setFillPattern(FillPatternType.SOLID_FOREGROUND);
         cellStyle3.setFillForegroundColor(color);
 
@@ -125,7 +127,7 @@ public class TslReportService {
         cell.setCellValue("地市");
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(1);
-        cell.setCellValue("投诉问题解决满意率");
+        cell.setCellValue("满意率");
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(2);
         cell.setCellValue("达标值");
@@ -157,6 +159,20 @@ public class TslReportService {
         rangeAddress = new CellRangeAddress(2, 13, 3, 3);
         setConditionalFormatting2(sheet4, rangeAddress);
 
+        // 设置列宽 2048 1304 2048 2304
+        for (int i = 0; i < 4; i++) {
+            sheet4.setColumnWidth(i, 2848);
+        }
+        // sheet4.setColumnWidth(0, 2048);
+        // sheet4.setColumnWidth(1, 2304);
+        // sheet4.setColumnWidth(2, 2048);
+        // sheet4.setColumnWidth(3, 2804);
+
+        // 设置行高 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);
@@ -171,7 +187,7 @@ public class TslReportService {
         cell.setCellValue("地市");
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(1);
-        cell.setCellValue("投诉问题解决率");
+        cell.setCellValue("解决率");
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(2);
         cell.setCellValue("达标值");
@@ -203,6 +219,20 @@ public class TslReportService {
         rangeAddress = new CellRangeAddress(2, 13, 3, 3);
         setConditionalFormatting2(sheet5, rangeAddress);
 
+        // 设置列宽 2048 1304 2048 2304
+        for (int i = 0; i < 4; i++) {
+            sheet5.setColumnWidth(i, 2848);
+        }
+        // sheet5.setColumnWidth(0, 2048);
+        // sheet5.setColumnWidth(1, 2304);
+        // sheet5.setColumnWidth(2, 2048);
+        // sheet5.setColumnWidth(3, 2804);
+
+        // 设置行高 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);
@@ -217,7 +247,7 @@ public class TslReportService {
         cell.setCellValue("地市");
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(1);
-        cell.setCellValue("投诉问题响应率");
+        cell.setCellValue("响应率");
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(2);
         cell.setCellValue("达标值");
@@ -248,6 +278,20 @@ public class TslReportService {
         // 设置条件格式D3-D14
         rangeAddress = new CellRangeAddress(2, 13, 3, 3);
         setConditionalFormatting2(sheet6, rangeAddress);
+
+        // 设置列宽 2048 1304 2048 2304
+        for (int i = 0; i < 4; i++) {
+            sheet6.setColumnWidth(i, 2848);
+        }
+        // sheet6.setColumnWidth(0, 2048);
+        // sheet6.setColumnWidth(1, 2304);
+        // sheet6.setColumnWidth(2, 2048);
+        // sheet6.setColumnWidth(3, 2848);
+
+        // 设置行高 15.0 15.0...
+        for (int i = 0; i < 15; i++) {
+            sheet6.getRow(i).setHeightInPoints(15.0F);
+        }
     }
 
     /**
@@ -274,12 +318,13 @@ public class TslReportService {
         CellRangeAddress rangeAddress;
         XSSFDataFormat dataFormat = getWorkbook().createDataFormat();
         XSSFFont font = getWorkbook().createFont();
-        font.setFontName("等线");
+        font.setFontName("微软雅黑");
         font.setFontHeightInPoints((short) 10);
-        // 基本模式 等线 10号字 带全边框 水平居中
+        // 基本模式 微软雅黑 10号字 带全边框 水平居中
         XSSFCellStyle baseStyle = getWorkbook().createCellStyle();
         baseStyle.setFont(font);
         baseStyle.setAlignment(HorizontalAlignment.CENTER);
+        baseStyle.setVerticalAlignment(VerticalAlignment.CENTER);
         baseStyle.setBorderBottom(BorderStyle.THIN);
         baseStyle.setBorderTop(BorderStyle.THIN);
         baseStyle.setBorderLeft(BorderStyle.THIN);
@@ -289,11 +334,11 @@ public class TslReportService {
         // 样式2 百分比 2位小数
         XSSFCellStyle cellStyle2 = baseStyle.copy();
         cellStyle2.setDataFormat(dataFormat.getFormat("0.00%"));
-        // 样式3 自动换行 背景色FFE7E6E6
+        // 样式3 自动换行 背景色FFE7E6E6 FFAEAAAA
         XSSFCellStyle cellStyle3 = baseStyle.copy();
-        cellStyle3.setWrapText(true);
+        // cellStyle3.setWrapText(true);
         XSSFColor color = new XSSFColor();
-        color.setARGBHex("FFE7E6E6");
+        color.setARGBHex("FFAEAAAA");
         cellStyle3.setFillPattern(FillPatternType.SOLID_FOREGROUND);
         cellStyle3.setFillForegroundColor(color);
         // 样式4 小数 保留2位
@@ -395,22 +440,23 @@ public class TslReportService {
         setConditionalFormatting(sheet, rangeAddress);
 
         // 设置列宽 2048 2276*3 2048*3 2276*2 3612
-        sheet.setColumnWidth(0, 2048);
-        sheet.setColumnWidth(1, 2276);
-        sheet.setColumnWidth(2, 2276);
-        sheet.setColumnWidth(3, 2276);
-        sheet.setColumnWidth(4, 2048);
-        sheet.setColumnWidth(5, 2048);
-        sheet.setColumnWidth(6, 2048);
-        sheet.setColumnWidth(7, 2276);
-        sheet.setColumnWidth(8, 2276);
-        sheet.setColumnWidth(9, 3612);
+        for (int i = 0; i < 10; i++) {
+            sheet.setColumnWidth(i, 2848);
+        }
+        // sheet.setColumnWidth(0, 2848);
+        // sheet.setColumnWidth(1, 2276);
+        // sheet.setColumnWidth(2, 2276);
+        // sheet.setColumnWidth(3, 2276);
+        // sheet.setColumnWidth(4, 2048);
+        // sheet.setColumnWidth(5, 2048);
+        // sheet.setColumnWidth(6, 2048);
+        // sheet.setColumnWidth(7, 2276);
+        // sheet.setColumnWidth(8, 2276);
+        // sheet.setColumnWidth(9, 3612);
 
         // 设置行高 14.25 25.5 14.25...
-        sheet.getRow(0).setHeightInPoints(14.25F);
-        sheet.getRow(1).setHeightInPoints(25.5F);
-        for (int i = 2; i < 15; i++) {
-            sheet.getRow(i).setHeightInPoints(14.25F);
+        for (int i = 0; i < 15; i++) {
+            sheet.getRow(i).setHeightInPoints(15.0F);
         }
     }
 
@@ -428,7 +474,7 @@ public class TslReportService {
             log.error("时间字符串解析失败--{}", day);
         }
         int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
-        int monthOfYear = calendar.get(Calendar.MONTH);
+        int monthOfYear = calendar.get(Calendar.MONTH) + 1;
         // 显示当前和前一天的对比
         int preDayOfMonth = (dayOfMonth > 1) ? dayOfMonth - 1 : dayOfMonth;
 
@@ -438,13 +484,14 @@ public class TslReportService {
         CellRangeAddress rangeAddress;
         XSSFFont font;
         XSSFDataFormat dataFormat = getWorkbook().createDataFormat();
-        // 基本模式 等线 10号字 带全边框 水平居中
+        // 基本模式 微软雅黑 10号字 带全边框 水平居中
         XSSFCellStyle baseStyle = getWorkbook().createCellStyle();
         font = getWorkbook().createFont();
-        font.setFontName("等线");
+        font.setFontName("微软雅黑");
         font.setFontHeightInPoints((short) 10);
         baseStyle.setFont(font);
         baseStyle.setAlignment(HorizontalAlignment.CENTER);
+        baseStyle.setVerticalAlignment(VerticalAlignment.CENTER);
         baseStyle.setBorderBottom(BorderStyle.THIN);
         baseStyle.setBorderTop(BorderStyle.THIN);
         baseStyle.setBorderLeft(BorderStyle.THIN);
@@ -454,11 +501,11 @@ public class TslReportService {
         // 带边框 百分比 2位小数
         XSSFCellStyle cellStyle2 = baseStyle.copy();
         cellStyle2.setDataFormat(dataFormat.getFormat("0.00%"));
-        // 等线 10号字 自动换行 背景色FFE7E6E6
+        // 微软雅黑 10号字 自动换行 背景色FFE7E6E6 FFAEAAAA
         XSSFCellStyle cellStyle3 = baseStyle.copy();
-        cellStyle3.setWrapText(true);
+        // cellStyle3.setWrapText(true);
         XSSFColor color = new XSSFColor();
-        color.setARGBHex("FFE7E6E6");
+        color.setARGBHex("FFAEAAAA");
         cellStyle3.setFillPattern(FillPatternType.SOLID_FOREGROUND);
         cellStyle3.setFillForegroundColor(color);
 
@@ -477,7 +524,7 @@ public class TslReportService {
         cell.setCellValue("");
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(1);
-        cell.setCellValue("重复投诉工单数");
+        cell.setCellValue("工单数");
         cell.setCellStyle(cellStyle3);
         // 合并单元格 B2-C2
         rangeAddress = new CellRangeAddress(1, 1, 1, 2);
@@ -513,7 +560,7 @@ public class TslReportService {
         cell.setCellValue(String.format("%s月截止%s日", monthOfYear, dayOfMonth));
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(5);
-        cell.setCellValue("重复投诉工单数");
+        cell.setCellValue("工单数");
         cell.setCellStyle(cellStyle3);
         cell = row.createCell(6);
         cell.setCellValue("重复投诉率");
@@ -563,15 +610,12 @@ public class TslReportService {
 
         // 设置列宽2048
         for (int i = 0; i <= 6; i++) {
-            sheet.setColumnWidth(i, 2048);
+            sheet.setColumnWidth(i, 2848);
         }
 
-        // 设置行高 14.25 27.5 25.5 14.25 ...
-        sheet.getRow(0).setHeightInPoints(14.25F);
-        sheet.getRow(1).setHeightInPoints(27.5F);
-        sheet.getRow(2).setHeightInPoints(25.5F);
-        for (int i = 3; i < 16; i++) {
-            sheet.getRow(i).setHeightInPoints(14.25F);
+        // 设置行高 15.0 ...
+        for (int i = 0; i < 16; i++) {
+            sheet.getRow(i).setHeightInPoints(15.0F);
         }
     }
 
@@ -592,8 +636,9 @@ public class TslReportService {
 
         XSSFCellStyle cellStyle1 = getWorkbook().createCellStyle();
         cellStyle1.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle1.setVerticalAlignment(VerticalAlignment.CENTER);
         XSSFFont font = getWorkbook().createFont();
-        font.setFontName("等线");
+        font.setFontName("微软雅黑");
         font.setBold(false);
         font.setFontHeightInPoints((short) 9);
         cellStyle1.setFont(font);
@@ -603,6 +648,7 @@ public class TslReportService {
         cellStyle1.setBorderRight(BorderStyle.THIN);
         XSSFCellStyle cellStyle3 = getWorkbook().createCellStyle();
         cellStyle3.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle3.setVerticalAlignment(VerticalAlignment.CENTER);
         cellStyle3.setFont(font);
         cellStyle3.setBorderBottom(BorderStyle.THIN);
         cellStyle3.setBorderTop(BorderStyle.THIN);
@@ -612,8 +658,9 @@ public class TslReportService {
         cellStyle3.setDataFormat(format.getFormat("0.00"));
         XSSFCellStyle cellStyle2 = getWorkbook().createCellStyle();
         cellStyle2.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
         font = getWorkbook().createFont();
-        font.setFontName("等线");
+        font.setFontName("微软雅黑");
         font.setBold(true);
         font.setFontHeightInPoints((short) 9);
         cellStyle2.setFont(font);

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

@@ -115,32 +115,32 @@ public class TslTaskService {
             // 截图1
             String area = "A1:" + CellRect.getColumnName(dayOfMonth + 7) + "15";
             screenShot = PoiUtil.screenShot(workbook.getSheet("管理端-移网质量类"), area, "微软雅黑");
-            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-投诉率.png"));
+            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-1-投诉率.png"));
 
             // 截图2
             if (!day.endsWith("01")) {
                 screenShot = PoiUtil.screenShot(workbook.getSheet("管理端-重复投诉率"), "A1:G16", "微软雅黑");
-                ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-重复投诉率.png"));
+                ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-2-重复投诉率.png"));
             }
 
             // 截图3 4
             Sheet sheet = workbook.getSheet("投诉处理时长、超时工单概况");
             screenShot = PoiUtil.screenShot(sheet, "A1:D15", "微软雅黑");
-            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-超时工单.png"));
+            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-3-超时工单.png"));
             screenShot = PoiUtil.screenShot(sheet, "G1:J14", "微软雅黑");
-            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-处理时长.png"));
+            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-4-处理时长.png"));
 
             // 截图5
             screenShot = PoiUtil.screenShot(workbook.getSheet("客户端-投诉问题解决满意度"), "A1:D15", "微软雅黑");
-            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-满意率.png"));
+            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-5-满意率.png"));
 
             // 截图6
             screenShot = PoiUtil.screenShot(workbook.getSheet("客户端-投诉问题解决率"), "A1:D15", "微软雅黑");
-            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-解决率.png"));
+            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-6-解决率.png"));
 
             // 截图7
             screenShot = PoiUtil.screenShot(workbook.getSheet("客户端-投诉问题响应率"), "A1:D15", "微软雅黑");
-            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-响应率.png"));
+            ImageIO.write(screenShot, "png", new File(screenShotPath + day + "-7-响应率.png"));
         } catch (EncryptedDocumentException | IOException | ParseException e) {
             throw new RuntimeException(e.getMessage());
         }

+ 23 - 3
tsl_data/src/main/java/com/nokia/tsl_data/service/TslWaraHouseService.java

@@ -1,5 +1,6 @@
 package com.nokia.tsl_data.service;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -17,9 +18,12 @@ import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import lombok.extern.slf4j.Slf4j;
+
 /**
  * 原始数据入库
  */
+@Slf4j
 @Service
 public class TslWaraHouseService {
 
@@ -49,7 +53,23 @@ public class TslWaraHouseService {
         this.jdbcTemplate = jdbcTemplate;
     }
 
-    
+    public String check(String day) {
+        String filePath1 = MOBILE_COMP_DIR + MOBILE_COMP_PREFIX + day + ".csv";
+        String filePath2 = HIGH_QUALITY_DIR + HIGH_QUALITY_PREFIX + day + ".csv";
+        File file1 = new File(filePath1);
+        File file2 = new File(filePath2);
+        StringBuffer stringBuffer = new StringBuffer();
+        if (!file1.exists()) {
+            stringBuffer.append("河北_CEM移网质量投诉明细_HE_D_MOBILE_COMP 表账期 ").append(day).append(" 缺失。");
+        }
+        if (!file2.exists()) {
+            stringBuffer.append("河北_CEM高品质2日统计_HE_D_HIGH_QUALITY 表账期 ").append(day).append(" 缺失。");
+        }
+        if (stringBuffer.length() == 0) {
+            stringBuffer.append("账期").append(day).append("数据源正常。");
+        }
+        return stringBuffer.toString();
+    }
 
     /**
      * 河北_CEM移网质量投诉明细 数据入库
@@ -79,6 +99,7 @@ public class TslWaraHouseService {
                 }
             }
             jdbcTemplate.batchUpdate(MOBILE_COMP_SQL, list);
+            log.debug("河北_CEM移网质量投诉明细 {} 入库成功", day);
         }
     }
 
@@ -109,9 +130,8 @@ public class TslWaraHouseService {
                     ps[i] = record.get(i);
                 }
             }
-            // 出发exception
-            // System.out.println(10 / 0);
             jdbcTemplate.batchUpdate(HIGH_QUALITY_SQL, list);
+            log.debug("河北_CEM高品质2日统计 {} 入库成功", day);
         }
     }
 }

+ 8 - 8
tsl_data/src/main/resources/application-dev.properties

@@ -1,14 +1,14 @@
 # 本地pc机数据库
-# spring.datasource.driver-class-name=org.postgresql.Driver
-# spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
-# spring.datasource.username=report_auto
-# spring.datasource.password=fantuan1985
-
-# 10.9上PG数据库
 spring.datasource.driver-class-name=org.postgresql.Driver
-spring.datasource.url=jdbc:postgresql://192.168.10.9:5432/sqmmt
+spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
 spring.datasource.username=report_auto
-spring.datasource.password=Richr00t!
+spring.datasource.password=fantuan1985
+
+# 10.9上PG数据库
+# spring.datasource.driver-class-name=org.postgresql.Driver
+# spring.datasource.url=jdbc:postgresql://192.168.10.9:5432/sqmmt
+# spring.datasource.username=report_auto
+# spring.datasource.password=Richr00t!
 
 # 测试环境路径配置--本地PC
 tslTask.source.MOBILE_COMP_DIR=D:/src/

+ 1 - 1
tsl_data/src/main/resources/application.properties

@@ -28,4 +28,4 @@ tslTask.outputPath=/data/report_auto/output/
 # 定时任务
 tslTask.isStarted=true
 # 定时任务表达式每天应只执行1次,默认每天14点10分执行
-tslTask.cronExpression=0 10 14 * * *
+tslTask.cronExpression=0 45 13 * * *

+ 8 - 7
tsl_data/src/main/resources/mapper/TslDao.xml

@@ -13,15 +13,16 @@
     <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 from
+        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) as complaint_satisfied,
-        sum(complaint_resolution_list) / sum(complaint_resolution_count) as complaint_resolution,
-        sum(complaint_response_list) / sum(complaint_response_count) as complaint_response from t1
-        union select businoareaname, complaint_satisfied_list / complaint_satisfied_count as
-        complaint_satisfied, complaint_resolution_list / complaint_resolution_count as
-        complaint_resolution, complaint_response_list / complaint_response_count as
+        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, complaint_satisfied_list / (complaint_satisfied_count + complaint) as
+        complaint_satisfied, complaint_resolution_list / (complaint_resolution_count + complaint) as
+        complaint_resolution, complaint_response_list / (complaint_response_count + complaint) as
         complaint_response from t1</select>
 
     <select id="selectOldTsDurationForMonth" resultType="Map"> select city_name,avg_duration from

+ 2 - 2
tsl_data/src/test/java/com/nokia/tsl_data/TslDataApplicationTest.java

@@ -15,7 +15,7 @@ public class TslDataApplicationTest {
 
     @Test
     void test() throws IOException {
-        // taskService.reportGenerateTask("20230501");
-        taskService.screenShotTask("20230501");
+        taskService.reportGenerateTask("20230502");
+        taskService.screenShotTask("20230502");
     }
 }