Java项目-苍穹外卖-Day05
文章目录
- 1. 新增套餐
- 1.1 需求分析和设计
- 1.2 代码实现
- 1.2.1 DishController
- 1.2.2 DishService
- 1.2.3 DishServiceImpl
- 1.2.4 DishMapper
- 1.2.5 DishMapper.xml
- 1.2.6 SetmealController
- 1.2.7 SetmealService
- 1.2.8 SetmealServiceImpl
- 1.2.9 SetmealMapper
- 1.2.10 SetmealMapper.xml
- 1.2.11 SetmealDishMapper
- 1.2.12 SetmealDishMapper.xml
- 1.3 功能测试
- 2. 套餐分页查询
- 2.1 需求分析和设计
- 2.2 代码实现
- 2.2.1 SetmealController
- 2.2.2 SetmealService
- 2.2.3 SetmealServiceImpl
- 2.2.4 SetmealMapper
- 2.2.5 SetmealMapper.xml
- 2.3 功能测试
- 3. 删除套餐
- 3.1 需求分析和设计
- 3.2 代码实现
- 3.2.1 SetmealController
- 3.2.2 SetmealService
- 3.2.3 SetmealServiceImpl
- 3.2.4 SetmealMapper
- 3.2.5 SetmealDishMapper
- 3.3 功能测试
- 4. 修改套餐
- 4.1 需求分析和设计
- 4.2 代码实现
- 4.2.1 SetmealController
- 4.2.2 SetmealService
- 4.2.3 SetmealServiceImpl
- 4.2.4 SetmealDishMapper
- 4.3 功能测试
- 5. 起售停售套餐
- 5.1 需求分析和设计
- 5.2 代码实现
- 5.2.1 SetmealController
- 5.2.2 SetmealService
- 5.2.3 SetmealServiceImpl
- 5.2.4 DishMapper
- 5.3 功能测试
主要是写代码
完成套餐功能
和之前那个菜品类似
这里我懒得贴我的代码了
写一下改的几个bug
1.修改菜品关联套餐的时候,对应的菜品关联数据要setSetmealId一下,因为接收数据是赋不到那个关联的ID值的,如果不设置新增的话对应的setmealID就会为null
2.注意,修改套餐为可售时,里面的菜品必须全为可售!
3.还有就是写动态sql的问题了,这部分基本就是我自己的问题

