☰
基于 SpringBoot + Vue3 的健康饮食记录与分析系统
2026/10/14 14:57:16 网站建设 项目流程

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片!

1. 项目背景与目标

随着人们健康意识的不断提升,日常饮食管理逐渐成为大众关注的重点。然而,多数人在记录饮食时缺乏系统化的工具支撑,难以直观了解自身营养摄入是否均衡。本项目基于 SpringBoot 与 Vue3 构建一套健康饮食记录与分析系统,帮助用户便捷记录每日三餐与加餐,并通过可视化分析掌握热量、蛋白质、脂肪、碳水化合物等关键营养指标的摄入情况。

系统面向普通用户与健康管理场景,核心目标包括:

  • 提供简洁高效的饮食记录入口,支持按餐次、时间、食物名称快速录入。
  • 内置常见食物营养数据库,自动计算单次摄入的营养成分。
  • 以图表形式展示每日、每周、每月的营养摄入趋势,辅助用户调整饮食结构。
  • 支持个人目标设定,如每日热量预算、蛋白质目标等,并给出达成度提示。

2. 技术选型

系统采用前后端分离架构,后端基于 SpringBoot 提供 RESTful API,前端基于 Vue3 与 Element Plus 构建交互界面,数据存储使用 MySQL 数据库。

层次技术栈说明
后端框架SpringBoot 2.7 / 3.x提供业务接口、鉴权与数据持久化
ORMMyBatis-Plus简化数据库操作,提升开发效率
前端框架Vue3 + Vite组件化开发,组合式 API 管理状态
UI 组件库Element Plus表格、表单、图表等基础组件
图表库ECharts营养摄入趋势与占比可视化
数据库MySQL 8.0存储用户、食物、饮食记录等数据
鉴权方案JWT + Spring Security无状态登录认证与接口权限控制

3. 系统功能模块

系统整体划分为用户管理、食物管理、饮食记录、营养分析与目标管理五大核心模块。

3.1 用户管理

支持用户注册、登录与个人信息维护。登录成功后签发 JWT 令牌,前端在请求头中携带令牌访问受保护接口。用户可维护身高、体重、年龄、活动等级等基础信息,用于后续热量需求估算。

3.2 食物管理

内置常见食物营养数据库,管理员可维护食物名称、分类、单位以及每 100 克对应的热量、蛋白质、脂肪、碳水化合物等数据。用户也可自定义添加个人常用食物,便于快速录入。

3.3 饮食记录

用户按早餐、午餐、晚餐、加餐四个餐次记录每日饮食。每条记录关联食物与食用量,系统自动根据食物营养数据计算该条记录的热量与各营养素数值。记录支持按日期范围查询与修改删除。

3.4 营养分析

基于饮食记录数据,系统以折线图展示每日热量与三大营养素摄入趋势,以饼图展示蛋白质、脂肪、碳水化合物的供能占比,帮助用户直观判断饮食结构是否合理。

3.5 目标管理

用户可设定每日热量预算与蛋白质目标。系统根据当日实际摄入自动计算达成率,并在首页以进度条形式展示,辅助用户进行饮食调整。

4. 数据库设计

系统核心数据表包括用户表、食物表、饮食记录表与目标表。以下为主要表结构说明。

4.1 用户表 user

CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(100) NOT NULL COMMENT '加密密码', `nickname` varchar(50) DEFAULT NULL COMMENT '昵称', `gender` tinyint DEFAULT NULL COMMENT '性别 1男 2女', `height` decimal(5,2) DEFAULT NULL COMMENT '身高cm', `weight` decimal(5,2) DEFAULT NULL COMMENT '体重kg', `age` int DEFAULT NULL COMMENT '年龄', `activity_level` tinyint DEFAULT NULL COMMENT '活动等级 1-5', `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

4.2 食物表 food

CREATE TABLE `food` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '食物名称', `category` varchar(20) DEFAULT NULL COMMENT '分类', `calorie` decimal(8,2) DEFAULT NULL COMMENT '热量kcal/100g', `protein` decimal(8,2) DEFAULT NULL COMMENT '蛋白质g/100g', `fat` decimal(8,2) DEFAULT NULL COMMENT '脂肪g/100g', `carbohydrate` decimal(8,2) DEFAULT NULL COMMENT '碳水g/100g', `user_id` bigint DEFAULT NULL COMMENT '自定义用户id,空为系统内置', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

4.3 饮食记录表 diet_record

CREATE TABLE `diet_record` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL COMMENT '用户id', `food_id` bigint NOT NULL COMMENT '食物id', `meal_type` tinyint NOT NULL COMMENT '餐次 1早餐 2午餐 3晚餐 4加餐', `amount` decimal(8,2) NOT NULL COMMENT '食用量g', `record_date` date NOT NULL COMMENT '记录日期', `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

4.4 目标表 goal

