瑞吉外卖项目 基于spring Boot+mybatis-plus开发 超详细笔记,有源码链接
源码地址:https://gitee.com/programmer-xiao-kai/reggie_tack_out
前置知识:
- Java基础知识
- Java Web vue
- Spring Boot
- SSM
- Maven
软件开发流程
角色分工
- 项目经理:对整个项目负责,任务分配、把控进度
- 产品经理:进行需求调研,输出需求调研文档、产品原型等UI设计师:根据产品原型输出界面效果图
- 架构师:项目整体架构设计、技术选型等开发工程师:代码实现
- 测试工程师:编写测试用例,输出测试报告运维工程师:软件环境搭建、项目上线
项目简介:
本项目(瑞吉外卖)是专门为餐饮企业(餐厅、饭店)定制的一款软件产品,包括系统管理后台和移动端应用两部分。其中系统管理后台主要提供给餐饮企业内部员工使用,可以对餐厅的菜品、套餐、订单等进行管理维护。移动端应用主要提供给消费者使用,可以在线浏览菜品、添加购物车、下单等。
技术选型:
功能架构:
角色:
- 后台系统管理员:登录后台管理系统,拥有后台系统中的所有权限
- 后台系统普通员工:登录后台管理系统,对菜品、套餐、订单等进行管理。
开发环境搭建
数据库环境搭建
数据库表
后台登录功能开发
开发步骤:
-
创建一个实体类Employee和employee表进行映射
-
创建Controller,Service,Mapper
-
导入返回结果类R
此类是一个通用类R,服务端响应的所有结果最终都会包装成此种类型返回给前端页面
- 在Controller中创建登录方法
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;/*** 员工登录* @param request* @param employee* @return*/@PostMapping("/login")public R<Employee> login(HttpServletRequest request,@RequestBody Employee employee){//1、将页面提交的密码password进行md5加密处理String password = employee.getPassword();password = DigestUtils.md5DigestAsHex(password.getBytes());//2、根据页面提交的用户名username查询数据库LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Employee::getUsername,employee.getUsername());Employee emp = employeeService.getOne(queryWrapper);//3、如果没有查询到则返回登录失败结果if(emp == null){return R.error("登录失败");}//4、密码比对,如果不一致则返回登录失败结果if(!emp.getPassword().equals(password)){return R.error("登录失败");}//5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果if(emp.getStatus() == 0){return R.error("账号已禁用");}//6、登录成功,将员工id存入Session并返回登录成功结果request.getSession().setAttribute("employee",emp.getId());return R.success(emp);}
}
处理逻辑如下:
- 将页面提交的密码password进行MD5加密处理
- 根据页面提交的用户名username查询数据库
- 如果没有查询到则返回登录失败结果
- 密码比对,如果不一致则返回登录失败结果
- 查看员工状态,如果为禁用状态,则返回员工已经禁用结果
- 登录成功,将员工id存入Session并返回登录成功结果
后台退出功能开发
用户点击页面中退出按钮,发送请求,请求地址为/employee/logout,请求方式为POST
- 清理Session中的用户id;
- 返回结果
/*** 员工退出* @param request* @return*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){//清理Session中保存的当前登录员工的idrequest.getSession().removeAttribute("employee");return R.success("退出成功");
}
员工管理后台开发
完善登录功能
方法:使用过滤器或者拦截器,中判断用户是否已经完成登录,如果没有登录则跳转到登录页面
- 获取本次请求的URI
- 判断本次请求是否需要处理
- 如果不需要处理,则直接放行
- 判断登录状态,如果一登录,则直接放行
- 如果未登录则返回结果直接放行
- 如果未登录则返回未登录的结果
新增员工
- 需求分析
- 数据模型
- 代码开发
(1)、页面发送ajax请求,将新增员工页面中输入的数据以json的数据形式提交到服务端
(2)、服务端Controller接收页面提交的数据并调用Service将数据进行保存
(3)、Service调用Mapper操作数据库,保存数据
- 功能测试
/*** 新增员工* @param employee* @return*/
@PostMapping
public R<String> save(HttpServletRequest request,@RequestBody Employee employee){log.info("新增员工,员工信息:{}",employee.toString());//设置初始密码123456,需要进行md5加密处理employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));//此部分抽取到common处//employee.setCreateTime(LocalDateTime.now());//employee.setUpdateTime(LocalDateTime.now());//获得当前登录用户的id//Long empId = (Long) request.getSession().getAttribute("employee");//employee.setCreateUser(empId);//employee.setUpdateUser(empId);employeeService.save(employee);return R.success("新增员工成功");
}
员工信息分页查询
- 需求分析
- 代码开发
- 页面发送ajax请求,将分页查询参数(page,pageSize,name) 提交到服务端
- 服务端Controller接收页面提交的数据并调用Service查询数据
- Service调用Mapper操作数据库,查询分页数据
- Controller将查询到的分页数据响应给页面
- 页面接收到分页数据并通过ElementUI的Table组件展示到页面上
- 功能测试
/*** 员工信息分页查询* @param page* @param pageSize* @param name* @return*/
@GetMapping("/page")
public R<Page> page(int page,int pageSize,String name){log.info("page = {},pageSize = {},name = {}" ,page,pageSize,name);//构造分页构造器Page pageInfo = new Page(page,pageSize);//构造条件构造器LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper();//添加过滤条件queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);//添加排序条件queryWrapper.orderByDesc(Employee::getUpdateTime);//执行查询employeeService.page(pageInfo,queryWrapper);return R.success(pageInfo);
}
启动/禁用员工账号
- 需求分析
在员工管理列表页面,可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登录系统,启用后的员工可以正常登录。
需要注意,只有管理员(admin用户)才可以对其他普通用户进行启动、禁用等操作,所以普通的用户登录系统后启动、禁用annual不显示。
- 代码开发
启用、禁用员工账号、本质上就是一个更新操作,也就是对status状态字段进行操作,在controller进行update的方法,此方法就是一个通用的修改员工的办法。
- 页面发送ajax请求,将参数(id,status)提交给服务端
- 服务端Controller接收页面提交的数据并调用Service更新数据
- Service调用Mapper操作数据库
- 功能测试
问题描述:
通过观察控制台输出的SQL页面发现页面传递过来的员工id的值和数据库中的id值不一样,由于分页查询时js对long型数据进行处理时丢失精度,导致提交的id和数据库中的值不一致
解决办法:
我们可以在服务端给页面响应json数据时处理,将long型数据统一转为字符串。
- 代码修复
修改员工信息
- 需求分析
在员工管理列表页面点击编辑按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击保存按钮。完成编辑操作
- 代码开发
- 点击编辑按钮时,页面跳转到add.html,并在url中携带参数[员工id]
- 在add.html页面获取url中的参数[员工id]
- 发送ajax请求,请求服务端,同时提交员工id参数
- 服务端接收请求,根据员工id查询员工信息,将员工信息以json形式响应给页面
- 页面接收服务端响应的json数据,通过VUE的数据绑定进行员工信息回显
- 点击保存按钮,发送ajax请求,将页面中的员工信息以json方式提交给
- 服务端服务端接收员工信息,并进行处理,完成后给页面响应
- 页面接收到服务端响应信息后进行相应处理
- 功能测试
/*** 根据id修改员工信息* @param employee* @return*/
@PutMapping
public R<String> update(HttpServletRequest request,@RequestBody Employee employee){log.info(employee.toString());long id = Thread.currentThread().getId();log.info("线程id为:{}",id);//此部分抽取到common处//Long empId = (Long)request.getSession().getAttribute("employee");//employee.setUpdateTime(LocalDateTime.now());//employee.setUpdateUser(empId);employeeService.updateById(employee);return R.success("员工信息修改成功");
}
分类管理业务开发
公共字段自动填充
- 问题分析
对于新增员工时需要设置的创建时间,创建人,修改时间,修改人等字段,在编辑员工时需要设置修改时间和修改人等字段。
- 代码实现
MybatisPlus 公共字段自动填充,也就是在插入或者更新的时候为指定的字段,提供赋予指定的值,使用它的好处就是可以统一进行处理,避免了重复的代码。
- 在实体类的属性上加入@TableField注解,指定自动填充的策略
- 按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口
- 功能测试
- 功能完善
还有一个小问题就是我们在自动填充createUser和updateUser时,我们的UserID没有动态获取到Id的值,故我们需要改造成动态获取当前用户的id
实现步骤:
- 编写BaseContext工具类,基于ThreadLocal封装的工具类
- 在LoginCheckFilter的doFilter方法中调用BaseContext来设置当前登录用户的id
- 在MymetaObjectHandler的方法中调用BaseContext获取用户的id
/*** 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id*/
public class BaseContext {private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();/*** 设置值* @param id*/public static void setCurrentId(Long id){threadLocal.set(id);}/*** 获取值* @return*/public static Long getCurrentId(){return threadLocal.get();}
}
新增分类
- 需求分析管理分类信息,分类包括两种类型,分别是菜品分类和套餐分类。当我们在后台系统中添加菜品时需要选择一个菜品分类,当我们在后台系统中添加一个套餐时需要选择一个套餐分类。
后台系统在可以
- 数据模型
- 代码开发
- 实体类Category
- Mapper接口CategoryMapper
- 业务层接口CategoryService
- 业务实现类CategoryServiceImpl
- 控制层CategoryController
页面(backend/page/category/list.html)发送ajax请求,将新增分类窗口输入的数据以json形式提交到服务端服务端Controller接收页面提交的数据并调用Service将数据进行保存
Service调用Mapper操作数据库,保存数据
- 功能测试
@Autowiredprivate CategoryService categoryService;/*** 新增分类* @param category* @return*/@PostMappingpublic R<String> save(@RequestBody Category category){log.info("category:{}",category);categoryService.save(category);return R.success("新增分类成功");}
分类信息分页查询
-
需求分析
-
代码开发
- 页面发送ajax请求,将分页查询参数(page、pageSize)提交到服务端
- 服务端Controller接收页面提交的数据并调用Service查询数据
- Service调用Mapper操作数据库,查询分页数据
- Controller将查询到的分页数据响应给页面
- 页面接收到分页数据并通过ElementUl的Table组件展示到页面上
- 功能测试
/*** 分页查询* @param page* @param pageSize* @return*/@GetMapping("/page")public R<Page> page(int page,int pageSize){//分页构造器Page<Category> pageInfo = new Page<>(page,pageSize);//条件构造器LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();//添加排序条件,根据sort进行排序queryWrapper.orderByAsc(Category::getSort);//分页查询categoryService.page(pageInfo,queryWrapper);return R.success(pageInfo);}
删除分类
- 需求分析
- 代码开发
- 页面发送ajax请求,将参数(id)提交到服务端
- 服务端Controller接收页面提交的数据并调用Service删除数据
- Service调用Mapper操作数据库
- 功能测试
/*** 根据id删除分类* @param id* @return*/
@DeleteMapping
public R<String> delete(Long id){log.info("删除分类,id为:{}",id);//categoryService.removeById(id);categoryService.remove(id);return R.success("分类信息删除成功");
}
- 功能完善
前面我们已经实现了根据id删除分类的功能,但是并没有检查删除的分类是否关联了菜品或者套餐,所以我们需要进行功能完善。
要完善分类删除功能,需要先准备基础的类和接口:
1、实体类Dish和Setmeal
2、Mapper接口DishMapper和SetmealMapper
3、Service接口DishService和SetmealService
4、Service实现类DishServicelmpl和SetmealServicelmpl
public interface SetmealService extends IService<Setmeal> {/*** 新增套餐,同时需要保存套餐和菜品的关联关系* @param setmealDto*/public void saveWithDish(SetmealDto setmealDto);/*** 删除套餐,同时需要删除套餐和菜品的关联数据* @param ids*/public void removeWithDish(List<Long> ids);
}
修改分类
在完成管理列表页面点击修改按钮,弹出修改窗口回显分类信息并进行修改,最后点击确定按钮完成修改操作。
文件上传下载
文件上传介绍
文件上传,也称为upload,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。
文件上传时,对页面的form表单由如下要求:
- method=“post” 采用post方式提交数据
- enctype=“multipart/form-data” 采用multipart格式上传文件
- type=“file” 使用input的file控件上床
<form method="post" action="/common/upload" enctype="multipart/form-data"><input name="myFile" type="file" /><input type="submit" value="提交"/>
</form>
文件上传是的输入框 必须是post
文件下载,也称为download,是指将文件从服务器传输到本地计算机的过程。
通过浏览器进行文件下载,通常有两种表现形式:
- 以附件形式下载,弹出保存对话框,将文件保存到指定磁盘目录
- 直接在浏览器中打开
通过浏览器进行文件下载,本质上就是服务端将文件以流的形式写回浏览器的过程。
文件的上传和下载代码实现:
文件上传,y
新增菜品
需求分析
数据模型
新增菜品,其实就是将新增页面录入的菜品信息插入到dish表,如果添加了口味做法,还需要向dish_flavor表插入数据。所以在新增菜品时,涉及到两个表:
代码开发
在开发业务之前,先将需要用到的类和接口基本结构创建好:
- 实体类DishFlavor
- Mapper接口DishFlavorMapper
- 业务层接口实现类
- 业务层实现类DishFlavorServiceIMpl
- 控制层DishController
代码完善
后台系统中可以管理菜品信息,通过新增功能莱添茄一个新的菜品,在添加菜品时需要选择当前菜品所属的菜品分类,并且需要上传菜品图片,在移动端会按照菜品分类来展示对应的菜品信息
在开发代码之前,需要梳理一下新增菜品时前端页面和服务器的交互过程:
- 页面backend/page/food/add.html发送ajax请求,请求服务端获取菜品分类数据并显示到下拉框中
DTO,全称为Data Transfer Object,即数据传输对象,一般用于展示层与服务层之间的数据传输。
菜品信息分页查询
- 需求分许
系统中的菜品数据很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。
- 代码开发
- 页面(backend/page/food/list/html)发送ajax请求,将分页查询参数(page、pageSize,name)提交到服务端,获取分页数据
- 页面发送请求,请求服务端进行图片下载,用于页面图片展示
开发菜品信息分页查询功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可。
- 功能测试
修改菜品
需求分析
在菜品管理列表页面点击修改按钮,跳转到修改菜品页面,在修改页面回显菜品相关信息并进行修改,最后点击确定按钮完成修改操作
代码开发-梳理交互过程
- 页面发送ajax请求,请求服务器获取分类数据,用于菜品分类下拉框中数据显示
- 页面发送ajax请求,请求服务端,根据id查询当前菜品信息,用于菜品信息回显
- 页面发送ajax请求,请求服务端进行图片下载,用于页面图片回显
- 点击保存,页面发送ajax请求,将修改后的菜品相关信息数据以json的格式提交到服务端
功能测试
代码完善
套餐业务开发
新增套餐
需求分析
后台系统中可以管理套餐信息,通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐。
数据模型
新增套餐,其实就是将新增页面录入的套餐信息插入到setmeal表,还需要向setmeal_dish表插入套餐和菜品关联数据。所以在新增套餐时,涉及到两个表:
- setmeal 套餐表
- setmeal_dish 套餐菜品关系表
代码开发
- 实体类SetmealDish
- DTO SetmealDto
- Mapper接口SetmealDishService
- 业务层实现类 SetmealDishServiceImpl
- 控制层SetmealController
代码开发——梳理交互过程
- 页面(backend/page/combo/add.html)发送ajax请求,请求服务端获取套餐分类数据并展示到下拉框中
- 页面发送ajax请求,请求服务端获取菜品分类数据并展示到添加菜品窗口中
- 页面发送ajax请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中
- 页面发送请求进行图片上传,请求服务端将图片保存到服务器
- 页面发送请求进行图片下载,将上传的图片进行回显
- 点击保存按钮,发送ajax请求,将套餐相关数据以json形式提交到服务端
短信发送
短信服务介绍:
这些第三方短信服务会和各个运营商(移动、联通、电信)对接,我们只需要注册称为会员并且按照开发文档进行调用就可以发送信息
常用短信服务:
阿里云短信服务介绍:
验证码、短信通知、推广短信
腾讯云
京东梦网
乐信
代码开发
使用阿里云短信服务发送短信,可以参考官方提供的文档即可
具体开发步骤:
- 导入maven
- 调用API
手机验证码登录
手机验证码登录方式,方便快捷,安全,没有传统的用户名
数据模型
通过手机验证码登录时,涉及到的为user表,即用户表
代码开发-梳理交互过程
- 在登录之前(front/page/login.html)输入手机号,点击【获取验证码】按钮,页面发送ajax请求,在服务端调用短信服务API给指定手机号发送验证码短信
- 在页面登录输入验证码,点击【登录】按钮,发送ajax请求,在服务端处理登录请求。
菜品展示,购物车,下单
- 导入用户地址薄相关功能代码
地址簿,指的是移动端消费者用户的地址信息,用户登录成功后可以维护自己的地址信息,但是同一个用户只能有一个默认地址
数据模型
用户的地址信息会存储在address_book表中,即地址簿
- 菜品展示
代码开发——梳理交互过程
- 交互页面(front/index.html)发送ajax请求,获取分类数据(菜品分类和套餐分类)
- 页面发送ajax请求,获取第一个分类下的菜品或者套餐
购物车功能模块开发
代码开发准备,先将需要用到的类和接口基本结构创建好:
- 实体类ShoppingCart
- Mapper接口ShoppingCartMapper
- 业务层接口ShoppingCartService
- 业务层实现类ShoppingCartServiceImpl
- 控制层ShoppingCartCont
- 导入maven
- 调用API
手机验证码登录
手机验证码登录方式,方便快捷,安全,没有传统的用户名
数据模型
通过手机验证码登录时,涉及到的为user表,即用户表
代码开发-梳理交互过程
- 在登录之前(front/page/login.html)输入手机号,点击【获取验证码】按钮,页面发送ajax请求,在服务端调用短信服务API给指定手机号发送验证码短信
- 在页面登录输入验证码,点击【登录】按钮,发送ajax请求,在服务端处理登录请求。
菜品展示,购物车,下单
- 导入用户地址薄相关功能代码
地址簿,指的是移动端消费者用户的地址信息,用户登录成功后可以维护自己的地址信息,但是同一个用户只能有一个默认地址
数据模型
用户的地址信息会存储在address_book表中,即地址簿
- 菜品展示
代码开发——梳理交互过程
- 交互页面(front/index.html)发送ajax请求,获取分类数据(菜品分类和套餐分类)
- 页面发送ajax请求,获取第一个分类下的菜品或者套餐
购物车功能模块开发
代码开发准备,先将需要用到的类和接口基本结构创建好:
- 实体类ShoppingCart
- Mapper接口ShoppingCartMapper
- 业务层接口ShoppingCartService
- 业务层实现类ShoppingCartServiceImpl
- 控制层ShoppingCartCont
相关文章:

瑞吉外卖项目 基于spring Boot+mybatis-plus开发 超详细笔记,有源码链接
源码地址:https://gitee.com/programmer-xiao-kai/reggie_tack_out 前置知识: Java基础知识Java Web vueSpring BootSSMMaven 软件开发流程 角色分工 项目经理:对整个项目负责,任务分配、把控进度产品经理:进行需求调研,输出需…...

Redis Cluster 在Spring中遇到的问题
Redis集群配置可能会在运行时更改。可以添加新节点,可以更改特定插槽的主节点。还有可能因为master宕机或网络抖动等原因,引起了主从切换。 无法感知集群槽位变化 SpringBoot2.x 开始默认使用的 Redis 客户端由 Jedis 变成了 Lettuce,但是当…...
linux远程桌面管理工具 xrdp
Xrdp 是一个微软远程桌面协议(RDP)的开源实现,它允许你通过图形界面控制远程系统。通过 RDP,你可以登录远程机器,并且创建一个真实的桌面会话,就像你登录本地机器一样。 如何在Ubuntu 20.04 上安装 Xrdp 服…...

硬件-8-操作系统的历史
操作系统的最强入门科普(Unix/Linux篇) 操作系统的发展史(DOS/Windows篇) Mac操作系统进化史 手机操作系统的沉浮往事(上) 手机操作系统的沉浮往事(下) 1 操作系统种类 我们天天都…...
self.register_buffer()中的值发生变化
PyTorch中定义模型时,有时候会遇到self.register_buffer(name, Tensor)的操作,该方法的作用是定义一组参数,该组参数的特别之处在于:模型训练时不会更新(即调用 optimizer.step() 后该组参数不会变化,只可人…...
[Tools: Pycharm] Bug合集
1. Debug mode:Pycharm不显示变量值(Unable to display frame variables);在python console中交互不输出值 选择Gevent compatible:File > Settings > Build, Execution, Deployment > Python Debugger >…...

【JAVASE】循环结构
⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈Java 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 循环 1. 循环结构1.1 while 循环1.2 bre…...

NoSQL之Redis配置使用
目录 一、关系数据库与非关系型数据库 1.1.关系型数据库的概述 1.2关系型数据库的优缺点 1.2.1优点 1.2.2缺点 1.3.非关系型数据库的概述 二.关系数据库与非关系型数据库的区别 2.1数据存储方式不同 2.2扩展方式不同 2.3对事务性的支持不同 2.4非关系型数据库产生背景 2…...
Ansible最佳实践之Playbook使用过滤器处理网络地址
写在前面 使用过滤器检查、验证和操作包含网络信息的变量理解不足小伙伴帮忙指正 傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去…...

测试常见前端bug
目录 协作 测试方法 标签:标签 内容/ref/ 判断 arr&&arr.length 交互 样式不生效:devtools查找,编译前的标签,运行时不一定存在 可交互的需要提示 hover样式 没有交互逻辑,就不要设置交互 无法交互…...

【Python数据分析】Python常用内置函数(一)
🎉欢迎来到Python专栏~Python常用内置函数(一) ☆* o(≧▽≦)o *☆嗨~我是小夏与酒🍹 ✨博客主页:小夏与酒的博客 🎈该系列文章专栏:Python学习专栏 文章作者技术和水平有限,如果文…...

OpenCV图像处理-图像分割-MeanShift
MeanShift 1. 基本概念2.代码示例 1. 基本概念 MeanShift严格说来并不是用来对图像进行分割的,而是在色彩层面的平滑滤波。它会中和色彩分布相近的颜色,平滑色彩细节,侵蚀掉面积较小的的颜色区域,它以图像上任意一点P为圆心&…...
【Rust 基础篇】Rust Trait 实现:灵活的接口抽象
导言 Rust是一种以安全性和高效性著称的系统级编程语言,其设计哲学是在不损失性能的前提下,保障代码的内存安全和线程安全。为了实现这一目标,Rust引入了"所有权系统"、"借用检查器"等特性,有效地避免了常见…...

【嵌入式Linux项目】基于Linux的全志H616开发板智能家居项目(语音控制、人脸识别、安卓APP和PC端QT客户端远程操控)有视频功能展示
目录 一、功能需求 二、开发环境 1、硬件: 2、软件: 3、引脚分配: 三、关键点 1、设计模式之工厂模式 2、wiringPi库下的相关硬件操作函数调用 3、语音模块的串口通信 4、线程 5、摄像头的实时监控和拍照功能 6、人脸识别 四、编…...
ElasticSearch基础篇-条件查询与映射
ElasticSearch基础篇二 条件查询 GET http://10.192.193.98:9200/shopping/_search?qtitle:小米手机q:代表查询条件 响应结果 {"took": 772,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped…...

大模型部署框架 FastLLM 实现细节解析
0x0. 前言 接着 大模型部署框架 FastLLM 简要解析 这篇文章首先梳理了一下FastLLM的调用链和关键的数据结构,然后解析了 FastLLM 的一些实现细节和CPU/GPU后端实现采用的优化技巧。 0x1. 调用链和数据结构解析 以chatglm-6b的支持为例,函数入口在 htt…...

Flutter ios真机调试连接断开后应用闪退
使用ios真机调试的时候,能正常打开应用,但是当数据线断开连接的时候,应用就会关闭,重新打开就会闪退。 原因是flutter默认在开发过程中使用debug模式编译 只需要将debug选择为release 重新编译就行。...
序列化,反序列化之实例
别怕,我一直陪着你 一.知识1.魔术方法 二.实例1.绕过__wakeup, private2.php://filter, data://, __tostring3. 一.知识 1.魔术方法 __construct() 当一个对象创建时自动调用 __destruct() 当对象被销毁时自动调用 (php绝大多数情况下会自动调用销毁对象) __sleep…...
2022年全国职业院校技能大赛(高职组)“软件测试”赛项竞赛任务书
2022年全国职业院校技能大赛(高职组) “软件测试”赛项竞赛任务书 2022年7月 一、竞赛时间、内容及成绩组成 (一)竞赛时间 本阶段竞赛时间共为8小时,参赛选手自行安排任务进度,休息、饮水、如厕等不设专…...
第18节:R语言分析:临床安全性数据的数据分析
临床安全性数据的数据分析 背景 医疗器械临床试验中收集的数据的主要组成部分是关于患者安全的。 不良事件被定义为“受试者、使用者或其他人的任何不良医疗事件、非预期疾病或伤害,或不良临床体征(包括异常实验室发现),无论是否与研究医疗器械相关”。 收集并用于此数据…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

OPENCV图形计算面积、弧长API讲解(1)
一.OPENCV图形面积、弧长计算的API介绍 之前我们已经把图形轮廓的检测、画框等功能讲解了一遍。那今天我们主要结合轮廓检测的API去计算图形的面积,这些面积可以是矩形、圆形等等。图形面积计算和弧长计算常用于车辆识别、桥梁识别等重要功能,常用的API…...

【Vue】scoped+组件通信+props校验
【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性, 令样式只作用于当前组件的标签 作用:防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...