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