当前位置: 首页 > news >正文

基于SpringBoot及PostgreSQL的国家减肥食谱管理项目(中):食谱与菜单配置搭建

目录

前言

一、项目需求简介

1、需求简介

2、本次实现介绍

二、SpringBoot后端实现

1、Model实现

2、业务层实现

2.1关于返回数量限制

2.2父子表单的后台新增实现

2.3父子表单的后台编辑实现

三、Thymeleaf前端实现

1、食谱管理实现

2、餐别及详情实现

3、父子表单提交

四、总结


前言

        在当今社会,健康意识的觉醒促使越来越多的人关注减肥与营养均衡。减肥不仅关乎外在形象,更是关乎内在健康的重要课题。一个科学合理的减肥食谱对于减肥者来说至关重要,它能够帮助人们在减少热量摄入的同时,保证身体获取足够的营养。然而,不同地区的人们由于生活习惯、饮食文化以及可获取食材的差异,对于减肥食谱有着各自独特的需求。基于此,开发一个国家减肥食谱管理系统显得尤为必要,它能够根据不同区域和省份的特点,为用户提供个性化的减肥食谱方案。博文基于SpringBoot及PostgreSQL的国家减肥食谱管理项目(上):区域与省份配置搭建中已经对食谱的区域和省份信息配置进行了详细的说明。

        本文作为健康项目的中篇,将详细介绍如何对区域食谱以及食谱对应的菜单详情进行配置,通过案例的讲解,大家可以看到整个的健康管理的全貌,对涉及的相关表有一个具体的认识。

        本例还在场景配置中介绍如何基于ruoyi开发父子表格提交的窗口,可以为类似的需求开发做一个技术参考。通过基于 SpringBoot 和 PostgreSQL 的技术实现,我们相信能够构建出一个稳定、高效、用户友好的系统,为全国不同地区的减肥者提供科学、个性化的减肥食谱服务。在接下来的章节中,我们将详细介绍具体实现过程,包括数据库设计、后端服务开发以及前端用户界面设计等方面的内容,让我们一起开启这段精彩的开发之旅吧。

一、项目需求简介

        本节将重点介绍国家减肥食谱项目的背景要求,分别从需求简介和本次需要实现的需求两个方面进行介绍,通过本节让大家可以了解一些背景信息,更好的去参与后期的项目建设。

1、需求简介

        在本项目的上篇中,我们将重点聚焦于区域和省份的配置搭建。区域和省份配置是整个减肥食谱管理系统的基础,它决定了系统能够覆盖的地理范围以及能够根据不同地区特点提供服务的能力。通过精心设计的区域和省份配置,系统可以针对不同地区的饮食偏好、食材供应情况等因素,生成更具针对性和实用性的减肥食谱。例如,在沿海地区,海鲜资源丰富,减肥食谱可以充分利用这一优势,设计出以海鲜为主的低热量、高蛋白的菜品;而在内陆地区,蔬菜和肉类的搭配则可能成为减肥食谱的重点。

2、本次实现介绍

         作为面向数据库的应用开发,数据库的设计直观重要。在之前的博文中对数据库表进行了深入的分析和讨论,详见:面向国家健康食谱指南的PostgreSQL物理表设计及数据存储实践方案。大家可以通过点击查看之前的博文。由于食谱的管理内容较多,设计到食谱区域、区域关联省份、餐次即食谱详情等,在之前的博文中详细介绍了食谱区域以及食谱区域对应的省份信息,本次将继续做好这个基础工作,主要是剩下的食谱、餐别及详情信息,也将为后续的工作提供基础。本次实现的需求如下图中的红框中的数据库表所示:

        以上数据库表格是后续功能实现的数据基础,需要重点理解掌握。

二、SpringBoot后端实现

         本节将以Ruoyi开发框架为例,重点讲解在SpringBoot后台中如何实现健康食谱的管理以及食谱对应的菜单信息管理。主要包括以下两个层的实现,即Model模型层和业务层。

1、Model实现

         与数据库设计一一对应,在SpringBoot中主要包含三个类,即食谱信息类、餐别信息类以及菜单详情信息类。食谱信息主要是按四季的维度组织数据,用于定义不同的季节吃什么样的食物。食谱信息类关键的代码如下:

