wangliang 1 周之前
父节点
当前提交
c525c9c55f

+ 36 - 1
src/main/java/com/qmth/cet/plug/api/CetPlugController.java

@@ -4,6 +4,7 @@ package com.qmth.cet.plug.api;
 import com.qmth.boot.api.annotation.Aac;
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.cet.plug.contant.SystemConstant;
+import com.qmth.cet.plug.service.LogicService;
 import com.qmth.cet.plug.util.Result;
 import com.qmth.cet.plug.util.ResultUtil;
 import io.swagger.annotations.Api;
@@ -12,13 +13,18 @@ import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.annotation.Resource;
 import java.io.IOException;
 import java.util.Objects;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 /**
  * <p>
@@ -35,12 +41,41 @@ import java.util.Objects;
 public class CetPlugController {
     private final static Logger log = LoggerFactory.getLogger(CetPlugController.class);
 
+    @Value("${com.qmth.cet4.dir}")
+    String cet4Dir;
+
+    @Value("${com.qmth.cet6.dir}")
+    String cet6Dir;
+
+    @Resource
+    LogicService logicService;
+
     @ApiOperation(value = "测试")
     @RequestMapping(value = "/test", method = RequestMethod.GET)
     @ApiResponses({@ApiResponse(code = 200, message = "返回数据", response = Objects.class)})
     @Aac(auth = false)
-    public Result test() throws IOException {
+    public Result test() throws IOException, InterruptedException {
         log.info("test is come in");
+        String projectPath = System.getProperty("user.dir");
+        int cpuNum = Runtime.getRuntime().availableProcessors();
+        ExecutorService executor = Executors.newFixedThreadPool(Math.abs(cpuNum / 2));
+        if (Objects.nonNull(cet4Dir)) {
+            logicService.execFile(cet4Dir, projectPath, "cet4");
+//            executor.submit(() -> {
+//                try {
+//                    SystemConstant.execFile(cet4Dir, projectPath, "cet4");
+//                } catch (IOException e) {
+//                    e.printStackTrace();
+//                }
+//            });
+        }
+        executor.shutdown();
+        while (!executor.awaitTermination(1, TimeUnit.MINUTES)) {
+            log.info("线程池没有关闭");
+        }
+        log.info("线程池已经关闭");
         return ResultUtil.ok();
     }
+
+
 }

+ 32 - 6
src/main/java/com/qmth/cet/plug/contant/SystemConstant.java

@@ -1,6 +1,12 @@
 package com.qmth.cet.plug.contant;
 
 import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.List;
+import java.util.Objects;
 
 /**
  * @Description: 系统常量
@@ -10,6 +16,7 @@ import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
  * @Date: 2019/10/11
  */
 public class SystemConstant {
+    private final static Logger log = LoggerFactory.getLogger(SystemConstant.class);
 
     /**
      * 系统常量
@@ -18,12 +25,8 @@ public class SystemConstant {
     public static final String PREFIX_URL_CET_PLUG = "/cet/plug";
     public static final String UPDATE_TIME = "updateTime";
     public static final String SUCCESS = "success";
-
-//    public static final String HEADER_AUTHORIZATION = "Authorization";
-//    public static final String HEADER_TIME = "time";
-//    public static final String HEADER_PLATFORM = "platform";
-//    public static final String HEADER_DEVICE_ID = "deviceId";
-//    public static final String MD5 = "MD5";
+    public static final int MAX_QUERY_SIZE = 10;
+    public static final int LOCK_TIME_OUT = 1800000;
 
     /**
      * 获取nanoId
@@ -33,4 +36,27 @@ public class SystemConstant {
     public static String getNanoId() {
         return NanoIdUtils.randomNanoId();
     }
+
+    /**
+     * 解压目录
+     *
+     * @param mkdir
+     * @param mkdirFileList
+     * @return
+     */
+    public static List<File> analyzeDir(File mkdir, List<File> mkdirFileList) {
+        if (!mkdir.exists() || !mkdir.isDirectory()) {
+            return mkdirFileList;
+        }
+        File[] files = mkdir.listFiles();
+        if (Objects.nonNull(files) && files.length > 0) {
+            for (int i = 0; i < files.length; i++) {
+                if (files[i].isDirectory() && !files[i].getAbsolutePath().endsWith("temp")) {
+                    mkdirFileList.add(files[i]);
+                    analyzeDir(files[i], mkdirFileList);
+                }
+            }
+        }
+        return mkdirFileList;
+    }
 }

+ 27 - 0
src/main/java/com/qmth/cet/plug/lock/LockService.java

