package com.ruoyi.app.position.service.impl; import com.alibaba.fastjson2.JSON; import com.ruoyi.alarm.wall.domain.ArdAlarmWall; import com.ruoyi.alarm.wall.mapper.ArdAlarmWallMapper; import com.ruoyi.alarm.wall.service.IArdAlarmWallService; import com.ruoyi.alarmpoints.wall.domain.ArdWall; import com.ruoyi.alarmpoints.wall.mapper.ArdWallMapper; import com.ruoyi.app.position.domain.ArdAppPosition; import com.ruoyi.app.position.mapper.ArdAppPositionMapper; import com.ruoyi.app.position.service.IArdAppPositionService; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.scheduling.domian.SchedulingParam; import com.ruoyi.system.mapper.SysUserMapper; import com.ruoyi.system.service.ISysUserService; import com.ruoyi.utils.gis.GisUtil; import com.ruoyi.utils.gis.Point; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; import static com.ruoyi.utils.websocket.util.WebSocketUtils.ONLINE_USER_SESSIONS; /** * app位置Service业务层处理 * * @author ard * @date 2023-07-18 */ @Service @Slf4j public class ArdAppPositionServiceImpl implements IArdAppPositionService { @Resource private ArdAppPositionMapper ardAppPositionMapper; @Resource private ISysUserService iSysUserService; @Resource RedisCache redisCache; @Resource ArdWallMapper ardWallMapper; @Resource IArdAlarmWallService ardAlarmWallService; @Resource private SysUserMapper sysUserMapper; Map firstAlarmMap = new HashMap<>();//首次报警缓存key:用户id_围栏id value: 报警id /** * 查询app位置 * * @param id app位置主键 * @return app位置 */ @Override public ArdAppPosition selectArdAppPositionById(String id) { return ardAppPositionMapper.selectArdAppPositionById(id); } /** * 按用户id查询最后的位置信息 * * @param userId app用户主键 * @return app位置 */ @Override public ArdAppPosition selectLastArdAppPositionByUserId(String userId) { return ardAppPositionMapper.selectLastArdAppPositionByUserId(userId); } /** * 查询app位置列表 * * @param ardAppPosition app位置 * @return app位置 */ @Override public List selectArdAppPositionList(ArdAppPosition ardAppPosition) { return ardAppPositionMapper.selectArdAppPositionList(ardAppPosition); } /** * 新增app位置 * * @param ardAppPosition app位置 * @return 结果 */ @Override public List insertArdAppPosition(ArdAppPosition ardAppPosition) { ardAppPosition.setId(IdUtils.simpleUUID()); ardAppPosition.setCreateTime(DateUtils.getNowDate()); ardAppPositionMapper.insertArdAppPosition(ardAppPosition); return DetectionWallAlarm(ardAppPosition); } /** * 修改app位置 * * @param ardAppPosition app位置 * @return 结果 */ @Override public int updateArdAppPosition(ArdAppPosition ardAppPosition) { return ardAppPositionMapper.updateArdAppPosition(ardAppPosition); } /** * 批量删除app位置 * * @param ids 需要删除的app位置主键 * @return 结果 */ @Override public int deleteArdAppPositionByIds(String[] ids) { return ardAppPositionMapper.deleteArdAppPositionByIds(ids); } /** * 删除app位置信息 * * @param id app位置主键 * @return 结果 */ @Override public int deleteArdAppPositionById(String id) { return ardAppPositionMapper.deleteArdAppPositionById(id); } /** * 获取封控圈内所有在线app用户 * 刘苏义 * 2023/8/17 13:56:36 */ @Override public List getNearAppUsers(SchedulingParam param) { List filteredList = new ArrayList<>(); try { Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId(); Double longitude = param.getLongitude(); Double latitude = param.getLatitude(); if (longitude == null && latitude == null) { log.debug("原点坐标为空"); return null; } Integer radius = param.getSealingRadius(); if (radius == null) { log.debug("半径距离为空"); return null; } SysUser user = new SysUser(); user.setDeptId(deptId); List appUserList = iSysUserService.selectAllAppUserList(user); //过滤在线和单兵端 List onLineList = appUserList.stream() .filter(sysUser -> (sysUser.getAppOnlineState().equals("1"))) .filter(sysUser -> (sysUser.getAppUserType().equals("1"))) .collect(Collectors.toList()); //过滤范围 for (SysUser sysUser : onLineList) { ArdAppPosition ardAppPosition = ardAppPositionMapper.selectLastArdAppPositionByUserId(sysUser.getUserId()); if (ardAppPosition != null) { Double lon = ardAppPosition.getLongitude(); Double lat = ardAppPosition.getLatitude(); if (longitude == null || latitude == null) { continue; } double distance = GisUtil.getDistance(new double[]{longitude, latitude}, new double[]{lon, lat}); if (distance <= radius) { Map params = new HashMap<>(); params.put("longitude", lon); params.put("latitude", lat); sysUser.setParams(params); filteredList.add(sysUser); // 将满足条件的用户添加到筛选列表中 } } } } catch (Exception ex) { log.error("获取封控圈内所有在线app用户异常" + ex.getMessage()); } return filteredList; } /** * 获取封控圈内所有在线app用户(多边形) * 刘苏义 * 2023/8/17 13:56:36 */ @Override public List getNearAppUsersWithPolygon(SchedulingParam param) { List filteredList = new ArrayList<>(); try { Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId(); List partitionLocation = param.getPartitionLocation(); SysUser user = new SysUser(); user.setDeptId(deptId); List appUserList = iSysUserService.selectAllAppUserList(user); //过滤在线 List onLineList = appUserList.stream() .filter(sysUser -> (sysUser.getAppOnlineState().equals("1"))) .filter(sysUser -> (sysUser.getAppUserType().equals("1"))) .collect(Collectors.toList()); //过滤范围 for (SysUser sysUser : onLineList) { ArdAppPosition ardAppPosition = ardAppPositionMapper.selectLastArdAppPositionByUserId(sysUser.getUserId()); if (ardAppPosition != null) { Double lon = ardAppPosition.getLongitude(); Double lat = ardAppPosition.getLatitude(); if (lon == null || lat == null) { continue; } Point point2D = new Point(lon, lat); boolean inPolygon = GisUtil.isInPolygon(point2D, partitionLocation); if (inPolygon) { Map params = new HashMap<>(); params.put("longitude", lon); params.put("latitude", lat); sysUser.setParams(params); filteredList.add(sysUser); // 将满足条件的用户添加到筛选列表中 } } } } catch (Exception ex) { log.error("获取封控圈内所有在线app用户异常" + ex.getMessage()); } return filteredList; } /** * 实时位置检测围栏报警 * 刘苏义 * 2023/8/31 8:54:06 */ /*public List DetectionWallAlarm(ArdAppPosition ardAppPosition) { List ardAlarmWalls = new ArrayList<>(); //获取当前用户的部门 String userId = ardAppPosition.getUserId(); //获取用户关联的所有电子围栏 List ardWalls = ardWallMapper.selectArdWallListByUserId(userId); if (ardWalls.size() > 0) { //遍历所有电子围栏 for (ArdWall wall : ardWalls) { String wallId = wall.getId();//围栏ID String wallType = wall.getType();//围栏类型 String wallPoi = wall.getWallPoi();//围栏坐标集合 //处理多边形的每个点的经纬度 String[] parts = wallPoi.split(","); List pointList = new ArrayList<>(); for (int i = 0; i < parts.length; i += 3) { Point point = new Point(); point.setLongitude(Double.valueOf(parts[i])); point.setLatitude(Double.valueOf(parts[i + 1])); pointList.add(point); } //当前用户的位置 Point userPoint = new Point(ardAppPosition.getLongitude(), ardAppPosition.getLatitude()); boolean inPolygon = GisUtil.isInPolygon(userPoint, pointList);//判断是否在围栏内 //创建围栏报警实体对象 ArdAlarmWall ardAlarmWall = new ArdAlarmWall(); ardAlarmWall.setWallId(wall.getId()); ardAlarmWall.setWallName(wall.getWallName()); ardAlarmWall.setUserId(userId); ardAlarmWall.setAlarmTime(DateUtils.getNowDate()); ardAlarmWall.setAlarmType(wall.getType()); ardAlarmWall.setLongitude(ardAppPosition.getLongitude()); ardAlarmWall.setLatitude(ardAppPosition.getLatitude()); ardAlarmWall.setAltitude(ardAppPosition.getAltitude()); String key = userId + "_" + wallId;//最后一次报警缓存key //按类型区分围栏禁入或者禁出 if ("1".equals(wallType)) { if (inPolygon) { //禁入围栏则若在围栏内,获取首次进入围栏报警ID String lastInAlarmId = firstAlarmMap.get(key); //判断当前用户是否首次进入围栏内 if (lastInAlarmId == null) { //当前用户首次进入生成报警 String uuid = IdUtils.simpleUUID(); ardAlarmWall.setId(uuid); ardAlarmWallService.insertArdAlarmWall(ardAlarmWall); //记录首次报警id firstAlarmMap.put(key, uuid); } else { //用户已进入更新最后报警 ardAlarmWall.setId(lastInAlarmId); ardAlarmWallService.updateArdAlarmWall(ardAlarmWall); } ardAlarmWalls.add(ardAlarmWall); } else { //禁入围栏则若在围栏外则移除报警缓存 firstAlarmMap.remove(key); } } else//禁出 { //判断当前用户位置是否在围栏外 if (!inPolygon) { //禁出围栏则若在围栏外,获取首次走出围栏报警ID String lastAlarmId = firstAlarmMap.get(key); //判断当前用户是否首次在围栏外 if (lastAlarmId == null) { String uuid = IdUtils.simpleUUID(); //当前用户首次出围栏生成报警 ardAlarmWall.setId(uuid); ardAlarmWallService.insertArdAlarmWall(ardAlarmWall); //记录首次报警id firstAlarmMap.put(key, uuid); } else { //用户已经在围栏外更新报警 ardAlarmWall.setId(lastAlarmId); ardAlarmWallService.updateArdAlarmWall(ardAlarmWall); } ardAlarmWalls.add(ardAlarmWall); } else { //移除首次报警缓存 firstAlarmMap.remove(key); } } } } return ardAlarmWalls; }*/ public List DetectionWallAlarm(ArdAppPosition ardAppPosition) { List ardAlarmWalls = new ArrayList<>(); //获取当前用户的部门 String userId = ardAppPosition.getUserId(); //获取用户关联的所有电子围栏 List ardWalls = ardWallMapper.selectArdWallListByUserId(userId); List ardWallsNoIn = new ArrayList();//禁入电子围栏 List ardWallsNoOut = new ArrayList();//禁出电子围栏 ardWallsNoIn = ardWalls.stream().filter(ardWall -> ardWall.getType().equals("1")).collect(Collectors.toList()); ardWallsNoOut = ardWalls.stream().filter(ardWall -> ardWall.getType().equals("2")).collect(Collectors.toList()); //当前用户的位置 Point userPoint = new Point(ardAppPosition.getLongitude(), ardAppPosition.getLatitude()); if(ardWallsNoIn.size() > 0){//判断禁入 for(ArdWall wall : ardWallsNoIn){ String wallId = wall.getId();//围栏ID String wallPoi = wall.getWallPoi();//围栏坐标集合 //处理多边形的每个点的经纬度 String[] parts = wallPoi.split(","); List pointList = new ArrayList<>(); for (int i = 0; i < parts.length; i += 3) { Point point = new Point(); point.setLongitude(Double.valueOf(parts[i])); point.setLatitude(Double.valueOf(parts[i + 1])); pointList.add(point); } boolean inPolygon = GisUtil.isInPolygon(userPoint, pointList);//判断是否在围栏内 //创建围栏报警实体对象 ArdAlarmWall ardAlarmWall = new ArdAlarmWall(); ardAlarmWall.setWallId(wall.getId()); ardAlarmWall.setWallName(wall.getWallName()); ardAlarmWall.setUserId(userId); ardAlarmWall.setAlarmTime(DateUtils.getNowDate()); ardAlarmWall.setAlarmType(wall.getType()); ardAlarmWall.setLongitude(ardAppPosition.getLongitude()); ardAlarmWall.setLatitude(ardAppPosition.getLatitude()); ardAlarmWall.setAltitude(ardAppPosition.getAltitude()); String key = userId + "_" + wallId;//最后一次报警缓存key if (inPolygon) { //禁入围栏则若在围栏内,获取首次进入围栏报警ID String lastInAlarmId = firstAlarmMap.get(key); //判断当前用户是否首次进入围栏内 if (lastInAlarmId == null) { //当前用户首次进入生成报警 String uuid = IdUtils.simpleUUID(); ardAlarmWall.setId(uuid); ardAlarmWallService.insertArdAlarmWall(ardAlarmWall); //记录首次报警id firstAlarmMap.put(key, uuid); } else { //用户已进入更新最后报警 ardAlarmWall.setId(lastInAlarmId); ardAlarmWallService.updateArdAlarmWall(ardAlarmWall); } ardAlarmWalls.add(ardAlarmWall); } else { //禁入围栏则若在围栏外则移除报警缓存 firstAlarmMap.remove(key); } } } Boolean noOutFlag = true; if(ardWallsNoOut.size() > 0) {//判断禁出 for(ArdWall wall : ardWallsNoOut){ String wallPoi = wall.getWallPoi();//围栏坐标集合 //处理多边形的每个点的经纬度 String[] parts = wallPoi.split(","); List pointList = new ArrayList<>(); for (int i = 0; i < parts.length; i += 3) { Point point = new Point(); point.setLongitude(Double.valueOf(parts[i])); point.setLatitude(Double.valueOf(parts[i + 1])); pointList.add(point); } boolean inPolygon = GisUtil.isInPolygon(userPoint, pointList);//判断是否在围栏内 if (!inPolygon) { noOutFlag = true; } else { noOutFlag = false; break; } } } if(noOutFlag){//全部禁出电子围栏都出去了 for(ArdWall wall : ardWallsNoOut){ String wallId = wall.getId();//围栏ID //创建围栏报警实体对象 ArdAlarmWall ardAlarmWall = new ArdAlarmWall(); ardAlarmWall.setWallId(wall.getId()); ardAlarmWall.setWallName(wall.getWallName()); ardAlarmWall.setUserId(userId); ardAlarmWall.setAlarmTime(DateUtils.getNowDate()); ardAlarmWall.setAlarmType(wall.getType()); ardAlarmWall.setLongitude(ardAppPosition.getLongitude()); ardAlarmWall.setLatitude(ardAppPosition.getLatitude()); ardAlarmWall.setAltitude(ardAppPosition.getAltitude()); String key = userId + "_" + wallId;//最后一次报警缓存key //禁出围栏则若在围栏外,获取首次走出围栏报警ID String lastAlarmId = firstAlarmMap.get(key); //判断当前用户是否首次在围栏外 if (lastAlarmId == null) { String uuid = IdUtils.simpleUUID(); //当前用户首次出围栏生成报警 ardAlarmWall.setId(uuid); ardAlarmWallService.insertArdAlarmWall(ardAlarmWall); //记录首次报警id firstAlarmMap.put(key, uuid); } else { //用户已经在围栏外更新报警 ardAlarmWall.setId(lastAlarmId); ardAlarmWallService.updateArdAlarmWall(ardAlarmWall); } ardAlarmWalls.add(ardAlarmWall); } }else{ for(ArdWall wall : ardWallsNoOut){ String wallId = wall.getId();//围栏ID String key = userId + "_" + wallId;//最后一次报警缓存key firstAlarmMap.remove(key); } } return ardAlarmWalls; } @Override public Map> getOnlinePCOrCommander(String usersId) { Map> result = new HashMap(); List commanderList = sysUserMapper.getOnlineCommander(usersId); result.put("commander",commanderList); try{ List onLinePCIdList = new ArrayList(); //onLinePCIdList.addAll(ONLINE_USER_SESSIONS.keySet()); for(String id : ONLINE_USER_SESSIONS.keySet()){ onLinePCIdList.add(id.split("_")[0]); } List pcList = sysUserMapper.getOnlinePC(usersId,onLinePCIdList); result.put("pc",pcList); }catch(Exception e){ result.put("pc",new ArrayList()); } return result; } @Override public List> getOnlineCommanderPosition(String soilderId) { List> result = ardAppPositionMapper.getOnlineCommanderPosition(soilderId); return result; } @Override public List getAPPPositionByUserIdAndTime(Map para) { String userId = para.get("userId"); String beginTime = para.get("beginTime"); String endTime = para.get("endTime"); List result = ardAppPositionMapper.getAPPPositionByUserIdAndTime(userId,beginTime,endTime); return result; } /*@Override public void sendCheckCommandersPosition(String usersId,Map para) { String reason = (String) para.get("reason"); List usersIdList = (List) para.get("usersIdList"); for(String commanderId : usersIdList){ //设置key为checkCommanderPosition_指挥端主键_单兵端主键 String key = "checkCommanderPosition_" + commanderId + "_" + usersId; Map value = new HashMap(); value.put("reason",reason); value.put("state","0"); value.put("begin",""); value.put("commanderId",commanderId); value.put("soilderId",usersId); redisCache.setCacheObject(key, JSON.toJSONString(value)); } }*/ /*@Override public void sendCheckSYCarsPosition(String usersId, Map para) { String reason = (String) para.get("reason"); List usersIdList = (List) para.get("usersIdList"); for(String commanderId : usersIdList){ //设置key为checkSYCarsPosition_指挥端主键/PC端主键_单兵端主键 String key = "checkSYCarsPosition_" + commanderId + "_" + usersId; Map value = new HashMap(); value.put("reason",reason); value.put("state","0"); value.put("begin",""); value.put("commanderId",commanderId); value.put("soilderId",usersId); redisCache.setCacheObject(key, JSON.toJSONString(value)); } }*/ /*@Override public List> getCheckCommandersPosition(String usersId) { String key = "checkCommanderPosition_" + usersId + "_"; List keyValueList = redisCache.getListKey(key); List> result = new ArrayList(); for(Object o : keyValueList){ Map map = JSON.parseObject((String) o); if(((String)map.get("state")).equals("0")){//state为0就是未审批 SysUser sysUser = sysUserMapper.selectUserById((String) map.get("soilderId")); map.put("userName",sysUser.getUserName()); result.add(map); } } return result; }*/ /*@Override public List> getCheckSYCarsPosition(String usersId) { String key = "checkSYCarsPosition_" + usersId + "_"; List keyValueList = redisCache.getListKey(key); List> result = new ArrayList(); for(Object o : keyValueList){ Map map = JSON.parseObject((String) o); if(((String)map.get("state")).equals("0")){//state为0就是未审批 SysUser sysUser = sysUserMapper.selectUserById((String) map.get("soilderId")); map.put("userName",sysUser.getUserName()); result.add(map); } } return result; }*/ /*@Override public Map>> getCheckPosition(String usersId) { Map>> result = new HashMap(); //查看指挥端位置申请 String keyCommanderPosition = "checkCommanderPosition_" + usersId + "_"; List keyValueCommanderPositionList = redisCache.getListKey(keyCommanderPosition); List> resultCommanderPosition = new ArrayList(); for(Object o : keyValueCommanderPositionList){ Map map = JSON.parseObject((String) o); if(((String)map.get("state")).equals("0")){//state为0就是未审批 SysUser sysUser = sysUserMapper.selectUserById((String) map.get("soilderId")); map.put("userName",sysUser.getUserName()); if(sysUser.getNickName() != null){ map.put("nickName",sysUser.getNickName()); }else{ map.put("nickName",sysUser.getNickName()); } resultCommanderPosition.add(map); } } //查看车辆位置申请 String keySYCarsPosition = "checkSYCarsPosition_" + usersId + "_"; List keyValueSYCarsPositionList = redisCache.getListKey(keySYCarsPosition); List> resultSYCarsPosition = new ArrayList(); for(Object o : keyValueSYCarsPositionList){ Map map = JSON.parseObject((String) o); if(((String)map.get("state")).equals("0")){//state为0就是未审批 SysUser sysUser = sysUserMapper.selectUserById((String) map.get("soilderId")); map.put("userName",sysUser.getUserName()); if(sysUser.getNickName() != null){ map.put("nickName",sysUser.getNickName()); }else{ map.put("nickName",sysUser.getNickName()); } resultSYCarsPosition.add(map); } } result.put("commander",resultCommanderPosition); result.put("SYCars",resultSYCarsPosition); return result; }*/ }