weijianghai 1 місяць тому
батько
коміт
a107f461e1

+ 12 - 12
pom.xml

@@ -81,18 +81,18 @@
             <artifactId>poi-ooxml</artifactId>
             <version>5.2.5</version>
         </dependency>
-        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-csv -->
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-csv</artifactId>
-            <version>1.10.0</version>
-        </dependency>
-        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-exec -->
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-exec</artifactId>
-            <version>1.3</version>
-        </dependency>
+<!--        &lt;!&ndash; https://mvnrepository.com/artifact/org.apache.commons/commons-csv &ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>org.apache.commons</groupId>-->
+<!--            <artifactId>commons-csv</artifactId>-->
+<!--            <version>1.10.0</version>-->
+<!--        </dependency>-->
+<!--        &lt;!&ndash; https://mvnrepository.com/artifact/org.apache.commons/commons-exec &ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>org.apache.commons</groupId>-->
+<!--            <artifactId>commons-exec</artifactId>-->
+<!--            <version>1.3</version>-->
+<!--        </dependency>-->
     </dependencies>
 
     <dependencyManagement>

+ 0 - 196
scripts/8000.conf

@@ -1,196 +0,0 @@
-server {
-    listen       8000 ssl;
-    listen  [::]:8000 ssl;
-    server_name localhost;
-
-    ssl_certificate /etc/nginx/ssl/server.crt;
-    ssl_certificate_key /etc/nginx/ssl/server.key;
-    ssl_session_timeout 1h;
-    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
-    ssl_protocols TLSv1.2 TLSv1.3;
-    ssl_prefer_server_ciphers on;
-    server_tokens off;
-    proxy_hide_header X-Powered-By;
-
-        proxy_hide_header Server;
-    #add_header X-Frame-Options SAMEORIGIN;
-    #access_log  /var/log/nginx/host.access.log  main;
-
-    # minio
-    location /house-car/oss {
-        proxy_pass http://172.16.107.4:39000;
-    }
-    
-    # 百度地图
-    location /dugis-baidu/baidumap/jsapi {
-        proxy_pass http://172.16.107.4:39000/house-car/oss/public/dugis-baidu/baidumap/jsapi;
-    }
-
-    # 不动产后端接口
-    location /house-car/house/api {
-        proxy_pass http://172.16.107.4:39100;
-    }
-
-    # 车辆后端接口
-    location /house-car/car/api {
-        proxy_pass http://172.16.107.4:39100;
-    }
-
-    # 不动产资源地图接口
-    location /house-car/house/resource-map/api {
-        proxy_pass http://172.16.107.4:39100;
-    }
-
-    # 不动产资源地图页面
-    location /house-car/house/resource-map {
-        rewrite ^/house-car/house/resource-map/(.*)$ /$1 break;
-        proxy_pass http://172.16.107.4:39201;
-    }
-
-    # 不动产报告页面接口
-    location /house-car/house/report/api {
-        proxy_pass http://172.16.107.4:39100;
-    }
-
-    # 不动产报告页面
-    location /house-car/house/report {
-        rewrite ^/house-car/house/report/(.*)$ /$1 break;
-        proxy_pass http://172.16.107.4:39202;
-    }
-
-    # 车辆报告页面接口
-    location /house-car/car/report/api {
-        proxy_pass http://172.16.107.4:39100;
-    }
-
-    # 车辆报告报告页面
-    location /house-car/car/report {
-        rewrite ^/house-car/car/report/(.*)$ /$1 break;
-        proxy_pass http://172.16.107.4:39203;
-    }
-
-    # 车辆资源地图接口
-    location /house-car/car/resource-map/api {
-        proxy_pass http://172.16.107.4:39100;
-    }
-
-    # 车辆资源地图页面
-    location /house-car/car/resource-map {
-        rewrite ^/house-car/car/resource-map/(.*)$ /$1 break;
-        proxy_pass http://172.16.107.4:39204;
-    }
-
-    # 不动产数据稽查页面接口
-    location /house-car/house/DATA-CHECK/api {
-        proxy_pass http://172.16.107.4:39100;
-    }
-
-    # 不动产数据稽查页面
-    location /house-car/house/DATA-CHECK {
-        rewrite ^/house-car/house/DATA-CHECK/(.*)$ /$1 break;
-        proxy_pass http://172.16.107.4:39205;
-    }
-
-    # 不动产数据稽查页面接口
-    location /house-car/house/data-check/api {
-        proxy_pass http://172.16.107.4:39100;
-    }
-
-    # 不动产数据稽查页面
-    location /house-car/house/data-check {
-        rewrite ^/house-car/house/data-check/(.*)$ /$1 break;
-        proxy_pass http://172.16.107.4:39205;
-    }
-
-    # 不动产gdc接口
-    location /house-car/house/dist/api {
-        proxy_pass http://172.16.107.4:39101;
-        #proxy_pass http://172.16.107.4:39089/house/dist/api;
-    }
-
-    # 不动产gdc页面
-    location /house-car/house/dist {
-        rewrite ^/house-car/house/dist/(.*)$ /$1 break;
-        proxy_pass http://172.16.107.4:39206;
-    }
-
-    # 不动产系统
-    #location /house-car/house/dist/ {
-    #    proxy_pass http://172.16.107.4:39089/house/dist/;
-    #}
-    #location /house-car/house/api/ { 
-  #	proxy_pass http://172.16.107.4:39089/house/api/; 
-   # }
-
-    #车辆系统
-    location /house-car/car/ {
-        proxy_redirect off;
-        proxy_set_header Host $host:$server_port;
-        proxy_set_header X-Real-IP  $remote_addr;
-        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-        proxy_pass https://127.0.0.1:8080/;
-     }
-
-     location /house-car/car/assets/ {
-        #    add_header Access-Control-Allow-Origin '*' always;
-        #    add_header Access-Control-Allow-Headers '*';
-        #    add_header Access-Control-Allow-Methods '*';
-        #    add_header Access-Control-Allow-Credentials 'false';
-        #    if ($request_method = 'OPTIONS') {
-        #        return 204;
-        #    }
-        proxy_redirect off;
-        proxy_set_header Host $host:$server_port;
-        proxy_set_header X-Real-IP  $remote_addr;
-        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-        proxy_pass https://127.0.0.1:8080/assets/;
-     }
-
-     location /assets/ {
-        proxy_redirect off;
-        proxy_set_header Host $host:$server_port;
-        proxy_set_header X-Real-IP  $remote_addr;
-        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-        proxy_pass https://127.0.0.1:8080/assets/;
-     }
-
-     location /assets/ {
-        proxy_redirect off;
-        proxy_set_header Host $host:$server_port;
-        proxy_set_header X-Real-IP  $remote_addr;
-        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-        proxy_pass https://127.0.0.1:8080/assets/;
-     }
-
-    #error_page  404              /404.html;
-
-    # redirect server error pages to the static page /50x.html
-    #
-    error_page   500 502 503 504  /50x.html;
-    location = /50x.html {
-        root   /usr/share/nginx/html;
-    }
-
-    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
-    #
-    #location ~ \.php$ {
-    #    proxy_pass   http://127.0.0.1;
-    #}
-
-    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
-    #
-    #location ~ \.php$ {
-    #    root           html;
-    #    fastcgi_pass   127.0.0.1:9000;
-    #    fastcgi_index  index.php;
-    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
-    #    include        fastcgi_params;
-    #}
-
-    # deny access to .htaccess files, if Apache's document root
-    # concurs with nginx's one
-    #
-    #location ~ /\.ht {
-    #    deny  all;
-    #}
-}

+ 91 - 91
src/main/java/com/nokia/financeapi/common/utils/psql/PsqlUtil.java

@@ -1,91 +1,91 @@
-package com.nokia.financeapi.common.utils.psql;
-
-import com.nokia.financeapi.common.exception.MyRuntimeException;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.exec.CommandLine;
-import org.apache.commons.exec.DefaultExecutor;
-import org.apache.commons.exec.ExecuteWatchdog;
-import org.apache.commons.exec.PumpStreamHandler;
-import org.springframework.util.StringUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * psql命令工具
- */
-@Slf4j
-public class PsqlUtil {
-    /**
-     * 匹配psql copy成功结果
-     */
-    private static final Pattern PATTERN = Pattern.compile("^(COPY) (\\d+)$");
-
-    /**
-     * 导入csv
-     *
-     * @param script         脚本
-     * @param dbHost         数据库主机
-     * @param dbPort         数据库端口
-     * @param dbUsername     数据库用户名
-     * @param dbPassword     数据库密码
-     * @param dbName         数据库名字
-     * @param dbTable        数据库表
-     * @param csv            csv
-     * @param columns        字段
-     * @param timeout        超时ms
-     * @param minInsertCount 最小值插入数
-     */
-    public static void copyCsv(String script, String dbHost, String dbPort, String dbUsername, String dbPassword,
-                               String dbName, String dbTable, String csv, String columns, Long timeout,
-                               Long minInsertCount) {
-        String command = "sh " + script;
-        CommandLine commandLine = CommandLine.parse(command);
-        commandLine.addArgument(dbHost);
-        commandLine.addArgument(dbPort);
-        commandLine.addArgument(dbUsername);
-        commandLine.addArgument(dbPassword);
-        commandLine.addArgument(dbName);
-        commandLine.addArgument(dbTable);
-        commandLine.addArgument(csv);
-        commandLine.addArgument(columns);
-        log.info("command: {}", commandLine);
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        ByteArrayOutputStream err = new ByteArrayOutputStream();
-        DefaultExecutor executor = new DefaultExecutor();
-        ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
-        executor.setWatchdog(watchdog);
-        PumpStreamHandler streamHandler = new PumpStreamHandler(out, err);
-        executor.setStreamHandler(streamHandler);
-        try {
-            int exitValue = executor.execute(commandLine);
-            log.info("exitValue: {}", exitValue);
-            String outString = out.toString();
-            Long count = null;
-            Matcher matcher = PATTERN.matcher(outString);
-            if (matcher.find()) {
-                count = Long.parseLong(matcher.group(2));
-            }
-            if (count == null) {
-                throw new MyRuntimeException("导入数据失败");
-            }
-            log.info("插入 {} 条数据", count);
-            if (minInsertCount != null && count < minInsertCount) {
-                throw new MyRuntimeException(csv + " 数据异常,少于 " + minInsertCount);
-            }
-        } catch (Exception e) {
-            if (watchdog.killedProcess()) {
-                throw new MyRuntimeException("执行超时", e);
-            }
-            throw new MyRuntimeException(e);
-        } finally {
-            String outString = out.toString();
-            String errString = err.toString();
-            log.info("out: {}", outString);
-            if (StringUtils.hasText(errString)) {
-                log.error("err: {}", errString);
-            }
-        }
-    }
-}
+//package com.nokia.financeapi.common.utils.psql;
+//
+//import com.nokia.financeapi.common.exception.MyRuntimeException;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.exec.CommandLine;
+//import org.apache.commons.exec.DefaultExecutor;
+//import org.apache.commons.exec.ExecuteWatchdog;
+//import org.apache.commons.exec.PumpStreamHandler;
+//import org.springframework.util.StringUtils;
+//
+//import java.io.ByteArrayOutputStream;
+//import java.util.regex.Matcher;
+//import java.util.regex.Pattern;
+//
+///**
+// * psql命令工具
+// */
+//@Slf4j
+//public class PsqlUtil {
+//    /**
+//     * 匹配psql copy成功结果
+//     */
+//    private static final Pattern PATTERN = Pattern.compile("^(COPY) (\\d+)$");
+//
+//    /**
+//     * 导入csv
+//     *
+//     * @param script         脚本
+//     * @param dbHost         数据库主机
+//     * @param dbPort         数据库端口
+//     * @param dbUsername     数据库用户名
+//     * @param dbPassword     数据库密码
+//     * @param dbName         数据库名字
+//     * @param dbTable        数据库表
+//     * @param csv            csv
+//     * @param columns        字段
+//     * @param timeout        超时ms
+//     * @param minInsertCount 最小值插入数
+//     */
+//    public static void copyCsv(String script, String dbHost, String dbPort, String dbUsername, String dbPassword,
+//                               String dbName, String dbTable, String csv, String columns, Long timeout,
+//                               Long minInsertCount) {
+//        String command = "sh " + script;
+//        CommandLine commandLine = CommandLine.parse(command);
+//        commandLine.addArgument(dbHost);
+//        commandLine.addArgument(dbPort);
+//        commandLine.addArgument(dbUsername);
+//        commandLine.addArgument(dbPassword);
+//        commandLine.addArgument(dbName);
+//        commandLine.addArgument(dbTable);
+//        commandLine.addArgument(csv);
+//        commandLine.addArgument(columns);
+//        log.info("command: {}", commandLine);
+//        ByteArrayOutputStream out = new ByteArrayOutputStream();
+//        ByteArrayOutputStream err = new ByteArrayOutputStream();
+//        DefaultExecutor executor = new DefaultExecutor();
+//        ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
+//        executor.setWatchdog(watchdog);
+//        PumpStreamHandler streamHandler = new PumpStreamHandler(out, err);
+//        executor.setStreamHandler(streamHandler);
+//        try {
+//            int exitValue = executor.execute(commandLine);
+//            log.info("exitValue: {}", exitValue);
+//            String outString = out.toString();
+//            Long count = null;
+//            Matcher matcher = PATTERN.matcher(outString);
+//            if (matcher.find()) {
+//                count = Long.parseLong(matcher.group(2));
+//            }
+//            if (count == null) {
+//                throw new MyRuntimeException("导入数据失败");
+//            }
+//            log.info("插入 {} 条数据", count);
+//            if (minInsertCount != null && count < minInsertCount) {
+//                throw new MyRuntimeException(csv + " 数据异常,少于 " + minInsertCount);
+//            }
+//        } catch (Exception e) {
+//            if (watchdog.killedProcess()) {
+//                throw new MyRuntimeException("执行超时", e);
+//            }
+//            throw new MyRuntimeException(e);
+//        } finally {
+//            String outString = out.toString();
+//            String errString = err.toString();
+//            log.info("out: {}", outString);
+//            if (StringUtils.hasText(errString)) {
+//                log.error("err: {}", errString);
+//            }
+//        }
+//    }
+//}

+ 31 - 31
src/main/java/com/nokia/financeapi/controller/car/CarDataImportController.java

@@ -1,31 +1,31 @@
-package com.nokia.financeapi.controller.car;
-
-import com.nokia.financeapi.common.R;
-import com.nokia.financeapi.pojo.dto.CarDataImportDto;
-import com.nokia.financeapi.service.car.CarDataImportService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestPart;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.validation.Valid;
-
-@Tag(name = "车辆数据导入")
-@RestController
-@RequestMapping("/house-car/car/data-import/api")
-public class CarDataImportController {
-    private final CarDataImportService carDataImportService;
-
-    public CarDataImportController(CarDataImportService carDataImportService) {
-        this.carDataImportService = carDataImportService;
-    }
-
-    @Operation(summary = "导入数据")
-    @PostMapping("/dataImport")
-    public R<Object> dataImport(@Valid CarDataImportDto dto, @RequestPart("file") MultipartFile file) {
-        return carDataImportService.dataImport(dto, file);
-    }
-}
+//package com.nokia.financeapi.controller.car;
+//
+//import com.nokia.financeapi.common.R;
+//import com.nokia.financeapi.pojo.dto.CarDataImportDto;
+//import com.nokia.financeapi.service.car.CarDataImportService;
+//import io.swagger.v3.oas.annotations.Operation;
+//import io.swagger.v3.oas.annotations.tags.Tag;
+//import org.springframework.web.bind.annotation.PostMapping;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.RequestPart;
+//import org.springframework.web.bind.annotation.RestController;
+//import org.springframework.web.multipart.MultipartFile;
+//
+//import javax.validation.Valid;
+//
+//@Tag(name = "车辆数据导入")
+//@RestController
+//@RequestMapping("/house-car/car/data-import/api")
+//public class CarDataImportController {
+//    private final CarDataImportService carDataImportService;
+//
+//    public CarDataImportController(CarDataImportService carDataImportService) {
+//        this.carDataImportService = carDataImportService;
+//    }
+//
+//    @Operation(summary = "导入数据")
+//    @PostMapping("/dataImport")
+//    public R<Object> dataImport(@Valid CarDataImportDto dto, @RequestPart("file") MultipartFile file) {
+//        return carDataImportService.dataImport(dto, file);
+//    }
+//}

+ 17 - 17
src/main/java/com/nokia/financeapi/dao/car/CarChaoBaoDao.java

@@ -1,17 +1,17 @@
-package com.nokia.financeapi.dao.car;
-
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-
-@Mapper
-public interface CarChaoBaoDao {
-    /**
-     * 判断是否有数据
-     * @param endYearMonth 账期
-     */
-    @Select("""
-select exists (select 1 from car.car_chao_bao where year_month = #{endYearMonth})
-""")
-    boolean hasData(@Param("endYearMonth") Integer endYearMonth);
-}
+//package com.nokia.financeapi.dao.car;
+//
+//import org.apache.ibatis.annotations.Mapper;
+//import org.apache.ibatis.annotations.Param;
+//import org.apache.ibatis.annotations.Select;
+//
+//@Mapper
+//public interface CarChaoBaoDao {
+//    /**
+//     * 判断是否有数据
+//     * @param endYearMonth 账期
+//     */
+//    @Select("""
+//select exists (select 1 from car.car_chao_bao where year_month = #{endYearMonth})
+//""")
+//    boolean hasData(@Param("endYearMonth") Integer endYearMonth);
+//}

+ 17 - 17
src/main/java/com/nokia/financeapi/dao/car/CarGuoJianDao.java

@@ -1,17 +1,17 @@
-package com.nokia.financeapi.dao.car;
-
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-
-@Mapper
-public interface CarGuoJianDao {
-    /**
-     * 判断是否有数据
-     * @param endYearMonth 账期
-     */
-    @Select("""
-select exists (select 1 from car.car_guo_jian where year_month = #{endYearMonth})
-""")
-    boolean hasData(@Param("endYearMonth") Integer endYearMonth);
-}
+//package com.nokia.financeapi.dao.car;
+//
+//import org.apache.ibatis.annotations.Mapper;
+//import org.apache.ibatis.annotations.Param;
+//import org.apache.ibatis.annotations.Select;
+//
+//@Mapper
+//public interface CarGuoJianDao {
+//    /**
+//     * 判断是否有数据
+//     * @param endYearMonth 账期
+//     */
+//    @Select("""
+//select exists (select 1 from car.car_guo_jian where year_month = #{endYearMonth})
+//""")
+//    boolean hasData(@Param("endYearMonth") Integer endYearMonth);
+//}

+ 100 - 100
src/main/java/com/nokia/financeapi/dao/car/CarWeiZhangDao.java

@@ -1,100 +1,100 @@
-package com.nokia.financeapi.dao.car;
-
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-import org.apache.ibatis.annotations.Update;
-
-@Mapper
-public interface CarWeiZhangDao {
-    /**
-     * 判断是否有车辆违章数据
-     * @param endYearMonth 账期
-     */
-    @Select("""
-select exists (select 1 from car.car_wei_zhang where year_month = #{endYearMonth})
-""")
-    boolean hasData(@Param("endYearMonth") Integer endYearMonth);
-
-    /**
-     * 插入违章长期未处理
-     * @param endYearMonth 账期
-     */
-    @Update("""
-insert
-    into
-    car.car_wei_zhang_chang_qi
-(
-year_month,
-    che_pai_hao,
-    raw_yi_ji,
-    raw_er_ji,
-    raw_san_ji,
-    wei_zhang_shi_jian,
-    wei_zhang_di_dian,
-    wei_zhang_xiang_qing,
-    kou_fen,
-    fa_kuan,
-    wei_zhang_wei_chu_li_shi_chang,
-    chu_li_zhuang_tai,
-    first_unit,
-    second_unit,
-    third_unit,
-    area_no,
-    area_name,
-    city_no,
-    city_name,
-    area_name2,
-    area_no2,
-    city_id,
-    city,
-    district_id,
-    district,
-    raw_che_pai_hao,
-    che_pai_fail,
-    wei_zhang_nian_yue,
-    year_no,
-    month_no,
-    source
-)
-select
-    year_month,
-    che_pai_hao,
-    raw_yi_ji,
-    raw_er_ji,
-    raw_san_ji,
-    wei_zhang_shi_jian,
-    wei_zhang_di_dian,
-    wei_zhang_xiang_qing,
-    kou_fen,
-    fa_kuan,
-    wei_zhang_wei_chu_li_shi_chang,
-    chu_li_zhuang_tai,
-    first_unit,
-    second_unit,
-    third_unit,
-    area_no,
-    area_name,
-    city_no,
-    city_name,
-    area_name2,
-    area_no2,
-    city_id,
-    city,
-    district_id,
-    district,
-    raw_che_pai_hao,
-    che_pai_fail,
-    wei_zhang_nian_yue,
-    year_no,
-    month_no,
-    source
-from
-    car.car_wei_zhang
-where
-    chu_li_zhuang_tai = '未处理'
-    and wei_zhang_wei_chu_li_shi_chang > 150
-    and year_month = #{endYearMonth}
-""")
-    int insertCarWeiZhangChangQi(@Param("endYearMonth") Integer endYearMonth);
-}
+//package com.nokia.financeapi.dao.car;
+//
+//import org.apache.ibatis.annotations.Mapper;
+//import org.apache.ibatis.annotations.Param;
+//import org.apache.ibatis.annotations.Select;
+//import org.apache.ibatis.annotations.Update;
+//
+//@Mapper
+//public interface CarWeiZhangDao {
+//    /**
+//     * 判断是否有车辆违章数据
+//     * @param endYearMonth 账期
+//     */
+//    @Select("""
+//select exists (select 1 from car.car_wei_zhang where year_month = #{endYearMonth})
+//""")
+//    boolean hasData(@Param("endYearMonth") Integer endYearMonth);
+//
+//    /**
+//     * 插入违章长期未处理
+//     * @param endYearMonth 账期
+//     */
+//    @Update("""
+//insert
+//    into
+//    car.car_wei_zhang_chang_qi
+//(
+//year_month,
+//    che_pai_hao,
+//    raw_yi_ji,
+//    raw_er_ji,
+//    raw_san_ji,
+//    wei_zhang_shi_jian,
+//    wei_zhang_di_dian,
+//    wei_zhang_xiang_qing,
+//    kou_fen,
+//    fa_kuan,
+//    wei_zhang_wei_chu_li_shi_chang,
+//    chu_li_zhuang_tai,
+//    first_unit,
+//    second_unit,
+//    third_unit,
+//    area_no,
+//    area_name,
+//    city_no,
+//    city_name,
+//    area_name2,
+//    area_no2,
+//    city_id,
+//    city,
+//    district_id,
+//    district,
+//    raw_che_pai_hao,
+//    che_pai_fail,
+//    wei_zhang_nian_yue,
+//    year_no,
+//    month_no,
+//    source
+//)
+//select
+//    year_month,
+//    che_pai_hao,
+//    raw_yi_ji,
+//    raw_er_ji,
+//    raw_san_ji,
+//    wei_zhang_shi_jian,
+//    wei_zhang_di_dian,
+//    wei_zhang_xiang_qing,
+//    kou_fen,
+//    fa_kuan,
+//    wei_zhang_wei_chu_li_shi_chang,
+//    chu_li_zhuang_tai,
+//    first_unit,
+//    second_unit,
+//    third_unit,
+//    area_no,
+//    area_name,
+//    city_no,
+//    city_name,
+//    area_name2,
+//    area_no2,
+//    city_id,
+//    city,
+//    district_id,
+//    district,
+//    raw_che_pai_hao,
+//    che_pai_fail,
+//    wei_zhang_nian_yue,
+//    year_no,
+//    month_no,
+//    source
+//from
+//    car.car_wei_zhang
+//where
+//    chu_li_zhuang_tai = '未处理'
+//    and wei_zhang_wei_chu_li_shi_chang > 150
+//    and year_month = #{endYearMonth}
+//""")
+//    int insertCarWeiZhangChangQi(@Param("endYearMonth") Integer endYearMonth);
+//}

