Pārlūkot izejas kodu

河北客户体验管理系统移网网络体验明细日信息定时任务

weijianghai 1 mēnesi atpakaļ
vecāks
revīzija
30b784406b

BIN
doc/河北客户体验管理系统移网网络体验明细日信息.xlsx


+ 26 - 10
pom.xml

@@ -14,7 +14,7 @@
     <name>pm_import</name>
     <description>pm_import</description>
     <properties>
-        <java.version>8</java.version>
+        <java.version>17</java.version>
         <maven.compiler.source>${java.version}</maven.compiler.source>
         <maven.compiler.target>${java.version}</maven.compiler.target>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -71,15 +71,31 @@
             <artifactId>commons-exec</artifactId>
             <version>1.4.0</version>
         </dependency>
-<!--        <dependency>-->
-<!--            <groupId>org.springframework.boot</groupId>-->
-<!--            <artifactId>spring-boot-starter-jdbc</artifactId>-->
-<!--        </dependency>-->
-<!--        <dependency>-->
-<!--            <groupId>org.postgresql</groupId>-->
-<!--            <artifactId>postgresql</artifactId>-->
-<!--            <scope>runtime</scope>-->
-<!--        </dependency>-->
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.10.1</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>3.5.10.1</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-freemarker -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-freemarker</artifactId>
+            <version>3.2.3</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>

+ 1 - 1
scripts/run.sh

@@ -1,3 +1,3 @@
 #!/bin/bash
 
-nohup java -Dspring.profiles.active=product -jar pm_import.jar >/dev/null 2>&1 &
+nohup /data/jdks/jdk17/bin/java -Dspring.profiles.active=product -jar pm_import.jar >/dev/null 2>&1 &

+ 26 - 0
src/main/java/com/nokia/pm_import/controller/JobController.java

@@ -0,0 +1,26 @@
+package com.nokia.pm_import.controller;
+
+import com.nokia.pm_import.task.HeDCemMobileExperienceListLogTask;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@RequiredArgsConstructor
+@RequestMapping("/job")
+@RestController
+public class JobController {
+    private final HeDCemMobileExperienceListLogTask heDCemMobileExperienceListLogTask;
+
+    /**
+     * 河北客户体验管理系统移网网络体验明细日信息定时任务
+     */
+    @GetMapping("/heDCemMobileExperienceListLogTask")
+    public Object heDCemMobileExperienceListLogTask(@RequestParam("param") String param) {
+        heDCemMobileExperienceListLogTask.runJob(param);
+        return "ok";
+    }
+}

+ 18 - 0
src/main/java/com/nokia/pm_import/mapper/CityCodeMapper.java

@@ -0,0 +1,18 @@
+package com.nokia.pm_import.mapper;
+
+import com.nokia.pm_import.pojos.po.CityCodePo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+
+/**
+ * <p>
+ * 地市码表 Mapper 接口
+ * </p>
+ *
+ */
+@Mapper
+public interface CityCodeMapper extends BaseMapper<CityCodePo> {
+
+}
+

+ 26 - 0
src/main/java/com/nokia/pm_import/mapper/HeDCemMobileExperienceListLogMapper.java

@@ -0,0 +1,26 @@
+package com.nokia.pm_import.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nokia.pm_import.pojos.po.HeDCemMobileExperienceListLogPo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.Set;
+
+
+/**
+ * <p>
+ * 河北客户体验管理系统移网网络体验明细日信息请求日志 Mapper 接口
+ * </p>
+ *
+ */
+@Mapper
+public interface HeDCemMobileExperienceListLogMapper extends BaseMapper<HeDCemMobileExperienceListLogPo> {
+
+    @Select("""
+select distinct day_id from cfm.he_d_cem_mobile_experience_list_log where month_id = #{monthId}
+""")
+    Set<String> getExistsDays(@Param("monthId") String monthId);
+}
+

+ 18 - 0
src/main/java/com/nokia/pm_import/pojos/po/CityCodePo.java

@@ -0,0 +1,18 @@
+package com.nokia.pm_import.pojos.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+/**
+ * <p>
+ * 地市码表
+ * </p>
+ *
+ */
+@Data
+@TableName("cfm.city_code")
+public class CityCodePo {
+
+    private String cityName;
+
+    private String cityCode;
+}

+ 55 - 0
src/main/java/com/nokia/pm_import/pojos/po/HeDCemMobileExperienceListLogPo.java

