commit d3a94abd6d4e5e2cea60d5d691228aca998d1680 Author: lichx Date: Tue Dec 19 16:25:28 2023 +0800 首次git提交,用于lichx个人的多端同步 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..7714df6 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://127.0.0.1:3306 + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/libraries/mysql_connector_java_8_0_27.xml b/.idea/libraries/mysql_connector_java_8_0_27.xml new file mode 100644 index 0000000..2a385cb --- /dev/null +++ b/.idea/libraries/mysql_connector_java_8_0_27.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..9a35717 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..862a8d3 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/MatchLogs.txt b/MatchLogs.txt new file mode 100644 index 0000000..d4fe56f Binary files /dev/null and b/MatchLogs.txt differ diff --git a/MatchedTransports.txt b/MatchedTransports.txt new file mode 100644 index 0000000..bab3217 Binary files /dev/null and b/MatchedTransports.txt differ diff --git a/Object-oriented vs. multithreaded synthesis experiments.iml b/Object-oriented vs. multithreaded synthesis experiments.iml new file mode 100644 index 0000000..508d399 --- /dev/null +++ b/Object-oriented vs. multithreaded synthesis experiments.iml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libs/mysql-connector-java-8.0.27.jar b/libs/mysql-connector-java-8.0.27.jar new file mode 100644 index 0000000..683ac26 Binary files /dev/null and b/libs/mysql-connector-java-8.0.27.jar differ diff --git a/src/com/qst/dms/db/DBUtil.java b/src/com/qst/dms/db/DBUtil.java new file mode 100644 index 0000000..80ebac4 --- /dev/null +++ b/src/com/qst/dms/db/DBUtil.java @@ -0,0 +1,119 @@ +package com.qst.dms.db; + +import java.sql.*; + +import com.qst.dms.util.Config; + + +public class DBUtil { + Connection conn = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + /** + * 得到数据库连接 + */ + public Connection getConnection() throws ClassNotFoundException, + SQLException, InstantiationException, IllegalAccessException { + // 通过Config获取MySQL数据库配置信息 + String driver = Config.getValue("driver"); + String url = Config.getValue("url"); + String user = Config.getValue("user"); + String pwd = Config.getValue("password"); + try { + // 指定驱动程序 + Class.forName(driver); + // 建立数据库连结 + conn = DriverManager.getConnection(url, user, pwd); + return conn; + } catch (Exception e) { + // 如果连接过程出现异常,抛出异常信息 + throw new SQLException("驱动错误或连接失败!"); + } + } + + /** + * 释放资源 + */ + public void closeAll() { + // 如果rs不空,关闭rs + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 如果pstmt不空,关闭pstmt + if (pstmt != null) { + try { + pstmt.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // 如果conn不空,关闭conn + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + + /** + * 执行SQL语句,可以进行查询 + */ + public ResultSet executeQuery(String preparedSql, Object[] param) { + // 处理SQL,执行SQL + try { + // 得到PreparedStatement对象 + pstmt = conn.prepareStatement(preparedSql); + if (param != null) { + for (int i = 0; i < param.length; i++) { + // 为预编译sql设置参数 + pstmt.setObject(i + 1, param[i]); + } + } + // 执行SQL语句 + rs = pstmt.executeQuery(); + } catch (SQLException e) { + // 处理SQLException异常 + e.printStackTrace(); + } + return rs; + } + + /** + * 执行SQL语句,可以进行增、删、改的操作,不能执行查询 + */ + public int executeUpdate(String preparedSql, Object[] param) throws SQLIntegrityConstraintViolationException + { + int num = 0; + // 处理SQL,执行SQL + try { + // 得到PreparedStatement对象 + pstmt = conn.prepareStatement(preparedSql); + if (param != null) { + for (int i = 0; i < param.length; i++) { + // 为预编译sql设置参数 + pstmt.setObject(i + 1, param[i]); + } + } + // 执行SQL语句 + num = pstmt.executeUpdate(); + } + catch(SQLIntegrityConstraintViolationException e) + { + throw e; + } + //你都catch完了 我catch啥 那SQLIntegrityConstraintViolationException应该打印吗? + //我觉得直接catch然后throw给外部吧 + catch (SQLException e) { + // 处理SQLException异常 + e.printStackTrace(); + } + return num; + } +} diff --git a/src/com/qst/dms/db/config/mysql.properties b/src/com/qst/dms/db/config/mysql.properties new file mode 100644 index 0000000..0be5ba7 --- /dev/null +++ b/src/com/qst/dms/db/config/mysql.properties @@ -0,0 +1,5 @@ +driver = com.mysql.cj.jdbc.Driver +url = jdbc:mysql://localhost:3306/q_dms?useUnicode=true&characterEncoding=UTF-8 +user = root +password = 123456 +serverIP=127.0.0.1 diff --git a/src/com/qst/dms/dos/DBDemo.java b/src/com/qst/dms/dos/DBDemo.java new file mode 100644 index 0000000..94196aa --- /dev/null +++ b/src/com/qst/dms/dos/DBDemo.java @@ -0,0 +1,66 @@ +package com.qst.dms.dos; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; + +import com.qst.dms.entity.DataBase; +import com.qst.dms.entity.LogRec; +import com.qst.dms.entity.MatchedLogRec; +import com.qst.dms.entity.MatchedTransport; +import com.qst.dms.entity.Transport; +import com.qst.dms.service.LogRecService; +import com.qst.dms.service.TransportService; + +public class DBDemo { + public static void main(String[] args) { + // 创建一个日志业务类 + LogRecService logService = new LogRecService(); + ArrayList matchLogs = new ArrayList<>(); + matchLogs.add(new MatchedLogRec( + new LogRec(1001, new Date(), "青島",DataBase.GATHER, "zhangsan", "192.168.1.1", 1), + new LogRec(1002, new Date(), "青島", DataBase.GATHER, "zhangsan", "192.168.1.1", 0))); + matchLogs.add(new MatchedLogRec( + new LogRec(1003, new Date(), "北京",DataBase.GATHER, "lisi", "192.168.1.6", 1), + new LogRec(1004, new Date(), "北京", DataBase.GATHER, "lisi", "192.168.1.6", 0))); + matchLogs.add(new MatchedLogRec( + new LogRec(1005, new Date(), "济南",DataBase.GATHER, "wangwu", "192.168.1.89", 1), + new LogRec(1006, new Date(), "济南", DataBase.GATHER, "wangwu", "192.168.1.89", 0))); + //保存匹配的日志信息到数据库中 + logService.saveMatchLogToDB(matchLogs); + //从数据库中读取匹配的日志信息 + ArrayList logList = null; + try + { + logList = logService.readMatchedLogFromDB(); + } catch (SQLException e) + { + e.printStackTrace(); + } + logService.showMatchLog(logList); + + // 创建一个物流业务类 + TransportService tranService = new TransportService(); + ArrayList matchTrans = new ArrayList<>(); + matchTrans.add(new MatchedTransport( + new Transport(2001, new Date(), "青島",DataBase.GATHER,"zhangsan","zhaokel",1), + new Transport(2002, new Date(), "北京",DataBase.GATHER,"lisi","zhaokel",2), + new Transport(2003, new Date(), "北京",DataBase.GATHER,"wangwu","zhaokel",3))); + matchTrans.add(new MatchedTransport( + new Transport(2004, new Date(), "青島",DataBase.GATHER,"maliu","w",1), + new Transport(2005, new Date(), "北京",DataBase.GATHER,"sunqi","w",2), + new Transport(2006, new Date(), "北京",DataBase.GATHER,"fengba","w",3))); + //保存匹配的物流信息到数据库中 + tranService.saveMatchTransportToDB(matchTrans); + //从数据库中中读取匹配的物流信息 + ArrayList transportList = null; + try + { + transportList = tranService.readMatchedTransportFromDB(); + } catch (SQLException e) + { + e.printStackTrace(); + } + tranService.showMatchTransport(transportList); + } +} diff --git a/src/com/qst/dms/dos/EntityDataDemo.java b/src/com/qst/dms/dos/EntityDataDemo.java new file mode 100644 index 0000000..a39d86b --- /dev/null +++ b/src/com/qst/dms/dos/EntityDataDemo.java @@ -0,0 +1,34 @@ +package com.qst.dms.dos; + +import com.qst.dms.entity.LogRec; +import com.qst.dms.entity.Transport; +import com.qst.dms.service.LogRecService; +import com.qst.dms.service.TransportService; + +public class EntityDataDemo { + public static void main(String[] args) { + // 创建一个日志业务类 + LogRecService logService = new LogRecService(); + // 创建一个日志对象数组,用于存放采集的三个日志信息 + LogRec[] logs = new LogRec[3]; + for (int i = 0; i < logs.length; i++) { + System.out.println("第"+(i+1)+"个日志数据采集:"); + logs[i] = logService.inputLog(); + } + // 输出采集的日志信息 + logService.showLog(logs); + + // 创建一个物流业务类 + TransportService tranService = new TransportService(); + // 创建一个物流对象数组,用于存放采集的两个物流信息 + Transport[] transports = new Transport[2]; + for (int i = 0; i < transports.length; i++) { + System.out.println("第"+(i+1)+"个物流数据采集:"); + transports[i] = tranService.inputTransport(); + } + //输出采集的物流信息 + tranService.showTransport(transports); + + } + +} diff --git a/src/com/qst/dms/dos/FileDemo.java b/src/com/qst/dms/dos/FileDemo.java new file mode 100644 index 0000000..9cf94ca --- /dev/null +++ b/src/com/qst/dms/dos/FileDemo.java @@ -0,0 +1,56 @@ +package com.qst.dms.dos; + +import java.util.ArrayList; +import java.util.Date; + +import com.qst.dms.entity.DataBase; +import com.qst.dms.entity.LogRec; +import com.qst.dms.entity.MatchedLogRec; +import com.qst.dms.entity.MatchedTransport; +import com.qst.dms.entity.Transport; +import com.qst.dms.service.LogRecService; +import com.qst.dms.service.TransportService; + +public class FileDemo { + public static void main(String[] args) { + // 创建一个日志业务类 + LogRecService logService = new LogRecService(); + ArrayList matchLogs = new ArrayList<>(); + matchLogs.add(new MatchedLogRec( + new LogRec(1001, new Date(), "青島",DataBase.GATHER, "zhangsan", "192.168.1.1", 1), + new LogRec(1002, new Date(), "青島", DataBase.GATHER, "zhangsan", "192.168.1.1", 0))); + matchLogs.add(new MatchedLogRec( + new LogRec(1003, new Date(), "北京",DataBase.GATHER, "lisi", "192.168.1.6", 1), + new LogRec(1004, new Date(), "北京", DataBase.GATHER, "lisi", "192.168.1.6", 0))); + matchLogs.add(new MatchedLogRec( + new LogRec(1005, new Date(), "济南",DataBase.GATHER, "wangwu", "192.168.1.89", 1), + new LogRec(1006, new Date(), "济南", DataBase.GATHER, "wangwu", "192.168.1.89", 0))); + //保存匹配的日志信息到文件中 + //logService.saveMatchLog(matchLogs); + logService.saveAndAppendMatchLog(matchLogs); //追加测试 + //保存匹配的日志信息到数据库中 + //logService.saveMatchLogToDB(matchLogs); + //从文件中读取匹配的日志信息 + ArrayList list1 = logService.readMatchLog(); + logService.showMatchLog(list1); + + // 创建一个物流业务类 + TransportService tranService = new TransportService(); + ArrayList matchTrans = new ArrayList<>(); + matchTrans.add(new MatchedTransport( + new Transport(2001, new Date(), "青島",DataBase.GATHER,"zhangsan","zhaokel",1), + new Transport(2002, new Date(), "北京",DataBase.GATHER,"lisi","zhaokel",2), + new Transport(2003, new Date(), "北京",DataBase.GATHER,"wangwu","zhaokel",3))); + matchTrans.add(new MatchedTransport( + new Transport(2004, new Date(), "青島",DataBase.GATHER,"maliu","zhaokel",1), + new Transport(2005, new Date(), "北京",DataBase.GATHER,"sunqi","zhaokel",2), + new Transport(2006, new Date(), "北京",DataBase.GATHER,"fengba","zhaokel",3))); + //保存匹配的物流信息到文件中 + tranService.saveMatchedTransport(matchTrans); + //保存匹配的物流信息到数据库中 + //tranService.saveMatchTransportToDB(matchTrans); + //从文件中读取匹配的物流信息 + ArrayList list2 = tranService.readMatchedTransport(); + tranService.showMatchTransport(list2); + } +} diff --git a/src/com/qst/dms/dos/LogRecDemo.java b/src/com/qst/dms/dos/LogRecDemo.java new file mode 100644 index 0000000..11e7f61 --- /dev/null +++ b/src/com/qst/dms/dos/LogRecDemo.java @@ -0,0 +1,20 @@ +package com.qst.dms.dos; + +import com.qst.dms.entity.LogRec; +import com.qst.dms.service.LogRecService; + +public class LogRecDemo { + public static void main(String[] args) { + // 创建一个日志业务类 + LogRecService logService = new LogRecService(); + // 创建一个日志对象数组,用于存放采集的三个日志信息 + LogRec[] logs = new LogRec[3]; + for (int i = 0; i < logs.length; i++) { + System.out.println("第" + (i + 1) + "个日志数据采集:"); + logs[i] = logService.inputLog(); + } + // 显示日志信息 + logService.showLog(logs); + } + +} diff --git a/src/com/qst/dms/dos/MenuDriver.java b/src/com/qst/dms/dos/MenuDriver.java new file mode 100644 index 0000000..fee77f0 --- /dev/null +++ b/src/com/qst/dms/dos/MenuDriver.java @@ -0,0 +1,210 @@ +package com.qst.dms.dos; + +import java.util.ArrayList; +import java.util.InputMismatchException; +import java.util.Scanner; + +import com.qst.dms.entity.LogRec; +import com.qst.dms.entity.MatchedLogRec; +import com.qst.dms.entity.MatchedTransport; +import com.qst.dms.entity.Transport; +import com.qst.dms.gather.LogRecAnalyse; +import com.qst.dms.gather.TransportAnalyse; +import com.qst.dms.service.LogRecService; +import com.qst.dms.service.TransportService; + +public class MenuDriver +{ + public static void main(String[] args) + { + // 建立一个从键盘接收数据的扫描器 + Scanner scanner = new Scanner(System.in); + // 创建一个泛型ArrayList集合存储日志数据 + ArrayList logRecList = new ArrayList<>(); + // 创建一个泛型ArrayList集合存储物流数据 + ArrayList transportList = new ArrayList<>(); + + // 创建一个日志业务类 + LogRecService logService = new LogRecService(); + // 创建一个物流业务类 + TransportService tranService = new TransportService(); + + // 日志数据匹配集合 + ArrayList matchedLogs = null; + // 物流数据匹配集合 + ArrayList matchedTrans = null; + + try + { + while (true) + { + // 输出菜单界面,需补充 + //... + System.out.println("********************************************"); + System.out.println("欢迎进入日志物流信息管理系统!"); + System.out.println("* 1、数据采集 2、数据匹配 *"); + System.out.println("* 3、数据记录 4、数据显示 *"); + System.out.println("* 5、数据发送 0、退出应用 *"); + System.out.println("********************************************"); + // 提示用户输入要操作的菜单项 + System.out.println("请输入菜单项(0~5):"); + // 接收键盘输入的选项 + int choice; + for (; ; ) + try + { + choice = scanner.nextInt(); + break; + } catch (InputMismatchException e) + { + System.out.println("输入数据不合法,请重新输入"); + scanner.nextLine(); + } + switch (choice) + { + case 1: + { + System.out.println("请输入采集数据类型:1.日志 2.物流"); + // 接收键盘输入的选项 + int type = scanner.nextInt(); + if (type == 1) + { + System.out.println("正在采集日志数据,请输入正确信息,确保数据的正常采集!"); + // 采集日志数据,需补充LogService类中的inputLog方法 + LogRec log = logService.inputLog(); + // 将采集的日志数据添加到logRecList集合中 + logRecList.add(log); + } else if (type == 2) + { + System.out.println("正在采集物流数据,请输入正确信息,确保数据的正常采集!"); + // 采集物流数据,需补充tranService类中的inputTransport方法 + Transport tran = tranService.inputTransport(); + // 将采集的物流数据添加到transportList集合中 + transportList.add(tran); + } + } + break; + case 2: + { + System.out.println("请输入匹配数据类型:1.日志 2.物流"); + // 接收键盘输入的选项 + int type = scanner.nextInt(); + if (type == 1) + { + System.out.println("正在日志数据过滤匹配..."); + // 创建日志数据分析对象,用于日志数据筛选与匹配 + LogRecAnalyse logAn = new LogRecAnalyse(logRecList); + // 需实现doFilter抽象方法,对日志数据进行过滤,根据日志登录状态 + //分别放在登录和登出两个集合中 + logAn.doFilter(); + // 日志数据分析 + matchedLogs = logAn.matchData(); + System.out.println("日志数据过滤匹配完成!"); + } else if (type == 2) + { + System.out.println("正在物流数据过滤匹配..."); + // 创建物流数据分析对象 + TransportAnalyse transAn = new TransportAnalyse( + transportList); + // 物流数据过滤 + transAn.doFilter(); + // 物流数据分析 + matchedTrans = transAn.matchData(); + System.out.println("物流数据过滤匹配完成!"); + } + } + break; + case 3: + System.out.println("请输入记录数据类型:1.日志 2.物流"); + int type = 0; + while (true) + { + if (scanner.hasNextInt()) + { + type = scanner.nextInt(); + if (type >= 1 && type <= 2) + break; + else + System.out.println("请输入合法的数字"); + } else + { + System.out.println("请输入合法的数字"); + scanner.nextLine(); + } + } + try + { + if (type == 1) + { + //logService.saveMatchLog(matchedLogs); 2023.11.17 改为追加方式 + logService.saveAndAppendMatchLog(matchedLogs); + logService.saveMatchLogToDB(matchedLogs);//添加至DB + logRecList.clear(); + matchedLogs.clear(); + //添加数据库追加 + } else if (type == 2) + { + //tranService.saveMatchedTransport(matchedTrans); 2023.11.17 改为追加方式 + tranService.saveAndAppendTransport(matchedTrans); + tranService.saveMatchTransportToDB(matchedTrans);//添加至DB + transportList.clear(); + matchedTrans.clear(); + } + } + catch(NullPointerException ex) + { + System.out.println("没有信息需要记录"); + } + + + break; + case 4: + { + System.out.println("显示匹配的数据:"); +// ArrayList last_log = logService.readMatchLog(); +// ArrayList last_transport = tranService.readMatchedTransport(); 2023.11.25改为读取数据库数据 + ArrayListlast_log = logService.readMatchedLogFromDB(); + ArrayListlast_transport = tranService.readMatchedTransportFromDB(); + if (last_log.isEmpty() && (matchedLogs == null || matchedLogs.isEmpty())) + { + System.out.println("匹配的日志记录是0条!"); + } else + { + //输出匹配的日志信息 + System.out.println("日志:"); + if (!last_log.isEmpty()) + logService.showMatchLog(last_log); + if (matchedLogs != null && (!matchedLogs.isEmpty())) + logService.showMatchLog(matchedLogs); + } + if (last_transport.isEmpty() && (matchedTrans == null || matchedTrans.isEmpty())) + { + System.out.println("匹配的物流记录是0条!"); + } else + { + // 输出匹配的物流信息 + System.out.println("物流:"); + if (!last_transport.isEmpty()) + tranService.showMatchTransport(last_transport); + if (matchedTrans != null && (!matchedTrans.isEmpty())) + tranService.showMatchTransport(matchedTrans); + } + } + break; + case 5: + System.out.println("数据发送 中..."); + break; + case 0: + // 应用程序退出 + System.exit(0); + default: + System.out.println("请输入正确的菜单项(0~5)!"); + } + + } + } catch (Exception e) + { + System.out.println("输入的数据不合法!"); + } + } +} diff --git a/src/com/qst/dms/dos/TransportDemo.java b/src/com/qst/dms/dos/TransportDemo.java new file mode 100644 index 0000000..902c314 --- /dev/null +++ b/src/com/qst/dms/dos/TransportDemo.java @@ -0,0 +1,22 @@ +package com.qst.dms.dos; + +import com.qst.dms.entity.Transport; +import com.qst.dms.service.TransportService; + +public class TransportDemo { + + public static void main(String[] args) { + // 创建一个物流业务类 + TransportService tranService = new TransportService(); + // 创建一个物流对象数组,用于存放采集的四个物流信息 + Transport[] transports = new Transport[4]; + for (int i = 0; i < transports.length; i++) { + System.out.println("第" + (i + 1) + "个物流数据采集:"); + transports[i] = tranService.inputTransport(); + } + // 显示物流信息 + tranService.showTransport(transports); + + } + +} diff --git a/src/com/qst/dms/entity/AppendObjectOutputStream.java b/src/com/qst/dms/entity/AppendObjectOutputStream.java new file mode 100644 index 0000000..eb9a85c --- /dev/null +++ b/src/com/qst/dms/entity/AppendObjectOutputStream.java @@ -0,0 +1,30 @@ +package com.qst.dms.entity; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +public class AppendObjectOutputStream extends ObjectOutputStream +{ + public static File file = null; + public AppendObjectOutputStream() throws IOException + { + super(new FileOutputStream(file,true)); + //AppendObjectOutputStream.file = file; 这不可行 因为 上面的构造函数调用了writeStreamHeadler 然后file=null 所以需要在外部提前赋值 + } + public void writeStreamHeader() throws IOException + { + if(file!=null) + { + if (file.length() == 0) + super.writeStreamHeader(); + else + { + //super. + this.reset(); + } + } else + super.writeStreamHeader(); + } +} diff --git a/src/com/qst/dms/entity/DataBase.java b/src/com/qst/dms/entity/DataBase.java new file mode 100644 index 0000000..d2b0da7 --- /dev/null +++ b/src/com/qst/dms/entity/DataBase.java @@ -0,0 +1,79 @@ +package com.qst.dms.entity; + +import java.io.Serializable; +import java.util.Date; + +//数据基础类 + +public class DataBase implements Serializable{ + // ID标识 + private int id; + // 时间 + private Date time; + // 地点 + private String address; + // 状态 + private int type; + // 状态常量 + public static final int GATHER=1;//"采集" + public static final int MATHCH=2;//"匹配"; + public static final int RECORD=3;//"记录"; + public static final int SEND=4;//"发送"; + public static final int RECIVE=5;//"接收"; + public static final int WRITE=6;//"归档"; + public static final int SAVE=7;//"保存"; + + public int getId() { + return id; + } + + + public void setId(int id) { + this.id = id; + } + + + public Date getTime() { + return time; + } + + + public void setTime(Date time) { + this.time = time; + } + + + public String getAddress() { + return address; + } + + + public void setAddress(String address) { + this.address = address; + } + + public int getType() { + return type; + } + + + public void setType(int type) { + this.type = type; + } + + public DataBase() { + } + + public DataBase(int id, Date time, String address, int type) { + this.id = id; + this.time = time; + this.address = address; + this.type = type; + } + + + public String toString() { + return id + "," + time + "," + address + "," + type; + } + +} diff --git a/src/com/qst/dms/entity/LogRec.java b/src/com/qst/dms/entity/LogRec.java new file mode 100644 index 0000000..e6300ae --- /dev/null +++ b/src/com/qst/dms/entity/LogRec.java @@ -0,0 +1,85 @@ + +package com.qst.dms.entity; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +//用户登录日志记录 +public class LogRec extends DataBase implements Serializable{ + /** + * 登录用户名 + */ + private String user; + /** + * 登录用户主机IP地址 + */ + private String ip; + /** + * 登录状态:登录、登出 + */ + private int logType; + /** + * 登录常量LOG_IN、登出常量常量LOG_OUT + */ + public static final int LOG_IN=1; + public static final int LOG_OUT=0; + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getLogType() { + return logType; + } + + public static LogRec get_LogRec(Object[] info) + { + int id = (int)info[0],type = (int)info[3],logtype = (int)info[6]; + Date time = Date.from( ((LocalDateTime)info[1]).atZone( ZoneId.systemDefault()).toInstant()); + String address = (String)info[2],username = (String)info[4],ip = (String)info[5]; + return new LogRec(id,time,address,type,username,ip,logtype); + } + public Object[] get_DB_param() + { + return new Object[]{ + this.getId(), + new Timestamp(this.getTime().getTime()), + this.getAddress(),this.getType(),this.getUser(), + this.getIp(),this.getLogType() + }; + } + + + public void setLogType(int logType) { + this.logType = logType; + } + + public LogRec() { + } + + public LogRec(int id, Date time, String address, int type,String user,String ip,int logType) { + super(id,time,address,type); + this.user=user; + this.ip=ip; + this.logType=logType; + } + + public String toString() { + return this.getId() + "," +this.getTime() + "," +this.getAddress() + "," + this.getType() + ","+user+","+ip+","+logType; + } +} diff --git a/src/com/qst/dms/entity/MatchedLogRec.java b/src/com/qst/dms/entity/MatchedLogRec.java new file mode 100644 index 0000000..db18404 --- /dev/null +++ b/src/com/qst/dms/entity/MatchedLogRec.java @@ -0,0 +1,72 @@ + +package com.qst.dms.entity; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Date; + +//匹配日志记录,"登录登出对" 类型 + +public class MatchedLogRec implements Serializable { + + private LogRec login; + private LogRec logout; + + // user用户登录名 + public String getUser() { + return login.getUser(); + } + + //登录地点 + public String getAddress(){return login.getAddress();} + // 登入时刻 + public Date getLogInTime() { + return login.getTime(); + } + + // 登出时刻 + public Date getLogoutTime() { + return logout.getTime(); + } + + // 登入记录 + public LogRec getLogin() { + return login; + } + + // 登出记录 + public LogRec getLogout() { + return logout; + } + + public Object[] get_DB_param() + { + return new Object[]{ + login.getId(),logout.getId() + }; + } + public MatchedLogRec() { + } + + public MatchedLogRec(LogRec login, LogRec logout) { + if (login.getLogType() != LogRec.LOG_IN) { + throw new RuntimeException("不是登录记录!"); + } + if (logout.getLogType() != LogRec.LOG_OUT) { + throw new RuntimeException("不是登出记录"); + } + if (!login.getUser().equals(logout.getUser())) { + throw new RuntimeException("登录登出必须是同一个用户!"); + } + if (!login.getIp().equals(logout.getIp())) { + throw new RuntimeException("登录登出必须是同一个IP地址!"); + } + this.login = login; + this.logout = logout; + } + + public String toString() { + return login.toString() + " | " + logout.toString(); + } + +} diff --git a/src/com/qst/dms/entity/MatchedTransport.java b/src/com/qst/dms/entity/MatchedTransport.java new file mode 100644 index 0000000..8eed66d --- /dev/null +++ b/src/com/qst/dms/entity/MatchedTransport.java @@ -0,0 +1,62 @@ +/** + * @公司 青软实训QST + * @作者 zhaokl + */ +package com.qst.dms.entity; + +import java.io.Serializable; + +public class MatchedTransport implements Serializable{ + private Transport send; + private Transport trans; + private Transport receive; + + public Transport getSend() { + return send; + } + + public void setSend(Transport send) { + this.send = send; + } + + public Transport getTrans() { + return trans; + } + + public void setTrans(Transport trans) { + this.trans = trans; + } + + public Transport getReceive() { + return receive; + } + + public void setReceive(Transport receive) { + this.receive = receive; + } + + public MatchedTransport() { + + } + + public MatchedTransport(Transport send, Transport trans, Transport receive) { + if (send.getTransportType() != Transport.SENDING) { + throw new RuntimeException("不是发货记录!"); + } + if (trans.getTransportType() != Transport.TRANSPORTING) { + throw new RuntimeException("不是送货记录!"); + } + if (receive.getTransportType() != Transport.RECEIVED) { + throw new RuntimeException("不是签收记录!"); + } + this.send = send; + this.trans = trans; + this.receive = receive; + } + + public String toString() { + // TODO Auto-generated method stub + return send.toString() + "|" + trans.toString() + "|" + receive; + } + +} diff --git a/src/com/qst/dms/entity/Transport.java b/src/com/qst/dms/entity/Transport.java new file mode 100644 index 0000000..472a860 --- /dev/null +++ b/src/com/qst/dms/entity/Transport.java @@ -0,0 +1,92 @@ +/** + * @公司 青软实训QST + * @作者 zhaokl + */ +package com.qst.dms.entity; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +//货运物流信息 +public class Transport extends DataBase implements Serializable{ + /** + * 经手人 + */ + private String handler; + /** + * 收货人 + */ + private String reciver; + /** + * 物流状态 + */ + private int transportType; + /** + * 物流状态常量:发货中, 送货中, 已签收 + */ + public static final int SENDING = 1;// 发货中 + public static final int TRANSPORTING = 2;// 送货中 + public static final int RECEIVED = 3;// 已签收 + + public String getHandler() { + return handler; + } + + public void setHandler(String handler) { + this.handler = handler; + } + + public String getReciver() { + return reciver; + } + + public void setReciver(String reciver) { + this.reciver = reciver; + } + + public int getTransportType() { + return transportType; + } + + public void setTransportType(int transportType) { + this.transportType = transportType; + } + + public Transport() { + + } + + public Transport(int id, Date time, String address, int type, + String handler, String reciver, int transportType) { + super(id, time, address, type); + this.handler = handler; + this.reciver = reciver; + this.transportType = transportType; + } + + static public Transport get_Transport(Object[] info) + { + int id = (Integer) info[0],type = (Integer) info[3],transportType = (Integer) info[6]; + Date time = Date.from( ((LocalDateTime)info[1]).atZone( ZoneId.systemDefault()).toInstant()); + String address = (String) info[2],handler = (String) info[4],reciver = (String)info[5]; + return new Transport(id,time,address,type,handler,reciver,transportType); + } + + public Object[] get_DB_param() + { + return new Object[]{ + this.getId(),new Timestamp(this.getTime().getTime()), + this.getAddress(),this.getType(),this.getHandler(),this.getReciver(), + this.getTransportType() + }; + } + + public String toString() { + return this.getId() + "," + this.getTime() + "," + this.getAddress() + + "," + this.getType() + "," + handler + "," + transportType; + } + +} diff --git a/src/com/qst/dms/entity/User.java b/src/com/qst/dms/entity/User.java new file mode 100644 index 0000000..e8a40c2 --- /dev/null +++ b/src/com/qst/dms/entity/User.java @@ -0,0 +1,99 @@ +package com.qst.dms.entity; + +//用户实体 +public class User { + // 用户id + private int id; + // 用户名 + private String username; + // 密码 + private String password; + // 性别 + private int sex; + // 爱好 + private String hobby; + // 地址 + private String address; + // 学历 + private String degree; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getSex() { + return sex; + } + + public void setSex(int sex) { + this.sex = sex; + } + + public String getHobby() { + return hobby; + } + + public void setHobby(String hobby) { + this.hobby = hobby; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getDegree() { + return degree; + } + + public void setDegree(String degree) { + this.degree = degree; + } + + public User() { + } + + public User(String username, String password, int sex, String hobby, + String address, String degree) { + this.username = username; + this.password = password; + this.sex = sex; + this.hobby = hobby; + this.address = address; + this.degree = degree; + } + + public User(int id, String username, String password, int sex, + String hobby, String address, String degree) { + this.id = id; + this.username = username; + this.password = password; + this.sex = sex; + this.hobby = hobby; + this.address = address; + this.degree = degree; + } +} diff --git a/src/com/qst/dms/exception/DataAnalyseException.java b/src/com/qst/dms/exception/DataAnalyseException.java new file mode 100644 index 0000000..52542e7 --- /dev/null +++ b/src/com/qst/dms/exception/DataAnalyseException.java @@ -0,0 +1,10 @@ +package com.qst.dms.exception; + +public class DataAnalyseException extends Exception { + public DataAnalyseException() { + } + + public DataAnalyseException(String msg) { + super(msg); + } +} diff --git a/src/com/qst/dms/gather/DataFilter.java b/src/com/qst/dms/gather/DataFilter.java new file mode 100644 index 0000000..5ed8d49 --- /dev/null +++ b/src/com/qst/dms/gather/DataFilter.java @@ -0,0 +1,31 @@ +package com.qst.dms.gather; + +import java.util.ArrayList; + +import com.qst.dms.entity.DataBase; + +//数据过滤抽象类 +public abstract class DataFilter { + // 数据集合,使用泛型集合 + private ArrayList datas; + + public ArrayList getDatas() { + return datas; + } + + public void setDatas(ArrayList datas) { + this.datas = datas; + } + + // 构造方法 + public DataFilter() { + + } + + public DataFilter(ArrayList datas) { + this.datas = datas; + } + + // 数据过滤抽象方法 + public abstract void doFilter(); +} diff --git a/src/com/qst/dms/gather/IDataAnalyse.java b/src/com/qst/dms/gather/IDataAnalyse.java new file mode 100644 index 0000000..c5bd66c --- /dev/null +++ b/src/com/qst/dms/gather/IDataAnalyse.java @@ -0,0 +1,9 @@ +package com.qst.dms.gather; + +import java.util.ArrayList; + +//数据分析接口 +public interface IDataAnalyse { + // 进行数据匹配,返回泛型ArrayList集合 + ArrayList matchData(); +} diff --git a/src/com/qst/dms/gather/LogRecAnalyse.java b/src/com/qst/dms/gather/LogRecAnalyse.java new file mode 100644 index 0000000..45989b4 --- /dev/null +++ b/src/com/qst/dms/gather/LogRecAnalyse.java @@ -0,0 +1,74 @@ +package com.qst.dms.gather; + +import java.util.ArrayList; + +import com.qst.dms.entity.DataBase; +import com.qst.dms.entity.LogRec; +import com.qst.dms.entity.MatchedLogRec; +import com.qst.dms.exception.DataAnalyseException; + +//日志分析类,继承DataFilter抽象类,实现数据分析接口 +public class LogRecAnalyse extends DataFilter implements IDataAnalyse { + // “登录”集合 + private ArrayList logIns = new ArrayList<>(); + // “登出”集合 + private ArrayList logOuts = new ArrayList<>(); + + // 构造方法 + public LogRecAnalyse() { + } + + public LogRecAnalyse(ArrayList logRecs) { + super(logRecs); + } + + // 实现DataFilter抽象类中的过滤抽象方法 + public void doFilter() { + // 获取数据集合 + ArrayList logs = (ArrayList) this.getDatas(); + // 遍历,对日志数据进行过滤,根据日志登录状态分别放在不同的数组中 + // 添加到“登录”日志集合中 + // 添加到“登出”日志集合中 + for (LogRec log:logs) + { + //1是登录,0是登出 + if(log.getLogType()==1) + logIns.add(log); + else + logOuts.add(log); + } + + + } + // 实现IDataAnalyse接口中数据分析方法 + public ArrayList matchData() { + // 创建日志匹配集合 + ArrayList matchLogs = new ArrayList<>(); + + // 数据匹配分析 + try + { + for(LogRec logIn:logIns) + for(LogRec logOut:logOuts) + try + { + matchLogs.add(new MatchedLogRec(logIn,logOut)); + } + catch(RuntimeException e) + { + continue; + } + if(matchLogs.isEmpty()) + throw new DataAnalyseException("没有匹配的数据"); + } + catch (DataAnalyseException e) + { + e.printStackTrace(); + } + //try + // 没找到匹配的数据,抛出DataAnalyseException异常 + //catch (DataAnalyseException e) { + //e.printStackTrace(); + return matchLogs; + } +} \ No newline at end of file diff --git a/src/com/qst/dms/gather/TransportAnalyse.java b/src/com/qst/dms/gather/TransportAnalyse.java new file mode 100644 index 0000000..efd8f0d --- /dev/null +++ b/src/com/qst/dms/gather/TransportAnalyse.java @@ -0,0 +1,75 @@ +package com.qst.dms.gather; + +import java.util.ArrayList; + +import com.qst.dms.entity.DataBase; +import com.qst.dms.entity.MatchedTransport; +import com.qst.dms.entity.Transport; +import com.qst.dms.exception.DataAnalyseException; + +//物流分析类,继承DataFilter抽象类,实现数据分析接口 +public class TransportAnalyse extends DataFilter implements IDataAnalyse { + // 发货集合 + private ArrayList transSends = new ArrayList<>(); + // 送货集合 + private ArrayList transIngs = new ArrayList<>(); + // 已签收集合 + private ArrayList transRecs = new ArrayList<>(); + + // 构造方法 + public TransportAnalyse() { + } + + public TransportAnalyse(ArrayList trans) { + super(trans); + } + + // 实现DataFilter抽象类中的过滤抽象方法 + public void doFilter() { + // 获取数据集合 + ArrayList trans = (ArrayList) this.getDatas(); + + // 遍历,对物流数据进行过滤,根据物流状态分别放在不同的集合中 + for (Transport tran : trans) { + if (tran.getTransportType() == Transport.SENDING) { + transSends.add(tran); + } else if (tran.getTransportType() == Transport.TRANSPORTING) { + transIngs.add(tran); + } else if (tran.getTransportType() == Transport.RECEIVED) { + transRecs.add(tran); + } + } + + } + + // 实现IDataAnalyse接口中数据分析方法 + public ArrayList matchData() { + // 创建物流匹配集合 + ArrayList matchTrans = new ArrayList<>(); + // 数据匹配分析 + for (Transport send : transSends) { + for (Transport tran : transIngs) { + for (Transport rec : transRecs) { + if ((send.getReciver().equals(tran.getReciver())) + && (send.getReciver().equals(rec.getReciver()))) { + // 修改物流状态类型为“匹配” + send.setType(DataBase.MATHCH); + tran.setType(DataBase.MATHCH); + rec.setType(DataBase.MATHCH); + // 添加到匹配集合中 + matchTrans.add(new MatchedTransport(send, tran, rec)); + } + } + } + } + try { + if (matchTrans.size() == 0) { + // 没找到匹配的数据,抛出DataAnalyseException异常 + throw new DataAnalyseException("没有匹配的物流数据!"); + } + } catch (DataAnalyseException e) { + e.printStackTrace(); + } + return matchTrans; + } +} diff --git a/src/com/qst/dms/security/String_SHA_256.java b/src/com/qst/dms/security/String_SHA_256.java new file mode 100644 index 0000000..04b6ea3 --- /dev/null +++ b/src/com/qst/dms/security/String_SHA_256.java @@ -0,0 +1,35 @@ +package com.qst.dms.security; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class String_SHA_256 +{ + public static String String_to_SHA256(String password) + { + StringBuilder hexString = new StringBuilder(); + if (password == null) + { + return null; + } + try { + // 创建MessageDigest实例并指定算法为SHA-256 + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + // 计算散列值 + byte[] hashBytes = digest.digest(password.getBytes()); + // 将散列值转换为十六进制字符串表示 + for (byte b : hashBytes) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + finally + { + return hexString.toString(); + } + } +} diff --git a/src/com/qst/dms/service/LogRecService.java b/src/com/qst/dms/service/LogRecService.java new file mode 100644 index 0000000..6da729e --- /dev/null +++ b/src/com/qst/dms/service/LogRecService.java @@ -0,0 +1,260 @@ +package com.qst.dms.service; +import java.io.EOFException; +import java.io.*; +import java.io.FileNotFoundException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.InputMismatchException; +import java.util.Scanner; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; + +import com.qst.dms.db.DBUtil; +import com.qst.dms.entity.*; +import com.sun.net.httpserver.Request; + +//日志业务类 +public class LogRecService { + // 日志数据采集 + public LogRec inputLog() { + LogRec log = null; + // 建立一个从键盘接收数据的扫描器 + Scanner scanner = new Scanner(System.in); + try { + // 提示用户输入ID标识 + System.out.println("请输入ID标识:"); + // 接收键盘输入的整数 + + int id =0; + for(;;) + try + { + id = scanner.nextInt(); + break; + } + catch(InputMismatchException e) + { + System.out.println("输入数据不合法,请重新输入"); + scanner.nextLine(); + } + // 获取当前系统时间 + Date nowDate = new Date(); + // 提示用户输入地址 + System.out.println("请输入地址:"); + // 接收键盘输入的字符串信息 + String address = scanner.next(); + // 数据状态是“采集” + int type = DataBase.GATHER; + // 提示用户输入登录用户名 + System.out.println("请输入登录用户名:"); + // 接收键盘输入的字符串信息 + String user = scanner.next(); + // 提示用户输入主机IP +// System.out.println("请输入主机IP:"); +// // 接收键盘输入的字符串信息 +// String ip = scanner.next(); + String ip = ""; + try { + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface iface = interfaces.nextElement(); + // 过滤回环接口和虚拟接口 + if (iface.isLoopback() || iface.isVirtual() || !iface.isUp()) { + continue; + } + Enumeration addresses = iface.getInetAddresses(); + while (addresses.hasMoreElements()) { + ip = addresses.nextElement().getHostAddress(); + } + } + + } catch (SocketException e) { + e.printStackTrace(); + } + // 提示用户输入登录状态、登出状态 + System.out.println("请输入登录状态:1是登录,0是登出"); + int logType = 0; + for(;;) + try + { + logType = scanner.nextInt(); + if(logType!=0&&logType!=1) + throw new InputMismatchException(); + break; + } + catch(InputMismatchException e) + { + System.out.println("输入数据不合法,请重新输入"); + scanner.nextLine(); + } + // 创建日志对象 + log = new LogRec(id, nowDate, address, type, user, ip, logType); + } catch (Exception e) { + System.out.println("采集的日志信息不合法"); + } + // 返回日志对象 + return log; + } + + public ArrayList readMatchLog() + { + ArrayList matchedLogs = new ArrayList<>(); + try(ObjectInputStream OIStream = new ObjectInputStream(new FileInputStream("MatchLogs.txt"))) + { + MatchedLogRec matchLog; + while((matchLog = (MatchedLogRec) OIStream.readObject())!=null) + matchedLogs.add(matchLog); + } + catch(FileNotFoundException ex) + { + ; + } + catch(EOFException ex) + { + ; + } + catch(Exception Ex) + { + Ex.printStackTrace(); + } + return matchedLogs; + } + public ArrayList readMatchedLogFromDB() throws SQLException + { + ArrayListmatchedLogRecs = new ArrayList<>(); + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + String sql = "select i.id,i.time,i.address,i.type,i.username,i.ip,i.logtype,"+ + "o.id,o.time,o.address,o.type,o.username,o.ip,o.logtype "+ + "from matched_logrec m,gather_logrec i,gather_logrec o "+ + "where m.loginid=i.id AND m.logoutid=o.id;"; + ResultSet resultSet = db.executeQuery(sql,null); + while(resultSet.next()) + { + Object[] temp = new Object[7]; + for(int i=1;i<=7;i++) + temp[i-1] = resultSet.getObject(i); + LogRec login = LogRec.get_LogRec(temp); + for(int i=8;i<=14;i++) + temp[i-8] = resultSet.getObject(i); + LogRec logout = LogRec.get_LogRec(temp); + matchedLogRecs.add(new MatchedLogRec(login,logout)); + } + db.closeAll(); + } + catch (SQLException e) + { + throw e; + } + catch (Exception e) + { + e.printStackTrace(); + } + return matchedLogRecs; + } + + public void saveMatchLog(ArrayListmatchLogs) + { + try{ + ObjectOutputStream obStream = new ObjectOutputStream(new FileOutputStream("MatchLogs.txt")); + for(MatchedLogRec log:matchLogs) + { + if(log==null) + continue; + obStream.writeObject(log); + obStream.flush(); + } + //null 代表结尾 + obStream.writeObject(null); + obStream.close(); + }catch(Exception Ex) + { + Ex.printStackTrace(); + } + } + + public void saveAndAppendMatchLog(ArrayListmatchLogs) + { + if(matchLogs==null) + return; + try + { + File file = new File("MatchLogs.txt"); + AppendObjectOutputStream.file = file; + AppendObjectOutputStream AOOStream = new AppendObjectOutputStream(); + for(MatchedLogRec log:matchLogs) + { + if(log==null) + continue; + AOOStream.writeObject(log); + AOOStream.flush(); + } + //null 代表结尾 + //AOOStream.writeObject(null); + AOOStream.close(); + } + catch (Exception Ex) + { + Ex.printStackTrace(); + } + } + public void saveMatchLogToDB(ArrayListmatchLogs) + { + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + for(MatchedLogRec logRec:matchLogs) + { + LogRec login = logRec.getLogin(); + LogRec logout = logRec.getLogout(); + //信息 + String sql = "INSERT INTO gather_logrec(id,time,address,type,username,ip,logtype) VALUES(?,?,?,?,?,?,?)"; + db.executeUpdate(sql, login.get_DB_param()); + db.executeUpdate(sql, logout.get_DB_param()); + //匹配对 + sql = "INSERT INTO matched_logrec(loginid,logoutid) VALUES(?,?)"; + db.executeUpdate(sql, logRec.get_DB_param()); + } + db.closeAll(); + } catch(Exception e) + { + e.printStackTrace(); + } + } + + + // 日志信息输出 + public void showLog(LogRec... logRecs) { + for (LogRec e : logRecs) { + if (e != null) { + System.out.println(e.toString()); + } + } + } + // 匹配日志信息输出,可变参数 + public void showMatchLog(MatchedLogRec... matchLogs) { + for (MatchedLogRec e : matchLogs) { + if (e != null) { + System.out.println(e.toString()); + } + } + } + + // 匹配日志信息输出,参数是集合 + public void showMatchLog(ArrayList matchLogs) { + for (MatchedLogRec e : matchLogs) { + if (e != null) { + System.out.println(e.toString()); + } + } + } + +} diff --git a/src/com/qst/dms/service/TransportService.java b/src/com/qst/dms/service/TransportService.java new file mode 100644 index 0000000..00ab064 --- /dev/null +++ b/src/com/qst/dms/service/TransportService.java @@ -0,0 +1,233 @@ +package com.qst.dms.service; + +import java.io.*; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLIntegrityConstraintViolationException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Scanner; + +import com.qst.dms.db.DBUtil; +import com.qst.dms.entity.*; + +public class TransportService { + // 物流数据采集 + public Transport inputTransport() { + Transport trans = null; + + // 建立一个从键盘接收数据的扫描器 + Scanner scanner = new Scanner(System.in); + try { + // 提示用户输入ID标识 + System.out.println("请输入ID标识:"); + // 接收键盘输入的整数 + int id = scanner.nextInt(); + // 获取当前系统时间 + Date nowDate = new Date(); + // 提示用户输入地址 + System.out.println("请输入地址:"); + // 接收键盘输入的字符串信息 + String address = scanner.next(); + // 数据状态是“采集” + int type = DataBase.GATHER; + + // 提示用户输入登录用户名 + System.out.println("请输入货物经手人:"); + // 接收键盘输入的字符串信息 + String handler = scanner.next(); + // 提示用户输入主机IP + System.out.println("请输入 收货人:"); + // 接收键盘输入的字符串信息 + String reciver = scanner.next(); + // 提示用于输入物流状态 + System.out.println("请输入物流状态:1发货中,2送货中,3已签收"); + // 接收物流状态 + int transportType = scanner.nextInt(); + // 创建物流信息对象 + trans = new Transport(id, nowDate, address, type, handler, reciver, + transportType); + } catch (Exception e) { + System.out.println("采集的日志信息不合法"); + } + // 返回物流对象 + return trans; + } + + // 物流信息输出 + public void showTransport(Transport... transports) { + for (Transport e : transports) { + if (e != null) { + System.out.println(e.toString()); + } + } + } + + // 匹配的物流信息输出,可变参数 + public void showMatchTransport(MatchedTransport... matchTrans) { + for (MatchedTransport e : matchTrans) { + if (e != null) { + System.out.println(e.toString()); + } + } + } + + // 匹配的物流信息输出,参数是集合 + public void showMatchTransport(ArrayList matchTrans) { + for (MatchedTransport e : matchTrans) { + if (e != null) { + System.out.println(e.toString()); + } + } + } + + public ArrayListreadMatchedTransportFromDB() throws SQLException + { + ArrayListmatchedTransports = new ArrayList<>(); + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + String sql = "select s.id,s.time,s.address,s.type,s.handler,s.reciver,s.transporttype,"+ + "t.id,t.time,t.address,t.type,t.handler,t.reciver,t.transporttype,"+ + "r.id,r.time,r.address,r.type,r.handler,r.reciver,r.transporttype "+ + "from matched_transport m,gather_transport s,gather_transport t,gather_transport r " + + "where m.sendid=s.id AND m.transid=t.id AND m.receiveid=r.id;"; + ResultSet resultSet = db.executeQuery(sql,null); + while(resultSet.next()) + { + Object[] temp = new Object[7]; + for(int i=1;i<=7;i++) + temp[i-1] = resultSet.getObject(i); + Transport send = Transport.get_Transport(temp); + for(int i=8;i<=14;i++) + temp[i-8] = resultSet.getObject(i); + Transport trans = Transport.get_Transport(temp); + for(int i=15;i<=21;i++) + temp[i-15] = resultSet.getObject(i); + Transport receive = Transport.get_Transport(temp); + MatchedTransport matchedTransport = new MatchedTransport(send,trans,receive); + matchedTransports.add(matchedTransport); + } + db.closeAll(); + } + catch(SQLException e) + { + throw e; + } + catch(Exception e) + { + e.printStackTrace(); + } + return matchedTransports; + } + // 匹配物流信息保存,参数是集合 + public void saveMatchedTransport(ArrayList matchTrans) { + // 创建一个ObjectOutputStream对象输出流,并连接文件输出流 + // 以可追加的方式创建文件输出流,数据保存到MatchedTransports.txt文件中 + try (ObjectOutputStream obs = new ObjectOutputStream( + new FileOutputStream("MatchedTransports.txt", true))) { + // 循环保存对象数据 + for (MatchedTransport e : matchTrans) { + if (e != null) { + // 把对象写入到文件中 + obs.writeObject(e); + obs.flush(); + } + } + // 文件末尾保存一个null对象,代表文件结束 + obs.writeObject(null); + obs.flush(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void saveMatchTransportToDB(ArrayList matchTrans) + { + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + for(MatchedTransport matchedTransport:matchTrans) + { + Transport send =matchedTransport.getSend(), + trans =matchedTransport.getTrans(), + receive = matchedTransport.getReceive(); + String sql = "insert into gather_transport(id,time,address,type,handler,reciver,transporttype) VALUES(?,?,?,?,?,?,?);"; + db.executeUpdate(sql, send.get_DB_param()); + db.executeUpdate(sql, trans.get_DB_param()); + db.executeUpdate(sql,receive.get_DB_param()); + sql = "insert into matched_transport(sendid,transid,receiveid) VALUES(?,?,?);"; + db.executeUpdate(sql,new Object[]{send.getId(),trans.getId(),receive.getId()}); + } + db.closeAll(); + } + catch(SQLIntegrityConstraintViolationException e) + {;} + catch(Exception e) + { + e.printStackTrace(); + } + } + public void saveAndAppendTransport(ArrayListmatchTrans) + { + if (matchTrans == null) + return; + try + { + File file = new File("MatchedTransports.txt"); + AppendObjectOutputStream.file = file; + AppendObjectOutputStream AOOStream = new AppendObjectOutputStream(); + for(MatchedTransport tran:matchTrans) + { + if(tran==null) + continue; + AOOStream.writeObject(tran); + AOOStream.flush(); + } + //null 代表结尾 + //AOOStream.writeObject(null); + AOOStream.close(); + } + catch (Exception Ex) + { + Ex.printStackTrace(); + } + } + // 读匹配物流信息保存,参数是集合 + public ArrayList readMatchedTransport() { + ArrayList matchTrans = new ArrayList<>(); + // 创建一个ObjectInputStream对象输入流,并连接文件输入流,读MatchedTransports.txt文件中 + try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream( + "MatchedTransports.txt"))) { + MatchedTransport matchTran; + // 循环读文件中的对象 + while ((matchTran = (MatchedTransport) ois.readObject()) != null) { + // 将对象添加到泛型集合中 + matchTrans.add(matchTran); + } + } + catch(FileNotFoundException ex) + { + ; + } + catch(EOFException ex) + { + ; + } + catch (Exception ex) { + ex.printStackTrace(); + } + return matchTrans; + } + + +} + + + + + + + diff --git a/src/com/qst/dms/service/UserService.java b/src/com/qst/dms/service/UserService.java new file mode 100644 index 0000000..214a380 --- /dev/null +++ b/src/com/qst/dms/service/UserService.java @@ -0,0 +1,85 @@ +package com.qst.dms.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +//import com.mysql.jdbc.Statement; +import com.qst.dms.db.DBUtil; +import com.qst.dms.entity.User; + +public class UserService { + private static Statement statement; //revised by yyc 20191012 + // 根据用户名查询用户 + public User findUserByName(String userName) throws SQLException + { + DBUtil db = new DBUtil(); + User user = null; + try { + // 获取数据库链接 + db.getConnection(); + // 使用PreparedStatement发送sql语句 + String sql = "SELECT * FROM userdetails WHERE username=?"; + // 设置参数 + Object[] param = new Object[] { userName }; + // 执行查询 + ResultSet rs = db.executeQuery(sql, param); + if (rs.next()) { + // 将结果集中的数据封装到对象中 + user = new User(rs.getInt(1), rs.getString(2), rs.getString(3), + rs.getInt(4), rs.getString(5), rs.getString(6), + rs.getString(7)); + } + }catch (SQLException e) + { + throw e; + } + catch (Exception e) { + e.printStackTrace(); + } finally { + // 关闭数据库的连接 + db.closeAll(); + } + // 返回用户对象 + return user; + } + + // 保存用户信息 + public boolean saveUser(User user) { + // 定义一个布尔返回值,初始值为false + boolean r = false; + DBUtil db = new DBUtil(); + try { + // 获取数据库连接 + db.getConnection(); + //start revised by yyc 20191012 +// String sqltest = "SELECT * FROM userdetails WHERE username=user"; +// ResultSet rs = statement.executeQuery(sqltest); + + //start revised by yyc 20191126 + String sqltest = "SELECT * FROM userdetails WHERE username='"+user.getUsername()+"'"; + ResultSet rs = db.executeQuery(sqltest,null); + if(rs.next()) + return r; + //end + // 使用PreparedStatement发送sql语句 + String sql = "INSERT INTO userdetails(username,password,sex,hobby,address,degree) VALUES (?,?,?,?,?,?)"; + // 设置参数 + Object[] param = new Object[] { user.getUsername(), + user.getPassword(), user.getSex(), user.getHobby(), + user.getAddress(), user.getDegree() }; + // 判断数据是否保存成功 + if (db.executeUpdate(sql, param) > 0) { + // 保存成功,设置返回值为true + r = true; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + // 关闭数据库的连接 + db.closeAll(); + } + // 返回 + return r; + } +} diff --git a/src/com/qst/dms/ui/InfoInputFXML.java b/src/com/qst/dms/ui/InfoInputFXML.java new file mode 100644 index 0000000..c8c998e --- /dev/null +++ b/src/com/qst/dms/ui/InfoInputFXML.java @@ -0,0 +1,820 @@ +package com.qst.dms.ui; + +import com.qst.dms.db.DBUtil; +import com.qst.dms.entity.*; +import com.qst.dms.gather.LogRecAnalyse; +import com.qst.dms.gather.TransportAnalyse; +import com.qst.dms.service.LogRecService; +import com.qst.dms.service.TransportService; +import javafx.animation.FadeTransition; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.KeyEvent; +import javafx.scene.paint.Color; +import javafx.scene.input.MouseEvent; +import javafx.util.Duration; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.sql.ResultSet; +import java.util.*; + +public class InfoInputFXML { + // 创建一个泛型ArrayList集合存储日志数据 + ArrayList logRecList = new ArrayList<>(); + // 创建一个泛型ArrayList集合存储物流数据 + ArrayList transportList = new ArrayList<>(); + + // 创建一个日志业务类 + LogRecService logService = new LogRecService(); + // 创建一个物流业务类 + TransportService tranService = new TransportService(); + + // 日志数据匹配集合 + ArrayList matchedLogs = null; + // 物流数据匹配集合 + ArrayList matchedTrans = null; + + @FXML + private TextField logID; + + @FXML + private TextField logIP; + + @FXML + private RadioButton logLogin; + + @FXML + private RadioButton logLogout; + + @FXML + private TextField logPosition; + + @FXML + private TextField logUser; + + @FXML + private TextField transportAddress; + + @FXML + private TextField transportHandler; + + @FXML + private TextField transportID; + + @FXML + private TextField transportReceiver; + + @FXML + private ChoiceBox transportMode; + + @FXML + private Label logLabelSuccess; + + @FXML + private Label transportLabelSuccess; + + @FXML + private Label logIDError; + + @FXML + private Label logUserEmpty; + + @FXML + private Label logAddressEmpty; + + @FXML + private Label logIPEmpty; + + @FXML + private Label logStateEmpty; + + @FXML + private Label transportIDError; + + @FXML + private Label transportAddressEmpty; + + @FXML + private Label transportReceiverEmpty; + + @FXML + private Label transportHandlerEmpty; + + @FXML + private Label transportStateEmpty; + + @FXML + private Button collectDataButton; + + @FXML + private Button matchLogButton; + + @FXML + private Button matchTransportButton; + + @FXML + private Button sandDataButton; + + @FXML + private Button saveDataButton; + + @FXML + private Button showDataButton; + + @FXML + private TabPane collectDataPane; + + @FXML + private Label logInfoLabel; + + @FXML + private Label transportInfoLabel; + private Button[] topButtons; + private String[] photos; + private TextField[] textFields; + private Label[] errorLabels; + private boolean[] textFieldChanged; + private int logMode;//0未选择 1登录 2登出 + private int transportModeVal;//0未选择 1发货中 2 运货中 3 已送达 + String defaultIP; + public static String loginUser; + private MainFrame mainFrame; + private int logUpVal; + private int transportUpVal; + private boolean logIDValid=true,transportIDValid=true; + private boolean sqlError; + FadeTransition transportSuccess; + FadeTransition logSuccess; + private Thread errorThread; + private Thread checkerThread; + private volatile boolean stopRequested = false; + private Image OKImage; + private Image errorImage; + private ImageView logImageView; + private ImageView transportImageView; + + void SQLErrorAlert() + { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("错误"); + alert.setHeaderText("连接到sql数据库失败"); + alert.setContentText("当前无法添加信息"); + alert.showAndWait(); + } + @FXML + void ConfirmLog(ActionEvent event) { + if(sqlError) + SQLErrorAlert(); + boolean canDo=true; + if(logMode==0) + {logStateEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;} + int id=0; + try + { + String Sid = logID.getText(); + if(Sid.isEmpty()) + throw new Exception("ID不能为空"); + if(!logIDValid) + throw new Exception("ID已被占用"); + id = Integer.parseInt(Sid); + } + catch(NumberFormatException e) + { + logIDError.setText("请输入纯数字"); + logIDError.setTextFill(Color.color(1,0,0,1)); + canDo=false; + } + catch(Exception e) + { + logIDError.setText(e.getMessage()); + logIDError.setTextFill(Color.color(1,0,0,1)); + canDo=false; + } + String address = logPosition.getText(); + if(address.isEmpty()) + {logAddressEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;} + String user = logUser.getText(); + if(user==null||user.isEmpty()) + {logUserEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;} + String ip = logIP.getText(); + if(ip.isEmpty()) + {logIPEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;} + Date nowDate = new Date(); + int logType = logMode==2?0:1; + if(!canDo) + return; + int type=0; + LogRec log = new LogRec(id, nowDate, address, type, user, ip, logType); + logRecList.add(log); + loginUser = user; + logUpVal++; + logMode=0; + logLogin.setSelected(false); + logLogout.setSelected(false); + Thread thread = new Thread(()->{Platform.runLater(()->{ + setLogTextFields();});}); + thread.start(); + logSuccessAnimation(); + } + + @FXML + void ConfirmTransport(ActionEvent event) { + if(sqlError) + SQLErrorAlert(); + boolean canDo = true; + int id = 0; + try + { + String Sid = transportID.getText(); + if(Sid.isEmpty()) + throw new Exception("ID不能为空"); + if(!transportIDValid) + throw new Exception("ID已被占用"); + id = Integer.parseInt(Sid); + } + catch(NumberFormatException e) + { + transportIDError.setText("请输入纯数字"); + transportIDError.setTextFill(Color.color(1,0,0,1)); + canDo=false; + } + catch(Exception e) + { + transportIDError.setText(e.getMessage()); + transportIDError.setTextFill(Color.color(1,0,0,1)); + canDo=false; + } + String transportModeString = transportMode.getValue(); + if(transportModeString==null) + { + transportModeVal = 0; + transportStateEmpty.setTextFill(Color.color(1,0,0,1)); + canDo=false; + } + else + switch(transportModeString) + { + case "发货中" ->transportModeVal=1; + case "运送中" ->transportModeVal=2; + case "已送达" ->transportModeVal=3; + } + String address = transportAddress.getText(); + if(address.isEmpty()) + {transportAddressEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;} + String handler = transportHandler.getText(); + if(handler.isEmpty()) + {transportHandlerEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;} + String receiver = transportReceiver.getText(); + if(receiver.isEmpty()) + {transportReceiverEmpty.setTextFill(Color.color(1,0,0,1));canDo=false;} + if(!canDo) + return; + Date nowDate = new Date(); + Transport transport = new Transport(id,nowDate,address,2,handler,receiver,transportModeVal); + transportList.add(transport); + transportUpVal++; + transportModeVal=0; + transportMode.setValue(null); + Thread thread = new Thread(()->{Platform.runLater(()->{ + setTransportTextFields();});}); + thread.start(); + transportSuccessAnimation(); + } + + void logIDTest() + { + logIDValid=true; + int logIDValue; + try + { + String s = logID.getText(); + if(s.isEmpty()) + throw new Exception(); + logIDValue = Integer.parseInt(s); + } + catch (Exception e) + {logIDValid=false;return;} + Thread thread = new Thread(()-> + { + Platform.runLater(()->{ + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + String sql = "SELECT id FROM gather_logrec WHERE id = "+ logIDValue; + ResultSet resultSet = db.executeQuery(sql,null); + if(resultSet.next()) + logIDValid = false; + db.closeAll(); + } catch(Exception e) + { + if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED) + { + db.closeAll(); + errorThread = new Thread(() -> { + setSqlError(); + }); + errorThread.start(); + } + } + }); + }); + thread.start(); + } + void updateSQLCheckerTime() + { + Thread thread = new Thread(()->{ + stopRequested=true; + while(checkerThread.isAlive()) + { + checkerThread.interrupt(); + try + { + Thread.sleep(50); + } catch (InterruptedException e) + { + e.printStackTrace(); + } + } + stopRequested=false; + checkerThread = new Thread(()->{ + SQLChecker(); + }); + checkerThread.start(); + }); + thread.start(); + } + + void SQLChecker() + { + while (!stopRequested) + { + try + { + Thread.sleep(UpdateTimeSetFXML.updateTime*1000); + } catch (InterruptedException e) + { + break; + } + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + String sql = "SELECT * FROM gather_transport"; + db.closeAll(); + } catch(Exception e) + { + db.closeAll(); + if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED) + { + errorThread = new Thread(() -> { + setSqlError(); + }); + errorThread.start(); + } + //e.printStackTrace(); + } + } + } + + void transportIDTest() + { + transportIDValid=true; + int transportIDValue; + try + { + String s = transportID.getText(); + if(s.isEmpty()) + throw new Exception(); + transportIDValue = Integer.parseInt(s); + } + catch (Exception e) + {transportIDValid=false;return;} + Thread thread = new Thread(()-> + { + Platform.runLater(()->{ + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + String sql = "SELECT id FROM gather_transport WHERE id = "+ transportIDValue; + ResultSet resultSet = db.executeQuery(sql,null); + if(resultSet.next()) + transportIDValid=false; + db.closeAll(); + } catch(Exception e) + { + db.closeAll(); + if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED) + { + errorThread = new Thread(() -> { + setSqlError(); + }); + errorThread.start(); + } + //e.printStackTrace(); + } + }); + }); + thread.start(); + } + + void setSqlError() + { + sqlError = true; + while (true) + { + for (int i = 3; i >= 0; i--) + { + int finalI = i; + Platform.runLater(()-> { + logInfoLabel.setTextFill(Color.color(1, 0, 0, 1)); + transportInfoLabel.setTextFill(Color.color(1, 0, 0, 1)); + logImageView.setImage(errorImage); + transportImageView.setImage(errorImage); + logInfoLabel.setText("数据库连接异常,将在" + finalI + "秒后重试"); + transportInfoLabel.setText("数据库连接异常,将在" + finalI + "秒后重试"); + }); + if (i != 0) + try + { + Thread.sleep(1000); + } catch (InterruptedException e) + { + e.printStackTrace(); + } + } + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + String sql = "SELECT id FROM gather_transport WHERE id = (SELECT MAX(id) FROM gather_transport)"; + ResultSet resultSet = db.executeQuery(sql,null); + db.closeAll(); + } catch(Exception e) + { + db.closeAll(); + continue; + } + break; + } + setReady(); + } + + private void setReady() + { + Platform.runLater(()->{ + logImageView.setImage(OKImage); + transportImageView.setImage(OKImage); + logInfoLabel.setText("就绪"); + transportInfoLabel.setText("就绪"); + logInfoLabel.setTextFill(Color.color(0,0,0,1)); + transportInfoLabel.setTextFill(Color.color(0,0,0,1)); + }); + sqlError=false; + } + @FXML + void LoginSet(ActionEvent event) { + logLogout.setSelected(false); + logMode = 1; + logStateEmpty.setTextFill(Color.color(1,0,0,0)); + } + + @FXML + void LogoutSet(ActionEvent event) { + logLogin.setSelected(false); + logMode = 2; + logStateEmpty.setTextFill(Color.color(1,0,0,0)); + } + + @FXML + void RedoALLLog(ActionEvent event) { + logUser.clear(); + logPosition.clear(); + logIP.clear(); + logID.clear(); + } + + @FXML + void RedoAllTransport(ActionEvent event) { + transportID.clear(); + transportAddress.clear(); + transportHandler.clear(); + transportReceiver.clear(); + } + + @FXML + public void matchedAcquisitionLogData(ActionEvent event) { + if(logRecList.isEmpty()) + { + matchedLogs = new ArrayList<>(); + return; + } + LogRecAnalyse logAn = new LogRecAnalyse(logRecList); + logAn.doFilter(); + matchedLogs = logAn.matchData(); + } + + @FXML + public void matchedAcquisitionTransportData(ActionEvent event){ + if(transportList.isEmpty()) + { + matchedTrans = new ArrayList<>(); + return; + } + TransportAnalyse transAn = new TransportAnalyse(transportList); + transAn.doFilter(); + matchedTrans = transAn.matchData(); + } + + @FXML + public void sandData(ActionEvent event) { + //开发中…… + } + + @FXML + public void saveData(ActionEvent event) { + boolean doLog=false,doTransport=false; + if((matchedLogs==null||matchedLogs.isEmpty())&&!logRecList.isEmpty()) + { + doLog=true; + Alert alert = new Alert(AlertType.CONFIRMATION); + alert.setTitle("Warning Dialog"); + alert.setHeaderText("配对的日志数据为空"); + alert.setContentText("你是否忘记匹配日志数据,要匹配日志数据吗?"); + Optional result = alert.showAndWait(); + if (result.get() == ButtonType.OK){ + matchedAcquisitionLogData(null); + if(matchedLogs.isEmpty()) + doLog=false; + } + else doLog=false; + } + if(doLog) + { + logService.saveAndAppendMatchLog(matchedLogs); + logService.saveMatchLogToDB(matchedLogs);//添加至DB + logRecList.clear(); + matchedLogs.clear(); + logUpVal=0; + } + if((matchedTrans==null|| matchedTrans.isEmpty())&&!transportList.isEmpty()) + { + doTransport=true; + Alert alert = new Alert(AlertType.CONFIRMATION); + alert.setTitle("Warning Dialog"); + alert.setHeaderText("配对的物流数据为空"); + alert.setContentText("你是否忘记匹配物流数据,要匹配物流数据吗?"); + Optional result = alert.showAndWait(); + if (result.get() == ButtonType.OK){ + matchedAcquisitionTransportData(null); + if(matchedTrans.isEmpty()) + doTransport=false; + } + else doTransport=false; + } + if(doTransport) + { + tranService.saveAndAppendTransport(matchedTrans); + tranService.saveMatchTransportToDB(matchedTrans);//添加至DB + transportList.clear(); + matchedTrans.clear(); + transportUpVal=0; + } + } + + @FXML + void toInfoInputFrame(ActionEvent event) { + ; + } + + @FXML + void toTableFrame(ActionEvent event) + { + fadeOut(()->{mainFrame.toTableFrame();}); + } + + public void getDelegation(MainFrame _mainFrame) + { + mainFrame = _mainFrame; + } + + void setLogTextFields() + { + sqlError = false; + DBUtil db = new DBUtil(); + int min_id=0; + try + { + db.getConnection(); + String sql = "SELECT id FROM gather_logrec WHERE id = (SELECT MAX(id) FROM gather_logrec)"; + ResultSet resultSet = db.executeQuery(sql,null); + if(resultSet.next()) + { + Integer id=(Integer) resultSet.getObject(1); + min_id = id.intValue()+ logUpVal +1; + } + db.closeAll(); + } catch(Exception e) + { + db.closeAll(); + if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED) + { + errorThread = new Thread(() -> { + setSqlError(); + }); + errorThread.start(); + } + } + for(TextField textField:textFields) + textField.setStyle("-fx-text-fill: #666"); + logUser.setText(loginUser); + logID.setText(""+min_id); + logIP.setText(defaultIP); + Arrays.fill(textFieldChanged,false); + } + + void setTransportTextFields() + { + sqlError = false; + DBUtil db = new DBUtil(); + int min_id=0; + try + { + db.getConnection(); + String sql = "SELECT id FROM gather_transport WHERE id = (SELECT MAX(id) FROM gather_transport)"; + ResultSet resultSet = db.executeQuery(sql,null); + if(resultSet.next()) + { + Integer id=(Integer) resultSet.getObject(1); + min_id = id.intValue()+ transportUpVal +1; + } + db.closeAll(); + } catch(Exception e) + { + db.closeAll(); + if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED) + { + errorThread = new Thread(() -> { + setSqlError(); + }); + errorThread.start(); + } + } + for(TextField textField:textFields) + textField.setStyle("-fx-text-fill: #666"); + transportID.setText(""+min_id); + Arrays.fill(textFieldChanged,false); + } + + @FXML + void beChanged(KeyEvent event) { + TextField textField = (TextField)event.getSource(); + for(int i = 0;i{ + SQLChecker(); + }); + checkerThread.start(); + logUpVal = 0; + transportUpVal = 0; + textFieldChanged = new boolean[8]; + Arrays.fill(textFieldChanged,false); + textFields = new TextField[]{logID,logUser,logPosition,logIP,transportID,transportAddress,transportHandler,transportReceiver}; + errorLabels = new Label[]{logIDError, logUserEmpty, logAddressEmpty, logIPEmpty,transportIDError,transportAddressEmpty,transportHandlerEmpty,transportReceiverEmpty,logStateEmpty,transportStateEmpty}; + topButtons = new Button[]{collectDataButton, matchLogButton, matchTransportButton, saveDataButton, sandDataButton, showDataButton}; + photos = new String[]{"dataCollection.png","logPair.png","transportPair.png","save.png","upload.png","table.png"}; + logMode = 0; + transportMode.getItems().addAll("发货中","运送中","已送达"); + setPhotos(); + for(Label label:errorLabels) + label.setTextFill(Color.color(1,0,0,0)); + logLabelSuccess.setTextFill(Color.color(0,1,0,0)); + transportLabelSuccess.setTextFill(Color.color(0,1,0,0)); + try { + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface iface = interfaces.nextElement(); + // 过滤回环接口和虚拟接口 + if (iface.isLoopback() || iface.isVirtual() || !iface.isUp()) { + continue; + } + Enumeration addresses = iface.getInetAddresses(); + while (addresses.hasMoreElements()) { + defaultIP = addresses.nextElement().getHostAddress(); + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + OKImage = new Image("resources/ok.png"); + errorImage = new Image("resources/error.png"); + logImageView = new ImageView(); + transportImageView = new ImageView(); + for(ImageView imageView : new ImageView[]{logImageView,transportImageView}) + { + imageView.setFitHeight(19); + imageView.setFitWidth(19); + } + logImageView.setImage(OKImage); + transportImageView.setImage(OKImage); + logInfoLabel.setGraphic(logImageView); + transportInfoLabel.setGraphic(transportImageView); + transportMode.setOnAction((event)->{transportStateEmpty.setTextFill(Color.color(1,0,0,0));}); + Thread thread = new Thread(()->{Platform.runLater(()->{ + setLogTextFields();setTransportTextFields();});}); + thread.start(); + } + + void setPhotos() + { + for(int i=0;i{ + if (action != null) + action.run();}); + fadeOut.play(); + } + void fadeIn(Runnable action) + { + // 创建FadeTransition对象 + FadeTransition fadeIn = new FadeTransition(Duration.seconds(0.5),collectDataPane ); + fadeIn.setFromValue(0); // 初始不透明度为0(完全透明) + fadeIn.setToValue(1); + fadeIn.setOnFinished((event)->{ + if (action != null) + action.run();}); + fadeIn.play(); + } + + void logSuccessAnimation() + { + logLabelSuccess.setTextFill(Color.color(0.26953125,0.66796875,0.26953125,1)); + if(logSuccess!=null) + logSuccess.stop(); + logSuccess = new FadeTransition(Duration.seconds(1),logLabelSuccess); + logSuccess.setFromValue(1); // 初始不透明度为1(完全可见) + logSuccess.setToValue(0); + logSuccess.setDelay(Duration.seconds(3)); + logSuccess.play(); + } + + void transportSuccessAnimation() + { + transportLabelSuccess.setTextFill(Color.color(0.26953125,0.66796875,0.26953125,1)); + if(transportSuccess!=null) + transportSuccess.stop(); + transportSuccess = new FadeTransition(Duration.seconds(1),transportLabelSuccess); + transportSuccess.setFromValue(1); // 初始不透明度为1(完全可见) + transportSuccess.setToValue(0); + transportSuccess.setDelay(Duration.seconds(3)); + transportSuccess.play(); + } + + public void updateFlushTime(ActionEvent event) + { + mainFrame.updateFlushTime(); + } +} diff --git a/src/com/qst/dms/ui/LoginFXML.java b/src/com/qst/dms/ui/LoginFXML.java new file mode 100644 index 0000000..f6b8aa3 --- /dev/null +++ b/src/com/qst/dms/ui/LoginFXML.java @@ -0,0 +1,94 @@ +package com.qst.dms.ui; + +import com.qst.dms.entity.User; +import com.qst.dms.security.String_SHA_256; +import com.qst.dms.service.UserService; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.*; + +import java.sql.SQLException; + + +public class LoginFXML +{ + @FXML + private TextField Username; + @FXML + private PasswordField Password; + @FXML + private Button Login_Button; + @FXML + private Button Reset_Button; + @FXML + private Button Register_Button; + @FXML + void Login(ActionEvent event) + { + UserService userService =new UserService(); + try + { + User user = userService.findUserByName(Username.getText()); + if(user==null||!(String_SHA_256.String_to_SHA256(Password.getText()).equals(user.getPassword()))) + Login_failed(); + else + { + InfoInputFXML.loginUser = Username.getText(); + LoginFrame.close_scene(); + } + } + catch(SQLException e) + { + SQLErrorAlert(0); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + void SQLErrorAlert(int type) + { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("错误"); + alert.setHeaderText("连接到sql数据库失败"); + if(type==0) + alert.setContentText("当前无法校验用户名和密码"); + if(type==1) + alert.setContentText("当前无法添加用户"); + alert.showAndWait(); + } + @FXML + void Reset(ActionEvent event) + { + Username.clear(); + Password.clear(); + } + @FXML + void Register(ActionEvent event) + { + UserService userService =new UserService(); + try + { + User user = userService.findUserByName(""); + RegistFrame.main(null); + } + catch (SQLException e) + { + SQLErrorAlert(1); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + void Login_failed() + { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("错误"); + alert.setHeaderText("用户名或密码错误"); + alert.setContentText("请检查输入的用户名和密码"); + alert.showAndWait(); + } + + +} diff --git a/src/com/qst/dms/ui/LoginFrame.java b/src/com/qst/dms/ui/LoginFrame.java new file mode 100644 index 0000000..96015c6 --- /dev/null +++ b/src/com/qst/dms/ui/LoginFrame.java @@ -0,0 +1,38 @@ +package com.qst.dms.ui; + + +import com.qst.dms.entity.User; +import com.qst.dms.service.UserService; +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Pane; +import javafx.stage.Stage; + +public class LoginFrame extends Application +{ + + private static Scene scene; + public static void main(String[] args) + { + Application.launch(args); + } + @Override + public void start(Stage stage) throws Exception + { + Pane pane = FXMLLoader.load(getClass().getClassLoader().getResource("resources/LoginFrame.fxml")); + scene = new Scene(pane); + stage.setScene(scene); + stage.setResizable(false); + stage.show(); + } + public static void close_scene() + { + Stage primaryStage=(Stage)scene.getWindow();//将submit(登录按钮)与MainApplication类中的primaryStage(新窗口)绑定 并执行close() + primaryStage.close();//打开新的窗口 所以要关闭当前的窗口 + MainFrame mainFrame = new MainFrame(); + mainFrame.startapp(); + } + +} \ No newline at end of file diff --git a/src/com/qst/dms/ui/MainFrame.java b/src/com/qst/dms/ui/MainFrame.java new file mode 100644 index 0000000..f7745be --- /dev/null +++ b/src/com/qst/dms/ui/MainFrame.java @@ -0,0 +1,87 @@ +package com.qst.dms.ui; + +import com.qst.dms.entity.*; +import com.qst.dms.service.LogRecService; +import com.qst.dms.service.TransportService; +import com.qst.dms.service.UserService; +import javafx.application.Application; +import javafx.event.ActionEvent; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Pane; +import javafx.stage.Stage; + +import java.util.ArrayList; + +public class MainFrame extends Application +{ + + public static void main(String[] args){ + Application.launch(args); + } + public void startapp() + { + try + { + this.start(new Stage()); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + private Stage stage; + private Scene infoInputScene,tableScene,updateTimeSetScene; + InfoInputFXML infoInputFXMLController; + TableFXML tableFXMLController; + UpdateTimeSetFXML updateTimeSetFXMLController; + @Override + public void start(Stage _stage) throws Exception + { + stage = _stage; + FXMLLoader infoInputFrameFXMLLoader = new FXMLLoader(); + FXMLLoader tableFrameFXMLLoader = new FXMLLoader(); + FXMLLoader updateTimeSetFXMLLoader = new FXMLLoader(); + infoInputFrameFXMLLoader.setLocation(getClass().getClassLoader().getResource("resources/InfoInputFrame.fxml")); + tableFrameFXMLLoader.setLocation(getClass().getClassLoader().getResource("resources/TableFrame.fxml")); + updateTimeSetFXMLLoader.setLocation(getClass().getClassLoader().getResource("resources/timeSetDialog.fxml")); + //set Scene + infoInputScene = new Scene(infoInputFrameFXMLLoader.load()); + tableScene = new Scene(tableFrameFXMLLoader.load()); + updateTimeSetScene = new Scene(updateTimeSetFXMLLoader.load()); + //set Controller + infoInputFXMLController = infoInputFrameFXMLLoader.getController(); + tableFXMLController = tableFrameFXMLLoader.getController(); + updateTimeSetFXMLController = updateTimeSetFXMLLoader.getController(); + //set Delegation + infoInputFXMLController.getDelegation(this); + tableFXMLController.getDelegation(this,infoInputFXMLController); + updateTimeSetFXMLController.getDelegation(infoInputFXMLController,tableFXMLController); + //set Stage + stage.setScene(infoInputScene); + stage.setResizable(false); + stage.show(); + } + public void toInfoInputFrame() { + stage.setScene(infoInputScene); + infoInputFXMLController.fadeIn(null); + } + + public void toTableFrame() { + tableFXMLController.setTable(); + stage.setScene(tableScene); + tableFXMLController.fadeIn(null); + } + + public void updateFlushTime() { + Stage subWindow = new Stage(); + subWindow.setScene(updateTimeSetScene); + subWindow.setOnCloseRequest((event)->{ + event.consume(); + updateTimeSetFXMLController.closeRequest(); + subWindow.close(); + }); + subWindow.show(); + } +} \ No newline at end of file diff --git a/src/com/qst/dms/ui/RegistFrame.java b/src/com/qst/dms/ui/RegistFrame.java new file mode 100644 index 0000000..91e995a --- /dev/null +++ b/src/com/qst/dms/ui/RegistFrame.java @@ -0,0 +1,216 @@ +package com.qst.dms.ui; + +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.ButtonGroup; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JRadioButton; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +import com.qst.dms.entity.User; +import com.qst.dms.security.String_SHA_256; +import com.qst.dms.service.UserService; + +//注册窗口 +public class RegistFrame extends JFrame { + // 主面板 + private JPanel p; + // 标签 + private JLabel lblName, lblPwd, lblRePwd, lblSex, lblHobby, lblAdress, + lblDegree; + // 用户名,文本框 + private JTextField txtName; + // 密码和确认密码,密码框 + private JPasswordField txtPwd, txtRePwd; + // 性别,单选按钮 + private JRadioButton rbMale, rbFemale; + // 爱好,多选框 + private JCheckBox ckbRead, ckbNet, ckbSwim, ckbTour; + // 地址,文本域 + private JTextArea txtAdress; + // 学历,组合框 + private JComboBox cmbDegree; + // 确认和取消,按钮 + private JButton btnOk, btnCancle; + // 注册的用户 + private static User user; + + // 用户业务类 + private UserService userService; + + // 构造方法 + public RegistFrame() { + super("用户注册"); + + // 实例化用户业务类对象 + userService = new UserService(); + + // 设置窗体的icon + ImageIcon icon = new ImageIcon("images\\dms.png"); + this.setIconImage(icon.getImage()); + + // 设置面板布局,网格布局 + p = new JPanel(new GridLayout(8, 1)); + // 实例化组件 + lblName = new JLabel("用 户 名:"); + lblPwd = new JLabel("密 码:"); + lblRePwd = new JLabel("确认密码:"); + lblSex = new JLabel("性 别:"); + lblHobby = new JLabel("爱 好:"); + lblAdress = new JLabel("地 址:"); + lblDegree = new JLabel("学 历:"); + txtName = new JTextField(16); + txtPwd = new JPasswordField(16); + txtRePwd = new JPasswordField(16); + rbMale = new JRadioButton("男"); + rbFemale = new JRadioButton("女"); + + // 性别的单选逻辑 + ButtonGroup bg = new ButtonGroup(); + bg.add(rbMale); + bg.add(rbFemale); + + ckbRead = new JCheckBox("阅读"); + ckbNet = new JCheckBox("上网"); + ckbSwim = new JCheckBox("游泳"); + ckbTour = new JCheckBox("旅游"); + txtAdress = new JTextArea(3, 20); + + // 组合框显示的学历数组 + String str[] = { "小学", "初中", "高中", "本科", "硕士", "博士" }; + cmbDegree = new JComboBox(str); + // 设置组合框可编辑 + cmbDegree.setEditable(true); + btnOk = new JButton("确定"); + // 注册监听器,监听确定按钮 + btnOk.addActionListener(new RegisterListener()); + btnCancle = new JButton("重置"); + // 注册监听器,监听重置按钮 + btnCancle.addActionListener(new ResetListener()); + // 将组件分组放入面板,然后将小面板放入主面板 + JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT)); + p1.add(lblName); + p1.add(txtName); + p.add(p1); + JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT)); + p2.add(lblPwd); + p2.add(txtPwd); + p.add(p2); + JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT)); + p3.add(lblRePwd); + p3.add(txtRePwd); + p.add(p3); + JPanel p4 = new JPanel(new FlowLayout(FlowLayout.LEFT)); + p4.add(lblSex); + p4.add(rbMale); + p4.add(rbFemale); + p.add(p4); + JPanel p5 = new JPanel(new FlowLayout(FlowLayout.LEFT)); + p5.add(lblHobby); + p5.add(ckbRead); + p5.add(ckbNet); + p5.add(ckbSwim); + p5.add(ckbTour); + p.add(p5); + JPanel p6 = new JPanel(new FlowLayout(FlowLayout.LEFT)); + p6.add(lblAdress); + p6.add(txtAdress); + p.add(p6); + JPanel p7 = new JPanel(new FlowLayout(FlowLayout.LEFT)); + p7.add(lblDegree); + p7.add(cmbDegree); + p.add(p7); + JPanel p8 = new JPanel(new FlowLayout(FlowLayout.CENTER)); + p8.add(btnOk); + p8.add(btnCancle); + p.add(p8); + // 主面板放入窗体中 + this.add(p); + // 设置窗体大小和位置 + this.setSize(310, 350); + this.setLocation(300, 300); + // 设置窗体不可改变大小 + this.setResizable(false); + + // 设置窗体初始可见 + this.setVisible(true); + } + + // 监听类,负责处理确认按钮的业务逻辑 + private class RegisterListener implements ActionListener { + // 重写actionPerFormed()方法,事件处理方法 + public void actionPerformed(ActionEvent e) { + // 获取用户输入的数据 + String userName = txtName.getText().trim(); + String password = new String(txtPwd.getPassword()); + String rePassword = new String(txtRePwd.getPassword()); + // 将性别“男”“女”对应转化为“1”“0” + int sex = Integer.parseInt(rbFemale.isSelected() ? "0" : "1"); + String hobby = (ckbRead.isSelected() ? "阅读" : "") + + (ckbNet.isSelected() ? "上网" : "") + + (ckbSwim.isSelected() ? "游泳" : "") + + (ckbTour.isSelected() ? "旅游" : ""); + String address = txtAdress.getText().trim(); + String degree = cmbDegree.getSelectedItem().toString().trim(); + // 判断两次输入密码是否一致 + if (password.equals(rePassword)) { + // 将数据封装到对象中 + password = String_SHA_256.String_to_SHA256(password); + user = new User(userName, password, sex, hobby, address, degree); + // 保存数据 + if (userService.saveUser(user)) { + // 输出提示信息 + //System.out.println("注册成功!"); + JOptionPane.showMessageDialog(null,"注册成功!","成功提示",JOptionPane.PLAIN_MESSAGE); + } else { + // 输出提示信息 + //System.out.println("注册失败!"); + JOptionPane.showMessageDialog(null,"注册失败!","错误提示",JOptionPane.ERROR_MESSAGE); + } + } else { + // 输出提示信息 + //System.out.println("两次输入的密码不一致!"); + JOptionPane.showMessageDialog(null,"两次输入的密码不一致!","错误提示",JOptionPane.ERROR_MESSAGE); + } + } + } + + // 监听类,负责处理重置按钮 + public class ResetListener implements ActionListener { + // 重写actionPerFormed()方法,重置组件内容事件处理方法 + public void actionPerformed(ActionEvent e) { + // 清空姓名、密码、确认密码内容 + txtName.setText(""); + txtPwd.setText(""); + txtRePwd.setText(""); + // 重置单选按钮为未选择 + rbMale.setSelected(false); + rbFemale.setSelected(false); + // 重置所有的复选按钮为未选择 + ckbRead.setSelected(false); + ckbNet.setSelected(false); + ckbSwim.setSelected(false); + ckbTour.setSelected(false); + // 清空地址栏 + txtAdress.setText(""); + // 重置组合框为未选择状态 + cmbDegree.setSelectedIndex(0); + } + } + + public static void main(String[] args) { + new RegistFrame(); + } +} diff --git a/src/com/qst/dms/ui/TableFXML.java b/src/com/qst/dms/ui/TableFXML.java new file mode 100644 index 0000000..5240c5c --- /dev/null +++ b/src/com/qst/dms/ui/TableFXML.java @@ -0,0 +1,356 @@ +package com.qst.dms.ui; + +import com.qst.dms.db.DBUtil; +import com.qst.dms.entity.MatchedLogRec; +import com.qst.dms.entity.MatchedTransport; +import com.qst.dms.entity.Transport; +import com.qst.dms.service.LogRecService; +import com.qst.dms.service.TransportService; +import javafx.animation.FadeTransition; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.paint.Color; +import javafx.util.Duration; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; + + +public class TableFXML { + + private MainFrame mainFrame; + private InfoInputFXML infoInputFrame; + // 创建一个日志业务类 + LogRecService logService = new LogRecService(); + // 创建一个物流业务类 + TransportService tranService = new TransportService(); + // 日志数据匹配集合 + ArrayList matchedLogs = null; + // 物流数据匹配集合 + ArrayList matchedTrans = null; + + @FXML + private TableView logTable; + + @FXML + private TableColumn logUsername; + + @FXML + private TableColumn loginTime; + + @FXML + private TableColumn logoutTime; + + @FXML + private TableColumn logAddress; + + @FXML + private TableColumn transAddress; + + @FXML + private TableColumn transHandler; + + @FXML + private TableColumn transID; + + @FXML + private TableColumn transReceiver; + + @FXML + private TableColumn transState; + + @FXML + private TableColumntransTime; + + @FXML + private TableColumn transType; + + @FXML + private TableView transportTable; + + @FXML + private Button collectDataButton; + + @FXML + private Button matchLogButton; + + @FXML + private Button matchTransportButton; + + @FXML + private Button sandDataButton; + + @FXML + private Button saveDataButton; + + @FXML + private Button showDataButton; + + @FXML + private TabPane tablePane; + + @FXML + private Label logSQLLabel; + + @FXML + private Label transportSQLLabel; + + private Image OKImage; + private Image errorImage; + + private ImageView logImageView; + private ImageView transportImageView; + + private Thread errorThread; + private volatile boolean stopRequested = false; + private Thread flusherThread; + + public void getDelegation(MainFrame _mainFrame,InfoInputFXML _infoInputFrame) + { + mainFrame = _mainFrame; + infoInputFrame =_infoInputFrame; + } + + public void setTable() + { + try + { + matchedLogs = logService.readMatchedLogFromDB(); + matchedTrans = tranService.readMatchedTransportFromDB(); + } + catch(SQLException e) + { + if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED) + { + errorThread = new Thread(this::SQLError); + errorThread.start(); + } + return; + } + logTable.getItems().clear(); + transportTable.getItems().clear(); + for(MatchedLogRec matchedLogRec:matchedLogs) + logTable.getItems().add(new logLine(matchedLogRec.getUser(),matchedLogRec.getLogInTime().toString(),matchedLogRec.getLogoutTime().toString(),matchedLogRec.getAddress())); + for(MatchedTransport matchedTransport :matchedTrans) + { + Transport[] transports = new Transport[]{ matchedTransport.getSend(), matchedTransport.getTrans(),matchedTransport.getReceive()}; + for(Transport transport:transports) + transportTable.getItems().add(new transportLine(transport.getId()+"",transport.getAddress(),transport.getHandler(),transport.getReciver(),"已禁用",transport.getTime().toString(),transport.getType())); + } + } + + void SQLError() + { + while(true) + { + for (int i = 3; i >= 0; i--) + { + int finalI = i; + Platform.runLater(() -> { + logSQLLabel.setTextFill(Color.color(1,0,0,1)); + transportSQLLabel.setTextFill(Color.color(1,0,0,1)); + logImageView.setImage(errorImage); + transportImageView.setImage(errorImage); + logSQLLabel.setText("数据库连接异常,将在" + finalI + "秒后重试"); + transportSQLLabel.setText("数据库连接异常,将在" + finalI + "秒后重试"); + }); + if (i != 0) + try + { + Thread.sleep(1000); + } catch (InterruptedException e) + { + e.printStackTrace(); + } + } + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + String sql = "SELECT * FROM gather_transport"; + ResultSet resultSet = db.executeQuery(sql,null); + db.closeAll(); + } catch(Exception e) + { + db.closeAll(); + continue; + } + break; + } + Platform.runLater(()->{ + logImageView.setImage(OKImage); + transportImageView.setImage(OKImage); + logSQLLabel.setText("就绪"); + transportSQLLabel.setText("就绪"); + logSQLLabel.setTextFill(Color.color(0,0,0,1)); + transportSQLLabel.setTextFill(Color.color(0,0,0,1)); + }); + } + + + @FXML + void matchedAcquisitionLogData(ActionEvent event) { + infoInputFrame.matchedAcquisitionLogData(null); + } + + @FXML + void matchedAcquisitionTransportData(ActionEvent event) { + infoInputFrame.matchedAcquisitionTransportData(null); + } + + @FXML + void sandData(ActionEvent event) { + infoInputFrame.sandData(null); + } + + @FXML + void saveData(ActionEvent event) { + infoInputFrame.saveData(null); + } + + @FXML + void toInfoInputFrame(ActionEvent event) { + fadeOut(()->{mainFrame.toInfoInputFrame();}); + } + + @FXML + void toTableFrame(ActionEvent event) { + ; + } + + private Button[] topButtons; + private String[] photos; + + public void initialize() + { + topButtons = new Button[]{collectDataButton, matchLogButton, matchTransportButton, saveDataButton, sandDataButton, showDataButton}; + photos = new String[]{"dataCollection.png","logPair.png","transportPair.png","save.png","upload.png","table.png"}; + setPhotos(); + logUsername.setCellValueFactory(new PropertyValueFactory("logUsername")); + loginTime.setCellValueFactory(new PropertyValueFactory("loginTime")); + logoutTime.setCellValueFactory(new PropertyValueFactory("logoutTime")); + logAddress.setCellValueFactory(new PropertyValueFactory("logAddress")); + transID.setCellValueFactory(new PropertyValueFactory<>("transID")); + transAddress.setCellValueFactory(new PropertyValueFactory<>("transAddress")); + transHandler.setCellValueFactory(new PropertyValueFactory<>("transHandler")); + transReceiver.setCellValueFactory(new PropertyValueFactory<>("transReceiver")); + transState.setCellValueFactory(new PropertyValueFactory<>("transState")); + transTime.setCellValueFactory(new PropertyValueFactory<>("transTime")); + transType.setCellValueFactory(new PropertyValueFactory<>("transType")); + OKImage = new Image("resources/ok.png"); + errorImage = new Image("resources/error.png"); + logImageView = new ImageView(); + transportImageView = new ImageView(); + for(ImageView imageView : new ImageView[]{logImageView,transportImageView}) + { + imageView.setFitHeight(19); + imageView.setFitWidth(19); + } + logImageView.setImage(OKImage); + transportImageView.setImage(OKImage); + logSQLLabel.setGraphic(logImageView); + transportSQLLabel.setGraphic(transportImageView); + flusherThread = new Thread(()->{flusher();}); + flusherThread.start(); + } + + void updateFlusherTime() + { + Thread thread = new Thread(()->{ + stopRequested=true; + while(flusherThread.isAlive()) + { + flusherThread.interrupt(); + try + { + Thread.sleep(50); + } catch (InterruptedException e) + { + e.printStackTrace(); + } + } + stopRequested=false; + flusherThread = new Thread(()->{ + flusher(); + }); + flusherThread.start(); + }); + thread.start(); + } + public void flusher() + { + while (!stopRequested) + { + try + { + Thread.sleep(UpdateTimeSetFXML.updateTime*1000); + } catch (InterruptedException e) + { + break; + } + DBUtil db = new DBUtil(); + try + { + db.getConnection(); + String sql = "SELECT * FROM gather_transport"; + db.closeAll(); + } catch(Exception e) + { + db.closeAll(); + if(errorThread==null||errorThread.getState()==Thread.State.TERMINATED) + { + errorThread = new Thread(this::SQLError); + errorThread.start(); + } + //e.printStackTrace(); + } + setTable(); + } + } + + void setPhotos() + { + for(int i=0;i{ + if (action != null) + action.run();}); + fadeOut.play(); + } + + void fadeIn(Runnable action) + { + // 创建FadeTransition对象 + FadeTransition fadeIn = new FadeTransition(Duration.seconds(0.5),tablePane ); + fadeIn.setFromValue(0); // 初始不透明度为1(完全可见) + fadeIn.setToValue(1); // 目标不透明度为0(完全透明) + fadeIn.setOnFinished((event)->{ + if (action != null) + action.run();}); + fadeIn.play(); + } + + public void updateFlushTime(ActionEvent event) + { + mainFrame.updateFlushTime(); + } +} diff --git a/src/com/qst/dms/ui/UpdateTimeSetFXML.java b/src/com/qst/dms/ui/UpdateTimeSetFXML.java new file mode 100644 index 0000000..c6f75fd --- /dev/null +++ b/src/com/qst/dms/ui/UpdateTimeSetFXML.java @@ -0,0 +1,70 @@ +package com.qst.dms.ui; + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.control.Slider; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseEvent; + +public class UpdateTimeSetFXML +{ + + public static int updateTime; + public int tempUpdateTime; + private InfoInputFXML infoInputFXML; + private TableFXML tableFXML; + private UpdateTimeSetFXML updateTimeSetFrame; + @FXML + private TextField timeField; + + @FXML + private Slider timeSlider; + + + @FXML + void mouseDragging(MouseEvent event) { + tempUpdateTime = (int)timeSlider.getValue(); + timeField.setText(""+tempUpdateTime); + } + + + public void initialize() + { + updateTime = 1; + timeSlider.setMin(1); + timeSlider.setMax(60); + timeSlider.setValue(1); + timeField.setText("1"); + } + + public void getDelegation(InfoInputFXML _infoInputFXMLController, TableFXML _tableFXMLController) + { + infoInputFXML=_infoInputFXMLController; + tableFXML=_tableFXMLController; + } + + public void beChanged(KeyEvent keyEvent) + { + String value = timeField.getText(); + int caretPosition = timeField.getCaretPosition(); + if (!value.matches("\\d*")) { + timeField.setText(value.replaceAll("[^\\d]", "")); + timeField.positionCaret(Math.max(0,caretPosition-1)); + } + else { + if(value.isEmpty()) + return; + tempUpdateTime = Math.max(1,Integer.parseInt(value)); + timeSlider.setValue(tempUpdateTime); + } + } + + public void closeRequest() + { + updateTime=tempUpdateTime; + infoInputFXML.updateSQLCheckerTime(); + tableFXML.updateFlusherTime(); + } + +} diff --git a/src/com/qst/dms/ui/logLine.java b/src/com/qst/dms/ui/logLine.java new file mode 100644 index 0000000..746e098 --- /dev/null +++ b/src/com/qst/dms/ui/logLine.java @@ -0,0 +1,37 @@ +package com.qst.dms.ui; + +public class logLine +{ + public logLine(String logUsername, String loginTime, String logoutTime, String logAddress) + { + this.logUsername = logUsername; + this.loginTime = loginTime; + this.logoutTime = logoutTime; + this.logAddress = logAddress; + } + + public String getLogUsername() + { + return logUsername; + } + + public String getLoginTime() + { + return loginTime; + } + + public String getLogoutTime() + { + return logoutTime; + } + + public String getLogAddress() + { + return logAddress; + } + + public String logUsername; + public String loginTime; + public String logoutTime; + public String logAddress; +} \ No newline at end of file diff --git a/src/com/qst/dms/ui/transportLine.java b/src/com/qst/dms/ui/transportLine.java new file mode 100644 index 0000000..3721873 --- /dev/null +++ b/src/com/qst/dms/ui/transportLine.java @@ -0,0 +1,62 @@ +package com.qst.dms.ui; + +import com.qst.dms.entity.Transport; + +public class transportLine +{ + public transportLine(String transID,String transAddress, String transHandler, String transReceiver, String transState, String transTime, int transType) + { + this.transID = transID; + this.transAddress = transAddress; + this.transHandler = transHandler; + this.transReceiver = transReceiver; + this.transState = transState; + this.transTime = transTime; + switch (transType) + { + case Transport.SENDING -> this.transType = "发货中"; + case Transport.TRANSPORTING -> this.transType = "送货中"; + case Transport.RECEIVED -> this.transType = "已签收"; + } + } + + public String getTransID() { return transID; } + + public String getTransAddress() + { + return transAddress; + } + + public String getTransHandler() + { + return transHandler; + } + + public String getTransReceiver() + { + return transReceiver; + } + + public String getTransState() + { + return transState; + } + + public String getTransTime() + { + return transTime; + } + + public String getTransType() + { + return transType; + } + + String transID; + String transAddress; + String transHandler; + String transReceiver; + String transState; + String transTime; + String transType; +} diff --git a/src/com/qst/dms/util/Config.java b/src/com/qst/dms/util/Config.java new file mode 100644 index 0000000..1dda3bc --- /dev/null +++ b/src/com/qst/dms/util/Config.java @@ -0,0 +1,22 @@ +package com.qst.dms.util; + +import java.io.FileInputStream; +import java.util.Properties; + +//配置类 +public class Config { + private static Properties p = null; + static { + try { + p = new Properties(); + //加载配置类 + p.load(new FileInputStream("src/com/qst/dms/db/config/mysql.properties")); + } catch (Exception e) { + e.printStackTrace(); + } + } + //获取配置类的参数 + public static String getValue(String key) { + return p.get(key).toString(); + } +} diff --git a/src/resources/InfoInputFrame.fxml b/src/resources/InfoInputFrame.fxml new file mode 100644 index 0000000..43cda58 --- /dev/null +++ b/src/resources/InfoInputFrame.fxml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +