From 68d54c3f1dfabe0181822abdf32533eb3ca5cdfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=9C=E5=A8=81=E5=9E=9A?= <273231185@qq.com> Date: Wed, 18 Dec 2024 13:13:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/dbuml.db3 | Bin 36864 -> 36864 bytes src/DML.java | 26 +++++++ src/Main.java | 43 +++++++++- src/model/DataManager.java | 138 +++++++++++++++++++++++---------- src/view/OperationLogView.java | 74 ++++++++++++++---- src/view/OutboundView.java | 18 +++-- 6 files changed, 238 insertions(+), 61 deletions(-) diff --git a/db/dbuml.db3 b/db/dbuml.db3 index c8e1aab96514488de09873414becbeb37227271c..6f6c90a58d5e840b832518ad8f7a094b0247cf6b 100644 GIT binary patch delta 1764 zcmai!-%Aux6vt;*&HXud1AAC9m>%{aVaB=l&aa&%5~T7$TD0g@E4C<#jqoKRW{u2* zqGFZI2qdiZK}lAOL<=PR1AOVV2WM3f{12o%bKRM{6K;?9aPIk>@A*}l4wt6G?U(y{ zZx0oOo5ctBt_=y8OL5^a*ChxX$K~I&cZc$egEK(jqXQf$0gf;6T(XornOI8T_of)VytUsNZ)?vB3NU$v$b^0F5` zl3>KMIyY(0zjiD$qt(hRu@sW6Zh9)4os);Y^>d**{yiAGVRlfHypJ?H%M>W{VS;c# zCijTtAVr0URsl8)EGv@d>B)wS&MD{N$#fsCLW@X*#W-c(V%bpF)T}-7iFBY58=9&v zd7ekJw|>00SH|s$XD%>S16qF1l`O;tq(pSITG=oml(2!Qr$VCaE<~kN8i0St7I|gqY6c9y3M7vWl=lf%e+mZh6FNAXGJFRr35jEd9u; zg-#|cy!vj|9vLgNk_^aZv7?JLoHaCmbS=7Xj#<|mM0U`3-QL->9SpmwBtFIU=S*>0Bo1pC2baGU#x`=>P<3OXtb) z@ee4u*q_Cy6RH1v_u=t%hr#e8)8U|J$_;6G7gwfpQ8zmMEfG<4lk-FBPOUXRr2AHy znV4Qka>U&;S$F4qLagBOui{w%*10g4=Sb`4o#t0k_dkGhZB1gxr_ho#6OA2yDpXyQ PHVJ0 ze^2*Kf7&%0ZmLCyp^=q=nU#@=9#9M1)Mp*r>z_?u0Cd+548x5~O%08)8ZLs>a8oNI zQ$3&-WWyn5$Do?+!N{R23Gxar$SaeN4*}tv%>o5;`R&cjS%sOk89n{L gF=S$C0Q9f{a@fK`fEnn1O{8D}yPRqBn|cue0ERKGvH$=8 diff --git a/src/DML.java b/src/DML.java index b0a0c25..8b55574 100644 --- a/src/DML.java +++ b/src/DML.java @@ -185,4 +185,30 @@ public class DML { System.out.println("删除出库记录失败:" + e.getMessage()); } } + + @Test + public void createOperationLogsTable() { + try (Connection conn = DriverManager.getConnection(URL); + Statement stmt = conn.createStatement()) { + + // 删除已存在的表 + stmt.execute("DROP TABLE IF EXISTS operation_logs"); + + // 创建新表 + String sql = "CREATE TABLE operation_logs (" + + "id TEXT PRIMARY KEY NOT NULL," + + "operation_type TEXT NOT NULL," + + "operation_target TEXT NOT NULL," + + "operator TEXT NOT NULL," + + "operation_time TEXT NOT NULL," + + "details TEXT" + + ")"; + + stmt.execute(sql); + System.out.println("操作日志表创建成功"); + + } catch (SQLException e) { + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/src/Main.java b/src/Main.java index 3aec2f6..ff9e0d2 100644 --- a/src/Main.java +++ b/src/Main.java @@ -6,6 +6,8 @@ import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.stage.Stage; import view.*; +import java.sql.*; +import model.DataManager; public class Main extends Application { @@ -14,6 +16,9 @@ public class Main extends Application { @Override public void start(Stage primaryStage) { try { + // 初始化数据库表 + initDatabase(); + // 创建主布局 BorderPane mainLayout = new BorderPane(); @@ -50,6 +55,35 @@ public class Main extends Application { } } + @Override + public void stop() { + // 关闭数据库连接 + DataManager.closeConnection(); + } + + private void initDatabase() { + String url = "jdbc:sqlite:db/dbuml.db3"; + try (Connection conn = DriverManager.getConnection(url); + Statement stmt = conn.createStatement()) { + + // 创建操作日志表 + String sql = "CREATE TABLE IF NOT EXISTS operation_logs (" + + "id TEXT PRIMARY KEY NOT NULL," + + "operation_type TEXT NOT NULL," + + "operation_target TEXT NOT NULL," + + "operator TEXT NOT NULL," + + "operation_time TEXT NOT NULL," + + "details TEXT" + + ")"; + + stmt.execute(sql); + + } catch (SQLException e) { + e.printStackTrace(); + showAlert("错误", "初始化数据库失败:" + e.getMessage()); + } + } + private VBox createLeftPanel() { VBox leftPanel = new VBox(10); leftPanel.setPadding(new Insets(10)); @@ -163,7 +197,7 @@ public class Main extends Application { TreeItem root = new TreeItem<>("功能导航"); root.setExpanded(true); - // 库存管理 + // 库管理 TreeItem inventory = new TreeItem<>("库存管理"); inventory.getChildren().addAll( new TreeItem<>("入库管理"), @@ -254,6 +288,13 @@ public class Main extends Application { OperationLogView operationLogView = new OperationLogView(); contentArea.setCenter(operationLogView); } + private void showAlert(String title, String content) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(content); + alert.showAndWait(); + } public static void main(String[] args) { launch(args); } diff --git a/src/model/DataManager.java b/src/model/DataManager.java index 253b18f..db9bbb2 100644 --- a/src/model/DataManager.java +++ b/src/model/DataManager.java @@ -8,9 +8,14 @@ import java.util.List; import java.util.Map; import java.time.LocalDateTime; import java.util.stream.Collectors; +import javafx.application.Platform; +import javafx.scene.control.Alert; public class DataManager { private static DataManager instance; + private static final String DB_URL = "jdbc:sqlite:db/dbuml.db3"; + private static Connection connection; + private Map goodsMap; private List suppliers; private Map inventory; @@ -161,58 +166,79 @@ public class DataManager { } public void addOperationLog(String operationType, String operationTarget, String operator, String details) { - String id = String.format("NO%014d", System.currentTimeMillis()); - OperationLog log = new OperationLog(id, operationType, operationTarget, - operator, LocalDateTime.now(), details); - operationLogs.add(log); + System.out.println("开始添加操作日志..."); + System.out.println("类型: " + operationType); + System.out.println("目标: " + operationTarget); + System.out.println("详情: " + details); + + String id = String.format("LOG%014d", System.currentTimeMillis()); + LocalDateTime now = LocalDateTime.now(); - // 添加数据库操作 - String url = "jdbc:sqlite:db/dbuml.db3"; String sql = "INSERT INTO operation_logs (id, operation_type, operation_target, operator, operation_time, details) " + - "VALUES (?, ?, ?, ?, ?, ?)"; - - try (Connection conn = DriverManager.getConnection(url); - PreparedStatement pstmt = conn.prepareStatement(sql)) { + "VALUES (?, ?, ?, ?, ?, ?)"; + + synchronized (DataManager.class) { + try (PreparedStatement pstmt = getConnection().prepareStatement(sql)) { + pstmt.setString(1, id); + pstmt.setString(2, operationType); + pstmt.setString(3, operationTarget); + pstmt.setString(4, operator); + pstmt.setString(5, now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + pstmt.setString(6, details); - pstmt.setString(1, log.getId()); - pstmt.setString(2, log.getOperationType()); - pstmt.setString(3, log.getOperationTarget()); - pstmt.setString(4, log.getOperator()); - pstmt.setString(5, log.getOperationTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); - pstmt.setString(6, log.getDetails()); - - pstmt.executeUpdate(); + int result = pstmt.executeUpdate(); + if (result > 0) { + OperationLog log = new OperationLog(id, operationType, operationTarget, + operator, now, details); + operationLogs.add(log); + System.out.println("操作日志已添加: " + details); + } - } catch (SQLException e) { - e.printStackTrace(); - showAlert("错误", "���存操作日志失败:" + e.getMessage()); + } catch (SQLException e) { + System.err.println("添加操作日志失败: " + e.getMessage()); + e.printStackTrace(); + } } } public List getOperationLogs() { List logs = new ArrayList<>(); - String url = "jdbc:sqlite:db/dbuml.db3"; String sql = "SELECT * FROM operation_logs ORDER BY operation_time DESC"; - try (Connection conn = DriverManager.getConnection(url); - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(sql)) { - - while (rs.next()) { - OperationLog log = new OperationLog( - rs.getString("id"), - rs.getString("operation_type"), - rs.getString("operation_target"), - rs.getString("operator"), - LocalDateTime.parse(rs.getString("operation_time")), - rs.getString("details") - ); - logs.add(log); + synchronized (DataManager.class) { + try (Statement stmt = getConnection().createStatement(); + ResultSet rs = stmt.executeQuery(sql)) { + + while (rs.next()) { + try { + String id = rs.getString("id"); + String operationType = rs.getString("operation_type"); + String operationTarget = rs.getString("operation_target"); + String operator = rs.getString("operator"); + String timeStr = rs.getString("operation_time"); + String details = rs.getString("details"); + + LocalDateTime operationTime = LocalDateTime.parse(timeStr); + + OperationLog log = new OperationLog( + id, operationType, operationTarget, + operator, operationTime, details + ); + logs.add(log); + + System.out.println("读取到日志: " + operationType + " - " + details); + } catch (Exception e) { + System.err.println("解析日志记录失败: " + e.getMessage()); + e.printStackTrace(); + } + } + + System.out.println("总共读取到 " + logs.size() + " 条日志记录"); + + } catch (SQLException e) { + System.err.println("查询操作日志失败: " + e.getMessage()); + e.printStackTrace(); } - - } catch (SQLException e) { - e.printStackTrace(); - showAlert("错误", "读取操作日志失败:" + e.getMessage()); } return logs; @@ -297,6 +323,7 @@ public class DataManager { addGoods(goods); // 将操作日志类型从"新增"改为"修改" + System.out.println("正在添加操作日志: " + "修改" + " - " + "修改货物: " + goods.getName()); addOperationLog("修改", goods.getId(), "当前用户", "修改货物: " + goods.getName()); } catch (SQLException e) { e.printStackTrace(); @@ -319,6 +346,7 @@ public class DataManager { pstmt.setString(6, goods.getId()); pstmt.executeUpdate(); + System.out.println("正在添加操作日志: " + "更新" + " - " + "更新货物: " + goods.getName()); addOperationLog("更新", goods.getId(), "当前用户", "更新货物: " + goods.getName()); } catch (SQLException e) { e.printStackTrace(); @@ -327,7 +355,14 @@ public class DataManager { } - protected static void showAlert(String 错误, String s) { + protected static void showAlert(String title, String content) { + Platform.runLater(() -> { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(content); + alert.showAndWait(); + }); } public List getAllCategories() { @@ -336,4 +371,25 @@ public class DataManager { .distinct() .collect(Collectors.toList()); } + + private static synchronized Connection getConnection() throws SQLException { + if (connection == null || connection.isClosed()) { + connection = DriverManager.getConnection(DB_URL); + // 启用WAL模式,提高并发性能 + try (Statement stmt = connection.createStatement()) { + stmt.execute("PRAGMA journal_mode=WAL"); + } + } + return connection; + } + + public static void closeConnection() { + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } } diff --git a/src/view/OperationLogView.java b/src/view/OperationLogView.java index c25c7ab..3d8ae24 100644 --- a/src/view/OperationLogView.java +++ b/src/view/OperationLogView.java @@ -9,6 +9,7 @@ import model.DataManager; import model.OperationLog; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.List; public class OperationLogView extends BorderPane { @@ -106,22 +107,67 @@ public class OperationLogView extends BorderPane { } private void loadLogData() { - // 从DataManager获取日志数据 - tableView.setItems(FXCollections.observableArrayList( - DataManager.getInstance().getOperationLogs() - )); + try { + List logs = DataManager.getInstance().getOperationLogs(); + System.out.println("获取到 " + logs.size() + " 条操作日志"); + + if (logs.isEmpty()) { + Label noDataLabel = new Label("暂无操作日志"); + noDataLabel.setStyle("-fx-font-size: 14px;"); + tableView.setPlaceholder(noDataLabel); + } + + tableView.getItems().clear(); + tableView.setItems(FXCollections.observableArrayList(logs)); + + // 打印每条日志的内容 + for (OperationLog log : logs) { + System.out.println(String.format("日志: %s - %s - %s", + log.getOperationType(), + log.getOperationTime(), + log.getDetails())); + } + + } catch (Exception e) { + System.err.println("加载操作日志失败: " + e.getMessage()); + e.printStackTrace(); + showAlert("错误", "加载操作日志失败:" + e.getMessage()); + } } private void handleSearch() { - // 根据搜索条件过滤日志数据 - LocalDateTime startDate = startDatePicker.getValue() != null ? - startDatePicker.getValue().atStartOfDay() : null; - LocalDateTime endDate = endDatePicker.getValue() != null ? - endDatePicker.getValue().atTime(23, 59, 59) : null; - String operationType = operationTypeComboBox.getValue(); - - tableView.setItems(FXCollections.observableArrayList( - DataManager.getInstance().getFilteredOperationLogs(startDate, endDate, operationType) - )); + try { + LocalDateTime startDate = startDatePicker.getValue() != null ? + startDatePicker.getValue().atStartOfDay() : null; + LocalDateTime endDate = endDatePicker.getValue() != null ? + endDatePicker.getValue().atTime(23, 59, 59) : null; + String operationType = operationTypeComboBox.getValue(); + + List filteredLogs = DataManager.getInstance() + .getFilteredOperationLogs(startDate, endDate, operationType); + + // 设置空数据提示 + if (filteredLogs.isEmpty()) { + Label noDataLabel = new Label("未找到符合条件的操作日志"); + noDataLabel.setStyle("-fx-font-size: 14px;"); + tableView.setPlaceholder(noDataLabel); + } + + tableView.setItems(FXCollections.observableArrayList(filteredLogs)); + System.out.println("搜索到 " + filteredLogs.size() + " 条操作日志"); // 添加调试输出 + + } catch (Exception e) { + e.printStackTrace(); + System.err.println("搜索操作日志失败: " + e.getMessage()); // 添加错误输出 + showAlert("错误", "搜索操作日志失败:" + e.getMessage()); + } + } + + private void showAlert(String title, String content) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(content); + alert.showAndWait(); } } \ No newline at end of file diff --git a/src/view/OutboundView.java b/src/view/OutboundView.java index 3d84a9e..6b45e12 100644 --- a/src/view/OutboundView.java +++ b/src/view/OutboundView.java @@ -243,10 +243,18 @@ public class OutboundView extends BorderPane { // 清空输入 handleClear(); - // 添加操作日志 - String details = String.format("出库货物:%s,数量:%d,供应商:%s", - goodsName, quantity, customer); - DataManager.getInstance().addOperationLog("出库", goodsName, "当前用户", details); + // 添加出库操作日志 + String details = String.format("出库货物:%s,数量:%d,客户:%s,备注:%s", + goodsName, quantity, customer, remark); + System.out.println("正在添加出库日志: " + details); + + try { + DataManager.getInstance().addOperationLog("出库", goodsName, "当前用户", details); + System.out.println("出库日志添加成功"); + } catch (Exception e) { + System.err.println("添加出库日志失败: " + e.getMessage()); + e.printStackTrace(); + } showAlert("成功", "出库记录已保存!"); } else { @@ -319,7 +327,7 @@ public class OutboundView extends BorderPane { } } - // ��加填充字段的方法 + // 加填充字段的方法 private void fillFields(OutboundRecord record) { goodsField.setText(record.getGoodsId()); customerField.setText(record.getCustomer());