fix:仿真参数库对象,支持不传文件

This commit is contained in:
2026-02-28 16:18:17 +08:00
parent f9e3c145b3
commit 6c540ea853
3 changed files with 104 additions and 139 deletions

View File

@@ -9,7 +9,7 @@ public class SimulationParameterItem {
private String parameterName;
@Schema(description = "参数值")
private Object parameterValue;
private String parameterValue;
@Schema(description = "单位")
private String unit;
@@ -17,9 +17,12 @@ public class SimulationParameterItem {
@Schema(description = "描述")
private String description;
@Schema(description = "创建人")
@Schema(description = "创建人ID")
private String creatorId;
@Schema(description = "创建人名称")
private String createName;
@Schema(description = "创建时间")
private String createTime;
}

View File

@@ -11,12 +11,12 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.sdm.data.model.req.SimulationParameterItem;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
@@ -52,6 +52,5 @@ public class SimulationParameterLibraryCategoryObjectResp {
private String creatorName;
// 参数文件JSON存储的数据
private List<Map<String, Object>> parameterJsonValue = new ArrayList<>();
private List<SimulationParameterItem> parameterJsonValue = new ArrayList<>();
}

View File

@@ -5,7 +5,8 @@ import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.core.type.TypeReference;
import com.sdm.data.model.req.SimulationParameterItem;
import com.sdm.common.common.SdmResponse;
import com.sdm.common.common.ThreadLocalContext;
import com.sdm.common.entity.enums.ApprovalFileDataStatusEnum;
@@ -43,6 +44,7 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
@@ -96,29 +98,50 @@ public class SimulationParameterLibraryServiceImpl extends ServiceImpl<Simulatio
return SdmResponse.success("仿真参数库分类添加成功");
}
/**
* 新增参数库分类对象,并处理文件上传和审批流程.
* <p>
* 如果请求中没有提供文件本方法会自动创建一个以参数对象名命名的空JSON文件。
* 如果提供了文件则会向文件内容中添加创建者ID和创建时间信息。
* 文件上传后,会保存分类对象元数据,并根据模板发起一个审批流程。
*
* @param req 包含参数库分类对象信息和可选文件的请求对象
* @return SdmResponse 包含操作结果的响应实体
*/
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse addLibraryCategoryObject(SimulationParameterLibraryCategoryObjectReq req) {
try {
// 添加创建人和创建时间
String originalJson = new String(req.getFile().getBytes(), StandardCharsets.UTF_8);
MultipartFile inputFile = req.getFile();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(originalJson);
List<Map<String, Object>> parameterJsonValueFromJsonNode = parseJsonArray(jsonNode);
if (!CollectionUtils.isEmpty(parameterJsonValueFromJsonNode)) {
parameterJsonValueFromJsonNode.forEach(map -> {
map.put("creatorId", ThreadLocalContext.getUserId());
map.put("createTime", DateUtils.format(new Date(), DateUtils.PATTERN_DEFAULT));
});
}
String content = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(parameterJsonValueFromJsonNode);
MultipartFile file = new MockMultipartFile(req.getFileName(), req.getFile().getOriginalFilename(), req.getFile().getContentType(), content.getBytes(StandardCharsets.UTF_8));
SdmResponse<Long> integerSdmResponse = dataFileService.uploadSimulationParamFile(file);
Long fileId = integerSdmResponse.getData();
MultipartFile fileToUpload;
SimulationParameterLibraryCategoryObject simulationParameterLibraryCategoryObject = new SimulationParameterLibraryCategoryObject();
BeanUtils.copyProperties(req, simulationParameterLibraryCategoryObject);
// 兼容未上传文件的情况自动创建空JSON文件
if (inputFile == null || inputFile.isEmpty()) {
String fileName = req.getParameterLibraryCategoryObjectName();
String emptyJsonContent = "[]";
fileToUpload = new MockMultipartFile(fileName, fileName + ".json", "application/json", emptyJsonContent.getBytes(StandardCharsets.UTF_8));
simulationParameterLibraryCategoryObject.setFileName(fileName+ ".json");
} else {
// 处理已上传的文件,并添加创建人、创建时间等信息
String originalJson = new String(inputFile.getBytes(), StandardCharsets.UTF_8);
List<SimulationParameterItem> parameterDataList = objectMapper.readValue(originalJson, new TypeReference<>() {});
if (!CollectionUtils.isEmpty(parameterDataList)) {
parameterDataList.forEach(pd -> {
pd.setCreatorId(String.valueOf(ThreadLocalContext.getUserId()));
pd.setCreateTime(DateUtils.format(new Date(), DateUtils.PATTERN_DEFAULT));
});
}
String content = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(parameterDataList);
fileToUpload = new MockMultipartFile(req.getFileName(), inputFile.getOriginalFilename(), inputFile.getContentType(), content.getBytes(StandardCharsets.UTF_8));
}
SdmResponse<Long> integerSdmResponse = dataFileService.uploadSimulationParamFile(fileToUpload);
Long fileId = integerSdmResponse.getData();
simulationParameterLibraryCategoryObject.setFileId(fileId);
simulationParameterLibraryCategoryObject.setCreatorId(ThreadLocalContext.getUserId());
simulationParameterLibraryCategoryObjectService.save(simulationParameterLibraryCategoryObject);
@@ -345,144 +368,84 @@ public class SimulationParameterLibraryServiceImpl extends ServiceImpl<Simulatio
private SimulationParameterLibraryCategoryObjectResp getSimulationParameterLibraryCategoryObjectInner(Long ObjectId) {
SimulationParameterLibraryCategoryObject simulationParameterLibraryCategoryObject = simulationParameterLibraryCategoryObjectService.getById(ObjectId);
SimulationParameterLibraryCategoryObjectResp simulationParameterLibraryCategoryObjectResp = new SimulationParameterLibraryCategoryObjectResp();
SimulationParameterLibraryCategoryObjectResp resp = new SimulationParameterLibraryCategoryObjectResp();
BeanUtils.copyProperties(simulationParameterLibraryCategoryObject, resp);
// 使用Jackson解析JSON
try {
InputStream minioInputStream = dataFileService.getMinioInputStream(simulationParameterLibraryCategoryObject.getFileId());
try (InputStream minioInputStream = dataFileService.getMinioInputStream(simulationParameterLibraryCategoryObject.getFileId())) {
if (ObjectUtils.isNotEmpty(minioInputStream)) {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(minioInputStream);
List<Map<String, Object>> parameterJsonValueFromJsonNode = parseJsonArray(jsonNode);
if (!CollectionUtils.isEmpty(parameterJsonValueFromJsonNode)) {
// 将 List<Long> userIds 转成set
Set<Long> userIdsSet = new HashSet<>();
for (Map<String, Object> map : parameterJsonValueFromJsonNode) {
userIdsSet.add(Long.valueOf((String) map.get("creatorId")));
}
Map<Long, String> longStringMap = userNameCacheService.batchGetUserNames(userIdsSet);
for (Map<String, Object> map : parameterJsonValueFromJsonNode) {
map.put("createName", longStringMap.get(Long.valueOf((String) map.get("creatorId"))));
simulationParameterLibraryCategoryObjectResp.setCreateTime(simulationParameterLibraryCategoryObject.getCreateTime());
}
// 使用泛型反序列化为强类型列表
List<SimulationParameterItem> parameterItemList = objectMapper.readValue(minioInputStream, new TypeReference<List<SimulationParameterItem>>() {});
if (!CollectionUtils.isEmpty(parameterItemList)) {
// 提取创建者ID并批量获取用户名
Set<Long> userIds = parameterItemList.stream()
.map(item -> Long.valueOf(item.getCreatorId()))
.collect(Collectors.toSet());
Map<Long, String> userNamesMap = userNameCacheService.batchGetUserNames(userIds);
// 将用户名填充回对象列表
parameterItemList.forEach(item -> item.setCreateName(userNamesMap.get(Long.valueOf(item.getCreatorId()))));
resp.setParameterJsonValue(parameterItemList);
// 设置创建时间为对象的创建时间
resp.setCreateTime(simulationParameterLibraryCategoryObject.getCreateTime());
} else {
resp.setParameterJsonValue(Collections.emptyList());
}
simulationParameterLibraryCategoryObjectResp.setParameterJsonValue(parameterJsonValueFromJsonNode);
} else {
// 兜底操作可能是清库了或者数据被删除了删除掉参数对象的json文件信息
simulationParameterLibraryCategoryObject.setFileId(null);
simulationParameterLibraryCategoryObject.setFileName(null);
simulationParameterLibraryCategoryObjectService.updateById(simulationParameterLibraryCategoryObject);
log.info("参数对象json文件信息被删除了请检查参数对象ID为{}的参数对象信息", ObjectId);
// 文件流为空的兜底操作
handleMissingFile(simulationParameterLibraryCategoryObject);
log.info("参数对象关联的文件流为空请检查文件ID{}", simulationParameterLibraryCategoryObject.getFileId());
}
BeanUtils.copyProperties(simulationParameterLibraryCategoryObject, simulationParameterLibraryCategoryObjectResp);
SimulationParameterLibraryCategory simulationParameterLibraryCategory = simulationParameterLibraryCategoryService.getById(simulationParameterLibraryCategoryObject.getParameterLibraryCategoryId());
SimulationParameterLibrary simulationParameterLibrary = this.getById(simulationParameterLibraryCategory.getParameterLibraryId());
simulationParameterLibraryCategoryObjectResp.setParameterLibraryId(simulationParameterLibrary.getId());
simulationParameterLibraryCategoryObjectResp.setParameterLibraryName(simulationParameterLibrary.getParameterLibraryName());
simulationParameterLibraryCategoryObjectResp.setParameterLibraryCategoryId(simulationParameterLibraryCategory.getId());
simulationParameterLibraryCategoryObjectResp.setParameterLibraryCategoryName(simulationParameterLibraryCategory.getParameterLibraryCategoryName());
Long creatorId = simulationParameterLibraryCategoryObject.getCreatorId();
// 将 List<Long> userIds 转成set
Set<Long> userIdsSet = new HashSet<>();
userIdsSet.add(creatorId);
Map<Long, String> longStringMap = userNameCacheService.batchGetUserNames(userIdsSet);
simulationParameterLibraryCategoryObjectResp.setCreatorName(longStringMap.get(creatorId));
simulationParameterLibraryCategoryObjectResp.setCreateTime(simulationParameterLibraryCategoryObject.getCreateTime());
FileMetadataInfo fileMetadataInfo = fileMetadataInfoService.getById(simulationParameterLibraryCategoryObject.getFileId());
simulationParameterLibraryCategoryObjectResp.setApproveType(fileMetadataInfo.getApproveType());
// 填充其他关联信息
populateAdditionalInfo(resp, simulationParameterLibraryCategoryObject);
} catch (Exception e) {
log.error("解析JSON文件时发生错误", e);
log.error("解析JSON文件或获取关联信息时发生错误对象ID: {}", ObjectId, e);
// 发生异常时,确保返回基础信息
handleMissingFile(simulationParameterLibraryCategoryObject);
}
return simulationParameterLibraryCategoryObjectResp;
return resp;
}
/**
* 解析JSON数组返回包含多个Map的List
* 每个Map对应数组中的一个对象键为属性名值为自动识别类型后的属性值
* 填充分类对象响应中的附加信息.
*
* @param jsonNode 从MinIO获取的JsonNode
* @return 解析后的List<Map<String, Object>>
* @param resp 需要填充的响应对象
* @param simulationParameterLibraryCategoryObject 数据源对象
*/
public List<Map<String, Object>> parseJsonArray(JsonNode jsonNode) {
List<Map<String, Object>> resultList = new ArrayList<>();
private void populateAdditionalInfo(SimulationParameterLibraryCategoryObjectResp resp, SimulationParameterLibraryCategoryObject simulationParameterLibraryCategoryObject) {
SimulationParameterLibraryCategory category = simulationParameterLibraryCategoryService.getById(simulationParameterLibraryCategoryObject.getParameterLibraryCategoryId());
SimulationParameterLibrary library = this.getById(category.getParameterLibraryId());
// 检查是否为有效的JSON数组
if (jsonNode == null || !jsonNode.isArray()) {
return resultList;
resp.setParameterLibraryId(library.getId());
resp.setParameterLibraryName(library.getParameterLibraryName());
resp.setParameterLibraryCategoryId(category.getId());
resp.setParameterLibraryCategoryName(category.getParameterLibraryCategoryName());
Long creatorId = simulationParameterLibraryCategoryObject.getCreatorId();
Map<Long, String> creatorNameMap = userNameCacheService.batchGetUserNames(Collections.singleton(creatorId));
resp.setCreatorName(creatorNameMap.get(creatorId));
resp.setCreateTime(simulationParameterLibraryCategoryObject.getCreateTime());
FileMetadataInfo fileMetadataInfo = fileMetadataInfoService.getById(simulationParameterLibraryCategoryObject.getFileId());
if (fileMetadataInfo != null) {
resp.setApproveType(fileMetadataInfo.getApproveType());
}
// 遍历数组中的每个对象
for (JsonNode objectNode : jsonNode) {
if (objectNode.isObject()) {
// 解析单个对象为Map
Map<String, Object> objectMap = parseJsonObject(objectNode);
resultList.add(objectMap);
}
}
return resultList;
}
/**
* 解析单个JSON对象为Map自动识别值的类型
* 处理文件丢失或无法访问的情况.
*
* @param object 需要处理的参数库对象
*/
private Map<String, Object> parseJsonObject(JsonNode objectNode) {
Map<String, Object> resultMap = new HashMap<>();
Iterator<Map.Entry<String, JsonNode>> fields = objectNode.fields();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> entry = fields.next();
String key = entry.getKey();
JsonNode valueNode = entry.getValue();
// 根据节点类型获取对应Java类型的值
Object value = getValueByNodeType(valueNode);
resultMap.put(key, value);
}
return resultMap;
}
/**
* 根据JsonNode类型获取对应Java类型的值
*/
private Object getValueByNodeType(JsonNode node) {
if (node.isNull()) {
return null;
} else if (node.isBoolean()) {
return node.asBoolean();
} else if (node.isInt()) {
return node.asInt();
} else if (node.isLong()) {
return node.asLong();
} else if (node.isDouble() || node.isFloat()) {
return node.asDouble();
} else if (node.isTextual()) {
return node.asText();
} else if (node.isArray()) {
// 如果值是数组,递归解析
List<Object> arrayList = new ArrayList<>();
for (JsonNode element : node) {
arrayList.add(getValueByNodeType(element));
}
return arrayList;
} else if (node.isObject()) {
// 如果值是对象,递归解析
return parseJsonObject(node);
} else {
// 其他未明确类型,转为字符串
return node.toString();
}
private void handleMissingFile(SimulationParameterLibraryCategoryObject object) {
object.setFileId(null);
object.setFileName(null);
simulationParameterLibraryCategoryObjectService.updateById(object);
log.info("参数对象ID为: {} 的文件信息已被清除,因文件无法访问。", object.getId());
}
/**