+ 352 - 352
src/main/java/com/nokia/financeapi/service/car/CarChaoBaoImportService.java

@@ -1,352 +1,352 @@
-package com.nokia.financeapi.service.car;
-
-import com.nokia.financeapi.common.exception.BizException;
-import com.nokia.financeapi.common.exception.MyRuntimeException;
-import com.nokia.financeapi.common.utils.psql.PsqlUtil;
-import com.nokia.financeapi.config.CarDataImportConfig;
-import com.nokia.financeapi.dao.car.CarChaoBaoDao;
-import com.nokia.financeapi.dao.gdc.GdcCarChaoBaoDao;
-import com.nokia.financeapi.pojo.dto.CarDataImportDto;
-import com.nokia.financeapi.pojo.po.common.AreaPo;
-import com.nokia.financeapi.pojo.po.common.OrganizationPo;
-import com.nokia.financeapi.service.common.AreaService;
-import com.nokia.financeapi.service.common.OrganizationService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.csv.CSVFormat;
-import org.apache.commons.csv.CSVPrinter;
-import org.apache.commons.io.FileUtils;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.DateUtil;
-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.xssf.usermodel.XSSFWorkbook;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.StringUtils;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.math.BigDecimal;
-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.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-
-@Slf4j
-@Service
-public class CarChaoBaoImportService {
-    private final CarDataImportConfig carDataImportConfig;
-    private final CarService carService;
-    private final OrganizationService organizationService;
-    private final AreaService areaService;
-    private final CarChaoBaoDao carChaoBaoDao;
-    private final GdcCarChaoBaoDao gdcCarChaoBaoDao;
-
-    public CarChaoBaoImportService(CarDataImportConfig carDataImportConfig, CarService carService,
-                                   OrganizationService organizationService, AreaService areaService,
-                                   CarChaoBaoDao carChaoBaoDao, GdcCarChaoBaoDao gdcCarChaoBaoDao) {
-        this.carDataImportConfig = carDataImportConfig;
-        this.carService = carService;
-        this.organizationService = organizationService;
-        this.areaService = areaService;
-        this.carChaoBaoDao = carChaoBaoDao;
-        this.gdcCarChaoBaoDao = gdcCarChaoBaoDao;
-    }
-
-    @Transactional(timeout = 120, rollbackFor = Exception.class)
-    public synchronized void dataImport(CarDataImportDto dto, MultipartFile file) throws IOException {
-        boolean flag = carChaoBaoDao.hasData(dto.getYearMonth());
-        if (flag) {
-            throw new BizException("该账期数据已存在");
-        }
-        Files.createDirectories(Paths.get(carDataImportConfig.getChaoBao()));
-        File fileNew = new File(carDataImportConfig.getChaoBao() + dto.getYearMonth() + ".xlsx");
-        FileUtils.copyInputStreamToFile(file.getInputStream(), fileNew);
-        Path path = fileNew.toPath();
-        List<Map<String, String>> list = readFile(path);
-        List<Map<String, String>> distinctList = dataProcessing(path, list, dto);
-        Path csvPath = toCsv(path, distinctList);
-        copyCsv(csvPath);
-        procedure(dto);
-    }
-
-    /**
-     * 读取文件
-     *
-     * @param path 文件路径
-     */
-    public List<Map<String, String>> readFile(Path path) throws IOException {
-        log.info("读取: {}", path);
-        List<String> rawHeaders = Stream.of("账期", "车牌号", "车型", "单位", "二级单位", "三级单位", "登记日期",
-                "进厂时间", "公里数", "截止数据提取日行驶里程", "是否应该保养", "超出建议保养时间(天)", "超出建议保养公里数")
-                .toList();
-        List<String> headers = Stream.of("year_month", "che_pai_hao", "che_xing", "raw_yi_ji", "raw_er_ji",
-                "raw_san_ji", "deng_ji_ri_qi", "jin_chang_shi_jian", "jin_chang_gong_li", "li_cheng", "bao_yang",
-                "chao_bao_tian_shu", "chao_bao_gong_li").toList();
-        try (InputStream inputStream = Files.newInputStream(path);
-             Workbook workbook = new XSSFWorkbook(inputStream)
-        ) {
-            List<Map<String, String>> resultList = new ArrayList<>();
-            // 读取第一个工作表
-            Sheet sheet = workbook.getSheetAt(0);
-            // 表头行
-            Row headerRow = sheet.getRow(0);
-            // 列数
-            int columnCount = headerRow.getPhysicalNumberOfCells();
-            log.info("columnCount: {}", columnCount);
-            // 检查表头
-            if (headers.size() != columnCount) {
-                throw new BizException("列数错误");
-            }
-            for (int i = 0; i < columnCount; i++) {
-                Cell cell = headerRow.getCell(i);
-                if (cell == null || !rawHeaders.get(i).equals(cell.getStringCellValue())) {
-                    throw new BizException("表头错误");
-                }
-            }
-            // 最后行数
-            int lastRowNum = sheet.getLastRowNum();
-            log.info("lastRowNum: {}", lastRowNum);
-            if (lastRowNum == 0) {
-                throw new BizException("文件为空");
-            }
-            // 遍历行
-            for (int i = 1; i <= lastRowNum; i++) {
-                Row row = sheet.getRow(i);
-                if (row == null) {
-                    continue;
-                }
-                Map<String, String> rowMap = new LinkedHashMap<>();
-                // 遍历列
-                for (int j = 0; j < columnCount; j++) {
-                    String header = headers.get(j);
-                    String cellValue = "";
-                    rowMap.put(header, cellValue);
-                    Cell cell = row.getCell(j);
-                    if (cell == null) {
-                        continue;
-                    }
-                    switch (cell.getCellType()) {
-                        case STRING:
-                            boolean skipTrim = "deng_ji_ri_qi".equals(header) || "jin_chang_shi_jian".equals(header);
-                            // 删除字符串空白字符
-                            cellValue = skipTrim ? cell.getStringCellValue()
-                                    : StringUtils.trimAllWhitespace(cell.getStringCellValue());
-                            break;
-                        case NUMERIC:
-                            if (DateUtil.isCellDateFormatted(cell)) {
-                                cellValue = DateUtil.getLocalDateTime(cell.getNumericCellValue())
-                                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-                                break;
-                            }
-                            cellValue = String.valueOf(cell.getNumericCellValue());
-                            break;
-                        case BOOLEAN:
-                            cellValue = String.valueOf(cell.getBooleanCellValue());
-                            break;
-                        default:
-                            break;
-                    }
-                    rowMap.put(header, cellValue);
-                }
-                resultList.add(rowMap);
-            }
-            return resultList;
-        }
-    }
-
-    /**
-     * 数据加工
-     *
-     * @param path 文件路径
-     * @param list 数据
-     * @param dto 请求参数
-     */
-    public List<Map<String, String>> dataProcessing(Path path, List<Map<String, String>> list, CarDataImportDto dto) {
-        String yearMonth = dto.getYearMonth().toString();
-        LocalDate localDate = LocalDate.parse(yearMonth + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
-        String year = String.valueOf(localDate.getYear());
-        String month = String.valueOf(localDate.getMonthValue());
-        List<OrganizationPo> secondOrgs = organizationService.getSecondOrgs();
-        List<OrganizationPo> thirdOrgs = organizationService.getThirdOrgs();
-        Map<String, OrganizationPo> orgMap = organizationService.getOrgMap(secondOrgs, thirdOrgs);
-        Map<String, List<OrganizationPo>> thirdOrganizationListMap =
-                organizationService.getThirdOrganizationListMap(secondOrgs, thirdOrgs);
-        List<AreaPo> cities = areaService.getCities();
-        List<AreaPo> districts = areaService.getDistricts();
-        Map<String, AreaPo> areaMap = areaService.getAreaMap(cities, districts);
-        Map<String, List<AreaPo>> districtListMap = areaService.getDistrictListMap(cities, districts);
-        for (Map<String, String> map : list) {
-            map.put("year_month", yearMonth);
-            map.put("year_no", year);
-            map.put("month_no", month);
-            String rawChePaiHao = map.get("che_pai_hao");
-            map.put("raw_che_pai_hao", rawChePaiHao);
-            String chePaiHao = carService.getChePai(rawChePaiHao);
-            map.put("che_pai_hao", chePaiHao);
-            String chePaiFail = carService.chePaiFail(rawChePaiHao);
-            map.put("che_pai_fail", chePaiFail);
-            String yj = map.get("raw_yi_ji");
-            String ej = map.get("raw_er_ji");
-            String sj = map.get("raw_san_ji");
-            String firstUnit = carService.getFirstUnit(yj);
-            map.put("first_unit", firstUnit);
-            String secondUnit = carService.getSecondUnit(ej, firstUnit);
-            map.put("second_unit", secondUnit);
-            String thirdUnit = carService.getThirdUnit(sj, secondUnit);
-            map.put("third_unit", thirdUnit);
-            String areaNo = carService.getAreaNo(secondOrgs, yj);
-            map.put("area_no", areaNo);
-            String areaName = carService.getOrgName(orgMap, areaNo);
-            map.put("area_name", areaName);
-            String cityNo = carService.getCityNo(thirdOrganizationListMap, areaNo, areaName, ej);
-            map.put("city_no", cityNo);
-            String cityName = carService.getOrgName(orgMap, cityNo);
-            map.put("city_name", cityName);
-            String areaNo2 = carService.getAreaNo2(areaName, cityName);
-            map.put("area_no2", areaNo2);
-            String areaName2 = carService.getOrgName(orgMap, areaNo2);
-            map.put("area_name2", areaName2);
-            String cityId = carService.getCityId(cities, yj);
-            map.put("city_id", cityId);
-            String city = carService.getAreaName(areaMap, cityId);
-            map.put("city", city);
-            String districtId = carService.getDistrictId(districtListMap, cityId, cityName, ej);
-            map.put("district_id", districtId);
-            String district = carService.getAreaName(areaMap, districtId);
-            map.put("district", district);
-            map.put("source", path.getFileName().toString());
-            String dengJiRiQi = map.get("deng_ji_ri_qi");
-            if (StringUtils.hasText(dengJiRiQi)) {
-                try {
-                    map.put("deng_ji_ri_qi",
-                            LocalDate.parse(dengJiRiQi).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
-                } catch (Exception e) {
-                    map.put("deng_ji_ri_qi", "");
-                    log.warn("{}登记日期解析失败: {}", rawChePaiHao, dengJiRiQi);
-                }
-            }
-            String jinChangShiJian = map.get("jin_chang_shi_jian");
-            if (StringUtils.hasText(jinChangShiJian)) {
-                try {
-                    map.put("jin_chang_shi_jian",
-                            LocalDate.parse(jinChangShiJian).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
-                } catch (Exception e) {
-                    map.put("jin_chang_shi_jian", "");
-                    log.warn("{}进厂时间解析失败: {}", rawChePaiHao, jinChangShiJian);
-                }
-            }
-            String jinChangGongLi = map.get("jin_chang_gong_li");
-            if (StringUtils.hasText(jinChangGongLi)) {
-                try {
-                    map.put("jin_chang_gong_li", new BigDecimal(jinChangGongLi).toString());
-                } catch (Exception e) {
-                    map.put("jin_chang_gong_li", "");
-                    log.warn("{}进厂公里数解析失败: {}", rawChePaiHao, jinChangGongLi);
-                }
-            }
-            String liCheng = map.get("li_cheng");
-            if (StringUtils.hasText(liCheng)) {
-                try {
-                    map.put("li_cheng", new BigDecimal(liCheng).toString());
-                } catch (Exception e) {
-                    map.put("li_cheng", "");
-                    log.warn("{}截止数据提取日行驶里程解析失败: {}", rawChePaiHao, liCheng);
-                }
-            }
-            String chaoBaoTianShu = map.get("chao_bao_tian_shu");
-            if (StringUtils.hasText(chaoBaoTianShu)) {
-                try {
-                    map.put("chao_bao_tian_shu", String.valueOf(new BigDecimal(chaoBaoTianShu).intValue()));
-                } catch (Exception e) {
-                    map.put("chao_bao_tian_shu", "");
-                    log.warn("{}超出建议保养时间(天)解析失败: {}", rawChePaiHao, chaoBaoTianShu);
-                }
-            }
-            String chaoBaoGongLi = map.get("chao_bao_gong_li");
-            if (StringUtils.hasText(chaoBaoGongLi)) {
-                try {
-                    map.put("chao_bao_gong_li", new BigDecimal(chaoBaoGongLi).toString());
-                } catch (Exception e) {
-                    map.put("chao_bao_gong_li", "");
-                    log.warn("{}超出建议保养公里数解析失败: {}", rawChePaiHao, chaoBaoGongLi);
-                }
-            }
-        }
-        // 去重
-        return list.stream().filter(distinctByKey(map -> map.get("che_pai_hao"))).toList();
-    }
-
-    /**
-     * 去重
-     */
-    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
-        Set<Object> set = ConcurrentHashMap.newKeySet();
-        return t -> set.add(keyExtractor.apply(t));
-    }
-
-    /**
-     * 生成csv
-     *
-     * @param path 源文件路径
-     * @param list 数据
-     */
-    public Path toCsv(Path path, List<Map<String, String>> list) throws IOException {
-        log.info("条数:{}", list.size());
-        Path csvPath = Paths.get(path + ".csv");
-        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
-                StandardCharsets.UTF_8);
-             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
-            // 添加bom头避免excel乱码
-            osw.write('\ufeff');
-            Map<String, String> header = list.get(0);
-            // 表头
-            printer.printRecord(header.keySet());
-            for (Map<String, String> map : list) {
-                printer.printRecord(map.values());
-            }
-        }
-        return csvPath;
-    }
-
-    /**
-     * 导入数据库
-     *
-     * @param path 文件路径
-     */
-    public void copyCsv(Path path) {
-        String dbTable = "car.car_chao_bao";
-        String csv = path.toString();
-        String columns = "(year_month,che_pai_hao,che_xing,raw_yi_ji,raw_er_ji,raw_san_ji,deng_ji_ri_qi,jin_chang_shi_jian,jin_chang_gong_li,li_cheng,bao_yang,chao_bao_tian_shu,chao_bao_gong_li,year_no,month_no,raw_che_pai_hao,che_pai_fail,first_unit,second_unit,third_unit,area_no,area_name,city_no,city_name,area_no2,area_name2,city_id,city,district_id,district,source)";
-        Long timeout = 60000L;
-        PsqlUtil.copyCsv(carDataImportConfig.getCopyScriptPath(), carDataImportConfig.getDbHost(),
-                carDataImportConfig.getDbPort(), carDataImportConfig.getDbUsername(), carDataImportConfig.getDbPassword(),
-                carDataImportConfig.getDbName(), dbTable, csv, columns, timeout, null);
-    }
-
-    /**
-     * 更新数据库
-     */
-    public void procedure(CarDataImportDto dto) {
-        int update1 = gdcCarChaoBaoDao.insertChaoBao(dto.getYearMonth());
-        log.info("insert car_theme.wz_f_severely_over_maintained_leased_vehicles_details: {}", update1);
-        if (update1 == 0) {
-            throw new MyRuntimeException("插入car_theme.wz_f_severely_over_maintained_leased_vehicles_details失败");
-        }
-    }
-}
+//package com.nokia.financeapi.service.car;
+//
+//import com.nokia.financeapi.common.exception.BizException;
+//import com.nokia.financeapi.common.exception.MyRuntimeException;
+//import com.nokia.financeapi.common.utils.psql.PsqlUtil;
+//import com.nokia.financeapi.config.CarDataImportConfig;
+//import com.nokia.financeapi.dao.car.CarChaoBaoDao;
+//import com.nokia.financeapi.dao.gdc.GdcCarChaoBaoDao;
+//import com.nokia.financeapi.pojo.dto.CarDataImportDto;
+//import com.nokia.financeapi.pojo.po.common.AreaPo;
+//import com.nokia.financeapi.pojo.po.common.OrganizationPo;
+//import com.nokia.financeapi.service.common.AreaService;
+//import com.nokia.financeapi.service.common.OrganizationService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.csv.CSVFormat;
+//import org.apache.commons.csv.CSVPrinter;
+//import org.apache.commons.io.FileUtils;
+//import org.apache.poi.ss.usermodel.Cell;
+//import org.apache.poi.ss.usermodel.DateUtil;
+//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.xssf.usermodel.XSSFWorkbook;
+//import org.springframework.stereotype.Service;
+//import org.springframework.transaction.annotation.Transactional;
+//import org.springframework.util.StringUtils;
+//import org.springframework.web.multipart.MultipartFile;
+//
+//import java.io.File;
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.io.OutputStreamWriter;
+//import java.math.BigDecimal;
+//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.format.DateTimeFormatter;
+//import java.util.ArrayList;
+//import java.util.LinkedHashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Set;
+//import java.util.concurrent.ConcurrentHashMap;
+//import java.util.function.Function;
+//import java.util.function.Predicate;
+//import java.util.stream.Stream;
+//
+//@Slf4j
+//@Service
+//public class CarChaoBaoImportService {
+//    private final CarDataImportConfig carDataImportConfig;
+//    private final CarService carService;
+//    private final OrganizationService organizationService;
+//    private final AreaService areaService;
+//    private final CarChaoBaoDao carChaoBaoDao;
+//    private final GdcCarChaoBaoDao gdcCarChaoBaoDao;
+//
+//    public CarChaoBaoImportService(CarDataImportConfig carDataImportConfig, CarService carService,
+//                                   OrganizationService organizationService, AreaService areaService,
+//                                   CarChaoBaoDao carChaoBaoDao, GdcCarChaoBaoDao gdcCarChaoBaoDao) {
+//        this.carDataImportConfig = carDataImportConfig;
+//        this.carService = carService;
+//        this.organizationService = organizationService;
+//        this.areaService = areaService;
+//        this.carChaoBaoDao = carChaoBaoDao;
+//        this.gdcCarChaoBaoDao = gdcCarChaoBaoDao;
+//    }
+//
+//    @Transactional(timeout = 120, rollbackFor = Exception.class)
+//    public synchronized void dataImport(CarDataImportDto dto, MultipartFile file) throws IOException {
+//        boolean flag = carChaoBaoDao.hasData(dto.getYearMonth());
+//        if (flag) {
+//            throw new BizException("该账期数据已存在");
+//        }
+//        Files.createDirectories(Paths.get(carDataImportConfig.getChaoBao()));
+//        File fileNew = new File(carDataImportConfig.getChaoBao() + dto.getYearMonth() + ".xlsx");
+//        FileUtils.copyInputStreamToFile(file.getInputStream(), fileNew);
+//        Path path = fileNew.toPath();
+//        List<Map<String, String>> list = readFile(path);
+//        List<Map<String, String>> distinctList = dataProcessing(path, list, dto);
+//        Path csvPath = toCsv(path, distinctList);
+//        copyCsv(csvPath);
+//        procedure(dto);
+//    }
+//
+//    /**
+//     * 读取文件
+//     *
+//     * @param path 文件路径
+//     */
+//    public List<Map<String, String>> readFile(Path path) throws IOException {
+//        log.info("读取: {}", path);
+//        List<String> rawHeaders = Stream.of("账期", "车牌号", "车型", "单位", "二级单位", "三级单位", "登记日期",
+//                "进厂时间", "公里数", "截止数据提取日行驶里程", "是否应该保养", "超出建议保养时间(天)", "超出建议保养公里数")
+//                .toList();
+//        List<String> headers = Stream.of("year_month", "che_pai_hao", "che_xing", "raw_yi_ji", "raw_er_ji",
+//                "raw_san_ji", "deng_ji_ri_qi", "jin_chang_shi_jian", "jin_chang_gong_li", "li_cheng", "bao_yang",
+//                "chao_bao_tian_shu", "chao_bao_gong_li").toList();
+//        try (InputStream inputStream = Files.newInputStream(path);
+//             Workbook workbook = new XSSFWorkbook(inputStream)
+//        ) {
+//            List<Map<String, String>> resultList = new ArrayList<>();
+//            // 读取第一个工作表
+//            Sheet sheet = workbook.getSheetAt(0);
+//            // 表头行
+//            Row headerRow = sheet.getRow(0);
+//            // 列数
+//            int columnCount = headerRow.getPhysicalNumberOfCells();
+//            log.info("columnCount: {}", columnCount);
+//            // 检查表头
+//            if (headers.size() != columnCount) {
+//                throw new BizException("列数错误");
+//            }
+//            for (int i = 0; i < columnCount; i++) {
+//                Cell cell = headerRow.getCell(i);
+//                if (cell == null || !rawHeaders.get(i).equals(cell.getStringCellValue())) {
+//                    throw new BizException("表头错误");
+//                }
+//            }
+//            // 最后行数
+//            int lastRowNum = sheet.getLastRowNum();
+//            log.info("lastRowNum: {}", lastRowNum);
+//            if (lastRowNum == 0) {
+//                throw new BizException("文件为空");
+//            }
+//            // 遍历行
+//            for (int i = 1; i <= lastRowNum; i++) {
+//                Row row = sheet.getRow(i);
+//                if (row == null) {
+//                    continue;
+//                }
+//                Map<String, String> rowMap = new LinkedHashMap<>();
+//                // 遍历列
+//                for (int j = 0; j < columnCount; j++) {
+//                    String header = headers.get(j);
+//                    String cellValue = "";
+//                    rowMap.put(header, cellValue);
+//                    Cell cell = row.getCell(j);
+//                    if (cell == null) {
+//                        continue;
+//                    }
+//                    switch (cell.getCellType()) {
+//                        case STRING:
+//                            boolean skipTrim = "deng_ji_ri_qi".equals(header) || "jin_chang_shi_jian".equals(header);
+//                            // 删除字符串空白字符
+//                            cellValue = skipTrim ? cell.getStringCellValue()
+//                                    : StringUtils.trimAllWhitespace(cell.getStringCellValue());
+//                            break;
+//                        case NUMERIC:
+//                            if (DateUtil.isCellDateFormatted(cell)) {
+//                                cellValue = DateUtil.getLocalDateTime(cell.getNumericCellValue())
+//                                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+//                                break;
+//                            }
+//                            cellValue = String.valueOf(cell.getNumericCellValue());
+//                            break;
+//                        case BOOLEAN:
+//                            cellValue = String.valueOf(cell.getBooleanCellValue());
+//                            break;
+//                        default:
+//                            break;
+//                    }
+//                    rowMap.put(header, cellValue);
+//                }
+//                resultList.add(rowMap);
+//            }
+//            return resultList;
+//        }
+//    }
+//
+//    /**
+//     * 数据加工
+//     *
+//     * @param path 文件路径
+//     * @param list 数据
+//     * @param dto 请求参数
+//     */
+//    public List<Map<String, String>> dataProcessing(Path path, List<Map<String, String>> list, CarDataImportDto dto) {
+//        String yearMonth = dto.getYearMonth().toString();
+//        LocalDate localDate = LocalDate.parse(yearMonth + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
+//        String year = String.valueOf(localDate.getYear());
+//        String month = String.valueOf(localDate.getMonthValue());
+//        List<OrganizationPo> secondOrgs = organizationService.getSecondOrgs();
+//        List<OrganizationPo> thirdOrgs = organizationService.getThirdOrgs();
+//        Map<String, OrganizationPo> orgMap = organizationService.getOrgMap(secondOrgs, thirdOrgs);
+//        Map<String, List<OrganizationPo>> thirdOrganizationListMap =
+//                organizationService.getThirdOrganizationListMap(secondOrgs, thirdOrgs);
+//        List<AreaPo> cities = areaService.getCities();
+//        List<AreaPo> districts = areaService.getDistricts();
+//        Map<String, AreaPo> areaMap = areaService.getAreaMap(cities, districts);
+//        Map<String, List<AreaPo>> districtListMap = areaService.getDistrictListMap(cities, districts);
+//        for (Map<String, String> map : list) {
+//            map.put("year_month", yearMonth);
+//            map.put("year_no", year);
+//            map.put("month_no", month);
+//            String rawChePaiHao = map.get("che_pai_hao");
+//            map.put("raw_che_pai_hao", rawChePaiHao);
+//            String chePaiHao = carService.getChePai(rawChePaiHao);
+//            map.put("che_pai_hao", chePaiHao);
+//            String chePaiFail = carService.chePaiFail(rawChePaiHao);
+//            map.put("che_pai_fail", chePaiFail);
+//            String yj = map.get("raw_yi_ji");
+//            String ej = map.get("raw_er_ji");
+//            String sj = map.get("raw_san_ji");
+//            String firstUnit = carService.getFirstUnit(yj);
+//            map.put("first_unit", firstUnit);
+//            String secondUnit = carService.getSecondUnit(ej, firstUnit);
+//            map.put("second_unit", secondUnit);
+//            String thirdUnit = carService.getThirdUnit(sj, secondUnit);
+//            map.put("third_unit", thirdUnit);
+//            String areaNo = carService.getAreaNo(secondOrgs, yj);
+//            map.put("area_no", areaNo);
+//            String areaName = carService.getOrgName(orgMap, areaNo);
+//            map.put("area_name", areaName);
+//            String cityNo = carService.getCityNo(thirdOrganizationListMap, areaNo, areaName, ej);
+//            map.put("city_no", cityNo);
+//            String cityName = carService.getOrgName(orgMap, cityNo);
+//            map.put("city_name", cityName);
+//            String areaNo2 = carService.getAreaNo2(areaName, cityName);
+//            map.put("area_no2", areaNo2);
+//            String areaName2 = carService.getOrgName(orgMap, areaNo2);
+//            map.put("area_name2", areaName2);
+//            String cityId = carService.getCityId(cities, yj);
+//            map.put("city_id", cityId);
+//            String city = carService.getAreaName(areaMap, cityId);
+//            map.put("city", city);
+//            String districtId = carService.getDistrictId(districtListMap, cityId, cityName, ej);
+//            map.put("district_id", districtId);
+//            String district = carService.getAreaName(areaMap, districtId);
+//            map.put("district", district);
+//            map.put("source", path.getFileName().toString());
+//            String dengJiRiQi = map.get("deng_ji_ri_qi");
+//            if (StringUtils.hasText(dengJiRiQi)) {
+//                try {
+//                    map.put("deng_ji_ri_qi",
+//                            LocalDate.parse(dengJiRiQi).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+//                } catch (Exception e) {
+//                    map.put("deng_ji_ri_qi", "");
+//                    log.warn("{}登记日期解析失败: {}", rawChePaiHao, dengJiRiQi);
+//                }
+//            }
+//            String jinChangShiJian = map.get("jin_chang_shi_jian");
+//            if (StringUtils.hasText(jinChangShiJian)) {
+//                try {
+//                    map.put("jin_chang_shi_jian",
+//                            LocalDate.parse(jinChangShiJian).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+//                } catch (Exception e) {
+//                    map.put("jin_chang_shi_jian", "");
+//                    log.warn("{}进厂时间解析失败: {}", rawChePaiHao, jinChangShiJian);
+//                }
+//            }
+//            String jinChangGongLi = map.get("jin_chang_gong_li");
+//            if (StringUtils.hasText(jinChangGongLi)) {
+//                try {
+//                    map.put("jin_chang_gong_li", new BigDecimal(jinChangGongLi).toString());
+//                } catch (Exception e) {
+//                    map.put("jin_chang_gong_li", "");
+//                    log.warn("{}进厂公里数解析失败: {}", rawChePaiHao, jinChangGongLi);
+//                }
+//            }
+//            String liCheng = map.get("li_cheng");
+//            if (StringUtils.hasText(liCheng)) {
+//                try {
+//                    map.put("li_cheng", new BigDecimal(liCheng).toString());
+//                } catch (Exception e) {
+//                    map.put("li_cheng", "");
+//                    log.warn("{}截止数据提取日行驶里程解析失败: {}", rawChePaiHao, liCheng);
+//                }
+//            }
+//            String chaoBaoTianShu = map.get("chao_bao_tian_shu");
+//            if (StringUtils.hasText(chaoBaoTianShu)) {
+//                try {
+//                    map.put("chao_bao_tian_shu", String.valueOf(new BigDecimal(chaoBaoTianShu).intValue()));
+//                } catch (Exception e) {
+//                    map.put("chao_bao_tian_shu", "");
+//                    log.warn("{}超出建议保养时间(天)解析失败: {}", rawChePaiHao, chaoBaoTianShu);
+//                }
+//            }
+//            String chaoBaoGongLi = map.get("chao_bao_gong_li");
+//            if (StringUtils.hasText(chaoBaoGongLi)) {
+//                try {
+//                    map.put("chao_bao_gong_li", new BigDecimal(chaoBaoGongLi).toString());
+//                } catch (Exception e) {
+//                    map.put("chao_bao_gong_li", "");
+//                    log.warn("{}超出建议保养公里数解析失败: {}", rawChePaiHao, chaoBaoGongLi);
+//                }
+//            }
+//        }
+//        // 去重
+//        return list.stream().filter(distinctByKey(map -> map.get("che_pai_hao"))).toList();
+//    }
+//
+//    /**
+//     * 去重
+//     */
+//    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
+//        Set<Object> set = ConcurrentHashMap.newKeySet();
+//        return t -> set.add(keyExtractor.apply(t));
+//    }
+//
+//    /**
+//     * 生成csv
+//     *
+//     * @param path 源文件路径
+//     * @param list 数据
+//     */
+//    public Path toCsv(Path path, List<Map<String, String>> list) throws IOException {
+//        log.info("条数:{}", list.size());
+//        Path csvPath = Paths.get(path + ".csv");
+//        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
+//                StandardCharsets.UTF_8);
+//             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
+//            // 添加bom头避免excel乱码
+//            osw.write('\ufeff');
+//            Map<String, String> header = list.get(0);
+//            // 表头
+//            printer.printRecord(header.keySet());
+//            for (Map<String, String> map : list) {
+//                printer.printRecord(map.values());
+//            }
+//        }
+//        return csvPath;
+//    }
+//
+//    /**
+//     * 导入数据库
+//     *
+//     * @param path 文件路径
+//     */
+//    public void copyCsv(Path path) {
+//        String dbTable = "car.car_chao_bao";
+//        String csv = path.toString();
+//        String columns = "(year_month,che_pai_hao,che_xing,raw_yi_ji,raw_er_ji,raw_san_ji,deng_ji_ri_qi,jin_chang_shi_jian,jin_chang_gong_li,li_cheng,bao_yang,chao_bao_tian_shu,chao_bao_gong_li,year_no,month_no,raw_che_pai_hao,che_pai_fail,first_unit,second_unit,third_unit,area_no,area_name,city_no,city_name,area_no2,area_name2,city_id,city,district_id,district,source)";
+//        Long timeout = 60000L;
+//        PsqlUtil.copyCsv(carDataImportConfig.getCopyScriptPath(), carDataImportConfig.getDbHost(),
+//                carDataImportConfig.getDbPort(), carDataImportConfig.getDbUsername(), carDataImportConfig.getDbPassword(),
+//                carDataImportConfig.getDbName(), dbTable, csv, columns, timeout, null);
+//    }
+//
+//    /**
+//     * 更新数据库
+//     */
+//    public void procedure(CarDataImportDto dto) {
+//        int update1 = gdcCarChaoBaoDao.insertChaoBao(dto.getYearMonth());
+//        log.info("insert car_theme.wz_f_severely_over_maintained_leased_vehicles_details: {}", update1);
+//        if (update1 == 0) {
+//            throw new MyRuntimeException("插入car_theme.wz_f_severely_over_maintained_leased_vehicles_details失败");
+//        }
+//    }
+//}

