当前位置: 首页 > news >正文

基于Javase的停车场收费管理系统

基于Javase的停车场收费管理系统

停车场管理系统开发文档

  1. 项目概述
    1.1 项目背景
    随着现代化城市的不断发展,车辆数量不断增加,停车难问题也日益突出。为了更好地管理停车场资
    源,提升停车效率,需要一个基于Java SE的停车场管理系统,来实现对车辆的有序管理和停车场的动态监控。
    1.2 项目目标
    停车场管理系统旨在提供停车位的分配、车辆进出场记录、停车费用计算等功能,提升停车场管理的效率和用户体验。
  2. 系统需求
    2.1 功能需求
    用户端
    车辆进场登记:记录车辆进场时间、车牌号及分配停车位。
    车辆出场登记:记录车辆出场时间、计算停车费用。
    停车位管理:实时查看停车位的空闲和占用情况。
    费用结算:按照停车时长计算停车费用,并支持不同的收费标准。
    报表生成:生成每日的停车场运营报表,记录车辆出场管理端生成验证码进行登录:
    当进入管理端时需要生成验证码并且输入,成功进入后台,输入机会只有三次
    在场车辆:查看当前停车场在场车辆
    离场车辆:查看当前停车场已经立场的车辆
    营业额统计:查看总营业额
    用户反馈:可以查看用户的反馈信息
    2.2 非功能需求
    易用性:系统界面简单易用,方便管理员操作。
    扩展性:系统应具备良好的扩展能力,能够根据需求添加新的功能模块。
  3. 详细设计
    4.1 车辆进出流程
  4. 车辆入场流程:
    当车辆到达停车场时,管理员在系统中输入车牌号,系统自动分配一个空闲的停车位并记录进
    场时间。
    若无空闲停车位,系统提示停车场已满。
    当输入车牌号时,需要辨别车牌号是否有效
  5. 车辆出场流程:
    当车辆离开时,管理员在系统中查找该车辆的停车记录,系统计算停车时长并依据收费标准计
    算停车费用。
    系统释放该停车位,将车辆记录标记为已出场。
    4.2 停车费用计算
    系统支持按小时、按分钟等方式计算费用,假设每小时收费10元,收费公式如下:
  6. 技术选型
    开发语言:Java SE
  7. 测试方案
    车辆进出场功能
    停车费用计算功能
    停车位分配功能
    6.3 用户测试
    模拟管理员的日常操作,测试系统界面的易用性、功能的完整性和系统性能

项目源码

创建汽车类Car

abstract class Car {
    // 车牌号
    private String CarNum;
    // 车辆类型
    private String CarType;
    // 车辆品牌
    private String CarBrand;
    // 车辆型号
    private String CarModel;
    // 入场时间
    private long CarInTime;
    // 出场时间
    private long CarOutTime;

    public Car(String carNum, String carType, String carBrand, String carModel, long carInTime, long carOutTime) {
        CarNum = carNum;
        CarType = carType;
        CarBrand = carBrand;
        CarModel = carModel;
        CarInTime = carInTime;
        CarOutTime = carOutTime;
    }

    public String getCarNum() {
        return CarNum;
    }

    public void setCarNum(String carNum) {
        CarNum = carNum;
    }

    public String getCarType() {
        return CarType;
    }

    public void setCarType(String carType) {
        CarType = carType;
    }

    public String getCarBrand() {
        return CarBrand;
    }

    public void setCarBrand(String carBrand) {
        CarBrand = carBrand;
    }

    public String getCarModel() {
        return CarModel;
    }

    public void setCarModel(String carModel) {
        CarModel = carModel;
    }

    public long getCarInTime() {
        return CarInTime;
    }

    public void setCarInTime(long carInTime) {
        CarInTime = carInTime;
    }

    public long getCarOutTime() {
        return CarOutTime;
    }

    public void setCarOutTime(long carOutTime) {
        CarOutTime = carOutTime;
    }

    // 抽象方法,由子类实现计算停车费用
    public abstract double calculateParkingFee();
}

创建轿车子类Sedan

// 轿车类,继承自Car类
class Sedan extends Car {
    public Sedan(String carNum, String carType, String carBrand, String carModel, long carInTime, long carOutTime) {
        super(carNum, carType, carBrand, carModel, carInTime, carOutTime);
    }

    @Override
    public double calculateParkingFee() {
        long duration = (getCarOutTime() - getCarInTime()) / 1000 / 60;
        if (duration <= 30) {
            return 2.5;
        } else if (duration <= 60) {
            return 5;
        } else {
            return 5 * (duration / 60) + (duration % 60 <= 30? 2.5 : 5);
        }
    }
}

创建客车子类Bus

