280 lines
12 KiB
Java
Raw Normal View History

package com.zhgd.xmgl.call;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
2025-11-03 10:34:58 +08:00
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zhgd.jeecg.common.execption.OpenAlertException;
import com.zhgd.jeecg.common.util.pass.HttpUtils;
2025-11-03 10:34:58 +08:00
import com.zhgd.redis.lock.RedisRepository;
import com.zhgd.xmgl.call.api.PoliceCameraManufacturer;
import com.zhgd.xmgl.call.util.Mcs8Util;
import com.zhgd.xmgl.modules.policecamera.entity.PoliceCameraItem;
import com.zhgd.xmgl.modules.policecamera.entity.PoliceCameraItemFile;
import com.zhgd.xmgl.modules.policecamera.entity.ProjectPoliceCameraConfig;
import com.zhgd.xmgl.modules.policecamera.entity.WorkTicketHistory;
import com.zhgd.xmgl.modules.policecamera.entity.bo.Mcs8FileBo;
import com.zhgd.xmgl.modules.policecamera.entity.bo.Mcs8FileSignedUrlBo;
import com.zhgd.xmgl.modules.policecamera.entity.vo.WorkTicketVo;
import com.zhgd.xmgl.modules.policecamera.service.IPoliceCameraItemFileService;
import com.zhgd.xmgl.modules.policecamera.service.IPoliceCameraItemService;
import com.zhgd.xmgl.modules.policecamera.service.IWorkTicketHistoryService;
import com.zhgd.xmgl.util.PathUtil;
import lombok.extern.slf4j.Slf4j;
2025-11-03 10:34:58 +08:00
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
2025-07-09 16:29:45 +08:00
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Lazy;
2025-07-09 16:29:45 +08:00
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Component
2025-07-09 16:29:45 +08:00
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Mcs8Call implements PoliceCameraManufacturer {
@Lazy
@Autowired
private Mcs8Call mcs8Call;
private ProjectPoliceCameraConfig config;
@Lazy
@Autowired
private IPoliceCameraItemFileService policeCameraItemFileService;
@Lazy
@Autowired
private IPoliceCameraItemService policeCameraItemService;
@Lazy
@Autowired
private IWorkTicketHistoryService workTicketHistoryService;
@Value("${mcs8.download.http.type:pubUrl}")
private String downloadType;
2025-11-03 10:34:58 +08:00
@Lazy
@Autowired
private RedisRepository redisRepository;
public void setConfig(ProjectPoliceCameraConfig config) {
this.config = config;
}
@Override
public void beginWork(WorkTicketVo ticket, String workNo, int no) {
if (CollUtil.isEmpty(ticket.getItemList())) {
throw new OpenAlertException("请先绑定设备");
}
try {
2025-09-17 11:38:29 +08:00
Mcs8Util.addTask(config, StrUtil.format("{}-{}-{}", ticket.getConstructionAreaNames(), ticket.getWorkTicketNumber(), "" + no + "次作业"), workNo, true);
String taskId = Mcs8Util.getTaskIdByWorkNo(config, workNo, true);
Mcs8Util.updateTaskDest(config, ticket.getItemList(), taskId);
2025-07-24 10:02:42 +08:00
// Mcs8Util.updateTaskStatus(config, 1, taskId);
} catch (OpenAlertException e) {
throw e;
} catch (Exception e) {
log.error("err", e);
throw new OpenAlertException("开启设备录像失败,请检查调度台服务器配置");
}
}
@Override
public void endWork(WorkTicketVo ticket, String workNo) {
if (CollUtil.isEmpty(ticket.getItemList())) {
throw new OpenAlertException("请先绑定设备");
}
try {
2025-09-17 11:38:29 +08:00
String taskId = Mcs8Util.getTaskIdByWorkNo(config, workNo, true);
Mcs8Util.updateTaskStatus(config, 2, taskId, true);
} catch (OpenAlertException e) {
throw e;
} catch (Exception e) {
log.error("err", e);
throw new OpenAlertException("关闭设备录像失败,请检查调度台服务器配置");
}
}
@Override
public void pullFile(Date begin, Date end) {
Map<String, PoliceCameraItem> cameraItemMap = policeCameraItemService.list(null).stream().collect(Collectors.toMap(PoliceCameraItem::getDevSn, Function.identity(), (o1, o2) -> o1));
int page = 1;
int pageSize = 1000;
List<Mcs8FileBo> bos = new ArrayList<>();
do {
2025-09-17 11:38:29 +08:00
JSONObject jsonObject = Mcs8Util.getRecordFileList(config, page, pageSize, begin, end, true);
bos = BeanUtil.copyToList(jsonObject.getJSONArray("data"), Mcs8FileBo.class);
for (Mcs8FileBo bo : bos) {
2025-11-03 10:34:58 +08:00
if (!Objects.equals(bo.getFType(),3)) {
downloadFileAndSave(bo, cameraItemMap);
}
}
page++;
} while (CollUtil.isNotEmpty(bos) && bos.size() == pageSize);
}
2025-07-25 10:35:03 +08:00
public void downloadFileAndSave(Mcs8FileBo bo, Map<String, PoliceCameraItem> cameraItemMap) {
int count = policeCameraItemFileService.count(new LambdaQueryWrapper<PoliceCameraItemFile>()
.eq(PoliceCameraItemFile::getExternalId, bo.getId()));
if (count > 0) {
return;
}
2025-09-17 11:38:29 +08:00
Mcs8FileSignedUrlBo signedUrl = Mcs8Util.getSignedUrl(config, bo.getId(), true);
PoliceCameraItem item = cameraItemMap.get(bo.getDevId());
WorkTicketHistory history = workTicketHistoryService.getById(bo.getWorkNo());
if (item != null) {
HashMap<String, String> headers = new HashMap<>();
headers.put("token", Mcs8Util.getToken(Mcs8Util.getHost(config), config.getPort(), config.getAccount(), config.getPassword()));
String pubUrl = getUrl(signedUrl);
File downloadFile = HttpUtils.downloadFile(pubUrl, PathUtil.getBasePath(), headers);
if (downloadFile != null) {
PoliceCameraItemFile file = new PoliceCameraItemFile();
file.setItemId(item.getItemId());
file.setHistoryId(Optional.ofNullable(history).map(WorkTicketHistory::getId).orElse(null));
file.setExternalId(bo.getId());
file.setProjectSn(item.getProjectSn());
file.setFileType(bo.getFType());
file.setUploadTime(bo.getUpLoadTime());
file.setFileName(bo.getFileName());
file.setFileUrl(downloadFile.getName());
file.setFileTime(bo.getFileTime());
file.setFileLen(bo.getFileLen());
file.setDuration(bo.getDuration());
file.setStartTime(bo.getStartTime());
file.setEndTime(bo.getEndTime());
count = policeCameraItemFileService.count(new LambdaQueryWrapper<PoliceCameraItemFile>()
.eq(PoliceCameraItemFile::getExternalId, bo.getId()));
if (count > 0) {
return;
}
policeCameraItemFileService.save(file);
}
}
}
private String getUrl(Mcs8FileSignedUrlBo bo) {
String pubUrl;
if (Objects.equals("pubUrl", downloadType)) {
pubUrl = bo.getPubUrl();
} else if (Objects.equals("privateUrl", downloadType)) {
pubUrl = bo.getPrivateUrl();
} else if (Objects.equals("httpPubUrl", downloadType)) {
pubUrl = bo.getHttpPubUrl();
} else {
pubUrl = bo.getHttpPrivateUrl();
}
return pubUrl;
}
@Override
2025-11-03 10:34:58 +08:00
public void updateStatus(Long cacheSeconds) {
2025-10-11 10:59:07 +08:00
if (configIsBlank()) {
return;
}
2025-11-03 10:34:58 +08:00
List<PoliceCameraItem> itemList = policeCameraItemService.getListByProjectSn(config.getProjectSn());
Integer page = 1;
int pageSize = 1000;
JSONArray devList = new JSONArray();
JSONArray tempList = new JSONArray();
2025-11-03 10:34:58 +08:00
// 生成缓存key
String cacheKey = null;
if (cacheSeconds != null && cacheSeconds > 0) {
cacheKey = "mcs8:devList:full:" + Mcs8Util.getHost(config) + ":" + config.getPort() + ":" + config.getAccount() + ":" + config.getPassword();
// 尝试从缓存获取完整设备列表
try {
String cachedData = (String) redisRepository.get(cacheKey);
if (StringUtils.isNotBlank(cachedData)) {
devList = JSONArray.parseArray(cachedData);
log.debug("从缓存获取完整设备列表,数量: {}", devList.size());
// 直接使用缓存数据更新设备状态
updateDeviceStatus(itemList, devList);
return;
}
} catch (Exception e) {
log.warn("从缓存获取设备列表失败,继续从接口获取", e);
}
}
// 缓存不存在或禁用缓存,从接口获取数据
do {
2025-09-17 11:38:29 +08:00
tempList = Mcs8Util.getDevList(config, page, pageSize, true);
devList.addAll(tempList);
page++;
} while (CollUtil.isNotEmpty(tempList) && tempList.size() == pageSize);
2025-11-03 10:34:58 +08:00
// 如果启用缓存,将完整设备列表存入缓存
if (cacheSeconds != null && cacheSeconds > 0 && cacheKey != null && CollUtil.isNotEmpty(devList)) {
try {
redisRepository.setExpire(cacheKey, devList.toJSONString(), cacheSeconds);
log.debug("设备列表已缓存,数量: {}, 缓存时间: {}s", devList.size(), cacheSeconds);
} catch (Exception e) {
log.warn("设备列表缓存失败", e);
}
}
// 更新设备状态
updateDeviceStatus(itemList, devList);
}
/**
* 从接口数据更新设备状态
*/
private void updateDeviceStatus(List<PoliceCameraItem> itemList, JSONArray devList) {
Map<String, JSONObject> devSnMap = devList.stream()
.collect(Collectors.toMap(
o -> ((JSONObject) o).getString("deviceId"),
o -> (JSONObject) o,
(o1, o2) -> o1
));
// 分组处理:在线设备和离线设备
List<Long> onlineIds = new ArrayList<>();
List<Long> offlineIds = new ArrayList<>();
for (PoliceCameraItem item : itemList) {
JSONObject jsonObject = devSnMap.get(item.getDevSn());
2025-11-03 10:34:58 +08:00
Integer newState = (jsonObject != null && jsonObject.getInteger("status") == 1) ? 1 : 2;
Integer oldState = item.getDeviceState();
if (oldState == null || !oldState.equals(newState)) {
if (newState == 1) {
onlineIds.add(item.getItemId());
} else {
offlineIds.add(item.getItemId());
}
}
}
2025-11-03 10:34:58 +08:00
// 批量更新在线设备
if (CollUtil.isNotEmpty(onlineIds)) {
policeCameraItemService.update(new LambdaUpdateWrapper<PoliceCameraItem>()
.set(PoliceCameraItem::getDeviceState, 1)
.in(PoliceCameraItem::getItemId, onlineIds)
);
}
// 批量更新离线设备
if (CollUtil.isNotEmpty(offlineIds)) {
policeCameraItemService.update(new LambdaUpdateWrapper<PoliceCameraItem>()
.set(PoliceCameraItem::getDeviceState, 2)
.in(PoliceCameraItem::getItemId, offlineIds)
);
}
}
2025-10-11 10:59:07 +08:00
public boolean configIsBlank() {
return StrUtil.isBlank(config.getIp())
|| StrUtil.isBlank(config.getPort())
|| StrUtil.isBlank(config.getAccount())
|| StrUtil.isBlank(config.getPassword());
}
}