2025-08-07 16:49:13 +08:00
|
|
|
|
package com.klp.controller;
|
|
|
|
|
|
|
2025-08-08 14:35:11 +08:00
|
|
|
|
import java.net.URLEncoder;
|
2025-08-07 16:49:13 +08:00
|
|
|
|
import java.util.List;
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
|
|
2025-08-08 14:35:11 +08:00
|
|
|
|
import com.alibaba.fastjson.JSON;
|
2025-08-08 16:04:55 +08:00
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
2025-08-08 14:35:11 +08:00
|
|
|
|
import com.klp.common.utils.StringUtils;
|
2025-08-07 16:49:13 +08:00
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import javax.validation.constraints.*;
|
2025-08-08 14:35:11 +08:00
|
|
|
|
|
2025-08-07 16:49:13 +08:00
|
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
import com.klp.common.annotation.RepeatSubmit;
|
|
|
|
|
|
import com.klp.common.annotation.Log;
|
|
|
|
|
|
import com.klp.common.core.controller.BaseController;
|
|
|
|
|
|
import com.klp.common.core.domain.PageQuery;
|
|
|
|
|
|
import com.klp.common.core.domain.R;
|
|
|
|
|
|
import com.klp.common.core.validate.AddGroup;
|
|
|
|
|
|
import com.klp.common.core.validate.EditGroup;
|
|
|
|
|
|
import com.klp.common.enums.BusinessType;
|
|
|
|
|
|
import com.klp.common.utils.poi.ExcelUtil;
|
|
|
|
|
|
import com.klp.domain.vo.WmsCameraManagementVo;
|
|
|
|
|
|
import com.klp.domain.bo.WmsCameraManagementBo;
|
|
|
|
|
|
import com.klp.service.IWmsCameraManagementService;
|
|
|
|
|
|
import com.klp.common.core.page.TableDataInfo;
|
2025-08-07 17:49:28 +08:00
|
|
|
|
import com.klp.common.config.CameraConfig;
|
2025-08-08 14:35:11 +08:00
|
|
|
|
import org.springframework.web.client.RestTemplate;
|
2025-08-07 16:49:13 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 摄像头管理
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author Joshi
|
|
|
|
|
|
* @date 2025-08-07
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Validated
|
|
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
|
|
@RestController
|
|
|
|
|
|
@RequestMapping("/wms/cameraManagement")
|
|
|
|
|
|
public class WmsCameraManagementController extends BaseController {
|
|
|
|
|
|
|
|
|
|
|
|
private final IWmsCameraManagementService iWmsCameraManagementService;
|
2025-08-07 17:49:28 +08:00
|
|
|
|
private final CameraConfig cameraConfig;
|
2025-08-07 16:49:13 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询摄像头管理列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
@GetMapping("/list")
|
|
|
|
|
|
public TableDataInfo<WmsCameraManagementVo> list(WmsCameraManagementBo bo, PageQuery pageQuery) {
|
|
|
|
|
|
return iWmsCameraManagementService.queryPageList(bo, pageQuery);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 导出摄像头管理列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Log(title = "摄像头管理", businessType = BusinessType.EXPORT)
|
|
|
|
|
|
@PostMapping("/export")
|
|
|
|
|
|
public void export(WmsCameraManagementBo bo, HttpServletResponse response) {
|
|
|
|
|
|
List<WmsCameraManagementVo> list = iWmsCameraManagementService.queryList(bo);
|
|
|
|
|
|
ExcelUtil.exportExcel(list, "摄像头管理", WmsCameraManagementVo.class, response);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取摄像头管理详细信息
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param cameraId 主键
|
|
|
|
|
|
*/
|
|
|
|
|
|
@GetMapping("/{cameraId}")
|
|
|
|
|
|
public R<WmsCameraManagementVo> getInfo(@NotNull(message = "主键不能为空")
|
|
|
|
|
|
@PathVariable Long cameraId) {
|
|
|
|
|
|
return R.ok(iWmsCameraManagementService.queryById(cameraId));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-07 17:49:28 +08:00
|
|
|
|
/**
|
2025-08-08 14:35:11 +08:00
|
|
|
|
* 获取 FLV地址并自动拉流
|
2025-08-07 17:49:28 +08:00
|
|
|
|
*/
|
|
|
|
|
|
@GetMapping("/stream/{cameraId}")
|
|
|
|
|
|
public R<WmsCameraManagementVo> getCameraStream(@PathVariable Long cameraId) {
|
2025-08-08 14:35:11 +08:00
|
|
|
|
// 1. 查询摄像头RTSP地址
|
2025-08-07 17:49:28 +08:00
|
|
|
|
WmsCameraManagementVo camera = iWmsCameraManagementService.queryById(cameraId);
|
2025-08-08 14:35:11 +08:00
|
|
|
|
if (camera == null || StringUtils.isBlank(camera.getRtspUrl())) {
|
|
|
|
|
|
return R.fail("摄像头配置错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 生成FLV播放地址
|
2025-08-08 16:04:55 +08:00
|
|
|
|
String flvUrl = String.format("%s/live/%s.live.flv",
|
2025-08-08 14:35:11 +08:00
|
|
|
|
cameraConfig.getMediaServerHost(),
|
|
|
|
|
|
camera.getCameraCode());
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 调用ZLMediaKit拉流
|
|
|
|
|
|
String apiUrl = String.format("%s/index/api/addStreamProxy?&vhost=__defaultVhost__&app=live&stream=%s&url=%s&secret=%s",
|
|
|
|
|
|
cameraConfig.getMediaServerHost(),
|
|
|
|
|
|
camera.getCameraCode(),
|
|
|
|
|
|
camera.getRtspUrl(),
|
|
|
|
|
|
cameraConfig.getApiSecret());
|
|
|
|
|
|
System.out.println("拉流API地址: " + apiUrl);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
String result = new RestTemplate().getForObject(apiUrl, String.class);
|
|
|
|
|
|
if (!JSON.parseObject(result).getInteger("code").equals(0)) {
|
|
|
|
|
|
return R.fail("拉流失败: " + JSON.parseObject(result).getString("msg"));
|
|
|
|
|
|
}
|
|
|
|
|
|
camera.setHttpFmp4(flvUrl);
|
|
|
|
|
|
return R.ok(camera);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
return R.fail("API调用失败: " + e.getMessage());
|
2025-08-07 17:49:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-08 16:04:55 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 手动关闭拉流代理
|
|
|
|
|
|
*/
|
2025-08-08 16:10:03 +08:00
|
|
|
|
@GetMapping("/streamClose/{cameraId}")
|
2025-08-08 16:04:55 +08:00
|
|
|
|
public R<String> closeCameraStream(@PathVariable Long cameraId) {
|
|
|
|
|
|
// 1. 查询摄像头信息,拿流名(cameraCode)
|
|
|
|
|
|
WmsCameraManagementVo camera = iWmsCameraManagementService.queryById(cameraId);
|
|
|
|
|
|
if (camera == null || StringUtils.isBlank(camera.getCameraCode())) {
|
|
|
|
|
|
return R.fail("摄像头配置错误或不存在");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 构造关闭拉流API地址
|
2025-08-08 16:18:17 +08:00
|
|
|
|
String apiUrl = String.format("%s/index/api/delStreamProxy?key=__defaultVhost__/live/%s&secret=%s",
|
2025-08-08 16:04:55 +08:00
|
|
|
|
cameraConfig.getMediaServerHost(),
|
|
|
|
|
|
camera.getCameraCode(),
|
|
|
|
|
|
cameraConfig.getApiSecret());
|
|
|
|
|
|
System.out.println("关闭拉流API地址: " + apiUrl);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 调用ZLMediaKit关闭拉流
|
|
|
|
|
|
try {
|
|
|
|
|
|
String result = new RestTemplate().getForObject(apiUrl, String.class);
|
|
|
|
|
|
JSONObject json = JSON.parseObject(result);
|
|
|
|
|
|
if (json.getInteger("code").equals(0)) {
|
|
|
|
|
|
return R.ok("关闭成功");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return R.fail("关闭失败: " + json.getString("msg"));
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
return R.fail("API调用异常: " + e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-07 16:49:13 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 新增摄像头管理
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Log(title = "摄像头管理", businessType = BusinessType.INSERT)
|
|
|
|
|
|
@RepeatSubmit()
|
|
|
|
|
|
@PostMapping()
|
|
|
|
|
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody WmsCameraManagementBo bo) {
|
|
|
|
|
|
return toAjax(iWmsCameraManagementService.insertByBo(bo));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 修改摄像头管理
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Log(title = "摄像头管理", businessType = BusinessType.UPDATE)
|
|
|
|
|
|
@RepeatSubmit()
|
|
|
|
|
|
@PutMapping()
|
|
|
|
|
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WmsCameraManagementBo bo) {
|
|
|
|
|
|
return toAjax(iWmsCameraManagementService.updateByBo(bo));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 删除摄像头管理
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param cameraIds 主键串
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Log(title = "摄像头管理", businessType = BusinessType.DELETE)
|
|
|
|
|
|
@DeleteMapping("/{cameraIds}")
|
|
|
|
|
|
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
|
|
|
|
|
@PathVariable Long[] cameraIds) {
|
|
|
|
|
|
return toAjax(iWmsCameraManagementService.deleteWithValidByIds(Arrays.asList(cameraIds), true));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|