代码优化
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
package com.example.workutils;
|
package com.example.workutils;
|
||||||
|
|
||||||
import com.example.workutils.system.menu.MenuRunner;
|
|
||||||
import com.example.workutils.system.tool.Tool;
|
import com.example.workutils.system.tool.Tool;
|
||||||
import com.example.workutils.system.tool.ToolRegistry;
|
import com.example.workutils.system.tool.Registry;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.CommandLineRunner;
|
import org.springframework.boot.CommandLineRunner;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
@@ -17,12 +16,10 @@ import java.util.Scanner;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class WorkUtilsApplication implements CommandLineRunner {
|
public class WorkUtilsApplication implements CommandLineRunner {
|
||||||
|
|
||||||
private final MenuRunner menuRunner;
|
private final Registry registry;
|
||||||
private final ToolRegistry toolRegistry;
|
|
||||||
|
|
||||||
public WorkUtilsApplication(MenuRunner menuRunner, ToolRegistry toolRegistry) {
|
public WorkUtilsApplication(Registry registry) {
|
||||||
this.menuRunner = menuRunner;
|
this.registry = registry;
|
||||||
this.toolRegistry = toolRegistry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@@ -40,7 +37,7 @@ public class WorkUtilsApplication implements CommandLineRunner {
|
|||||||
|
|
||||||
private void showInteractiveMenu() {
|
private void showInteractiveMenu() {
|
||||||
Scanner scanner = new Scanner(System.in);
|
Scanner scanner = new Scanner(System.in);
|
||||||
menuRunner.run(scanner);
|
registry.runMainMenu(scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +47,7 @@ public class WorkUtilsApplication implements CommandLineRunner {
|
|||||||
private void processCommand(String... args) throws Exception {
|
private void processCommand(String... args) throws Exception {
|
||||||
String command = args[0].toLowerCase();
|
String command = args[0].toLowerCase();
|
||||||
|
|
||||||
Optional<Tool> toolOpt = toolRegistry.getToolByCommand(command);
|
Optional<Tool> toolOpt = registry.getToolByCommand(command);
|
||||||
if (toolOpt.isPresent()) {
|
if (toolOpt.isPresent()) {
|
||||||
Tool tool = toolOpt.get();
|
Tool tool = toolOpt.get();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.example.workutils.biz.git.menu;
|
|||||||
|
|
||||||
import com.example.workutils.biz.git.service.GitService;
|
import com.example.workutils.biz.git.service.GitService;
|
||||||
import com.example.workutils.biz.git.util.GitCommandExecutor;
|
import com.example.workutils.biz.git.util.GitCommandExecutor;
|
||||||
import com.example.workutils.system.tool.AbstractTool;
|
import com.example.workutils.system.tool.Tool;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -19,7 +19,7 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GitMenu extends AbstractTool {
|
public class GitMenu implements Tool {
|
||||||
|
|
||||||
private static final String[] MENU_OPTIONS = {
|
private static final String[] MENU_OPTIONS = {
|
||||||
"1. 检测所有仓库健康状态",
|
"1. 检测所有仓库健康状态",
|
||||||
@@ -45,7 +45,7 @@ public class GitMenu extends AbstractTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleChoice(int choice, Scanner scanner) throws Exception {
|
public void handleChoice(int choice, Scanner scanner) throws Exception {
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 1:
|
case 1:
|
||||||
checkAllReposHealth(scanner);
|
checkAllReposHealth(scanner);
|
||||||
@@ -61,13 +61,13 @@ public class GitMenu extends AbstractTool {
|
|||||||
|
|
||||||
private void checkAllReposHealth(Scanner scanner) {
|
private void checkAllReposHealth(Scanner scanner) {
|
||||||
printMenuTitle("开始检测所有仓库");
|
printMenuTitle("开始检测所有仓库");
|
||||||
info("开始检测所有仓库健康状态");
|
log.info("开始检测所有仓库健康状态");
|
||||||
|
|
||||||
List<GitCommandExecutor.RepoHealthResult> results = gitService.checkCorruptedRepos(scanner);
|
List<GitCommandExecutor.RepoHealthResult> results = gitService.checkCorruptedRepos(scanner);
|
||||||
|
|
||||||
if (results.isEmpty()) {
|
if (results.isEmpty()) {
|
||||||
System.out.println("所有仓库状态正常!");
|
System.out.println("所有仓库状态正常!");
|
||||||
info("所有仓库状态正常");
|
log.info("所有仓库状态正常");
|
||||||
} else {
|
} else {
|
||||||
System.out.println("\n发现 " + results.size() + " 个损坏的仓库:");
|
System.out.println("\n发现 " + results.size() + " 个损坏的仓库:");
|
||||||
for (int i = 0; i < results.size(); i++) {
|
for (int i = 0; i < results.size(); i++) {
|
||||||
@@ -76,7 +76,7 @@ public class GitMenu extends AbstractTool {
|
|||||||
extractProjectName(result.getRepoPath()),
|
extractProjectName(result.getRepoPath()),
|
||||||
result.getCorruptionReason());
|
result.getCorruptionReason());
|
||||||
}
|
}
|
||||||
info("检测完成,发现 {} 个损坏仓库", results.size());
|
log.info("检测完成,发现 {} 个损坏仓库", results.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,11 +108,11 @@ public class GitMenu extends AbstractTool {
|
|||||||
String confirm = scanner.nextLine().trim();
|
String confirm = scanner.nextLine().trim();
|
||||||
if (!"y".equalsIgnoreCase(confirm)) {
|
if (!"y".equalsIgnoreCase(confirm)) {
|
||||||
System.out.println("已取消修复操作。");
|
System.out.println("已取消修复操作。");
|
||||||
info("用户取消修复操作");
|
log.info("用户取消修复操作");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info("开始修复 {} 个仓库", selectedIndices.size());
|
log.info("开始修复 {} 个仓库", selectedIndices.size());
|
||||||
int successCount = 0;
|
int successCount = 0;
|
||||||
int failCount = 0;
|
int failCount = 0;
|
||||||
for (Integer index : selectedIndices) {
|
for (Integer index : selectedIndices) {
|
||||||
@@ -132,7 +132,7 @@ public class GitMenu extends AbstractTool {
|
|||||||
printMenuTitle("修复完成");
|
printMenuTitle("修复完成");
|
||||||
System.out.println("成功: " + successCount);
|
System.out.println("成功: " + successCount);
|
||||||
System.out.println("失败: " + failCount);
|
System.out.println("失败: " + failCount);
|
||||||
info("修复完成,成功: {},失败: {}", successCount, failCount);
|
log.info("修复完成,成功: {},失败: {}", successCount, failCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Integer> parseSelectedIndices(String input, int repoCount) {
|
private List<Integer> parseSelectedIndices(String input, int repoCount) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.example.workutils.biz.mybatis.menu;
|
package com.example.workutils.biz.mybatis.menu;
|
||||||
|
|
||||||
import com.example.workutils.biz.mybatis.generator.MyBatisGeneratorService;
|
import com.example.workutils.biz.mybatis.generator.MyBatisGeneratorService;
|
||||||
import com.example.workutils.system.tool.AbstractTool;
|
import com.example.workutils.system.tool.Tool;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -17,7 +17,7 @@ import java.util.Scanner;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MyBatisGeneratorMenu extends AbstractTool {
|
public class MyBatisGeneratorMenu implements Tool {
|
||||||
|
|
||||||
private static final String[] MENU_OPTIONS = {
|
private static final String[] MENU_OPTIONS = {
|
||||||
"1. 根据表名生成(单表)",
|
"1. 根据表名生成(单表)",
|
||||||
@@ -46,7 +46,7 @@ public class MyBatisGeneratorMenu extends AbstractTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleChoice(int choice, Scanner scanner) throws Exception {
|
public void handleChoice(int choice, Scanner scanner) throws Exception {
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 1:
|
case 1:
|
||||||
generateBySingleTable(scanner);
|
generateBySingleTable(scanner);
|
||||||
@@ -78,7 +78,7 @@ public class MyBatisGeneratorMenu extends AbstractTool {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info("开始生成表 [{}] 的Mapper文件", tableName);
|
log.info("开始生成表 [{}] 的Mapper文件", tableName);
|
||||||
String result = generatorService.generateByTableNames(Arrays.asList(tableName), true);
|
String result = generatorService.generateByTableNames(Arrays.asList(tableName), true);
|
||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
printSuccess("生成完成");
|
printSuccess("生成完成");
|
||||||
@@ -98,7 +98,7 @@ public class MyBatisGeneratorMenu extends AbstractTool {
|
|||||||
tableNames.set(i, tableNames.get(i).trim());
|
tableNames.set(i, tableNames.get(i).trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
info("开始生成 {} 个表的Mapper文件", tableNames.size());
|
log.info("开始生成 {} 个表的Mapper文件", tableNames.size());
|
||||||
String result = generatorService.generateByTableNames(tableNames, true);
|
String result = generatorService.generateByTableNames(tableNames, true);
|
||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
printSuccess("生成完成");
|
printSuccess("生成完成");
|
||||||
@@ -131,7 +131,7 @@ public class MyBatisGeneratorMenu extends AbstractTool {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info("开始根据通配符 [{}] 生成 {} 张表的Mapper文件", pattern, matchedTables.size());
|
log.info("开始根据通配符 [{}] 生成 {} 张表的Mapper文件", pattern, matchedTables.size());
|
||||||
String result = generatorService.generateByTableNames(matchedTables, true);
|
String result = generatorService.generateByTableNames(matchedTables, true);
|
||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
printSuccess("生成完成");
|
printSuccess("生成完成");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.example.workutils.biz.mybatis.menu;
|
package com.example.workutils.biz.mybatis.menu;
|
||||||
|
|
||||||
import com.example.workutils.biz.mybatis.export.MyBatisExportService;
|
import com.example.workutils.biz.mybatis.export.MyBatisExportService;
|
||||||
import com.example.workutils.system.tool.AbstractTool;
|
import com.example.workutils.system.tool.Tool;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -16,7 +16,7 @@ import java.util.Scanner;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MyBatisMenu extends AbstractTool {
|
public class MyBatisMenu implements Tool {
|
||||||
|
|
||||||
private static final String[] MENU_OPTIONS = {
|
private static final String[] MENU_OPTIONS = {
|
||||||
"1. 导出所有SQL",
|
"1. 导出所有SQL",
|
||||||
@@ -85,7 +85,7 @@ public class MyBatisMenu extends AbstractTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleChoice(int choice, Scanner scanner) throws Exception {
|
public void handleChoice(int choice, Scanner scanner) throws Exception {
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 1:
|
case 1:
|
||||||
exportAllSql();
|
exportAllSql();
|
||||||
@@ -110,7 +110,7 @@ public class MyBatisMenu extends AbstractTool {
|
|||||||
|
|
||||||
private void exportAllSql() throws Exception {
|
private void exportAllSql() throws Exception {
|
||||||
printMenuTitle("导出所有SQL");
|
printMenuTitle("导出所有SQL");
|
||||||
info("开始导出所有SQL");
|
log.info("开始导出所有SQL");
|
||||||
myBatisExportService.exportSQL();
|
myBatisExportService.exportSQL();
|
||||||
printSuccess("导出所有SQL");
|
printSuccess("导出所有SQL");
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ public class MyBatisMenu extends AbstractTool {
|
|||||||
System.out.println("表名不能为空");
|
System.out.println("表名不能为空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
info("按表名导出SQL: {}", tableName);
|
log.info("按表名导出SQL: {}", tableName);
|
||||||
myBatisExportService.exportSQLByTable(tableName);
|
myBatisExportService.exportSQLByTable(tableName);
|
||||||
printSuccess("按表名导出SQL");
|
printSuccess("按表名导出SQL");
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ public class MyBatisMenu extends AbstractTool {
|
|||||||
System.out.println("表名不能为空");
|
System.out.println("表名不能为空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
info("按多个表名导出SQL: {}", tableNames);
|
log.info("按多个表名导出SQL: {}", tableNames);
|
||||||
myBatisExportService.exportSQLByTables(Arrays.asList(tableNames.split(",")));
|
myBatisExportService.exportSQLByTables(Arrays.asList(tableNames.split(",")));
|
||||||
printSuccess("按多个表名导出SQL");
|
printSuccess("按多个表名导出SQL");
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ public class MyBatisMenu extends AbstractTool {
|
|||||||
System.out.println("关键字不能为空");
|
System.out.println("关键字不能为空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
info("按关键字导出SQL: {}", keyword);
|
log.info("按关键字导出SQL: {}", keyword);
|
||||||
myBatisExportService.exportSQLByKeyword(keyword);
|
myBatisExportService.exportSQLByKeyword(keyword);
|
||||||
printSuccess("按关键字导出SQL");
|
printSuccess("按关键字导出SQL");
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ public class MyBatisMenu extends AbstractTool {
|
|||||||
System.out.println("标签ID不能为空");
|
System.out.println("标签ID不能为空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
info("按标签ID导出SQL: {}", tagId);
|
log.info("按标签ID导出SQL: {}", tagId);
|
||||||
myBatisExportService.exportSQLByTagId(tagId);
|
myBatisExportService.exportSQLByTagId(tagId);
|
||||||
printSuccess("按标签ID导出SQL");
|
printSuccess("按标签ID导出SQL");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.example.workutils.biz.output.menu;
|
|||||||
|
|
||||||
import com.example.workutils.biz.mybatis.export.MyBatisExportService;
|
import com.example.workutils.biz.mybatis.export.MyBatisExportService;
|
||||||
import com.example.workutils.biz.scanner.service.ScanService;
|
import com.example.workutils.biz.scanner.service.ScanService;
|
||||||
import com.example.workutils.system.tool.AbstractTool;
|
import com.example.workutils.system.tool.Tool;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -18,7 +18,7 @@ import java.util.Scanner;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class BatchMenu extends AbstractTool {
|
public class BatchMenu implements Tool {
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ExceptionRunnable {
|
public interface ExceptionRunnable {
|
||||||
@@ -63,13 +63,13 @@ public class BatchMenu extends AbstractTool {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeCommand(String... args) throws Exception {
|
public void executeCommand(String... args) throws Exception {
|
||||||
info("命令行模式: 开始执行所有检查");
|
log.info("命令行模式: 开始执行所有检查");
|
||||||
executeAllChecks();
|
executeAllChecks();
|
||||||
System.out.println("批量处理完成!");
|
System.out.println("批量处理完成!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleChoice(int choice, Scanner scanner) throws Exception {
|
public void handleChoice(int choice, Scanner scanner) throws Exception {
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 1:
|
case 1:
|
||||||
executeAllChecks();
|
executeAllChecks();
|
||||||
@@ -85,7 +85,7 @@ public class BatchMenu extends AbstractTool {
|
|||||||
|
|
||||||
private void executeAllChecks() throws Exception {
|
private void executeAllChecks() throws Exception {
|
||||||
printMenuTitle("执行所有检查");
|
printMenuTitle("执行所有检查");
|
||||||
info("开始执行所有检查");
|
log.info("开始执行所有检查");
|
||||||
|
|
||||||
executeStep("1. 导出SQL...", () -> myBatisExportService.exportSQL());
|
executeStep("1. 导出SQL...", () -> myBatisExportService.exportSQL());
|
||||||
executeStep("2. 扫描Dubbo接口...",
|
executeStep("2. 扫描Dubbo接口...",
|
||||||
@@ -94,7 +94,7 @@ public class BatchMenu extends AbstractTool {
|
|||||||
() -> scanService.scanRedisKeysWithDefaultName("redis\\.opsFor"));
|
() -> scanService.scanRedisKeysWithDefaultName("redis\\.opsFor"));
|
||||||
|
|
||||||
printSuccess("所有检查");
|
printSuccess("所有检查");
|
||||||
info("所有检查执行完成");
|
log.info("所有检查执行完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeCustomChecks(Scanner scanner) throws Exception {
|
private void executeCustomChecks(Scanner scanner) throws Exception {
|
||||||
@@ -105,7 +105,7 @@ public class BatchMenu extends AbstractTool {
|
|||||||
String choices = scanner.nextLine().trim();
|
String choices = scanner.nextLine().trim();
|
||||||
List<String> choiceList = parseCommaSeparatedInput(choices);
|
List<String> choiceList = parseCommaSeparatedInput(choices);
|
||||||
|
|
||||||
info("用户选择执行检查项: {}", choiceList);
|
log.info("用户选择执行检查项: {}", choiceList);
|
||||||
|
|
||||||
for (String choice : choiceList) {
|
for (String choice : choiceList) {
|
||||||
try {
|
try {
|
||||||
@@ -132,7 +132,7 @@ public class BatchMenu extends AbstractTool {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
error("执行检查项失败: " + choice, e);
|
log.error("执行检查项失败: " + choice, e);
|
||||||
System.out.println("检查项 " + choice + " 执行失败: " + e.getMessage());
|
System.out.println("检查项 " + choice + " 执行失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.example.workutils.biz.scanner.menu;
|
package com.example.workutils.biz.scanner.menu;
|
||||||
|
|
||||||
import com.example.workutils.biz.scanner.service.ScanService;
|
import com.example.workutils.biz.scanner.service.ScanService;
|
||||||
import com.example.workutils.system.tool.AbstractTool;
|
import com.example.workutils.system.tool.Tool;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -15,7 +15,7 @@ import java.util.Scanner;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ScanMenu extends AbstractTool {
|
public class ScanMenu implements Tool {
|
||||||
|
|
||||||
private static final String[] MENU_OPTIONS = {
|
private static final String[] MENU_OPTIONS = {
|
||||||
"1. 关键词扫描",
|
"1. 关键词扫描",
|
||||||
@@ -75,7 +75,7 @@ public class ScanMenu extends AbstractTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleChoice(int choice, Scanner scanner) throws Exception {
|
public void handleChoice(int choice, Scanner scanner) throws Exception {
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 1:
|
case 1:
|
||||||
scanByKeyword(scanner);
|
scanByKeyword(scanner);
|
||||||
@@ -88,7 +88,7 @@ public class ScanMenu extends AbstractTool {
|
|||||||
|
|
||||||
private void scanByKeyword(Scanner scanner) throws Exception {
|
private void scanByKeyword(Scanner scanner) throws Exception {
|
||||||
printMenuTitle("关键词扫描");
|
printMenuTitle("关键词扫描");
|
||||||
info("开始关键词扫描");
|
log.info("开始关键词扫描");
|
||||||
|
|
||||||
System.out.print("请输入关键词: ");
|
System.out.print("请输入关键词: ");
|
||||||
String keyword = scanner.nextLine().trim();
|
String keyword = scanner.nextLine().trim();
|
||||||
@@ -98,7 +98,7 @@ public class ScanMenu extends AbstractTool {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info("扫描关键词: {}", keyword);
|
log.info("扫描关键词: {}", keyword);
|
||||||
scanService.scanKeywordsWithDefaultName(keyword);
|
scanService.scanKeywordsWithDefaultName(keyword);
|
||||||
|
|
||||||
printSuccess("关键词扫描");
|
printSuccess("关键词扫描");
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
package com.example.workutils.system.menu;
|
|
||||||
|
|
||||||
import com.example.workutils.system.ConsoleHelper;
|
|
||||||
import com.example.workutils.system.tool.Tool;
|
|
||||||
import com.example.workutils.system.tool.ToolRegistry;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Scanner;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 菜单运行器
|
|
||||||
* 从ToolRegistry动态构建主菜单,无需硬编码Menu引用
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class MenuRunner {
|
|
||||||
|
|
||||||
private static final int EXIT_CODE = 0;
|
|
||||||
|
|
||||||
private final ToolRegistry toolRegistry;
|
|
||||||
|
|
||||||
public MenuRunner(ToolRegistry toolRegistry) {
|
|
||||||
this.toolRegistry = toolRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 运行主菜单循环
|
|
||||||
*/
|
|
||||||
public void run(Scanner scanner) {
|
|
||||||
log.info("启动主菜单");
|
|
||||||
while (true) {
|
|
||||||
ConsoleHelper.printMenuTitle("主菜单");
|
|
||||||
displayMainMenu();
|
|
||||||
|
|
||||||
int choice = ConsoleHelper.readChoice(scanner);
|
|
||||||
scanner.nextLine();
|
|
||||||
|
|
||||||
if (choice == EXIT_CODE) {
|
|
||||||
log.info("用户退出系统");
|
|
||||||
System.out.println("感谢使用,再见!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleChoice(choice, scanner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 动态构建主菜单
|
|
||||||
*/
|
|
||||||
private void displayMainMenu() {
|
|
||||||
System.out.println("请选择操作:");
|
|
||||||
List<Tool> tools = toolRegistry.getEnabledTools();
|
|
||||||
for (int i = 0; i < tools.size(); i++) {
|
|
||||||
System.out.println((i + 1) + ". " + tools.get(i).getName());
|
|
||||||
}
|
|
||||||
System.out.println(EXIT_CODE + ". 退出系统");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理用户选择,工具隔离
|
|
||||||
* 单个工具异常不影响平台和其他工具
|
|
||||||
*/
|
|
||||||
private void handleChoice(int choice, Scanner scanner) {
|
|
||||||
List<Tool> tools = toolRegistry.getEnabledTools();
|
|
||||||
int index = choice - 1;
|
|
||||||
|
|
||||||
if (index >= 0 && index < tools.size()) {
|
|
||||||
Tool tool = tools.get(index);
|
|
||||||
try {
|
|
||||||
tool.execute(scanner);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("工具执行失败: {} [{}]", tool.getName(), tool.getId(), e);
|
|
||||||
System.out.println("工具执行失败: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ConsoleHelper.printInvalidOption();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
package com.example.workutils.system.tool;
|
|
||||||
|
|
||||||
import com.example.workutils.system.ConsoleHelper;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.util.Scanner;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 工具基类
|
|
||||||
* 提供共享的菜单循环模板方法,消除各Menu中的重复代码
|
|
||||||
* 子类只需实现handleChoice()定义具体交互逻辑
|
|
||||||
*
|
|
||||||
* 控制台I/O方法委托给ConsoleHelper,日志方法保留在此类
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public abstract class AbstractTool implements Tool {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模板方法:标准菜单交互循环
|
|
||||||
* displayMenu → readChoice → if 0 return → handleChoice → repeat
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void execute(Scanner scanner) {
|
|
||||||
while (true) {
|
|
||||||
ConsoleHelper.printMenuTitle(getName());
|
|
||||||
ConsoleHelper.displayMenu(getMenuOptions());
|
|
||||||
|
|
||||||
int choice = ConsoleHelper.readChoice(scanner);
|
|
||||||
scanner.nextLine();
|
|
||||||
|
|
||||||
if (choice == 0) {
|
|
||||||
info("返回上级菜单");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
handleChoice(choice, scanner);
|
|
||||||
} catch (Exception e) {
|
|
||||||
error(getName() + "执行失败", e);
|
|
||||||
ConsoleHelper.printError(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理子菜单选择,子类实现具体switch-case逻辑
|
|
||||||
*/
|
|
||||||
protected abstract void handleChoice(int choice, Scanner scanner) throws Exception;
|
|
||||||
|
|
||||||
// ============ 日志方法 ============
|
|
||||||
|
|
||||||
protected void info(String message) {
|
|
||||||
log.info(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void info(String message, Object... args) {
|
|
||||||
log.info(message, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void error(String message) {
|
|
||||||
log.error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void error(String message, Exception e) {
|
|
||||||
log.error(message, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ 控制台I/O方法(委托给ConsoleHelper,子类可直接调用) ============
|
|
||||||
|
|
||||||
protected void printMenuTitle(String title) {
|
|
||||||
ConsoleHelper.printMenuTitle(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void displayMenu(String[] options) {
|
|
||||||
ConsoleHelper.displayMenu(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void printSuccess(String operation) {
|
|
||||||
ConsoleHelper.printSuccess(operation);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void printError(String message) {
|
|
||||||
ConsoleHelper.printError(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void printInvalidOption() {
|
|
||||||
ConsoleHelper.printInvalidOption();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+55
-23
@@ -1,5 +1,6 @@
|
|||||||
package com.example.workutils.system.tool;
|
package com.example.workutils.system.tool;
|
||||||
|
|
||||||
|
import com.example.workutils.system.ConsoleHelper;
|
||||||
import com.example.workutils.system.config.WorkUtilsProperties;
|
import com.example.workutils.system.config.WorkUtilsProperties;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -10,11 +11,14 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 工具注册中心
|
* 工具注册中心
|
||||||
* 自动发现Spring容器中的Tool Bean,按配置过滤启用/禁用
|
* 自动发现 Spring 容器中的 Tool Bean,按配置过滤启用/禁用
|
||||||
|
* 同时负责主菜单循环(从 MenuRunner 合并)
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class ToolRegistry {
|
public class Registry {
|
||||||
|
|
||||||
|
private static final int EXIT_CODE = 0;
|
||||||
|
|
||||||
private final List<Tool> allTools;
|
private final List<Tool> allTools;
|
||||||
private final WorkUtilsProperties properties;
|
private final WorkUtilsProperties properties;
|
||||||
@@ -22,11 +26,7 @@ public class ToolRegistry {
|
|||||||
private Map<String, Tool> toolByIdMap;
|
private Map<String, Tool> toolByIdMap;
|
||||||
private Map<String, Tool> toolByCommandMap;
|
private Map<String, Tool> toolByCommandMap;
|
||||||
|
|
||||||
/**
|
public Registry(List<Tool> tools, WorkUtilsProperties properties) {
|
||||||
* Spring自动注入所有Tool Bean
|
|
||||||
* 新增工具只需创建@Component类实现Tool接口,无需修改此类
|
|
||||||
*/
|
|
||||||
public ToolRegistry(List<Tool> tools, WorkUtilsProperties properties) {
|
|
||||||
this.allTools = tools;
|
this.allTools = tools;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,6 @@ public class ToolRegistry {
|
|||||||
log.info("跳过已禁用工具: {} [{}]", tool.getName(), tool.getId());
|
log.info("跳过已禁用工具: {} [{}]", tool.getName(), tool.getId());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 工具隔离:单个工具初始化异常不影响平台和其他工具
|
|
||||||
log.error("工具初始化失败: {} [{}]", tool.getName(), tool.getId(), e);
|
log.error("工具初始化失败: {} [{}]", tool.getName(), tool.getId(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,33 +59,66 @@ public class ToolRegistry {
|
|||||||
log.info("工具注册完成: {}/{} 已启用", enabledTools.size(), allTools.size());
|
log.info("工具注册完成: {}/{} 已启用", enabledTools.size(), allTools.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// ==================== 主菜单(从 MenuRunner 合并) ====================
|
||||||
* 获取所有已启用工具
|
|
||||||
*/
|
public void runMainMenu(Scanner scanner) {
|
||||||
|
log.info("启动主菜单");
|
||||||
|
while (true) {
|
||||||
|
ConsoleHelper.printMenuTitle("主菜单");
|
||||||
|
displayMainMenu();
|
||||||
|
|
||||||
|
int choice = ConsoleHelper.readChoice(scanner);
|
||||||
|
scanner.nextLine();
|
||||||
|
|
||||||
|
if (choice == EXIT_CODE) {
|
||||||
|
log.info("用户退出系统");
|
||||||
|
System.out.println("感谢使用,再见!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatchTool(choice, scanner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayMainMenu() {
|
||||||
|
System.out.println("请选择操作:");
|
||||||
|
for (int i = 0; i < enabledTools.size(); i++) {
|
||||||
|
System.out.println((i + 1) + ". " + enabledTools.get(i).getName());
|
||||||
|
}
|
||||||
|
System.out.println(EXIT_CODE + ". 退出系统");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatchTool(int choice, Scanner scanner) {
|
||||||
|
int index = choice - 1;
|
||||||
|
if (index >= 0 && index < enabledTools.size()) {
|
||||||
|
Tool tool = enabledTools.get(index);
|
||||||
|
try {
|
||||||
|
tool.execute(scanner);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("工具执行失败: {} [{}]", tool.getName(), tool.getId(), e);
|
||||||
|
System.out.println("工具执行失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ConsoleHelper.printInvalidOption();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 查找方法 ====================
|
||||||
|
|
||||||
public List<Tool> getEnabledTools() {
|
public List<Tool> getEnabledTools() {
|
||||||
return Collections.unmodifiableList(enabledTools);
|
return Collections.unmodifiableList(enabledTools);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 按ID查找工具
|
|
||||||
*/
|
|
||||||
public Optional<Tool> getToolById(String id) {
|
public Optional<Tool> getToolById(String id) {
|
||||||
return Optional.ofNullable(toolByIdMap.get(id));
|
return Optional.ofNullable(toolByIdMap.get(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 按命令行命令名查找工具
|
|
||||||
*/
|
|
||||||
public Optional<Tool> getToolByCommand(String command) {
|
public Optional<Tool> getToolByCommand(String command) {
|
||||||
return Optional.ofNullable(toolByCommandMap.get(command));
|
return Optional.ofNullable(toolByCommandMap.get(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// ==================== 启用/禁用解析 ====================
|
||||||
* 根据配置解析启用的工具ID集合
|
|
||||||
* 优先级: enabled白名单 > disabled黑名单 > 全部启用
|
|
||||||
*
|
|
||||||
* @return null表示全部启用,否则为启用的ID集合
|
|
||||||
*/
|
|
||||||
private Set<String> resolveEnabledIds() {
|
private Set<String> resolveEnabledIds() {
|
||||||
WorkUtilsProperties.ToolsConfig toolsConfig = properties.getTools();
|
WorkUtilsProperties.ToolsConfig toolsConfig = properties.getTools();
|
||||||
if (toolsConfig == null) {
|
if (toolsConfig == null) {
|
||||||
@@ -1,53 +1,90 @@
|
|||||||
package com.example.workutils.system.tool;
|
package com.example.workutils.system.tool;
|
||||||
|
|
||||||
|
import com.example.workutils.system.ConsoleHelper;
|
||||||
|
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 工具策略接口
|
* 工具策略接口
|
||||||
* 所有可插拔工具实现此接口,Spring自动发现Tool Bean
|
* 所有可插拔工具实现此接口,Spring 自动发现 Tool Bean
|
||||||
|
* <p>
|
||||||
|
* 提供交互式菜单(execute)和命令行(executeCommand)两种执行模式。
|
||||||
|
* 交互模式由默认 execute() 模板方法驱动,子类实现 handleChoice() 定义选择逻辑。
|
||||||
*/
|
*/
|
||||||
public interface Tool {
|
public interface Tool {
|
||||||
|
|
||||||
/**
|
/** 工具唯一标识(如 "scan", "mybatis") */
|
||||||
* 工具唯一标识(用于配置启用/禁用)
|
|
||||||
* 示例: "scan", "mybatis", "batch", "git-health", "mybatis-generator"
|
|
||||||
*/
|
|
||||||
String getId();
|
String getId();
|
||||||
|
|
||||||
/**
|
/** 菜单显示名称(如 "关键词扫描", "MyBatis SQL导出") */
|
||||||
* 菜单显示名称
|
|
||||||
* 示例: "关键词扫描", "MyBatis导出"
|
|
||||||
*/
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
/**
|
/** 子菜单选项,返回空数组表示无子菜单 */
|
||||||
* 子菜单选项
|
|
||||||
* 返回空数组表示无子菜单
|
|
||||||
*/
|
|
||||||
String[] getMenuOptions();
|
String[] getMenuOptions();
|
||||||
|
|
||||||
/**
|
/** 命令行命令名(如 "sql", "scan"),返回空字符串表示不支持命令行模式 */
|
||||||
* 命令行模式下的命令名,如 "sql", "scan", "batch"
|
|
||||||
* 返回空字符串表示不支持命令行模式
|
|
||||||
*/
|
|
||||||
default String getCommandName() {
|
default String getCommandName() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// ==================== 交互模式(模板方法) ====================
|
||||||
* 执行工具的交互会话
|
|
||||||
*
|
|
||||||
* @param scanner 控制台输入
|
|
||||||
*/
|
|
||||||
void execute(Scanner scanner);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 命令行模式执行(无交互)
|
* 交互式菜单循环(默认实现,从 AbstractTool 合并而来)
|
||||||
* 默认实现打印不支持提示
|
* displayMenu → readChoice → if 0 return → handleChoice → repeat
|
||||||
*
|
*/
|
||||||
* @param args 命令行参数(不含命令名本身)
|
default void execute(Scanner scanner) {
|
||||||
|
while (true) {
|
||||||
|
ConsoleHelper.printMenuTitle(getName());
|
||||||
|
ConsoleHelper.displayMenu(getMenuOptions());
|
||||||
|
|
||||||
|
int choice = ConsoleHelper.readChoice(scanner);
|
||||||
|
scanner.nextLine();
|
||||||
|
|
||||||
|
if (choice == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
handleChoice(choice, scanner);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ConsoleHelper.printError(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 处理子菜单选择,子类实现具体分发逻辑 */
|
||||||
|
default void handleChoice(int choice, Scanner scanner) throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 命令行模式 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命令行模式执行(无交互),默认打印不支持提示
|
||||||
*/
|
*/
|
||||||
default void executeCommand(String... args) throws Exception {
|
default void executeCommand(String... args) throws Exception {
|
||||||
System.out.println("工具 [" + getName() + "] 不支持命令行模式");
|
System.out.println("工具 [" + getName() + "] 不支持命令行模式");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 控制台输出辅助方法 ====================
|
||||||
|
|
||||||
|
default void printMenuTitle(String title) {
|
||||||
|
ConsoleHelper.printMenuTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void displayMenu(String[] options) {
|
||||||
|
ConsoleHelper.displayMenu(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void printSuccess(String operation) {
|
||||||
|
ConsoleHelper.printSuccess(operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void printError(String message) {
|
||||||
|
ConsoleHelper.printError(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void printInvalidOption() {
|
||||||
|
ConsoleHelper.printInvalidOption();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user