ソースを参照

优化预置位/自动扫描/巡航设置

648540858 11 ヶ月 前
コミット
efc62ed3f1

+ 289 - 42
src/main/java/com/genersoft/iot/vmp/gb28181/controller/PtzController.java

@@ -24,10 +24,10 @@ import javax.sip.SipException;
 import java.text.ParseException;
 import java.util.UUID;
 
-@Tag(name  = "云台控制")
+@Tag(name  = "前端设备控制")
 @Slf4j
 @RestController
-@RequestMapping("/api/ptz")
+@RequestMapping("/api/front-end")
 public class PtzController {
 
 	@Autowired
@@ -39,30 +39,43 @@ public class PtzController {
 	@Autowired
 	private DeferredResultHolder resultHolder;
 
-	/***
-	 * 云台控制
-	 * @param deviceId 设备id
-	 * @param channelId 通道id
-	 * @param command	控制指令
-	 * @param horizonSpeed	水平移动速度
-	 * @param verticalSpeed	垂直移动速度
-	 * @param zoomSpeed	    缩放速度
-	 */
+	@Operation(summary = "通用前端控制命令(参考国标文档A.3.1指令格式)", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "cmdCode", description = "指令码(对应国标文档指令格式中的字节4)", required = true)
+	@Parameter(name = "parameter1", description = "数据一(对应国标文档指令格式中的字节5)", required = true)
+	@Parameter(name = "parameter2", description = "数据二(对应国标文档指令格式中的字节6)", required = true)
+	@Parameter(name = "combindCode2", description = "组合码二(对应国标文档指令格式中的字节7:组合码2,高4位是数据3,低4位是地址的高4位)", required = true)
+	@PostMapping("/common/{deviceId}/{channelId}")
+	public void frontEndCommand(@PathVariable String deviceId,@PathVariable String channelId,int cmdCode, int parameter1, int parameter2, int combindCode2){
+
+		if (log.isDebugEnabled()) {
+			log.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,cmdCode:%d parameter1:%d parameter2:%d",deviceId, channelId, cmdCode, parameter1, parameter2));
+		}
+		Device device = deviceService.getDeviceByDeviceId(deviceId);
+
+		try {
+			cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2);
+		} catch (SipException | InvalidArgumentException | ParseException e) {
+			log.error("[命令发送失败] 前端控制: {}", e.getMessage());
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
+		}
+	}
 
 	@Operation(summary = "云台控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
 	@Parameter(name = "channelId", description = "通道国标编号", required = true)
 	@Parameter(name = "command", description = "控制指令,允许值: left, right, up, down, upleft, upright, downleft, downright, zoomin, zoomout, stop", required = true)
-	@Parameter(name = "horizonSpeed", description = "水平速度", required = true)
-	@Parameter(name = "verticalSpeed", description = "垂直速度", required = true)
-	@Parameter(name = "zoomSpeed", description = "缩放速度", required = true)
-	@PostMapping("/control/{deviceId}/{channelId}")
+	@Parameter(name = "horizonSpeed", description = "水平速度(0-255)", required = true)
+	@Parameter(name = "verticalSpeed", description = "垂直速度(0-255)", required = true)
+	@Parameter(name = "zoomSpeed", description = "缩放速度(0-16)", required = true)
+	@PostMapping("/ptz/{deviceId}/{channelId}")
 	public void ptz(@PathVariable String deviceId,@PathVariable String channelId, String command, int horizonSpeed, int verticalSpeed, int zoomSpeed){
 
 		if (log.isDebugEnabled()) {
 			log.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,command:%s ,horizonSpeed:%d ,verticalSpeed:%d ,zoomSpeed:%d",deviceId, channelId, command, horizonSpeed, verticalSpeed, zoomSpeed));
 		}
-		Device device = deviceService.getDeviceByDeviceId(deviceId);
+
 		int cmdCode = 0;
 		switch (command){
 			case "left":
@@ -103,38 +116,67 @@ public class PtzController {
 			default:
 				break;
 		}
-		try {
-			cmder.frontEndCmd(device, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed);
-		} catch (SipException | InvalidArgumentException | ParseException e) {
-			log.error("[命令发送失败] 云台控制: {}", e.getMessage());
-			throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
-		}
+		frontEndCommand(deviceId, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed);
 	}
 
 
-	@Operation(summary = "通用前端控制命令", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Operation(summary = "光圈控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
 	@Parameter(name = "channelId", description = "通道国标编号", required = true)
-	@Parameter(name = "cmdCode", description = "指令码", required = true)
-	@Parameter(name = "parameter1", description = "数据一", required = true)
-	@Parameter(name = "parameter2", description = "数据二", required = true)
-	@Parameter(name = "combindCode2", description = "组合码二", required = true)
-	@PostMapping("/fi/{deviceId}/{channelId}")
-	public void frontEndCommand(@PathVariable String deviceId,@PathVariable String channelId,int cmdCode, int parameter1, int parameter2, int combindCode2){
+	@Parameter(name = "command", description = "控制指令,允许值: in, out, stop", required = true)
+	@Parameter(name = "speed", description = "光圈速度(0-255)", required = true)
+	@PostMapping("/fi/iris/{deviceId}/{channelId}")
+	public void iris(@PathVariable String deviceId,@PathVariable String channelId, String command, int speed){
 
 		if (log.isDebugEnabled()) {
-			log.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,cmdCode:%d parameter1:%d parameter2:%d",deviceId, channelId, cmdCode, parameter1, parameter2));
+			log.debug("设备光圈控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,speed:{} ",deviceId, channelId, command, speed);
 		}
-		Device device = deviceService.getDeviceByDeviceId(deviceId);
 
-		try {
-			cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2);
-		} catch (SipException | InvalidArgumentException | ParseException e) {
-			log.error("[命令发送失败] 前端控制: {}", e.getMessage());
-			throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
+		int cmdCode = 0x40;
+		switch (command){
+			case "in":
+				cmdCode = 0x48;
+				break;
+			case "out":
+				cmdCode = 0x44;
+				break;
+			case "stop":
+				speed = 0;
+				break;
+			default:
+				break;
 		}
+		frontEndCommand(deviceId, channelId, cmdCode, 0, speed, 0);
 	}
 
+	@Operation(summary = "聚焦控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "command", description = "控制指令,允许值: near, far, stop", required = true)
+	@Parameter(name = "speed", description = "聚焦速度(0-255)", required = true)
+	@PostMapping("/fi/focus/{deviceId}/{channelId}")
+	public void focus(@PathVariable String deviceId,@PathVariable String channelId, String command, int speed){
+
+		if (log.isDebugEnabled()) {
+			log.debug("设备聚焦控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,speed:{} ",deviceId, channelId, command, speed);
+		}
+
+		int cmdCode = 0x40;
+		switch (command){
+			case "near":
+				cmdCode = 0x42;
+				break;
+			case "far":
+				cmdCode = 0x41;
+				break;
+			case "stop":
+				speed = 0;
+				break;
+			default:
+				break;
+		}
+		frontEndCommand(deviceId, channelId, cmdCode, speed, 0, 0);
+	}
 
 	@Operation(summary = "查询预置位", security = @SecurityRequirement(name = JwtUtils.HEADER))
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
@@ -176,10 +218,10 @@ public class PtzController {
 		return result;
 	}
 
-	@Operation(summary = "新增预置位", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Operation(summary = "预置位指令-设置预置位", security = @SecurityRequirement(name = JwtUtils.HEADER))
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
 	@Parameter(name = "channelId", description = "通道国标编号", required = true)
-	@Parameter(name = "presetId", description = "预置位编号", required = true)
+	@Parameter(name = "presetId", description = "预置位编号(0-255)", required = true)
 	@GetMapping("/preset/add/{deviceId}/{channelId}")
 	public void addPreset(@PathVariable String deviceId, @PathVariable String channelId, Integer presetId) {
 		if (presetId == null || presetId < 1 || presetId > 255) {
@@ -188,10 +230,10 @@ public class PtzController {
 		frontEndCommand(deviceId, channelId, 0x81, 1, presetId, 0);
 	}
 
-	@Operation(summary = "调用预置位", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Operation(summary = "预置位指令-调用预置位", security = @SecurityRequirement(name = JwtUtils.HEADER))
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
 	@Parameter(name = "channelId", description = "通道国标编号", required = true)
-	@Parameter(name = "presetId", description = "预置位编号", required = true)
+	@Parameter(name = "presetId", description = "预置位编号(0-255)", required = true)
 	@GetMapping("/preset/call/{deviceId}/{channelId}")
 	public void callPreset(@PathVariable String deviceId, @PathVariable String channelId, Integer presetId) {
 		if (presetId == null || presetId < 1 || presetId > 255) {
@@ -200,10 +242,10 @@ public class PtzController {
 		frontEndCommand(deviceId, channelId, 0x82, 1, presetId, 0);
 	}
 
-	@Operation(summary = "删除预置位", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Operation(summary = "预置位指令-删除预置位", security = @SecurityRequirement(name = JwtUtils.HEADER))
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
 	@Parameter(name = "channelId", description = "通道国标编号", required = true)
-	@Parameter(name = "presetId", description = "预置位编号", required = true)
+	@Parameter(name = "presetId", description = "预置位编号(0-255)", required = true)
 	@GetMapping("/preset/delete/{deviceId}/{channelId}")
 	public void deletePreset(@PathVariable String deviceId, @PathVariable String channelId, Integer presetId) {
 		if (presetId == null || presetId < 1 || presetId > 255) {
@@ -211,4 +253,209 @@ public class PtzController {
 		}
 		frontEndCommand(deviceId, channelId, 0x83, 1, presetId, 0);
 	}
+
+	@Operation(summary = "巡航指令-加入巡航点", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "cruiseId", description = "巡航组号(0-255)", required = true)
+	@Parameter(name = "presetId", description = "预置位编号(0-255)", required = true)
+	@GetMapping("/cruise/point/add/{deviceId}/{channelId}")
+	public void addCruisePoint(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId, Integer presetId) {
+		if (presetId == null || cruiseId == null || presetId < 1 || presetId > 255 || cruiseId < 1 || cruiseId > 255) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "编号必须为1-255之间的数字");
+		}
+		frontEndCommand(deviceId, channelId, 0x84, cruiseId, presetId, 0);
+	}
+
+	@Operation(summary = "巡航指令-删除一个巡航点", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "cruiseId", description = "巡航组号(1-255)", required = true)
+	@Parameter(name = "presetId", description = "预置位编号(0-255, 为0时删除整个巡航)", required = true)
+	@GetMapping("/cruise/point/delete/{deviceId}/{channelId}")
+	public void deleteCruisePoint(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId, Integer presetId) {
+		if (presetId == null || cruiseId == null || presetId < 0 || presetId > 255 || cruiseId < 1 || cruiseId > 255) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "编号必须为1-255之间的数字");
+		}
+		frontEndCommand(deviceId, channelId, 0x85, cruiseId, presetId, 0);
+	}
+
+	@Operation(summary = "巡航指令-设置巡航速度", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "cruiseId", description = "巡航组号(0-255)", required = true)
+	@Parameter(name = "speed", description = "巡航速度(1-4095)", required = true)
+	@GetMapping("/cruise/speed/{deviceId}/{channelId}")
+	public void setCruiseSpeed(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId, Integer speed) {
+		if (cruiseId == null || cruiseId < 1 || cruiseId > 255) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "编号必须为1-255之间的数字");
+		}
+		if (speed == null || speed < 1 || speed > 4095) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航速度必须为1-4095之间的数字");
+		}
+		int parameter2 = speed >> 4;
+		int combindCode2 =  speed - parameter2 << 4 ;
+		frontEndCommand(deviceId, channelId, 0x86, cruiseId, parameter2, combindCode2);
+	}
+
+	@Operation(summary = "巡航指令-设置巡航停留时间", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "cruiseId", description = "巡航组号", required = true)
+	@Parameter(name = "time", description = "巡航停留时间(1-4095)", required = true)
+	@GetMapping("/cruise/time/{deviceId}/{channelId}")
+	public void setCruiseTime(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId, Integer time) {
+		if (cruiseId == null || cruiseId < 1 || cruiseId > 255) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "编号必须为1-255之间的数字");
+		}
+		if (time == null || time < 1 || time > 4095) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航停留时间必须为1-4095之间的数字");
+		}
+		int parameter2 = time >> 4;
+		int combindCode2 =  time - parameter2 << 4 ;
+		frontEndCommand(deviceId, channelId, 0x87, cruiseId, parameter2, combindCode2);
+	}
+
+	@Operation(summary = "巡航指令-开始巡航", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "cruiseId", description = "巡航组号)", required = true)
+	@GetMapping("/cruise/start/{deviceId}/{channelId}")
+	public void startCruise(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId) {
+		if (cruiseId == null || cruiseId < 1 || cruiseId > 255) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "编号必须为1-255之间的数字");
+		}
+		frontEndCommand(deviceId, channelId, 0x88, cruiseId, 0, 0);
+	}
+
+	@Operation(summary = "巡航指令-停止巡航", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "cruiseId", description = "巡航组号", required = true)
+	@GetMapping("/cruise/stop/{deviceId}/{channelId}")
+	public void stopCruise(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId) {
+		if (cruiseId == null || cruiseId < 1 || cruiseId > 255) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "编号必须为1-255之间的数字");
+		}
+		frontEndCommand(deviceId, channelId, 0, 0, 0, 0);
+	}
+
+	@Operation(summary = "扫描指令-开始自动扫描", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "scanId", description = "扫描组号(0-255)", required = true)
+	@GetMapping("/scan/start/{deviceId}/{channelId}")
+	public void startScan(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId) {
+		if (scanId == null || scanId < 1 || scanId > 255 ) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为1-255之间的数字");
+		}
+		frontEndCommand(deviceId, channelId, 0x89, scanId, 0, 0);
+	}
+
+	@Operation(summary = "扫描指令-停止自动扫描", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "scanId", description = "扫描组号(0-255)", required = true)
+	@GetMapping("/scan/stop/{deviceId}/{channelId}")
+	public void stopScan(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId) {
+		if (scanId == null || scanId < 1 || scanId > 255 ) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为1-255之间的数字");
+		}
+		frontEndCommand(deviceId, channelId, 0, 0, 0, 0);
+	}
+
+	@Operation(summary = "扫描指令-设置自动扫描左边界", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "scanId", description = "扫描组号(0-255)", required = true)
+	@GetMapping("/scan/set/left/{deviceId}/{channelId}")
+	public void setScanLeft(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId) {
+		if (scanId == null || scanId < 1 || scanId > 255 ) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为1-255之间的数字");
+		}
+		frontEndCommand(deviceId, channelId, 0x89, scanId, 1, 0);
+	}
+
+	@Operation(summary = "扫描指令-设置自动扫描右边界", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "scanId", description = "扫描组号(0-255)", required = true)
+	@GetMapping("/scan/set/right/{deviceId}/{channelId}")
+	public void setScanRight(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId) {
+		if (scanId == null || scanId < 1 || scanId > 255 ) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为1-255之间的数字");
+		}
+		frontEndCommand(deviceId, channelId, 0x89, scanId, 2, 0);
+	}
+
+
+	@Operation(summary = "扫描指令-设置自动扫描速度", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "scanId", description = "扫描组号(0-255)", required = true)
+	@Parameter(name = "speed", description = "自动扫描速度(1-16)", required = true)
+	@GetMapping("/scan/set/speed/{deviceId}/{channelId}")
+	public void setScanSpeed(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId, Integer speed) {
+		if (scanId == null || scanId < 1 || scanId > 255 ) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为1-255之间的数字");
+		}
+		if (speed == null || speed < 1 || speed > 4095) {
+			throw new ControllerException(ErrorCode.ERROR100.getCode(), "自动扫描速度必须为1-4095之间的数字");
+		}
+		int parameter2 = speed >> 4;
+		int combindCode2 =  speed - parameter2 << 4 ;
+		frontEndCommand(deviceId, channelId, 0x8A, scanId, parameter2, combindCode2);
+	}
+
+
+	@Operation(summary = "辅助开关控制指令-雨刷控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "command", description = "控制指令,允许值: on, off", required = true)
+	@PostMapping("/wiper/{deviceId}/{channelId}")
+	public void wiper(@PathVariable String deviceId,@PathVariable String channelId, String command){
+
+		if (log.isDebugEnabled()) {
+			log.debug("辅助开关控制指令-雨刷控制 API调用,deviceId:{} ,channelId:{} ,command:{}",deviceId, channelId, command);
+		}
+
+		int cmdCode = 0;
+		switch (command){
+			case "on":
+				cmdCode = 0x8c;
+				break;
+			case "off":
+				cmdCode = 0x8d;
+				break;
+			default:
+				break;
+		}
+		frontEndCommand(deviceId, channelId, cmdCode, 1, 0, 0);
+	}
+
+	@Operation(summary = "辅助开关控制指令", security = @SecurityRequirement(name = JwtUtils.HEADER))
+	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
+	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "command", description = "控制指令,允许值: on, off", required = true)
+	@Parameter(name = "switchId", description = "开关编号", required = true)
+	@PostMapping("/auxiliary/{deviceId}/{channelId}")
+	public void auxiliarySwitch(@PathVariable String deviceId,@PathVariable String channelId, String command, Integer switchId){
+
+		if (log.isDebugEnabled()) {
+			log.debug("辅助开关控制指令-雨刷控制 API调用,deviceId:{} ,channelId:{} ,command:{}, switchId: {}",deviceId, channelId, command, switchId);
+		}
+
+		int cmdCode = 0;
+		switch (command){
+			case "on":
+				cmdCode = 0x8c;
+				break;
+			case "off":
+				cmdCode = 0x8d;
+				break;
+			default:
+				break;
+		}
+		frontEndCommand(deviceId, channelId, cmdCode, switchId, 0, 0);
+	}
 }