package com.yelang.project.extend.earthquake.domain;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/*** - 四季食谱信息表* @author 夜郎king*/
@TableName(value = "biz_four_seasons_recipe")
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class FourSeasonsRecipe implements Serializable {private static final long serialVersionUID = -6072349554277340610L;@TableId(value = "pk_id")private Long pkId;// 主键@TableField(value = "food_id")private Long foodId;// 区域饮食主键@TableField(value = "food_name")private String foodName;// 食谱名称@TableField(value = "total_energy")private Integer totalEnergy;// 总能量,单位kcalprivate Integer season;// 季节标志,1:春季 2:夏季 3:秋季 4:冬季@TableField(value = "order_num")private Integer orderNum;// 排序号private String remark;// 备注public FourSeasonsRecipe(Long foodId, String foodName, Integer totalEnergy, Integer season, Integer orderNum,String remark) {super();this.foodId = foodId;this.foodName = foodName;this.totalEnergy = totalEnergy;this.season = season;this.orderNum = orderNum;this.remark = remark;}
}

        需要注意的是,这里我们使用1、2、3、4四个数字分别对应一年春夏秋冬四季。有了一年四季的食谱后,接下来就是季节内一日三餐或者需要加餐信息的管理,所以我们增加一个餐别的管理,餐别管理的核心代码如下:

package com.yelang.project.extend.earthquake.domain;
import java.io.Serializable;
import java.util.List;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/*** - 食谱餐别信息表* @author 夜郎king*/
@TableName(value = "biz_recipe_meal_type")
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class RecipeMealType implements Serializable {private static final long serialVersionUID = 4399855059597304978L;@TableId(value = "pk_id")private Long pkId;// 主键@TableField(value = "recipe_id")private Long recipeId;// 食谱id@TableField(value = "meal_type_name")private String mealTypeName;// 餐别名称,如早餐、加餐等@TableField(value = "order_num")private Integer orderNum;// 排序号@TableField(exist = false)private List<RecipeDetails> recipeDetailsList;//菜单详情public RecipeMealType(Long recipeId, String mealTypeName, Integer orderNum) {super();this.recipeId = recipeId;this.mealTypeName = mealTypeName;this.orderNum = orderNum;}
}

        针对不同类型的餐别,比如早餐、中餐、晚餐等,我们会根据时间来进行不同食物的准备。所以在定义好餐别后,我们可以基于餐别来详细定义不同的餐别的食物,也就是菜单。菜单信息类的核心代码如下:

package com.yelang.project.extend.earthquake.domain;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/*** - 菜单详情信息表* @author 夜郎king*/
@TableName(value = "biz_recipe_details")
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class RecipeDetails implements Serializable {private static final long serialVersionUID = -4003180539390925788L;@TableId(value = "pk_id")private Long pkId;// 主键@TableField(value = "meal_type_id")private Long mealTypeId;// 餐别idprivate String name;// 名称private String formula;// 配方信息@TableField(value = "order_num")private Integer orderNum;// 排序号public RecipeDetails(Long mealTypeId, String name, String formula, Integer orderNum) {super();this.mealTypeId = mealTypeId;this.name = name;this.formula = formula;this.orderNum = orderNum;}
}

        大家可以看到,在餐别信息类中,我们定义个菜单详情的集合,方便的对应的业务层中进行统一保存。与模型层配套的用于数据库读写的是Mapper,由于不包含太复杂的业务,这里不进行赘述。

2、业务层实现

        类似于这种业务,对于控制层的实现并不是很复杂,但是业务层还是一个核心,其中包含了一些基本的业务规则的校验和关联等。比如有的时候需要使用MybatisPlus的一些高级语法进行数据的查询。因此本文将重点和目光聚焦在业务层,重点讲讲在业务层可能会遇到什么问题。

2.1关于返回数量限制

        如果要在MybatisPlus中执行SQL语句时,使用Limit等子句来进行返回结果集的限制。则可以使用以下代码:

