跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Java大前端java

Java Web 厨艺交流平台系统:SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0 设计实现

综述由AI生成介绍基于 SpringBoot2、Vue3、MyBatis-Plus 和 MySQL8.0 的厨艺交流平台系统。系统采用前后端分离架构,包含用户管理、菜谱发布、评论互动及收藏等功能模块。数据库设计了用户信息、菜谱信息和评论互动三张核心表。后端使用 Spring Boot 实现业务逻辑与权限控制,前端利用 Vue3 构建响应式界面。文章提供了部分核心 Controller 代码示例及技术架构说明,旨在展示企业级 Web 应用开发流程与技术选型方案。

HadoopMan发布于 2026/4/6更新于 2026/5/2025 浏览
Java Web 厨艺交流平台系统:SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0 设计实现

摘要

随着互联网技术的快速发展,线上交流平台逐渐成为人们分享知识和兴趣的重要渠道。厨艺作为一种普及性高且具有广泛受众的爱好,其线上交流需求日益增长。传统的厨艺交流方式受限于地域和时间,无法满足用户即时互动和内容共享的需求。因此,开发一个基于现代 Web 技术的厨艺交流平台具有重要的现实意义。该平台能够为用户提供菜谱分享、烹饪技巧讨论、社区互动等功能,有效促进厨艺爱好者的交流与合作。

本系统采用前后端分离架构,后端基于 SpringBoot2 框架实现高效稳定的服务端逻辑,前端使用 Vue3 构建动态响应式用户界面,数据库采用 MySQL8.0 存储结构化数据,并通过 MyBatis-Plus 简化数据访问层的开发。系统功能模块包括用户管理、菜谱发布、评论互动、收藏管理等,支持多角色权限控制,确保数据安全性和用户体验。系统还实现了图片上传、实时搜索、分页加载等扩展功能,提升了平台的实用性和易用性。

数据表

用户信息数据表

用户注册及登录过程中,系统自动生成唯一用户标识,创建时间通过函数自动获取,用户 ID 是该表的主键,存储用户基本信息及权限相关属性。

字段名数据类型描述
user_idBIGINT用户唯一标识(主键)
usernameVARCHAR(50)用户名(唯一)
password_hashVARCHAR(64)密码哈希值
emailVARCHAR(50)邮箱(唯一)
avatar_urlVARCHAR(255)头像 URL
role_typeTINYINT角色类型(0-普通用户,1-管理员)
created_timeDATETIME账户创建时间
last_loginDATETIME最后登录时间

菜谱信息数据表

菜谱内容编辑过程中,创建时间通过函数自动获取,菜谱 ID 是该表的主键,存储菜谱的基本信息和关联属性。

字段名数据类型描述
recipe_idBIGINT菜谱唯一标识(主键)
user_idBIGINT发布者用户 ID
titleVARCHAR(100)菜谱标题
descriptionTEXT详细制作步骤
cover_imageVARCHAR(255)封面图片 URL
cooking_timeINT预估烹饪时间(分钟)
difficultyTINYINT难度等级(1-5)
created_timeDATETIME创建时间
view_countINT浏览量

评论互动数据表

用户评论过程中,创建时间通过函数自动获取,评论 ID 是该表的主键,存储用户对菜谱的评论及互动信息。

字段名数据类型描述
comment_idBIGINT评论唯一标识(主键)
user_idBIGINT评论者用户 ID
recipe_idBIGINT关联菜谱 ID
contentTEXT评论内容
created_timeDATETIME评论时间
like_countINT点赞数
parent_idBIGINT父评论 ID(回复功能)

技术架构栈

后端技术:Spring Boot

Spring Boot 作为现代 Java 企业级开发的核心框架,以其'约定优于配置'的设计哲学重新定义了应用开发模式。

核心特性解析:

  • 零配置启动:集成自动配置机制,大幅减少 XML 配置文件编写
  • 嵌入式服务器:内置 Tomcat/Jetty/Undertow,支持独立 JAR 包部署
  • 生产就绪:集成 Actuator 监控组件,提供健康检查、指标收集等企业级特性
  • 微服务友好:天然支持分布式架构,与 Spring Cloud 生态无缝集成

开发优势: 通过 Starter 依赖体系和智能自动装配,开发者可将精力完全聚焦于业务逻辑实现,而非底层基础设施搭建。单一可执行 JAR 的部署模式极大简化了运维流程。

前端技术:Vue.js

Vue.js 以其渐进式框架设计和卓越的开发体验,成为现代前端开发的首选解决方案。

