SpringBoot+微信小程序在线订餐小程序系统 附带详细运行指导视频

文章目录

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

一、项目演示

项目演示地址: 视频地址

二、项目介绍

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

项目功能:此项目分为两个角色:普通用户管理员普通用户有登录注册、浏览商品信息、添加购物车、结算订单、查看个人信息、查看个人订单详情、管理个人地址信息、发布评价信息等等功能。管理员有管理所有商品信息、管理所有订单信息、管理所有用户信息、管理所有评价信息等等功能。

应用技术:SpringBoot + 微信小程序 + MySQL + MyBatis + Redis + ElementUI + Lua + 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<OrderDTO> submitOrder(OrderDTO orderDTO) {
        UserDTO userDTO = new UserDTO();
        userDTO.setToken(orderDTO.getToken());
        ResponseDTO<UserDTO> loginUserResponse = userService.getLoginUser(userDTO);
        if(!CodeMsg.SUCCESS.getCode().equals(loginUserResponse.getCode())) {
            return ResponseDTO.errorByMsg(CodeMsg.USER_SESSION_EXPIRED);
        }
        // 获取登录用户信息
        userDTO = loginUserResponse.getData();
        AddressExample addressExample = new AddressExample();
        addressExample.createCriteria().andUserIdEqualTo(userDTO.getId());
        if(addressMapper.selectByExample(addressExample).size() == 0) {
            return ResponseDTO.errorByMsg(CodeMsg.ADDRESS_NOT_EXIST);
        }

        String[] cartIdList = orderDTO.getCartIdList().split(",");
        CartExample cartExample = new CartExample();
        cartExample.createCriteria().andIdIn(Arrays.stream(cartIdList).collect(Collectors.toList()));
        List<Cart> cartList = cartMapper.selectByExample(cartExample);
        List<String> productIdList = cartList.stream().map(Cart::getProductId).collect(Collectors.toList());
        ProductExample productExample = new ProductExample();
        productExample.createCriteria().andIdIn(productIdList);
        List<Product> productList = productMapper.selectByExample(productExample);
        List<String> productNameList = productList.stream().map(Product::getName).collect(Collectors.toList());
        List<String> productPriceList = productList.stream().map(Product::getPrice).map(String::valueOf).collect(Collectors.toList());
        List<String> productPhotoList = productList.stream().map(Product::getPhoto).map(String::valueOf).collect(Collectors.toList());
        List<String> cartQuantityList = cartList.stream().map(Cart::getQuantity).map(String::valueOf).collect(Collectors.toList());
        String orderId = UuidUtil.getShortUuid();
        String orderDate = CommonUtil.getFormatterDate(new Date(), "yyyy-MM-dd HH:mm:ss");
        // 执行lua脚本
        String result = stringRedisTemplate.execute(
                SECKILL_SCRIPT,
                Collections.singletonList(RedisConstant.STOCK_REDIS_KEY_TEMPLATE),
                StringUtils.join(productIdList, ","),
                StringUtils.join(productNameList, ","),
                StringUtils.join(cartQuantityList, ","),
                orderId,
                userDTO.getId(),
                orderDate,
                StringUtils.join(productPriceList, ","),
                StringUtils.join(productPhotoList, ","),
                StringUtils.join(Arrays.asList(cartIdList), ",")
        );
        if(!"成功".equals(result)) {
            CodeMsg codeMsg = CodeMsg.PRODUCT_STOCK_OVER;
            codeMsg.setMsg(result);
            return ResponseDTO.errorByMsg(codeMsg);
        }
        orderDTO.setId(orderId);
        return ResponseDTO.success(orderDTO);
    }

