基于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;}
}