计算机毕业设计选题推荐-智能停车计费系统-Java项目实战

本文探讨了一种智能停车计费系统,利用物联网技术改进传统系统,关注车位信息实时更新、停车行为监管、用户服务等功能。通过SpringBoot和MySQL构建,详细介绍了角色权限、代码设计以及系统优化点。
摘要由CSDN通过智能技术生成

作者主页:IT研究室✨
个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。
☑文末获取源码☑
精彩专栏推荐⬇⬇⬇
Java项目
Python项目
安卓项目
微信小程序项目

一、前言

随着经济的发展和城市化进程的加快,越来越多的家庭拥有车辆,而城市内的停车位也因此变得紧张。在这种情况下,智能停车计费系统应运而生。该系统利用物联网技术,对停车场的停车位进行实时监控,对车辆的进出进行自动化管理,以此提高停车效率,减少人力成本,同时为车主提供方便、快捷的停车服务。

然而,尽管智能停车计费系统在一定程度上解决了城市停车难的问题,但在实际应用中仍然存在一些问题。例如,现有的系统通常只关注车辆的进出管理,而忽视了车位信息的实时更新和停车行为的监管,这可能导致车主在寻找停车位时浪费时间和精力。另外,系统的自动化管理也可能导致一些违规行为无法及时发现和处理。因此,为了更好地解决这些问题,我们提出了一个更加完善的智能停车计费系统。

当前,很多停车场都采用了智能停车计费系统,但这些系统普遍存在一些问题。首先,它们无法实时更新车位信息,导致车主在寻找停车位时浪费时间和精力。其次,这些系统对车辆的进出管理虽然实现了自动化,但缺乏对停车行为的监管,容易滋生违规行为。此外,现有的系统通常只提供基础的论坛交流和公告功能,而缺乏对用户投诉建议的及时响应和处理,无法满足用户的需求。因此,我们需要一个更加完善、更加智能的停车计费系统来解决这些问题。

本课题的研究目的是开发一个更加完善的智能停车计费系统,该系统能够实时更新车位信息,对车辆的进出和停车行为进行全面监管,同时提供更加丰富、实用的服务功能,如论坛交流、公告、投诉建议处理等。通过实现这些功能,我们的研究旨在提高停车效率、减少人力成本、方便车主停车的同时,也能够提高停车场的管理效率和质量。

智能停车计费系统的研究对于解决城市停车难的问题具有重要意义。首先,该系统能够实时监控车位信息,帮助车主快速找到合适的停车位,节省时间和精力。其次,系统的自动化管理能够提高停车场的运行效率和管理质量,减少人力成本。此外,通过对停车行为的监管和对违规行为的及时处理,能够维护停车场的秩序和安全。最后,系统的投诉建议处理和论坛交流功能能够提高用户满意度和参与度,促进停车场与用户之间的互动和沟通。因此,智能停车计费系统的研究对于提高城市交通效率、改善城市环境、提升用户体验等方面都具有重要的意义。

二、开发环境

  • 开发语言:Java
  • 数据库:MySQL
  • 系统架构:B/S
  • 后端:SpringBoot
  • 前端:Vue

三、系统功能模块

  • 角色:用户、管理员
  • 功能:
    用户
    车位信息、论坛交流、公告、投诉建议、在线交流、车辆进场管理、车辆离场管理 、违规处罚管理;
    管理员
    用户管理、车位分类管理、车位信息管理、车辆进场管理、车辆离场管理 、违规处罚管理、投诉建议管理、论坛管理、在线交流、公告管理。

四、系统界面展示

  • 智能停车计费系统-界面展示:
    智能停车计费系统-车位信息
    智能停车计费系统-停车场详情
    智能停车计费系统-投诉建议
    智能停车计费系统-车辆进场管理
    智能停车计费系统-车辆离场管理
    智能停车计费系统-车位信息管理
    智能停车计费系统-车辆离场管理-管理员

