物流项目第十期(轨迹微服务)
本项目专栏:
物流项目_Auc23的博客-CSDN博客
建议先看这期:
MongoDB入门之Java的使用-CSDN博客
物流项目第九期(MongoDB的应用之作业范围)-CSDN博客
业务需求
快递员取件成功后,需要将订单转成运单,用户会比较关注目前包裹走到哪里,类似这样:
需求描述
轨迹微服务是一个独立的微服务,主要提供创建运单轨迹点、记录最新位置、查询轨迹这些服务,具体要求如下:
- 运单创建成功后,为运单创建轨迹点数据,并且将此数据持久化,以供后续的查询
- 司机端在运输途中,需要上报最新的位置,更新相应的运单的最新位置数据
- 快递员端在运输途中,需要上报最新的位置,更新相应的运单的最新位置数据
- 提供查询轨迹的接口服务
- 为查询轨迹接口服务设置缓存
- 用户签收后,需要关闭轨迹的更新,不再更新最新位置数据
业务流程
MQListener
@Slf4j
@Component
public class MQListener {@Resourceprivate TrackService trackService;/*** 创建运单后创建轨迹** @param msg 消息*/@RabbitListener(bindings = @QueueBinding(value = @Queue(name = Constants.MQ.Queues.TRACK_TRANSPORT_ORDER_CREATED),exchange = @Exchange(name = Constants.MQ.Exchanges.TRANSPORT_ORDER_DELAYED, type = ExchangeTypes.TOPIC, delayed = Constants.MQ.DELAYED),key = Constants.MQ.RoutingKeys.TRANSPORT_ORDER_CREATE))public void listenTransportOrderCreatedMsg(String msg) {log.info("接收到新增运单的消息 ({})-> {}", Constants.MQ.Queues.TRACK_TRANSPORT_ORDER_CREATED, msg);TransportOrderMsg transportOrderMsg = JSONUtil.toBean(msg, TransportOrderMsg.class);this.trackService.create(transportOrderMsg.getId());}/*** 运单签收后完成轨迹** @param msg 消息*/@RabbitListener(bindings = @QueueBinding(value = @Queue(name = Constants.MQ.Queues.TRACK_TRANSPORT_ORDER_UPDATE_STATUS),exchange = @Exchange(name = Constants.MQ.Exchanges.TRANSPORT_ORDER_DELAYED, type = ExchangeTypes.TOPIC, delayed = Constants.MQ.DELAYED),key = Constants.MQ.RoutingKeys.TRANSPORT_ORDER_UPDATE_STATUS_PREFIX + "RECEIVED"))public void listenTransportOrderUpdateStatusMsg(String msg) {log.info("接收到更新运单状态的消息 ({})-> {}", Constants.MQ.Queues.TRACK_TRANSPORT_ORDER_UPDATE_STATUS, msg);TransportOrderStatusMsg transportOrderStatusMsg = JSONUtil.toBean(msg, TransportOrderStatusMsg.class);this.trackService.complete(transportOrderStatusMsg.getIdList());}
}
util
public class TrackEntityUtil {/*** 将 TrackEntity 转换为 TrackDTO* 主要用于接口返回或业务层使用,脱敏敏感字段并格式化数据结构** @param trackEntity 原始实体对象(来自数据库)* @return 转换后的 DTO 对象(用于返回给前端或其他服务)*/public static TrackDTO toDTO(TrackEntity trackEntity) {// 创建 CopyOptions 配置项,指定忽略某些字段的复制// 这里忽略了 planGeoJsonLine 和 lastPoint 字段,因为这两个字段是 GeoJSON 类型,不适合直接暴露给外部// ignoreNullValue 表示不复制 null 值属性,避免空值污染 DTOCopyOptions copyOptions = CopyOptions.create().setIgnoreProperties("planGeoJsonLine", "lastPoint").ignoreNullValue();// 使用 Hutool 的 BeanUtil.toBean 方法进行基础字段拷贝// 会自动将 trackEntity 中非忽略字段复制到 TrackDTO 中TrackDTO trackDTO = BeanUtil.toBean(trackEntity, TrackDTO.class, copyOptions);// 处理计划轨迹点(planGeoJsonLine):这是一个 GeoJsonLineString 类型的地理轨迹线GeoJsonLineString planGeoJsonLine = trackEntity.getPlanGeoJsonLine();if (ObjectUtil.isAllNotEmpty(planGeoJsonLine, planGeoJsonLine.getCoordinates())) {// 如果轨迹线及其坐标列表存在且非空,则进行转换// 将 GeoJsonLineString 中的坐标点列表转换为 MarkerPointDTO 列表List<MarkerPointDTO> coordinateList = planGeoJsonLine.getCoordinates().stream()// 每个 Coordinate 点转成 MarkerPointDTO(只包含 x 和 y 坐标).map(point -> new MarkerPointDTO(point.getX(), point.getY()))// 收集为 List<MarkerPointDTO>.collect(Collectors.toList());// 设置到 DTO 的 pointList 字段中,供前端展示使用trackDTO.setPointList(coordinateList);}// 处理最新位置坐标(lastPoint):是一个 GeoJsonPoint 类型的点if (ObjectUtil.isNotEmpty(trackEntity.getLastPoint())) {// 如果 lastPoint 存在// 获取该点的经纬度信息GeoJsonPoint point = trackEntity.getLastPoint();// 转换成 MarkerPointDTO 并设置到 DTO 中trackDTO.setLastPoint(new MarkerPointDTO(point.getX(), point.getY()));}// 返回最终处理好的 DTO 对象return trackDTO;}}
entity
/*** 轨迹数据** @author zzj* @version 1.0*/
@Data
@Document("sl_track")
public class TrackEntity {@Id@JsonIgnoreprivate ObjectId id;/*** 运单id*/@Indexedprivate String transportOrderId;/*** 规划的轨迹坐标点线(通过地图服务商规划出来的轨迹点)*/private GeoJsonLineString planGeoJsonLine;/*** 距离,单位:米*/private Double distance;/*** 最新的位置坐标,x:经度,y:纬度*/private GeoJsonPoint lastPoint;/*** 状态*/private TrackStatusEnum status;/*** 类型*/private TrackTypeEnum type;/*** 创建时间*/private Long created;/*** 更新时间*/private Long updated;}
enums
/*** 异常枚举** @author zzj* @version 1.0*/
public enum TrackExceptionEnum implements BaseExceptionEnum {TRACK_ALREADY_EXISTS(1001, "轨迹已经存在");private Integer code;private Integer status;private String value;TrackExceptionEnum(Integer code, String value) {this.code = code;this.value = value;this.status = 500;}TrackExceptionEnum(Integer code, Integer status, String value) {this.code = code;this.value = value;this.status = status;}@Overridepublic Integer getCode() {return this.code;}@Overridepublic String getValue() {return this.value;}@Overridepublic Integer getStatus() {return this.status;}public static TrackExceptionEnum codeOf(Integer code) {return EnumUtil.getBy(TrackExceptionEnum::getCode, code);}
}
controller
@RestController
@Api(tags = "轨迹管理")
@RequestMapping("track")
public class TrackController {@Resourceprivate TrackService trackService;@PostMapping@ApiOperation(value = "创建轨迹", notes = "创建轨迹,会完成路线规划")@ApiImplicitParams({@ApiImplicitParam(name = "transportOrderId", value = "运单号", required = true)})public boolean create(@RequestParam("transportOrderId") String transportOrderId) {return this.trackService.create(transportOrderId);}@PutMapping("complete")@ApiOperation(value = "完成轨迹", notes = " 完成轨迹,修改为完成状态")@ApiImplicitParams({@ApiImplicitParam(name = "transportOrderIds", value = "运单号列表", required = true)})public boolean complete(@RequestParam("transportOrderIds") List<String> transportOrderIds) {return this.trackService.complete(transportOrderIds);}/*** 通过运单号查询轨迹** @param transportOrderId 运单号* @return 轨迹数据*/@GetMapping("{transportOrderId}")@ApiOperation(value = "查询轨迹", notes = "通过运单号查询轨迹")@ApiImplicitParams({@ApiImplicitParam(name = "transportOrderId", value = "运单号", required = true)})public TrackDTO queryByTransportOrderId(@PathVariable("transportOrderId") String transportOrderId) {TrackEntity trackEntity = this.trackService.queryByTransportOrderId(transportOrderId);return TrackEntityUtil.toDTO(trackEntity);}@PutMapping("upload/truck")@ApiOperation(value = "车辆上报位置", notes = "车辆上报位置")@ApiImplicitParams({@ApiImplicitParam(name = "transportTaskId", value = "运输任务id", required = true),@ApiImplicitParam(name = "lng", value = "经度", required = true),@ApiImplicitParam(name = "lat", value = "纬度", required = true),})public boolean uploadFromTruck(@RequestParam("transportTaskId") Long transportTaskId,@RequestParam("lng") double lng,@RequestParam("lat") double lat) {return this.trackService.uploadFromTruck(transportTaskId, lng, lat);}@PutMapping("upload/courier")@ApiOperation(value = "快递员上报位置", notes = "快递员上报位置")@ApiImplicitParams({@ApiImplicitParam(name = "transportOrderIds", value = "运单号列表", required = true),@ApiImplicitParam(name = "lng", value = "经度", required = true),@ApiImplicitParam(name = "lat", value = "纬度", required = true),})public boolean uploadFromCourier(@RequestParam("transportOrderIds") List<String> transportOrderIds,@RequestParam("lng") double lng,@RequestParam("lat") double lat) {return this.trackService.uploadFromCourier(transportOrderIds, lng, lat);}}
service
/*** 轨迹服务** @author zzj* @version 1.0*/
public interface TrackService {/*** 创建轨迹,会完成路线规划** @param transportOrderId 运单号* @return 是否成功*/boolean create(String transportOrderId);/*** 完成轨迹,修改为完成状态** @param transportOrderIds 运单号列表* @return 是否成功*/boolean complete(List<String> transportOrderIds);/*** 通过运单号查询轨迹** @param transportOrderId 运单号* @return 轨迹数据*/TrackEntity queryByTransportOrderId(String transportOrderId);/*** 车辆上报位置** @param transportTaskId 运输任务id* @param lng 经度* @param lat 纬度* @return 是否成功*/boolean uploadFromTruck(Long transportTaskId, double lng, double lat);/*** 快递员上报位置** @param transportOrderIds 运单号列表* @param lng 经度* @param lat 纬度* @return 是否成功*/boolean uploadFromCourier(List<String> transportOrderIds, double lng, double lat);}
实现接口
/*** TrackServiceImpl 是一个服务实现类,用于处理物流轨迹相关的业务逻辑。* 包括创建轨迹、更新状态、路径规划、位置上报等功能。*/
@Service // Spring 注解,表示这是一个服务层 Bean,可被自动注入使用
public class TrackServiceImpl implements TrackService {/*** MongoDB 操作模板,用于持久化 TrackEntity 数据*/@Resourceprivate MongoTemplate mongoTemplate;/*** 自定义的地图服务模板(如封装了高德地图 API),用于路径规划等地理操作*/@Resourceprivate EagleMapTemplate eagleMapTemplate;/*** Feign 客户端,用于调用运输订单微服务接口*/@Resourceprivate TransportOrderFeign transportOrderFeign;/*** Feign 客户端,用于调用运输任务微服务接口*/@Resourceprivate TransportTaskFeign transportTaskFeign;/*** Feign 客户端,用于调用订单微服务接口*/@Resourceprivate OrderFeign orderFeign;/*** Feign 客户端,用于调用组织机构微服务接口*/@Resourceprivate OrganFeign organFeign;/*** 创建一个新的物流轨迹记录** @param transportOrderId 运单 ID* @return 是否创建成功*/@Overridepublic boolean create(String transportOrderId) {// 构造查询条件:根据 transportOrderId 查询是否已有对应轨迹记录Query query = Query.query(Criteria.where("transportOrderId").is(transportOrderId));// 从 MongoDB 中查找是否存在该运单的轨迹信息TrackEntity trackEntity = mongoTemplate.findOne(query, TrackEntity.class);// 如果已经存在轨迹数据,则抛出自定义异常 TRACK_ALREADY_EXISTSif (ObjectUtil.isNotEmpty(trackEntity)) {throw new SLException(TrackExceptionEnum.TRACK_ALREADY_EXISTS);}// 创建新的轨迹实体对象TrackEntity track = new TrackEntity();track.setTransportOrderId(transportOrderId); // 设置运单 IDtrack.setStatus(TrackStatusEnum.NEW); // 设置初始状态为“新建”track.setCreated(System.currentTimeMillis()); // 设置创建时间戳track.setUpdated(track.getCreated()); // 初始更新时间等于创建时间// 调用方法获取计划路线 GeoJSON 线段,并设置到轨迹实体中track.setPlanGeoJsonLine(this.queryPlanGeoJsonLineString(transportOrderId, track));// 将新创建的轨迹实体保存到 MongoDBthis.mongoTemplate.save(track);// 返回 true 表示创建成功return true;}/*** 获取计划路线的 GeoJsonLineString(即路径线)** @param transportOrderId 运单 ID* @param track 当前轨迹实体(用于设置距离等属性)* @return GeoJsonLineString 表示路径线*/private GeoJsonLineString queryPlanGeoJsonLineString(String transportOrderId, TrackEntity track) {// 通过 Feign 接口获取运输订单详情TransportOrderDTO transportOrderDTO = transportOrderFeign.findById(transportOrderId);// 获取运输线路字符串(通常是 JSON 格式的运输节点列表)String transportLine = transportOrderDTO.getTransportLine();String wayPoints = null;// 如果运输线路不为空if (StrUtil.isNotEmpty(transportLine)) {// 解析成 JSON 对象JSONObject transportLineJson = JSONUtil.parseObj(transportLine);// 获取节点列表 JSONArrayJSONArray nodeList = transportLineJson.getJSONArray("nodeList");// 遍历每个节点,提取经纬度并格式化为 "lng,lat" 字符串List<String> pointList = nodeList.stream().map(obj -> {JSONObject json = (JSONObject) obj;double longitude = json.getDouble("longitude", 0d);double latitude = json.getDouble("latitude", 0d);// 如果经纬度为 0,标记为错误点if (ObjectUtil.equalsAny(0d, longitude, latitude)) {return "err";}// 正常点则格式化为字符串return StrUtil.format("{},{}", longitude, latitude);})// 过滤掉错误点.filter(o -> ObjectUtil.notEqual(o, "err")).collect(Collectors.toList());// 多个坐标点之间用分号拼接,作为途经点参数wayPoints = StrUtil.join(";", pointList);} else {// 如果没有运输线路信息,则尝试获取当前网点的经纬度作为起点OrganDTO organDTO = this.organFeign.queryById(transportOrderDTO.getCurrentAgencyId());if (ObjectUtil.isNotEmpty(organDTO)) {// 使用网点坐标作为途经点wayPoints = StrUtil.format("{},{}", organDTO.getLongitude(), organDTO.getLatitude());} else {// 理论上不会出现这种情况,如果没有就不设置途经点}}// 获取订单的位置信息(发货地和收货地)OrderLocationDTO orderLocationDTO = this.orderFeign.findOrderLocationByOrderId(transportOrderDTO.getOrderId());// 格式化发货地和收货地坐标CoordinateUtil.Coordinate origin = CoordinateUtil.format(orderLocationDTO.getSendLocation());CoordinateUtil.Coordinate destination = CoordinateUtil.format(orderLocationDTO.getReceiveLocation());// 构建请求参数 MapMap<String, Object> param = MapUtil.<String, Object>builder().put(ObjectUtil.isNotEmpty(wayPoints), "waypoints", wayPoints) // 添加途经点(如果有的话).put("show_fields", "polyline") // 请求返回 polyline 字段.build();// 调用地图服务,获取驾车路线规划结果String driving = this.eagleMapTemplate.opsForDirection().driving(ProviderEnum.AMAP, new Coordinate(origin), new Coordinate(destination), param);// 如果返回为空,说明调用失败或无结果if (StrUtil.isEmpty(driving)) {return null;}// 解析返回的 JSON 数据JSONObject jsonObject = JSONUtil.parseObj(driving);// 提取总距离Double distance = Convert.toDouble(jsonObject.getByPath("route.paths[0].distance"), -1d);track.setDistance(distance); // 设置到轨迹实体中// 提取步骤列表JSONArray steps = jsonObject.getByPath("route.paths[0].steps", JSONArray.class);// 收集所有坐标点List<Point> points = new ArrayList<>();// 获取所有 polyline 字段值(每一步的坐标点集合)List<Object> polyLines = CollUtil.getFieldValues(steps, "polyline");for (Object polyLine : polyLines) {// 将 polyline 字符串拆分成多个坐标点List<GeoJsonPoint> list = StrUtil.split(Convert.toStr(polyLine), ';').stream().map(coordinateStr -> {// 拆分为 lng 和 latdouble[] ds = Convert.convert(double[].class, StrUtil.splitTrim(coordinateStr, ','));return new GeoJsonPoint(ds[0], ds[1]);}).collect(Collectors.toList());// 添加到总坐标点列表中points.addAll(list);}// 返回构造好的 GeoJsonLineString(代表整条路径线)return new GeoJsonLineString(points);}/*** 批量完成轨迹记录(更新状态为 COMPLETE)** @param transportOrderIds 运单 ID 列表* @return 是否有记录被修改*/@Overridepublic boolean complete(List<String> transportOrderIds) {// 构造查询条件:匹配 transportOrderId 在传入列表中的记录,且状态为 NEWQuery query = Query.query(Criteria.where("transportOrderId").in(transportOrderIds));// 构造更新语句:将 status 更新为 COMPLETEUpdate update = Update.update("status", TrackStatusEnum.COMPLETE);// 执行批量更新UpdateResult updateResult = this.mongoTemplate.updateMulti(query, update, TrackEntity.class);// 如果修改了至少一条记录,返回 truereturn updateResult.getModifiedCount() > 0;}/*** 根据运单 ID 查询轨迹实体** @param transportOrderId 运单 ID* @return 查询到的 TrackEntity 实体对象 或 null*/@Overridepublic TrackEntity queryByTransportOrderId(String transportOrderId) {// 构造查询条件:按 transportOrderId 查询Query query = Query.query(Criteria.where("transportOrderId").is(transportOrderId));// 查询唯一匹配的记录return this.mongoTemplate.findOne(query, TrackEntity.class);}/*** 司机端上报当前位置** @param transportTaskId 运输任务 ID* @param lng 经度* @param lat 纬度* @return 是否上报成功*/@Overridepublic boolean uploadFromTruck(Long transportTaskId, double lng, double lat) {// 根据运输任务 ID 查询对应的运单 ID 列表List<String> list = this.transportTaskFeign.queryTransportOrderIdListById(transportTaskId);// 调用通用上传方法,类型为 DRIVERreturn upload(list, lng, lat, TrackTypeEnum.DRIVER);}/*** 快递员端上报当前位置** @param transportOrderIds 运单 ID 列表* @param lng 经度* @param lat 纬度* @return 是否上报成功*/@Overridepublic boolean uploadFromCourier(List<String> transportOrderIds, double lng, double lat) {// 直接调用通用上传方法,类型为 COURIERreturn upload(transportOrderIds, lng, lat, TrackTypeEnum.COURIER);}/*** 通用位置上报逻辑** @param transportOrderIds 运单 ID 列表* @param lng 经度* @param lat 纬度* @param trackTypeEnum 上报类型(DRIVER/COURIER)* @return 是否更新成功*/private boolean upload(List<String> transportOrderIds, double lng, double lat, TrackTypeEnum trackTypeEnum) {// 如果运单列表为空,直接返回 falseif (CollUtil.isEmpty(transportOrderIds)) {return false;}// 构造查询条件:transportOrderId 在列表中,且状态为 NEWQuery query = Query.query(Criteria.where("transportOrderId").in(transportOrderIds).and("status").is(TrackStatusEnum.NEW));// 构造更新内容:更新 lastPoint(最新位置)、type(轨迹类型)、updated(更新时间)Update update = Update.update("lastPoint", new GeoJsonPoint(lng, lat)).set("type", trackTypeEnum).set("updated", System.currentTimeMillis());// 执行批量更新UpdateResult updateResult = this.mongoTemplate.updateMulti(query, update, TrackEntity.class);// 返回是否成功更新(是否有记录被修改)return updateResult.getModifiedCount() > 0;}
}
相关文章:

物流项目第十期(轨迹微服务)
本项目专栏: 物流项目_Auc23的博客-CSDN博客 建议先看这期: MongoDB入门之Java的使用-CSDN博客 物流项目第九期(MongoDB的应用之作业范围)-CSDN博客 业务需求 快递员取件成功后,需要将订单转成运单,用…...
Python 入门到进阶全指南:从语言特性到实战项目
一、Python 简介 Python 是一种高级、跨平台、解释型编程语言,以简洁语法和高可读性著称,既适合编程初学者快速入门,也能满足资深开发者的复杂需求。其核心特性与应用场景如下: 核心特性解析 解释型语言:无需编译即可…...

【数据库】关系数据理论--规范化
1.问题的提出 关系模式由五部分组成,是一个五元组: R(U, D, DOM, F) (1)关系名R是符号化的元组语义 (2)U为一组属性 (3)D为属性组U中的属性所来自的域 (4)DOM…...
SQL 中 JOIN 的执行顺序优化指南
SQL 中 JOIN 的执行顺序优化指南 一、JOIN 执行顺序基础原理 在 SQL 查询中,JOIN的执行顺序是查询优化的重要环节。数据库引擎会根据多种因素决定最优的 JOIN 顺序: 逻辑执行顺序:SQL 语句的书写顺序(如 FROM → WHERE → GROUP BY)并不代表实际执行顺序物理执行顺序:由查…...

Oracle双平面适用场景讨论会议
4月28日,我在杭州组织召开了Oracle双平面会议讨论沙龙。在国产化数据库浪潮的今天,Oracle数据库作为国产数据库的应急库,在国产数据库发生故障或者性能下降时,如何更好的使用Oracle。会议主题如下: 1、背景与痛点速览&…...
OD 算法题 B卷【矩阵稀疏扫描】
文章目录 矩阵稀疏扫描 矩阵稀疏扫描 如果矩阵中的很多系数都为零,则为稀疏矩阵,给定一个矩阵,如果某行、列存在0的个数超出(包含)了行宽、列宽的一半(整除),则认为该行、列为稀疏的…...

使用BERT/BiLSTM + CRF 模型进行NER进展记录~
使用代码处理数据集,发现了一些问题,以及解决办法~ 下载了一组数据集,数据存放在CSV中,GBK格式。如下: 首先对每一列直接进行NER抽取,结果非常不好: 几乎是乱抽取的,解决办法是自己创…...
HarmonyOS运动开发:精准估算室内运动的距离、速度与步幅
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在室内运动场景中,由于缺乏 GPS 信号,传统的基于卫星定位的运动数据追踪方法无法使用。因此,如何准确估算室内运动的距离、速度和步幅,…...

Web攻防-SQL注入高权限判定跨库查询文件读写DNS带外SecurePriv开关绕过
知识点: 1、Web攻防-SQL注入-高权限用户差异 2、Web攻防-SQL注入-跨库注入&文件读写&DNS带外 案例说明: 在应用中,数据库用户不同,可操作的数据库和文件读写权限不一,所有在注入过程中可以有更多的利用思路&a…...

C语言数据结构笔记3:Union联合体+结构体取8位Bool量
本文衔接上文要求,新增8位bool量的获取方式。 目录 问题提出: Union联合体struct结构体(方式1): Union联合体struct结构体(方式2): BYTE方式读取: 问题提出: 在STM32单片机的编程中,无法定义Boo…...
深拷贝与浅拷贝的区别?如何手写实现一个深拷贝?
导语: “深拷贝 VS 浅拷贝”是前端面试中绕不开的经典问题,既能考察 JavaScript 基础功,又能延伸至手写代码、递归、循环引用处理等进阶话题。本文从面试官视角解析其考察重点,并详解如何手写一个实用的深拷贝函数,助你…...
grafana 批量视图备份及恢复(含数据源)
一、grafana 批量视图备份 import requests import json import urllib3 import osfrom requests.auth import HTTPBasicAuthfilename_folders_map "folders_map.json" type_folder "dash-folder" type_dashboard "dash-db"# Grafana服务器地…...

SAP学习笔记 - 开发22 - 前端Fiori开发 数据绑定(Jason),Data Types(数据类型)
上一章讲了Icons(图标),Icon Explorer。 SAP学习笔记 - 开发21 - 前端Fiori开发 Icons(图标),Icon Explorer(图标浏览器)-CSDN博客 本章继续讲SAP Fiori开发的知识。 目录 1&…...

网络编程之TCP编程
基于 C/S :客户端(client)/服务器端(server) 1.流程 2. 函数接口 所有函数所需头文件: #include <sys/types.h> #include <sys/socket.h> 系统定义好了用来存储网络信息的结构体 ipv4通信使…...

C++进阶--C++11(04)
文章目录 C进阶--C11(04)lambdalambda表达式语法捕捉列表lambda的应用lambda的原理 包装器functionbind 总结结语 很高兴和大家见面,给生活加点impetus!!开启今天的编程之路!! 今天我们进一步c…...

当AI遇上防火墙:新一代智能安全解决方案全景解析
在2025年网络安全攻防升级的背景下,AI与防火墙的融合正重塑安全防御体系。以下三款产品通过机器学习、行为分析等技术创新,为企业提供智能化主动防护: 1. 保旺达数据安全管控平台——AI驱动的动态治理引擎 智能分类分级:基于…...
STL 库基础概念与示例
一、STL 库基础概念与示例 1. 容器分类 顺序容器 核心特性:按元素插入顺序存储,支持下标访问(类似数组),动态扩展内存。典型容器:vector(动态数组)。适用场景:需要频繁…...

Spring MVC参数绑定终极手册:单多参/对象/集合/JSON/文件上传精讲
我们通过浏览器访问不同的路径,就是在发送不同的请求,在发送请求时,可能会带一些参数,本文将介绍了Spring MVC中处理不同请求参数的多种方式 一、传递单个参数 接收单个参数,在Spring MVC中直接用方法中的参数就可以&…...

Fluence推出“Pointless计划”:五种方式参与RWA算力资产新时代
2025年6月1日,去中心化算力平台 Fluence 正式宣布启动“Pointless 计划”——这是其《Fluence Vision 2026》战略中四项核心举措之一,旨在通过贡献驱动的积分体系,激励更广泛的社区参与,为用户带来现实世界资产(RWA&am…...

innovus: ecoAddRepeater改变hier层级解决办法
我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 来自星球提问: 星主,我在A/B/C/D/E/U0这个cell后面插入一个BUFF,生成的名字为A/B/C/BUFF1,少了D/E两个层级,不应该是生成A/B/C/…...

华为OD机试真题——硬件产品销售方案(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《硬件产品销售方案》: 目录…...
突破数据孤岛:StarRocks联邦查询实战指南
随着企业数据生态的复杂化,跨多个数据存储系统进行联合查询的需求日益增长。本文将深入解析如何利用StarRocks构建高效的数据联邦查询体系,实现与Apache Doris和Hive数据仓库的无缝对接。 ### 一、StarRocks联邦查询架构解析 StarRocks采用分布式架构设…...

传统业务对接AI-AI编程框架-Rasa的业务应用实战(1)--项目背景即学习初衷
我的初衷:我想学习AI。具体的方向是这样的:原本传统的平台业务去对接智能体。比如发票业务,发票的开具、审核、计税、回款等。根据用户在业务系统前台界面输入若干提示词 或者 语音输入简短语音信息,可以通过智能体给出需要处理的…...

低功耗架构突破:STM32H750 与 SD NAND (存储芯片)如何延长手环续航至 14 天
低功耗架构突破:STM32H750 与 SD NAND (存储芯片)如何延长手环续航至 14 天 卓越性能强化安全高效能效图形处理优势丰富集成特性 模拟模块实时监控保障数据完整性提升安全性与可靠性测量原理采样率相关结束语 在智能皮电手环及数据存储技术不…...
CSS选择子元素
通过选择器 为所有子元素应用样式。以下是几种常见方法: 1. 选择所有直接子元素(不包括孙级) css 复制 下载 .parent > * {/* 样式规则 */color: red; } > 选择器:只匹配直接子元素 * 通配符:匹配任意类型…...
git cherry-pick (28)
1.1 目的 本文档用于说明如何git上,通过cherry-pick命令合并某个功能。 将分支bg_device的 AHB New feature support libalgo arm64 lib 提交内容合并至 分支spfl_device 分支当中 1.2适配步骤 1.2.1 实操过程 > 分支sfpl_device的状态 rootxrootx-ThinkPad:~/workdir…...
android与Qt类比
一、概念对应关系 Android RecyclerView 组件类比描述Qt 模型 - 视图组件Qt 类比描述RecyclerView画板(容器)QAbstractItemView视图(展示数据的容器,如列表、表格)RecyclerView.Adapter画布(数据桥梁&…...
AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片 支持高清CMOS Sensor输入 国产品牌
AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片 支持高清CMOS Sensor输入 国产品牌 产品概述: AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片,支持高清CMOS Sensor输入,经ISP处理、视频前处理以及音视频编…...

Linux(11)——基础IO(上)
目录 一、理解文件 二、回顾C文件的接口 📄 C语言文件操作函数表 编辑📄 三个文件流 三、系统文件I/O 1️⃣open 2️⃣close 3️⃣write 4️⃣read 四、文件描述符 💡用户操作文件的底层逻辑是什么? Ǵ…...

ABP-Book Store Application中文讲解 - Part 9: Authors: User Interface
ABP-Book Store Application中文讲解 - Part 9: Authors: User Interface TBD 1. 汇总 ABP-Book Store Application中文讲解-汇总-CSDN博客 2. 前一章 ABP-Book Store Application中文讲解 - Part 8: Authors: Application Layer-CSDN博客 项目之间的引用关系。 目…...