+ 1 - 1
src/main/resources/application.yml

@@ -2,4 +2,4 @@ spring:
   application:
     name: wvp
   profiles:
-    active: dev
+    active: 273

+ 302 - 82
web_src/src/components/common/ptzCruising.vue

@@ -1,38 +1,99 @@
 <template>
-  <div id="ptzPreset" style="width: 100%">
-    <el-tag v-for="item in presetList"
-            key="item.presetId"
-            closable
-            @close="delPreset(item)"
-            @click="gotoPreset(item)"
-            style="margin-right: 1rem; cursor: pointer"
-    >
-      {{item.presetName?item.presetName:item.presetId}}
-    </el-tag>
-    <el-input
-      min="1"
-      max="255"
-      placeholder="预置位编号"
-      addonBefore="预置位编号"
-      addonAfter="(1-255)"
-      style="width: 120px; vertical-align: bottom;"
-      v-if="inputVisible"
-      v-model="ptzPresetId"
-      ref="saveTagInput"
-      size="small"
-    >
-      <template v-slot:append>
-        <el-button  @click="addPreset()">保存</el-button>
-      </template>
-    </el-input>
-    <el-button v-else size="small" @click="showInput">+ 添加</el-button>
+  <div id="ptzCruising">
+    <div style="display: grid; grid-template-columns: 80px auto; line-height: 28px">
+      <span>巡航组号: </span>
+      <el-input
+        min="1"
+        max="255"
+        placeholder="巡航组号"
+        addonBefore="巡航组号"
+        addonAfter="(1-255)"
+        v-model="cruiseId"
+        size="mini"
+      >
+      </el-input>
+    </div>
+    <p>
+      <el-tag v-for="(item, index) in presetList"
+              key="item.presetId"
+              closable
+              @close="delPreset(item, index)"
+              style="margin-right: 1rem; cursor: pointer"
+      >
+        {{item.presetName?item.presetName:item.presetId}}
+      </el-tag>
+    </p>
+
+    <el-form size="mini" :inline="true" v-if="selectPresetVisible">
+      <el-form-item >
+        <el-select v-model="selectPreset" placeholder="请选择预置点">
+          <el-option
+            v-for="item in allPresetList"
+            :key="item.presetId"
+            :label="item.presetName"
+            :value="item">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="addCruisePoint">保存</el-button>
+        <el-button type="primary" @click="cancelAddCruisePoint">取消</el-button>
+      </el-form-item>
+    </el-form>
+    <el-button size="mini" v-else @click="selectPresetVisible=true">添加巡航点</el-button>
+
+    <el-form size="mini" :inline="true" v-if="setSpeedVisible">
+      <el-form-item >
+        <el-input
+          min="1"
+          max="4095"
+          placeholder="巡航速度"
+          addonBefore="巡航速度"
+          addonAfter="(1-4095)"
+          v-if="setSpeedVisible"
+          v-model="cruiseSpeed"
+          size="mini"
+        >
+        </el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="setCruiseSpeed">保存</el-button>
+        <el-button @click="cancelSetCruiseSpeed">取消</el-button>
+      </el-form-item>
+    </el-form>
+    <el-button v-else size="mini" @click="setSpeedVisible = true">设置巡航速度</el-button>
+
+
+
+    <el-form size="mini" :inline="true" v-if="setTimeVisible">
+      <el-form-item >
+        <el-input
+          min="1"
+          max="4095"
+          placeholder="巡航停留时间(秒)"
+          addonBefore="巡航停留时间(秒)"
+          addonAfter="(1-4095)"
+          style="width: 100%;"
+          v-model="cruiseTime"
+        >
+        </el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="setCruiseTime">保存</el-button>
+        <el-button @click="cancelSetCruiseTime">取消</el-button>
+      </el-form-item>
+    </el-form>
+    <el-button v-else size="mini" @click="setTimeVisible = true">设置巡航时间</el-button>
+    <el-button size="mini" @click="startCruise">开始巡航</el-button>
+    <el-button size="mini" @click="stopCruise">停止巡航</el-button>
+    <el-button size="mini" type="danger" @click="deleteCruise">删除巡航</el-button>
   </div>
 </template>
 
 <script>
 
 export default {
-  name: "ptzPreset",
+  name: "ptzCruising",
   props: [ 'channelDeviceId', 'deviceId'],
   components: {},
   created() {
@@ -40,23 +101,26 @@ export default {
   },
   data() {
     return {
+      cruiseId: 1,
       presetList: [],
+      allPresetList: [],
+      selectPreset: "",
       inputVisible: false,
-      ptzPresetId: '',
+      selectPresetVisible: false,
+      setSpeedVisible: false,
+      setTimeVisible: false,
+      cruiseSpeed: '',
+      cruiseTime: '',
     };
   },
   methods: {
     getPresetList: function () {
       this.$axios({
         method: 'get',
-        url: `/api/ptz/preset/query/${this.deviceId}/${this.channelDeviceId}`,
+        url: `/api/front-end/preset/query/${this.deviceId}/${this.channelDeviceId}`,
       }).then((res)=> {
         if (res.data.code === 0) {
-          this.presetList = res.data.data;
-          // 防止出现表格错位
-          this.$nextTick(() => {
-            this.$refs.channelListTable.doLayout();
-          })
+          this.allPresetList = res.data.data;
         }
 
       }).catch((error)=> {
@@ -64,13 +128,7 @@ export default {
         console.log(error);
       });
     },
-    showInput() {
-      this.inputVisible = true;
-      this.$nextTick(_ => {
-        this.$refs.saveTagInput.$refs.input.focus();
-      });
-    },
-    addPreset: function (){
+    addCruisePoint: function (){
       const loading = this.$loading({
         lock: true,
         fullscreen: true,
@@ -80,22 +138,15 @@ export default {
       })
       this.$axios({
         method: 'get',
-        url: `/api/ptz/preset/add/${this.deviceId}/${this.channelDeviceId}`,
+        url: `/api/front-end/cruise/point/add/${this.deviceId}/${this.channelDeviceId}`,
         params: {
-          presetId: this.ptzPresetId
+          cruiseId: this.cruiseId,
+          presetId: this.selectPreset.presetId
         }
       }).then((res)=> {
         if (res.data.code === 0) {
-          setTimeout(()=>{
-            loading.close()
-            this.inputVisible = false;
-            this.ptzPresetId = ""
-            this.getPresetList()
-          }, 1000)
+          this.presetList.push(this.selectPreset)
         }else {
-          loading.close()
-          this.inputVisible = false;
-          this.ptzPresetId = ""
           this.$message({
             showClose: true,
             message: res.data.msg,
@@ -103,31 +154,39 @@ export default {
           });
         }
       }).catch((error)=> {
-        loading.close()
-        this.inputVisible = false;
-        this.ptzPresetId = ""
         this.$message({
           showClose: true,
           message: error,
           type: 'error'
         });
-      });
+      }).finally(()=>{
+        this.selectPreset = ""
+        this.selectPresetVisible = false;
+        loading.close()
+      })
+    },
+    cancelAddCruisePoint: function () {
+      this.selectPreset = ""
+      this.selectPresetVisible = false;
     },
-    gotoPreset: function (preset){
-      console.log(preset)
+    delPreset: function (preset, index){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
       this.$axios({
         method: 'get',
-        url: `/api/ptz/preset/call/${this.deviceId}/${this.channelDeviceId}`,
+        url: `/api/front-end/cruise/point/delete/${this.deviceId}/${this.channelDeviceId}`,
         params: {
+          cruiseId: this.cruiseId,
           presetId: preset.presetId
         }
       }).then((res)=> {
         if (res.data.code === 0) {
-          this.$message({
-            showClose: true,
-            message: '调用成功',
-            type: 'success'
-          });
+          this.presetList.splice(index, 1)
         }else {
           this.$message({
             showClose: true,
@@ -141,10 +200,12 @@ export default {
           message: error,
           type: 'error'
         });
-      });
+      }).finally(()=>{
+        loading.close()
+      })
     },
-    delPreset: function (preset){
-      this.$confirm("确定删除此预置位", '提示', {
+    deleteCruise: function (preset, index){
+      this.$confirm("确定删除此巡航组", '提示', {
         dangerouslyUseHTMLString: true,
         confirmButtonText: '确定',
         cancelButtonText: '取消',
@@ -159,39 +220,198 @@ export default {
         })
         this.$axios({
           method: 'get',
-          url: `/api/ptz/preset/delete/${this.deviceId}/${this.channelDeviceId}`,
+          url: `/api/front-end/cruise/point/delete/${this.deviceId}/${this.channelDeviceId}`,
           params: {
-            presetId: preset.presetId
+            cruiseId: this.cruiseId,
+            presetId: 0
           }
         }).then((res)=> {
           if (res.data.code === 0) {
-            setTimeout(()=>{
-              loading.close()
-              this.getPresetList()
-            }, 1000)
+            this.presetList.splice(index, 1)
           }else {
-            loading.close()
             this.$message({
               showClose: true,
               message: res.data.msg,
               type: 'error'
             });
           }
-
         }).catch((error)=> {
-          loading.close()
           this.$message({
             showClose: true,
             message: error,
             type: 'error'
           });
+        }).finally(()=>{
+          loading.close()
+        })
+      })
+    },
+    setCruiseSpeed: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/cruise/speed/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          cruiseId: this.cruiseId,
+          speed: this.cruiseSpeed
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "保存成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
         });
-      }).catch(() => {
-
-      });
-
+      }).finally(()=>{
+        this.cruiseSpeed = ""
+        this.setSpeedVisible = false
+        loading.close()
+      })
+    },
+    cancelSetCruiseSpeed: function (){
+      this.cruiseSpeed = ""
+      this.setSpeedVisible = false
+    },
+    setCruiseTime: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/cruise/time/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          cruiseId: this.cruiseId,
+          time: this.cruiseTime
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "保存成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      }).finally(()=>{
+        this.setTimeVisible = false;
+        this.cruiseTime = "";
+        loading.close()
+      })
+    },
+    cancelSetCruiseTime: function (){
+      this.setTimeVisible = false;
+      this.cruiseTime = "";
+    },
+    startCruise: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/cruise/start/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          cruiseId: this.cruiseId
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "发送成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      }).finally(()=>{
+        loading.close()
+      })
+    },
+    stopCruise: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/cruise/stop/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          cruiseId: this.cruiseId
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "发送成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      }).finally(()=>{
+        loading.close()
+      })
     },
