xushili 1 سال پیش
والد
کامیت
b516da9e40

+ 22 - 0
web/runeconomy-jjyx/src/main/java/com/gyee/runeconomy/controller/goodness/StationAnalysisController.java

@@ -9,6 +9,8 @@ import com.gyee.runeconomy.dto.response.InverterAnalysis;
 import com.gyee.runeconomy.dto.response.InverterAnalysis2;
 import com.gyee.runeconomy.dto.response.StationAnalysis;
 import com.gyee.runeconomy.model.fitting.ProEconAnalysisClean;
+import com.gyee.runeconomy.service.auto.IProEconPowerstationInfoDay1Service;
+import com.gyee.runeconomy.service.fitting.EconomyAnalysisService;
 import com.gyee.runeconomy.service.goodness.WindturbinegoodnessService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -27,6 +29,8 @@ public class StationAnalysisController {
 
     @Resource
     private WindturbinegoodnessService windturbinegoodnessService;
+    @Resource
+    private EconomyAnalysisService economyAnalysisService;
 
 
     /**
@@ -53,6 +57,24 @@ public class StationAnalysisController {
         }
     }
 
+    @GetMapping("/analysis")
+    @ResponseBody
+    @ApiOperation(value = "场站性能分析报告", notes = "场站性能分析报告")
+    public R stationAnalyse(@RequestParam(value = "wpid", required = true) String wpid,
+                            @RequestParam(value = "year", required = true) String year,
+                            @RequestParam(value = "month", required = true) String month,
+                            @RequestParam(value = "target", required = false) String target,
+                            @RequestParam(value = "sort", required = false) String sort
+    ) throws Exception {
+
+        Map<String, List<String>> resultList = economyAnalysisService.getReport(wpid, year, month, target, sort);
+
+        if (StringUtils.isNotNull(resultList)) {
+            return R.data(ResultMsg.ok(resultList));
+        } else {
+            return R.error(ResultMsg.error());
+        }
+    }
 
     /**
      * 逆变器分析

+ 410 - 0
web/runeconomy-jjyx/src/main/java/com/gyee/runeconomy/service/fitting/EconomyAnalysisService.java

@@ -0,0 +1,410 @@
+package com.gyee.runeconomy.service.fitting;
+
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.gyee.runeconomy.dto.response.StationAnalysis;
+import com.gyee.runeconomy.init.CacheContext;
+import com.gyee.runeconomy.model.auto.ProBasicOrganizeTree;
+import com.gyee.runeconomy.model.auto.ProBasicProjectPlan;
+import com.gyee.runeconomy.model.auto.ProEconBenchmark;
+import com.gyee.runeconomy.model.auto.ProEconPowerstationInfoDay1;
+import com.gyee.runeconomy.service.auto.IProBasicProjectPlanService;
+import com.gyee.runeconomy.service.auto.IProEconBenchmarkService;
+import com.gyee.runeconomy.service.auto.IProEconPowerstationInfoDay1Service;
+import com.gyee.runeconomy.util.MathUtil;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class EconomyAnalysisService {
+
+    @Resource
+    private IProBasicProjectPlanService projectPlanService;
+    @Resource
+    private IProEconPowerstationInfoDay1Service powerstationInfoDay1Service;
+    @Resource
+    private IProEconBenchmarkService benchmarkService;
+
+    private List<String> stationList;
+
+    /**
+     * 场站,指标,数据
+     */
+    private Map<String, Map<String, String>> monthMap = new HashMap<>();
+
+    public Map<String, List<String>> getReport(String wpid, String year, String month, String target, String sort) {
+        calc(year, month);
+        Map<String, List<String>> word = getWord(wpid, year, month);
+        return word;
+    }
+
+    public void calc(String year, String month) {
+        getMonthMap();
+        //月初
+        DateTime monthbegin = DateUtil.parse(year + "-" + month + "-01");
+        //月结束
+        DateTime monthend = DateUtil.endOfMonth(monthbegin);
+        //去年同期
+        DateTime lastyearbegin = DateUtil.offset(monthbegin, DateField.YEAR, -1);
+        //上期
+        DateTime lastmonthbegin = DateUtil.offsetMonth(monthbegin, -1);
+        //去年同期结束
+        DateTime lastyearend = DateUtil.offset(monthend, DateField.YEAR, -1);
+        //上期结束
+        DateTime lastmonthend = DateUtil.offsetMonth(monthend, -1);
+
+        QueryWrapper<ProBasicProjectPlan> ppwrapper = new QueryWrapper<>();
+        ppwrapper.eq("YEAR", year).eq("MONTH", month);
+        List<ProBasicProjectPlan> pplist = projectPlanService.list(ppwrapper);
+
+        Map<String, Double> gczyjhfdl = pplist.stream().collect(Collectors.groupingBy(ProBasicProjectPlan::getWindpowerstationId, Collectors.summingDouble(gc -> gc.getGeneratingCapacity())));
+        gczyjhfdl.forEach((cz, jhfdl) -> {
+            monthMap.get(cz).put("计划电量", String.valueOf(jhfdl));
+        });
+
+        QueryWrapper<ProEconPowerstationInfoDay1> pepidWrapper = new QueryWrapper<>();
+        List<ProEconPowerstationInfoDay1> pepidList = powerstationInfoDay1Service.list(pepidWrapper.clone().between("record_date", monthbegin, monthend));
+        List<ProEconPowerstationInfoDay1> pepidListTq = powerstationInfoDay1Service.list(pepidWrapper.clone().between("record_date", lastyearbegin, lastyearend));
+        List<ProEconPowerstationInfoDay1> pepidListSq = powerstationInfoDay1Service.list(pepidWrapper.clone().between("record_date", lastmonthbegin, lastmonthend));
+
+        Map<String, BigDecimal> pepidMap = pepidList.stream().filter(p->p.getWindpowerstationId()!=null&&p.getRfdl()!=null)
+                .collect(Collectors.groupingBy(ProEconPowerstationInfoDay1::getWindpowerstationId, Collectors.reducing(BigDecimal.ZERO, ProEconPowerstationInfoDay1::getRfdl, BigDecimal::add)));
+        Map<String, BigDecimal> pepidMapTq = pepidListTq.stream().filter(p->p.getWindpowerstationId()!=null&&p.getRfdl()!=null)
+                .collect(Collectors.groupingBy(ProEconPowerstationInfoDay1::getWindpowerstationId, Collectors.reducing(BigDecimal.ZERO, ProEconPowerstationInfoDay1::getRfdl, BigDecimal::add)));
+        Map<String, BigDecimal> pepidMapSq = pepidListSq.stream().filter(p->p.getWindpowerstationId()!=null&&p.getRfdl()!=null)
+                .collect(Collectors.groupingBy(ProEconPowerstationInfoDay1::getWindpowerstationId, Collectors.reducing(BigDecimal.ZERO, ProEconPowerstationInfoDay1::getRfdl, BigDecimal::add)));
+
+        for (ProEconPowerstationInfoDay1 day1 : pepidList) {
+            String wpid = day1.getWindpowerstationId();
+            monthMap.get(wpid).put("实际电量", MathUtil.plain(pepidMap.get(wpid),2));
+            monthMap.get(wpid).put("去年同期实际电量", MathUtil.plain(pepidMapTq.get(wpid),2));
+            monthMap.get(wpid).put("上期实际电量", MathUtil.plain(pepidMapSq.get(wpid),2));
+            monthMap.get(wpid).put("实际电量同比", getRatio(wpid, "实际电量", "去年同期实际电量"));
+            monthMap.get(wpid).put("实际电量环比", getRatio(wpid, "实际电量", "上期实际电量"));
+            monthMap.get(wpid).put("实际电量完成率", getCompletRate(wpid, "实际电量", "计划电量"));
+        }
+
+        /*----------------------------------------本月----------------------------------------------*/
+        QueryWrapper<ProEconBenchmark> bmwrapper = new QueryWrapper<>();
+        bmwrapper.between("record_date", monthbegin, monthend);
+        List<ProEconBenchmark> bmlist = benchmarkService.list(bmwrapper);
+
+        Map<String, List<ProEconBenchmark>> bmsl = bmlist.stream().collect(Collectors.groupingBy(ProEconBenchmark::getForeignKeyId));
+        bmsl.forEach((cz, bml) -> {
+            putBenchmarkData(cz, "", bml);
+        });
+
+        bmwrapper.clear();
+        bmwrapper.between("record_date", lastyearbegin, lastyearend);
+        List<ProEconBenchmark> qntqbmlist = benchmarkService.list(bmwrapper);
+        Map<String, List<ProEconBenchmark>> qntqbmsl = qntqbmlist.stream().collect(Collectors.groupingBy(ProEconBenchmark::getForeignKeyId));
+        qntqbmsl.forEach((cz, bml) -> {
+            putBenchmarkData(cz, "去年同期", bml);
+        });
+
+        bmwrapper.clear();
+        bmwrapper.between("record_date", lastmonthbegin, lastmonthend);
+        List<ProEconBenchmark> sqbmlist = benchmarkService.list(bmwrapper);
+        Map<String, List<ProEconBenchmark>> sqbmsl = sqbmlist.stream().collect(Collectors.groupingBy(ProEconBenchmark::getForeignKeyId));
+        sqbmsl.forEach((cz, bml) -> {
+            putBenchmarkData(cz, "上期", bml);
+        });
+
+        for (String s : getStationList()) {
+            putBenchmarkTBHBData(s);
+        }
+    }
+
+    //经济运行首页数据同比环比
+    private void putBenchmarkTBHBData(String station) {
+        monthMap.get(station).put("理论发电量同比", getRatio(station, "理论发电量", "去年同期理论发电量"));
+        monthMap.get(station).put("理论发电量环比", getRatio(station, "理论发电量", "上期理论发电量"));
+        monthMap.get(station).put("实际电量同比", getRatio(station, "实际电量", "去年同期实际电量"));
+        monthMap.get(station).put("实际电量环比", getRatio(station, "实际电量", "上期实际电量"));
+        monthMap.get(station).put("设备利用小时同比", getRatioNoBFB(station, "设备利用小时", "去年同期设备利用小时"));
+        monthMap.get(station).put("设备利用小时环比", getRatioNoBFB(station, "设备利用小时", "上期设备利用小时"));
+        monthMap.get(station).put("风能利用率同比", getRatio(station, "风能利用率", "去年同期风能利用率"));
+        monthMap.get(station).put("风能利用率环比", getRatio(station, "风能利用率", "上期风能利用率"));
+        monthMap.get(station).put("故障损失电量同比", getRatio(station, "故障损失电量", "去年同期故障损失电量"));
+        monthMap.get(station).put("故障损失电量环比", getRatio(station, "故障损失电量", "上期故障损失电量"));
+        monthMap.get(station).put("限电损失电量同比", getRatio(station, "限电损失电量", "去年同期限电损失电量"));
+        monthMap.get(station).put("限电损失电量环比", getRatio(station, "限电损失电量", "上期限电损失电量"));
+        monthMap.get(station).put("受累损失电量同比", getRatio(station, "受累损失电量", "去年同期受累损失电量"));
+        monthMap.get(station).put("受累损失电量环比", getRatio(station, "受累损失电量", "上期受累损失电量"));
+        monthMap.get(station).put("性能损失电量同比", getRatioNoBFB(station, "性能损失电量", "去年同期性能损失电量"));
+        monthMap.get(station).put("性能损失电量环比", getRatioNoBFB(station, "性能损失电量", "上期性能损失电量"));
+        monthMap.get(station).put("计划检修损失电量同比", getRatio(station, "计划检修损失电量", "去年同期计划检修损失电量"));
+        monthMap.get(station).put("计划检修损失电量环比", getRatio(station, "计划检修损失电量", "上期计划检修损失电量"));
+        monthMap.get(station).put("故障损失率同比", getRatio(station, "故障损失率", "去年同期故障损失率"));
+        monthMap.get(station).put("故障损失率环比", getRatio(station, "故障损失率", "上期故障损失率"));
+        monthMap.get(station).put("限电损失率同比", getRatio(station, "限电损失率", "去年同期限电损失率"));
+        monthMap.get(station).put("限电损失率环比", getRatio(station, "限电损失率", "上期限电损失率"));
+        monthMap.get(station).put("受累损失率同比", getRatio(station, "受累损失率", "去年同期受累损失率"));
+        monthMap.get(station).put("受累损失率环比", getRatio(station, "受累损失率", "上期受累损失率"));
+        monthMap.get(station).put("性能损失率同比", getRatio(station, "性能损失率", "去年同期性能损失率"));
+        monthMap.get(station).put("性能损失率环比", getRatio(station, "性能损失率", "上期性能损失率"));
+        monthMap.get(station).put("计划检修损失率同比", getRatio(station, "计划检修损失率", "去年同期计划检修损失率"));
+        monthMap.get(station).put("计划检修损失率环比", getRatio(station, "计划检修损失率", "上期计划检修损失率"));
+        monthMap.get(station).put("平均风速同比", getRatio(station, "平均风速", "去年同期平均风速"));
+        monthMap.get(station).put("平均风速环比", getRatio(station, "平均风速", "上期平均风速"));
+        monthMap.get(station).put("损失电量同比", getRatio(station, "损失电量", "去年同期损失电量"));
+        monthMap.get(station).put("损失电量环比", getRatio(station, "损失电量", "上期损失电量"));
+        monthMap.get(station).put("损失率同比", getRatio(station, "损失率", "去年同期损失率"));
+        monthMap.get(station).put("损失率环比", getRatio(station, "损失率", "上期损失率"));
+        monthMap.get(station).put("复位及时率同比", getRatio(station, "复位及时率", "去年同期复位及时率"));
+        monthMap.get(station).put("复位及时率环比", getRatio(station, "复位及时率", "上期复位及时率"));
+        monthMap.get(station).put("状态转换率同比", getRatio(station, "状态转换率", "去年同期状态转换率"));
+        monthMap.get(station).put("状态转换率环比", getRatio(station, "状态转换率", "上期状态转换率"));
+        monthMap.get(station).put("消缺及时率同比", getRatio(station, "消缺及时率", "去年同期消缺及时率"));
+        monthMap.get(station).put("消缺及时率环比", getRatio(station, "消缺及时率", "上期消缺及时率"));
+        monthMap.get(station).put("厂用电率同比", getRatio(station, "厂用电率", "去年同期厂用电率"));
+        monthMap.get(station).put("厂用电率环比", getRatio(station, "厂用电率", "上期厂用电率"));
+        monthMap.get(station).put("厂用电量同比", getRatioNoBFB(station, "厂用电量", "去年同期厂用电量"));
+        monthMap.get(station).put("厂用电量环比", getRatioNoBFB(station, "厂用电量", "上期厂用电量"));
+    }
+
+    //经济运行首页数据
+    private void putBenchmarkData(String station, String addStr, List<ProEconBenchmark> bml) {
+        double llfdlsum = bml.stream().mapToDouble(ProEconBenchmark::getTheoreticalPower).sum();
+        monthMap.get(station).put(addStr + "理论发电量", String.valueOf(llfdlsum));
+        double sjdlsum = bml.stream().mapToDouble(ProEconBenchmark::getActualPower).sum();
+        monthMap.get(station).put(addStr + "实际电量", NumberUtil.roundStr(sjdlsum,2));
+        double sblyxssum = bml.stream().mapToDouble(ProEconBenchmark::getUtilizationHours).sum();
+        monthMap.get(station).put(addStr + "设备利用小时", String.valueOf(sblyxssum));
+        double fnlylsum = bml.stream().mapToDouble(ProEconBenchmark::getWindenergy).average().orElse(0);
+        monthMap.get(station).put(addStr + "风能利用率", NumberUtil.roundStr(fnlylsum, 2));
+        double gzsssum = bml.stream().mapToDouble(ProEconBenchmark::getDaynhgzssdl).sum();
+        monthMap.get(station).put(addStr + "故障损失电量", String.valueOf(gzsssum));
+        monthMap.get(station).put(addStr + "故障损失率", getCompletRate(station, addStr + "故障损失电量", addStr + "实际电量"));
+        double xdsssum = bml.stream().mapToDouble(ProEconBenchmark::getDaynhxdssdl).sum();
+        monthMap.get(station).put(addStr + "限电损失电量", NumberUtil.roundStr(xdsssum, 2));
+        double xdssl = bml.stream().mapToDouble(ProEconBenchmark::getPowerLossRate).average().orElse(0);
+        monthMap.get(station).put(addStr + "限电损失率", NumberUtil.roundStr(xdssl, 2));
+        double slsssum = bml.stream().mapToDouble(ProEconBenchmark::getDaynhcfdl).sum();
+        monthMap.get(station).put(addStr + "受累损失电量", String.valueOf(slsssum));
+        monthMap.get(station).put(addStr + "受累损失率", getCompletRate(station, addStr + "受累损失电量", addStr + "实际电量"));
+        double xnsssum = bml.stream().mapToDouble(ProEconBenchmark::getDaynhqfdl).sum();
+        monthMap.get(station).put(addStr + "性能损失电量", String.valueOf(xnsssum));
+        double xnssl = bml.stream().mapToDouble(ProEconBenchmark::getPerformanceLossRate).average().orElse(0);
+        monthMap.get(station).put(addStr + "性能损失率", NumberUtil.roundStr(xnssl, 2));
+        double jhjxsum = bml.stream().mapToDouble(ProEconBenchmark::getDaynhwhssdl).sum();
+        monthMap.get(station).put(addStr + "计划检修损失电量", String.valueOf(jhjxsum));
+        monthMap.get(station).put(addStr + "计划检修损失率", getCompletRate(station, addStr + "计划检修损失电量", addStr + "实际电量"));
+        double pjfssum = bml.stream().filter(bm -> bm.getSpeed() > 0).mapToDouble(ProEconBenchmark::getSpeed).average().orElse(0);
+        monthMap.get(station).put(addStr + "平均风速", NumberUtil.roundStr(pjfssum, 2));
+        monthMap.get(station).put(addStr + "损失电量", getSum(station, addStr + "故障损失电量", addStr + "限电损失电量", addStr + "受累损失电量", addStr + "性能损失电量", addStr + "计划检修损失电量"));
+        monthMap.get(station).put(addStr + "损失率", getCompletRate(station, addStr + "损失电量", addStr + "实际电量"));
+        double fwjsl = bml.stream().mapToDouble(ProEconBenchmark::getResetTimelyRate).average().orElse(0);
+        monthMap.get(station).put(addStr + "复位及时率", NumberUtil.roundStr(fwjsl, 2));
+        double ztzhl = bml.stream().mapToDouble(ProEconBenchmark::getStateTransitionRate).average().orElse(0);
+        monthMap.get(station).put(addStr + "状态转换率", NumberUtil.roundStr(ztzhl, 2));
+        double xqjsl = bml.stream().mapToDouble(ProEconBenchmark::getEliminationRate).average().orElse(0);
+        monthMap.get(station).put(addStr + "消缺及时率", NumberUtil.roundStr(xqjsl, 2));
+        double cydl = bml.stream().mapToDouble(ProEconBenchmark::getComprehensiveRate).average().orElse(0);
+        monthMap.get(station).put(addStr + "厂用电率", NumberUtil.roundStr(cydl, 2));
+        monthMap.get(station).put(addStr + "厂用电量", getProduct(station, addStr + "实际电量", addStr + "厂用电率"));
+        monthMap.get(station).put(addStr + "实际电量完成率", getCompletRate(station, addStr + "实际电量", addStr + "计划电量"));
+    }
+
+    private String getProduct(String station, String one, String two) {
+        String oone = monthMap.get(station).get(one);
+        String otwo = monthMap.get(station).get(two);
+        if (oone == null || otwo == null) return "NaN";
+        Double v = Double.parseDouble(oone) * Double.parseDouble(otwo)/100;
+        if(!(v.isInfinite()||v.isNaN()))
+            return NumberUtil.roundStr(v, 2);
+        return "NaN";
+    }
+
+    //和
+    private String getSum(String cz, String... ws) {
+        double o = 0;
+        for (String w : ws) {
+            o += Double.parseDouble(monthMap.get(cz).get(w));
+        }
+        return String.valueOf(o);
+    }
+
+    //初始化monthMap
+    public Map<String, Map<String, String>> getMonthMap() {
+        if (monthMap.isEmpty()) {
+            for (String s : getStationList()) {
+                monthMap.put(s, new LinkedHashMap<>());
+            }
+        }
+        return monthMap;
+    }
+
+    //定义场站
+    private List<String> getStationList() {
+        if (stationList == null) {
+            stationList = CacheContext.wpls.stream().map(ProBasicOrganizeTree::getId).collect(Collectors.toList());
+            stationList.add("0");
+            stationList.add("-1");
+            stationList.add("-2");
+        }
+        return stationList;
+    }
+
+    //场站,同比环比双方,算同比环比
+    private String getRatio(String cz, String one, String two) {
+        String oone = monthMap.get(cz).get(one);
+        String otwo = monthMap.get(cz).get(two);
+        if (oone == null || otwo == null) return "NaN";
+        Double twodou = Double.parseDouble(otwo);
+        Double v = (Double.parseDouble(oone) - twodou) / twodou * 100;
+        if(!(v.isInfinite()||v.isNaN()))
+            return NumberUtil.roundStr(v, 2);
+        return "NaN";
+    }
+
+    //算同比环比,不是百分比
+    private String getRatioNoBFB(String cz, String one, String two) {
+        String oone = monthMap.get(cz).get(one);
+        String otwo = monthMap.get(cz).get(two);
+        if (oone == null || otwo == null) return "NaN";
+        Double v = Double.valueOf(oone) - Double.valueOf(otwo);
+        if(!(v.isInfinite()||v.isNaN()))
+            return NumberUtil.roundStr(v, 2);
+        return "NaN";
+    }
+    private String douStr2Str3(String str, String one, String two) {
+        if (str!=null && str.startsWith("-")) {
+            return str.replaceFirst("-", two);
+        } else {
+            return one + str;
+        }
+    }
+    private String douStr2Str(String str) {
+        return douStr2Str3(str, "增加", "减少");
+    }
+    private String douStr2Str2(String str) {
+        return douStr2Str3(str, "上升", "下降");
+    }
+
+    //算比率
+    private String getCompletRate(String cz, String one, String two) {
+        String oone = monthMap.get(cz).get(one);
+        String otwo = monthMap.get(cz).get(two);
+        if (StrUtil.isEmpty(oone) || StrUtil.isEmpty(otwo)) return "NaN";
+        double v = Double.valueOf(oone) / Double.valueOf(otwo) * 100;
+        return String.format("%.2f", v);
+    }
+
+    //过滤期次
+    private boolean isnotqc(String cz) {
+        return cz.endsWith("DC") || cz.equals("0") || cz.equals("-1") || cz.equals("-2");
+    }
+
+    private Map<String, List<String>> getWord(String wpid, String year, String month) {
+        Map<String, List<String>> map = new LinkedHashMap<>();
+        List<String> title = new ArrayList<>();
+        String str;
+        title.add(StrUtil.format("{}年{}月经济运行分析报告", year, month));
+        map.put("标题", title);
+        title = new ArrayList<>();
+        str = "{}本月计划电量为{}万千瓦时,实际完成{}万千瓦时,同比{}%,环比{}%,计划完成率{}%。";
+        title.add(StrUtil.format(str, CacheContext.wpmap.get(wpid).getAname(),
+                monthMap.get(wpid).get("计划电量"), monthMap.get(wpid).get("实际电量"),
+                douStr2Str(monthMap.get(wpid).get("实际电量同比")), douStr2Str(monthMap.get(wpid).get("实际电量环比")), monthMap.get(wpid).get("实际电量完成率")));
+        map.put("发电量完成情况", title);
+        title = new ArrayList<>();
+        str = "{}月累计辐照总量{}MJ/㎡,同比{}%,环比{}%。光伏理论发电量{}万千瓦时,同比{}%,环比{}%。";
+        title.add(StrUtil.format(str, CacheContext.wpmap.get(wpid).getAname(),
+                monthMap.get(wpid).get("平均风速"), douStr2Str(monthMap.get(wpid).get("平均风速同比")), douStr2Str(monthMap.get(wpid).get("平均风速环比"))
+                , monthMap.get(wpid).get("理论发电量"), douStr2Str(monthMap.get(wpid).get("理论发电量同比")), douStr2Str(monthMap.get(wpid).get("理论发电量环比"))));
+        str = "{}发生极端天气{}次,持续时长{}小时,受累损失电量{}万千瓦时。主要事件为:{}";
+        title.add(StrUtil.format(str, CacheContext.wpmap.get(wpid).getAname(),"0","0",monthMap.get("0").get("受累损失电量"),""));
+        map.put("资源及理论发电量平衡分析", title);
+        title = new ArrayList<>();
+        str = "本月{}累计发生输变电故障2次,故障消缺时长累计18小时,损失电量9.78万千瓦时。";
+        title.add(StrUtil.format(str, CacheContext.wpmap.get(wpid).getAname()));
+        str = "本月{}平均故障消缺时间为4.8小时,同比下降10%,环比下降5%;故障消缺及时率86%,同比增加10%,环比减少5%。";
+        title.add(StrUtil.format(str, CacheContext.wpmap.get(wpid).getAname()));
+        map.put("故障及损失分析", title);
+        title = new ArrayList<>();
+
+        //性能损失率排序
+        List<String> xnsslpx = getTargetSort("GDC", "性能损失率");
+        List<String> xnsslhbpx = getTargetSort("GDC", "性能损失率环比");
+        if(xnsslpx.size()>0&&xnsslhbpx.size()>0){
+            str = "本月{}发电性能损失{}万千瓦时,同比{}万千瓦时,环比{}万千瓦时。损失率{}%,同比{}%,环比{}%;其中性能损失率最高的是{},性能损失率{}%,性能损失率最低的是{},性能损失率{}%;性能损失率改善的有:{};性能损失率劣化的有{}。";
+            title.add(StrUtil.format(str, CacheContext.wpmap.get(wpid).getAname(), monthMap.get(wpid).get("性能损失电量"), douStr2Str2(monthMap.get(wpid).get("性能损失电量同比"))
+                    , douStr2Str2(monthMap.get(wpid).get("性能损失电量环比")), monthMap.get(wpid).get("性能损失率")
+                    , douStr2Str2(monthMap.get(wpid).get("性能损失率同比")), douStr2Str2(monthMap.get(wpid).get("性能损失率环比"))
+                    , max(xnsslpx), monthMap.get(xnsslpx.get(xnsslpx.size() - 1)).get("性能损失率")
+                    , min(xnsslpx), monthMap.get(xnsslpx.get(0)).get("性能损失率")
+                    , max2(xnsslhbpx), min2(xnsslhbpx)));
+        }else {
+            str = "本月{}发电性能损失{}万千瓦时,同比{}万千瓦时,环比{}万千瓦时。损失率{}%,同比{}%,环比{}%。";
+            title.add(StrUtil.format(str, CacheContext.wpmap.get(wpid).getAname(), monthMap.get(wpid).get("性能损失电量"), douStr2Str2(monthMap.get(wpid).get("性能损失电量同比"))
+                    , douStr2Str2(monthMap.get(wpid).get("性能损失电量环比")), monthMap.get(wpid).get("性能损失率")
+                    , douStr2Str2(monthMap.get(wpid).get("性能损失率同比")), douStr2Str2(monthMap.get(wpid).get("性能损失率环比"))));
+        }
+
+        map.put("性能损失分析", title);
+        title = new ArrayList<>();
+        str = "本月{}场用电量累计{}万千瓦时,同比{}千瓦时,环比{}千瓦时;综合场用电率{}%,同比{}%,环比{}%。";
+        title.add(StrUtil.format(str, CacheContext.wpmap.get(wpid).getAname(), monthMap.get(wpid).get("场用电量"), douStr2Str(monthMap.get(wpid).get("场用电量同比"))
+                , douStr2Str(monthMap.get(wpid).get("场用电量环比")), monthMap.get(wpid).get("场用电率"),
+                douStr2Str2(monthMap.get(wpid).get("场用电率同比")), douStr2Str2(monthMap.get(wpid).get("场用电率环比"))));
+        map.put("厂用电量分析", title);
+        title = new ArrayList<>();
+        //风能利用率排序
+        List<String> xnssdlpx = getTargetSort("GDC", "性能损失电量");
+        str = "{}:性能损失电量高,存在性能缺陷的风机多,需要整改。";
+        title.add(StrUtil.format(str,max(xnssdlpx)));
+        map.put("场站问题总结和建议", title);
+        return map;
+    }
+
+    private String min(List<String> list) {
+        return CacheContext.wpmap.get(list.get(0)).getAname();
+    }
+
+    private String max(List<String> list) {
+        if(list.size()==0) return "";
+        return CacheContext.wpmap.get(list.get(list.size() - 1)).getAname();
+    }
+
+    private String min2(List<String> list) {
+        return CacheContext.wpmap.get(list.get(1)).getAname() + "," + CacheContext.wpmap.get(list.get(0)).getAname();
+    }
+
+    private String max2(List<String> list) {
+        return CacheContext.wpmap.get(list.get(list.size() - 1)).getAname() + "," + CacheContext.wpmap.get(list.get(list.size() - 2)).getAname();
+    }
+
+    /**
+     * 按指标从小到大排序
+     *
+     * @param dc     风电场or光电场
+     * @param target 指标
+     * @return 按指标从小到大排序场站
+     */
+    private List<String> getTargetSort(String dc, String target) {
+        List<String> lists = new ArrayList<>();
+        getStationTarget(dc, target).entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(o -> lists.add(o.getKey()));
+        return lists;
+    }
+
+    /**
+     * 场站,指标值
+     */
+    public Map<String, Double> getStationTarget(String dc, String target) {
+        Map<String, Double> map = new HashMap<>();
+        monthMap.forEach((cz, zb) -> {
+            if (cz.endsWith(dc))
+                map.put(cz, Double.valueOf(zb.get(target)));
+        });
+        return map;
+    }
+}

+ 5 - 0
web/runeconomy-jjyx/src/main/java/com/gyee/runeconomy/util/MathUtil.java

@@ -1,6 +1,7 @@
 package com.gyee.runeconomy.util;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.Date;
 
 public class MathUtil {
@@ -121,4 +122,8 @@ public class MathUtil {
         return Double.parseDouble(str);
     }
 
+    public static String plain(BigDecimal bigDecimal, int i) {
+
+        return bigDecimal.setScale(i, RoundingMode.HALF_UP).toPlainString();
+    }
 }