commit b9df03f93b4eb6e0ab296bb34c262a9ee7562b17
Author: zyx <1029606625@qq.com>
Date: Fri May 20 17:56:40 2022 +0800
v1.0.0 项目完成
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/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..fa8838a
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..3104a9c
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..c9c447f
--- /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..e96534f
--- /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/lib/jxl.jar b/lib/jxl.jar
new file mode 100644
index 0000000..4a1fc64
Binary files /dev/null and b/lib/jxl.jar differ
diff --git a/lib/mysql-connector-java-8.0.26.jar b/lib/mysql-connector-java-8.0.26.jar
new file mode 100644
index 0000000..c5c07f6
Binary files /dev/null and b/lib/mysql-connector-java-8.0.26.jar differ
diff --git a/src/cn/czyx007/Main.java b/src/cn/czyx007/Main.java
new file mode 100644
index 0000000..55fdb79
--- /dev/null
+++ b/src/cn/czyx007/Main.java
@@ -0,0 +1,29 @@
+package cn.czyx007;
+
+import cn.czyx007.bean.User;
+import cn.czyx007.service.transaction.Login;
+import cn.czyx007.service.transaction.Menu;
+import cn.czyx007.util.JDBCUtils;
+
+import java.sql.Connection;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 22:29
+ */
+public class Main {
+ public static void main(String[] args) {
+ Connection connection = null;
+ try {
+ connection = JDBCUtils.getConnection();
+ User login = Login.login(connection);
+ if(login != null){
+ Menu.mainMenu(connection,login);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ JDBCUtils.closeResource(connection);
+ }
+ }
+}
diff --git a/src/cn/czyx007/bean/Product.java b/src/cn/czyx007/bean/Product.java
new file mode 100644
index 0000000..820c47d
--- /dev/null
+++ b/src/cn/czyx007/bean/Product.java
@@ -0,0 +1,68 @@
+package cn.czyx007.bean;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:24
+ */
+public class Product {
+ //商品条形码
+ private String barCode;
+ //商品名称
+ private String productName;
+ //单价
+ private Double price;
+ //供应商
+ private String supply;
+
+ public Product() {
+ }
+
+ public Product(String barCode, String productName, Double price, String supply) {
+ this.barCode = barCode;
+ this.productName = productName;
+ this.price = price;
+ this.supply = supply;
+ }
+
+ public String getBarCode() {
+ return barCode;
+ }
+
+ public void setBarCode(String barCode) {
+ this.barCode = barCode;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public Double getPrice() {
+ return price;
+ }
+
+ public void setPrice(Double price) {
+ this.price = price;
+ }
+
+ public String getSupply() {
+ return supply;
+ }
+
+ public void setSupply(String supply) {
+ this.supply = supply;
+ }
+
+ @Override
+ public String toString() {
+ return "Product{" +
+ "barCode='" + barCode + '\'' +
+ ", productName='" + productName + '\'' +
+ ", price=" + price +
+ ", supply='" + supply + '\'' +
+ '}';
+ }
+}
diff --git a/src/cn/czyx007/bean/SaleDetail.java b/src/cn/czyx007/bean/SaleDetail.java
new file mode 100644
index 0000000..69e894c
--- /dev/null
+++ b/src/cn/czyx007/bean/SaleDetail.java
@@ -0,0 +1,112 @@
+package cn.czyx007.bean;
+
+import java.util.Date;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:24
+ */
+public class SaleDetail {
+ //流水号
+ private String lsh;
+ //商品条形码
+ private String barCode;
+ //商品名称
+ private String productName;
+ //商品单价
+ private Double price;
+ //数量
+ private Integer count;
+ //收银员
+ private String operator;
+ //销售时间
+ private Date saleTime;
+
+ public SaleDetail() {
+ }
+
+ public SaleDetail(String lsh, String barCode, String productName, Double price, Integer count, String operator, Date saleTime) {
+ this.lsh = lsh;
+ this.barCode = barCode;
+ this.productName = productName;
+ this.price = price;
+ this.count = count;
+ this.operator = operator;
+ this.saleTime = saleTime;
+ }
+
+ public String getLsh() {
+ return lsh;
+ }
+
+ public void setLsh(String lsh) {
+ this.lsh = lsh;
+ }
+
+ public String getBarCode() {
+ return barCode;
+ }
+
+ public void setBarCode(String barCode) {
+ this.barCode = barCode;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public Double getPrice() {
+ return price;
+ }
+
+ public void setPrice(Double price) {
+ this.price = price;
+ }
+
+ public Integer getCount() {
+ return count;
+ }
+
+ public void setCount(Integer count) {
+ this.count = count;
+ }
+
+ public String getOperator() {
+ return operator;
+ }
+
+ public void setOperator(String operator) {
+ this.operator = operator;
+ }
+
+ public Date getSaleTime() {
+ return saleTime;
+ }
+
+ public void setSaleTime(Date saleTime) {
+ this.saleTime = saleTime;
+ }
+
+ @Override
+ public String toString() {
+ return "SaleDetail{" +
+ "lsh='" + lsh + '\'' +
+ ", barCode='" + barCode + '\'' +
+ ", productName='" + productName + '\'' +
+ ", price=" + price +
+ ", count=" + count +
+ ", operator='" + operator + '\'' +
+ ", saleTime=" + saleTime +
+ '}';
+ }
+
+ public void showInfoBySaleTime(){
+ System.out.print(lsh + "\t" + productName + "\t");
+ System.out.printf("% 4.2f\t% 4d\t% 4.2f\t",price,count,price*count);
+ System.out.print(saleTime + "\t");
+ }
+}
diff --git a/src/cn/czyx007/bean/User.java b/src/cn/czyx007/bean/User.java
new file mode 100644
index 0000000..ac5d580
--- /dev/null
+++ b/src/cn/czyx007/bean/User.java
@@ -0,0 +1,68 @@
+package cn.czyx007.bean;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:24
+ */
+public class User {
+ //用户登录名
+ private String userName;
+ //密码 sha1加密存储
+ private String password;
+ //中文名
+ private String chrName;
+ //用户角色 管理员/收银员
+ private String role;
+
+ public User() {
+ }
+
+ public User(String userName, String password, String chrName, String role) {
+ this.userName = userName;
+ this.password = password;
+ this.chrName = chrName;
+ this.role = role;
+ }
+
+ 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 String getChrName() {
+ return chrName;
+ }
+
+ public void setChrName(String chrName) {
+ this.chrName = chrName;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "userName='" + userName + '\'' +
+ ", password='" + password + '\'' +
+ ", chrName='" + chrName + '\'' +
+ ", role='" + role + '\'' +
+ '}';
+ }
+}
diff --git a/src/cn/czyx007/exception/BarCodeException.java b/src/cn/czyx007/exception/BarCodeException.java
new file mode 100644
index 0000000..4919e0d
--- /dev/null
+++ b/src/cn/czyx007/exception/BarCodeException.java
@@ -0,0 +1,14 @@
+package cn.czyx007.exception;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/15 - 12:46
+ */
+public class BarCodeException extends Exception{
+ public BarCodeException() {
+ }
+
+ public BarCodeException(String message) {
+ super(message);
+ }
+}
diff --git a/src/cn/czyx007/exception/PasswordException.java b/src/cn/czyx007/exception/PasswordException.java
new file mode 100644
index 0000000..cae887c
--- /dev/null
+++ b/src/cn/czyx007/exception/PasswordException.java
@@ -0,0 +1,14 @@
+package cn.czyx007.exception;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/15 - 14:45
+ */
+public class PasswordException extends Exception{
+ public PasswordException() {
+ }
+
+ public PasswordException(String message) {
+ super(message);
+ }
+}
diff --git a/src/cn/czyx007/exception/ProductException.java b/src/cn/czyx007/exception/ProductException.java
new file mode 100644
index 0000000..54a3a0b
--- /dev/null
+++ b/src/cn/czyx007/exception/ProductException.java
@@ -0,0 +1,14 @@
+package cn.czyx007.exception;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/15 - 13:07
+ */
+public class ProductException extends Exception{
+ public ProductException() {
+ }
+
+ public ProductException(String message) {
+ super(message);
+ }
+}
diff --git a/src/cn/czyx007/service/dao/ProductDAO.java b/src/cn/czyx007/service/dao/ProductDAO.java
new file mode 100644
index 0000000..f8c6c58
--- /dev/null
+++ b/src/cn/czyx007/service/dao/ProductDAO.java
@@ -0,0 +1,44 @@
+package cn.czyx007.service.dao;
+
+import cn.czyx007.bean.Product;
+
+import java.sql.Connection;
+import java.util.List;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:38
+ */
+public interface ProductDAO {
+ /**
+ * 添加一个新商品
+ * @param connection
+ * @param product
+ * @return
+ */
+ int insertProduct(Connection connection, Product product);
+
+ /**
+ * 根据商品条形码删除一个商品
+ * @param connection
+ * @param barCode
+ * @return
+ */
+ int deleteProduct(Connection connection,String barCode);
+
+ /**
+ * 根据商品名称模糊查询商品数据
+ * @param connection
+ * @param productName
+ * @return
+ */
+ List queryProductByName(Connection connection, String productName);
+
+ /**
+ * 根据商品条形码查询商品表,若可选参数为0则返回所有商品
+ * @param connection
+ * @param barCodes
+ * @return
+ */
+ List queryProductByCode(Connection connection, String ...barCodes);
+}
diff --git a/src/cn/czyx007/service/dao/SaleDetailDAO.java b/src/cn/czyx007/service/dao/SaleDetailDAO.java
new file mode 100644
index 0000000..64d567a
--- /dev/null
+++ b/src/cn/czyx007/service/dao/SaleDetailDAO.java
@@ -0,0 +1,44 @@
+package cn.czyx007.service.dao;
+
+import cn.czyx007.bean.SaleDetail;
+
+import java.sql.Connection;
+import java.util.List;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:38
+ */
+public interface SaleDetailDAO {
+ /**
+ * 添加一个销售明细
+ * @param connection
+ * @param saleDetail
+ * @return
+ */
+ int insertSaleDetail(Connection connection, SaleDetail saleDetail);
+
+ /**
+ * 根据流水号删除一个销售明细
+ * @param connection
+ * @param lsh
+ * @return
+ */
+ int deleteSaleDetail(Connection connection,String lsh);
+
+ /**
+ * 根据流水号查询销售明细表,若可选参数为0则返回所有销售明细
+ * @param connection
+ * @param lshs
+ * @return
+ */
+ List querySaleDetailByLsh(Connection connection, String ...lshs);
+
+ /**
+ * 根据销售时间查询销售明细表
+ * @param connection
+ * @param date
+ * @return
+ */
+ List querySaleDetailBySaleTime(Connection connection, String date);
+}
diff --git a/src/cn/czyx007/service/dao/UserDAO.java b/src/cn/czyx007/service/dao/UserDAO.java
new file mode 100644
index 0000000..2f27c3a
--- /dev/null
+++ b/src/cn/czyx007/service/dao/UserDAO.java
@@ -0,0 +1,54 @@
+package cn.czyx007.service.dao;
+
+import cn.czyx007.bean.User;
+
+import java.sql.Connection;
+import java.util.List;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:37
+ */
+public interface UserDAO {
+ /**
+ * 检查用户名与密码是否匹配,用于登录校验
+ * @param connection
+ * @param userName
+ * @param password
+ * @return
+ */
+ long checkUserPassword(Connection connection,String userName,String password);
+
+ /**
+ * 插入一个新用户
+ * @param connection
+ * @param user
+ * @return
+ */
+ int insertUser(Connection connection, User user);
+
+ /**
+ * 根据用户登录名删除一个用户
+ * @param connection
+ * @param userName
+ * @return
+ */
+ int deleteUser(Connection connection,String userName);
+
+ /**
+ * 根据用户登录名修改用户密码
+ * @param connection
+ * @param userName
+ * @param newPassword
+ * @return
+ */
+ int updateUser(Connection connection,String userName,String newPassword);
+
+ /**
+ * 根据用户登录名查询用户表,若可选参数为0则返回所有用户
+ * @param connection
+ * @param userNames
+ * @return
+ */
+ List queryUser(Connection connection,String ...userNames);
+}
diff --git a/src/cn/czyx007/service/dao/base/BaseDAO.java b/src/cn/czyx007/service/dao/base/BaseDAO.java
new file mode 100644
index 0000000..8db1fe4
--- /dev/null
+++ b/src/cn/czyx007/service/dao/base/BaseDAO.java
@@ -0,0 +1,128 @@
+package cn.czyx007.service.dao.base;
+
+import cn.czyx007.util.JDBCUtils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.sql.*;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 22:22
+ */
+public class BaseDAO {
+ private Class clazz = null;
+
+ //获取当前BaseDAO的子类继承的父类中的泛型
+ {//只能用非静态,静态代码块内不能调用非静态
+ //获取当前对象的父类的泛型
+ //此处this对象是子类的对象
+ Type genericSuperclass = this.getClass().getGenericSuperclass();
+ ParameterizedType paramType = (ParameterizedType) genericSuperclass;
+ //获取了父类的泛型参数
+ Type[] typeArguments = paramType.getActualTypeArguments();
+ //泛型的第一个参数
+ clazz = (Class) typeArguments[0];
+ }
+
+ public static int update(Connection connection, String sql, Object... args) {
+ PreparedStatement ps = null;
+ try {
+ ps = connection.prepareStatement(sql);
+ for (int i = 0; i < args.length; i++) {
+ ps.setObject(i + 1, args[i]);
+ }
+ //返回增删改操作影响的行数
+ return ps.executeUpdate();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ JDBCUtils.closeResource(null, ps);
+ }
+ return 0;
+ }
+
+ /**
+ * 针对不同的表的通用的查询操作,返回所有记录
+ * ver2.0 考虑到数据库事务
+ *
+ * @param sql 要执行的sql语句
+ * @param args 填充占位符
+ * @return List返回查询结果记录
+ */
+ public List search(Connection connection, String sql, Object... args) {
+ PreparedStatement ps = null;
+ ResultSet resultSet = null;
+ try {
+ ps = connection.prepareStatement(sql);
+ for (int i = 0; i < args.length; i++) {
+ ps.setObject(i + 1, args[i]);
+ }
+
+ resultSet = ps.executeQuery();
+
+ ResultSetMetaData metaData = resultSet.getMetaData();
+ int columnCount = metaData.getColumnCount();
+
+ ArrayList results = new ArrayList<>();
+
+ while (resultSet.next()) {
+ T t = clazz.newInstance();
+ for (int i = 0; i < columnCount; i++) {
+ Object columnValue = resultSet.getObject(i + 1);
+ if (columnValue instanceof BigDecimal){
+ columnValue = Double.parseDouble(columnValue.toString());
+ }
+ if (columnValue instanceof LocalDateTime){
+ columnValue = Date.from(((LocalDateTime) columnValue).atZone(ZoneId.systemDefault()).toInstant());
+ }
+
+ //获取列的别名(没有起别名时默认就是列名)
+ String columnLabel = metaData.getColumnLabel(i + 1);
+
+ Field field = t.getClass().getDeclaredField(columnLabel);
+ field.setAccessible(true);
+// System.out.print(columnLabel + ", " + columnValue + " ");
+// System.out.println(columnValue.getClass());
+ field.set(t, columnValue);
+ }
+ results.add(t);
+ }
+
+ return results;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ JDBCUtils.closeResource(null, ps, resultSet);
+ }
+ return null;
+ }
+
+ //用于查询特殊值的通用方法
+ public E getValue(Connection connection,String sql,Object ...args) {
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ ps = connection.prepareStatement(sql);
+ for (int i = 0; i < args.length; i++) {
+ ps.setObject(i+1,args[i]);
+ }
+ rs = ps.executeQuery();
+ if (rs.next()){
+ return (E) rs.getObject(1);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ } finally {
+ JDBCUtils.closeResource(null,ps,rs);
+ }
+ return null;
+ }
+}
diff --git a/src/cn/czyx007/service/dao/impl/ProductDAOImpl.java b/src/cn/czyx007/service/dao/impl/ProductDAOImpl.java
new file mode 100644
index 0000000..54f3096
--- /dev/null
+++ b/src/cn/czyx007/service/dao/impl/ProductDAOImpl.java
@@ -0,0 +1,52 @@
+package cn.czyx007.service.dao.impl;
+
+import cn.czyx007.bean.Product;
+import cn.czyx007.service.dao.ProductDAO;
+import cn.czyx007.service.dao.base.BaseDAO;
+
+import java.sql.Connection;
+import java.util.List;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:39
+ */
+public class ProductDAOImpl extends BaseDAO implements ProductDAO {
+ @Override
+ public int insertProduct(Connection connection, Product product) {
+ //language=MySQL
+ String sql = "insert into sale.tproduct values (?,?,?,?)";
+ return update(connection,sql,product.getBarCode(),product.getProductName(),product.getPrice(),product.getSupply());
+ }
+
+ @Override
+ public int deleteProduct(Connection connection, String barCode) {
+ //language=MySQL
+ String sql = "delete from sale.tproduct where bar_code = ?";
+ return update(connection,sql,barCode);
+ }
+
+ @Override
+ public List queryProductByName(Connection connection, String productName) {
+ //language=MySQL
+ String sql = "select bar_code barCode, product_name productName, price, supply from sale.tproduct where product_name like ?";
+ return search(connection,sql,"%" + productName + "%");
+ }
+
+ @Override
+ public List queryProductByCode(Connection connection, String... barCodes) {
+ //language=MySQL
+ StringBuilder sql = new StringBuilder("select bar_code barCode, product_name productName, price, supply from sale.tproduct");
+ if (barCodes.length > 0){
+ sql.append(" where bar_code in (");
+ for (int i = 0; i < barCodes.length; i++) {
+ sql.append("?");
+ if (i < barCodes.length-1)
+ sql.append(",");
+ }
+ sql.append(")");
+ return search(connection,sql.toString(), (Object[]) barCodes);
+ }
+ return search(connection,sql.toString());
+ }
+}
diff --git a/src/cn/czyx007/service/dao/impl/SaleDetailDAOImpl.java b/src/cn/czyx007/service/dao/impl/SaleDetailDAOImpl.java
new file mode 100644
index 0000000..83d3686
--- /dev/null
+++ b/src/cn/czyx007/service/dao/impl/SaleDetailDAOImpl.java
@@ -0,0 +1,53 @@
+package cn.czyx007.service.dao.impl;
+
+import cn.czyx007.bean.SaleDetail;
+import cn.czyx007.service.dao.SaleDetailDAO;
+import cn.czyx007.service.dao.base.BaseDAO;
+
+import java.sql.Connection;
+import java.util.List;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:39
+ */
+public class SaleDetailDAOImpl extends BaseDAO implements SaleDetailDAO {
+ @Override
+ public int insertSaleDetail(Connection connection, SaleDetail saleDetail) {
+ //language=MySQL
+ String sql = "insert into sale.tsaledetail values (?,?,?,?,?,?,?)";
+ return update(connection,sql,saleDetail.getLsh(),saleDetail.getBarCode(), saleDetail.getProductName(),
+ saleDetail.getPrice(),saleDetail.getCount(), saleDetail.getOperator(), saleDetail.getSaleTime());
+ }
+
+ @Override
+ public int deleteSaleDetail(Connection connection, String lsh) {
+ //language=MySQL
+ String sql = "delete from sale.tsaledetail where lsh = ?";
+ return update(connection,sql,lsh);
+ }
+
+ @Override
+ public List querySaleDetailByLsh(Connection connection, String... lshs) {
+ //language=MySQL
+ StringBuilder sql = new StringBuilder("select lsh, bar_code barCode, product_name productName, price, count, operator, sale_time saleTime from sale.tsaledetail");
+ if (lshs.length > 0){
+ sql.append(" where lsh in (");
+ for (int i = 0; i < lshs.length; i++) {
+ sql.append("?");
+ if (i < lshs.length-1)
+ sql.append(",");
+ }
+ sql.append(")");
+ return search(connection,sql.toString(), (Object[]) lshs);
+ }
+ return search(connection,sql.toString());
+ }
+
+ @Override
+ public List querySaleDetailBySaleTime(Connection connection, String date) {
+ //language=MySQL
+ String sql = "SELECT lsh, bar_code barCode, product_name productName, price, count, operator, sale_time saleTime FROM sale.tsaledetail WHERE STR_TO_DATE(sale_time,'%Y-%m-%d') = ?";
+ return search(connection,sql,date);
+ }
+}
diff --git a/src/cn/czyx007/service/dao/impl/UserDAOImpl.java b/src/cn/czyx007/service/dao/impl/UserDAOImpl.java
new file mode 100644
index 0000000..62d6f73
--- /dev/null
+++ b/src/cn/czyx007/service/dao/impl/UserDAOImpl.java
@@ -0,0 +1,61 @@
+package cn.czyx007.service.dao.impl;
+
+import cn.czyx007.bean.User;
+import cn.czyx007.service.dao.UserDAO;
+import cn.czyx007.service.dao.base.BaseDAO;
+
+import java.sql.Connection;
+import java.util.List;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 23:39
+ */
+public class UserDAOImpl extends BaseDAO implements UserDAO {
+ @Override
+ public long checkUserPassword(Connection connection, String userName, String password) {
+ //language=MySQL
+ String sql = "select password = sha1(?) from sale.tuser where user_name = ?";
+ Object value = getValue(connection, sql, password, userName);
+ if (value == null)
+ return 0;
+ return (long) value;
+ }
+
+ @Override
+ public int insertUser(Connection connection, User user) {
+ //language=MySQL
+ String sql = "insert into sale.tuser values (?,sha1(?),?,?)";
+ return update(connection,sql,user.getUserName(),user.getPassword(),user.getChrName(),user.getRole());
+ }
+
+ @Override
+ public int deleteUser(Connection connection, String userName) {
+ //language=MySQL
+ String sql = "delete from sale.tuser where user_name = ?";
+ return update(connection,sql,userName);
+ }
+
+ @Override
+ public int updateUser(Connection connection, String userName, String newPassword) {
+ //language=MySQL
+ String sql = "update sale.tuser set password = sha1(?) where user_name = ?";
+ return update(connection,sql,newPassword,userName);
+ }
+
+ @Override
+ public List queryUser(Connection connection, String... userNames) {
+ //language=MySQL
+ StringBuilder sql = new StringBuilder("select user_name userName, password, chr_name chrName, role from sale.tuser");
+ if (userNames.length > 0){
+ sql.append(" where user_name in (");
+ for (int i = 0; i < userNames.length; i++) {
+ sql.append("?");
+ if (i < userNames.length-1)
+ sql.append(",");
+ }
+ sql.append(")");
+ }
+ return search(connection,sql.toString(), (Object[]) userNames);
+ }
+}
diff --git a/src/cn/czyx007/service/transaction/DataExportMenu.java b/src/cn/czyx007/service/transaction/DataExportMenu.java
new file mode 100644
index 0000000..96cca50
--- /dev/null
+++ b/src/cn/czyx007/service/transaction/DataExportMenu.java
@@ -0,0 +1,80 @@
+package cn.czyx007.service.transaction;
+
+import cn.czyx007.bean.Product;
+import cn.czyx007.service.dao.impl.ProductDAOImpl;
+import jxl.Workbook;
+import jxl.write.Label;
+import jxl.write.Number;
+import jxl.write.WritableSheet;
+import jxl.write.WritableWorkbook;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.sql.Connection;
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/15 - 14:59
+ */
+public class DataExportMenu {
+ public static void exportDataToExcel(Connection connection){
+ String[] dateStr = LocalDate.now().toString().split("-");
+ String exportExcelName = "saleDetail" + dateStr[0].concat(dateStr[1]).concat(dateStr[2]) + ".xls";
+ WritableWorkbook wwb = null;
+ try {
+ wwb = Workbook.createWorkbook(new File("src/" + exportExcelName));
+ WritableSheet ws = wwb.createSheet("商品表", 0);
+
+ ws.addCell(new Label(0,0,"barCode"));
+ ws.addCell(new Label(1,0,"productName"));
+ ws.addCell(new Label(2,0,"price"));
+ ws.addCell(new Label(3,0,"supply"));
+
+ List products = new ProductDAOImpl().queryProductByCode(connection);
+ for (int i = 0; i < products.size(); i++) {
+ ws.addCell(new Label(0,i+1,products.get(i).getBarCode()));
+ ws.addCell(new Label(1,i+1,products.get(i).getProductName()));
+ ws.addCell(new Number(2,i+1,products.get(i).getPrice()));
+ ws.addCell(new Label(3,i+1,products.get(i).getSupply()));
+ }
+ wwb.write();
+ System.out.println("成功导出 " + products.size() + " 条销售数据到 excel 文件中");
+ System.out.print("按任意键返回主菜单");
+ System.in.read();
+ } catch (Exception e) {
+ System.out.println("数据导入失败!");
+ e.printStackTrace();
+ }finally {
+ if (wwb != null){
+ try {
+ wwb.close();
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ public static void exportDataToText(Connection connection){
+ String[] dateStr = LocalDate.now().toString().split("-");
+ String exportTextName = "saleDetail" + dateStr[0].concat(dateStr[1]).concat(dateStr[2]) + ".txt";
+ try (BufferedWriter bw = new BufferedWriter(new FileWriter("src/" + exportTextName))){
+ bw.write("barCode productName price supply\n");
+ List products = new ProductDAOImpl().queryProductByCode(connection);
+ for (int i = 0; i < products.size(); i++) {
+ bw.write(products.get(i).getBarCode() + " ");
+ bw.write(products.get(i).getProductName() + " ");
+ bw.write(products.get(i).getPrice() + " ");
+ bw.write(products.get(i).getSupply() + "\n");
+ }
+ bw.flush();
+ System.out.println("成功导出 " + products.size() + " 条销售数据到文本文件中");
+ System.out.print("按任意键返回主菜单");
+ System.in.read();
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/cn/czyx007/service/transaction/GoodsMaintenanceMenu.java b/src/cn/czyx007/service/transaction/GoodsMaintenanceMenu.java
new file mode 100644
index 0000000..6ba146c
--- /dev/null
+++ b/src/cn/czyx007/service/transaction/GoodsMaintenanceMenu.java
@@ -0,0 +1,200 @@
+package cn.czyx007.service.transaction;
+
+import cn.czyx007.bean.Product;
+import cn.czyx007.exception.ProductException;
+import cn.czyx007.service.dao.impl.ProductDAOImpl;
+import cn.czyx007.util.BarCodeCheck;
+import jxl.Sheet;
+import jxl.Workbook;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/15 - 10:57
+ */
+public class GoodsMaintenanceMenu {
+ /**
+ * 从excel导入数据
+ *
+ * @param connection
+ */
+ public static void loadDataFromExcel(Connection connection) {
+ Workbook workbook = null;
+ try {
+ workbook = Workbook.getWorkbook(new File("src/product.xls"));
+ Sheet sheet = workbook.getSheet(0);
+
+ ArrayList products = new ArrayList<>();
+ Product product;
+ int rows = sheet.getRows();
+ int columns = sheet.getColumns();
+ for (int i = 1; i < rows; i++) {
+ product = new Product();
+ for (int j = 0; j < columns; j++) {
+ String columnLabel = sheet.getCell(j, 0).getContents();
+ Object columnValue = sheet.getCell(j, i).getContents();
+ if ("price".equals(columnLabel))
+ columnValue = Double.parseDouble((String) columnValue);
+
+ Field field = product.getClass().getDeclaredField(columnLabel);
+ field.setAccessible(true);
+ field.set(product, columnValue);
+ }
+ products.add(product);
+ }
+
+ int cnt = 0;
+ ProductDAOImpl productDAO = new ProductDAOImpl();
+ for (int i = 0; i < products.size(); i++) {
+ List queryProduct = productDAO.queryProductByCode(connection, products.get(i).getBarCode());
+ if (queryProduct.size() == 0) {
+ productDAO.insertProduct(connection, products.get(i));
+ cnt++;
+ }
+ }
+ System.out.println("成功从 excel 文件导入 " + cnt + " 条商品数据");
+ System.out.print("按任意键返回主菜单");
+ System.in.read();
+ } catch (Exception e) {
+ System.out.println("数据导入失败!");
+ e.printStackTrace();
+ }finally {
+ if (workbook != null){
+ try {
+ workbook.close();
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * 从txt文件导入数据
+ *
+ * @param connection
+ */
+ public static void loadDataFromText(Connection connection) {
+ try (BufferedReader br = new BufferedReader(new FileReader("src/product.txt"))) {
+ int cnt = 0;
+ String line;
+ String[] titles = null;
+ ArrayList datas = new ArrayList<>();
+ while ((line = br.readLine()) != null) {
+ cnt++;
+ if (cnt == 1) {
+ titles = line.split(" ");
+ } else {
+ datas.add(line);
+ }
+ }
+
+ ArrayList products = new ArrayList<>();
+ Product product;
+ for (int i = 0; i < datas.size(); i++) {
+ product = new Product();
+ String[] rowData = datas.get(i).split(" ");
+ for (int j = 0; j < titles.length; j++) {
+ String columnLabel = titles[j];
+ Object columnValue = rowData[j];
+ if ("price".equals(columnLabel))
+ columnValue = Double.parseDouble((String) columnValue);
+
+ Field field = product.getClass().getDeclaredField(columnLabel);
+ field.setAccessible(true);
+ field.set(product, columnValue);
+ }
+ products.add(product);
+ }
+
+ cnt = 0;
+ ProductDAOImpl productDAO = new ProductDAOImpl();
+ for (int i = 0; i < products.size(); i++) {
+ List queryProduct = productDAO.queryProductByCode(connection, products.get(i).getBarCode());
+ if (queryProduct.size() == 0) {
+ productDAO.insertProduct(connection, products.get(i));
+ cnt++;
+ }
+ }
+ System.out.println("成功从文本文件导入 " + cnt + " 条商品数据");
+ System.out.print("按任意键返回主菜单");
+ System.in.read();
+ } catch (Exception e) {
+ System.out.println("数据导入失败!");
+ }
+ }
+
+ /**
+ * 从键盘依次录入商品信息
+ * @param connection
+ */
+ public static void loadDataFromKeyboard(Connection connection) {
+ ProductDAOImpl productDAO = new ProductDAOImpl();
+ Scanner scanner = new Scanner(System.in);
+ while (true) {
+ try {
+ System.out.print("请输入待录入的商品信息(格式为:");
+ System.out.println("商品条形码,商品名称,单价,供应商):");
+ String input = scanner.next();
+ String[] product = input.split(",");
+ if (product.length != 4)
+ throw new ProductException("你输入的数据格式不正确,请重新输入");
+
+ if (BarCodeCheck.checkFormat(product[0])) {
+ List queryProduct = productDAO.queryProductByCode(connection, product[0]);
+ if (queryProduct.size() != 0)
+ throw new ProductException("条形码不能重复,请重新输入");
+
+ try {
+ Double price = Double.parseDouble(product[2]);
+ int res = productDAO.insertProduct(connection, new Product(product[0], product[1], price, product[3]));
+ if (res == 1) System.out.println("添加成功");
+ else System.out.println("添加失败");
+ }catch (NumberFormatException e){
+ System.out.println("输入的价格格式不正确");
+ }
+ System.out.println("是否继续录入?(y/n):");
+ String opt = scanner.next();
+ if ("n".equalsIgnoreCase(opt))
+ return;
+ }
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * 商品查询
+ * 根据输入的商品名称进行模糊查询
+ * @param connection
+ */
+ public static void productQuery(Connection connection){
+ Scanner scanner = new Scanner(System.in);
+ System.out.println("请输入查询的商品名称:");
+ String productName = scanner.next();
+
+ List products = new ProductDAOImpl().queryProductByName(connection, productName);
+ System.out.printf("满足条件的记录总共%d条,信息如下:\n",products.size());
+ System.out.println("序号 条形码 商品名称 单价\t供应商");
+ System.out.println("=== ===== ======= \t ====\t=====");
+ if (products.size() > 0)
+ for (int i = 0; i < products.size(); i++) {
+ System.out.print((i+1) + "\t" + products.get(i).getBarCode() + "\t" + products.get(i).getProductName() + "\t");
+ System.out.printf("%- 7.2f\t",products.get(i).getPrice());
+ System.out.println(products.get(i).getSupply());
+ }
+ System.out.print("按任意键返回主菜单");
+ try {
+ System.in.read();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/cn/czyx007/service/transaction/Login.java b/src/cn/czyx007/service/transaction/Login.java
new file mode 100644
index 0000000..0f819d3
--- /dev/null
+++ b/src/cn/czyx007/service/transaction/Login.java
@@ -0,0 +1,52 @@
+package cn.czyx007.service.transaction;
+
+import cn.czyx007.bean.User;
+import cn.czyx007.service.dao.impl.UserDAOImpl;
+
+import java.sql.Connection;
+import java.util.Scanner;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/14 - 12:15
+ */
+public class Login {
+ private static String userName;
+ private static String password;
+
+ public static void getUserNameAndPassword(Scanner scanner){
+ System.out.print("请输入用户名:");
+ userName = scanner.next();
+ System.out.print("请输入密码:");
+ password = scanner.next();
+ }
+
+ public static User login(Connection connection){
+ Scanner scanner = new Scanner(System.in);
+ System.out.println("欢迎使用超市收银系统,请登陆:");
+ getUserNameAndPassword(scanner);
+
+ int loginCnt = 0;
+ while (true) {
+ if (loginSystem(connection) == 1) {
+ System.out.println("登录成功");
+ return new UserDAOImpl().queryUser(connection,userName).get(0);
+ }else {
+ loginCnt++;
+ if (loginCnt < 3) {
+ System.out.println("用户名或密码不正确,请重新输入");
+ getUserNameAndPassword(scanner);
+ }
+ else {
+ System.out.println("最多只能尝试 3 次");
+ return null;
+ }
+ }
+ }
+ }
+
+ public static long loginSystem(Connection connection){
+ UserDAOImpl userDAO = new UserDAOImpl();
+ return userDAO.checkUserPassword(connection,userName,password);
+ }
+}
diff --git a/src/cn/czyx007/service/transaction/Menu.java b/src/cn/czyx007/service/transaction/Menu.java
new file mode 100644
index 0000000..562040e
--- /dev/null
+++ b/src/cn/czyx007/service/transaction/Menu.java
@@ -0,0 +1,52 @@
+package cn.czyx007.service.transaction;
+
+import cn.czyx007.bean.User;
+import cn.czyx007.util.MenuUtils;
+
+import java.sql.Connection;
+import java.util.Scanner;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/14 - 12:15
+ */
+public class Menu {
+ public static void mainMenu(Connection connection, User user) {
+ Scanner scanner = new Scanner(System.in);
+ int opt;
+ while (true) {
+ while (true) {
+ System.out.printf("\n===超市收银系统=== \n" +
+ "1、收银\n" +
+ "2、查询统计\n" +
+ "3、商品维护\n" +
+ "4、修改密码\n" +
+ "5、数据导出\n" +
+ "6、退出\n" +
+ "当前收银员:" + user.getChrName() + "\n请选择(1-6):");
+ opt = MenuUtils.checkInputNumber(scanner,1,6);
+ if (opt != -1) break;
+ }
+ switch (opt) {
+ case 1:
+ SystemFunction.cashier(connection, user);
+ break;
+ case 2:
+ SystemFunction.query(connection,user);
+ break;
+ case 3:
+ SystemFunction.goodsMaintenance(connection,user);
+ break;
+ case 4:
+ SystemFunction.changePassword(connection,user);
+ break;
+ case 5:
+ SystemFunction.dataExport(connection);
+ break;
+ case 6:
+ SystemFunction.exit();
+ break;
+ }
+ }
+ }
+}
diff --git a/src/cn/czyx007/service/transaction/SystemFunction.java b/src/cn/czyx007/service/transaction/SystemFunction.java
new file mode 100644
index 0000000..1ab9a8b
--- /dev/null
+++ b/src/cn/czyx007/service/transaction/SystemFunction.java
@@ -0,0 +1,241 @@
+package cn.czyx007.service.transaction;
+
+import cn.czyx007.bean.Product;
+import cn.czyx007.bean.SaleDetail;
+import cn.czyx007.bean.User;
+import cn.czyx007.exception.BarCodeException;
+import cn.czyx007.exception.PasswordException;
+import cn.czyx007.service.dao.impl.ProductDAOImpl;
+import cn.czyx007.service.dao.impl.SaleDetailDAOImpl;
+import cn.czyx007.service.dao.impl.UserDAOImpl;
+import cn.czyx007.util.BarCodeCheck;
+import cn.czyx007.util.MenuUtils;
+import cn.czyx007.util.PasswordCheck;
+
+import java.sql.Connection;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/14 - 15:30
+ */
+public class SystemFunction {
+ /**
+ * 收银功能
+ *
+ * @param connection
+ * @param user
+ */
+ public static void cashier(Connection connection, User user) {
+ Scanner scanner = new Scanner(System.in);
+ String code;
+ while (true) {
+ System.out.println("请输入商品条形码(6 位数字字符):");
+ code = scanner.next();
+ try {
+ if (BarCodeCheck.checkFormat(code)) {
+ List products = new ProductDAOImpl().queryProductByCode(connection, code);
+ if (products.size() == 1) {
+ Product product = products.get(0);
+ while (true) {
+ try {
+ System.out.println("输入商品数量:");
+ int cnt = Integer.parseInt(scanner.next());
+ if (cnt <= 0) throw new NumberFormatException("输入的不是正整数");
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ int insertSaleDetail = new SaleDetailDAOImpl().insertSaleDetail(connection,
+ new SaleDetail(String.valueOf(System.currentTimeMillis()),
+ code, product.getProductName(), product.getPrice(),
+ cnt, user.getUserName(), sdf.parse(sdf.format(System.currentTimeMillis()))));
+ if (insertSaleDetail == 1) {
+ System.out.println("成功增加一笔销售数据");
+ System.out.print("按任意键返回主菜单");
+ System.in.read();
+ return;
+ }
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+ }else System.out.println("您输入的商品条形码不存在,请确认后重新输入");
+ }
+ } catch (BarCodeException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * 查询统计功能
+ *
+ * @param connection
+ * @param user
+ */
+ public static void query(Connection connection, User user) {
+ Scanner scanner = new Scanner(System.in);
+ System.out.println("请输入销售日期(yyyy-MM-dd):");
+ String dateStr = scanner.next();
+ try {
+ Date date = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
+ String[] dateDetail = dateStr.split("-");
+
+ List saleDetails = new SaleDetailDAOImpl().querySaleDetailBySaleTime(connection, dateStr);
+
+ System.out.println(dateDetail[0] + " 年 " + dateDetail[1] + " 月 " + dateDetail[2] + " 日销售如下");
+ System.out.println("\t流水号\t\t商品名称\t 单价\t 数量\t 金额\t\t\t时间\t\t\t\t\t收银员\n" +
+ "=============\t======\t ====\t ====\t ====\t==============================\t======");
+ int productNum = 0;
+ double saleMoney = 0;
+ if (saleDetails != null) {
+ for (int i = 0; i < saleDetails.size(); i++) {
+ saleDetails.get(i).showInfoBySaleTime();
+ System.out.println(user.getUserName());
+ productNum += saleDetails.get(i).getCount();
+ saleMoney += saleDetails.get(i).getCount() * saleDetails.get(i).getPrice();
+ }
+ }
+ System.out.println("销售总数:" + saleDetails.size() + " 商品总件:" + productNum + " 销售总金额:" + saleMoney);
+ System.out.println("日期:" + dateDetail[0] + " 年 " + dateDetail[1] + " 月 " + dateDetail[2] + " 日");
+ System.out.print("按任意键返回主菜单");
+ System.in.read();
+ } catch (Exception e) {
+ System.out.println("你输入的日期格式不正确,请重新输入");
+ }
+ }
+
+ /**
+ * 商品维护功能
+ *
+ * @param connection
+ * @param user
+ */
+ public static void goodsMaintenance(Connection connection, User user) {
+ if (!("管理员".equals(user.getRole()))) {
+ System.out.println("当前用户没有执行该项功能的权限");
+ return;
+ }
+
+ int opt;
+ Scanner scanner = new Scanner(System.in);
+ while (true) {
+ while (true) {
+ System.out.print("===超市商品管理维护====\n" +
+ "1、从 excel 中导入数据\n" +
+ "2、从文本文件导入数据\n" +
+ "3、键盘输入\n" +
+ "4、商品查询\n" +
+ "5、返回主菜单\n" +
+ "请选择(1-5):");
+ opt = MenuUtils.checkInputNumber(scanner, 1, 5);
+ if (opt != -1) break;
+ }
+ switch (opt) {
+ case 1://从excel中导入数据
+ GoodsMaintenanceMenu.loadDataFromExcel(connection);
+ break;
+ case 2://从文本文件导入数据
+ GoodsMaintenanceMenu.loadDataFromText(connection);
+ break;
+ case 3://键盘输入数据
+ GoodsMaintenanceMenu.loadDataFromKeyboard(connection);
+ break;
+ case 4://商品查询
+ GoodsMaintenanceMenu.productQuery(connection);
+ break;
+ case 5://返回主菜单
+ return;
+ }
+ }
+ }
+
+ /**
+ * 修改密码功能
+ *
+ * @param connection
+ * @param user
+ */
+ public static void changePassword(Connection connection, User user) {
+ Scanner scanner = new Scanner(System.in);
+ UserDAOImpl userDAO = new UserDAOImpl();
+ String pwd;
+ while (true) {
+ System.out.println("请输入当前用户的原密码:");
+ pwd = scanner.next();
+ if(userDAO.checkUserPassword(connection, user.getUserName(), pwd) == 0){
+ System.out.println("原密码输入不正确,请重新输入");
+ }else break;
+ }
+ System.out.println("请设置新的密码:");
+ while (true){
+ try {
+ pwd = scanner.next();
+ if(PasswordCheck.checkFormat(pwd)){
+ System.out.println("请输入确认密码:");
+ String ensurePwd = scanner.next();
+ if (pwd.equals(ensurePwd)){
+ userDAO.updateUser(connection,user.getUserName(),ensurePwd);
+ System.out.println("您已成功修改密码,请谨记");
+ System.out.print("按任意键返回主菜单");
+ System.in.read();
+ return;
+ }else throw new PasswordException("两次输入的密码必须一致,请重新输入密码");
+ }
+ }catch (Exception e){
+ System.out.println(e.getMessage());
+ }
+ }
+
+ }
+
+ /**
+ * 数据导出功能
+ *
+ * @param connection
+ */
+ public static void dataExport(Connection connection) {
+ int opt;
+ Scanner scanner = new Scanner(System.in);
+ while (true) {
+ while (true) {
+ System.out.print("===超市销售信息导出====\n" +
+ "1、导出到 excel 文件\n" +
+ "2、导出到文本文件\n" +
+ "3、返回主菜单\n" +
+ "请选择(1-3):");
+ opt = MenuUtils.checkInputNumber(scanner, 1, 3);
+ if (opt != -1) break;
+ }
+ switch (opt) {
+ case 1://导出到 excel 文件
+ DataExportMenu.exportDataToExcel(connection);
+ break;
+ case 2://导出到文本文件
+ DataExportMenu.exportDataToText(connection);
+ break;
+ case 3://返回主菜单
+ return;
+ }
+ }
+ }
+
+ /**
+ * 退出功能
+ */
+ public static void exit() {
+ Scanner scanner = new Scanner(System.in);
+ while (true) {
+ System.out.println("您确认退出系统吗(y/n)");
+ String opt = scanner.next();
+ if ("y".equalsIgnoreCase(opt)) {
+ System.out.println("欢迎下次继续使用");
+ System.exit(0);
+ } else if ("n".equalsIgnoreCase(opt))
+ return;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/cn/czyx007/util/BarCodeCheck.java b/src/cn/czyx007/util/BarCodeCheck.java
new file mode 100644
index 0000000..0432779
--- /dev/null
+++ b/src/cn/czyx007/util/BarCodeCheck.java
@@ -0,0 +1,18 @@
+package cn.czyx007.util;
+
+import cn.czyx007.exception.BarCodeException;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/15 - 12:44
+ */
+public class BarCodeCheck {
+ public static boolean checkFormat(String code) throws BarCodeException{
+ if (code.length() == 6) {
+ for (int i = 0; i < 6; i++)
+ if (!(code.charAt(i) >= '0' && code.charAt(i) <= '9'))
+ throw new BarCodeException("输入的条形码不是纯数字");
+ return true;
+ }else throw new BarCodeException("输入的条形码长度不正确");
+ }
+}
diff --git a/src/cn/czyx007/util/JDBCUtils.java b/src/cn/czyx007/util/JDBCUtils.java
new file mode 100644
index 0000000..2a83e0b
--- /dev/null
+++ b/src/cn/czyx007/util/JDBCUtils.java
@@ -0,0 +1,101 @@
+package cn.czyx007.util;
+
+import java.io.InputStream;
+import java.sql.*;
+import java.util.Properties;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/13 - 22:23
+ */
+public class JDBCUtils {
+ /**
+ * 获取数据库的连接
+ * @return
+ * @throws Exception
+ */
+ public static Connection getConnection() throws Exception{
+ //读取配置文件中的4个基本信息
+ Properties pros = new Properties();
+ InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
+ pros.load(is);
+
+ String user = pros.getProperty("user");
+ String password = pros.getProperty("password");
+ String url = pros.getProperty("url");
+ String driverClass = pros.getProperty("driverClass");
+
+ //加载驱动
+ Class.forName(driverClass);
+
+ //获取连接
+ Connection connection = DriverManager.getConnection(url, user, password);
+
+ return connection;
+ }
+
+ /**
+ * 关闭数据库连接
+ * @param connection
+ */
+ public static void closeResource(Connection connection){
+ if (connection != null){
+ try {
+ connection.close();
+ }catch (SQLException e){
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * 关闭数据库连接和Statement的操作
+ * @param connection
+ * @param ps
+ */
+ public static void closeResource(Connection connection, Statement ps){
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * 关闭数据库连接和Statement的操作以及结果集
+ * @param connection
+ * @param ps
+ */
+ public static void closeResource(Connection connection, Statement ps, ResultSet rs){
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ if (rs != null){
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/src/cn/czyx007/util/MenuUtils.java b/src/cn/czyx007/util/MenuUtils.java
new file mode 100644
index 0000000..4476308
--- /dev/null
+++ b/src/cn/czyx007/util/MenuUtils.java
@@ -0,0 +1,24 @@
+package cn.czyx007.util;
+
+import java.util.Scanner;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/15 - 15:30
+ */
+public class MenuUtils {
+ public static int checkInputNumber(Scanner scanner, int low, int high) {
+ String input = scanner.next();
+ try {
+ int opt = Integer.parseInt(input);
+ if (opt >= low && opt <= high)
+ return opt;
+ else {
+ System.out.println("输入无效,只能输入" + low + "-" + high);
+ }
+ } catch (NumberFormatException e) {
+ System.out.println("输入无效,只能输入" + low + "-" + high);
+ }
+ return -1;
+ }
+}
diff --git a/src/cn/czyx007/util/PasswordCheck.java b/src/cn/czyx007/util/PasswordCheck.java
new file mode 100644
index 0000000..34f4104
--- /dev/null
+++ b/src/cn/czyx007/util/PasswordCheck.java
@@ -0,0 +1,28 @@
+package cn.czyx007.util;
+
+import cn.czyx007.exception.PasswordException;
+
+/**
+ * @author : 张宇轩
+ * @createTime : 2022/5/15 - 14:44
+ */
+public class PasswordCheck {
+ private static final String PASSWORD_SECURITY_ERROR = "您的密码不符合复杂性要求(密码长度不少于 6 个字符,至少有一个小写字母,至少有一个大写字母,至少一个数字),请重新输入:";
+
+ public static boolean checkFormat(String pwd) throws PasswordException {
+ if (pwd.length() >= 6) {
+ int numCnt = 0, lowCnt = 0, upCnt = 0;
+ for (int i = 0; i < pwd.length(); i++) {
+ if (pwd.charAt(i) >= '0' && pwd.charAt(i) <= '9')
+ numCnt++;
+ else if (pwd.charAt(i) >= 'a' && pwd.charAt(i) <= 'z')
+ lowCnt++;
+ else if (pwd.charAt(i) >= 'A' && pwd.charAt(i) <= 'Z')
+ upCnt++;
+ }
+ if (numCnt >= 1 && lowCnt >= 1 && upCnt >= 1)
+ return true;
+ else throw new PasswordException(PASSWORD_SECURITY_ERROR);
+ } else throw new PasswordException(PASSWORD_SECURITY_ERROR);
+ }
+}
diff --git a/src/jdbc.properties b/src/jdbc.properties
new file mode 100644
index 0000000..b333f79
--- /dev/null
+++ b/src/jdbc.properties
@@ -0,0 +1,4 @@
+user=root
+password=zyx007
+url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
+driverClass=com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/work2.iml b/work2.iml
new file mode 100644
index 0000000..4ec8d60
--- /dev/null
+++ b/work2.iml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file