private FourSeasonsRecipe getFourSeasonsRecipe(FourSeasonsRecipe fourSeasonsRecipe) {QueryWrapper<FourSeasonsRecipe> queryWrapper = new QueryWrapper<FourSeasonsRecipe>();queryWrapper.eq("food_id", fourSeasonsRecipe.getFoodId());if(StringUtils.isNotBlank(fourSeasonsRecipe.getFoodName())){queryWrapper.like("food_name", fourSeasonsRecipe.getFoodName());}//在末尾追加limit1,表示限制返回数量queryWrapper.last(" limit 1 ");return this.baseMapper.selectOne(queryWrapper);
}

        通过这段代码就可以实现Limit子句的添加和执行。

2.2父子表单的后台新增实现

        关于有父子表单的实现,这里以餐别和菜单详情的关系,一个餐别入早餐,势必会有多种菜单,也就是一对多的关系。在这种场景下就比较适合实用父子表单来进行业务的管理和实现。相对而言,新增的业务处理场景是比较简单的,因此首先我们来讲解一下父子表单的新增实现。业务层的核心代码如下:

@Override
@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
public int insertEntity(RecipeMealType recipeMealType) {int result = this.baseMapper.insert(recipeMealType);Long pkId = recipeMealType.getPkId();List<RecipeDetails> recipeDetailsList = recipeMealType.getRecipeDetailsList();for(RecipeDetails details : recipeDetailsList) {details.setMealTypeId(pkId);}recipeDetailsService.saveBatch(recipeDetailsList);return result;
}

        在调用MybatisPlus的新增方法后,新生成一个pkid的字段,需要在批量插入时设置好对应的ID即可。

2.3父子表单的后台编辑实现

        编辑的功能实现其实与新增相差不大,这里我们采用比较简单的一种方式,即在使用编辑功能时,先将所有的菜单详情删除,然后再全部采用新增的模式。这种模式比较粗暴,在实际业务中,需要开发人员进行选择。实现代码如下:

三、Thymeleaf前端实现

        在完成了SpringBoot的后端程序设计与实现之后,下面我们就需要使用Thymeleaf的方式来进行前端界面的实现。这里依然以我们熟悉的单体架构模式进行集成,如需要分离版本,可以自己设计。

1、食谱管理实现

        在食谱的管理中,我们需要支持不同的地区进行统一管理,因此我们需要在打开的每个tab页中记住之前所选择的地区信息。对应的窗口处理Javascript脚本如下:

function recipemealtypeConfig(recipeId,foodName){var url = ctx + "/eq/foodarea/recipemealtype/" + recipeId;$.modal.openTab("[" + foodName + "]餐别配置", url);
}

        不仅如此,食谱的管理还支持按照食谱名称进行查询,列表页面如下:

        食谱的新增页面需要按照一年四季进行管理,因此在新增或者编辑页面中也需要支持四季的选择,实现效果如下:

        这里将食谱的新增和编辑功能一并讲解。

2、餐别及详情实现

        基于一年四季的食谱定义完成之后,接下来就需要对餐别即中餐、加餐、中餐、晚餐等进行统一的管理配置。同时还要支持不同的餐别的菜单配置,到这里才是重点的饮食控制。

        餐别的新增和编辑页面实现效果如下:

3、父子表单提交

        父子表单域普通表单还是有蛮大的区别的。在这里菜单和详情之间其实就一个父子表单关系,因此我们可以使用这种方式进行数据的提交和管理。下面我们以新增功能为例,讲解如何进行集成。首先是html页面中需要做如下定义:

<h4 class="form-header h4">菜单详情</h4><div class="row"><div class="col-sm-12"><button type="button" class="btn btn-white btn-sm" onclick="addRow()"><i class="fa fa-plus"> 增加</i></button><button type="button" class="btn btn-white btn-sm" onclick="sub.delRow()"><i class="fa fa-minus"> 删除</i></button><div class="col-sm-12 select-table table-striped"><table id="bootstrap-table"></table>/div></div></div></div>

        最主要的是下面的JS脚本,用户子表单的新增和功能交互:

