项目权限
This commit is contained in:
parent
86c7d1c7a9
commit
f59dd61da4
@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||||
|
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
@ -45,6 +46,7 @@ public class AlgorithmController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "新增算法", module = "算法管理")
|
@Log(value = "新增算法", module = "算法管理")
|
||||||
|
// @PreAuthorize("hasAuthority('algorithm:add')")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@Operation(summary = "新增算法", description = "请求体传入算法对象,返回是否新增成功")
|
@Operation(summary = "新增算法", description = "请求体传入算法对象,返回是否新增成功")
|
||||||
public boolean createAlgorithm(@RequestBody Algorithm algorithm) {
|
public boolean createAlgorithm(@RequestBody Algorithm algorithm) {
|
||||||
@ -55,6 +57,7 @@ public class AlgorithmController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "修改算法", module = "算法管理")
|
@Log(value = "修改算法", module = "算法管理")
|
||||||
|
// @PreAuthorize("hasAuthority('algorithm:update')")
|
||||||
@PutMapping
|
@PutMapping
|
||||||
@Operation(summary = "修改算法", description = "请求体传入算法对象(需包含主键),返回是否修改成功")
|
@Operation(summary = "修改算法", description = "请求体传入算法对象(需包含主键),返回是否修改成功")
|
||||||
public boolean updateAlgorithm(@RequestBody Algorithm algorithm) {
|
public boolean updateAlgorithm(@RequestBody Algorithm algorithm) {
|
||||||
@ -64,6 +67,7 @@ public class AlgorithmController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "删除算法", module = "算法管理")
|
@Log(value = "删除算法", module = "算法管理")
|
||||||
|
// @PreAuthorize("hasAuthority('algorithm:delete')")
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
@Operation(summary = "删除算法(单条)", description = "根据算法ID删除算法")
|
@Operation(summary = "删除算法(单条)", description = "根据算法ID删除算法")
|
||||||
public boolean deleteAlgorithm(@PathVariable String id) {
|
public boolean deleteAlgorithm(@PathVariable String id) {
|
||||||
@ -71,6 +75,7 @@ public class AlgorithmController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "批量删除算法", module = "算法管理")
|
@Log(value = "批量删除算法", module = "算法管理")
|
||||||
|
// @PreAuthorize("hasAuthority('algorithm:deleteBatch')")
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
@Operation(summary = "删除算法(批量)", description = "请求体传入算法ID列表,批量删除算法")
|
@Operation(summary = "删除算法(批量)", description = "请求体传入算法ID列表,批量删除算法")
|
||||||
public boolean deleteAlgorithms(@RequestBody List<String> ids) {
|
public boolean deleteAlgorithms(@RequestBody List<String> ids) {
|
||||||
@ -78,7 +83,7 @@ public class AlgorithmController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "激活算法", module = "算法管理")
|
@Log(value = "激活算法", module = "算法管理")
|
||||||
//算法类型激活
|
// @PreAuthorize("hasAuthority('algorithm:activate')")
|
||||||
@PostMapping("/activate")
|
@PostMapping("/activate")
|
||||||
@Operation(summary = "激活算法", description = "激活当前算法类型")
|
@Operation(summary = "激活算法", description = "激活当前算法类型")
|
||||||
public boolean activate(@RequestParam String algorithmId) {
|
public boolean activate(@RequestParam String algorithmId) {
|
||||||
@ -92,7 +97,7 @@ public class AlgorithmController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "关闭算法", module = "算法管理")
|
@Log(value = "关闭算法", module = "算法管理")
|
||||||
//算法类型关闭
|
// @PreAuthorize("hasAuthority('algorithm:unactivate')")
|
||||||
@PostMapping("/unactivate")
|
@PostMapping("/unactivate")
|
||||||
@Operation(summary = "关闭算法", description = "关闭当前算法类型")
|
@Operation(summary = "关闭算法", description = "关闭当前算法类型")
|
||||||
public boolean unactivate(@RequestParam String algorithmId) {
|
public boolean unactivate(@RequestParam String algorithmId) {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||||
|
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
@ -53,6 +54,7 @@ public class AlgorithmModelController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "新增模型版本", module = "算法模型管理")
|
@Log(value = "新增模型版本", module = "算法模型管理")
|
||||||
|
// @PreAuthorize("hasAuthority('algorithmModel:add')")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@Operation(summary = "新增模型版本", description = "请求体传入模型版本对象,返回是否新增成功")
|
@Operation(summary = "新增模型版本", description = "请求体传入模型版本对象,返回是否新增成功")
|
||||||
public boolean create(@RequestBody AlgorithmModel model) {
|
public boolean create(@RequestBody AlgorithmModel model) {
|
||||||
@ -63,6 +65,7 @@ public class AlgorithmModelController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "修改模型版本", module = "算法模型管理")
|
@Log(value = "修改模型版本", module = "算法模型管理")
|
||||||
|
// @PreAuthorize("hasAuthority('algorithmModel:update')")
|
||||||
@PutMapping
|
@PutMapping
|
||||||
@Operation(summary = "修改模型版本", description = "请求体传入模型版本对象(需包含主键),返回是否修改成功")
|
@Operation(summary = "修改模型版本", description = "请求体传入模型版本对象(需包含主键),返回是否修改成功")
|
||||||
public boolean update(@RequestBody AlgorithmModel model) {
|
public boolean update(@RequestBody AlgorithmModel model) {
|
||||||
@ -72,6 +75,7 @@ public class AlgorithmModelController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "删除模型版本", module = "算法模型管理")
|
@Log(value = "删除模型版本", module = "算法模型管理")
|
||||||
|
// @PreAuthorize("hasAuthority('algorithmModel:delete')")
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
@Operation(summary = "删除模型版本(单条)", description = "根据模型ID删除模型版本")
|
@Operation(summary = "删除模型版本(单条)", description = "根据模型ID删除模型版本")
|
||||||
public boolean delete(@PathVariable String id) {
|
public boolean delete(@PathVariable String id) {
|
||||||
@ -79,6 +83,7 @@ public class AlgorithmModelController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "批量删除模型版本", module = "算法模型管理")
|
@Log(value = "批量删除模型版本", module = "算法模型管理")
|
||||||
|
// @PreAuthorize("hasAuthority('algorithmModel:deleteBatch')")
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
@Operation(summary = "删除模型版本(批量)", description = "请求体传入模型ID列表,批量删除模型版本")
|
@Operation(summary = "删除模型版本(批量)", description = "请求体传入模型ID列表,批量删除模型版本")
|
||||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||||
@ -124,7 +129,7 @@ public class AlgorithmModelController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(value = "激活模型版本", module = "算法模型管理")
|
@Log(value = "激活模型版本", module = "算法模型管理")
|
||||||
//版本激活
|
@PreAuthorize("hasAuthority('algorithmModel:activate')")
|
||||||
@PostMapping("/activate")
|
@PostMapping("/activate")
|
||||||
@Operation(summary = "激活模型版本", description = "将目标模型版本设为当前,并将同组(算法+设备+材料)其他版本设为非当前")
|
@Operation(summary = "激活模型版本", description = "将目标模型版本设为当前,并将同组(算法+设备+材料)其他版本设为非当前")
|
||||||
public boolean activate(@RequestParam String algorithmModelId) {
|
public boolean activate(@RequestParam String algorithmModelId) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.yfd.business.css.controller;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.business.css.domain.Device;
|
import com.yfd.business.css.domain.Device;
|
||||||
|
import com.yfd.business.css.security.ProjectAccessHelper;
|
||||||
import com.yfd.business.css.service.DeviceService;
|
import com.yfd.business.css.service.DeviceService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -24,6 +25,8 @@ public class DeviceController {
|
|||||||
private DeviceService deviceService;
|
private DeviceService deviceService;
|
||||||
@Resource
|
@Resource
|
||||||
private IUserService userService;
|
private IUserService userService;
|
||||||
|
@Resource
|
||||||
|
private ProjectAccessHelper projectAccessHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. 新增设备
|
* 1. 新增设备
|
||||||
@ -35,6 +38,9 @@ public class DeviceController {
|
|||||||
@Log(value = "新增设备", module = "设备管理")
|
@Log(value = "新增设备", module = "设备管理")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public boolean create(@RequestBody Device device) {
|
public boolean create(@RequestBody Device device) {
|
||||||
|
if (device.getProjectId() != null && !device.getProjectId().isBlank() && !"-1".equals(device.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(device.getProjectId());
|
||||||
|
}
|
||||||
device.setModifier(currentUsername());
|
device.setModifier(currentUsername());
|
||||||
return deviceService.createDevice(device);
|
return deviceService.createDevice(device);
|
||||||
}
|
}
|
||||||
@ -42,6 +48,9 @@ public class DeviceController {
|
|||||||
@Log(value = "保存或更新设备", module = "设备管理")
|
@Log(value = "保存或更新设备", module = "设备管理")
|
||||||
@PostMapping("/saveOrUpdate")
|
@PostMapping("/saveOrUpdate")
|
||||||
public boolean saveOrUpdate(@RequestBody Device device) {
|
public boolean saveOrUpdate(@RequestBody Device device) {
|
||||||
|
if (device.getProjectId() != null && !device.getProjectId().isBlank() && !"-1".equals(device.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(device.getProjectId());
|
||||||
|
}
|
||||||
device.setModifier(currentUsername());
|
device.setModifier(currentUsername());
|
||||||
return deviceService.saveOrUpdateByBusiness(device);
|
return deviceService.saveOrUpdateByBusiness(device);
|
||||||
}
|
}
|
||||||
@ -56,6 +65,12 @@ public class DeviceController {
|
|||||||
@Log(value = "编辑设备", module = "设备管理")
|
@Log(value = "编辑设备", module = "设备管理")
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public boolean update(@RequestBody Device device) {
|
public boolean update(@RequestBody Device device) {
|
||||||
|
if (device.getDeviceId() != null && !device.getDeviceId().isBlank()) {
|
||||||
|
Device db = deviceService.getById(device.getDeviceId());
|
||||||
|
if (db != null && db.getProjectId() != null && !db.getProjectId().isBlank() && !"-1".equals(db.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(db.getProjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
device.setModifier(currentUsername());
|
device.setModifier(currentUsername());
|
||||||
device.setUpdatedAt(LocalDateTime.now());
|
device.setUpdatedAt(LocalDateTime.now());
|
||||||
return deviceService.updateById(device);
|
return deviceService.updateById(device);
|
||||||
@ -71,6 +86,10 @@ public class DeviceController {
|
|||||||
@Log(value = "删除设备", module = "设备管理")
|
@Log(value = "删除设备", module = "设备管理")
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public boolean delete(@PathVariable String id) {
|
public boolean delete(@PathVariable String id) {
|
||||||
|
Device db = deviceService.getById(id);
|
||||||
|
if (db != null && db.getProjectId() != null && !db.getProjectId().isBlank() && !"-1".equals(db.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(db.getProjectId());
|
||||||
|
}
|
||||||
return deviceService.removeById(id);
|
return deviceService.removeById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +103,14 @@ public class DeviceController {
|
|||||||
@Log(value = "批量删除设备", module = "设备管理")
|
@Log(value = "批量删除设备", module = "设备管理")
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||||
|
if (ids != null && !ids.isEmpty()) {
|
||||||
|
List<Device> list = deviceService.list(new QueryWrapper<Device>().in("device_id", ids));
|
||||||
|
for (Device d : list) {
|
||||||
|
if (d.getProjectId() != null && !d.getProjectId().isBlank() && !"-1".equals(d.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(d.getProjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return deviceService.removeByIds(ids);
|
return deviceService.removeByIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +140,9 @@ public class DeviceController {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/by-project")
|
@GetMapping("/by-project")
|
||||||
public List<Device> listByProject(@RequestParam String projectId) {
|
public List<Device> listByProject(@RequestParam String projectId) {
|
||||||
|
if (projectId != null && !projectId.isBlank() && !"-1".equals(projectId)) {
|
||||||
|
projectAccessHelper.assertCanReadProject(projectId);
|
||||||
|
}
|
||||||
return deviceService.list(
|
return deviceService.list(
|
||||||
new QueryWrapper<Device>()
|
new QueryWrapper<Device>()
|
||||||
.eq("project_id", projectId)
|
.eq("project_id", projectId)
|
||||||
|
|||||||
@ -2,7 +2,10 @@ package com.yfd.business.css.controller;
|
|||||||
|
|
||||||
import com.yfd.business.css.domain.Device;
|
import com.yfd.business.css.domain.Device;
|
||||||
import com.yfd.business.css.domain.Event;
|
import com.yfd.business.css.domain.Event;
|
||||||
|
import com.yfd.business.css.domain.Scenario;
|
||||||
|
import com.yfd.business.css.security.ProjectAccessHelper;
|
||||||
import com.yfd.business.css.service.EventService;
|
import com.yfd.business.css.service.EventService;
|
||||||
|
import com.yfd.business.css.service.ScenarioService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -40,6 +43,10 @@ public class EventController {
|
|||||||
private ObjectMapper objectMapper;
|
private ObjectMapper objectMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private IUserService userService;
|
private IUserService userService;
|
||||||
|
@Resource
|
||||||
|
private ScenarioService scenarioService;
|
||||||
|
@Resource
|
||||||
|
private ProjectAccessHelper projectAccessHelper;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,6 +55,7 @@ public class EventController {
|
|||||||
@Log(value = "新增始发事件", module = "事件管理")
|
@Log(value = "新增始发事件", module = "事件管理")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseEntity<Map<String, Object>> addEvent(@RequestBody Event event) {
|
public ResponseEntity<Map<String, Object>> addEvent(@RequestBody Event event) {
|
||||||
|
assertCanWriteByScenarioId(event.getScenarioId());
|
||||||
event.setModifier(currentUsername());
|
event.setModifier(currentUsername());
|
||||||
eventService.save(event);
|
eventService.save(event);
|
||||||
Event savedEvent = event;
|
Event savedEvent = event;
|
||||||
@ -69,6 +77,14 @@ public class EventController {
|
|||||||
@Log(value = "修改始发事件", module = "事件管理")
|
@Log(value = "修改始发事件", module = "事件管理")
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public boolean update(@RequestBody Event event) {
|
public boolean update(@RequestBody Event event) {
|
||||||
|
if (event.getScenarioId() != null && !event.getScenarioId().isBlank()) {
|
||||||
|
assertCanWriteByScenarioId(event.getScenarioId());
|
||||||
|
} else if (event.getEventId() != null && !event.getEventId().isBlank()) {
|
||||||
|
Event db = eventService.getById(event.getEventId());
|
||||||
|
if (db != null) {
|
||||||
|
assertCanWriteByScenarioId(db.getScenarioId());
|
||||||
|
}
|
||||||
|
}
|
||||||
event.setModifier(currentUsername());
|
event.setModifier(currentUsername());
|
||||||
event.setUpdatedAt(LocalDateTime.now());
|
event.setUpdatedAt(LocalDateTime.now());
|
||||||
return eventService.updateById(event);
|
return eventService.updateById(event);
|
||||||
@ -89,6 +105,14 @@ public class EventController {
|
|||||||
List<Event> savedEvents = new ArrayList<>();
|
List<Event> savedEvents = new ArrayList<>();
|
||||||
|
|
||||||
for (Event event : events) {
|
for (Event event : events) {
|
||||||
|
if (event.getScenarioId() != null && !event.getScenarioId().isBlank()) {
|
||||||
|
assertCanWriteByScenarioId(event.getScenarioId());
|
||||||
|
} else if (event.getEventId() != null && !event.getEventId().isBlank()) {
|
||||||
|
Event db = eventService.getById(event.getEventId());
|
||||||
|
if (db != null) {
|
||||||
|
assertCanWriteByScenarioId(db.getScenarioId());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (event.getEventId() != null && eventService.getById(event.getEventId()) != null) {
|
if (event.getEventId() != null && eventService.getById(event.getEventId()) != null) {
|
||||||
// 更新逻辑
|
// 更新逻辑
|
||||||
event.setModifier(currentUser);
|
event.setModifier(currentUser);
|
||||||
@ -122,6 +146,10 @@ public class EventController {
|
|||||||
@PathVariable String eventId,
|
@PathVariable String eventId,
|
||||||
@RequestBody Map<String, Object> requestBody
|
@RequestBody Map<String, Object> requestBody
|
||||||
) {
|
) {
|
||||||
|
Event db = eventService.getById(eventId);
|
||||||
|
if (db != null) {
|
||||||
|
assertCanWriteByScenarioId(db.getScenarioId());
|
||||||
|
}
|
||||||
Object attrChanges = requestBody.get("attr_changes");
|
Object attrChanges = requestBody.get("attr_changes");
|
||||||
if (attrChanges == null) {
|
if (attrChanges == null) {
|
||||||
return ResponseEntity.badRequest().body(Map.of(
|
return ResponseEntity.badRequest().body(Map.of(
|
||||||
@ -159,6 +187,7 @@ public class EventController {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/by-scenario")
|
@GetMapping("/by-scenario")
|
||||||
public List<Event> listByScenario(@RequestParam String scenarioId) {
|
public List<Event> listByScenario(@RequestParam String scenarioId) {
|
||||||
|
assertCanReadByScenarioId(scenarioId);
|
||||||
return eventService.list(
|
return eventService.list(
|
||||||
new QueryWrapper<Event>()
|
new QueryWrapper<Event>()
|
||||||
.select("event_id","scenario_id","device_id","material_id","attr_changes","trigger_time","created_at","modifier")
|
.select("event_id","scenario_id","device_id","material_id","attr_changes","trigger_time","created_at","modifier")
|
||||||
@ -177,6 +206,10 @@ public class EventController {
|
|||||||
@Log(value = "删除始发事件", module = "事件管理")
|
@Log(value = "删除始发事件", module = "事件管理")
|
||||||
@DeleteMapping("/{eventId}")
|
@DeleteMapping("/{eventId}")
|
||||||
public ResponseEntity<Map<String, Object>> deleteEvent(@PathVariable String eventId) {
|
public ResponseEntity<Map<String, Object>> deleteEvent(@PathVariable String eventId) {
|
||||||
|
Event db = eventService.getById(eventId);
|
||||||
|
if (db != null) {
|
||||||
|
assertCanWriteByScenarioId(db.getScenarioId());
|
||||||
|
}
|
||||||
boolean ok = eventService.removeById(eventId);
|
boolean ok = eventService.removeById(eventId);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return ResponseEntity.ok(Map.of(
|
return ResponseEntity.ok(Map.of(
|
||||||
@ -201,6 +234,9 @@ public class EventController {
|
|||||||
@GetMapping("/{eventId}/attr-parse")
|
@GetMapping("/{eventId}/attr-parse")
|
||||||
public ResponseEntity<Map<String, Object>> parseAttrChanges(@PathVariable String eventId) {
|
public ResponseEntity<Map<String, Object>> parseAttrChanges(@PathVariable String eventId) {
|
||||||
Event ev = eventService.getById(eventId);
|
Event ev = eventService.getById(eventId);
|
||||||
|
if (ev != null) {
|
||||||
|
assertCanReadByScenarioId(ev.getScenarioId());
|
||||||
|
}
|
||||||
List<String> issues = new ArrayList<>();
|
List<String> issues = new ArrayList<>();
|
||||||
EventAttrParseResult result = new EventAttrParseResult();
|
EventAttrParseResult result = new EventAttrParseResult();
|
||||||
result.setEventId(eventId);
|
result.setEventId(eventId);
|
||||||
@ -384,6 +420,22 @@ public class EventController {
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertCanReadByScenarioId(String scenarioId) {
|
||||||
|
if (scenarioId == null || scenarioId.isBlank()) return;
|
||||||
|
Scenario sc = scenarioService.getById(scenarioId);
|
||||||
|
if (sc == null) return;
|
||||||
|
if (sc.getProjectId() == null || sc.getProjectId().isBlank()) return;
|
||||||
|
projectAccessHelper.assertCanReadProject(sc.getProjectId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertCanWriteByScenarioId(String scenarioId) {
|
||||||
|
if (scenarioId == null || scenarioId.isBlank()) return;
|
||||||
|
Scenario sc = scenarioService.getById(scenarioId);
|
||||||
|
if (sc == null) return;
|
||||||
|
if (sc.getProjectId() == null || sc.getProjectId().isBlank()) return;
|
||||||
|
projectAccessHelper.assertCanWriteProject(sc.getProjectId());
|
||||||
|
}
|
||||||
|
|
||||||
private String currentUsername() {
|
private String currentUsername() {
|
||||||
try {
|
try {
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.business.css.domain.Device;
|
import com.yfd.business.css.domain.Device;
|
||||||
import com.yfd.business.css.domain.Material;
|
import com.yfd.business.css.domain.Material;
|
||||||
|
import com.yfd.business.css.security.ProjectAccessHelper;
|
||||||
import com.yfd.business.css.service.MaterialService;
|
import com.yfd.business.css.service.MaterialService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -25,6 +26,8 @@ public class MaterialController {
|
|||||||
private MaterialService materialService;
|
private MaterialService materialService;
|
||||||
@Resource
|
@Resource
|
||||||
private IUserService userService;
|
private IUserService userService;
|
||||||
|
@Resource
|
||||||
|
private ProjectAccessHelper projectAccessHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. 新增物料
|
* 1. 新增物料
|
||||||
@ -36,6 +39,9 @@ public class MaterialController {
|
|||||||
@Log(value = "新增物料", module = "物料管理")
|
@Log(value = "新增物料", module = "物料管理")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public boolean create(@RequestBody Material material) {
|
public boolean create(@RequestBody Material material) {
|
||||||
|
if (material.getProjectId() != null && !material.getProjectId().isBlank() && !"-1".equals(material.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(material.getProjectId());
|
||||||
|
}
|
||||||
material.setModifier(currentUsername());
|
material.setModifier(currentUsername());
|
||||||
return materialService.saveMaterial(material);
|
return materialService.saveMaterial(material);
|
||||||
}
|
}
|
||||||
@ -43,6 +49,9 @@ public class MaterialController {
|
|||||||
@Log(value = "保存或更新物料", module = "物料管理")
|
@Log(value = "保存或更新物料", module = "物料管理")
|
||||||
@PostMapping("/saveOrUpdate")
|
@PostMapping("/saveOrUpdate")
|
||||||
public boolean saveOrUpdate(@RequestBody Material material) {
|
public boolean saveOrUpdate(@RequestBody Material material) {
|
||||||
|
if (material.getProjectId() != null && !material.getProjectId().isBlank() && !"-1".equals(material.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(material.getProjectId());
|
||||||
|
}
|
||||||
material.setModifier(currentUsername());
|
material.setModifier(currentUsername());
|
||||||
return materialService.saveOrUpdateByBusiness(material);
|
return materialService.saveOrUpdateByBusiness(material);
|
||||||
}
|
}
|
||||||
@ -57,6 +66,12 @@ public class MaterialController {
|
|||||||
@Log(value = "编辑物料", module = "物料管理")
|
@Log(value = "编辑物料", module = "物料管理")
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public boolean update(@RequestBody Material material) {
|
public boolean update(@RequestBody Material material) {
|
||||||
|
if (material.getMaterialId() != null && !material.getMaterialId().isBlank()) {
|
||||||
|
Material db = materialService.getById(material.getMaterialId());
|
||||||
|
if (db != null && db.getProjectId() != null && !db.getProjectId().isBlank() && !"-1".equals(db.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(db.getProjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
material.setModifier(currentUsername());
|
material.setModifier(currentUsername());
|
||||||
material.setUpdatedAt(LocalDateTime.now());
|
material.setUpdatedAt(LocalDateTime.now());
|
||||||
return materialService.updateById(material);
|
return materialService.updateById(material);
|
||||||
@ -72,6 +87,10 @@ public class MaterialController {
|
|||||||
@Log(value = "删除物料", module = "物料管理")
|
@Log(value = "删除物料", module = "物料管理")
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public boolean delete(@PathVariable String id) {
|
public boolean delete(@PathVariable String id) {
|
||||||
|
Material db = materialService.getById(id);
|
||||||
|
if (db != null && db.getProjectId() != null && !db.getProjectId().isBlank() && !"-1".equals(db.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(db.getProjectId());
|
||||||
|
}
|
||||||
return materialService.removeById(id);
|
return materialService.removeById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +104,14 @@ public class MaterialController {
|
|||||||
@Log(value = "批量删除物料", module = "物料管理")
|
@Log(value = "批量删除物料", module = "物料管理")
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||||
|
if (ids != null && !ids.isEmpty()) {
|
||||||
|
List<Material> list = materialService.list(new QueryWrapper<Material>().in("material_id", ids));
|
||||||
|
for (Material m : list) {
|
||||||
|
if (m.getProjectId() != null && !m.getProjectId().isBlank() && !"-1".equals(m.getProjectId())) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(m.getProjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return materialService.removeByIds(ids);
|
return materialService.removeByIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +157,9 @@ public class MaterialController {
|
|||||||
public Page<Material> pageByProject(@RequestParam String projectId,
|
public Page<Material> pageByProject(@RequestParam String projectId,
|
||||||
@RequestParam(defaultValue = "1") long pageNum,
|
@RequestParam(defaultValue = "1") long pageNum,
|
||||||
@RequestParam(defaultValue = "20") long pageSize) {
|
@RequestParam(defaultValue = "20") long pageSize) {
|
||||||
|
if (projectId != null && !projectId.isBlank() && !"-1".equals(projectId)) {
|
||||||
|
projectAccessHelper.assertCanReadProject(projectId);
|
||||||
|
}
|
||||||
QueryWrapper<Material> qw = new QueryWrapper<Material>()
|
QueryWrapper<Material> qw = new QueryWrapper<Material>()
|
||||||
.eq("project_id", projectId)
|
.eq("project_id", projectId)
|
||||||
.orderByDesc("created_at");
|
.orderByDesc("created_at");
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import com.yfd.business.css.service.ModelTrainService;
|
|||||||
import com.yfd.business.css.service.TrainWebSocketService;
|
import com.yfd.business.css.service.TrainWebSocketService;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.config.ResponseResult;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@ -57,13 +58,17 @@ public class ModelTrainController {
|
|||||||
@PostMapping("/upload")
|
@PostMapping("/upload")
|
||||||
public ResponseResult upload(@RequestParam("file") MultipartFile file) {
|
public ResponseResult upload(@RequestParam("file") MultipartFile file) {
|
||||||
String path = modelTrainService.uploadDataset(file);
|
String path = modelTrainService.uploadDataset(file);
|
||||||
return ResponseResult.successData(path);
|
return ResponseResult.successData(Map.of(
|
||||||
|
"path", path,
|
||||||
|
"columns", modelTrainService.parseDatasetColumns(path)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交训练任务 (支持文件上传和 JSON 参数)
|
* 提交训练任务 (支持文件上传和 JSON 参数)
|
||||||
*/
|
*/
|
||||||
@Log(value = "提交训练任务", module = "模型训练")
|
@Log(value = "提交训练任务", module = "模型训练")
|
||||||
|
// @PreAuthorize("hasAuthority('modelTrain:submit')")
|
||||||
@PostMapping("/submit")
|
@PostMapping("/submit")
|
||||||
public ResponseResult submit(@RequestPart("task") String taskJson,
|
public ResponseResult submit(@RequestPart("task") String taskJson,
|
||||||
@RequestPart(value = "file", required = false) MultipartFile file) {
|
@RequestPart(value = "file", required = false) MultipartFile file) {
|
||||||
@ -137,6 +142,7 @@ public class ModelTrainController {
|
|||||||
* 发布模型
|
* 发布模型
|
||||||
*/
|
*/
|
||||||
@Log(value = "发布训练模型", module = "模型训练")
|
@Log(value = "发布训练模型", module = "模型训练")
|
||||||
|
// @PreAuthorize("hasAuthority('modelTrain:publish')")
|
||||||
@PostMapping("/publish")
|
@PostMapping("/publish")
|
||||||
public ResponseResult publish(@RequestBody Map<String, String> body) {
|
public ResponseResult publish(@RequestBody Map<String, String> body) {
|
||||||
String taskId = body.get("taskId");
|
String taskId = body.get("taskId");
|
||||||
@ -149,6 +155,8 @@ public class ModelTrainController {
|
|||||||
* 删除训练任务
|
* 删除训练任务
|
||||||
*/
|
*/
|
||||||
@Log(value = "删除训练任务", module = "模型训练")
|
@Log(value = "删除训练任务", module = "模型训练")
|
||||||
|
@PreAuthorize("hasAuthority('modelTrain:delete')")
|
||||||
|
//删除训练任务
|
||||||
@DeleteMapping("/{taskId}")
|
@DeleteMapping("/{taskId}")
|
||||||
public ResponseResult delete(@PathVariable String taskId) {
|
public ResponseResult delete(@PathVariable String taskId) {
|
||||||
boolean success = modelTrainService.removeById(taskId);
|
boolean success = modelTrainService.removeById(taskId);
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.yfd.business.css.controller;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.business.css.domain.Project;
|
import com.yfd.business.css.domain.Project;
|
||||||
|
import com.yfd.business.css.security.ProjectAccessHelper;
|
||||||
import com.yfd.business.css.service.ProjectService;
|
import com.yfd.business.css.service.ProjectService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -16,6 +17,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -33,6 +35,8 @@ public class ProjectController {
|
|||||||
private com.fasterxml.jackson.databind.ObjectMapper objectMapper;
|
private com.fasterxml.jackson.databind.ObjectMapper objectMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private IUserService userService;
|
private IUserService userService;
|
||||||
|
@Resource
|
||||||
|
private ProjectAccessHelper projectAccessHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. 新增项目
|
* 1. 新增项目
|
||||||
@ -45,6 +49,15 @@ public class ProjectController {
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
@Operation(summary = "新增项目", description = "请求体传入项目对象,返回是否新增成功")
|
@Operation(summary = "新增项目", description = "请求体传入项目对象,返回是否新增成功")
|
||||||
public boolean create(@RequestBody Project project) {
|
public boolean create(@RequestBody Project project) {
|
||||||
|
if (project.getVisibility() == null || project.getVisibility().isBlank()) {
|
||||||
|
project.setVisibility("PRIVATE");
|
||||||
|
} else {
|
||||||
|
project.setVisibility(projectAccessHelper.normalizeVisibility(project.getVisibility()));
|
||||||
|
}
|
||||||
|
if (project.getCreator() == null || project.getCreator().isBlank()) {
|
||||||
|
var u = userService.getUserInfo();
|
||||||
|
if (u != null) project.setCreator(u.getId());
|
||||||
|
}
|
||||||
project.setModifier(currentUsername());
|
project.setModifier(currentUsername());
|
||||||
return projectService.save(project);
|
return projectService.save(project);
|
||||||
}
|
}
|
||||||
@ -60,11 +73,32 @@ public class ProjectController {
|
|||||||
@PutMapping
|
@PutMapping
|
||||||
@Operation(summary = "修改项目", description = "请求体传入项目对象(需包含主键),返回是否修改成功")
|
@Operation(summary = "修改项目", description = "请求体传入项目对象(需包含主键),返回是否修改成功")
|
||||||
public boolean update(@RequestBody Project project) {
|
public boolean update(@RequestBody Project project) {
|
||||||
|
if (project.getProjectId() != null) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(project.getProjectId());
|
||||||
|
}
|
||||||
project.setModifier(currentUsername());
|
project.setModifier(currentUsername());
|
||||||
project.setUpdatedAt(LocalDateTime.now());
|
project.setUpdatedAt(LocalDateTime.now());
|
||||||
return projectService.updateById(project);
|
return projectService.updateById(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Log(value = "修改项目可见性", module = "项目管理")
|
||||||
|
@PutMapping("/{id}/visibility")
|
||||||
|
@Operation(summary = "修改项目可见性", description = "仅项目所有者或管理员可修改(PRIVATE/READONLY/PUBLIC)")
|
||||||
|
public boolean updateVisibility(@PathVariable @Parameter(description = "项目ID", required = true) String id,
|
||||||
|
@RequestBody Map<String, String> body) {
|
||||||
|
projectAccessHelper.assertCanManageVisibility(id);
|
||||||
|
String visibility = body == null ? null : body.get("visibility");
|
||||||
|
if (visibility == null || visibility.isBlank()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Project p = new Project();
|
||||||
|
p.setProjectId(id);
|
||||||
|
p.setVisibility(projectAccessHelper.normalizeVisibility(visibility));
|
||||||
|
p.setModifier(currentUsername());
|
||||||
|
p.setUpdatedAt(LocalDateTime.now());
|
||||||
|
return projectService.updateById(p);
|
||||||
|
}
|
||||||
|
|
||||||
private String currentUsername() {
|
private String currentUsername() {
|
||||||
try {
|
try {
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
@ -88,6 +122,7 @@ public class ProjectController {
|
|||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
@Operation(summary = "删除项目(单条)", description = "根据项目ID删除项目")
|
@Operation(summary = "删除项目(单条)", description = "根据项目ID删除项目")
|
||||||
public boolean delete(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
public boolean delete(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(id);
|
||||||
return projectService.removeById(id);
|
return projectService.removeById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +137,11 @@ public class ProjectController {
|
|||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
@Operation(summary = "删除项目(批量)", description = "请求体传入项目ID列表,批量删除项目")
|
@Operation(summary = "删除项目(批量)", description = "请求体传入项目ID列表,批量删除项目")
|
||||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||||
|
if (ids != null) {
|
||||||
|
for (String id : ids) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
return projectService.removeByIds(ids);
|
return projectService.removeByIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +182,7 @@ public class ProjectController {
|
|||||||
@GetMapping("/{id}/exportProject")
|
@GetMapping("/{id}/exportProject")
|
||||||
@Operation(summary = "导出项目工程(多Sheet)", description = "根据项目ID导出工程数据,返回 Excel 附件 project_{id}.xlsx")
|
@Operation(summary = "导出项目工程(多Sheet)", description = "根据项目ID导出工程数据,返回 Excel 附件 project_{id}.xlsx")
|
||||||
public ResponseEntity<byte[]> exportProjectExcel(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
public ResponseEntity<byte[]> exportProjectExcel(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
||||||
|
projectAccessHelper.assertCanReadProject(id);
|
||||||
byte[] bytes = projectService.exportProjectEngineeringExcel(id);
|
byte[] bytes = projectService.exportProjectEngineeringExcel(id);
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=project_" + id + ".xlsx")
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=project_" + id + ".xlsx")
|
||||||
@ -149,6 +190,15 @@ public class ProjectController {
|
|||||||
.body(bytes);
|
.body(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Log(value = "导入项目工程", module = "项目管理")
|
||||||
|
@PostMapping("/importProject")
|
||||||
|
@Operation(summary = "导入项目工程(多Sheet)", description = "上传 Excel 工程文件;若项目ID存在且 overwrite=false 则返回提示;overwrite=true 将先删除再导入")
|
||||||
|
public ResponseEntity<Map<String, Object>> importProject(@RequestParam("file") MultipartFile file,
|
||||||
|
@RequestParam(defaultValue = "false") boolean overwrite) {
|
||||||
|
var res = projectService.importProjectEngineeringExcel(file, overwrite);
|
||||||
|
return ResponseEntity.ok(res);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 6. 根据项目名称搜索(可为空)并分页返回
|
* 6. 根据项目名称搜索(可为空)并分页返回
|
||||||
* 输入参数:查询参数 name(项目名称关键词,可为空),pageNum(页码,默认1),pageSize(每页条数,默认10)
|
* 输入参数:查询参数 name(项目名称关键词,可为空),pageNum(页码,默认1),pageSize(每页条数,默认10)
|
||||||
@ -167,6 +217,14 @@ public class ProjectController {
|
|||||||
if (name != null && !name.isEmpty()) {
|
if (name != null && !name.isEmpty()) {
|
||||||
qw.like("name", name);
|
qw.like("name", name);
|
||||||
}
|
}
|
||||||
|
if (!projectAccessHelper.isAdmin()) {
|
||||||
|
String uid = projectAccessHelper.currentUserId();
|
||||||
|
qw.and(w -> w.isNull("visibility")
|
||||||
|
.or().eq("visibility", "")
|
||||||
|
.or().eq("visibility", "PUBLIC")
|
||||||
|
.or().eq("visibility", "READONLY")
|
||||||
|
.or().eq("creator", uid));
|
||||||
|
}
|
||||||
Page<Project> page = new Page<>(pageNum, pageSize, true);
|
Page<Project> page = new Page<>(pageNum, pageSize, true);
|
||||||
return projectService.page(page, qw);
|
return projectService.page(page, qw);
|
||||||
}
|
}
|
||||||
@ -181,7 +239,13 @@ public class ProjectController {
|
|||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
@Operation(summary = "根据项目ID获取项目信息", description = "项目不存在时返回空对象")
|
@Operation(summary = "根据项目ID获取项目信息", description = "项目不存在时返回空对象")
|
||||||
public Project getById(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
public Project getById(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
||||||
return projectService.getById(id);
|
Project p = projectService.getById(id);
|
||||||
|
if (p != null) {
|
||||||
|
if (!projectAccessHelper.canRead(p)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,6 +261,7 @@ public class ProjectController {
|
|||||||
@Operation(summary = "更新项目拓扑结构", description = "请求体需包含合法的 topology JSON(对象或字符串)")
|
@Operation(summary = "更新项目拓扑结构", description = "请求体需包含合法的 topology JSON(对象或字符串)")
|
||||||
public ResponseEntity<Map<String, Object>> updateTopology(@PathVariable @Parameter(description = "项目ID", required = true) String id,
|
public ResponseEntity<Map<String, Object>> updateTopology(@PathVariable @Parameter(description = "项目ID", required = true) String id,
|
||||||
@RequestBody Map<String, Object> requestBody) {
|
@RequestBody Map<String, Object> requestBody) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(id);
|
||||||
Object topology = requestBody.get("topology");
|
Object topology = requestBody.get("topology");
|
||||||
if (topology == null) {
|
if (topology == null) {
|
||||||
return ResponseEntity.badRequest().body(Map.of(
|
return ResponseEntity.badRequest().body(Map.of(
|
||||||
@ -240,6 +305,7 @@ public class ProjectController {
|
|||||||
*/
|
*/
|
||||||
@Operation(summary = "解析项目拓扑结构", description = "返回属性节点、影响边与线性计算计划")
|
@Operation(summary = "解析项目拓扑结构", description = "返回属性节点、影响边与线性计算计划")
|
||||||
public ResponseEntity<Map<String, Object>> parseTopology(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
public ResponseEntity<Map<String, Object>> parseTopology(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
||||||
|
projectAccessHelper.assertCanReadProject(id);
|
||||||
var result = projectService.parseTopology(id);
|
var result = projectService.parseTopology(id);
|
||||||
return ResponseEntity.ok(Map.of(
|
return ResponseEntity.ok(Map.of(
|
||||||
"code", 0,
|
"code", 0,
|
||||||
@ -256,6 +322,7 @@ public class ProjectController {
|
|||||||
*/
|
*/
|
||||||
@Operation(summary = "解析拓扑设备顺序", description = "根据 devices 出现顺序返回设备与物料属性视图")
|
@Operation(summary = "解析拓扑设备顺序", description = "根据 devices 出现顺序返回设备与物料属性视图")
|
||||||
public ResponseEntity<Map<String, Object>> parseDeviceOrder(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
public ResponseEntity<Map<String, Object>> parseDeviceOrder(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
||||||
|
projectAccessHelper.assertCanReadProject(id);
|
||||||
Object list = projectService.parseDeviceOrderWithMaterials(id);
|
Object list = projectService.parseDeviceOrderWithMaterials(id);
|
||||||
return ResponseEntity.ok(Map.of(
|
return ResponseEntity.ok(Map.of(
|
||||||
"code", 0,
|
"code", 0,
|
||||||
@ -272,6 +339,7 @@ public class ProjectController {
|
|||||||
*/
|
*/
|
||||||
@Operation(summary = "解析画布视图数据", description = "返回设备/管线/边界与显示配置")
|
@Operation(summary = "解析画布视图数据", description = "返回设备/管线/边界与显示配置")
|
||||||
public ResponseEntity<Map<String, Object>> parseCanvas(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
public ResponseEntity<Map<String, Object>> parseCanvas(@PathVariable @Parameter(description = "项目ID", required = true) String id) {
|
||||||
|
projectAccessHelper.assertCanReadProject(id);
|
||||||
var view = projectService.parseCanvasView(id);
|
var view = projectService.parseCanvasView(id);
|
||||||
return ResponseEntity.ok(Map.of(
|
return ResponseEntity.ok(Map.of(
|
||||||
"code", 0,
|
"code", 0,
|
||||||
@ -285,6 +353,7 @@ public class ProjectController {
|
|||||||
public ResponseEntity<Map<String, Object>> initSimulation(@RequestParam @Parameter(description = "项目ID", required = true) String projectId,
|
public ResponseEntity<Map<String, Object>> initSimulation(@RequestParam @Parameter(description = "项目ID", required = true) String projectId,
|
||||||
@RequestParam @Parameter(description = "情景ID", required = true) String scenarioId,
|
@RequestParam @Parameter(description = "情景ID", required = true) String scenarioId,
|
||||||
@RequestBody(required = false) Map<String, Object> params) {
|
@RequestBody(required = false) Map<String, Object> params) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(projectId);
|
||||||
var res = projectService.initSimulation(projectId, scenarioId, params == null ? Map.of() : params);
|
var res = projectService.initSimulation(projectId, scenarioId, params == null ? Map.of() : params);
|
||||||
return ResponseEntity.ok(Map.of(
|
return ResponseEntity.ok(Map.of(
|
||||||
"code", 0,
|
"code", 0,
|
||||||
@ -299,6 +368,7 @@ public class ProjectController {
|
|||||||
public ResponseEntity<Map<String, Object>> runSimulation(@RequestParam @Parameter(description = "项目ID", required = true) String projectId,
|
public ResponseEntity<Map<String, Object>> runSimulation(@RequestParam @Parameter(description = "项目ID", required = true) String projectId,
|
||||||
@RequestParam @Parameter(description = "情景ID", required = true) String scenarioId,
|
@RequestParam @Parameter(description = "情景ID", required = true) String scenarioId,
|
||||||
@RequestBody(required = false) Map<String, Object> params) {
|
@RequestBody(required = false) Map<String, Object> params) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(projectId);
|
||||||
var res = projectService.runSimulation(projectId, scenarioId, params == null ? Map.of() : params);
|
var res = projectService.runSimulation(projectId, scenarioId, params == null ? Map.of() : params);
|
||||||
return ResponseEntity.ok(Map.of(
|
return ResponseEntity.ok(Map.of(
|
||||||
"code", 0,
|
"code", 0,
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.yfd.business.css.controller;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.business.css.domain.Scenario;
|
import com.yfd.business.css.domain.Scenario;
|
||||||
|
import com.yfd.business.css.security.ProjectAccessHelper;
|
||||||
import com.yfd.business.css.service.ScenarioService;
|
import com.yfd.business.css.service.ScenarioService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -23,6 +24,8 @@ public class ScenarioController {
|
|||||||
private ScenarioService scenarioService;
|
private ScenarioService scenarioService;
|
||||||
@Resource
|
@Resource
|
||||||
private IUserService userService;
|
private IUserService userService;
|
||||||
|
@Resource
|
||||||
|
private ProjectAccessHelper projectAccessHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. 新增情景
|
* 1. 新增情景
|
||||||
@ -34,6 +37,9 @@ public class ScenarioController {
|
|||||||
@Log(value = "新增情景", module = "情景管理")
|
@Log(value = "新增情景", module = "情景管理")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public boolean create(@RequestBody Scenario scenario) {
|
public boolean create(@RequestBody Scenario scenario) {
|
||||||
|
if (scenario.getProjectId() != null && !scenario.getProjectId().isBlank()) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(scenario.getProjectId());
|
||||||
|
}
|
||||||
scenario.setModifier(currentUsername());
|
scenario.setModifier(currentUsername());
|
||||||
scenario.setCreatedAt(LocalDateTime.now());
|
scenario.setCreatedAt(LocalDateTime.now());
|
||||||
scenario.setUpdatedAt(LocalDateTime.now());
|
scenario.setUpdatedAt(LocalDateTime.now());
|
||||||
@ -51,6 +57,9 @@ public class ScenarioController {
|
|||||||
@Log(value = "新增情景并返回", module = "情景管理")
|
@Log(value = "新增情景并返回", module = "情景管理")
|
||||||
@PostMapping("/createAndReturn")
|
@PostMapping("/createAndReturn")
|
||||||
public java.util.Map<String, Object> createAndReturn(@RequestBody Scenario scenario) {
|
public java.util.Map<String, Object> createAndReturn(@RequestBody Scenario scenario) {
|
||||||
|
if (scenario.getProjectId() != null && !scenario.getProjectId().isBlank()) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(scenario.getProjectId());
|
||||||
|
}
|
||||||
scenario.setModifier(currentUsername());
|
scenario.setModifier(currentUsername());
|
||||||
scenario.setCreatedAt(LocalDateTime.now());
|
scenario.setCreatedAt(LocalDateTime.now());
|
||||||
scenario.setUpdatedAt(LocalDateTime.now());
|
scenario.setUpdatedAt(LocalDateTime.now());
|
||||||
@ -72,6 +81,12 @@ public class ScenarioController {
|
|||||||
@Log(value = "修改情景", module = "情景管理")
|
@Log(value = "修改情景", module = "情景管理")
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public boolean update(@RequestBody Scenario scenario) {
|
public boolean update(@RequestBody Scenario scenario) {
|
||||||
|
if (scenario.getScenarioId() != null && !scenario.getScenarioId().isBlank()) {
|
||||||
|
Scenario db = scenarioService.getById(scenario.getScenarioId());
|
||||||
|
if (db != null && db.getProjectId() != null && !db.getProjectId().isBlank()) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(db.getProjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
scenario.setModifier(currentUsername());
|
scenario.setModifier(currentUsername());
|
||||||
scenario.setUpdatedAt(LocalDateTime.now());
|
scenario.setUpdatedAt(LocalDateTime.now());
|
||||||
return scenarioService.updateById(scenario);
|
return scenarioService.updateById(scenario);
|
||||||
@ -87,6 +102,10 @@ public class ScenarioController {
|
|||||||
@Log(value = "删除情景", module = "情景管理")
|
@Log(value = "删除情景", module = "情景管理")
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public boolean delete(@PathVariable String id) {
|
public boolean delete(@PathVariable String id) {
|
||||||
|
Scenario db = scenarioService.getById(id);
|
||||||
|
if (db != null && db.getProjectId() != null && !db.getProjectId().isBlank()) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(db.getProjectId());
|
||||||
|
}
|
||||||
return scenarioService.removeById(id);
|
return scenarioService.removeById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +119,14 @@ public class ScenarioController {
|
|||||||
@Log(value = "批量删除情景", module = "情景管理")
|
@Log(value = "批量删除情景", module = "情景管理")
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
public boolean deleteBatch(@RequestBody List<String> ids) {
|
public boolean deleteBatch(@RequestBody List<String> ids) {
|
||||||
|
if (ids != null && !ids.isEmpty()) {
|
||||||
|
List<Scenario> list = scenarioService.list(new QueryWrapper<Scenario>().in("scenario_id", ids));
|
||||||
|
for (Scenario sc : list) {
|
||||||
|
if (sc.getProjectId() != null && !sc.getProjectId().isBlank()) {
|
||||||
|
projectAccessHelper.assertCanWriteProject(sc.getProjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return scenarioService.removeByIds(ids);
|
return scenarioService.removeByIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +141,11 @@ public class ScenarioController {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public Scenario getById(@PathVariable String id) {
|
public Scenario getById(@PathVariable String id) {
|
||||||
return scenarioService.getById(id);
|
Scenario sc = scenarioService.getById(id);
|
||||||
|
if (sc != null && sc.getProjectId() != null && !sc.getProjectId().isBlank()) {
|
||||||
|
projectAccessHelper.assertCanReadProject(sc.getProjectId());
|
||||||
|
}
|
||||||
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,6 +163,9 @@ public class ScenarioController {
|
|||||||
@RequestParam(required = false) String name,
|
@RequestParam(required = false) String name,
|
||||||
@RequestParam(defaultValue = "1") long pageNum,
|
@RequestParam(defaultValue = "1") long pageNum,
|
||||||
@RequestParam(defaultValue = "20") long pageSize) {
|
@RequestParam(defaultValue = "20") long pageSize) {
|
||||||
|
if (projectId != null && !projectId.isBlank()) {
|
||||||
|
projectAccessHelper.assertCanReadProject(projectId);
|
||||||
|
}
|
||||||
QueryWrapper<Scenario> qw = new QueryWrapper<Scenario>().eq("project_id", projectId).orderByDesc("created_at");
|
QueryWrapper<Scenario> qw = new QueryWrapper<Scenario>().eq("project_id", projectId).orderByDesc("created_at");
|
||||||
if (name != null && !name.isEmpty()) {
|
if (name != null && !name.isEmpty()) {
|
||||||
qw.like("name", name);
|
qw.like("name", name);
|
||||||
|
|||||||
@ -2,8 +2,11 @@ package com.yfd.business.css.controller;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.yfd.business.css.domain.Scenario;
|
||||||
import com.yfd.business.css.domain.ScenarioResult;
|
import com.yfd.business.css.domain.ScenarioResult;
|
||||||
|
import com.yfd.business.css.security.ProjectAccessHelper;
|
||||||
import com.yfd.business.css.service.ScenarioResultService;
|
import com.yfd.business.css.service.ScenarioResultService;
|
||||||
|
import com.yfd.business.css.service.ScenarioService;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -23,6 +26,10 @@ public class ScenarioResultController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ScenarioResultService scenarioResultService;
|
private ScenarioResultService scenarioResultService;
|
||||||
|
@Resource
|
||||||
|
private ScenarioService scenarioService;
|
||||||
|
@Resource
|
||||||
|
private ProjectAccessHelper projectAccessHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据场景ID分页查询模拟结果
|
* 根据场景ID分页查询模拟结果
|
||||||
@ -43,6 +50,10 @@ public class ScenarioResultController {
|
|||||||
@RequestParam(defaultValue = "1") long pageNum,
|
@RequestParam(defaultValue = "1") long pageNum,
|
||||||
@RequestParam(defaultValue = "10") long pageSize
|
@RequestParam(defaultValue = "10") long pageSize
|
||||||
) {
|
) {
|
||||||
|
Scenario sc = scenarioService.getById(scenarioId);
|
||||||
|
if (sc != null && sc.getProjectId() != null && !sc.getProjectId().isBlank()) {
|
||||||
|
projectAccessHelper.assertCanReadProject(sc.getProjectId());
|
||||||
|
}
|
||||||
QueryWrapper<ScenarioResult> qw = new QueryWrapper<ScenarioResult>()
|
QueryWrapper<ScenarioResult> qw = new QueryWrapper<ScenarioResult>()
|
||||||
.eq("scenario_id", scenarioId);
|
.eq("scenario_id", scenarioId);
|
||||||
if (deviceId != null && !deviceId.isEmpty()) {
|
if (deviceId != null && !deviceId.isEmpty()) {
|
||||||
@ -79,6 +90,10 @@ public class ScenarioResultController {
|
|||||||
@RequestParam(required = false) String deviceId,
|
@RequestParam(required = false) String deviceId,
|
||||||
@RequestParam(required = false) Integer stepFrom,
|
@RequestParam(required = false) Integer stepFrom,
|
||||||
@RequestParam(required = false) Integer stepTo) throws IOException {
|
@RequestParam(required = false) Integer stepTo) throws IOException {
|
||||||
|
Scenario sc = scenarioService.getById(scenarioId);
|
||||||
|
if (sc != null && sc.getProjectId() != null && !sc.getProjectId().isBlank()) {
|
||||||
|
projectAccessHelper.assertCanReadProject(sc.getProjectId());
|
||||||
|
}
|
||||||
|
|
||||||
// 设置响应头信息以便浏览器识别并触发下载行为
|
// 设置响应头信息以便浏览器识别并触发下载行为
|
||||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@TableName(value = "model_train_task", autoResultMap = true)
|
@TableName(value = "model_train_task", autoResultMap = true)
|
||||||
@ -47,6 +48,9 @@ public class ModelTrainTask implements Serializable {
|
|||||||
|
|
||||||
@TableField("error_log")
|
@TableField("error_log")
|
||||||
private String errorLog;
|
private String errorLog;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Map<String, Object> featureMapConfig;
|
||||||
|
|
||||||
@TableField(value = "created_at")
|
@TableField(value = "created_at")
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
|
|||||||
@ -30,6 +30,12 @@ public class Project implements Serializable {
|
|||||||
@TableField("topology")
|
@TableField("topology")
|
||||||
private String topology;
|
private String topology;
|
||||||
|
|
||||||
|
@TableField("visibility")
|
||||||
|
private String visibility;
|
||||||
|
|
||||||
|
@TableField("creator")
|
||||||
|
private String creator;
|
||||||
|
|
||||||
@TableField("created_at")
|
@TableField("created_at")
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,94 @@
|
|||||||
|
package com.yfd.business.css.security;
|
||||||
|
|
||||||
|
import com.yfd.business.css.common.exception.BizException;
|
||||||
|
import com.yfd.business.css.domain.Project;
|
||||||
|
import com.yfd.business.css.service.ProjectService;
|
||||||
|
import com.yfd.platform.system.domain.SysUser;
|
||||||
|
import com.yfd.platform.system.service.IUserService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ProjectAccessHelper {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ProjectService projectService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IUserService userService;
|
||||||
|
|
||||||
|
public boolean isAdmin() {
|
||||||
|
SysUser u = userService.getUserInfo();
|
||||||
|
return u != null && u.getUsertype() != null && u.getUsertype() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String currentUserId() {
|
||||||
|
SysUser u = userService.getUserInfo();
|
||||||
|
return u == null ? null : u.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertCanReadProject(String projectId) {
|
||||||
|
Project p = projectService.getById(projectId);
|
||||||
|
if (p == null) {
|
||||||
|
throw new BizException("项目不存在");
|
||||||
|
}
|
||||||
|
if (!canRead(p)) {
|
||||||
|
throw new BizException("无权限访问该项目");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertCanWriteProject(String projectId) {
|
||||||
|
Project p = projectService.getById(projectId);
|
||||||
|
if (p == null) {
|
||||||
|
throw new BizException("项目不存在");
|
||||||
|
}
|
||||||
|
if (!canWrite(p)) {
|
||||||
|
throw new BizException("无权限修改该项目");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertCanManageVisibility(String projectId) {
|
||||||
|
Project p = projectService.getById(projectId);
|
||||||
|
if (p == null) {
|
||||||
|
throw new BizException("项目不存在");
|
||||||
|
}
|
||||||
|
if (!canManageVisibility(p)) {
|
||||||
|
throw new BizException("无权限修改项目可见性");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canRead(Project p) {
|
||||||
|
if (p == null) return false;
|
||||||
|
if (isAdmin()) return true;
|
||||||
|
String visibility = normalizeVisibility(p.getVisibility());
|
||||||
|
if ("PUBLIC".equals(visibility) || "READONLY".equals(visibility)) return true;
|
||||||
|
if ("PRIVATE".equals(visibility)) {
|
||||||
|
String uid = currentUserId();
|
||||||
|
return uid != null && uid.equals(p.getCreator());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canWrite(Project p) {
|
||||||
|
if (p == null) return false;
|
||||||
|
if (isAdmin()) return true;
|
||||||
|
String uid = currentUserId();
|
||||||
|
if (uid != null && uid.equals(p.getCreator())) return true;
|
||||||
|
String visibility = normalizeVisibility(p.getVisibility());
|
||||||
|
return "PUBLIC".equals(visibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canManageVisibility(Project p) {
|
||||||
|
if (p == null) return false;
|
||||||
|
if (isAdmin()) return true;
|
||||||
|
String uid = currentUserId();
|
||||||
|
return uid != null && uid.equals(p.getCreator());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String normalizeVisibility(String visibility) {
|
||||||
|
if (visibility == null || visibility.isBlank()) return "PUBLIC";
|
||||||
|
String v = visibility.trim().toUpperCase();
|
||||||
|
if ("PRIVATE".equals(v) || "READONLY".equals(v) || "PUBLIC".equals(v)) return v;
|
||||||
|
return "PUBLIC";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||||||
import com.yfd.business.css.domain.ModelTrainTask;
|
import com.yfd.business.css.domain.ModelTrainTask;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface ModelTrainService extends IService<ModelTrainTask> {
|
public interface ModelTrainService extends IService<ModelTrainTask> {
|
||||||
/**
|
/**
|
||||||
* 上传数据集
|
* 上传数据集
|
||||||
@ -12,6 +14,8 @@ public interface ModelTrainService extends IService<ModelTrainTask> {
|
|||||||
*/
|
*/
|
||||||
String uploadDataset(MultipartFile file);
|
String uploadDataset(MultipartFile file);
|
||||||
|
|
||||||
|
List<String> parseDatasetColumns(String datasetPath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交训练任务
|
* 提交训练任务
|
||||||
* @param task 任务信息
|
* @param task 任务信息
|
||||||
|
|||||||
@ -18,6 +18,8 @@ public interface ProjectService extends IService<Project> {
|
|||||||
*/
|
*/
|
||||||
byte[] exportProjectEngineeringExcel(String projectId);
|
byte[] exportProjectEngineeringExcel(String projectId);
|
||||||
|
|
||||||
|
java.util.Map<String, Object> importProjectEngineeringExcel(org.springframework.web.multipart.MultipartFile file, boolean overwrite);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析指定项目的拓扑结构
|
* 解析指定项目的拓扑结构
|
||||||
* @param projectId 项目ID
|
* @param projectId 项目ID
|
||||||
|
|||||||
@ -23,9 +23,17 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.apache.poi.ss.usermodel.DataFormatter;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@ -33,6 +41,9 @@ import java.nio.file.StandardCopyOption;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -108,6 +119,25 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> parseDatasetColumns(String datasetPath) {
|
||||||
|
if (datasetPath == null || datasetPath.isBlank()) {
|
||||||
|
throw new BizException("数据集路径不能为空");
|
||||||
|
}
|
||||||
|
Path p = Paths.get(datasetPath);
|
||||||
|
if (!Files.exists(p)) {
|
||||||
|
throw new BizException("数据集文件不存在: " + datasetPath);
|
||||||
|
}
|
||||||
|
String lower = p.getFileName().toString().toLowerCase();
|
||||||
|
if (lower.endsWith(".xlsx") || lower.endsWith(".xls")) {
|
||||||
|
return parseExcelHeader(p.toFile());
|
||||||
|
}
|
||||||
|
if (lower.endsWith(".csv")) {
|
||||||
|
return parseCsvHeader(p);
|
||||||
|
}
|
||||||
|
throw new BizException("不支持的数据集格式: " + p.getFileName());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public String submitTask(ModelTrainTask task) {
|
public String submitTask(ModelTrainTask task) {
|
||||||
@ -116,6 +146,20 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
|||||||
if (task.getTaskId() == null) {
|
if (task.getTaskId() == null) {
|
||||||
task.setTaskId(UUID.randomUUID().toString());
|
task.setTaskId(UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
if (task.getFeatureMapConfig() != null && !task.getFeatureMapConfig().isEmpty()) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
if (task.getTrainParams() != null && !task.getTrainParams().isBlank()) {
|
||||||
|
try {
|
||||||
|
params.putAll(objectMapper.readValue(task.getTrainParams(), new TypeReference<Map<String, Object>>() {}));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params.put("feature_map", task.getFeatureMapConfig());
|
||||||
|
try {
|
||||||
|
task.setTrainParams(objectMapper.writeValueAsString(params));
|
||||||
|
} catch (JsonProcessingException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
this.save(task);
|
this.save(task);
|
||||||
|
|
||||||
// 2. 异步调用 Python 训练
|
// 2. 异步调用 Python 训练
|
||||||
@ -145,6 +189,12 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
|||||||
try {
|
try {
|
||||||
Map<String, Object> params = objectMapper.readValue(task.getTrainParams(), new TypeReference<Map<String, Object>>() {});
|
Map<String, Object> params = objectMapper.readValue(task.getTrainParams(), new TypeReference<Map<String, Object>>() {});
|
||||||
request.put("hyperparameters", params);
|
request.put("hyperparameters", params);
|
||||||
|
if (task.getFeatureMapConfig() == null) {
|
||||||
|
Object fm = params.get("feature_map");
|
||||||
|
if (fm instanceof Map) {
|
||||||
|
request.put("feature_map", fm);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("解析训练参数失败,将作为原始字符串发送: {}", e.getMessage());
|
log.error("解析训练参数失败,将作为原始字符串发送: {}", e.getMessage());
|
||||||
request.put("hyperparameters", task.getTrainParams());
|
request.put("hyperparameters", task.getTrainParams());
|
||||||
@ -152,6 +202,9 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
|||||||
} else {
|
} else {
|
||||||
request.put("hyperparameters", new HashMap<>());
|
request.put("hyperparameters", new HashMap<>());
|
||||||
}
|
}
|
||||||
|
if (task.getFeatureMapConfig() != null && !task.getFeatureMapConfig().isEmpty()) {
|
||||||
|
request.put("feature_map", task.getFeatureMapConfig());
|
||||||
|
}
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
@ -200,6 +253,69 @@ public class ModelTrainServiceImpl extends ServiceImpl<ModelTrainTaskMapper, Mod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> parseExcelHeader(File file) {
|
||||||
|
DataFormatter df = new DataFormatter();
|
||||||
|
try (Workbook wb = WorkbookFactory.create(file)) {
|
||||||
|
Sheet sheet = wb.getNumberOfSheets() > 0 ? wb.getSheetAt(0) : null;
|
||||||
|
if (sheet == null) return List.of();
|
||||||
|
Row row = sheet.getRow(sheet.getFirstRowNum());
|
||||||
|
if (row == null) return List.of();
|
||||||
|
short last = row.getLastCellNum();
|
||||||
|
List<String> cols = new ArrayList<>();
|
||||||
|
for (int i = 0; i < last; i++) {
|
||||||
|
String v = df.formatCellValue(row.getCell(i));
|
||||||
|
if (v != null) {
|
||||||
|
String t = v.trim();
|
||||||
|
if (!t.isBlank()) cols.add(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cols;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new BizException("解析Excel表头失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> parseCsvHeader(Path p) {
|
||||||
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(p), StandardCharsets.UTF_8))) {
|
||||||
|
String line = br.readLine();
|
||||||
|
if (line == null) return List.of();
|
||||||
|
List<String> cols = parseCsvLine(line).stream()
|
||||||
|
.map(s -> s == null ? "" : s.trim())
|
||||||
|
.filter(s -> !s.isBlank())
|
||||||
|
.toList();
|
||||||
|
return cols;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new BizException("解析CSV表头失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> parseCsvLine(String line) {
|
||||||
|
List<String> out = new ArrayList<>();
|
||||||
|
if (line == null) return out;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
boolean inQuotes = false;
|
||||||
|
for (int i = 0; i < line.length(); i++) {
|
||||||
|
char c = line.charAt(i);
|
||||||
|
if (c == '"') {
|
||||||
|
if (inQuotes && i + 1 < line.length() && line.charAt(i + 1) == '"') {
|
||||||
|
sb.append('"');
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
inQuotes = !inQuotes;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == ',' && !inQuotes) {
|
||||||
|
out.add(sb.toString());
|
||||||
|
sb.setLength(0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
out.add(sb.toString());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelTrainTask syncTaskStatus(String taskId) {
|
public ModelTrainTask syncTaskStatus(String taskId) {
|
||||||
ModelTrainTask task = this.getById(taskId);
|
ModelTrainTask task = this.getById(taskId);
|
||||||
|
|||||||
@ -43,8 +43,13 @@ import java.util.Comparator;
|
|||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.DataFormatter;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -1308,6 +1313,283 @@ public class ProjectServiceImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> importProjectEngineeringExcel(MultipartFile file, boolean overwrite) {
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
return Map.of("code", 1, "msg", "文件不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
DataFormatter df = new DataFormatter();
|
||||||
|
|
||||||
|
try (Workbook wb = new XSSFWorkbook(file.getInputStream())) {
|
||||||
|
Sheet projectsSheet = wb.getSheet("projects");
|
||||||
|
if (projectsSheet == null) {
|
||||||
|
return Map.of("code", 1, "msg", "缺少 projects Sheet");
|
||||||
|
}
|
||||||
|
Row header = projectsSheet.getRow(0);
|
||||||
|
Row dataRow = projectsSheet.getRow(1);
|
||||||
|
if (header == null || dataRow == null) {
|
||||||
|
return Map.of("code", 1, "msg", "projects Sheet 内容为空");
|
||||||
|
}
|
||||||
|
Map<String, Integer> h = headerIndex(header, df);
|
||||||
|
String projectId = cell(df, dataRow, h.get("project_id"));
|
||||||
|
if (projectId == null || projectId.isBlank()) {
|
||||||
|
return Map.of("code", 1, "msg", "project_id 不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
Project exists = this.getById(projectId);
|
||||||
|
if (exists != null && !overwrite) {
|
||||||
|
return Map.of("code", 2, "msg", "项目ID已存在", "data", Map.of("projectId", projectId));
|
||||||
|
}
|
||||||
|
if (exists != null) {
|
||||||
|
deleteProjectCascade(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Project p = new Project();
|
||||||
|
p.setProjectId(projectId);
|
||||||
|
p.setCode(cell(df, dataRow, h.get("code")));
|
||||||
|
p.setName(cell(df, dataRow, h.get("name")));
|
||||||
|
p.setDescription(cell(df, dataRow, h.get("description")));
|
||||||
|
p.setTopology(cell(df, dataRow, h.get("topology")));
|
||||||
|
p.setModifier(cell(df, dataRow, h.get("modifier")));
|
||||||
|
|
||||||
|
String visibility = cell(df, dataRow, h.get("visibility"));
|
||||||
|
if (visibility != null && !visibility.isBlank()) {
|
||||||
|
p.setVisibility(visibility);
|
||||||
|
}
|
||||||
|
String creator = cell(df, dataRow, h.get("creator"));
|
||||||
|
if (creator != null && !creator.isBlank()) {
|
||||||
|
p.setCreator(creator);
|
||||||
|
}
|
||||||
|
|
||||||
|
String createdAt = cell(df, dataRow, h.get("created_at"));
|
||||||
|
if (createdAt != null && !createdAt.isBlank()) {
|
||||||
|
try { p.setCreatedAt(LocalDateTime.parse(createdAt, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
String updatedAt = cell(df, dataRow, h.get("updated_at"));
|
||||||
|
if (updatedAt != null && !updatedAt.isBlank()) {
|
||||||
|
try { p.setUpdatedAt(LocalDateTime.parse(updatedAt, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
this.save(p);
|
||||||
|
|
||||||
|
Sheet devicesSheet = wb.getSheet("devices");
|
||||||
|
if (devicesSheet != null) {
|
||||||
|
List<Device> devices = new ArrayList<>();
|
||||||
|
Map<String, Integer> dh = headerIndex(devicesSheet.getRow(0), df);
|
||||||
|
int last = devicesSheet.getLastRowNum();
|
||||||
|
for (int i = 1; i <= last; i++) {
|
||||||
|
Row r = devicesSheet.getRow(i);
|
||||||
|
if (r == null) continue;
|
||||||
|
String deviceId = cell(df, r, dh.get("device_id"));
|
||||||
|
if (deviceId == null || deviceId.isBlank()) continue;
|
||||||
|
Device d = new Device();
|
||||||
|
d.setDeviceId(deviceId);
|
||||||
|
d.setProjectId(projectId);
|
||||||
|
d.setCode(cell(df, r, dh.get("code")));
|
||||||
|
d.setType(cell(df, r, dh.get("type")));
|
||||||
|
d.setName(cell(df, r, dh.get("name")));
|
||||||
|
d.setSize(cell(df, r, dh.get("size")));
|
||||||
|
d.setVolume(parseDoubleObj(cell(df, r, dh.get("volume"))));
|
||||||
|
d.setFlowRate(parseDoubleObj(cell(df, r, dh.get("flow_rate"))));
|
||||||
|
d.setPulseVelocity(parseDoubleObj(cell(df, r, dh.get("pulse_velocity"))));
|
||||||
|
d.setModifier(cell(df, r, dh.get("modifier")));
|
||||||
|
String dCreated = cell(df, r, dh.get("created_at"));
|
||||||
|
if (dCreated != null && !dCreated.isBlank()) {
|
||||||
|
try { d.setCreatedAt(LocalDateTime.parse(dCreated, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
String dUpdated = cell(df, r, dh.get("updated_at"));
|
||||||
|
if (dUpdated != null && !dUpdated.isBlank()) {
|
||||||
|
try { d.setUpdatedAt(LocalDateTime.parse(dUpdated, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
devices.add(d);
|
||||||
|
}
|
||||||
|
if (!devices.isEmpty()) {
|
||||||
|
deviceService.saveBatch(devices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sheet materialsSheet = wb.getSheet("materials");
|
||||||
|
if (materialsSheet != null) {
|
||||||
|
List<Material> materials = new ArrayList<>();
|
||||||
|
Map<String, Integer> mh = headerIndex(materialsSheet.getRow(0), df);
|
||||||
|
int last = materialsSheet.getLastRowNum();
|
||||||
|
for (int i = 1; i <= last; i++) {
|
||||||
|
Row r = materialsSheet.getRow(i);
|
||||||
|
if (r == null) continue;
|
||||||
|
String materialId = cell(df, r, mh.get("material_id"));
|
||||||
|
if (materialId == null || materialId.isBlank()) continue;
|
||||||
|
Material m = new Material();
|
||||||
|
m.setMaterialId(materialId);
|
||||||
|
m.setProjectId(projectId);
|
||||||
|
m.setName(cell(df, r, mh.get("name")));
|
||||||
|
m.setUConcentration(parseBigDecimal(cell(df, r, mh.get("u_concentration"))));
|
||||||
|
m.setUo2Density(parseBigDecimal(cell(df, r, mh.get("uo2_density"))));
|
||||||
|
m.setUEnrichment(parseBigDecimal(cell(df, r, mh.get("u_enrichment"))));
|
||||||
|
m.setPuConcentration(parseBigDecimal(cell(df, r, mh.get("pu_concentration"))));
|
||||||
|
m.setPuo2Density(parseBigDecimal(cell(df, r, mh.get("puo2_density"))));
|
||||||
|
m.setPuIsotope(parseBigDecimal(cell(df, r, mh.get("pu_isotope"))));
|
||||||
|
m.setHno3Acidity(parseBigDecimal(cell(df, r, mh.get("hno3_acidity"))));
|
||||||
|
m.setH2c2o4Concentration(parseBigDecimal(cell(df, r, mh.get("h2c2o4_concentration"))));
|
||||||
|
m.setOrganicRatio(parseBigDecimal(cell(df, r, mh.get("organic_ratio"))));
|
||||||
|
m.setMoistureContent(parseBigDecimal(cell(df, r, mh.get("moisture_content"))));
|
||||||
|
m.setCustomAttrs(cell(df, r, mh.get("custom_attrs")));
|
||||||
|
m.setModifier(cell(df, r, mh.get("modifier")));
|
||||||
|
String mCreated = cell(df, r, mh.get("created_at"));
|
||||||
|
if (mCreated != null && !mCreated.isBlank()) {
|
||||||
|
try { m.setCreatedAt(LocalDateTime.parse(mCreated, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
String mUpdated = cell(df, r, mh.get("updated_at"));
|
||||||
|
if (mUpdated != null && !mUpdated.isBlank()) {
|
||||||
|
try { m.setUpdatedAt(LocalDateTime.parse(mUpdated, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
materials.add(m);
|
||||||
|
}
|
||||||
|
if (!materials.isEmpty()) {
|
||||||
|
materialService.saveBatch(materials);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sheet scenariosSheet = wb.getSheet("scenarios");
|
||||||
|
List<String> scenarioIds = new ArrayList<>();
|
||||||
|
if (scenariosSheet != null) {
|
||||||
|
List<Scenario> scenarios = new ArrayList<>();
|
||||||
|
Map<String, Integer> sh = headerIndex(scenariosSheet.getRow(0), df);
|
||||||
|
int last = scenariosSheet.getLastRowNum();
|
||||||
|
for (int i = 1; i <= last; i++) {
|
||||||
|
Row r = scenariosSheet.getRow(i);
|
||||||
|
if (r == null) continue;
|
||||||
|
String scenarioId = cell(df, r, sh.get("scenario_id"));
|
||||||
|
if (scenarioId == null || scenarioId.isBlank()) continue;
|
||||||
|
Scenario sc = new Scenario();
|
||||||
|
sc.setScenarioId(scenarioId);
|
||||||
|
sc.setProjectId(projectId);
|
||||||
|
sc.setName(cell(df, r, sh.get("name")));
|
||||||
|
sc.setDescription(cell(df, r, sh.get("description")));
|
||||||
|
sc.setModifier(cell(df, r, sh.get("modifier")));
|
||||||
|
String sCreated = cell(df, r, sh.get("created_at"));
|
||||||
|
if (sCreated != null && !sCreated.isBlank()) {
|
||||||
|
try { sc.setCreatedAt(LocalDateTime.parse(sCreated, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
String sUpdated = cell(df, r, sh.get("updated_at"));
|
||||||
|
if (sUpdated != null && !sUpdated.isBlank()) {
|
||||||
|
try { sc.setUpdatedAt(LocalDateTime.parse(sUpdated, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
scenarios.add(sc);
|
||||||
|
scenarioIds.add(scenarioId);
|
||||||
|
}
|
||||||
|
if (!scenarios.isEmpty()) {
|
||||||
|
scenarioService.saveBatch(scenarios);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sheet eventsSheet = wb.getSheet("events");
|
||||||
|
if (eventsSheet != null) {
|
||||||
|
List<Event> events = new ArrayList<>();
|
||||||
|
Map<String, Integer> eh = headerIndex(eventsSheet.getRow(0), df);
|
||||||
|
int last = eventsSheet.getLastRowNum();
|
||||||
|
for (int i = 1; i <= last; i++) {
|
||||||
|
Row r = eventsSheet.getRow(i);
|
||||||
|
if (r == null) continue;
|
||||||
|
String eventId = cell(df, r, eh.get("event_id"));
|
||||||
|
if (eventId == null || eventId.isBlank()) continue;
|
||||||
|
Event ev = new Event();
|
||||||
|
ev.setEventId(eventId);
|
||||||
|
ev.setScenarioId(cell(df, r, eh.get("scenario_id")));
|
||||||
|
ev.setDeviceId(cell(df, r, eh.get("device_id")));
|
||||||
|
ev.setMaterialId(cell(df, r, eh.get("material_id")));
|
||||||
|
ev.setTriggerTime(parseDoubleObj(cell(df, r, eh.get("trigger_time"))));
|
||||||
|
ev.setAttrChanges(cell(df, r, eh.get("attr_changes")));
|
||||||
|
ev.setModifier(cell(df, r, eh.get("modifier")));
|
||||||
|
String eCreated = cell(df, r, eh.get("created_at"));
|
||||||
|
if (eCreated != null && !eCreated.isBlank()) {
|
||||||
|
try { ev.setCreatedAt(LocalDateTime.parse(eCreated, fmt)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
events.add(ev);
|
||||||
|
}
|
||||||
|
if (!events.isEmpty()) {
|
||||||
|
eventService.saveBatch(events);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sheet resultsSheet = wb.getSheet("scenario_results");
|
||||||
|
if (resultsSheet != null) {
|
||||||
|
List<ScenarioResult> results = new ArrayList<>();
|
||||||
|
Map<String, Integer> rh = headerIndex(resultsSheet.getRow(0), df);
|
||||||
|
int last = resultsSheet.getLastRowNum();
|
||||||
|
for (int i = 1; i <= last; i++) {
|
||||||
|
Row r = resultsSheet.getRow(i);
|
||||||
|
if (r == null) continue;
|
||||||
|
String sid = cell(df, r, rh.get("scenario_id"));
|
||||||
|
if (sid == null || sid.isBlank()) continue;
|
||||||
|
ScenarioResult sr = new ScenarioResult();
|
||||||
|
sr.setScenarioId(sid);
|
||||||
|
sr.setDeviceId(cell(df, r, rh.get("device_id")));
|
||||||
|
String step = cell(df, r, rh.get("step"));
|
||||||
|
if (step != null && !step.isBlank()) {
|
||||||
|
try { sr.setStep((int) Double.parseDouble(step)); } catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
sr.setKeffValue(parseBigDecimal(cell(df, r, rh.get("keff_value"))));
|
||||||
|
sr.setAttrState(cell(df, r, rh.get("attr_state")));
|
||||||
|
results.add(sr);
|
||||||
|
}
|
||||||
|
if (!results.isEmpty()) {
|
||||||
|
scenarioResultService.saveBatch(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Map.of("code", 0, "msg", "导入成功", "data", Map.of("projectId", projectId));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Map.of("code", 1, "msg", "导入失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteProjectCascade(String projectId) {
|
||||||
|
List<Scenario> scenarios = scenarioService.list(new QueryWrapper<Scenario>().select("scenario_id").eq("project_id", projectId));
|
||||||
|
List<String> scenarioIds = scenarios.stream().map(Scenario::getScenarioId).filter(Objects::nonNull).toList();
|
||||||
|
if (!scenarioIds.isEmpty()) {
|
||||||
|
scenarioResultService.remove(new QueryWrapper<ScenarioResult>().in("scenario_id", scenarioIds));
|
||||||
|
eventService.remove(new QueryWrapper<Event>().in("scenario_id", scenarioIds));
|
||||||
|
}
|
||||||
|
scenarioService.remove(new QueryWrapper<Scenario>().eq("project_id", projectId));
|
||||||
|
materialService.remove(new QueryWrapper<Material>().eq("project_id", projectId));
|
||||||
|
deviceService.remove(new QueryWrapper<Device>().eq("project_id", projectId));
|
||||||
|
this.removeById(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Integer> headerIndex(Row header, DataFormatter df) {
|
||||||
|
Map<String, Integer> map = new HashMap<>();
|
||||||
|
if (header == null) return map;
|
||||||
|
short last = header.getLastCellNum();
|
||||||
|
for (int i = 0; i < last; i++) {
|
||||||
|
Cell c = header.getCell(i);
|
||||||
|
String v = c == null ? "" : df.formatCellValue(c);
|
||||||
|
if (v != null && !v.isBlank()) {
|
||||||
|
map.put(v.trim(), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cell(DataFormatter df, Row row, Integer idx) {
|
||||||
|
if (row == null || idx == null) return null;
|
||||||
|
Cell c = row.getCell(idx);
|
||||||
|
if (c == null) return null;
|
||||||
|
String v = df.formatCellValue(c);
|
||||||
|
return v == null ? null : v.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Double parseDoubleObj(String s) {
|
||||||
|
if (s == null || s.isBlank()) return null;
|
||||||
|
try { return Double.parseDouble(s); } catch (Exception e) { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal parseBigDecimal(String s) {
|
||||||
|
if (s == null || s.isBlank()) return null;
|
||||||
|
try { return new BigDecimal(s.trim()); } catch (Exception e) { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
//运行项目模拟
|
//运行项目模拟
|
||||||
@Override
|
@Override
|
||||||
public java.util.Map<String, Object> runSimulation(String projectId, String scenarioId, java.util.Map<String, Object> params) {
|
public java.util.Map<String, Object> runSimulation(String projectId, String scenarioId, java.util.Map<String, Object> params) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user