# Parking_Server **Repository Path**: mercy1108/parking_-server ## Basic Information - **Project Name**: Parking_Server - **Description**: 停车收费管理系统 - 后端 后端采用Java语言 + Springboot框架 + Mybatis-plus框架 + Mysql数据库设计 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 0 - **Created**: 2023-02-19 - **Last Updated**: 2026-02-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Parking lot management-需求分析 环境:SpringBoot + Vue2 + MySQL +SpringMVC + Mybatis-plus + Element UI 停车场收费管理系统是帮助用户节约时间,减少经济的费用的系统,有效管理的系统,能实现快速查询停车空位和优惠费用等功能。相应的需求有:能快速对信息的整合并显示,能准确进行判断。 ## 普通用户功能分析: 1. 登录停车系统(注册停车收费系统) 2. 查询停车场停车情况(看车位) 3. 预约停车(选取停车位) 4. 开始停车(开始计费) 5. 取消停车(费用结算) 6. 查看停车情况(查看当前订单) 7. 查看缴费记录(进行计费统计) 8. 普通用户登录后如图所示:(隐藏管理模块 + 统计报表) ## 管理员功能分析: 1. 对用户进行增删改查(修改属性) 2. 对车辆进行增删改查(修改属性) 3. 查看订单(做统计报表) 4. 管理员登录后如图所示:(显示管理模块 + 统计报表) ## 一.登录注册功能 1. 用户登录输入账户(手机号) + 密码进行校验,验证成功即可跳转首页 2. 用户首次登录进行数据库人员查询,如首次登录将输入的账户 + 密码存入数据库,并生成随机6位字符的昵称 3. 生成新人员的同时,相应的生成车辆信息数据,具体数据可等用户主动更新 4. 登录成功之后跳转首页 5.用户登录成功后,可在个人主页查看个人信息(图为已经更新完信息的用户) 6.用户登陆后,可在注册车辆模块,进行车辆信息的更新(用户未注册车辆信息,是不允许使用停车功能) 7.图为新用户还未注册车辆信息,点击注册车辆信息会有提示 8.不注册车辆信息无法使用停车功能,有提示 ## 二.用户管理模块(管理员权限) ### 1.1.需求 #### 用户功能: 1. 用户查询停车场内的停车情况、 2. 停车剩余情况、 3. 以及缴费记录, 4. 当停车场已满,没有空车位时,自动提示用户该停车场无空车位,请及时更换停车场停车; 5. 用户可以预约空余车位,预约成功后,该车位为不在显示空余,而是显示已经预约; #### 管理员功能: 1. 系统管理员可以对用户的信息、用户车辆的信息、用户的缴费情况进行增删改查; 2. 管理员可以通过对用户填写的信息进行操作,添加、删除、编辑用户信息 ### 1.2.数据库建表: 登录注册时填写用户个人信息 ### 1.3.页面 #### 用户管理 #### 1.首页 #### 点击编辑按钮,弹出子组件 1. 编辑信息按钮:弹出子组件,进行信息更新的保存 2. 删除按钮:删除用户信息(直接操作DB) 3. 搜索按钮:建议是按姓名搜索 ## 三.车辆管理模块(管理员权限) ### 2.1.需求 1. 根据车辆管理模块功能,管理员可以查看、编辑、删除当前所有车辆的信息。 ### 2.2.数据库建表: ### 2.3.页面 #### 1.首页 #### 2.点击编辑按钮,弹出子组件 1. 编辑信息按钮:弹出新的路由组件,进行信息更新的保存 2. 删除按钮:删除车辆信息(直接操作DB) 3. 搜索按钮:按车牌号搜索 ## ###总结: 1. 用户管理+车辆管理模块为管理员可操作的模块,普通用户登陆后隐藏不显示, 2. 都做了分页操作,基于ELement UI的pagination组件,后端为Mybaits-plus的Page类 ## 四.查询管理模块+预约停车模块 ### 3.1.需求 1. 根据查询管理模块,用户可以查询停车场内的停车情况以及停车场车位剩余情况,查询缴费记录(按月、按年、按次),查询场内车辆信息。 2. 根据预约管理模块,用户可以对剩余的车位进行预约,预约成功后,该车位信息显示已预约。 ### 3.2.业务: 1. 查询车库信息(查询停车位) 2. 预约成功即生成订单,保存相关信息 3. 预约成功车位属性变化 4. 查询停车订单表(缴费记录、按年、月、次整理) ### 3.3页面 1.此页面显示车位空余状态 2.随机点击一个车位后的预约按钮 3.预约成功页面,该车位状态发生改变,按钮禁用 4.当用户停车后,再次点击其他车位的停车按钮,会被系统拒绝 5.此页面为没有空余车位 ## 五.订单结算管理模块 ### 5.1.需求 1. 根据费用管理模块,管理员可以看到所有的车辆收费类型并可以进行修改。系统将给出相应的优惠政策,用户可以根据需求选择相应的优惠。 ### 5.2.数据库建表: ### 5.3.业务 2. 用户可以查看停车的订单记录 2. 进行结算业务 ### 5.4.页面 1.用户成功停车后,点击费用,可查看自己当前的订单(包括已经完成的订单) 2.点击按钮结算,会根据用户停车的时长,车位的单价进行计算(时长不满一小时,费用按一小时计算-起步价) 3.用户点击结算时,数据库会查询用户的账户余额,如果不够支付停车费,系统会提示 4.订单编号基于Mybatis-plus提供的ID生成器,这里使用了雪花算法,保证订单的唯一性 ## 六.统计报表管理模块(管理员权限) ### 6.1.需求 1. 根据统计报表管理模块,能够显示所有的缴费信息,并提供明细,方便管理员统计。 ### 6.2.业务 1. 根据订单表计算价格总和,便于统计 2.可选择时间区间,进行订单的筛选 3.底部有统计缴费金额,方便统计管理 4.同样使用Element UI的分页插件 5.增加导出功能,导出已结算的订单信息为Excel Excel文件: 导出功能使用alibaba开源框架easyexcel,定义文件保存路径为DeskTop。 ## Java部分业务代码 #### 登录业务代码 ~~~java @Override public Result login(LoginFrom loginFrom) { String phone = loginFrom.getPhone(); String password = loginFrom.getPassword(); //检验手机号是否合法 if (RegexUtils.isPhoneInvalid(phone)) { return Result.fail("手机号不合法"); } //根据手机号查询数据库 User user = userMapper.getByPhone(phone); //如果用户不存在,就自动创建 if (user == null) { //创建新用户 保存手机号和密码 User createUser = new User(); createUser.setPhone(phone); createUser.setPassword(password); createUser.setUsername(RandomString.make(6)); userService.save(createUser); user = createUser; } //如果用户存在 去数据库调取密码验证 else if (!user.getPassword().equals(password)) { return Result.fail("密码错误"); } //返回当前登录用户的id return Result.successData(user.getUserId()); } /** * 新用户自动创建车辆信息 * @param userId * @return */ @GetMapping("/createCar/{userId}") public Result createCar(@PathVariable Integer userId){ User user = userService.getById(userId); CarInfo info = carInfoMapper.getByLogin(userId); if (info != null){ return Result.fail(""); } //自动创建车辆信息 CarInfo carInfo = new CarInfo(); carInfo.setUserId(userId); carInfo.setPhone(user.getPhone()); carInfo.setCreateTime(LocalDateTime.now()); carInfo.setCarNum(""); carInfo.setCarType(""); carInfo.setAddress("不详"); carInfoService.save(carInfo); CarFrom carFrom = BeanUtil.copyProperties(carInfo, CarFrom.class); return Result.successData(carFrom); } ~~~ ### 缴费功能 ~~~java /** * 结算功能-结束停车计费 * @param garageId * @param userId * @return */ @Override public Result pay(Integer garageId, Integer userId) { //用户点击结算 按车位金额计算价格 //获取车位的信息(金额) Garage garage = garageService.getById(garageId); //车位的单价 BigDecimal price = garage.getPrice(); //TODO 计算停车的时长,按小时百分比计费 //获取当前时间-结束时间 DateTime now = DateTime.now(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String nowTime = dateFormat.format(now); //查询出当前进行中的订单 Order order = orderMapper.getById(userId); //将当前时间设置为订单结束时间(结算失败时间不影响) order.setEndTime(nowTime); //订单开始的时间 LocalDateTime startDateTime = LocalDateTime.parse(order.getBeginTime(),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); //订单结束的时间 LocalDateTime endDateTime = LocalDateTime.parse(order.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); //计算两个时间的差值 Duration duration = Duration.between(startDateTime, endDateTime); //计算毫秒数 BigDecimal decimal = new BigDecimal(duration.toMillis()); //计算小时 精确两位小数 BigDecimal hours = decimal.divide(BigDecimal.valueOf(3600000),2,BigDecimal.ROUND_UP); //TODO 如果停车时间低于一小时 BigDecimal start = new BigDecimal(1);//起步价 = 1小时车位费 PayDTO payDTO = new PayDTO(); if(hours.compareTo(start) == -1){ //缴费金额就是最低单价/h order.setAmount(price); User user = userService.getById(userId); //缴费金额 > 账户余额 返回1 if (price.compareTo(user.getBalance()) == 1) { return Result.fail("您账户余额不足,请联系管理员进行充值"); } //进行账户的扣款-缴费成功 BigDecimal newBalance = user.getBalance().subtract(price); user.setBalance(newBalance); //扣款成功后的更新操作 upUserAndOrder(user,order,garage); //返回停车的时长 + 缴费金额 payDTO.setHours(hours); payDTO.setAmount(price); }else { //TODO 超过1h(正常的结算价) // 计算停车费金额 单价 * 时长 BigDecimal money = price.multiply(hours).setScale(2); order.setAmount(money); //查询用户账户余额,小于价格提醒充值,结算失败 User user = userService.getById(userId); //缴费金额 > 账户余额 返回1 if (money.compareTo(user.getBalance()) == 1) { return Result.fail("您账户余额不足,请先充值"); } //进行账户的扣款-缴费成功 BigDecimal newBalance = user.getBalance().subtract(money); user.setBalance(newBalance); //扣款成功后的更新操作 upUserAndOrder(user,order,garage); //返回停车的时长 + 缴费金额 payDTO.setHours(hours); payDTO.setAmount(money); } //返回停车时长 + 缴费金额 return Result.successData(payDTO); } //扣款后更新的方法 public Result upUserAndOrder(User user,Order order,Garage garage){ userMapper.updateById(user);//更新用户 //订单状态修改为1(结束) order.setState(1); orderMapper.updateById(order);//更新订单 //车位状态修改为0(空闲状态) garage.setState(String.valueOf(0)); garageMapper.updateById(garage);//更新车位 return Result.success(); } } ~~~