计算机毕业设计 饮食营养管理信息系统 平衡膳食管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

news2024/9/20 7:51:10

🍊作者:计算机编程-吉哥
🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。
🍊心愿:点赞 👍 收藏 ⭐评论 📝
🍅 文末获取源码联系

👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~
Java毕业设计项目~热门选题推荐《1000套》

目录

1.技术选型

2.开发工具

3.功能

3.1【角色】

3.2【前端功能模块】

3.3【后端功能模块】

4.项目演示截图

4.1 注册

4.2 首页

4.3 食物营养

4.4 菜谱信息

4.5 营养知识科普

4.6 用户管理

4.7 食物营养管理

4.8 饮食记录管理

5.核心代码

5.1拦截器

5.2分页工具类

5.3文件上传下载

5.4前端请求

6.LW文档大纲参考


背景意义介绍:

 在当今社会,随着人们生活节奏的加快和健康意识的提高,合理膳食和营养均衡越来越受到重视。饮食营养管理信息系统的开发,对于指导用户科学饮食、促进健康生活方式具有重要的现实意义。

本文介绍的系统采用Java作为后端开发语言,结合SpringBoot框架,确保了服务端应用的高效性和稳定性。前端则采用Vue.js技术,为用户提供了直观、易用的交互界面。系统服务于管理员和用户两种角色,提供了包括登录注册、食物营养查询、菜谱信息浏览、营养知识科普等功能。

后端管理模块为管理员提供了用户管理、食物营养数据管理、菜谱信息管理、饮食记录和营养评估等强大的管理工具。这些功能的实现,不仅方便了用户对日常饮食的规划和营养的跟踪,也为管理员提供了便捷的数据维护和管理途径。

饮食营养管理信息系统的实现,有助于用户更好地了解食物的营养价值,制定合理的饮食计划,实现个性化的营养管理。系统的数据分析和评估功能还可以帮助用户发现潜在的营养问题,及时调整饮食结构。总之,该系统对于提升公众的营养健康意识、推动健康中国建设具有重要的社会价值和实践意义。

1.技术选型

springboot、mybatisplus、vue、elementui、html、css、js、mysql、jdk1.8

2.开发工具

idea、navicat

3.功能

3.1【角色】

管理员、用户

3.2【前端功能模块】

  • 登录
  • 注册
  • 食物营养
  • 菜谱信息
  • 营养知识科普
  • 个人中心(个人信息、修改密码、饮食记录、营养评估、我的收藏)

3.3【后端功能模块】

  • 登录
  • 用户
  • 食物营养
  • 菜谱信息
  • 饮食记录
  • 营养评估
  • 菜谱类型
  • 系统管理
  • 用户资料

4.项目演示截图

4.1 注册

4.2 首页

4.3 食物营养

4.4 菜谱信息

4.5 营养知识科普

4.6 用户管理

4.7 食物营养管理

4.8 饮食记录管理

5.核心代码

5.1拦截器

package com.interceptor;
 
import com.alibaba.fastjson.JSONObject;
import com.annotation.IgnoreAuth;
import com.entity.TokenEntity;
import com.service.TokenService;
import com.utils.R;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
 
/**
 * 权限(Token)验证
 */
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {
 
    public static final String LOGIN_TOKEN_KEY = "Token";
 
    @Autowired
    private TokenService tokenService;
    
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 
		//支持跨域请求
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
	// 跨域时会首先发送一个OPTIONS请求,这里我们给OPTIONS请求直接返回正常状态
	if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
        	response.setStatus(HttpStatus.OK.value());
            return false;
        }
        
        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            return true;
        }
 
        //从header中获取token
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        
        /**
         * 不需要验证权限的方法直接放过
         */
        if(annotation!=null) {
        	return true;
        }
        
        TokenEntity tokenEntity = null;
        if(StringUtils.isNotBlank(token)) {
        	tokenEntity = tokenService.getTokenEntity(token);
        }
        
        if(tokenEntity != null) {
        	request.getSession().setAttribute("userId", tokenEntity.getUserid());
        	request.getSession().setAttribute("role", tokenEntity.getRole());
        	request.getSession().setAttribute("tableName", tokenEntity.getTablename());
        	request.getSession().setAttribute("username", tokenEntity.getUsername());
        	return true;
        }
        
		PrintWriter writer = null;
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		try {
		    writer = response.getWriter();
		    writer.print(JSONObject.toJSONString(R.error(401, "请先登录")));
		} finally {
		    if(writer != null){
		        writer.close();
		    }
		}
		return false;
    }
}