-
   },
 };
 </script>

+ 212 - 0
web_src/src/components/common/ptzPreset.vue

@@ -0,0 +1,212 @@
+<template>
+  <div id="ptzPreset" style="width: 100%">
+    <el-tag v-for="item in presetList"
+            key="item.presetId"
+            closable
+            @close="delPreset(item)"
+            @click="gotoPreset(item)"
+            size="mini"
+            style="margin-right: 1rem; cursor: pointer; margin-bottom: 0.6rem"
+    >
+      {{item.presetName?item.presetName:item.presetId}}
+    </el-tag>
+    <el-input
+      min="1"
+      max="255"
+      placeholder="预置位编号"
+      addonBefore="预置位编号"
+      addonAfter="(1-255)"
+      style="width: 300px; vertical-align: bottom;"
+      v-if="inputVisible"
+      v-model="ptzPresetId"
+      ref="saveTagInput"
+      size="small"
+    >
+      <template v-slot:append>
+        <el-button  @click="addPreset()">保存</el-button>
+        <el-button  @click="cancel()">取消</el-button>
+      </template>
+    </el-input>
+    <el-button v-else size="small" @click="showInput">+ 添加</el-button>
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: "ptzPreset",
+  props: [ 'channelDeviceId', 'deviceId'],
+  components: {},
+  created() {
+    this.getPresetList()
+  },
+  data() {
+    return {
+      presetList: [],
+      inputVisible: false,
+      ptzPresetId: '',
+    };
+  },
+  methods: {
+    getPresetList: function () {
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/preset/query/${this.deviceId}/${this.channelDeviceId}`,
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.presetList = res.data.data;
+          // 防止出现表格错位
+          this.$nextTick(() => {
+            this.$refs.channelListTable.doLayout();
+          })
+        }
+
+      }).catch((error)=> {
+
+        console.log(error);
+      });
+    },
+    showInput() {
+      this.inputVisible = true;
+      this.$nextTick(_ => {
+        this.$refs.saveTagInput.$refs.input.focus();
+      });
+    },
+    addPreset: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/preset/add/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          presetId: this.ptzPresetId
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          setTimeout(()=>{
+            loading.close()
+            this.inputVisible = false;
+            this.ptzPresetId = ""
+            this.getPresetList()
+          }, 1000)
+        }else {
+          loading.close()
+          this.inputVisible = false;
+          this.ptzPresetId = ""
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        loading.close()
+        this.inputVisible = false;
+        this.ptzPresetId = ""
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      });
+    },
+    cancel: function () {
+      this.inputVisible = false;
+      this.ptzPresetId = ""
+    },
+    gotoPreset: function (preset){
+      console.log(preset)
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/preset/call/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          presetId: preset.presetId
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: '调用成功',
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      });
+    },
+    delPreset: function (preset){
+      this.$confirm("确定删除此预置位", '提示', {
+        dangerouslyUseHTMLString: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        const loading = this.$loading({
+          lock: true,
+          fullscreen: true,
+          text: '正在发送指令',
+          spinner: 'el-icon-loading',
+          background: 'rgba(0, 0, 0, 0.7)'
+        })
+        this.$axios({
+          method: 'get',
+          url: `/api/front-end/preset/delete/${this.deviceId}/${this.channelDeviceId}`,
+          params: {
+            presetId: preset.presetId
+          }
+        }).then((res)=> {
+          if (res.data.code === 0) {
+            setTimeout(()=>{
+              loading.close()
+              this.getPresetList()
+            }, 1000)
+          }else {
+            loading.close()
+            this.$message({
+              showClose: true,
+              message: res.data.msg,
+              type: 'error'
+            });
+          }
+
+        }).catch((error)=> {
+          loading.close()
+          this.$message({
+            showClose: true,
+            message: error,
+            type: 'error'
+          });
+        });
+      }).catch(() => {
+
+      });
+
+    },
+
+  },
+};
+</script>
+<style>
+.channel-form {
+  display: grid;
+  background-color: #FFFFFF;
+  padding: 1rem 2rem 0 2rem;
+  grid-template-columns: 1fr 1fr 1fr;
+  gap: 1rem;
+}
+</style>

+ 273 - 0
web_src/src/components/common/ptzScan.vue

@@ -0,0 +1,273 @@
+<template>
+  <div id="ptzScan">
+    <div style="display: grid; grid-template-columns: 80px auto; line-height: 28px">
+      <span>扫描组号: </span>
+      <el-input
+        min="1"
+        max="255"
+        placeholder="扫描组号"
+        addonBefore="扫描组号"
+        addonAfter="(1-255)"
+        v-model="scanId"
+        size="mini"
+      >
+      </el-input>
+    </div>
+
+    <el-button size="mini" @click="setScanLeft">设置左边界</el-button>
+    <el-button size="mini" @click="setScanRight">设置右边界</el-button>
+
+    <el-form size="mini" :inline="true" v-if="setSpeedVisible">
+      <el-form-item >
+        <el-input
+          min="1"
+          max="4095"
+          placeholder="巡航速度"
+          addonBefore="巡航速度"
+          addonAfter="(1-4095)"
+          v-if="setSpeedVisible"
+          v-model="speed"
+          size="mini"
+        >
+        </el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="setSpeed">保存</el-button>
+        <el-button @click="cancelSetSpeed">取消</el-button>
+      </el-form-item>
+    </el-form>
+    <el-button v-else size="mini" @click="setSpeedVisible = true">设置扫描速度</el-button>
+
+    <el-button size="mini" @click="startScan">开始自动扫描</el-button>
+    <el-button size="mini" @click="stopScan">停止自动扫描</el-button>
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: "ptzScan",
+  props: [ 'channelDeviceId', 'deviceId'],
+  components: {},
+  created() {
+  },
+  data() {
+    return {
+      scanId: 1,
+      setSpeedVisible: false,
+      speed: '',
+    };
+  },
+  methods: {
+    setSpeed: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/scan/set/speed/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          scanId: this.scanId,
+          speed: this.speed
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "保存成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      }).finally(()=>{
+        this.speed = ""
+        this.setSpeedVisible = false
+        loading.close()
+      })
+    },
+    cancelSetSpeed: function (){
+      this.speed = ""
+      this.setSpeedVisible = false
+    },
+    setScanLeft: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/scan/set/left/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          scanId: this.scanId,
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "保存成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      }).finally(()=>{
+        loading.close()
+      })
+    },
+    setScanRight: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/scan/set/right/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          scanId: this.scanId,
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "保存成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      }).finally(()=>{
+        this.setSpeedVisible = false;
+        this.speed = "";
+        loading.close()
+      })
+    },
+    startScan: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/scan/start/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          scanId: this.scanId
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "发送成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      }).finally(()=>{
+        loading.close()
+      })
+    },
+    stopScan: function (){
+      const loading = this.$loading({
+        lock: true,
+        fullscreen: true,
+        text: '正在发送指令',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      this.$axios({
+        method: 'get',
+        url: `/api/front-end/scan/stop/${this.deviceId}/${this.channelDeviceId}`,
+        params: {
+          scanId: this.scanId
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message({
+            showClose: true,
+            message: "发送成功",
+            type: 'success'
+          });
+        }else {
+          this.$message({
+            showClose: true,
+            message: res.data.msg,
+            type: 'error'
+          });
+        }
+      }).catch((error)=> {
+        this.$message({
+          showClose: true,
+          message: error,
+          type: 'error'
+        });
+      }).finally(()=>{
+        loading.close()
+      })
+    },
+  },
+};
+</script>
+<style>
+.channel-form {
+  display: grid;
+  background-color: #FFFFFF;
+  padding: 1rem 2rem 0 2rem;
+  grid-template-columns: 1fr 1fr 1fr;
+  gap: 1rem;
+}
+
+</style>

+ 12 - 99
web_src/src/components/dialog/devicePlayer.vue

@@ -190,110 +190,19 @@
                 <el-select
                   v-model="ptzMethod"
                   style="width: 100%"
+                  size="mini"
                   placeholder="请选择云台功能"
                 >
                   <el-option label="预置点" value="preset"></el-option>
                   <el-option label="巡航组" value="cruising"></el-option>
-                  <el-option label="线性扫描" value="scan"></el-option>
-                  <el-option label="巡迹" value="cruise"></el-option>
+                  <el-option label="自动扫描" value="scan"></el-option>
+                  <el-option label="雨刷" value="wiper"></el-option>
                 </el-select>
 
                 <ptzPreset :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'preset'" style="margin-top: 1rem"></ptzPreset>
-                <ptzCruising :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'cruising'" style="margin-top: 1rem"></ptzCruising>
-                <div v-if="ptzMethod === 'scan'">
-                  111
-                </div>
-                <div v-if="ptzMethod === 'cruise'">
-                  111
-                </div>
-              </div>
-            </div>
-
-
-            <div style="display: flex; justify-content: left;">
-
-
-              <div class="control-panel">
-                <el-button-group>
-                  <el-tag style="position :absolute; left: 0rem; top: 0rem; width: 5rem; text-align: center"
-                          size="medium">预置位编号
-                  </el-tag>
-                  <el-input-number style="position: absolute; left: 5rem; top: 0rem; width: 6rem" size="mini"
-                                   v-model="presetPos" controls-position="right" :precision="0" :step="1" :min="1"
-                                   :max="255"></el-input-number>
-                  <el-button style="position: absolute; left: 11rem; top: 0rem; width: 5rem" size="mini"
-                             icon="el-icon-add-location" @click="presetPosition(129, presetPos)">设置
-                  </el-button>
-                  <el-button style="position: absolute; left: 27rem; top: 0rem; width: 5rem" size="mini" type="primary"
-                             icon="el-icon-place" @click="presetPosition(130, presetPos)">调用
-                  </el-button>
-                  <el-button style="position: absolute; left: 16rem; top: 0rem; width: 5rem" size="mini"
-                             icon="el-icon-delete-location" @click="presetPosition(131, presetPos)">删除
-                  </el-button>
-                  <el-tag style="position :absolute; left: 0rem; top: 2.5rem; width: 5rem; text-align: center"
-                          size="medium">巡航速度
-                  </el-tag>
-                  <el-input-number style="position: absolute; left: 5rem; top: 2.5rem; width: 6rem" size="mini"
-                                   v-model="cruisingSpeed" controls-position="right" :precision="0" :min="1"
-                                   :max="4095"></el-input-number>
-                  <el-button style="position: absolute; left: 11rem; top: 2.5rem; width: 5rem" size="mini"
-                             icon="el-icon-loading" @click="setSpeedOrTime(134, cruisingGroup, cruisingSpeed)">设置
-                  </el-button>
-                  <el-tag style="position :absolute; left: 16rem; top: 2.5rem; width: 5rem; text-align: center"
-                          size="medium">停留时间
-                  </el-tag>
-                  <el-input-number style="position: absolute; left: 21rem; top: 2.5rem; width: 6rem" size="mini"
-                                   v-model="cruisingTime" controls-position="right" :precision="0" :min="1"
-                                   :max="4095"></el-input-number>
-                  <el-button style="position: absolute; left: 27rem; top: 2.5rem; width: 5rem" size="mini"
-                             icon="el-icon-timer" @click="setSpeedOrTime(135, cruisingGroup, cruisingTime)">设置
-                  </el-button>
-                  <el-tag style="position :absolute; left: 0rem; top: 4.5rem; width: 5rem; text-align: center"
-                          size="medium">巡航组编号
-                  </el-tag>
-                  <el-input-number style="position: absolute; left: 5rem; top: 4.5rem; width: 6rem" size="mini"
-                                   v-model="cruisingGroup" controls-position="right" :precision="0" :min="0"
-                                   :max="255"></el-input-number>
-                  <el-button style="position: absolute; left: 11rem; top: 4.5rem; width: 5rem" size="mini"
-                             icon="el-icon-add-location" @click="setCommand(132, cruisingGroup, presetPos)">添加点
-                  </el-button>
-                  <el-button style="position: absolute; left: 16rem; top: 4.5rem; width: 5rem" size="mini"
-                             icon="el-icon-delete-location" @click="setCommand(133, cruisingGroup, presetPos)">删除点
-                  </el-button>
-                  <el-button style="position: absolute; left: 21rem; top: 4.5rem; width: 5rem" size="mini"
-                             icon="el-icon-delete" @click="setCommand(133, cruisingGroup, 0)">删除组
-                  </el-button>
-                  <el-button style="position: absolute; left: 27rem; top: 5rem; width: 5rem" size="mini" type="primary"
-                             icon="el-icon-video-camera-solid" @click="setCommand(136, cruisingGroup, 0)">巡航
-                  </el-button>
-                  <el-tag style="position :absolute; left: 0rem; top: 7rem; width: 5rem; text-align: center"
-                          size="medium">扫描速度
-                  </el-tag>
-                  <el-input-number style="position: absolute; left: 5rem; top: 7rem; width: 6rem" size="mini"
-                                   v-model="scanSpeed" controls-position="right" :precision="0" :min="1"
-                                   :max="4095"></el-input-number>
-                  <el-button style="position: absolute; left: 11rem; top: 7rem; width: 5rem" size="mini"
-                             icon="el-icon-loading" @click="setSpeedOrTime(138, scanGroup, scanSpeed)">设置
-                  </el-button>
-                  <el-tag style="position :absolute; left: 0rem; top: 9rem; width: 5rem; text-align: center"
-                          size="medium">扫描组编号
-                  </el-tag>
-                  <el-input-number style="position: absolute; left: 5rem; top: 9rem; width: 6rem" size="mini"
-                                   v-model="scanGroup" controls-position="right" :precision="0" :step="1" :min="0"
-                                   :max="255"></el-input-number>
-                  <el-button style="position: absolute; left: 11rem; top: 9rem; width: 5rem" size="mini"
-                             icon="el-icon-d-arrow-left" @click="setCommand(137, scanGroup, 1)">左边界
-                  </el-button>
-                  <el-button style="position: absolute; left: 16rem; top: 9rem; width: 5rem" size="mini"
-                             icon="el-icon-d-arrow-right" @click="setCommand(137, scanGroup, 2)">右边界
-                  </el-button>
-                  <el-button style="position: absolute; left: 27rem; top: 7rem; width: 5rem" size="mini" type="primary"
-                             icon="el-icon-video-camera-solid" @click="setCommand(137, scanGroup, 0)">扫描
-                  </el-button>
-                  <el-button style="position: absolute; left: 27rem; top: 9rem; width: 5rem" size="mini" type="danger"
-                             icon="el-icon-switch-button" @click="ptzCamera('stop')">停止
-                  </el-button>
-                </el-button-group>
+                <ptzCruising :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'cruise'" style="margin-top: 1rem"></ptzCruising>
+                <ptzScan :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'scan'" style="margin-top: 1rem"></ptzScan>
+<!--                <ptzWiper :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'wiper'" style="margin-top: 1rem"></ptzWiper>-->
               </div>
             </div>
           </el-tab-pane>
@@ -356,12 +265,13 @@ import crypto from 'crypto'
 import jessibucaPlayer from '../common/jessibuca.vue'
 import PtzPreset from "../common/ptzPreset.vue";
 import PtzCruising from "../common/ptzCruising.vue";
+import ptzScan from "../common/ptzScan.vue";
 
 export default {
   name: 'devicePlayer',
   props: {},
   components: {
-    PtzPreset,PtzCruising,
+    PtzPreset,PtzCruising,ptzScan,
     LivePlayer, jessibucaPlayer, rtcPlayer,
   },
   computed: {
@@ -628,7 +538,7 @@ export default {
       let that = this;
       this.$axios({
         method: 'post',
-        url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed
+        url: '/api/front-end/ptz/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed
       }).then(function (res) {
       });
     },
@@ -1033,4 +943,7 @@ export default {
   width: 80%;
   padding: 0 10%;
 }
+.el-dialog__body{
+  padding: 10px 20px;
+}
 </style>