diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java index 4936c7c..1b3e705 100644 --- a/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java +++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/app/AppController.java @@ -99,16 +99,16 @@ public class AppController extends BaseController /** - * 根据定位获取运营区详细信息 + * 根据定位获取运营区详细信息 device not subscribed */ @GetMapping(value = "/area/info") - public AjaxResult areaInfo(String longitude,String latitude) + public AjaxResult areaInfo(String longitude,String latitude, String deptId) { if(StrUtil.isBlank(longitude) || StrUtil.isBlank(latitude)){ logger.info("没有经纬度参数:【longitude={}】,【latitude={}】",longitude,latitude); return error("请传经纬度参数"+"【longitude="+longitude+"】,【latitude="+latitude+"】"); } - EtOperatingArea area = etOperatingAreaService.getAreaInfoByLocation(longitude,latitude); + EtOperatingArea area = etOperatingAreaService.getAreaInfoByLocation(longitude,latitude,deptId); return success(area); } diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/iot/receive/ReceiveController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/iot/receive/ReceiveController.java index 0dbac07..bd9b700 100644 --- a/electripper-admin/src/main/java/com/ruoyi/web/controller/iot/receive/ReceiveController.java +++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/iot/receive/ReceiveController.java @@ -77,6 +77,8 @@ public class ReceiveController { @Autowired private ScheduledExecutorService scheduledExecutorService; + private final Object lock = new Object(); + /** * 功能描述:第三方平台数据接收。

@@ -97,16 +99,37 @@ public class ReceiveController { log.info("receive方法接收到参数: body String --- " +body); /************************************************ * 解析数据推送请求,非加密模式。 - * 如果是明文模式使用以下代码 + * 如果是明文模式使用以下代码 hangdleBody(body, false); ChatGPT is under heavy load **************************************************/ /*************明文模式 start****************/ BodyObj obj = Util.resolveBody(body, false); log.info("receive方法解析对象: body Object --- " + JSON.toJSONString(obj)); + // 起一个异步线程处理数据 + scheduledExecutorService.schedule(() -> { + new Thread(() -> { + synchronized (lock) { + try { + handleBody(obj); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } + } + }).start(); + }, 0, TimeUnit.SECONDS); + /*************明文模式 end****************/ + return "ok"; + } + + private void handleBody(BodyObj obj) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException { if (obj != null){ boolean dataRight = Util.checkSignature(obj, token); if (dataRight){ log.info("receive方法验证签名正确: content" + JSON.toJSONString(obj)); - String msg = (String)obj.getMsg(); + String msg = (String) obj.getMsg(); log.info("receive方法-获取到消息体: msg---" +msg); JSONObject jsonObject = JSONObject.parseObject(msg, JSONObject.class); if(IotConstants.ONENET_LOCATION.equals(jsonObject.get("ds_id")) && ObjectUtil.isNotNull(jsonObject.get("value"))){ @@ -161,17 +184,26 @@ public class ReceiveController { String noRidingOutage = area.getNoRidingOutage(); if (noRidingOutage.equals("1") && value.getStatus() != 3) { // 禁行区内断电 log.info("禁行区内断电命令--SN:" + device.getSn()); - asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE, "禁行区内断电"); + asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE+IotConstants.COMMAND_FREQUENCY_5, "禁行区内断电"); } } /** 3.超出运营区外断电*/ boolean isAreaZone = asDeviceService.isAreaZone(device.getSn(), area); if(!isAreaZone){ - String isAdminUnlocking = device.getIsAdminUnlocking();// 是否管理员开锁 - String areaOutOutage = area.getAreaOutOutage(); - if (areaOutOutage.equals("1") && value.getStatus() != 3 && !isAdminUnlocking.equals("1")) { // 超出营运区断电 - log.info("超出营运区断电命令--SN:" + device.getSn()); - asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE, "超出营运区断电"); + //是否在20米范围内 + boolean inPolygon = GeoUtils.isInPolygonWithTolerance(lon.toString(), lat.toString(), GeoUtils.fromWkt(area.getBoundary()), 20); + if(inPolygon){ + //在20米范围内,发报警 + log.info("超出运营区20米内发送警告命令--SN:" + device.getSn()); + asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY3, "超出运营区20米内"); + }else{ + //超出运营区外断电 + String isAdminUnlocking = device.getIsAdminUnlocking();// 是否管理员开锁 + String areaOutOutage = area.getAreaOutOutage(); + if (areaOutOutage.equals("1") && value.getStatus() != 3 && !isAdminUnlocking.equals("1")) { // 超出营运区断电 + log.info("超出营运区断电命令--SN:" + device.getSn()); + asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE+IotConstants.COMMAND_FREQUENCY_5, "超出营运区断电"); + } } } /** 4.行程线路添加,更新订单中的trip_route字段 */ @@ -254,8 +286,6 @@ public class ReceiveController { }else { log.info("receive方法参数为空: body empty error"); } - /*************明文模式 end****************/ - return "ok"; } private boolean isLastPointSame(JSONArray jsonArray, BigDecimal lon, BigDecimal lat) { diff --git a/electripper-common/src/main/java/com/ruoyi/common/constant/IotConstants.java b/electripper-common/src/main/java/com/ruoyi/common/constant/IotConstants.java index e9ec82b..a108622 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/constant/IotConstants.java +++ b/electripper-common/src/main/java/com/ruoyi/common/constant/IotConstants.java @@ -116,6 +116,22 @@ public class IotConstants { */ public static final String COMMAND_PLAY8 = "play8@"; + /** + * 命令 频率:5秒 + */ + public static final String COMMAND_FREQUENCY_5 = "sub10@"; + + /** + * 命令 频率:20秒 + */ + public static final String COMMAND_FREQUENCY_20 = "sub20@"; + + /** + * 命令 频率:一个小时 + */ + public static final String COMMAND_FREQUENCY_3600 = "sub3600@"; + + /**----------------------------命令end----------------------------*/ diff --git a/electripper-system/src/main/java/com/ruoyi/system/domain/EtOperatingArea.java b/electripper-system/src/main/java/com/ruoyi/system/domain/EtOperatingArea.java index 624c655..4d9efab 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/domain/EtOperatingArea.java +++ b/electripper-system/src/main/java/com/ruoyi/system/domain/EtOperatingArea.java @@ -30,6 +30,10 @@ public class EtOperatingArea extends BaseEntityPlus implements Serializable @TableId(value = "area_id", type = IdType.AUTO) private Long areaId; + /** 运营商id */ + @TableField(exist = false) + private Long deptId; + /** 区域名称 */ @Excel(name = "区域名称") private String areaName; diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/IEtOperatingAreaService.java b/electripper-system/src/main/java/com/ruoyi/system/service/IEtOperatingAreaService.java index 687a47a..81fa979 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/IEtOperatingAreaService.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/IEtOperatingAreaService.java @@ -92,9 +92,10 @@ public interface IEtOperatingAreaService extends IService * * @param longitude 经度 * @param latitude 纬度 + * @param deptId 运营商id * @return 结果 */ - EtOperatingArea getAreaInfoByLocation(String longitude, String latitude); + EtOperatingArea getAreaInfoByLocation(String longitude, String latitude,String deptId); /** * 根据部门ID获取运营区选择框列表 diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsDeviceServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsDeviceServiceImpl.java index fd48bb5..e689631 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsDeviceServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/AsDeviceServiceImpl.java @@ -437,7 +437,7 @@ public class AsDeviceServiceImpl extends ServiceImpl i String token = Token.getToken(); String finalOrderNo = orderNo; /** 2.发送命令*/ - ResponseVo responseVo = sendCommandWithResp(asDevice.getMac(), token, IotConstants.COMMAND_OPEN, "编号开锁"); + ResponseVo responseVo = sendCommandWithResp(asDevice.getMac(), token, IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_5, "编号开锁"); if(responseVo.getCode() != 0){ throw new ServiceException("【扫码/编号开锁骑行】更新车辆状态失败"); } @@ -501,7 +501,7 @@ public class AsDeviceServiceImpl extends ServiceImpl i String token = Token.getToken(); Boolean execute = transactionTemplate.execute(e -> { /** 2.发送命令*/ - sendCommand(asDevice.getMac(), token,IotConstants.COMMAND_OPEN,"管理员开锁"); + sendCommand(asDevice.getMac(), token,IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_20,"管理员开锁"); asDevice.setIsAdminUnlocking("1"); asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_OPEN); int i = asDeviceMapper.updateAsDevice(asDevice); @@ -689,7 +689,7 @@ public class AsDeviceServiceImpl extends ServiceImpl i /** 1.获取token*/ String token = Token.getToken(); /** 2.发送命令*/ - sendCommand(asDevice.getMac(), token,IotConstants.COMMAND_LLOSE,"临时锁车"); + sendCommand(asDevice.getMac(), token,IotConstants.COMMAND_LLOSE+IotConstants.COMMAND_FREQUENCY_3600,"临时锁车"); asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); if(StrUtil.isNotBlank(orderNo)){//有订单号,则是用户临时锁车 /** 改变车辆状态:4-临时锁车 */ @@ -721,7 +721,7 @@ public class AsDeviceServiceImpl extends ServiceImpl i if(StrUtil.isBlank(sn))throw new ServiceException("sn不能为空"); AsDevice asDevice = asDeviceMapper.selectAsDeviceBySn(sn); /** 2.发送命令*/ - sendCommand(asDevice.getMac(), Token.getToken(),IotConstants.COMMAND_CLOSE,"管理员锁车"); + sendCommand(asDevice.getMac(), Token.getToken(),IotConstants.COMMAND_CLOSE+IotConstants.COMMAND_FREQUENCY_3600,"管理员锁车"); asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); asDevice.setIsAdminUnlocking("0"); int device = asDeviceMapper.updateAsDevice(asDevice); @@ -750,7 +750,7 @@ public class AsDeviceServiceImpl extends ServiceImpl i Boolean execute = transactionTemplate.execute(e -> { /** TODO 临时解锁*/ /** 2.发送命令*/ - sendCommand(asDevice.getMac(), token,IotConstants.COMMAND_OPEN,"临时解锁"); + sendCommand(asDevice.getMac(), token,IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_5,"临时解锁"); //间隔1秒 // try { // Thread.sleep(500); @@ -960,7 +960,7 @@ public class AsDeviceServiceImpl extends ServiceImpl i String token = Token.getToken(); AsDevice device = asDeviceMapper.selectAsDeviceBySn(order.getSn()); /** 2. 车辆远程关锁*/ - sendCommand(device.getMac(), token,IotConstants.COMMAND_CLOSE,"还车关锁"); + sendCommand(device.getMac(), token,IotConstants.COMMAND_CLOSE+IotConstants.COMMAND_FREQUENCY_3600,"还车关锁"); /** 4. 更新车辆状态*/ device.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL); device.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); @@ -1260,7 +1260,8 @@ public class AsDeviceServiceImpl extends ServiceImpl i List parkingAreas = parkingAreaService.selectEtParkingAreaList(parkingArea); if(ObjectUtil.isNull(parkingAreas) || parkingAreas.size() == 0){ log.info("运营区【{}】没有禁停区,",areaId); - throw new ServiceException("运营区【{}】没有禁停区"+areaId.toString()); + return false; +// throw new ServiceException("运营区【{}】没有禁停区"+areaId.toString()); } for (EtParkingArea etParkingArea : parkingAreas) { if(etParkingArea.getType().equals(ServiceConstants.PARKING_AREA_TYPE_NO_PARKFING)){ diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOperatingAreaServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOperatingAreaServiceImpl.java index aee02a8..27e6295 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOperatingAreaServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOperatingAreaServiceImpl.java @@ -12,6 +12,7 @@ import com.ruoyi.common.annotation.DataScope; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.entity.AsUser; import com.ruoyi.common.core.domain.entity.SysDictType; +import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.map.GeoUtils; @@ -243,13 +244,16 @@ public class EtOperatingAreaServiceImpl extends ServiceImpl etOperatingAreas = etOperatingAreaService.selectEtOperatingAreaList(new EtOperatingArea()); + EtOperatingArea area1 = new EtOperatingArea(); + area1.setDeptId(Long.parseLong(deptId)); + List etOperatingAreas = etOperatingAreaService.selectEtOperatingAreaList(area1); EtOperatingArea area = null; for(EtOperatingArea etOperatingArea:etOperatingAreas){ String boundary = etOperatingArea.getBoundary(); @@ -274,21 +278,25 @@ public class EtOperatingAreaServiceImpl extends ServiceImpl0){ + for(EtOperatingArea etOperatingArea:etOperatingAreas){ + Geometry geometry = GeoUtils.fromWkt(etOperatingArea.getBoundary()); + if (geometry.contains(point)) { + return etOperatingArea; + }else{ + // 获取多边形的外边界 + Coordinate[] coordinates = geometry.getCoordinates(); + for (Coordinate coord : coordinates) { + double distance = GeoUtils.calculateDistance(lat, lon, coord.y, coord.x); + if (distance < minDistance) { + minDistance = distance; + closestArea = etOperatingArea; + } } } } + }else{ + throw new ServiceException("没有找到任何运营区"); } return closestArea; } diff --git a/electripper-system/src/main/resources/mapper/system/EtOperatingAreaMapper.xml b/electripper-system/src/main/resources/mapper/system/EtOperatingAreaMapper.xml index 0ac699d..e5b6787 100644 --- a/electripper-system/src/main/resources/mapper/system/EtOperatingAreaMapper.xml +++ b/electripper-system/src/main/resources/mapper/system/EtOperatingAreaMapper.xml @@ -66,6 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join sys_dept d on d.dept_id = ad.dept_id where 1 = 1 and a.area_name like concat('%', #{areaName}, '%') + and d.dept_id = #{deptId} ${params.dataScope} diff --git a/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml b/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml index 7437508..a67a7e3 100644 --- a/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml +++ b/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -104,7 +104,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"