package com.cloud.device.service.impl; import com.alibaba.fastjson.JSONObject; import com.cloud.common.utils.PageUtil; import com.cloud.common.utils.RestTemplateUtil; import com.cloud.common.utils.StringUtil; import com.cloud.device.constants.Constants; import com.cloud.device.dao.DeviceDao; import com.cloud.device.dao.DicDao; import com.cloud.device.dao.NodeDao; import com.cloud.device.dao.OrgDao; import com.cloud.device.model.Device; import com.cloud.device.model.Dic; import com.cloud.device.model.Node; import com.cloud.device.model.Org; import com.cloud.device.service.DeviceService; import com.cloud.device.utils.CreatePhUtil; import com.cloud.device.utils.EnumStr; import com.cloud.device.vo.MapDeviceVo; import com.cloud.device.vo.MenuTreeVo; import com.cloud.device.vo.OrgDeviceVO; import com.cloud.model.common.Page; import lombok.extern.log4j.Log4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.io.IOException; import java.util.*; /** * @author lp */ @Log4j @Service public class DeviceServiceImpl implements DeviceService { @Autowired private DeviceDao deviceDao; @Autowired private NodeDao nodeDao; @Autowired private OrgDao orgDao; @Autowired private CreatePhUtil createPhUtil; @Autowired private EnumStr enumStr; /** * 获取平台设备列表(分页) * @param * @return */ @Override public Page findPlatDeviceList(Map param) { int total = 0; List list = new ArrayList<>(); String type = param.get("type").toString(); log.info("type:"+type); if(type.equals(Constants.TYPE_MENU)){//点击的是菜单 total = deviceDao.countPlatDevice(param); if(total > 0){ PageUtil.pageParamConver(param,true); list = deviceDao.findPlatDevicePageList(param); if(list !=null && list.size()>0){ for(Device device: list){ if(device.getOrgId() !=null){ Org org = orgDao.selectById(device.getOrgId()); if(org !=null) device.setOrgName(org.getName()); } setDeviceSubType(device); } } } }else{ String id = param.get("orgId").toString(); Device device = deviceDao.selectById(id); if(device !=null){ if(device.getOrgId() !=null){ Org org = orgDao.selectById(device.getOrgId()); if(org !=null) device.setOrgName(org.getName()); } setDeviceSubType(device); total =1; list.add(device); } } return new Page<>(total, list); } /** * 获取所有非集群监控设备,不分页 * @param param * @return */ public List findAllPlatDeviceList(Map param){ List list = new ArrayList<>(); String type = param.get("type").toString(); log.info("type:"+type); if(type.equals(Constants.TYPE_MENU)){//点击的是菜单 list = deviceDao.findAllPlatDeviceList(param); if(list !=null && list.size()>0){ for(Device device: list){ if(device.getOrgId() !=null){ Org org = orgDao.selectById(device.getOrgId()); if(org !=null) device.setOrgName(org.getName()); } setDeviceSubType(device); } } }else{ String id = param.get("orgId").toString(); Device device = deviceDao.selectById(id); if(device !=null){ if(device.getOrgId() !=null){ Org org = orgDao.selectById(device.getOrgId()); if(org !=null) device.setOrgName(org.getName()); } setDeviceSubType(device); list.add(device); } } return list; } @Override public Device selectById(String id) { return deviceDao.selectById(id); } /** * 保存设备 * @param model * @return */ @Override public int saveDevice(Device model) { if(StringUtils.isEmpty(model.getId())){ model.setId(UUID.randomUUID().toString()); return deviceDao.insertSelective(model); }else{ return deviceDao.updateByIdSelective(model); } } /** * 更新设备所属组织 * @param id * @param orgId * @return */ public int updateOrg(String id, Integer orgId){ Device device = new Device(); device.setId(id); device.setOrgId(orgId.longValue()); return deviceDao.updateByIdSelective(device); } /** * 更新设备的经纬度信息 * @param param * @return */ public int updatePosById(Map param){ Device device = new Device(); device.setId(param.get("id").toString()); device.setLongitude(param.get("longitude").toString()); device.setLatitude(param.get("latitude").toString()); return deviceDao.updateByIdSelective(device); } /** * 目前是更新分析节点的公网ip和端口 * @param param * @return */ public int updatePublicIpPort(Map param){ Node node = new Node(); node.setId(param.get("id").toString()); node.setPublicIp(param.get("publicIp").toString()); node.setPublicPort(param.get("publicPort").toString()); return nodeDao.updateByIdSelective(node); } /** * 删除设备 * @param id * @return */ @Override public int deleteById(String id) { return deviceDao.deleteById(id); } public Device findByIp(String ip){ return deviceDao.findByIp(ip); } /** * 获取组织设备树 * @return */ @Override public List getOrgDeviceTree(Map param) { List dataList = new ArrayList<>();//返回的列表 List orgIds = new ArrayList<>(); List all = orgDao.findAll(null);//所有组织机构 List searchedOrgs = orgDao.findAll(param); if(searchedOrgs !=null && searchedOrgs.size()>0){ //搜索出来的有菜单 for(Org org:searchedOrgs){ String parentIds = org.getParentIds(); if(StringUtils.isNotEmpty(parentIds)){ String[] orgIdArr = parentIds.substring(1, parentIds.length() - 1).split(","); for(String str : orgIdArr){ Long orgId = Long.parseLong(str); if(!orgIds.contains(orgId)){ orgIds.add(orgId); } } } if(!orgIds.contains(org.getId())){ orgIds.add(org.getId()); } } } if(param.containsKey("name")){ param.put("condition", param.get("name")); } List searchedDevices = deviceDao.findAllOrgDevice(param); if(searchedDevices !=null && searchedDevices.size() >0){ for(Device device:searchedDevices){ if(device.getOrgId() > 0){ Org deviceOrg = orgDao.selectById(device.getOrgId()); String parentIds = deviceOrg.getParentIds(); if(StringUtils.isNotEmpty(parentIds)){ String[] orgIdArr = parentIds.substring(1, parentIds.length() - 1).split(","); for(String str : orgIdArr){ Long orgId = Long.parseLong(str); if(!orgIds.contains(orgId)){ orgIds.add(orgId); } } } if(!orgIds.contains(device.getOrgId())){ orgIds.add(device.getOrgId()); } } } } if(orgIds.size()>0){ List showOrgs = new ArrayList<>(); for(Org org : all){ if(orgIds.contains(org.getId())){ showOrgs.add(org); } } setOrgDeviceTree(0L, showOrgs, searchedDevices, dataList); } return dataList; } @Override public List findByOrgId(Long id) { return deviceDao.findByOrgId(id); } private void setOrgDeviceTree(Long parentId,List all, List allDevices, List list){ all.forEach(org->{ if(parentId.equals(org.getParentId())){ MenuTreeVo menuTreeVo = new MenuTreeVo(); menuTreeVo.setId(org.getId().toString()); menuTreeVo.setName(org.getName()); menuTreeVo.setType(Constants.TYPE_MENU); list.add(menuTreeVo); List child = new ArrayList<>(); menuTreeVo.setChild(child); setOrgDeviceTree(org.getId(), all, allDevices, child); } }); allDevices.forEach(device -> { if(parentId.equals(device.getOrgId())){ MenuTreeVo menuTreeVo = new MenuTreeVo(); menuTreeVo.setId(device.getId()); menuTreeVo.setName(device.getName()); menuTreeVo.setIcon(""); menuTreeVo.setType(device.getType()); menuTreeVo.setStatus(device.getStatus()); menuTreeVo.setChild(new ArrayList<>()); if(StringUtils.isNotEmpty(device.getLongitude()) && StringUtils.isNotEmpty(device.getLatitude())) menuTreeVo.setIsOnMap(1);//已定位到地图 else menuTreeVo.setIsOnMap(0);//未定位到地图 list.add(menuTreeVo); } }); } public MapDeviceVo findAllDevices(){ MapDeviceVo all = new MapDeviceVo(); List noPosDevices = deviceDao.findNoPosDevices(); List posDevices = deviceDao.findPosDevices(); if(noPosDevices !=null && noPosDevices.size()>0){ for(Device device : noPosDevices){ setDeviceSubType(device); } } if(posDevices !=null && posDevices.size()>0){ for(Device device : posDevices){ setDeviceSubType(device); } } all.setNoPosList(noPosDevices); all.setPosList(posDevices); return all; } @Override public List findByArea(Map param){ List dataList = new ArrayList<>();//返回的列表 if(param.containsKey("condition")){ param.put("name", param.get("condition")); } List orgIds = new ArrayList<>(); List all = orgDao.findAll(null);//所有组织机构 List searchedOrgs = orgDao.findAll(param); if(searchedOrgs !=null && searchedOrgs.size()>0){ //搜索出来的有菜单 for(Org org:searchedOrgs){ String parentIds = org.getParentIds(); if(StringUtils.isNotEmpty(parentIds)){ String[] orgIdArr = parentIds.substring(1, parentIds.length() - 1).split(","); for(String str : orgIdArr){ Long orgId = Long.parseLong(str); if(!orgIds.contains(orgId)){ orgIds.add(orgId); } } } if(!orgIds.contains(org.getId())){ orgIds.add(org.getId()); } } } log.info("第一次获取到的菜单列表:"+orgIds); List searchedDevices = deviceDao.findAllDevice(param); if(searchedDevices !=null && searchedDevices.size() >0){ for(Device device:searchedDevices){ log.info("device.name:"+device.getName()); if(device.getOrgId() !=null && device.getOrgId() > 0){ Org deviceOrg = orgDao.selectById(device.getOrgId()); String parentIds = deviceOrg.getParentIds(); if(StringUtils.isNotEmpty(parentIds)){ String[] orgIdArr = parentIds.substring(1, parentIds.length() - 1).split(","); for(String str : orgIdArr){ Long orgId = Long.parseLong(str); if(!orgIds.contains(orgId)){ orgIds.add(orgId); } } } if(!orgIds.contains(device.getOrgId())){ orgIds.add(device.getOrgId()); } } } } log.info("第二次获取到的菜单列表:"+orgIds); if(orgIds.size()>0){ List showOrgs = new ArrayList<>(); for(Org org : all){ if(orgIds.contains(org.getId())){ showOrgs.add(org); } } setOrgDeviceTree(0L, showOrgs, searchedDevices, dataList); } return dataList; } /** * 点击区域上的菜单或者设备 * @param param * @return */ public List findAllDeviceByArea(Map param){ List list = new ArrayList<>(); String type = param.get("type").toString(); log.info("type:"+type); if(type.equals(Constants.TYPE_MENU)){//点击的是菜单 list = deviceDao.findAllDeviceList(param); if(list !=null && list.size()>0){ for(Device device: list){ if(device.getOrgId() !=null){ Org org = orgDao.selectById(device.getOrgId()); if(org !=null) device.setOrgName(org.getName()); } setDeviceSubType(device); } } }else{ String id = param.get("orgId").toString(); Device device = deviceDao.selectById(id); if(device !=null){ if(device.getOrgId() !=null){ Org org = orgDao.selectById(device.getOrgId()); if(org !=null) device.setOrgName(org.getName()); } setDeviceSubType(device); list.add(device); } } return list; } /** * 设置设备的子类型(摄像机:分析摄像机还是监控摄像机) * @param device */ private void setDeviceSubType(Device device){ if(Device.DEVICE_TYPE_CAMERA.equals(device.getType())){//摄像机需要细分是分析摄像机还是监控摄像机 String deviceType = device.getType(); if(StringUtils.isNotEmpty(device.getNodeId())){ device.setSubType(deviceType+Device.DEVICE_TYPE_CAMERA_FX);//分析摄像机 }else{ device.setSubType(deviceType+Device.DEVICE_TYPE_CAMERA_JK);//监控摄像机 } } } public Node getNodeByDevId(String devId){ return nodeDao.getNodeByDevId(devId); } /** * 依据设备id 获取 设备信息 * wp * 19-02-20 * @param devId * @return */ @Override public JSONObject getDevSnapshot(String devId) throws IOException { Device device = deviceDao.selectById(devId); // "rtsp://admin:a1234567@192.168.1.215:554/h264/ch1/main/av_stream" JSONObject resp = new JSONObject(); if (!new Integer(0).equals(device.getCameraType())){ // 调用 c 接口 查询实时 视频 return getDevSnapshotByCserver( device); } String brand = null; switch (device.getBrand()){ case "haikang": brand = "/h264/ch1/main/av_stream";break; // rtsp://[username]:[password]@[ip]:[port]/h264/ch1/main/av_stream case "dahua": brand = "/cam/realmonitor?channel=1&subtype=0";break; // rtsp://[username]:[password]@[ip]:[port]/cam/realmonitor?channel=1&subtype=0 case "yushi": brand = "/video";break; // rtsp://[username]:[password]@[ip]:[port]/video default: brand = null; } if (StringUtils.isBlank(brand)){ throw new RuntimeException("本地摄像机"+devId+"品牌未知,无法获取视频流地址。"); } String streamUrl = "rtsp://"+device.getUsername()+":"+device.getPassword()+"@"+device.getIp()+":"+enumStr.getCameraPort()+brand; String s = createPhUtil.processImg(streamUrl); if (s == null) throw new RuntimeException("截取地址不存在,摄像机未连接在局域网,请联系管理员。"); // 将 截图 存入摄像机 属性 device.setId(devId); device.setBasePhoto(s); int i = deviceDao.updateByIdSelective(device); if (i < 1){ log.info("摄像机"+devId+"的实时视频截图存储"+s+"失败,为了返回页面截图只打印log,不抛出修改失败错误。"); } // 返回页面数据 // s = enumStr.getHttpImgUrl()+s; resp.put("imgUrl",s); return resp; } private JSONObject getDevSnapshotByCserver(Device device){ JSONObject resp = new JSONObject(); String devId = device.getId(); Node node = nodeDao.selectById(device.getNodeId()); String nodeIp = null; Integer nodePort = enumStr.getC_PORT(); if (node != null) {nodeIp = node.getNodeIp(); } else throw new RuntimeException("国标摄像机"+devId+"所在node节点未知。"); if (StringUtils.isBlank(nodeIp) ) throw new RuntimeException("国标摄像机"+devId+"所在node节点ip 或port未知。"); String url = "http://"+nodeIp+":"+nodePort + "/getSnapshot"; JSONObject params = new JSONObject(); params.put("id",devId); params.put("str_brand",device.getBrand()); params.put("str_ip",device.getBrand()); params.put("n_port",device.getBrand()); params.put("str_username",device.getBrand()); params.put("str_password",device.getBrand()); String post = RestTemplateUtil.post(url, params, MediaType.APPLICATION_JSON_UTF8, false); JSONObject jsonObject = JSONObject.parseObject(post); // ret_status imgUrl String s = jsonObject.getString("imgUrl"); if (StringUtils.isBlank(s)){ throw new RuntimeException("调用c 接口获取实时截图错误信息;"+jsonObject.getString("ret_status")); } // 将 截图 存入摄像机 属性 device.setId(devId); device.setBasePhoto(s); int i = deviceDao.updateByIdSelective(device); if (i < 1){ log.info("摄像机"+devId+"的实时视频截图存储"+s+"失败,为了返回页面截图只打印log,不抛出修改失败错误。"); } resp.put("imgUrl",s); return resp; } }