SpringBoot+微信小程序实现的酒店预订小程序系统 附带详细运行指导视频

news2024/11/16 19:26:23

文章目录

  • 一、项目介绍
  • 二、项目介绍
  • 三、运行截图
  • 四、主要代码

一、项目介绍

项目演示地址:视频地址

二、项目介绍

项目描述:这是一个基于SpringBoot+微信小程序框架开发的酒店预订小程序系统。首先,这是一个前后端分离的项目,代码简洁规范,注释说明详细,易于理解和学习。其次,这项目功能丰富,具有一个酒店预订小程序系统该有的所有功能。

项目功能:此项目分为两个角色:普通用户管理员普通用户有微信授权登录、浏览房间信息、提交房间预订订单、浏览酒店图集和配套设施信息、浏览公告信息、管理个人基本信息、查看个人订单信息、管理个人评价信息、发布评价信息等等功能。管理员有管理所有房间信息、管理所有订单信息、管理所有用户信息、管理所有评价信息、管理所有公告信息、管理所有图集信息、浏览收益图表数据等等功能。

应用技术:SpringBoot + 微信小程序 + MySQL + MyBatis + Redis + ElementUI + Vue + Vant Weapp

运行环境:IntelliJ IDEA2019.3.5 + 微信开发者工具(项目压缩包中自带)+ MySQL5.7(项目压缩包中自带) + Redis5.0.5(项目压缩包中自带) + JDK1.8 + Maven3.6.3(项目压缩包中自带)+ Node14.16.1(项目压缩包中自带)

三、运行截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、主要代码

1.提交预订房间订单代码:

/**
 * 提交订单操作
 * @param orderDTO
 * @return
 */
@Override
public ResponseDTO<Boolean> submitOrder(OrderDTO orderDTO) {
    ResponseDTO<UserDTO> loginUserResponse = userService.getLoginUser(orderDTO.getToken());
    if(!CodeMsg.SUCCESS.getCode().equals(loginUserResponse.getCode())) {
        return ResponseDTO.errorByMsg(CodeMsg.USER_SESSION_EXPIRED);
    }
    UserDTO loginUserDTO = loginUserResponse.getData();
    // 进行统一表单验证
    CodeMsg validate = ValidateEntityUtil.validate(orderDTO);
    if(!validate.getCode().equals(CodeMsg.SUCCESS.getCode())){
        return ResponseDTO.errorByMsg(validate);
    }
    Room room = roomMapper.selectByPrimaryKey(orderDTO.getRoomId());
    if(room == null) {
        return ResponseDTO.errorByMsg(CodeMsg.ROOM_NOT_EXIST);
    }
    Order order = CopyUtil.copy(orderDTO, Order.class);
    if(order.getNum() > room.getNum()) {
        return ResponseDTO.errorByMsg(CodeMsg.ROOM_NOT_ENOUGH);
    }
    RoomExample roomExample = new RoomExample();
    // 乐观锁控制更新房间余量  防止超卖
    roomExample.createCriteria().andIdEqualTo(room.getId()).andVersionEqualTo(room.getVersion());
    // 版本号 + 1
    room.setVersion(room.getVersion() + 1);
    room.setNum(room.getNum() - order.getNum());
    if(roomMapper.updateByExampleSelective(room, roomExample) == 0) {
        return ResponseDTO.errorByMsg(CodeMsg.ORDER_BUSY);
    }
    order.setId(UuidUtil.getShortUuid());
    order.setCreateTime(new Date());
    order.setRoomType(room.getType());
    order.setRoomPhoto(room.getPhoto());
    order.setUserId(loginUserDTO.getId());
    order.setRoomPrice(room.getPrice());
    order.setTotalPrice(room.getPrice().multiply(new BigDecimal(order.getNum())));
    // 入队操作,队列已满则阻塞等待
    try {
        blockingQueue.put(order);
    } catch (InterruptedException e) {
        e.printStackTrace();
        return ResponseDTO.errorByMsg(CodeMsg.ORDER_BUSY);
    }
    return ResponseDTO.successByMsg(true, "预订成功!");
}

