feat(device): 集成 zt-device 服务

- 移除 DeviceController、DeviceService 相关代码
- 更新 ViidController、WvpController 使用 DeviceIntegrationService
- 修改 DeviceFactory 创建 DeviceEntity 的方式
- 更新 DeviceRepository 使用 DeviceV2DTO
-调整 CustomUploadTaskService、AppScenicServiceImpl 中的设备相关逻辑
- 移除 DeviceServiceImpl 类
- 更新 VideoPieceCleaner、VideoPieceGetter 任务类,使用 DeviceIntegrationService 获取设备信息
This commit is contained in:
2025-09-04 10:03:00 +08:00
parent 9a086fc86d
commit 7779b84c81
11 changed files with 159 additions and 390 deletions

View File

@@ -1,79 +0,0 @@
package com.ycwl.basic.controller.pc;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.model.pc.device.req.DeviceAddOrUpdateReq;
import com.ycwl.basic.model.pc.device.req.DeviceBatchSortRequest;
import com.ycwl.basic.model.pc.device.req.DeviceReqQuery;
import com.ycwl.basic.model.pc.device.req.DeviceSortRequest;
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
import com.ycwl.basic.model.pc.template.req.TemplateSortRequest;
import com.ycwl.basic.service.pc.DeviceService;
import com.ycwl.basic.utils.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @Author:longbinbin
* @Date:2024/12/2 16:13
*/
@RestController
@RequestMapping("/api/device/v1")
// 设备管理
public class DeviceController {
@Autowired
private DeviceService deviceService;
// 设备分页查询
@PostMapping("/page")
public ApiResponse<PageInfo<DeviceRespVO>> pageQuery(@RequestBody DeviceReqQuery deviceReqQuery) {
return deviceService.pageQuery(deviceReqQuery);
}
// 设备列表查询
@PostMapping("/list")
public ApiResponse list(@RequestBody DeviceReqQuery deviceReqQuery) {
return deviceService.list(deviceReqQuery);
}
// 设备详情查询
@GetMapping("/getDetails/{id}")
public ApiResponse<DeviceRespVO> getDetails(@PathVariable("id") Long id) {
return deviceService.getById(id);
}
// 新增或修改设备
@PostMapping("/addOrUpdate")
public ApiResponse addOrUpdate(@RequestBody DeviceAddOrUpdateReq deviceReqQuery) {
return deviceService.addOrUpdate(deviceReqQuery);
}
// 删除设备
@DeleteMapping("/delete/{id}")
public ApiResponse delete(@PathVariable("id") Long id) {
return deviceService.deleteById(id);
}
// 修改设备状态
@PutMapping("/updateStatus/{id}")
public ApiResponse updateStatus(@PathVariable("id") Long id) {
return deviceService.updateStatus(id);
}
// 排序设备
@PostMapping("/sort")
public ApiResponse<Boolean> sortDevice(@RequestBody DeviceSortRequest request) {
return deviceService.sortDevice(request.getDeviceId(), request.getAfterDeviceId());
}
@PostMapping("/scenic/{scenicId}/sortBatch")
public ApiResponse<Boolean> sortDeviceBatch(@PathVariable("scenicId") Long scenicId, @RequestBody DeviceBatchSortRequest request) {
return deviceService.batchSort(scenicId, request);
}
@GetMapping("/config/{id}")
public ApiResponse<DeviceConfigEntity> getConfig(@PathVariable("id") Long id) {
return ApiResponse.success(deviceService.getConfig(id));
}
@PostMapping("/saveConfig/{configId}")
public ApiResponse saveConfig(@PathVariable("configId") Long configId, @RequestBody DeviceConfigEntity deviceConfigEntity) {
deviceService.saveConfig(configId, deviceConfigEntity);
return ApiResponse.success(null);
}
}

View File