@@ -0,0 +1,27 @@
+package com.qmth.cet.plug.lock;
+
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Component
+public class LockService {
+
+    @Resource
+    private MemoryLock memoryLock;
+
+    /**
+     * 加锁
+     *
+     * @param key     缓存key
+     * @param value   缓存value
+     * @param timeout 缓存过期时间 单位毫秒
+     */
+    public boolean lock(String key, String value, int timeout) {
+        return memoryLock.lock(key, value, timeout);
+    }
+
+    public void unlock(String key, String value) {
+        memoryLock.unlock(key, value);
+    }
+}

+ 46 - 0
src/main/java/com/qmth/cet/plug/lock/MemoryLock.java

@@ -0,0 +1,46 @@
+package com.qmth.cet.plug.lock;
+
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 内存锁
+ *
+ * @author tianjun
+ */
+@Component
+public class MemoryLock {
+
+    private static ConcurrentHashMap<String, String> stringCache = new ConcurrentHashMap<String, String>();// 缓存
+    private static ConcurrentHashMap<String, Long> timeCache = new ConcurrentHashMap<String, Long>();
+
+    /**
+     * 加锁
+     *
+     * @param key     缓存key
+     * @param value   缓存value
+     * @param timeout 缓存过期时间 单位毫秒
+     */
+    public boolean lock(String key, String value, int timeout) {
+        if (stringCache.get(key) == null) {
+            stringCache.put(key, value);
+            timeCache.put(key, System.currentTimeMillis() + Long.valueOf(timeout + ""));
+            return true;
+        } else {
+            if (timeCache.get(key).longValue() < System.currentTimeMillis()) {
+                //锁已经过期
+                stringCache.put(key, value);
+                timeCache.put(key, System.currentTimeMillis() + Long.valueOf(timeout + ""));
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    public void unlock(String key, String value) {
+        stringCache.remove(key);
+        timeCache.remove(key);
+    }
+}

+ 22 - 0
src/main/java/com/qmth/cet/plug/service/LogicService.java

@@ -0,0 +1,22 @@
+package com.qmth.cet.plug.service;
+
+import java.io.IOException;
+
+/**
+ * @Description: logic service
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2025/6/13
+ */
+public interface LogicService {
+
+    /**
+     * 执行解析数据
+     *
+     * @param fileName
+     * @param projectPath
+     * @param rootDirName
+     */
+    void execFile(String fileName, String projectPath, String rootDirName) throws IOException, InterruptedException;
+}

+ 197 - 0
src/main/java/com/qmth/cet/plug/service/impl/LogicServiceImpl.java

@@ -0,0 +1,197 @@
+package com.qmth.cet.plug.service.impl;
+
+import com.qmth.cet.plug.contant.SystemConstant;
+import com.qmth.cet.plug.enums.ExceptionResultEnum;
+import com.qmth.cet.plug.lock.LockService;
+import com.qmth.cet.plug.service.LogicService;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * @Description: logic service impl
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2025/6/13
+ */
+@Service
+public class LogicServiceImpl implements LogicService {
+    private final static Logger log = LoggerFactory.getLogger(LogicServiceImpl.class);
+
+    @Resource
+    LockService lockService;
+
+    /**
+     * 执行解析数据
+     *
+     * @param fileName
+     * @param projectPath
+     * @param rootDirName
+     */
+    @Override
+    public void execFile(String fileName, String projectPath, String rootDirName) throws IOException, InterruptedException {
+        File mkdir = new File(fileName);
+        if (!mkdir.exists()) {
+            throw ExceptionResultEnum.ERROR.exception(rootDirName + "目录不存在");
+        }
+        if (mkdir.isDirectory()) {
+            File[] files = mkdir.listFiles();
+            if (Objects.nonNull(files) && files.length > 0) {
+                List<File> mkdirFileList = new ArrayList<>();
+                for (int i = 0; i < files.length; i++) {
+                    mkdirFileList = SystemConstant.analyzeDir(files[i], mkdirFileList);
+                }
+                log.info("mkdirFileList:{}", mkdirFileList);
+                for (File file : mkdirFileList) {
+                    String rootPath = file.getAbsolutePath();
+                    rootPath = rootDirName + rootPath.replaceAll(fileName, "");
+                    File root = new File(projectPath, rootPath);
+                    if (!root.exists()) {
+                        root.mkdirs();
+                    }
+                    log.info("root:{}", root);
+
+                    String lockKey = rootPath;
+                    for (; ; ) {
+                        boolean scanLock = lockService.lock(lockKey, lockKey, SystemConstant.LOCK_TIME_OUT);//30分钟
+                        if (scanLock) {
+                            try {
+                                this.scanTxtExecLogic(projectPath, rootPath, file);//扫描txt处理
+                            } catch (Exception e) {
+                                log.error(SystemConstant.LOG_ERROR, e);
+                            } finally {
+                                lockService.unlock(lockKey, lockKey);
+                                break;
+                            }
+                        } else {
+                            Thread.sleep(5000);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 扫描文件执行逻辑
+     *
+     * @param projectPath
+     * @param rootPath
+     * @param file
+     * @throws IOException
+     */
+    protected void scanTxtExecLogic(String projectPath, String rootPath, File file) throws IOException {
+        //扫描txt处理
+        File[] fileArray = file.listFiles();
+        List<File> fileList = new ArrayList<>(Arrays.asList(fileArray));
+        int min = 0, max = SystemConstant.MAX_QUERY_SIZE, size = fileList
+                .size();
+        if (max >= size) {
+            max = size;
+        }
+        while (max <= size) {
+            List<File> subList = fileList.subList(min, max);
+            List<String> scanList = null;
+            StringJoiner scanSj = new StringJoiner("\r\n");//全量扫描数据
+            StringJoiner scanIncrementSj = new StringJoiner("\r\n");//增量扫描数据
+            File scanTxtFile = new File(projectPath, rootPath + File.separator + "scan.txt");
+            if (!scanTxtFile.exists()) {
+                scanTxtFile.createNewFile();
+            } else {
+                ByteArrayOutputStream ou = new ByteArrayOutputStream();
+                IOUtils.copy(new FileInputStream(scanTxtFile), ou);
+                String string = new String(ou.toByteArray(), StandardCharsets.UTF_8);
+                scanSj.add(string);
+                String temp = new String(string);
+                String[] strs = StringUtils.split(temp, "\r\n");
+                scanList = new ArrayList<>(Arrays.asList(strs));
+            }
+            boolean write = false;
+            for (int y = 0; y < subList.size(); y++) {
+                String path = subList.get(y).getAbsolutePath();
+                if (!path.endsWith("temp") && (path.endsWith("jpg") || path.endsWith("JPG"))) {
+                    if (!CollectionUtils.isEmpty(scanList)) {
+                        if (!scanList.contains(path)) {
+                            scanIncrementSj.add(path);
+                            scanSj.add(path);
+                            write = true;
+                        }
+                    } else {
+                        scanSj.add(path);
+                        write = true;
+                    }
+                }
+            }
+            if (write) {
+                IOUtils.write(scanSj.toString().getBytes(StandardCharsets.UTF_8), new FileOutputStream(scanTxtFile));
+            }
+
+            //temp临时目录
+            String tempDir = file.getAbsolutePath() + File.separator + "temp" + File.separator;
+            File tempFileDir = new File(tempDir);
+            if (!tempFileDir.exists()) {
+                tempFileDir.mkdirs();
+            }
+            if (write) {
+                //生成临时scanTxt和scanResultTxt文件
+                String tempUUid = SystemConstant.getNanoId();
+                File tempScanTxt = new File(tempDir, tempUUid + ".txt");
+                tempScanTxt.createNewFile();
+                File tempScanResultTxt = new File(tempDir, tempUUid + "-result.txt");
+                tempScanResultTxt.createNewFile();
+                if (scanIncrementSj.length() > 0) {
+                    IOUtils.write(scanIncrementSj.toString().getBytes(StandardCharsets.UTF_8), new FileOutputStream(tempScanTxt));
+                } else {
+                    IOUtils.write(scanSj.toString().getBytes(StandardCharsets.UTF_8), new FileOutputStream(tempScanTxt));
+                }
+            }
+            if (max == size) {
+                break;
+            }
+            min = max;
+            max += SystemConstant.MAX_QUERY_SIZE;
+            if (max >= size) {
+                max = size;
+            }
+        }
+    }
+
+    /**
+     * 执行成功文件逻辑
+     *
+     * @param projectPath
+     * @param rootPath
+     * @param file
+     * @throws IOException
+     */
+    protected void successTxtExecLogic(String projectPath, String rootPath, File file) throws IOException {
+        File successTxtFile = new File(projectPath, rootPath + File.separator + "success.txt");
+        if (!successTxtFile.exists()) {
+            successTxtFile.createNewFile();
+        }
+    }
+
+    /**
+     * 执行错误文件逻辑
+     *
+     * @param projectPath
+     * @param rootPath
+     * @param file
+     * @throws IOException
+     */
+    protected void errorTxtExecLogic(String projectPath, String rootPath, File file) throws IOException {
+        File errorTxtFile = new File(projectPath, rootPath + File.separator + "error.txt");
+        if (!errorTxtFile.exists()) {
+            errorTxtFile.createNewFile();
+        }
+    }
+}

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

@@ -29,4 +29,8 @@ spring.jackson.time-zone=GMT+8
 
 #\u65E5\u5FD7\u914D\u7F6E
 com.qmth.logging.root-level=info
-com.qmth.logging.file-path=/Users/king/Downloads/cet-plug.log
+com.qmth.logging.file-path=/Users/king/Downloads/cet-plug.log
+
+com.qmth.client.dir=
+com.qmth.cet4.dir=/Users/king/Downloads/cet4
+com.qmth.cet6.dir=/Users/king/Downloads/cet6