+ 50 - 50
src/main/java/com/nokia/financeapi/service/car/CarDataImportService.java

@@ -1,50 +1,50 @@
-package com.nokia.financeapi.service.car;
-
-import com.nokia.financeapi.common.R;
-import com.nokia.financeapi.common.exception.BizException;
-import com.nokia.financeapi.pojo.dto.CarDataImportDto;
-import com.nokia.financeapi.pojo.enums.CarDataImportEnum;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.util.StringUtils;
-import org.springframework.web.multipart.MultipartFile;
-
-@Slf4j
-@Service
-public class CarDataImportService {
-    private final CarWeiZhangImportService carWeiZhangImportService;
-    private final CarChaoBaoImportService carChaoBaoImportService;
-    private final CarGuoJianImportService carGuoJianImportService;
-
-    public CarDataImportService(CarWeiZhangImportService carWeiZhangImportService,
-                                CarChaoBaoImportService carChaoBaoImportService,
-                                CarGuoJianImportService carGuoJianImportService) {
-        this.carWeiZhangImportService = carWeiZhangImportService;
-        this.carChaoBaoImportService = carChaoBaoImportService;
-        this.carGuoJianImportService = carGuoJianImportService;
-    }
-
-    public R<Object> dataImport(CarDataImportDto dto, MultipartFile file) {
-        try {
-            if (file.isEmpty()) {
-                return R.error("文件为空");
-            }
-            if (!StringUtils.endsWithIgnoreCase(file.getOriginalFilename(), ".xlsx")) {
-                return R.error("文件格式错误");
-            }
-            if (CarDataImportEnum.WEI_ZHANG.equals(dto.getId())) {
-                carWeiZhangImportService.dataImport(dto, file);
-            } else if (CarDataImportEnum.CHAO_BAO.equals(dto.getId())) {
-                carChaoBaoImportService.dataImport(dto, file);
-            } else if (CarDataImportEnum.GUO_JIAN.equals(dto.getId())) {
-                carGuoJianImportService.dataImport(dto, file);
-            }
-            return R.ok();
-        } catch (BizException e) {
-            return R.error(e.getMessage());
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            return R.error("导入失败");
-        }
-    }
-}
+//package com.nokia.financeapi.service.car;
+//
+//import com.nokia.financeapi.common.R;
+//import com.nokia.financeapi.common.exception.BizException;
+//import com.nokia.financeapi.pojo.dto.CarDataImportDto;
+//import com.nokia.financeapi.pojo.enums.CarDataImportEnum;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.stereotype.Service;
+//import org.springframework.util.StringUtils;
+//import org.springframework.web.multipart.MultipartFile;
+//
+//@Slf4j
+//@Service
+//public class CarDataImportService {
+//    private final CarWeiZhangImportService carWeiZhangImportService;
+//    private final CarChaoBaoImportService carChaoBaoImportService;
+//    private final CarGuoJianImportService carGuoJianImportService;
+//
+//    public CarDataImportService(CarWeiZhangImportService carWeiZhangImportService,
+//                                CarChaoBaoImportService carChaoBaoImportService,
+//                                CarGuoJianImportService carGuoJianImportService) {
+//        this.carWeiZhangImportService = carWeiZhangImportService;
+//        this.carChaoBaoImportService = carChaoBaoImportService;
+//        this.carGuoJianImportService = carGuoJianImportService;
+//    }
+//
+//    public R<Object> dataImport(CarDataImportDto dto, MultipartFile file) {
+//        try {
+//            if (file.isEmpty()) {
+//                return R.error("文件为空");
+//            }
+//            if (!StringUtils.endsWithIgnoreCase(file.getOriginalFilename(), ".xlsx")) {
+//                return R.error("文件格式错误");
+//            }
+//            if (CarDataImportEnum.WEI_ZHANG.equals(dto.getId())) {
+//                carWeiZhangImportService.dataImport(dto, file);
+//            } else if (CarDataImportEnum.CHAO_BAO.equals(dto.getId())) {
+//                carChaoBaoImportService.dataImport(dto, file);
+//            } else if (CarDataImportEnum.GUO_JIAN.equals(dto.getId())) {
+//                carGuoJianImportService.dataImport(dto, file);
+//            }
+//            return R.ok();
+//        } catch (BizException e) {
+//            return R.error(e.getMessage());
+//        } catch (Exception e) {
+//            log.error(e.getMessage(), e);
+//            return R.error("导入失败");
+//        }
+//    }
+//}

+ 314 - 314
src/main/java/com/nokia/financeapi/service/car/CarGuoJianImportService.java