5.2分页工具类

 
package com.utils;
 
import java.io.Serializable;
import java.util.List;
import java.util.Map;
 
import com.baomidou.mybatisplus.plugins.Page;
 
/**
 * 分页工具类
 */
public class PageUtils implements Serializable {
	private static final long serialVersionUID = 1L;
	//总记录数
	private long total;
	//每页记录数
	private int pageSize;
	//总页数
	private long totalPage;
	//当前页数
	private int currPage;
	//列表数据
	private List<?> list;
	
	/**
	 * 分页
	 * @param list        列表数据
	 * @param totalCount  总记录数
	 * @param pageSize    每页记录数
	 * @param currPage    当前页数
	 */
	public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
		this.list = list;
		this.total = totalCount;
		this.pageSize = pageSize;
		this.currPage = currPage;
		this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
	}
 
	/**
	 * 分页
	 */
	public PageUtils(Page<?> page) {
		this.list = page.getRecords();
		this.total = page.getTotal();
		this.pageSize = page.getSize();
		this.currPage = page.getCurrent();
		this.totalPage = page.getPages();
	}
	
	/*
	 * 空数据的分页
	 */
	public PageUtils(Map<String, Object> params) {
 		Page page =new Query(params).getPage();
		new PageUtils(page);
	}
 
	 
	public int getPageSize() {
		return pageSize;
	}
 
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
 
	public int getCurrPage() {
		return currPage;
	}
 
	public void setCurrPage(int currPage) {
		this.currPage = currPage;
	}
 
	public List<?> getList() {
		return list;
	}
 
	public void setList(List<?> list) {
		this.list = list;
	}
 
	public long getTotalPage() {
		return totalPage;
	}
 
	public void setTotalPage(long totalPage) {
		this.totalPage = totalPage;
	}
 
	public long getTotal() {
		return total;
	}
 
	public void setTotal(long total) {
		this.total = total;
	}
	
}

5.3文件上传下载

package com.controller;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
 
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
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 org.springframework.web.multipart.MultipartFile;
 
import com.annotation.IgnoreAuth;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.ConfigEntity;
import com.entity.EIException;
import com.service.ConfigService;
import com.utils.R;
 
/**
 * 上传文件映射表
 */
@RestController
@RequestMapping("file")
@SuppressWarnings({"unchecked","rawtypes"})
public class FileController{
	@Autowired
    private ConfigService configService;
	/**
	 * 上传文件
	 */
	@RequestMapping("/upload")
    @IgnoreAuth
	public R upload(@RequestParam("file") MultipartFile file,String type) throws Exception {
		if (file.isEmpty()) {
			throw new EIException("上传文件不能为空");
		}
		String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
		File path = new File(ResourceUtils.getURL("classpath:static").getPath());
		if(!path.exists()) {
		    path = new File("");
		}
		File upload = new File(path.getAbsolutePath(),"/upload/");
		if(!upload.exists()) {
		    upload.mkdirs();
		}
		String fileName = new Date().getTime()+"."+fileExt;
		File dest = new File(upload.getAbsolutePath()+"/"+fileName);
		file.transferTo(dest);
		if(StringUtils.isNotBlank(type) && type.equals("1")) {
			ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
			if(configEntity==null) {
				configEntity = new ConfigEntity();
				configEntity.setName("faceFile");
				configEntity.setValue(fileName);
			} else {
				configEntity.setValue(fileName);
			}
			configService.insertOrUpdate(configEntity);
		}
		return R.ok().put("file", fileName);
	}
	