CREATE TABLE `goal` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL COMMENT '用户id', `daily_calorie` decimal(8,2) DEFAULT NULL COMMENT '每日热量目标', `daily_protein` decimal(8,2) DEFAULT NULL COMMENT '每日蛋白质目标g', `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

5. 后端核心实现

后端采用分层架构,Controller 层负责接收请求与参数校验,Service 层处理业务逻辑,Mapper 层基于 MyBatis-Plus 完成数据访问。

5.1 项目依赖配置

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>

5.2 饮食记录接口示例

以下代码展示新增饮食记录的核心逻辑,系统根据食物 id 查询营养数据,再按食用量折算实际摄入值。

@RestController @RequestMapping("/api/record") public class DietRecordController { @Resource private DietRecordService recordService; @PostMapping public Result&lt;Void&gt; addRecord(@RequestBody DietRecordDTO dto) { recordService.addRecord(dto); return Result.success(); } @GetMapping("/daily") public Result&lt;DailyNutritionVO&gt; getDailyNutrition( @RequestParam Long userId, @RequestParam String date) { return Result.success(recordService.getDailyNutrition(userId, date)); } }
@Service public class DietRecordServiceImpl implements DietRecordService { @Resource private DietRecordMapper recordMapper; @Resource private FoodMapper foodMapper; @Override public void addRecord(DietRecordDTO dto) { Food food = foodMapper.selectById(dto.getFoodId()); if (food == null) { throw new BusinessException("食物不存在"); } DietRecord record = new DietRecord(); record.setUserId(dto.getUserId()); record.setFoodId(dto.getFoodId()); record.setMealType(dto.getMealType()); record.setAmount(dto.getAmount()); record.setRecordDate(dto.getRecordDate()); recordMapper.insert(record); } @Override public DailyNutritionVO getDailyNutrition(Long userId, String date) { List&lt;DietRecord&gt; records = recordMapper.selectList( new LambdaQueryWrapper&lt;DietRecord&gt;() .eq(DietRecord::getUserId, userId) .eq(DietRecord::getRecordDate, date)); DailyNutritionVO vo = new DailyNutritionVO(); for (DietRecord record : records) { Food food = foodMapper.selectById(record.getFoodId()); double ratio = record.getAmount() / 100.0; vo.setCalorie(vo.getCalorie() + food.getCalorie() * ratio); vo.setProtein(vo.getProtein() + food.getProtein() * ratio); vo.setFat(vo.getFat() + food.getFat() * ratio); vo.setCarbohydrate(vo.getCarbohydrate() + food.getCarbohydrate() * ratio); } return vo; } }

6. 前端核心实现

前端基于 Vue3 组合式 API 开发,使用 Vite 构建,Element Plus 提供界面组件,ECharts 完成数据可视化。

6.1 项目初始化

npm create vite@latest health-diet-frontend -- --template vue cd health-diet-frontend npm install element-plus @element-plus/icons-vue axios echarts pinia

6.2 饮食记录表单组件

以下为新增饮食记录的表单组件,用户选择食物、填写食用量后提交到后端接口。

<template> <el-form :model="form" label-width="80px"> <el-form-item label="食物"> <el-select v-model="form.foodId" placeholder="请选择食物"> <el-option v-for="item in foodList" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> <el-form-item label="餐次"> <el-radio-group v-model="form.mealType"> <el-radio :label="1">早餐</el-radio> <el-radio :label="2">午餐</el-radio> <el-radio :label="3">晚餐</el-radio> <el-radio :label="4">加餐</el-radio> </el-radio-group> </el-form-item> <el-form-item label="食用量"> <el-input-number v-model="form.amount" :min="1" :max="1000" /> <span> 克</span> </el-form-item> <el-form-item> <el-button type="primary" @click="submit">保存记录</el-button> </el-form-item> </el-form> </template> <script setup> import { reactive, ref, onMounted } from 'vue' import { ElMessage } from 'element-plus' import request from '@/utils/request' const form = reactive({ foodId: null, mealType: 1, amount: 100 }) const foodList = ref([]) const loadFoods = async () => { const res = await request.get('/api/food/list') foodList.value = res.data } const submit = async () => { await request.post('/api/record', form) ElMessage.success('记录成功') } onMounted(loadFoods) </script>

6.3 营养趋势图表

以下代码使用 ECharts 展示近七日热量摄入趋势,数据由后端聚合接口返回。

<template> <div ref="chartRef" style="height: 360px" /> </template> <script setup> import { ref, onMounted, onBeforeUnmount } from 'vue' import * as echarts from 'echarts' import request from '@/utils/request' const chartRef = ref(null) let chart = null const loadTrend = async () => { const res = await request.get('/api/record/week-trend', { params: { userId: 1 } }) chart = echarts.init(chartRef.value) chart.setOption({ title: { text: '近七日热量摄入趋势' }, tooltip: { trigger: 'axis' }, xAxis: { type: 'category', data: res.data.dates }, yAxis: { type: 'value', name: 'kcal' }, series: [{ name: '热量摄入', type: 'line', smooth: true, data: res.data.calories }] }) } onMounted(loadTrend) onBeforeUnmount(() => { chart && chart.dispose() }) </script>

7. 系统部署与运行

系统采用前后端分离部署方式,后端打包为可执行 Jar 包,前端构建为静态资源后由 Nginx 托管。

7.1 后端启动

mvn clean package -DskipTests java -jar target/health-diet-server.jar --spring.profiles.active=prod

7.2 前端构建

npm run build # 构建产物位于 dist 目录,配置 Nginx 指向该目录并代理 /api 请求
server { listen 80; server_name example.com; location / { root /var/www/health-diet; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

8. 总结与展望

本文基于 SpringBoot 与 Vue3 设计并实现了一套健康饮食记录与分析系统,覆盖饮食录入、营养计算、趋势分析与目标管理全流程。系统采用前后端分离架构,后端接口清晰、前端交互友好,能够满足日常饮食管理的基本需求。

后续可从以下方向持续优化:

  • 接入第三方食物营养数据库,扩充食物覆盖范围。
  • 增加膳食均衡评分与个性化推荐功能。
  • 引入定时提醒与打卡机制,提升用户使用粘性。
  • 结合运动数据,实现热量摄入与消耗的综合分析。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询