文件上传下载功能

This commit is contained in:
xy
2024-09-11 11:37:58 +08:00
parent 9dab90ab88
commit 72e81b1b6d
45 changed files with 1611 additions and 400 deletions

View File

@@ -0,0 +1,21 @@
package com.njcn.stat.api;
import com.njcn.common.pojo.constant.ServerInfo;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.mq.message.AppAutoDataMessage;
import com.njcn.stat.api.fallback.WlRecordClientFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author xy
*/
@FeignClient(value = ServerInfo.CS_STAT_BOOT, path = "/record", fallbackFactory = WlRecordClientFallbackFactory.class,contextId = "record")
public interface WlRecordFeignClient {
@PostMapping("/addOrUpdateBaseData")
HttpResult<String> addOrUpdateBaseData(@RequestBody @Validated AppAutoDataMessage appAutoDataMessage);
}

View File

@@ -0,0 +1,35 @@
package com.njcn.stat.api.fallback;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.mq.message.AppAutoDataMessage;
import com.njcn.stat.api.WlRecordFeignClient;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author xy
*/
@Slf4j
@Component
public class WlRecordClientFallbackFactory implements FallbackFactory<WlRecordFeignClient> {
@Override
public WlRecordFeignClient create(Throwable cause) {
//判断抛出异常是否为解码器抛出的业务异常
Enum<?> exceptionEnum = CommonResponseEnum.SERVICE_FALLBACK;
if (cause.getCause() instanceof BusinessException) {
BusinessException businessException = (BusinessException) cause.getCause();
}
Enum<?> finalExceptionEnum = exceptionEnum;
return new WlRecordFeignClient() {
@Override
public HttpResult<String> addOrUpdateBaseData(AppAutoDataMessage appAutoDataMessage) {
log.error("{}异常,降级处理,异常为:{}","新增或更新装置基础数据",cause.toString());
throw new BusinessException(finalExceptionEnum);
}
};
}
}

View File

@@ -0,0 +1,48 @@
package com.njcn.stat.controller;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.mq.message.AppAutoDataMessage;
import com.njcn.stat.service.IWlRecordService;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2024/9/10 9:23
*/
@Slf4j
@RestController
@RequestMapping("/record")
@Api(tags = "便携式基础数据录入")
@AllArgsConstructor
public class WlRecordController extends BaseController {
private final IWlRecordService wlRecordService;
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/addOrUpdateBaseData")
@ApiOperation("新增或更新装置基础数据")
@ApiImplicitParam(name = "appAutoDataMessage", value = "数据实体", required = true)
public HttpResult<String> addOrUpdateBaseData(@RequestBody @Validated AppAutoDataMessage appAutoDataMessage){
String methodDescribe = getMethodDescribe("addOrUpdateBaseData");
wlRecordService.addOrUpdateBaseData(appAutoDataMessage);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
}
}

View File

