Merge branch 'develop-business-css' of http://121.37.111.42:3000/ThbTech/JavaProjectRepo into develop-business-css
This commit is contained in:
commit
4aca24a8c1
@ -1,23 +1,30 @@
|
||||
package com.yfd.business.css.config;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.ibatis.plugin.Interceptor;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
public class MybatisConfig {
|
||||
|
||||
@Resource
|
||||
private MybatisPlusInterceptor mybatisPlusInterceptor;
|
||||
|
||||
@Bean
|
||||
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
|
||||
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
|
||||
factoryBean.setDataSource(dataSource);
|
||||
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
|
||||
.getResources("classpath*:/mapper/**/*.xml"));
|
||||
factoryBean.setPlugins(new Interceptor[]{ mybatisPlusInterceptor });
|
||||
return factoryBean.getObject();
|
||||
}
|
||||
|
||||
|
||||
@ -66,20 +66,13 @@ public class AlgorithmController {
|
||||
public Page<Algorithm> searchAlgorithms(@RequestParam(required = false) String name,
|
||||
@RequestParam(defaultValue = "1") long pageNum,
|
||||
@RequestParam(defaultValue = "20") long pageSize) {
|
||||
long offset = Math.max(0, (pageNum - 1) * pageSize);
|
||||
QueryWrapper<Algorithm> qw = new QueryWrapper<>();
|
||||
if (name != null && !name.isEmpty()) {
|
||||
qw.like("name", name);
|
||||
}
|
||||
qw.orderByDesc("updated_at").last("LIMIT " + offset + "," + pageSize);
|
||||
java.util.List<Algorithm> records = algorithmService.list(qw);
|
||||
long total = (name != null && !name.isEmpty())
|
||||
? algorithmService.count(new QueryWrapper<Algorithm>().like("name", name))
|
||||
: algorithmService.count();
|
||||
qw.orderByDesc("updated_at");
|
||||
Page<Algorithm> page = new Page<>(pageNum, pageSize, true);
|
||||
page.setRecords(records);
|
||||
page.setTotal(total);
|
||||
return page;
|
||||
return algorithmService.page(page, qw);
|
||||
}
|
||||
|
||||
private String currentUsername() {
|
||||
|
||||
@ -76,8 +76,9 @@ public class CriticalDataController {
|
||||
* @return 是否导入成功
|
||||
*/
|
||||
@PostMapping("/import")
|
||||
public boolean importCriticalData(@RequestParam("file") MultipartFile file) {
|
||||
return criticalDataService.importCriticalData(file);
|
||||
public boolean importCriticalData(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam String deviceType) {
|
||||
return criticalDataService.importCriticalData(file, deviceType);
|
||||
}
|
||||
|
||||
|
||||
@ -95,16 +96,10 @@ public class CriticalDataController {
|
||||
public Page<CriticalData> listByDeviceType(@RequestParam String deviceType,
|
||||
@RequestParam(defaultValue = "1") long pageNum,
|
||||
@RequestParam(defaultValue = "20") long pageSize) {
|
||||
long offset = Math.max(0, (pageNum - 1) * pageSize);
|
||||
Page<CriticalData> page = new Page<>(pageNum, pageSize, true);
|
||||
QueryWrapper<CriticalData> qw = new QueryWrapper<CriticalData>()
|
||||
.eq("device_type", deviceType)
|
||||
.orderByDesc("created_at")
|
||||
.last("LIMIT " + offset + "," + pageSize);
|
||||
java.util.List<CriticalData> records = criticalDataService.list(qw);
|
||||
long total = criticalDataService.count(new QueryWrapper<CriticalData>().eq("device_type", deviceType));
|
||||
Page<CriticalData> page = new Page<>(pageNum, pageSize, true);
|
||||
page.setRecords(records);
|
||||
page.setTotal(total);
|
||||
return page;
|
||||
.orderByDesc("created_at");
|
||||
return criticalDataService.page(page, qw);
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,8 +85,9 @@ public class DeviceController {
|
||||
* @return 是否导入成功
|
||||
*/
|
||||
@PostMapping("/import")
|
||||
public boolean importDevices(@RequestParam("file") MultipartFile file) {
|
||||
return deviceService.importDevices(file);
|
||||
public boolean importDevices(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam String deviceType) {
|
||||
return deviceService.importDevices(file, deviceType);
|
||||
}
|
||||
|
||||
|
||||
@ -124,7 +125,6 @@ public class DeviceController {
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(defaultValue = "1") long pageNum,
|
||||
@RequestParam(defaultValue = "20") long pageSize) {
|
||||
long offset = Math.max(0, (pageNum - 1) * pageSize);
|
||||
QueryWrapper<Device> qw = new QueryWrapper<>();
|
||||
if (type != null && !type.isEmpty()) {
|
||||
qw.eq("type", type);
|
||||
@ -132,20 +132,9 @@ public class DeviceController {
|
||||
if (name != null && !name.isEmpty()) {
|
||||
qw.like("name", name);
|
||||
}
|
||||
qw.orderByDesc("created_at").last("LIMIT " + offset + "," + pageSize);
|
||||
java.util.List<Device> records = deviceService.list(qw);
|
||||
QueryWrapper<Device> countQw = new QueryWrapper<>();
|
||||
if (type != null && !type.isEmpty()) {
|
||||
countQw.eq("type", type);
|
||||
}
|
||||
if (name != null && !name.isEmpty()) {
|
||||
countQw.like("name", name);
|
||||
}
|
||||
long total = deviceService.count(countQw);
|
||||
qw.orderByDesc("created_at");
|
||||
Page<Device> page = new Page<>(pageNum, pageSize, true);
|
||||
page.setRecords(records);
|
||||
page.setTotal(total);
|
||||
return page;
|
||||
return deviceService.page(page, qw);
|
||||
}
|
||||
|
||||
private String currentUsername() {
|
||||
|
||||
@ -102,37 +102,23 @@ public class MaterialController {
|
||||
public Page<Material> search(@RequestParam(required = false) String name,
|
||||
@RequestParam(defaultValue = "1") long pageNum,
|
||||
@RequestParam(defaultValue = "20") long pageSize) {
|
||||
long offset = Math.max(0, (pageNum - 1) * pageSize);
|
||||
QueryWrapper<Material> qw = new QueryWrapper<Material>().orderByDesc("created_at");
|
||||
if (name != null && !name.isEmpty()) {
|
||||
qw.like("name", name);
|
||||
}
|
||||
qw.last("LIMIT " + offset + "," + pageSize);
|
||||
java.util.List<Material> records = materialService.list(qw);
|
||||
long total = (name != null && !name.isEmpty())
|
||||
? materialService.count(new QueryWrapper<Material>().like("name", name))
|
||||
: materialService.count();
|
||||
Page<Material> page = new Page<>(pageNum, pageSize, true);
|
||||
page.setRecords(records);
|
||||
page.setTotal(total);
|
||||
return page;
|
||||
return materialService.page(page, qw);
|
||||
}
|
||||
|
||||
@GetMapping("/by-project")
|
||||
public Page<Material> pageByProject(@RequestParam String projectId,
|
||||
@RequestParam(defaultValue = "1") long pageNum,
|
||||
@RequestParam(defaultValue = "20") long pageSize) {
|
||||
long offset = Math.max(0, (pageNum - 1) * pageSize);
|
||||
QueryWrapper<Material> qw = new QueryWrapper<Material>()
|
||||
.eq("project_id", projectId)
|
||||
.orderByDesc("created_at")
|
||||
.last("LIMIT " + offset + "," + pageSize);
|
||||
java.util.List<Material> records = materialService.list(qw);
|
||||
long total = materialService.count(new QueryWrapper<Material>().eq("project_id", projectId));
|
||||
.orderByDesc("created_at");
|
||||
Page<Material> page = new Page<>(pageNum, pageSize, true);
|
||||
page.setRecords(records);
|
||||
page.setTotal(total);
|
||||
return page;
|
||||
return materialService.page(page, qw);
|
||||
}
|
||||
|
||||
private String currentUsername() {
|
||||
|
||||
@ -156,23 +156,12 @@ public class ProjectController {
|
||||
public Page<Project> search(@RequestParam(required = false) @Parameter(description = "项目名称关键词,可为空") String name,
|
||||
@RequestParam(defaultValue = "1") @Parameter(description = "页码,默认1") long pageNum,
|
||||
@RequestParam(defaultValue = "20") @Parameter(description = "每页条数,默认20") long pageSize) {
|
||||
long offset = Math.max(0, (pageNum - 1) * pageSize);
|
||||
QueryWrapper<Project> qw = new QueryWrapper<Project>().orderByDesc("created_at");
|
||||
if (name != null && !name.isEmpty()) {
|
||||
qw.like("name", name);
|
||||
}
|
||||
qw.last("LIMIT " + offset + "," + pageSize);
|
||||
java.util.List<Project> records = projectService.list(qw);
|
||||
long total;
|
||||
if (name != null && !name.isEmpty()) {
|
||||
total = projectService.count(new QueryWrapper<Project>().like("name", name));
|
||||
} else {
|
||||
total = projectService.count();
|
||||
}
|
||||
Page<Project> page = new Page<>(pageNum, pageSize, true);
|
||||
page.setRecords(records);
|
||||
page.setTotal(total);
|
||||
return page;
|
||||
return projectService.page(page, qw);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -103,20 +103,12 @@ public class ScenarioController {
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(defaultValue = "1") long pageNum,
|
||||
@RequestParam(defaultValue = "20") long pageSize) {
|
||||
long offset = Math.max(0, (pageNum - 1) * pageSize);
|
||||
QueryWrapper<Scenario> qw = new QueryWrapper<Scenario>().eq("project_id", projectId).orderByDesc("created_at");
|
||||
if (name != null && !name.isEmpty()) {
|
||||
qw.like("name", name);
|
||||
}
|
||||
qw.last("LIMIT " + offset + "," + pageSize);
|
||||
java.util.List<Scenario> records = scenarioService.list(qw);
|
||||
long total = (name != null && !name.isEmpty())
|
||||
? scenarioService.count(new QueryWrapper<Scenario>().eq("project_id", projectId).like("name", name))
|
||||
: scenarioService.count(new QueryWrapper<Scenario>().eq("project_id", projectId));
|
||||
Page<Scenario> page = new Page<>(pageNum, pageSize, true);
|
||||
page.setRecords(records);
|
||||
page.setTotal(total);
|
||||
return page;
|
||||
return scenarioService.page(page, qw);
|
||||
}
|
||||
|
||||
private String currentUsername() {
|
||||
|
||||
@ -9,7 +9,7 @@ public interface CriticalDataService extends IService<CriticalData> {
|
||||
/**
|
||||
* 导入临界数据
|
||||
*/
|
||||
boolean importCriticalData(MultipartFile file);
|
||||
boolean importCriticalData(MultipartFile file, String deviceType);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -7,5 +7,5 @@ public interface DeviceService extends IService<Device> {
|
||||
/**
|
||||
* 导入设备
|
||||
*/
|
||||
boolean importDevices(MultipartFile file);
|
||||
boolean importDevices(MultipartFile file, String deviceType);
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ public class CriticalDataServiceImpl
|
||||
@Resource
|
||||
private IUserService userService;
|
||||
@Override
|
||||
public boolean importCriticalData(MultipartFile file) {
|
||||
public boolean importCriticalData(MultipartFile file, String deviceType) {
|
||||
try {
|
||||
String name = file.getOriginalFilename();
|
||||
log.info("critical-data import start name={} size={} contentType={}", name, file.getSize(), file.getContentType());
|
||||
@ -48,10 +48,10 @@ public class CriticalDataServiceImpl
|
||||
String lower = name.toLowerCase();
|
||||
if (lower.endsWith(".xlsx")) {
|
||||
log.info("critical-data detected type=xlsx");
|
||||
return importExcel(new XSSFWorkbook(file.getInputStream()));
|
||||
return importExcel(new XSSFWorkbook(file.getInputStream()), deviceType);
|
||||
} else if (lower.endsWith(".xls")) {
|
||||
log.info("critical-data detected type=xls");
|
||||
return importExcel(new HSSFWorkbook(file.getInputStream()));
|
||||
return importExcel(new HSSFWorkbook(file.getInputStream()), deviceType);
|
||||
} else {
|
||||
log.warn("critical-data unsupported file type name={}", name);
|
||||
return false;
|
||||
@ -62,7 +62,7 @@ public class CriticalDataServiceImpl
|
||||
}
|
||||
}
|
||||
|
||||
private boolean importExcel(Workbook workbook) {
|
||||
private boolean importExcel(Workbook workbook, String deviceType) {
|
||||
try (Workbook wb = workbook) {
|
||||
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
|
||||
evaluator.evaluateAll();
|
||||
@ -86,7 +86,7 @@ public class CriticalDataServiceImpl
|
||||
}
|
||||
log.info("critical-data excel header keys={}", idx.keySet());
|
||||
String[] keys = new String[]{
|
||||
"device_type","diameter","height",
|
||||
"diameter","height",
|
||||
"fissile_concentration","isotopic_abundance",
|
||||
"keff_value","extra_features"
|
||||
};
|
||||
@ -101,7 +101,7 @@ public class CriticalDataServiceImpl
|
||||
Row row = sheet.getRow(r);
|
||||
if (row == null) continue;
|
||||
CriticalData cd = new CriticalData();
|
||||
cd.setDeviceType(cleanString(getString(row, idx.get("device_type"))));
|
||||
cd.setDeviceType(deviceType);
|
||||
cd.setDiameter(cleanDecimal(getDecimalFlexible(row, idx.get("diameter"), evaluator, formatter)));
|
||||
cd.setHeight(cleanDecimal(getDecimalFlexible(row, idx.get("height"), evaluator, formatter)));
|
||||
cd.setFissileConcentration(cleanDecimal(getDecimalFlexible(row, idx.get("fissile_concentration"), evaluator, formatter)));
|
||||
|
||||
@ -35,15 +35,15 @@ public class DeviceServiceImpl
|
||||
@Resource
|
||||
private IUserService userService;
|
||||
@Override
|
||||
public boolean importDevices(MultipartFile file) {
|
||||
public boolean importDevices(MultipartFile file, String deviceType) {
|
||||
try {
|
||||
String name = file.getOriginalFilename();
|
||||
if (name == null) return false;
|
||||
String lower = name.toLowerCase();
|
||||
if (lower.endsWith(".xlsx")) {
|
||||
return importExcel(new XSSFWorkbook(file.getInputStream()));
|
||||
return importExcel(new XSSFWorkbook(file.getInputStream()), deviceType);
|
||||
} else if (lower.endsWith(".xls")) {
|
||||
return importExcel(new HSSFWorkbook(file.getInputStream()));
|
||||
return importExcel(new HSSFWorkbook(file.getInputStream()), deviceType);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -52,7 +52,7 @@ public class DeviceServiceImpl
|
||||
}
|
||||
}
|
||||
|
||||
private boolean importExcel(Workbook workbook) {
|
||||
private boolean importExcel(Workbook workbook, String deviceType) {
|
||||
try (Workbook wb = workbook) {
|
||||
Sheet sheet = wb.getSheetAt(0);
|
||||
if (sheet == null) return false;
|
||||
@ -65,7 +65,7 @@ public class DeviceServiceImpl
|
||||
String key = c.getStringCellValue();
|
||||
if (key != null) idx.put(key.trim().toLowerCase(), i);
|
||||
}
|
||||
String[] keys = new String[]{"type","code","name","size","volume","flow_rate","pulse_velocity"};
|
||||
String[] keys = new String[]{"code","name","size","volume","flow_rate","pulse_velocity"};
|
||||
for (String k : keys) {
|
||||
if (!idx.containsKey(k)) return false;
|
||||
}
|
||||
@ -74,7 +74,7 @@ public class DeviceServiceImpl
|
||||
Row row = sheet.getRow(r);
|
||||
if (row == null) continue;
|
||||
Device d = new Device();
|
||||
d.setType(getString(row, idx.get("type")));
|
||||
d.setType(deviceType);
|
||||
d.setCode(getString(row, idx.get("code")));
|
||||
d.setName(getString(row, idx.get("name")));
|
||||
d.setSize(validateJson(getString(row, idx.get("size"))));
|
||||
|
||||
@ -190,17 +190,29 @@ public class ProjectServiceImpl
|
||||
src.put("delayMs", delayMs);
|
||||
srcList.add(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, Object> plan = new HashMap<>();
|
||||
plan.put("target", Map.of("entityType","device","entityId",deviceId,"property",propName));
|
||||
plan.put("bias", prop.path("bias").isNumber() ? prop.path("bias").asDouble() : 0.0);
|
||||
plan.put("sources", srcList);
|
||||
plans.add(plan);
|
||||
}
|
||||
});
|
||||
}
|
||||
// materials can be array or single object; also some payloads use "material" key
|
||||
Map<String, Object> plan = new HashMap<>();
|
||||
plan.put("target", Map.of("entityType","device","entityId",deviceId,"property",propName));
|
||||
plan.put("bias", prop.path("bias").isNumber() ? prop.path("bias").asDouble() : 0.0);
|
||||
plan.put("sources", srcList);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
double b = prop.path("bias").isNumber() ? prop.path("bias").asDouble() : 0.0;
|
||||
sb.append(b);
|
||||
for (Map<String, Object> s : srcList) {
|
||||
double coef = s.get("coefficient") instanceof Number ? ((Number) s.get("coefficient")).doubleValue() : 1.0;
|
||||
String seId = String.valueOf(s.get("entityId"));
|
||||
String seProp = String.valueOf(s.get("property"));
|
||||
long dms = s.get("delayMs") instanceof Number ? ((Number) s.get("delayMs")).longValue() : 0L;
|
||||
long ds = dms / 1000L;
|
||||
sb.append(" + ").append(coef).append("*").append(seId).append(".").append(seProp).append("@").append(ds).append("s");
|
||||
}
|
||||
plan.put("formula", sb.toString());
|
||||
plans.add(plan);
|
||||
}
|
||||
});
|
||||
}
|
||||
// materials can be array or single object; also some payloads use "material" key
|
||||
JsonNode mats = dn.path("materials");
|
||||
if (mats.isMissingNode() || mats.isNull()) {
|
||||
mats = dn.path("material");
|
||||
@ -298,16 +310,28 @@ public class ProjectServiceImpl
|
||||
src.put("delayMs", delayMs);
|
||||
srcList.add(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, Object> plan = new HashMap<>();
|
||||
plan.put("target", Map.of("entityType","material","entityId",mid,"property",propName));
|
||||
plan.put("bias", prop.path("bias").isNumber() ? prop.path("bias").asDouble() : 0.0);
|
||||
plan.put("sources", srcList);
|
||||
plans.add(plan);
|
||||
}
|
||||
});
|
||||
}
|
||||
Map<String, Object> plan = new HashMap<>();
|
||||
plan.put("target", Map.of("entityType","material","entityId",mid,"property",propName));
|
||||
plan.put("bias", prop.path("bias").isNumber() ? prop.path("bias").asDouble() : 0.0);
|
||||
plan.put("sources", srcList);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
double b = prop.path("bias").isNumber() ? prop.path("bias").asDouble() : 0.0;
|
||||
sb.append(b);
|
||||
for (Map<String, Object> s : srcList) {
|
||||
double coef = s.get("coefficient") instanceof Number ? ((Number) s.get("coefficient")).doubleValue() : 1.0;
|
||||
String seId = String.valueOf(s.get("entityId"));
|
||||
String seProp = String.valueOf(s.get("property"));
|
||||
long dms = s.get("delayMs") instanceof Number ? ((Number) s.get("delayMs")).longValue() : 0L;
|
||||
long ds = dms / 1000L;
|
||||
sb.append(" + ").append(coef).append("*").append(seId).append(".").append(seProp).append("@").append(ds).append("s");
|
||||
}
|
||||
plan.put("formula", sb.toString());
|
||||
plans.add(plan);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static String optText(JsonNode n, String field) {
|
||||
@ -497,10 +521,6 @@ public class ProjectServiceImpl
|
||||
return out;
|
||||
}
|
||||
JsonNode root = objectMapper.readTree(p.getTopology());
|
||||
long start = getLongParam(params, "startTime", 0L);
|
||||
long end = getLongParam(params, "endTime", 60L);
|
||||
long stepSec = getLongParam(params, "step", 1L);
|
||||
if (end < start) end = start;
|
||||
List<Device> devs = parseDeviceOrder(projectId);
|
||||
if (devs.isEmpty()) {
|
||||
issues.add("devices为空");
|
||||
@ -508,27 +528,42 @@ public class ProjectServiceImpl
|
||||
out.put("frames", frames);
|
||||
return out;
|
||||
}
|
||||
Map<String, String> devToMat = buildDeviceMaterialMap(root, issues);
|
||||
Map<String, Map<String, Double>> devStatic = new HashMap<>();
|
||||
Map<String, Map<String, Object>> devInfluence = new HashMap<>();
|
||||
parseDeviceStaticsAndInfluences(root, devStatic, devInfluence, issues);
|
||||
Map<String, Map<String, Double>> matStatic = new HashMap<>();
|
||||
Map<String, Map<String, Object>> matInfluence = new HashMap<>();
|
||||
parseMaterialStaticsAndInfluences(root, matStatic, matInfluence, issues);
|
||||
Map<String, Map<String, Double>> matStaticDb = buildMaterialStaticFromDb(devToMat);
|
||||
List<Event> events = eventService.list(
|
||||
new QueryWrapper<Event>()
|
||||
.select("event_id","scenario_id","device_id","material_id","attr_changes","trigger_time","created_at","modifier")
|
||||
.eq("scenario_id", scenarioId)
|
||||
);
|
||||
Map<String, Object> valueProviders = buildValueProviders(events, issues);
|
||||
List<Long> timePoints = collectTimePoints(valueProviders);
|
||||
if (timePoints.isEmpty()) {
|
||||
issues.add("事件为空或未提供时间点,无法生成帧");
|
||||
out.put("generated", Map.of("events", events.size(), "snapshots", 0));
|
||||
out.put("frames", frames);
|
||||
return out;
|
||||
}
|
||||
Map<String, String> devTypeMap = buildDeviceTypeMap(root);
|
||||
int snapshots = 0;
|
||||
for (long t = start; t <= end; t += stepSec) {
|
||||
int stepIndex = (int) ((t - start) / stepSec);
|
||||
for (int idx = 0; idx < timePoints.size(); idx++) {
|
||||
long t = timePoints.get(idx);
|
||||
int stepIndex = idx;
|
||||
Map<String, Map<String, Object>> deviceStates = new HashMap<>();
|
||||
for (Device d : devs) {
|
||||
String did = d.getDeviceId();
|
||||
String dtype = devTypeMap.getOrDefault(did, d.getType());
|
||||
Map<String, Object> state = new HashMap<>();
|
||||
Map<String, Double> s = devStatic.getOrDefault(did, Map.of());
|
||||
for (Map.Entry<String, Double> e : s.entrySet()) state.put(e.getKey(), e.getValue());
|
||||
if (dtype != null && !dtype.isEmpty()) {
|
||||
state.put("deviceType", dtype);
|
||||
}
|
||||
Map<String, Double> sdev = devStatic.getOrDefault(did, Map.of());
|
||||
for (Map.Entry<String, Double> e : sdev.entrySet()) state.put(e.getKey(), e.getValue());
|
||||
Map<String, Object> infl = devInfluence.getOrDefault(did, Map.of());
|
||||
for (Map.Entry<String, Object> e : infl.entrySet()) {
|
||||
String prop = e.getKey();
|
||||
@ -552,12 +587,17 @@ public class ProjectServiceImpl
|
||||
}
|
||||
state.put(prop, sum + bias);
|
||||
}
|
||||
Map<String, Object> materialsState = new HashMap<>();
|
||||
for (Map.Entry<String, Map<String, Double>> me : matStatic.entrySet()) {
|
||||
String mid = me.getKey();
|
||||
Map<String, Object> mstate = new HashMap<>();
|
||||
for (Map.Entry<String, Double> e : me.getValue().entrySet()) mstate.put(e.getKey(), e.getValue());
|
||||
Map<String, Object> minfl = matInfluence.getOrDefault(mid, Map.of());
|
||||
String boundMid = devToMat.get(did);
|
||||
if (boundMid != null) {
|
||||
Map<String, Double> smatDb = matStaticDb.getOrDefault(boundMid, Map.of());
|
||||
for (Map.Entry<String, Double> e : smatDb.entrySet()) {
|
||||
state.put(e.getKey(), e.getValue());
|
||||
}
|
||||
Map<String, Double> smatTopo = matStatic.getOrDefault(boundMid, Map.of());
|
||||
for (Map.Entry<String, Double> e : smatTopo.entrySet()) {
|
||||
state.put(e.getKey(), e.getValue());
|
||||
}
|
||||
Map<String, Object> minfl = matInfluence.getOrDefault(boundMid, Map.of());
|
||||
for (Map.Entry<String, Object> e : minfl.entrySet()) {
|
||||
String prop = e.getKey();
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -578,11 +618,13 @@ public class ProjectServiceImpl
|
||||
sum += coef * val;
|
||||
}
|
||||
}
|
||||
mstate.put(prop, sum + bias);
|
||||
state.put(prop, sum + bias);
|
||||
}
|
||||
materialsState.put(mid, mstate);
|
||||
}
|
||||
state.put("materials", materialsState);
|
||||
// apply material event overrides
|
||||
overrideWithEvents(state, "material", boundMid, t, valueProviders);
|
||||
}
|
||||
// apply device event overrides
|
||||
overrideWithEvents(state, "device", did, t, valueProviders);
|
||||
deviceStates.put(did, state);
|
||||
}
|
||||
snapshots += devs.size();
|
||||
@ -834,6 +876,112 @@ public class ProjectServiceImpl
|
||||
return s.getOrDefault(property, 0.0);
|
||||
}
|
||||
|
||||
private List<Long> collectTimePoints(Map<String, Object> providers) {
|
||||
Set<Long> ts = new HashSet<>();
|
||||
for (Object v : providers.values()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> pv = (Map<String, Object>) v;
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> schedule = (List<Map<String, Object>>) pv.get("schedule");
|
||||
if (schedule == null) continue;
|
||||
for (Map<String, Object> s : schedule) {
|
||||
String type = String.valueOf(s.get("type"));
|
||||
if ("step-set".equals(type)) {
|
||||
long t = (long) toDouble(s.get("time"));
|
||||
ts.add(t);
|
||||
} else if ("ramp".equals(type)) {
|
||||
long st = (long) toDouble(s.get("startTime"));
|
||||
long et = (long) toDouble(s.get("endTime"));
|
||||
ts.add(st);
|
||||
ts.add(et);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Long> list = new ArrayList<>(ts);
|
||||
list.sort(Comparator.naturalOrder());
|
||||
return list;
|
||||
}
|
||||
|
||||
private Map<String, String> buildDeviceMaterialMap(JsonNode root, List<String> issues) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
JsonNode devicesNode = root.path("devices");
|
||||
if (!devicesNode.isArray()) return map;
|
||||
for (JsonNode dn : devicesNode) {
|
||||
String did = optText(dn, "deviceId");
|
||||
if (did == null || did.isEmpty()) continue;
|
||||
JsonNode mats = dn.path("materials");
|
||||
if (mats.isMissingNode() || mats.isNull()) mats = dn.path("material");
|
||||
if (mats.isArray()) {
|
||||
for (JsonNode mn : mats) {
|
||||
String mid = optText(mn, "materialId");
|
||||
if (mid != null && !mid.isEmpty()) {
|
||||
map.put(did, mid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (mats.isObject()) {
|
||||
String mid = optText(mats, "materialId");
|
||||
if (mid != null && !mid.isEmpty()) {
|
||||
map.put(did, mid);
|
||||
} else {
|
||||
issues.add("材料缺少materialId: device=" + did);
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private Map<String, String> buildDeviceTypeMap(JsonNode root) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
JsonNode devicesNode = root.path("devices");
|
||||
if (!devicesNode.isArray()) return map;
|
||||
for (JsonNode dn : devicesNode) {
|
||||
String did = optText(dn, "deviceId");
|
||||
String tp = optText(dn, "type");
|
||||
if (did != null && !did.isEmpty() && tp != null && !tp.isEmpty()) {
|
||||
map.put(did, tp);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void overrideWithEvents(Map<String, Object> state, String entityType, String entityId, long t, Map<String, Object> providers) {
|
||||
String prefix = entityType + ":" + entityId + ":";
|
||||
for (String key : providers.keySet()) {
|
||||
if (!key.startsWith(prefix)) continue;
|
||||
String prop = key.substring(prefix.length());
|
||||
double val = readValue(entityType, entityId, prop, t, Map.of(), Map.of(), providers);
|
||||
state.put(prop, val);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Map<String, Double>> buildMaterialStaticFromDb(Map<String, String> devToMat) {
|
||||
Map<String, Map<String, Double>> out = new HashMap<>();
|
||||
if (devToMat == null || devToMat.isEmpty()) return out;
|
||||
Set<String> mids = new HashSet<>(devToMat.values());
|
||||
if (mids.isEmpty()) return out;
|
||||
List<Material> mats = materialService.list(new QueryWrapper<Material>().in("material_id", mids));
|
||||
Map<String, Material> mm = new HashMap<>();
|
||||
for (Material m : mats) mm.put(m.getMaterialId(), m);
|
||||
for (String mid : mids) {
|
||||
Material m = mm.get(mid);
|
||||
if (m == null) continue;
|
||||
Map<String, Double> s = new HashMap<>();
|
||||
if (m.getUConcentration() != null) s.put("u_concentration", toDouble(m.getUConcentration()));
|
||||
if (m.getUo2Density() != null) s.put("uo2_density", toDouble(m.getUo2Density()));
|
||||
if (m.getUEnrichment() != null) s.put("u_enrichment", toDouble(m.getUEnrichment()));
|
||||
if (m.getPuConcentration() != null) s.put("pu_concentration", toDouble(m.getPuConcentration()));
|
||||
if (m.getPuo2Density() != null) s.put("puo2_density", toDouble(m.getPuo2Density()));
|
||||
if (m.getPuIsotope() != null) s.put("pu_isotope", toDouble(m.getPuIsotope()));
|
||||
if (m.getHno3Acidity() != null) s.put("hno3_acidity", toDouble(m.getHno3Acidity()));
|
||||
if (m.getH2c2o4Concentration() != null) s.put("h2c2o4_concentration", toDouble(m.getH2c2o4Concentration()));
|
||||
if (m.getOrganicRatio() != null) s.put("organic_ratio", toDouble(m.getOrganicRatio()));
|
||||
if (m.getMoistureContent() != null) s.put("moisture_content", toDouble(m.getMoistureContent()));
|
||||
out.put(mid, s);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private long getLongParam(Map<String, Object> params, String key, long def) {
|
||||
if (params == null) return def;
|
||||
Object v = params.get(key);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user