技术亮点:

  • 响应式数据流:基于依赖追踪的响应式系统,实现高效的视图更新
  • 组件化架构:单文件组件(SFC)设计,实现样式、逻辑、模板的完美封装
  • 灵活的渐进式设计:可从简单的视图层库扩展至完整的 SPA 解决方案
  • 丰富的生态系统:Vue Router、Vuex/Pinia、Vue CLI 等官方工具链完备

开发效率: 直观的模板语法结合强大的指令系统,让复杂的用户交互变得简洁明了。优秀的 TypeScript 支持和开发者工具,为大型项目提供可靠的开发保障。

系统界面展示

系统界面

系统界面

系统界面

系统界面

系统界面

核心代码

package com.controller;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.utils.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.annotation.IgnoreAuth;
import com.entity.ShangpinxinxiEntity;
import com.entity.view.ShangpinxinxiView;
import com.service.ShangpinxinxiService;
import com.service.TokenService;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.MD5Util;
import com.utils.MPUtil;
import com.utils.CommonUtil;
import java.io.IOException;
import com.service.StoreupService;
import com.entity.StoreupEntity;

/**
 * 商品信息
 * 后端接口
 * @author *
 * @email *
 * @date 2023-05-08 15:26:09
 */
@RestController
@RequestMapping("/shangpinxinxi")
public class ShangpinxinxiController {
    @Autowired
    private ShangpinxinxiService shangpinxinxiService;
    @Autowired
    private StoreupService storeupService;

    /**
     * 后端列表
     */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params,ShangpinxinxiEntity shangpinxinxi, 
                  @RequestParam(required = false) Double pricestart, 
                  @RequestParam(required = false) Double priceend, HttpServletRequest request){
        String tableName = request.getSession().getAttribute("tableName").toString();
        if(tableName.equals("shangjia")) {
            shangpinxinxi.setShangpubianhao((String)request.getSession().getAttribute("username"));
        }
        EntityWrapper<ShangpinxinxiEntity> ew = new EntityWrapper<ShangpinxinxiEntity>();
        if(pricestart!=null) ew.ge("price", pricestart);
        if(priceend!=null) ew.le("price", priceend);
        PageUtils page = shangpinxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, shangpinxinxi), params), params));
        return R.ok().put("data", page);
    }

    /**
     * 前端列表
     */
    @IgnoreAuth
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params,ShangpinxinxiEntity shangpinxinxi, 
                  @RequestParam(required = false) Double pricestart, 
                  @RequestParam(required = false) Double priceend, HttpServletRequest request){
        EntityWrapper<ShangpinxinxiEntity> ew = new EntityWrapper<ShangpinxinxiEntity>();
        if(pricestart!=null) ew.ge("price", pricestart);
        if(priceend!=null) ew.le("price", priceend);
        PageUtils page = shangpinxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, shangpinxinxi), params), params));
        return R.ok().put("data", page);
    }

    /**
     * 列表
     */
    @RequestMapping("/lists")
    public R list( ShangpinxinxiEntity shangpinxinxi){
        EntityWrapper<ShangpinxinxiEntity> ew = new EntityWrapper<ShangpinxinxiEntity>();
        ew.allEq(MPUtil.allEQMapPre( shangpinxinxi, "shangpinxinxi"));
        return R.ok().put("data", shangpinxinxiService.selectListView(ew));
    }

    /**
     * 查询
     */
    @RequestMapping("/query")
    public R query(ShangpinxinxiEntity shangpinxinxi){
        EntityWrapper< ShangpinxinxiEntity> ew = new EntityWrapper< ShangpinxinxiEntity>();
        ew.allEq(MPUtil.allEQMapPre( shangpinxinxi, "shangpinxinxi"));
        ShangpinxinxiView shangpinxinxiView = shangpinxinxiService.selectView(ew);
        return R.ok("查询商品信息成功").put("data", shangpinxinxiView);
    }

    /**
     * 后端详情
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        ShangpinxinxiEntity shangpinxinxi = shangpinxinxiService.selectById(id);
        shangpinxinxi.setClicknum(shangpinxinxi.getClicknum()+1);
        shangpinxinxi.setClicktime(new Date());
        shangpinxinxiService.updateById(shangpinxinxi);
        return R.ok().put("data", shangpinxinxi);
    }

    /**
     * 前端详情
     */
    @IgnoreAuth
    @RequestMapping("/detail/{id}")
    public R detail(@PathVariable("id") Long id){
        ShangpinxinxiEntity shangpinxinxi = shangpinxinxiService.selectById(id);
        shangpinxinxi.setClicknum(shangpinxinxi.getClicknum()+1);
        shangpinxinxi.setClicktime(new Date());
        shangpinxinxiService.updateById(shangpinxinxi);
        return R.ok().put("data", shangpinxinxi);
    }

    /**
     * 赞或踩
     */
    @RequestMapping("/thumbsup/{id}")
    public R vote(@PathVariable("id") String id,String type){
        ShangpinxinxiEntity shangpinxinxi = shangpinxinxiService.selectById(id);
        if(type.equals("1")) { 
            shangpinxinxi.setThumbsupnum(shangpinxinxi.getThumbsupnum()+1); 
        } else { 
            shangpinxinxi.setCrazilynum(shangpinxinxi.getCrazilynum()+1); 
        }
        shangpinxinxiService.updateById(shangpinxinxi);
        return R.ok("投票成功");
    }

    /**
     * 后端保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody ShangpinxinxiEntity shangpinxinxi, HttpServletRequest request){
        shangpinxinxi.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
        //ValidatorUtils.validateEntity(shangpinxinxi);
        shangpinxinxiService.insert(shangpinxinxi);
        return R.ok();
    }

    /**
     * 前端保存
     */
    @RequestMapping("/add")
    public R add(@RequestBody ShangpinxinxiEntity shangpinxinxi, HttpServletRequest request){
        shangpinxinxi.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
        //ValidatorUtils.validateEntity(shangpinxinxi);
        shangpinxinxiService.insert(shangpinxinxi);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @Transactional
    public R update(@RequestBody ShangpinxinxiEntity shangpinxinxi, HttpServletRequest request){
        //ValidatorUtils.validateEntity(shangpinxinxi);
        shangpinxinxiService.updateById(shangpinxinxi);//全部更新
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
        shangpinxinxiService.deleteBatchIds(Arrays.asList(ids));
        return R.ok();
    }

    /**
     * 前端智能排序
     */
    @IgnoreAuth
    @RequestMapping("/autoSort")
    public R autoSort(@RequestParam Map<String, Object> params,ShangpinxinxiEntity shangpinxinxi, 
                      HttpServletRequest request,String pre){
        EntityWrapper<ShangpinxinxiEntity> ew = new EntityWrapper<ShangpinxinxiEntity>();
        Map<String, Object> newMap = new HashMap<String, Object>();
        Map<String, Object> param = new HashMap<String, Object>();
        Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();
            String key = entry.getKey();
            String newKey = entry.getKey();
            if (pre.endsWith(".")) { 
                newMap.put(pre + newKey, entry.getValue()); 
            } else if (StringUtils.isEmpty(pre)) { 
                newMap.put(newKey, entry.getValue()); 
            } else { 
                newMap.put(pre + "." + newKey, entry.getValue()); 
            }
        }
        params.put("sort", "clicknum");
        params.put("order", "desc");
        PageUtils page = shangpinxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, shangpinxinxi), params), params));
        return R.ok().put("data", page);
    }
}