@@ -1,314 +1,314 @@
-package com.nokia.financeapi.service.car;
-
-import com.nokia.financeapi.common.exception.BizException;
-import com.nokia.financeapi.common.exception.MyRuntimeException;
-import com.nokia.financeapi.common.utils.psql.PsqlUtil;
-import com.nokia.financeapi.config.CarDataImportConfig;
-import com.nokia.financeapi.dao.car.CarGuoJianDao;
-import com.nokia.financeapi.dao.gdc.GdcCarGuoJianDao;
-import com.nokia.financeapi.pojo.dto.CarDataImportDto;
-import com.nokia.financeapi.pojo.po.common.AreaPo;
-import com.nokia.financeapi.pojo.po.common.OrganizationPo;
-import com.nokia.financeapi.service.common.AreaService;
-import com.nokia.financeapi.service.common.OrganizationService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.csv.CSVFormat;
-import org.apache.commons.csv.CSVPrinter;
-import org.apache.commons.io.FileUtils;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.DateUtil;
-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.xssf.usermodel.XSSFWorkbook;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.StringUtils;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-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.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-
-@Slf4j
-@Service
-public class CarGuoJianImportService {
-    private final CarDataImportConfig carDataImportConfig;
-    private final CarService carService;
-    private final OrganizationService organizationService;
-    private final AreaService areaService;
-    private final CarGuoJianDao carGuoJianDao;
-    private final GdcCarGuoJianDao gdcCarGuoJianDao;
-
-    public CarGuoJianImportService(CarDataImportConfig carDataImportConfig, CarService carService,
-                                   OrganizationService organizationService, AreaService areaService,
-                                   CarGuoJianDao carGuoJianDao, GdcCarGuoJianDao gdcCarGuoJianDao) {
-        this.carDataImportConfig = carDataImportConfig;
-        this.carService = carService;
-        this.organizationService = organizationService;
-        this.areaService = areaService;
-        this.carGuoJianDao = carGuoJianDao;
-        this.gdcCarGuoJianDao = gdcCarGuoJianDao;
-    }
-
-    @Transactional(timeout = 120, rollbackFor = Exception.class)
-    public synchronized void dataImport(CarDataImportDto dto, MultipartFile file) throws IOException {
-        boolean flag = carGuoJianDao.hasData(dto.getYearMonth());
-        if (flag) {
-            throw new BizException("该账期数据已存在");
-        }
-        Files.createDirectories(Paths.get(carDataImportConfig.getGuoJian()));
-        File fileNew = new File(carDataImportConfig.getGuoJian() + dto.getYearMonth() + ".xlsx");
-        FileUtils.copyInputStreamToFile(file.getInputStream(), fileNew);
-        Path path = fileNew.toPath();
-        List<Map<String, String>> list = readFile(path);
-        List<Map<String, String>> distinctList = dataProcessing(path, list, dto);
-        Path csvPath = toCsv(path, distinctList);
-        copyCsv(csvPath);
-        procedure(dto);
-    }
-
-    /**
-     * 读取文件
-     *
-     * @param path 文件路径
-     */
-    public List<Map<String, String>> readFile(Path path) throws IOException {
-        log.info("读取: {}", path);
-        List<String> rawHeaders = Stream.of("账期", "车牌号", "车型", "一级单位", "二级单位", "三级单位", "登记日期",
-                        "年检时间", "是否过检", "是否本月应检", "本月是否年检").toList();
-        List<String> headers = Stream.of("year_month", "che_pai_hao", "che_xing", "raw_yi_ji", "raw_er_ji",
-                "raw_san_ji", "deng_ji_ri_qi", "nian_jian_shi_jian", "shi_fou_guo_jian", "shi_fou_ben_yue_ying_jian",
-                "ben_yue_shi_fou_nian_jian").toList();
-        try (InputStream inputStream = Files.newInputStream(path);
-             Workbook workbook = new XSSFWorkbook(inputStream)
-        ) {
-            List<Map<String, String>> resultList = new ArrayList<>();
-            // 读取第一个工作表
-            Sheet sheet = workbook.getSheetAt(0);
-            // 表头行
-            Row headerRow = sheet.getRow(0);
-            // 列数
-            int columnCount = headerRow.getPhysicalNumberOfCells();
-            log.info("columnCount: {}", columnCount);
-            // 检查表头
-            if (headers.size() != columnCount) {
-                throw new BizException("列数错误");
-            }
-            for (int i = 0; i < columnCount; i++) {
-                Cell cell = headerRow.getCell(i);
-                if (cell == null || !rawHeaders.get(i).equals(cell.getStringCellValue())) {
-                    throw new BizException("表头错误");
-                }
-            }
-            // 最后行数
-            int lastRowNum = sheet.getLastRowNum();
-            log.info("lastRowNum: {}", lastRowNum);
-            if (lastRowNum == 0) {
-                throw new BizException("文件为空");
-            }
-            // 遍历行
-            for (int i = 1; i <= lastRowNum; i++) {
-                Row row = sheet.getRow(i);
-                if (row == null) {
-                    continue;
-                }
-                Map<String, String> rowMap = new LinkedHashMap<>();
-                // 遍历列
-                for (int j = 0; j < columnCount; j++) {
-                    String header = headers.get(j);
-                    String cellValue = "";
-                    rowMap.put(header, cellValue);
-                    Cell cell = row.getCell(j);
-                    if (cell == null) {
-                        continue;
-                    }
-                    switch (cell.getCellType()) {
-                        case STRING:
-                            boolean skipTrim = "deng_ji_ri_qi".equals(header) || "nian_jian_shi_jian".equals(header);
-                            // 删除字符串空白字符
-                            cellValue = skipTrim ? cell.getStringCellValue()
-                                    : StringUtils.trimAllWhitespace(cell.getStringCellValue());
-                            break;
-                        case NUMERIC:
-                            if (DateUtil.isCellDateFormatted(cell)) {
-                                cellValue = DateUtil.getLocalDateTime(cell.getNumericCellValue())
-                                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-                                break;
-                            }
-                            cellValue = String.valueOf(cell.getNumericCellValue());
-                            break;
-                        case BOOLEAN:
-                            cellValue = String.valueOf(cell.getBooleanCellValue());
-                            break;
-                        default:
-                            break;
-                    }
-                    rowMap.put(header, cellValue);
-                }
-                resultList.add(rowMap);
-            }
-            return resultList;
-        }
-    }
-
-    /**
-     * 数据加工
-     *
-     * @param path 文件路径
-     * @param list 数据
-     * @param dto 请求参数
-     */
-    public List<Map<String, String>> dataProcessing(Path path, List<Map<String, String>> list, CarDataImportDto dto) {
-        String yearMonth = dto.getYearMonth().toString();
-        LocalDate localDate = LocalDate.parse(yearMonth + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
-        String year = String.valueOf(localDate.getYear());
-        String month = String.valueOf(localDate.getMonthValue());
-        List<OrganizationPo> secondOrgs = organizationService.getSecondOrgs();
-        List<OrganizationPo> thirdOrgs = organizationService.getThirdOrgs();
-        Map<String, OrganizationPo> orgMap = organizationService.getOrgMap(secondOrgs, thirdOrgs);
-        Map<String, List<OrganizationPo>> thirdOrganizationListMap =
-                organizationService.getThirdOrganizationListMap(secondOrgs, thirdOrgs);
-        List<AreaPo> cities = areaService.getCities();
-        List<AreaPo> districts = areaService.getDistricts();
-        Map<String, AreaPo> areaMap = areaService.getAreaMap(cities, districts);
-        Map<String, List<AreaPo>> districtListMap = areaService.getDistrictListMap(cities, districts);
-        for (Map<String, String> map : list) {
-            map.put("year_month", yearMonth);
-            map.put("year_no", year);
-            map.put("month_no", month);
-            String rawChePaiHao = map.get("che_pai_hao");
-            map.put("raw_che_pai_hao", rawChePaiHao);
-            String chePaiHao = carService.getChePai(rawChePaiHao);
-            map.put("che_pai_hao", chePaiHao);
-            String chePaiFail = carService.chePaiFail(rawChePaiHao);
-            map.put("che_pai_fail", chePaiFail);
-            String yj = map.get("raw_yi_ji");
-            String ej = map.get("raw_er_ji");
-            String sj = map.get("raw_san_ji");
-            String firstUnit = carService.getFirstUnit(yj);
-            map.put("first_unit", firstUnit);
-            String secondUnit = carService.getSecondUnit(ej, firstUnit);
-            map.put("second_unit", secondUnit);
-            String thirdUnit = carService.getThirdUnit(sj, secondUnit);
-            map.put("third_unit", thirdUnit);
-            String areaNo = carService.getAreaNo(secondOrgs, yj);
-            map.put("area_no", areaNo);
-            String areaName = carService.getOrgName(orgMap, areaNo);
-            map.put("area_name", areaName);
-            String cityNo = carService.getCityNo(thirdOrganizationListMap, areaNo, areaName, ej);
-            map.put("city_no", cityNo);
-            String cityName = carService.getOrgName(orgMap, cityNo);
-            map.put("city_name", cityName);
-            String areaNo2 = carService.getAreaNo2(areaName, cityName);
-            map.put("area_no2", areaNo2);
-            String areaName2 = carService.getOrgName(orgMap, areaNo2);
-            map.put("area_name2", areaName2);
-            String cityId = carService.getCityId(cities, yj);
-            map.put("city_id", cityId);
-            String city = carService.getAreaName(areaMap, cityId);
-            map.put("city", city);
-            String districtId = carService.getDistrictId(districtListMap, cityId, cityName, ej);
-            map.put("district_id", districtId);
-            String district = carService.getAreaName(areaMap, districtId);
-            map.put("district", district);
-            map.put("source", path.getFileName().toString());
-            String dengJiRiQi = map.get("deng_ji_ri_qi");
-            if (StringUtils.hasText(dengJiRiQi)) {
-                try {
-                    map.put("deng_ji_ri_qi",
-                            LocalDate.parse(dengJiRiQi).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
-                } catch (Exception e) {
-                    map.put("deng_ji_ri_qi", "");
-                    log.warn("{}登记日期解析失败: {}", rawChePaiHao, dengJiRiQi);
-                }
-            }
-            String nianJianShiJian = map.get("nian_jian_shi_jian");
-            if (StringUtils.hasText(nianJianShiJian)) {
-                try {
-                    map.put("nian_jian_shi_jian",
-                            LocalDate.parse(nianJianShiJian).format(DateTimeFormatter.ofPattern("yyyyMM")));
-                } catch (Exception e) {
-                    map.put("nian_jian_shi_jian", "");
-                    log.warn("{}年检时间解析失败: {}", rawChePaiHao, nianJianShiJian);
-                }
-            }
-        }
-        // 去重
-        return list.stream().filter(distinctByKey(map -> map.get("che_pai_hao"))).toList();
-    }
-
-    /**
-     * 去重
-     */
-    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
-        Set<Object> set = ConcurrentHashMap.newKeySet();
-        return t -> set.add(keyExtractor.apply(t));
-    }
-
-    /**
-     * 生成csv
-     *
-     * @param path 源文件路径
-     * @param list 数据
-     */
-    public Path toCsv(Path path, List<Map<String, String>> list) throws IOException {
-        log.info("条数:{}", list.size());
-        Path csvPath = Paths.get(path + ".csv");
-        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
-                StandardCharsets.UTF_8);
-             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
-            // 添加bom头避免excel乱码
-            osw.write('\ufeff');
-            Map<String, String> header = list.get(0);
-            // 表头
-            printer.printRecord(header.keySet());
-            for (Map<String, String> map : list) {
-                printer.printRecord(map.values());
-            }
-        }
-        return csvPath;
-    }
-
-    /**
-     * 导入数据库
-     *
-     * @param path 文件路径
-     */
-    public void copyCsv(Path path) {
-        String dbTable = "car.car_guo_jian";
-        String csv = path.toString();
-        String columns = "(year_month,che_pai_hao,che_xing,raw_yi_ji,raw_er_ji,raw_san_ji,deng_ji_ri_qi,nian_jian_shi_jian,shi_fou_guo_jian,shi_fou_ben_yue_ying_jian,ben_yue_shi_fou_nian_jian,year_no,month_no,raw_che_pai_hao,che_pai_fail,first_unit,second_unit,third_unit,area_no,area_name,city_no,city_name,area_no2,area_name2,city_id,city,district_id,district,source)";
-        Long timeout = 60000L;
-        PsqlUtil.copyCsv(carDataImportConfig.getCopyScriptPath(), carDataImportConfig.getDbHost(),
-                carDataImportConfig.getDbPort(), carDataImportConfig.getDbUsername(), carDataImportConfig.getDbPassword(),
-                carDataImportConfig.getDbName(), dbTable, csv, columns, timeout, null);
-    }
-
-    /**
-     * 更新数据库
-     */
-    public void procedure(CarDataImportDto dto) {
-        int update1 = gdcCarGuoJianDao.insertChaoBao(dto.getYearMonth());
-        log.info("insert car_theme.wz_f_un_annual_inspectionleased_vehicles_details: {}", update1);
-        if (update1 == 0) {
-            throw new MyRuntimeException("插入car_theme.wz_f_un_annual_inspectionleased_vehicles_details失败");
-        }
-    }
-}
+//package com.nokia.financeapi.service.car;
+//
+//import com.nokia.financeapi.common.exception.BizException;
+//import com.nokia.financeapi.common.exception.MyRuntimeException;
+//import com.nokia.financeapi.common.utils.psql.PsqlUtil;
+//import com.nokia.financeapi.config.CarDataImportConfig;
+//import com.nokia.financeapi.dao.car.CarGuoJianDao;
+//import com.nokia.financeapi.dao.gdc.GdcCarGuoJianDao;
+//import com.nokia.financeapi.pojo.dto.CarDataImportDto;
+//import com.nokia.financeapi.pojo.po.common.AreaPo;
+//import com.nokia.financeapi.pojo.po.common.OrganizationPo;
+//import com.nokia.financeapi.service.common.AreaService;
+//import com.nokia.financeapi.service.common.OrganizationService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.csv.CSVFormat;
+//import org.apache.commons.csv.CSVPrinter;
+//import org.apache.commons.io.FileUtils;
+//import org.apache.poi.ss.usermodel.Cell;
+//import org.apache.poi.ss.usermodel.DateUtil;
+//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.xssf.usermodel.XSSFWorkbook;
+//import org.springframework.stereotype.Service;
+//import org.springframework.transaction.annotation.Transactional;
+//import org.springframework.util.StringUtils;
+//import org.springframework.web.multipart.MultipartFile;
+//
+//import java.io.File;
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.io.OutputStreamWriter;
+//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.format.DateTimeFormatter;
+//import java.util.ArrayList;
+//import java.util.LinkedHashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Set;
+//import java.util.concurrent.ConcurrentHashMap;
+//import java.util.function.Function;
+//import java.util.function.Predicate;
+//import java.util.stream.Stream;
+//
+//@Slf4j
+//@Service
+//public class CarGuoJianImportService {
+//    private final CarDataImportConfig carDataImportConfig;
+//    private final CarService carService;
+//    private final OrganizationService organizationService;
+//    private final AreaService areaService;
+//    private final CarGuoJianDao carGuoJianDao;
+//    private final GdcCarGuoJianDao gdcCarGuoJianDao;
+//
+//    public CarGuoJianImportService(CarDataImportConfig carDataImportConfig, CarService carService,
+//                                   OrganizationService organizationService, AreaService areaService,
+//                                   CarGuoJianDao carGuoJianDao, GdcCarGuoJianDao gdcCarGuoJianDao) {
+//        this.carDataImportConfig = carDataImportConfig;
+//        this.carService = carService;
+//        this.organizationService = organizationService;
+//        this.areaService = areaService;
+//        this.carGuoJianDao = carGuoJianDao;
+//        this.gdcCarGuoJianDao = gdcCarGuoJianDao;
+//    }
+//
+//    @Transactional(timeout = 120, rollbackFor = Exception.class)
+//    public synchronized void dataImport(CarDataImportDto dto, MultipartFile file) throws IOException {
+//        boolean flag = carGuoJianDao.hasData(dto.getYearMonth());
+//        if (flag) {
+//            throw new BizException("该账期数据已存在");
+//        }
+//        Files.createDirectories(Paths.get(carDataImportConfig.getGuoJian()));
+//        File fileNew = new File(carDataImportConfig.getGuoJian() + dto.getYearMonth() + ".xlsx");
+//        FileUtils.copyInputStreamToFile(file.getInputStream(), fileNew);
+//        Path path = fileNew.toPath();
+//        List<Map<String, String>> list = readFile(path);
+//        List<Map<String, String>> distinctList = dataProcessing(path, list, dto);
+//        Path csvPath = toCsv(path, distinctList);
+//        copyCsv(csvPath);
+//        procedure(dto);
+//    }
+//
+//    /**
+//     * 读取文件
+//     *
+//     * @param path 文件路径
+//     */
+//    public List<Map<String, String>> readFile(Path path) throws IOException {
+//        log.info("读取: {}", path);
+//        List<String> rawHeaders = Stream.of("账期", "车牌号", "车型", "一级单位", "二级单位", "三级单位", "登记日期",
+//                        "年检时间", "是否过检", "是否本月应检", "本月是否年检").toList();
+//        List<String> headers = Stream.of("year_month", "che_pai_hao", "che_xing", "raw_yi_ji", "raw_er_ji",
+//                "raw_san_ji", "deng_ji_ri_qi", "nian_jian_shi_jian", "shi_fou_guo_jian", "shi_fou_ben_yue_ying_jian",
+//                "ben_yue_shi_fou_nian_jian").toList();
+//        try (InputStream inputStream = Files.newInputStream(path);
+//             Workbook workbook = new XSSFWorkbook(inputStream)
+//        ) {
+//            List<Map<String, String>> resultList = new ArrayList<>();
+//            // 读取第一个工作表
+//            Sheet sheet = workbook.getSheetAt(0);
+//            // 表头行
+//            Row headerRow = sheet.getRow(0);
+//            // 列数
+//            int columnCount = headerRow.getPhysicalNumberOfCells();
+//            log.info("columnCount: {}", columnCount);
+//            // 检查表头
+//            if (headers.size() != columnCount) {
+//                throw new BizException("列数错误");
+//            }
+//            for (int i = 0; i < columnCount; i++) {
+//                Cell cell = headerRow.getCell(i);
+//                if (cell == null || !rawHeaders.get(i).equals(cell.getStringCellValue())) {
+//                    throw new BizException("表头错误");
+//                }
+//            }
+//            // 最后行数
+//            int lastRowNum = sheet.getLastRowNum();
+//            log.info("lastRowNum: {}", lastRowNum);
+//            if (lastRowNum == 0) {
+//                throw new BizException("文件为空");
+//            }
+//            // 遍历行
+//            for (int i = 1; i <= lastRowNum; i++) {
+//                Row row = sheet.getRow(i);
+//                if (row == null) {
+//                    continue;
+//                }
+//                Map<String, String> rowMap = new LinkedHashMap<>();
+//                // 遍历列
+//                for (int j = 0; j < columnCount; j++) {
+//                    String header = headers.get(j);
+//                    String cellValue = "";
+//                    rowMap.put(header, cellValue);
+//                    Cell cell = row.getCell(j);
+//                    if (cell == null) {
+//                        continue;
+//                    }
+//                    switch (cell.getCellType()) {
+//                        case STRING:
+//                            boolean skipTrim = "deng_ji_ri_qi".equals(header) || "nian_jian_shi_jian".equals(header);
+//                            // 删除字符串空白字符
+//                            cellValue = skipTrim ? cell.getStringCellValue()
+//                                    : StringUtils.trimAllWhitespace(cell.getStringCellValue());
+//                            break;
+//                        case NUMERIC:
+//                            if (DateUtil.isCellDateFormatted(cell)) {
+//                                cellValue = DateUtil.getLocalDateTime(cell.getNumericCellValue())
+//                                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+//                                break;
+//                            }
+//                            cellValue = String.valueOf(cell.getNumericCellValue());
+//                            break;
+//                        case BOOLEAN:
+//                            cellValue = String.valueOf(cell.getBooleanCellValue());
+//                            break;
+//                        default:
+//                            break;
+//                    }
+//                    rowMap.put(header, cellValue);
+//                }
+//                resultList.add(rowMap);
+//            }
+//            return resultList;
+//        }
+//    }
+//
+//    /**
+//     * 数据加工
+//     *
+//     * @param path 文件路径
+//     * @param list 数据
+//     * @param dto 请求参数
+//     */
+//    public List<Map<String, String>> dataProcessing(Path path, List<Map<String, String>> list, CarDataImportDto dto) {
+//        String yearMonth = dto.getYearMonth().toString();
+//        LocalDate localDate = LocalDate.parse(yearMonth + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
+//        String year = String.valueOf(localDate.getYear());
+//        String month = String.valueOf(localDate.getMonthValue());
+//        List<OrganizationPo> secondOrgs = organizationService.getSecondOrgs();
+//        List<OrganizationPo> thirdOrgs = organizationService.getThirdOrgs();
+//        Map<String, OrganizationPo> orgMap = organizationService.getOrgMap(secondOrgs, thirdOrgs);
+//        Map<String, List<OrganizationPo>> thirdOrganizationListMap =
+//                organizationService.getThirdOrganizationListMap(secondOrgs, thirdOrgs);
+//        List<AreaPo> cities = areaService.getCities();
+//        List<AreaPo> districts = areaService.getDistricts();
+//        Map<String, AreaPo> areaMap = areaService.getAreaMap(cities, districts);
+//        Map<String, List<AreaPo>> districtListMap = areaService.getDistrictListMap(cities, districts);
+//        for (Map<String, String> map : list) {
+//            map.put("year_month", yearMonth);
+//            map.put("year_no", year);
+//            map.put("month_no", month);
+//            String rawChePaiHao = map.get("che_pai_hao");
+//            map.put("raw_che_pai_hao", rawChePaiHao);
+//            String chePaiHao = carService.getChePai(rawChePaiHao);
+//            map.put("che_pai_hao", chePaiHao);
+//            String chePaiFail = carService.chePaiFail(rawChePaiHao);
+//            map.put("che_pai_fail", chePaiFail);
+//            String yj = map.get("raw_yi_ji");
+//            String ej = map.get("raw_er_ji");
+//            String sj = map.get("raw_san_ji");
+//            String firstUnit = carService.getFirstUnit(yj);
+//            map.put("first_unit", firstUnit);
+//            String secondUnit = carService.getSecondUnit(ej, firstUnit);
+//            map.put("second_unit", secondUnit);
+//            String thirdUnit = carService.getThirdUnit(sj, secondUnit);
+//            map.put("third_unit", thirdUnit);
+//            String areaNo = carService.getAreaNo(secondOrgs, yj);
+//            map.put("area_no", areaNo);
+//            String areaName = carService.getOrgName(orgMap, areaNo);
+//            map.put("area_name", areaName);
+//            String cityNo = carService.getCityNo(thirdOrganizationListMap, areaNo, areaName, ej);
+//            map.put("city_no", cityNo);
+//            String cityName = carService.getOrgName(orgMap, cityNo);
+//            map.put("city_name", cityName);
+//            String areaNo2 = carService.getAreaNo2(areaName, cityName);
+//            map.put("area_no2", areaNo2);
+//            String areaName2 = carService.getOrgName(orgMap, areaNo2);
+//            map.put("area_name2", areaName2);
+//            String cityId = carService.getCityId(cities, yj);
+//            map.put("city_id", cityId);
+//            String city = carService.getAreaName(areaMap, cityId);
+//            map.put("city", city);
+//            String districtId = carService.getDistrictId(districtListMap, cityId, cityName, ej);
+//            map.put("district_id", districtId);
+//            String district = carService.getAreaName(areaMap, districtId);
+//            map.put("district", district);
+//            map.put("source", path.getFileName().toString());
+//            String dengJiRiQi = map.get("deng_ji_ri_qi");
+//            if (StringUtils.hasText(dengJiRiQi)) {
+//                try {
+//                    map.put("deng_ji_ri_qi",
+//                            LocalDate.parse(dengJiRiQi).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+//                } catch (Exception e) {
+//                    map.put("deng_ji_ri_qi", "");
+//                    log.warn("{}登记日期解析失败: {}", rawChePaiHao, dengJiRiQi);
+//                }
+//            }
+//            String nianJianShiJian = map.get("nian_jian_shi_jian");
+//            if (StringUtils.hasText(nianJianShiJian)) {
+//                try {
+//                    map.put("nian_jian_shi_jian",
+//                            LocalDate.parse(nianJianShiJian).format(DateTimeFormatter.ofPattern("yyyyMM")));
+//                } catch (Exception e) {
+//                    map.put("nian_jian_shi_jian", "");
+//                    log.warn("{}年检时间解析失败: {}", rawChePaiHao, nianJianShiJian);
+//                }
+//            }
+//        }
+//        // 去重
+//        return list.stream().filter(distinctByKey(map -> map.get("che_pai_hao"))).toList();
+//    }
+//
+//    /**
+//     * 去重
+//     */
+//    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
+//        Set<Object> set = ConcurrentHashMap.newKeySet();
+//        return t -> set.add(keyExtractor.apply(t));
+//    }
+//
+//    /**
+//     * 生成csv
+//     *
+//     * @param path 源文件路径
+//     * @param list 数据
+//     */
+//    public Path toCsv(Path path, List<Map<String, String>> list) throws IOException {
+//        log.info("条数:{}", list.size());
+//        Path csvPath = Paths.get(path + ".csv");
+//        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
+//                StandardCharsets.UTF_8);
+//             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
+//            // 添加bom头避免excel乱码
+//            osw.write('\ufeff');
+//            Map<String, String> header = list.get(0);
+//            // 表头
+//            printer.printRecord(header.keySet());
+//            for (Map<String, String> map : list) {
+//                printer.printRecord(map.values());
+//            }
+//        }
+//        return csvPath;
+//    }
+//
+//    /**
+//     * 导入数据库
+//     *
+//     * @param path 文件路径
+//     */
+//    public void copyCsv(Path path) {
+//        String dbTable = "car.car_guo_jian";
+//        String csv = path.toString();
+//        String columns = "(year_month,che_pai_hao,che_xing,raw_yi_ji,raw_er_ji,raw_san_ji,deng_ji_ri_qi,nian_jian_shi_jian,shi_fou_guo_jian,shi_fou_ben_yue_ying_jian,ben_yue_shi_fou_nian_jian,year_no,month_no,raw_che_pai_hao,che_pai_fail,first_unit,second_unit,third_unit,area_no,area_name,city_no,city_name,area_no2,area_name2,city_id,city,district_id,district,source)";
+//        Long timeout = 60000L;
+//        PsqlUtil.copyCsv(carDataImportConfig.getCopyScriptPath(), carDataImportConfig.getDbHost(),
+//                carDataImportConfig.getDbPort(), carDataImportConfig.getDbUsername(), carDataImportConfig.getDbPassword(),
+//                carDataImportConfig.getDbName(), dbTable, csv, columns, timeout, null);
+//    }
+//
+//    /**
+//     * 更新数据库
+//     */
+//    public void procedure(CarDataImportDto dto) {
+//        int update1 = gdcCarGuoJianDao.insertChaoBao(dto.getYearMonth());
+//        log.info("insert car_theme.wz_f_un_annual_inspectionleased_vehicles_details: {}", update1);
+//        if (update1 == 0) {
+//            throw new MyRuntimeException("插入car_theme.wz_f_un_annual_inspectionleased_vehicles_details失败");
+//        }
+//    }
+//}