@@ -10,7 +10,10 @@ import com.ycwl.basic.annotation.IgnoreLogReq;
import com.ycwl.basic.annotation.IgnoreToken;
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
import com.ycwl.basic.facebody.entity.AddFaceResp;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
import com.ycwl.basic.integration.device.dto.device.CreateDeviceRequest;
import com.ycwl.basic.integration.device.dto.device.UpdateDeviceRequest;
import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO;
import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
@@ -80,7 +83,7 @@ import static com.ycwl.basic.constant.StorageConstant.VIID_FACE;
@Slf4j
public class ViidController {
@Autowired
private DeviceMapper deviceMapper;
private DeviceIntegrationService deviceIntegrationService;
private static final String serverId = "00000000000000000001";
@Autowired
private SourceMapper sourceMapper;
@@ -127,12 +130,21 @@ public class ViidController {
}
device.setKeepaliveAt(new Date());
device.setIpAddr(IpUtils.getIpAddr(request));
if (device.getId() != null) {
deviceMapper.updateEntity(device);
} else {
device.setId(SnowFlakeUtil.getLongId());
deviceMapper.addEntity(device);
deviceRepository.clearDeviceCache(deviceId);
if (device.getId() == null) {
// 通过zt-device服务创建新设备
CreateDeviceRequest createRequest = new CreateDeviceRequest();
createRequest.setName(device.getName());
createRequest.setNo(device.getNo());
createRequest.setType("IPC"); // 默认类型为IPC
createRequest.setIsActive(0);
createRequest.setScenicId(0L);
createRequest.setSort(0);
try {
DeviceV2DTO createdDevice = deviceIntegrationService.createDevice(createRequest);
device.setId(createdDevice.getId());
} catch (Exception e) {
log.warn("创建设备失败,设备编号: {}, 错误: {}", deviceId, e.getMessage());
}
}
return new VIIDBaseResp(
new ResponseStatusObject(serverId, "/VIID/System/Register", "0", "注册成功", sdfTime.format(new Date()))
@@ -164,9 +176,20 @@ public class ViidController {
device.setOnline(1);
device.setKeepaliveAt(new Date());
device.setIpAddr(IpUtils.getIpAddr(request));
device.setId(SnowFlakeUtil.getLongId());
deviceMapper.addEntity(device);
deviceRepository.clearDeviceCache(deviceId);
// 通过zt-device服务创建新设备
CreateDeviceRequest createRequest = new CreateDeviceRequest();
createRequest.setName(device.getName());
createRequest.setNo(device.getNo());
createRequest.setType("IPC"); // 默认类型为IPC
createRequest.setIsActive(0);
createRequest.setScenicId(0L);
createRequest.setSort(0);
try {
DeviceV2DTO createdDevice = deviceIntegrationService.createDevice(createRequest);
device.setId(createdDevice.getId());
} catch (Exception e) {
log.warn("创建设备失败,设备编号: {}, 错误: {}", deviceId, e.getMessage());
}
} else {
deviceRepository.updateOnlineStatus(device.getId(), IpUtils.getIpAddr(request), 1, new Date());
}

View File

@@ -6,7 +6,6 @@ import com.ycwl.basic.constant.StorageConstant;
import com.ycwl.basic.device.entity.common.FileObject;
import com.ycwl.basic.device.operator.WvpPassiveStorageOperator;
import com.ycwl.basic.model.wvp.WvpSyncReqVo;
import com.ycwl.basic.service.pc.DeviceService;
import com.ycwl.basic.service.pc.ScenicService;
import com.ycwl.basic.storage.adapters.IStorageAdapter;
import com.ycwl.basic.storage.enums.StorageAcl;
@@ -30,15 +29,12 @@ import java.util.List;
@RequestMapping("/wvp/v1/")
public class WvpController {
@Autowired
private DeviceService deviceService;
@Autowired
private ScenicService scenicService;
@IgnoreLogReq
@PostMapping("/scenic/{scenicId}/sync")
public ApiResponse<List<WvpPassiveStorageOperator.Task>> sync(@PathVariable("scenicId") Long scenicId, @RequestBody WvpSyncReqVo reqVo) {
deviceService.updateDevices(scenicId, reqVo);
return ApiResponse.success(WvpPassiveStorageOperator.getTaskListByScenicId(scenicId));
}

View File

@@ -11,10 +11,13 @@ import com.ycwl.basic.device.operator.VptPassiveStorageOperator;
import com.ycwl.basic.device.operator.WvpActiveStorageOperator;
import com.ycwl.basic.device.operator.WvpPassiveStorageOperator;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import java.time.ZoneId;
import java.util.Date;
public class DeviceFactory {
public static IDeviceStorageOperator getDeviceStorageOperator(DeviceEntity device, DeviceConfigEntity config) {
public static IDeviceStorageOperator getDeviceStorageOperator(DeviceV2DTO device, DeviceConfigEntity config) {
IDeviceStorageOperator operator = null;
if (config == null) {
return null;
@@ -35,11 +38,34 @@ public class DeviceFactory {
if (operator == null) {
return null;
}
operator.setDevice(device);
operator.setDevice(convertToEntity(device));
operator.setDeviceConfig(config);
return operator;
}
/**
* 将DeviceV2DTO转换为DeviceEntity
*/
private static DeviceEntity convertToEntity(DeviceV2DTO dto) {
if (dto == null) {
return null;
}
DeviceEntity entity = new DeviceEntity();
entity.setId(dto.getId());
entity.setName(dto.getName());
entity.setNo(dto.getNo());
entity.setScenicId(dto.getScenicId());
entity.setStatus(dto.getIsActive());
// 转换时间格式:LocalDateTime -> Date
if (dto.getCreateTime() != null) {
entity.setCreateAt(Date.from(dto.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()));
}
if (dto.getUpdateTime() != null) {
entity.setUpdateAt(Date.from(dto.getUpdateTime().atZone(ZoneId.systemDefault()).toInstant()));
}
return entity;
}
public static IDeviceStatusChecker getDeviceStatusChecker(DeviceEntity device, DeviceConfigEntity config) {
IDeviceStatusChecker checker = null;
if (config.getOnlineCheck() <= 0) {

View File

@@ -3,7 +3,6 @@ package com.ycwl.basic.repository;
import com.ycwl.basic.integration.device.service.DeviceConfigIntegrationService;
import com.ycwl.basic.integration.device.dto.config.DeviceConfigV2DTO;
import com.ycwl.basic.utils.JacksonUtil;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.utils.SnowFlakeUtil;
@@ -19,13 +18,10 @@ import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Component
public class DeviceRepository {
@Autowired
private DeviceMapper deviceMapper;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
@@ -33,8 +29,6 @@ public class DeviceRepository {
public static final String DEVICE_ONLINE_CACHE_KEY = "device:online_status:%s";
public static final String DEVICE_CACHE_KEY = "device:%s";
public static final String DEVICE_CONFIG_CACHE_KEY = "device:%s:config";
public static final String DEVICE_CONFIG_MANAGER_CACHE_KEY = "device:%s:config:manager";
@Autowired
private DeviceConfigIntegrationService deviceConfigIntegrationService;
@@ -114,35 +108,6 @@ public class DeviceRepository {
return entity;
}
public boolean clearDeviceCache(String deviceNo) {
if (deviceNo == null) {
return true;
}
if (redisTemplate.hasKey(String.format(DEVICE_CACHE_KEY, deviceNo))) {
DeviceEntity device = getDeviceByDeviceNo(deviceNo);
if (device != null) {
redisTemplate.delete(String.format(DEVICE_CACHE_KEY, device.getNo()));
clearDeviceCache(device.getId());
} else {
redisTemplate.delete(String.format(DEVICE_CACHE_KEY, deviceNo));
}
}
redisTemplate.delete(String.format(DEVICE_CACHE_KEY, deviceNo));
return true;
}
public boolean clearDeviceCache(Long deviceId) {
if (redisTemplate.hasKey(String.format(DEVICE_CACHE_KEY, deviceId))) {
DeviceEntity device = getDevice(deviceId);
redisTemplate.delete(String.format(DEVICE_CACHE_KEY, device.getNo()));
redisTemplate.delete(String.format(DEVICE_CONFIG_CACHE_KEY, device.getNo()));
redisTemplate.delete(String.format(DEVICE_CONFIG_MANAGER_CACHE_KEY, device.getNo()));
}
redisTemplate.delete(String.format(DEVICE_CACHE_KEY, deviceId));
redisTemplate.delete(String.format(DEVICE_CONFIG_CACHE_KEY, deviceId));
redisTemplate.delete(String.format(DEVICE_CONFIG_MANAGER_CACHE_KEY, deviceId));
return true;
}
public void updateOnlineStatus(String deviceNo, int online, Date keepaliveAt) {
DeviceEntity device = getDeviceByDeviceNo(deviceNo);
if (null == device) {
@@ -177,8 +142,15 @@ public class DeviceRepository {
redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_KEY, device.getNo()), JacksonUtil.toJSONString(device));
}
public List<DeviceEntity> getAllDeviceByScenicId(Long scenicId) {
List<Long> deviceIdList = deviceMapper.listAllByScenicId(scenicId);
return deviceIdList.stream().map(this::getDevice).collect(Collectors.toList());
public List<DeviceV2DTO> getAllDeviceByScenicId(Long scenicId) {
try {
var deviceListResponse = deviceIntegrationService.getScenicActiveDevices(scenicId, 1, 1000);
if (deviceListResponse != null && deviceListResponse.getList() != null) {
return deviceListResponse.getList();
}
} catch (Exception e) {
log.warn("获取景区设备列表失败,景区ID: {}, 错误: {}", scenicId, e.getMessage());
}
return List.of();
}
}

View File

@@ -1,7 +1,5 @@
package com.ycwl.basic.service.custom;
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.mts20140618.models.QuerySmarttagJobRequest;
import com.aliyun.mts20140618.models.QuerySmarttagJobResponse;
import com.aliyun.mts20140618.models.QuerySmarttagJobResponseBody;
@@ -10,11 +8,11 @@ import com.aliyun.mts20140618.models.SubmitSmarttagJobResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
import com.ycwl.basic.facebody.entity.AddFaceResp;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO;
import com.ycwl.basic.mapper.CustomUploadTaskMapper;
import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.custom.entity.CustomUploadTaskEntity;
import com.ycwl.basic.model.custom.entity.FaceData;
import com.ycwl.basic.model.custom.req.CreateUploadTaskReq;
@@ -30,20 +28,15 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static com.ycwl.basic.constant.StorageConstant.VIID_FACE;
@Slf4j
@Service
public class CustomUploadTaskService {
@@ -52,7 +45,7 @@ public class CustomUploadTaskService {
private CustomUploadTaskMapper customUploadTaskMapper;
@Autowired
private DeviceMapper deviceMapper;
private DeviceIntegrationService deviceIntegrationService;
@Autowired
private ScenicService scenicService;
@@ -80,7 +73,7 @@ public class CustomUploadTaskService {
}
// 验证设备访问权限
DeviceEntity device = validateDeviceAccess(req.getAccessKey(), req.getType());
DeviceV2DTO device = validateDeviceAccess(req.getAccessKey(), req.getType());
long taskId = SnowFlakeUtil.getLongId();
String savePath = generateSavePath(device.getScenicId(), req.getFileName());
@@ -108,7 +101,7 @@ public class CustomUploadTaskService {
public void completeUpload(String accessKey, Long taskId) {
// 验证设备访问权限
DeviceEntity device = validateDeviceAccess(accessKey, null);
DeviceV2DTO device = validateDeviceAccess(accessKey, null);
CustomUploadTaskEntity task = customUploadTaskMapper.selectById(taskId);
if (task == null) {
@@ -146,7 +139,7 @@ public class CustomUploadTaskService {
public void markTaskFailed(String accessKey, Long taskId, String errorMsg) {
// 验证设备访问权限
DeviceEntity device = validateDeviceAccess(accessKey, null);
DeviceV2DTO device = validateDeviceAccess(accessKey, null);
CustomUploadTaskEntity task = customUploadTaskMapper.selectById(taskId);
if (task == null) {
@@ -214,17 +207,18 @@ public class CustomUploadTaskService {
}
}
private DeviceEntity validateDeviceAccess(String accessKey, String type) {
private DeviceV2DTO validateDeviceAccess(String accessKey, String type) {
if (StringUtils.isBlank(accessKey)) {
throw new RuntimeException("设备访问密钥不能为空");
}
DeviceEntity device = deviceMapper.getByDeviceNo(accessKey);
if (device == null || device.getStatus() != 1) {
// 通过zt-device服务获取设备信息
DeviceV2DTO deviceV2DTO = deviceIntegrationService.getDeviceByNo(accessKey);
if (deviceV2DTO == null || deviceV2DTO.getIsActive() != 1) {
throw new RuntimeException("无效的设备访问密钥或设备已被禁用");
}
return device;
return deviceV2DTO;
}
private String createAliyunMtsTask(String inputPath) {

View File

@@ -2,8 +2,10 @@ package com.ycwl.basic.service.mobile.impl;
import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
import com.ycwl.basic.integration.device.dto.device.DeviceV2ListResponse;
import com.ycwl.basic.mapper.ExtraDeviceMapper;
import com.ycwl.basic.mapper.ScenicAccountMapper;
import com.ycwl.basic.model.jwt.JwtInfo;
@@ -34,8 +36,10 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import static com.ycwl.basic.constant.JwtRoleConstant.MERCHANT;
@@ -48,7 +52,7 @@ import static com.ycwl.basic.constant.JwtRoleConstant.MERCHANT;
public class AppScenicServiceImpl implements AppScenicService {
@Autowired
private DeviceMapper deviceMapper;
private DeviceIntegrationService deviceIntegrationService;
@Autowired
private ScenicAccountMapper scenicAccountMapper;
@Autowired
@@ -80,7 +84,14 @@ public class AppScenicServiceImpl implements AppScenicService {
@Override
public ApiResponse<ScenicDeviceCountVO> deviceCountByScenicId(Long scenicId) {
JwtInfo worker = JwtTokenUtil.getWorker();
ScenicDeviceCountVO scenicDeviceCountVO = deviceMapper.deviceCountByScenicId(scenicId);
// 通过zt-device服务获取设备统计
DeviceV2ListResponse deviceListResponse = deviceIntegrationService.getScenicActiveDevices(scenicId, 1, 1000);
ScenicDeviceCountVO scenicDeviceCountVO = new ScenicDeviceCountVO();
if (deviceListResponse != null && deviceListResponse.getList() != null) {
scenicDeviceCountVO.setTotalDeviceCount(deviceListResponse.getList().size());
} else {
scenicDeviceCountVO.setTotalDeviceCount(0);
}
return ApiResponse.success(scenicDeviceCountVO);
}
@@ -107,7 +118,14 @@ public class AppScenicServiceImpl implements AppScenicService {
scenicRespVO.setKfCodeUrl(scenic.getKfCodeUrl());
}
ScenicDeviceCountVO scenicDeviceCountVO = deviceMapper.deviceCountByScenicId(id);
// 通过zt-device服务获取设备统计
DeviceV2ListResponse deviceListResponse = deviceIntegrationService.getScenicActiveDevices(id, 1, 1000);
ScenicDeviceCountVO scenicDeviceCountVO = new ScenicDeviceCountVO();
if (deviceListResponse != null && deviceListResponse.getList() != null) {
scenicDeviceCountVO.setTotalDeviceCount(deviceListResponse.getList().size());
} else {
scenicDeviceCountVO.setTotalDeviceCount(0);
}
scenicRespVO.setLensNum(scenicDeviceCountVO.getTotalDeviceCount());
return ApiResponse.success(scenicRespVO);
}
@@ -257,7 +275,18 @@ public class AppScenicServiceImpl implements AppScenicService {
@Override
public ApiResponse<List<DeviceRespVO>> getDevices(Long scenicId) {
List<DeviceRespVO> deviceRespVOList = deviceMapper.listByScenicIdWithWVP(scenicId);
DeviceV2ListResponse deviceV2ListResponse = deviceIntegrationService.listDevices(1, 1000, null, null, null, 1, scenicId);
List<DeviceRespVO> deviceRespVOList = deviceV2ListResponse.getList().stream().map(device -> {
DeviceRespVO deviceRespVO = new DeviceRespVO();
deviceRespVO.setId(device.getId());
deviceRespVO.setName(device.getName());
deviceRespVO.setNo(device.getNo());
DeviceConfigManager config = deviceRepository.getDeviceConfigManager(device.getId());
deviceRespVO.setDeviceNo(device.getNo());
deviceRespVO.setChannelNo(config.getString("channel_no"));
return deviceRespVO;
}).collect(Collectors.toList());
for (DeviceRespVO deviceRespVO : deviceRespVOList) {
DeviceEntity onlineStatus = deviceRepository.getOnlineStatus(deviceRespVO.getId());
if (onlineStatus != null) {
@@ -282,7 +311,7 @@ public class AppScenicServiceImpl implements AppScenicService {
deviceRespVO.setOnline(0);
continue;
}
Long ts = Long.parseLong(onlineTs);
long ts = Long.parseLong(onlineTs);
Date keepaliveAt = new Date(ts*1000);
deviceRespVO.setUpdateAt(keepaliveAt);
deviceRespVO.setKeepaliveAt(keepaliveAt);

View File

@@ -1,35 +0,0 @@
package com.ycwl.basic.service.pc;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.model.pc.device.req.DeviceAddOrUpdateReq;
import com.ycwl.basic.model.pc.device.req.DeviceBatchSortRequest;
import com.ycwl.basic.model.pc.device.req.DeviceReqQuery;
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
import com.ycwl.basic.model.wvp.WvpSyncReqVo;
import com.ycwl.basic.utils.ApiResponse;
import java.util.List;
/**
* @Author:longbinbin
* @Date:2024/12/2 16:14
* 设备管理
*/
public interface DeviceService {
ApiResponse<PageInfo<DeviceRespVO>> pageQuery(DeviceReqQuery deviceReqQuery);
ApiResponse<List<DeviceRespVO>> list(DeviceReqQuery deviceReqQuery);
ApiResponse<DeviceRespVO> getById(Long id);
ApiResponse addOrUpdate(DeviceAddOrUpdateReq deviceReqQuery);
ApiResponse deleteById(Long id);
ApiResponse updateStatus(Long id);
DeviceConfigEntity getConfig(Long id);
void saveConfig(Long configId, DeviceConfigEntity config);
void updateDevices(Long scenicId, WvpSyncReqVo reqVo);
ApiResponse<Boolean> sortDevice(Long deviceId, Long afterDeviceId);
ApiResponse<Boolean> batchSort(Long scenicId, DeviceBatchSortRequest request);
}

View File

@@ -1,175 +0,0 @@
package com.ycwl.basic.service.pc.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.pc.device.req.DeviceBatchSortRequest;
import com.ycwl.basic.model.wvp.WvpSyncReqVo;
import com.ycwl.basic.repository.DeviceRepository;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.model.pc.device.req.DeviceAddOrUpdateReq;
import com.ycwl.basic.model.pc.device.req.DeviceReqQuery;
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
import com.ycwl.basic.service.pc.DeviceService;
import com.ycwl.basic.utils.ApiResponse;
import com.ycwl.basic.utils.SnowFlakeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Author:longbinbin
* @Date:2024/12/2 16:18
*/
@Service
public class DeviceServiceImpl implements DeviceService {
@Autowired
private DeviceMapper deviceMapper;
@Autowired
private DeviceRepository deviceRepository;
@Override
public ApiResponse<PageInfo<DeviceRespVO>> pageQuery(DeviceReqQuery deviceReqQuery) {
PageHelper.startPage(deviceReqQuery.getPageNum(), deviceReqQuery.getPageSize());
List<DeviceRespVO> list = deviceMapper.list(deviceReqQuery);
for (DeviceRespVO deviceRespVO : list) {
DeviceEntity onlineStatus = deviceRepository.getOnlineStatus(deviceRespVO.getId());
if (onlineStatus != null) {
deviceRespVO.setKeepaliveAt(onlineStatus.getKeepaliveAt());
if (new Date().getTime() - onlineStatus.getKeepaliveAt().getTime() > 300000) {
deviceRespVO.setOnline(0);
} else {
deviceRespVO.setOnline(onlineStatus.getOnline());
}
} else {
deviceRespVO.setOnline(0);
deviceRespVO.setKeepaliveAt(null);
}
}
PageInfo<DeviceRespVO> pageInfo = new PageInfo<>(list);
return ApiResponse.success(pageInfo);
}
@Override
public ApiResponse<List<DeviceRespVO>> list(DeviceReqQuery deviceReqQuery) {
return ApiResponse.success(deviceMapper.list(deviceReqQuery));
}
@Override
public ApiResponse<DeviceRespVO> getById(Long id) {
return ApiResponse.success(deviceMapper.getById(id));
}
@Override
public ApiResponse addOrUpdate(DeviceAddOrUpdateReq deviceReqQuery) {
Long id = deviceReqQuery.getId();
if (id == null) {
deviceReqQuery.setId(SnowFlakeUtil.getLongId());
if (StringUtils.isBlank(deviceReqQuery.getNo())) {
deviceReqQuery.setNo(deviceReqQuery.getId().toString());
}
deviceReqQuery.setStatus(0);
return ApiResponse.success(deviceMapper.add(deviceReqQuery));
} else {
deviceRepository.clearDeviceCache(deviceReqQuery.getId());
deviceMapper.update(deviceReqQuery);
deviceRepository.clearDeviceCache(deviceReqQuery.getId());
return ApiResponse.success(0);
}
}
@Override
public ApiResponse deleteById(Long id) {
return ApiResponse.success(deviceMapper.deleteById(id));
}
@Override
public ApiResponse updateStatus(Long id) {
deviceRepository.clearDeviceCache(id);
deviceMapper.updateStatus(id);
deviceRepository.clearDeviceCache(id);
return ApiResponse.success(1);
}
@Override
public DeviceConfigEntity getConfig(Long id) {
DeviceConfigEntity config = deviceMapper.getConfigByDeviceId(id);
if (config == null) {
config = new DeviceConfigEntity();
config.setId(SnowFlakeUtil.getLongId());
config.setDeviceId(id);
deviceMapper.addConfig(config);
}
return config;
}
@Override
public void saveConfig(Long configId, DeviceConfigEntity config) {
config.setId(configId);
deviceMapper.updateConfig(config);
deviceRepository.clearDeviceCache(config.getDeviceId());
}
@Override
public void updateDevices(Long scenicId, WvpSyncReqVo reqVo) {
if (reqVo == null) {
return;
}
if (reqVo.getDevices() != null && !reqVo.getDevices().isEmpty()) {
for (WvpSyncReqVo.DeviceItem deviceItem : reqVo.getDevices()) {
DeviceEntity device = deviceRepository.getDeviceByDeviceNo(deviceItem.getDeviceNo());
if (device != null) {
device.setOnline(deviceItem.getOnline());
device.setKeepaliveAt(deviceItem.getKeepaliveAt());
deviceRepository.updateOnlineStatus(device.getId(), deviceItem.getIp(), 1, deviceItem.getKeepaliveAt());
}
}
}
}
@Override
public ApiResponse<Boolean> sortDevice(Long deviceId, Long afterDeviceId) {
DeviceEntity device = deviceRepository.getDevice(deviceId);
if (device == null) {
return ApiResponse.fail("设备不存在");
}
List<DeviceEntity> scenicDeviceList = deviceRepository.getAllDeviceByScenicId(device.getScenicId());
AtomicInteger sortNum = new AtomicInteger(0);
for (DeviceEntity item : scenicDeviceList) {
item.setSort(sortNum.addAndGet(1));
}
Optional<DeviceEntity> templateOptional = scenicDeviceList.stream().filter(item -> item.getId().equals(deviceId)).findAny();
if (templateOptional.isEmpty()) {
return ApiResponse.fail("设备不存在");
}
Optional<DeviceEntity> afterTemplateOptional = scenicDeviceList.stream().filter(item -> item.getId().equals(afterDeviceId)).findAny();
if (afterTemplateOptional.isPresent()) {
DeviceEntity afterTemplate = afterTemplateOptional.get();
Integer newSort = afterTemplate.getSort();
DeviceEntity oldTemplate = templateOptional.get();
Integer oldSort = oldTemplate.getSort();
afterTemplate.setSort(oldSort);
oldTemplate.setSort(newSort);
}
scenicDeviceList.forEach(item -> {
deviceMapper.updateSort(item.getId(), item.getSort());
deviceRepository.clearDeviceCache(item.getId());
deviceRepository.clearDeviceCache(item.getNo());
});
return ApiResponse.success(true);
}
@Override
public ApiResponse<Boolean> batchSort(Long scenicId, DeviceBatchSortRequest request) {
for (DeviceBatchSortRequest.SortItem item : request.getList()) {
deviceMapper.updateSort(item.getId(), item.getSort());
deviceRepository.clearDeviceCache(item.getId());
}
return ApiResponse.success(true);
}
}

View File

@@ -3,11 +3,16 @@ package com.ycwl.basic.task;
import com.ycwl.basic.device.DeviceFactory;
import com.ycwl.basic.device.operator.IDeviceStorageOperator;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
import com.ycwl.basic.integration.device.dto.device.DeviceV2ListResponse;
import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO;
import java.util.stream.Collectors;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.pc.device.req.DeviceReqQuery;
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
import com.ycwl.basic.repository.DeviceRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
@@ -24,29 +29,33 @@ import java.util.List;
@Profile("prod")
public class VideoPieceCleaner {
@Autowired
private DeviceMapper deviceMapper;
private DeviceIntegrationService deviceIntegrationService;
@Autowired
private DeviceRepository deviceRepository;
@Scheduled(cron = "0 0 0 * * ?")
public void clean() {
log.info("开始删除视频文件");
List<DeviceEntity> deviceList = deviceMapper.listAll();
for (DeviceEntity device : deviceList) {
DeviceConfigEntity config = deviceMapper.getConfigByDeviceId(device.getId());
if (config == null) {
// 通过zt-device服务获取所有激活设备
DeviceV2ListResponse deviceListResponse = deviceIntegrationService.listDevices(1, 10000, null, null, null, 1, null);
List<DeviceEntity> deviceList;
if (deviceListResponse == null) {
return;
}
for (DeviceV2DTO device : deviceListResponse.getList()) {
DeviceConfigManager config = deviceRepository.getDeviceConfigManager(device.getId());
DeviceConfigEntity dConfig = deviceRepository.getDeviceConfig(device.getId());
Integer storeExpireDay = config.getInteger("store_expire_day");
if (storeExpireDay == null || storeExpireDay <= 0) {
continue;
}
if (config.getStoreExpireDay() == null) {
continue;
}
if (config.getStoreExpireDay() <= 0) {
continue;
}
IDeviceStorageOperator storageOperator = DeviceFactory.getDeviceStorageOperator(device, config);
IDeviceStorageOperator storageOperator = DeviceFactory.getDeviceStorageOperator(device, dConfig);
if (storageOperator == null) {
continue;
}
storageOperator.removeFilesBeforeDate(new Date(System.currentTimeMillis() - config.getStoreExpireDay() * 24 * 60 * 60 * 1000));
storageOperator.removeFilesBeforeDate(new Date(System.currentTimeMillis() - storeExpireDay * 24 * 60 * 60 * 1000));
log.info("删除视频文件完成");
}
}
}

View File

@@ -16,6 +16,8 @@ import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
@@ -77,6 +79,8 @@ public class VideoPieceGetter {
private VideoReUploader videoReUploader;
@Autowired
private ScenicRepository scenicRepository;
@Autowired
private DeviceIntegrationService deviceIntegrationService;
@Data
public static class Task {
@@ -145,7 +149,7 @@ public class VideoPieceGetter {
Map<Long, Long> pairDeviceMap = new ConcurrentHashMap<>();
if (!list.isEmpty()) {
Long scenicId = list.getFirst().getScenicId();
List<DeviceEntity> allDeviceByScenicId = deviceRepository.getAllDeviceByScenicId(scenicId);
List<DeviceV2DTO> allDeviceByScenicId = deviceRepository.getAllDeviceByScenicId(scenicId);
allDeviceByScenicId.forEach(device -> {
Long deviceId = device.getId();
DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(deviceId);
@@ -256,16 +260,21 @@ public class VideoPieceGetter {
}
private boolean doCut(Long deviceId, Long faceSampleId, Date baseTime, Task task) {
DeviceEntity device = deviceRepository.getDevice(deviceId);
// 通过zt-device服务获取设备信息
DeviceV2DTO deviceV2 = deviceIntegrationService.getDevice(deviceId);
if (deviceV2 == null) {
log.warn("设备不存在,设备ID: {}", deviceId);
return false;
}
DeviceConfigManager config = deviceRepository.getDeviceConfigManager(deviceId);
DeviceConfigEntity dConfig = deviceRepository.getDeviceConfig(deviceId);
SourceEntity source = sourceMapper.querySameVideo(faceSampleId, device.getId());
SourceEntity source = sourceMapper.querySameVideo(faceSampleId, deviceV2.getId());
if (source == null || task.force) {
BigDecimal cutPre = config.getBigDecimal("cut_pre", BigDecimal.valueOf(5L));
BigDecimal cutPost = config.getBigDecimal("cut_post", BigDecimal.valueOf(5L));
IDeviceStorageOperator pieceGetter = DeviceFactory.getDeviceStorageOperator(device, dConfig);
IDeviceStorageOperator pieceGetter = DeviceFactory.getDeviceStorageOperator(deviceV2, dConfig);
if (pieceGetter == null) {
return false;
}
@@ -316,7 +325,7 @@ public class VideoPieceGetter {
}
sourceEntity.setVideoUrl(url);
sourceEntity.setFaceSampleId(faceSampleId);
sourceEntity.setScenicId(device.getScenicId());
sourceEntity.setScenicId(deviceV2.getScenicId());
sourceEntity.setDeviceId(deviceId);
sourceEntity.setType(1);
if (task.memberId != null && task.faceId != null) {
@@ -324,9 +333,9 @@ public class VideoPieceGetter {
videoSource.setMemberId(task.getMemberId());
videoSource.setType(1);
videoSource.setFaceId(task.getFaceId());
videoSource.setScenicId(device.getScenicId());
videoSource.setScenicId(deviceV2.getScenicId());
videoSource.setSourceId(sourceEntity.getId());
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), device.getScenicId(), 1, task.getFaceId());
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), deviceV2.getScenicId(), 1, task.getFaceId());
if (isBuy.isBuy()) { // 如果用户买过
videoSource.setIsBuy(1);
} else if (isBuy.isFree()) { // 全免费逻辑
@@ -352,10 +361,10 @@ public class VideoPieceGetter {
int count = sourceMapper.hasRelationTo(task.getMemberId(), source.getId(), 1);
if (count <= 0) {
// 没有关联
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), device.getScenicId(), 1, task.getFaceId());
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), deviceV2.getScenicId(), 1, task.getFaceId());
MemberSourceEntity videoSource = new MemberSourceEntity();
videoSource.setId(SnowFlakeUtil.getLongId());
videoSource.setScenicId(device.getScenicId());
videoSource.setScenicId(deviceV2.getScenicId());
videoSource.setFaceId(task.getFaceId());
videoSource.setMemberId(task.getMemberId());
videoSource.setType(1);