// 客车类,继承自Car类
class Bus extends Car {
    public Bus(String carNum, String carType, String carBrand, String carModel, long carInTime, long carOutTime) {
        super(carNum, carType, carBrand, carModel, carInTime, carOutTime);
    }

    @Override
    public double calculateParkingFee() {
        long duration = (getCarOutTime() - getCarInTime()) / 1000 / 60;
        if (duration <= 30) {
            return 5;
        } else if (duration <= 60) {
            return 10;
        } else {
            return 10 * (duration / 60) + (duration % 60 <= 30? 5: 10);
        }
    }
}

创建停车场管理类ParkingLotManager

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

// 停车场管理类
class ParkingLotManager {
    // 已停车车辆列表
    private List<Car> parkedCars;
    // 总车位数
    private int totalSlots;
    // 剩余车位数
    private int availableSlots;
    // 用户评价列表
    public List<String> feedbackList;
    // 用于存储离场车辆
    private List<Car> departedCars;

    public ParkingLotManager(int totalSlots) {
        this.parkedCars = new ArrayList<>();
        this.totalSlots = totalSlots;
        this.availableSlots = totalSlots;
        this.feedbackList = new ArrayList<>();
        // 初始化离场车辆列表
        this.departedCars = new ArrayList<>();
    }

    // 车辆进场方法
    public void parkCar() {
        if (availableSlots <= 0) {
            System.out.println("停车场已满");
            return;
        }
        Scanner scanner = new Scanner(System.in);
        System.out.println("1.轿车 \t\t2.客车");
        System.out.println("请选择你的车辆类型");
        int carTypeChoice = scanner.nextInt();
        String carType = null;
        if (carTypeChoice == 1) {
            carType = "轿车";
        } else if (carTypeChoice == 2) {
            carType = "客车";
        }
        System.out.println("请输入车牌号");
        String carNum = scanner.next();
        //这行代码获取当前时间的时间戳,单位为毫秒。它用于记录车辆进入停车场的精确时间,后续可用于计算停车费用
        long inTime = System.currentTimeMillis();
        Car car;
        if ("轿车".equals(carType)) {
            car = new Sedan(carNum, carType, null, null, inTime, 0);
        } else {
            car = new Bus(carNum, carType, null, null, inTime, 0);
        }
        parkedCars.add(car);
        availableSlots--;
        System.out.println("以下为您的停车信息,请核实");
        System.out.println("***************************************");
        System.out.println("车辆类型\t车牌号\t入场时间");
        System.out.println(car.getCarType() + "\t\t" + car.getCarNum() + "\t\t" + new java.util.Date(car.getCarInTime()));
        System.out.println("***************************************");
    }

    // 车辆离场方法
    public void unparkCar() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入车牌号");
        String carNum = scanner.next();
        boolean found = false;
        for (Car car : parkedCars) {
            if (car.getCarNum().equals(carNum)) {
                found = true;
                System.out.println("请输入离场时间,请按正确的格式输入(yyyy-MM-dd/HH:mm:ss)");
                String outTimeStr = scanner.next();
                try {
                    //这段代码的功能是将用户输入的离场时间字符串解析为时间戳,并设置到车辆对象中
                    long outTime = new SimpleDateFormat("yyyy-MM-dd/HH:mm:ss").parse(outTimeStr).getTime();
                    car.setCarOutTime(outTime);
                    double fee = car.calculateParkingFee();
                    System.out.println("正在为您打印小票,请稍后...");
                    System.out.println("车牌号为" + car.getCarNum() + "的车辆停车时长为" + calculateDuration(car.getCarInTime(), car.getCarOutTime()));
                    System.out.println("************乾坤停车场管理系统小票***********");
                    System.out.println("车辆类型:" + car.getCarType());
                    System.out.println("车牌号:" + car.getCarNum());
                    System.out.println("车辆入场时间:" + new java.util.Date(car.getCarInTime()));
                    System.out.println("车辆离场时间:" + new java.util.Date(car.getCarOutTime()));
                    System.out.println("祝您一路顺风");
                    System.out.println("*********************");
                    System.out.println("您应缴费" + fee + "¥");
                    parkedCars.remove(car);
                    departedCars.add(car);
                    availableSlots++;
                    System.out.println("请留下您对此系统的评价或反馈");
                    String feedList = scanner.next();
                    feedbackList.add(feedList);
                } catch (Exception e) {
                    System.out.println("输入的离场时间格式错误");
                }
                break;
            }
        }
        if (!found) {
            System.out.println("输入错误,停车场无此车");
        }
    }

    // 计算停车时长方法
    private String calculateDuration(long inTime, long outTime) {
        long diff = outTime - inTime;
        long diffSeconds = diff / 1000 % 60;
        long diffMinutes = diff / (1000 * 60) % 60;
        long diffHours = diff / (1000 * 60 * 60) % 24;
        long diffDays = diff / (1000 * 60 * 60 * 24);
        return diffDays + "天" + diffHours + "小时" + diffMinutes + "分钟" + diffSeconds + "秒";
    }

    // 查看剩余车位方法
    public void checkAvailableSlots() {
        System.out.println("此停车场剩余" + availableSlots + "个停车位");
    }
    // 获取在场车辆信息
    public void getPresentCarsInfo() {
        if (parkedCars.isEmpty()) {
            System.out.println("当前停车场内没有车辆。");
            return;
        }
        System.out.println("当前在场车辆信息:");
        System.out.println("车辆类型\t车牌号\t入场时间");
        for (Car car : parkedCars) {
            System.out.println(car.getCarType() + "\t" + car.getCarNum() + "\t" + new java.util.Date(car.getCarInTime()));
        }
    }

    // 获取离场车辆信息
    public void getDepartedCarsInfo() {
        if (departedCars.isEmpty()) {
            System.out.println("目前没有车辆离场。");
            return;
        }
        System.out.println("离场车辆信息:");
        System.out.println("车辆类型\t车牌号\t入场时间\t离场时间");
        for (Car car : departedCars) {
            System.out.println(car.getCarType() + "\t" + car.getCarNum() + "\t" + new java.util.Date(car.getCarInTime()) + "\t" + new java.util.Date(car.getCarOutTime()));
        }
    }


    // 统计营业额
    public double calculateTurnover() {
        double totalFee = 0;
        for (Car car : departedCars) {
            if (car.getCarOutTime() != 0) {
                totalFee += car.calculateParkingFee();
            }
        }
        return totalFee;
    }
}

