根据设备类型删除临界数据,bug修改
This commit is contained in:
parent
6a27d4d7d0
commit
8d2e7e1cee
@ -272,7 +272,7 @@ public class SimBuilder {
|
|||||||
// 简化起见,假设 Event 表中 device_id 有值,或者我们在 buildEvents 时传入 devToMat 映射关系?
|
// 简化起见,假设 Event 表中 device_id 有值,或者我们在 buildEvents 时传入 devToMat 映射关系?
|
||||||
// Event 表有 device_id 字段,可以直接用。
|
// Event 表有 device_id 字段,可以直接用。
|
||||||
if ("material".equals(entityType)) {
|
if ("material".equals(entityType)) {
|
||||||
if (ev.getDeviceId() != null) targetUnitId = ev.getDeviceId();
|
if (ev.getDeviceId() != null && !ev.getDeviceId().isBlank()) targetUnitId = ev.getDeviceId().trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
SimPropertyKey key = SimPropertyKey.of(targetUnitId, property);
|
SimPropertyKey key = SimPropertyKey.of(targetUnitId, property);
|
||||||
|
|||||||
@ -113,6 +113,26 @@ public class CriticalDataController {
|
|||||||
return criticalDataService.removeByIds(ids);
|
return criticalDataService.removeByIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('criticalData:del')")
|
||||||
|
@Log(value = "按设备类型清空临界数据", module = "临界数据管理")
|
||||||
|
@DeleteMapping("/by-device-type")
|
||||||
|
public ResponseEntity<Map<String, Object>> deleteByDeviceType(@RequestParam String deviceType,
|
||||||
|
@RequestParam(defaultValue = "false") boolean confirm) {
|
||||||
|
if (deviceType == null || deviceType.isBlank()) {
|
||||||
|
return ResponseEntity.badRequest().body(Map.of("code", 1, "msg", "deviceType不能为空"));
|
||||||
|
}
|
||||||
|
if (!confirm) {
|
||||||
|
return ResponseEntity.badRequest().body(Map.of("code", 1, "msg", "请确认删除:confirm=true"));
|
||||||
|
}
|
||||||
|
String dt = deviceType.trim();
|
||||||
|
int deleted = criticalDataService.deleteByDeviceType(dt);
|
||||||
|
return ResponseEntity.ok(Map.of(
|
||||||
|
"code", 0,
|
||||||
|
"msg", "清空成功",
|
||||||
|
"data", Map.of("deviceType", dt, "deleted", deleted)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 4. 导入临界数据(Excel)
|
* 4. 导入临界数据(Excel)
|
||||||
* 输入参数:表单文件字段 file
|
* 输入参数:表单文件字段 file
|
||||||
|
|||||||
@ -56,6 +56,8 @@ public class EventController {
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseEntity<Map<String, Object>> addEvent(@RequestBody Event event) {
|
public ResponseEntity<Map<String, Object>> addEvent(@RequestBody Event event) {
|
||||||
assertCanWriteByScenarioId(event.getScenarioId());
|
assertCanWriteByScenarioId(event.getScenarioId());
|
||||||
|
event.setDeviceId(normalizeBlankToNull(event.getDeviceId()));
|
||||||
|
event.setMaterialId(normalizeBlankToNull(event.getMaterialId()));
|
||||||
event.setModifier(currentUsername());
|
event.setModifier(currentUsername());
|
||||||
eventService.save(event);
|
eventService.save(event);
|
||||||
Event savedEvent = event;
|
Event savedEvent = event;
|
||||||
@ -89,6 +91,8 @@ public class EventController {
|
|||||||
}
|
}
|
||||||
assertCanWriteByScenarioId(db.getScenarioId());
|
assertCanWriteByScenarioId(db.getScenarioId());
|
||||||
}
|
}
|
||||||
|
event.setDeviceId(normalizeBlankToNull(event.getDeviceId()));
|
||||||
|
event.setMaterialId(normalizeBlankToNull(event.getMaterialId()));
|
||||||
event.setModifier(currentUsername());
|
event.setModifier(currentUsername());
|
||||||
event.setUpdatedAt(LocalDateTime.now());
|
event.setUpdatedAt(LocalDateTime.now());
|
||||||
return eventService.updateById(event);
|
return eventService.updateById(event);
|
||||||
@ -133,12 +137,16 @@ public class EventController {
|
|||||||
}
|
}
|
||||||
if (event.getEventId() != null && !event.getEventId().isBlank() && exists != null) {
|
if (event.getEventId() != null && !event.getEventId().isBlank() && exists != null) {
|
||||||
// 更新逻辑
|
// 更新逻辑
|
||||||
|
event.setDeviceId(normalizeBlankToNull(event.getDeviceId()));
|
||||||
|
event.setMaterialId(normalizeBlankToNull(event.getMaterialId()));
|
||||||
event.setModifier(currentUser);
|
event.setModifier(currentUser);
|
||||||
event.setUpdatedAt(now);
|
event.setUpdatedAt(now);
|
||||||
eventService.updateById(event);
|
eventService.updateById(event);
|
||||||
savedEvents.add(event);
|
savedEvents.add(event);
|
||||||
} else {
|
} else {
|
||||||
// 新增逻辑
|
// 新增逻辑
|
||||||
|
event.setDeviceId(normalizeBlankToNull(event.getDeviceId()));
|
||||||
|
event.setMaterialId(normalizeBlankToNull(event.getMaterialId()));
|
||||||
event.setCreatedAt(now);
|
event.setCreatedAt(now);
|
||||||
event.setModifier(currentUser);
|
event.setModifier(currentUser);
|
||||||
event.setUpdatedAt(now);
|
event.setUpdatedAt(now);
|
||||||
@ -440,6 +448,12 @@ public class EventController {
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String normalizeBlankToNull(String s) {
|
||||||
|
if (s == null) return null;
|
||||||
|
String v = s.trim();
|
||||||
|
return v.isEmpty() ? null : v;
|
||||||
|
}
|
||||||
|
|
||||||
private void assertCanReadByScenarioId(String scenarioId) {
|
private void assertCanReadByScenarioId(String scenarioId) {
|
||||||
if (scenarioId == null || scenarioId.isBlank()) {
|
if (scenarioId == null || scenarioId.isBlank()) {
|
||||||
throw new RuntimeException("scenarioId不能为空");
|
throw new RuntimeException("scenarioId不能为空");
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.yfd.business.css.controller;
|
package com.yfd.business.css.controller;
|
||||||
|
|
||||||
import com.yfd.business.css.build.SimBuilder;
|
import com.yfd.business.css.build.SimBuilder;
|
||||||
|
import com.yfd.business.css.domain.Event;
|
||||||
import com.yfd.business.css.domain.Scenario;
|
import com.yfd.business.css.domain.Scenario;
|
||||||
import com.yfd.business.css.domain.ScenarioResult;
|
import com.yfd.business.css.domain.ScenarioResult;
|
||||||
import com.yfd.business.css.facade.SimDataFacade;
|
import com.yfd.business.css.facade.SimDataFacade;
|
||||||
@ -12,6 +13,7 @@ import com.yfd.business.css.service.SimService;
|
|||||||
import com.yfd.business.css.service.SimInferService;
|
import com.yfd.business.css.service.SimInferService;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.config.ResponseResult;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
@ -39,6 +41,9 @@ public class SimController {
|
|||||||
@Autowired private ScenarioResultService scenarioResultService;
|
@Autowired private ScenarioResultService scenarioResultService;
|
||||||
@Autowired private ObjectMapper objectMapper;
|
@Autowired private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
private static final int DEFAULT_STEPS = 10;
|
||||||
|
private static final int MAX_STEPS = 10000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行仿真计算
|
* 执行仿真计算
|
||||||
*
|
*
|
||||||
@ -50,7 +55,7 @@ public class SimController {
|
|||||||
public ResponseResult run(@RequestBody Map<String, Object> req) {
|
public ResponseResult run(@RequestBody Map<String, Object> req) {
|
||||||
String projectId = (String) req.get("projectId");
|
String projectId = (String) req.get("projectId");
|
||||||
String scenarioId = (String) req.get("scenarioId");
|
String scenarioId = (String) req.get("scenarioId");
|
||||||
int steps = req.containsKey("steps") ? (int) req.get("steps") : 10;
|
Integer requestedSteps = parseSteps(req.get("steps"));
|
||||||
boolean clearResult = Boolean.TRUE.equals(req.get("clearResult"));
|
boolean clearResult = Boolean.TRUE.equals(req.get("clearResult"));
|
||||||
|
|
||||||
Scenario sc = scenarioService.getById(scenarioId);
|
Scenario sc = scenarioService.getById(scenarioId);
|
||||||
@ -77,6 +82,8 @@ public class SimController {
|
|||||||
// 1. Load Data: 获取项目、设备和事件数据
|
// 1. Load Data: 获取项目、设备和事件数据
|
||||||
SimDataPackage data = simDataFacade.loadSimulationData(projectId, scenarioId);
|
SimDataPackage data = simDataFacade.loadSimulationData(projectId, scenarioId);
|
||||||
|
|
||||||
|
int steps = resolveSteps(requestedSteps, data.getEvents());
|
||||||
|
|
||||||
// 2. Build Model: 将原始数据转换为仿真模型 (Units, Events, Nodes)
|
// 2. Build Model: 将原始数据转换为仿真模型 (Units, Events, Nodes)
|
||||||
List<SimUnit> units = simBuilder.buildUnits(data, materialService);
|
List<SimUnit> units = simBuilder.buildUnits(data, materialService);
|
||||||
List<SimEvent> events = simBuilder.buildEvents(data.getEvents());
|
List<SimEvent> events = simBuilder.buildEvents(data.getEvents());
|
||||||
@ -90,6 +97,7 @@ public class SimController {
|
|||||||
|
|
||||||
// 6. Convert Result: 将仿真结果转换为前端友好的格式,包含静态属性补全和元数据
|
// 6. Convert Result: 将仿真结果转换为前端友好的格式,包含静态属性补全和元数据
|
||||||
Map<String, Object> resultData = SimResultConverter.toFrames(ctx, units, projectId, scenarioId);
|
Map<String, Object> resultData = SimResultConverter.toFrames(ctx, units, projectId, scenarioId);
|
||||||
|
resultData.put("steps", steps);
|
||||||
|
|
||||||
// 为了让前端明确感知推理是否启动成功,这里增加一个状态提示
|
// 为了让前端明确感知推理是否启动成功,这里增加一个状态提示
|
||||||
// 但因为是异步的,我们只能保证“已提交”。真正的成败由 asyncInferAndSave 决定。
|
// 但因为是异步的,我们只能保证“已提交”。真正的成败由 asyncInferAndSave 决定。
|
||||||
@ -118,6 +126,58 @@ public class SimController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int resolveSteps(Integer requestedSteps, List<Event> events) {
|
||||||
|
int steps;
|
||||||
|
if (requestedSteps != null) {
|
||||||
|
steps = requestedSteps;
|
||||||
|
} else {
|
||||||
|
int derived = deriveStepsFromEvents(events);
|
||||||
|
steps = Math.max(DEFAULT_STEPS, derived);
|
||||||
|
}
|
||||||
|
if (steps < 0) steps = DEFAULT_STEPS;
|
||||||
|
if (steps > MAX_STEPS) steps = MAX_STEPS;
|
||||||
|
return steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer parseSteps(Object raw) {
|
||||||
|
if (raw == null) return null;
|
||||||
|
if (raw instanceof Number n) return n.intValue();
|
||||||
|
String s = String.valueOf(raw).trim();
|
||||||
|
if (s.isEmpty()) return null;
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(s);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int deriveStepsFromEvents(List<Event> events) {
|
||||||
|
if (events == null || events.isEmpty()) return 0;
|
||||||
|
double maxT = 0.0;
|
||||||
|
for (Event ev : events) {
|
||||||
|
String json = ev.getAttrChanges();
|
||||||
|
if (json == null || json.isBlank()) continue;
|
||||||
|
double base = ev.getTriggerTime() == null ? 0.0 : ev.getTriggerTime();
|
||||||
|
try {
|
||||||
|
JsonNode root = objectMapper.readTree(json);
|
||||||
|
JsonNode segments = root.path("segments");
|
||||||
|
if (!segments.isArray()) continue;
|
||||||
|
for (JsonNode seg : segments) {
|
||||||
|
JsonNode timeline = seg.path("timeline");
|
||||||
|
if (!timeline.isArray()) continue;
|
||||||
|
for (JsonNode p : timeline) {
|
||||||
|
double t = p.path("t").asDouble(Double.NaN);
|
||||||
|
if (!Double.isFinite(t)) continue;
|
||||||
|
maxT = Math.max(maxT, base + t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxT <= 0) return 0;
|
||||||
|
return (int) Math.ceil(maxT);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateScenarioStatus(String scenarioId, String status, String failDetail) {
|
private void updateScenarioStatus(String scenarioId, String status, String failDetail) {
|
||||||
try {
|
try {
|
||||||
Scenario scenario = new Scenario();
|
Scenario scenario = new Scenario();
|
||||||
|
|||||||
@ -20,4 +20,6 @@ public interface CriticalDataService extends IService<CriticalData> {
|
|||||||
|
|
||||||
byte[] templateCriticalDataV2(String deviceType);
|
byte[] templateCriticalDataV2(String deviceType);
|
||||||
|
|
||||||
|
int deleteByDeviceType(String deviceType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.yfd.business.css.service.impl;
|
package com.yfd.business.css.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.yfd.business.css.domain.CriticalData;
|
import com.yfd.business.css.domain.CriticalData;
|
||||||
import com.yfd.business.css.mapper.CriticalDataMapper;
|
import com.yfd.business.css.mapper.CriticalDataMapper;
|
||||||
@ -143,6 +144,13 @@ public class CriticalDataServiceImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int deleteByDeviceType(String deviceType) {
|
||||||
|
if (deviceType == null || deviceType.isBlank()) return 0;
|
||||||
|
String dt = deviceType.trim();
|
||||||
|
return this.baseMapper.delete(new QueryWrapper<CriticalData>().eq("device_type", dt));
|
||||||
|
}
|
||||||
|
|
||||||
private boolean importExcel(Workbook workbook, String deviceType) {
|
private boolean importExcel(Workbook workbook, String deviceType) {
|
||||||
try (Workbook wb = workbook) {
|
try (Workbook wb = workbook) {
|
||||||
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
|
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
|
||||||
|
|||||||
@ -1576,8 +1576,8 @@ public class ProjectServiceImpl
|
|||||||
Event ev = new Event();
|
Event ev = new Event();
|
||||||
ev.setEventId(eventId);
|
ev.setEventId(eventId);
|
||||||
ev.setScenarioId(cell(df, r, eh.get("scenario_id")));
|
ev.setScenarioId(cell(df, r, eh.get("scenario_id")));
|
||||||
ev.setDeviceId(cell(df, r, eh.get("device_id")));
|
ev.setDeviceId(normalizeJsonText(cell(df, r, eh.get("device_id"))));
|
||||||
ev.setMaterialId(cell(df, r, eh.get("material_id")));
|
ev.setMaterialId(normalizeJsonText(cell(df, r, eh.get("material_id"))));
|
||||||
ev.setTriggerTime(parseDoubleObj(cell(df, r, eh.get("trigger_time"))));
|
ev.setTriggerTime(parseDoubleObj(cell(df, r, eh.get("trigger_time"))));
|
||||||
ev.setAttrChanges(normalizeJsonText(cell(df, r, eh.get("attr_changes"))));
|
ev.setAttrChanges(normalizeJsonText(cell(df, r, eh.get("attr_changes"))));
|
||||||
ev.setModifier(cell(df, r, eh.get("modifier")));
|
ev.setModifier(cell(df, r, eh.get("modifier")));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user