2025-07-04 14:57:13 +08:00
|
|
|
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;
|
2025-07-04 14:57:13 +08:00
|
|
|
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;
|
2025-07-04 14:57:13 +08:00
|
|
|
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;
|
2025-07-04 14:57:13 +08:00
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
2025-09-19 16:49:04 +08:00
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
2025-07-09 16:29:45 +08:00
|
|
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
2025-07-04 14:57:13 +08:00
|
|
|
import org.springframework.context.annotation.Lazy;
|
2025-07-09 16:29:45 +08:00
|
|
|
import org.springframework.context.annotation.Scope;
|
2025-07-04 14:57:13 +08:00
|
|
|
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)
|
2025-07-04 14:57:13 +08:00
|
|
|
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;
|
2025-09-19 16:49:04 +08:00
|
|
|
@Value("${mcs8.download.http.type:pubUrl}")
|
|
|
|
|
private String downloadType;
|
2025-11-03 10:34:58 +08:00
|
|
|
@Lazy
|
|
|
|
|
@Autowired
|
|
|
|
|
private RedisRepository redisRepository;
|
2025-07-04 14:57:13 +08:00
|
|
|
|
|
|
|
|
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("请先绑定设备");
|
|
|
|
|
}
|
2025-07-11 17:28:09 +08:00
|
|
|
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);
|
2025-07-11 17:28:09 +08:00
|
|
|
Mcs8Util.updateTaskDest(config, ticket.getItemList(), taskId);
|
2025-07-24 10:02:42 +08:00
|
|
|
// Mcs8Util.updateTaskStatus(config, 1, taskId);
|
2025-07-11 17:28:09 +08:00
|
|
|
} catch (OpenAlertException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("err", e);
|
|
|
|
|
throw new OpenAlertException("开启设备录像失败,请检查调度台服务器配置");
|
|
|
|
|
}
|
2025-07-04 14:57:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void endWork(WorkTicketVo ticket, String workNo) {
|
|
|
|
|
if (CollUtil.isEmpty(ticket.getItemList())) {
|
|
|
|
|
throw new OpenAlertException("请先绑定设备");
|
|
|
|
|
}
|
2025-07-11 17:28:09 +08:00
|
|
|
try {
|
2025-09-17 11:38:29 +08:00
|
|
|
String taskId = Mcs8Util.getTaskIdByWorkNo(config, workNo, true);
|
|
|
|
|
Mcs8Util.updateTaskStatus(config, 2, taskId, true);
|
2025-07-11 17:28:09 +08:00
|
|
|
} catch (OpenAlertException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("err", e);
|
|
|
|
|
throw new OpenAlertException("关闭设备录像失败,请检查调度台服务器配置");
|
|
|
|
|
}
|
2025-07-04 14:57:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@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);
|
2025-07-04 14:57:13 +08:00
|
|
|
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);
|
|
|
|
|
}
|
2025-07-04 14:57:13 +08:00
|
|
|
}
|
|
|
|
|
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) {
|
2025-07-04 14:57:13 +08:00
|
|
|
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);
|
2025-07-04 14:57:13 +08:00
|
|
|
PoliceCameraItem item = cameraItemMap.get(bo.getDevId());
|
|
|
|
|
WorkTicketHistory history = workTicketHistoryService.getById(bo.getWorkNo());
|
|
|
|
|
if (item != null) {
|
|
|
|
|
HashMap<String, String> headers = new HashMap<>();
|
2025-07-11 17:28:09 +08:00
|
|
|
headers.put("token", Mcs8Util.getToken(Mcs8Util.getHost(config), config.getPort(), config.getAccount(), config.getPassword()));
|
2025-09-19 16:49:04 +08:00
|
|
|
String pubUrl = getUrl(signedUrl);
|
|
|
|
|
File downloadFile = HttpUtils.downloadFile(pubUrl, PathUtil.getBasePath(), headers);
|
2025-07-04 14:57:13 +08:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 16:49:04 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-04 14:57:13 +08:00
|
|
|
@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());
|
2025-07-04 14:57:13 +08:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 缓存不存在或禁用缓存,从接口获取数据
|
2025-07-04 14:57:13 +08:00
|
|
|
do {
|
2025-09-17 11:38:29 +08:00
|
|
|
tempList = Mcs8Util.getDevList(config, page, pageSize, true);
|
2025-07-04 14:57:13 +08:00
|
|
|
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<>();
|
|
|
|
|
|
2025-07-04 14:57:13 +08:00
|
|
|
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-07-04 14:57:13 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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-07-04 14:57:13 +08:00
|
|
|
}
|
2025-07-11 17:28:09 +08:00
|
|
|
|
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());
|
|
|
|
|
}
|
2025-07-11 17:28:09 +08:00
|
|
|
|
2025-07-04 14:57:13 +08:00
|
|
|
}
|