	/**
	 * 下载文件
	 */
	@IgnoreAuth
	@RequestMapping("/download")
	public ResponseEntity<byte[]> download(@RequestParam String fileName) {
		try {
			File path = new File(ResourceUtils.getURL("classpath:static").getPath());
			if(!path.exists()) {
			    path = new File("");
			}
			File upload = new File(path.getAbsolutePath(),"/upload/");
			if(!upload.exists()) {
			    upload.mkdirs();
			}
			File file = new File(upload.getAbsolutePath()+"/"+fileName);
			if(file.exists()){
 
				HttpHeaders headers = new HttpHeaders();
			    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);    
			    headers.setContentDispositionFormData("attachment", fileName);    
			    return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return new ResponseEntity<byte[]>(HttpStatus.INTERNAL_SERVER_ERROR);
	}
	
}

5.4前端请求

import axios from 'axios'
import router from '@/router/router-static'
import storage from '@/utils/storage'
 
const http = axios.create({
    timeout: 1000 * 86400,
    withCredentials: true,
    baseURL: '/furniture',
    headers: {
        'Content-Type': 'application/json; charset=utf-8'
    }
})
// 请求拦截
http.interceptors.request.use(config => {
    config.headers['Token'] = storage.get('Token') // 请求头带上token
    return config
}, error => {
    return Promise.reject(error)
})
// 响应拦截
http.interceptors.response.use(response => {
    if (response.data && response.data.code === 401) { // 401, token失效
        router.push({ name: 'login' })
    }
    return response
}, error => {
    return Promise.reject(error)
})
export default http

6.LW文档大纲参考