1. 新增套餐
1.1 需求分析和设计
业务规则:
- 套餐名称唯一
- 套餐必须属于某个分类
- 套餐必须包含菜品
- 名称、分类、价格、图片为必填项
- 添加菜品窗口需要根据分类类型来展示菜品
- 新增的套餐默认为停售状态
接口设计(共涉及到4个接口):
- 根据类型查询分类(已完成)
- 根据分类id查询菜品
- 图片上传(已完成)
- 新增套餐
setmeal表为套餐表,用于存储套餐的信息。具体表结构如下:
字段名 | 数据类型 | 说明 | 备注 |
---|---|---|---|
id | bigint | 主键 | 自增 |
name | varchar(32) | 套餐名称 | 唯一 |
category_id | bigint | 分类id | 逻辑外键 |
price | decimal(10,2) | 套餐价格 | |
image | varchar(255) | 图片路径 | |
description | varchar(255) | 套餐描述 | |
status | int | 售卖状态 | 1起售 0停售 |
create_time | datetime | 创建时间 | |
update_time | datetime | 最后修改时间 | |
create_user | bigint | 创建人id | |
update_user | bigint | 最后修改人id |
setmeal_dish表为套餐菜品关系表,用于存储套餐和菜品的关联关系。具体表结构如下:
字段名 | 数据类型 | 说明 | 备注 |
---|---|---|---|
id | bigint | 主键 | 自增 |
setmeal_id | bigint | 套餐id | 逻辑外键 |
dish_id | bigint | 菜品id | 逻辑外键 |
name | varchar(32) | 菜品名称 | 冗余字段 |
price | decimal(10,2) | 菜品单价 | 冗余字段 |
copies | int | 菜品份数 |
1.2 代码实现
1.2.1 DishController
/*** 根据分类id查询菜品* @param categoryId* @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<Dish>> list(Long categoryId){List<Dish> list = dishService.list(categoryId);return Result.success(list);
}
1.2.2 DishService
/*** 根据分类id查询菜品* @param categoryId* @return
*/
List<Dish> list(Long categoryId);
1.2.3 DishServiceImpl
/*** 根据分类id查询菜品* @param categoryId* @return
*/
public List<Dish> list(Long categoryId) {Dish dish = Dish.builder().categoryId(categoryId).status(StatusConstant.ENABLE).build();return dishMapper.list(dish);
}
1.2.4 DishMapper
/*** 动态条件查询菜品* @param dish* @return
*/
List<Dish> list(Dish dish);
1.2.5 DishMapper.xml
<select id="list" resultType="Dish" parameterType="Dish">select * from dish<where><if test="name != null">and name like concat('%',#{name},'%')</if><if test="categoryId != null">and category_id = #{categoryId}</if><if test="status != null">and status = #{status}</if></where>order by create_time desc
</select>
1.2.6 SetmealController
/*** 套餐管理*/
@RestController
@RequestMapping("/admin/setmeal")
@Api(tags = "套餐相关接口")
@Slf4j
public class SetmealController {@Autowiredprivate SetmealService setmealService;/*** 新增套餐* @param setmealDTO* @return*/@PostMapping@ApiOperation("新增套餐")public Result save(@RequestBody SetmealDTO setmealDTO) {setmealService.saveWithDish(setmealDTO);return Result.success();}
}
1.2.7 SetmealService
public interface SetmealService {/*** 新增套餐,同时需要保存套餐和菜品的关联关系* @param setmealDTO*/void saveWithDish(SetmealDTO setmealDTO);
}
1.2.8 SetmealServiceImpl
/*** 套餐业务实现*/
@Service
@Slf4j
public class SetmealServiceImpl implements SetmealService {@Autowiredprivate SetmealMapper setmealMapper;@Autowiredprivate SetmealDishMapper setmealDishMapper;@Autowiredprivate DishMapper dishMapper;/*** 新增套餐,同时需要保存套餐和菜品的关联关系* @param setmealDTO*/@Transactionalpublic void saveWithDish(SetmealDTO setmealDTO) {Setmeal setmeal = new Setmeal();BeanUtils.copyProperties(setmealDTO, setmeal);//向套餐表插入数据setmealMapper.insert(setmeal);//获取生成的套餐idLong setmealId = setmeal.getId();List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();setmealDishes.forEach(setmealDish -> {setmealDish.setSetmealId(setmealId);});//保存套餐和菜品的关联关系setmealDishMapper.insertBatch(setmealDishes);}
}
1.2.9 SetmealMapper
/*** 新增套餐* @param setmeal
*/
@AutoFill(OperationType.INSERT)
void insert(Setmeal setmeal);
1.2.10 SetmealMapper.xml
<insert id="insert" parameterType="Setmeal" useGeneratedKeys="true" keyProperty="id">insert into setmeal(category_id, name, price, status, description, image, create_time, update_time, create_user, update_user)values (#{categoryId}, #{name}, #{price}, #{status}, #{description}, #{image}, #{createTime}, #{updateTime},#{createUser}, #{updateUser})
</insert>
1.2.11 SetmealDishMapper
/*** 批量保存套餐和菜品的关联关系* @param setmealDishes
*/
void insertBatch(List<SetmealDish> setmealDishes);
1.2.12 SetmealDishMapper.xml
<insert id="insertBatch" parameterType="list">insert into setmeal_dish(setmeal_id,dish_id,name,price,copies)values<foreach collection="setmealDishes" item="sd" separator=",">(#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})</foreach>
</insert>
1.3 功能测试
略
2. 套餐分页查询
2.1 需求分析和设计
略
2.2 代码实现
2.2.1 SetmealController
/*** 分页查询* @param setmealPageQueryDTO* @return
*/
@GetMapping("/page")
@ApiOperation("分页查询")
public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO) {PageResult pageResult = setmealService.pageQuery(setmealPageQueryDTO);return Result.success(pageResult);
}
2.2.2 SetmealService
/*** 分页查询* @param setmealPageQueryDTO* @return
*/
PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
2.2.3 SetmealServiceImpl
/*** 分页查询* @param setmealPageQueryDTO* @return
*/
public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {int pageNum = setmealPageQueryDTO.getPage();int pageSize = setmealPageQueryDTO.getPageSize();PageHelper.startPage(pageNum, pageSize);Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);return new PageResult(page.getTotal(), page.getResult());
}
2.2.4 SetmealMapper
/*** 分页查询* @param setmealPageQueryDTO* @return
*/
Page<SetmealVO> pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
2.2.5 SetmealMapper.xml
<select id="pageQuery" resultType="com.sky.vo.SetmealVO">selects.*,c.name categoryNamefromsetmeal sleft joincategory cons.category_id = c.id<where><if test="name != null">and s.name like concat('%',#{name},'%')</if><if test="status != null">and s.status = #{status}</if><if test="categoryId != null">and s.category_id = #{categoryId}</if></where>order by s.create_time desc
</select>
2.3 功能测试
略
3. 删除套餐
3.1 需求分析和设计
业务规则:
- 可以一次删除一个套餐,也可以批量删除套餐
- 起售中的套餐不能删除
3.2 代码实现
3.2.1 SetmealController
/*** 批量删除套餐* @param ids* @return
*/
@DeleteMapping
@ApiOperation("批量删除套餐")
public Result delete(@RequestParam List<Long> ids){setmealService.deleteBatch(ids);return Result.success();
}
3.2.2 SetmealService
/*** 批量删除套餐* @param ids
*/
void deleteBatch(List<Long> ids);
3.2.3 SetmealServiceImpl
/*** 批量删除套餐* @param ids
*/
@Transactional
public void deleteBatch(List<Long> ids) {ids.forEach(id -> {Setmeal setmeal = setmealMapper.getById(id);if(StatusConstant.ENABLE == setmeal.getStatus()){//起售中的套餐不能删除throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);}});ids.forEach(setmealId -> {//删除套餐表中的数据setmealMapper.deleteById(setmealId);//删除套餐菜品关系表中的数据setmealDishMapper.deleteBySetmealId(setmealId);});
}
3.2.4 SetmealMapper
/*** 根据id查询套餐* @param id* @return
*/
@Select("select * from setmeal where id = #{id}")
Setmeal getById(Long id);/*** 根据id删除套餐* @param setmealId
*/
@Delete("delete from setmeal where id = #{id}")
void deleteById(Long setmealId);
3.2.5 SetmealDishMapper
/*** 根据套餐id删除套餐和菜品的关联关系* @param setmealId
*/
@Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")
void deleteBySetmealId(Long setmealId);
3.3 功能测试
略
4. 修改套餐
4.1 需求分析和设计
接口设计(共涉及到5个接口):
- 根据id查询套餐
- 根据类型查询分类(已完成)
- 根据分类id查询菜品(已完成)
- 图片上传(已完成)
- 修改套餐
4.2 代码实现
4.2.1 SetmealController
/*** 根据id查询套餐,用于修改页面回显数据** @param id* @return
*/
@GetMapping("/{id}")
@ApiOperation("根据id查询套餐")
public Result<SetmealVO> getById(@PathVariable Long id) {SetmealVO setmealVO = setmealService.getByIdWithDish(id);return Result.success(setmealVO);
}/*** 修改套餐** @param setmealDTO* @return
*/
@PutMapping
@ApiOperation("修改套餐")
public Result update(@RequestBody SetmealDTO setmealDTO) {setmealService.update(setmealDTO);return Result.success();
}
4.2.2 SetmealService
/*** 根据id查询套餐和关联的菜品数据* @param id* @return
*/
SetmealVO getByIdWithDish(Long id);/*** 修改套餐* @param setmealDTO
*/
void update(SetmealDTO setmealDTO);
4.2.3 SetmealServiceImpl
/*** 根据id查询套餐和套餐菜品关系** @param id* @return
*/
public SetmealVO getByIdWithDish(Long id) {Setmeal setmeal = setmealMapper.getById(id);List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealId(id);SetmealVO setmealVO = new SetmealVO();BeanUtils.copyProperties(setmeal, setmealVO);setmealVO.setSetmealDishes(setmealDishes);return setmealVO;
}/*** 修改套餐** @param setmealDTO
*/
@Transactional
public void update(SetmealDTO setmealDTO) {Setmeal setmeal = new Setmeal();BeanUtils.copyProperties(setmealDTO, setmeal);//1、修改套餐表,执行updatesetmealMapper.update(setmeal);//套餐idLong setmealId = setmealDTO.getId();//2、删除套餐和菜品的关联关系,操作setmeal_dish表,执行deletesetmealDishMapper.deleteBySetmealId(setmealId);List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();setmealDishes.forEach(setmealDish -> {setmealDish.setSetmealId(setmealId);});//3、重新插入套餐和菜品的关联关系,操作setmeal_dish表,执行insertsetmealDishMapper.insertBatch(setmealDishes);
}
4.2.4 SetmealDishMapper
/*** 根据套餐id查询套餐和菜品的关联关系* @param setmealId* @return*/@Select("select * from setmeal_dish where setmeal_id = #{setmealId}")List<SetmealDish> getBySetmealId(Long setmealId);
4.3 功能测试
略
5. 起售停售套餐
5.1 需求分析和设计
业务规则:
- 可以对状态为起售的套餐进行停售操作,可以对状态为停售的套餐进行起售操作
- 起售的套餐可以展示在用户端,停售的套餐不能展示在用户端
- 起售套餐时,如果套餐内包含停售的菜品,则不能起售
5.2 代码实现
5.2.1 SetmealController
/*** 套餐起售停售* @param status* @param id* @return
*/
@PostMapping("/status/{status}")
@ApiOperation("套餐起售停售")
public Result startOrStop(@PathVariable Integer status, Long id) {setmealService.startOrStop(status, id);return Result.success();
}
5.2.2 SetmealService
/*** 套餐起售、停售* @param status* @param id
*/
void startOrStop(Integer status, Long id);
5.2.3 SetmealServiceImpl
/*** 套餐起售、停售* @param status* @param id
*/
public void startOrStop(Integer status, Long id) {//起售套餐时,判断套餐内是否有停售菜品,有停售菜品提示"套餐内包含未启售菜品,无法启售"if(status == StatusConstant.ENABLE){//select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = ?List<Dish> dishList = dishMapper.getBySetmealId(id);if(dishList != null && dishList.size() > 0){dishList.forEach(dish -> {if(StatusConstant.DISABLE == dish.getStatus()){throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);}});}}Setmeal setmeal = Setmeal.builder().id(id).status(status).build();setmealMapper.update(setmeal);
}
5.2.4 DishMapper
/*** 根据套餐id查询菜品* @param setmealId* @return
*/
@Select("select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = #{setmealId}")
List<Dish> getBySetmealId(Long setmealId);
5.3 功能测试
略
相关文章:

Java项目-苍穹外卖-Day05
文章目录 1. 新增套餐1.1 需求分析和设计1.2 代码实现1.2.1 DishController1.2.2 DishService1.2.3 DishServiceImpl1.2.4 DishMapper1.2.5 DishMapper.xml1.2.6 SetmealController1.2.7 SetmealService1.2.8 SetmealServiceImpl1.2.9 SetmealMapper1.2.10 SetmealMapper.xml1.…...

取模运算符在数组下标的应用
什么是取模运算符%? 定义: a mod b,设a、b属于正整数且b>0,如果q、r属于正整数满足aq*br,且0≤r<b,则定义: a mod b r 注意:取模运算符两侧的除数和被除数都是整数ÿ…...

Firefox(火狐),使用技巧汇总,问题处理
本文目的 说明火狐如何安装在C盘之外的盘,即定制安装路径。如何将同步功能切换到本地服务上。默认是国际服务器。安装在C盘之后如何解决,之前安装的扩展无法自动同步的问题。顺带讲解一下,火狐的一些比较好用的扩展。 安装路径定制 火狐目前…...

耐腐蚀高速数控针阀和多功能PID控制器在流量比率控制中的应用
摘要:在目前的流体比值混合控制系统中,普遍采用的是多通道闭环PID控制系统对各路流量进行准确控制后再进行混合,这种控制方式普遍存在的问题是对流量调节阀的响应速度、耐腐蚀性和线性度有很高要求。为此本文提出的第一个解决方案是采用NCNV系…...

C语言:选择+编程(每日一练Day6)
目录 编辑选择题: 题一: 题二: 题三: 题四: 题五: 编程题: 题一:至少是其他数字两倍的最大数 思路一: 思路二: 题二:两个数组的交集…...
微信小程序教学系列(8)
微信小程序教学系列 第八章:小程序国际化开发 欢迎来到第八章!这一次我们要谈论的是小程序国际化开发。你可能会问,什么是国际化?简单来说,国际化就是让小程序能够适应不同的语言和地区,让用户们感受到更…...

情人节定制:HTML5 Canvas全屏七夕爱心表白特效
❤️ 前言 “这个世界乱糟糟的而你干干净净可以悬在我心上做太阳和月亮。”,七夕节表白日,你要错过吗?如果你言辞不善,羞于开口的话,可以使用 html5 canvas 制作浪漫的七夕爱心表白动画特效,全屏的爱心和…...

操作系统-笔记-第五章-输入输出管理
目录 五、第五章——输入输出管理 1、IO设备的概念和分类 (1)IO设备分类——使用特性 (2)IO设备分类——传输速率 (3)IO设备分类——信息交换(块、字符) 2、IO控制器 &#x…...
感觉自己效率不高吗?学习实现目标的六个关键步骤,让你做任何事都事半功倍!
概述 是否感觉自己效率不高?做任何事情都提不起来精神?开发的时候要完成的功能很多,却不知该如何下手去做?那么你通过这篇文章可以学习到六个完成工作和学习目标的关键步骤,只要简单重复这六个步骤,就可以很轻松的达到你想做到的任何目标。是不是感觉很神奇,我也是亲测…...

【高级IO】- 五种 IO 模型 | 多路转接 - select
目录 IO的基本概念 什么是高效的IO? 五种IO模型 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO 同步通信VS异步通信(synchronous communication / asynchronous communication) 同步通信VS同步与互斥 阻塞VS非阻塞 其他高级IO …...

在Linux搭建GitLab私有仓库配置实现远程访问私有仓库Gitlab ——【内网穿透】
🎬 鸽芷咕:个人主页 🔥 个人专栏: 《高效编程技巧》《cpolar》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留…...

ChatGPT应用于高职教育的四大潜在风险
目前,ChatGPT还是一种仍未成熟的技术,当其介入高职教育生态后,高职院校师生在享受ChatGPT带来的便利的同时,也应该明白ChatGPT引发的风险也会随之进入高职教育领域,如存在知识信息、伦理意识与学生主体方面的风险与挑战…...
uni-app在组件中内嵌webView,实现自定义webView的大小,并处理页面中有webview时其他元素点击事件失效的问题
uni-app在组件中内嵌webView,实现自定义webView的大小,并处理页面中有webview时其他元素点击事件失效的问题 uni-app在组件中内嵌webView,实现自定义webView的大小 setWebviewTop() {// #ifdef APP-PLUSvar currentWebview this.$scope.$g…...

档案开发:增加查询和打卡按钮
档案开发:增加查询和打卡按钮 和单据开发的不同点 没有单据类型不是右击–>特性–>单据主表/单据子表,而是右击–>特性–>选择想要的接口访问器类型是NCVO不需要映射不是项目右键–>新建–>其他–>主子表单据结点,而是…...
redis基础细心讲解,一篇了解常用的缓存技术!
今日内容 redis 1. 概念 2. 下载安装 3. 命令操作1. 数据结构 4. 持久化操作 5. 使用Java客户端操作redis 6. 在ssm项目中使用缓冲进行CRUD操作Redis 1. 概念 redis是一款高性能的NOSQL系列的非关系型数据库 1.1.什么是NOSQL NoSQL(NoSQL = Not Only SQL),意即“不仅仅…...
Three.js之几何体、高光材质、渲染器设置、gui
参考资料 阵列立方体和相机适配体验Threejs常见几何体简介…gui.js库(可视化改变三维场景) 知识点 注:基于Three.jsv0.155.0 长方体:oxGeometry球体:SphereGeometry圆柱:CylinderGeometry矩形平面:PlaneGeometry圆…...

UE4如何连接dmx---摇头矩阵灯具的创建
UE4如何连接dmx---摇头矩阵灯具的创建 开始创建库! 然后我们开始创建多少个灯珠(注意了:这是矩阵灯,是看灯珠的) 那么这里我们创建6X6灯珠 下面设置灯珠的属性,灯珠有什么属性呢,只有颜色属性&…...

网络聊天室
一、项目要求 利用UDP协议,实现一套聊天室软件。服务器端记录客户端的地址,客户端发送消息后,服务器群发给各个客户端软件。 问题思考 客户端会不会知道其它客户端地址? UDP客户端不会直接互连,所以不会获知其它客…...

ChatGPT只是玩具:生成式人工智能在不同行业的应用
源自:IT经理网 生成式人工智能的十一个行业用例 打开生成式 AI的正确姿势 声明:公众号转载的文章及图片出于非商业性的教育和科研目的供大家参考和探讨,并不意味着支持其观点或证实其内容的真实性。版权归原作者所有,如转载稿涉及版权等问题&…...
RestFul的风格是什么
RestFul的风格是什么? 当我们谈论RESTful风格时,它指的是一种设计和构建网络应用程序的原则和约定。以下是RESTful风格的一些主要特点: 资源:将应用程序的功能封装为资源,每个资源都有一个唯一的标识符(U…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...