From 41543cc5a546249671c5f794d82a3bb54656890f Mon Sep 17 00:00:00 2001 From: George Date: Sat, 7 Mar 2026 22:36:25 +0800 Subject: [PATCH] =?UTF-8?q?20260307:=E5=9C=B0=E5=9B=BE=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yml | 3 + .../src/main/resources/application-prod.yml | 4 ++ .../controller/ForestExampleController.java | 8 +-- .../http/map/BaiduLocationService.java | 62 ++++++++++++++++++ .../com/fastbee/http/map/LocationService.java | 26 ++++++++ .../http/map/LocationServiceFactory.java | 40 ++++++++++++ .../com/fastbee/http/model/Coordinate.java | 50 +++++++-------- .../iot/service/impl/DeviceServiceImpl.java | 64 +++++++------------ .../iot/service/impl/ProductServiceImpl.java | 4 +- .../mapper/iot/ProductSubGatewayMapper.xml | 17 ++++- 10 files changed, 200 insertions(+), 78 deletions(-) create mode 100644 fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/BaiduLocationService.java create mode 100644 fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/LocationService.java create mode 100644 fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/LocationServiceFactory.java diff --git a/fastbee-admin/src/main/resources/application-dev.yml b/fastbee-admin/src/main/resources/application-dev.yml index 0d2457b2..1edf2dc5 100644 --- a/fastbee-admin/src/main/resources/application-dev.yml +++ b/fastbee-admin/src/main/resources/application-dev.yml @@ -155,3 +155,6 @@ swagger: enabled: true # 是否开启swagger pathMapping: /dev-api # 请求前缀 +# 地图配置 +map: + provider: baidu \ No newline at end of file diff --git a/fastbee-admin/src/main/resources/application-prod.yml b/fastbee-admin/src/main/resources/application-prod.yml index c936a670..9ff7919b 100644 --- a/fastbee-admin/src/main/resources/application-prod.yml +++ b/fastbee-admin/src/main/resources/application-prod.yml @@ -153,3 +153,7 @@ logging: swagger: enabled: true # 是否开启swagger pathMapping: /prod-api # 请求前缀 + +# 地图配置 +map: + provider: baidu \ No newline at end of file diff --git a/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/controller/ForestExampleController.java b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/controller/ForestExampleController.java index 720a2d14..b4ea9d02 100644 --- a/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/controller/ForestExampleController.java +++ b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/controller/ForestExampleController.java @@ -29,8 +29,8 @@ public class ForestExampleController { @GetMapping("/amap/location2") public Map amapLocation2(@RequestParam BigDecimal longitude, @RequestParam BigDecimal latitude) { Coordinate coordinate = new Coordinate( - longitude.toEngineeringString(), - latitude.toEngineeringString()); + new BigDecimal(longitude.toEngineeringString()), + new BigDecimal(latitude.toEngineeringString())); Map result = amap.getLocation(coordinate); return result; } @@ -38,8 +38,8 @@ public class ForestExampleController { @GetMapping("/amap/location3") public Map amapLocation3(@RequestParam BigDecimal longitude, @RequestParam BigDecimal latitude) { Coordinate coordinate = new Coordinate( - longitude.toEngineeringString(), - latitude.toEngineeringString()); + new BigDecimal(longitude.toEngineeringString()), + new BigDecimal(latitude.toEngineeringString())); Map result = amap.getLocationByCoordinate(coordinate); return result; } diff --git a/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/BaiduLocationService.java b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/BaiduLocationService.java new file mode 100644 index 00000000..dfb28e0a --- /dev/null +++ b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/BaiduLocationService.java @@ -0,0 +1,62 @@ +package com.fastbee.http.map; +import com.alibaba.fastjson2.JSONObject; +import com.fastbee.common.constant.Constants; +import com.fastbee.common.exception.ServerException; +import com.fastbee.common.utils.http.HttpUtils; +import com.fastbee.http.model.Coordinate; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +/** + * @description: 百度地图API接口服务 + * + * @author Sumuxi + * @date 2026/3/7 + */ +@Slf4j +@Service("baiduLocationService") +public class BaiduLocationService implements LocationService { + + @Value("${other.baidu_ak}") + private String baiduAK; + + interface API { + String BAIDU_URL = "http://api.map.baidu.com"; + + String geocoding = "/geocoding/v3/"; + } + + /** + * 根据结构化地址获取地理编码(即经纬度) + * 地理编码服务提供将结构化地址数据(如:北京市海淀区上地十街十号)转换为对应坐标点(经纬度)功能。 + * @param address 地址 + * @return 经纬度对象 + */ + @Override + public Coordinate getCoordinateByAddress(String address) { + + String baseUri = API.BAIDU_URL + API.geocoding; + address = StringUtils.isEmpty(address) ? "湖南省长沙市岳麓区" : address; + String encodedAddress; + try { + encodedAddress = URLEncoder.encode(address, StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException e) { + throw new ServerException(100001, "地理编码异常"); + } + String baiduResponse = HttpUtils.sendGet(baseUri, "address=" + encodedAddress + "&output=json&ak=" + baiduAK, Constants.UTF8); + if (!StringUtils.isEmpty(baiduResponse)) { + JSONObject baiduObject = JSONObject.parseObject(baiduResponse); + JSONObject location = baiduObject.getJSONObject("result").getJSONObject("location"); + log.info("设置经度:{},设置纬度:{}", location.getBigDecimal("lng"), location.getBigDecimal("lat")); + return new Coordinate(location.getBigDecimal("lng"), location.getBigDecimal("lat")); + } + return null; + } + +} diff --git a/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/LocationService.java b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/LocationService.java new file mode 100644 index 00000000..d6726ad4 --- /dev/null +++ b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/LocationService.java @@ -0,0 +1,26 @@ +package com.fastbee.http.map; + +import com.fastbee.http.model.Coordinate; + +/** + * @description: 地理位置服务接口 + * + * @author Sumuxi + * @date 2026/3/7 + */ +public interface LocationService { + + /** + * 根据地址获取经纬度坐标 + * @param address 详细地址 + * @return 经纬度对象 + */ + Coordinate getCoordinateByAddress(String address); + + /** + * 根据经纬度获取详细地址 + * @param coordinate 经纬度 + * @return 详细地址信息 + */ + //AddressInfo getAddressByCoordinate(Coordinate coordinate); +} diff --git a/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/LocationServiceFactory.java b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/LocationServiceFactory.java new file mode 100644 index 00000000..9e1df41f --- /dev/null +++ b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/map/LocationServiceFactory.java @@ -0,0 +1,40 @@ +package com.fastbee.http.map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @description: 地图工厂 + * + * @author Sumuxi + * @date 2026/3/7 + */ +@Component +public class LocationServiceFactory { + + @Resource + private LocationService baiduLocationService; + +// @Resource +// private LocationService gaodeLocationService; + + // 从配置文件读取当前使用的服务商 + @Value("${map.provider:baidu}") + private String provider; + + /** + * 获取当前配置的 LocationService 实例 + * @return 具体服务实现 + */ + public LocationService getLocationService() { +// if ("gaode".equalsIgnoreCase(provider)) { +// return gaodeLocationService; +// } else if ("tencent".equalsIgnoreCase(provider)) { +// return tencentLocationService; +// } + // 默认返回百度 + return baiduLocationService; + } +} diff --git a/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/model/Coordinate.java b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/model/Coordinate.java index 6ff353a4..20cf9f76 100644 --- a/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/model/Coordinate.java +++ b/fastbee-plugs/fastbee-http/src/main/java/com/fastbee/http/model/Coordinate.java @@ -1,34 +1,30 @@ -package com.fastbee.http.model; +package com.fastbee.http.model;/** + * @description: 地理位置坐标 + * @author Sumuxi + * @date 2026/3/7 + */ + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; /** - * @author gongjun - * @since 2016-06-01 + * @description: 地理位置坐标 + * + * @author Sumuxi + * @date 2026/3/7 */ +@Data +@AllArgsConstructor +@NoArgsConstructor public class Coordinate { - private String longitude; + @ApiModelProperty("经度") + private BigDecimal longitude; - private String latitude; - - public Coordinate(String longitude, String latitude) { - this.longitude = longitude; - this.latitude = latitude; - } - - - public String getLongitude() { - return longitude; - } - - public void setLongitude(String longitude) { - this.longitude = longitude; - } - - public String getLatitude() { - return latitude; - } - - public void setLatitude(String latitude) { - this.latitude = latitude; - } + @ApiModelProperty("纬度") + private BigDecimal latitude; } diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceServiceImpl.java index 09be416b..be63ec99 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/DeviceServiceImpl.java @@ -1,7 +1,6 @@ package com.fastbee.iot.service.impl; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; @@ -28,6 +27,9 @@ import com.fastbee.common.utils.StringUtils; import com.fastbee.common.utils.http.HttpUtils; import com.fastbee.common.utils.ip.IpUtils; import com.fastbee.common.utils.json.JsonUtils; +import com.fastbee.http.map.LocationService; +import com.fastbee.http.map.LocationServiceFactory; +import com.fastbee.http.model.Coordinate; import com.fastbee.iot.cache.IDeviceCache; import com.fastbee.iot.cache.ITSLCache; import com.fastbee.iot.cache.ITSLValueCache; @@ -57,7 +59,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Caching; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @@ -65,11 +66,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Method; import java.math.BigDecimal; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -90,8 +87,6 @@ public class DeviceServiceImpl implements IDeviceService { private static final Logger log = LoggerFactory.getLogger(DeviceServiceImpl.class); @Value("${server.broker.port}") private Long brokerPort; - @Value("${other.baidu_ak}") - private String baiduAK; @Autowired private ITSLCache itslCache; @Autowired @@ -130,6 +125,9 @@ public class DeviceServiceImpl implements IDeviceService { @Lazy private IDataRepairService dataRepairService; + @Resource + private LocationServiceFactory locationServiceFactory; + @Resource private EventLogMapper eventLogMapper; @Resource @@ -371,11 +369,11 @@ public class DeviceServiceImpl implements IDeviceService { } Long[] shareSceneIds = null; List deviceShares = deviceShareService.selectDeviceShareByDeviceId(deviceId); - if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(deviceShares)) { + if (!CollectionUtils.isEmpty(deviceShares)) { List userIdList = deviceShares.stream().map(DeviceShare::getUserId).collect(Collectors.toList()); userIdSceneList.addAll(userIdList); } - if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(userIdSceneList)) { + if (!CollectionUtils.isEmpty(userIdSceneList)) { shareSceneIds = sceneDeviceMapper.listSceneIdByDeviceIdAndUserId(device.getSerialNumber(), userIdSceneList); } if (isGeneralUser) { @@ -847,7 +845,7 @@ public class DeviceServiceImpl implements IDeviceService { } else { serialNumberList = list.stream().map(DeviceShortOutput::getSerialNumber).collect(Collectors.toList()); } - if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(serialNumberList)) { + if (!CollectionUtils.isEmpty(serialNumberList)) { List alist = alertLogService.selectDeviceAlertCount(serialNumberList); for (DeviceAlertCount item : alist) { list.stream() @@ -1126,8 +1124,8 @@ public class DeviceServiceImpl implements IDeviceService { } } } else if (DeviceType.GATEWAY.getCode() == device.getDeviceType()) { - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(ProductSubGateway::getGwProductId, product.getProductId()); +// LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// queryWrapper.eq(ProductSubGateway::getGwProductId, product.getProductId()); // 处理子设备添加和子设备轮询 ProductSubGateway productSubGateway = new ProductSubGateway(); productSubGateway.setGwProductId(product.getProductId()); @@ -1138,9 +1136,9 @@ public class DeviceServiceImpl implements IDeviceService { productSubGatewayList.sort(Comparator.comparing(ProductSubGatewayVO::getSlaveId)); List subProductIdList = productSubGatewayList.stream().map(ProductSubGatewayVO::getSubProductId) .collect(Collectors.toList()); - LambdaQueryWrapper queryWrapper1 = new LambdaQueryWrapper<>(); - queryWrapper1.in(ProductModbusJob::getProductId, subProductIdList); - List productModbusJobList = productModbusJobMapper.selectList(queryWrapper1); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(ProductModbusJob::getProductId, subProductIdList); + List productModbusJobList = productModbusJobMapper.selectList(queryWrapper); Map> productModbusJobMap = productModbusJobList.stream() .collect(Collectors.groupingBy(ProductModbusJob::getProductId)); // 新增子设备、绑定子设备、子设备生成轮询 @@ -1171,7 +1169,7 @@ public class DeviceServiceImpl implements IDeviceService { subGatewayMapper.insertGateway(subGateway); List productModbusList = productModbusJobMap .get(productSubGatewayVO.getSubProductId()); - if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(productModbusList)) { + if (!CollectionUtils.isEmpty(productModbusList)) { for (ProductModbusJob productModbusJob : productModbusList) { ModbusJob modbusJob = new ModbusJob(); modbusJob.setJobName(productModbusJob.getJobName()); @@ -1590,36 +1588,18 @@ public class DeviceServiceImpl implements IDeviceService { if (!StringUtils.isEmpty(rspStr)) { JSONObject obj = JSONObject.parseObject(rspStr); device.setNetworkAddress(obj.getString("addr")); - System.out.println(device.getSerialNumber() + "- 设置地址:" + obj.getString("addr")); + log.info("{}- 设置地址:{}", device.getSerialNumber(), obj.getString("addr")); // 查询经纬度 - setLatitudeAndLongitude(obj.getString("city"), device); + LocationService service = locationServiceFactory.getLocationService(); + Coordinate coordinate = service.getCoordinateByAddress(obj.getString("city")); + device.setLongitude(coordinate.getLongitude()); + device.setLatitude(coordinate.getLatitude()); } } catch (Exception e) { log.error(e.getMessage()); } } - /** - * 设置经纬度 - * - * @param city - */ - private void setLatitudeAndLongitude(String city, Device device) throws UnsupportedEncodingException { - String BAIDU_URL = "http://api.map.baidu.com/geocoding/v3/"; - city = StrUtil.isEmpty(city) ? "湖南省长沙市岳麓区" : city; - String encodedAddress = URLEncoder.encode(city, StandardCharsets.UTF_8.toString()); - String baiduResponse = HttpUtils.sendGet(BAIDU_URL, "address=" + encodedAddress + "&output=json&ak=" + baiduAK, - Constants.UTF8); - if (!StringUtils.isEmpty(baiduResponse)) { - JSONObject baiduObject = JSONObject.parseObject(baiduResponse); - JSONObject location = baiduObject.getJSONObject("result").getJSONObject("location"); - device.setLongitude(location.getBigDecimal("lng")); - device.setLatitude(location.getBigDecimal("lat")); - System.out.println(device.getSerialNumber() + "- 设置经度:" + location.getBigDecimal("lng") + ",设置纬度:" - + location.getBigDecimal("lat")); - } - } - /** * 根据产品ID获取产品下所有编号 * @@ -1652,7 +1632,7 @@ public class DeviceServiceImpl implements IDeviceService { List serialNumberList = deviceImportVOList.stream().map(DeviceImportVO::getSerialNumber) .collect(Collectors.toList()); List oldSerialNumberList = deviceMapper.checkExistBySerialNumbers(serialNumberList); - if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(oldSerialNumberList)) { + if (!CollectionUtils.isEmpty(oldSerialNumberList)) { return "以下设备编号(" + JSON.toJSONString(oldSerialNumberList) + ")已存在,请修改后重试"; } List deviceList = new ArrayList<>(); @@ -1705,7 +1685,7 @@ public class DeviceServiceImpl implements IDeviceService { List serialNumberList = deviceAssignmentVOS.stream().map(DeviceAssignmentVO::getSerialNumber) .collect(Collectors.toList()); List oldSerialNumberList = deviceMapper.checkExistBySerialNumbers(serialNumberList); - if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(oldSerialNumberList)) { + if (!CollectionUtils.isEmpty(oldSerialNumberList)) { return "以下设备编号(" + JSON.toJSONString(oldSerialNumberList) + ")已存在,请修改后重试"; } SysDept sysDept = sysDeptMapper.selectDeptById(deptId); diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/ProductServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/ProductServiceImpl.java index b482d0a6..1bd76ba7 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/ProductServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/service/impl/ProductServiceImpl.java @@ -129,8 +129,8 @@ public class ProductServiceImpl implements IProductService { @Transactional public AjaxResult deleteProductByProductIds(Long[] productIds) { // 删除物模型JSON缓存 - for (int i = 0; i < productIds.length; i++) { - String key = RedisKeyBuilder.buildTSLCacheKey(productIds[i]); + for (Long productId : productIds) { + String key = RedisKeyBuilder.buildTSLCacheKey(productId); redisCache.deleteObject(key); } // 产品下不能有固件 diff --git a/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/ProductSubGatewayMapper.xml b/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/ProductSubGatewayMapper.xml index cbecfd12..f08cec31 100644 --- a/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/ProductSubGatewayMapper.xml +++ b/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/ProductSubGatewayMapper.xml @@ -21,9 +21,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"