 具体LW如何写法,可以咨询博主,耐心分享!

你可能还有感兴趣的项目👇🏻👇🏻👇🏻

更多项目推荐:计算机毕业设计项目

如果大家有任何疑虑,请在下方咨询或评论

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

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

相关文章

【嵌入式开发之网络编程】网络分层、OSI七层模型、TCP/IP及五层体系结构

计算机网络体系的形成 两台计算机要互相传送文件需解决很多问题&#xff0c;比如&#xff1a; 必须有一条传送数据的通路。发起方必须激活通路。要告诉网络如何识别接收方。发起方要清楚对方是否已开机&#xff0c;且与网络连接正常。发起方要清楚对方是否准备好接收和存储文…

JS UI库DHTMLX Suite v8.4全新发布——图表、网格组件等API全面升级

DHTMLX UI 组件库允许您更快地构建跨平台、跨浏览器 Web 和移动应用程序。它包括一组丰富的即用式 HTML5 组件&#xff0c;这些组件可以轻松组合到单个应用程序界面中。DHTMLX JS UI 组件可用于任何服务器端技术&#xff1a;PHP、Java、ASP.NET、Ruby、Grails、ColdFusion、Pyt…

糟糕界面集锦-控件篇10

想要让自己的程序别具一格&#xff0c;正是出于这种被误导的动机。IBM 的Aptiva Communitations Center 开发者决定不使用Windows 自己的控件&#xff0c;用自行开发的控件取而代之。他们非常成功地做到了这一点&#xff1a;该程序看上去与其他Windows 环境下运行的程序完全不同…

C语言-在主函数中输入10个等长的字符串。用另一函数对他们进行排序,然后再主函数输出这10个排好序的数列(分别用①数组法和②指针法实现)

在主函数中输入10个等长的字符串。用另一函数对他们进行排序&#xff0c;然后再主函数输出这10个排好序的数列&#xff08;分别用数组法和指针法实现&#xff09; 一、数组法实现 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> void str_sort(char str[][32], …

【C语言】时间函数详解

目录 C语言时间函数详解表格汇总1. time2. localtime3. gmtime4. strftime5. clock6. difftime函数详解示例解释 7. mktime8. asctime9. ctime10. clock_gettime 和 clock_settime总结9. 结束语相关文章&#xff1a; C语言时间函数详解 在C语言中&#xff0c;时间处理功能由标…

【国奖学姐力荐】matlab智能算法的案例分析和源代码

现在各类数模比赛特别是国赛优化问题越来越多&#xff0c;而求解这些优化问题往往要用到智能启发式算法&#xff0c;今天带大家看一下matlab智能算法的案例分析和源代码&#xff0c;有两本书推荐给大家。 有需要这两本书籍电子版和单独案例的家人可以公屏留言&#xff0c;我会依…

【C# WPF WeChat UI 简单布局】

创建WPF项目 VS创建一个C#的WPF应用程序: 创建完成后项目目录下会有一个MainWindow.xaml文件以及MainWindow.cs文件,此处将MainWindow.xaml文件作为主页面的布局文件,也即为页面的主题布局都在该文件进行。 布局和数据 主体布局 Wechat的布局可暂时分为三列, 第一列为菜…

【Spring Boot】拦截器的使用

目录 前言 拦截器的使用 1.创建一个拦截器 2.注册拦截器 3.配置拦截器的匹配规则 拦截器的实际使用场景 拦截器 vs 过滤器 vs AOP 前言 在Spring Boot中&#xff0c;拦截器&#xff08;interceptor&#xff09;是一种用于拦截和处理请求的机制。通过拦截器&#xff0c;可…

聊天机器人正在膨胀技术

API 在软件中发挥的作用比任何其他东西都要大 当团队与外部 API&#xff08;包括第三方 AI&#xff09;集成时&#xff0c;他们可以将预制的外部功能引入产品中。我使用 API 让用户根据matchboxxr上的提示生成 3D 模型。 但是&#xff0c;尽管越来越多的初创公司只关注人工智能…

Java开发工具IDEA入门指南——如何从VS Code迁移到IDEA?(一)

IntelliJ IDEA是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的Java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能是非常强大的。 在本文中&#x…

【java基础】IDEA 的断点调试(Debug)

目录 1.为什么需要 Debug 2.Debug的步骤 2.1添加断点 2.2单步调试工具介绍 2.2.1 Step Over 2.2.2 Step Into 2.2.3 Force Step Into 2.2.4 Step Out 2.2.5 Run To Cursor 2.2.6 Show Execution Poiint 2.2.7 Resume Program 3.多种 Debug 情况介绍 3.1行断点 3.2方…

XSS GAME

源网站&#xff1a;XSS 游戏 - 学习 XSS 变得简单&#xff01; |创建者 PwnFunction 以下为解码工具&#xff1a; 在线 JSFuck 加密 - 百川在线工具箱 (chaitin.cn) CyberChef 1、Ma Spaghet! 条件 Difficulty is Easy.Pop an alert(1337) on sandbox.pwnfunction.com.No…

分析FP -Growth代码运行内存太大而无法运行的原因

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

随记 - 2024 年 4 月 12 日

写在前面 444 字 | 生活 | 经历 | 感触 正文 或许因为压力大&#xff0c;亦或者简单的糖分不足&#xff0c;今晚好想吃面包和蛋糕。 蛋糕吃不完也买不起&#xff0c;面包还是可以。 实在饿&#xff0c;出门了。 导航两家西点店&#xff0c;关门。怏怏地找另一家。 在十点前&a…

效果炫酷的3D翻转书特效WordPress主题模板MagicBook主题v1.19

正文&#xff1a; MagicBook是一款支持3D翻书特效的书籍WordPress主题。支持可视化页面搭建&#xff0c;3D菜单&#xff0c;完全自适应设计,WPML多语言支持。 这款主题一定会让你爱不释手。虽然他是英文的&#xff0c;但不可不承认的是&#xff0c;它优雅的设计会让你愿意花时…

[Linux]将一个文件复制到多个文件夹下

一、简介 本文介绍了在linux下如何使用cp命令将一个文件复制到多个文件夹、多个文件复制到一个文件夹和多个文件复制到多个文件夹下。 二、代码 假设初始时test/文件夹的结构如下&#xff1a; 1. 将一个文件复制到多个文件夹 a.命令示例 将file1复制到目录des_dir1/&#…

【PGCCC】pg_bestmatch.rs:使用 BM25 提升您的 PostgreSQL 文本查询#PCA

这是一个 PostgreSQL 扩展&#xff0c;它将最佳匹配 25 分数 (BM25) 文本查询的强大功能引入您的数据库&#xff0c;从而增强您执行高效和准确的文本检索的能力。此扩展允许用户从文本生成 BM25 统计稀疏向量&#xff0c;利用 BM25 在各种基准测试任务中经过验证的性能。 为什…

8.16 QT

1.思维导图 2 将day1做的登录界面升级优化【资源文件的添加】 2> 在登录界面的登录取消按钮进行一下设置&#xff1a; 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5…

《SPSS零基础入门教程》学习笔记——03.变量的统计描述

文章目录 3.1 连续变量&#xff08;1&#xff09;集中趋势&#xff08;2&#xff09;离散趋势&#xff08;3&#xff09;分布特征 3.2 分类变量&#xff08;1&#xff09;单个分类变量&#xff08;2&#xff09;多个分类变量 3.1 连续变量 &#xff08;1&#xff09;集中趋势 …

使用 Python 解密加密的 PDF 文件

使用 Python 进行 PDF 文件加密-CSDN博客文章浏览阅读89次&#xff0c;点赞2次&#xff0c;收藏2次。定义一个名为的函数&#xff0c;该函数接受三个参数&#xff1a;输入的 PDF 文件路径input_pdf、输出的加密 PDF 文件路径output_pdf和密码password。https://blog.csdn.net/q…