Java超市收银系统(四、收银功能)

引言

        今天,我们实现收银功能。系统显示“请输入商品条形码(6位数字字符):”,用户输入的条形码在商品表中存在,则显示“输入商品数量:”,否则,提示“您输入的商品条形码不存在,请确认后重新输入”, 条形码和数量输入完毕后在销售明细表中增加一条记录(各字段信息如下:流水号根据规则生成,条形码为用户输入,商品名称及商品单价是根据输入的条形码查找商品表获取的,收银员为当前登陆用户名,销售时间为系统当前时间yyyy-mm-dd hh:mm:ss),增加成功后显示“成功增加一笔销售数据”,显示提示“是否继续收银(y/n)”。

功能实现

        我们实现了一个基本的收银系统,通过产品条形码查找商品,记录销售数据,并生成唯一的流水号。它处理了用户输入、商品验证、销售记录生成和数据库插入等操作,并确保在多线程环境下流水号的唯一性。

1、数据库相关

        在sale数据库中创建商品表和收银明细表,表中参数分别对应vo数据信息包中product和sale,在这两个函数中定义变量时要参数与数据库保持一致。

2、java相关

        我们首先来讲一下生成流水号功能,private static Map<String, Integer> lastNumbers:一个静态 HashMap 用于存储每天的最后一个流水号序号。键是日期字符串(如 20240811),值是当天的最后一个流水号的编号。

        private static void cashier():定义一个私有静态方法 cashier,用于处理收银操作。Scanner scan = new Scanner(System.in):创建 Scanner 对象以从控制台读取输入。

检查商品是否存在:        

        创建 Product 对象并设置条形码。

        使用 ProductDAO.query(product) 查询商品是否存在。

        如果 productList 为空,表示商品不存在,打印错误消息并退出循环。

        如果商品存在,询问用户输入商品数量和收银员名字。 scan.nextLine(); 用于消耗 nextInt() 读取后留下的换行符。

        从查询结果中获取找到的商品,获取商品的价格和收银员的名字。 使用 Timestamp 记录当前时间。使用 SimpleDateFormat 格式化当前日期为 yyyyMMdd 格式的字符串。

同步获取和更新今天的流水号序号:

        使用 synchronized 关键字确保线程安全地访问和更新 lastNumbers。

        从 lastNumbers 中获取当天的流水号并递增。

        将流水号格式化为四位数字,并生成完整的流水号 (lsh)。

        创建 Sale 对象,包含流水号、条形码、商品名称、价格、数量、操作员和销售时间。

        将 Sale 对象插入数据库,检查插入是否成功。 根据用户输入决定是否继续收银或退出程序。 System.exit(0); 用于退出程序,input.equals("y") 和 input.equals("n") 用于判断用户输入。

结果展示

完整代码

vo—product

package vo;
public class Product {
    private String barCode;
    private String productName;
    private float price;
    private String supply;
    public Product() {
    }
    public Product(String barCode, String productName, float 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 float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }

    public String getSupply() {
        return supply;
    }

    public void setSupply(String supply) {
        this.supply = supply;
    }
}

vo—sale

package vo;

import java.sql.Timestamp;

public class Sale {
    private String lsh;
    private String barCode;
    private String productName;
    private float price;
    private int count;
    private String operator;
    private Timestamp saleTime;

    public Sale() {
    }