@@ -1,67 +1,67 @@
package com.njcn.stat.listener;
import cn.hutool.core.collection.CollectionUtil;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.redis.pojo.enums.AppRedisKey;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.stat.enums.StatResponseEnum;
import com.njcn.system.api.EpdFeignClient;
import com.njcn.system.pojo.dto.EpdDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author hongawen
* @version 1.0.0
* @date 2022年04月02日 14:31
*/
@Slf4j
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
@Resource
private EpdFeignClient epdFeignClient;
@Resource
private RedisUtil redisUtil;
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
/**
* 针对redis数据失效事件进行数据处理
* 注意message.toString()可以获取失效的key
*/
@Override
@Order(0)
public void onMessage(Message message, byte[] pattern) {
if (StringUtils.isBlank(message.toString())) {
return;
}
//判断失效的key
String expiredKey = message.toString();
if(expiredKey.equals(AppRedisKey.ELE_EPD_PQD)){
Map<String,String> map = new HashMap<>();
List<EpdDTO> list = epdFeignClient.findAll().getData();
if (CollectionUtil.isEmpty(list)){
throw new BusinessException(StatResponseEnum.DICT_NULL);
}
list.forEach(item->{
map.put(item.getDictName(),item.getTableName());
});
redisUtil.saveByKeyWithExpire(AppRedisKey.ELE_EPD_PQD,map,3600L);
}
}
}
//package com.njcn.stat.listener;
//
//import cn.hutool.core.collection.CollectionUtil;
//import com.njcn.common.pojo.exception.BusinessException;
//import com.njcn.redis.pojo.enums.AppRedisKey;
//import com.njcn.redis.utils.RedisUtil;
//import com.njcn.stat.enums.StatResponseEnum;
//import com.njcn.system.api.EpdFeignClient;
//import com.njcn.system.pojo.dto.EpdDTO;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.core.annotation.Order;
//import org.springframework.data.redis.connection.Message;
//import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
//import org.springframework.data.redis.listener.RedisMessageListenerContainer;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
///**
// * @author hongawen
// * @version 1.0.0
// * @date 2022年04月02日 14:31
// */
//@Slf4j
//@Component
//public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
//
// @Resource
// private EpdFeignClient epdFeignClient;
//
// @Resource
// private RedisUtil redisUtil;
//
// public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
// super(listenerContainer);
// }
//
//
// /**
// * 针对redis数据失效事件进行数据处理
// * 注意message.toString()可以获取失效的key
// */
// @Override
// @Order(0)
// public void onMessage(Message message, byte[] pattern) {
// if (StringUtils.isBlank(message.toString())) {
// return;
// }
// //判断失效的key
// String expiredKey = message.toString();
// if(expiredKey.equals(AppRedisKey.ELE_EPD_PQD)){
// Map<String,String> map = new HashMap<>();
// List<EpdDTO> list = epdFeignClient.findAll().getData();
// if (CollectionUtil.isEmpty(list)){
// throw new BusinessException(StatResponseEnum.DICT_NULL);
// }
// list.forEach(item->{
// map.put(item.getDictName(),item.getTableName());
// });
// redisUtil.saveByKeyWithExpire(AppRedisKey.ELE_EPD_PQD,map,3600L);
// }
// }
//}

View File

@@ -0,0 +1,12 @@
package com.njcn.stat.service;
import com.njcn.mq.message.AppAutoDataMessage;
/**
* @author xy
*/
public interface IWlRecordService {
void addOrUpdateBaseData(AppAutoDataMessage appAutoDataMessage);
}

View File