测试类Text

import java.io.*;
import java.util.Random;
import java.util.Scanner;

public class Text {
    // 管理员登录信息
//    private static final String ADMIN_USERNAME = "admin";
//    private static final String ADMIN_PASSWORD = "123456";

    public static void main(String[] args) {
        // 初始化停车场,假设总车位100个
        ParkingLotManager manager = new ParkingLotManager(100);
        try (Scanner scanner = new Scanner(System.in)) {
            while (true) {
                System.out.println("************欢迎进入乾坤停车场管理系统***********");
                System.out.println("请选择入口:");
                System.out.println("1. 用户停车入口\t\t2.系统管理员入口");
                int choice = scanner.nextInt();
                scanner.nextLine(); // 清除缓冲区
                switch (choice) {
                    case 1:
                        userMenu(manager, scanner);
                        break;
                    case 2:
                        adminMenu(manager, scanner);
                        break;
                    default:
                        System.out.println("输入错误,请重新选择");
                }
            }
        }
    }

    // 用户停车入口的菜单
    private static void userMenu(ParkingLotManager manager, Scanner scanner) {
        while (true) {
            System.out.print("1. 记录车辆信息");
            System.out.print("\t2. 车辆离场结算");
            System.out.print("\t3. 车位数量");
            System.out.println("\t4. 退出用户菜单");
            System.out.println("请用户选择执行的操作");
            int choice = scanner.nextInt();
            scanner.nextLine(); // 清除缓冲区
            switch (choice) {
                case 1:
                    manager.parkCar();
                    break;
                case 2:
                    manager.unparkCar();
                    break;
                case 3:
                    manager.checkAvailableSlots();
                    break;
                case 4:
                    if (confirmExit(scanner)) {
                        System.out.println("已退出用户菜单");
                        return;
                    }
                    break;
            }
        }
    }

    // 确认是否退出的方法
    private static boolean confirmExit(Scanner scanner) {
        System.out.println("您确定要退出吗?  1.残忍拒绝 2.我再想想");
        int confirmChoice = scanner.nextInt();
        scanner.nextLine(); // 清除缓冲区
        return confirmChoice == 1;
    }

    // 管理员菜单
    private static void adminMenu(ParkingLotManager manager, Scanner scanner) {
        while (true) {
            System.out.println("1. 获取生成验证码  2. 退出管理");
            int choice = scanner.nextInt();
            scanner.nextLine(); // 清除缓冲区
            switch (choice) {
                case 1:
                    generateAndVerifyCode(manager, scanner);
                    break;
                case 2:
                    System.out.println("已退出管理");
                    return;
                default:
                    System.out.println("输入错误,请重新选择");
            }
        }
    }

