插件版本功能更新完毕
This commit is contained in:
@@ -493,10 +493,23 @@ public class GitSyncPlugin implements Plugin, InitializingBean {
|
||||
log.warn("fetch 失败: {} -> {}", repoPath, r1.error);
|
||||
}
|
||||
|
||||
// 2. checkout
|
||||
// 2. checkout:先 stash 本地修改,避免因未提交修改导致 checkout 失败
|
||||
boolean didStash = false;
|
||||
CmdResult r2 = runGit(repoPath, "git checkout " + branch);
|
||||
if (!r2.ok) {
|
||||
// checkout 失败常见原因:有未提交修改 → stash 后重试
|
||||
CmdResult stashResult = runGit(repoPath, "git stash push -m \"workutils-auto-stash\"");
|
||||
if (stashResult.ok) {
|
||||
didStash = true;
|
||||
r2 = runGit(repoPath, "git checkout " + branch);
|
||||
}
|
||||
}
|
||||
if (!r2.ok) {
|
||||
log.warn("checkout 失败: {} -> {},标记为损坏", repoPath, r2.error);
|
||||
// 如果 stash 了但 checkout 仍失败,恢复 stash
|
||||
if (didStash) {
|
||||
runGit(repoPath, "git stash pop");
|
||||
}
|
||||
SyncResult r = SyncResult.DAMAGED;
|
||||
r.error = "checkout 失败: " + r2.error;
|
||||
r.remoteUrl = getRemoteUrl(repoPath, baseUrlMap);
|
||||
@@ -507,12 +520,24 @@ public class GitSyncPlugin implements Plugin, InitializingBean {
|
||||
CmdResult r3 = runGit(repoPath, "git pull origin " + branch);
|
||||
if (!r3.ok) {
|
||||
log.warn("pull 失败: {} -> {},标记为损坏", repoPath, r3.error);
|
||||
// pull 失败时恢复 stash(如果 stash 过)
|
||||
if (didStash) {
|
||||
runGit(repoPath, "git stash pop");
|
||||
}
|
||||
SyncResult r = SyncResult.DAMAGED;
|
||||
r.error = "pull 失败: " + r3.error;
|
||||
r.remoteUrl = getRemoteUrl(repoPath, baseUrlMap);
|
||||
return r;
|
||||
}
|
||||
|
||||
// 4. 恢复之前 stash 的修改(忽略冲突,保留 stash 让用户手动处理)
|
||||
if (didStash) {
|
||||
CmdResult popResult = runGit(repoPath, "git stash pop");
|
||||
if (!popResult.ok) {
|
||||
log.warn("stash pop 有冲突: {} -> {},已保留在 stash 中", repoPath, popResult.error);
|
||||
}
|
||||
}
|
||||
|
||||
SyncResult result = SyncResult.OK;
|
||||
result.output = r3.output;
|
||||
return result;
|
||||
|
||||
+87
-51
@@ -158,8 +158,9 @@ public class MyBatisGeneratorWindow {
|
||||
ToggleButton btn = new ToggleButton(label);
|
||||
btn.setToggleGroup(fillTargetGroup);
|
||||
btn.setUserData(userData);
|
||||
btn.setPrefWidth(85);
|
||||
btn.setStyle("-fx-font-size: " + fsButton() + "px; -fx-cursor: hand;");
|
||||
btn.setMinWidth(Region.USE_PREF_SIZE);
|
||||
btn.setStyle("-fx-font-size: " + fsButton() + "px; -fx-cursor: hand; "
|
||||
+ "-fx-padding: 6 16;");
|
||||
// 点击按钮时,将当前树节点路径填充到对应字段
|
||||
btn.setOnAction(e -> {
|
||||
TreeItem<String> selected = projectTree.getSelectionModel().getSelectedItem();
|
||||
@@ -176,71 +177,103 @@ public class MyBatisGeneratorWindow {
|
||||
boolean active = (btn == cur);
|
||||
btn.setStyle(active
|
||||
? "-fx-background-color: #4a90d9; -fx-text-fill: white; -fx-font-size: " + fsButton() + "px; "
|
||||
+ "-fx-background-radius: 4; -fx-padding: 6 18;"
|
||||
+ "-fx-background-radius: 4; -fx-padding: 6 16;"
|
||||
: "-fx-background-color: #e0e0e0; -fx-text-fill: #333; -fx-font-size: " + fsButton() + "px; "
|
||||
+ "-fx-background-radius: 4; -fx-padding: 6 18;");
|
||||
+ "-fx-background-radius: 4; -fx-padding: 6 16;");
|
||||
});
|
||||
// 初始化默认选中样式
|
||||
btn.fire();
|
||||
return btn;
|
||||
}
|
||||
|
||||
private HBox createDbInfoSection() {
|
||||
HBox box = new HBox(15);
|
||||
box.setPadding(new Insets(8, 12, 8, 12));
|
||||
box.setStyle("-fx-background-color: #e8f0fe; -fx-background-radius: 4;");
|
||||
box.setAlignment(Pos.CENTER_LEFT);
|
||||
private boolean refreshingDatasource = false;
|
||||
|
||||
private HBox createDbInfoSection() {
|
||||
// 与 SplitPane 相同的比例:左侧 28% = 左面板宽度,右侧 72%
|
||||
GridPane grid = new GridPane();
|
||||
grid.setHgap(10);
|
||||
grid.setPadding(new Insets(8, 12, 8, 12));
|
||||
grid.setStyle("-fx-background-color: #e8f0fe; -fx-background-radius: 4;");
|
||||
|
||||
ColumnConstraints colLeft = new ColumnConstraints();
|
||||
colLeft.setPercentWidth(28);
|
||||
ColumnConstraints colRight = new ColumnConstraints();
|
||||
colRight.setPercentWidth(72);
|
||||
grid.getColumnConstraints().addAll(colLeft, colRight);
|
||||
|
||||
// --- 左侧:数据源选择,宽度与下方左面板对齐 ---
|
||||
Label dsLabel = new Label("数据源:");
|
||||
dsLabel.setFont(Font.font("Microsoft YaHei", fsBody()));
|
||||
dsLabel.setMinWidth(Region.USE_PREF_SIZE);
|
||||
|
||||
datasourceCmb = new ComboBox<>();
|
||||
datasourceCmb.setPrefWidth(160);
|
||||
datasourceCmb.setStyle("-fx-font-size: " + fsBody() + "px;");
|
||||
HBox.setHgrow(datasourceCmb, Priority.ALWAYS);
|
||||
|
||||
Button refreshDsBtn = new Button("刷新");
|
||||
refreshDsBtn.setMinWidth(Region.USE_PREF_SIZE);
|
||||
refreshDsBtn.setStyle("-fx-font-size: " + (fsBody() - 1) + "px; -fx-padding: 2 8;");
|
||||
|
||||
// 加载数据源列表
|
||||
refreshDatasourceList();
|
||||
datasourceCmb.setOnAction(e -> {
|
||||
if (refreshingDatasource) return;
|
||||
String selected = datasourceCmb.getValue();
|
||||
if (selected != null) {
|
||||
callback.switchDatasource("默认配置".equals(selected) ? null : selected);
|
||||
updateDbInfo();
|
||||
}
|
||||
});
|
||||
|
||||
dbUrlLabel = new Label();
|
||||
dbUrlLabel.setFont(Font.font("Consolas", fsBody() - 1));
|
||||
dbUserLabel = new Label();
|
||||
dbUserLabel.setFont(Font.font("Microsoft YaHei", fsBody() - 1));
|
||||
updateDbInfo();
|
||||
|
||||
Button refreshDsBtn = new Button("刷新");
|
||||
refreshDsBtn.setStyle("-fx-font-size: " + (fsBody() - 1) + "px; -fx-padding: 2 8;");
|
||||
refreshDsBtn.setOnAction(e -> {
|
||||
refreshDatasourceList();
|
||||
updateDbInfo();
|
||||
});
|
||||
|
||||
VBox infoBox = new VBox(3, dbUrlLabel, dbUserLabel);
|
||||
HBox leftBox = new HBox(8, dsLabel, datasourceCmb, refreshDsBtn);
|
||||
leftBox.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
box.getChildren().addAll(dsLabel, datasourceCmb, refreshDsBtn, infoBox);
|
||||
return box;
|
||||
// --- 右侧:连接信息,白底灰框 ---
|
||||
dbUrlLabel = new Label();
|
||||
dbUrlLabel.setFont(Font.font("Consolas", fsBody() - 1));
|
||||
dbUrlLabel.setMaxWidth(Double.MAX_VALUE);
|
||||
dbUrlLabel.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);
|
||||
dbUserLabel = new Label();
|
||||
dbUserLabel.setFont(Font.font("Microsoft YaHei", fsBody() - 1));
|
||||
updateDbInfo();
|
||||
|
||||
VBox infoBox = new VBox(3, dbUrlLabel, dbUserLabel);
|
||||
infoBox.setPadding(new Insets(4, 10, 4, 10));
|
||||
infoBox.setStyle("-fx-border-color: #b0c4de; -fx-border-width: 1; -fx-border-radius: 3; "
|
||||
+ "-fx-background-color: #ffffff; -fx-background-radius: 3;");
|
||||
infoBox.setAlignment(Pos.CENTER_LEFT);
|
||||
infoBox.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
grid.add(leftBox, 0, 0);
|
||||
grid.add(infoBox, 1, 0);
|
||||
|
||||
HBox wrapper = new HBox(grid);
|
||||
HBox.setHgrow(grid, Priority.ALWAYS);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private void refreshDatasourceList() {
|
||||
String current = datasourceCmb.getValue();
|
||||
datasourceCmb.getItems().clear();
|
||||
datasourceCmb.getItems().add("默认配置");
|
||||
datasourceCmb.getItems().addAll(callback.getDatasourceNames());
|
||||
if (current != null && datasourceCmb.getItems().contains(current)) {
|
||||
datasourceCmb.setValue(current);
|
||||
} else {
|
||||
String dsName = callback.getCurrentDatasourceName();
|
||||
if (dsName != null && datasourceCmb.getItems().contains(dsName)) {
|
||||
datasourceCmb.setValue(dsName);
|
||||
refreshingDatasource = true;
|
||||
try {
|
||||
String current = datasourceCmb.getValue();
|
||||
datasourceCmb.getItems().clear();
|
||||
datasourceCmb.getItems().add("默认配置");
|
||||
datasourceCmb.getItems().addAll(callback.getDatasourceNames());
|
||||
if (current != null && datasourceCmb.getItems().contains(current)) {
|
||||
datasourceCmb.setValue(current);
|
||||
} else {
|
||||
datasourceCmb.setValue("默认配置");
|
||||
String dsName = callback.getCurrentDatasourceName();
|
||||
if (dsName != null && datasourceCmb.getItems().contains(dsName)) {
|
||||
datasourceCmb.setValue(dsName);
|
||||
} else {
|
||||
datasourceCmb.setValue("默认配置");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
refreshingDatasource = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,22 +312,7 @@ public class MyBatisGeneratorWindow {
|
||||
|
||||
VBox.setVgrow(projectTree, Priority.ALWAYS);
|
||||
|
||||
// 填充目标选择(按钮组)
|
||||
Label quickLabel = new Label("点击按钮填充到:");
|
||||
quickLabel.setFont(Font.font("Microsoft YaHei", fsBody()));
|
||||
quickLabel.setPadding(new Insets(10, 0, 2, 0));
|
||||
|
||||
this.fillTargetGroup = new ToggleGroup();
|
||||
|
||||
ToggleButton btnModel = createFillButton("Model", "model");
|
||||
btnModel.setSelected(true);
|
||||
ToggleButton btnXml = createFillButton("XML", "xml");
|
||||
ToggleButton btnMapper = createFillButton("Mapper", "mapper");
|
||||
|
||||
HBox rbBox = new HBox(10, btnModel, btnXml, btnMapper);
|
||||
rbBox.setPadding(new Insets(5, 0, 5, 0));
|
||||
|
||||
panel.getChildren().addAll(treeTitle, projectTree, quickLabel, rbBox);
|
||||
panel.getChildren().addAll(treeTitle, projectTree);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -410,9 +428,27 @@ public class MyBatisGeneratorWindow {
|
||||
VBox box = new VBox(8);
|
||||
box.setPadding(new Insets(10, 0, 0, 0));
|
||||
|
||||
// 标题行:左侧"输出目录设置",右侧快速填充按钮
|
||||
Label dirLabel = new Label("输出目录设置:");
|
||||
dirLabel.setFont(Font.font("Microsoft YaHei", fsSection()));
|
||||
|
||||
this.fillTargetGroup = new ToggleGroup();
|
||||
|
||||
Label quickLabel = new Label("快速填充:");
|
||||
quickLabel.setFont(Font.font("Microsoft YaHei", fsBody()));
|
||||
quickLabel.setMinWidth(Region.USE_PREF_SIZE);
|
||||
|
||||
ToggleButton btnModel = createFillButton("Model", "model");
|
||||
btnModel.setSelected(true);
|
||||
ToggleButton btnXml = createFillButton("XML", "xml");
|
||||
ToggleButton btnMapper = createFillButton("Mapper", "mapper");
|
||||
|
||||
Region spacer = new Region();
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
|
||||
HBox headerRow = new HBox(10, dirLabel, spacer, quickLabel, btnModel, btnXml, btnMapper);
|
||||
headerRow.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
HBox modelRow = createDirRow("Model (PO)", fm -> modelDirField = fm);
|
||||
modelDirField = (TextField) modelRow.getChildren().get(1);
|
||||
HBox xmlRow = createDirRow("XML Mapper", fm -> xmlDirField = fm);
|
||||
@@ -422,7 +458,7 @@ public class MyBatisGeneratorWindow {
|
||||
|
||||
loadDefaultDirs();
|
||||
|
||||
box.getChildren().addAll(dirLabel, modelRow, xmlRow, mapperRow);
|
||||
box.getChildren().addAll(headerRow, modelRow, xmlRow, mapperRow);
|
||||
return box;
|
||||
}
|
||||
|
||||
|
||||
+108
-5
@@ -101,7 +101,7 @@ public class MyBatisGeneratorService {
|
||||
DbConnection db = getDbConnection();
|
||||
String dbName = extractDatabaseName(db.url);
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(db.url, db.username, db.password)) {
|
||||
try (Connection conn = openConnection(db)) {
|
||||
String sql = "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME LIKE ?";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setString(1, dbName);
|
||||
@@ -124,7 +124,7 @@ public class MyBatisGeneratorService {
|
||||
DbConnection db = getDbConnection();
|
||||
String dbName = extractDatabaseName(db.url);
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(db.url, db.username, db.password)) {
|
||||
try (Connection conn = openConnection(db)) {
|
||||
String sql = "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? ORDER BY TABLE_NAME";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setString(1, dbName);
|
||||
@@ -138,6 +138,39 @@ public class MyBatisGeneratorService {
|
||||
return tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开数据库连接。先尝试配置的驱动,失败则回退 MySQL 驱动并改写 URL。
|
||||
*/
|
||||
private Connection openConnection(DbConnection db) throws SQLException {
|
||||
// 第一优先级:尝试用配置的驱动连接
|
||||
try {
|
||||
Class.forName(db.driverClass);
|
||||
return DriverManager.getConnection(db.url, db.username, db.password);
|
||||
} catch (Exception e) {
|
||||
log.warn("驱动 {} 不可用或连接失败,尝试 MySQL 驱动回退: {}", db.driverClass, e.getMessage());
|
||||
}
|
||||
|
||||
// 第二优先级:MySQL 驱动回退
|
||||
try {
|
||||
Class.forName("com.mysql.jdbc.Driver");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
|
||||
// 第三优先级:尝试 MySQL 5.1 之后的驱动类名
|
||||
try {
|
||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
|
||||
// 将 jdbc:oceanbase:// 替换为 jdbc:mysql://(OB 4.x MySQL 模式兼容 MySQL 协议)
|
||||
String fallbackUrl = db.url;
|
||||
if (fallbackUrl.startsWith("jdbc:oceanbase://")) {
|
||||
fallbackUrl = fallbackUrl.replace("jdbc:oceanbase://", "jdbc:mysql://");
|
||||
log.info("URL 已改写为 MySQL 协议: {}", fallbackUrl);
|
||||
}
|
||||
return DriverManager.getConnection(fallbackUrl, db.username, db.password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前生效的数据库连接信息
|
||||
* 优先级: 选中的数据源 > 外部配置(workutils.config) > 内置classpath属性
|
||||
@@ -145,11 +178,12 @@ public class MyBatisGeneratorService {
|
||||
private DbConnection getDbConnection() {
|
||||
DatasourceConfig ds = getCurrentDatasource();
|
||||
if (ds != null) {
|
||||
return new DbConnection(ds.getUrl(), ds.getUsername(), ds.getPassword());
|
||||
return new DbConnection(ds.getDriver(), ds.getUrl(), ds.getUsername(), ds.getPassword());
|
||||
}
|
||||
// 回退: data/ 外部配置 → classpath 内置配置
|
||||
Properties props = loadMybatisProperties();
|
||||
return new DbConnection(
|
||||
props.getProperty("db_driver", "com.mysql.jdbc.Driver"),
|
||||
props.getProperty("db_url", ""),
|
||||
props.getProperty("db_username", ""),
|
||||
props.getProperty("db_password", "")
|
||||
@@ -158,10 +192,12 @@ public class MyBatisGeneratorService {
|
||||
|
||||
/** 内部数据类:数据库连接信息 */
|
||||
private static class DbConnection {
|
||||
final String driverClass;
|
||||
final String url;
|
||||
final String username;
|
||||
final String password;
|
||||
DbConnection(String url, String username, String password) {
|
||||
DbConnection(String driverClass, String url, String username, String password) {
|
||||
this.driverClass = driverClass;
|
||||
this.url = url;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
@@ -264,6 +300,10 @@ public class MyBatisGeneratorService {
|
||||
"<properties url=\"" + fileUrl + "\" />");
|
||||
}
|
||||
|
||||
// ★ 关键修复:将 JDBC 连接属性直接注入到 XML 中(绕过 properties 文件),
|
||||
// 并自动执行 OB→MySQL 驱动/URL 兜底,确保 MBG 总能连上数据库
|
||||
content = injectJdbcFallback(content);
|
||||
|
||||
// 截掉 </generatorConfiguration> 之后的内容(防止尾随垃圾导致 XML 解析失败)
|
||||
int endIdx = content.lastIndexOf("</generatorConfiguration>");
|
||||
if (endIdx >= 0) {
|
||||
@@ -335,9 +375,25 @@ public class MyBatisGeneratorService {
|
||||
"$1" + java.util.regex.Matcher.quoteReplacement(mapperPkg) + "$2");
|
||||
}
|
||||
|
||||
// 从 JDBC URL 中提取数据库名作为 schema,避免 MyBatis Generator 找不到表
|
||||
String schema = "";
|
||||
try {
|
||||
Properties props = getConfigurationProperties();
|
||||
String url = props.getProperty("db_url", "");
|
||||
if (!url.isEmpty()) {
|
||||
schema = extractDatabaseName(url);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
StringBuilder tableElements = new StringBuilder();
|
||||
for (String tableName : tableNames) {
|
||||
tableElements.append(" <table schema=\"\" tableName=\"")
|
||||
// 必须同时设置 catalog 和 schema,OceanBase 驱动仅靠 schema 可能匹配不上
|
||||
tableElements.append(" <table catalog=\"")
|
||||
.append(schema)
|
||||
.append("\" schema=\"")
|
||||
.append(schema)
|
||||
.append("\" tableName=\"")
|
||||
.append(tableName)
|
||||
.append("\"\n")
|
||||
.append(" domainObjectName=\"")
|
||||
@@ -387,6 +443,53 @@ public class MyBatisGeneratorService {
|
||||
return new String[]{projectRoot, packageName};
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 JDBC 连接属性直接注入到 XML 中,并自动执行 OB→MySQL 驱动/URL 兜底。
|
||||
* 这样 MBG 不需要从外部 properties 文件读取连接信息,避免因 properties
|
||||
* 文件中写的是 OB 驱动而运行时类路径中只有 MySQL 驱动导致的连接失败。
|
||||
*/
|
||||
private String injectJdbcFallback(String xmlContent) {
|
||||
Properties props = getConfigurationProperties();
|
||||
String driver = props.getProperty("db_driver", "com.mysql.jdbc.Driver");
|
||||
String url = props.getProperty("db_url", "");
|
||||
String username = props.getProperty("db_username", "");
|
||||
String password = props.getProperty("db_password", "");
|
||||
|
||||
// 检测 OB 驱动是否可用,不可用则回退到 MySQL 驱动并改写 URL
|
||||
boolean obAvailable;
|
||||
try {
|
||||
Class.forName(driver);
|
||||
obAvailable = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
obAvailable = false;
|
||||
}
|
||||
if (!obAvailable && url.startsWith("jdbc:oceanbase://")) {
|
||||
log.info("MBG 配置: OB 驱动不可用,URL 改写为 MySQL 协议");
|
||||
url = url.replace("jdbc:oceanbase://", "jdbc:mysql://");
|
||||
driver = "com.mysql.jdbc.Driver";
|
||||
}
|
||||
|
||||
// 直接替换 XML 中的 ${db_driver} / ${db_url} / ${db_username} / ${db_password} 占位符
|
||||
// 注意: 只替换 jdbcConnection 元素中的属性值,避免影响其他地方
|
||||
// 对可能含 & 等 XML 特殊字符的值做转义
|
||||
return xmlContent
|
||||
.replace("${db_driver}", xmlEscape(driver))
|
||||
.replace("${db_url}", xmlEscape(url))
|
||||
.replace("${db_username}", xmlEscape(username))
|
||||
.replace("${db_password}", xmlEscape(password));
|
||||
}
|
||||
|
||||
/** 对注入到 XML 属性中的值做特殊字符转义 */
|
||||
private static String xmlEscape(String value) {
|
||||
if (value == null) return "";
|
||||
return value
|
||||
.replace("&", "&")
|
||||
.replace("\"", """)
|
||||
.replace("'", "'")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表名生成实体类名
|
||||
*/
|
||||
|
||||
@@ -58,7 +58,7 @@ public class ExternalConfigManager {
|
||||
public static final String KEY_FONT_BODY = "font.size.body"; // 正文/提示 默认14
|
||||
public static final String KEY_FONT_MONO = "font.size.mono"; // 等宽/代码 默认14
|
||||
|
||||
/** 配置节定义:名称 → 键列表 */
|
||||
/** 配置节定义:名称 → 键列表(MYBATIS 相关配置已迁移到 data/mybatis-generator.properties 独立管理) */
|
||||
private static final LinkedHashMap<String, String[]> SECTIONS = new LinkedHashMap<>();
|
||||
|
||||
static {
|
||||
@@ -68,13 +68,6 @@ public class ExternalConfigManager {
|
||||
SECTIONS.put("===== 数据文件路径 =====", new String[]{
|
||||
KEY_PROJECT_PATHS, KEY_DAMAGED_REPOS
|
||||
});
|
||||
SECTIONS.put("===== MyBatis 数据库连接(覆盖内置 mybatis-generator.properties)=====", new String[]{
|
||||
KEY_MYBATIS_DRIVER, KEY_MYBATIS_URL, KEY_MYBATIS_USERNAME,
|
||||
KEY_MYBATIS_PASSWORD
|
||||
});
|
||||
SECTIONS.put("===== MyBatis 代码生成包路径 =====", new String[]{
|
||||
KEY_MYBATIS_MODEL_PKG, KEY_MYBATIS_DAO_PKG, KEY_MYBATIS_SQLMAPPER_PKG
|
||||
});
|
||||
SECTIONS.put("===== 字体大小(显示设置) =====", new String[]{
|
||||
KEY_FONT_SECTION_TITLE, KEY_FONT_FIELD_LABEL, KEY_FONT_BUTTON,
|
||||
KEY_FONT_BODY, KEY_FONT_MONO
|
||||
|
||||
@@ -22,6 +22,7 @@ public class SettingsService {
|
||||
|
||||
private final WorkUtilsProperties properties;
|
||||
private final ExternalConfigManager configManager;
|
||||
private final DatasourceConfigManager datasourceConfigManager;
|
||||
|
||||
/**
|
||||
* 打开系统设置 GUI 窗口
|
||||
@@ -30,7 +31,7 @@ public class SettingsService {
|
||||
*/
|
||||
public void showSettings(Scanner scanner, Runnable onConfigChanged) {
|
||||
try {
|
||||
SettingsWindow window = new SettingsWindow(properties, configManager, onConfigChanged);
|
||||
SettingsWindow window = new SettingsWindow(properties, configManager, datasourceConfigManager, onConfigChanged);
|
||||
window.showAndWait();
|
||||
} catch (Exception e) {
|
||||
log.error("打开设置窗口失败,回退到控制台模式", e);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -69,11 +69,11 @@ public class WorkUtilsProperties {
|
||||
private final Map<String, String> mybatisOverrides = new LinkedHashMap<>();
|
||||
|
||||
// ---- 字体大小(显示设置) ----
|
||||
private int fontSectionTitle = 20; // 节标题
|
||||
private int fontFieldLabel = 18; // 字段标签
|
||||
private int fontButton = 18; // 按钮
|
||||
private int fontBody = 18; // 正文/提示
|
||||
private int fontMono = 18; // 等宽/代码
|
||||
private int fontSectionTitle = 24; // 节标题
|
||||
private int fontFieldLabel = 20; // 字段标签
|
||||
private int fontButton = 20; // 按钮
|
||||
private int fontBody = 20; // 正文/提示
|
||||
private int fontMono = 20; // 等宽/代码
|
||||
|
||||
// ==================== 外部配置加载 ====================
|
||||
|
||||
@@ -167,11 +167,11 @@ public class WorkUtilsProperties {
|
||||
projectPathsFile = defaults.get(ExternalConfigManager.KEY_PROJECT_PATHS);
|
||||
damagedReposFile = defaults.get(ExternalConfigManager.KEY_DAMAGED_REPOS);
|
||||
mybatisOverrides.clear();
|
||||
fontSectionTitle = 20;
|
||||
fontFieldLabel = 18;
|
||||
fontButton = 18;
|
||||
fontBody = 18;
|
||||
fontMono = 18;
|
||||
fontSectionTitle = 24;
|
||||
fontFieldLabel = 20;
|
||||
fontButton = 20;
|
||||
fontBody = 20;
|
||||
fontMono = 20;
|
||||
log.info("配置已重置为默认值");
|
||||
}
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ public class PluginManager {
|
||||
break;
|
||||
}
|
||||
|
||||
// 'S' / 's' 字符(readChoiceOrChar 将单字母转成负ASCII码)
|
||||
if (choice == -'S') {
|
||||
// '?' 字符(readChoiceOrChar 将单字母转成负ASCII码)
|
||||
if (choice == -'?') {
|
||||
settingsService.showSettings(scanner, pluginContext::resetConfigChecks);
|
||||
// JavaFX 后台线程在 Windows 上可能污染 System.in,
|
||||
// 清理残留字节并重建 Scanner,确保后续输入正常
|
||||
@@ -126,7 +126,7 @@ public class PluginManager {
|
||||
PluginDescriptor desc = enabledPlugins.get(i).getDescriptor();
|
||||
System.out.println((i + 1) + ". " + desc.getName() + " [v" + desc.getVersion() + "]");
|
||||
}
|
||||
System.out.println("S. 系统设置");
|
||||
System.out.println("?. 系统设置");
|
||||
System.out.println(EXIT_CODE + ". 退出系统");
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ public class PluginManager {
|
||||
System.out.println("插件 [" + desc.getName() + "] 配置异常:");
|
||||
System.out.println(configError);
|
||||
System.out.println();
|
||||
System.out.println("请进入「系统设置(S)」进行配置后再使用。");
|
||||
System.out.println("请进入「系统设置(?)」进行配置后再使用。");
|
||||
System.out.println("==============================");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
[
|
||||
{
|
||||
"name": "开发环境",
|
||||
"name": "本地环境-loacalhost-db",
|
||||
"driver": "com.mysql.jdbc.Driver",
|
||||
"url": "jdbc:mysql://localhost:3306/disburse?useUnicode=true&characterEncoding=utf8&useSSL=false",
|
||||
"username": "root",
|
||||
"password": "1Qaz@4772"
|
||||
},
|
||||
{
|
||||
"name": "SIT环境",
|
||||
"driver": "com.mysql.jdbc.Driver",
|
||||
"url": "jdbc:mysql://sit-server:3306/disburse?useUnicode=true&characterEncoding=utf8&useSSL=false",
|
||||
"username": "sit_user",
|
||||
"password": ""
|
||||
"name": "ft_loancapital_core_db",
|
||||
"driver": "com.oceanbase.jdbc.Driver",
|
||||
"url": "jdbc:oceanbase://ob4x-xyd.bestpay.dev-db:2883/ft_loancapital_core_db?rewriteBatchedStatements=true&allowMultiQueries=true&useLocalSessionState=true&useUnicode=true&characterEncoding=utf-8&socketTimeout=6000000",
|
||||
"username": "ft_loancapital_core_app@xydcs_gcz_tnt#ob4x_cluster_xyd",
|
||||
"password": "FT_LOANCAPITAL_CORE@123"
|
||||
},
|
||||
{
|
||||
"name": "生产环境(只读)",
|
||||
"driver": "com.mysql.jdbc.Driver",
|
||||
"url": "jdbc:mysql://prod-server:3306/disburse?useUnicode=true&characterEncoding=utf8&useSSL=false",
|
||||
"username": "readonly",
|
||||
"password": ""
|
||||
"name": "cf_loan_core_db",
|
||||
"driver": "com.oceanbase.jdbc.Driver",
|
||||
"url": "jdbc:oceanbase://ob4x-ky.bestpay.46-db:2883/cf_loan_core_db?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&socketTimeout=30000&connectTimeout=10000",
|
||||
"username": "cf_loan_core_app@obtest_tnt#ob4x_cluster_test",
|
||||
"password": "CF_LOAN_CORE@123"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user