$(function() {// 初始化数据, 可以由后台传过来var data = [{pkId: "",name: "",formula: "",orderNum: "1",}];var options = {data: data,pagination: false,showSearch: false,showRefresh: false,showToggle: false,showColumns: false,sidePagination: "client",columns: [{checkbox: true},{field: 'index',align: 'center',title: "序号",formatter: function (value, row, index) {var columnIndex = $.common.sprintf("<input type='hidden' name='index' value='%s'>", $.table.serialNumber(index));	return columnIndex + $.table.serialNumber(index);}},{field: 'name',align: 'center',title: '菜单名称',formatter: function(value, row, index) {var html = $.common.sprintf("<input class='form-control' type='text' name='recipeDetailsList[%s].name' value='%s'>", index, value);return html;}},{field: 'formula',align: 'center',title: '配方信息',formatter: function(value, row, index) {var html = $.common.sprintf("<input class='form-control' type='text' name='recipeDetailsList[%s].formula' value='%s'>", index, value);return html;}},{field: 'orderNum',align: 'center',title: '排序号',formatter: function(value, row, index) {var html = $.common.sprintf("<input class='form-control' type='text' name='recipeDetailsList[%s].orderNum' value='%s'>", index, value);return html;}},{title: '操作',align: 'center',formatter: function(value, row, index) {var value = $.common.isNotEmpty(row.index) ? row.index : $.table.serialNumber(index);return '<a class="btn btn-danger btn-xs" href="javascript:void(0)" onclick="sub.delRowByIndex(\'' + value + '\')"><i class="fa fa-remove"></i>删除</a>';}}]};$.table.init(options);});function addRow() {var count = $("#" + table.options.id).bootstrapTable('getData').length;var row = {index: $.table.serialNumber(count),name: "",formula: "",orderNum: "",}sub.addRow(row);}

        使用以上定义基本可以实现父子表单的前端定义,来看一下实际效果:

四、总结

        以上就是本文的主要内容,本文作为健康项目的中篇,将详细介绍如何对区域食谱以及食谱对应的菜单详情进行配置,通过案例的讲解,大家可以看到整个的健康管理的全貌,对涉及的相关表有一个具体的认识。本例还在场景配置中介绍如何基于ruoyi开发父子表格提交的窗口,可以为类似的需求开发做一个技术参考。通过基于 SpringBoot 和 PostgreSQL 的技术实现,我们相信能够构建出一个稳定、高效、用户友好的系统,为全国不同地区的减肥者提供科学、个性化的减肥食谱服务。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。

http://www.dtcms.com/a/499471.html

相关文章:

  • 网站建设 需要准备材料安徽六安特产有哪些
  • Qt的QT_QPA_EGLFS_INTEGRATION环境变量浅解
  • ppt设计网站有哪些银行管理系统网站建设
  • 矽塔 SA8209 输入耐压36V 8A过流保护阈值 过压过流保护芯片 SOT23
  • 【Trae】如何使用Trae编译C++(附带MinGW)
  • thinkpad t480 更换开机LOGO
  • 重庆网站建设就选承越做国外的众筹网站
  • Go基础知识(二)
  • Go小工具合集
  • Go 1.26 内置函数 new 新特性
  • 十堰微网站建设多少钱wordpress开头
  • Debian 的 网络管理器 被意外卸载,修复过程
  • 网站备案流程浏览器打不开网页是什么原因
  • Rust中字符串与格式化
  • Linux网络--6、网络层
  • 福州网站建设哪家专业怎么在自己的网站上推广业务
  • 数据结构——队列的顺序存储结构
  • Android Bootloader启动逻辑深度解析
  • 【机械臂运动学基础】变换矩阵
  • 购物网站开发意义大气广告设计网站源码 企业公司模板 dedecms5.7 企业网站
  • 包资源管理器NPM 使用
  • 在PHP框架里如何进行数据库连接?
  • 网站建设后压缩代码邢台又一地被划定高风险区域
  • 《彻底理解C语言指针全攻略(6)-- qsort、sizeof和strlen》
  • 网站开发的工资是多少wordpress 获取文章图片标题
  • C++ - List
  • 阿里服务器怎么做网站服务器上海网站制作公司介绍
  • MAC mini /绿联NAS 上安装本地AFFiNE
  • h5游戏免费下载:怪物联盟
  • 酒店网站建设方案网站验证码出不来