添加创建人

This commit is contained in:
wanxiaoli 2025-12-24 15:46:21 +08:00
parent 4d40414e82
commit 02375f3b03
13 changed files with 310 additions and 192 deletions

8
.vscode/launch.json vendored
View File

@ -1,5 +1,13 @@
{
"configurations": [
{
"type": "java",
"name": "Attach to Remote Program5005",
"request": "attach",
"hostName": "localhost",
"port": "5005"
},
java
{
"type": "java",
"name": "CriticalScenarioApplication",

View File

@ -4,10 +4,15 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.business.css.domain.Algorithm;
import com.yfd.business.css.service.AlgorithmService;
import com.yfd.platform.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import java.util.List;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/api/algorithms")
@ -15,6 +20,8 @@ public class AlgorithmController {
@Autowired
private AlgorithmService algorithmService;
@Autowired
private IUserService userService;
@GetMapping("/{id}")
@ -24,12 +31,15 @@ public class AlgorithmController {
@PostMapping
public boolean createAlgorithm(@RequestBody Algorithm algorithm) {
algorithm.setModifier(currentUsername());
return algorithmService.save(algorithm);
}
@PutMapping("/{id}")
public boolean updateAlgorithm(@PathVariable String id, @RequestBody Algorithm algorithm) {
algorithm.setAlgorithmId(id);
algorithm.setModifier(currentUsername());
algorithm.setUpdatedAt(LocalDateTime.now());
return algorithmService.updateById(algorithm);
}
@ -63,4 +73,16 @@ public class AlgorithmController {
Page<Algorithm> page = new Page<>(pageNum, pageSize);
return algorithmService.page(page, queryWrapper);
}
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
}
}

View File

@ -66,9 +66,10 @@ public class CriticalDataController {
}
/**
* 4. 导入临界数据Excel/CSV
* 4. 导入临界数据Excel
* 输入参数表单文件字段 file
* 模板表头device_type, diameter, height, fissile_concentration, isotopic_abundance, keff_value, extra_features
* excel文件中diameter,height,fissile_concentration, isotopic_abundance支持数值型公式型
* 采集规则仅采集上述字段表头中多余字段不予采集extra_features 校验为合法 JSON非法或占位符将置为 null
* 输出参数布尔值表示是否导入成功
* @param file Excel/CSV 文件

View File

@ -4,11 +4,16 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.business.css.domain.Device;
import com.yfd.business.css.service.DeviceService;
import com.yfd.platform.system.service.IUserService;
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 org.springframework.security.authentication.AnonymousAuthenticationToken;
import jakarta.annotation.Resource;
import java.util.List;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/devices")
@ -16,6 +21,8 @@ public class DeviceController {
@Resource
private DeviceService deviceService;
@Resource
private IUserService userService;
/**
* 1. 新增设备
@ -26,6 +33,7 @@ public class DeviceController {
*/
@PostMapping
public boolean create(@RequestBody Device device) {
device.setModifier(currentUsername());
return deviceService.save(device);
}
@ -38,6 +46,8 @@ public class DeviceController {
*/
@PutMapping
public boolean update(@RequestBody Device device) {
device.setModifier(currentUsername());
device.setUpdatedAt(LocalDateTime.now());
return deviceService.updateById(device);
}
@ -66,7 +76,7 @@ public class DeviceController {
}
/**
* 4. 导入设备Excel/CSV
* 4. 导入设备Excel
* 输入参数表单文件字段 file
* 模板表头type, code, name, size, volume, flow_rate, pulse_velocity
* 采集规则仅采集上述字段表头中多余字段不予采集size 校验为合法 JSON非法或占位符将置为 null导入记录的 project_id 统一写入 -1
@ -126,4 +136,16 @@ public class DeviceController {
return deviceService.page(page, wrapper.orderByDesc("created_at"));
}
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
}
}

View File

@ -2,12 +2,17 @@ package com.yfd.business.css.controller;
import com.yfd.business.css.domain.Event;
import com.yfd.business.css.service.EventService;
import com.yfd.platform.system.service.IUserService;
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 org.springframework.security.authentication.AnonymousAuthenticationToken;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.util.Map;
import java.util.List;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
@ -23,10 +28,12 @@ public class EventController {
private final EventService eventService;
private final ObjectMapper objectMapper;
private final IUserService userService;
public EventController(EventService eventService, ObjectMapper objectMapper) {
public EventController(EventService eventService, ObjectMapper objectMapper, IUserService userService) {
this.eventService = eventService;
this.objectMapper = objectMapper;
this.userService = userService;
}
/**
@ -55,6 +62,8 @@ public class EventController {
public ResponseEntity<Map<String, Object>> updateEvent(@PathVariable String eventId,
@RequestBody Event event) {
event.setEventId(eventId);
event.setModifier(currentUsername());
event.setUpdatedAt(LocalDateTime.now());
boolean ok = eventService.updateById(event);
if (!ok) {
return ResponseEntity.badRequest().body(Map.of(
@ -96,6 +105,7 @@ public class EventController {
Event updatedEvent = new Event();
updatedEvent.setEventId(eventId);
updatedEvent.setAttrChanges(String.valueOf(attrChanges));
updatedEvent.setModifier(currentUsername());
eventService.updateById(updatedEvent);
return ResponseEntity.ok(Map.of(
"code", 0,
@ -268,4 +278,16 @@ public class EventController {
return 0.0;
}
}
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
}
}

View File

@ -4,11 +4,16 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.business.css.domain.Material;
import com.yfd.business.css.service.MaterialService;
import com.yfd.platform.system.service.IUserService;
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 org.springframework.security.authentication.AnonymousAuthenticationToken;
import jakarta.annotation.Resource;
import java.util.List;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/materials")
@ -16,6 +21,8 @@ public class MaterialController {
@Resource
private MaterialService materialService;
@Resource
private IUserService userService;
/**
* 1. 新增物料
@ -26,6 +33,7 @@ public class MaterialController {
*/
@PostMapping
public boolean create(@RequestBody Material material) {
material.setModifier(currentUsername());
return materialService.save(material);
}
@ -38,6 +46,8 @@ public class MaterialController {
*/
@PutMapping
public boolean update(@RequestBody Material material) {
material.setModifier(currentUsername());
material.setUpdatedAt(LocalDateTime.now());
return materialService.updateById(material);
}
@ -111,5 +121,15 @@ public class MaterialController {
return materialService.page(page, wrapper);
}
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
}
}

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.business.css.domain.Project;
import com.yfd.business.css.service.ProjectService;
import com.yfd.platform.system.service.IUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -11,6 +12,9 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
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 org.springframework.security.authentication.AnonymousAuthenticationToken;
import jakarta.annotation.Resource;
import java.util.List;
@ -21,6 +25,7 @@ import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/projects")
@ -31,6 +36,8 @@ public class ProjectController {
private ProjectService projectService;
@Resource
private com.fasterxml.jackson.databind.ObjectMapper objectMapper;
@Resource
private IUserService userService;
/**
* 1. 新增项目
@ -42,6 +49,7 @@ public class ProjectController {
@PostMapping
@Operation(summary = "新增项目", description = "请求体传入项目对象,返回是否新增成功")
public boolean create(@RequestBody Project project) {
project.setModifier(currentUsername());
return projectService.save(project);
}
@ -55,9 +63,23 @@ public class ProjectController {
@PutMapping
@Operation(summary = "修改项目", description = "请求体传入项目对象(需包含主键),返回是否修改成功")
public boolean update(@RequestBody Project project) {
project.setModifier(currentUsername());
project.setUpdatedAt(LocalDateTime.now());
return projectService.updateById(project);
}
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
}
/**
* 3.1 删除项目单条
* 输入参数路径参数项目ID
@ -198,6 +220,8 @@ public class ProjectController {
Project updated = new Project();
updated.setProjectId(id);
updated.setTopology(json);
updated.setModifier(currentUsername());
updated.setUpdatedAt(LocalDateTime.now());
projectService.updateById(updated);
return ResponseEntity.ok(Map.of(
"code", 0,

View File

@ -4,10 +4,15 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.business.css.domain.Scenario;
import com.yfd.business.css.service.ScenarioService;
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 org.springframework.security.authentication.AnonymousAuthenticationToken;
import jakarta.annotation.Resource;
import java.util.List;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/scenarios")
@ -15,6 +20,8 @@ public class ScenarioController {
@Resource
private ScenarioService scenarioService;
@Resource
private IUserService userService;
/**
* 1. 新增情景
@ -25,6 +32,7 @@ public class ScenarioController {
*/
@PostMapping
public boolean create(@RequestBody Scenario scenario) {
scenario.setModifier(currentUsername());
return scenarioService.save(scenario);
}
@ -37,6 +45,8 @@ public class ScenarioController {
*/
@PutMapping
public boolean update(@RequestBody Scenario scenario) {
scenario.setModifier(currentUsername());
scenario.setUpdatedAt(LocalDateTime.now());
return scenarioService.updateById(scenario);
}
@ -100,4 +110,16 @@ public class ScenarioController {
}
return scenarioService.page(page, wrapper.orderByDesc("created_at"));
}
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
}
}

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.business.css.domain.CriticalData;
import com.yfd.business.css.mapper.CriticalDataMapper;
import com.yfd.business.css.service.CriticalDataService;
import com.yfd.platform.system.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@ -11,55 +12,71 @@ import org.apache.poi.ss.usermodel.Cell;
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.DataFormatter;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import java.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class CriticalDataServiceImpl
extends ServiceImpl<CriticalDataMapper, CriticalData>
implements CriticalDataService {
@Resource
private ObjectMapper objectMapper;
@Resource
private IUserService userService;
@Override
public boolean importCriticalData(MultipartFile file) {
try {
String name = file.getOriginalFilename();
log.info("critical-data 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("critical-data detected type=xlsx");
return importExcel(new XSSFWorkbook(file.getInputStream()));
} else if (lower.endsWith(".xls")) {
log.info("critical-data detected type=xls");
return importExcel(new HSSFWorkbook(file.getInputStream()));
} else if (lower.endsWith(".csv")) {
return importCsv(file.getInputStream());
} else {
log.warn("critical-data unsupported file type name={}", name);
return false;
}
} catch (Exception e) {
log.error("critical-data import failed", e);
return false;
}
}
private boolean importExcel(Workbook workbook) {
try (Workbook wb = workbook) {
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
evaluator.evaluateAll();
DataFormatter formatter = new DataFormatter();
Sheet sheet = wb.getSheetAt(0);
if (sheet == null) return false;
if (sheet == null) {
log.warn("critical-data excel sheet null");
return false;
}
Row headerRow = sheet.getRow(0);
if (headerRow == null) return false;
if (headerRow == null) {
log.warn("critical-data 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);
@ -67,69 +84,59 @@ public class CriticalDataServiceImpl
String key = c.getStringCellValue();
if (key != null) idx.put(key.trim().toLowerCase(), i);
}
log.info("critical-data excel header keys={}", idx.keySet());
String[] keys = new String[]{
"device_type","diameter","height",
"fissile_concentration","isotopic_abundance",
"keff_value","extra_features"
};
for (String k : keys) if (!idx.containsKey(k)) return false;
List<String> missing = new ArrayList<>();
for (String k : keys) if (!idx.containsKey(k)) missing.add(k);
if (!missing.isEmpty()) {
log.warn("critical-data excel missing headers={}", missing);
return false;
}
List<CriticalData> list = new ArrayList<>();
for (int r = 1; r <= sheet.getLastRowNum(); r++) {
Row row = sheet.getRow(r);
if (row == null) continue;
CriticalData cd = new CriticalData();
cd.setDeviceType(cleanString(getString(row, idx.get("device_type"))));
cd.setDiameter(cleanDecimal(getDecimal(row, idx.get("diameter"))));
cd.setHeight(cleanDecimal(getDecimal(row, idx.get("height"))));
cd.setFissileConcentration(cleanDecimal(getDecimal(row, idx.get("fissile_concentration"))));
cd.setIsotopicAbundance(cleanDecimal(getDecimal(row, idx.get("isotopic_abundance"))));
cd.setKeffValue(cleanDecimal(getDecimal(row, idx.get("keff_value"))));
cd.setExtraFeatures(validateJson(cleanString(getString(row, idx.get("extra_features")))));
cd.setDiameter(cleanDecimal(getDecimalFlexible(row, idx.get("diameter"), evaluator, formatter)));
cd.setHeight(cleanDecimal(getDecimalFlexible(row, idx.get("height"), evaluator, formatter)));
cd.setFissileConcentration(cleanDecimal(getDecimalFlexible(row, idx.get("fissile_concentration"), evaluator, formatter)));
cd.setIsotopicAbundance(cleanDecimal(getDecimalFlexible(row, idx.get("isotopic_abundance"), evaluator, formatter)));
cd.setKeffValue(cleanDecimal(getDecimalFlexible(row, idx.get("keff_value"), evaluator, formatter)));
String extraRaw = cleanString(getString(row, idx.get("extra_features")));
String extra = validateJson(extraRaw);
if (extraRaw != null && extra == null) {
log.warn("critical-data excel invalid JSON at row={} raw={}", r, extraRaw);
}
cd.setExtraFeatures(extra);
cd.setCreatedAt(LocalDateTime.now());
cd.setUpdatedAt(LocalDateTime.now());
if (isEmpty(cd)) continue;
cd.setModifier(currentUsername());
List<String> miss = missingRequired(cd);
if (!miss.isEmpty()) {
log.warn("critical-data excel skip row={} missing={}", r, miss);
continue;
}
if (isOutOfRange(cd.getFissileConcentration(), 7, 3)) {
log.warn("critical-data excel skip row={} out_of_range field=fissile_concentration value={}", r, cd.getFissileConcentration());
continue;
}
list.add(cd);
}
if (list.isEmpty()) return false;
return this.saveBatch(list);
} catch (Exception e) {
log.info("critical-data excel parsed rows={} valid={}", sheet.getLastRowNum(), list.size());
if (list.isEmpty()) {
log.warn("critical-data excel parsed list empty");
return false;
}
}
private boolean importCsv(InputStream is) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String header = br.readLine();
if (header == null) return false;
String[] hs = header.split(",");
Map<String, Integer> idx = new HashMap<>();
for (int i = 0; i < hs.length; i++) idx.put(hs[i].trim().toLowerCase(), i);
String[] keys = new String[]{
"device_type","diameter","height",
"fissile_concentration","isotopic_abundance",
"keff_value","extra_features"
};
for (String k : keys) if (!idx.containsKey(k)) return false;
List<CriticalData> list = new ArrayList<>();
String line;
while ((line = br.readLine()) != null) {
String[] cols = line.split(",");
CriticalData cd = new CriticalData();
cd.setDeviceType(cleanString(get(cols, idx.get("device_type"))));
cd.setDiameter(cleanDecimal(parseDecimal(get(cols, idx.get("diameter")))));
cd.setHeight(cleanDecimal(parseDecimal(get(cols, idx.get("height")))));
cd.setFissileConcentration(cleanDecimal(parseDecimal(get(cols, idx.get("fissile_concentration")))));
cd.setIsotopicAbundance(cleanDecimal(parseDecimal(get(cols, idx.get("isotopic_abundance")))));
cd.setKeffValue(cleanDecimal(parseDecimal(get(cols, idx.get("keff_value")))));
cd.setExtraFeatures(validateJson(cleanString(get(cols, idx.get("extra_features")))));
cd.setCreatedAt(LocalDateTime.now());
cd.setUpdatedAt(LocalDateTime.now());
if (isEmpty(cd)) continue;
list.add(cd);
}
if (list.isEmpty()) return false;
return this.saveBatch(list);
boolean ok = this.saveBatch(list, 500);
log.info("critical-data excel saveBatch result={}", ok);
return ok;
} catch (Exception e) {
log.error("critical-data excel import failed", e);
return false;
}
}
@ -145,27 +152,40 @@ public class CriticalDataServiceImpl
}
}
private BigDecimal getDecimal(Row row, int i) {
private BigDecimal getDecimalFlexible(Row row, int i, FormulaEvaluator evaluator, DataFormatter formatter) {
Cell c = row.getCell(i);
if (c == null) return null;
switch (c.getCellType()) {
case NUMERIC: return BigDecimal.valueOf(c.getNumericCellValue());
case STRING:
try { return new BigDecimal(c.getStringCellValue().trim()); } catch (Exception e) { return null; }
default: return null;
}
}
private String get(String[] cols, int i) {
if (i < 0 || i >= cols.length) return null;
String v = cols[i];
if (v == null) return null;
return v.trim();
String txt = formatter.formatCellValue(c, evaluator);
return parseDecimal(txt);
}
private BigDecimal parseDecimal(String s) {
if (s == null || s.isEmpty()) return null;
try { return new BigDecimal(s.trim()); } catch (Exception e) { return null; }
String t = s.trim().replace(",", "");
try { return new BigDecimal(t); } catch (Exception e) {
StringBuilder sb = new StringBuilder();
boolean started = false;
for (int idx = 0; idx < t.length(); idx++) {
char ch = t.charAt(idx);
if (!started) {
if (ch == '+' || ch == '-' || Character.isDigit(ch)) {
sb.append(ch);
started = true;
} else if (ch == '.') {
sb.append(ch);
started = true;
}
} else {
if (Character.isDigit(ch) || ch == '.') {
sb.append(ch);
} else {
break;
}
}
}
if (sb.length() == 0) return null;
try { return new BigDecimal(sb.toString()); } catch (Exception ex) { return null; }
}
}
private boolean isPlaceholder(String s) {
@ -182,8 +202,22 @@ public class CriticalDataServiceImpl
return d;
}
private boolean isEmpty(CriticalData cd) {
return cd.getDeviceType() == null || cd.getDeviceType().isEmpty();
private List<String> missingRequired(CriticalData cd) {
List<String> miss = new ArrayList<>();
if (cd.getDeviceType() == null || cd.getDeviceType().isEmpty()) miss.add("device_type");
if (cd.getHeight() == null) miss.add("height");
if (cd.getDiameter() == null) miss.add("diameter");
if (cd.getFissileConcentration() == null) miss.add("fissile_concentration");
if (cd.getIsotopicAbundance() == null) miss.add("isotopic_abundance");
if (cd.getKeffValue() == null) miss.add("keff_value");
return miss;
}
private boolean isOutOfRange(BigDecimal v, int maxIntegerDigits, int maxScale) {
if (v == null) return false;
int scale = Math.max(v.scale(), 0);
int intDigits = v.precision() - scale;
return intDigits > maxIntegerDigits || scale > maxScale;
}
private String validateJson(String s) {
@ -196,4 +230,15 @@ public class CriticalDataServiceImpl
}
}
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
}
}

