package com.ruoyi.other.controller; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.other.api.domain.TDevice; import com.ruoyi.other.query.VideoMonitorControlRequest; import com.ruoyi.other.query.VideoMonitorPageQuery; import com.ruoyi.other.service.TDeviceService; import com.ruoyi.other.util.EzvizOpenApiUtils; import com.ruoyi.other.vo.VideoMonitorDeviceVO; import io.swagger.annotations.ApiOperation; import org.springframework.beans.BeanUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.List; import java.util.stream.Collectors; /** * 视频监控控制器 * * @author ruoyi */ @RestController @RequestMapping("/video-monitor") public class VideoMonitorController { private static final String SUCCESS_CODE = "200"; @Resource private TDeviceService deviceService; @Resource private EzvizOpenApiUtils ezvizOpenApiUtils; @ResponseBody @GetMapping("/pageList") @ApiOperation(value = "获取视频监控列表", tags = {"管理后台-视频监控"}) public AjaxResult> pageList(VideoMonitorPageQuery query) { Page page = deviceService.lambdaQuery() .eq(TDevice::getIssueStatus, 1) .like(StringUtils.hasText(query.getDeviceName()), TDevice::getDeviceName, query.getDeviceName()) .eq(query.getPartnerType() != null, TDevice::getPartnerType, query.getPartnerType()) .eq(query.getPartnerId() != null, TDevice::getPartnerId, query.getPartnerId()) .eq(query.getSiteId() != null && query.getSiteId() != 0, TDevice::getSiteId, query.getSiteId()) .orderByDesc(TDevice::getCreateTime) .page(Page.of(query.getPageCurr(), query.getPageSize())); List records = page.getRecords().stream() .map(this::toMonitorVO) .peek(this::fillOnlineStatus) .filter(item -> query.getOnlineStatus() == null || query.getOnlineStatus().equals(item.getOnlineStatus())) .collect(Collectors.toList()); PageInfo pageInfo = new PageInfo<>(query.getPageCurr(), query.getPageSize()); pageInfo.setTotal(page.getTotal()); pageInfo.setRecords(records); return AjaxResult.success(pageInfo); } @ResponseBody @GetMapping("/detail/{id}") @ApiOperation(value = "获取视频监控详情", tags = {"管理后台-视频监控"}) public AjaxResult detail(@PathVariable Integer id) { TDevice device = getIssuedDevice(id); if (device == null) { return AjaxResult.error("设备不存在或未下发"); } VideoMonitorDeviceVO vo = toMonitorVO(device); fillOnlineStatus(vo); fillLiveAddress(vo, device); return AjaxResult.success(vo); } @ResponseBody @PostMapping("/ptz") @ApiOperation(value = "视频监控云台控制", tags = {"管理后台-视频监控"}) public AjaxResult ptz(@RequestBody VideoMonitorControlRequest request) { TDevice device = getIssuedDevice(request.getId()); if (device == null) { return AjaxResult.error("设备不存在或未下发"); } JSONObject result = ezvizOpenApiUtils.ptzControl( device.getDeviceSerial(), StringUtils.hasText(request.getAction()) ? request.getAction() : "start", request.getCommand(), request.getSpeed() ); return buildEzvizResult(result, "云台控制失败"); } @ResponseBody @PostMapping("/sceneSwitch") @ApiOperation(value = "视频监控镜头开关", tags = {"管理后台-视频监控"}) public AjaxResult sceneSwitch(@RequestBody VideoMonitorControlRequest request) { TDevice device = getIssuedDevice(request.getId()); if (device == null) { return AjaxResult.error("设备不存在或未下发"); } JSONObject result = ezvizOpenApiUtils.setSceneSwitch( device.getDeviceSerial(), defaultChannelNo(request.getChannelNo()), request.getEnable() ); return buildEzvizResult(result, "摄像头开关控制失败"); } @ResponseBody @PostMapping("/focus") @ApiOperation(value = "视频监控焦距控制", tags = {"管理后台-视频监控"}) public AjaxResult focus(@RequestBody VideoMonitorControlRequest request) { TDevice device = getIssuedDevice(request.getId()); if (device == null) { return AjaxResult.error("设备不存在或未下发"); } JSONObject result = ezvizOpenApiUtils.ptzControl( device.getDeviceSerial(), "start", request.getCommand(), request.getSpeed() ); if (isEzvizSuccess(result)) { ezvizOpenApiUtils.ptzControl(device.getDeviceSerial(), "stop", request.getCommand(), null); } return buildEzvizResult(result, "焦距控制失败"); } @ResponseBody @PostMapping("/playback") @ApiOperation(value = "获取视频监控回放地址", tags = {"管理后台-视频监控"}) public AjaxResult playback(@RequestBody VideoMonitorControlRequest request) { TDevice device = getIssuedDevice(request.getId()); if (device == null) { return AjaxResult.error("设备不存在或未下发"); } JSONObject result; if (Integer.valueOf(2).equals(request.getType())) { result = ezvizOpenApiUtils.getLocalPlaybackAddress( device.getDeviceSerial(), device.getValidateCode(), defaultChannelNo(request.getChannelNo()), request.getStartTime(), request.getStopTime() ); } else { result = ezvizOpenApiUtils.getCloudPlaybackAddress( device.getDeviceSerial(), device.getValidateCode(), defaultChannelNo(request.getChannelNo()), request.getStartTime(), request.getStopTime() ); } if (!isEzvizSuccess(result)) { return AjaxResult.error(ezvizErrorMessage("获取回放地址失败", result)); } VideoMonitorDeviceVO vo = toMonitorVO(device); vo.setPlaybackAddress(resolveVideoUrl(result)); return AjaxResult.success(vo); } private TDevice getIssuedDevice(Integer id) { if (id == null) { return null; } TDevice device = deviceService.getById(id); if (device == null || !Integer.valueOf(1).equals(device.getIssueStatus())) { return null; } return device; } private VideoMonitorDeviceVO toMonitorVO(TDevice device) { VideoMonitorDeviceVO vo = new VideoMonitorDeviceVO(); BeanUtils.copyProperties(device, vo); return vo; } private void fillOnlineStatus(VideoMonitorDeviceVO vo) { try { JSONObject result = ezvizOpenApiUtils.getDeviceInfo(vo.getDeviceSerial()); if (!isEzvizSuccess(result)) { result = ezvizOpenApiUtils.getDeviceStatus(vo.getDeviceSerial()); } if (!isEzvizSuccess(result)) { vo.setOnlineStatus(0); vo.setStatusMsg(ezvizErrorMessage("获取在线状态失败", result)); return; } JSONObject data = result.getJSONObject("data"); Integer status = data == null ? null : data.getInteger("status"); if (status == null && data != null) { status = data.getInteger("onlineStatus"); } vo.setOnlineStatus(Integer.valueOf(1).equals(status) ? 1 : 0); vo.setStatusMsg(Integer.valueOf(1).equals(vo.getOnlineStatus()) ? "在线" : "不在线"); } catch (Exception e) { vo.setOnlineStatus(0); vo.setStatusMsg("获取在线状态失败:" + e.getMessage()); } } private void fillLiveAddress(VideoMonitorDeviceVO vo, TDevice device) { try { JSONObject result = ezvizOpenApiUtils.getLiveAddress( device.getDeviceSerial(), device.getValidateCode(), 1 ); if (isEzvizSuccess(result)) { vo.setLiveAddress(resolveVideoUrl(result)); } else { vo.setStatusMsg(ezvizErrorMessage("获取直播地址失败", result)); } } catch (Exception e) { vo.setStatusMsg("获取直播地址失败:" + e.getMessage()); } } private AjaxResult buildEzvizResult(JSONObject result, String defaultMessage) { if (isEzvizSuccess(result)) { return AjaxResult.success(result); } return AjaxResult.error(ezvizErrorMessage(defaultMessage, result)); } private boolean isEzvizSuccess(JSONObject result) { return result != null && SUCCESS_CODE.equals(result.getString("code")); } private String ezvizErrorMessage(String defaultMessage, JSONObject result) { if (result == null) { return defaultMessage; } String message = result.getString("msg"); return StringUtils.hasText(message) ? message : defaultMessage; } private String resolveVideoUrl(JSONObject result) { JSONObject data = result.getJSONObject("data"); if (data == null) { return null; } String url = data.getString("url"); if (StringUtils.hasText(url)) { return url; } return data.getString("ezopen"); } private Integer defaultChannelNo(Integer channelNo) { return channelNo == null ? 1 : channelNo; } }