    // 生成验证码并进行密钥验证
    private static void generateAndVerifyCode(ParkingLotManager manager, Scanner scanner) {
        System.out.println("为了系统和个人隐私安全,请咨询系统总部要密钥");
        String verificationCode = generateVerificationCode();
        System.out.println("验证码已生成,正在发送到系统总部......");
        System.out.println("验证码已发送到系统总部");
        // 将验证码写入文件
        writeVerificationCodeToFile(verificationCode);
        int attempt = 3;
        while (attempt > 0) {
            System.out.println("请输入密钥");
            String input = scanner.nextLine().trim(); // 使用 nextLine 并去除首尾空格
            if (input.equals(verificationCode)) {
                System.out.println("密钥输入正确");
                // 这里可以添加后续管理员执行的操作,比如查看记录等
                innerAdminMenu(manager, scanner);
                return;
            } else {
                attempt--;
                if (attempt > 0) {
                    System.out.println("请重新输入,还有" + attempt + "次机会");
                } else {
                    System.out.println("机会已用完,返回管理菜单");
                    return; // 尝试次数用完后立即返回
                }
            }
        }
    }

    // 生成验证码
    private static String generateVerificationCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    // 新增方法:将验证码写入文件
    private static void writeVerificationCodeToFile(String verificationCode) {
        try (FileWriter writer = new FileWriter("C:\\Users\\H\\Desktop\\密码.txt")) {
            writer.write(verificationCode);
            System.out.println("验证码已保存到文件中");
        } catch (IOException e) {
            System.err.println("写入验证码到文件时发生错误: " + e.getMessage());
        }
    }
    // 验证码验证通过后的管理菜单
    private static void innerAdminMenu(ParkingLotManager manager, Scanner scanner) {
        while (true) {
            System.out.println("1. 查看在场车辆    2. 查看离场车辆相关信息   3. 统计营业额   4. 查看用户反馈   5. 退出管理员操作菜单   6.退出系统");
            int choice = scanner.nextInt();
            scanner.nextLine(); // 清除缓冲区
            switch (choice) {
                case 1:
                    manager.getPresentCarsInfo();
                    break;
                case 2:
                    manager.getDepartedCarsInfo();
                    break;
                case 3:
                    double turnover = manager.calculateTurnover();
                    System.out.println("当前停车场的营业额为:" + turnover + "¥");
                    break;
                case 4:
                    if (manager.feedbackList.isEmpty()) {
                        System.out.println("目前没有用户反馈信息。");
                    } else {
                        System.out.println("用户反馈信息如下:");
                        for (String feedback : manager.feedbackList) {
                            System.out.println(feedback);
                        }
                    }
                    break;
                case 5:
                        System.out.println("已退出管理员操作菜单");
                        return;
                case 6:
                    if (confirmExit2(scanner)){
                    System.out.println("乾坤管理系统已退出,谢谢使用");
                    System.exit(0);
                    }
            }
        }
    }
    private static boolean confirmExit2(Scanner scanner) {
        System.out.println("你好,你确定要退出系统吗?  1.确认 2.取消");
        int confirmChoice = scanner.nextInt();
        scanner.nextLine(); // 清除缓冲区
        return confirmChoice == 1;
    }
}

相关文章:

  • 视频编解码技术-3: H.264和VP9压缩效率和编码时延
  • 学习路程八 langchin核心组件 Models补充 I/O和 Redis Cache
  • API,URL,Token,XML,JSON是干嘛的
  • C#:泛型与类和结构的比较(接口,结构体,类,泛型)
  • 文件操作 -- IO [Java EE 初阶]
  • 浅谈C++/C命名冲突
  • MySQL的存储引擎
  • Postman接口测试工具使用
  • Redis 分布式锁
  • DeepSeek R1 简易指南:架构、本地部署和硬件要求
  • 【RAG生成】生成模块核心技术解密:从理论到实践的全链路优化
  • RabbitMQ 的介绍与使用
  • 极速探索 HarmonyOS NEXT:开启国产操作系统开发的新篇章
  • Unity 列表滚动到指定位置
  • c++ std::array使用笔记
  • Python之re模块
  • 【HarmonyOS Next】鸿蒙状态管理装饰器V1和V2混用方案
  • 【Linux】进程间通信——命名管道
  • ONNX转RKNN的环境搭建
  • 计算机毕设-基于springboot的融合多源高校画像数据与协同过滤算法的高考择校推荐系统的设计与实现(附源码+lw+ppt+开题报告)
  • 自己建设网站怎么盈利/舆情监控系统
  • 仙桃网站设计公司/b2b平台有哪些
  • wordpress七牛云token/四川seo快速排名
  • 商城类网站建设需要多少钱/aso优化app推广
  • 网站设计制作的服务机构/看广告赚钱的平台
  • phpwind 做的网站/seo排名优化怎样