@@ -0,0 +1,55 @@
+package com.nokia.pm_import.pojos.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.time.LocalDateTime;
+/**
+ * <p>
+ * 河北客户体验管理系统移网网络体验明细日信息请求日志
+ * </p>
+ *
+ */
+@Getter
+@Setter
+@ToString
+@TableName("cfm.he_d_cem_mobile_experience_list_log")
+public class HeDCemMobileExperienceListLogPo {
+
+    /**
+     * 账期月
+     */
+    private String monthId;
+
+    /**
+     * 账期日
+     */
+    private String dayId;
+
+    /**
+     * 接口调用是否成功,0否1是
+     */
+    private String status;
+
+    /**
+     * 接口请求参数
+     */
+    private String request;
+
+    /**
+     * 接口响应
+     */
+    private String response;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 异常信息
+     */
+    private String exception;
+}

+ 258 - 0
src/main/java/com/nokia/pm_import/task/HeDCemMobileExperienceListLogTask.java

@@ -0,0 +1,258 @@
+package com.nokia.pm_import.task;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nokia.common.exception.MyRuntimeException;
+import com.nokia.pm_import.mapper.CityCodeMapper;
+import com.nokia.pm_import.mapper.HeDCemMobileExperienceListLogMapper;
+import com.nokia.pm_import.pojos.po.CityCodePo;
+import com.nokia.pm_import.pojos.po.HeDCemMobileExperienceListLogPo;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
+import org.slf4j.MDC;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * 河北客户体验管理系统移网网络体验明细日信息定时任务
+ */
+@ConfigurationProperties("task.mobile-experience")
+@Data
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class HeDCemMobileExperienceListLogTask {
+    // 源文件目录
+    private String sourceDir;
+    // 文件前缀
+    private String prefix;
+    // API地址
+    private String api;
+
+    private final HeDCemMobileExperienceListLogMapper heDCemMobileExperienceListLogMapper;
+    private final CityCodeMapper cityCodeMapper;
+
+    /**
+     * 定时任务处理方法
+     * 该方法用于处理移动体验列表数据,从CSV文件中读取数据并发送到指定API,同时记录处理日志。
+     */
+    @XxlJob("heDCemMobileExperienceListJobHandler")
+    public void heDCemMobileExperienceListJobHandler() {
+        // 生成一个唯一的跟踪ID
+        String traceId = UUID.randomUUID().toString().replace("-", "");
+        // 日志添加跟踪id
+        MDC.put("traceId", traceId);
+        try {
+            // 异步执行任务
+            CompletableFuture.runAsync(() -> {
+                MDC.put("traceId", traceId);
+                runJob(null);
+                // 等待任务完成
+            }).join();
+        } catch (Exception e) {
+            // 记录错误日志
+            log.error("发生异常了: {}", e.getMessage(), e);
+            XxlJobHelper.log("发生异常了: {}", e.getMessage(), e);
+            // 处理任务失败
+            XxlJobHelper.handleFail(e.getMessage());
+        }
+    }
+
+    public void runJob(String param) {
+        try {
+            // 获取昨天的日期
+            LocalDate localDate = LocalDate.now().minusDays(1);
+            // 检查是否有传入的参数
+            if (StringUtils.hasText(param)) {
+                // 如果参数有文本内容,将其解析为日期格式,并更新localDate变量
+                localDate = LocalDate.parse(param, DateTimeFormatter.ofPattern("yyyyMMdd"));
+            }
+            // 格式化日期为字符串
+            String date = localDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+            // 格式化月份为字符串
+            String month = localDate.format(DateTimeFormatter.ofPattern("yyyyMM"));
+            // 构建文件路径
+            String filePath = sourceDir + prefix + date + ".csv";
+            // 获取文件路径对象
+            Path path = Paths.get(filePath);
+            // 如果文件不存在
+            if (Files.notExists(path)) {
+                // 抛出异常
+                throw new MyRuntimeException(path + " 不存在");
+            }
+            // 如果文件大小为0
+            if (Files.size(path) == 0) {
+                // 抛出异常
+                throw new MyRuntimeException(path.getFileName() + " 空文件");
+            }
+            // 获取已存在的天数
+            Set<String> existsDays = heDCemMobileExperienceListLogMapper.getExistsDays(month);
+            // 记录日志
+            log.info("读取: {}", path);
+            XxlJobHelper.log("读取: {}", path);
+            // 定义CSV文件的表头
+            List<String> headers = Stream.of("month_id", "day_id", "service_id", "contact_id", "create_time",
+                    "mobile_no", "service_type_name1", "pro_name", "code_cust_area", "zyx", "lwly_name", "big_type_name",
+                    "small_type_name", "acct_month", "day_id1", "sheet_no", "compl_city_local").toList();
+            // 获取表头的大小
+            int headerSize = headers.size();
+            // 定义CSV文件的分隔符
+            char delimiter = 1;
+            // 创建CSV解析器
+            try (CSVParser parser = CSVFormat.DEFAULT.builder().setDelimiter(delimiter).build()
+                    .parse(new InputStreamReader(Files.newInputStream(path), StandardCharsets.UTF_8))
+            ) {
+                // 查询城市代码列表
+                List<CityCodePo> cityCodePos = cityCodeMapper.selectList(null);
+                // 将城市代码列表转换为Map
+                Map<String, String> cityMap = cityCodePos.stream()
+                        .collect(Collectors.toMap(CityCodePo::getCityName, CityCodePo::getCityCode));
+                // 遍历CSV记录
+                for (CSVRecord csvRecord : parser) {
+                    // 创建ObjectMapper对象
+                    ObjectMapper objectMapper = new ObjectMapper();
+                    // 定义变量
+                    String dayId = null;
+                    String r = null;
+                    Map<String, Object> m = new HashMap<>();
+                    try {
+                        // 创建行数据的Map
+                        Map<String, String> rowMap = new HashMap<>();
+                        // 遍历表头
+                        for (int i = 0; i < headerSize; i++) {
+                            // 获取表头
+                            String header = headers.get(i);
+                            // 获取值
+                            String value = csvRecord.get(i);
+                            // 将表头和值放入行数据的Map
+                            rowMap.put(header, value);
+                        }
+                        // 获取day_id1的值
+                        dayId = rowMap.get("day_id1");
+                        // 如果day_id1已存在
+                        if (existsDays.contains(dayId)) {
+                            // 跳过当前记录
+                            continue;
+                        }
+                        // 获取城市代码
+                        String cityCode = cityMap.get(rowMap.get("code_cust_area"));
+                        // 创建数据的Map
+                        Map<String, Object> data = new HashMap<>();
+                        // 创建请求体的Map
+                        Map<String, Object> body = new HashMap<>();
+                        // 将数据放入请求体的Map
+                        body.put("data", data);
+                        // 创建请求的Map
+                        Map<String, Object> request = new HashMap<>();
+                        // 将请求体放入请求的Map
+                        request.put("body", body);
+                        // 将请求放入m的Map
+                        m.put("request", request);
+                        // 将acceptNo放入数据的Map
+                        data.put("acceptNo", rowMap.get("mobile_no"));
+                        // 将acceptTime放入数据的Map
+                        data.put("acceptTime", rowMap.get("create_time"));
+                        // 将callingNo放入数据的Map
+                        data.put("callingNo", rowMap.get("mobile_no"));
+                        // 将city放入数据的Map
+                        data.put("city", cityCode);
+                        // 将complaintNumber放入数据的Map
+                        data.put("complaintNumber", rowMap.get("contact_id"));
+                        // 将countyCode放入数据的Map
+                        data.put("countyCode", cityCode);
+                        // 将cplAddress放入数据的Map
+                        data.put("cplAddress", rowMap.get("compl_city_local"));
+                        // 将cplContent放入数据的Map
+                        data.put("cplContent", rowMap.get("service_type_name1"));
+                        // 将custTel放入数据的Map
+                        data.put("custTel", rowMap.get("mobile_no"));
+                        // 将faultTime放入数据的Map
+                        data.put("faultTime", rowMap.get("create_time"));
+                        // 将kfSn放入数据的Map
+                        data.put("kfSn", rowMap.get("contact_id"));
+                        // 将province放入数据的Map
+                        data.put("province", "130000");
+                        // 创建RestTemplate对象
+                        RestTemplate restTemplate = new RestTemplate();
+                        // 发送POST请求
+                        r = restTemplate.postForObject(api, m, String.class);
+                        // 解析响应
+                        JsonNode jsonNode = objectMapper.readTree(r);
+                        // 如果响应结果不为1
+                        if (!"1".equals(jsonNode.get("response").get("head").get("result").asText())) {
+                            // 抛出异常
+                            throw new MyRuntimeException("请求异常");
+                        }
+                        // 创建HeDCemMobileExperienceListLogPo对象
+                        HeDCemMobileExperienceListLogPo po = new HeDCemMobileExperienceListLogPo();
+                        // 设置monthId
+                        po.setMonthId(month);
+                        // 设置dayId
+                        po.setDayId(dayId);
+                        // 设置状态为1
+                        po.setStatus("1");
+                        // 设置请求
+                        po.setRequest(objectMapper.writeValueAsString(m));
+                        // 设置响应
+                        po.setResponse(r);
+                        // 设置创建时间
+                        po.setCreateTime(LocalDateTime.now());
+                        // 插入数据
+                        heDCemMobileExperienceListLogMapper.insert(po);
+                    } catch (Exception e) {
+                        // 记录错误日志
+                        log.error("发生异常了: {} {} {}", e.getMessage(), m, r, e);
+                        XxlJobHelper.log("发生异常了: {} {} {}", e.getMessage(), m, r, e);
+                        // 创建HeDCemMobileExperienceListLogPo对象
+                        HeDCemMobileExperienceListLogPo po = new HeDCemMobileExperienceListLogPo();
+                        // 设置monthId
+                        po.setMonthId(month);
+                        // 设置dayId
+                        po.setDayId(dayId);
+                        // 设置状态为0
+                        po.setStatus("0");
+                        // 设置请求
+                        po.setRequest(objectMapper.writeValueAsString(m));
+                        // 设置响应
+                        po.setResponse(r);
+                        // 设置创建时间
+                        po.setCreateTime(LocalDateTime.now());
+                        // 设置异常信息
+                        po.setException(e.toString());
+                        // 插入数据
+                        heDCemMobileExperienceListLogMapper.insert(po);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            // 抛出运行时异常
+            throw new MyRuntimeException(e);
+        }
+    }
+
+}

+ 7 - 0
src/main/resources/application-product.properties

@@ -44,3 +44,10 @@ task.pm4g.source-dir=/data/out2/pm_4g_hour/
 task.pm4g.download-dir=download/4g/
 task.pm4g.file-prefix=pm_4g_hour_
 task.pm4g.distinct-dir=distinct/4g/
+task.mobile-experience.source-dir=/data/nenglishangdian/HE_D_CEM_MOBILE_EXPERIENCE_LIST/
+task.mobile-experience.prefix=HE_D_CEM_MOBILE_EXPERIENCE_LIST_1193846275255566336_
+task.mobile-experience.api=http://192.168.70.171:8044/service2/optimization/mainAction/casHandler
+spring.datasource.driver-class-name=org.postgresql.Driver
+spring.datasource.username=sqmdb
+spring.datasource.password=sqmdb_1QAZ
+spring.datasource.url=jdbc:postgresql://192.168.70.172:5432/sqmmt

+ 21 - 0
src/test/java/com/nokia/pm_import/MobileExperienceListTests.java

@@ -0,0 +1,21 @@
+package com.nokia.pm_import;
+
+import com.nokia.pm_import.task.HeDCemMobileExperienceListLogTask;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+@Slf4j
+@SpringBootTest
+@ActiveProfiles("product")
+class MobileExperienceListTests {
+    @Autowired
+    HeDCemMobileExperienceListLogTask heDCemMobileExperienceListLogTask;
+
+    @Test
+    void runJobTest() {
+        heDCemMobileExperienceListLogTask.heDCemMobileExperienceListJobHandler();
+    }
+}

+ 41 - 0
src/test/java/com/nokia/pm_import/MybatisPlusGeneratorTest.java

@@ -0,0 +1,41 @@
+package com.nokia.pm_import;
+
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+
+public class MybatisPlusGeneratorTest {
+    public static void main(String[] args) {
+        FastAutoGenerator.create(
+                new DataSourceConfig.Builder("jdbc:postgresql://192.168.70.172:5432/sqmmt",
+                        "sqmdb",
+                        "sqmdb_1QAZ").schema("cfm"))
+                .globalConfig(builder -> {
+                    builder.outputDir("z:/").disableOpenDir();
+                })
+                .packageConfig(builder -> builder
+                        .parent("com.nokia.pm_import")
+                        .entity("pojos.po")
+                        .mapper("mapper")
+                        .service("dao")
+                        .serviceImpl("dao.impl")
+                        .xml("mapper.xml")
+                )
+                .strategyConfig(builder -> {
+                    builder.addInclude("city_code")
+                            .entityBuilder()
+                            .disableSerialVersionUID()
+                            .formatFileName("%sPo")
+                            .enableFileOverride()
+                            .enableLombok()
+                            .controllerBuilder()
+                            .enableFileOverride()
+                            .mapperBuilder()
+                            .enableFileOverride()
+                            .serviceBuilder()
+                            .enableFileOverride();
+                })
+                .templateEngine(new FreemarkerTemplateEngine())
+                .execute();
+    }
+}