From b2f0a44319360d288dfdd80c534d11b7cd8f0f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Mon, 9 Oct 2023 21:42:34 +0800 Subject: [PATCH 1/9] =?UTF-8?q?+=20=E6=A0=B7=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/light/theme/ThemeDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/light/theme/ThemeDialog.java b/src/main/java/com/light/theme/ThemeDialog.java index 88e1b02..fe7fa80 100644 --- a/src/main/java/com/light/theme/ThemeDialog.java +++ b/src/main/java/com/light/theme/ThemeDialog.java @@ -35,6 +35,7 @@ public final class ThemeDialog extends ModalDialog { thumbnailsGroup.selectedToggleProperty().addListener((obs, old, val) -> { if (val != null && val.getUserData() instanceof Theme theme) { + FxDataUtil.CURRENT_THEME_NAME.set(theme.getName()); Application.setUserAgentStylesheet(theme.getUserAgentStylesheet()); } }); -- Gitee From 4166b8c1c43165287f0bd1b5ad07a453cdeeed14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Mon, 9 Oct 2023 22:53:56 +0800 Subject: [PATCH 2/9] =?UTF-8?q?+=20=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/light/layout/MenuPane.java | 3 +- src/main/java/com/light/layout/NavItem.java | 21 ++++++++-- src/main/java/com/light/util/FxDataUtil.java | 8 ++++ .../java/com/light/view/NotificationView.java | 13 +++++++ src/main/resources/css/menu.css | 38 +++++++++++++++---- 5 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/light/view/NotificationView.java diff --git a/src/main/java/com/light/layout/MenuPane.java b/src/main/java/com/light/layout/MenuPane.java index 68e0cad..9bc9679 100644 --- a/src/main/java/com/light/layout/MenuPane.java +++ b/src/main/java/com/light/layout/MenuPane.java @@ -7,6 +7,7 @@ import com.light.util.FxUtil; import com.light.util.Lazy; import com.light.view.HomeView; import com.light.view.ManagerView; +import com.light.view.NotificationView; import javafx.geometry.Orientation; import javafx.geometry.Pos; import javafx.scene.control.Label; @@ -30,7 +31,7 @@ public class MenuPane extends StackPane { // 顶部导航栏 private final NavItem setting = new NavItem(new FontIcon(AntDesignIconsFilled.SETTING), "设置", new Lazy<>(ThemeDialog::new)); - private final NavItem notification = new NavItem(new FontIcon(AntDesignIconsFilled.NOTIFICATION), "通知", null); + private final NavItem notification = new NavItem(new FontIcon(AntDesignIconsFilled.NOTIFICATION), "通知", null, new NotificationView(), true); private final VBox topMenu = new VBox(setting, notification); // 动态导航栏 diff --git a/src/main/java/com/light/layout/NavItem.java b/src/main/java/com/light/layout/NavItem.java index edd90a3..a75bd9a 100644 --- a/src/main/java/com/light/layout/NavItem.java +++ b/src/main/java/com/light/layout/NavItem.java @@ -15,27 +15,42 @@ public class NavItem extends HBox { /** * 图标 */ - private Label iconLabel = new Label(); + private final Label iconLabel = new Label(); /** * 标题 */ - private Label titleLabel = new Label(); + private final Label titleLabel = new Label(); /** * 内容界面 */ - private Lazy content; + private final Lazy content; + + /** + * 通知 + */ + private final Node notice; + private final boolean noticeFlag; public NavItem(FontIcon fontIcon, String title, Lazy content) { + this(fontIcon, title, content, null, false); + } + + public NavItem(FontIcon fontIcon, String title, Lazy content, Node noticeLabel, boolean noticeFlag) { this.iconLabel.setGraphic(fontIcon); this.titleLabel.setText(title); this.content = content; + this.notice = noticeLabel; + this.noticeFlag = noticeFlag; initialize(); } private void initialize() { getChildren().addAll(iconLabel, titleLabel); + if (noticeFlag && notice != null) { + getChildren().add(notice); + } // 标题占满剩余空间 titleLabel.setMaxSize(Double.MAX_VALUE, USE_PREF_SIZE); HBox.setHgrow(titleLabel, Priority.ALWAYS); diff --git a/src/main/java/com/light/util/FxDataUtil.java b/src/main/java/com/light/util/FxDataUtil.java index 8091777..4d278ed 100644 --- a/src/main/java/com/light/util/FxDataUtil.java +++ b/src/main/java/com/light/util/FxDataUtil.java @@ -27,6 +27,9 @@ public final class FxDataUtil { public static final AtomicInteger UPDATE_NUMBER = new AtomicInteger(0); public static final SimpleIntegerProperty UPDATE_PROPERTY = new SimpleIntegerProperty(UPDATE_NUMBER.intValue()); + /** + * git项目集合 + */ public static final ObservableList GIT_PROJECT_OBSERVABLE_LIST = FXCollections.observableArrayList(); /** @@ -38,4 +41,9 @@ public final class FxDataUtil { * 所有主题 */ public static final List THEME_LIST = new ArrayList<>(7); + + /** + * 历史通知集合 + */ + public static final ObservableList HISTORY_NOTICE_LIST = FXCollections.observableArrayList(); } diff --git a/src/main/java/com/light/view/NotificationView.java b/src/main/java/com/light/view/NotificationView.java new file mode 100644 index 0000000..16e16b2 --- /dev/null +++ b/src/main/java/com/light/view/NotificationView.java @@ -0,0 +1,13 @@ +package com.light.view; + +import com.light.util.FxDataUtil; +import javafx.collections.ListChangeListener; +import javafx.scene.control.Label; + +public class NotificationView extends Label { + public NotificationView() { + super(FxDataUtil.HISTORY_NOTICE_LIST.size() + ""); + this.getStyleClass().add("notice-label"); + FxDataUtil.HISTORY_NOTICE_LIST.addListener((ListChangeListener) c -> setText(FxDataUtil.HISTORY_NOTICE_LIST.size() + "")); + } +} diff --git a/src/main/resources/css/menu.css b/src/main/resources/css/menu.css index 3abb496..f313809 100644 --- a/src/main/resources/css/menu.css +++ b/src/main/resources/css/menu.css @@ -34,10 +34,21 @@ -fx-text-fill: derive(-cf-text-color, 30%); } +.nav-item > .notice-label { + -fx-font-size: 14px; + -fx-pref-height: 30px; + -fx-alignment: center; + -fx-text-fill: derive(-cf-text-color, 30%); +} + .nav-item:hover > .name-label { -fx-text-fill: -cf-primary-color; } +.nav-item:hover > .notice-label { + -fx-text-fill: -cf-primary-color; +} + .nav-item:hover > .icon-label > .ikonli-font-icon { -fx-icon-color: -cf-primary-color; } @@ -108,23 +119,36 @@ -fx-icon-color: -cf-success-color; } -.cf-message{ +.cf-message { -fx-alignment: center-left; -fx-min-height: 40px; -fx-graphic-text-gap: 8px; -fx-padding: 0 10px; -fx-background-color: rgb(168, 70, 70); - -fx-background-radius:3px; + -fx-background-radius: 3px; -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.2), 10.0, 0, 0, 0); -fx-text-fill: -cf-text-color; -fx-font-size: 14px; -fx-wrap-text: true; } -.cf-message > .ikonli-font-icon{ + +.cf-message > .ikonli-font-icon { -fx-icon-color: -cf-primary-color; -fx-icon-size: 18px; } -.cf-message.success > .ikonli-font-icon{-fx-icon-color: -cf-success-color;} -.cf-message.info > .ikonli-font-icon{-fx-icon-color: -cf-info-color;} -.cf-message.warn > .ikonli-font-icon{-fx-icon-color: -cf-warn-color;} -.cf-message.danger > .ikonli-font-icon{-fx-icon-color: -cf-danger-color;} \ No newline at end of file + +.cf-message.success > .ikonli-font-icon { + -fx-icon-color: -cf-success-color; +} + +.cf-message.info > .ikonli-font-icon { + -fx-icon-color: -cf-info-color; +} + +.cf-message.warn > .ikonli-font-icon { + -fx-icon-color: -cf-warn-color; +} + +.cf-message.danger > .ikonli-font-icon { + -fx-icon-color: -cf-danger-color; +} \ No newline at end of file -- Gitee From 0aa6fd694c70731f40795487c1b9f4841595ec2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Tue, 10 Oct 2023 09:01:03 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=AD=97=E4=BD=93?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/css/menu.css | 6 +++--- src/main/resources/css/root.css | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/resources/css/menu.css b/src/main/resources/css/menu.css index f313809..fca6cca 100644 --- a/src/main/resources/css/menu.css +++ b/src/main/resources/css/menu.css @@ -24,21 +24,21 @@ .nav-item > .icon-label > .ikonli-font-icon { -fx-icon-size: 20px; - -fx-icon-color: derive(-cf-text-color, 30%); + -fx-icon-color: derive(-color-fg-default, 30%); } .nav-item > .name-label { -fx-font-size: 14px; -fx-pref-height: 30px; -fx-font-weight: bolder; - -fx-text-fill: derive(-cf-text-color, 30%); + -fx-text-fill: derive(-color-fg-default, 30%); } .nav-item > .notice-label { -fx-font-size: 14px; -fx-pref-height: 30px; -fx-alignment: center; - -fx-text-fill: derive(-cf-text-color, 30%); + -fx-text-fill: derive(-color-fg-default, 30%); } .nav-item:hover > .name-label { diff --git a/src/main/resources/css/root.css b/src/main/resources/css/root.css index 26a7725..1e94ac2 100644 --- a/src/main/resources/css/root.css +++ b/src/main/resources/css/root.css @@ -5,10 +5,10 @@ -fx-min-height: 40px; -fx-graphic-text-gap: 8px; -fx-padding: 0 10px; - -fx-background-color: rgb(255, 255, 255); + -fx-background-color: -color-bg-default; -fx-background-radius: 3px; -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.2), 10.0, 0, 0, 0); - -fx-text-fill: -cf-text-color; + -fx-text-fill: -color-fg-default; -fx-font-size: 14px; -fx-wrap-text: true; } -- Gitee From e1c6302eed03f966ac6068e751400141da8c4a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Tue, 10 Oct 2023 09:25:22 +0800 Subject: [PATCH 4/9] =?UTF-8?q?+=20=E8=B0=83=E6=95=B4=E8=BE=B9=E7=95=8C?= =?UTF-8?q?=E6=84=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/light/view/ManagerView.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/light/view/ManagerView.java b/src/main/java/com/light/view/ManagerView.java index c509130..f09db25 100644 --- a/src/main/java/com/light/view/ManagerView.java +++ b/src/main/java/com/light/view/ManagerView.java @@ -65,14 +65,13 @@ public class ManagerView extends StackPane { addLocalButton.setMnemonicParsing(true); updateButton.setMnemonicParsing(true); hBox.getChildren().addAll(searchField, addLocalButton, updateButton); - hBox.setPadding(new Insets(5, 0, 0, 0)); HBox.setHgrow(searchField, Priority.ALWAYS); // 初始化表格 initTable(); vBox.getChildren().addAll(hBox, tableView); - vBox.setPadding(new Insets(0, 1, 0, 1)); + vBox.setPadding(new Insets(5, 2, 5, 2)); VBox.setVgrow(tableView, Priority.ALWAYS); } -- Gitee From 37e1bb41dab8e65aa712ffb5f9ba38054ca1ac51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Tue, 10 Oct 2023 13:12:51 +0800 Subject: [PATCH 5/9] =?UTF-8?q?+=20=E5=A2=9E=E5=8A=A0h2=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/light/GitManagerApp.java | 24 +- src/main/java/com/light/util/DateUtils.java | 1023 +++++++++++++++++ src/main/java/com/light/util/H2PoolUtils.java | 182 +++ src/main/resources/db.properties | 9 + src/main/resources/db/schema.sql | 38 + 5 files changed, 1274 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/light/util/DateUtils.java create mode 100644 src/main/java/com/light/util/H2PoolUtils.java create mode 100644 src/main/resources/db.properties create mode 100644 src/main/resources/db/schema.sql diff --git a/src/main/java/com/light/GitManagerApp.java b/src/main/java/com/light/GitManagerApp.java index 2179a7e..175d58e 100644 --- a/src/main/java/com/light/GitManagerApp.java +++ b/src/main/java/com/light/GitManagerApp.java @@ -6,6 +6,7 @@ import com.light.layout.ContentPane; import com.light.layout.MenuPane; import com.light.util.FxDataUtil; import com.light.util.FxUtil; +import com.light.util.H2PoolUtils; import com.light.util.NodeUtils; import javafx.application.Application; import javafx.geometry.Insets; @@ -27,8 +28,11 @@ public class GitManagerApp extends Application { private static final String STYLE_SHEET = FxUtil.getResource("/css/root.css"); + private long startTime; + @Override public void init() throws Exception { + startTime = System.currentTimeMillis(); super.init(); // 初始化主题 THEME_LIST.add(new PrimerLight()); @@ -38,11 +42,21 @@ public class GitManagerApp extends Application { THEME_LIST.add(new CupertinoLight()); THEME_LIST.add(new CupertinoDark()); THEME_LIST.add(new Dracula()); + + // 初始化 + try { + String gitDbInit = H2PoolUtils.queryDictByLabel("GIT_DB_INIT"); + if ("0".equals(gitDbInit)) { + H2PoolUtils.createTable(); + H2PoolUtils.initGitProjectDictData(); + } + } catch (Exception e) { + LOGGER.error("h2 执行异常:{}", e.getMessage()); + } } @Override public void start(Stage stage) throws Exception { - long startTime = System.currentTimeMillis(); // 设置主题 Application.setUserAgentStylesheet(THEME_LIST.get(0).getUserAgentStylesheet()); @@ -77,7 +91,13 @@ public class GitManagerApp extends Application { stage.show(); scene.getStylesheets().add(STYLE_SHEET); - LOGGER.info("项目启动完成。。。{}", System.currentTimeMillis() - startTime); + LOGGER.info("项目启动完成,耗时 {} ms", System.currentTimeMillis() - startTime); + } + + @Override + public void stop() throws Exception { + super.stop(); + H2PoolUtils.closeConnectionPool(); } public static void main(String[] args) { diff --git a/src/main/java/com/light/util/DateUtils.java b/src/main/java/com/light/util/DateUtils.java new file mode 100644 index 0000000..14a63fd --- /dev/null +++ b/src/main/java/com/light/util/DateUtils.java @@ -0,0 +1,1023 @@ +package com.light.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +public class DateUtils { + + /** + * 一星期的天数 + */ + public static final int WEEK_DAYS = 7; + /** + * 一年的月份数 + */ + public static final int YEAR_MONTHS = 12; + /** + * 一天的小时数 + */ + public static final int DAY_HOURS = 24; + /** + * 一小时分钟数 + */ + public static final int HOUR_MINUTES = 60; + /** + * 一天分钟数 (24 * 60) + */ + public static final int DAY_MINUTES = 1440; + /** + * 一分钟的秒数 + */ + public static final int MINUTE_SECONDS = 60; + /** + * 一个小时的秒数 (60 * 60) + */ + public static final int HOUR_SECONDS = 3600; + /** + * 一天的秒数 (24 * 60 * 60) + */ + public static final int DAY_SECONDS = 86400; + /** + * 一秒的毫秒数 + */ + public static final long SECOND_MILLISECONDS = 1000L; + /** + * 一分钟的毫秒数(60 * 1000) + */ + public static final long MINUTE_MILLISECONDS = 60000L; + /** + * 一小时的毫秒数(60 * 60 * 1000) + */ + public static final long HOUR_MILLISECONDS = 3600000L; + /** + * 一天的毫秒数(24 * 60* 60* 1000) + */ + public static final long DAY_MILLISECONDS = 86400000L; + /** + * 星期一 + */ + public static final int WEEK_1_MONDAY = 1; + /** + * 星期二 + */ + public static final int WEEK_2_TUESDAY = 2; + /** + * 星期三 + */ + public static final int WEEK_3_WEDNESDAY = 3; + /** + * 星期四 + */ + public static final int WEEK_4_THURSDAY = 4; + /** + * 星期五 + */ + public static final int WEEK_5_FRIDAY = 5; + /** + * 星期六 + */ + public static final int WEEK_6_SATURDAY = 6; + /** + * 星期天 + */ + public static final int WEEK_7_SUNDAY = 7; + /** + * 一月 + */ + public static final int MONTH_1_JANUARY = 1; + /** + * 二月 + */ + public static final int MONTH_2_FEBRUARY = 2; + /** + * 三月 + */ + public static final int MONTH_3_MARCH = 3; + /** + * 四月 + */ + public static final int MONTH_4_APRIL = 4; + /** + * 五月 + */ + public static final int MONTH_5_MAY = 5; + /** + * 六月 + */ + public static final int MONTH_6_JUNE = 6; + /** + * 七月 + */ + public static final int MONTH_7_JULY = 7; + /** + * 八月 + */ + public static final int MONTH_8_AUGUST = 8; + /** + * 九月 + */ + public static final int MONTH_9_SEPTEMBER = 9; + /** + * 十月 + */ + public static final int MONTH_10_OCTOBER = 10; + /** + * 十一月 + */ + public static final int MONTH_11_NOVEMBER = 11; + /** + * 十二月 + */ + public static final int MONTH_12_DECEMBER = 12; + /** + * 显示到日期 + */ + public static final String FORMAT_DATE = "yyyy-MM-dd"; + /** + * 显示到小时 + */ + public static final String FORMAT_HOUR = "yyyy-MM-dd HH"; + /** + * 显示到分 + */ + public static final String FORMAT_MINUTE = "yyyy-MM-dd HH:mm"; + /** + * 显示到秒 + */ + public static final String FORMAT_SECOND = "yyyy-MM-dd HH:mm:ss"; + /** + * 显示到毫秒 + */ + public static final String FORMAT_MILLISECOND = "yyyy-MM-dd HH:mm:ss:SSS"; + /** + * 显示到日期(数字格式) + */ + public static final String FORMAT_NO_DATE = "yyyyMMdd"; + /** + * 显示到小时(数字格式) + */ + public static final String FORMAT_NO_HOUR = "yyyyMMddHH"; + /** + * 显示到分(数字格式) + */ + public static final String FORMAT_NO_MINUTE = "yyyyMMddHHmm"; + /** + * 显示到秒(数字格式) + */ + public static final String FORMAT_NO_SECOND = "yyyyMMddHHmmss"; + /** + * 显示到毫秒(数字格式) + */ + public static final String FORMAT_NO_MILLISECOND = "yyyyMMddHHmmssSSS"; + /** + * 时间格式化器集合 + */ + private static final Map simpleDateFormatMap = new HashMap(); + + static { + simpleDateFormatMap.put(FORMAT_DATE, new SimpleDateFormat(FORMAT_DATE)); + simpleDateFormatMap.put(FORMAT_HOUR, new SimpleDateFormat(FORMAT_HOUR)); + simpleDateFormatMap.put(FORMAT_MINUTE, new SimpleDateFormat(FORMAT_MINUTE)); + simpleDateFormatMap.put(FORMAT_SECOND, new SimpleDateFormat(FORMAT_SECOND)); + simpleDateFormatMap.put(FORMAT_MILLISECOND, new SimpleDateFormat(FORMAT_MILLISECOND)); + simpleDateFormatMap.put(FORMAT_NO_DATE, new SimpleDateFormat(FORMAT_NO_DATE)); + simpleDateFormatMap.put(FORMAT_NO_HOUR, new SimpleDateFormat(FORMAT_NO_HOUR)); + simpleDateFormatMap.put(FORMAT_NO_MINUTE, new SimpleDateFormat(FORMAT_NO_MINUTE)); + simpleDateFormatMap.put(FORMAT_NO_SECOND, new SimpleDateFormat(FORMAT_NO_SECOND)); + simpleDateFormatMap.put(FORMAT_NO_MILLISECOND, new SimpleDateFormat(FORMAT_NO_MILLISECOND)); + } + + /** + * 获取指定时间格式化器 + * + * @param formatStyle 时间格式 + * @return 时间格式化器 + */ + private static SimpleDateFormat getSimpleDateFormat(String formatStyle) { + SimpleDateFormat dateFormat = simpleDateFormatMap.get(formatStyle); + if (Objects.nonNull(dateFormat)) { + return dateFormat; + } + return new SimpleDateFormat(formatStyle); + } + + /** + * 将 Date 格式时间转化为指定格式时间 + * + * @param date Date 格式时间 + * @param formatStyle 转化指定格式(如: yyyy-MM-dd HH:mm:ss) + * @return 转化格式时间 + */ + public static String format(Date date, String formatStyle) { + if (Objects.isNull(date)) { + return ""; + } + return getSimpleDateFormat(formatStyle).format(date); + } + + /** + * 将 Date 格式时间转化为 yyyy-MM-dd 格式时间 + * + * @param date Date 格式时间 + * @return yyyy-MM-dd 格式时间(如:2022-06-17) + */ + public static String formatDate(Date date) { + return format(date, FORMAT_DATE); + } + + /** + * 将 Date 格式时间转化为 yyyy-MM-dd HH:mm:ss 格式时间 + * + * @param date Date 格式时间 + * @return yyyy-MM-dd HH:mm:ss 格式时间(如:2022-06-17 16:06:17) + */ + public static String formatDateTime(Date date) { + return format(date, FORMAT_SECOND); + } + + /** + * 将 Date 格式时间转化为 yyyy-MM-dd HH:mm:ss:SSS 格式时间 + * + * @param date Date 格式时间 + * @return yyyy-MM-dd HH:mm:ss:SSS 格式时间(如:2022-06-17 16:06:17:325) + */ + public static String formatDateTimeStamp(Date date) { + return format(date, FORMAT_MILLISECOND); + } + + /** + * 将 yyyy-MM-dd 格式时间转化为 Date 格式时间 + * + * @param dateString yyyy-MM-dd 格式时间(如:2022-06-17) + * @return Date 格式时间 + */ + public static Date parseDate(String dateString) { + return parse(dateString, FORMAT_DATE); + } + + /** + * 将 yyyy-MM-dd HH:mm:ss 格式时间转化为 Date 格式时间 + * + * @param dateTimeStr yyyy-MM-dd HH:mm:ss 格式时间(如:2022-06-17 16:06:17) + * @return Date 格式时间 + */ + public static Date parseDateTime(String dateTimeStr) { + return parse(dateTimeStr, FORMAT_SECOND); + } + + /** + * 将 yyyy-MM-dd HH:mm:ss:SSS 格式时间转化为 Date 格式时间 + * + * @param dateTimeStr yyyy-MM-dd HH:mm:ss:SSS 格式时间(如:2022-06-17 16:06:17) + * @return Date 格式时间 + */ + public static Date parseDateTimeStamp(String dateTimeStampStr) { + return parse(dateTimeStampStr, FORMAT_MILLISECOND); + } + + /** + * 将字符串格式时间转化为 Date 格式时间 + * + * @param dateString 字符串时间(如:2022-06-17 16:06:17) + * @return formatStyle 格式内容 + * @return Date 格式时间 + */ + public static Date parse(String dateString, String formatStyle) { + String s = getString(dateString); + if (s.isEmpty()) { + return null; + } + try { + return getSimpleDateFormat(formatStyle).parse(dateString); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取字符串有效内容 + * + * @param s 字符串 + * @return 有效内容 + */ + private static String getString(String s) { + return Objects.isNull(s) ? "" : s.trim(); + } + + /** + * 获取一天的开始时间(即:0 点 0 分 0 秒 0 毫秒) + * + * @param date 指定时间 + * @return 当天的开始时间 + */ + public static Date getDateStart(Date date) { + if (Objects.isNull(date)) { + return null; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTime(); + } + + /** + * 获取一天的截止时间(即:23 点 59 分 59 秒 999 毫秒) + * + * @param date 指定时间 + * @return 当天的开始时间 + */ + public static Date getDateEnd(Date date) { + if (Objects.isNull(date)) { + return null; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + return calendar.getTime(); + } + + /** + * 获取日期数字 + * + * @param date 日期 + * @return 日期数字 + */ + public static int getDateNo(Date date) { + if (Objects.isNull(date)) { + return 0; + } + return Integer.valueOf(format(date, FORMAT_NO_DATE)); + } + + /** + * 获取日期时间数字(到秒) + * + * @param date 日期 + * @return 日期数字 + */ + public static long getDateTimeNo(Date date) { + if (Objects.isNull(date)) { + return 0L; + } + return Long.valueOf(format(date, FORMAT_NO_SECOND)); + } + + /** + * 获取日期时间数字(到毫秒) + * + * @param date 日期 + * @return 日期数字 + */ + public static long getDateTimeStampNo(Date date) { + if (Objects.isNull(date)) { + return 0L; + } + return Long.valueOf(format(date, FORMAT_NO_MILLISECOND)); + } + + /** + * 获取星期几 + * + * @param date 时间 + * @return 0(时间为空), 1(周一), 2(周二),3(周三),4(周四),5(周五),6(周六),7(周日) + */ + public static int getWeek(Date date) { + if (Objects.isNull(date)) { + return 0; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return getWeek(calendar); + } + + /** + * 获取星期几 + * + * @param date 时间 + * @return 0(时间为空), 1(周一), 2(周二),3(周三),4(周四),5(周五),6(周六),7(周日) + */ + private static int getWeek(Calendar calendar) { + switch (calendar.get(Calendar.DAY_OF_WEEK)) { + case Calendar.MONDAY: + return 1; + case Calendar.TUESDAY: + return 2; + case Calendar.WEDNESDAY: + return 3; + case Calendar.THURSDAY: + return 4; + case Calendar.FRIDAY: + return 5; + case Calendar.SATURDAY: + return 6; + case Calendar.SUNDAY: + return 7; + default: + return 0; + } + } + + /** + * 获取该日期是今年的第几周(以本年的周一为第1周,详见下面说明)
+ *

+ * 【说明】
+ * 比如 2022-01-01(周六)和 2022-01-02(周日)虽然在 2022 年里,但他们两天则属于 2021 年最后一周,
+ * 那么这两天不会算在 2022 年第 1 周里,此时会返回 0 ;而 2022 年第 1 周将从 2022-01-03(周一) 开始计算。
+ * + * @param date 时间 + * @return -1(时间为空), 0(为上个年的最后一周),其他数字(今年的第几周) + */ + public static int getWeekOfYear(Date date) { + if (Objects.isNull(date)) { + return -1; + } + int weeks = getWeekOfYearIgnoreLastYear(date); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.MONTH, Calendar.JANUARY); + calendar.set(Calendar.DAY_OF_MONTH, 1); + int week = getWeek(calendar); + if (week == 1) { + return weeks; + } + return weeks - 1; + } + + /** + * 获取今年的第几周(以本年的1月1日为第1周第1天)
+ * + * @param date 时间 + * @return -1(时间为空),其他数字(今年的第几周) + */ + public static int getWeekOfYearIgnoreLastYear(Date date) { + if (Objects.isNull(date)) { + return -1; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int days = calendar.get(Calendar.DAY_OF_YEAR); + int weeks = days / 7; + // 如果是 7 的倍数,则表示恰好是多少周 + if (days % 7 == 0) { + return weeks; + } + // 如果有余数,则需要再加 1 + return weeks + 1; + } + + /** + * 获取时间节点对象 + * + * @param date 时间对象 + * @return DateNode + */ + public static DateNode getDateNode(Date date) { + if (Objects.isNull(date)) { + return null; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + DateNode node = new DateNode(); + node.setTime(format(date, FORMAT_MILLISECOND)); + node.setYear(calendar.get(Calendar.YEAR)); + node.setMonth(calendar.get(Calendar.MONTH) + 1); + node.setDay(calendar.get(Calendar.DAY_OF_MONTH)); + node.setHour(calendar.get(Calendar.HOUR_OF_DAY)); + node.setMinute(calendar.get(Calendar.MINUTE)); + node.setSecond(calendar.get(Calendar.SECOND)); + node.setMillisecond(calendar.get(Calendar.MILLISECOND)); + node.setWeek(getWeek(calendar)); + node.setDayOfYear(calendar.get(Calendar.DAY_OF_YEAR)); + node.setWeekOfYear(getWeekOfYear(date)); + node.setWeekOfYearIgnoreLastYear(getWeekOfYearIgnoreLastYear(date)); + node.setMillisecondStamp(date.getTime()); + node.setSecondStamp(node.getMillisecondStamp() / 1000); + return node; + } + + /** + * 日期变更 + * + * @param date 指定日期 + * @param field 变更属性(如变更年份,则该值为 Calendar.DAY_OF_YEAR) + * @param amount 变更大小(大于 0 时增加,小于 0 时减少) + * @return 变更后的日期时间 + */ + public static Date add(Date date, int field, int amount) { + if (Objects.isNull(date)) { + return null; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(field, amount); + return calendar.getTime(); + } + + /** + * 指定日期加减年份 + * + * @param date 指定日期 + * @param year 变更年份(大于 0 时增加,小于 0 时减少) + * @return 变更年份后的日期 + */ + public static Date addYear(Date date, int year) { + return add(date, Calendar.YEAR, year); + } + + /** + * 指定日期加减月份 + * + * @param date 指定日期 + * @param month 变更月份(大于 0 时增加,小于 0 时减少) + * @return 变更月份后的日期 + */ + public static Date addMonth(Date date, int month) { + return add(date, Calendar.MONTH, month); + } + + /** + * 指定日期加减天数 + * + * @param date 指定日期 + * @param day 变更天数(大于 0 时增加,小于 0 时减少) + * @return 变更天数后的日期 + */ + public static Date addDay(Date date, int day) { + return add(date, Calendar.DAY_OF_YEAR, day); + } + + /** + * 指定日期加减星期 + * + * @param date 指定日期 + * @param week 变更星期数(大于 0 时增加,小于 0 时减少) + * @return 变更星期数后的日期 + */ + public static Date addWeek(Date date, int week) { + return add(date, Calendar.WEEK_OF_YEAR, week); + } + + /** + * 指定日期加减小时 + * + * @param date 指定日期时间 + * @param hour 变更小时数(大于 0 时增加,小于 0 时减少) + * @return 变更小时数后的日期时间 + */ + public static Date addHour(Date date, int hour) { + return add(date, Calendar.HOUR_OF_DAY, hour); + } + + /** + * 指定日期加减分钟 + * + * @param date 指定日期时间 + * @param minute 变更分钟数(大于 0 时增加,小于 0 时减少) + * @return 变更分钟数后的日期时间 + */ + public static Date addMinute(Date date, int minute) { + return add(date, Calendar.MINUTE, minute); + } + + /** + * 指定日期加减秒 + * + * @param date 指定日期时间 + * @param second 变更秒数(大于 0 时增加,小于 0 时减少) + * @return 变更秒数后的日期时间 + */ + public static Date addSecond(Date date, int second) { + return add(date, Calendar.SECOND, second); + } + + /** + * 指定日期加减秒 + * + * @param date 指定日期时间 + * @param minute 变更毫秒数(大于 0 时增加,小于 0 时减少) + * @return 变更毫秒数后的日期时间 + */ + public static Date addMillisecond(Date date, int millisecond) { + return add(date, Calendar.MILLISECOND, millisecond); + } + + /** + * 获取该日期所在周指定星期的日期 + * + * @param date 日期所在时间 + * @return index 指定星期(1 - 7 分别对应星期一到星期天) + */ + public static Date getWeekDate(Date date, int index) { + if (index < WEEK_1_MONDAY || index > WEEK_7_SUNDAY) { + return null; + } + int week = getWeek(date); + return addDay(date, index - week); + } + + /** + * 获取该日期所在周开始日期 + * + * @param date 日期所在时间 + * @return 所在周开始日期 + */ + public static Date getWeekDateStart(Date date) { + return getDateStart(getWeekDate(date, WEEK_1_MONDAY)); + } + + /** + * 获取该日期所在周开始日期 + * + * @param date 日期所在时间 + * @return 所在周开始日期 + */ + public static Date getWeekDateEnd(Date date) { + return getWeekDateEnd(getWeekDate(date, WEEK_7_SUNDAY)); + } + + /** + * 获取该日期所在周的所有日期(周一到周日) + * + * @param Date 日期 + * @return 该日照所在周的所有日期 + */ + public static List getWeekDateList(Date date) { + if (Objects.isNull(date)) { + return Collections.emptyList(); + } + // 获取本周开始时间 + Date weekFromDate = getWeekDateStart(date); + // 获取本周截止时间 + Date weekeEndDate = getWeekDateEnd(date); + return getBetweenDateList(weekFromDate, weekeEndDate, true); + } + + /** + * 获取该日期所在周的所有日期(周一到周日) + * + * @param dateString + * @return 该日照所在周的所有日期 + */ + public static List getWeekDateList(String dateString) { + Date date = parseDate(dateString); + if (Objects.isNull(date)) { + return Collections.emptyList(); + } + return getDateStrList(getWeekDateList(date)); + } + + /** + * 获取该日期所在月的所有日期 + * + * @param dateString + * @return 该日照所月的所有日期 + */ + public static List getMonthDateList(Date date) { + if (Objects.isNull(date)) { + return Collections.emptyList(); + } + Date monthDateStart = getMonthDateStart(date); + Date monthDateEnd = getMonthDateEnd(date); + return getBetweenDateList(monthDateStart, monthDateEnd, true); + } + + /** + * 获取该日期所在月的所有日期 + * + * @param dateString + * @return 该日照所月的所有日期 + */ + public static List getMonthDateList(String dateString) { + Date date = parseDate(dateString); + if (Objects.isNull(date)) { + return Collections.emptyList(); + } + return getDateStrList(getMonthDateList(date)); + } + + /** + * 获取本日期所在月第一天 + * + * @param date 日期 + * @return 本日期所在月第一天 + */ + public static Date getMonthDateStart(Date date) { + if (Objects.isNull(date)) { + return null; + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DAY_OF_MONTH, 1); + return getDateStart(calendar.getTime()); + } + + /** + * 获取本日期所在月最后一天 + * + * @param date 日期 + * @return 本日期所在月最后一天 + */ + public static Date getMonthDateEnd(Date date) { + if (Objects.isNull(date)) { + return null; + } + Date monthDateStart = getMonthDateStart(date); + Date nextMonthDateStart = getMonthDateStart(addMonth(monthDateStart, 1)); + return getDateEnd(addDay(nextMonthDateStart, -1)); + } + + /** + * 获取两个日期相差的天数(以日期为单位计算,不以24小时制计算,详见下面说明)
+ *

+ * 【说明】比如 2022-06-17 23:00:00 和 2022-06-17 01:00:00,两者虽然只相差 2 个小时,但也算相差 1 天
+ * + * @param date1 日期1 + * @param date2 日期2 + * @return 相差天数(若返回 -1,则至少有一个日期存在为空,此时不能进行比较) + */ + public static int countBetweenDays(Date date1, Date date2) { + if (Objects.isNull(date1) || Objects.isNull(date2)) { + return -1; + } + // 获取两个日期 0 点 0 时 0 分 0 秒 0 毫秒时的时间戳(毫秒级) + long t1 = getDateStart(date1).getTime(); + long t2 = getDateStart(date2).getTime(); + // 相差天数 = 相差的毫秒数 / 一天的毫秒数 + return (int) (Math.abs(t1 - t2) / DAY_MILLISECONDS); + } + + /** + * 获取两个日期之间的所有日期 + * + * @param date1 日期1 + * @param date2 日期2 + * @return 两个日期之间的所有日期的开始时间 + */ + public static List getBetweenDateList(Date date1, Date date2) { + return getBetweenDateList(date1, date2, false); + } + + /** + * 获取两个日期之间的所有日期 + * + * @param date1 日期1 + * @param date2 日期2 + * @return 两个日期之间的所有日期的开始时间 + */ + public static List getBetweenDateList(Date date1, Date date2, boolean isContainParams) { + if (Objects.isNull(date1) || Objects.isNull(date2)) { + return Collections.emptyList(); + } + // 确定前后日期 + Date fromDate = date1; + Date toDate = date2; + if (date2.before(date1)) { + fromDate = date2; + toDate = date1; + } + // 获取两个日期每天的开始时间 + Date from = getDateStart(fromDate); + Date to = getDateStart(toDate); + // 获取日期,开始循环 + List dates = new ArrayList(); + if (isContainParams) { + dates.add(from); + } + Date date = from; + boolean isBefore = true; + while (isBefore) { + date = addDay(date, 1); + isBefore = date.before(to); + if (isBefore) { + dates.add(getDateStart(date)); + } + } + if (isContainParams) { + dates.add(to); + } + return dates; + } + + /** + * 获取两个日期之间的所有日期 + * + * @param dateString1 日期1(如:2022-06-20) + * @param dateString2 日期2(如:2022-07-15) + * @return 两个日期之间的所有日期(不包含参数日期) + */ + public static List getBetweenDateList(String dateString1, String dateString2) { + return getBetweenDateList(dateString1, dateString2, false); + } + + /** + * 获取两个日期之间的所有日期 + * + * @param dateString1 日期1(如:2022-06-20) + * @param dateString2 日期2(如:2022-07-15) + * @param isContainParams 是否包含参数的两个日期 + * @return 两个日期之间的所有日期的开始时间 + */ + public static List getBetweenDateList(String dateString1, String dateString2, boolean isContainParams) { + Date date1 = parseDate(dateString1); + Date date2 = parseDate(dateString2); + List dates = getBetweenDateList(date1, date2, isContainParams); + return getDateStrList(dates); + } + + /** + * List 转 List + * + * @param dates 日期集合 + * @return 日期字符串集合 + */ + public static List getDateStrList(List dates) { + if (dates.isEmpty()) { + return Collections.emptyList(); + } + List dateList = new ArrayList(); + for (Date date : dates) { + dateList.add(formatDate(date)); + } + return dateList; + } + + static class DateNode { + /** + * 年 + */ + private int year; + /** + * 月 + */ + private int month; + /** + * 日 + */ + private int day; + /** + * 时 + */ + private int hour; + /** + * 分 + */ + private int minute; + /** + * 秒 + */ + private int second; + /** + * 毫秒 + */ + private int millisecond; + /** + * 星期几( 1 - 7 对应周一到周日) + */ + private int week; + /** + * 当年第几天 + */ + private int dayOfYear; + /** + * 当年第几周(本年周 1 为第 1 周,0 则表示属于去年最后一周) + */ + private int weekOfYear; + /** + * 当年第几周(本年周 1 为第 1 周,0 则表示属于去年最后一周) + */ + private int weekOfYearIgnoreLastYear; + /** + * 时间戳(秒级) + */ + private long secondStamp; + /** + * 时间戳(毫秒级) + */ + private long millisecondStamp; + /** + * 显示时间 + */ + private String time; + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public int getMonth() { + return month; + } + + public void setMonth(int month) { + this.month = month; + } + + public int getDay() { + return day; + } + + public void setDay(int day) { + this.day = day; + } + + public int getHour() { + return hour; + } + + public void setHour(int hour) { + this.hour = hour; + } + + public int getMinute() { + return minute; + } + + public void setMinute(int minute) { + this.minute = minute; + } + + public int getSecond() { + return second; + } + + public void setSecond(int second) { + this.second = second; + } + + public int getMillisecond() { + return millisecond; + } + + public void setMillisecond(int millisecond) { + this.millisecond = millisecond; + } + + public int getWeek() { + return week; + } + + public void setWeek(int week) { + this.week = week; + } + + public int getDayOfYear() { + return dayOfYear; + } + + public void setDayOfYear(int dayOfYear) { + this.dayOfYear = dayOfYear; + } + + public int getWeekOfYear() { + return weekOfYear; + } + + public void setWeekOfYear(int weekOfYear) { + this.weekOfYear = weekOfYear; + } + + public int getWeekOfYearIgnoreLastYear() { + return weekOfYearIgnoreLastYear; + } + + public void setWeekOfYearIgnoreLastYear(int weekOfYearIgnoreLastYear) { + this.weekOfYearIgnoreLastYear = weekOfYearIgnoreLastYear; + } + + public long getSecondStamp() { + return secondStamp; + } + + public void setSecondStamp(long secondStamp) { + this.secondStamp = secondStamp; + } + + public long getMillisecondStamp() { + return millisecondStamp; + } + + public void setMillisecondStamp(long millisecondStamp) { + this.millisecondStamp = millisecondStamp; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + } +} diff --git a/src/main/java/com/light/util/H2PoolUtils.java b/src/main/java/com/light/util/H2PoolUtils.java new file mode 100644 index 0000000..38ccf6a --- /dev/null +++ b/src/main/java/com/light/util/H2PoolUtils.java @@ -0,0 +1,182 @@ +package com.light.util; + +import org.h2.jdbcx.JdbcConnectionPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Date; +import java.util.Properties; + +/** + * @Author: wangss + * @CreateTime: 2023-05-19 22:36 + * @Description: H2连接池 + */ +public class H2PoolUtils { + + public static final Logger LOGGER = LoggerFactory.getLogger(H2PoolUtils.class); + private static JdbcConnectionPool connectionPool = null; + + private static final String DB_DRIVER; + private static final String DB_URL; + private static final String DB_URL_PREFIX; + private static final String DB_URL_SUFFIX; + private static final String DB_USERNAME; + private static final String DB_PASSWORD; + private static final int DB_POOL_MAXIDLE; + private static final int DB_POOL_MAXACTIVE; + + static { + Properties properties = new Properties(); + try { + properties.load(H2PoolUtils.class.getResourceAsStream("/db.properties")); + DB_DRIVER = properties.getProperty("jdbc.driver", "org.h2.Driver"); + DB_URL_PREFIX = properties.getProperty("jdbc.url.prefix", "jdbc:h2:file:"); + DB_URL_SUFFIX = properties.getProperty("jdbc.url.suffix", "/.h2/git-db;AUTO_SERVER=TRUE"); + DB_USERNAME = properties.getProperty("jdbc.username", "git"); + DB_PASSWORD = properties.getProperty("jdbc.password", "git@123"); + DB_POOL_MAXIDLE = Integer.parseInt(properties.getProperty("jdbc.pool.maxIdle", "5")); + DB_POOL_MAXACTIVE = Integer.parseInt(properties.getProperty("jdbc.pool.maxActive", "20")); + DB_URL = DB_URL_PREFIX + System.getProperty("user.home") + DB_URL_SUFFIX; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * 获取链接 + * + * @return + * @throws SQLException + */ + public static Connection getConnection() throws SQLException { + if (connectionPool == null) { + createConnectionPool(); + } + return connectionPool.getConnection(); + } + + /** + * 创建连接池 + */ + private static void createConnectionPool() { + connectionPool = JdbcConnectionPool.create(DB_URL, DB_USERNAME, DB_PASSWORD); + connectionPool.setMaxConnections(DB_POOL_MAXACTIVE); + LOGGER.info("h2 连接池初始化成功"); + } + + /** + * 关闭连接池 + */ + public static void closeConnectionPool() { + if (null != connectionPool) { + connectionPool.dispose(); + LOGGER.info("h2 连接池关闭"); + } + } + + /** + * 创建项目所需表 + * + * @throws SQLException + */ + public static void createTable() throws SQLException { + Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + stmt.executeUpdate("drop table git_project_info if exists"); + stmt.executeUpdate("drop table git_project_dict if exists"); + stmt.executeUpdate("drop table git_project_notice_history if exists"); + // 初始化项目信息表 + String createGitProjectInfoTable = """ + create table git_project_info + ( + id INT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(100) NOT NULL comment '项目名称', + author varchar(100) comment '作者', + branch VARCHAR(100) comment '当前分支', + remote varchar(255) comment '仓库地址', + local varchar(255) comment '本地地址', + createtime varchar(20) comment '创建时间', + updatetime varchar(20) comment '更新时间', + description VARCHAR(1000) comment '描述', + remark VARCHAR(1000) comment '备注', + level int default 0 comment '学习等级' + ) + """; + stmt.executeUpdate(createGitProjectInfoTable); + LOGGER.info("h2 项目信息表创建成功"); + + // 初始化字典表 + String createGitProjectDictTable = """ + create table git_project_dict + ( + id int primary key auto_increment, + label varchar(100) comment '标签', + label_value varchar(100) comment '值', + description VARCHAR(255) comment '描述', + createtime varchar(20) comment '创建时间', + updatetime varchar(20) comment '更新时间' + ) + """; + stmt.executeUpdate(createGitProjectDictTable); + LOGGER.info("h2 字典表创建成功"); + + // 初始化通知历史表 + String createGitProjectNoticeHistoryTable = """ + create table git_project_notice_history + ( + id int primary key auto_increment, + notice varchar(1000) comment '通知信息', + level varchar(10) comment '通知等级', + createtime varchar(20) comment '创建时间' + ) + """; + stmt.executeUpdate(createGitProjectNoticeHistoryTable); + LOGGER.info("h2 通知消息历史表创建成功"); + } + + /** + * 初始化字典表数据 + * + * @throws SQLException + */ + public static void initGitProjectDictData() throws SQLException { + Date currentDate = new Date(); + Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + String sql = "insert into git_project_dict(label, label_value, description, createtime, updatetime) values('GIT_DB_INIT','1','项目数据库初始化标识:0 未初始化,1 初始化', " + + "'" + DateUtils.formatDateTime(currentDate) + "', '" + DateUtils.formatDateTime(currentDate) + "')"; + stmt.addBatch(sql); + String sql2 = "insert into git_project_dict(label, label_value, description, createtime, updatetime) values('GIT_CURRENT_THEME','Primer Light','项目当前主题', " + + "'" + DateUtils.formatDateTime(currentDate) + "', '" + DateUtils.formatDateTime(currentDate) + "')"; + stmt.addBatch(sql2); + stmt.executeBatch(); + LOGGER.info("h2 字典表数据初始化成功"); + } + + public static String queryDictByLabel(String label) { + String value = "0"; + try { + Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + String sql = "select * from git_project_dict where label = '" + label + "'"; + ResultSet resultSet = stmt.executeQuery(sql); + while (resultSet.next()) { + value = resultSet.getString("label_value"); + } + } catch (SQLException e) { + LOGGER.error("通过 {} 查询数据异常:{}", label, e.getMessage()); + } + LOGGER.info("通过 {} 查询数据结果:{}", label, value); + return value; + } + + public static void updateDictData(String label, String value) { + + } +} diff --git a/src/main/resources/db.properties b/src/main/resources/db.properties new file mode 100644 index 0000000..907a0be --- /dev/null +++ b/src/main/resources/db.properties @@ -0,0 +1,9 @@ +#h2 database settings +jdbc.driver=org.h2.Driver +jdbc.url.prefix=jdbc:h2:file: +jdbc.url.suffix=/.h2/git-db;AUTO_SERVER=TRUE +jdbc.username=git +jdbc.password=git@123 +#connection pool settings +jdbc.pool.maxIdle=5 +jdbc.pool.maxActive=20 \ No newline at end of file diff --git a/src/main/resources/db/schema.sql b/src/main/resources/db/schema.sql new file mode 100644 index 0000000..af9387d --- /dev/null +++ b/src/main/resources/db/schema.sql @@ -0,0 +1,38 @@ +/*开源项目信息*/ +create table git_project_info +( + id INT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(100) NOT NULL comment '项目名称', + author varchar(100) comment '作者', + branch VARCHAR(100) comment '当前分支', + remote varchar(255) comment '仓库地址', + local varchar(255) comment '本地地址', + createtime varchar(20) comment '创建时间', + updatetime varchar(20) comment '更新时间', + description VARCHAR(1000) comment '描述', + remark VARCHAR(1000) comment '备注', + level int default 0 comment '学习等级' +); + +/*字典表*/ +create table git_project_dict +( + id int primary key auto_increment, + label varchar(100) comment '标签', + label_value varchar(100) comment '值', + description VARCHAR(255) comment '描述', + createtime varchar(20) comment '创建时间', + updatetime varchar(20) comment '更新时间' +); + +insert into git_project_dict(label, label_value, description) values('GIT_DB_INIT','1','项目数据库初始化标识:0 未初始化,1 初始化'); +insert into git_project_dict(label, label_value, description) values('GIT_CURRENT_THEME','Primer Light','项目当前主题'); + +/*通知历史记录表*/ +create table git_project_notice_history +( + id int primary key auto_increment, + notice varchar(1000) comment '通知信息', + level varchar(10) comment '通知等级', + createtime varchar(20) comment '创建时间' +); \ No newline at end of file -- Gitee From 51161a6d51894156708334ad6b00651d427ced7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Tue, 10 Oct 2023 18:41:36 +0800 Subject: [PATCH 6/9] =?UTF-8?q?+=20=E8=B0=83=E6=95=B4java=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 ++-- src/main/java/com/light/util/H2Utils.java | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 src/main/java/com/light/util/H2Utils.java diff --git a/pom.xml b/pom.xml index de51eb2..a28c40d 100644 --- a/pom.xml +++ b/pom.xml @@ -126,8 +126,8 @@ maven-compiler-plugin 3.8.1 - 20 - 20 + 21 + 21 diff --git a/src/main/java/com/light/util/H2Utils.java b/src/main/java/com/light/util/H2Utils.java deleted file mode 100644 index 186e4c2..0000000 --- a/src/main/java/com/light/util/H2Utils.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.light.util; - -public class H2Utils { -} -- Gitee From 643cc3a44d129203b6ea18e4a27ed260051232e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Wed, 11 Oct 2023 11:26:17 +0800 Subject: [PATCH 7/9] =?UTF-8?q?+=20=E5=A2=9E=E5=8A=A0=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/light/GitManagerApp.java | 57 +++++++++-------- src/main/java/com/light/layout/MenuPane.java | 8 +-- src/main/java/com/light/thread/AsyncTask.java | 62 +++++++++++++++++++ .../java/com/light/thread/GitThreadPool.java | 28 +++++++++ src/main/java/com/light/util/FxDataUtil.java | 2 +- src/main/java/com/light/util/H2PoolUtils.java | 4 +- src/main/java/com/light/view/ManagerView.java | 11 +++- 7 files changed, 136 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/light/thread/AsyncTask.java create mode 100644 src/main/java/com/light/thread/GitThreadPool.java diff --git a/src/main/java/com/light/GitManagerApp.java b/src/main/java/com/light/GitManagerApp.java index 175d58e..8688f45 100644 --- a/src/main/java/com/light/GitManagerApp.java +++ b/src/main/java/com/light/GitManagerApp.java @@ -4,6 +4,8 @@ import atlantafx.base.controls.ModalPane; import atlantafx.base.theme.*; import com.light.layout.ContentPane; import com.light.layout.MenuPane; +import com.light.thread.AsyncTask; +import com.light.thread.GitThreadPool; import com.light.util.FxDataUtil; import com.light.util.FxUtil; import com.light.util.H2PoolUtils; @@ -28,40 +30,45 @@ public class GitManagerApp extends Application { private static final String STYLE_SHEET = FxUtil.getResource("/css/root.css"); + private Scene scene; private long startTime; @Override public void init() throws Exception { startTime = System.currentTimeMillis(); super.init(); - // 初始化主题 - THEME_LIST.add(new PrimerLight()); - THEME_LIST.add(new PrimerDark()); - THEME_LIST.add(new NordLight()); - THEME_LIST.add(new NordDark()); - THEME_LIST.add(new CupertinoLight()); - THEME_LIST.add(new CupertinoDark()); - THEME_LIST.add(new Dracula()); - - // 初始化 - try { - String gitDbInit = H2PoolUtils.queryDictByLabel("GIT_DB_INIT"); - if ("0".equals(gitDbInit)) { - H2PoolUtils.createTable(); - H2PoolUtils.initGitProjectDictData(); + AsyncTask.runOnce(new AsyncTask("data_init", "初始化数据库和主题数据") { + @Override + protected void handler() throws Exception { + String gitDbInit = H2PoolUtils.queryDictByLabel("GIT_DB_INIT", "0"); + if ("0".equals(gitDbInit)) { + H2PoolUtils.createTable(); + H2PoolUtils.initGitProjectDictData(); + } + + THEME_LIST.add(new PrimerLight()); + THEME_LIST.add(new PrimerDark()); + THEME_LIST.add(new NordLight()); + THEME_LIST.add(new NordDark()); + THEME_LIST.add(new CupertinoLight()); + THEME_LIST.add(new CupertinoDark()); + THEME_LIST.add(new Dracula()); + + // 设置主题 + String themeName = H2PoolUtils.queryDictByLabel("GIT_CURRENT_THEME", "Primer Light"); + FxDataUtil.CURRENT_THEME_NAME.set(themeName); + THEME_LIST.stream().filter(theme -> theme.getName().equals(themeName)) + .findFirst() + .ifPresentOrElse(theme -> Application.setUserAgentStylesheet(theme.getUserAgentStylesheet()), + () -> Application.setUserAgentStylesheet(THEME_LIST.getFirst().getUserAgentStylesheet()) + ); } - } catch (Exception e) { - LOGGER.error("h2 执行异常:{}", e.getMessage()); - } + }); } @Override public void start(Stage stage) throws Exception { - - // 设置主题 - Application.setUserAgentStylesheet(THEME_LIST.get(0).getUserAgentStylesheet()); - FxDataUtil.CURRENT_THEME_NAME.set(THEME_LIST.get(0).getName()); - + Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet()); // 根节点 StackPane root = new StackPane(); @@ -82,14 +89,13 @@ public class GitManagerApp extends Application { NodeUtils.setAnchors(root, Insets.EMPTY); // 场景 - Scene scene = new Scene(root); + scene = new Scene(root); stage.setTitle("Git批量管理工具"); stage.setMinWidth(1100); stage.setMinHeight(650); stage.getIcons().add(new Image(this.getClass().getResource("/icons/git.png").toExternalForm())); stage.setScene(scene); stage.show(); - scene.getStylesheets().add(STYLE_SHEET); LOGGER.info("项目启动完成,耗时 {} ms", System.currentTimeMillis() - startTime); } @@ -98,6 +104,7 @@ public class GitManagerApp extends Application { public void stop() throws Exception { super.stop(); H2PoolUtils.closeConnectionPool(); + GitThreadPool.close(); } public static void main(String[] args) { diff --git a/src/main/java/com/light/layout/MenuPane.java b/src/main/java/com/light/layout/MenuPane.java index 9bc9679..ee74d11 100644 --- a/src/main/java/com/light/layout/MenuPane.java +++ b/src/main/java/com/light/layout/MenuPane.java @@ -54,14 +54,10 @@ public class MenuPane extends StackPane { this.contentPane = contentPane; initialize(); - // 子菜单 - Lazy managerViewLazy = new Lazy<>(ManagerView::new); - Lazy homeViewLazy = new Lazy<>(HomeView::new); - // 菜单栏标题 dynamicMenu.getItems().addAll( - new NavItem(new FontIcon(AntDesignIconsOutlined.DOWNLOAD), "下载", homeViewLazy), - new NavItem(new FontIcon(AntDesignIconsOutlined.PARTITION), "管理", managerViewLazy), + new NavItem(new FontIcon(AntDesignIconsOutlined.DOWNLOAD), "下载", new Lazy<>(HomeView::new)), + new NavItem(new FontIcon(AntDesignIconsOutlined.PARTITION), "管理", new Lazy<>(ManagerView::new)), new NavItem(new FontIcon(AntDesignIconsOutlined.EDIT), "笔记", null) ); dynamicMenu.getSelectionModel().selectFirst(); diff --git a/src/main/java/com/light/thread/AsyncTask.java b/src/main/java/com/light/thread/AsyncTask.java new file mode 100644 index 0000000..93198d8 --- /dev/null +++ b/src/main/java/com/light/thread/AsyncTask.java @@ -0,0 +1,62 @@ +package com.light.thread; + +import javafx.concurrent.Task; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AsyncTask extends Task { + + public static final Logger LOGGER = LoggerFactory.getLogger(AsyncTask.class); + + /** + * 线程名称 + */ + private final String threadName; + + private final String description; + + private final long startTime; + + public AsyncTask() { + this(null, null); + } + + public AsyncTask(String threadName, String description) { + this.threadName = threadName; + this.description = description; + this.startTime = System.currentTimeMillis(); + } + + @Override + protected Void call() throws Exception { + try { + LOGGER.info("Task {} 开始执行 - {}", threadName, description); + handler(); + } catch (Exception e) { + LOGGER.info("Task {} 执行异常:{}", threadName, e.getMessage()); + } + return null; + } + + @Override + protected void succeeded() { + super.succeeded(); + LOGGER.info("Task {} 执行结束,耗时 {} ms", threadName, System.currentTimeMillis() - startTime); + } + + @Override + protected void failed() { + super.failed(); + LOGGER.info("Task {} 执行失败", threadName); + } + + protected abstract void handler() throws Exception; + + public static void runOnce(AsyncTask asyncTask) { + GitThreadPool.EXECUTOR_SERVICE.execute(asyncTask); + } + + public String getThreadName() { + return threadName; + } +} diff --git a/src/main/java/com/light/thread/GitThreadPool.java b/src/main/java/com/light/thread/GitThreadPool.java new file mode 100644 index 0000000..3b158c1 --- /dev/null +++ b/src/main/java/com/light/thread/GitThreadPool.java @@ -0,0 +1,28 @@ +package com.light.thread; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +public class GitThreadPool { + public static final Logger LOGGER = LoggerFactory.getLogger(GitThreadPool.class); + + // 普通线程池 + public static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(5); + + // 定时线程池 + public static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newScheduledThreadPool(5); + + public static void close() { + if (!EXECUTOR_SERVICE.isShutdown()) { + EXECUTOR_SERVICE.shutdown(); + } + if (!SCHEDULED_EXECUTOR_SERVICE.isShutdown()) { + SCHEDULED_EXECUTOR_SERVICE.shutdown(); + } + LOGGER.info("线程池关闭"); + } +} diff --git a/src/main/java/com/light/util/FxDataUtil.java b/src/main/java/com/light/util/FxDataUtil.java index 4d278ed..7fb351e 100644 --- a/src/main/java/com/light/util/FxDataUtil.java +++ b/src/main/java/com/light/util/FxDataUtil.java @@ -1,6 +1,6 @@ package com.light.util; -import atlantafx.base.theme.Theme; +import atlantafx.base.theme.*; import com.light.model.GitProject; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleStringProperty; diff --git a/src/main/java/com/light/util/H2PoolUtils.java b/src/main/java/com/light/util/H2PoolUtils.java index 38ccf6a..84e099d 100644 --- a/src/main/java/com/light/util/H2PoolUtils.java +++ b/src/main/java/com/light/util/H2PoolUtils.java @@ -159,8 +159,8 @@ public class H2PoolUtils { LOGGER.info("h2 字典表数据初始化成功"); } - public static String queryDictByLabel(String label) { - String value = "0"; + public static String queryDictByLabel(String label, String defaultValue) { + String value = defaultValue; try { Connection conn = getConnection(); Statement stmt = conn.createStatement(); diff --git a/src/main/java/com/light/view/ManagerView.java b/src/main/java/com/light/view/ManagerView.java index f09db25..59d1dee 100644 --- a/src/main/java/com/light/view/ManagerView.java +++ b/src/main/java/com/light/view/ManagerView.java @@ -8,6 +8,7 @@ import com.light.component.OperationTableCell; import com.light.component.TooltipTableRow; import com.light.enums.Level; import com.light.model.GitProject; +import com.light.thread.AsyncTask; import com.light.util.FxDataUtil; import com.light.util.NoticeUtils; import javafx.beans.property.SimpleBooleanProperty; @@ -54,8 +55,14 @@ public class ManagerView extends StackPane { public ManagerView() { this.getChildren().add(vBox); initialize(); - initData(); initEvent(); + // 异步初始化数据 + AsyncTask.runOnce(new AsyncTask("init_project_data", "初始化项目数据") { + @Override + protected void handler() throws Exception { + initData(); + } + }); } public void initialize() { @@ -132,7 +139,7 @@ public class ManagerView extends StackPane { public void initData() { // TODO 查H2数据库获取数据 - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 10; i++) { GitProject gitProject = new GitProject(i + "", "g" + i + "it", "project", "develop", "2023-09-30", "2023-09-30", "https://gitee.com/code-poison/git-manager-client-fx.git", "D:\\workspace\\workspace-dev\\git-manager-client-fx", "测试一下效果", "", i % 5, new SimpleDoubleProperty(0.0), new SimpleBooleanProperty(false)); gitProject.addSelectedListener(); -- Gitee From b4c8fd4e96df257d593df0200d62b53d7343dfa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Wed, 11 Oct 2023 14:30:36 +0800 Subject: [PATCH 8/9] =?UTF-8?q?+=20=E5=AE=8C=E5=96=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/light/component/TooltipTableRow.java | 6 +- src/main/java/com/light/model/GitNotice.java | 4 + src/main/java/com/light/model/GitProject.java | 20 +-- src/main/java/com/light/util/H2PoolUtils.java | 148 ++++++++++++++++-- src/main/java/com/light/view/ManagerView.java | 28 ++-- 5 files changed, 167 insertions(+), 39 deletions(-) create mode 100644 src/main/java/com/light/model/GitNotice.java diff --git a/src/main/java/com/light/component/TooltipTableRow.java b/src/main/java/com/light/component/TooltipTableRow.java index ec59b3c..a98d7ec 100644 --- a/src/main/java/com/light/component/TooltipTableRow.java +++ b/src/main/java/com/light/component/TooltipTableRow.java @@ -64,14 +64,14 @@ public class TooltipTableRow extends TableRow { private void refreshData(GitProject item) { levelBox.getChildren().clear(); // 项目名称 - name.setTitle(item.name()); - name.setDescription(item.description()); + name.setTitle(item.name().get()); + name.setDescription(item.description().get()); author.setText("仓库 作者: " + item.author()); remoteAddr.setText("仓库 地址: " + item.remote()); localAddr.setText("本地 地址: " + item.local()); level.setText("学习 等级: "); levelBox.getChildren().add(level); - for (int i = 0; i < item.level(); i++) { + for (int i = 0; i < item.level().get(); i++) { levelBox.getChildren().add(new FontIcon(AntDesignIconsOutlined.STAR)); } remark.setText("仓库 备注: " + item.remark()); diff --git a/src/main/java/com/light/model/GitNotice.java b/src/main/java/com/light/model/GitNotice.java new file mode 100644 index 0000000..b05aea4 --- /dev/null +++ b/src/main/java/com/light/model/GitNotice.java @@ -0,0 +1,4 @@ +package com.light.model; + +public record GitNotice(int id, String notice, String level, String createTime) { +} diff --git a/src/main/java/com/light/model/GitProject.java b/src/main/java/com/light/model/GitProject.java index 8faa3e9..4d7a557 100644 --- a/src/main/java/com/light/model/GitProject.java +++ b/src/main/java/com/light/model/GitProject.java @@ -3,18 +3,20 @@ package com.light.model; import com.light.util.FxDataUtil; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleStringProperty; -public record GitProject(String id, - String name, - String author, - String branch, +public record GitProject(SimpleStringProperty id, + SimpleStringProperty name, + SimpleStringProperty author, + SimpleStringProperty branch, String createTime, - String updateTime, + SimpleStringProperty updateTime, String remote, - String local, - String description, - String remark, - int level, + SimpleStringProperty local, + SimpleStringProperty description, + SimpleStringProperty remark, + SimpleIntegerProperty level, SimpleDoubleProperty downloadRate, SimpleBooleanProperty selected) { diff --git a/src/main/java/com/light/util/H2PoolUtils.java b/src/main/java/com/light/util/H2PoolUtils.java index 84e099d..1dd4e2e 100644 --- a/src/main/java/com/light/util/H2PoolUtils.java +++ b/src/main/java/com/light/util/H2PoolUtils.java @@ -1,15 +1,21 @@ package com.light.util; +import com.light.model.GitNotice; +import com.light.model.GitProject; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleStringProperty; +import org.apache.commons.lang3.StringUtils; import org.h2.jdbcx.JdbcConnectionPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; +import java.sql.*; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Properties; /** @@ -161,11 +167,11 @@ public class H2PoolUtils { public static String queryDictByLabel(String label, String defaultValue) { String value = defaultValue; - try { - Connection conn = getConnection(); - Statement stmt = conn.createStatement(); - String sql = "select * from git_project_dict where label = '" + label + "'"; - ResultSet resultSet = stmt.executeQuery(sql); + try (Connection conn = getConnection();) { + String sql = "select * from git_project_dict where label = ?"; + PreparedStatement statement = conn.prepareStatement(sql); + statement.setString(1, label); + ResultSet resultSet = statement.executeQuery(); while (resultSet.next()) { value = resultSet.getString("label_value"); } @@ -177,6 +183,130 @@ public class H2PoolUtils { } public static void updateDictData(String label, String value) { + try (Connection conn = getConnection()) { + String sql = "update git_project_dict set label_value = ? where label = ?"; + PreparedStatement statement = conn.prepareStatement(sql); + statement.setString(1, value); + statement.setString(2, label); + statement.executeUpdate(); + } catch (SQLException ignored) { + LOGGER.error("通过 {} 更新数据为 {} 失败:{}", label, value, ignored.getMessage()); + } + LOGGER.info("通过 {} 更新数据为 {} 成功", label, value); + } + + public static void insertNoticeHistory(String notice, String level) { + try (Connection conn = getConnection()) { + String sql = "INSERT INTO git_project_notice_history(notice, level, createtime) values(?,?,?)"; + PreparedStatement statement = conn.prepareStatement(sql); + statement.setString(1, notice); + statement.setString(2, level); + statement.setString(3, DateUtils.formatDateTime(new Date())); + statement.executeUpdate(); + } catch (SQLException e) { + LOGGER.error("记录 {} 数据异常:{}", notice, e.getMessage()); + } + LOGGER.info("记录 {} 数据成功", notice); + } + + public static List queryNoticeHistory(String level, boolean sort, int limit) { + List result = new ArrayList<>(); + try (Connection conn = getConnection()) { + String sql = "select * from git_project_notice_history " + (StringUtils.isBlank(level) ? "" : "where level = ?") + " order by createtime " + (sort ? "" : "desc") + " limit ? "; + PreparedStatement statement = conn.prepareStatement(sql); + if (StringUtils.isBlank(level)) { + statement.setInt(1, limit); + } else { + statement.setString(1, level); + statement.setInt(2, limit); + } + statement.executeQuery(); + + ResultSet resultSet = statement.getResultSet(); + while (resultSet.next()) { + GitNotice gitNotice = new GitNotice(resultSet.getInt("id"), + resultSet.getString("label"), resultSet.getString("label_value"), + resultSet.getString("createtime")); + result.add(gitNotice); + } + } catch (SQLException e) { + LOGGER.error("通过 {} 获取通知数据异常:{}", level, e.getMessage()); + } + return result; + } + public static List queryNoticeHistory(boolean sort, int limit) { + return queryNoticeHistory(null, sort, limit); + } + + public static void insertProjectInfo(GitProject project) { + try (Connection conn = getConnection()) { + String sql = """ + INSERT INTO git_project_info(name, author, + branch, remote, local, createtime, updatetime + ) values(?,?,?,?,?,?,?) + """; + PreparedStatement statement = conn.prepareStatement(sql); + statement.setString(1, project.name().get()); + statement.setString(2, project.author().get()); + statement.setString(3, project.branch().get()); + statement.setString(4, project.remote()); + statement.setString(5, project.local().get()); + Date date = new Date(); + statement.setString(6, DateUtils.formatDateTime(date)); + statement.setString(7, DateUtils.formatDateTime(date)); + statement.executeUpdate(); + } catch (SQLException e) { + LOGGER.error("项目信息保存异常:{}", e.getMessage()); + } + LOGGER.info("项目信息 {} 保存成功", project); + } + + public static void queryGitProjects() { + try (Connection conn = getConnection()) { + String sql = "select * from git_project_info order by id"; + PreparedStatement statement = conn.prepareStatement(sql); + statement.executeQuery(); + + ResultSet resultSet = statement.getResultSet(); + while (resultSet.next()) { + GitProject gitProject = new GitProject( + new SimpleStringProperty(resultSet.getInt("id") + ""), + new SimpleStringProperty(resultSet.getString("name")), + new SimpleStringProperty(resultSet.getString("author")), + new SimpleStringProperty(resultSet.getString("branch")), + resultSet.getString("createtime"), + new SimpleStringProperty(resultSet.getString("updatetime")), + resultSet.getString("remote"), + new SimpleStringProperty(resultSet.getString("local")), + new SimpleStringProperty(resultSet.getString("description")), + new SimpleStringProperty(resultSet.getString("remark")), + new SimpleIntegerProperty(resultSet.getInt("level")), + new SimpleDoubleProperty(0.0), + new SimpleBooleanProperty(false) + ); + gitProject.addSelectedListener(); + FxDataUtil.GIT_PROJECT_OBSERVABLE_LIST.add(gitProject); + } + } catch (SQLException e) { + LOGGER.error("获取所有项目信息异常:{}", e.getMessage()); + } + } + + public static void updateGitProject(GitProject project) { + try (Connection conn = getConnection()) { + String sql = "update git_project_info set branch = ? ,updatetime = ?, local = ?, description = ?, remark = ?, level = ? where id = ?"; + PreparedStatement statement = conn.prepareStatement(sql); + statement.setString(1, project.branch().get()); + statement.setString(2, project.updateTime().get()); + statement.setString(3, project.local().get()); + statement.setString(4, project.description().get()); + statement.setString(5, project.remark().get()); + statement.setInt(6, project.level().get()); + statement.setInt(7, Integer.parseInt(project.id().get())); + statement.executeUpdate(); + } catch (SQLException e) { + LOGGER.error("更新项目信息异常:{}", e.getMessage()); + } } } diff --git a/src/main/java/com/light/view/ManagerView.java b/src/main/java/com/light/view/ManagerView.java index 59d1dee..32dd5d6 100644 --- a/src/main/java/com/light/view/ManagerView.java +++ b/src/main/java/com/light/view/ManagerView.java @@ -10,11 +10,8 @@ import com.light.enums.Level; import com.light.model.GitProject; import com.light.thread.AsyncTask; import com.light.util.FxDataUtil; +import com.light.util.H2PoolUtils; import com.light.util.NoticeUtils; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleDoubleProperty; -import javafx.beans.property.SimpleIntegerProperty; -import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -93,25 +90,25 @@ public class ManagerView extends StackPane { select.setMinWidth(40d); var id = new TableColumn("序号"); - id.setCellValueFactory(c -> new SimpleStringProperty(c.getValue().id())); + id.setCellValueFactory(c -> c.getValue().id()); id.setPrefWidth(50d); id.setMaxWidth(50d); id.setMinWidth(50d); var warehouse = new TableColumn("仓库"); - warehouse.setCellValueFactory(c -> new SimpleStringProperty(c.getValue().name())); + warehouse.setCellValueFactory(c -> c.getValue().name()); var author = new TableColumn("作者"); - author.setCellValueFactory(c -> new SimpleStringProperty(c.getValue().author())); + author.setCellValueFactory(c -> c.getValue().author()); var branch = new TableColumn("分支"); branch.setSortable(false); branch.setCellFactory(ChoiceBoxTableCell.forTableColumn("master", "develop")); - branch.setCellValueFactory(c -> new SimpleStringProperty(c.getValue().branch())); + branch.setCellValueFactory(c -> c.getValue().branch()); var level = new TableColumn("学习等级"); level.setCellFactory(LevelTableCell.forTableColumn()); - level.setCellValueFactory(c -> new SimpleIntegerProperty(c.getValue().level()).asObject()); + level.setCellValueFactory(c -> c.getValue().level().asObject()); var process = new TableColumn("更新进度"); process.setSortable(false); @@ -121,7 +118,7 @@ public class ManagerView extends StackPane { var operation = new TableColumn("操作"); operation.setSortable(false); operation.setCellFactory(OperationTableCell.forTableColumn()); - operation.setCellValueFactory(c -> new SimpleStringProperty(c.getValue().id())); + operation.setCellValueFactory(c -> c.getValue().id()); operation.setPrefWidth(120d); operation.setMaxWidth(120d); operation.setMinWidth(120d); @@ -139,12 +136,7 @@ public class ManagerView extends StackPane { public void initData() { // TODO 查H2数据库获取数据 - for (int i = 0; i < 10; i++) { - GitProject gitProject = new GitProject(i + "", "g" + i + "it", "project", "develop", "2023-09-30", - "2023-09-30", "https://gitee.com/code-poison/git-manager-client-fx.git", "D:\\workspace\\workspace-dev\\git-manager-client-fx", "测试一下效果", "", i % 5, new SimpleDoubleProperty(0.0), new SimpleBooleanProperty(false)); - gitProject.addSelectedListener(); - FxDataUtil.GIT_PROJECT_OBSERVABLE_LIST.add(gitProject); - } + H2PoolUtils.queryGitProjects(); } public void initEvent() { @@ -216,10 +208,10 @@ public class ManagerView extends StackPane { List list; if (FxDataUtil.GIT_PROJECT_OBSERVABLE_LIST.size() > 10000) { list = FxDataUtil.GIT_PROJECT_OBSERVABLE_LIST. - parallelStream().filter(param -> param.name().contains(text) || param.author().contains(text)).toList(); + parallelStream().filter(param -> param.name().get().contains(text) || param.author().get().contains(text)).toList(); } else { list = FxDataUtil.GIT_PROJECT_OBSERVABLE_LIST. - stream().filter(param -> param.name().contains(text) || param.author().contains(text)).toList(); + stream().filter(param -> param.name().get().contains(text) || param.author().get().contains(text)).toList(); } tableView.setItems(FXCollections.observableList(list)); } else { -- Gitee From db206daa56c96b6017d0126b86f552de19a05e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=99=BD=E4=B8=8E=E5=AD=9F=E6=B5=A9=E7=84=B6?= <1063889643@qq.com> Date: Wed, 11 Oct 2023 14:39:53 +0800 Subject: [PATCH 9/9] =?UTF-8?q?+=20=E5=AE=8C=E5=96=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/light/theme/ThemeDialog.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/light/theme/ThemeDialog.java b/src/main/java/com/light/theme/ThemeDialog.java index fe7fa80..8128403 100644 --- a/src/main/java/com/light/theme/ThemeDialog.java +++ b/src/main/java/com/light/theme/ThemeDialog.java @@ -4,7 +4,9 @@ package com.light.theme; import atlantafx.base.theme.Theme; import com.light.layout.ModalDialog; +import com.light.thread.AsyncTask; import com.light.util.FxDataUtil; +import com.light.util.H2PoolUtils; import javafx.application.Application; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -37,6 +39,12 @@ public final class ThemeDialog extends ModalDialog { if (val != null && val.getUserData() instanceof Theme theme) { FxDataUtil.CURRENT_THEME_NAME.set(theme.getName()); Application.setUserAgentStylesheet(theme.getUserAgentStylesheet()); + AsyncTask.runOnce(new AsyncTask("","主题更新成功") { + @Override + protected void handler() throws Exception { + H2PoolUtils.updateDictData("GIT_CURRENT_THEME", theme.getName()); + } + }); } }); } -- Gitee