更新版本(1.0->1.1):
1. 步骤任务超时终止配置 2. 步骤辅助关闭后主界面自动调整尺寸 3. 扫描超时会显示最后扫描的文件 4. track日志实时记录扫描文件 5. 一些不影响主功能的,细微调整(如FXML UI文件)
This commit is contained in:
parent
d1608666db
commit
96f7acb2a9
|
|
@ -4,7 +4,9 @@
|
|||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="LOCAL" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="$PROJECT_DIR$/../../projEnv/gradle/gradle-8.6" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
project_group =top.r3944realms.docchecktoolrefacored
|
||||
project_name = doc-check-tool
|
||||
project_version = 1.0
|
||||
project_version = 1.1
|
||||
|
|
@ -12,7 +12,7 @@ public class JavaFxApplication extends Application {
|
|||
@Override
|
||||
public void init() throws Exception {
|
||||
super.init();
|
||||
System.setVersion("1.0");
|
||||
System.setVersion("1.1");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package top.r3944realms.docchecktoolrefactored;
|
|||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import top.r3944realms.docchecktoolrefactored.core.Setting;
|
||||
import top.r3944realms.docchecktoolrefactored.ui.module.ProjectInfoPaneController;
|
||||
|
|
@ -28,6 +27,7 @@ public enum System {
|
|||
private static final Properties properties = new Properties();
|
||||
private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
// 默认值
|
||||
private static final boolean DEFAULT_ENABLE_TASK_TIMEOUT = false;
|
||||
private static final long DEFAULT_SINGLE_TIMEOUT = 30;
|
||||
private static final long DEFAULT_TOTAL_TIMEOUT = 12600;
|
||||
private static final boolean DEFAULT_ENABLE_STEP = false;
|
||||
|
|
@ -116,6 +116,7 @@ public enum System {
|
|||
/** 将Setting对象转换为Properties */
|
||||
private static void settingToProperties(Setting setting, Properties props) {
|
||||
props.setProperty("scanTimeOutS", String.valueOf(setting.getScanTimeout()));
|
||||
props.setProperty("enableTaskTimeout", String.valueOf(setting.isEnableTaskTimeout()));
|
||||
props.setProperty("taskTimeOutS", String.valueOf(setting.getTaskTimeout()));
|
||||
props.setProperty("enableStep", String.valueOf(setting.isEnableStep()));
|
||||
}
|
||||
|
|
@ -123,7 +124,12 @@ public enum System {
|
|||
/** 将Properties转换为Setting对象 */
|
||||
private static Setting propertiesToSetting(Properties props) {
|
||||
Setting s = new Setting();
|
||||
|
||||
try {
|
||||
s.setEnableTaskTimeout((Boolean.parseBoolean(props.getProperty("enableTaskTimeout", String.valueOf(DEFAULT_ENABLE_TASK_TIMEOUT)))));
|
||||
} catch (Exception e) {
|
||||
s.setScanTimeout(DEFAULT_SINGLE_TIMEOUT);
|
||||
log.error(LoggerMarker.DEBUG_MARKER, "enableTaskTimeout格式错误,使用默认值{}", DEFAULT_ENABLE_TASK_TIMEOUT);
|
||||
}
|
||||
try {
|
||||
s.setScanTimeout(Long.parseLong(props.getProperty("scanTimeOutS", String.valueOf(DEFAULT_SINGLE_TIMEOUT))));
|
||||
} catch (NumberFormatException e) {
|
||||
|
|
@ -150,6 +156,7 @@ public enum System {
|
|||
/** 获取默认Setting */
|
||||
private static Setting defaultSetting() {
|
||||
Setting s = new Setting();
|
||||
s.setEnableStep(DEFAULT_ENABLE_TASK_TIMEOUT);
|
||||
s.setScanTimeout(DEFAULT_SINGLE_TIMEOUT);
|
||||
s.setTaskTimeout(DEFAULT_TOTAL_TIMEOUT);
|
||||
return s;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public class HashFileGenerator {
|
|||
public void onError(Path path, Exception e) {
|
||||
log.error(LoggerMarker.TRACE_MARKER, "扫描错误: {} - {}", path, e.getMessage());
|
||||
}
|
||||
});
|
||||
}, System.getSetting().getScanTimeout());
|
||||
|
||||
// 使用带超时的等待,并响应中断
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
@Slf4j
|
||||
public class Setting {
|
||||
private long scanTimeout = 30;
|
||||
private boolean enableTaskTimeout = false;
|
||||
private long taskTimeout = 60 * 5;
|
||||
private boolean enableStep = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,16 +9,25 @@ import java.nio.file.AccessDeniedException;
|
|||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@Slf4j
|
||||
public class RobustParallelScanner implements FileScanner {
|
||||
private final ForkJoinPool forkJoinPool;
|
||||
private volatile boolean cancelled = false;
|
||||
|
||||
// 用于记录当前正在扫描的路径
|
||||
private final AtomicReference<Path> currentScanningPath = new AtomicReference<>();
|
||||
private final AtomicReference<String> lastProcessedFile = new AtomicReference<>();
|
||||
private final AtomicInteger totalFilesScanned = new AtomicInteger(0);
|
||||
private final AtomicInteger totalDirectoriesScanned = new AtomicInteger(0);
|
||||
private volatile LocalDateTime scanStartTime;
|
||||
|
||||
private final int maxDepth;
|
||||
public RobustParallelScanner(int maxDepth) {
|
||||
this(Runtime.getRuntime().availableProcessors(), maxDepth);
|
||||
|
|
@ -67,45 +76,117 @@ public class RobustParallelScanner implements FileScanner {
|
|||
scanInternal(rootPath, listener, totalFiles, 30);
|
||||
}
|
||||
private void scanInternal(Path rootPath, FileScanListener listener, AtomicLong totalFiles, long timeout) {
|
||||
resetScanState();
|
||||
scanStartTime = LocalDateTime.now();
|
||||
currentScanningPath.set(rootPath);
|
||||
|
||||
try {
|
||||
validateDirectory(rootPath);
|
||||
|
||||
forkJoinPool.submit(() -> {
|
||||
ForkJoinTask<?> submit = forkJoinPool.submit(() -> {
|
||||
try {
|
||||
AtomicInteger processedFiles = new AtomicInteger(0);
|
||||
scanDirectory(rootPath, listener, processedFiles, totalFiles, 0);
|
||||
|
||||
if (!cancelled) {
|
||||
listener.onScanComplete();
|
||||
logScanStatistics();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
listener.onError(rootPath, e);
|
||||
}
|
||||
}).get(timeout, TimeUnit.SECONDS);
|
||||
} catch (TimeoutException e) {
|
||||
log.error(LoggerMarker.TRACE_MARKER, "Scan timeout: {}", rootPath, e);
|
||||
forkJoinPool.shutdownNow();
|
||||
listener.onError(rootPath, new TimeoutException("扫描超时30秒"));
|
||||
});
|
||||
handleTimeout(submit, rootPath, listener, timeout);
|
||||
} catch (Exception e) {
|
||||
listener.onError(rootPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTimeout(Future<?> scanFuture, Path rootPath,
|
||||
FileScanListener listener, long timeout) throws TimeoutException {
|
||||
try {
|
||||
scanFuture.get(timeout, TimeUnit.SECONDS);
|
||||
} catch (TimeoutException e) {
|
||||
// 获取详细的超时信息
|
||||
String timeoutInfo = buildTimeoutInfo(rootPath);
|
||||
log.error(LoggerMarker.RELEASE_MARKER, "扫描超时 - {}", timeoutInfo, e);
|
||||
|
||||
// 取消扫描任务
|
||||
cancelled = true;
|
||||
scanFuture.cancel(true);
|
||||
forkJoinPool.shutdownNow();
|
||||
log.info("扫描超时 - {}", timeoutInfo);
|
||||
// 创建详细的超时异常
|
||||
throw new TimeoutException(
|
||||
String.format("扫描超时: 已执行 %d 秒\n%s", timeout, timeoutInfo)
|
||||
);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
listener.onError(rootPath, new InterruptedException("扫描被中断"));
|
||||
} catch (ExecutionException e) {
|
||||
listener.onError(rootPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetScanState() {
|
||||
cancelled = false;
|
||||
currentScanningPath.set(null);
|
||||
lastProcessedFile.set(null);
|
||||
totalFilesScanned.set(0);
|
||||
totalDirectoriesScanned.set(0);
|
||||
}
|
||||
|
||||
private String buildTimeoutInfo(Path rootPath) {
|
||||
return "扫描开始时间: " + formatDateTime(scanStartTime) + "\n" +
|
||||
"扫描根目录: " + rootPath.toAbsolutePath() + "\n" +
|
||||
"当前扫描路径: " + currentScanningPath.get() + "\n" +
|
||||
"最后处理的文件: " + lastProcessedFile.get() + "\n" +
|
||||
"已扫描文件数: " + totalFilesScanned.get() + "\n" +
|
||||
"已扫描目录数: " + totalDirectoriesScanned.get() + "\n"
|
||||
;
|
||||
}
|
||||
private void logScanStatistics() {
|
||||
LocalDateTime endTime = LocalDateTime.now();
|
||||
log.info(LoggerMarker.DEBUG_MARKER, """
|
||||
扫描统计信息:
|
||||
开始时间: {}
|
||||
结束时间: {}
|
||||
总扫描时间: {} 秒
|
||||
扫描文件数: {}
|
||||
扫描目录数: {}
|
||||
最后扫描路径: {}
|
||||
""",
|
||||
formatDateTime(scanStartTime),
|
||||
formatDateTime(endTime),
|
||||
java.time.Duration.between(scanStartTime, endTime).getSeconds(),
|
||||
totalFilesScanned.get(),
|
||||
totalDirectoriesScanned.get(),
|
||||
currentScanningPath.get()
|
||||
);
|
||||
}
|
||||
|
||||
private void scanDirectory(Path dir, FileScanListener listener,
|
||||
AtomicInteger processedFiles, AtomicLong totalFiles, int currentDepth) {
|
||||
if (cancelled || currentDepth > maxDepth) return;
|
||||
|
||||
currentScanningPath.set(dir);
|
||||
totalDirectoriesScanned.incrementAndGet();
|
||||
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
|
||||
for (Path path : stream) {
|
||||
if (cancelled) break;
|
||||
|
||||
if (Files.isDirectory(path)) {
|
||||
// 记录目录扫描开始
|
||||
log.trace(LoggerMarker.TRACE_MARKER, "扫描目录: {}, 深度: {}", path, currentDepth + 1);
|
||||
scanDirectory(path, listener, processedFiles, totalFiles, currentDepth + 1);
|
||||
} else if (Files.isRegularFile(path)) {
|
||||
lastProcessedFile.set(path.toAbsolutePath().toString());
|
||||
processFile(path, listener, processedFiles, totalFiles);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn(LoggerMarker.TRACE_MARKER, "无法访问目录: {}", dir, e);
|
||||
listener.onError(dir, e);
|
||||
}
|
||||
}
|
||||
|
|
@ -115,14 +196,20 @@ public class RobustParallelScanner implements FileScanner {
|
|||
|
||||
try {
|
||||
listener.onFileFound(file);
|
||||
totalFilesScanned.incrementAndGet();
|
||||
|
||||
// 进度更新处理
|
||||
if (listener instanceof ProgressAwareListener progressListener && totalFiles != null) {
|
||||
if (totalFilesScanned.get() % 1000 == 0) {
|
||||
log.debug(LoggerMarker.TRACE_MARKER, "已扫描 {} 个文件,当前文件: {}",
|
||||
totalFilesScanned.get(), file);
|
||||
}
|
||||
if (listener instanceof ProgressAwareListener progressListener) {
|
||||
int processed = processedFiles.incrementAndGet();
|
||||
long total = totalFiles.get();
|
||||
progressListener.onProgressUpdate(processed, (int)total);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn(LoggerMarker.TRACE_MARKER, "处理文件失败: {}", file, e);
|
||||
listener.onError(file, e);
|
||||
}
|
||||
}
|
||||
|
|
@ -139,6 +226,16 @@ public class RobustParallelScanner implements FileScanner {
|
|||
path.toString().contains("$")) {
|
||||
throw new IOException("系统目录禁止访问: " + path);
|
||||
}
|
||||
long freeSpace = Files.getFileStore(path).getUsableSpace();
|
||||
if (freeSpace < 1024 * 1024 * 10) { // 小于10MB
|
||||
log.warn(LoggerMarker.TRACE_MARKER, "磁盘空间不足: {},可用空间: {} MB",
|
||||
path, freeSpace / (1024 * 1024));
|
||||
}
|
||||
}
|
||||
|
||||
private String formatDateTime(LocalDateTime dateTime) {
|
||||
if (dateTime == null) return "N/A";
|
||||
return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ import javafx.scene.input.KeyCodeCombination;
|
|||
import javafx.scene.input.KeyCombination;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import top.r3944realms.docchecktoolrefactored.System;
|
||||
|
|
@ -53,6 +56,7 @@ public class MainStageController {
|
|||
@FXML private MenuItem exitMI;
|
||||
@FXML private MenuItem logoutMI;
|
||||
@FXML private MenuItem settingMI;
|
||||
@FXML private HBox stepAssistant;
|
||||
|
||||
private List<Tab> tabs;
|
||||
private int currentIndex = 0;
|
||||
|
|
@ -257,8 +261,24 @@ public class MainStageController {
|
|||
}
|
||||
public void updateStepButtonsVisibility() {
|
||||
Setting setting = System.getSetting();
|
||||
boolean visible = setting.isEnableStep(); // 由enableStep控制
|
||||
boolean visible = setting.isEnableStep();
|
||||
|
||||
// 设置容器可见性和管理状态
|
||||
stepAssistant.setVisible(visible);
|
||||
stepAssistant.setManaged(visible);
|
||||
|
||||
// 同时设置按钮的可见性(可选,因为容器已控制)
|
||||
nextB.setVisible(visible);
|
||||
prevB.setVisible(visible);
|
||||
|
||||
// 如果隐藏按钮区域,调整布局
|
||||
if (!visible) {
|
||||
// 确保TabPane占据剩余空间
|
||||
VBox.setVgrow(tabPane, Priority.ALWAYS);
|
||||
} else {
|
||||
// 恢复默认的垂直增长策略
|
||||
VBox.setVgrow(tabPane, Priority.ALWAYS);
|
||||
VBox.setVgrow(stepAssistant, Priority.NEVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ import java.util.ResourceBundle;
|
|||
|
||||
public class SettingDialogController implements Initializable {
|
||||
|
||||
@FXML private CheckBox enableStepCB;
|
||||
@FXML private CheckBox enableStepCB, enableTaskTimeoutCB;
|
||||
@FXML private Button resetB, saveB, cancelB;
|
||||
@FXML private Spinner<Long> scanTimeOutS, taskTimeOutS;
|
||||
|
||||
|
|
@ -35,11 +35,19 @@ public class SettingDialogController implements Initializable {
|
|||
setting = System.getSetting();
|
||||
|
||||
// 初始化 Spinner
|
||||
enableTaskTimeoutCB.setSelected(setting.isEnableTaskTimeout());
|
||||
scanTimeOutS.setValueFactory(new LongSpinnerValueFactory(1, 3600, setting.getScanTimeout()));
|
||||
scanTimeOutS.setEditable(true);
|
||||
if (setting.isEnableTaskTimeout()) {
|
||||
taskTimeOutS.setEditable(true);
|
||||
taskTimeOutS.setDisable(false);
|
||||
} else {
|
||||
taskTimeOutS.setDisable(true);
|
||||
}
|
||||
taskTimeOutS.setValueFactory(new LongSpinnerValueFactory(1, 3600 * 24, setting.getTaskTimeout()));
|
||||
taskTimeOutS.setEditable(true);
|
||||
|
||||
|
||||
// 添加焦点离开时校验
|
||||
addSpinnerValidation(scanTimeOutS, SINGLE_MIN, SINGLE_MAX);
|
||||
addSpinnerValidation(taskTimeOutS, TOTAL_MIN, TOTAL_MAX);
|
||||
|
|
@ -53,6 +61,7 @@ public class SettingDialogController implements Initializable {
|
|||
setting.setScanTimeout(scanTimeOutS.getValue());
|
||||
setting.setTaskTimeout(taskTimeOutS.getValue());
|
||||
setting.setEnableStep(enableStepCB.isSelected());
|
||||
setting.setEnableTaskTimeout(enableTaskTimeoutCB.isSelected());
|
||||
// 保存到配置文件
|
||||
System.saveSettingsNow();
|
||||
// 通知主界面刷新按钮状态
|
||||
|
|
@ -69,6 +78,7 @@ public class SettingDialogController implements Initializable {
|
|||
scanTimeOutS.getValueFactory().setValue(30L); // 默认单次超时
|
||||
taskTimeOutS.getValueFactory().setValue(300L); // 默认总超时
|
||||
enableStepCB.setSelected(false);
|
||||
enableTaskTimeoutCB.setSelected(false);
|
||||
}
|
||||
|
||||
/** 取消修改 */
|
||||
|
|
@ -83,14 +93,19 @@ public class SettingDialogController implements Initializable {
|
|||
}
|
||||
|
||||
@FXML
|
||||
void onCheckTwo(MouseDragEvent mouseDragEvent) {
|
||||
void onCheckThree(MouseDragEvent mouseDragEvent) {
|
||||
validateSpinnerValue(taskTimeOutS, 60, 3600 * 24);
|
||||
}
|
||||
@FXML
|
||||
void onSettingThree(ActionEvent actionEvent) {
|
||||
void onSettingTwo(ActionEvent actionEvent) {
|
||||
taskTimeOutS.setDisable(!enableTaskTimeoutCB.isSelected());
|
||||
}
|
||||
@FXML
|
||||
void onSettingFour(ActionEvent actionEvent) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** 给 Spinner 添加离开焦点校验 */
|
||||
private void addSpinnerValidation(Spinner<Long> spinner, long min, long max) {
|
||||
spinner.getEditor().focusedProperty().addListener((obs, oldVal, newVal) -> {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import javafx.stage.DirectoryChooser;
|
|||
import javafx.stage.Stage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import top.r3944realms.docchecktoolrefactored.System;
|
||||
import top.r3944realms.docchecktoolrefactored.core.ScanningException;
|
||||
import top.r3944realms.docchecktoolrefactored.ui.SceneManager;
|
||||
import top.r3944realms.docchecktoolrefactored.ui.task.DuplicateDocumentDetectionTask;
|
||||
import top.r3944realms.docchecktoolrefactored.ui.utils.DialogUtil;
|
||||
|
|
@ -18,6 +19,8 @@ import top.r3944realms.docchecktoolrefactored.ui.utils.ProgressBar;
|
|||
import top.r3944realms.docchecktoolrefactored.util.LoggerMarker;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type Duplicate document pane controller.
|
||||
*/
|
||||
|
|
@ -119,10 +122,18 @@ public class DuplicateDocumentPaneController {
|
|||
Throwable exception = task.getException();
|
||||
currentTask.progressProperty().removeListener(progressChangeListener);
|
||||
// currentTask.messageProperty().removeListener(messageChangeListener);
|
||||
result1TA.setText("检测过程中发生错误: " + exception.getMessage());
|
||||
|
||||
// 调用提取的样式方法:添加结果文本域错误态
|
||||
addResultErrorStyle();
|
||||
DialogUtil.showDetailedErrorDialog("错误", "检测过程中发生错误", exception.getMessage());
|
||||
if (exception instanceof ScanningException e1) {
|
||||
List<String> list = e1.exceptions.stream().map(Throwable::getMessage).toList();
|
||||
String message = String.join("\n", list);
|
||||
DialogUtil.showDetailedErrorDialog("错误", "检测过程中发生错误", message);
|
||||
result1TA.setText("检测过程中发生错误: " + message);
|
||||
} else {
|
||||
DialogUtil.showDetailedErrorDialog("错误", "检测过程中发生错误", exception.getMessage());
|
||||
result1TA.setText("检测过程中发生错误: " + exception.getMessage());
|
||||
}
|
||||
start1B.setDisable(false);
|
||||
// 调用提取的样式方法:移除开始按钮加载态
|
||||
removeStartButtonLoadingStyle();
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ package top.r3944realms.docchecktoolrefactored.ui.task;
|
|||
|
||||
import javafx.concurrent.Task;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import top.r3944realms.docchecktoolrefactored.System;
|
||||
import top.r3944realms.docchecktoolrefactored.core.AddressFileComparator;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
|
|
@ -71,9 +73,10 @@ public class AddressFileComparisonTask extends Task<AddressFileComparator.Compar
|
|||
|
||||
try {
|
||||
// 构建显示文本
|
||||
return comparator.compareFiles(physicalFilePath, logicalFilePath, compareMode)
|
||||
.get(timeoutSeconds, TimeUnit.SECONDS);
|
||||
|
||||
CompletableFuture<AddressFileComparator.ComparisonResult> comparisonResult = comparator.compareFiles(physicalFilePath, logicalFilePath, compareMode);
|
||||
if (System.getSetting().isEnableTaskTimeout()) {
|
||||
return comparisonResult.get(timeoutSeconds, TimeUnit.SECONDS);
|
||||
} else return comparisonResult.get();
|
||||
} catch (TimeoutException e) {
|
||||
updateMessage("文件比对超时,请考虑在‘文件’-‘设置’里增加‘步骤任务超时时间’。");
|
||||
log.error("文件比对超时", e);
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@ public class AddressFileGenerationTask extends Task<String> {
|
|||
|
||||
try {
|
||||
// 等待执行完成或超时
|
||||
future.get(System.getSetting().getTaskTimeout(), TimeUnit.SECONDS);
|
||||
if (System.getSetting().isEnableTaskTimeout()){
|
||||
future.get(System.getSetting().getTaskTimeout(), TimeUnit.SECONDS);
|
||||
} else future.get();
|
||||
return outputFile.getAbsolutePath();
|
||||
|
||||
} catch (TimeoutException e) {
|
||||
|
|
|
|||
|
|
@ -114,11 +114,14 @@ public class DuplicateDocumentDetectionTask extends Task<String>{
|
|||
findThread.start();
|
||||
|
||||
// 简单等待,Task取消时会自动中断
|
||||
long totalTimeout = System.getSetting().getTaskTimeout();
|
||||
if (!latch.await(totalTimeout, TimeUnit.SECONDS)) {
|
||||
duplicateFinder.shutdown();
|
||||
throw new TimeoutException(String.format("任务超时(%d秒),请考虑在‘文件’-‘设置’里增加‘步骤任务超时时间’", totalTimeout));
|
||||
}
|
||||
boolean isEnableTaskTimout = System.getSetting().isEnableTaskTimeout();
|
||||
if (isEnableTaskTimout) {
|
||||
long totalTimeout = System.getSetting().getTaskTimeout();
|
||||
if (!latch.await(totalTimeout, TimeUnit.SECONDS)) {
|
||||
duplicateFinder.shutdown();
|
||||
throw new TimeoutException(String.format("任务超时(%d秒),请考虑在‘文件’-‘设置’里增加‘步骤任务超时时间’", totalTimeout));
|
||||
}
|
||||
} else latch.await();
|
||||
|
||||
// 检查是否有错误
|
||||
if (errorRef.get() != null) {
|
||||
|
|
|
|||
|
|
@ -57,9 +57,12 @@ public class HashFileGenerationTask extends Task<String> {
|
|||
});
|
||||
|
||||
try {
|
||||
// 设置超时时间
|
||||
long timeoutSeconds = System.getSetting().getTaskTimeout();
|
||||
future.get(timeoutSeconds, TimeUnit.SECONDS);
|
||||
boolean enableTaskTimeout = System.getSetting().isEnableTaskTimeout();
|
||||
if (enableTaskTimeout) {
|
||||
// 设置超时时间
|
||||
long timeoutSeconds = System.getSetting().getTaskTimeout();
|
||||
future.get(timeoutSeconds, TimeUnit.SECONDS);
|
||||
} else future.get();
|
||||
|
||||
log.info(LoggerMarker.DEBUG_MARKER, "哈希文件生成任务完成,输出文件: {}", finalOutputFile.getAbsolutePath());
|
||||
return "哈希列表文件已生成: " + finalOutputFile.getAbsolutePath();
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
<HBox nodeOrientation="RIGHT_TO_LEFT" prefHeight="100.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
|
||||
<HBox fx:id="stepAssistant" nodeOrientation="RIGHT_TO_LEFT" prefHeight="100.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
|
||||
<children>
|
||||
<Button fx:id="nextB" mnemonicParsing="false" onAction="#onNext" prefHeight="100.0" prefWidth="500.0" text="下一步">
|
||||
<HBox.margin>
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@
|
|||
<ColumnConstraints />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="151.33334350585938" percentHeight="7.0" prefHeight="55.00001017252603" vgrow="NEVER" />
|
||||
<RowConstraints maxHeight="508.33333333333326" percentHeight="7.0" prefHeight="73.99999491373697" vgrow="NEVER" />
|
||||
<RowConstraints maxHeight="592.6666666666666" percentHeight="7.0" prefHeight="581.3333536783855" vgrow="NEVER" />
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" prefHeight="581.3333536783855" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="151.33334350585938" prefHeight="55.00001017252603" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="508.33333333333326" percentHeight="7.0" prefHeight="73.99999491373697" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="592.6666666666666" prefHeight="51.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="-Infinity" prefHeight="605.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label prefHeight="23.0" prefWidth="141.0" text="载入数字化成果:">
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
|
||||
</padding>
|
||||
</TextField>
|
||||
<TextArea fx:id="result7TA" editable="false" prefWidth="400.0" GridPane.columnSpan="3" GridPane.rowIndex="3">
|
||||
<TextArea fx:id="result7TA" editable="false" prefHeight="450.0" prefWidth="400.0" GridPane.columnSpan="3" GridPane.rowIndex="3">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
|
|
@ -118,7 +118,7 @@
|
|||
<Font size="14.0" />
|
||||
</font>
|
||||
</Button>
|
||||
<TextArea editable="false" maxWidth="1.7976931348623157E308" prefWidth="400.0" text="1.对照《存储载体检查登记表》(附件7)检查并记录存储载体的类型/数量/内容/可读性情况; 2.计算数字化成果(包括单页、多页文件)的MD5码,生成列表文件,保存在目录所在文件夹; 3.将列表文件、目录文件、检测过程文件(第2步生成的逻辑地址、物理地址等csv文件)打包生成"数字化验收检测包.rar"; 4.计算并验证压缩包的MD5码或哈希值; 5.结果填入《存储载体检查登记表》。(附件7)" wrapText="true" GridPane.columnIndex="3" GridPane.columnSpan="2" GridPane.rowIndex="3">
|
||||
<TextArea editable="false" prefHeight="450.0" prefWidth="400.0" text="1.对照《存储载体检查登记表》(附件7)检查并记录存储载体的类型/数量/内容/可读性情况; 2.计算数字化成果(包括单页、多页文件)的MD5码,生成列表文件,保存在目录所在文件夹; 3.将列表文件、目录文件、检测过程文件(第2步生成的逻辑地址、物理地址等csv文件)打包生成"数字化验收检测包.rar"; 4.计算并验证压缩包的MD5码或哈希值; 5.结果填入《存储载体检查登记表》。(附件7)" wrapText="true" GridPane.columnIndex="3" GridPane.columnSpan="2" GridPane.rowIndex="3">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
|
||||
</rowConstraints>
|
||||
|
|
@ -37,12 +38,12 @@
|
|||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
</Spinner>
|
||||
<Label prefHeight="19.0" prefWidth="167.0" text="步骤任务超时时间:" GridPane.rowIndex="2">
|
||||
<Label prefHeight="19.0" prefWidth="167.0" text="步骤任务超时时间:" GridPane.rowIndex="3">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<Spinner fx:id="taskTimeOutS" onMouseDragExited="#onCheckTwo" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<Spinner fx:id="taskTimeOutS" onMouseDragExited="#onCheckThree" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
|
|
@ -53,8 +54,9 @@
|
|||
</font>
|
||||
</Label>
|
||||
<Label text="秒" GridPane.columnIndex="2" GridPane.rowIndex="1" />
|
||||
<Label text="秒" GridPane.columnIndex="2" GridPane.rowIndex="2" />
|
||||
<CheckBox fx:id="enableStepCB" mnemonicParsing="false" onAction="#onSettingThree" text="启用步骤辅助" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER" />
|
||||
<Label text="秒" GridPane.columnIndex="2" GridPane.rowIndex="3" />
|
||||
<CheckBox fx:id="enableStepCB" mnemonicParsing="false" onAction="#onSettingFour" text="启用步骤辅助" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="4" GridPane.valignment="CENTER" />
|
||||
<CheckBox fx:id="enableTaskTimeoutCB" mnemonicParsing="false" onAction="#onSettingTwo" text="启用步骤任务超时终止" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<HBox alignment="CENTER">
|
||||
|
|
|
|||
BIN
源程序文档_2025-11-27-2.docx
Normal file
BIN
源程序文档_2025-11-27-2.docx
Normal file
Binary file not shown.
BIN
源程序文档_2025-11-27.docx
Normal file
BIN
源程序文档_2025-11-27.docx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user