Merge branch 'device-microservice'
All checks were successful
ZhenTu-BE/pipeline/head This commit looks good

# Conflicts:
#	src/main/java/com/ycwl/basic/integration/scenic/service/ScenicConfigIntegrationService.java
#	src/main/java/com/ycwl/basic/integration/scenic/service/ScenicIntegrationService.java
This commit is contained in:
2025-09-04 12:28:32 +08:00
53 changed files with 3675 additions and 874 deletions

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,176 +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());
deviceRepository.clearDeviceCache(item.getNo2());
});
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

@@ -9,6 +9,7 @@ import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.enums.StatisticEnum;
import com.ycwl.basic.exception.BaseException;
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.mapper.FaceMapper;
@@ -290,7 +291,7 @@ public class FaceServiceImpl implements FaceService {
if (sampleListIds != null && !sampleListIds.isEmpty()) {// 匹配原片:照片
List<SourceEntity> sourceEntities = sourceMapper.listBySampleIds(sampleListIds);
List<MemberSourceEntity> memberSourceEntityList = sourceEntities.stream().map(sourceEntity -> {
DeviceConfigEntity deviceConfig = deviceRepository.getDeviceConfig(sourceEntity.getDeviceId());
DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(sourceEntity.getDeviceId());
MemberSourceEntity memberSourceEntity = new MemberSourceEntity();
memberSourceEntity.setScenicId(face.getScenicId());
memberSourceEntity.setFaceId(face.getId());
@@ -300,11 +301,11 @@ public class FaceServiceImpl implements FaceService {
memberSourceEntity.setIsFree(0);
if (deviceConfig != null) {
if (sourceEntity.getType() == 1) {
if (Integer.valueOf(1).equals(deviceConfig.getVideoFree())) {
if (Integer.valueOf(1).equals(deviceConfig.getInteger("video_free"))) {
memberSourceEntity.setIsFree(1);
}
} else if (sourceEntity.getType() == 2) {
if (Integer.valueOf(1).equals(deviceConfig.getImageFree())) {
if (Integer.valueOf(1).equals(deviceConfig.getInteger("image_free"))) {
memberSourceEntity.setIsFree(1);
}
}

View File

@@ -3,7 +3,6 @@ package com.ycwl.basic.service.pc.impl;
import com.ycwl.basic.facebody.FaceBodyFactory;
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
import com.ycwl.basic.pay.PayFactory;
import com.ycwl.basic.pay.adapter.IPayAdapter;
@@ -12,10 +11,9 @@ import com.ycwl.basic.service.pc.ScenicService;
import com.ycwl.basic.storage.StorageFactory;
import com.ycwl.basic.storage.adapters.IStorageAdapter;
import com.ycwl.basic.storage.exceptions.StorageUnsupportedException;
import com.ycwl.basic.util.ScenicConfigManager;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.util.TtlCacheMap;
import com.ycwl.basic.utils.ApiResponse;
import com.ycwl.basic.utils.JacksonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -1,6 +1,7 @@
package com.ycwl.basic.service.task.impl;
import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
import com.ycwl.basic.utils.JacksonUtil;
import com.aliyuncs.facebody.model.v20191230.SearchFaceRequest;
import com.ycwl.basic.biz.OrderBiz;
@@ -115,7 +116,7 @@ public class TaskFaceServiceImpl implements TaskFaceService {
if (sampleListIds != null && !sampleListIds.isEmpty()) {// 匹配原片:照片
List<SourceEntity> sourceEntities = sourceMapper.listBySampleIds(sampleListIds);
List<MemberSourceEntity> memberSourceEntityList = sourceEntities.stream().map(sourceEntity -> {
DeviceConfigEntity deviceConfig = deviceRepository.getDeviceConfig(sourceEntity.getDeviceId());
DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(sourceEntity.getDeviceId());
MemberSourceEntity memberSourceEntity = new MemberSourceEntity();
memberSourceEntity.setScenicId(scenicId);
memberSourceEntity.setFaceId(faceEntity.getId());
@@ -125,11 +126,11 @@ public class TaskFaceServiceImpl implements TaskFaceService {
memberSourceEntity.setIsFree(0);
if (deviceConfig != null) {
if (sourceEntity.getType() == 1) {
if (Integer.valueOf(1).equals(deviceConfig.getVideoFree())) {
if (Integer.valueOf(1).equals(deviceConfig.getInteger("video_free"))) {
memberSourceEntity.setIsFree(1);
}
} else if (sourceEntity.getType() == 2) {
if (Integer.valueOf(1).equals(deviceConfig.getImageFree())) {
if (Integer.valueOf(1).equals(deviceConfig.getInteger("image_free"))) {
memberSourceEntity.setIsFree(1);
}
}