    public Sale(String lsh, String barCode, String productName, float price, int count, String operator, Timestamp 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 float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getOperator() {
        return operator;
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    public Timestamp getSaleTime() {
        return saleTime;
    }

    public void setSaleTime(Timestamp saleTime) {
        this.saleTime = saleTime;
    }
}

dao—ProductDAO

package dao;

import util.DBUtil;
import vo.Product;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ProductDAO {
    public static List<Product> query(Product product) {
        Connection con = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        List<Product> productList = new ArrayList<>();
        try {
            con = DBUtil.getConnection();
            StringBuilder sql = new StringBuilder("SELECT * FROM t_shangping WHERE 1 = 1");
            if (product.getBarCode() != null) {
                sql.append(" AND tiaoma = ?");
            }

            pst = con.prepareStatement(sql.toString());
            int paramIndex = 1;
            if (product.getBarCode() != null) {
                pst.setString(paramIndex++, product.getBarCode());
            }

            rs = pst.executeQuery();
            while (rs.next()) {
                Product p = new Product();
                p.setBarCode(rs.getString("tiaoma"));
                p.setProductName(rs.getString("mingcheng"));
                p.setPrice(rs.getFloat("danjia"));
                p.setSupply(rs.getString("gongyingshang"));
                productList.add(p);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(con, pst);
        }
        return productList;
    }
}

dao—SaleDAO

package dao;
import util.DBUtil;
import vo.Sale;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
public class SaleDAO {
    public static boolean insert(Sale sale) {
        Connection con = null;
        PreparedStatement pst = null;
        boolean success = false;
        try {
            con = DBUtil.getConnection();
            String sql = "INSERT INTO t_shouyinmingxi (liushuihao,tiaoma, mingcheng, " +
                    "danjia, shuliang, shouyinyuan, xiaoshoushijian) VALUES (?,?, ?, ?, ?, ?, ?)";
            pst = con.prepareStatement(sql);
            pst.setString(1,sale.getLsh());
            pst.setString(2, sale.getBarCode());
            pst.setString(3, sale.getProductName());
            pst.setFloat(4, sale.getPrice());
            pst.setInt(5, sale.getCount());
            pst.setString(6, sale.getOperator());
            pst.setTimestamp(7, new Timestamp(sale.getSaleTime().getTime()));
            int rowsAffected = pst.executeUpdate();
            if (rowsAffected > 0) {
                success = true;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(con, pst);
        }
        return success;
    }
}

util—DBUtil

package util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DBUtil {

    //驱动加载,只需执行一次
    static{
        String driveName = "com.mysql.cj.jdbc.Driver";
        try {
            Class.forName(driveName);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    //获取链接
    public static Connection getConnection(){
        String url = "jdbc:mysql://localhost:3306/sale?useUnicode=true&characterEncoding=utf-8";
        String user = "root";
        String password = "123456";
        Connection con = null;
        try {
            con = DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return con;
    }

    //关闭资源
    public static void close(Connection con, PreparedStatement pst){
        if(con!=null) {
            try {
                con.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(pst!=null) {
            try {
                pst.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

}

ui—Driver

package ui;

import dao.ProductDAO;
import dao.SaleDAO;
import vo.Product;
import vo.Sale;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

public class Driver {

    // 使用Map来存储每天的最后一个流水号序号
    private static Map<String, Integer> lastNumbers = new HashMap<>();

    public static void main(String[] args) {
        System.out.println("欢迎使用阳光超市收银系统");

        cashier();
    }

    private static void cashier() {
        Scanner scan = new Scanner(System.in);

        while (true) {

            System.out.println("请输入商品条形码(6位数字字符):");
            String barCode = scan.nextLine();

            // 检查商品是否存在
            Product product = new Product();
            product.setBarCode(barCode);
            List<Product> productList = ProductDAO.query(product);
            if (productList.isEmpty()) {
                System.out.println("您输入的商品条形码不存在,请确认后重新输入");
                break;
            }

            // 商品存在,询问商品数量
            System.out.println("请输入商品数量:");
            int count = scan.nextInt();
            scan.nextLine(); // 消耗换行符
            // 收银员
            System.out.println("请输入收银员:");
            String name = scan.nextLine();
            //scan.nextLine();

            // 生成销售记录
            Product foundProduct = productList.get(0); // 假设只有一个匹配的商品
            float price = foundProduct.getPrice();
            String operator = name;

            //***数据库中DateTime类型对应java中Timestamp类型
            Timestamp saleTime = new Timestamp(System.currentTimeMillis()); // 获取当前时间

            Date d = new Date();
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
            String todayStr = df.format(d);

            // 同步获取和更新今天的流水号序号
            synchronized (lastNumbers) {
                // 获取当前日期的序号,并递增
                int lastNum = lastNumbers.getOrDefault(todayStr, 1);
                lastNum++;
                lastNumbers.put(todayStr, lastNum);

                // 格式化序号部分为四位数字
                String lastNums = String.format("%04d", lastNum-1);
                String lsh = todayStr + lastNums; // 生成完整的流水号
                Sale sale = new Sale(lsh, foundProduct.getBarCode(), foundProduct.getProductName(), price, count, operator, saleTime);

                // 插入销售记录
                if (SaleDAO.insert(sale)) {
                    System.out.println("成功增加一笔销售数据");
                } else {
                    System.out.println("销售数据插入失败");
                }
                System.out.println("是否继续收银(y/n:)");
                String input = scan.nextLine();
                if (input.equals("y")) {

                } else if (input.equals("n")) {
                    System.out.println("成功退出收银程序");
                    System.exit(0);
                } else {
                    System.out.println("错误");
                }
            }
        }
    }

}

mysql—workbench

​CREATE DATABASE sale;

USE sale;

DROP TABLE IF EXISTS `t_shangping`;
CREATE TABLE `t_shangping` (
  `tiaoma` varchar(255) NOT NULL,
  `mingcheng` varchar(255) DEFAULT NULL,
  `danjia` decimal(10,2) DEFAULT NULL,
  `gongyingshang` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`tiaoma`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
select * from t_shangping;

INSERT INTO `t_shangping` VALUES ('100001', '手机', '4500.00', '华为');
INSERT INTO `t_shangping` VALUES ('100002', '鼠标', '61.00', '华为');
INSERT INTO `t_shangping` VALUES ('100003', '矿泉水', '2.50', '农夫山泉');
INSERT INTO `t_shangping` VALUES ('100004', '香烟', '20.00', '武汉卷烟厂');
INSERT INTO `t_shangping` VALUES ('100005', '牙膏', '4.50', '中华牙膏厂');
INSERT INTO `t_shangping` VALUES ('200001', '电脑', '4300.00', 'dell');
INSERT INTO `t_shangping` VALUES ('200002', '小明同学', '5.50', '武汉饮料集团');

DROP TABLE IF EXISTS `t_shouyinmingxi`;
CREATE TABLE `t_shouyinmingxi` (
  `liushuihao` varchar(255) NOT NULL,
  `tiaoma` varchar(255) DEFAULT NULL,
  `mingcheng` varchar(255) DEFAULT NULL,
  `danjia` decimal(10,0) DEFAULT NULL,
  `shuliang` int DEFAULT NULL,
  `shouyinyuan` varchar(255) DEFAULT NULL,
  `xiaoshoushijian` datetime DEFAULT NULL,
  PRIMARY KEY (`liushuihao`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
select * from t_shouyinmingxi;

其他

        其他超市系统用户功能详见:

Java超市收银系统(一、用户登录)_收银系统开发教程-CSDN博客

Java超市收银系统(二、用户权限)-CSDN博客

Java超市收银系统(三、密码修改)-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值