@@ -99,36 +99,36 @@ public class StatServiceImpl implements IStatService {
lineId = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.LINE_POSITION+appAutoDataMessage.getId())), Map.class).get(appAutoDataMessage.getMsg().getClDid().toString()).toString();
}
}
//缓存指标和influxDB表关系
Object object2 = redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD);
if(Objects.isNull(object2)) {
saveData();
}
// //缓存指标和influxDB表关系
// Object object2 = redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD);
// if(Objects.isNull(object2)) {
// saveData();
// }
//获取当前设备信息
if (CollectionUtil.isNotEmpty(list)){
List<String> recordList = new ArrayList<>();
for (AppAutoDataMessage.DataArray item : list) {
switch (item.getDataAttr()) {
case 1:
log.info("{}-->处理最大值", po.getNdid());
log.info("{}-->处理最大值", po.getNdid() + appAutoDataMessage.getDid() + appAutoDataMessage.getMsg().getClDid());
dataArrayParam.setStatMethod("max");
break;
case 2:
log.info("{}-->处理最小值", po.getNdid());
log.info("{}-->处理最小值", po.getNdid() + appAutoDataMessage.getDid() + appAutoDataMessage.getMsg().getClDid());
dataArrayParam.setStatMethod("min");
break;
case 3:
log.info("{}-->处理avg", po.getNdid());
log.info("{}-->处理avg", po.getNdid() + appAutoDataMessage.getDid() + appAutoDataMessage.getMsg().getClDid());
dataArrayParam.setStatMethod("avg");
break;
case 4:
log.info("{}-->处理cp95", po.getNdid());
log.info("{}-->处理cp95", po.getNdid() + appAutoDataMessage.getDid() + appAutoDataMessage.getMsg().getClDid());
dataArrayParam.setStatMethod("cp95");
break;
default:
break;
}
Object object = redisUtil.getObjectByKey(appAutoDataMessage.getId() + appAutoDataMessage.getDid() + appAutoDataMessage.getMsg().getClDid());
Object object = redisUtil.getObjectByKey(appAutoDataMessage.getId() + appAutoDataMessage.getDid() + appAutoDataMessage.getMsg().getClDid() + dataArrayParam.getStatMethod());
List<CsDataArray> dataArrayList;
if (Objects.isNull(object)){
dataArrayList = saveModelData(dataArrayParam);
@@ -168,29 +168,29 @@ public class StatServiceImpl implements IStatService {
}
}
}
redisUtil.saveByKeyWithExpire(AppRedisKey.LINE_POSITION+id,map,600L);
redisUtil.saveByKey(AppRedisKey.LINE_POSITION+id,map);
}
/**
* 缓存字典和influxDB表关系
*/
public void saveData() {
Map<String,String> map = new HashMap<>();
List<EpdDTO> list = epdFeignClient.findAll().getData();
if (CollectionUtil.isEmpty(list)){
throw new BusinessException(StatResponseEnum.DICT_NULL);
}
list.forEach(item->{
map.put(item.getDictName(),item.getTableName());
});
redisUtil.saveByKeyWithExpire(AppRedisKey.ELE_EPD_PQD,map,3600L);
}
// /**
// * 缓存字典和influxDB表关系
// */
// public void saveData() {
// Map<String,String> map = new HashMap<>();
// List<EpdDTO> list = epdFeignClient.findAll().getData();
// if (CollectionUtil.isEmpty(list)){
// throw new BusinessException(StatResponseEnum.DICT_NULL);
// }
// list.forEach(item->{
// map.put(item.getDictName(),item.getTableName());
// });
// redisUtil.saveByKeyWithExpire(AppRedisKey.ELE_EPD_PQD,map,3600L);
// }
/**
* 缓存设备模板信息
*/
public List<CsDataArray> saveModelData(DataArrayParam dataArrayParam) {
String key = dataArrayParam.getId() + dataArrayParam.getDid() + dataArrayParam.getCldId();
String key = dataArrayParam.getId() + dataArrayParam.getDid() + dataArrayParam.getCldId() + dataArrayParam.getStatMethod();
List<CsDataArray> dataArrayList = dataArrayFeignClient.findListByParam(dataArrayParam).getData();
if (CollectionUtil.isEmpty(dataArrayList)){
throw new BusinessException(StatResponseEnum.DATA_ARRAY_NULL);
@@ -214,10 +214,10 @@ public class StatServiceImpl implements IStatService {
if (!Objects.equals(dataArrayList.size(),floats.size())){
throw new BusinessException(StatResponseEnum.ARRAY_DATA_NOT_MATCH);
}
//判断字典数据是否存在
if (Objects.isNull(redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD))){
saveData();
}
// //判断字典数据是否存在
// if (Objects.isNull(redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD))){
// saveData();
// }
Map<String,String> map = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD)), Map.class);
for (int i = 0; i < dataArrayList.size(); i++) {
String tableName = map.get(dataArrayList.get(i).getName());

View File

@@ -0,0 +1,44 @@
package com.njcn.stat.service.impl;
import com.njcn.csdevice.api.EquipmentFeignClient;
import com.njcn.csdevice.api.WlRecordFeignClient;
import com.njcn.csdevice.pojo.po.CsEquipmentDeliveryPO;
import com.njcn.csdevice.pojo.po.WlRecord;
import com.njcn.mq.message.AppAutoDataMessage;
import com.njcn.stat.service.IWlRecordService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2023/8/14 9:32
*/
@Service
@Slf4j
@AllArgsConstructor
public class WlRecordServiceImpl implements IWlRecordService{
private final EquipmentFeignClient equipmentFeignClient;
private final WlRecordFeignClient wlRecordFeignClient;
@Override
public void addOrUpdateBaseData(AppAutoDataMessage appAutoDataMessage) {
WlRecord wlRecord = new WlRecord();
CsEquipmentDeliveryPO po = equipmentFeignClient.findDevByNDid(appAutoDataMessage.getId()).getData();
AppAutoDataMessage.DataArray dataArray = appAutoDataMessage.getMsg().getDataArray().get(0);
BeanUtils.copyProperties(dataArray, wlRecord);
wlRecord.setDevId(po.getId());
wlRecord.setLineId(po.getNdid() + appAutoDataMessage.getMsg().getClDid());
wlRecord.setGcDataPath(dataArray.getPrjDataPath());
if (dataArray.getPrjTimeEnd() == -1) {
wlRecord.setEndTime(null);
}
wlRecordFeignClient.addBaseData(wlRecord);
}
}

View File

@@ -43,21 +43,16 @@ public class RedisKeyExpirationListener extends KeyExpirationEventMessageListene
@Resource
private EpdFeignClient epdFeignClient;
@Resource
private RedisUtil redisUtil;
@Resource
private CsTopicFeignClient csTopicFeignClient;
@Resource
private MqttPublisher publisher;
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
/**
* 针对redis数据失效事件进行数据处理
* 注意message.toString()可以获取失效的key

View File

@@ -137,6 +137,10 @@ public class EventServiceImpl implements IEventService {
if (Objects.equals(param.getName(),ZlConstant.EVT_PARAM_TM)){
csEvent.setPersistTime(Double.parseDouble(param.getData().toString()));
}
lineId = appEventMessage.getId() + appEventMessage.getMsg().getClDid();
fields.put(param.getName(),appEventMessage.getMsg().getClDid()==1?"电网侧":"负载侧");
csEvent.setLocation(appEventMessage.getMsg().getClDid()==1?ZlConstant.GRID:ZlConstant.LOAD);
csEvent.setClDid(appEventMessage.getMsg().getClDid());
fields.put(param.getName(),param.getData());
}
//fixme 这边前置传递的应该是UTC时间,但是前置说是传递的北京时间,讨论了一下没太理解。这边暂时先这样处理,influx入库处理成北京时间,减去8小时。

View File

@@ -4,15 +4,14 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.alibaba.nacos.shaded.com.google.gson.GsonBuilder;
import com.github.tocrhz.mqtt.publisher.MqttPublisher;
import com.njcn.access.api.CsTopicFeignClient;
import com.njcn.access.enums.AccessEnum;
import com.njcn.access.enums.AccessResponseEnum;
import com.njcn.access.enums.TypeEnum;
import com.njcn.access.pojo.dto.ReqAndResDto;
import com.njcn.access.utils.CRC32Utils;
import com.njcn.common.config.GeneralInfo;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csharmonic.api.WavePicFeignClient;
@@ -41,7 +40,6 @@ import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* 类的介绍:
@@ -112,7 +110,7 @@ public class FileServiceImpl implements IFileService {
csWave.setStatus(0);
csWaveService.save(csWave);
//请求当前文件的数据
askFileStream(appFileMessage.getId(),mid,fileName,-1,range);
askFileStream(appFileMessage.getId(),mid,fileName,0,range);
redisUtil.saveByKey(AppRedisKey.RMQ_FILE_CONSUME_KEY.concat(fileInfoDto.getName()), fileInfoDto);
redisUtil.delete(AppRedisKey.TIME+fileName);
} else {
@@ -123,7 +121,7 @@ public class FileServiceImpl implements IFileService {
@Override
public void analysisFileStream(AppFileMessage appFileMessage) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
String filePath;
String filePath = null;
List<Integer> list = new ArrayList<>();
FileStreamDto fileStreamDto = new FileStreamDto();
//波形文件上传成功后,将文件信息存储一下,方便后期查看
@@ -138,18 +136,53 @@ public class FileServiceImpl implements IFileService {
try {
//todo 目前文件先只处理波形事件的,后续有其他文件再做处理
String fileName = appFileMessage.getMsg().getName();
//String lsFileName =fileName.split(StrUtil.SLASH)[fileName.split(StrUtil.SLASH).length - 1];
String lsFileName = generalInfo.getBusinessTempPath() + File.separator + fileName.split(StrUtil.SLASH)[fileName.split(StrUtil.SLASH).length - 1];
File lsFile =new File(generalInfo.getBusinessTempPath());
//如果文件夹不存在则创建
if (!lsFile.exists() && !lsFile.isDirectory()){
lsFile .mkdirs();
}
//获取缓存的文件信息
Object fileInfo = redisUtil.getObjectByKey(AppRedisKey.RMQ_FILE_CONSUME_KEY.concat(fileName));
FileInfoDto fileInfoDto = JSON.parseObject(JSON.toJSONString(fileInfo), FileInfoDto.class);
//1.判断当前文件是否之前缓存过,没缓存,则先缓存(这边缓存两条记录,一条是用来判断超时的,还有一条记录文件数据,文件数据目前没有过期时间,文件数据收完才会删除)
//2.缓存了判断收到的报文个数是否和总个数一致,一致则解析文件;不一致则更新缓存
//3.超时判断: 30s分钟未收到相关文件信息核查文件个数看丢失哪些帧重新请求
if(fileName.contains(".cfg") || fileName.contains(".dat")) {
if (Objects.isNull(fileInfoDto)) {
String fileCheck = redisUtil.getObjectByKey("fileCheck"+fileName).toString();
if (appFileMessage.getMsg().getFrameTotal() == 1){
//解析文件入库
filePath = fileStream(1,null,appFileMessage.getMsg().getData(),fileName,appFileMessage.getId());
filePath = fileStream(1,null,appFileMessage.getMsg().getData(),fileName,appFileMessage.getId(),fileCheck,"download");
} else {
//最后一帧
if (Objects.equals(appFileMessage.getMsg().getFrameTotal(), appFileMessage.getMsg().getFrameCurr())) {
Map<Integer, String> filePartMap = readFile(lsFileName);
filePartMap.put(appFileMessage.getMsg().getFrameCurr(), appFileMessage.getMsg().getData());
//解析文件
filePath = fileStream(appFileMessage.getMsg().getFrameTotal(), filePartMap, null, fileName, appFileMessage.getId(),fileCheck,"download");
//删除临时文件
File file = new File(lsFileName);
if (file.exists()) {
file.delete();
}
}
//中间帧
else {
Map<Integer, String> filePartMap = readFile(lsFileName);
if (Objects.isNull(filePartMap.get(appFileMessage.getMsg().getFrameCurr()))) {
appendFile(lsFileName,appFileMessage.getMsg().getFrameCurr(),appFileMessage.getMsg().getData());
}
}
}
if (!Objects.isNull(filePath)){
redisUtil.saveByKey("downloadFilePath:"+appFileMessage.getMsg().getName(),filePath);
}
}
//录波文件下载
//1.判断当前文件是否之前缓存过,没缓存,则先缓存(这边缓存两条记录,一条是用来判断超时的,还有一条记录文件数据,文件数据目前没有过期时间,文件数据收完才会删除)
//2.缓存了判断收到的报文个数是否和总个数一致,一致则解析文件;不一致则更新缓存
//3.超时判断: 30s未收到相关文件信息核查文件个数看丢失哪些帧重新请求
else {
if (appFileMessage.getMsg().getFrameTotal() == 1){
//解析文件入库
filePath = fileStream(1,null,appFileMessage.getMsg().getData(),fileName,appFileMessage.getId(),fileInfoDto.getFileCheck(),"event");
csEventLogs.setStatus(1);
csEventLogs.setRemark("当前文件1帧,全部收到,解析成功!");
csEventLogs.setNowStep(1);
@@ -178,7 +211,7 @@ public class FileServiceImpl implements IFileService {
csEventLogs.setNowStep(appFileMessage.getMsg().getFrameCurr());
csEventLogs.setAllStep(appFileMessage.getMsg().getFrameTotal());
csEventLogs.setIsAll(0);
redisUtil.saveByKeyWithExpire(AppRedisKey.FILE_PART_TIME.concat(appFileMessage.getMsg().getName()), null, 30L);
redisUtil.saveByKeyWithExpire(AppRedisKey.FILE_PART_TIME.concat(appFileMessage.getMsg().getName()), null, 5L);
redisUtil.saveByKey(AppRedisKey.FILE_PART.concat(appFileMessage.getMsg().getName()), fileStreamDto);
//将数据写入临时文件
appendFile(lsFileName,appFileMessage.getMsg().getFrameCurr(),appFileMessage.getMsg().getData());
@@ -192,7 +225,7 @@ public class FileServiceImpl implements IFileService {
Map<Integer, String> filePartMap = readFile(lsFileName);
filePartMap.put(appFileMessage.getMsg().getFrameCurr(), appFileMessage.getMsg().getData());
//解析文件
filePath = fileStream(appFileMessage.getMsg().getFrameTotal(), filePartMap, null, fileName, appFileMessage.getId());
filePath = fileStream(appFileMessage.getMsg().getFrameTotal(), filePartMap, null, fileName, appFileMessage.getId(),fileInfoDto.getFileCheck(),"event");
csEventLogs.setStatus(1);
csEventLogs.setRemark("当前文件" + appFileMessage.getMsg().getFrameTotal() + "帧,这是第" + appFileMessage.getMsg().getFrameCurr() + "帧,全部收到,解析成功!");
csEventLogs.setNowStep(appFileMessage.getMsg().getFrameCurr());
@@ -224,17 +257,21 @@ public class FileServiceImpl implements IFileService {
csEventLogs.setNowStep(appFileMessage.getMsg().getFrameCurr());
csEventLogs.setAllStep(appFileMessage.getMsg().getFrameTotal());
csEventLogs.setIsAll(0);
redisUtil.saveByKey(AppRedisKey.FILE_PART.concat(appFileMessage.getMsg().getName()), dto);
long time1 = System.currentTimeMillis();
//将数据写入临时文件
appendFile(lsFileName, appFileMessage.getMsg().getFrameCurr(), appFileMessage.getMsg().getData());
long time2 = System.currentTimeMillis();
System.out.println("time==:" + (time2 - time1));
log.info("当前文件 {} 帧,这是第 {} 帧报文,记录成功", appFileMessage.getMsg().getFrameTotal(), appFileMessage.getMsg().getFrameCurr());
if (Objects.isNull(object2)) {
redisUtil.saveByKeyWithExpire(AppRedisKey.FILE_PART_TIME.concat(appFileMessage.getMsg().getName()), null, 30L);
redisUtil.saveByKeyWithExpire(AppRedisKey.FILE_PART_TIME.concat(appFileMessage.getMsg().getName()), null, 10L);
} else {
redisUtil.saveByKeyWithExpire(AppRedisKey.FILE_PART_TIME.concat(appFileMessage.getMsg().getName()), null, 1L);
}
redisUtil.saveByKey(AppRedisKey.FILE_PART.concat(appFileMessage.getMsg().getName()), dto);
//将数据写入临时文件
appendFile(lsFileName, appFileMessage.getMsg().getFrameCurr(), appFileMessage.getMsg().getData());
log.info("当前文件 {} 帧,这是第 {} 帧报文,记录成功", appFileMessage.getMsg().getFrameTotal(), appFileMessage.getMsg().getFrameCurr());
}
} else {
redisUtil.saveByKeyWithExpire(AppRedisKey.FILE_PART_TIME.concat(appFileMessage.getMsg().getName()), null, 1L);
csEventLogs.setStatus(1);
csEventLogs.setRemark("当前文件为重复帧,这是第" + appFileMessage.getMsg().getFrameCurr() + "帧,不做记录!");
csEventLogs.setNowStep(appFileMessage.getMsg().getFrameCurr());
@@ -249,9 +286,6 @@ public class FileServiceImpl implements IFileService {
csEventLogs.setLocation(fileInfoDto.getLocation());
//记录日志
csEventLogsService.save(csEventLogs);
} else {
//todo 处理其他文件
log.info("暂未做其他文件处理");
}
} catch (Exception e){
csEventLogs.setStatus(0);
@@ -283,10 +317,10 @@ public class FileServiceImpl implements IFileService {
/**
* 组装文件
*/
public String fileStream(Integer number, Map<Integer,String> map, String data, String fileName, String nDid) {
public String fileStream(Integer number, Map<Integer,String> map, String data, String fileName, String nDid, String fileCheck,String type) {
String filePath;
if (number == 1){
filePath = stream(true,data,nDid,fileName,null);
filePath = stream(true,data,nDid,fileName,null,fileCheck,type);
} else {
int lengthByte = 0;
for (int i = 1; i <= number; i++) {
@@ -300,7 +334,7 @@ public class FileServiceImpl implements IFileService {
System.arraycopy(byteArray, 0, allByte, countLength, byteArray.length);
countLength += byteArray.length;
}
filePath = stream(false,null,nDid,fileName,allByte);
filePath = stream(false,null,nDid,fileName,allByte,fileCheck,type);
}
return filePath;
}
@@ -308,7 +342,8 @@ public class FileServiceImpl implements IFileService {
/**
* 解析存储文件信息
*/
public String stream(boolean bool, String stream, String folder, String fileName, byte[] bytes) {
public String stream(boolean bool, String stream, String folder, String fileName, byte[] bytes, String fileCheck, String type) {
String path;
byte[] byteArray = null;
//将文件后缀替换成大写
String[] parts = fileName.split(StrUtil.SLASH);
@@ -321,9 +356,18 @@ public class FileServiceImpl implements IFileService {
} else {
byteArray = bytes;
}
//todo 此处需要做文件crc校验或者md5校验目前不知道怎么处理先放一下
//文件校验
int crc = CRC32Utils.calculateCRC32(byteArray,byteArray.length,0xffffffff);
String hexString = String.format("%08X", crc);
if (!Objects.equals(hexString,fileCheck)) {
throw new BusinessException(AccessResponseEnum.FILE_CHECK_ERROR);
}
InputStream inputStream = new ByteArrayInputStream(byteArray);
String path = fileStorageUtil.uploadStreamSpecifyName(inputStream, OssPath.WAVE_DIR + folder + StrUtil.SLASH,fileName);
if (Objects.equals(type,"download")) {
path = fileStorageUtil.uploadStreamSpecifyName(inputStream, OssPath.DOWNLOAD_DIR + folder + StrUtil.SLASH,fileName);
} else {
path = fileStorageUtil.uploadStreamSpecifyName(inputStream, OssPath.WAVE_DIR + folder + StrUtil.SLASH,fileName);
}
try {
inputStream.close();
} catch (IOException e) {

View File

@@ -1,59 +0,0 @@
package com.njcn.zlevent.utils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.CRC32;
/**
* 类的介绍:用于文件校验
*
* @author xuyang
* @version 1.0.0
* @createTime 2023/9/8 13:32
*/
public class FileCheckUtils {
/**
* 32位CRC检验
* @param inputStream 文件流
* @return
* @throws IOException
*/
public static long calculateCRC32Checksum(InputStream inputStream) throws IOException {
CRC32 crc32 = new CRC32();
// 用于读取文件内容的缓冲区
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
crc32.update(buffer, 0, bytesRead);
}
return crc32.getValue();
}
/**
* MD5检验
* @param inputStream 文件流
* @return
* @throws IOException
*/
public static String calculateMD5Checksum(InputStream inputStream) throws IOException, NoSuchAlgorithmException {
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 用于读取文件内容的缓冲区
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
md5.update(buffer, 0, bytesRead);
}
byte[] digest = md5.digest();
// 将MD5摘要转换为十六进制字符串
StringBuilder md5Checksum = new StringBuilder();
for (byte b : digest) {
md5Checksum.append(String.format("%02x", b));
}
return md5Checksum.toString();
}
}

View File

@@ -18,7 +18,6 @@ import com.njcn.user.pojo.po.app.AppInfoSet;
import com.njcn.zlevent.pojo.dto.NoticeUserDto;
import com.njcn.zlevent.service.ICsEventUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -32,7 +31,6 @@ import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;