|
@@ -0,0 +1,278 @@
|
|
|
|
+package com.nokia.dingtalk_auto.service;
|
|
|
|
+
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Calendar;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
+
|
|
|
|
+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;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 向钉钉群发送投诉清单各地市投诉率
|
|
|
|
+ */
|
|
|
|
+@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;
|
|
|
|
+
|
|
|
|
+ @Value("${tslTask.localDir:./download}")
|
|
|
|
+ private String localDir;
|
|
|
|
+
|
|
|
|
+ @Value("${tslTask.remoteHost:133.96.94.105}")
|
|
|
|
+ private String remoteHost;
|
|
|
|
+
|
|
|
|
+ @Value("${tslTask.remotePort:22}")
|
|
|
|
+ private int remotePort;
|
|
|
|
+
|
|
|
|
+ @Value("${tslTask.remoteUser:do}")
|
|
|
|
+ private String remoteUser;
|
|
|
|
+
|
|
|
|
+ @Value("${tslTask.remotePassword:Richr00t}")
|
|
|
|
+ private String remotePassword;
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private RestTemplate restTemplate;
|
|
|
|
+ @Resource
|
|
|
|
+ private RedisTemplate<String, Object> redisTemplate;
|
|
|
|
+ @Resource
|
|
|
|
+ private ObjectMapper objectMapper;
|
|
|
|
+
|
|
|
|
+ // 完成指定日期的发送任务
|
|
|
|
+ public void runTask(String day) {
|
|
|
|
+ // 1. 下载文件
|
|
|
|
+ download(day);
|
|
|
|
+ // 2. 发送文件
|
|
|
|
+ sendDingTalkMsg(day);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void sendDingTalkMsg(String day) {
|
|
|
|
+ DingTalkUtil dingTalkUtil = new DingTalkUtil(appKey, appSecret, openConversationId, restTemplate,
|
|
|
|
+ redisTemplate, objectMapper);
|
|
|
|
+ String localPath = localDir + "/" + day;
|
|
|
|
+ File[] files = new File(localPath).listFiles();
|
|
|
|
+ for (File file : files) {
|
|
|
|
+ try {
|
|
|
|
+ String mediaId = dingTalkUtil.upload(file.getAbsolutePath());
|
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
|
+ map.put("photoURL", mediaId);
|
|
|
|
+ dingTalkUtil.sendMsgWithRobot(map);
|
|
|
|
+ } catch (DingTalkApiException e) {
|
|
|
|
+ // TODO Auto-generated catch block
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 截图,组织一段话
|
|
|
|
+ *
|
|
|
|
+ * 2023年4月截至23日移动网投诉情况统计:
|
|
|
|
+ * 管理端-移网质量类:投诉率:石家庄、承德、雄安、张家口、沧州、衡水、唐山未达到目标值,石家庄、雄安、承德排名靠后;重复投诉率:唐山、沧州、廊坊增长较快。
|
|
|
|
+ * 客户端-移网网络体验:投诉问题解决满意率:雄安、张家口、唐山较低,与达标值差距较大;投诉问题解决率:雄安、张家口、唐山较低,与达标值差距较大;
|
|
|
|
+ * 投诉问题响应率:雄安、张家口、石家庄较低,与达标值差距较大。投诉处理时长、超时工单概况:
|
|
|
|
+ * 超时工单:雄安、石家庄、张家口分公司超时工单占比较高,石家庄、唐山、邯郸超时工单数量较多。
|
|
|
|
+ * 平均处理时长:本月相对较长的地市为雄安、石家庄、张家口;与3月比雄安时长增幅较大。
|
|
|
|
+ *
|
|
|
|
+ * @param day
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public String getFilesToSend(String day) throws Exception {
|
|
|
|
+ String localPath = localDir + "/" + day + "/";
|
|
|
|
+ String localFile = localPath + "投诉清单各地市投诉率" + day + ".xlsx";
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
|
+ calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
|
|
|
|
+ int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
|
|
|
|
+ stringBuffer.append(calendar.get(Calendar.YEAR))
|
|
|
|
+ .append("年")
|
|
|
|
+ .append(calendar.get(Calendar.MONTH))
|
|
|
|
+ .append("月截至")
|
|
|
|
+ .append(dayOfMonth)
|
|
|
|
+ .append("日移动网投诉情况统计:管理端-移网质量类:投诉率:");
|
|
|
|
+ File file = new File(localFile);
|
|
|
|
+ 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) {
|
|
|
|
+ List<Object> list2 = new ArrayList<>();
|
|
|
|
+ list.add(list2);
|
|
|
|
+ list2.add(0, value);
|
|
|
|
+ list2.add(1, cells.get(i, dayOfMonth + 7).getStringValue());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 排序
|
|
|
|
+ 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("未达到目标值,")
|
|
|
|
+ .append(stringBuffer2.toString())
|
|
|
|
+ .append("排名靠后;重复投诉率:");
|
|
|
|
+
|
|
|
|
+ // 截图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("增长较快。客户端-移网网络体验:投诉问题解决满意率:");
|
|
|
|
+
|
|
|
|
+ // 截图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("较低,与达标值差距较大;投诉问题解决率:");
|
|
|
|
+
|
|
|
|
+ // 截图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("较低,与达标值差距较大;投诉问题响应率:");
|
|
|
|
+
|
|
|
|
+ // 截图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("较低,与达标值差距较大。投诉处理时长、超时工单概况:超时工单:");
|
|
|
|
+
|
|
|
|
+ // 截图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("分公司超时工单占比较高,");
|
|
|
|
+ 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("超时工单数量较多。平均处理时长:本月相对较长的地市为");
|
|
|
|
+
|
|
|
|
+ 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(";与").append(cells.get(1, 7).getStringValue()).append("比")
|
|
|
|
+ .append(cells.get(2, 6).getStringValue()).append("时长增幅较大。");
|
|
|
|
+
|
|
|
|
+ workbook.dispose();
|
|
|
|
+ return stringBuffer.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 下载xlsx文件
|
|
|
|
+ *
|
|
|
|
+ * @param day
|
|
|
|
+ */
|
|
|
|
+ public void download(String day) {
|
|
|
|
+ SftpUtil sftpUtil = new SftpUtil().setHost(remoteHost)
|
|
|
|
+ .setPort(remotePort)
|
|
|
|
+ .setUser(remoteUser)
|
|
|
|
+ .setPassword(remotePassword);
|
|
|
|
+
|
|
|
|
+ String remotePath = remoteDir + "/" + day;
|
|
|
|
+ String localPath = localDir + "/" + day;
|
|
|
|
+
|
|
|
|
+ File localFile = new File(localPath);
|
|
|
|
+ if (!localFile.exists()) {
|
|
|
|
+ localFile.mkdirs();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ sftpUtil.connect();
|
|
|
|
+ List<String> files = sftpUtil.ls(remotePath);
|
|
|
|
+ for (String fileName : files) {
|
|
|
|
+ if (fileName.endsWith(".xlsx")) {
|
|
|
|
+ sftpUtil.get(remotePath + "/" + fileName, localPath + "/" + fileName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (JSchException | SftpException | IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } finally {
|
|
|
|
+ sftpUtil.disconnect();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|