+ 547 - 547
src/main/java/com/nokia/financeapi/service/car/CarService.java

@@ -1,547 +1,547 @@
-package com.nokia.financeapi.service.car;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.nokia.financeapi.common.exception.MyRuntimeException;
-import com.nokia.financeapi.pojo.po.common.AreaPo;
-import com.nokia.financeapi.pojo.po.common.OrganizationPo;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-@Slf4j
-@Service
-public class CarService {
-    /**
-     * 匹配车牌省份
-     */
-    static final Pattern HAS_CHE_PAI_PROVINCE_PATTERN = Pattern.compile("[" + Pattern.quote("京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁国防") + "]");
-    /**
-     * 匹配非车牌字符
-     */
-    static final Pattern NOT_CHE_PAI_PATTERN = Pattern.compile("[^京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新港澳学挂领试超练警国防A-Z\\d]");
-    /**
-     * 车牌正则
-     */
-    static final Pattern CHE_PAI_PATTERN = Pattern.compile(
-            "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z][A-Z](([DF]((?![IO])[A-Z0-9](?![IO]))\\d{4})|(\\d{5}[DF]))|[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z][A-Z][A-Z0-9]{4}[A-Z0-9挂学警港澳])"
-    );
-
-    /**
-     * 一级单位的二级单位字典
-     */
-    static final Map<String, List<String>> ER_JI_MAP;
-
-    static {
-        try {
-            ER_JI_MAP = new ObjectMapper().readValue(
-                    """
-{
-    "石家庄": ["鹿泉", "藁城", "栾城", "井陉矿区", "井陉", "无极", "正定", "元氏", "新乐", "晋州", "平山", "灵寿", "赞皇", "赵县", "行唐", "高邑", "辛集", "深泽"],
-    "唐山": ["唐山高开区", "迁西", "海港", "开平", "丰南", "滦县", "乐亭", "丰润", "玉田", "古冶", "曹妃甸", "遵化", "滦南", "迁安"],
-    "秦皇岛": ["北戴河新区", "北戴河", "山海关", "昌黎", "卢龙", "青龙", "抚宁"],
-    "邯郸": ["曲周", "魏县", "馆陶", "磁县", "大名", "鸡泽", "成安", "涉县", "永年", "武安", "峰峰", "广平", "临漳", "邱县", "肥乡"],
-    "邢台": ["新河", "南宫", "隆尧", "内邱", "平乡", "宁晋", "广宗", "清河", "临西", "任县", "巨鹿", "沙河", "威县", "临城", "柏乡", "南和"],
-    "保定": ["涞水", "蠡县", "顺平", "博野", "安国", "涞源", "唐县", "定州", "高阳", "曲阳", "阜平", "清苑", "高碑店", "满城", "涿州", "易县", "望都", "徐水", "定兴", "白沟"],
-    "张家口": ["张北", "崇礼", "康保", "赤城", "阳原", "万全", "下花园", "尚义", "怀安", "怀来", "蔚县", "涿鹿", "沽源", "宣化"],
-    "承德": ["承德县", "兴隆", "宽城", "平泉", "营子", "隆化", "滦平", "围场", "丰宁", "双滦"],
-    "廊坊": ["文安", "霸州", "大城", "廊坊开发区", "三河", "香河", "永清", "胜芳", "燕郊", "固安", "大厂"],
-    "沧州": ["东光", "吴桥", "黄骅", "盐山", "孟村", "泊头", "献县", "南皮", "渤海新区", "海兴", "沧县", "河间", "青县", "任丘", "肃宁"],
-    "衡水": ["景县", "阜城", "枣强", "深州", "饶阳", "故城", "武强", "武邑", "冀州", "安平"],
-    "雄安": ["容城", "雄县", "安新"]
-}
-                            """,
-                    TypeFactory.defaultInstance().constructMapType(Map.class, String.class, List.class)
-            );
-        } catch (JsonProcessingException e) {
-            throw new MyRuntimeException(e);
-        }
-    }
-
-    /**
-     * 匹配车牌
-     * @param chePai 车牌
-     */
-    public String getChePai(String chePai) {
-        if (!StringUtils.hasText(chePai)) {
-            return "";
-        }
-        // 字母转大写
-        String upperCase = chePai.toUpperCase();
-        // 删除非车牌字符
-        String s = NOT_CHE_PAI_PATTERN.matcher(upperCase).replaceAll("");
-        Matcher m = CHE_PAI_PATTERN.matcher(s);
-        if (m.find()) {
-            return m.group(0);
-        }
-        if (HAS_CHE_PAI_PROVINCE_PATTERN.matcher(chePai).find()) {
-            log.warn("车牌匹配失败: {} -> {}", chePai, s);
-            return s;
-        }
-        log.warn("车牌匹配失败: {} -> {}", chePai, upperCase);
-        return upperCase;
-    }
-
-    /**
-     * 车牌是否匹配失败
-     * @param chePai 车牌
-     */
-    public String chePaiFail(String chePai) {
-        if (!StringUtils.hasText(chePai)) {
-            return "1";
-        }
-        // 字母转大写删除非车牌字符
-        String s = NOT_CHE_PAI_PATTERN.matcher(chePai.toUpperCase()).replaceAll("");
-        Matcher m = CHE_PAI_PATTERN.matcher(s);
-        if (m.find()) {
-            return "0";
-        }
-        return "1";
-    }
-
-    /**
-     * 车牌是否包含报废
-     * @param chePai 车牌
-     */
-    public String baoFei(String chePai) {
-        if (chePai.contains("报废")) {
-            return "1";
-        }
-        return "0";
-    }
-
-    /**
-     * 获取一级单位
-     * @param unit 单位
-     */
-    public String getFirstUnit(String unit) {
-        if (!StringUtils.hasText(unit)) {
-            return "";
-        }
-        if (unit.contains("机动通信局") || unit.contains("机动局") || unit.contains("传输局") || unit.contains("线路维护中心")) {
-            return "机动局";
-        }
-        if (unit.contains("雄安基地建设部")) {
-            return "雄安基地建设部";
-        }
-        if (unit.contains("华北基地建设部")) {
-            return "华北基地建设部";
-        }
-        for (String yj : ER_JI_MAP.keySet()) {
-            if (unit.contains(yj)) {
-                return yj;
-            }
-        }
-        return "省公司本部";
-    }
-
-    /**
-     * 获取而二级单位
-     * @param unit 单位
-     * @param firstUnit 一级单位
-     */
-    public String getSecondUnit(String unit, String firstUnit) {
-        if (!StringUtils.hasText(unit)) {
-            return firstUnit;
-        }
-        if ("省公司本部".equals(firstUnit)) {
-            return firstUnit;
-        }
-        if ("机动局".equals(firstUnit)) {
-            for (String yj : ER_JI_MAP.keySet()) {
-                if (unit.contains(yj)) {
-                    return "机动局" + yj;
-                }
-            }
-            return "机动局本部";
-        }
-        if ("石家庄".equals(firstUnit)) {
-            if (unit.contains("开发区")) {
-                return "石家庄开发区";
-            }
-        }
-        if ("廊坊".equals(firstUnit)) {
-            if (unit.contains("开发区")) {
-                return "廊坊开发区";
-            }
-        }
-        if ("邢台".equals(firstUnit)) {
-            if (unit.contains("内丘")) {
-                return "内邱";
-            }
-            if (unit.contains("任泽")) {
-                return "任县";
-            }
-        }
-        if ("唐山".equals(firstUnit)) {
-            if (unit.contains("高开区")) {
-                return "唐山高开区";
-            }
-            if (unit.contains("滦州")) {
-                return "滦县";
-            }
-        }
-        List<String> ejs = ER_JI_MAP.get(firstUnit);
-        if (CollectionUtils.isEmpty(ejs)) {
-            return firstUnit;
-        }
-        if ("雄安".equals(firstUnit)) {
-            unit = unit.replace("雄安新区", "");
-        }
-        for (String ej : ejs) {
-            if (unit.contains(ej)) {
-                return ej;
-            }
-        }
-        return firstUnit + "本部";
-    }
-
-    /**
-     * 获取三级单位
-     * @param unit 单位
-     * @param secondUnit 二级单位
-     */
-    public String getThirdUnit(String unit, String secondUnit) {
-        if (!StringUtils.hasText(unit)) {
-            return secondUnit;
-        }
-        String[] a = unit.split("_");
-        if (a.length == 1) {
-            return unit;
-        }
-        if (a.length < 4) {
-            return secondUnit;
-        }
-        return a[3];
-    }
-
-    /**
-     * 获取二级组织机构编码
-     * @param secondOrgs 二级组织机构列表
-     * @param unit 单位
-     */
-    public String getAreaNo(List<OrganizationPo> secondOrgs, String unit) {
-        if (!StringUtils.hasText(unit)) {
-            return "";
-        }
-        if (unit.contains("机动通信局") || unit.contains("机动局") || unit.contains("传输局") || unit.contains("线路维护中心")) {
-            return "-11";
-        }
-        if (unit.contains("省公司本部") || unit.contains("雄安基地建设部") || unit.contains("华北基地建设部")) {
-            return "-12";
-        }
-        for (OrganizationPo secondOrg : secondOrgs) {
-            if (unit.contains(secondOrg.getName())) {
-                return secondOrg.getId();
-            }
-        }
-        return "-12";
-    }
-
-    /**
-     * 获取组织机构名称
-     * @param orgMap 组织机构字典
-     * @param orgNo 组织机构编码
-     */
-    public String getOrgName(Map<String, OrganizationPo> orgMap, String orgNo) {
-        if (!StringUtils.hasText(orgNo)) {
-            return "";
-        }
-        OrganizationPo po = orgMap.get(orgNo);
-        if (po != null) {
-            return po.getName();
-        }
-        return "";
-    }
-
-    /**
-     * 获取三级组织机构编码
-     * @param thirdOrgListMap 三级组织机构列表字典
-     * @param areaNo 二级组织机构编码
-     * @param areaName 二级组织机构名称
-     * @param unit 单位
-     */
-    public String getCityNo(Map<String, List<OrganizationPo>> thirdOrgListMap, String areaNo, String areaName,
-                            String unit) {
-        if (!StringUtils.hasText(areaNo) || !StringUtils.hasText(areaName)) {
-            return "";
-        }
-        if ("石家庄".equals(areaName)) {
-            if (unit.contains("井陉矿区")) {
-                return "D0130185";
-            }
-            if (unit.contains("井陉")) {
-                return "D0130121";
-            }
-        }
-        if ("秦皇岛".equals(areaName)) {
-            if (unit.contains("北戴河新区")) {
-                return "D0130325";
-            }
-            if (unit.contains("北戴河")) {
-                return "D0130304";
-            }
-        }
-        if ("邯郸".equals(areaName)) {
-            if (unit.contains("峰峰")) {
-                return "D0130406";
-            }
-        }
-        if ("邢台".equals(areaName)) {
-            if (unit.contains("内丘")) {
-                return "D0130523";
-            }
-            if (unit.contains("任泽")) {
-                return "D0130526";
-            }
-        }
-        if ("省机动局".equals(areaName)) {
-            if (unit.contains("沧州")) {
-                return "HECS180";
-            }
-            if (unit.contains("唐山")) {
-                return "HECS181";
-            }
-            if (unit.contains("秦皇岛")) {
-                return "HECS182";
-            }
-            if (unit.contains("廊坊")) {
-                return "HECS183";
-            }
-            if (unit.contains("张家口")) {
-                return "HECS184";
-            }
-            if (unit.contains("邢台")) {
-                return "HECS185";
-            }
-            if (unit.contains("邯郸")) {
-                return "HECS186";
-            }
-            if (unit.contains("保定")) {
-                return "HECS187";
-            }
-            if (unit.contains("石家庄")) {
-                return "HECS188";
-            }
-            if (unit.contains("承德")) {
-                return "HECS189";
-            }
-            if (unit.contains("衡水")) {
-                return "HECS720";
-            }
-            if (unit.contains("雄安")) {
-                return "HECS728";
-            }
-            return "HECS018";
-        }
-        if ("雄安".equals(areaName)) {
-            unit = unit.replace("雄安新区", "");
-        }
-        List<OrganizationPo> l3 = thirdOrgListMap.getOrDefault(areaNo, new ArrayList<>());
-        for (OrganizationPo organizationPo : l3) {
-            if (unit.contains(organizationPo.getName())) {
-                return organizationPo.getId();
-            }
-        }
-        // 市区
-        if ("沧州".equals(areaName)) {
-            return "D0130911";
-        }
-        if ("唐山".equals(areaName)) {
-            return "D0130202";
-        }
-        if ("秦皇岛".equals(areaName)) {
-            return "D0130302";
-        }
-        if ("廊坊".equals(areaName)) {
-            return "D0131000";
-        }
-        if ("张家口".equals(areaName)) {
-            return "D0130701";
-        }
-        if ("邢台".equals(areaName)) {
-            return "D0130502";
-        }
-        if ("邯郸".equals(areaName)) {
-            return "D0130402";
-        }
-        if ("保定".equals(areaName)) {
-            return "D0130601";
-        }
-        if ("石家庄".equals(areaName)) {
-            return "D0130186";
-        }
-        if ("承德".equals(areaName)) {
-            return "D0130801";
-        }
-        if ("衡水".equals(areaName)) {
-            return "D0133001";
-        }
-        if ("雄安".equals(areaName)) {
-            return "D0130830";
-        }
-        // 河北省分公司
-        return "HE001";
-    }
-
-    /**
-     * 获取地图匹配的二级组织机构编码,车效大屏
-     * @param areaName 二级组织机构名称
-     * @param cityName 三级组织机构名称
-     */
-    public String getAreaNo2(String areaName, String cityName) {
-        if (!StringUtils.hasText(areaName)) {
-            return "";
-        }
-        if ("省机动局".equals(areaName) && StringUtils.hasText(cityName)) {
-            if (cityName.contains("沧州")) {
-                return "180";
-            }
-            if (cityName.contains("唐山")) {
-                return "181";
-            }
-            if (cityName.contains("秦皇岛")) {
-                return "182";
-            }
-            if (cityName.contains("廊坊")) {
-                return "183";
-            }
-            if (cityName.contains("张家口")) {
-                return "184";
-            }
-            if (cityName.contains("邢台")) {
-                return "185";
-            }
-            if (cityName.contains("邯郸")) {
-                return "186";
-            }
-            if (cityName.contains("保定")) {
-                return "187";
-            }
-            if (cityName.contains("石家庄")) {
-                return "188";
-            }
-            if (cityName.contains("承德")) {
-                return "189";
-            }
-            if (cityName.contains("衡水")) {
-                return "720";
-            }
-            if (cityName.contains("雄安")) {
-                return "782";
-            }
-        }
-        if (areaName.contains("沧州")) {
-            return "180";
-        }
-        if (areaName.contains("唐山")) {
-            return "181";
-        }
-        if (areaName.contains("秦皇岛")) {
-            return "182";
-        }
-        if (areaName.contains("廊坊")) {
-            return "183";
-        }
-        if (areaName.contains("张家口")) {
-            return "184";
-        }
-        if (areaName.contains("邢台")) {
-            return "185";
-        }
-        if (areaName.contains("邯郸")) {
-            return "186";
-        }
-        if (areaName.contains("保定")) {
-            return "187";
-        }
-        if (areaName.contains("石家庄")) {
-            return "188";
-        }
-        if (areaName.contains("承德")) {
-            return "189";
-        }
-        if (areaName.contains("衡水")) {
-            return "720";
-        }
-        if (areaName.contains("雄安")) {
-            return "782";
-        }
-        return "";
-    }
-
-    /**
-     * 获取地市id
-     * @param cities 地市列表
-     * @param unit 单位
-     */
-    public String getCityId(List<AreaPo> cities, String unit) {
-        if (!StringUtils.hasText(unit)) {
-            return "";
-        }
-        for (AreaPo city : cities) {
-            if (unit.contains(city.getShortName())) {
-                return city.getAreaId();
-            }
-        }
-        return "";
-    }
-
-    /**
-     * 获取地区名称
-     * @param areaMap 地区map
-     * @param id 地区id
-     */
-    public String getAreaName(Map<String, AreaPo> areaMap, String id) {
-        if (!StringUtils.hasText(id)) {
-            return "";
-        }
-        AreaPo areaPo = areaMap.get(id);
-        if (null != areaPo) {
-            return areaPo.getAreaName();
-        }
-        return "";
-    }
-
-    /**
-     * 获取区县id
-     * @param districtListMap 区县列表map
-     * @param cityId 地市id
-     * @param cityName 地市名称
-     * @param unit 单位
-     */
-    public String getDistrictId(Map<String, List<AreaPo>> districtListMap, String cityId, String cityName, String unit) {
-        if (!StringUtils.hasText(cityId) || !StringUtils.hasText(cityName) || !StringUtils.hasText(unit)) {
-            return "";
-        }
-        if ("石家庄".equals(cityName)) {
-            if (unit.contains("井陉矿区")) {
-                return "130107";
-            }
-            if (unit.contains("井陉")) {
-                return "130121";
-            }
-        }
-        if ("雄安".equals(cityName)) {
-            unit = unit.replace("雄安新区", "");
-        }
-        List<AreaPo> districts = districtListMap.get(cityId);
-        if (CollectionUtils.isEmpty(districts)) {
-            return "";
-        }
-        for (AreaPo district : districts) {
-            if (unit.contains(district.getShortName())) {
-                return district.getAreaId();
-            }
-        }
-        return "";
-    }
-}
+//package com.nokia.financeapi.service.car;
+//
+//import com.fasterxml.jackson.core.JsonProcessingException;
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.fasterxml.jackson.databind.type.TypeFactory;
+//import com.nokia.financeapi.common.exception.MyRuntimeException;
+//import com.nokia.financeapi.pojo.po.common.AreaPo;
+//import com.nokia.financeapi.pojo.po.common.OrganizationPo;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.stereotype.Service;
+//import org.springframework.util.CollectionUtils;
+//import org.springframework.util.StringUtils;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.regex.Matcher;
+//import java.util.regex.Pattern;
+//
+//@Slf4j
+//@Service
+//public class CarService {
+//    /**
+//     * 匹配车牌省份
+//     */
+//    static final Pattern HAS_CHE_PAI_PROVINCE_PATTERN = Pattern.compile("[" + Pattern.quote("京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁国防") + "]");
+//    /**
+//     * 匹配非车牌字符
+//     */
+//    static final Pattern NOT_CHE_PAI_PATTERN = Pattern.compile("[^京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新港澳学挂领试超练警国防A-Z\\d]");
+//    /**
+//     * 车牌正则
+//     */
+//    static final Pattern CHE_PAI_PATTERN = Pattern.compile(
+//            "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z][A-Z](([DF]((?![IO])[A-Z0-9](?![IO]))\\d{4})|(\\d{5}[DF]))|[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z][A-Z][A-Z0-9]{4}[A-Z0-9挂学警港澳])"
+//    );
+//
+//    /**
+//     * 一级单位的二级单位字典
+//     */
+//    static final Map<String, List<String>> ER_JI_MAP;
+//
+//    static {
+//        try {
+//            ER_JI_MAP = new ObjectMapper().readValue(
+//                    """
+//{
+//    "石家庄": ["鹿泉", "藁城", "栾城", "井陉矿区", "井陉", "无极", "正定", "元氏", "新乐", "晋州", "平山", "灵寿", "赞皇", "赵县", "行唐", "高邑", "辛集", "深泽"],
+//    "唐山": ["唐山高开区", "迁西", "海港", "开平", "丰南", "滦县", "乐亭", "丰润", "玉田", "古冶", "曹妃甸", "遵化", "滦南", "迁安"],
+//    "秦皇岛": ["北戴河新区", "北戴河", "山海关", "昌黎", "卢龙", "青龙", "抚宁"],
+//    "邯郸": ["曲周", "魏县", "馆陶", "磁县", "大名", "鸡泽", "成安", "涉县", "永年", "武安", "峰峰", "广平", "临漳", "邱县", "肥乡"],
+//    "邢台": ["新河", "南宫", "隆尧", "内邱", "平乡", "宁晋", "广宗", "清河", "临西", "任县", "巨鹿", "沙河", "威县", "临城", "柏乡", "南和"],
+//    "保定": ["涞水", "蠡县", "顺平", "博野", "安国", "涞源", "唐县", "定州", "高阳", "曲阳", "阜平", "清苑", "高碑店", "满城", "涿州", "易县", "望都", "徐水", "定兴", "白沟"],
+//    "张家口": ["张北", "崇礼", "康保", "赤城", "阳原", "万全", "下花园", "尚义", "怀安", "怀来", "蔚县", "涿鹿", "沽源", "宣化"],
+//    "承德": ["承德县", "兴隆", "宽城", "平泉", "营子", "隆化", "滦平", "围场", "丰宁", "双滦"],
+//    "廊坊": ["文安", "霸州", "大城", "廊坊开发区", "三河", "香河", "永清", "胜芳", "燕郊", "固安", "大厂"],
+//    "沧州": ["东光", "吴桥", "黄骅", "盐山", "孟村", "泊头", "献县", "南皮", "渤海新区", "海兴", "沧县", "河间", "青县", "任丘", "肃宁"],
+//    "衡水": ["景县", "阜城", "枣强", "深州", "饶阳", "故城", "武强", "武邑", "冀州", "安平"],
+//    "雄安": ["容城", "雄县", "安新"]
+//}
+//                            """,
+//                    TypeFactory.defaultInstance().constructMapType(Map.class, String.class, List.class)
+//            );
+//        } catch (JsonProcessingException e) {
+//            throw new MyRuntimeException(e);
+//        }
+//    }
+//
+//    /**
+//     * 匹配车牌
+//     * @param chePai 车牌
+//     */
+//    public String getChePai(String chePai) {
+//        if (!StringUtils.hasText(chePai)) {
+//            return "";
+//        }
+//        // 字母转大写
+//        String upperCase = chePai.toUpperCase();
+//        // 删除非车牌字符
+//        String s = NOT_CHE_PAI_PATTERN.matcher(upperCase).replaceAll("");
+//        Matcher m = CHE_PAI_PATTERN.matcher(s);
+//        if (m.find()) {
+//            return m.group(0);
+//        }
+//        if (HAS_CHE_PAI_PROVINCE_PATTERN.matcher(chePai).find()) {
+//            log.warn("车牌匹配失败: {} -> {}", chePai, s);
+//            return s;
+//        }
+//        log.warn("车牌匹配失败: {} -> {}", chePai, upperCase);
+//        return upperCase;
+//    }
+//
+//    /**
+//     * 车牌是否匹配失败
+//     * @param chePai 车牌
+//     */
+//    public String chePaiFail(String chePai) {
+//        if (!StringUtils.hasText(chePai)) {
+//            return "1";
+//        }
+//        // 字母转大写删除非车牌字符
+//        String s = NOT_CHE_PAI_PATTERN.matcher(chePai.toUpperCase()).replaceAll("");
+//        Matcher m = CHE_PAI_PATTERN.matcher(s);
+//        if (m.find()) {
+//            return "0";
+//        }
+//        return "1";
+//    }
+//
+//    /**
+//     * 车牌是否包含报废
+//     * @param chePai 车牌
+//     */
+//    public String baoFei(String chePai) {
+//        if (chePai.contains("报废")) {
+//            return "1";
+//        }
+//        return "0";
+//    }
+//
+//    /**
+//     * 获取一级单位
+//     * @param unit 单位
+//     */
+//    public String getFirstUnit(String unit) {
+//        if (!StringUtils.hasText(unit)) {
+//            return "";
+//        }
+//        if (unit.contains("机动通信局") || unit.contains("机动局") || unit.contains("传输局") || unit.contains("线路维护中心")) {
+//            return "机动局";
+//        }
+//        if (unit.contains("雄安基地建设部")) {
+//            return "雄安基地建设部";
+//        }
+//        if (unit.contains("华北基地建设部")) {
+//            return "华北基地建设部";
+//        }
+//        for (String yj : ER_JI_MAP.keySet()) {
+//            if (unit.contains(yj)) {
+//                return yj;
+//            }
+//        }
+//        return "省公司本部";
+//    }
+//
+//    /**
+//     * 获取而二级单位
+//     * @param unit 单位
+//     * @param firstUnit 一级单位
+//     */
+//    public String getSecondUnit(String unit, String firstUnit) {
+//        if (!StringUtils.hasText(unit)) {
+//            return firstUnit;
+//        }
+//        if ("省公司本部".equals(firstUnit)) {
+//            return firstUnit;
+//        }
+//        if ("机动局".equals(firstUnit)) {
+//            for (String yj : ER_JI_MAP.keySet()) {
+//                if (unit.contains(yj)) {
+//                    return "机动局" + yj;
+//                }
+//            }
+//            return "机动局本部";
+//        }
+//        if ("石家庄".equals(firstUnit)) {
+//            if (unit.contains("开发区")) {
+//                return "石家庄开发区";
+//            }
+//        }
+//        if ("廊坊".equals(firstUnit)) {
+//            if (unit.contains("开发区")) {
+//                return "廊坊开发区";
+//            }
+//        }
+//        if ("邢台".equals(firstUnit)) {
+//            if (unit.contains("内丘")) {
+//                return "内邱";
+//            }
+//            if (unit.contains("任泽")) {
+//                return "任县";
+//            }
+//        }
+//        if ("唐山".equals(firstUnit)) {
+//            if (unit.contains("高开区")) {
+//                return "唐山高开区";
+//            }
+//            if (unit.contains("滦州")) {
+//                return "滦县";
+//            }
+//        }
+//        List<String> ejs = ER_JI_MAP.get(firstUnit);
+//        if (CollectionUtils.isEmpty(ejs)) {
+//            return firstUnit;
+//        }
+//        if ("雄安".equals(firstUnit)) {
+//            unit = unit.replace("雄安新区", "");
+//        }
+//        for (String ej : ejs) {
+//            if (unit.contains(ej)) {
+//                return ej;
+//            }
+//        }
+//        return firstUnit + "本部";
+//    }
+//
+//    /**
+//     * 获取三级单位
+//     * @param unit 单位
+//     * @param secondUnit 二级单位
+//     */
+//    public String getThirdUnit(String unit, String secondUnit) {
+//        if (!StringUtils.hasText(unit)) {
+//            return secondUnit;
+//        }
+//        String[] a = unit.split("_");
+//        if (a.length == 1) {
+//            return unit;
+//        }
+//        if (a.length < 4) {
+//            return secondUnit;
+//        }
+//        return a[3];
+//    }
+//
+//    /**
+//     * 获取二级组织机构编码
+//     * @param secondOrgs 二级组织机构列表
+//     * @param unit 单位
+//     */
+//    public String getAreaNo(List<OrganizationPo> secondOrgs, String unit) {
+//        if (!StringUtils.hasText(unit)) {
+//            return "";
+//        }
+//        if (unit.contains("机动通信局") || unit.contains("机动局") || unit.contains("传输局") || unit.contains("线路维护中心")) {
+//            return "-11";
+//        }
+//        if (unit.contains("省公司本部") || unit.contains("雄安基地建设部") || unit.contains("华北基地建设部")) {
+//            return "-12";
+//        }
+//        for (OrganizationPo secondOrg : secondOrgs) {
+//            if (unit.contains(secondOrg.getName())) {
+//                return secondOrg.getId();
+//            }
+//        }
+//        return "-12";
+//    }
+//
+//    /**
+//     * 获取组织机构名称
+//     * @param orgMap 组织机构字典
+//     * @param orgNo 组织机构编码
+//     */
+//    public String getOrgName(Map<String, OrganizationPo> orgMap, String orgNo) {
+//        if (!StringUtils.hasText(orgNo)) {
+//            return "";
+//        }
+//        OrganizationPo po = orgMap.get(orgNo);
+//        if (po != null) {
+//            return po.getName();
+//        }
+//        return "";
+//    }
+//
+//    /**
+//     * 获取三级组织机构编码
+//     * @param thirdOrgListMap 三级组织机构列表字典
+//     * @param areaNo 二级组织机构编码
+//     * @param areaName 二级组织机构名称
+//     * @param unit 单位
+//     */
+//    public String getCityNo(Map<String, List<OrganizationPo>> thirdOrgListMap, String areaNo, String areaName,
+//                            String unit) {
+//        if (!StringUtils.hasText(areaNo) || !StringUtils.hasText(areaName)) {
+//            return "";
+//        }
+//        if ("石家庄".equals(areaName)) {
+//            if (unit.contains("井陉矿区")) {
+//                return "D0130185";
+//            }
+//            if (unit.contains("井陉")) {
+//                return "D0130121";
+//            }
+//        }
+//        if ("秦皇岛".equals(areaName)) {
+//            if (unit.contains("北戴河新区")) {
+//                return "D0130325";
+//            }
+//            if (unit.contains("北戴河")) {
+//                return "D0130304";
+//            }
+//        }
+//        if ("邯郸".equals(areaName)) {
+//            if (unit.contains("峰峰")) {
+//                return "D0130406";
+//            }
+//        }
+//        if ("邢台".equals(areaName)) {
+//            if (unit.contains("内丘")) {
+//                return "D0130523";
+//            }
+//            if (unit.contains("任泽")) {
+//                return "D0130526";
+//            }
+//        }
+//        if ("省机动局".equals(areaName)) {
+//            if (unit.contains("沧州")) {
+//                return "HECS180";
+//            }
+//            if (unit.contains("唐山")) {
+//                return "HECS181";
+//            }
+//            if (unit.contains("秦皇岛")) {
+//                return "HECS182";
+//            }
+//            if (unit.contains("廊坊")) {
+//                return "HECS183";
+//            }
+//            if (unit.contains("张家口")) {
+//                return "HECS184";
+//            }
+//            if (unit.contains("邢台")) {
+//                return "HECS185";
+//            }
+//            if (unit.contains("邯郸")) {
+//                return "HECS186";
+//            }
+//            if (unit.contains("保定")) {
+//                return "HECS187";
+//            }
+//            if (unit.contains("石家庄")) {
+//                return "HECS188";
+//            }
+//            if (unit.contains("承德")) {
+//                return "HECS189";
+//            }
+//            if (unit.contains("衡水")) {
+//                return "HECS720";
+//            }
+//            if (unit.contains("雄安")) {
+//                return "HECS728";
+//            }
+//            return "HECS018";
+//        }
+//        if ("雄安".equals(areaName)) {
+//            unit = unit.replace("雄安新区", "");
+//        }
+//        List<OrganizationPo> l3 = thirdOrgListMap.getOrDefault(areaNo, new ArrayList<>());
+//        for (OrganizationPo organizationPo : l3) {
+//            if (unit.contains(organizationPo.getName())) {
+//                return organizationPo.getId();
+//            }
+//        }
+//        // 市区
+//        if ("沧州".equals(areaName)) {
+//            return "D0130911";
+//        }
+//        if ("唐山".equals(areaName)) {
+//            return "D0130202";
+//        }
+//        if ("秦皇岛".equals(areaName)) {
+//            return "D0130302";
+//        }
+//        if ("廊坊".equals(areaName)) {
+//            return "D0131000";
+//        }
+//        if ("张家口".equals(areaName)) {
+//            return "D0130701";
+//        }
+//        if ("邢台".equals(areaName)) {
+//            return "D0130502";
+//        }
+//        if ("邯郸".equals(areaName)) {
+//            return "D0130402";
+//        }
+//        if ("保定".equals(areaName)) {
+//            return "D0130601";
+//        }
+//        if ("石家庄".equals(areaName)) {
+//            return "D0130186";
+//        }
+//        if ("承德".equals(areaName)) {
+//            return "D0130801";
+//        }
+//        if ("衡水".equals(areaName)) {
+//            return "D0133001";
+//        }
+//        if ("雄安".equals(areaName)) {
+//            return "D0130830";
+//        }
+//        // 河北省分公司
+//        return "HE001";
+//    }
+//
+//    /**
+//     * 获取地图匹配的二级组织机构编码,车效大屏
+//     * @param areaName 二级组织机构名称
+//     * @param cityName 三级组织机构名称
+//     */
+//    public String getAreaNo2(String areaName, String cityName) {
+//        if (!StringUtils.hasText(areaName)) {
+//            return "";
+//        }
+//        if ("省机动局".equals(areaName) && StringUtils.hasText(cityName)) {
+//            if (cityName.contains("沧州")) {
+//                return "180";
+//            }
+//            if (cityName.contains("唐山")) {
+//                return "181";
+//            }
+//            if (cityName.contains("秦皇岛")) {
+//                return "182";
+//            }
+//            if (cityName.contains("廊坊")) {
+//                return "183";
+//            }
+//            if (cityName.contains("张家口")) {
+//                return "184";
+//            }
+//            if (cityName.contains("邢台")) {
+//                return "185";
+//            }
+//            if (cityName.contains("邯郸")) {
+//                return "186";
+//            }
+//            if (cityName.contains("保定")) {
+//                return "187";
+//            }
+//            if (cityName.contains("石家庄")) {
+//                return "188";
+//            }
+//            if (cityName.contains("承德")) {
+//                return "189";
+//            }
+//            if (cityName.contains("衡水")) {
+//                return "720";
+//            }
+//            if (cityName.contains("雄安")) {
+//                return "782";
+//            }
+//        }
+//        if (areaName.contains("沧州")) {
+//            return "180";
+//        }
+//        if (areaName.contains("唐山")) {
+//            return "181";
+//        }
+//        if (areaName.contains("秦皇岛")) {
+//            return "182";
+//        }
+//        if (areaName.contains("廊坊")) {
+//            return "183";
+//        }
+//        if (areaName.contains("张家口")) {
+//            return "184";
+//        }
+//        if (areaName.contains("邢台")) {
+//            return "185";
+//        }
+//        if (areaName.contains("邯郸")) {
+//            return "186";
+//        }
+//        if (areaName.contains("保定")) {
+//            return "187";
+//        }
+//        if (areaName.contains("石家庄")) {
+//            return "188";
+//        }
+//        if (areaName.contains("承德")) {
+//            return "189";
+//        }
+//        if (areaName.contains("衡水")) {
+//            return "720";
+//        }
+//        if (areaName.contains("雄安")) {
+//            return "782";
+//        }
+//        return "";
+//    }
+//
+//    /**
+//     * 获取地市id
+//     * @param cities 地市列表
+//     * @param unit 单位
+//     */
+//    public String getCityId(List<AreaPo> cities, String unit) {
+//        if (!StringUtils.hasText(unit)) {
+//            return "";
+//        }
+//        for (AreaPo city : cities) {
+//            if (unit.contains(city.getShortName())) {
+//                return city.getAreaId();
+//            }
+//        }
+//        return "";
+//    }
+//
+//    /**
+//     * 获取地区名称
+//     * @param areaMap 地区map
+//     * @param id 地区id
+//     */
+//    public String getAreaName(Map<String, AreaPo> areaMap, String id) {
+//        if (!StringUtils.hasText(id)) {
+//            return "";
+//        }
+//        AreaPo areaPo = areaMap.get(id);
+//        if (null != areaPo) {
+//            return areaPo.getAreaName();
+//        }
+//        return "";
+//    }
+//
+//    /**
+//     * 获取区县id
+//     * @param districtListMap 区县列表map
+//     * @param cityId 地市id
+//     * @param cityName 地市名称
+//     * @param unit 单位
+//     */
+//    public String getDistrictId(Map<String, List<AreaPo>> districtListMap, String cityId, String cityName, String unit) {
+//        if (!StringUtils.hasText(cityId) || !StringUtils.hasText(cityName) || !StringUtils.hasText(unit)) {
+//            return "";
+//        }
+//        if ("石家庄".equals(cityName)) {
+//            if (unit.contains("井陉矿区")) {
+//                return "130107";
+//            }
+//            if (unit.contains("井陉")) {
+//                return "130121";
+//            }
+//        }
+//        if ("雄安".equals(cityName)) {
+//            unit = unit.replace("雄安新区", "");
+//        }
+//        List<AreaPo> districts = districtListMap.get(cityId);
+//        if (CollectionUtils.isEmpty(districts)) {
+//            return "";
+//        }
+//        for (AreaPo district : districts) {
+//            if (unit.contains(district.getShortName())) {
+//                return district.getAreaId();
+//            }
+//        }
+//        return "";
+//    }
+//}

