后端更新
This commit is contained in:
parent
666248b402
commit
d82e34d803
@ -15,6 +15,7 @@ import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
"com.yfd.platform.system",
|
||||
"com.yfd.platform.utils",
|
||||
"com.yfd.platform.component",
|
||||
"com.yfd.platform.aspect",
|
||||
"com.yfd.business.css"
|
||||
},
|
||||
exclude = {DataSourceAutoConfiguration.class, RedisAutoConfiguration.class}
|
||||
|
||||
@ -9,6 +9,7 @@ import com.yfd.business.css.domain.Material;
|
||||
import com.yfd.business.css.domain.Project;
|
||||
import com.yfd.business.css.model.*;
|
||||
import com.yfd.business.css.service.MaterialService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
@ -17,6 +18,7 @@ import java.util.*;
|
||||
* 仿真模型构建器
|
||||
* 负责将原始的 Project (Topology) 和 Event 数据解析转换为 SimUnit, SimEvent, SimInfluenceNode
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SimBuilder {
|
||||
|
||||
@ -99,6 +101,7 @@ public class SimBuilder {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Build units failed: {}", e.getMessage(), e);
|
||||
throw new RuntimeException("Build units failed", e);
|
||||
}
|
||||
return units;
|
||||
@ -175,7 +178,7 @@ public class SimBuilder {
|
||||
parseCommonSize(sizeNode, staticProps);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("解析Device.size失败:" + e.getMessage());
|
||||
log.warn("解析Device.size失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,7 +260,7 @@ public class SimBuilder {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// log error
|
||||
log.error("解析事件失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return simEvents;
|
||||
@ -292,6 +295,7 @@ public class SimBuilder {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Build influence nodes failed: {}", e.getMessage(), e);
|
||||
throw new RuntimeException("Build influence nodes failed", e);
|
||||
}
|
||||
return nodes;
|
||||
|
||||
@ -11,6 +11,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@ -43,6 +44,7 @@ public class AlgorithmController {
|
||||
return algorithmService.getOne(qw);
|
||||
}
|
||||
|
||||
@Log(value = "新增算法", module = "算法管理")
|
||||
@PostMapping
|
||||
@Operation(summary = "新增算法", description = "请求体传入算法对象,返回是否新增成功")
|
||||
public boolean createAlgorithm(@RequestBody Algorithm algorithm) {
|
||||
@ -52,6 +54,7 @@ public class AlgorithmController {
|
||||
return algorithmService.save(algorithm);
|
||||
}
|
||||
|
||||
@Log(value = "修改算法", module = "算法管理")
|
||||
@PutMapping
|
||||
@Operation(summary = "修改算法", description = "请求体传入算法对象(需包含主键),返回是否修改成功")
|
||||
public boolean updateAlgorithm(@RequestBody Algorithm algorithm) {
|
||||
@ -60,18 +63,21 @@ public class AlgorithmController {
|
||||
return algorithmService.updateById(algorithm);
|
||||
}
|
||||
|
||||
@Log(value = "删除算法", module = "算法管理")
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "删除算法(单条)", description = "根据算法ID删除算法")
|
||||
public boolean deleteAlgorithm(@PathVariable String id) {
|
||||
return algorithmService.removeById(id);
|
||||
}
|
||||
|
||||
@Log(value = "批量删除算法", module = "算法管理")
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除算法(批量)", description = "请求体传入算法ID列表,批量删除算法")
|
||||
public boolean deleteAlgorithms(@RequestBody List<String> ids) {
|
||||
return algorithmService.removeByIds(ids);
|
||||
}
|
||||
|
||||
@Log(value = "激活算法", module = "算法管理")
|
||||
//算法类型激活
|
||||
@PostMapping("/activate")
|
||||
@Operation(summary = "激活算法", description = "激活当前算法类型")
|
||||
@ -85,6 +91,7 @@ public class AlgorithmController {
|
||||
return algorithmService.updateById(algorithm);
|
||||
}
|
||||
|
||||
@Log(value = "关闭算法", module = "算法管理")
|
||||
//算法类型关闭
|
||||
@PostMapping("/unactivate")
|
||||
@Operation(summary = "关闭算法", description = "关闭当前算法类型")
|
||||
|
||||
@ -13,6 +13,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@ -51,6 +52,7 @@ public class AlgorithmModelController {
|
||||
return algorithmModelService.getById(id);
|
||||
}
|
||||
|
||||
@Log(value = "新增模型版本", module = "算法模型管理")
|
||||
@PostMapping
|
||||
@Operation(summary = "新增模型版本", description = "请求体传入模型版本对象,返回是否新增成功")
|
||||
public boolean create(@RequestBody AlgorithmModel model) {
|
||||
@ -60,6 +62,7 @@ public class AlgorithmModelController {
|
||||
return algorithmModelService.save(model);
|
||||
}
|
||||
|
||||
@Log(value = "修改模型版本", module = "算法模型管理")
|
||||
@PutMapping
|
||||
@Operation(summary = "修改模型版本", description = "请求体传入模型版本对象(需包含主键),返回是否修改成功")
|
||||
public boolean update(@RequestBody AlgorithmModel model) {
|
||||
@ -68,12 +71,14 @@ public class AlgorithmModelController {
|
||||
return algorithmModelService.updateById(model);
|
||||
}
|
||||
|
||||
@Log(value = "删除模型版本", module = "算法模型管理")
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "删除模型版本(单条)", description = "根据模型ID删除模型版本")
|
||||
public boolean delete(@PathVariable String id) {
|
||||
return algorithmModelService.removeById(id);
|
||||
}
|
||||
|
||||
@Log(value = "批量删除模型版本", module = "算法模型管理")
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除模型版本(批量)", description = "请求体传入模型ID列表,批量删除模型版本")
|
||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||
@ -118,6 +123,7 @@ public class AlgorithmModelController {
|
||||
return algorithmModelService.getOne(qw, false); // 使用 false 避免多条结果时抛出异常,虽然正常不应该有多条
|
||||
}
|
||||
|
||||
@Log(value = "激活模型版本", module = "算法模型管理")
|
||||
//版本激活
|
||||
@PostMapping("/activate")
|
||||
@Operation(summary = "激活模型版本", description = "将目标模型版本设为当前,并将同组(算法+设备+材料)其他版本设为非当前")
|
||||
@ -143,6 +149,7 @@ public class AlgorithmModelController {
|
||||
return algorithmModelService.updateById(model);
|
||||
}
|
||||
|
||||
@Log(value = "在线训练(Excel)", module = "算法模型管理")
|
||||
// 在线训练(Excel 数据集)
|
||||
@PostMapping("/train/excel")
|
||||
@Operation(summary = "在线训练(Excel)", description = "传入算法类型、设备类型与Excel路径,训练完成新增模型版本记录,可选激活")
|
||||
@ -216,6 +223,7 @@ public class AlgorithmModelController {
|
||||
return Map.of("code", 0, "msg", "训练成功", "data", model);
|
||||
}
|
||||
|
||||
@Log(value = "在线训练(样本)", module = "算法模型管理")
|
||||
// 在线训练(样本集合)
|
||||
@PostMapping("/train/samples")
|
||||
@Operation(summary = "在线训练(样本集合)", description = "传入算法类型、设备类型与样本集,训练完成新增模型版本记录,可选激活")
|
||||
|
||||
@ -7,6 +7,7 @@ import com.yfd.business.css.service.CriticalDataService;
|
||||
import com.yfd.platform.system.service.IUserService;
|
||||
|
||||
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -34,6 +35,7 @@ public class CriticalDataController {
|
||||
* @param data 临界数据对象
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Log(value = "新增临界数据", module = "临界数据管理")
|
||||
@PostMapping
|
||||
public boolean create(@RequestBody CriticalData data) {
|
||||
data.setModifier(currentUsername());
|
||||
@ -59,6 +61,7 @@ public class CriticalDataController {
|
||||
* @param data 临界数据对象
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Log(value = "修改临界数据", module = "临界数据管理")
|
||||
@PutMapping
|
||||
public boolean update(@RequestBody CriticalData data) {
|
||||
data.setModifier(currentUsername());
|
||||
@ -73,6 +76,7 @@ public class CriticalDataController {
|
||||
* @param id 临界数据ID
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "删除临界数据", module = "临界数据管理")
|
||||
@DeleteMapping("/{id}")
|
||||
public boolean delete(@PathVariable String id) {
|
||||
return criticalDataService.removeById(id);
|
||||
@ -85,6 +89,7 @@ public class CriticalDataController {
|
||||
* @param ids 临界数据ID列表
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "批量删除临界数据", module = "临界数据管理")
|
||||
@DeleteMapping
|
||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||
return criticalDataService.removeByIds(ids);
|
||||
@ -100,6 +105,7 @@ public class CriticalDataController {
|
||||
* @param file Excel/CSV 文件
|
||||
* @return 是否导入成功
|
||||
*/
|
||||
@Log(value = "导入临界数据", module = "临界数据管理")
|
||||
@PostMapping("/import")
|
||||
public boolean importCriticalData(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam String deviceType) {
|
||||
|
||||
@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
@ -31,12 +32,14 @@ public class DeviceController {
|
||||
* @param device 设备对象
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Log(value = "新增设备", module = "设备管理")
|
||||
@PostMapping
|
||||
public boolean create(@RequestBody Device device) {
|
||||
device.setModifier(currentUsername());
|
||||
return deviceService.createDevice(device);
|
||||
}
|
||||
|
||||
@Log(value = "保存或更新设备", module = "设备管理")
|
||||
@PostMapping("/saveOrUpdate")
|
||||
public boolean saveOrUpdate(@RequestBody Device device) {
|
||||
device.setModifier(currentUsername());
|
||||
@ -50,6 +53,7 @@ public class DeviceController {
|
||||
* @param device 设备对象
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Log(value = "编辑设备", module = "设备管理")
|
||||
@PutMapping
|
||||
public boolean update(@RequestBody Device device) {
|
||||
device.setModifier(currentUsername());
|
||||
@ -64,6 +68,7 @@ public class DeviceController {
|
||||
* @param id 设备ID
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "删除设备", module = "设备管理")
|
||||
@DeleteMapping("/{id}")
|
||||
public boolean delete(@PathVariable String id) {
|
||||
return deviceService.removeById(id);
|
||||
@ -76,6 +81,7 @@ public class DeviceController {
|
||||
* @param ids 设备ID列表
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "批量删除设备", module = "设备管理")
|
||||
@DeleteMapping
|
||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||
return deviceService.removeByIds(ids);
|
||||
@ -90,6 +96,7 @@ public class DeviceController {
|
||||
* @param file Excel/CSV 文件
|
||||
* @return 是否导入成功
|
||||
*/
|
||||
@Log(value = "导入设备", module = "设备管理")
|
||||
@PostMapping("/import")
|
||||
public boolean importDevices(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam String deviceType) {
|
||||
|
||||
@ -10,6 +10,7 @@ import jakarta.annotation.Resource;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@ -44,6 +45,7 @@ public class EventController {
|
||||
/**
|
||||
* 新增始发事件
|
||||
*/
|
||||
@Log(value = "新增始发事件", module = "事件管理")
|
||||
@PostMapping
|
||||
public ResponseEntity<Map<String, Object>> addEvent(@RequestBody Event event) {
|
||||
event.setModifier(currentUsername());
|
||||
@ -64,6 +66,7 @@ public class EventController {
|
||||
* @param event 事件对象
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Log(value = "修改始发事件", module = "事件管理")
|
||||
@PutMapping
|
||||
public boolean update(@RequestBody Event event) {
|
||||
event.setModifier(currentUsername());
|
||||
@ -76,6 +79,7 @@ public class EventController {
|
||||
* @param events
|
||||
* @return
|
||||
*/
|
||||
@Log(value = "批量保存或更新事件", module = "事件管理")
|
||||
@PostMapping("/batchSave")
|
||||
@Transactional
|
||||
public ResponseEntity<Map<String, Object>> batchSaveOrUpdateEvents(@RequestBody List<Event> events) {
|
||||
@ -112,6 +116,7 @@ public class EventController {
|
||||
/**
|
||||
* 修改 Event 的 attr_changes
|
||||
*/
|
||||
@Log(value = "修改事件属性变更配置", module = "事件管理")
|
||||
@PutMapping("/{eventId}/attr-changes")
|
||||
public ResponseEntity<Map<String, Object>> updateAttrChanges(
|
||||
@PathVariable String eventId,
|
||||
@ -169,6 +174,7 @@ public class EventController {
|
||||
* @param eventId 事件ID
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Log(value = "删除始发事件", module = "事件管理")
|
||||
@DeleteMapping("/{eventId}")
|
||||
public ResponseEntity<Map<String, Object>> deleteEvent(@PathVariable String eventId) {
|
||||
boolean ok = eventService.removeById(eventId);
|
||||
|
||||
@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
@ -32,12 +33,14 @@ public class MaterialController {
|
||||
* @param material 物料对象
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Log(value = "新增物料", module = "物料管理")
|
||||
@PostMapping
|
||||
public boolean create(@RequestBody Material material) {
|
||||
material.setModifier(currentUsername());
|
||||
return materialService.saveMaterial(material);
|
||||
}
|
||||
|
||||
@Log(value = "保存或更新物料", module = "物料管理")
|
||||
@PostMapping("/saveOrUpdate")
|
||||
public boolean saveOrUpdate(@RequestBody Material material) {
|
||||
material.setModifier(currentUsername());
|
||||
@ -51,6 +54,7 @@ public class MaterialController {
|
||||
* @param material 物料对象
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Log(value = "编辑物料", module = "物料管理")
|
||||
@PutMapping
|
||||
public boolean update(@RequestBody Material material) {
|
||||
material.setModifier(currentUsername());
|
||||
@ -65,6 +69,7 @@ public class MaterialController {
|
||||
* @param id 物料ID
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "删除物料", module = "物料管理")
|
||||
@DeleteMapping("/{id}")
|
||||
public boolean delete(@PathVariable String id) {
|
||||
return materialService.removeById(id);
|
||||
@ -77,6 +82,7 @@ public class MaterialController {
|
||||
* @param ids 物料ID列表
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "批量删除物料", module = "物料管理")
|
||||
@DeleteMapping
|
||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||
return materialService.removeByIds(ids);
|
||||
@ -91,6 +97,7 @@ public class MaterialController {
|
||||
* @param file Excel/CSV 文件
|
||||
* @return 是否导入成功
|
||||
*/
|
||||
@Log(value = "导入物料", module = "物料管理")
|
||||
@PostMapping("/import")
|
||||
public boolean importMaterials(@RequestParam("file") MultipartFile file) {
|
||||
return materialService.importMaterials(file);
|
||||
|
||||
@ -9,6 +9,7 @@ import com.yfd.business.css.service.ModelTrainService;
|
||||
import com.yfd.platform.config.ResponseResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.Map;
|
||||
@ -26,6 +27,7 @@ public class ModelTrainController {
|
||||
/**
|
||||
* 上传数据集
|
||||
*/
|
||||
@Log(value = "上传训练数据集", module = "模型训练")
|
||||
@PostMapping("/upload")
|
||||
public ResponseResult upload(@RequestParam("file") MultipartFile file) {
|
||||
String path = modelTrainService.uploadDataset(file);
|
||||
@ -35,6 +37,7 @@ public class ModelTrainController {
|
||||
/**
|
||||
* 提交训练任务 (支持文件上传和 JSON 参数)
|
||||
*/
|
||||
@Log(value = "提交训练任务", module = "模型训练")
|
||||
@PostMapping("/submit")
|
||||
public ResponseResult submit(@RequestPart("task") String taskJson,
|
||||
@RequestPart(value = "file", required = false) MultipartFile file) {
|
||||
@ -107,6 +110,7 @@ public class ModelTrainController {
|
||||
/**
|
||||
* 发布模型
|
||||
*/
|
||||
@Log(value = "发布训练模型", module = "模型训练")
|
||||
@PostMapping("/publish")
|
||||
public ResponseResult publish(@RequestBody Map<String, String> body) {
|
||||
String taskId = body.get("taskId");
|
||||
@ -118,6 +122,7 @@ public class ModelTrainController {
|
||||
/**
|
||||
* 删除训练任务
|
||||
*/
|
||||
@Log(value = "删除训练任务", module = "模型训练")
|
||||
@DeleteMapping("/{taskId}")
|
||||
public ResponseResult delete(@PathVariable String taskId) {
|
||||
boolean success = modelTrainService.removeById(taskId);
|
||||
|
||||
@ -14,6 +14,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
@ -40,6 +41,7 @@ public class ProjectController {
|
||||
* @param project 项目对象
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Log(value = "新增项目", module = "项目管理")
|
||||
@PostMapping
|
||||
@Operation(summary = "新增项目", description = "请求体传入项目对象,返回是否新增成功")
|
||||
public boolean create(@RequestBody Project project) {
|
||||
@ -54,6 +56,7 @@ public class ProjectController {
|
||||
* @param project 项目对象
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Log(value = "修改项目", module = "项目管理")
|
||||
@PutMapping
|
||||
@Operation(summary = "修改项目", description = "请求体传入项目对象(需包含主键),返回是否修改成功")
|
||||
public boolean update(@RequestBody Project project) {
|
||||
@ -81,6 +84,7 @@ public class ProjectController {
|
||||
* @param id 项目ID
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "删除项目", module = "项目管理")
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "删除项目(单条)", description = "根据项目ID删除项目")
|
||||
public boolean delete(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
||||
@ -94,6 +98,7 @@ public class ProjectController {
|
||||
* @param ids 项目ID列表
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "批量删除项目", module = "项目管理")
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除项目(批量)", description = "请求体传入项目ID列表,批量删除项目")
|
||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||
@ -108,6 +113,7 @@ public class ProjectController {
|
||||
* 导出列:project_id, code, name, description, topology,created_at, updated_at,modifier
|
||||
* @return 附件响应,文件名为 projects.xlsx
|
||||
*/
|
||||
@Log(value = "导出所有项目", module = "项目管理")
|
||||
@GetMapping("/exportAllExports")
|
||||
@Operation(summary = "导出所有项目(Excel)", description = "返回所有项目的 Excel 附件 projects.xlsx")
|
||||
public ResponseEntity<byte[]> exportAllExports() {
|
||||
@ -132,6 +138,7 @@ public class ProjectController {
|
||||
* @param id 项目ID
|
||||
* @return 附件响应,文件名为 project_{id}.xlsx
|
||||
*/
|
||||
@Log(value = "导出项目工程", module = "项目管理")
|
||||
@GetMapping("/{id}/exportProject")
|
||||
@Operation(summary = "导出项目工程(多Sheet)", description = "根据项目ID导出工程数据,返回 Excel 附件 project_{id}.xlsx")
|
||||
public ResponseEntity<byte[]> exportProjectExcel(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
||||
@ -185,6 +192,7 @@ public class ProjectController {
|
||||
* @param requestBody 请求体,需包含 topology 字段
|
||||
* @return 标准响应结构
|
||||
*/
|
||||
@Log(value = "更新项目拓扑", module = "项目管理")
|
||||
@PutMapping("/{id}/topology")
|
||||
@Operation(summary = "更新项目拓扑结构", description = "请求体需包含合法的 topology JSON(对象或字符串)")
|
||||
public ResponseEntity<Map<String, Object>> updateTopology(@PathVariable @Parameter(description = "项目ID", required = true) String id,
|
||||
|
||||
@ -8,6 +8,7 @@ import com.yfd.platform.system.service.IUserService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
@ -30,6 +31,7 @@ public class ScenarioController {
|
||||
* @param scenario 情景对象
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Log(value = "新增情景", module = "情景管理")
|
||||
@PostMapping
|
||||
public boolean create(@RequestBody Scenario scenario) {
|
||||
scenario.setModifier(currentUsername());
|
||||
@ -46,6 +48,7 @@ public class ScenarioController {
|
||||
* @param scenario 情景对象
|
||||
* @return 标准响应结构
|
||||
*/
|
||||
@Log(value = "新增情景并返回", module = "情景管理")
|
||||
@PostMapping("/createAndReturn")
|
||||
public java.util.Map<String, Object> createAndReturn(@RequestBody Scenario scenario) {
|
||||
scenario.setModifier(currentUsername());
|
||||
@ -66,6 +69,7 @@ public class ScenarioController {
|
||||
* @param scenario 情景对象
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Log(value = "修改情景", module = "情景管理")
|
||||
@PutMapping
|
||||
public boolean update(@RequestBody Scenario scenario) {
|
||||
scenario.setModifier(currentUsername());
|
||||
@ -80,6 +84,7 @@ public class ScenarioController {
|
||||
* @param id 情景ID
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "删除情景", module = "情景管理")
|
||||
@DeleteMapping("/{id}")
|
||||
public boolean delete(@PathVariable String id) {
|
||||
return scenarioService.removeById(id);
|
||||
@ -92,6 +97,7 @@ public class ScenarioController {
|
||||
* @param ids 情景ID列表
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Log(value = "批量删除情景", module = "情景管理")
|
||||
@DeleteMapping
|
||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||
return scenarioService.removeByIds(ids);
|
||||
|
||||
@ -10,6 +10,7 @@ import com.yfd.business.css.service.SimService;
|
||||
import com.yfd.business.css.service.SimInferService;
|
||||
import com.yfd.platform.config.ResponseResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.yfd.platform.annotation.Log;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@ -37,6 +38,7 @@ public class SimController {
|
||||
* @param req 请求参数,包含 projectId, scenarioId, steps
|
||||
* @return 仿真结果,包含 code, msg, data (data.frames)
|
||||
*/
|
||||
@Log(value = "执行仿真计算", module = "仿真计算")
|
||||
@PostMapping("/run")
|
||||
public ResponseResult run(@RequestBody Map<String, Object> req) {
|
||||
String projectId = (String) req.get("projectId");
|
||||
|
||||
@ -26,6 +26,16 @@ public interface AlgorithmModelService extends IService<AlgorithmModel> {
|
||||
*/
|
||||
String getCurrentModelPath(String algorithmType, String deviceType, String materialType);
|
||||
|
||||
/**
|
||||
* 根据算法类型、设备类型、材料类型,获取当前激活的模型对象
|
||||
*
|
||||
* @param algorithmType 算法类型
|
||||
* @param deviceType 设备类型
|
||||
* @param materialType 材料类型(如Pu/U)
|
||||
* @return 激活版本的模型对象
|
||||
*/
|
||||
AlgorithmModel getCurrentModel(String algorithmType, String deviceType, String materialType);
|
||||
|
||||
boolean deleteBatchWithCheck(List<String> ids);
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import com.yfd.business.css.model.InferResponse;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
@ -23,6 +24,7 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DeviceInferService {
|
||||
@Value("${python.api.url:http://localhost:8000}")
|
||||
@ -57,8 +59,9 @@ public class DeviceInferService {
|
||||
|
||||
// 全局算法类型
|
||||
String globalAlgorithmType = scenario.getAlgorithmType();
|
||||
if (globalAlgorithmType == null) {
|
||||
throw new IllegalArgumentException("场景 " + scenarioId + " 未配置全局算法类型");
|
||||
if (globalAlgorithmType == null || globalAlgorithmType.isBlank()) {
|
||||
log.warn("场景 {} 未配置全局算法类型,将默认使用 GPR", scenarioId);
|
||||
globalAlgorithmType = "GPR";
|
||||
}
|
||||
|
||||
// 解析设备级算法配置
|
||||
@ -67,7 +70,7 @@ public class DeviceInferService {
|
||||
try {
|
||||
deviceAlgoConfig = objectMapper.readValue(scenario.getDeviceAlgoConfig(), new TypeReference<Map<String, String>>() {});
|
||||
} catch (Exception e) {
|
||||
System.err.println("解析设备算法配置失败: " + e.getMessage());
|
||||
log.error("解析设备算法配置失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,31 +108,47 @@ public class DeviceInferService {
|
||||
String currentMaterialType = matEntry.getKey();
|
||||
List<DeviceStepInfo> batchDevices = matEntry.getValue();
|
||||
|
||||
// 获取模型路径(根据算法类型、设备类型、材料类型)
|
||||
System.out.println("Processing inference for algorithmType: " + currentAlgoType +
|
||||
", deviceType: " + deviceType + ", materialType: " + currentMaterialType);
|
||||
String modelRelPath = algorithmModelService.getCurrentModelPath(currentAlgoType, deviceType, currentMaterialType);
|
||||
System.out.println("modelRelPath=" + modelRelPath);
|
||||
// 获取模型对象(根据算法类型、设备类型、材料类型)
|
||||
log.info("Processing inference for algorithmType: {}, deviceType: {}, materialType: {}", currentAlgoType, deviceType, currentMaterialType);
|
||||
AlgorithmModel model = algorithmModelService.getCurrentModel(currentAlgoType, deviceType, currentMaterialType);
|
||||
|
||||
if (modelRelPath == null) {
|
||||
System.err.println("Model path not found for algorithmType: " + currentAlgoType +
|
||||
", deviceType: " + deviceType + ", materialType: " + currentMaterialType);
|
||||
if (model == null || model.getModelPath() == null) {
|
||||
log.error("Model path not found for algorithmType: {}, deviceType: {}, materialType: {}", currentAlgoType, deviceType, currentMaterialType);
|
||||
hasAnyError = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
String modelRelPath = model.getModelPath();
|
||||
log.debug("modelRelPath={}", modelRelPath);
|
||||
|
||||
// 解析模型的特征映射(feature_map_snapshot)以进行特征过滤
|
||||
List<String> requiredFeatures = new ArrayList<>();
|
||||
if (model.getFeatureMapSnapshot() != null && !model.getFeatureMapSnapshot().isBlank()) {
|
||||
try {
|
||||
// 解析 {"features": ["diameter", "height", ...]} 或者直接是一个 List
|
||||
JsonNode fNode = objectMapper.readTree(model.getFeatureMapSnapshot());
|
||||
if (fNode.isArray()) {
|
||||
for (JsonNode node : fNode) requiredFeatures.add(node.asText());
|
||||
} else if (fNode.has("features") && fNode.get("features").isArray()) {
|
||||
for (JsonNode node : fNode.get("features")) requiredFeatures.add(node.asText());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析特征映射快照失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 将相对路径转换为绝对路径
|
||||
String absoluteModelPath = Paths.get(modelRootPath).resolve(modelRelPath).toAbsolutePath().normalize().toString();
|
||||
System.out.println("Absolute modelPath=" + absoluteModelPath);
|
||||
log.debug("Absolute modelPath={}", absoluteModelPath);
|
||||
|
||||
// 封装推理请求
|
||||
InferRequest request = buildInferenceRequest(deviceType, batchDevices, absoluteModelPath);
|
||||
System.out.println("request=" + request);
|
||||
InferRequest request = buildInferenceRequest(deviceType, batchDevices, absoluteModelPath, requiredFeatures);
|
||||
log.debug("request={}", request);
|
||||
|
||||
try {
|
||||
// 调用Python推理服务
|
||||
InferResponse response = infer(request);
|
||||
System.out.println("推理服务返回结果: code=" + (response != null ? response.getCode() : "null"));
|
||||
log.info("推理服务返回结果: code={}", (response != null ? response.getCode() : "null"));
|
||||
|
||||
// 处理推理结果
|
||||
if (response != null && response.getCode() == 0) {
|
||||
@ -149,12 +168,11 @@ public class DeviceInferService {
|
||||
processInferenceResults(projectId, scenarioId, deviceType, batchDevices, reconstructedResponse);
|
||||
hasAnySuccess = true;
|
||||
} else {
|
||||
System.err.println("推理服务调用失败: " + (response != null ? response.getMsg() : "未知错误"));
|
||||
log.error("推理服务调用失败: {}", (response != null ? response.getMsg() : "未知错误"));
|
||||
hasAnyError = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("推理异常: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
log.error("推理异常: {}", e.getMessage(), e);
|
||||
hasAnyError = true;
|
||||
}
|
||||
}
|
||||
@ -167,7 +185,7 @@ public class DeviceInferService {
|
||||
}
|
||||
}
|
||||
|
||||
private InferRequest buildInferenceRequest(String deviceType,List<DeviceStepInfo> devices,String modelPath) {
|
||||
private InferRequest buildInferenceRequest(String deviceType,List<DeviceStepInfo> devices,String modelPath, List<String> requiredFeatures) {
|
||||
InferRequest request = new InferRequest();
|
||||
request.setModelDir(modelPath); // 设置模型路径
|
||||
request.setDeviceType(deviceType);
|
||||
@ -176,7 +194,22 @@ public class DeviceInferService {
|
||||
List<Map<String, Object>> batchData = new ArrayList<>();
|
||||
for (DeviceStepInfo device : devices) {
|
||||
Map<String, Object> deviceData = new HashMap<>();
|
||||
deviceData.put("features", device.getProperties());
|
||||
|
||||
// 特征过滤逻辑
|
||||
Map<String, Object> allProps = device.getProperties();
|
||||
Map<String, Object> filteredProps = new HashMap<>();
|
||||
|
||||
if (requiredFeatures != null && !requiredFeatures.isEmpty()) {
|
||||
for (String featureName : requiredFeatures) {
|
||||
// 如果设备属性中包含模型需要的特征,则提取;否则填 0 或抛出异常(这里选择填 0.0,具体看业务要求)
|
||||
filteredProps.put(featureName, allProps.getOrDefault(featureName, 0.0));
|
||||
}
|
||||
} else {
|
||||
// 如果模型没有保存特征快照,退退回发送全部属性
|
||||
filteredProps.putAll(allProps);
|
||||
}
|
||||
|
||||
deviceData.put("features", filteredProps);
|
||||
deviceData.put("meta", buildDeviceMeta(device));
|
||||
batchData.add(deviceData);
|
||||
}
|
||||
@ -228,7 +261,7 @@ public class DeviceInferService {
|
||||
|
||||
|
||||
scenarioResultService.saveBatch(inferenceResults);
|
||||
System.out.println("保存推理结果: " + inferenceResults.size() + " 条记录");
|
||||
log.info("保存推理结果: {} 条记录", inferenceResults.size());
|
||||
}
|
||||
|
||||
// 合并的Python推理调用方法
|
||||
|
||||
@ -2,6 +2,7 @@ package com.yfd.business.css.service;
|
||||
|
||||
import com.yfd.business.css.domain.Scenario;
|
||||
import com.yfd.business.css.model.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -14,6 +15,7 @@ import java.util.stream.Collectors;
|
||||
* 仿真推理服务
|
||||
* 负责将仿真计算结果 (SimContext) 转换为推理请求,并异步调用 Python 推理服务入库
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SimInferService {
|
||||
|
||||
@ -79,7 +81,7 @@ public class SimInferService {
|
||||
}
|
||||
|
||||
if (groupedDevices.isEmpty()) {
|
||||
System.out.println("No device data found for inference.");
|
||||
log.warn("No device data found for inference. scenarioId: {}", scenarioId);
|
||||
// 即使没有数据,也应该更新状态为完成,或者视为正常结束
|
||||
updateScenarioStatus(scenarioId, "2");
|
||||
return;
|
||||
@ -97,10 +99,10 @@ public class SimInferService {
|
||||
// 简单改进:如果 groupedDevices 非空,但所有组都因为找不到模型而跳过,应该视为失败吗?
|
||||
// 目前策略:只要没有抛出未捕获异常,就视为 Success。
|
||||
updateScenarioStatus(scenarioId, "2");
|
||||
log.info("Async inference completed successfully. scenarioId: {}", scenarioId);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Async inference failed: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
log.error("Async inference failed. scenarioId: {}, error: {}", scenarioId, e.getMessage(), e);
|
||||
// 5. 更新状态为失败 (假设 3 代表失败)
|
||||
updateScenarioStatus(scenarioId, "3");
|
||||
}
|
||||
@ -114,7 +116,7 @@ public class SimInferService {
|
||||
scenario.setUpdatedAt(LocalDateTime.now());
|
||||
scenarioService.updateById(scenario);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to update scenario status to " + status + ": " + e.getMessage());
|
||||
log.error("Failed to update scenario status to {}. scenarioId: {}, error: {}", status, scenarioId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.yfd.business.css.service;
|
||||
|
||||
import com.yfd.business.css.model.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -11,6 +12,7 @@ import java.util.Map;
|
||||
* 仿真核心计算引擎
|
||||
* 负责执行时间步推进,处理静态属性、事件输入、影响传播和强制覆盖
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SimService {
|
||||
|
||||
@ -30,6 +32,8 @@ public class SimService {
|
||||
|
||||
SimContext ctx = new SimContext();
|
||||
|
||||
log.info("Starting simulation... total steps: {}", steps);
|
||||
|
||||
// Step 1: 初始化静态基线 (t=0)
|
||||
// 将所有单元的静态属性写入初始上下文
|
||||
for (SimUnit unit : units) {
|
||||
@ -56,6 +60,7 @@ public class SimService {
|
||||
ctx.snapshot(step);
|
||||
}
|
||||
|
||||
log.info("Simulation finished.");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
@ -6,11 +6,13 @@ import com.yfd.business.css.domain.AlgorithmModel;
|
||||
import com.yfd.business.css.mapper.AlgorithmModelMapper;
|
||||
import com.yfd.business.css.service.AlgorithmModelService;
|
||||
import com.yfd.business.css.common.exception.BizException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
@Service
|
||||
public class AlgorithmModelServiceImpl extends ServiceImpl<AlgorithmModelMapper, AlgorithmModel> implements AlgorithmModelService {
|
||||
|
||||
@ -21,7 +23,7 @@ public class AlgorithmModelServiceImpl extends ServiceImpl<AlgorithmModelMapper,
|
||||
|
||||
@Override
|
||||
public String getCurrentModelPath(String algorithmType, String deviceType, String materialType) {
|
||||
System.out.println("Querying current model path for algorithmType: " + algorithmType + ", deviceType: " + deviceType + ", materialType: " + materialType);
|
||||
log.debug("Querying current model path for algorithmType: {}, deviceType: {}, materialType: {}", algorithmType, deviceType, materialType);
|
||||
QueryWrapper<AlgorithmModel> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("algorithm_type", algorithmType)
|
||||
.eq("device_type", deviceType)
|
||||
@ -39,10 +41,30 @@ public class AlgorithmModelServiceImpl extends ServiceImpl<AlgorithmModelMapper,
|
||||
List<AlgorithmModel> models = list(queryWrapper);
|
||||
if (models != null && !models.isEmpty()) {
|
||||
AlgorithmModel model = models.get(0);
|
||||
System.out.println("Found model: " + model.getModelPath());
|
||||
log.debug("Found model: {}", model.getModelPath());
|
||||
return model.getModelPath();
|
||||
} else {
|
||||
System.out.println("Model not found in database.");
|
||||
log.warn("Model not found in database for algorithmType: {}, deviceType: {}, materialType: {}", algorithmType, deviceType, materialType);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlgorithmModel getCurrentModel(String algorithmType, String deviceType, String materialType) {
|
||||
log.debug("Querying current model for algorithmType: {}, deviceType: {}, materialType: {}", algorithmType, deviceType, materialType);
|
||||
QueryWrapper<AlgorithmModel> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("algorithm_type", algorithmType)
|
||||
.eq("device_type", deviceType)
|
||||
.eq("is_current", 1); // 当前激活版本
|
||||
|
||||
if (materialType != null && !materialType.isEmpty()) {
|
||||
queryWrapper.eq("material_type", materialType);
|
||||
}
|
||||
|
||||
List<AlgorithmModel> models = list(queryWrapper);
|
||||
if (models != null && !models.isEmpty()) {
|
||||
return models.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.business.css.domain.Algorithm;
|
||||
import com.yfd.business.css.mapper.AlgorithmMapper;
|
||||
import com.yfd.business.css.service.AlgorithmService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class AlgorithmServiceImpl extends ServiceImpl<AlgorithmMapper, Algorithm> implements AlgorithmService {
|
||||
}
|
||||
@ -9,6 +9,7 @@ import com.yfd.platform.system.service.IUserService;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -30,6 +31,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DeviceServiceImpl
|
||||
extends ServiceImpl<DeviceMapper, Device>
|
||||
@ -42,16 +44,21 @@ public class DeviceServiceImpl
|
||||
public boolean importDevices(MultipartFile file, String deviceType) {
|
||||
try {
|
||||
String name = file.getOriginalFilename();
|
||||
log.info("device import start name={} size={} contentType={}", name, file.getSize(), file.getContentType());
|
||||
if (name == null) return false;
|
||||
String lower = name.toLowerCase();
|
||||
if (lower.endsWith(".xlsx")) {
|
||||
log.info("device detected type=xlsx");
|
||||
return importExcel(new XSSFWorkbook(file.getInputStream()), deviceType);
|
||||
} else if (lower.endsWith(".xls")) {
|
||||
log.info("device detected type=xls");
|
||||
return importExcel(new HSSFWorkbook(file.getInputStream()), deviceType);
|
||||
} else {
|
||||
log.warn("device unsupported file type name={}", name);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("device import failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -93,9 +100,15 @@ public class DeviceServiceImpl
|
||||
private boolean importExcel(Workbook workbook, String deviceType) {
|
||||
try (Workbook wb = workbook) {
|
||||
Sheet sheet = wb.getSheetAt(0);
|
||||
if (sheet == null) return false;
|
||||
if (sheet == null) {
|
||||
log.warn("device excel sheet null");
|
||||
return false;
|
||||
}
|
||||
Row headerRow = sheet.getRow(0);
|
||||
if (headerRow == null) return false;
|
||||
if (headerRow == null) {
|
||||
log.warn("device excel header row null");
|
||||
return false;
|
||||
}
|
||||
Map<String, Integer> idx = new HashMap<>();
|
||||
for (int i = 0; i < headerRow.getLastCellNum(); i++) {
|
||||
Cell c = headerRow.getCell(i);
|
||||
@ -103,9 +116,15 @@ public class DeviceServiceImpl
|
||||
String key = c.getStringCellValue();
|
||||
if (key != null) idx.put(key.trim().toLowerCase(), i);
|
||||
}
|
||||
log.info("device excel header keys={}", idx.keySet());
|
||||
String[] keys = new String[]{"code","name","size","volume","flow_rate","pulse_velocity"};
|
||||
List<String> missing = new ArrayList<>();
|
||||
for (String k : keys) {
|
||||
if (!idx.containsKey(k)) return false;
|
||||
if (!idx.containsKey(k)) missing.add(k);
|
||||
}
|
||||
if (!missing.isEmpty()) {
|
||||
log.warn("device excel missing headers={}", missing);
|
||||
return false;
|
||||
}
|
||||
List<Device> devices = new ArrayList<>();
|
||||
for (int r = 1; r <= sheet.getLastRowNum(); r++) {
|
||||
@ -123,12 +142,22 @@ public class DeviceServiceImpl
|
||||
d.setCreatedAt(LocalDateTime.now());
|
||||
d.setUpdatedAt(LocalDateTime.now());
|
||||
d.setModifier(currentUsername());
|
||||
if (isEmpty(d)) continue;
|
||||
if (isEmpty(d)) {
|
||||
log.warn("device excel skip empty row={}", r);
|
||||
continue;
|
||||
}
|
||||
devices.add(d);
|
||||
}
|
||||
if (devices.isEmpty()) return false;
|
||||
return this.saveBatch(devices);
|
||||
log.info("device excel parsed rows={} valid={}", sheet.getLastRowNum(), devices.size());
|
||||
if (devices.isEmpty()) {
|
||||
log.warn("device excel parsed list empty");
|
||||
return false;
|
||||
}
|
||||
boolean ok = this.saveBatch(devices);
|
||||
log.info("device excel saveBatch result={}", ok);
|
||||
return ok;
|
||||
} catch (Exception e) {
|
||||
log.error("device excel import failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.business.css.domain.Event;
|
||||
import com.yfd.business.css.mapper.EventMapper;
|
||||
import com.yfd.business.css.service.EventService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class EventServiceImpl
|
||||
extends ServiceImpl<EventMapper, Event>
|
||||
|
||||
@ -10,6 +10,7 @@ import com.yfd.platform.system.service.IUserService;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@ -32,6 +33,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MaterialServiceImpl
|
||||
extends ServiceImpl<MaterialMapper, Material>
|
||||
@ -44,16 +46,21 @@ public class MaterialServiceImpl
|
||||
public boolean importMaterials(MultipartFile file) {
|
||||
try {
|
||||
String name = file.getOriginalFilename();
|
||||
log.info("material import start name={} size={} contentType={}", name, file.getSize(), file.getContentType());
|
||||
if (name == null) return false;
|
||||
String lower = name.toLowerCase();
|
||||
if (lower.endsWith(".xlsx")) {
|
||||
log.info("material detected type=xlsx");
|
||||
return importExcel(new XSSFWorkbook(file.getInputStream()));
|
||||
} else if (lower.endsWith(".xls")) {
|
||||
log.info("material detected type=xls");
|
||||
return importExcel(new HSSFWorkbook(file.getInputStream()));
|
||||
} else {
|
||||
log.warn("material unsupported file type name={}", name);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("material import failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -95,9 +102,15 @@ public class MaterialServiceImpl
|
||||
private boolean importExcel(Workbook workbook) {
|
||||
try (Workbook wb = workbook) {
|
||||
Sheet sheet = wb.getSheetAt(0);
|
||||
if (sheet == null) return false;
|
||||
if (sheet == null) {
|
||||
log.warn("material excel sheet null");
|
||||
return false;
|
||||
}
|
||||
Row headerRow = sheet.getRow(0);
|
||||
if (headerRow == null) return false;
|
||||
if (headerRow == null) {
|
||||
log.warn("material excel header row null");
|
||||
return false;
|
||||
}
|
||||
Map<String, Integer> idx = new HashMap<>();
|
||||
for (int i = 0; i < headerRow.getLastCellNum(); i++) {
|
||||
Cell c = headerRow.getCell(i);
|
||||
@ -105,14 +118,20 @@ public class MaterialServiceImpl
|
||||
String key = c.getStringCellValue();
|
||||
if (key != null) idx.put(key.trim().toLowerCase(), i);
|
||||
}
|
||||
log.info("material excel header keys={}", idx.keySet());
|
||||
String[] keys = new String[]{
|
||||
"name","u_concentration","uo2_density","u_enrichment",
|
||||
"pu_concentration","puo2_density","pu_isotope",
|
||||
"hno3_acidity","h2c2o4_concentration","organic_ratio",
|
||||
"moisture_content","custom_attrs"
|
||||
};
|
||||
List<String> missing = new ArrayList<>();
|
||||
for (String k : keys) {
|
||||
if (!idx.containsKey(k)) return false;
|
||||
if (!idx.containsKey(k)) missing.add(k);
|
||||
}
|
||||
if (!missing.isEmpty()) {
|
||||
log.warn("material excel missing headers={}", missing);
|
||||
return false;
|
||||
}
|
||||
List<Material> list = new ArrayList<>();
|
||||
for (int r = 1; r <= sheet.getLastRowNum(); r++) {
|
||||
@ -135,12 +154,22 @@ public class MaterialServiceImpl
|
||||
m.setCreatedAt(LocalDateTime.now());
|
||||
m.setUpdatedAt(LocalDateTime.now());
|
||||
m.setModifier(currentUsername());
|
||||
if (isEmpty(m)) continue;
|
||||
if (isEmpty(m)) {
|
||||
log.warn("material excel skip empty row={}", r);
|
||||
continue;
|
||||
}
|
||||
list.add(m);
|
||||
}
|
||||
if (list.isEmpty()) return false;
|
||||
return this.saveBatch(list);
|
||||
log.info("material excel parsed rows={} valid={}", sheet.getLastRowNum(), list.size());
|
||||
if (list.isEmpty()) {
|
||||
log.warn("material excel parsed list empty");
|
||||
return false;
|
||||
}
|
||||
boolean ok = this.saveBatch(list);
|
||||
log.info("material excel saveBatch result={}", ok);
|
||||
return ok;
|
||||
} catch (Exception e) {
|
||||
log.error("material excel import failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import com.yfd.business.css.domain.ModelTrainTask;
|
||||
import com.yfd.business.css.mapper.ModelTrainTaskMapper;
|
||||
import com.yfd.business.css.service.AlgorithmModelService;
|
||||
import com.yfd.business.css.service.ModelTrainService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
@ -36,6 +37,7 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, ModelTrainTask> implements ModelTrainService {
|
||||
|
||||
@ -144,7 +146,7 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
||||
Map<String, Object> params = objectMapper.readValue(task.getTrainParams(), new TypeReference<Map<String, Object>>() {});
|
||||
request.put("hyperparameters", params);
|
||||
} catch (Exception e) {
|
||||
System.err.println("解析训练参数失败,将作为原始字符串发送: " + e.getMessage());
|
||||
log.error("解析训练参数失败,将作为原始字符串发送: {}", e.getMessage());
|
||||
request.put("hyperparameters", task.getTrainParams());
|
||||
}
|
||||
} else {
|
||||
@ -162,9 +164,9 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
||||
Map body = response.getBody();
|
||||
if (body != null) {
|
||||
try {
|
||||
System.out.println("训练服务响应: " + objectMapper.writeValueAsString(body));
|
||||
log.debug("训练服务响应: {}", objectMapper.writeValueAsString(body));
|
||||
} catch (JsonProcessingException ignored) {
|
||||
System.out.println("训练服务响应: " + body);
|
||||
log.debug("训练服务响应: {}", body);
|
||||
}
|
||||
Object codeObj = body.get("code");
|
||||
Integer code = null;
|
||||
@ -183,7 +185,7 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
||||
return;
|
||||
}
|
||||
}
|
||||
System.out.println("训练任务提交成功: " + task.getTaskId());
|
||||
log.info("训练任务提交成功: {}", task.getTaskId());
|
||||
} else {
|
||||
task.setStatus("Failed");
|
||||
task.setErrorLog("提交训练任务失败: " + response.getStatusCode());
|
||||
@ -194,7 +196,7 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
||||
task.setStatus("Failed");
|
||||
task.setErrorLog("调用 Python 服务异常: " + e.getMessage());
|
||||
this.updateById(task);
|
||||
e.printStackTrace();
|
||||
log.error("调用 Python 训练服务异常: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,7 +287,7 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("同步任务状态失败: " + e.getMessage());
|
||||
log.error("同步任务状态失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,7 +379,7 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 附加文件复制失败不应阻断发布主流程,仅记录日志
|
||||
System.err.println("复制附加训练文件失败: " + e.getMessage());
|
||||
log.warn("复制附加训练文件失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.business.css.domain.Project;
|
||||
import com.yfd.business.css.mapper.ProjectMapper;
|
||||
import com.yfd.business.css.service.ProjectService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
@ -45,6 +46,7 @@ import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ProjectServiceImpl
|
||||
extends ServiceImpl<ProjectMapper, Project>
|
||||
@ -73,6 +75,7 @@ public class ProjectServiceImpl
|
||||
|
||||
@Override
|
||||
public byte[] exportAllProjectsExcel() {
|
||||
log.info("exportAllProjectsExcel start");
|
||||
try (Workbook wb = new XSSFWorkbook(); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
List<Project> list = this.list(new QueryWrapper<Project>().orderByDesc("created_at"));
|
||||
Sheet sheet = wb.createSheet("projects");
|
||||
@ -96,6 +99,7 @@ public class ProjectServiceImpl
|
||||
wb.write(out);
|
||||
return out.toByteArray();
|
||||
} catch (Exception e) {
|
||||
log.error("exportAllProjectsExcel error", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@ -107,6 +111,7 @@ public class ProjectServiceImpl
|
||||
* @return TopologyParseResult
|
||||
*/
|
||||
public TopologyParseResult parseTopology(String projectId) {
|
||||
log.info("parseTopology start projectId={}", projectId);
|
||||
try {
|
||||
Project p = this.getById(projectId);
|
||||
TopologyParseResult r = new TopologyParseResult();
|
||||
@ -253,6 +258,7 @@ public class ProjectServiceImpl
|
||||
r.setEdgeCount(edges.size());
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
log.error("parseTopology error projectId={}", projectId, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@ -369,6 +375,7 @@ public class ProjectServiceImpl
|
||||
|
||||
@Override
|
||||
public List<Device> parseDeviceOrder(String projectId) {
|
||||
log.info("parseDeviceOrder start projectId={}", projectId);
|
||||
try {
|
||||
Project p = this.getById(projectId);
|
||||
List<Device> devices = new ArrayList<>();
|
||||
@ -394,6 +401,7 @@ public class ProjectServiceImpl
|
||||
}
|
||||
return devices;
|
||||
} catch (Exception e) {
|
||||
log.error("parseDeviceOrder error projectId={}", projectId, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@ -405,6 +413,7 @@ public class ProjectServiceImpl
|
||||
* @return Map 视图对象
|
||||
*/
|
||||
public Map<String, Object> parseCanvasView(String projectId) {
|
||||
log.info("parseCanvasView start projectId={}", projectId);
|
||||
try {
|
||||
Project p = this.getById(projectId);
|
||||
Map<String, Object> res = new HashMap<>();
|
||||
@ -511,12 +520,14 @@ public class ProjectServiceImpl
|
||||
}
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
log.error("parseCanvasView error projectId={}", projectId, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> parseDeviceOrderWithMaterials(String projectId) {
|
||||
log.info("parseDeviceOrderWithMaterials start projectId={}", projectId);
|
||||
try {
|
||||
Project p = this.getById(projectId);
|
||||
List<Map<String, Object>> out = new ArrayList<>();
|
||||
@ -607,12 +618,14 @@ public class ProjectServiceImpl
|
||||
}
|
||||
return out;
|
||||
} catch (Exception e) {
|
||||
log.error("parseDeviceOrderWithMaterials error projectId={}", projectId, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> initSimulation(String projectId, String scenarioId, Map<String, Object> params) {
|
||||
log.info("initSimulation start projectId={} scenarioId={}", projectId, scenarioId);
|
||||
//改变场景状态
|
||||
Scenario scenario = new Scenario();
|
||||
scenario.setScenarioId(scenarioId);
|
||||
@ -767,6 +780,7 @@ public class ProjectServiceImpl
|
||||
out.put("frames", frames);
|
||||
return out;
|
||||
} catch (Exception ex) {
|
||||
log.error("initSimulation error projectId={} scenarioId={}", projectId, scenarioId, ex);
|
||||
issues.add("初始化失败:" + ex.getMessage());
|
||||
out.put("generated", Map.of("events", 0, "snapshots", 0));
|
||||
out.put("frames", frames);
|
||||
@ -1297,6 +1311,7 @@ public class ProjectServiceImpl
|
||||
//运行项目模拟
|
||||
@Override
|
||||
public java.util.Map<String, Object> runSimulation(String projectId, String scenarioId, java.util.Map<String, Object> params) {
|
||||
log.info("runSimulation start projectId={} scenarioId={}", projectId, scenarioId);
|
||||
//1. 校验项目是否存在
|
||||
Project project = this.getOne(new LambdaQueryWrapper<Project>().eq(Project::getProjectId, projectId));
|
||||
if (project == null) throw new IllegalArgumentException("项目不存在");
|
||||
@ -1318,10 +1333,10 @@ public class ProjectServiceImpl
|
||||
throw new RuntimeException("模拟参数序列化失败", e);
|
||||
}
|
||||
// 解析并按设备类型分组,后续批量推理将依赖此结果
|
||||
System.out.println("projectId="+projectId);
|
||||
System.out.println("scenarioId="+scenarioId);
|
||||
System.out.println("params="+params);
|
||||
System.out.println("jsonParams="+jsonParams);
|
||||
log.debug("projectId={}", projectId);
|
||||
log.debug("scenarioId={}", scenarioId);
|
||||
log.debug("params={}", params);
|
||||
log.debug("jsonParams={}", jsonParams);
|
||||
|
||||
// jsonParams ="{\"data\":{\"frames\":[{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":160.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":160.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":20.0,\"u_enrichment\":0.01,\"height\":20.0,\"u_concentration\":20.0}},\"step\":0,\"time\":0},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":170.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":170.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":50.0,\"u_enrichment\":0.01,\"height\":50.0,\"u_concentration\":20.0}},\"step\":1,\"time\":2},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":180.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":180.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":70.0,\"u_enrichment\":0.01,\"height\":70.0,\"u_concentration\":20.0}},\"step\":2,\"time\":4},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":190.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":190.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":100.0,\"u_enrichment\":0.01,\"height\":100.0,\"u_concentration\":20.0}},\"step\":3,\"time\":6},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":200.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":200.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":120.0,\"u_enrichment\":0.01,\"height\":120.0,\"u_concentration\":20.0}},\"step\":4,\"time\":8},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":210.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":210.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":150.0,\"u_enrichment\":0.01,\"height\":150.0,\"u_concentration\":20.0}},\"step\":5,\"time\":10},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":220.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":220.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":200.0,\"u_enrichment\":0.01,\"height\":200.0,\"u_concentration\":20.0}},\"step\":6,\"time\":12},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":230.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":230.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":220.0,\"u_enrichment\":0.01,\"height\":220.0,\"u_concentration\":20.0}},\"step\":7,\"time\":14},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":240.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":240.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":250.0,\"u_enrichment\":0.01,\"height\":250.0,\"u_concentration\":20.0}},\"step\":8,\"time\":16},{\"devices\":{\"dev-003-uuid\":{\"deviceType\":\"AnnularTank\",\"diameter\":250.0,\"pu_isotope\":0.13,\"pu_concentration\":20.0,\"height\":250.0},\"dev-002-uuid\":{\"deviceType\":\"CylindricalTank\",\"diameter\":300.0,\"u_enrichment\":0.01,\"height\":300.0,\"u_concentration\":20.0}},\"step\":9,\"time\":18}],\"generated\":{\"snapshots\":20,\"events\":2},\"projectId\":\"proj-0001-uuid\",\"scenarioId\":\"scen-001-uuid\",\"issues\":[]}}";
|
||||
|
||||
@ -1332,11 +1347,10 @@ public class ProjectServiceImpl
|
||||
|
||||
// 输出结果
|
||||
for (Map.Entry<String, List<DeviceStepInfo>> entry : groupedDevices.entrySet()) {
|
||||
System.out.println("Device Type: " + entry.getKey());
|
||||
log.debug("Device Type: {}", entry.getKey());
|
||||
for (DeviceStepInfo device : entry.getValue()) {
|
||||
System.out.println(" " + device);
|
||||
log.debug(" {}", device);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
//6. 调用模型进行推理,把结果写入推理结果表
|
||||
deviceInferService.processDeviceInference(projectId, scenarioId, groupedDevices);
|
||||
|
||||
@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.business.css.domain.ScenarioResult;
|
||||
import com.yfd.business.css.mapper.ScenarioResultMapper;
|
||||
import com.yfd.business.css.service.ScenarioResultService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ScenarioResultServiceImpl
|
||||
extends ServiceImpl<ScenarioResultMapper, ScenarioResult>
|
||||
|
||||
@ -4,16 +4,20 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.business.css.domain.Scenario;
|
||||
import com.yfd.business.css.mapper.ScenarioMapper;
|
||||
import com.yfd.business.css.service.ScenarioService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ScenarioServiceImpl
|
||||
extends ServiceImpl<ScenarioMapper, Scenario>
|
||||
implements ScenarioService {
|
||||
@Override
|
||||
public String getAlgorithmType(String scenarioId) {
|
||||
log.debug("getAlgorithmType for scenarioId={}", scenarioId);
|
||||
Scenario scenario = baseMapper.selectById(scenarioId);
|
||||
if (scenario == null) {
|
||||
log.warn("getAlgorithmType scenario not found id={}", scenarioId);
|
||||
return null;
|
||||
}
|
||||
return scenario.getAlgorithmType();
|
||||
|
||||
@ -3,20 +3,24 @@ package com.yfd.business.css.service.impl;
|
||||
import com.yfd.business.css.model.SimulationRequest;
|
||||
import com.yfd.business.css.model.SimulationResult;
|
||||
import com.yfd.business.css.service.SimulationService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SimulationServiceImpl implements SimulationService {
|
||||
@Override
|
||||
public SimulationResult runSimulation(SimulationRequest request) {
|
||||
log.info("SimulationServiceImpl runSimulation start request={}", request);
|
||||
// TODO: 引入 framework 公共模块的算法与工具进行真实计算
|
||||
SimulationResult result = new SimulationResult();
|
||||
result.setScenarioName(request.getScenarioName());
|
||||
result.setStartTime(Instant.now().toString());
|
||||
result.setStatus("SUCCESS");
|
||||
result.setSummary("占位结果:根据输入参数完成快速估算");
|
||||
log.info("SimulationServiceImpl runSimulation finish status={}", result.getStatus());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -353,6 +353,9 @@
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>exec</classifier>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
@ -75,9 +75,21 @@ public class LogAspect {
|
||||
SysLog log = new SysLog("INFO");
|
||||
currentTime.remove();
|
||||
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
||||
|
||||
// 修复:不直接依赖 userService.getNameInfo(),防止匿名用户转换异常
|
||||
String nickname = "匿名用户";
|
||||
String username = getUsername(); // 调用本类包装好的获取用户名方法
|
||||
if (StringUtils.isNotBlank(username)) {
|
||||
try {
|
||||
Map<String, String> nameInfo = userService.getNameInfo();
|
||||
String nickname = nameInfo.get("nickname");
|
||||
String username = nameInfo.get("username");
|
||||
nickname = nameInfo.get("nickname");
|
||||
username = nameInfo.get("username");
|
||||
} catch (Exception e) {
|
||||
// 如果发生异常(比如不是 UsernamePasswordAuthenticationToken),则回退使用 username
|
||||
nickname = username;
|
||||
}
|
||||
}
|
||||
|
||||
sysLogService.save(nickname, username, StringUtils.getBrowser(request),
|
||||
StringUtils.getIp(request), joinPoint, log);
|
||||
return result;
|
||||
|
||||
@ -69,35 +69,56 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
|
||||
***********************************/
|
||||
@Override
|
||||
public String getUsername() {
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
try {
|
||||
Object auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth instanceof UsernamePasswordAuthenticationToken) {
|
||||
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) auth;
|
||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
||||
String acountname =
|
||||
loginuser.getUser().getNickname();
|
||||
return acountname;
|
||||
//return "admin";
|
||||
return loginuser.getUser().getNickname();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return "anonymous";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getNameInfo() {
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
try {
|
||||
Object auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth instanceof UsernamePasswordAuthenticationToken) {
|
||||
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) auth;
|
||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
||||
String nickname = loginuser.getUser().getNickname();
|
||||
String username = loginuser.getUser().getUsername();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("nickname", nickname);
|
||||
map.put("username", username);
|
||||
} else {
|
||||
map.put("nickname", "匿名用户");
|
||||
map.put("username", "anonymous");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
map.put("nickname", "匿名用户");
|
||||
map.put("username", "anonymous");
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUser getUserInfo() {
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
try {
|
||||
Object auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth instanceof UsernamePasswordAuthenticationToken) {
|
||||
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) auth;
|
||||
LoginUser loginuser = (LoginUser) authentication.getPrincipal();
|
||||
return loginuser.getUser();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseResult getLoginUserInfo() {
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
<configuration scan="true" scanPeriod="60 seconds">
|
||||
<!-- 通用变量 -->
|
||||
<property name="LOG_PATH" value="logs"/>
|
||||
<property name="LOG_FILE" value="platform"/>
|
||||
<!-- 从 application.yml 读取 spring.application.name,如果没有则默认叫 platform -->
|
||||
<springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="platform"/>
|
||||
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
|
||||
|
||||
<!-- 控制台输出:强制 UTF-8 编码 -->
|
||||
@ -15,13 +16,13 @@
|
||||
|
||||
<!-- 文件输出:滚动日志,UTF-8 编码 -->
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_PATH}/${LOG_FILE}.log</file>
|
||||
<file>${LOG_PATH}/${APP_NAME}.log</file>
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<charset>UTF-8</charset>
|
||||
<pattern>${LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/${LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<fileNamePattern>${LOG_PATH}/${APP_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user