2.购物车保存操作(添加、减少)代码

 	/**
     * 购物车保存操作(添加、减少)
     * @param cartDTO
     * @return
     */
    @Override
    public ResponseDTO<Boolean> saveCart(CartDTO cartDTO) {
        UserDTO userDTO = new UserDTO();
        userDTO.setToken(cartDTO.getToken());
        ResponseDTO<UserDTO> loginUserResponse = userService.getLoginUser(userDTO);
        if(!CodeMsg.SUCCESS.getCode().equals(loginUserResponse.getCode())) {
            return ResponseDTO.errorByMsg(CodeMsg.USER_SESSION_EXPIRED);
        }
        // 获取登录用户信息
        userDTO = loginUserResponse.getData();
        cartDTO.setUserId(userDTO.getId());

        Product product = productMapper.selectByPrimaryKey(cartDTO.getProductId());
        if (product == null) {
            return ResponseDTO.errorByMsg(CodeMsg.PRODUCT_NOT_EXIST);
        }
        Cart cart = CopyUtil.copy(cartDTO, Cart.class);
        // 判断购物车是否已经有此商品
        CartExample cartExample = new CartExample();
        cartExample.createCriteria().andProductIdEqualTo(cartDTO.getProductId()).andUserIdEqualTo(cartDTO.getUserId());
        List<Cart> cartList = cartMapper.selectByExample(cartExample);
        if(cartList.size() > 0) {
            // 购物车中已经有此商品
            if(CartOperateEnum.ADD.getCode().equals(cartDTO.getOperateType())) {
                // 添加操作
                if(cart.getQuantity() + cartList.get(0).getQuantity() > product.getStock()) {
                    return ResponseDTO.errorByMsg(CodeMsg.PRODUCT_STOCK_OVER);
                }
                cartList.get(0).setQuantity(cart.getQuantity() + cartList.get(0).getQuantity());
            } else if (CartOperateEnum.SUB.getCode().equals(cartDTO.getOperateType())) {
                // 减少操作
                if(cartList.get(0).getQuantity() <= cart.getQuantity()) {
                    // 删除
                    CartDTO copy = CopyUtil.copy(cartList.get(0), CartDTO.class);
                    copy.setToken(cartDTO.getToken());
                    removeCart(copy);
                    return ResponseDTO.successByMsg(true, "购物车操作成功!");
                } else {
                    cartList.get(0).setQuantity(cartList.get(0).getQuantity() - cart.getQuantity());
                }
            }
            // 更新数据
            if(cartMapper.updateByPrimaryKeySelective(cartList.get(0)) == 0) {
                return ResponseDTO.errorByMsg(CodeMsg.CART_SAVE_ERROR);
            }

        } else {
            // 购物车中没有此商品
            if(product.getStock() == 0) {
                return ResponseDTO.errorByMsg(CodeMsg.PRODUCT_STOCK_OVER);
            }
            cart.setId(UuidUtil.getShortUuid());
            // 添加数据
            if(cartMapper.insertSelective(cart) == 0) {
                return ResponseDTO.errorByMsg(CodeMsg.CART_SAVE_ERROR);
            }
        }
        return ResponseDTO.successByMsg(true, "购物车操作成功!");
    }

