修复问题
This commit is contained in:
@@ -143,6 +143,13 @@
|
|||||||
<version>1.2.12</version>
|
<version>1.2.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 将 Log4j2 API 调用桥接到 SLF4J,避免 "Log4j2 could not find a logging implementation" 警告 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-to-slf4j</artifactId>
|
||||||
|
<version>2.20.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba</groupId>
|
<groupId>com.alibaba</groupId>
|
||||||
<artifactId>easyexcel</artifactId>
|
<artifactId>easyexcel</artifactId>
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ public class ApiDocPlugin implements Plugin {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
private static final String[] MENU_OPTIONS = {
|
private static final String[] MENU_OPTIONS = {
|
||||||
"1. 自定义路径导出 (输入文件或目录路径)",
|
"1. 自定义路径导出(输入文件或目录路径)",
|
||||||
"2. 全限定名导出 (仅输入类名,自动匹配项目)",
|
"2. 全限定名导出 (仅输入类名,自动匹配项目)",
|
||||||
"3. 批量导出 (从配置文件读取项目列表,自动遍历所有模块)",
|
"3. 批量导出 (从配置文件选择项目导出)",
|
||||||
"0. 返回上级菜单"
|
"0. 返回上级菜单"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public class ApiDocPlugin implements Plugin {
|
|||||||
// ==================== 批量导出(遍历所有项目) ====================
|
// ==================== 批量导出(遍历所有项目) ====================
|
||||||
|
|
||||||
private void exportAll(Scanner scanner) throws Exception {
|
private void exportAll(Scanner scanner) throws Exception {
|
||||||
System.out.println("\n=== 批量导出(从 代码仓库项目路径.txt 读取项目列表)===");
|
System.out.println("\n=== 批量导出(按项目)===");
|
||||||
|
|
||||||
// 1) 从配置文件读取项目路径
|
// 1) 从配置文件读取项目路径
|
||||||
Path configFile = properties.getProjectPathsFilePath();
|
Path configFile = properties.getProjectPathsFilePath();
|
||||||
@@ -87,17 +87,45 @@ public class ApiDocPlugin implements Plugin {
|
|||||||
System.out.println("配置文件中未配置任何项目路径。");
|
System.out.println("配置文件中未配置任何项目路径。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("配置文件: " + configFile.toAbsolutePath());
|
|
||||||
System.out.println("配置项目数: " + projectPaths.size());
|
// 2) 列出项目,让用户选择
|
||||||
|
System.out.println("\n配置项目列表:");
|
||||||
|
for (int i = 0; i < projectPaths.size(); i++) {
|
||||||
|
String projPath = projectPaths.get(i);
|
||||||
|
String projName = Paths.get(projPath).getFileName().toString();
|
||||||
|
System.out.printf(" %d. %s (%s)%n", i + 1, projName, projPath);
|
||||||
|
}
|
||||||
|
System.out.println(" 0. 全部导出");
|
||||||
|
|
||||||
|
System.out.print("\n请选择要导出的项目 (1-" + projectPaths.size() + ",0 全部): ");
|
||||||
|
String choice = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
// 筛选要导出的项目路径
|
||||||
|
List<String> selectedPaths = new ArrayList<>();
|
||||||
|
if ("0".equals(choice)) {
|
||||||
|
selectedPaths.addAll(projectPaths);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
int idx = Integer.parseInt(choice) - 1;
|
||||||
|
if (idx < 0 || idx >= projectPaths.size()) {
|
||||||
|
System.out.println("无效选择。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedPaths.add(projectPaths.get(idx));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.out.println("无效输入。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
System.out.print("导出格式 (1-HTML / 2-Markdown / 3-两者都导出,默认 3): ");
|
System.out.print("导出格式 (1-HTML / 2-Markdown / 3-两者都导出,默认 3): ");
|
||||||
String fmt = scanner.nextLine().trim();
|
String fmt = scanner.nextLine().trim();
|
||||||
|
|
||||||
// 2) 扫描每个配置路径下所有模块
|
// 3) 扫描选中项目下所有模块
|
||||||
Set<String> seenSrcBases = new HashSet<>(); // 去重
|
Set<String> seenSrcBases = new HashSet<>();
|
||||||
List<ModuleInfo> modules = new ArrayList<>();
|
List<ModuleInfo> modules = new ArrayList<>();
|
||||||
|
|
||||||
for (String projPath : projectPaths) {
|
for (String projPath : selectedPaths) {
|
||||||
Path projDir = Paths.get(projPath);
|
Path projDir = Paths.get(projPath);
|
||||||
if (!Files.isDirectory(projDir)) {
|
if (!Files.isDirectory(projDir)) {
|
||||||
System.out.println(" [跳过] 目录不存在: " + projPath);
|
System.out.println(" [跳过] 目录不存在: " + projPath);
|
||||||
|
|||||||
@@ -489,6 +489,7 @@ public class JavaSourceParser {
|
|||||||
*/
|
*/
|
||||||
private List<FieldInfo> resolveDtoFieldsByShortName(String shortName, ClassInfo ci, Path srcBaseDir) {
|
private List<FieldInfo> resolveDtoFieldsByShortName(String shortName, ClassInfo ci, Path srcBaseDir) {
|
||||||
if (shortName == null || shortName.isEmpty()) return null;
|
if (shortName == null || shortName.isEmpty()) return null;
|
||||||
|
if (isInvalidTypeName(shortName)) return null; // 含非法字符(如引号),说明被错误解析
|
||||||
if (isSkipType(shortName) || shortName.contains(".")) {
|
if (isSkipType(shortName) || shortName.contains(".")) {
|
||||||
// 已是全限定名或为基础类型,直接按 FQN 解析
|
// 已是全限定名或为基础类型,直接按 FQN 解析
|
||||||
return resolveDtoFields(shortName.contains(".") ? shortName : ("java.lang." + shortName), srcBaseDir);
|
return resolveDtoFields(shortName.contains(".") ? shortName : ("java.lang." + shortName), srcBaseDir);
|
||||||
@@ -745,8 +746,20 @@ public class JavaSourceParser {
|
|||||||
*/
|
*/
|
||||||
private Path resolveDtonToPath(String fqn, Path srcBaseDir) {
|
private Path resolveDtonToPath(String fqn, Path srcBaseDir) {
|
||||||
if (fqn == null || srcBaseDir == null) return null;
|
if (fqn == null || srcBaseDir == null) return null;
|
||||||
String relativePath = fqn.replace('.', '/') + ".java";
|
String relativePath;
|
||||||
Path direct = srcBaseDir.resolve(relativePath);
|
try {
|
||||||
|
relativePath = fqn.replace('.', '/') + ".java";
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("非法 FQN,跳过 DTO 解析: {}", fqn);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Path direct;
|
||||||
|
try {
|
||||||
|
direct = srcBaseDir.resolve(relativePath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("非法路径,跳过 DTO 解析: {}", relativePath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (Files.isRegularFile(direct)) return direct;
|
if (Files.isRegularFile(direct)) return direct;
|
||||||
|
|
||||||
// 如果不在当前模块,尝试扫描父目录下所有模块的 src/main/java
|
// 如果不在当前模块,尝试扫描父目录下所有模块的 src/main/java
|
||||||
@@ -782,6 +795,20 @@ public class JavaSourceParser {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 类型名是否包含非法字符(如引号、换行等,说明被错误解析) */
|
||||||
|
private static boolean isInvalidTypeName(String name) {
|
||||||
|
if (name == null || name.isEmpty()) return true;
|
||||||
|
for (int i = 0; i < name.length(); i++) {
|
||||||
|
char c = name.charAt(i);
|
||||||
|
// 合法的 Java 类型名字符:字母、数字、.、$、_、<、>、,、空格、?、[、]
|
||||||
|
if (Character.isLetterOrDigit(c)) continue;
|
||||||
|
if (c == '.' || c == '$' || c == '_' || c == '<' || c == '>'
|
||||||
|
|| c == ',' || c == ' ' || c == '?' || c == '[' || c == ']') continue;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private int countChar(String s, char c) {
|
private int countChar(String s, char c) {
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (int i = 0; i < s.length(); i++) {
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
|||||||
+19
@@ -133,6 +133,19 @@ public class MyBatisGeneratorService {
|
|||||||
* 内部生成方法
|
* 内部生成方法
|
||||||
*/
|
*/
|
||||||
private String generateInternal(List<String> tableNames, boolean overwrite) throws Exception {
|
private String generateInternal(List<String> tableNames, boolean overwrite) throws Exception {
|
||||||
|
// 确保 targetProject 目录存在,避免 "does not exist" 警告
|
||||||
|
Properties props = getConfigurationProperties();
|
||||||
|
for (String key : new String[]{"model_target_project", "sqlmapper_target_project", "dao_target_project"}) {
|
||||||
|
String dir = props.getProperty(key);
|
||||||
|
if (dir != null && !dir.isEmpty()) {
|
||||||
|
File targetDir = new File(dir);
|
||||||
|
if (!targetDir.exists()) {
|
||||||
|
targetDir.mkdirs();
|
||||||
|
log.info("已创建目标目录: {}", targetDir.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
File tempConfigFile = createTempConfigWithTables(tableNames);
|
File tempConfigFile = createTempConfigWithTables(tableNames);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -183,6 +196,12 @@ public class MyBatisGeneratorService {
|
|||||||
content = sb.toString();
|
content = sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 截掉 </generatorConfiguration> 之后的内容(防止尾随垃圾导致 XML 解析失败)
|
||||||
|
int endIdx = content.lastIndexOf("</generatorConfiguration>");
|
||||||
|
if (endIdx >= 0) {
|
||||||
|
content = content.substring(0, endIdx + "</generatorConfiguration>".length());
|
||||||
|
}
|
||||||
|
|
||||||
java.util.regex.Pattern tablePattern = java.util.regex.Pattern.compile(
|
java.util.regex.Pattern tablePattern = java.util.regex.Pattern.compile(
|
||||||
"<table[^>]*/>|<table[^>]*>.*?</table>",
|
"<table[^>]*/>|<table[^>]*>.*?</table>",
|
||||||
java.util.regex.Pattern.DOTALL
|
java.util.regex.Pattern.DOTALL
|
||||||
|
|||||||
@@ -12,11 +12,11 @@
|
|||||||
<property name="replaceString" value="Criteria" />
|
<property name="replaceString" value="Criteria" />
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- 只保留Selective版本的方法 -->
|
<!-- 只保留Selective版本的方法 -->
|
||||||
<plugin type="com.example.workutils.biz.mybatis.service.generator.SelectiveOnlyPlugin" />
|
<plugin type="com.example.workutils.biz.mybatisgenerator.service.generator.SelectiveOnlyPlugin" />
|
||||||
<!-- 使用Lombok @Data注解,不生成getter/setter -->
|
<!-- 使用Lombok @Data注解,不生成getter/setter -->
|
||||||
<plugin type="com.example.workutils.biz.mybatis.service.generator.LombokPlugin" />
|
<plugin type="com.example.workutils.biz.mybatisgenerator.service.generator.LombokPlugin" />
|
||||||
|
|
||||||
<commentGenerator type="com.example.workutils.biz.mybatis.service.generator.CustomCommentGenerator">
|
<commentGenerator type="com.example.workutils.biz.mybatisgenerator.service.generator.CustomCommentGenerator">
|
||||||
<!-- 开启数据库字段的中文注释(保留表/字段备注) -->
|
<!-- 开启数据库字段的中文注释(保留表/字段备注) -->
|
||||||
<property name="addRemarkComments" value="true"/>
|
<property name="addRemarkComments" value="true"/>
|
||||||
</commentGenerator>
|
</commentGenerator>
|
||||||
@@ -52,7 +52,3 @@
|
|||||||
|
|
||||||
</context>
|
</context>
|
||||||
</generatorConfiguration>
|
</generatorConfiguration>
|
||||||
|
|
||||||
https://srd17321104074@code.srdcloud.cn/bestpay-cf/cf/cf/ft-loan-core
|
|
||||||
|
|
||||||
https://srd17321104074@code.srdcloud.cn/bestpay-cf/cf/ft-loan-core
|
|
||||||
Reference in New Issue
Block a user