From e9a97a331bd9c3575ad449bd9e9a08b105af7650 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 07 九月 2026 17:12:29 +0800
Subject: [PATCH] 补齐拼接来源校验与统计
---
ruoyi-admin/src/main/resources/db/migration-final/V17__splice_reports.sql | 2 +-
battery-business/src/main/java/com/battery/business/report/SpliceReportService.java | 9 ++++-----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/battery-business/src/main/java/com/battery/business/report/SpliceReportService.java b/battery-business/src/main/java/com/battery/business/report/SpliceReportService.java
index 32e265c..d312f06 100644
--- a/battery-business/src/main/java/com/battery/business/report/SpliceReportService.java
+++ b/battery-business/src/main/java/com/battery/business/report/SpliceReportService.java
@@ -13,12 +13,11 @@
public List<Candidate> sources(){ TTest q=new TTest(); q.setTestStatus("COMPLETED"); List<Candidate> out=new ArrayList<>(); for(TTest s:tests.selectTestList(q)){TTest t=tests.selectTestById(s.getTestId()); for(TTestBattery b:t.getBatteries()) out.add(candidate(t,b));} return out; }
public Matrix preview(List<SpliceReportRequest.Selection> selections){
if(selections==null||selections.size()<2||new HashSet<>(selections).size()!=selections.size()) throw new ServiceException("请选择至少两个不重复的检测完成测试电池");
- List<Map<String,Object>> segments=new ArrayList<>(); Set<Long> groups=new HashSet<>(); Set<String> batteries=new HashSet<>(); int offset=0; long group=0;
- for(var sel:selections){TTest t=tests.selectTestById(sel.testId()); if(t==null||!"COMPLETED".equals(t.getTestStatus())) throw new ServiceException("仅可选择检测完成测试"); TTestBattery b=t.getBatteries().stream().filter(x->sel.testBatteryId().equals(x.getTestBatteryId())).findFirst().orElseThrow(()->new ServiceException("电池不属于所选测试")); if(group==0)group=b.getGroupId(); if(group!=b.getGroupId()) throw new ServiceException("拼接测试必须属于同一电池组"); groups.add(b.getGroupId()); batteries.add(b.getBatteryNo());
- List<Map<String,Object>> rows=data.cycles(sel.testId()).stream().filter(r->Objects.equals(r.get("batteryNo"),b.getBatteryNo())).toList(); List<Integer> nos=rows.stream().map(this::cycle).filter(x->x>0).distinct().sorted().toList(); Map<String,Object> seg=new LinkedHashMap<>(); seg.put("source",candidate(t,b)); seg.put("offset",offset); seg.put("cycles",rows); seg.put("originalCycleNos",nos); seg.put("statistics",statistics(rows,nos)); segments.add(seg); offset += nos.size(); }
+ List<Map<String,Object>> segments=new ArrayList<>(); Set<Long> groups=new HashSet<>(); Set<String> batteries=new HashSet<>(); int offset=0; long group=0; String commonBattery=null;
+ for(var sel:selections){TTest t=tests.selectTestById(sel.testId()); if(t==null||!"COMPLETED".equals(t.getTestStatus())) throw new ServiceException("仅可选择检测完成测试"); TTestBattery b=t.getBatteries().stream().filter(x->sel.testBatteryId().equals(x.getTestBatteryId())).findFirst().orElseThrow(()->new ServiceException("电池不属于所选测试")); if(group==0)group=b.getGroupId(); if(group!=b.getGroupId()) throw new ServiceException("拼接测试必须属于同一电池组"); if(commonBattery==null)commonBattery=b.getBatteryNo(); if(!commonBattery.equals(b.getBatteryNo())) throw new ServiceException("拼接测试必须选择共同参与的电池号"); groups.add(b.getGroupId()); batteries.add(b.getBatteryNo());
+ List<Map<String,Object>> rows=data.cycles(sel.testId()).stream().filter(r->Objects.equals(r.get("batteryNo"),b.getBatteryNo())).toList(); List<Integer> nos=rows.stream().map(this::cycle).filter(x->x>0).distinct().sorted().toList(); List<Map<String,Object>> stepRows=data.steps(sel.testId()).stream().filter(r->Objects.equals(r.get("batteryNo"),b.getBatteryNo())).toList(); Map<String,Object> seg=new LinkedHashMap<>(); seg.put("source",candidate(t,b)); seg.put("offset",offset); seg.put("cycles",rows); seg.put("originalCycleNos",nos); seg.put("statistics",statistics(rows,stepRows,nos)); segments.add(seg); offset += nos.isEmpty()?0:nos.get(nos.size()-1); }
if(batteries.size()==0) throw new ServiceException("未找到共同参与电池"); return new Matrix(segments,java.util.stream.IntStream.range(1,offset+1).boxed().toList()); }
- private Map<String,Object> statistics(List<Map<String,Object>> rows,List<Integer> nos){Map<String,Object> out=new LinkedHashMap<>(); for(int no:nos){var m=rows.stream().filter(r->cycle(r)==no).toList(); Map<String,Object> v=new LinkedHashMap<>(); if(m.size()==1){Map<String,Object> row=m.get(0); for(String k:List.of("chargeEnergy","dischargeEnergy","chargeCapacity","dischargeCapacity")) if(row.get(k)!=null)v.put(k,row.get(k)); Number c=num(v.get("chargeEnergy")),d=num(v.get("dischargeEnergy")); if(c!=null&&d!=null&&c.doubleValue()>0)v.put("energyEfficiency",BigDecimal.valueOf(d.doubleValue()).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(c.doubleValue()),MathContext.DECIMAL128));} out.put(Integer.toString(no),v);} return out;}
- private List<Map<String,Object>> dataStepRows(Map<String,Object> row){return List.of();}
+ private Map<String,Object> statistics(List<Map<String,Object>> rows,List<Map<String,Object>> stepRows,List<Integer> nos){Map<String,Object> out=new LinkedHashMap<>(); for(int no:nos){var m=rows.stream().filter(r->cycle(r)==no).toList(); Map<String,Object> v=new LinkedHashMap<>(); if(m.size()==1){Map<String,Object> row=m.get(0); for(String k:List.of("chargeEnergy","dischargeEnergy","chargeCapacity","dischargeCapacity")) if(row.get(k)!=null)v.put(k,row.get(k)); List<Map<String,Object>> steps=stepRows.stream().filter(r->cycle(r)==no).toList(); Object end=steps.stream().map(r->r.get("endVoltage")).filter(Objects::nonNull).reduce((a,b)->b).orElse(null); if(end!=null)v.put("finalVoltage1",end); Number c=num(v.get("chargeEnergy")),d=num(v.get("dischargeEnergy")); if(c!=null&&d!=null&&c.doubleValue()>0)v.put("energyEfficiency",BigDecimal.valueOf(d.doubleValue()).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(c.doubleValue()),MathContext.DECIMAL128));} out.put(Integer.toString(no),v);} return out;}
private Number num(Object x){return x instanceof Number?n((Number)x):null;} private Number n(Number x){return x;}
@Transactional public Map<String,Object> create(SpliceReportRequest r,long uid,String user){Matrix m=preview(r.selections()); Map<String,Object> snap=new LinkedHashMap<>(); snap.put("name",r.name().trim());snap.put("description",r.description());snap.put("selections",r.selections());snap.put("segments",m.segments());snap.put("cycleNos",m.cycleNos());snap.put("settings",r.settings()); return get(reports.insert(r.name().trim(),JSON.toJSONString(snap),uid,user,System.currentTimeMillis()),null);}
public Map<String,Object> get(long id,Integer version){var v=reports.get(id,version);Map<String,Object> x=JSON.parseObject(v.snapshotJson());x.put("id",id);x.put("versionNo",v.versionNo());x.put("creator",v.report().creator());x.put("createdAt",v.report().createdAt());x.put("operatorName",v.operatorName());x.put("versionCreatedAt",v.versionCreatedAt());x.put("changeSummary",v.changeSummary());return x;}
diff --git a/ruoyi-admin/src/main/resources/db/migration-final/V17__splice_reports.sql b/ruoyi-admin/src/main/resources/db/migration-final/V17__splice_reports.sql
index 3917a55..7ffcca9 100644
--- a/ruoyi-admin/src/main/resources/db/migration-final/V17__splice_reports.sql
+++ b/ruoyi-admin/src/main/resources/db/migration-final/V17__splice_reports.sql
@@ -3,5 +3,5 @@
CREATE TABLE t_splice_report_version LIKE t_compare_report_version;
ALTER TABLE t_splice_report_version COMMENT='拼接报表独立版本';
INSERT INTO sys_menu(menu_name,parent_id,order_num,path,component,route_name,menu_type,visible,status,perms,icon,create_by,create_time,remark)
-SELECT '拼接报表导出', parent_id, 5, '#', 'F','0','0','0','analysis:splice-report:export','#','admin',UTC_TIMESTAMP(3),'拼接报表导出权限'
+SELECT '拼接报表导出', parent_id, 5, '#', 'F','0','0','0','0','analysis:splice-report:export','#','admin',UTC_TIMESTAMP(3),'拼接报表导出权限'
FROM sys_menu WHERE perms='analysis:splice-report:list' LIMIT 1;
--
Gitblit v1.7.1