3.小程序登录操作代码

	/**
     * 小程序用户登录操作
     * @param userDTO
     * @return
     */
    @Override
    public ResponseDTO<UserDTO> appLogin(UserDTO userDTO) {
        // 进行是否为空判断
        if(CommonUtil.isEmpty(userDTO.getUsername())){
            return ResponseDTO.errorByMsg(CodeMsg.USERNAME_EMPTY);
        }
        if(CommonUtil.isEmpty(userDTO.getPassword())){
            return ResponseDTO.errorByMsg(CodeMsg.PASSWORD_EMPTY);
        }
        // 对比昵称和密码是否正确
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUsernameEqualTo(userDTO.getUsername()).andPasswordEqualTo(userDTO.getPassword());
        List<User> userList = userMapper.selectByExample(userExample);
        if(userList == null || userList.size() != 1){
            return ResponseDTO.errorByMsg(CodeMsg.USERNAME_PASSWORD_ERROR);
        }
        // 生成登录token并存入Redis中
        User selectedUser = userList.get(0);
        UserDTO selectedUserDTO = CopyUtil.copy(selectedUser, UserDTO.class);
        String token = UuidUtil.getShortUuid();
        selectedUserDTO.setToken(token);
        //把token存入redis中 有效期1小时
        stringRedisTemplate.opsForValue().set("USER_" + token, JSON.toJSONString(selectedUser), 3600, TimeUnit.SECONDS);
        return ResponseDTO.successByMsg(selectedUserDTO, "登录成功!");
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3D 目标检测 SFD 问题记录

问题1&#xff1a;read timeout 顺着网址手动下载&#xff0c;然后放入相应的目录下 问题2&#xff1a;SparseModule import spconv 要改写成 import spconv.pytorch as spconv 问题3&#xff1a;skimage pip install scikit-image -i https://pypi.tuna.tsinghua.edu.cn/si…

C国演义 [第十章]

第十章 最佳买卖股票时机含冷冻期题目理解步骤dp数组递推公式初始化遍历方向 代码 买卖股票的最佳时机含手续费题目理解步骤dp数组递推公式初始化遍历方向 代码 最佳买卖股票时机含冷冻期 力扣链接 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格…

python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示

文章目录 ⭐前言⭐selenuim获取新星赛道选手主页&#x1f496; 获取参赛选手主页思路分析&#x1f496; 获取参赛选手ip属地思路分析&#x1f496; echarts可视化展示 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享python_selenuim获取csdn新星赛道选手所在…

js的this绑定规则以及箭头函数

目录 调用位置默认绑定隐式绑定隐式丢失 显式绑定callapplybind new绑定装箱绑定优先级this规则之外忽略显式绑定间接函数引用 箭头函数 调用位置 从字面意思上来理解&#xff0c;this似乎是指向自己的 然而在JavaScript中&#xff0c;this并不是绑定到自身的 可以看这一个例子…

PyTorch翻译官网教程6-AUTOMATIC DIFFERENTIATION WITH TORCH.AUTOGRAD

官网链接 Automatic Differentiation with torch.autograd — PyTorch Tutorials 2.0.1cu117 documentation 使用TORCH.AUTOGRAD 自动微分 当训练神经网络时&#xff0c;最常用的算法是方向传播算法。在该算法中&#xff0c;根据损失函数与给定参数的梯度来调整模型参数&…

Python程序设计基础:列表与元组(二)

文章目录 一、数值列表的生成1、通过input()函数输入创建列表2、通过list()函数转换3、列表生成式4、数值列表的几种统计计算 二、元组1、元组的定义2、元组的操作3、元组作为列表元素 三、转换函数1、元组和列表之间的转换2、字符串和列表之间的转换3、split()方法 一、数值列…

2024考研408-操作系统 第二章-进程与线程 学习笔记

文章目录 前言一、进程1.1、进程的概念、组成与特征1.1.1、进程的概念1.1.2、进程的组成认识PCB认识程序段与数据段&#xff08;包含进程实体概念&#xff09; 1.1.3、进程的特征知识回顾与重要考点 1.2、进程的状态、状态间的转换和组织方式1.2.1、进程的状态进程的五种状态详…

RandLA-Net 复现

GPU3090 CUDA12 1、代码 [github地址] git clone --depth1 https://github.com/QingyongHu/RandLA-Net && cd RandLA-Net 2、虚拟环境中配置&#xff1a; 在跑代码的时候出现错误&#xff1a;open3d.so文件中函数报错。查看open3d版本发现不是要求的0.3版本&#xff…

设计模式 ~ 工厂模式

工厂模式 工厂模式是一种设计模式&#xff0c;指在通过使用工厂函数或构造函数来创建对象&#xff1b; 它提供了一种灵活的方式来创建对象实例&#xff0c;而无需直接调用构造函数或使用new关键字&#xff1b; 可以分类&#xff0c;解耦&#xff1b; 可以扩展多个类&#xff0…

【Spring——Spring的基础与创建】

目录 &#x1f367;1. 什么是 Spring &#xff1f; &#x1fad6;1.1 容器 &#x1f359;1.2 IoC &#x1f97d;1.3 汽车类——传统写法 &#x1f358;1.4 汽车类——IoC 写法 &#x1f32d;2. 配置 maven 国内源 &#x1f32e;2.1 在设置中勾选文件 &#x1f364;2.2 在…

【网站建设】HTTP/HTTPS 是什么?有什么区别?

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前学习C/C、算法、Java等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&#xff0c;感…

自定义程序包不存在的解决方法

方案一&#xff1a; 在pom文件中加入以下代码 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.4.2</version><configuration><skipTests>true</sk…

openResty的Redis模块踩坑记录

OpenResty提供了操作Redis的模块&#xff0c;我们只要引入该模块就能直接使用。说是这样说&#xff0c;但是实践起来好像并不太顺利。 1.设置了密码的redis&#xff0c;lua业务逻辑中需要添加身份认证代码 网上很多资料、文章似乎都是没有设置redis密码&#xff0c;说来也奇怪…

fileinclude

前提知识&#xff1a; filter伪协议 include函数用php://filter伪协议来绕过 题目&#xff1a; 打开题目 页面显示如图&#xff0c;可以知道flag在flag.php中&#xff0c;还知道当前页面的绝对路径 先查看源代码 15行$lan用$_cookie传参&#xff0c;可以修改cookie值从而控制…

探索非洲专线物流的新时代_国际物流供应链管理平台_箱讯科技

随着全球化的发展&#xff0c;非洲作为一个充满机遇和挑战的大陆&#xff0c;吸引着越来越多的企业和投资者。然而&#xff0c;由于非洲的地理复杂性和基础设施不完善&#xff0c;物流问题一直是制约非洲发展的瓶颈之一。为了解决这一问题&#xff0c;非洲专线物流应运而生。本…

网络原理之传输层与网络层重点协议

目录 传输层重点协议 TCP协议 TCP协议段格式 TCP原理 确认应答机制&#xff08;安全机制&#xff09; 超时重传机制&#xff08;安全机制&#xff09; 连接管理机制&#xff08;安全机制&#xff09; 滑动窗口&#xff08;效率机制&#xff09; 流量控制&#xff08;安…

数字IC笔试面试常考问题及答案汇总(内含各岗位大厂题目)

经历了无数的笔试面试之后&#xff0c;不知道大家有没有发现数字IC的笔试面试还是有很多共通之处和规律可循的。所以一定要掌握笔试面试常考的问题。 数字IC笔试面试常考问题及答案汇总&#xff08;文末可领全部哦~&#xff09; 验证方向&#xff08;部分题目&#xff09; Q1…

数据可视化分析,2023结婚全品类消费趋势洞察报告

结婚消费与人们的关系密切相关。结婚是一个重要的人生事件&#xff0c;往往伴随着大量的消费。人们倾向于在婚礼仪式、婚纱摄影、宴会等方面进行豪华的投资&#xff0c;以展示社会地位和个人品味。此外&#xff0c;结婚还涉及到婚戒、婚庆、蜜月旅行等费用。然而&#xff0c;随…

Jenkins+Robot 接口自动化测试

目录 前言&#xff1a; 设计目标 项目说明 目录结构 配置 jenkins 1.安装插件 2.配置项目 前言&#xff1a; JenkinsRobot是一种常见的接口自动化测试方案&#xff0c;可以实现自动化的接口测试和持续集成。Jenkins是一个流行的持续集成工具&#xff0c;而Robot Framew…

【5G PHY】5G 调制与编码策略(MCS)介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…