目录

  1. 摘要
  2. 数据表
  3. 用户信息数据表
  4. 菜谱信息数据表
  5. 评论互动数据表
  6. 技术架构栈
  7. 后端技术:Spring Boot
  8. 前端技术:Vue.js
  9. 系统界面展示
  10. 核心代码
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenClaw 本地部署与飞书机器人接入指南
  • FPGA 光通信开发——Aurora 64B/66B 使用指南
  • 从零开始训练大型语言模型(LLM)实战指南
  • VR-Reversal 插件实现 3D 视频转 2D 格式教程
  • AI 工具前端提示词实战:从设计原则到工程化落地
  • FPGA Flash 烧写步骤详解(基于 Vivado)
  • RAG 工作流深度解析:数据摄取与处理
  • 基于 OpenClaw 与 Claude 的自动化写作工作流搭建实践
  • Stable Diffusion XL 1.0 多场景应用:AR 滤镜素材批量生成方案
  • 反无人机技术原理与反制手段详解
  • 前端组件库:避免重复造轮子
  • Docker 部署 music-tag-web 音乐标签编辑器
  • 前端状态管理:Recoil的原子世界
  • Docker Compose rm 命令详解与使用指南
  • 解决 Java 源发行版 17 与目标发行版不匹配问题
  • Java 面试核心基础:集合、并发与 JVM 详解
  • 前端状态管理:Recoil 原子化实践
  • QGroundControl 跨平台安装指南:Windows macOS Linux Android 部署
  • 前端状态管理:Recoil 的原子化方案
  • 递归实现阶乘:Python、Java 与 JavaScript 代码对比

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online