+ 307 - 307
src/main/java/com/nokia/financeapi/service/car/CarWeiZhangImportService.java

@@ -1,307 +1,307 @@
-package com.nokia.financeapi.service.car;
-
-import com.nokia.financeapi.common.exception.BizException;
-import com.nokia.financeapi.common.exception.MyRuntimeException;
-import com.nokia.financeapi.common.utils.psql.PsqlUtil;
-import com.nokia.financeapi.config.CarDataImportConfig;
-import com.nokia.financeapi.dao.car.CarWeiZhangDao;
-import com.nokia.financeapi.dao.gdc.GdcCarWeiZhangDao;
-import com.nokia.financeapi.pojo.dto.CarDataImportDto;
-import com.nokia.financeapi.pojo.po.common.AreaPo;
-import com.nokia.financeapi.pojo.po.common.OrganizationPo;
-import com.nokia.financeapi.service.common.AreaService;
-import com.nokia.financeapi.service.common.OrganizationService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.csv.CSVFormat;
-import org.apache.commons.csv.CSVPrinter;
-import org.apache.commons.io.FileUtils;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.DateUtil;
-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.xssf.usermodel.XSSFWorkbook;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.StringUtils;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.math.BigDecimal;
-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.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-@Slf4j
-@Service
-public class CarWeiZhangImportService {
-    private final CarDataImportConfig carDataImportConfig;
-    private final CarService carService;
-    private final OrganizationService organizationService;
-    private final AreaService areaService;
-    private final CarWeiZhangDao carWeiZhangDao;
-    private final GdcCarWeiZhangDao gdcCarWeiZhangDao;
-
-    public CarWeiZhangImportService(CarDataImportConfig carDataImportConfig, CarService carService,
-                                    OrganizationService organizationService, AreaService areaService,
-                                    CarWeiZhangDao carWeiZhangDao, GdcCarWeiZhangDao gdcCarWeiZhangDao) {
-        this.carDataImportConfig = carDataImportConfig;
-        this.carService = carService;
-        this.organizationService = organizationService;
-        this.areaService = areaService;
-        this.carWeiZhangDao = carWeiZhangDao;
-        this.gdcCarWeiZhangDao = gdcCarWeiZhangDao;
-    }
-
-    @Transactional(timeout = 120, rollbackFor = Exception.class)
-    public synchronized void dataImport(CarDataImportDto dto, MultipartFile file) throws IOException {
-        boolean flag = carWeiZhangDao.hasData(dto.getYearMonth());
-        if (flag) {
-            throw new BizException("该账期数据已存在");
-        }
-        Files.createDirectories(Paths.get(carDataImportConfig.getWeiZhang()));
-        File fileNew = new File(carDataImportConfig.getWeiZhang() + dto.getYearMonth() + ".xlsx");
-        FileUtils.copyInputStreamToFile(file.getInputStream(), fileNew);
-        Path path = fileNew.toPath();
-        List<Map<String, String>> list = readFile(path);
-        List<Map<String, String>> distinctList = dataProcessing(path, list, dto);
-        Path csvPath = toCsv(path, distinctList);
-        copyCsv(csvPath);
-        procedure(dto);
-    }
-
-    /**
-     * 读取文件
-     *
-     * @param path 文件路径
-     */
-    public List<Map<String, String>> readFile(Path path) throws IOException {
-        log.info("读取: {}", path);
-        List<String> rawHeaders = Stream.of("账期", "车牌号", "一级单位", "二级单位", "三级单位", "车架号", "违章时间",
-                "违章地点", "违章详情", "扣分", "罚款", "三方处理状态", "处理时间", "违章未处理时长(天)").toList();
-        List<String> headers = Stream.of("year_month", "che_pai_hao", "raw_yi_ji", "raw_er_ji", "raw_san_ji",
-                "che_jia_hao", "wei_zhang_shi_jian", "wei_zhang_di_dian", "wei_zhang_xiang_qing", "kou_fen", "fa_kuan",
-                "chu_li_zhuang_tai", "chu_li_shi_jian", "wei_zhang_wei_chu_li_shi_chang").toList();
-        try (InputStream inputStream = Files.newInputStream(path);
-             Workbook workbook = new XSSFWorkbook(inputStream)
-        ) {
-            List<Map<String, String>> resultList = new ArrayList<>();
-            // 读取第一个工作表
-            Sheet sheet = workbook.getSheetAt(0);
-            // 表头行
-            Row headerRow = sheet.getRow(0);
-            // 列数
-            int columnCount = headerRow.getPhysicalNumberOfCells();
-            log.info("columnCount: {}", columnCount);
-            // 检查表头
-            if (headers.size() != columnCount) {
-                throw new BizException("列数错误");
-            }
-            for (int i = 0; i < columnCount; i++) {
-                Cell cell = headerRow.getCell(i);
-                if (cell == null || !rawHeaders.get(i).equals(cell.getStringCellValue())) {
-                    throw new BizException("表头错误");
-                }
-            }
-            // 最后行数
-            int lastRowNum = sheet.getLastRowNum();
-            log.info("lastRowNum: {}", lastRowNum);
-            if (lastRowNum == 0) {
-                throw new BizException("文件为空");
-            }
-            // 遍历行
-            for (int i = 1; i <= lastRowNum; i++) {
-                Row row = sheet.getRow(i);
-                if (row == null) {
-                    continue;
-                }
-                Map<String, String> rowMap = new LinkedHashMap<>();
-                // 遍历列
-                for (int j = 0; j < columnCount; j++) {
-                    String header = headers.get(j);
-                    String cellValue = "";
-                    rowMap.put(header, cellValue);
-                    Cell cell = row.getCell(j);
-                    if (cell == null) {
-                        continue;
-                    }
-                    switch (cell.getCellType()) {
-                        case STRING:
-                            boolean skipTrim = "wei_zhang_shi_jian".equals(header) || "chu_li_shi_jian".equals(header);
-                            // 删除字符串空白字符
-                            cellValue = skipTrim ? cell.getStringCellValue()
-                                    : StringUtils.trimAllWhitespace(cell.getStringCellValue());
-                            break;
-                        case NUMERIC:
-                            if (DateUtil.isCellDateFormatted(cell)) {
-                                cellValue = DateUtil.getLocalDateTime(cell.getNumericCellValue())
-                                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-                                break;
-                            }
-                            cellValue = String.valueOf(cell.getNumericCellValue());
-                            break;
-                        case BOOLEAN:
-                            cellValue = String.valueOf(cell.getBooleanCellValue());
-                            break;
-                        default:
-                            break;
-                    }
-                    rowMap.put(header, cellValue);
-                }
-                resultList.add(rowMap);
-            }
-            return resultList;
-        }
-    }
-
-    /**
-     * 数据加工
-     *
-     * @param path 文件路径
-     * @param list 数据
-     * @param dto 请求参数
-     */
-    public List<Map<String, String>> dataProcessing(Path path, List<Map<String, String>> list, CarDataImportDto dto) {
-        String yearMonth = dto.getYearMonth().toString();
-        LocalDate localDate = LocalDate.parse(yearMonth + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
-        String year = String.valueOf(localDate.getYear());
-        String month = String.valueOf(localDate.getMonthValue());
-        List<OrganizationPo> secondOrgs = organizationService.getSecondOrgs();
-        List<OrganizationPo> thirdOrgs = organizationService.getThirdOrgs();
-        Map<String, OrganizationPo> orgMap = organizationService.getOrgMap(secondOrgs, thirdOrgs);
-        Map<String, List<OrganizationPo>> thirdOrganizationListMap =
-                organizationService.getThirdOrganizationListMap(secondOrgs, thirdOrgs);
-        List<AreaPo> cities = areaService.getCities();
-        List<AreaPo> districts = areaService.getDistricts();
-        Map<String, AreaPo> areaMap = areaService.getAreaMap(cities, districts);
-        Map<String, List<AreaPo>> districtListMap = areaService.getDistrictListMap(cities, districts);
-        for (Map<String, String> map : list) {
-            map.put("year_month", yearMonth);
-            map.put("year_no", year);
-            map.put("month_no", month);
-            String rawChePaiHao = map.get("che_pai_hao");
-            map.put("raw_che_pai_hao", rawChePaiHao);
-            String chePaiHao = carService.getChePai(rawChePaiHao);
-            map.put("che_pai_hao", chePaiHao);
-            String chePaiFail = carService.chePaiFail(rawChePaiHao);
-            map.put("che_pai_fail", chePaiFail);
-            String yj = map.get("raw_yi_ji");
-            String ej = map.get("raw_er_ji");
-            String sj = map.get("raw_san_ji");
-            String firstUnit = carService.getFirstUnit(yj);
-            map.put("first_unit", firstUnit);
-            String secondUnit = carService.getSecondUnit(ej, firstUnit);
-            map.put("second_unit", secondUnit);
-            String thirdUnit = carService.getThirdUnit(sj, secondUnit);
-            map.put("third_unit", thirdUnit);
-            String areaNo = carService.getAreaNo(secondOrgs, yj);
-            map.put("area_no", areaNo);
-            String areaName = carService.getOrgName(orgMap, areaNo);
-            map.put("area_name", areaName);
-            String cityNo = carService.getCityNo(thirdOrganizationListMap, areaNo, areaName, ej);
-            map.put("city_no", cityNo);
-            String cityName = carService.getOrgName(orgMap, cityNo);
-            map.put("city_name", cityName);
-            String areaNo2 = carService.getAreaNo2(areaName, cityName);
-            map.put("area_no2", areaNo2);
-            String areaName2 = carService.getOrgName(orgMap, areaNo2);
-            map.put("area_name2", areaName2);
-            String cityId = carService.getCityId(cities, yj);
-            map.put("city_id", cityId);
-            String city = carService.getAreaName(areaMap, cityId);
-            map.put("city", city);
-            String districtId = carService.getDistrictId(districtListMap, cityId, cityName, ej);
-            map.put("district_id", districtId);
-            String district = carService.getAreaName(areaMap, districtId);
-            map.put("district", district);
-            String weiZhangShiJian = map.get("wei_zhang_shi_jian");
-            LocalDateTime weiZhangShiJianLocalDateTime = LocalDateTime.parse(weiZhangShiJian,
-                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-            String weiZhangNianYue = weiZhangShiJianLocalDateTime.format(DateTimeFormatter.ofPattern("yyyyMM"));
-            map.put("wei_zhang_nian_yue", weiZhangNianYue);
-            String chuLiShiJian = map.get("chu_li_shi_jian");
-            String chuLiNianYue = "";
-            if (StringUtils.hasText(chuLiShiJian)) {
-                LocalDateTime chuLiShiJianLocalDateTime = LocalDateTime.parse(chuLiShiJian,
-                        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-                chuLiNianYue = chuLiShiJianLocalDateTime.format(DateTimeFormatter.ofPattern("yyyyMM"));
-            }
-            map.put("chu_li_nian_yue", chuLiNianYue);
-            map.put("source", path.getFileName().toString());
-            String kouFen = map.get("kou_fen");
-            if (StringUtils.hasText(kouFen)) {
-                map.put("kou_fen", String.valueOf(new BigDecimal(kouFen).intValue()));
-            }
-            String weiZhangWeiChuLiShiChang = map.get("wei_zhang_wei_chu_li_shi_chang");
-            if (StringUtils.hasText(weiZhangWeiChuLiShiChang)) {
-                map.put("wei_zhang_wei_chu_li_shi_chang",
-                        String.valueOf(new BigDecimal(weiZhangWeiChuLiShiChang).intValue()));
-            }
-        }
-        return list;
-    }
-
-    /**
-     * 生成csv
-     *
-     * @param path 源文件路径
-     * @param list 数据
-     */
-    public Path toCsv(Path path, List<Map<String, String>> list) throws IOException {
-        log.info("条数:{}", list.size());
-        Path csvPath = Paths.get(path + ".csv");
-        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
-                StandardCharsets.UTF_8);
-             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
-            // 添加bom头避免excel乱码
-            osw.write('\ufeff');
-            Map<String, String> header = list.get(0);
-            // 表头
-            printer.printRecord(header.keySet());
-            for (Map<String, String> map : list) {
-                printer.printRecord(map.values());
-            }
-        }
-        return csvPath;
-    }
-
-    /**
-     * 导入数据库
-     *
-     * @param path 文件路径
-     */
-    public void copyCsv(Path path) {
-        String dbTable = "car.car_wei_zhang";
-        String csv = path.toString();
-        String columns = "(year_month,che_pai_hao,raw_yi_ji,raw_er_ji,raw_san_ji,che_jia_hao,wei_zhang_shi_jian,wei_zhang_di_dian,wei_zhang_xiang_qing,kou_fen,fa_kuan,chu_li_zhuang_tai,chu_li_shi_jian,wei_zhang_wei_chu_li_shi_chang,year_no,month_no,raw_che_pai_hao,che_pai_fail,first_unit,second_unit,third_unit,area_no,area_name,city_no,city_name,area_no2,area_name2,city_id,city,district_id,district,wei_zhang_nian_yue,chu_li_nian_yue,source)";
-        Long timeout = 60000L;
-        PsqlUtil.copyCsv(carDataImportConfig.getCopyScriptPath(), carDataImportConfig.getDbHost(),
-                carDataImportConfig.getDbPort(), carDataImportConfig.getDbUsername(), carDataImportConfig.getDbPassword(),
-                carDataImportConfig.getDbName(), dbTable, csv, columns, timeout, null);
-    }
-
-    /**
-     * 更新数据库
-     */
-    public void procedure(CarDataImportDto dto) {
-        int update1 = carWeiZhangDao.insertCarWeiZhangChangQi(dto.getYearMonth());
-        log.info("insert car.car_wei_zhang_chang_qi: {}", update1);
-        int update2 = gdcCarWeiZhangDao.insertWeiZhang(dto.getYearMonth());
-        log.info("insert car_theme.wz_f_violation_details: {}", update2);
-        if (update2 == 0) {
-            throw new MyRuntimeException("插入car_theme.wz_f_violation_details失败");
-        }
-    }
-}
+//package com.nokia.financeapi.service.car;
+//
+//import com.nokia.financeapi.common.exception.BizException;
+//import com.nokia.financeapi.common.exception.MyRuntimeException;
+//import com.nokia.financeapi.common.utils.psql.PsqlUtil;
+//import com.nokia.financeapi.config.CarDataImportConfig;
+//import com.nokia.financeapi.dao.car.CarWeiZhangDao;
+//import com.nokia.financeapi.dao.gdc.GdcCarWeiZhangDao;
+//import com.nokia.financeapi.pojo.dto.CarDataImportDto;
+//import com.nokia.financeapi.pojo.po.common.AreaPo;
+//import com.nokia.financeapi.pojo.po.common.OrganizationPo;
+//import com.nokia.financeapi.service.common.AreaService;
+//import com.nokia.financeapi.service.common.OrganizationService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.csv.CSVFormat;
+//import org.apache.commons.csv.CSVPrinter;
+//import org.apache.commons.io.FileUtils;
+//import org.apache.poi.ss.usermodel.Cell;
+//import org.apache.poi.ss.usermodel.DateUtil;
+//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.xssf.usermodel.XSSFWorkbook;
+//import org.springframework.stereotype.Service;
+//import org.springframework.transaction.annotation.Transactional;
+//import org.springframework.util.StringUtils;
+//import org.springframework.web.multipart.MultipartFile;
+//
+//import java.io.File;
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.io.OutputStreamWriter;
+//import java.math.BigDecimal;
+//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.ArrayList;
+//import java.util.LinkedHashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.stream.Stream;
+//
+//@Slf4j
+//@Service
+//public class CarWeiZhangImportService {
+//    private final CarDataImportConfig carDataImportConfig;
+//    private final CarService carService;
+//    private final OrganizationService organizationService;
+//    private final AreaService areaService;
+//    private final CarWeiZhangDao carWeiZhangDao;
+//    private final GdcCarWeiZhangDao gdcCarWeiZhangDao;
+//
+//    public CarWeiZhangImportService(CarDataImportConfig carDataImportConfig, CarService carService,
+//                                    OrganizationService organizationService, AreaService areaService,
+//                                    CarWeiZhangDao carWeiZhangDao, GdcCarWeiZhangDao gdcCarWeiZhangDao) {
+//        this.carDataImportConfig = carDataImportConfig;
+//        this.carService = carService;
+//        this.organizationService = organizationService;
+//        this.areaService = areaService;
+//        this.carWeiZhangDao = carWeiZhangDao;
+//        this.gdcCarWeiZhangDao = gdcCarWeiZhangDao;
+//    }
+//
+//    @Transactional(timeout = 120, rollbackFor = Exception.class)
+//    public synchronized void dataImport(CarDataImportDto dto, MultipartFile file) throws IOException {
+//        boolean flag = carWeiZhangDao.hasData(dto.getYearMonth());
+//        if (flag) {
+//            throw new BizException("该账期数据已存在");
+//        }
+//        Files.createDirectories(Paths.get(carDataImportConfig.getWeiZhang()));
+//        File fileNew = new File(carDataImportConfig.getWeiZhang() + dto.getYearMonth() + ".xlsx");
+//        FileUtils.copyInputStreamToFile(file.getInputStream(), fileNew);
+//        Path path = fileNew.toPath();
+//        List<Map<String, String>> list = readFile(path);
+//        List<Map<String, String>> distinctList = dataProcessing(path, list, dto);
+//        Path csvPath = toCsv(path, distinctList);
+//        copyCsv(csvPath);
+//        procedure(dto);
+//    }
+//
+//    /**
+//     * 读取文件
+//     *
+//     * @param path 文件路径
+//     */
+//    public List<Map<String, String>> readFile(Path path) throws IOException {
+//        log.info("读取: {}", path);
+//        List<String> rawHeaders = Stream.of("账期", "车牌号", "一级单位", "二级单位", "三级单位", "车架号", "违章时间",
+//                "违章地点", "违章详情", "扣分", "罚款", "三方处理状态", "处理时间", "违章未处理时长(天)").toList();
+//        List<String> headers = Stream.of("year_month", "che_pai_hao", "raw_yi_ji", "raw_er_ji", "raw_san_ji",
+//                "che_jia_hao", "wei_zhang_shi_jian", "wei_zhang_di_dian", "wei_zhang_xiang_qing", "kou_fen", "fa_kuan",
+//                "chu_li_zhuang_tai", "chu_li_shi_jian", "wei_zhang_wei_chu_li_shi_chang").toList();
+//        try (InputStream inputStream = Files.newInputStream(path);
+//             Workbook workbook = new XSSFWorkbook(inputStream)
+//        ) {
+//            List<Map<String, String>> resultList = new ArrayList<>();
+//            // 读取第一个工作表
+//            Sheet sheet = workbook.getSheetAt(0);
+//            // 表头行
+//            Row headerRow = sheet.getRow(0);
+//            // 列数
+//            int columnCount = headerRow.getPhysicalNumberOfCells();
+//            log.info("columnCount: {}", columnCount);
+//            // 检查表头
+//            if (headers.size() != columnCount) {
+//                throw new BizException("列数错误");
+//            }
+//            for (int i = 0; i < columnCount; i++) {
+//                Cell cell = headerRow.getCell(i);
+//                if (cell == null || !rawHeaders.get(i).equals(cell.getStringCellValue())) {
+//                    throw new BizException("表头错误");
+//                }
+//            }
+//            // 最后行数
+//            int lastRowNum = sheet.getLastRowNum();
+//            log.info("lastRowNum: {}", lastRowNum);
+//            if (lastRowNum == 0) {
+//                throw new BizException("文件为空");
+//            }
+//            // 遍历行
+//            for (int i = 1; i <= lastRowNum; i++) {
+//                Row row = sheet.getRow(i);
+//                if (row == null) {
+//                    continue;
+//                }
+//                Map<String, String> rowMap = new LinkedHashMap<>();
+//                // 遍历列
+//                for (int j = 0; j < columnCount; j++) {
+//                    String header = headers.get(j);
+//                    String cellValue = "";
+//                    rowMap.put(header, cellValue);
+//                    Cell cell = row.getCell(j);
+//                    if (cell == null) {
+//                        continue;
+//                    }
+//                    switch (cell.getCellType()) {
+//                        case STRING:
+//                            boolean skipTrim = "wei_zhang_shi_jian".equals(header) || "chu_li_shi_jian".equals(header);
+//                            // 删除字符串空白字符
+//                            cellValue = skipTrim ? cell.getStringCellValue()
+//                                    : StringUtils.trimAllWhitespace(cell.getStringCellValue());
+//                            break;
+//                        case NUMERIC:
+//                            if (DateUtil.isCellDateFormatted(cell)) {
+//                                cellValue = DateUtil.getLocalDateTime(cell.getNumericCellValue())
+//                                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+//                                break;
+//                            }
+//                            cellValue = String.valueOf(cell.getNumericCellValue());
+//                            break;
+//                        case BOOLEAN:
+//                            cellValue = String.valueOf(cell.getBooleanCellValue());
+//                            break;
+//                        default:
+//                            break;
+//                    }
+//                    rowMap.put(header, cellValue);
+//                }
+//                resultList.add(rowMap);
+//            }
+//            return resultList;
+//        }
+//    }
+//
+//    /**
+//     * 数据加工
+//     *
+//     * @param path 文件路径
+//     * @param list 数据
+//     * @param dto 请求参数
+//     */
+//    public List<Map<String, String>> dataProcessing(Path path, List<Map<String, String>> list, CarDataImportDto dto) {
+//        String yearMonth = dto.getYearMonth().toString();
+//        LocalDate localDate = LocalDate.parse(yearMonth + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
+//        String year = String.valueOf(localDate.getYear());
+//        String month = String.valueOf(localDate.getMonthValue());
+//        List<OrganizationPo> secondOrgs = organizationService.getSecondOrgs();
+//        List<OrganizationPo> thirdOrgs = organizationService.getThirdOrgs();
+//        Map<String, OrganizationPo> orgMap = organizationService.getOrgMap(secondOrgs, thirdOrgs);
+//        Map<String, List<OrganizationPo>> thirdOrganizationListMap =
+//                organizationService.getThirdOrganizationListMap(secondOrgs, thirdOrgs);
+//        List<AreaPo> cities = areaService.getCities();
+//        List<AreaPo> districts = areaService.getDistricts();
+//        Map<String, AreaPo> areaMap = areaService.getAreaMap(cities, districts);
+//        Map<String, List<AreaPo>> districtListMap = areaService.getDistrictListMap(cities, districts);
+//        for (Map<String, String> map : list) {
+//            map.put("year_month", yearMonth);
+//            map.put("year_no", year);
+//            map.put("month_no", month);
+//            String rawChePaiHao = map.get("che_pai_hao");
+//            map.put("raw_che_pai_hao", rawChePaiHao);
+//            String chePaiHao = carService.getChePai(rawChePaiHao);
+//            map.put("che_pai_hao", chePaiHao);
+//            String chePaiFail = carService.chePaiFail(rawChePaiHao);
+//            map.put("che_pai_fail", chePaiFail);
+//            String yj = map.get("raw_yi_ji");
+//            String ej = map.get("raw_er_ji");
+//            String sj = map.get("raw_san_ji");
+//            String firstUnit = carService.getFirstUnit(yj);
+//            map.put("first_unit", firstUnit);
+//            String secondUnit = carService.getSecondUnit(ej, firstUnit);
+//            map.put("second_unit", secondUnit);
+//            String thirdUnit = carService.getThirdUnit(sj, secondUnit);
+//            map.put("third_unit", thirdUnit);
+//            String areaNo = carService.getAreaNo(secondOrgs, yj);
+//            map.put("area_no", areaNo);
+//            String areaName = carService.getOrgName(orgMap, areaNo);
+//            map.put("area_name", areaName);
+//            String cityNo = carService.getCityNo(thirdOrganizationListMap, areaNo, areaName, ej);
+//            map.put("city_no", cityNo);
+//            String cityName = carService.getOrgName(orgMap, cityNo);
+//            map.put("city_name", cityName);
+//            String areaNo2 = carService.getAreaNo2(areaName, cityName);
+//            map.put("area_no2", areaNo2);
+//            String areaName2 = carService.getOrgName(orgMap, areaNo2);
+//            map.put("area_name2", areaName2);
+//            String cityId = carService.getCityId(cities, yj);
+//            map.put("city_id", cityId);
+//            String city = carService.getAreaName(areaMap, cityId);
+//            map.put("city", city);
+//            String districtId = carService.getDistrictId(districtListMap, cityId, cityName, ej);
+//            map.put("district_id", districtId);
+//            String district = carService.getAreaName(areaMap, districtId);
+//            map.put("district", district);
+//            String weiZhangShiJian = map.get("wei_zhang_shi_jian");
+//            LocalDateTime weiZhangShiJianLocalDateTime = LocalDateTime.parse(weiZhangShiJian,
+//                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+//            String weiZhangNianYue = weiZhangShiJianLocalDateTime.format(DateTimeFormatter.ofPattern("yyyyMM"));
+//            map.put("wei_zhang_nian_yue", weiZhangNianYue);
+//            String chuLiShiJian = map.get("chu_li_shi_jian");
+//            String chuLiNianYue = "";
+//            if (StringUtils.hasText(chuLiShiJian)) {
+//                LocalDateTime chuLiShiJianLocalDateTime = LocalDateTime.parse(chuLiShiJian,
+//                        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+//                chuLiNianYue = chuLiShiJianLocalDateTime.format(DateTimeFormatter.ofPattern("yyyyMM"));
+//            }
+//            map.put("chu_li_nian_yue", chuLiNianYue);
+//            map.put("source", path.getFileName().toString());
+//            String kouFen = map.get("kou_fen");
+//            if (StringUtils.hasText(kouFen)) {
+//                map.put("kou_fen", String.valueOf(new BigDecimal(kouFen).intValue()));
+//            }
+//            String weiZhangWeiChuLiShiChang = map.get("wei_zhang_wei_chu_li_shi_chang");
+//            if (StringUtils.hasText(weiZhangWeiChuLiShiChang)) {
+//                map.put("wei_zhang_wei_chu_li_shi_chang",
+//                        String.valueOf(new BigDecimal(weiZhangWeiChuLiShiChang).intValue()));
+//            }
+//        }
+//        return list;
+//    }
+//
+//    /**
+//     * 生成csv
+//     *
+//     * @param path 源文件路径
+//     * @param list 数据
+//     */
+//    public Path toCsv(Path path, List<Map<String, String>> list) throws IOException {
+//        log.info("条数:{}", list.size());
+//        Path csvPath = Paths.get(path + ".csv");
+//        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
+//                StandardCharsets.UTF_8);
+//             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
+//            // 添加bom头避免excel乱码
+//            osw.write('\ufeff');
+//            Map<String, String> header = list.get(0);
+//            // 表头
+//            printer.printRecord(header.keySet());
+//            for (Map<String, String> map : list) {
+//                printer.printRecord(map.values());
+//            }
+//        }
+//        return csvPath;
+//    }
+//
+//    /**
+//     * 导入数据库
+//     *
+//     * @param path 文件路径
+//     */
+//    public void copyCsv(Path path) {
+//        String dbTable = "car.car_wei_zhang";
+//        String csv = path.toString();
+//        String columns = "(year_month,che_pai_hao,raw_yi_ji,raw_er_ji,raw_san_ji,che_jia_hao,wei_zhang_shi_jian,wei_zhang_di_dian,wei_zhang_xiang_qing,kou_fen,fa_kuan,chu_li_zhuang_tai,chu_li_shi_jian,wei_zhang_wei_chu_li_shi_chang,year_no,month_no,raw_che_pai_hao,che_pai_fail,first_unit,second_unit,third_unit,area_no,area_name,city_no,city_name,area_no2,area_name2,city_id,city,district_id,district,wei_zhang_nian_yue,chu_li_nian_yue,source)";
+//        Long timeout = 60000L;
+//        PsqlUtil.copyCsv(carDataImportConfig.getCopyScriptPath(), carDataImportConfig.getDbHost(),
+//                carDataImportConfig.getDbPort(), carDataImportConfig.getDbUsername(), carDataImportConfig.getDbPassword(),
+//                carDataImportConfig.getDbName(), dbTable, csv, columns, timeout, null);
+//    }
+//
+//    /**
+//     * 更新数据库
+//     */
+//    public void procedure(CarDataImportDto dto) {
+//        int update1 = carWeiZhangDao.insertCarWeiZhangChangQi(dto.getYearMonth());
+//        log.info("insert car.car_wei_zhang_chang_qi: {}", update1);
+//        int update2 = gdcCarWeiZhangDao.insertWeiZhang(dto.getYearMonth());
+//        log.info("insert car_theme.wz_f_violation_details: {}", update2);
+//        if (update2 == 0) {
+//            throw new MyRuntimeException("插入car_theme.wz_f_violation_details失败");
+//        }
+//    }
+//}

+ 263 - 262
src/test/java/com/nokia/financeapi/shouqi/CarZuLinTests.java

@@ -1,262 +1,263 @@
-package com.nokia.financeapi.shouqi;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.nokia.financeapi.common.exception.MyRuntimeException;
-import com.nokia.financeapi.service.car.CarService;
-import com.nokia.financeapi.service.common.AreaService;
-import com.nokia.financeapi.service.common.OrganizationService;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.csv.CSVFormat;
-import org.apache.commons.csv.CSVPrinter;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CellValue;
-import org.apache.poi.ss.usermodel.DateUtil;
-import org.apache.poi.ss.usermodel.FormulaEvaluator;
-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.xssf.usermodel.XSSFWorkbook;
-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;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-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.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.stream.Stream;
-
-/**
- * 首汽车辆租赁费加工测试
- */
-@Slf4j
-@SpringBootTest
-@ActiveProfiles("prod")
-class CarZuLinTests {
-    @Autowired
-    CarService carService;
-    @Autowired
-    OrganizationService organizationService;
-    @Autowired
-    AreaService areaService;
-
-    @Test
-    void runJobTest() {
-        runJob();
-    }
-
-    /**
-     * 执行任务
-     */
-    public void runJob() {
-        // 数据目录
-        Path dir = Paths.get("test/data/");
-        try (Stream<Path> stream = Files.list(dir)) {
-            // 获取数据目录下的文件列表
-            List<Path> pathList = stream.filter(t -> t.toString().endsWith(".xlsx")).sorted().toList();
-            log.info("数据文件列表: {}", pathList);
-            if (CollectionUtils.isEmpty(pathList)) {
-                throw new MyRuntimeException("没有文件");
-            }
-            for (Path path : pathList) {
-                singleJob(path);
-            }
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-        }
-    }
-
-    /**
-     * 处理单个文件
-     *
-     * @param path 文件路径
-     */
-    public void singleJob(Path path) throws Exception {
-        List<LinkedHashMap<String, String>> list = readFile(path);
-        List<LinkedHashMap<String, String>> distinctList = dataProcessing(path, list);
-        Path csvPath = toCsv(path, distinctList);
-    }
-
-    /**
-     * 读取文件
-     *
-     * @param path 文件路径
-     */
-    public List<LinkedHashMap<String, String>> readFile(Path path) throws Exception {
-        log.info("读取: {}", path);
-        List<String> headers = Stream.of("year_month", "che_pai_hao_he_tong", "che_xing", "che_liang_suo_shu_dan_wei",
-                "he_tong_ming_cheng", "he_tong_bian_hao", "jia_shui_he_ji_jin_e", "bu_han_shui_jin_e", "shui_e",
-                "zu_qi", "che_pai_hao_ti_huan", "ti_huan_nian_yue", "bei_zhu").toList();
-        try (InputStream inputStream = Files.newInputStream(path);
-             Workbook workbook = new XSSFWorkbook(inputStream)
-        ) {
-            FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
-            List<LinkedHashMap<String, String>> resultList = new ArrayList<>();
-            // 读取第一个工作表
-            Sheet sheet = workbook.getSheetAt(0);
-            // 表头行
-            Row headerRow = sheet.getRow(0);
-            // 列数
-            int columnCount = headerRow.getPhysicalNumberOfCells();
-            log.info("columnCount: {}", columnCount);
-            // 最后行数
-            int lastRowNum = sheet.getLastRowNum();
-            log.info("lastRowNum: {}", lastRowNum);
-            if (lastRowNum == 0) {
-                throw new MyRuntimeException(path.getFileName() + " 为空");
-            }
-            // 遍历行
-            for (int i = 1; i <= lastRowNum; i++) {
-                Row row = sheet.getRow(i);
-                if (row == null) {
-                    continue;
-                }
-                LinkedHashMap<String, String> rowMap = new LinkedHashMap<>();
-                // 遍历列
-                for (int j = 0; j < columnCount; j++) {
-                    String value = "";
-                    rowMap.put(headers.get(j), value);
-                    Cell cell = row.getCell(j);
-                    if (cell == null) {
-                        continue;
-                    }
-                    switch (cell.getCellType()) {
-                        case STRING:
-                            // 删除字符串空白字符
-                            value = StringUtils.trimAllWhitespace(cell.getStringCellValue());
-                            break;
-                        case NUMERIC:
-                            if (DateUtil.isCellDateFormatted(cell)) {
-                                value = DateUtil.getLocalDateTime(cell.getNumericCellValue())
-                                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-                                break;
-                            }
-                            value = String.valueOf(cell.getNumericCellValue());
-                            break;
-                        case BOOLEAN:
-                            value = String.valueOf(cell.getBooleanCellValue());
-                            break;
-                        case FORMULA:
-                            CellValue cellValue = evaluator.evaluate(cell);
-                            switch (cellValue.getCellType()){
-                                case STRING:
-                                    value = StringUtils.trimAllWhitespace(cellValue.getStringValue());
-                                    break;
-                                case NUMERIC:
-                                    value = String.valueOf(cellValue.getNumberValue());
-                                    break;
-                                default:
-                                    break;
-                            }
-                        default:
-                            break;
-                    }
-                    rowMap.put(headers.get(j), value);
-                }
-                resultList.add(rowMap);
-            }
-            return resultList;
-        }
-    }
-
-    /**
-     * 数据加工
-     *
-     * @param path 文件路径
-     * @param list 数据
-     */
-    public List<LinkedHashMap<String, String>> dataProcessing(Path path, List<LinkedHashMap<String, String>> list) {
-        ObjectMapper objectMapper = new ObjectMapper();
-        List<LinkedHashMap<String, String>> resultList = new ArrayList<>();
-        for (LinkedHashMap<String, String> map : list) {
-            String yearMonth = map.get("year_month");
-            Integer yearMonthInteger = Double.valueOf(yearMonth).intValue();
-            LocalDate localDate = LocalDate.parse(  Double.valueOf(yearMonth).intValue() + "01",
-                    DateTimeFormatter.ofPattern("yyyyMMdd"));
-            String rawChePaiHaoHeTong = map.get("che_pai_hao_he_tong");
-            map.put("raw_che_pai_hao_he_tong", rawChePaiHaoHeTong);
-            String chePaiHaoHeTong = carService.getChePai(rawChePaiHaoHeTong);
-            map.put("che_pai_hao_he_tong", chePaiHaoHeTong);
-            String chePaiHeTongFail = carService.chePaiFail(rawChePaiHaoHeTong);
-            map.put("che_pai_he_tong_fail", chePaiHeTongFail);
-            String rawChePaiHaoTiHuan = map.get("che_pai_hao_ti_huan");
-            map.put("raw_che_pai_hao_ti_huan", rawChePaiHaoTiHuan);
-            String chePaiHaoTiHuan = carService.getChePai(rawChePaiHaoTiHuan);
-            map.put("che_pai_hao_ti_huan", chePaiHaoTiHuan);
-            String chePaiTiHuanFail = carService.chePaiFail(rawChePaiHaoTiHuan);
-            map.put("che_pai_ti_huan_fail", chePaiTiHuanFail);
-            String cheLiangSuoShuDanWei = map.get("che_liang_suo_shu_dan_wei");
-            String firstUnit = carService.getFirstUnit(cheLiangSuoShuDanWei);
-            map.put("first_unit", firstUnit);
-            String zuQi = map.get("zu_qi");
-            int zuQiInt = Double.valueOf(zuQi).intValue();
-            String tiHuanNianYue = map.get("ti_huan_nian_yue");
-            Integer tiHuanNianYueInteger = StringUtils.hasText(tiHuanNianYue)
-                    ? Double.valueOf(tiHuanNianYue).intValue() : null;
-            map.put("che_pai_hao", tiHuanNianYueInteger != null
-                    && yearMonthInteger.compareTo(tiHuanNianYueInteger) >= 0 ? chePaiHaoTiHuan : chePaiHaoHeTong);
-            if (StringUtils.hasText(chePaiHaoTiHuan)) {
-                log.info("{} -> {} -> {} -> {}", chePaiHaoHeTong, yearMonthInteger, tiHuanNianYueInteger,
-                        tiHuanNianYueInteger != null && yearMonthInteger.compareTo(tiHuanNianYueInteger) >= 0);
-            }
-            map.put("source", path.getFileName().toString());
-            map.put("year_no", localDate.format(DateTimeFormatter.ofPattern("yyyy")));
-            map.put("month_no", localDate.format(DateTimeFormatter.ofPattern("MM")));
-            resultList.add(map);
-            for (int i = 1; i < zuQiInt; i++) {
-                try {
-                    LinkedHashMap<String, String> t = objectMapper.readValue(objectMapper.writeValueAsString(map),
-                            TypeFactory.defaultInstance().constructMapType(LinkedHashMap.class, String.class, String.class));
-                    localDate = localDate.plusMonths(1);
-                    Integer nextMonthInteger = Integer.valueOf(localDate.format(DateTimeFormatter.ofPattern("yyyyMM")));
-                    t.put("year_month", nextMonthInteger.toString());
-                    t.put("year_no", localDate.format(DateTimeFormatter.ofPattern("yyyy")));
-                    t.put("month_no", localDate.format(DateTimeFormatter.ofPattern("MM")));
-                    t.put("che_pai_hao", tiHuanNianYueInteger != null
-                            && nextMonthInteger.compareTo(tiHuanNianYueInteger) >= 0 ? chePaiHaoTiHuan : chePaiHaoHeTong);
-                    resultList.add(t);
-                } catch (Exception e) {
-                    log.error(e.toString(), e);
-                }
-            }
-        }
-        // 去重
-        return resultList;
-    }
-
-    /**
-     * 生成csv
-     *
-     * @param path 源文件路径
-     * @param list 数据
-     */
-    public Path toCsv(Path path, List<LinkedHashMap<String, String>> list) throws Exception {
-        log.info("去重后条数:{}", list.size());
-        Files.createDirectories(Paths.get("test/history/"));
-        Path csvPath = Paths.get("test/history/" + path.getFileName() + ".csv");
-        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
-                StandardCharsets.UTF_8);
-             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
-            // 添加bom头避免excel乱码
-            osw.write('\ufeff');
-            LinkedHashMap<String, String> header = list.get(0);
-            // 表头
-            printer.printRecord(header.keySet());
-            for (LinkedHashMap<String, String> map : list) {
-                printer.printRecord(map.values());
-            }
-        }
-        return csvPath;
-    }
-}
+//package com.nokia.financeapi.shouqi;
+//
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.fasterxml.jackson.databind.type.TypeFactory;
+//import com.nokia.financeapi.common.exception.MyRuntimeException;
+//import com.nokia.financeapi.service.car.CarService;
+//import com.nokia.financeapi.service.common.AreaService;
+//import com.nokia.financeapi.service.common.OrganizationService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.csv.CSVFormat;
+//import org.apache.commons.csv.CSVPrinter;
+//import org.apache.poi.ss.usermodel.Cell;
+//import org.apache.poi.ss.usermodel.CellValue;
+//import org.apache.poi.ss.usermodel.DateUtil;
+//import org.apache.poi.ss.usermodel.FormulaEvaluator;
+//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.xssf.usermodel.XSSFWorkbook;
+//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;
+//import org.springframework.util.CollectionUtils;
+//import org.springframework.util.StringUtils;
+//
+//import java.io.InputStream;
+//import java.io.OutputStreamWriter;
+//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.format.DateTimeFormatter;
+//import java.util.ArrayList;
+//import java.util.LinkedHashMap;
+//import java.util.List;
+//import java.util.stream.Stream;
+//
+///**
+// * 首汽车辆租赁费加工测试
+// */
+//@Slf4j
+//@SpringBootTest
+//@ActiveProfiles("prod")
+//class CarZuLinTests {
+//    @Autowired
+//    CarService carService;
+//    @Autowired
+//    OrganizationService organizationService;
+//    @Autowired
+//    AreaService areaService;
+//
+//    @Test
+//    void runJobTest() {
+//        runJob();
+//    }
+//
+//    /**
+//     * 执行任务
+//     */
+//    public void runJob() {
+//        // 数据目录
+//        Path dir = Paths.get("test/data/");
+//        try (Stream<Path> stream = Files.list(dir)) {
+//            // 获取数据目录下的文件列表
+//            List<Path> pathList = stream.filter(t -> t.toString().endsWith(".xlsx")).sorted().toList();
+//            log.info("数据文件列表: {}", pathList);
+//            if (CollectionUtils.isEmpty(pathList)) {
+//                throw new MyRuntimeException("没有文件");
+//            }
+//            for (Path path : pathList) {
+//                singleJob(path);
+//            }
+//        } catch (Exception e) {
+//            log.error(e.getMessage(), e);
+//        }
+//    }
+//
+//    /**
+//     * 处理单个文件
+//     *
+//     * @param path 文件路径
+//     */
+//    public void singleJob(Path path) throws Exception {
+//        List<LinkedHashMap<String, String>> list = readFile(path);
+//        List<LinkedHashMap<String, String>> distinctList = dataProcessing(path, list);
+//        Path csvPath = toCsv(path, distinctList);
+//    }
+//
+//    /**
+//     * 读取文件
+//     *
+//     * @param path 文件路径
+//     */
+//    public List<LinkedHashMap<String, String>> readFile(Path path) throws Exception {
+//        log.info("读取: {}", path);
+//        List<String> headers = Stream.of("year_month", "che_pai_hao_he_tong", "che_xing", "che_liang_suo_shu_dan_wei",
+//                "he_tong_ming_cheng", "he_tong_bian_hao", "jia_shui_he_ji_jin_e", "bu_han_shui_jin_e", "shui_e",
+//                "zu_qi", "che_pai_hao_ti_huan", "ti_huan_nian_yue", "bei_zhu").toList();
+//        try (InputStream inputStream = Files.newInputStream(path);
+//             Workbook workbook = new XSSFWorkbook(inputStream)
+//        ) {
+//            FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
+//            List<LinkedHashMap<String, String>> resultList = new ArrayList<>();
+//            // 读取第一个工作表
+//            Sheet sheet = workbook.getSheetAt(0);
+//            // 表头行
+//            Row headerRow = sheet.getRow(0);
+//            // 列数
+//            int columnCount = headerRow.getPhysicalNumberOfCells();
+//            log.info("columnCount: {}", columnCount);
+//            // 最后行数
+//            int lastRowNum = sheet.getLastRowNum();
+//            log.info("lastRowNum: {}", lastRowNum);
+//            if (lastRowNum == 0) {
+//                throw new MyRuntimeException(path.getFileName() + " 为空");
+//            }
+//            // 遍历行
+//            for (int i = 1; i <= lastRowNum; i++) {
+//                Row row = sheet.getRow(i);
+//                if (row == null) {
+//                    continue;
+//                }
+//                LinkedHashMap<String, String> rowMap = new LinkedHashMap<>();
+//                // 遍历列
+//                for (int j = 0; j < columnCount; j++) {
+//                    String value = "";
+//                    rowMap.put(headers.get(j), value);
+//                    Cell cell = row.getCell(j);
+//                    if (cell == null) {
+//                        continue;
+//                    }
+//                    switch (cell.getCellType()) {
+//                        case STRING:
+//                            // 删除字符串空白字符
+//                            value = StringUtils.trimAllWhitespace(cell.getStringCellValue());
+//                            break;
+//                        case NUMERIC:
+//                            if (DateUtil.isCellDateFormatted(cell)) {
+//                                value = DateUtil.getLocalDateTime(cell.getNumericCellValue())
+//                                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+//                                break;
+//                            }
+//                            value = String.valueOf(cell.getNumericCellValue());
+//                            break;
+//                        case BOOLEAN:
+//                            value = String.valueOf(cell.getBooleanCellValue());
+//                            break;
+//                        case FORMULA:
+//                            CellValue cellValue = evaluator.evaluate(cell);
+//                            switch (cellValue.getCellType()){
+//                                case STRING:
+//                                    value = StringUtils.trimAllWhitespace(cellValue.getStringValue());
+//                                    break;
+//                                case NUMERIC:
+//                                    value = String.valueOf(cellValue.getNumberValue());
+//                                    break;
+//                                default:
+//                                    break;
+//                            }
+//                            break;
+//                        default:
+//                            break;
+//                    }
+//                    rowMap.put(headers.get(j), value);
+//                }
+//                resultList.add(rowMap);
+//            }
+//            return resultList;
+//        }
+//    }
+//
+//    /**
+//     * 数据加工
+//     *
+//     * @param path 文件路径
+//     * @param list 数据
+//     */
+//    public List<LinkedHashMap<String, String>> dataProcessing(Path path, List<LinkedHashMap<String, String>> list) {
+//        ObjectMapper objectMapper = new ObjectMapper();
+//        List<LinkedHashMap<String, String>> resultList = new ArrayList<>();
+//        for (LinkedHashMap<String, String> map : list) {
+//            String yearMonth = map.get("year_month");
+//            Integer yearMonthInteger = Double.valueOf(yearMonth).intValue();
+//            LocalDate localDate = LocalDate.parse(  Double.valueOf(yearMonth).intValue() + "01",
+//                    DateTimeFormatter.ofPattern("yyyyMMdd"));
+//            String rawChePaiHaoHeTong = map.get("che_pai_hao_he_tong");
+//            map.put("raw_che_pai_hao_he_tong", rawChePaiHaoHeTong);
+//            String chePaiHaoHeTong = carService.getChePai(rawChePaiHaoHeTong);
+//            map.put("che_pai_hao_he_tong", chePaiHaoHeTong);
+//            String chePaiHeTongFail = carService.chePaiFail(rawChePaiHaoHeTong);
+//            map.put("che_pai_he_tong_fail", chePaiHeTongFail);
+//            String rawChePaiHaoTiHuan = map.get("che_pai_hao_ti_huan");
+//            map.put("raw_che_pai_hao_ti_huan", rawChePaiHaoTiHuan);
+//            String chePaiHaoTiHuan = carService.getChePai(rawChePaiHaoTiHuan);
+//            map.put("che_pai_hao_ti_huan", chePaiHaoTiHuan);
+//            String chePaiTiHuanFail = carService.chePaiFail(rawChePaiHaoTiHuan);
+//            map.put("che_pai_ti_huan_fail", chePaiTiHuanFail);
+//            String cheLiangSuoShuDanWei = map.get("che_liang_suo_shu_dan_wei");
+//            String firstUnit = carService.getFirstUnit(cheLiangSuoShuDanWei);
+//            map.put("first_unit", firstUnit);
+//            String zuQi = map.get("zu_qi");
+//            int zuQiInt = Double.valueOf(zuQi).intValue();
+//            String tiHuanNianYue = map.get("ti_huan_nian_yue");
+//            Integer tiHuanNianYueInteger = StringUtils.hasText(tiHuanNianYue)
+//                    ? Double.valueOf(tiHuanNianYue).intValue() : null;
+//            map.put("che_pai_hao", tiHuanNianYueInteger != null
+//                    && yearMonthInteger.compareTo(tiHuanNianYueInteger) >= 0 ? chePaiHaoTiHuan : chePaiHaoHeTong);
+//            if (StringUtils.hasText(chePaiHaoTiHuan)) {
+//                log.info("{} -> {} -> {} -> {}", chePaiHaoHeTong, yearMonthInteger, tiHuanNianYueInteger,
+//                        tiHuanNianYueInteger != null && yearMonthInteger.compareTo(tiHuanNianYueInteger) >= 0);
+//            }
+//            map.put("source", path.getFileName().toString());
+//            map.put("year_no", localDate.format(DateTimeFormatter.ofPattern("yyyy")));
+//            map.put("month_no", localDate.format(DateTimeFormatter.ofPattern("MM")));
+//            resultList.add(map);
+//            for (int i = 1; i < zuQiInt; i++) {
+//                try {
+//                    LinkedHashMap<String, String> t = objectMapper.readValue(objectMapper.writeValueAsString(map),
+//                            TypeFactory.defaultInstance().constructMapType(LinkedHashMap.class, String.class, String.class));
+//                    localDate = localDate.plusMonths(1);
+//                    Integer nextMonthInteger = Integer.valueOf(localDate.format(DateTimeFormatter.ofPattern("yyyyMM")));
+//                    t.put("year_month", nextMonthInteger.toString());
+//                    t.put("year_no", localDate.format(DateTimeFormatter.ofPattern("yyyy")));
+//                    t.put("month_no", localDate.format(DateTimeFormatter.ofPattern("MM")));
+//                    t.put("che_pai_hao", tiHuanNianYueInteger != null
+//                            && nextMonthInteger.compareTo(tiHuanNianYueInteger) >= 0 ? chePaiHaoTiHuan : chePaiHaoHeTong);
+//                    resultList.add(t);
+//                } catch (Exception e) {
+//                    log.error(e.toString(), e);
+//                }
+//            }
+//        }
+//        // 去重
+//        return resultList;
+//    }
+//
+//    /**
+//     * 生成csv
+//     *
+//     * @param path 源文件路径
+//     * @param list 数据
+//     */
+//    public Path toCsv(Path path, List<LinkedHashMap<String, String>> list) throws Exception {
+//        log.info("去重后条数:{}", list.size());
+//        Files.createDirectories(Paths.get("test/history/"));
+//        Path csvPath = Paths.get("test/history/" + path.getFileName() + ".csv");
+//        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(csvPath),
+//                StandardCharsets.UTF_8);
+//             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT)) {
+//            // 添加bom头避免excel乱码
+//            osw.write('\ufeff');
+//            LinkedHashMap<String, String> header = list.get(0);
+//            // 表头
+//            printer.printRecord(header.keySet());
+//            for (LinkedHashMap<String, String> map : list) {
+//                printer.printRecord(map.values());
+//            }
+//        }
+//        return csvPath;
+//    }
+//}