|
|
@@ -22,6 +22,8 @@ import net.sourceforge.tess4j.TesseractException;
|
|
|
import org.apache.pdfbox.Loader;
|
|
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
|
|
import org.apache.pdfbox.text.PDFTextStripper;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
import space.anyi.amountVerification.model.InputModel;
|
|
|
import space.anyi.amountVerification.model.OutputErrorModel;
|
|
|
import space.anyi.amountVerification.model.OutputModel;
|
|
|
@@ -43,6 +45,7 @@ import java.util.regex.Pattern;
|
|
|
* @Description:
|
|
|
*/
|
|
|
public class App extends Application {
|
|
|
+ public static final Logger log = LoggerFactory.getLogger(App.class);
|
|
|
/**
|
|
|
* 主窗口
|
|
|
* @see Stage
|
|
|
@@ -114,6 +117,8 @@ public class App extends Application {
|
|
|
this.tesseract = new Tesseract();
|
|
|
String workDir = System.getProperty("user.dir") + "/tessdata";
|
|
|
this.tesseract.setDatapath(workDir);
|
|
|
+ log.info("tessdata路径:{}",workDir);
|
|
|
+ //this.tesseract.setDatapath("D:\\tools\\tessdata\\fast");
|
|
|
//设置识别语言为中文简体,(如果要设置为英文可改为"eng")
|
|
|
this.tesseract.setLanguage("chi_sim");
|
|
|
}
|
|
|
@@ -251,6 +256,7 @@ public class App extends Application {
|
|
|
|
|
|
File selectedFile = fileChooser.showOpenDialog(null);
|
|
|
if (selectedFile != null) {
|
|
|
+ log.info("成功选择文件:{}",selectedFile.getAbsolutePath());
|
|
|
fileField.setText(selectedFile.getAbsolutePath());
|
|
|
}
|
|
|
}
|
|
|
@@ -260,6 +266,7 @@ public class App extends Application {
|
|
|
directoryChooser.setTitle("选择文件夹");
|
|
|
File selectedFolder = directoryChooser.showDialog(null);
|
|
|
if (selectedFolder != null) {
|
|
|
+ log.info("成功选择文件夹:{}",selectedFolder.getAbsolutePath());
|
|
|
folderField.setText(selectedFolder.getAbsolutePath());
|
|
|
}
|
|
|
}
|
|
|
@@ -278,15 +285,16 @@ public class App extends Application {
|
|
|
|
|
|
private void startVerification() {
|
|
|
//如果当前时间大于2025-11-28,则关闭程序
|
|
|
- if (System.currentTimeMillis() > 1764341281000L) {
|
|
|
- new Alert(Alert.AlertType.ERROR, "软件已过期,请联系作者获取最新版本").showAndWait();
|
|
|
- Platform.exit();
|
|
|
- }
|
|
|
+ //if (System.currentTimeMillis() > 1764341281000L) {
|
|
|
+ // new Alert(Alert.AlertType.ERROR, "软件已过期,请联系作者获取最新版本").showAndWait();
|
|
|
+ // Platform.exit();
|
|
|
+ //}
|
|
|
startButton.setDisable(true);
|
|
|
String filePath = fileField.getText();
|
|
|
String folderPath = folderField.getText();
|
|
|
|
|
|
if (filePath.isEmpty() || folderPath.isEmpty()) {
|
|
|
+ log.warn("未选择文件和文件夹");
|
|
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
|
|
alert.setHeaderText("请选择文件和文件夹");
|
|
|
alert.showAndWait();
|
|
|
@@ -295,6 +303,7 @@ public class App extends Application {
|
|
|
//开启一个新的线程处理
|
|
|
Thread thread = new Thread(() -> {
|
|
|
try {
|
|
|
+ log.info("开始验证");
|
|
|
// 初始化进度条
|
|
|
progressBar.setProgress(0);
|
|
|
progressBar.setVisible(true);
|
|
|
@@ -307,16 +316,23 @@ public class App extends Application {
|
|
|
List<OutputErrorModel> errorImeiList = new ArrayList<>();
|
|
|
|
|
|
// 读取excel
|
|
|
+ log.info("开始读取Excel文件");
|
|
|
updateProgress("正在读取Excel文件...", 0.1);
|
|
|
readExcel(filePath);
|
|
|
+ log.info("读取Excel文件结束");
|
|
|
updateProgress("Excel文件读取完成,正在扫描文件夹...", 0.25);
|
|
|
//读取文件夹
|
|
|
+ log.info("开始读取文件夹");
|
|
|
readFolder(folderPath);
|
|
|
+ log.info("读取文件夹结束");
|
|
|
updateProgress("文件夹扫描完成,开始解析工单文件...", 0.5);
|
|
|
- // 解析PDF文件
|
|
|
+ // 解析工单文件
|
|
|
+ log.info("开始解析工单文件");
|
|
|
handler(errorImeiList);
|
|
|
+ log.info("解析PDF工单结束");
|
|
|
updateProgress("工单文件解析完成,正在生成输出文件...", 0.9);
|
|
|
//输出最终文件
|
|
|
+ log.info("开始输出结果文件");
|
|
|
String outputFileName = filePath.substring(0, filePath.lastIndexOf(".")) + "_" + System.currentTimeMillis() + "_output.xlsx";
|
|
|
outputFileHandler(outputFileName, errorImeiList);
|
|
|
updateProgress("验证完成!输出文件: " + outputFileName, 1.0);
|
|
|
@@ -362,21 +378,26 @@ public class App extends Application {
|
|
|
|
|
|
private void handler(List<OutputErrorModel> errorImeiList) {
|
|
|
int totalWorkOrders = inputModelList.size();
|
|
|
+ log.info("待处理对账工单数:{}",totalWorkOrders);
|
|
|
int processedWorkOrders = 0;
|
|
|
|
|
|
for (InputModel inputModel : inputModelList) {
|
|
|
OutputModel outputModel = new OutputModel(inputModel);
|
|
|
- String imei = inputModel.getImei();
|
|
|
+ String imei = inputModel.getImei().trim();
|
|
|
+ log.info("开始对账IMEI:{}",imei);
|
|
|
//找到对应工单文件的路径
|
|
|
File workOrderFile = workOrderFileMap.getOrDefault(imei, null);
|
|
|
if (Objects.isNull(workOrderFile)) {
|
|
|
+ log.warn("未找到IMEI:{}对应的工单文件",imei);
|
|
|
errorImeiList.add(new OutputErrorModel(imei));
|
|
|
processedWorkOrders++;
|
|
|
double progress = 0.5 + (0.4 * processedWorkOrders / totalWorkOrders);
|
|
|
updateProgress("解析工单文件: " + processedWorkOrders + "/" + totalWorkOrders + " (IMEI未找到: " + imei + ")", progress);
|
|
|
continue;
|
|
|
}
|
|
|
+ log.info("找到IMEI:{}对应的工单文件:{}",imei,workOrderFile.getName());
|
|
|
//解析工单文件
|
|
|
+ log.info("开始解析工单文件:{}",workOrderFile.getName());
|
|
|
String text = null;
|
|
|
if (workOrderFile.getName().endsWith(".pdf")) {
|
|
|
//pdf
|
|
|
@@ -388,26 +409,28 @@ public class App extends Application {
|
|
|
//解析pdf
|
|
|
if (Objects.isNull(text)) {
|
|
|
//没有文本
|
|
|
+ log.warn("解析IMEI:{}对应的工单文件: {} 失败",imei,workOrderFile.getName());
|
|
|
errorImeiList.add(new OutputErrorModel(imei));
|
|
|
}else{
|
|
|
Matcher matcher = pattern.matcher(text);
|
|
|
if (matcher.find()) {
|
|
|
String money = matcher.group("money"); // 获取命名分组 "money"
|
|
|
- //System.out.println("金额: " + money); // 输出: 金额
|
|
|
+ log.info("IMEI:{},匹配到金额:{}",imei,money);
|
|
|
BigDecimal amount1 = new BigDecimal(inputModel.getAmount());
|
|
|
BigDecimal amount2 = new BigDecimal(money);
|
|
|
outputModel.setPdfAmount(amount2.doubleValue());
|
|
|
outputModel.setMargin(amount1.subtract(amount2).doubleValue());
|
|
|
} else {
|
|
|
- //System.out.println("未匹配到金额");
|
|
|
+ log.warn("IMEI:{}未匹配到金额",imei);
|
|
|
errorImeiList.add(new OutputErrorModel(imei));
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ log.info("解析IMEI:{}对应的工单文件: {} 完成",imei,workOrderFile.getName());
|
|
|
outputModelList.add(outputModel);
|
|
|
|
|
|
processedWorkOrders++;
|
|
|
double progress = 0.5 + (0.4 * processedWorkOrders / totalWorkOrders);
|
|
|
+ log.info("进度:{}",progress);
|
|
|
updateProgress("解析工单文件: " + processedWorkOrders + "/" + totalWorkOrders, progress);
|
|
|
}
|
|
|
}
|
|
|
@@ -430,12 +453,11 @@ public class App extends Application {
|
|
|
bufferedImage = ImageIO.read(workOrderFile);
|
|
|
//直接处理二进制数据,避免因为文件扩展名错误导致的处理失败
|
|
|
text = tesseract.doOCR(bufferedImage);
|
|
|
-
|
|
|
- } catch (TesseractException e) {
|
|
|
- e.printStackTrace();
|
|
|
- } catch (IOException e) {
|
|
|
+ log.debug("OCR解析{}到{}",workOrderFile.getAbsolutePath(),text);
|
|
|
+ } catch (TesseractException | IOException e) {
|
|
|
+ log.warn("OCR解析{}失败,case:{}",workOrderFile.getAbsolutePath(),e.getMessage());
|
|
|
e.printStackTrace();
|
|
|
- }finally {
|
|
|
+ } finally {
|
|
|
if (!Objects.isNull(bufferedImage)) {
|
|
|
//释放资源
|
|
|
bufferedImage.flush();
|
|
|
@@ -460,7 +482,9 @@ public class App extends Application {
|
|
|
PDFTextStripper textStripper = new PDFTextStripper();
|
|
|
//提取文本
|
|
|
text = textStripper.getText(pdDocument);
|
|
|
+ log.debug("PDF解析{}到{}",workOrderFile.getAbsolutePath(),text);
|
|
|
}catch (IOException e) {
|
|
|
+ log.warn("PDF解析{}失败,case:{}",workOrderFile.getAbsolutePath(),e.getMessage());
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
return text;
|
|
|
@@ -478,13 +502,16 @@ public class App extends Application {
|
|
|
if (file.isFile()) {
|
|
|
continue;
|
|
|
}
|
|
|
+ log.info("正在扫描文件夹,查找工单文件: {}", file.getName());
|
|
|
File[] listFiles = file.listFiles();
|
|
|
String[] split = file.getName().split("-");
|
|
|
- String imei = split[split.length-1];
|
|
|
+ String imei = split[split.length-1].trim();
|
|
|
+ log.debug("IMEI: {}", imei);
|
|
|
//拿到文件夹里的工单文件(文件类型可能是PDF或JPG)
|
|
|
for (File workOrderFile : listFiles) {
|
|
|
if (workOrderFile.getName().contains("工单照片")) {
|
|
|
if (workOrderFileMap.containsKey(imei)) {
|
|
|
+ log.warn("出现重复的imei: {}", imei);
|
|
|
//出现重复的imei
|
|
|
Platform.runLater(()->{
|
|
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
|
|
@@ -494,6 +521,7 @@ public class App extends Application {
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
+ log.info("找到IMEI;{}对应的工单文件: {}", imei,workOrderFile.getName());
|
|
|
workOrderFileMap.put(imei, workOrderFile);
|
|
|
break;
|
|
|
}
|
|
|
@@ -508,6 +536,7 @@ public class App extends Application {
|
|
|
private void readExcel(String filePath) {
|
|
|
EasyExcel.read(filePath, InputModel.class, new PageReadListener<InputModel>(dataList -> {
|
|
|
for (InputModel inputModel : dataList) {
|
|
|
+ log.debug("读取到一行数据:{}",inputModel);
|
|
|
inputModelList.add(inputModel);
|
|
|
}
|
|
|
})).sheet().doRead();
|