2.小程序微信授权登录代码:

	/**
     * 小程序授权登录验证
     * @param userDTO
     * @return
     */
    @Override
    public ResponseDTO<UserDTO> appWxLogin(UserDTO userDTO) {
        String url = LOGIN_URL + "?appid=" + APP_ID + "&secret="+ APP_SECRET + "&grant_type=authorization_code&js_code=" + userDTO.getCode();
        HttpClient client = HttpClients.createDefault(); // 创建默认http连接
        HttpGet getRequest = new HttpGet(url);// 创建一个post请求
        LoginDTO loginDTO = new LoginDTO();
        try {
            // 用http连接去执行get请求并且获得http响应
            HttpResponse response = client.execute(getRequest);
            // 从response中取到响实体
            HttpEntity entity = response.getEntity();
            // 把响应实体转成文本
            String html = EntityUtils.toString(entity);
            loginDTO = JSON.parseObject(html, LoginDTO.class);
            if(null == loginDTO.getErrcode()) {
                userDTO.setWxId(loginDTO.getOpenid());
            } else {
                return ResponseDTO.errorByMsg(CodeMsg.USER_WX_LOGIN_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDTO.errorByMsg(CodeMsg.USER_WX_LOGIN_ERROR);
        }
        // 使用微信openId查询是否有此用户
        UserExample userExample = new UserExample();
        userExample.createCriteria().andWxIdEqualTo(userDTO.getWxId());
        List<User> userList = userMapper.selectByExample(userExample);
        if(null != userList && userList.size() > 0) {
            // 已经存在用户信息,读取数据库中用户信息
            User user = userList.get(0);
            userDTO = CopyUtil.copy(user, UserDTO.class);
        } else {
            // 数据库中不存在,注册用户信息
            User user = CopyUtil.copy(userDTO, User.class);
            user.setId(UuidUtil.getShortUuid());
            user.setUsername(user.getWxUsername());
            user.setHeadPic(user.getWxHeadPic());
            user.setRoleId(RoleEnum.USER.getCode());
            if(userMapper.insertSelective(user) == 0) {
                return ResponseDTO.errorByMsg(CodeMsg.USER_REGISTER_ERROR);
            }
            userDTO = CopyUtil.copy(user, UserDTO.class);
        }
        userDTO.setToken(UuidUtil.getShortUuid());
        stringRedisTemplate.opsForValue().set("USER_" + userDTO.getToken(), JSON.toJSONString(userMapper.selectByPrimaryKey(userDTO.getId())), 3600, TimeUnit.SECONDS);
        return ResponseDTO.successByMsg(userDTO, "登录成功!");
    }

3.提交评价信息代码:

	 /**
     * 提交评价信息
     * @param commentDTO
     * @return
     */
    @Override
    public ResponseDTO<Boolean> submitComment(CommentDTO commentDTO) {
        ResponseDTO<UserDTO> loginUserResponse = userService.getLoginUser(commentDTO.getToken());
        if(!CodeMsg.SUCCESS.getCode().equals(loginUserResponse.getCode())) {
            return ResponseDTO.errorByMsg(CodeMsg.USER_SESSION_EXPIRED);
        }
        UserDTO loginUserDTO = loginUserResponse.getData();
        // 进行统一表单验证
        CodeMsg validate = ValidateEntityUtil.validate(commentDTO);
        if(!validate.getCode().equals(CodeMsg.SUCCESS.getCode())){
            return ResponseDTO.errorByMsg(validate);
        }
        Comment comment = CopyUtil.copy(commentDTO, Comment.class);
        comment.setId(UuidUtil.getShortUuid());
        comment.setCreateTime(new Date());
        comment.setUserId(loginUserDTO.getId());
        if(commentMapper.insertSelective(comment) == 0) {
            return ResponseDTO.errorByMsg(CodeMsg.COMMENT_ADD_ERROR);
        }
        return ResponseDTO.successByMsg(true, "评价成功!");
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1118991.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录:Unity脚本的编写4.0

目录 前言导入音乐编写脚本 前言 之前使用脚本对uniry中的模型进行了控制&#xff0c;诸如使用键盘控制对象模型的移动或者使用鼠标对对象模型进行角度的切换&#xff08;或者是类似的东西&#xff09;&#xff0c;而我们在游戏的过程中&#xff0c;总是伴随着一些好听的bgm&a…

打造自己的前端组件库(奶妈版,超详细)

打造自己的前端组件库 demo是开源的&#xff0c;自己上npm 或者 github 上都能搜到 新建vue项目(sass js vue2) vue create yt-ui 修改文件目录(如下) 修改&#xff1a; 1.src 更名 examples; 2. src/components移动到项目最外层&#xff1b;3.vue.config.js更改入口文件 /…

论文阅读[51]通过深度学习快速识别荧光组分

【论文基本信息】 标题&#xff1a;Fast identification of fluorescent components in three-dimensional excitation-emission matrix fluorescence spectra via deep learning 标题译名&#xff1a;通过深度学习快速识别 三维激发-发射矩阵荧光光谱中的荧光组分 期刊与年份&…

安装IDEA

文章目录 前言一、下载二、安装1.选择目录2.安装配置3.安装完成 三、安装插件1.安装插件2.注册账号3.关闭共享4.使用插件 总结 前言 亚马逊推出了编码助手CodeWhisperer&#xff0c;以插件的形式配合IDE使用&#xff0c;推荐个人练习使用&#xff0c;敏感项目不建议&#xff1…

栈和队列的C++模拟实现

一、栈stack 1.介绍&#xff08;库里面的文档介绍&#xff09; 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack是作为容器适配器被实现的&#xff0c;容器适配器即是对…

YOLOv5算法改进(16)— 增加小目标检测层 | 四头检测机制(包括代码+添加步骤+网络结构图)

前言:Hello大家好,我是小哥谈。小目标检测层是指在目标检测任务中用于检测小尺寸目标的特定网络层。由于小目标具有较小的尺寸和低分辨率,它们往往更加难以检测和定位。YOLOv5算法的检测速度与精度较为平衡,但是对于小目标的检测效果不佳,根据一些论文,我们可以通过增加检…

ThreeJS光照类型详解及示例演示

ThreeJS中的光照计算是基于物理学的光照模型&#xff0c;通过模拟光线与物体表面的交互作用&#xff0c;计算出物体表面在各个方向上的明暗程度&#xff0c;从而实现逼真的视觉效果。具体来说&#xff0c;ThreeJS采用了基于Lambertian反射模型和Phong着色模型的光照计算方式&am…

Qt设置horizontal line 和vertical line的颜色

在Qt中&#xff0c;要设置水平线&#xff08;QFrame&#xff09;和垂直线&#xff08;QSplitter&#xff09;的颜色&#xff0c;可以使用样式表&#xff08;stylesheet&#xff09;或者直接设置QPalette。 下面是两种设置的示例&#xff1a; 使用样式表&#xff08;stylesheet…

Day6力扣打卡

打卡记录 统计无向图中无法互相到达点对数&#xff08;并查集 / DFS&#xff09; 链接 并查集 思路&#xff1a;用并查集将连通区域的连在一起&#xff0c;再遍历所有点&#xff0c;用hash表存储不同连通块的元素个数&#xff0c;然后 乘积和 便是答案。 注意&#xff1a; /…

QT中窗口自绘制效果展示

项目中需要使用QT进行窗口自绘&#xff0c;前期先做一下技术探索&#xff0c;参考相关资料代码熟悉流程。本着代码是最好的老师原则&#xff0c;在此记录一下。 目录 1.运行效果 2.代码结构 3.具体代码 1.运行效果 2.代码结构 3.具体代码 myspeed.pro QT core gui…

经典算法试题(二)

文章目录 一、岁数1、题目2、思路讲解3、代码实现4、结果 二、打碎的鸡蛋1、题目2、思路讲解3、代码实现4、结果 三、分糖1、题目2、思路讲解3、代码实现4、结果 四、兔子产子1、题目2、思路讲解3、代码实现4、结果 五、矩阵问题1、题目2、思路讲解3、代码实现4、结果 六、谁是…

一例jse蠕虫的分析

概述 这是一例jse格式的蠕虫病毒&#xff0c;会隐藏系统中所有的doc、docx和rtf文件&#xff0c;创建同名的.jse文件&#xff0c;诱导用户点击执行&#xff0c;通过感染U盘和网络驱动器、光盘刻录临时文件夹、html文件进行传播。 这个样本是使用JScript语言编写的加密脚本文件…

全网最丑焊锡教程(仅排针焊接心得)

一直以来玩各种开发板&#xff0c;焊接水平太差始终是阻碍我买性价比高的板子的最大原因。淘宝上好多芯片搭载上肥猪流板子是不包排针焊接的。终于下定决心要克服这个困难。不过&#xff0c;只是会焊接排针在高手面前最好不要说自己会焊锡&#xff0c;这应该是两码事。 首先上…

智慧矿山矿山安全生产:皮带撕裂识别AI算法不用激光,能迅速识别皮带纵撕!

近些年来&#xff0c;智慧矿山在煤矿行业中发挥着越来越重要的作用。皮带的功能对于矿山运营至关重要&#xff0c;而皮带撕裂是造成生产中断、人身伤害等问题的重要原因之一。为了准确、及时地检测皮带撕裂的情况&#xff0c;AI算法的应用成为智慧矿山的关键。 ​​​​​​​…

Leetcode—2530.执行K次操作后的最大分数【中等】(C语言向上取整数学公式)

2023每日刷题&#xff08;五&#xff09; Leetcode—2530.执行K次操作后的最大分数 向上取整思想 参考了这篇文章 有人肯定会问&#xff0c;这个向上取整为什么是这样来的。接下来我简单讲解一下。 数学式&#xff1a; x y 数学式&#xff1a;\frac{x}{y} 数学式&#xff1a…

【Java 进阶篇】深入了解 Bootstrap 组件

Bootstrap 是一个流行的前端框架&#xff0c;提供了丰富的组件&#xff0c;用于创建各种网页元素和交互效果。这些组件可以帮助开发者轻松构建漂亮、响应式的网页&#xff0c;而无需深入的前端开发知识。在本文中&#xff0c;我们将深入探讨 Bootstrap 中一些常用的组件&#x…

【Django 04】Serialization 序列化的高级使用

序列化器 serializers 序列化器的作用 序列化将 queryset 和 instance 转换为 json/xml/yaml 返回给前端 反序列化与序列化则相反 定义序列化器 定义类&#xff0c;继承自 Serializer 通常新建一个 serializers.py 文件 撰写序列化内容 suah as 目前只支持 read_only 只…

软件报错msvcr120.dll丢失怎么办?五个有效修复方法分享

msvcr120.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C 2012 Redistributable Package的一部分。如果你的电脑在运行一些需要这个文件的程序时出现了“msvcr120.dll丢失”的错误&#xff0c;那么就意味着你的电脑缺少了这个文件&#xff0c;或者这个文件已经损坏…

使用 类加载器 或者 类对象 读取文件

相对路径&#xff1a;项目 的 根目录 开始查找。&#xff08; 但是在我们真正开发的时候&#xff0c;我们读到的更多的文件并不是直接放在我们项目里面这个文件夹里面&#xff0c;而是放在我们模块里面 &#xff09;同理可得&#xff0c;我们直接创建 文件 b.txt 会在项目的根目…

Python---死循环概念---while True

在编程中一个靠自身控制无法终止的程序称为“死循环”。 在Python中&#xff0c;我们也可以使用while True来模拟死循环&#xff1a; 代码&#xff1a; while True: print(每天进步一点点) 图示 应用&#xff1a; 比如&#xff0c;在测试里面&#xff0c;自动化测试用例…