View File

@ -4,8 +4,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.business.css.domain.Device;
import com.yfd.business.css.mapper.DeviceMapper;
import com.yfd.business.css.service.DeviceService;
import com.yfd.platform.system.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
@ -16,10 +20,6 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.util.ArrayList;
@ -32,6 +32,8 @@ public class DeviceServiceImpl
implements DeviceService {
@Resource
private ObjectMapper objectMapper;
@Resource
private IUserService userService;
@Override
public boolean importDevices(MultipartFile file) {
try {
@ -42,8 +44,6 @@ public class DeviceServiceImpl
return importExcel(new XSSFWorkbook(file.getInputStream()));
} else if (lower.endsWith(".xls")) {
return importExcel(new HSSFWorkbook(file.getInputStream()));
} else if (lower.endsWith(".csv")) {
return importCsv(file.getInputStream());
} else {
return false;
}
@ -84,40 +84,7 @@ public class DeviceServiceImpl
d.setProjectId("-1");
d.setCreatedAt(LocalDateTime.now());
d.setUpdatedAt(LocalDateTime.now());
if (isEmpty(d)) continue;
devices.add(d);
}
if (devices.isEmpty()) return false;
return this.saveBatch(devices);
} catch (Exception e) {
return false;
}
}
private boolean importCsv(InputStream is) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String header = br.readLine();
if (header == null) return false;
String[] hs = header.split(",");
Map<String, Integer> idx = new HashMap<>();
for (int i = 0; i < hs.length; i++) idx.put(hs[i].trim().toLowerCase(), i);
String[] keys = new String[]{"type","code","name","size","volume","flow_rate","pulse_velocity"};
for (String k : keys) if (!idx.containsKey(k)) return false;
List<Device> devices = new ArrayList<>();
String line;
while ((line = br.readLine()) != null) {
String[] cols = line.split(",");
Device d = new Device();
d.setType(get(cols, idx.get("type")));
d.setCode(get(cols, idx.get("code")));
d.setName(get(cols, idx.get("name")));
d.setSize(validateJson(get(cols, idx.get("size"))));
d.setVolume(parseDouble(get(cols, idx.get("volume"))));
d.setFlowRate(parseDouble(get(cols, idx.get("flow_rate"))));
d.setPulseVelocity(parseDouble(get(cols, idx.get("pulse_velocity"))));
d.setProjectId("-1");
d.setCreatedAt(LocalDateTime.now());
d.setUpdatedAt(LocalDateTime.now());
d.setModifier(currentUsername());
if (isEmpty(d)) continue;
devices.add(d);
}
@ -150,18 +117,6 @@ public class DeviceServiceImpl
}
}
private String get(String[] cols, int i) {
if (i < 0 || i >= cols.length) return null;
String v = cols[i];
if (v == null) return null;
return v.trim();
}
private Double parseDouble(String s) {
if (s == null || s.isEmpty()) return null;
try { return Double.parseDouble(s); } catch (Exception e) { return null; }
}
private boolean isEmpty(Device d) {
return (d.getCode() == null || d.getCode().isEmpty()) && (d.getName() == null || d.getName().isEmpty());
}
@ -175,4 +130,16 @@ public class DeviceServiceImpl
return null;
}
}
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
}
}

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.business.css.domain.Material;
import com.yfd.business.css.mapper.MaterialMapper;
import com.yfd.business.css.service.MaterialService;
import com.yfd.platform.system.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@ -16,10 +17,9 @@ import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import java.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.ArrayList;
@ -33,6 +33,8 @@ public class MaterialServiceImpl
implements MaterialService {
@Resource
private ObjectMapper objectMapper;
@Resource
private IUserService userService;
@Override
public boolean importMaterials(MultipartFile file) {
try {
@ -43,8 +45,6 @@ public class MaterialServiceImpl
return importExcel(new XSSFWorkbook(file.getInputStream()));
} else if (lower.endsWith(".xls")) {
return importExcel(new HSSFWorkbook(file.getInputStream()));
} else if (lower.endsWith(".csv")) {
return importCsv(file.getInputStream());
} else {
return false;
}
@ -95,50 +95,7 @@ public class MaterialServiceImpl
m.setProjectId("-1");
m.setCreatedAt(LocalDateTime.now());
m.setUpdatedAt(LocalDateTime.now());
if (isEmpty(m)) continue;
list.add(m);
}
if (list.isEmpty()) return false;
return this.saveBatch(list);
} catch (Exception e) {
return false;
}
}
private boolean importCsv(InputStream is) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String header = br.readLine();
if (header == null) return false;
String[] hs = header.split(",");
Map<String, Integer> idx = new HashMap<>();
for (int i = 0; i < hs.length; i++) idx.put(hs[i].trim().toLowerCase(), i);
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"
};
for (String k : keys) if (!idx.containsKey(k)) return false;
List<Material> list = new ArrayList<>();
String line;
while ((line = br.readLine()) != null) {
String[] cols = line.split(",");
Material m = new Material();
m.setName(cleanString(get(cols, idx.get("name"))));
m.setUConcentration(cleanDecimal(parseDecimal(get(cols, idx.get("u_concentration")))));
m.setUo2Density(cleanDecimal(parseDecimal(get(cols, idx.get("uo2_density")))));
m.setUEnrichment(cleanDecimal(parseDecimal(get(cols, idx.get("u_enrichment")))));
m.setPuConcentration(cleanDecimal(parseDecimal(get(cols, idx.get("pu_concentration")))));
m.setPuo2Density(cleanDecimal(parseDecimal(get(cols, idx.get("puo2_density")))));
m.setPuIsotope(cleanDecimal(parseDecimal(get(cols, idx.get("pu_isotope")))));
m.setHno3Acidity(cleanDecimal(parseDecimal(get(cols, idx.get("hno3_acidity")))));
m.setH2c2o4Concentration(cleanDecimal(parseDecimal(get(cols, idx.get("h2c2o4_concentration")))));
m.setOrganicRatio(cleanDecimal(parseDecimal(get(cols, idx.get("organic_ratio")))));
m.setMoistureContent(cleanDecimal(parseDecimal(get(cols, idx.get("moisture_content")))));
m.setCustomAttrs(validateJson(cleanString(get(cols, idx.get("custom_attrs")))));
m.setProjectId("-1");
m.setCreatedAt(LocalDateTime.now());
m.setUpdatedAt(LocalDateTime.now());
m.setModifier(currentUsername());
if (isEmpty(m)) continue;
list.add(m);
}
@ -171,16 +128,16 @@ public class MaterialServiceImpl
}
}
private String get(String[] cols, int i) {
if (i < 0 || i >= cols.length) return null;
String v = cols[i];
if (v == null) return null;
return v.trim();
private String currentUsername() {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth instanceof AnonymousAuthenticationToken) {
return "anonymous";
}
return userService.getUsername();
} catch (Exception e) {
return "anonymous";
}
private BigDecimal parseDecimal(String s) {
if (s == null || s.isEmpty()) return null;
try { return new BigDecimal(s.trim()); } catch (Exception e) { return null; }
}
private boolean isEmpty(Material m) {

View File

@ -15,10 +15,15 @@ spring:
username: root
password: ylfw20230626@
file-space: #项目文档空间
files: D:\css\files\ #单独上传的文件附件
system: D:\css\system\ #单独上传的文件
file-space:
files: D:\css\files\
system: D:\css\system\
security:
dev:
permit: true
logging:
file:
name: logs/business-css.log
level:
root: INFO

View File

@ -228,6 +228,9 @@ scripts\mvn17.cmd -s mvn-settings.xml -DskipTests -pl framework -am install
scripts\mvn17.cmd -s mvn-settings.xml -DskipTests -f business-css\pom.xml spring-boot:run -Dspring-boot.run.profiles=business
- debug方式启动
scripts\mvn17-debug.cmd -s mvn-settings.xml -DskipTests -f business-css\pom.xml spring-boot:run -Dspring-boot.run.profiles=business
## 在工具内终端验证并调整到 17
- 验证: mvn -version 、 where java 、 where mvn
- 临时修正当前终端(一次性手动):