五、部分代码设计

  • Java项目实战-代码参考:
 /**
     * 判断用户是否还有未完成订单
     * @return 用户未完成的预约订单VO 或 null
     */
    @GetMapping("getLastAppointmentOrder")
    @ApiOperation(value = "获取未完成订单",notes = "获取用户未完成的预约或续约订单")
    private Result getLastAppointmentOrder(){
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        Long uid = activeUser.getUid();
        //从redis获取用户最后一条预约订单或续约订单
        AppointmentOrder lastOrder = null;
        AppointmentOrder appointmentOrder = (AppointmentOrder) redisTemplate.opsForValue().get("last_appOrder_uid:" + uid);
        AppointmentOrder renewalOrder = (AppointmentOrder) redisTemplate.opsForValue().get("last_renOrder_uid:" + uid);
        //如果续约不是空 就用续约 是空 就用预约 如果预约不是空 就用预约 是空 就查数据库(应该不用查数据库)
        if (renewalOrder != null){
            lastOrder = renewalOrder;
        }else if (appointmentOrder != null){
            lastOrder = appointmentOrder;
        }
        //如果lastOrder为null 返回null
        if (lastOrder == null){
            return Result.ok("没有未完成订单",null);
        }
        //验证订单是否在预约时间内
        if (!DelayQueueUtil.isSave(lastOrder.getAoOrderNum())){
            return Result.ok("没有未完成订单",null);
        }
        //返回预约订单信息VO
        AppointmentOrderVO appointmentOrderVO = new AppointmentOrderVO();
        BeanUtils.copyProperties(lastOrder,appointmentOrderVO);
        return Result.ok("查询成功",appointmentOrderVO);
    }

    /**
     * 获取停车场信息VO
     * @param pid 停车场id
     * @return 停车场信息VO
     */
    @GetMapping("getParkLotInfo")
    @ApiOperation(value = "获取停车场信息",notes = "获取用户选择的停车场信息")
    private Result getParkLotInfo(Long pid) {
        ParkLotVO parkLotVO = new ParkLotVO();
        ParkLot parkLot = getParkingLotInfo(pid);
        if (parkLot == null){
            return Result.error("停车场信息错误");
        }
        //返回停车场信息VO
        BeanUtils.copyProperties(parkLot,parkLotVO);
        return Result.ok("查询成功", parkLotVO);
    }

    /**
     * 获取停车场信息
     * @param pid 停车场id
     * @return 停车场信息
     */
    private ParkLot getParkingLotInfo(Long pid) {
        ParkLot parkLot = appointmentService.selectParkLotInfoByPid(pid);
        //如果为null 返回null
        if (parkLot == null) {
            return null;
        }
        //更新redis中停车场空闲车位数量 此处为实时更新
        redisTemplate.opsForValue().set("free_parkSpace_pid:" + pid, parkLot.getMaxSpace() - parkLot.getNowSpace());
        return parkLot;
    }

    /**
     * 获取用户的默认车牌号
     * @return 默认车牌号
     */
    @GetMapping("getCarNumber")
    @ApiOperation(value = "获取默认车牌",notes = "获取用户默认车牌号,没有就需要输入")
    private Result getCarNumber(){
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        Long uid = activeUser.getUid();
        //从redis获取用户的默认车牌号
        Licenseplate licensePlate = (Licenseplate) redisTemplate.opsForValue().get("default_license_uid:" + uid);
        //如果为null 从数据库获取
        if (licensePlate == null){
            licensePlate = appointmentService.selectCarNumberByUid(uid);
        }
        //如果为null 返回null
        if (licensePlate == null){
            return Result.ok("没有绑定车牌",null);
        }
        //如果有数据 放进redis
        redisTemplate.opsForValue().set("default_license_uid:" + uid,licensePlate,5, TimeUnit.MINUTES);
        //返回默认车牌号
        return Result.ok("查询成功",licensePlate.getCarNum());
    }

    /**
     * 用户确认下订单(停车场预约)
     * @param appointmentDTO 预约信息DTO
     * @return 预约订单确认信息VO
     */
    @PostMapping("sureAppointmentOrder")
    @ApiOperation(value = "确认下预约订单",notes = "生成预约订单存入数据,返回订单信息")
    private Result sureAppointmentOrder(@RequestBody AppointmentDTO appointmentDTO){
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        AppointmentOrder appointmentOrder = null;
        //获取用户信誉分
        Integer creditPoint = appointmentService.selectCreditPointByUid(activeUser.getUid());
        //查询停车场信息 更新free_parkSpace
        ParkLot parkingLotInfo = getParkingLotInfo(appointmentDTO.getPid());
        //创建预约订单
        try {
            appointmentOrder = createAppointmentOrder(appointmentDTO,creditPoint);
        } catch (RuntimeException e){
            log.info("RuntimeException 错误信息{}",e.getMessage());
            return Result.error(e.getMessage());
        } catch (Exception e){
            //将保持信息放到日志中
            ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
            e.printStackTrace(new PrintStream(byteArrayOS));
            String exception = byteArrayOS.toString();
            log.info("Exception 错误信息{}",exception);
            return Result.error(e.getMessage()+"请通知管理员");
        }
        //预约订单放进数据库
        boolean isSuccess = appointmentService.insertAppointmentOrder(appointmentOrder);
        //插入成功 返回预约订单确认信息VO 插入失败 提示重新操作 其实可以程序内部再次插入
        if (!isSuccess){
            return Result.error("预约失败,请重新操作");
        }
        //预约成功放进redis 预约支付时间为5分钟
        redisTemplate.opsForValue().set("last_appOrder_uid:" + activeUser.getUid(), appointmentOrder, 5, TimeUnit.MINUTES);
        //放入队列中
        DelayQueueUtil.inputOrder(appointmentOrder.getAoOrderNum(),5);
        //返回预约订单确认信息VO
        AppointmentOrderVO appointmentOrderVO = new AppointmentOrderVO();
        BeanUtils.copyProperties(appointmentOrder,appointmentOrderVO);
        appointmentOrderVO.setCreditPoint(creditPoint);
        return Result.ok("预约订单生成成功",appointmentOrderVO);
    }

    /**
     * 生成停车场预约订单
     * @param appointmentDTO 预约信息DTO
     * @return 预约订单
     */
    private AppointmentOrder createAppointmentOrder(AppointmentDTO appointmentDTO, Integer creditPoint){
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        Integer appointmentDuration = appointmentDTO.getAppointmentDuration();
        //判断信誉分给出金额系数 如果信誉分过低就禁止预约 之后还需要提醒用户
        double coefficient_money = 0.3;
        if (creditPoint < 60){
            throw new RuntimeException("信誉分过低,禁止预约");
        }else if (creditPoint < 80){
            coefficient_money = 0.4;
        }
        //修改停车场现在占用数量 修改失败抛出异常 修改redis中的数据 redis中线程安全 需求每天定时往redis中更新数据
        updateFreeParkSpace(appointmentDTO.getPid(),-1);
        //获取停车场停车单价
        ParkLot parkLot = getParkingLotInfo(appointmentDTO.getPid());
        if (parkLot == null){
            throw new RuntimeException("停车场信息错误,请通知管理员");
        }
        BigDecimal parkPrice = parkLot.getParkPrice();
        //获取时长系数
        double coefficient_time = 1;
        if (appointmentDuration == 30){
            coefficient_time = 0.5;
        }
        //计算金额 时长*单价*系数
        BigDecimal money = parkPrice.multiply(BigDecimal.valueOf(coefficient_money)).multiply(BigDecimal.valueOf(coefficient_time));
        //计算时间
        Date startTime = new Date();
        Date endTime = new Date(startTime.getTime() + appointmentDuration * 60 * 1000);
        //创建要返回的订单
        String orderNum = SnowFlake.getOrderNum();
        AppointmentOrder appointmentOrder = new AppointmentOrder();
        appointmentOrder.setUid(activeUser.getUid());
        appointmentOrder.setPid(appointmentDTO.getPid());
        appointmentOrder.setCarNum(appointmentDTO.getCarNum());
        appointmentOrder.setAoOrderNum(orderNum);
        appointmentOrder.setMoney(money);
        appointmentOrder.setAppointmentTime(startTime);
        appointmentOrder.setAppointmentDuration(appointmentDuration);
        appointmentOrder.setEndTime(endTime);
        appointmentOrder.setState((byte) 0);//数据库有默认信息
        return appointmentOrder;
    }

    /**
     * 修改停车场剩余停车位
     * @param pid 停车场id
     * @param num 修改数量
     */
    private void updateFreeParkSpace(Long pid, Integer num){
        Integer freeParkingSpace = (Integer) redisTemplate.opsForValue().get("free_parkSpace_pid:" + pid);
        if (freeParkingSpace == null || freeParkingSpace < 0){
            throw new RuntimeException("停车场信息错误,请通知管理员");
        }
        //防止加数量的时候抛异常
        if (freeParkingSpace + num <= -1){
            throw new RuntimeException("车位暂无");
        }
        //停车场还有空位 操作空位数量
        redisTemplate.opsForValue().set("free_parkSpace_pid:" + pid,freeParkingSpace + num);
        //修改数据库 做到同步
        boolean isSuccess = appointmentService.updateNowSpaceByPid(pid, num);
        if (!isSuccess){
            throw new RuntimeException("同步数据错误");
        }
    }

    /**
     * 主动取消订单 支付成功后不支持取消
     * @param orderNum 订单号
     * @return 是否取消成功
     */
    @GetMapping("cancelAppointmentOrder")
    @ApiOperation(value = "取消订单",notes = "订单生成5分钟内未支付,可以主动取消订单,五分钟后自动取消")
    private Result cancelAppointmentOrder(String orderNum){
        if (timeoutHandler(orderNum)){
            if (DelayQueueUtil.outputOrder(orderNum)){
                return Result.ok("取消成功");
            }
        }
        return Result.error("取消失败");
    }

    /**
     * 超时处理
     * @param orderNum 订单号
     * @return 处理结果
     */
    public boolean timeoutHandler(String orderNum) {
        //获取要取消的订单信息
        AppointmentOrder appointmentOrder = appointmentService.selectAppointmentOrderByOrderNum(orderNum);
        if (appointmentOrder == null) {
            return false;
        }
        //从redis中去掉
        if (appointmentOrder.getRenewalDuration() != null){
            redisTemplate.delete("last_renOrder_uid:" + appointmentOrder.getUid());
        }else {
            redisTemplate.delete("last_appOrder_uid:" + appointmentOrder.getUid());
        }

        if (appointmentOrder.getState() == 0){
            //订单超时 自动取消 修改订单状态为2 预约订单才恢复停车场空闲车位数量
            try {
                if (appointmentOrder.getAppointmentDuration() != null){
                    updateFreeParkSpace(appointmentOrder.getPid(),1);
                }
            } catch (RuntimeException e){
                log.info("RuntimeException 错误信息{}",e.getMessage());
                return false;
            } catch (Exception e){
                //将保持信息放到日志中
                ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
                e.printStackTrace(new PrintStream(byteArrayOS));
                String exception = byteArrayOS.toString();
                log.info("Exception 错误信息{}",exception);
                return false;
            }
            return appointmentService.updateAppointmentOrder(appointmentOrder.getAoid(),(byte) 2);
        }else if (appointmentOrder.getState() == 1){
            //订单超时 扣除信誉分
            return appointmentService.updateCreditPointByUid(appointmentOrder.getUid(),-10);
        }
        return false;
    }

    /**
     * 支付成功后的变动
     * @param payStatusDTO 支付回调
     * @return
     */
    @PostMapping("callBack")
    @ApiOperation(value = "支付回调接口",notes = "回调支付状态,更新数据信息,返回更新结果")
    private Result callBack(@RequestBody PayStatusDTO payStatusDTO){
        if ("支付成功".equals(payStatusDTO.getState())){
            //获取订单信息
            AppointmentOrder appointmentOrder = appointmentService.selectAppointmentOrderByOrderNum(payStatusDTO.getOrderNum());
            if (appointmentOrder != null){
                boolean b = appointmentService.updateAppointmentOrder(appointmentOrder.getAoid(), (byte) 1);
                if (b){
                    //从队列中取出订单信息 重新存入
                    DelayQueueUtil.outputOrder(payStatusDTO.getOrderNum());
                    if (appointmentOrder.getRenewalDuration() != null){
                        DelayQueueUtil.inputOrder(payStatusDTO.getOrderNum(),appointmentOrder.getRenewalDuration());
                        appointmentOrder.setState((byte) 1);//因为改了数据库没有再查询 所以就直接给赋值了
                        redisTemplate.opsForValue().set("last_renOrder_uid:" + appointmentOrder.getUid(), appointmentOrder, appointmentOrder.getRenewalDuration(), TimeUnit.MINUTES);
                        //把预约订单的redis和队列都取出
                        AppointmentOrder o = (AppointmentOrder) redisTemplate.opsForValue().get("last_appOrder_uid:" + appointmentOrder.getUid());
                        if (o == null){
                            //throw new RuntimeException("应该不会有问题 要是抛这个异常 redis有问题");
                            return Result.error("redis服务器错误");
                        }
                        DelayQueueUtil.outputOrder(o.getAoOrderNum());
                        redisTemplate.delete("last_appOrder_uid:" + appointmentOrder.getUid());
                    }else {
                        DelayQueueUtil.inputOrder(payStatusDTO.getOrderNum(),appointmentOrder.getAppointmentDuration());
                        appointmentOrder.setState((byte) 1);//因为改了数据库没有再查询 所以就直接给赋值了
                        redisTemplate.opsForValue().set("last_appOrder_uid:" + appointmentOrder.getUid(), appointmentOrder, appointmentOrder.getAppointmentDuration(), TimeUnit.MINUTES);
                    }
                    return Result.ok("状态变更成功");
                }
            }
        }
        return Result.error("状态变更失败");
    }

    /**
     * 续约
     * @return 续约订单信息
     */
    @GetMapping("sureRenewalOrder")
    @ApiOperation(value = "确认下续约订单",notes = "生成续约订单存入数据,返回订单信息")
    private Result sureRenewalOrder(){
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        Long uid = activeUser.getUid();
        //从redis获取用户最后一条预约订单
        AppointmentOrder appointmentOrder = (AppointmentOrder) redisTemplate.opsForValue().get("last_appOrder_uid:" + uid);
        //如果为null 从数据库获取最后一条订单
        if (appointmentOrder == null){
            appointmentOrder = appointmentService.getLastAppointmentOrderByUid(activeUser.getUid());
        }
        //如果为null 返回null
        if (appointmentOrder == null || !DelayQueueUtil.isSave(appointmentOrder.getAoOrderNum())){
            return Result.error("没有预约信息");
        }
        //验证订单是否在预约时间内
        boolean save = DelayQueueUtil.isSave(appointmentOrder.getAoOrderNum());
        //判断能否续约
        if (!save || appointmentOrder.getRenewalDuration() != null || appointmentOrder.getState() != 1){
            return Result.error("不能重复续约");
        }
        //能续约 续30分钟
        AppointmentOrder renewalOrder = createRenewalOrder(appointmentOrder);
        //预约订单放进数据库
        boolean isSuccess = appointmentService.insertAppointmentOrder(renewalOrder);
        //插入成功 返回预约订单确认信息VO 插入失败 提示重新操作 其实可以程序内部再次插入
        if (!isSuccess){
            return Result.error("续约失败");
        }
        //redis存入续约单
        redisTemplate.opsForValue().set("last_renOrder_uid:" + renewalOrder.getUid(), renewalOrder, 5, TimeUnit.MINUTES);
        //放入队列中
        DelayQueueUtil.inputOrder(renewalOrder.getAoOrderNum(),5);
        //返回预约订单确认信息VO
        AppointmentOrderVO appointmentOrderVO = new AppointmentOrderVO();
        BeanUtils.copyProperties(renewalOrder,appointmentOrderVO);
        return Result.ok("续约订单生成成功",appointmentOrderVO);
    }

    /**
     * 生成续约订单
     * @param appointmentOrder 预约订单
     * @return 续约订单
     */
    private AppointmentOrder createRenewalOrder(AppointmentOrder appointmentOrder){
        //计算时间
        Date startTime = new Date();
        Date endTime = new Date(startTime.getTime() + 30 * 60 * 1000);
        //计算价格
        BigDecimal money = appointmentOrder.getMoney();
        if (appointmentOrder.getAppointmentDuration() == 60){
            money = appointmentOrder.getMoney().divide(BigDecimal.valueOf(2),2, RoundingMode.UNNECESSARY);
        }
        //创建要返回的订单
        String orderNum = SnowFlake.getOrderNum();
        AppointmentOrder renewalOrder = new AppointmentOrder();
        renewalOrder.setUid(appointmentOrder.getUid());
        renewalOrder.setPid(appointmentOrder.getPid());
        renewalOrder.setCarNum(appointmentOrder.getCarNum());
        renewalOrder.setAoOrderNum(orderNum);
        renewalOrder.setMoney(money);
        renewalOrder.setRenewalTime(startTime);
        renewalOrder.setRenewalDuration(30);
        renewalOrder.setEndTime(endTime);
        renewalOrder.setState((byte) 0);//数据库有默认信息
        return renewalOrder;
    }

    /*//测试专用方法
    @GetMapping("selectQueue")
    private void selectQueue(){
        System.out.println(DelayQueueUtil.selectQueue());
    }
    @GetMapping("test")
    private void test() throws InterruptedException {
        DelayQueueUtil.inputOrder("123",2);
        Thread.sleep(2000);
        boolean b = DelayQueueUtil.outputOrder("123");
        System.out.println(b);
    }

六、论文参考

  • 计算机毕业设计选题推荐-智能停车计费系统-论文参考:
    计算机毕业设计选题推荐-智能停车计费系统-论文参考

七、系统视频

智能停车计费系统-项目视频:

基于SpringBoot的智能停车计费系统

结语

计算机毕业设计选题推荐-智能停车计费系统-Java项目实战
大家可以帮忙点赞、收藏、关注、评论啦~
源码获取:私信我

精彩专栏推荐⬇⬇⬇
Java项目
Python项目
安卓项目
微信小程序项目

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT研究室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值