Bladeren bron

发电能力分析新增晋能模块

chenminghua 1 jaar geleden
bovenliggende
commit
5ea6746943
100 gewijzigde bestanden met toevoegingen van 8430 en 0 verwijderingen
  1. 1 0
      pom.xml
  2. 147 0
      power-fitting-JN/pom.xml
  3. 206 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/MapperGenerator.java
  4. 46 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/PowerBootApplication.java
  5. 308 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/CurrentVoltageCalc.java
  6. 9 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/CurveFitting.java
  7. 39 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/DBSCANPointALG.java
  8. 446 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/MpptFittingAlg.java
  9. 201 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/PolynomialCurveFitting.java
  10. 327 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/PowerFittingALG.java
  11. 352 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/PowerProcessALG.java
  12. 72 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/PowerTemperatureAlg.java
  13. 22 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/TimeCostCalculator.java
  14. 284 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/WindDirectionALG.java
  15. 102 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/base/ExcludeQueryWrapper.java
  16. 22 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/CorsConfig.java
  17. 22 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/DataSourceConfig.java
  18. 93 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/GyeeConfig.java
  19. 50 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/ThreadPoolConfig.java
  20. 20 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/WebSocketConfig.java
  21. 29 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/constants/Constants.java
  22. 58 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/exception/AdviceException.java
  23. 23 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/exception/CustomException.java
  24. 32 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/FeignsBuilder.java
  25. 38 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/IAdapterService.java
  26. 26 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/IDataAdapter.java
  27. 31 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/RemoteServiceBuilder.java
  28. 67 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/result/JsonResult.java
  29. 89 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/result/ResultCode.java
  30. 19 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/spring/ExitDisposable.java
  31. 235 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/spring/InitialRunner.java
  32. 110 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/spring/SpringContextUtil.java
  33. 124 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/Base64Util.java
  34. 37 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/CollectUtil.java
  35. 625 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/DateUtil.java
  36. 359 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/DateUtils.java
  37. 256 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/FileUtil.java
  38. 26 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/JudeSystem.java
  39. 109 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/NumberUtil.java
  40. 62 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/PowerFittingUtil.java
  41. 162 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/SnowFlakeUtil.java
  42. 45 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/TokenGenerator.java
  43. 60 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/agc/AgcDeviateController.java
  44. 23 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/base/CurveFittingController.java
  45. 70 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/base/WindInfoController.java
  46. 140 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/DataFittingController.java
  47. 83 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/DataPrepareController.java
  48. 106 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/DataProcessController.java
  49. 61 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/DateOptionController.java
  50. 69 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/FiveLossInfoController.java
  51. 58 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/PowerTemperatureController.java
  52. 35 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/RatedPowerController.java
  53. 78 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/WindDirectionController.java
  54. 164 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/gf/PhotovoltaicController.java
  55. 12 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/AgcDeviateMapper.java
  56. 18 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/EquipmentmodelMapper.java
  57. 17 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/LineMapper.java
  58. 18 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/ModelpowerdetailsMapper.java
  59. 16 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PhotovoltaiccapacityMapper.java
  60. 18 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PhotovoltaicivMapper.java
  61. 18 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PowerfittinganalysisMapper.java
  62. 16 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PowerlossinfoMapper.java
  63. 16 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PowermodelMapper.java
  64. 16 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PowerwindinfoMapper.java
  65. 16 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/ProjectMapper.java
  66. 19 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/WindpowerstationMapper.java
  67. 18 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/Windpowerstationtestingpoint2Mapper.java
  68. 19 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/WindturbineMapper.java
  69. 18 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/Windturbinetestingpointai2Mapper.java
  70. 92 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/AgcDeviateModel.java
  71. 72 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Equipmentmodel.java
  72. 60 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Line.java
  73. 47 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Modelpowerdetails.java
  74. 78 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Photovoltaiccapacity.java
  75. 77 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Photovoltaiciv.java
  76. 93 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Powerfittinganalysis.java
  77. 77 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Powerlossinfo.java
  78. 47 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Powermodel.java
  79. 57 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Powerwindinfo.java
  80. 76 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Project.java
  81. 97 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Windpowerstation.java
  82. 199 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Windpowerstationtestingpoint2.java
  83. 73 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Windturbine.java
  84. 86 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Windturbinetestingpointai2.java
  85. 48 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/AgcDeviateConfig.java
  86. 33 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/AgcDeviateTag.java
  87. 56 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/AiPoints.java
  88. 35 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/PointData.java
  89. 76 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/anno/AnnotationTool.java
  90. 22 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/anno/Desc.java
  91. 28 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/anno/FixedVo.java
  92. 64 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/FjjxbVo.java
  93. 35 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/LineCurveFitting.java
  94. 63 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PhotovoltaicInfo.java
  95. 16 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/Point.java
  96. 19 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PointVo.java
  97. 36 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PowerFittingData.java
  98. 106 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PowerPointData.java
  99. 29 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PowerTemperatureData.java
  100. 0 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/TableTitle.java

+ 1 - 0
pom.xml

@@ -24,6 +24,7 @@
         <module>consumer</module>
         <module>gyee-sample-impala</module>
         <module>power-fitting</module>
+        <module>power-fitting-JN</module>
     </modules>
 
 

+ 147 - 0
power-fitting-JN/pom.xml

@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>sis-background</artifactId>
+        <groupId>com.gyee</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>power-fitting-JN</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.2.11</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>3.1.1</version>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+            <version>2.7.4</version>
+        </dependency>
+
+
+        <!--        <dependency>-->
+        <!--            <groupId>com.oracle</groupId>-->
+        <!--            <artifactId>ojdbc6</artifactId>-->
+        <!--            <version>11.2.0.3</version>-->
+        <!--        </dependency>-->
+
+        <!--oracle驱动-->
+        <!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
+        <dependency>
+            <groupId>com.oracle.database.jdbc</groupId>
+            <artifactId>ojdbc8</artifactId>
+            <version>19.7.0.0</version>
+        </dependency>
+
+        <!-- oracle字符集  https://mvnrepository.com/artifact/cn.easyproject/orai18n -->
+        <dependency>
+            <groupId>cn.easyproject</groupId>
+            <artifactId>orai18n</artifactId>
+            <version>12.1.0.2.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.xerial</groupId>
+            <artifactId>sqlite-jdbc</artifactId>
+            <version>3.36.0.3</version>
+        </dependency>
+
+        <!--mybatis依赖-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>3.3.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.17</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-math3</artifactId>
+            <version>3.6.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity-engine-core</artifactId>
+            <version>2.2</version>
+        </dependency>
+
+        <!--http请求-->
+        <dependency>
+            <groupId>com.netflix.feign</groupId>
+            <artifactId>feign-core</artifactId>
+            <version>8.18.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.netflix.feign</groupId>
+            <artifactId>feign-jackson</artifactId>
+            <version>8.18.0</version>
+        </dependency>
+        <!--http请求-->
+
+        <!--常用工具类 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 206 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/MapperGenerator.java

@@ -0,0 +1,206 @@
+package com.gyee.power.fitting;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 代码生成器
+ */
+public class MapperGenerator {
+    //项目路径
+    private static String canonicalPath = "";
+
+    //基本包名
+    private static String basePackage = "com.gyee.power.fitting";
+    //作者
+    private static String authorName = "chenmh";
+    //要生成的表名
+    private static String[] tables = {"POWERWINDINFO"};
+    //table前缀
+    private static String prefix = "";
+
+    //数据库类型
+    private static DbType dbType = DbType.ORACLE;
+    //数据库配置四要素
+//    private static String driverName = "com.mysql.cj.jdbc.Driver";
+//    private static String url = "jdbc:mysql://localhost:3306/gyee_sample_kudu?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC";
+//    private static String username = "root";
+//    private static String password = "";
+
+//    private static String driverName = "org.sqlite.JDBC";
+//    private static String url = "jdbc:sqlite::resource:DataMiningTools.db";
+//    private static String username = null;
+//    private static String password = null;
+
+    private static String driverName = "oracle.jdbc.driver.OracleDriver";
+    private static String url = "jdbc:oracle:thin:@192.168.1.105:1521:gdnxfd";
+    private static String username = "nxfdprod";
+    private static String password = "gdnxfd123";
+
+
+    public static void main(String[] args) {
+        AutoGenerator gen = new AutoGenerator();
+
+        /**
+         * 获取项目路径
+         */
+        try {
+            canonicalPath = new File("").getCanonicalPath();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        /**
+         * 数据库配置
+         */
+        gen.setDataSource(new DataSourceConfig()
+                .setDbType(dbType)
+                .setDriverName(driverName)
+                .setUrl(url)
+                .setUsername(username)
+                .setPassword(password)
+                .setTypeConvert(new MySqlTypeConvert() {
+                    // 自定义数据库表字段类型转换【可选】
+                    //@Override
+                    //public DbColumnType processTypeConvert(String fieldType) {
+                    //System.out.println("转换类型:" + fieldType);
+                    // if ( fieldType.toLowerCase().contains( "tinyint" ) ) {
+                    //    return DbColumnType.BOOLEAN;
+                    // }
+                    //return super.processTypeConvert(fieldType);
+                    //}
+                }));
+
+        /**
+         * 全局配置
+         */
+        gen.setGlobalConfig(new GlobalConfig()
+                .setOutputDir( canonicalPath + "/src/main/java")//输出目录
+                .setFileOverride(true)// 是否覆盖文件
+                .setActiveRecord(true)// 开启 activeRecord 模式
+                .setEnableCache(false)// XML 二级缓存
+                .setBaseResultMap(true)// XML ResultMap
+                .setBaseColumnList(true)// XML columList
+                .setOpen(false)//生成后打开文件夹
+                .setAuthor(authorName)
+                // 自定义文件命名,注意 %s 会自动填充表实体属性!
+                .setMapperName("%sMapper")
+                .setXmlName("%sMapper")
+                .setServiceName("%sService")
+                .setServiceImplName("%sServiceImpl")
+                .setControllerName("%sController")
+        );
+
+        /**
+         * 策略配置
+         */
+        gen.setStrategy(new StrategyConfig()
+                        // .setCapitalMode(true)// 全局大写命名
+                        //.setDbColumnUnderline(true)//全局下划线命名
+                        .setTablePrefix(new String[]{prefix})// 此处可以修改为您的表前缀
+                        .setNaming(NamingStrategy.underline_to_camel)// 表名生成策略
+                        .setInclude(tables) // 需要生成的表
+                        .setRestControllerStyle(true)
+                        //.setExclude(new String[]{"test"}) // 排除生成的表
+                        // 自定义实体父类
+                        // .setSuperEntityClass("com.baomidou.demo.TestEntity")
+                        // 自定义实体,公共字段
+                        //.setSuperEntityColumns(new String[]{"test_id"})
+                        //.setTableFillList(tableFillList)
+                        // 自定义 mapper 父类 默认BaseMapper
+                        //.setSuperMapperClass("com.baomidou.mybatisplus.mapper.BaseMapper")
+                        // 自定义 service 父类 默认IService
+                        // .setSuperServiceClass("com.baomidou.demo.TestService")
+                        // 自定义 service 实现类父类 默认ServiceImpl
+                        // .setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl")
+                        // 自定义 controller 父类
+                        //.setSuperControllerClass("com.kichun."+packageName+".controller.AbstractController")
+                        // 【实体】是否生成字段常量(默认 false)
+                        // public static final String ID = "test_id";
+                        // .setEntityColumnConstant(true)
+                        // 【实体】是否为构建者模型(默认 false)
+                        // public User setName(String name) {this.name = name; return this;}
+                        // .setEntityBuilderModel(true)
+                        // 【实体】是否为lombok模型(默认 false)<a href="https://projectlombok.org/">document</a>
+                        .setEntityLombokModel(true)
+                // Boolean类型字段是否移除is前缀处理
+                // .setEntityBooleanColumnRemoveIsPrefix(true)
+                // .setRestControllerStyle(true)
+                // .setControllerMappingHyphenStyle(true)
+        );
+
+        /**
+         * 包配置
+         */
+        gen.setPackageInfo(new PackageConfig()
+                //.setModuleName("User")
+                .setParent(basePackage)// 自定义包路径
+                .setController("controller")// 这里是控制器包名,默认 web
+                .setEntity("model") // 设置Entity包名,默认entity
+                .setMapper("mapper") // 设置Mapper包名,默认mapper
+                .setService("service") // 设置Service包名,默认service
+                .setServiceImpl("service.impl") // 设置Service Impl包名,默认service.impl
+                .setXml("mapper") // 设置Mapper XML包名,默认mapper.xml
+        );
+
+        /**
+         * 注入自定义配置
+         */
+        // 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值
+        InjectionConfig abc = new InjectionConfig() {
+            @Override
+            public void initMap() {
+                Map<String, Object> map = new HashMap<String, Object>();
+                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
+                this.setMap(map);
+            }
+        };
+        //自定义文件输出位置(非必须)
+        List<FileOutConfig> fileOutList = new ArrayList<FileOutConfig>();
+        fileOutList.add(new FileOutConfig("/templates/mapper.xml.vm") {
+            @Override
+            public String outputFile(TableInfo tableInfo) {
+                return canonicalPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper.xml";
+            }
+        });
+        abc.setFileOutConfigList(fileOutList);
+        gen.setCfg(abc);
+
+        /**
+         * 指定模板引擎 默认是VelocityTemplateEngine ,需要引入相关引擎依赖
+         */
+        //gen.setTemplateEngine(new FreemarkerTemplateEngine());
+
+        /**
+         * 模板配置
+         */
+        gen.setTemplate(
+                // 关闭默认 xml 生成,调整生成 至 根目录
+                new TemplateConfig().setXml(null)
+                // 自定义模板配置,模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
+                // 至您项目 src/main/resources/template 目录下,模板名称也可自定义如下配置:
+                // .setController("...");
+                // .setEntity("...");
+                // .setMapper("...");
+                // .setXml("...");
+                // .setService("...");
+                // .setServiceImpl("...");
+        );
+
+        // 执行生成
+        gen.execute();
+
+    }
+}

+ 46 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/PowerBootApplication.java

@@ -0,0 +1,46 @@
+package com.gyee.power.fitting;
+
+import com.gyee.power.fitting.common.config.GyeeConfig;
+import com.gyee.power.fitting.common.spring.SpringContextUtil;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import java.io.File;
+
+
+/**
+ * 使用exclude = {DataSourceAutoConfiguration.class}
+ * 禁用springboot默认加载的application.properties单数据源配置
+ * 关闭springBoot关于mybatisPlus的一些自动注入
+ */
+@EnableAsync(proxyTargetClass = true)
+@EnableCaching
+@EnableScheduling
+@SpringBootApplication
+@MapperScan("com.gyee.power.fitting.mapper")
+public class PowerBootApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(PowerBootApplication.class, args);
+
+        createFile();
+    }
+
+    /**
+     * 创建数据准备、数据预处理、数据拟合.......目录
+     */
+    private static void createFile(){
+        GyeeConfig bean = SpringContextUtil.getBean(GyeeConfig.class);
+        String[] fileName = {bean.getFilePathPrepare(), bean.getFilePathProcess(), bean.getFilePathFitting(), bean.getFilePathDownload()};
+        for (String path : fileName){
+            File file = new File(path);
+            if (!file.exists())
+                file.mkdirs();
+        }
+    }
+
+}

+ 308 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/CurrentVoltageCalc.java

@@ -0,0 +1,308 @@
+package com.gyee.power.fitting.common.alg;
+
+import com.gyee.power.fitting.model.custom.PhotovoltaicInfo;
+import com.gyee.power.fitting.model.custom.TsDoubleData;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class CurrentVoltageCalc {
+
+    private static final double a = 0.0025;
+    private static final double b = 0.5;
+    private static final double c = 0.00288;
+    //标准点
+    private static Map<String, PhotovoltaicInfo> aFixe = new HashMap<>();
+    private static Map<String, PhotovoltaicInfo> bFixe = new HashMap<>();
+    private static Map<String, PhotovoltaicInfo> cFixe = new HashMap<>();
+    //电压系数
+    private final double dyxs = 1.22;
+    //电流系数
+    private final double dlxs = 1.07;
+
+    /**
+     * 计算任意温度下的I、V
+     *
+     * @param Tp 待计算IV的温度
+     * @param Sp 待计算IV的光照
+     * @param T  已测量温度
+     * @param S  已测量光照
+     * @param Im 已测量I
+     * @param Vm 已测量V
+     * @return 待计算I、V
+     */
+    public static PhotovoltaicInfo Calculate(double Tp, double Sp, double T, double S, double Im, double Vm) {
+
+        PhotovoltaicInfo pi = new PhotovoltaicInfo();
+
+        if (Sp < 1 || S < 1) {
+            pi.setT(Tp);
+            pi.setS(Sp);
+            pi.setI(0);
+            pi.setV(0);
+        } else {
+            double DTp = Tp - 25;
+            double DSp = Sp / 1000 - 1;
+            double DT = T - 25;
+            double DS = S / 1000 - 1;
+
+            double Imp = (Im * Sp * (1 + a * DTp)) / (S * (1 + a * DT));
+            double Vmp = (Vm * (1 - c * DTp) * Math.log(Math.E + b * DSp)) / ((1 - c * DT) * Math.log(Math.E + b * DS));
+
+            pi.setT(Tp);
+            pi.setS(Sp);
+            pi.setI(Imp);
+            pi.setV(Vmp);
+        }
+
+        return pi;
+    }
+
+    public static double influencingFactor(double T, double S) {
+
+        if (S < 1) {
+            return 0;
+        } else {
+            double DT = T - 25;
+            double DS = S / 1000 - 1;
+
+            double factor = (S * (1 + a * DT)) * ((1 - c * DT) * Math.log(Math.E + b * DS));
+            return factor;
+        }
+
+    }
+
+    /**
+     * 把每个测点值当成现场测量值,选优
+     *
+     * @param fc 光电场
+     * @param fj 逆变器
+     * @param zl 支路
+     * @return 最优测量点 List<Double> time, T, S, Im, Vm
+     */
+    public static PhotovoltaicInfo ChoosePoint(String fc, String fj, String zl, List<TsDoubleData> T, List<TsDoubleData> S, List<TsDoubleData> Im, List<TsDoubleData> Vm) throws Exception {
+
+        PhotovoltaicInfo standardPI = new PhotovoltaicInfo();
+
+        List<PhotovoltaicInfo> calc = new ArrayList<>();
+
+        for (int m = 0; m < T.size(); m++) {
+            double Tm = T.get(m).getDoubleValue();
+            double Sm = S.get(m).getDoubleValue();
+            double Imm = Im.get(m).getDoubleValue();
+            double Vmm = Vm.get(m).getDoubleValue();
+            long ts = T.get(m).getTs();
+            if (Sm < 5 || Imm < 3 || Vmm < 3) continue;
+            //System.out.println(T.get(m).getTs());
+            PhotovoltaicInfo c = CurrentVoltageCalc.Calculate(20, 400, Tm, Sm, Imm, Vmm);
+            c.setTime(ts);
+            calc.add(c);
+            /*String s = DateUtils.date2StringL(new Date(T.get(m).getTs()));
+            System.out.print(s+","+Tm+","+Sm+","+Imm+","+Vmm+","+c.getI()+","+c.getV());
+            System.out.println();
+            if(standardPI==null){
+                standardPI = new PhotovoltaicInfo();
+                standardPI.setStation(fc);
+                standardPI.setInverter(fj);
+                standardPI.setBranch(zl);
+                standardPI.setT(Tm);
+                standardPI.setS(Sm);
+                standardPI.setI(Imm);
+                standardPI.setV(Vmm);
+            } else if (c.getI() > standardPI.getI() && c.getV() > standardPI.getV() &&
+                    c.getI() < standardPI.getI() * 1.5 && c.getV() < standardPI.getV() * 1.5 &&
+                    c.getI() * c.getV() < 2 * standardPI.getI() * standardPI.getV()) {
+                standardPI.setT(Tm);
+                standardPI.setS(Sm);
+                standardPI.setI(Imm);
+                standardPI.setV(Vmm);
+            }*/
+        }
+        calc = calc.stream().sorted(Comparator.comparing(PhotovoltaicInfo::getP)).collect(Collectors.toList());
+        long time = calc.get(calc.size() / 2).getTime();
+
+        standardPI.setStation(fc);
+        standardPI.setInverter(fj);
+        standardPI.setBranch(zl);
+        standardPI.setTime(time);
+        double TValue = T.stream().filter(t -> t.getTs() == time).findFirst().get().getDoubleValue();
+        double SValue = S.stream().filter(t -> t.getTs() == time).findFirst().get().getDoubleValue();
+        double ImValue = Im.stream().filter(t -> t.getTs() == time).findFirst().get().getDoubleValue();
+        double VmValue = Vm.stream().filter(t -> t.getTs() == time).findFirst().get().getDoubleValue();
+        standardPI.setT(TValue);
+        standardPI.setS(SValue);
+        standardPI.setI(ImValue);
+        standardPI.setV(VmValue);
+
+        return standardPI;
+    }
+
+    public static List<PhotovoltaicInfo> Calculate(List<TsDoubleData> Tp, List<TsDoubleData> Sp, double T, double S, double Im, double Vm) {
+
+        List<PhotovoltaicInfo> pis = new ArrayList<>();
+        for (int i = 0; i < Tp.size(); i++) {
+            PhotovoltaicInfo c = CurrentVoltageCalc.Calculate(Tp.get(i).getDoubleValue(), Sp.get(i).getDoubleValue(), T, S, Im, Vm);
+            c.setTime(Tp.get(i).getTs());
+            pis.add(c);
+        }
+        return pis;
+    }
+
+    public static PhotovoltaicInfo info2Photovoltaic(String station, String inverter, String branch, List<TsDoubleData> zjwdDatas, List<TsDoubleData> zfsDatas, List<TsDoubleData> dlDatas, List<TsDoubleData> dyDatas) {
+        PhotovoltaicInfo pi = new PhotovoltaicInfo();
+        int j = 0;
+        double k = 0;
+        for (int i = 0; i < zjwdDatas.size(); i++) {
+            double v = dlDatas.get(i).getDoubleValue() * dyDatas.get(i).getDoubleValue();
+            if (v > k) {
+                k = v;
+                j = i;
+            }
+        }
+        pi.setStation(station);
+        pi.setInverter(inverter);
+        pi.setBranch(branch);
+        pi.setTime(zjwdDatas.get(j).getTs());
+        pi.setT(zjwdDatas.get(j).getDoubleValue());
+        pi.setS(zfsDatas.get(j).getDoubleValue());
+        pi.setI(dlDatas.get(j).getDoubleValue());
+        pi.setV(dyDatas.get(j).getDoubleValue());
+        return pi;
+    }
+
+    public static List<PhotovoltaicInfo> CalcTheoryPower(List<PhotovoltaicInfo> infos, Map<String, PhotovoltaicInfo> bzcldMap) {
+        //计算理论功率
+        for (PhotovoltaicInfo info : infos) {
+            double theoryPower1 = CurrentVoltageCalc.Calculate(info, bzcldMap.get(info.getInverter()));
+            info.setIdeaP(theoryPower1);
+        }
+        return infos;
+    }
+
+    public static List<PhotovoltaicInfo> CalcTheoryPowerHZJ(List<PhotovoltaicInfo> infos, Map<String, PhotovoltaicInfo> bzcldMap) {
+        //获取标准测量点
+        /*double pMax1 = 0,pMax2 = 0,pMax3 = 0;
+        int j1 = 0, j2 = 0, j3 = 0;
+        for (int i = 0; i <infos.size(); i++) {
+            PhotovoltaicInfo info = infos.get(i);
+            double p1 = info.getAI() * info.getAV();
+            double p2 = info.getBI() * info.getBV();
+            double p3 = info.getCI() * info.getCV();
+            if(p1>pMax1) {
+                pMax1 = p1;
+                j1 = i;
+            }
+            if(p2>pMax2) {
+                pMax2 = p2;
+                j2 = i;
+            }
+            if(p3>pMax3) {
+                pMax3 = p3;
+                j3 = i;
+            }
+        }
+        String inverter = infos.get(0).getInverter();
+        PhotovoltaicInfo aInfo = infos.get(j1);
+        PhotovoltaicInfo bInfo = infos.get(j2);
+        PhotovoltaicInfo cInfo = infos.get(j3);
+        aInfo.setI(aInfo.getAI());
+        aInfo.setV(aInfo.getAV());
+        bInfo.setI(bInfo.getBI());
+        bInfo.setV(bInfo.getBV());
+        cInfo.setI(cInfo.getCI());
+        cInfo.setV(cInfo.getCV());
+        if(!aFixe.containsKey(inverter)){
+            aFixe.put(inverter, aInfo);
+        }else if(aFixe.get(inverter).getAI()*aFixe.get(inverter).getAV()< aInfo.getAI()* aInfo.getAV()){
+            aFixe.put(inverter, aInfo);
+        }
+        if(!bFixe.containsKey(inverter)){
+            bFixe.put(inverter, bInfo);
+        }else if(bFixe.get(inverter).getBI()*bFixe.get(inverter).getBV()< bInfo.getBI()* bInfo.getBV()){
+            bFixe.put(inverter, bInfo);
+        }
+        if(!cFixe.containsKey(inverter)){
+            cFixe.put(inverter, cInfo);
+        }else if(cFixe.get(inverter).getCI()*cFixe.get(inverter).getCV()< cInfo.getCI()* cInfo.getCV()){
+            cFixe.put(inverter, cInfo);
+        }*/
+        //计算理论功率
+        for (PhotovoltaicInfo info : infos) {
+            PhotovoltaicInfo bzcld = bzcldMap.get(info.getInverter());
+            bzcld.setI(bzcld.getAI());
+            bzcld.setV(bzcld.getAV());
+            double theoryPower1 = CurrentVoltageCalc.Calculate(info, bzcld);
+            bzcld.setI(bzcld.getBI());
+            bzcld.setV(bzcld.getBV());
+            double theoryPower2 = CurrentVoltageCalc.Calculate(info, bzcld);
+            bzcld.setI(bzcld.getCI());
+            bzcld.setV(bzcld.getCV());
+            double theoryPower3 = CurrentVoltageCalc.Calculate(info, bzcld);
+            info.setIdeaP(theoryPower1 + theoryPower2 + theoryPower3);
+        }
+        return infos;
+    }
+
+    /**
+     * 计算理论功率
+     *
+     * @param info    需要计算的光照Sp、温度Tp
+     * @param infoMax 标准点
+     * @return
+     */
+    public static double Calculate(PhotovoltaicInfo info, PhotovoltaicInfo infoMax) {
+
+        double p = 0;
+        double Sp = info.getS();
+        double S = infoMax.getS();
+        double Tp = info.getT();
+        double T = infoMax.getT();
+        double Im = infoMax.getI();
+        double Vm = infoMax.getV();
+
+        if (Sp < 1 || S < 1) {
+            return 0;
+        } else {
+            double DTp = Tp - 25;
+            double DSp = Sp / 1000 - 1;
+            double DT = T - 25;
+            double DS = S / 1000 - 1;
+
+            double Imp = (Im * Sp * (1 + a * DTp)) / (S * (1 + a * DT));
+            double Vmp = (Vm * (1 - c * DTp) * Math.log(Math.E + b * DSp)) / ((1 - c * DT) * Math.log(Math.E + b * DS));
+
+            p = Imp * Vmp;
+        }
+        return p;
+    }
+
+    //计算理论功率
+    public static double[] Calculate(double s, double t, PhotovoltaicInfo infoMax) {
+
+        double p = 0;
+        double Sp = s;
+        double S = infoMax.getS();
+        double Tp = t;
+        double T = infoMax.getT();
+        double Im = infoMax.getI();
+        double Vm = infoMax.getV();
+
+        double[] db = new double[2];
+
+        if (Sp < 1 || S < 1) {
+            return db;
+        } else {
+            double DTp = Tp - 25;
+            double DSp = Sp / 1000 - 1;
+            double DT = T - 25;
+            double DS = S / 1000 - 1;
+
+            double Imp = (Im * Sp * (1 + a * DTp)) / (S * (1 + a * DT));
+            double Vmp = (Vm * (1 - c * DTp) * Math.log(Math.E + b * DSp)) / ((1 - c * DT) * Math.log(Math.E + b * DS));
+
+            db[0] = Imp;
+            db[1] = Vmp;
+        }
+        return db;
+    }
+}

+ 9 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/CurveFitting.java

@@ -0,0 +1,9 @@
+package com.gyee.power.fitting.common.alg;
+
+import java.util.List;
+
+public interface CurveFitting {
+    //Object run(List<Object> params);
+    List<Object> getParams(); 
+    void printResult(Object result,double accuracy);
+}

+ 39 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/DBSCANPointALG.java

@@ -0,0 +1,39 @@
+package com.gyee.power.fitting.common.alg;
+
+import com.gyee.power.fitting.model.custom.PowerPointData;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 散点聚合
+ */
+public class DBSCANPointALG {
+
+    /**
+     * 功率曲线拟合 散点聚合
+     * @param points  散点list
+     * @param param   聚合参数  10
+     * @return
+     */
+    public static  Map<String, List<PowerPointData>> dbscan(List<PowerPointData> points, double param){
+        Map<String, List<PowerPointData>> map = new HashMap<>();
+
+        for (PowerPointData item : points){
+            double x = item.getSpeed() * param;
+            double y = item.getPower() / param;
+
+            String key = Math.round(x) +  String.valueOf(Math.round(y));
+
+            if (!map.containsKey(key)){
+                map.put(key, new ArrayList<>());
+            }
+            map.get(key).add(item);
+        }
+
+        return map;
+    }
+
+}

+ 446 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/MpptFittingAlg.java

@@ -0,0 +1,446 @@
+package com.gyee.power.fitting.common.alg;
+
+import java.util.List;
+
+import com.gyee.power.fitting.model.custom.PointVo;
+
+import java.util.ArrayList;
+
+import org.apache.commons.math3.fitting.PolynomialCurveFitter;
+import org.apache.commons.math3.fitting.WeightedObservedPoints;
+
+
+/**
+ * I-V曲线拟合算法
+ * 最小二乘法
+ */
+public class MpptFittingAlg {
+
+
+    public static List<PointVo> BuildLine_IV_LSC(double[] arrX, double[] arrY, int length, int dimension, double scale){
+
+        List<PointVo> points = new ArrayList<>();
+
+        if(arrX.length != arrY.length || arrX.length < 3){
+            return points;
+        }
+
+        double minValue = arrY[arrY.length - 1];
+        double maxValue = arrY[0];
+
+        double min = 0;
+        double max = 0;
+
+        double[] coefficient = MultiLine(arrX, arrY, length, dimension);
+
+        for (double i = arrX[arrX.length - 1]; i > arrX[0]; i -= scale) {
+            PointVo point = new PointVo();
+            point.setX(i);
+
+            for (int j = 0; j < coefficient.length; j++) {
+                if (j == 0) {
+                    point.setY(coefficient[j] * Math.pow(point.getX(), j));
+                } else {
+                    double temp = coefficient[j] *Math.pow(point.getX(), j);
+                    point.setY(point.getY() + temp);
+                }
+            }
+
+            if (point.getY() < minValue) {
+                point.setY(minValue);
+
+
+            }
+            if (point.getY() > maxValue) {
+                point.setY(maxValue);
+
+            }
+
+            if (point.getY() < min) {
+                min = point.getY();
+            }
+            if (point.getY() > max) {
+                max = point.getY();
+            }
+
+            points.add(point);
+        }
+        Builder(points, min, max);
+        System.out.print("X轴数据\n");
+        int len = points.size();
+        double[] aX = new double[len];
+        for (int i = len-1; i >0; i --){
+            aX[i] = points.get(i).getX();
+            System.out.print(aX[i]+",");
+            System.out.print("\n");
+        }
+        System.out.print("\n");
+        System.out.print("Y轴数据\n");
+
+        double[] aY = new double[len];
+        for(int i = len-1;i >0; i--){
+            aY[i] = points.get(i).getY();
+            System.out.print(aY[i]+",");
+            System.out.print("\n");
+        }
+
+        return points;
+    }
+    /**
+     * P-V曲线拟合算法
+     * 最小二乘法
+     */
+    public static List<PointVo> BuildLine_PV_LSC(double[] arrX, double[] arrY, int length, int dimension, double scale){
+
+        List<PointVo> points = new ArrayList<>();
+
+        if(arrX.length != arrY.length || arrX.length < 3){
+            return points;
+        }
+
+        double minValue = arrY[0];
+        double maxValue = 0;
+        for(int i = 0 ;i < arrY.length; i++){
+            double val = arrY[i];
+            if(val > maxValue){
+                maxValue = val;
+            }
+        }
+
+        double min = 0;
+        double max = 0;
+
+        double[] coefficient = MultiLine(arrX, arrY, length, dimension);
+
+        for (double i = arrX[arrX.length - 1]; i > arrX[0]; i -= scale) {
+            PointVo point = new PointVo();
+            point.setX(i);
+
+            for (int j = 0; j < coefficient.length; j++) {
+                if (j == 0) {
+                    point.setY(coefficient[j] * Math.pow(point.getX(), j));
+                } else {
+                    double temp = coefficient[j] *Math.pow(point.getX(), j);
+                    point.setY(point.getY() + temp);
+                }
+            }
+
+            if (point.getY() < minValue) {
+                point.setY(minValue);
+
+
+            }
+            if (point.getY() > maxValue) {
+                point.setY(maxValue);
+
+            }
+
+            if (point.getY() < min) {
+                min = point.getY();
+            }
+            if (point.getY() > max) {
+                max = point.getY();
+            }
+
+            points.add(point);
+        }
+        Builder(points, min, max);
+        System.out.print("X轴数据\n");
+        int len = points.size();
+        double[] aX = new double[len];
+        for (int i = len-1; i >0; i --){
+            aX[i] = points.get(i).getX();
+            System.out.print(aX[i]+",");
+            System.out.print("\n");
+        }
+        System.out.print("\n");
+        System.out.print("Y轴数据\n");
+
+        double[] aY = new double[len];
+        for (int i = len-1;i >0; i--){
+            aY[i] = points.get(i).getY();
+            System.out.print(aY[i]+",");
+            System.out.print("\n");
+        }
+
+        return points;
+    }
+
+    private static void Builder(List<PointVo> points, double min, double max) {
+        boolean b = false;
+        for (int i = 0; i < points.size(); i++) {
+            if (b) {
+                points.get(i).setY(max);
+            } else {
+                if (max == points.get(i).getY()) {
+                    b = true;
+                }
+            }
+
+        }
+        for (int i = points.size() - 1; i > -1; i--) {
+            if (!b) {
+                points.get(i).setY(min);
+            } else {
+                if (min == points.get(i).getY()) {
+                    b = false;
+                }
+            }
+        }
+    }
+
+    private static double[] MultiLine(double[] arrX, double[] arrY, int length,int dimension)
+    {
+        int n = dimension + 1;                  //dimension次方程需要求 dimension+1个 系数
+        double[][] Guass = new double[n][n + 1];      //高斯矩阵 例如:y=a0+a1*x+a2*x*x
+        for (int i = 0; i < n; i++) {
+            int j;
+            for (j = 0; j < n; j++) {
+                Guass[i][j] = SumArr(arrX, j + i, length);
+            }
+            Guass[i][j] = SumArr(arrX, i, arrY, 1, length);
+        }
+        return ComputGauss(Guass, n);
+    }
+
+    private static double SumArr(double[] arr, int n, int length) //求数组的元素的n次方的和
+    {
+        double s = 0;
+        for (int i = 0; i < length; i++) {
+            if (arr[i] != 0 || n != 0)
+                s = s + Math.pow(arr[i], n);
+            else
+                s = s + 1;
+        }
+        return s;
+    }
+
+    private static double SumArr(double[] arr1, int n1, double[] arr2, int n2, int length) {
+        double s = 0;
+        for (int i = 0; i < length; i++) {
+            if ((arr1[i] != 0 || n1 != 0) && (arr2[i] != 0 || n2 != 0))
+                s = s + Math.pow(arr1[i], n1) * Math.pow(arr2[i], n2);
+            else
+                s = s + 1;
+        }
+        return s;
+
+    }
+
+    private static double[] ComputGauss(double[][] Guass, int n) {
+        int i, j;
+        int k, m;
+        double temp;
+        double max;
+        double s;
+        double[] x = new double[n];
+        for (i = 0; i < n; i++) x[i] = 0.0;//初始化
+
+        for (j = 0; j < n; j++) {
+            max = 0;
+            k = j;
+            for (i = j; i < n; i++) {
+                if (Math.abs(Guass[i][j]) > max) {
+                    max = Guass[i][j];
+                    k = i;
+                }
+            }
+
+
+            if (k != j) {
+                for (m = j; m < n + 1; m++) {
+                    temp = Guass[j][m];
+                    Guass[j][m] = Guass[k][m];
+                    Guass[k][m] = temp;
+                }
+            }
+            if (0 == max) {
+                // "此线性方程为奇异线性方程"
+                return x;
+            }
+
+            for (i = j + 1; i < n; i++) {
+                s = Guass[i][j];
+                for (m = j; m < n + 1; m++) {
+                    Guass[i][m] = Guass[i][m] - Guass[j][m] * s / (Guass[j][j]);
+                }
+            }
+
+        }//结束for (j=0;j<n;j++)
+
+        for (i = n - 1; i >= 0; i--) {
+            s = 0;
+            for (j = i + 1; j < n; j++) {
+                s = s + Guass[i][j] * x[j];
+            }
+            x[i] = (Guass[i][n] - s) / Guass[i][i];
+        }
+        return x;
+    }//返回值是函数的系数
+
+
+
+    /**
+     * P-V曲线拟合算法
+     * 多项式曲线拟合
+     * @param arrX --功率(P)值
+     * @param arrY  --电流(I)值
+     * @param order 进行拟合的阶数
+     */
+
+    public static List<PointVo> BuildLine_PV_Poly(double[] arrX, double[] arrY, int order) {
+
+        double[] aX = new double[10];
+
+        double maxValue = 0;
+        for(int i = 0 ;i < arrX.length; i++){
+            double val = arrX[i];
+            if(val > maxValue){
+                maxValue = val;
+            }
+        }
+        double scale = 0.1;
+        int ylen = (int)(maxValue/scale);
+
+        double[] aY = new double[ylen];
+        for(int i = 0; i< arrX.length; i++){
+            aX[i] = arrX[i];
+        }
+        PointVo point = new PointVo();
+        List<PointVo> points = new ArrayList<>();
+
+        // N阶多项式会有N+1个系数,其中之一为常数项
+        double[] factor = new double[order + 1];
+        for(int index = 0; index < factor.length; index++) {
+            factor[index] = index + 1;
+        }
+        for(int index = 0; index < arrY.length; index++) {
+            arrX[index] = index * 0.00001;
+            arrY[index] = calcPoly(arrX[index], factor); // y = sum(x[n) * fact[n])
+
+        }
+
+        //调用将arrX和arrY序列中的数据逐个添加到观察点序列对象中
+        WeightedObservedPoints point1 = new WeightedObservedPoints();
+        for(int index = 0; index < arrX.length; index++) {
+            point1.add(arrX[index], arrY[index]);
+        }
+       // 创建PolynomialCurveFitter对象,需指定拟合多项式的阶数
+        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(order);
+
+        List<Object> params = new ArrayList<Object>();
+        params.add(point1);
+       // 调用PolynomialCurveFitter的fit方法进行多项式曲线拟合
+        WeightedObservedPoints point2 = (WeightedObservedPoints)params.get(0);
+     //   拟合结果通过一个double数组返回,按元素顺序依次是常数项、一次项、二次项、……。
+        double[] result = fitter.fit(point2.toList());//例如 3,4,2,6 y=3*x^3+4*x^2+2*x+6
+
+       // String y = printPoly(result);
+        int k = result.length - 1;
+        System.out.print("X轴数据\n");
+        for(int i = 0;i < aX.length; i++){
+            System.out.print(aX[i]+",");
+            System.out.print("\n");
+        }
+        System.out.print("Y轴数据\n");
+
+        int q = 0;
+
+        for (double i = aX[aX.length - 1]; i > aX[0]; i -= scale) {
+
+            for (int j = 0; j < result.length; j++) {
+                if (j == 0) {
+                    aY[q] = result[k];
+                } else {
+                    aY[q] += Math.pow(arrX[q], j) * result[k - j];
+                }
+            }
+            System.out.print(aY[q]+",");
+            System.out.print("\n");
+            q++;
+        }
+        return points;
+    }
+
+    /**
+     * P-V曲线拟合算法
+     * 多项式曲线拟合
+     *
+     * @param arrX --电压(V)值
+     * @param arrY  --电流(I)值
+     * @param order 进行拟合的阶数
+     */
+
+    public static List<PointVo> BuildLine_IV_Poly(double[] arrX, double[] arrY, int order) {
+
+        PointVo point = new PointVo();
+        List<PointVo> points = new ArrayList<>();
+
+        // N阶多项式会有N+1个系数,其中之一为常数项
+        double[] factor = new double[order + 1];
+        for(int index = 0; index < factor.length; index++)
+        {
+            factor[index] = index + 1;
+        }
+        for(int index = 0; index < arrY.length; index++)
+        {
+            arrX[index] = index * 0.00001;
+            arrY[index] = calcPoly(arrX[index], factor); // y = sum(x[n) * fact[n])
+        }
+        //调用将arrX和arrY序列中的数据逐个添加到观察点序列对象中
+        WeightedObservedPoints point1 = new WeightedObservedPoints();
+        for(int index = 0; index < arrX.length; index++)
+        {
+            point1.add(arrX[index], arrY[index]);
+        }
+        // 创建PolynomialCurveFitter对象,需指定拟合多项式的阶数
+        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(order);
+
+        List<Object> params = new ArrayList<Object>();
+        params.add(point1);
+        // 调用PolynomialCurveFitter的fit方法进行多项式曲线拟合
+        WeightedObservedPoints point2 = (WeightedObservedPoints)params.get(0);
+        //   拟合结果通过一个double数组返回,按元素顺序依次是常数项、一次项、二次项、……。
+        double[] result = fitter.fit(point2.toList());//例如 3,4,2,6 y=3*x^3+4*x^2+2*x+6
+
+        int k = result.length - 1;
+        for (int i = 0 ; i <= arrX[arrX.length - 1]; i++) {
+            for (int j = 0; j < result.length; j++) {
+                if (j == 0) {
+                    arrY[i] = result[k];
+                    break;
+                }
+                arrY[i] += Math.pow(arrX[i], j) * result[k - j];
+            }
+            point.setX(arrX[i]);
+            point.setX(arrY[i]);
+            points.add(point);
+        }
+
+        return points;
+    }
+
+    public static double calcPoly(double x, double[] factor)
+    {
+        double y = 0;
+        for(int deg = 0; deg < factor.length; deg++)
+        {
+            y += Math.pow(x, deg) * factor[deg];
+        }
+        return y;
+    }
+    public static String printPoly(double[] result) {
+
+        String polynomialString = "";
+        for (int i = 0; i < result.length; i++) {
+            if (i == 0) {
+                polynomialString += result[i];
+                break;
+            }
+            polynomialString += result[i] + "x^" + i + " ";
+        }
+        return polynomialString;
+    }
+}
+
+

+ 201 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/PolynomialCurveFitting.java

@@ -0,0 +1,201 @@
+package com.gyee.power.fitting.common.alg;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.gyee.power.fitting.model.custom.TsDoubleData;
+import org.apache.commons.math3.fitting.PolynomialCurveFitter;
+import org.apache.commons.math3.fitting.WeightedObservedPoint;
+import org.apache.commons.math3.fitting.WeightedObservedPoints;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+@Component
+public class PolynomialCurveFitting implements CurveFitting {
+
+    private WeightedObservedPoints points = null;
+    private final int degree = 3; // 阶数
+
+    private double[] inputDataX = null;
+    private double[] inputDataY = null;
+
+    public void CalcCurveFitting() {
+        inputDataX = new double[17];
+        inputDataY = new double[17];
+        importdata_1("data1", inputDataX);
+        importdata_1("data2", inputDataY);
+        System.out.print("本算例用于计算多项式曲线拟合。已加载计算数据(" + inputDataX.length + "点, " + degree + "阶)... ...");
+        /*double[] factor = new double[degree + 1];
+        // N阶多项式会有N+1个系数,其中之一为常数项
+        for (int index = 0; index < factor.length; index++) {
+            factor[index] = index + 1;
+        }
+        for (int index = 0; index < inputDataY.length; index++) {
+            inputDataX[index] = index * 0.1;
+            inputDataY[index] = calcPoly(inputDataX[index], factor); // y = sum(x[n) * fact[n])
+            // System.out.print(inputDataY[index] + ", ");
+        }*/
+        points = new WeightedObservedPoints();
+        for (int index = 0; index < inputDataX.length; index++) {
+            points.add(inputDataX[index], inputDataY[index]);
+        }
+        System.out.println("初始化完成");
+    }
+
+    public double[] run(List<WeightedObservedPoint> params) {
+        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(degree);
+        double[] result = fitter.fit(params);
+        return result;
+    }
+
+    public double[] run(WeightedObservedPoints params) {
+        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(degree);
+        double[] result = fitter.fit(params.toList());
+        return result;
+    }
+
+    @Override
+    public List<Object> getParams() {
+        CalcCurveFitting();
+        List<Object> params = new ArrayList<Object>();
+        params.add(points);
+        return params;
+    }
+
+    @Override
+    //例如 3,4,2,6 y=3*x^3+4*x^2+2*x+6
+    public void printResult(Object r,double accuracy) {
+        double[] result = (double[]) r;
+
+        List<Double> dataX = new ArrayList<>();
+        List<Double> dataY = new ArrayList<>();
+
+        for (double index = inputDataX[0]; index < inputDataX[inputDataX.length-1]; index+=accuracy) {
+            //int i = 0;
+            dataX.add(index);
+            dataY.add(calcPoly(index, result));
+            //i++;
+        }
+        System.out.print("\n\n\nX轴数据\n\n");
+        for (Double x : dataX) {
+            System.out.println(x+",");
+        }
+        System.out.print("\n\n\nY轴数据\n\n");
+        for (Double y : dataY) {
+            System.out.println(y+",");
+        }
+    }
+    public void printResultAll(List<TsDoubleData> x, double[] result,double accuracy) {
+
+        List<Double> dataX = new ArrayList<>();
+        List<Double> dataY = new ArrayList<>();
+
+        for (double index = x.get(0).getDoubleValue(); index < x.get(x.size()-1).getDoubleValue(); index+=accuracy) {
+            //int i = 0;
+            dataX.add(index);
+            dataY.add(calcPoly(index, result));
+            //i++;
+        }
+        System.out.print("\n\n\nX轴数据\n\n");
+        for (Double d : dataX) {
+            System.out.print(d + ",");
+        }
+        System.out.print("\n\n\nY轴数据\n\n");
+        for (Double y : dataY) {
+            System.out.print(y + ",");
+        }
+        System.out.println();
+    }
+
+    public void printResultAll2(List<Double> points, double[] result, double accuracy) {
+        List<Double> dataX = new ArrayList<>();
+        List<Double> dataY = new ArrayList<>();
+
+        for (double index = points.get(0); index < points.get(points.size() - 1); index += accuracy) {
+            //int i = 0;
+            dataX.add(index);
+            dataY.add(calcPoly(index, result));
+            //i++;
+        }
+        System.out.print("\n\n\nX轴数据\n\n");
+        for (Double d : dataX) {
+            System.out.print(d + ",");
+        }
+        System.out.print("\n\n\nY轴数据\n\n");
+        for (Double y : dataY) {
+            System.out.print(y + ",");
+        }
+        System.out.println();
+    }
+
+    public String printResultY(List<TsDoubleData> x, double[] result) {
+        System.out.print("\n\n\nY轴数据\n\n");
+        String ss = "";
+        for (TsDoubleData v : x) {
+            double y = calcPoly(v.getDoubleValue(), result);
+            String s = y + ",";
+            ss += s;
+        }
+        return ss;
+    }
+
+    public double calcPoly(double x, double[] factor) {
+        double y = 0;
+        for (int deg = 0; deg < factor.length; deg++) {
+            y += Math.pow(x, deg) * factor[deg];
+        }
+        return y;
+    }
+
+    public double calcLow(Map<Double, Double> points, double[] factor) {
+        double sum = 0;
+        for (Map.Entry<Double, Double> dde : points.entrySet()) {
+            sum += dde.getValue() - calcPoly(dde.getKey(), factor);
+        }
+        return sum/points.size();
+    }
+
+    /**
+     * 从execl中导入数据
+     */
+    public static void importdata_1(String sheet, final double[] data)
+    {
+        int i=0;
+        List<Map<Integer,String>> list = new LinkedList<>(); //初始化列表
+
+        EasyExcel.read("D:/光伏经济运行/WTest0.xlsx") //文件路径
+                .sheet(sheet) //表单名
+                .registerReadListener(new AnalysisEventListener<Map<Integer,String>>() { //监听器,以行的形式读取Excel
+
+                    //一行一行读取Excel,在这里处理读取到的数据
+                    @Override
+                    public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
+                        // TODO Auto-generated method stub
+                        list.add(integerStringMap); //将读取到的每一行为一组存入列表中
+                    }
+
+                    //数据读取完毕后运行下面
+                    @Override
+                    public void doAfterAllAnalysed(AnalysisContext context) {
+                        System.out.println("数据读取完毕");
+                    }
+                }).headRowNumber(1).doRead(); //headRowNumber(num)为指定前num行为表头,从num+1开始读,默认为1
+
+        //遍历列表存储数据
+        for (Map<Integer, String> integerStringMap : list)
+        {
+            Set<Integer> keySet =integerStringMap.keySet();
+            Iterator<Integer> iterator = keySet.iterator();
+            while (iterator.hasNext())
+            {
+                Integer key = iterator.next();
+                Double val = Double.valueOf(integerStringMap.get(key));
+                System.out.print(val+",");
+                data[i++] = val;
+            }
+        }
+        System.out.println();
+        System.out.println(i+"条数据已导入");
+    }
+}

+ 327 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/PowerFittingALG.java

@@ -0,0 +1,327 @@
+package com.gyee.power.fitting.common.alg;
+
+import com.gyee.power.fitting.model.custom.LineCurveFitting;
+import com.gyee.power.fitting.model.custom.Point;
+import com.gyee.power.fitting.model.custom.PointVo;
+import com.gyee.power.fitting.model.custom.PowerPointData;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 功率曲线拟合算法
+ * 最小二乘法
+ */
+public class PowerFittingALG {
+
+    /**
+     * 功率曲线拟合
+     *
+     * @param arrX        风速数组
+     * @param arrY        功率数据
+     * @param length      点个数
+     * @param dimension   维度
+     * @param scale       精度  0.1  0.01
+     * @return
+     */
+    public static List<Point> buildLine(double[] arrX, double[] arrY, int length, int dimension, double scale) {
+
+        List<Point> points = new ArrayList<>();
+
+        if (arrX.length != arrY.length || arrX.length < 3) {
+            return points;
+        }
+
+        double minValue = arrY[0];
+        double maxValue = arrY[arrY.length - 1];
+
+        double min = 0;
+        double max = 0;
+
+        double[] coefficient = MultiLine(arrX, arrY, length, dimension);
+
+        for (double i = arrX[0]; i <= arrX[arrX.length - 1]; i += scale) {
+            Point point = new Point();
+            point.setX(i);
+
+
+            for (int j = 0; j < coefficient.length; j++) {
+                if (j == 0) {
+                    point.setY(coefficient[j] * Math.pow(point.getX(), j));
+                } else {
+                    double temp = coefficient[j] * Math.pow(point.getX(), j);
+                    point.setY(point.getY() + temp);
+                }
+
+            }
+            if (point.getY() < minValue) {
+                point.setY(minValue);
+
+            }
+            if (point.getY() > maxValue) {
+                point.setY(maxValue);
+            }
+
+            if (point.getY() < min) {
+                min = point.getY();
+            }
+            if (point.getY() > max) {
+                max = point.getY();
+            }
+
+            points.add(point);
+        }
+        Builder(points, min, max);
+        return points;
+    }
+
+    private static void Builder(List<Point> points, double min, double max) {
+        boolean b = false;
+        for (int i = 0; i < points.size(); i++) {
+            if (b) {
+                points.get(i).setY(max);
+            } else {
+                if (max == points.get(i).getY()) {
+                    b = true;
+                }
+            }
+
+        }
+
+        for (int i = points.size() - 1; i > -1; i--) {
+            if (!b) {
+                points.get(i).setY(min);
+            } else {
+                if (min == points.get(i).getY()) {
+                    b = false;
+                }
+            }
+
+        }
+    }
+
+
+    ///<summary>
+    ///用最小二乘法拟合二元多次曲线
+    ///</summary>
+    ///<param name="arrX">已知点的x坐标集合</param>
+    ///<param name="arrY">已知点的y坐标集合</param>
+    ///<param name="length">已知点的个数</param>
+    ///<param name="dimension">方程的最高次数</param>
+    //二元多次线性方程拟合曲线
+    private static double[] MultiLine(double[] arrX, double[] arrY, int length, int dimension) {
+        int n = dimension + 1;                  //dimension次方程需要求 dimension+1个 系数
+        double[][] Guass = new double[n][n + 1];      //高斯矩阵 例如:y=a0+a1*x+a2*x*x
+        for (int i = 0; i < n; i++) {
+            int j;
+            for (j = 0; j < n; j++) {
+                Guass[i][j] = SumArr(arrX, j + i, length);
+            }
+            Guass[i][j] = SumArr(arrX, i, arrY, 1, length);
+        }
+        return ComputGauss(Guass, n);
+    }
+
+    //求数组的元素的n次方的和
+    private static double SumArr(double[] arr, int n, int length) {
+        double s = 0;
+        for (int i = 0; i < length; i++) {
+            if (arr[i] != 0 || n != 0)
+                s = s + Math.pow(arr[i], n);
+            else
+                s = s + 1;
+        }
+        return s;
+    }
+
+    private static double SumArr(double[] arr1, int n1, double[] arr2, int n2, int length) {
+        double s = 0;
+        for (int i = 0; i < length; i++) {
+            if ((arr1[i] != 0 || n1 != 0) && (arr2[i] != 0 || n2 != 0))
+                s = s + Math.pow(arr1[i], n1) * Math.pow(arr2[i], n2);
+            else
+                s = s + 1;
+        }
+        return s;
+
+    }
+
+    private static double[] ComputGauss(double[][] Guass, int n) {
+        int i, j;
+        int k, m;
+        double temp;
+        double max;
+        double s;
+        double[] x = new double[n];
+        for (i = 0; i < n; i++) x[i] = 0.0;//初始化
+
+        for (j = 0; j < n; j++) {
+            max = 0;
+            k = j;
+            for (i = j; i < n; i++) {
+                if (Math.abs(Guass[i][j]) > max) {
+                    max = Guass[i][j];
+                    k = i;
+                }
+            }
+
+
+            if (k != j) {
+                for (m = j; m < n + 1; m++) {
+                    temp = Guass[j][m];
+                    Guass[j][m] = Guass[k][m];
+                    Guass[k][m] = temp;
+                }
+            }
+            if (0 == max) {
+                // "此线性方程为奇异线性方程" 
+                return x;
+            }
+
+            for (i = j + 1; i < n; i++) {
+                s = Guass[i][j];
+                for (m = j; m < n + 1; m++) {
+                    Guass[i][m] = Guass[i][m] - Guass[j][m] * s / (Guass[j][j]);
+                }
+            }
+
+        }//结束for (j=0;j<n;j++)
+
+        for (i = n - 1; i >= 0; i--) {
+            s = 0;
+            for (j = i + 1; j < n; j++) {
+                s = s + Guass[i][j] * x[j];
+            }
+            x[i] = (Guass[i][n] - s) / Guass[i][i];
+        }
+        return x;
+    }//返回值是函数的系数
+
+
+    /**
+     * 推力系数 CP 值
+     * @param sweptarea  扫风面积
+     * @param line
+     * @return
+     */
+    public static LineCurveFitting buildCp(Double sweptarea, LineCurveFitting line){
+        List<Point> cpValue = new ArrayList<>();
+
+        double kqmd = 1.225; //空气密度
+        double max = 0;
+        double cpAvg = 0;
+        double sum1 = 0;
+
+        for (int i = 0; i < line.getYLines().size(); i++)
+        {
+            Point point = line.getYLines().get(i);
+            double speed = point.getX();
+            double power = point.getY();
+            double k = 0.5 * kqmd * Math.pow(speed, 3) * sweptarea;
+            double result = 0;
+            if (k != 0)
+                result = power / k * 1000;
+            //s5.Points.AddXY(speed, result);
+            Point cppoint = new Point();
+            cppoint.setX(speed);
+            cppoint.setY(result);
+            cpValue.add(cppoint);
+
+            if (max < result)
+            {
+                max = result;
+            }
+
+            if (result > 0 && speed >= 3 && speed <= 25)
+            {
+                cpAvg += result;
+                sum1++;
+
+            }
+
+        }
+        if(sum1>0)
+            cpAvg /= sum1;
+
+        line.setCpValue(cpValue);
+        line.setCpAvg(new BigDecimal(cpAvg).setScale(2, BigDecimal.ROUND_CEILING).doubleValue());
+
+        return line;
+    }
+
+
+
+
+
+    /**
+     * 曲线偏差率
+     * @param points1 风速功率数组
+     * @param points2
+     * @param maxp
+     * @return
+     */
+    public static double curveDeviationRatio(List<Point> points1, List<Point> points2, double maxp) {
+        double result = -0;
+        double pc = 0;
+        if (points1 != null && points1.size() > 0 && points2 != null && points2.size() > 0)
+        {
+            double count = 0;
+            double sum = 0;
+            for (Point point : points1){
+                Optional<Point> p = points2.stream().filter(it -> it.getX() == point.getX()).findFirst();
+                if (p.isPresent()){
+                    sum += Math.pow(point.getY() - p.get().getY(), 2);
+                    count ++;
+                    pc += point.getY() - p.get().getY();
+                }
+            }
+            sum = Math.sqrt(sum);
+            count = Math.sqrt(count);
+            maxp = maxp * count;
+            if (maxp != 0)
+                result = sum / maxp * 100;
+            if (pc < 0)
+                result = 0 - result;
+        }
+        return result;
+    }
+
+    /**
+     * 曲线偏差率  正负偏差
+     * @param points1 风速功率数组
+     * @param points2 风速功率数组(保证功率)
+     * @param maxp  区间内的最大保证功率
+     * @param mins 最小风速
+     * @param maxs 最大风速
+     * @return
+     */
+    public static double curveDeviationRatio2(List<Point> points1, List<Point> points2, double maxp, double mins, double maxs) {
+        double result = -0;
+        double pc = 0;
+        if (points1 != null && points1.size() > 0 && points2 != null && points2.size() > 0)
+        {
+            double count = 0;
+            double sum = 0;
+            for (Point point : points1){
+                Optional<Point> p = points2.stream().filter(it -> it.getX() == point.getX()).findFirst();
+                if (p.isPresent() && p.get().getX() >= mins && p.get().getX() < maxs){
+                    sum += Math.pow(point.getY() - p.get().getY(), 2);
+                    count ++;
+                    pc += point.getY() - p.get().getY();
+                }
+            }
+            sum = Math.sqrt(sum);
+            count = Math.sqrt(count);
+            maxp = maxp * count;
+            if (maxp != 0)
+                result = sum / maxp * 100;
+            if (pc < 0)
+                result = 0 - result;
+        }
+        return result;
+    }
+
+}
+

+ 352 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/PowerProcessALG.java

@@ -0,0 +1,352 @@
+package com.gyee.power.fitting.common.alg;
+
+import com.gyee.power.fitting.common.util.DateUtil;
+import com.gyee.power.fitting.model.custom.PowerPointData;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 数据预处理算法
+ */
+public class PowerProcessALG {
+
+
+    /**
+     * 数据预处理
+     *
+     * @param list   预处理的数据
+     * @param map    风速对应的保证功率
+     * @param maxs   最大风速
+     * @param mins   最小风速
+     * @param maxp   最大功率
+     * @param minp   最小功率
+     * @param isfbw  是否并网
+     * @param isfhl  是否合理值
+     * @param isbw   并网后10分钟
+     * @param istj   停机前10分钟
+     * @param isglpc 功率曲线偏差
+     * @param isqfh  是否欠符合
+     * @param qfhdj  欠符合等级
+     * @return
+     */
+    public static List<PowerPointData> dataProcess(List<PowerPointData> list, Map<Double, Double> map,
+                                                   Double maxs, Double mins, Double maxp, Double minp, Boolean isfbw,
+                                                   Boolean isfhl, Boolean isbw, Boolean istj, Boolean isglpc, Boolean isqfh, Integer qfhdj){
+        String timeBW = DateUtil.format(new Date(0), DateUtil.DATE_TIME_PATTERN);
+        List<PowerPointData> tempei = new ArrayList<>();
+        List<PowerPointData> tempqf = new ArrayList<>();
+
+        //TODO 数据过滤  // 0正常,1过滤掉
+        for (PowerPointData item : list) {
+            int filter = 0;
+            int fjstatus = 0;
+            if (timeBW == DateUtil.format(new Date(0), DateUtil.DATE_TIME_PATTERN)){
+                timeBW = item.getTime();
+            }
+            // 过滤非并网值  风机状态不等于2
+            if (filter == 0 && isfbw && item.getMxzt() != 2) {
+                filter = 1;
+                fjstatus = 1;
+                timeBW = item.getTime();
+            } else {
+                filter = 0;
+                fjstatus = 0;
+            }
+            // 按给定风速功率过滤
+            if (item.getSpeed() < mins || item.getSpeed() > maxs || item.getPower() < minp || item.getPower() > maxp) {
+                filter = 1;
+            }
+            // 过滤非合理值 并网状态下功率小于等于0
+            if (filter == 0 && isfhl && item.getSpeed() < 0 && item.getPower() <= minp) {
+                filter = 1;
+            }
+            // 过滤并网后十分钟
+            if (filter == 0 && isbw) {
+                if (DateUtil.getTimeDiff(item.getTime(), timeBW) <= 10)
+                    filter = 1;
+            }
+            // 过滤停机前十分钟
+            if (istj) {
+                if (fjstatus == 0) {
+                    if (tempei.size() > 0) {
+                        if (DateUtil.getTimeDiff(tempei.get(0).getTime(), timeBW) >= 10) {
+                            tempei.remove(0);
+                        }
+                    }
+                    tempei.add(item);
+                } else {
+                    for (PowerPointData temp : tempei) {
+                        temp.setFilter(1);
+                    }
+                    tempei.clear();
+                }
+            }
+            //欠发
+            if (filter == 0 && item.getSpeed() >= 6 && item.getSpeed() < 12.5 && isqfh && qfhdj < item.getQfzt()) {
+                filter = 1;
+                for (PowerPointData temp : tempqf) {
+                    temp.setFilter(1);
+                }
+            } else if (filter == 0 && item.getSpeed() >= 12.5 && isqfh && qfhdj < 1) {
+                filter = 1;
+                for (PowerPointData temp : tempqf) {
+                    temp.setFilter(1);
+                }
+            }
+            if (tempqf.size() > 0) {
+                if (DateUtil.getTimeDiff(tempqf.get(0).getTime(), item.getTime()) >= 5) {
+                    tempqf.remove(0);
+                }
+            }
+            tempqf.add(0, item);
+            item.setFilter(filter);
+
+            //功率曲线偏差
+            if (isglpc) {
+                if (map.containsKey(item.getSpeed())) {
+                    double power = map.get(item.getSpeed());  //不同风速对应的保证功率
+                    double maxPower = map.get(24.0);     //最大保证功率
+                    double k = item.getPower() / power;  //保证功率/实际功率   k:偏差百分比
+                    if (item.getPower() > 0) {
+                        if (k < 0.95 && maxPower <= power) {
+                            item.setFilter(1);
+                        }
+                        if (k < 0.9 && maxPower > power) {
+                            item.setFilter(1);
+                        }
+                        if (k < 0.85 && item.getSpeed() < 6 && item.getSpeed() > 4) {
+                            item.setFilter(1);
+                        }
+
+                        if (k < 0.9 && item.getSpeed() <= 4 && item.getSpeed() > 3.5) {
+                            item.setFilter(1);
+                        }
+//                        if (k < 0.85 && item.getSpeed() <= 3.5 && item.getSpeed() > 3) {
+//                            item.setFilter(1);
+//                        }
+//                        if (k < 0.4 && item.getSpeed() <= 3 && item.getSpeed() > 0) {
+//                            item.setFilter(1);
+//                        }
+                    }
+                }
+            }
+        }
+
+        return list;
+    }
+
+
+    /**
+     * 按照给定风俗功率过滤
+     * @param list
+     * @param maxs  最大风速
+     * @param mins  最小风速
+     * @param maxp  最大功率
+     * @param minp  最小风速
+     * @return
+     */
+    public static List<PowerPointData> dataProcessPS(List<PowerPointData> list, Double maxs, Double mins, Double maxp, Double minp){
+        //TODO 数据过滤  // 0正常,1过滤掉
+        for (PowerPointData item : list) {
+            int filter = 0;
+            // 按给定风速功率过滤
+            if (item.getSpeed() < mins || item.getSpeed() > maxs || item.getPower() < minp || item.getPower() > maxp) {
+                filter = 1;
+            }
+
+            item.setFilter(filter);
+        }
+
+        return list;
+    }
+
+    /**
+     * 过滤非并网值
+     * @param list
+     * @return
+     */
+    public static List<PowerPointData> dataProcessFBW(List<PowerPointData> list){
+        //TODO 数据过滤  // 0正常,1过滤掉
+        for (PowerPointData item : list) {
+            int filter = 0;
+            // 过滤非并网值  风机状态不等于2
+            if (filter == 0 && item.getMxzt() != 2)
+                filter = 1;
+
+            item.setFilter(filter);
+        }
+
+        return list;
+    }
+
+
+    /**
+     * 过滤非合理值
+     * @param list
+     * @return
+     */
+    public static List<PowerPointData> dataProcessFHLZ(List<PowerPointData> list){
+        //TODO 数据过滤  // 0正常,1过滤掉
+        for (PowerPointData item : list) {
+            int filter = 0;
+            // 过滤非合理值 并网状态下功率小于等于0
+            if (filter == 0 && item.getMxzt() != 2 && item.getPower() <= 0) {
+                filter = 1;
+            }
+
+            item.setFilter(filter);
+        }
+
+        return list;
+    }
+
+    /**
+     * 过滤并网后几分钟内数据
+     * @param list
+     * @param minute  分钟
+     * @return
+     */
+    public static List<PowerPointData> dataProcessBWH(List<PowerPointData> list, int minute){
+        String timeBW = DateUtil.format(new Date(0), DateUtil.DATE_TIME_PATTERN);
+        //TODO 数据过滤  // 0正常,1过滤掉
+        for (PowerPointData item : list) {
+            int filter = 0;
+            if (timeBW == DateUtil.format(new Date(0), DateUtil.DATE_TIME_PATTERN)){
+                timeBW = item.getTime();
+            }
+            // 过滤并网后十分钟
+            if (filter == 0 && DateUtil.getTimeDiff(item.getTime(), timeBW) <= minute){
+                filter = 1;
+            }
+
+            item.setFilter(filter);
+        }
+
+        return list;
+    }
+
+
+    /**
+     * 过滤停机前几分钟内数据
+     * @param list
+     * @param minute  分钟
+     * @return
+     */
+    public static List<PowerPointData> dataProcessTJQ(List<PowerPointData> list, int minute){
+        String timeBW = DateUtil.format(new Date(0), DateUtil.DATE_TIME_PATTERN);
+        List<PowerPointData> tempei = new ArrayList<>();
+
+        //TODO 数据过滤  // 0正常,1过滤掉
+        for (PowerPointData item : list) {
+            int filter = 0;
+            int fjstatus = 0;
+            if (timeBW == DateUtil.format(new Date(0), DateUtil.DATE_TIME_PATTERN)){
+                timeBW = item.getTime();
+            }
+            if (filter == 0 && item.getMxzt() != 2) {
+                filter = 1;
+                fjstatus = 1;
+                timeBW = item.getTime();
+            } else {
+                filter = 0;
+                fjstatus = 0;
+            }
+            // 过滤停机前十分钟
+            if (fjstatus == 0) {
+                if (tempei.size() > 0) {
+                    if (DateUtil.getTimeDiff(tempei.get(0).getTime(), timeBW) >= minute) {
+                        tempei.remove(0);
+                    }
+                }
+                tempei.add(item);
+            } else {
+                for (PowerPointData temp : tempei) {
+                    temp.setFilter(1);
+                }
+                tempei.clear();
+            }
+
+            item.setFilter(filter);
+        }
+
+        return list;
+    }
+
+    /**
+     * 曲线偏差率过滤
+     * @param list
+     * @param map  风速对应的保证功率
+     * @return
+     */
+    public static List<PowerPointData> dataProcessQXPC(List<PowerPointData> list, Map<Double, Double> map){
+        //TODO 数据过滤  // 0正常,1过滤掉
+        for (PowerPointData item : list) {
+            if (map.containsKey(item.getSpeed())) {
+                double power = map.get(item.getSpeed());  //不同风速对应的保证功率
+                double maxPower = map.get(24.0);     //最大保证功率
+                double k = item.getPower() / power;  //保证功率/实际功率   k:偏差百分比
+                if (item.getPower() > 0) {
+                    if (k < 0.95 && maxPower <= power) {
+                        item.setFilter(1);
+                    }
+                    if (k < 0.9 && maxPower > power) {
+                        item.setFilter(1);
+                    }
+                    if (k < 0.85 && item.getSpeed() < 6 && item.getSpeed() > 4) {
+                        item.setFilter(1);
+                    }
+
+                    if (k < 0.9 && item.getSpeed() <= 4 && item.getSpeed() > 3.5) {
+                        item.setFilter(1);
+                    }
+                    if (k < 0.85 && item.getSpeed() <= 3.5 && item.getSpeed() > 3) {
+                        item.setFilter(1);
+                    }
+                    if (k < 0.4 && item.getSpeed() <= 3 && item.getSpeed() > 0) {
+                        item.setFilter(1);
+                    }
+                }
+            }
+        }
+
+        return list;
+    }
+
+    /**
+     * 根据欠发过滤
+     * @param list
+     * @param qfhdj 签发等级
+     * @return
+     */
+    public static List<PowerPointData> dataProcessQF(List<PowerPointData> list, int qfhdj){
+        List<PowerPointData> tempqf = new ArrayList<>();
+        //TODO 数据过滤  // 0正常,1过滤掉
+        for (PowerPointData item : list) {
+            int filter = 0;
+            //欠发
+            if (filter == 0 && item.getSpeed() >= 6 && item.getSpeed() < 12.5 && qfhdj < item.getQfzt()) {
+                filter = 1;
+                for (PowerPointData temp : tempqf) {
+                    temp.setFilter(1);
+                }
+            } else if (filter == 0 && item.getSpeed() >= 12.5 && qfhdj < 1) {
+                filter = 1;
+                for (PowerPointData temp : tempqf) {
+                    temp.setFilter(1);
+                }
+            }
+            if (tempqf.size() > 0) {
+                if (DateUtil.getTimeDiff(tempqf.get(0).getTime(), item.getTime()) >= 5) {
+                    tempqf.remove(0);
+                }
+            }
+            tempqf.add(0, item);
+            item.setFilter(filter);
+        }
+
+        return list;
+    }
+}

+ 72 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/PowerTemperatureAlg.java

@@ -0,0 +1,72 @@
+package com.gyee.power.fitting.common.alg;
+
+
+import com.gyee.power.fitting.model.custom.PowerPointData;
+
+import java.util.*;
+
+/**
+ * 温度功率算法
+ */
+public class PowerTemperatureAlg {
+
+
+    /**
+     * 风速大于12m时的平均额定功率与额定功率的差值
+     * @param points  测点数据
+     * @param power   该型号风机的额定功率
+     * @param minT    最小温度
+     * @param maxT    最大温度
+     * 统计跨度温度内是否欠满发   实发总功率/次数 - 理论功率
+     */
+    public static Map<String, Integer> temperatureRatedPower(List<PowerPointData> points, double power, double minT, double maxT){
+        Map<Integer, int[]> map = new TreeMap<>(); //[0]计数  [1]功率求和
+        int mint = (int) minT;
+        int maxt = (int) maxT;
+        int split = 2;  //温度间隔步调2°
+
+        points.stream().filter(f -> !(f.getSpeed() < 12.0 || f.getSpeed() > 25.0 || f.getMxzt() != 2))
+                .sorted(Comparator.comparing(PowerPointData::getHjwd)).forEach(item -> {
+            int T = (int) item.getHjwd();
+            if (!map.containsKey(T)) {
+                map.put(T, new int[2]);
+            }
+            int[] value = map.get(T);
+            value[0]++;
+            value[1] += item.getPower();
+        });
+
+        Map<String, Integer> result = new LinkedHashMap<>();
+        for (int i = mint; i <= maxt; i+=split){
+            int count = 0;
+            double totalPower = 0;
+            for (int j = 0; j < split; j++){
+                if (!map.containsKey(i + j))
+                    continue;
+                count += map.get(i + j)[0];
+                totalPower += map.get(i + j)[1];
+            }
+            result.put("(" + i + "," + (i + split) + "]", (int)(totalPower/count - power));
+        }
+
+        return result;
+    }
+
+
+    /**
+     * 额定功率vs.温度分析
+     * @param points  测点
+     * @return  风速大于12m/s满发状态时的
+     */
+    public static List<int[]> temperatureRatedPower(List<PowerPointData> points){
+        List<int[]> list = new ArrayList<>();
+        points.stream().filter(f -> f.getSpeed() >= 12.0 && f.getSpeed() <= 25.0 && f.getMxzt() == 2)
+                .sorted(Comparator.comparing(PowerPointData::getHjwd)).forEach(item -> {
+                    int t = (int) item.getHjwd();
+                    int v = (int) item.getPower();
+                    int[] temp = new int[]{t, v};
+                    list.add(temp);
+                });
+        return list;
+    }
+}

+ 22 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/TimeCostCalculator.java

@@ -0,0 +1,22 @@
+package com.gyee.power.fitting.common.alg;
+
+import java.util.List;
+
+public class TimeCostCalculator {
+    /**
+     * 计算指定对象的运行时间开销。
+     * @param testCase 指定被测对象。
+     * @return 返回sub.run的时间开销,单位为s。
+     */
+    public double calcTimeCost(CurveFitting testCase) {
+        List<Object> params = testCase.getParams();
+        long startTime = System.nanoTime();
+        //拟合结果通过一个double数组返回,按元素顺序依次是常数项、一次项、二次项、……。
+        //Object result = testCase.run(params);
+        long stopTime = System.nanoTime();
+        //testCase.printResult(result,0.5);
+        //System.out.println("start: " + startTime + " / stop: " + stopTime);
+        double timeCost = (stopTime - startTime) * 1.0e-9;
+        return timeCost;
+    }
+}

+ 284 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/alg/WindDirectionALG.java

@@ -0,0 +1,284 @@
+package com.gyee.power.fitting.common.alg;
+
+import com.gyee.power.fitting.model.custom.Point;
+import com.gyee.power.fitting.model.custom.PowerPointData;
+
+import java.text.DecimalFormat;
+import java.util.*;
+
+/**
+ * 风向玫瑰图
+ * 风向频次玫瑰图
+ */
+public class WindDirectionALG {
+
+    /**
+     * 风速风向玫瑰图
+     * 风速:[0,2.5) [2.5,5) [5,7.5) [7.5,10) [10,12.5) [12.5,15) [15,17.5) [17.5,20) [20,22.5) [22.5,25) [25,inf)  11
+     * @param list
+     */
+    public static Object fxRoses(List<PowerPointData> list){
+        int[][] count = new int[11][16];
+
+        list.stream().forEach(item -> {
+            int fx = windFXAngle(item.getFx());
+            int speed = windSpeed(item.getSpeed());
+            if (speed < 11 && fx < 16)
+                count[speed][fx] = 1;
+        });
+
+        return count;
+    }
+
+
+    /**
+     * 风向频次玫瑰图
+     * 风速:[0,2.5) [2.5,5) [5,7.5) [7.5,10) [10,12.5) [12.5,15) [15,17.5) [17.5,20) [20,22.5) [22.5,25) [25,inf)  11
+     * @param list
+     */
+    public static int[][] fxCountRoses(List<PowerPointData> list){
+        int[][] count = new int[11][16];
+        list.stream().sorted(Comparator.comparing(PowerPointData::getSpeed)).forEach(item -> {
+            int fx = windFXAngle(item.getFx());
+            int speed = windSpeed(item.getSpeed());
+            if (speed < 11 && fx < 16)
+                count[speed][fx] ++;
+        });
+
+        return count;
+    }
+
+
+    /**
+     * 风向频次雷达图
+     * @param list
+     * @return
+     */
+    public static int[] fxRadarRoses(List<PowerPointData> list){
+        int[] count = new int[16];
+        list.stream().sorted(Comparator.comparing(PowerPointData::getSpeed)).forEach(item -> {
+            int df = windDFAngle(item.getDfwc());
+            if (count[df] < 1000) {
+                count[df]++;
+            }
+        });
+
+        return count;
+    }
+
+
+    /**
+     * 静风频率计算 、平均风速计算
+     * @param list  风速数组
+     * @param cutInSpeed 切入风速
+     * @return
+     */
+    public static List<Double> frequency(List<Double> list, double cutInSpeed){
+        List<Double> result = new ArrayList<>();
+        DecimalFormat df = new DecimalFormat("0.00");
+        int count = 0;
+        double speed = 0.0;
+        for (Double fs : list){
+            speed += fs;
+            if (fs < cutInSpeed)
+                count ++;
+        }
+        double frequency = list.size() > 0 ? Double.valueOf(df.format(((double)count / list.size() * 100 ))) : 0;
+        double speedAVG = list.size() > 0 ? Double.valueOf(df.format(speed/list.size())) : 0;
+        result.add(frequency);
+        result.add(speedAVG);
+        return result;
+    }
+
+
+
+    /**
+     * 对风偏差散点过滤  统计-50 到 50的
+     * 频次
+     * @param list
+     *
+     *
+     * @return
+     */
+    public static List<Point> windDeviationScatter(List<PowerPointData> list){
+        //正负偏差 [-50,-49,....,0,1,2,.....50]
+        List<Point> ls = new ArrayList<>();
+        LinkedHashSet<Double> keys = new LinkedHashSet<>();  //散点太多去重
+        //次数统计
+        for (int i = 0; i < list.size(); i++){
+            PowerPointData item = list.get(i);
+            int ele = (int)Math.round((item.getFx() + Math.abs(item.getDfwc())));
+            int index = ele - 180;
+            if (index >= -50 && index <= 50) {
+                double key = Math.abs(index) + item.getSpeed();
+                if (!keys.contains(key))
+                    ls.add(new Point(index, item.getSpeed()));
+                keys.add(key);
+            }
+        }
+
+        return ls;
+    }
+
+
+    /**
+     * 静态偏航对风分析
+     * 对风偏差散点过滤  统计-15 到 15的  正负偏差 [-15,-14,....,0,1,2,.....15]
+     * 数据为二维数组 内层数组为3项. 第一项表示Y轴索引(风速),  第二项代表X轴的索引(正负偏差) 第三项代表value值.
+     * @param points
+     * @return
+     */
+    public static Map<String, Object> windDeviationPoint(List<PowerPointData> points){
+        List<PowerPointData> list = new ArrayList<>();
+        List<Object> temp = new ArrayList<>();
+        Map<String, Object> result = new HashMap<>();
+        Map<Integer, double[]> map = new LinkedHashMap<>();
+
+        //过滤对风偏差
+        for (int i = 0; i < points.size(); i++){
+            PowerPointData item = points.get(i);
+            if ((item.getSpeed() < 4.5 || item.getSpeed() >= 10.5) && item.getMxzt() != 2)
+                continue;
+
+            list.add(item);
+            Integer speed = Math.toIntExact(Math.round(item.getSpeed()));
+            if (!map.containsKey(speed))
+                map.put(speed, new double[2]);  //[0]最小值 [1]最大值
+
+            double[] value = map.get(speed);
+            double power = item.getPower() < 0 ? 0 : item.getPower();
+            value[0] = power < value[0] ? power : value[0]; //最小值
+            value[1] = power > value[1] ? power : value[1]; //最大值
+        }
+
+        int avg = 0;
+        DecimalFormat sf = new DecimalFormat("0.00");
+        for (int i = 0; i < list.size(); i++){
+            PowerPointData item = list.get(i);
+            Integer speed = Math.toIntExact(Math.round(item.getSpeed()));
+            int ele = (int) (Math.abs(item.getFx()) + Math.abs(item.getAngle()));
+            int index = ele - 180;
+            if (index >= -30 && index <= 30 && item.getPower() > 0) {
+                avg += index;
+                double[] value = map.get(speed);
+                double v = (item.getPower() - value[0]) / (value[1] - value[0]);
+                double s[] = {speed, index, Double.valueOf(sf.format(v)).doubleValue()};
+                temp.add(s);
+            }
+        }
+        result.put("data", temp);
+        result.put("avg", temp.size() > 0 ? avg/temp.size() : 0);
+
+        return result;
+    }
+
+
+    /**
+     * 对风偏差频次统计  统计-50 到 50
+     * @param list
+     * @return
+     */
+    public static int[] windDeviationRatio(List<PowerPointData> list){
+        int[] pc = new int[101];  //正负偏差 [-50,-49,....,0,1,2,.....50]
+        //次数统计
+        for (int i = 0; i < list.size(); i++){
+            PowerPointData item = list.get(i);
+            int ele = (int) (Math.abs(item.getFx()) + Math.abs(item.getDfwc()));
+            int index = ele - 180;
+            if (index >= -50 && index <= 50)
+                pc[50-(index > 0 ? -index : Math.abs(index))]++;
+        }
+
+        return pc;
+    }
+
+
+    /**
+     * 风向划分
+     * 0:0-22.5
+     * 1:22.5-45
+     * 2:90-135
+     * .。。。。。。
+     * @param fx
+     * @return params: 0,1,2。。。。。15
+     */
+    private static int windFXAngle(double fx){
+        int split = 16;  //风向分为16个角度
+        double angle = (double)360 / split;
+        int index = Math.abs((int) (fx / angle));
+        return index;
+    }
+
+    /**
+     * 对风角度计算
+     * 0:0-22.5
+     * 1:22.5-45
+     * 2:90-135
+     * .。。。。。。
+     * @param
+     * @return
+     */
+    private static int windDFAngle(double angle){
+        int split = 16;  //风向分为8个角度
+        double interval = (double)360 / split;
+        angle = angle > 360 ? 720 - 360 : angle;
+        int index = (int) (Math.abs(angle) / interval);
+        return index;
+    }
+
+    /**
+     * 风速区域划分
+     * @param speed
+     * @return
+     */
+    private static int windSpeed(double speed){
+        if (speed < 2.5)
+            return 0;
+        else if (speed < 5)
+            return 1;
+        else if (speed < 7.5)
+            return 2;
+        else if (speed < 10)
+            return 3;
+        else if (speed < 12.5)
+            return 4;
+        else if (speed < 15)
+            return 5;
+        else if (speed < 17.5)
+            return 6;
+        else if (speed < 20)
+            return 7;
+        else if (speed < 22.5)
+            return 8;
+        else if (speed < 25)
+            return 9;
+        else
+            return 10;
+    }
+
+
+    /**
+     * 数据聚合  间隔10
+     * @param list
+     * @return
+     */
+    private static Object arrayDistinct(List<List<Double>> list){
+        for (List<Double> item : list){
+            List<Double> lt = new ArrayList<>();
+            LinkedHashSet<Integer> ls = new LinkedHashSet<>();
+            item.forEach(ele -> {
+                if (ele == null)
+                    return;
+                int v = (int) (ele / 10);
+                if (!ls.contains(v))
+                    lt.add(ele);
+
+                ls.add(v);
+            });
+            item.clear();
+            item.addAll(lt);
+        }
+
+        return list;
+    }
+}

+ 102 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/base/ExcludeQueryWrapper.java

@@ -0,0 +1,102 @@
+package com.gyee.power.fitting.common.base;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+
+import java.util.Collection;
+
+public class ExcludeQueryWrapper<T> extends QueryWrapper<T> {
+
+    @Override
+    public QueryWrapper<T> eq(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.eq(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> in(boolean condition, String column, Collection<?> val) {
+        condition = !(null == val || val.size() <= 0);
+//        condition = !ObjectUtils.isEmpty(val);
+        return super.in(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> ne(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.ne(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> gt(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.gt(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> ge(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.ge(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> lt(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.lt(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> le(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.le(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> like(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.like(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> notLike(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.notLike(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> likeLeft(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.likeLeft(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> likeRight(boolean condition, String column, Object val) {
+        condition = !ObjectUtils.isEmpty(val);
+        return super.likeRight(condition, column, val);
+    }
+
+    @Override
+    public QueryWrapper<T> between(boolean condition, String column, Object val1, Object val2) {
+        if (ObjectUtils.isEmpty(val1) && ObjectUtils.isEmpty(val2)) {
+            condition = false;
+        } else if (ObjectUtils.isEmpty(val1)) {
+            return super.lt(true, column, val2);
+        } else if (ObjectUtils.isEmpty(val2)) {
+            return super.ge(true, column, val1);
+        }
+        return super.between(condition, column, val1, val2);
+    }
+
+    @Override
+    public QueryWrapper<T> notBetween(boolean condition, String column, Object val1, Object val2) {
+        if (ObjectUtils.isEmpty(val1) && ObjectUtils.isEmpty(val2)) {
+            condition = false;
+        } else if (ObjectUtils.isEmpty(val1)) {
+            return super.lt(true, column, val2);
+        } else if (ObjectUtils.isEmpty(val2)) {
+            return super.ge(true, column, val1);
+        }
+        return super.notBetween(condition, column, val1, val2);
+    }
+
+
+}

+ 22 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/CorsConfig.java

@@ -0,0 +1,22 @@
+package com.gyee.power.fitting.common.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ */
+@Configuration
+public class CorsConfig implements WebMvcConfigurer {
+
+    static final String[] ORIGINS = new String[]{"GET", "POST", "PUT", "DELETE"};  //请求方式
+
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**") //所有的当前站点的请求地址,都支持跨域访问
+                .allowedOrigins("*")// 所有的外部域都可跨域访问,这里注意2.4.0以后是allowedOriginPatterns,以前是allowedOrigins
+                .allowCredentials(true)  //是否支持跨域用户凭证
+                .allowedMethods(ORIGINS) //当前站点支持的跨域请求类型是什么
+                .maxAge(3600);  //超是时长,单位为秒。
+    }
+}

+ 22 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/DataSourceConfig.java

@@ -0,0 +1,22 @@
+package com.gyee.power.fitting.common.config;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.sql.DataSource;
+
+/**
+ * 三区oracle数据源
+ */
+@Configuration
+public class DataSourceConfig {
+
+    @Bean
+    @ConfigurationProperties(prefix = "spring.datasource")
+    public DataSource druidDataSource() {
+        DruidDataSource druidDataSource = new DruidDataSource();
+        return druidDataSource;
+    }
+}

+ 93 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/GyeeConfig.java

@@ -0,0 +1,93 @@
+package com.gyee.power.fitting.common.config;
+
+import com.gyee.power.fitting.model.anno.AnnotationTool;
+import com.gyee.power.fitting.model.anno.FixedVo;
+import com.gyee.power.fitting.model.custom.PowerPointData;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.system.ApplicationHome;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Data
+@Order(0)
+@Component
+@ConfigurationProperties(prefix = "gyee")
+public class GyeeConfig {
+
+    public File jarF = null;
+    {
+        ApplicationHome h = new ApplicationHome(getClass());
+        jarF = h.getSource();
+        //jarF = new File("D:\\java\\sis-background\\power-fitting\\target\\classes");
+    }
+
+    /** 数据适配器网址 **/
+    private String adapterUrl;
+    /** 数据准备保存路径(原始数据) **/
+    private String filePathPrepare;
+    /** 数据处理保存路径(处理后的数据) **/
+    private String filePathProcess;
+    /** 数据拟合保存路径(拟合后的数据) **/
+    private String filePathFitting;
+    /** 数据压缩下载 **/
+    private String filePathDownload;
+    /** 功率曲线拟合测点 **/
+    private String points;
+    /** 适配器读取数据等间隔时间 **/
+    private Integer interval;
+    /** 数据是否离线执行 **/
+    private boolean offLine;
+    /** 是否实时计算 **/
+    private boolean realTimeCal;
+
+    public List<String> getPoints() {
+        return getUniformCodes();
+    }
+
+    public String getFilePathPrepare() {
+        return jarF.getParentFile().getAbsolutePath() + File.separator + filePathPrepare;
+    }
+
+    public void setFilePathPrepare(String filePathPrepare) {
+        this.filePathPrepare = filePathPrepare;
+    }
+
+    public String getFilePathProcess() {
+        return jarF.getParentFile().getAbsolutePath() + File.separator + filePathProcess;
+    }
+
+    public void setFilePathProcess(String filePathProcess) {
+        this.filePathProcess = filePathProcess;
+    }
+
+    public String getFilePathFitting() {
+        return jarF.getParentFile().getAbsolutePath() + File.separator + filePathFitting;
+    }
+
+    public void setFilePathFitting(String filePathFitting) {
+        this.filePathFitting = filePathFitting;
+    }
+
+    public String getFilePathDownload() {
+        return jarF.getParentFile().getAbsolutePath() + File.separator + filePathDownload;
+    }
+
+    public void setFilePathDownload(String filePathDownload) {
+        this.filePathDownload = filePathDownload;
+    }
+
+
+    private List<String> getUniformCodes(){
+        List<FixedVo> fxList = AnnotationTool.getFixedVoList(PowerPointData.class);
+        List<String> codes = fxList.stream().filter(f -> !StringUtils.isEmpty(f.getUniformCode()))
+                .map(d -> d.getUniformCode()).collect(Collectors.toList());
+
+        return codes;
+    }
+}

+ 50 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/ThreadPoolConfig.java

@@ -0,0 +1,50 @@
+package com.gyee.power.fitting.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ThreadPoolExecutor;
+
+
+@Configuration
+public class ThreadPoolConfig {
+    /**
+     *   默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,
+     *	当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
+     *  当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝
+     */
+
+    /** 核心线程数(默认线程数) */
+    private static final int corePoolSize = 10;
+    /** 最大线程数 */
+    private static final int maxPoolSize = 20;
+    /** 允许线程空闲时间(单位:默认为秒) */
+    private static final int keepAliveTime = 60;
+    /** 缓冲队列大小 */
+    private static final int queueCapacity = 100;
+    /** 允许等待最长时间 */
+    private static final int awaitTime = 15;
+    /** 线程池名前缀 */
+    private static final String threadNamePrefix = "GYEE-Thread-";
+
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor(){
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(corePoolSize);
+        executor.setMaxPoolSize(maxPoolSize);
+        executor.setQueueCapacity(queueCapacity);
+        executor.setKeepAliveSeconds(keepAliveTime);
+        executor.setThreadNamePrefix(threadNamePrefix);
+        executor.setAwaitTerminationSeconds(awaitTime);
+
+        // 线程池对拒绝任务的处理策略
+        // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 初始化
+        executor.initialize();
+        return executor;
+    }
+
+}

+ 20 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/WebSocketConfig.java

@@ -0,0 +1,20 @@
+package com.gyee.power.fitting.common.config;
+
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * 开启 WebSocket 支持
+ **/
+@Configuration
+public class WebSocketConfig {
+
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        System.out.println("开启websocket支持。。。。。");
+        return new ServerEndpointExporter();
+    }
+
+}

+ 29 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/constants/Constants.java

@@ -0,0 +1,29 @@
+package com.gyee.power.fitting.common.constants;
+
+import com.gyee.power.fitting.model.anno.Desc;
+
+public class Constants {
+
+    // 数据准备  标记
+    public static final String DATA_PREPARE = "prepare";
+
+    // 数据处理完  标记
+    public static final String DATA_PROCESS = "process";
+
+    // 数据处理完  标记
+    public static final String DATA_FITTING = "fitting";
+
+    //功率
+    public static final String CODE_POINT_POWER = "AI130";
+
+    //风速
+    public static final String CODE_POINT_SPEED = "AI022";
+
+    //明细状态
+    // 0-待机  1-手动停机  2-正常发电  3-缺陷降出力  4-限电降出力  5-限电停机  6-故障停机
+    // 7-场内受累停机  8-检修停机  9-场内受累检修  10-电网受累  11-环境受累  12-风机离线
+    public static final String CODE_POINT_MXZT = "ZTMX";
+
+    //电量
+    public static final String CODE_POINT_RFDL = "RFDL";
+}

+ 58 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/exception/AdviceException.java

@@ -0,0 +1,58 @@
+package com.gyee.power.fitting.common.exception;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@Slf4j
+@RestControllerAdvice
+public class AdviceException {
+
+    /**
+     * 拦截未知的运行时异常
+     */
+    @ExceptionHandler(Exception.class)
+    public JSONObject runException(Exception e)
+    {
+        log.error(e.getMessage());
+        return JsonResult.error(ResultCode.ERROR);
+    }
+
+
+    /**
+     * 拦截未知的运行时异常
+     */
+    @ExceptionHandler(NullPointerException.class)
+    public JSONObject nullPointerException(NullPointerException e)
+    {
+        log.error(e.getMessage());
+        return JsonResult.error(ResultCode.ERROR);
+    }
+
+
+    /**
+     * 拦截自定义异常
+     */
+    @ExceptionHandler(RuntimeException.class)
+    public JSONObject runException(RuntimeException e)
+    {
+        log.error(e.getMessage());
+        return JsonResult.error(ResultCode.ERROR);
+    }
+
+
+
+    /**
+     * 拦截自定义异常
+     */
+    @ExceptionHandler(CustomException.class)
+    public JSONObject customException(CustomException e)
+    {
+        log.error(e.getMessage());
+        return JsonResult.error(e.getCode(), e.getMessage());
+    }
+
+}

+ 23 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/exception/CustomException.java

@@ -0,0 +1,23 @@
+package com.gyee.power.fitting.common.exception;
+
+import com.gyee.power.fitting.common.result.ResultCode;
+import lombok.Data;
+
+@Data
+public class CustomException extends RuntimeException {
+
+    private Integer code;
+    private String message;
+
+    public CustomException(){}
+
+    public CustomException(ResultCode result){
+        super();
+        this.code = result.getCode();
+        this.message = result.getMessage();
+    }
+
+    public CustomException(Exception e){
+        super();
+    }
+}

+ 32 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/FeignsBuilder.java

@@ -0,0 +1,32 @@
+package com.gyee.power.fitting.common.feign;
+
+import feign.Feign;
+import feign.Request;
+import feign.Retryer;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author xysn
+ */
+@Configuration
+public class FeignsBuilder {
+    /**
+     * 数据适配器url
+     */
+    @Value("${gyee.adapter-url:http://192.168.101.8:8011}")
+    private String adapterUrl;
+
+    @Bean
+    public IDataAdapter dataAdapter() {
+        return Feign.builder()
+                .encoder(new JacksonEncoder())
+                .decoder(new JacksonDecoder())
+                .options(new Request.Options(1000, 100000))
+                .retryer(new Retryer.Default(5000, 5000, 3))
+                .target(IDataAdapter.class, adapterUrl);
+    }
+}

+ 38 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/IAdapterService.java

@@ -0,0 +1,38 @@
+package com.gyee.power.fitting.common.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.model.custom.TsDoubleData;
+import feign.Headers;
+import feign.Param;
+import feign.RequestLine;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import java.util.List;
+
+
+public interface IAdapterService {
+
+
+    @Headers({"Content-Type: application/json", "Accept: application/json"})
+    @RequestLine("GET /ts/latest?keys={points}")
+    JSONObject getLatest(@Param(value = "points") String points);
+
+    @Headers({"Content-Type: application/json", "Accept: application/json"})
+    @RequestLine("GET /ts/history/snap?tagName={tagName}&startTs={startTs}&endTs={endTs}&interval={interval}")
+    List<TsDoubleData> getHistorySnap(@Param(value = "tagName") String tagName, @Param(value = "startTs") long startTs,
+                                        @Param(value = "endTs") long endTs, @Param(value = "interval") Integer interval);
+    
+    @Headers({"Content-Type: application/json", "Accept: application/json"})
+    @RequestLine("GET /ts/history/snap?tagName={tagName}&startTs={startTs}&endTs={endTs}&interval={interval}")
+    List<TsDoubleData> getValuesByKey(@Param(value = "tagName") String tagName, @Param(value = "startTs") long startTs,
+                                   @Param(value = "endTs") long endTs, @Param(value = "interval") int interval);
+    
+    @Headers({"Content-Type: application/json", "Accept: application/json"})
+    @RequestLine("GET /ts/history/raw?tagName={tagName}&startTs={startTs}&endTs={endTs}")
+    List<TsDoubleData> getRawValuesByKey(@Param(value = "tagName") String tagName, @Param(value = "startTs") long startTs,
+                                      @Param(value = "endTs") long endTs);
+
+    @Headers({"Content-Type: application/json", "Accept: application/json"})
+    @RequestLine("GET /ts/history/section?tagNames={tagNames}&ts={ts}")
+    JSONObject getHistorySection(@Param(value = "tagNames") String tagNames, @Param(value = "ts") long ts);
+}

+ 26 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/IDataAdapter.java

@@ -0,0 +1,26 @@
+package com.gyee.power.fitting.common.feign;
+
+import com.gyee.power.fitting.model.agc.PointData;
+import feign.Param;
+import feign.RequestLine;
+
+import java.util.List;
+
+/**
+ * DataAdapter数据请求
+ */
+public interface IDataAdapter {
+    /**
+     * 获取等间隔历史数据
+     *
+     * @param tagName  测点名称
+     * @param startTs  开始时间
+     * @param endTs    结束时间
+     * @param interval 数据间隔
+     * @return 历史数据
+     */
+    @RequestLine("GET /ts/history/snap?tagName={tagName}&startTs={startTs}&endTs={endTs}&interval={interval}")
+    List<PointData> getSnapValuesByKey(@Param(value = "tagName") String tagName, @Param(value = "startTs") long startTs,
+                                       @Param(value = "endTs") long endTs, @Param(value = "interval") int interval);
+}
+

+ 31 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/RemoteServiceBuilder.java

@@ -0,0 +1,31 @@
+package com.gyee.power.fitting.common.feign;
+
+import com.gyee.power.fitting.common.config.GyeeConfig;
+import feign.Feign;
+import feign.Request;
+import feign.Retryer;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+
+@Slf4j
+@Component
+public class RemoteServiceBuilder {
+
+    @Autowired
+    private GyeeConfig config;
+
+    @Bean
+    public IAdapterService adapter() {
+        return Feign.builder()
+                .encoder(new JacksonEncoder())
+                .decoder(new JacksonDecoder())
+                .options(new Request.Options(5000, 600000))
+                .retryer(new Retryer.Default(10000, 10000, 3))
+                .target(IAdapterService.class, config.getAdapterUrl());
+    }
+}

+ 67 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/result/JsonResult.java

@@ -0,0 +1,67 @@
+package com.gyee.power.fitting.common.result;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+@Data
+public class JsonResult extends HashMap<String, Object> implements Serializable {
+
+    private Integer code;
+    private String message;
+    private Object data;
+    private ResultCode resultCode;
+
+    public static JSONObject error(){
+        JSONObject json = new JSONObject();
+        json.put("code", ResultCode.SUCCESS.getCode());
+        json.put("msg", ResultCode.SUCCESS.getMessage());
+        return json;
+    }
+
+    public static JSONObject error(ResultCode resultCode){
+        JSONObject json = new JSONObject();
+        json.put("code", resultCode.getCode());
+        json.put("msg", resultCode.getMessage());
+        return json;
+    }
+
+    public static JSONObject error(int code, String message){
+        JSONObject json = new JSONObject();
+        json.put("code", code);
+        json.put("msg", message);
+        return json;
+    }
+
+    public static JSONObject success(){
+        JSONObject json = new JSONObject();
+        json.put("code", ResultCode.SUCCESS.getCode());
+        json.put("msg", ResultCode.SUCCESS.getMessage());
+        return json;
+    }
+
+    public static JSONObject seccess(int code, String message){
+        JSONObject json = new JSONObject();
+        json.put("code", code);
+        json.put("msg", message);
+        return json;
+    }
+
+    public static JSONObject success(ResultCode resultCode){
+        JSONObject json = new JSONObject();
+        json.put("code", resultCode.getCode());
+        json.put("msg", resultCode.getMessage());
+        return json;
+    }
+
+    public static JSONObject successData(ResultCode code, Object data){
+        JSONObject json = new JSONObject();
+        json.put("code", code.getCode());
+        json.put("msg", code.getMessage());
+        json.put("data", data != null ? data : null);
+        return json;
+    }
+
+}

+ 89 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/result/ResultCode.java

@@ -0,0 +1,89 @@
+package com.gyee.power.fitting.common.result;
+
+/*
+ * #1001~1999 区间表示参数错误
+ * #2001~2999 区间表示用户错误
+ * #3001~3999 区间表示权限异常
+ */
+
+public enum ResultCode {
+    /* 成功 */
+    SUCCESS(200, "成功"),
+    SUCCESS_DATA_PREPARE(200, "数据已提交,稍后查看"),
+
+    /* 默认失败 */
+    ERROR(4000, "失败"),
+    ERROR_FILE_NO(4001, "文件未找到"),
+    ERROR_FILE_TYPE(4002, "文件类型不正确"),
+    ERROR_FILE_DATA(4003, "数据为空"),
+    ERROR_DATA_TYPE(4004, "数据格式不正确"),
+    ERROR_CONNECT(4005, "数据库连接异常"),
+    ERROR_DATA(4006, "数据库操作失败"),
+    ERROR_DATA_REPEAT(4007, "数据已存在"),
+    ERROR_SQL(4008, "sql语法不正确"),
+    ERROR_MODEL(4009, "自算功率数据为空"),
+
+
+    /* 参数错误:1000~1999 */
+    PARAM_NOT_VALID(1001, "参数无效"),
+    PARAM_IS_BLANK(1002, "参数为空"),
+    PARAM_TYPE_ERROR(1003, "参数类型错误"),
+    PARAM_NOT_COMPLETE(1004, "参数缺失"),
+    ERROR_DATA_DIR(1005, "目录创建失败"),
+    ERROR_DATA_FILE(1006, "文件上传失败"),
+
+    /* 用户错误 */
+    USER_NOT_LOGIN(2001, "用户未登录"),
+    USER_ACCOUNT_ERROR(2002, "账号或密码错误"),
+    USER_FAIL_LOGIN(2003, "登录失败"),
+    USER_OUT_LOGIN(2004, "登出成功"),
+    USER_ERROR_TOKEN(2005, "登录已过期,请重新登录"),
+
+    /* 业务错误 */
+    NO_PERMISSION(3001, "没有权限"),
+    ERROR_ENABLE(3002, "模型为启用状态,不允许删除"),
+    ERROR_TASK(3003, "有正在进行的任务,请稍后在试");
+
+    private Integer code;
+    private String message;
+
+    ResultCode(Integer code) {
+        this.code = code;
+    }
+
+    ResultCode(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    /**
+     * 根据code获取message
+     *
+     * @param code
+     * @return
+     */
+    public static String getMessageByCode(Integer code) {
+        for (ResultCode ele : values()) {
+            if (ele.getCode().equals(code)) {
+                return ele.getMessage();
+            }
+        }
+        return null;
+    }
+}

+ 19 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/spring/ExitDisposable.java

@@ -0,0 +1,19 @@
+package com.gyee.power.fitting.common.spring;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.boot.ExitCodeGenerator;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ExitDisposable implements DisposableBean, ExitCodeGenerator {
+
+
+    @Override
+    public void destroy() throws Exception {
+    }
+
+    @Override
+    public int getExitCode() {
+        return 0;
+    }
+}

+ 235 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/spring/InitialRunner.java

@@ -0,0 +1,235 @@
+package com.gyee.power.fitting.common.spring;
+
+import com.gyee.power.fitting.common.config.GyeeConfig;
+import com.gyee.power.fitting.model.*;
+import com.gyee.power.fitting.service.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 服务启动前执行,进行全局变量初始化
+ */
+@Slf4j
+@Component
+@Order(1)
+public class InitialRunner implements CommandLineRunner {
+
+    @Resource
+    GyeeConfig config;
+    @Resource
+    private WindturbineService windturbineService;
+    @Resource
+    private WindpowerstationService windpowerstationService;
+    @Resource
+    private Windturbinetestingpointai2Service pointService;
+    @Resource
+    private EquipmentmodelService equipmentmodelService;
+    @Resource
+    private ModelpowerdetailsService modelpowerdetailsService;
+    @Resource
+    private ProjectService projectService;
+    @Resource
+    private LineService lineService;
+    @Resource
+    private PowermodelService powermodelService;
+
+
+    /**
+     * 场站所有信息
+     **/
+    public static List<Windpowerstation> wpList = new ArrayList<>();
+    /**
+     * <MHS_FDC, 麻黄山风电场>
+     **/
+    public static Map<String, String> stationMap = new HashMap<>();
+
+    /**
+     * 所有的风机
+     **/
+    public static List<Windturbine> wtList = new ArrayList<>();
+    /**
+     * key:wtId NG01_01
+     **/
+    public static Map<String, Windturbine> wtMap = new HashMap<>();
+
+    /**场站的风机  key:NSS_FDC**/
+    public static Map<String, List<Windturbine>> wpMap = new HashMap<>();
+
+    /**
+     * 光伏
+     */
+    public static List<Windpowerstation> gfwpList = new ArrayList<>();
+    public static Map<String, String> gfstationMap = new HashMap<>();
+    public static List<Windturbine> gfwtList = new ArrayList<>();
+    public static Map<String, Windturbine> gfwtMap = new HashMap<>();
+    public static Map<String, List<Windturbine>> gfwpMap = new HashMap<>();
+    /**
+     * 光照强度-场站
+     */
+    public static Map<String, Windpowerstationtestingpoint2> zfsMap = new HashMap<>();
+    /**
+     * 组件温度-场站
+     */
+    public static Map<String, Windpowerstationtestingpoint2> zjwdMap = new HashMap<>();
+    /**
+     * 功率-场站
+     */
+    public static Map<String, List<Windturbinetestingpointai2>> zglMap = new HashMap<>();
+    /**
+     * 期次
+     **/
+    public static List<Project> projectList = new ArrayList<>();
+    /**
+     * 线路
+     **/
+    public static List<Line> lineList = new ArrayList<>();
+    public static Map<String, Project> projectMap = new HashMap<>();
+    /**
+     * 所有设备型号
+     **/
+    public static List<Equipmentmodel> equipmentList = new ArrayList<>();
+    public static Map<String, Line> lineMap = new HashMap<>();
+
+    /**
+     * key: NG01_01
+     **/
+    public static Map<String, List<Windturbinetestingpointai2>> pointMap = new HashMap<>();
+    @Resource
+    private IWindpowerstationtestingpoint2Service windpowerstationtestingpoint2Service;
+    public static Map<String, Equipmentmodel> equipmentMap = new HashMap<>();
+    /**
+     * key: model  UP82
+     **/
+    public static Map<String, List<Modelpowerdetails>> modelPowerDetailMap = new HashMap<>();
+    /** key: NG01_01, speed, power**/
+    public static Map<String, Map<Double, Double>> zsllglMap = new HashMap<>();
+
+    @Override
+    public void run(String... args) {
+        System.out.println(">>>>>>>>>>>>>>>服务启动,正在缓存数据<<<<<<<<<<<<<<");
+
+        cacheStation();
+        cachePoints();
+        cacheEquipment();
+        cacheProject();
+        cacheLine();
+        cachePhotovoltaicInfo();
+
+        // 耗时缓存
+        new Thread(){
+            @Override
+            public void run() {
+                super.run();
+                cacheModelPower();
+                cacheZSLLGL(null);
+            }
+        }.start();
+
+        System.out.println(">>>>>>>>>>>>>>>数据缓存完成<<<<<<<<<<<<<<");
+    }
+
+    private void cachePhotovoltaicInfo() {
+        List<Windpowerstationtestingpoint2> zfsPoints = windpowerstationtestingpoint2Service.getPoints("GDC", "SSFS");
+        List<Windpowerstationtestingpoint2> zjwdPoints = windpowerstationtestingpoint2Service.getPoints("GDC", "FCCFTWD");
+        zfsMap = zfsPoints.stream().collect(Collectors.toMap(Windpowerstationtestingpoint2::getWindpowerstationid, Function.identity()));
+        zjwdMap = zjwdPoints.stream().collect(Collectors.toMap(Windpowerstationtestingpoint2::getWindpowerstationid, Function.identity()));
+        List<Windturbinetestingpointai2> zglPoints = pointService.getPoints("GDC", null, "AI130");
+        zglMap = zglPoints.stream().collect(Collectors.groupingBy(Windturbinetestingpointai2::getWindpowerstationid));
+    }
+
+    /**
+     * 缓存场站、风机数据
+     * 数据新增或删除后需要更新,故每次清空
+     */
+    public void cacheStation() {
+        List<Windpowerstation> stations = windpowerstationService.selectList();
+        wpList = stations.stream().filter(f -> f.getId().contains("FDC")).collect(Collectors.toList());
+        gfwpList = stations.stream().filter(f -> f.getId().contains("GDC")).collect(Collectors.toList());
+        wpList.forEach(obj -> {
+            List<Windturbine> wts = windturbineService.selectList(obj.getId());
+            stationMap.put(obj.getId(), obj.getName());
+            wpMap.put(obj.getId(), wts);
+            wtList.addAll(wts);
+
+            wts.forEach(u -> wtMap.put(u.getId(), u));
+        });
+        gfwpList.stream().forEach(obj -> {
+            List<Windturbine> wts = windturbineService.selectList(obj.getId());
+            gfstationMap.put(obj.getId(), obj.getName());
+            gfwpMap.put(obj.getId(), wts);
+            gfwtList.addAll(wts);
+
+            wts.stream().forEach(u -> gfwtMap.put(u.getId(), u));
+        });
+        log.info("场站数据缓存完成");
+    }
+
+    /**
+     * 缓存测点数据
+     */
+    private void cachePoints() {
+        List<Windturbinetestingpointai2> list = new ArrayList<>();
+        wpList.stream().forEach(d -> list.addAll(pointService.selectList(d.getId(), config.getPoints())));
+        pointMap.putAll(list.stream().collect(Collectors.groupingBy(u -> u.getWindturbineid())));
+        log.info("cachePoints: " + pointMap.size());
+        if (pointMap.size() == 0)
+            log.error("cachePoints", "测点数据缓存失败");
+    }
+
+    /**
+     * 缓存设备型号
+     */
+    private void cacheEquipment() {
+        equipmentList.addAll(equipmentmodelService.selectList());
+        for (Equipmentmodel eq : equipmentList)
+            equipmentMap.put(eq.getId(), eq);
+        log.info("设备型号数据缓存完成");
+    }
+
+    private void cacheModelPower() {
+        List<Modelpowerdetails> lsMPD = modelpowerdetailsService.selectList();
+        modelPowerDetailMap.putAll(lsMPD.stream().collect(Collectors.groupingBy(u -> u.getModelid())));
+        log.info("保证功率数据缓存完成");
+    }
+
+    private void cacheProject(){
+        projectList.addAll(projectService.selectList());
+        projectList.forEach(f -> projectMap.put(f.getId(), f));
+        log.info("期次数据缓存完成");
+    }
+
+    private void cacheLine(){
+        lineList.addAll(lineService.selectList());
+        lineList.forEach(f -> lineMap.put(f.getId(), f));
+        log.info("线路数据缓存完成");
+    }
+
+    /**
+     * 自算理论功率
+     */
+    public void cacheZSLLGL(String wtId){
+        if (StringUtils.isEmpty(wtId)){
+            zsllglMap = powermodelService.selectList().stream()
+                    .collect(Collectors.groupingBy(Powermodel::getWindturbineid,
+                            Collectors.toMap(Powermodel::getSpeed, Powermodel::getPower)));
+        }else{
+            List<Powermodel> list = powermodelService.selectByWtId(wtId);
+            Map<Double, Double> collect = list.stream().collect(Collectors.toMap(Powermodel::getSpeed, Powermodel::getPower));
+            zsllglMap.replace(wtId, collect);
+        }
+        log.info("自算功率数据缓存完成");
+    }
+
+}

+ 110 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/spring/SpringContextUtil.java

@@ -0,0 +1,110 @@
+package com.gyee.power.fitting.common.spring;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SpringContextUtil implements ApplicationContextAware, DisposableBean {
+
+    private static ApplicationContext applicationContext = null;
+
+    /***
+     * 当继承了ApplicationContextAware类之后,那么程序在调用 getBean(String)的时候会自动调用该方法, 不用自己操作
+     */
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextUtil.applicationContext = applicationContext;
+    }
+
+    /**
+     * 实现DisposableBean接口, 在Context关闭时清理静态变量.
+     */
+    @Override
+    public void destroy() throws Exception {
+        SpringContextUtil.clearHolder();
+    }
+
+    /**
+     * 取得存储在静态变量中的ApplicationContext.
+     */
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    /***
+     * 根据一个bean的id获取配置文件中相应的bean
+     *
+     * @param name
+     * @return
+     * @throws BeansException
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getBean(String name) throws BeansException {
+        return (T) applicationContext.getBean(name);
+    }
+
+    /***
+     * 类似于getBean(String name)只是在参数中提供了需要返回到的类型。
+     *
+     * @param name
+     * @param requiredType
+     * @return
+     * @throws BeansException
+     */
+    public static <T> T getBean(Class<T> requiredType) throws BeansException {
+        return applicationContext.getBean(requiredType);
+    }
+
+    /**
+     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
+     *
+     * @param name
+     * @return boolean
+     */
+    public static boolean containsBean(String name) {
+        return applicationContext.containsBean(name);
+    }
+
+    /**
+     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
+     * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
+     *
+     * @param name
+     * @return boolean
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+        return applicationContext.isSingleton(name);
+    }
+
+    /**
+     * @param name
+     * @return Class 注册对象的类型
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
+        return applicationContext.getType(name);
+    }
+
+    /**
+     * 如果给定的bean名字在bean定义中有别名,则返回这些别名
+     *
+     * @param name
+     * @return
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+        return applicationContext.getAliases(name);
+    }
+
+    /**
+     * 清除SpringContextHolder中的ApplicationContext为Null.
+     */
+    public static void clearHolder() {
+        applicationContext = null;
+    }
+}

+ 124 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/Base64Util.java

@@ -0,0 +1,124 @@
+package com.gyee.power.fitting.common.util;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Base64;
+
+public class Base64Util {
+
+    public static final String UTF_8 = "UTF-8";
+    public static Base64.Encoder encoder;
+    //即为安全的编码方式,替换“+” “/” “-”为“_”
+    public static Base64.Encoder urlEncoder;
+    public static Base64.Decoder decoder;
+    public static Base64.Decoder urlDecoder;
+
+    static {
+        encoder = Base64.getEncoder();
+        urlEncoder = Base64.getUrlEncoder();
+        decoder = Base64.getDecoder();
+        urlDecoder = Base64.getUrlDecoder();
+    }
+
+    //encode
+    public static byte[] encode(byte[] bytes) {
+        return encoder.encode(bytes);
+    }
+
+
+    public static String encode(String string) {
+        byte[] encode = encode(string.getBytes());
+        try {
+            return new String(encode, UTF_8);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static String encode2String(byte[] bytes) {
+        return encoder.encodeToString(bytes);
+    }
+
+    public static byte[] encode2Byte(String string) {
+        return encode(string.getBytes());
+    }
+
+    //urlEncoder
+    public static byte[] urlEncode(byte[] bytes) {
+        return urlEncoder.encode(bytes);
+    }
+
+    public static String urlEncode(String string) {
+        byte[] encode = urlEncode(string.getBytes());
+        try {
+            return new String(encode, UTF_8);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static String urlEncode2String(byte[] bytes) {
+        return urlEncoder.encodeToString(bytes);
+    }
+
+    public static byte[] urlEncode2Byte(String string) {
+        return urlEncode(string.getBytes());
+    }
+
+    //decode
+    public static byte[] decode(byte[] bytes) {
+        return decoder.decode(bytes);
+    }
+
+    public static byte[] decode2Byte(String string) {
+        return decoder.decode(string.getBytes());
+    }
+
+    public static String decode2String(byte[] bytes) {
+        try {
+            return new String(decoder.decode(bytes),UTF_8);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static String decode(String string) {
+        byte[] decode = decode(string.getBytes());
+        try {
+            return new String(decode, UTF_8);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    //urlDecode
+    public static byte[] urlDecode(byte[] bytes) {
+        return urlDecoder.decode(bytes);
+    }
+
+    public static byte[] urlDecode2Byte(String string) {
+        return urlDecode(string.getBytes());
+    }
+
+    public static String urlDecode2String(byte[] bytes) {
+        try {
+            return new String(urlDecode(bytes),UTF_8);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static String urlDecode(String string) {
+        byte[] decode = urlDecode(string.getBytes());
+        try {
+            return new String(decode, UTF_8);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 37 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/CollectUtil.java

@@ -0,0 +1,37 @@
+package com.gyee.power.fitting.common.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class CollectUtil {
+
+    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
+        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
+        return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null;
+    }
+
+    /**
+     * 通过数量分组
+     * @param list
+     * @param qty
+     * @return
+     * @param <T>
+     */
+    public static <T> List<List<T>> groupListByQty(List<T> list, int qty) {
+        if (list == null || list.size() == 0 || qty <= 0) {
+            return Collections.EMPTY_LIST;
+        }
+        List<List<T>> result = new ArrayList<>();
+        int count = 0;
+        while (count < list.size()) {
+            result.add(new ArrayList<>(list.subList(count, Math.min((count + qty), list.size()))));
+            count += qty;
+        }
+        return result;
+    }
+}

+ 625 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/DateUtil.java

@@ -0,0 +1,625 @@
+package com.gyee.power.fitting.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.commons.lang3.time.DateUtils;
+
+import java.lang.management.ManagementFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+@Slf4j
+public class DateUtil extends DateUtils {
+
+    /**
+     * 获取当前时间
+     *
+     * @return
+     */
+    public static String getCurrentDate() {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+        String date = df.format(new Date());
+        return date;
+    }
+
+    /**
+     * 获取前 N 小时的时间
+     *
+     * @param hour
+     * @return
+     */
+    public static String getPreviousDate(int hour) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - hour);
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String date = df.format(calendar.getTime());
+        return date;
+    }
+
+    /**
+     * 获取当前时间后 N 小时的时间
+     *
+     * @param hour
+     * @return
+     */
+    public static String getNextDate(int hour) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + hour);
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String date = df.format(calendar.getTime());
+        return date;
+    }
+
+    /**
+     * 获取当前时间后 N 小时的时间
+     *
+     * @param hour
+     * @return
+     */
+    public static Long getNextDateTimestamp(int hour) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + hour);
+        long time = calendar.getTime().getTime();
+        return time;
+    }
+
+
+    /**
+     * 字符串时间转时间戳
+     * @param time
+     * @return
+     */
+    public static Long covertDateTimestamp(String time){
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        long stamp = 0;
+        try {
+            stamp = sdf.parse(time).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+
+        return stamp;
+    }
+
+    /**
+     * 时间格式(yyyy-MM-dd)
+     */
+    public final static String DATE_PATTERN = "yyyy-MM-dd";
+    /**
+     * 时间格式(yyyy-MM-dd HH:mm:ss)
+     */
+    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
+
+    public static String format(Date date) {
+        return format(date, DATE_PATTERN);
+    }
+
+    public static String formatDateTime(Date date) {
+        return format(date, DATE_TIME_PATTERN);
+    }
+    /**
+     * 时间转换
+     *
+     * @param date
+     * @param pattern
+     * @return
+     */
+    public static String format(Date date, String pattern) {
+        if (date != null) {
+            SimpleDateFormat df = new SimpleDateFormat(pattern);
+            return df.format(date);
+        }
+        return null;
+    }
+
+    /**
+     * 字符串格式化
+     * @param time
+     * @param pattern
+     * @return
+     */
+    public static String format(String time,String pattern) {
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        Date dateTime = null;
+        try {
+            dateTime = sdf.parse(time);
+        } catch (ParseException e) {
+            e.printStackTrace();
+
+        }
+        return format(dateTime, pattern);
+    }
+
+    /**
+     * 时间转换
+     *
+     * @param time
+     * @param pattern
+     * @return
+     */
+    public static String format(Long time, String pattern) {
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        Date date = new Date(time);
+        String format = sdf.format(date);
+        return format;
+    }
+
+
+    public static String YYYY = "yyyy";
+
+    public static String YYYY_MM = "yyyy-MM";
+
+    public static String YYYY_MM_DD_CHN = "yyyy年MM月dd日";
+
+    public static String YYYY_MM_DD = "yyyy-MM-dd";
+
+    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+
+    private static String[] parsePatterns = {
+            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
+            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+    /**
+     * 获取当前Date型日期
+     *
+     * @return Date() 当前日期
+     */
+    public static Date getNowDate() {
+        return new Date();
+    }
+
+    /**
+     * 获取当前日期, 默认格式为yyyy-MM-dd
+     *
+     * @return String
+     */
+    public static String getDate() {
+        return dateTimeNow(YYYY_MM_DD);
+    }
+
+    public static final String getTimeDiff() {
+        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
+    }
+
+    public static final String dateTimeNow() {
+        return dateTimeNow(YYYYMMDDHHMMSS);
+    }
+
+    public static final String dateTimeNow(final String format) {
+        return parseDateToStr(format, new Date());
+    }
+
+    public static final String dateTime(final Date date) {
+        return parseDateToStr(YYYY_MM_DD, date);
+    }
+
+    public static final String parseDateToStr(final String format, final Date date) {
+        return new SimpleDateFormat(format).format(date);
+    }
+
+    public static final Date dateTime(final String format, final String ts) {
+        try {
+            return new SimpleDateFormat(format).parse(ts);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 获取0点0分0秒值
+     * @param date
+     * @return
+     */
+    public static final Date dateZeroFormat(Date date){
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH),
+                0, 0, 0);
+        Date time = cal.getTime();
+        return time;
+    }
+
+    /**
+     * 日期路径 即年/月/日 如2018/08/08
+     */
+    public static final String datePath() {
+        Date now = new Date();
+        return DateFormatUtils.format(now, "yyyy/MM/dd");
+    }
+
+    /**
+     * 日期路径 即年/月/日 如20180808
+     */
+    public static final String dateTime() {
+        Date now = new Date();
+        return DateFormatUtils.format(now, "yyyyMMdd");
+    }
+
+    /**
+     * 日期型字符串转化为日期 格式
+     */
+    public static Date parseDate(Object str) {
+        if (str == null) {
+            return null;
+        }
+        try {
+            return parseDate(str.toString(), parsePatterns);
+        } catch (ParseException e) {
+            return null;
+        }
+    }
+
+    /**
+     * 获取服务器启动时间
+     */
+    public static Date getServerStartDate() {
+        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+        return new Date(time);
+    }
+
+    /**
+     * 计算两个时间差
+     */
+    public static String getDatePoor(Date endDate, Date nowDate) {
+        long nd = 1000 * 24 * 60 * 60;
+        long nh = 1000 * 60 * 60;
+        long nm = 1000 * 60;
+        // long ns = 1000;
+        // 获得两个时间的毫秒时间差异
+        long diff = endDate.getTime() - nowDate.getTime();
+        // 计算差多少天
+        long day = diff / nd;
+        // 计算差多少小时
+        long hour = diff % nd / nh;
+        // 计算差多少分钟
+        long min = diff % nd % nh / nm;
+        // 计算差多少秒//输出结果
+        // long sec = diff % nd % nh % nm / ns;
+        return day + "天" + hour + "小时" + min + "分钟";
+    }
+
+    /**
+     * 将时间的时分秒毫秒字段去掉
+     *
+     * @param date
+     * @return
+     */
+    public static Date truncate(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        return cal.getTime();
+    }
+
+    /**
+     * 计算两个时间之间差的天数(取整后)
+     *
+     * @param d1
+     * @param d2
+     * @return
+     */
+    public static int daysDiff(Date d1, Date d2) {
+        return (int) Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (60 * 60 * 24 * 1000));
+    }
+
+    /**
+     * 将字符串日期转换成日期类型
+     *
+     * @param time
+     * @return
+     */
+    public static Date parseStrtoDate(String time) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date dateTime = null;
+        try {
+            dateTime = sdf.parse(time);
+        } catch (ParseException e) {
+            e.printStackTrace();
+
+        }
+        return dateTime;
+    }
+
+    public static Date parseStrtoDate(String time,String pattern) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        Date dateTime = null;
+        try {
+            dateTime = sdf.parse(time);
+        } catch (ParseException e) {
+            e.printStackTrace();
+
+        }
+        return dateTime;
+    }
+
+    public static Date str2DateTime(String time,String pattern) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        Date dateTime = null;
+        try {
+            dateTime = sdf.parse(time);
+        } catch (ParseException e) {
+            e.printStackTrace();
+
+        }
+        return dateTime;
+    }
+    public static Date str2DateTime(String time) {
+        return str2DateTime(time,DATE_TIME_PATTERN);
+    }
+
+    /**
+     * 加减年份
+     */
+    public static Date dateTimeAddYear(Date date,int k) {
+        Calendar instance = Calendar.getInstance();
+        instance.setTime(date);
+        instance.add(Calendar.YEAR,k);
+        return instance.getTime();
+    }
+
+    public static String datetime2Str(Date time,String pattern) {
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        return sdf.format(time);
+    }
+    public static String datetime2Str(Date time) {
+        return datetime2Str(time,DATE_TIME_PATTERN);
+    }
+
+    public static double hoursDiff1(Date d1, Date d2) {
+        return Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (double) (60 * 60 * 1000));
+    }
+
+    public static double hoursDiff2(Date d1, Date d2) {
+        return Math.abs((d1.getTime() - d2.getTime())) / (double) (60 * 60 * 1000);
+    }
+
+    /**
+     * 计算两个时间之间差的分钟数(取整后)
+     *
+     * @param d1
+     * @param d2
+     * @return
+     */
+    public static int minutesDiff(Date d1, Date d2) {
+        return (int) Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (60 * 1000));
+    }
+
+    /**
+     * 计算两个时间之间差的分钟数(取整后)
+     *
+     * @param d1
+     * @param d2
+     * @return
+     */
+    public static double minutesDiff2(Date d1, Date d2) {
+        return Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (60 * 1000));
+    }
+
+    /**
+     * 获取系统时间
+     *
+     * @return
+     */
+    public static Date now() {
+        return new Date();
+    }
+
+    /**
+     * 获取当前月的第一天
+     *
+     * @return
+     */
+    public static String getCurrtenFirstDay() {
+
+        Calendar c = Calendar.getInstance();
+        // c.add(Calendar.MONTH, 0);
+        c.set(Calendar.DAY_OF_MONTH, 1);
+        return new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
+    }
+
+    /**
+     * 获取当前月的最后一天
+     *
+     * @return
+     */
+    public static String getCurrtenLastDay() {
+
+        Calendar ca = Calendar.getInstance();
+        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
+        return new SimpleDateFormat("yyyy-MM-dd").format(ca.getTime());
+    }
+    /**
+     * 计算两个时间之间差的小时数(取整后)
+     *
+     * @param d1
+     * @param d2
+     * @return
+     */
+    public static int hoursDiff(Date d1, Date d2) {
+        return (int) Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (60 * 60 * 1000));
+    }
+
+    /**
+     * 获取当前整点数
+     *
+     * @return
+     */
+    public static Date getCurrHourTime(Date date) {
+        Calendar ca = Calendar.getInstance();
+        int minute = ca.get(Calendar.MINUTE);
+        if (minute < 30) {
+            ca.set(Calendar.MINUTE, 30);
+        } else {
+            ca.add(Calendar.HOUR, 1);
+            ca.set(Calendar.MINUTE, 0);
+        }
+
+        ca.set(Calendar.SECOND, 5);
+        date = ca.getTime();
+
+        return date;
+    }
+
+    //普通时间转为UTC
+    public static String localToUTC(String localTimeStr) {
+        try {
+            Date localDate = getLocalSDF().parse(localTimeStr);
+            return getUTCSDF().format(localDate);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+    //UTC转为普通时间
+    public static String utcToLocal(String utcTimeStr) {
+        try {
+            Date date = getUTCSDF().parse(utcTimeStr);
+            return getLocalSDF().format(date);
+
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private static SimpleDateFormat getLocalSDF() {
+        return new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
+    }
+
+    private static SimpleDateFormat getUTCSDF() {
+        SimpleDateFormat utcSDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+        utcSDF.setTimeZone(TimeZone.getTimeZone("UTC"));
+        return utcSDF;
+    }
+
+    // 获取两个时间相差分钟数
+    public static int getTimeDiff(String oldTime, String newTime) {
+        int diff = 0;
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        long NTime = 0;
+        long OTime = 0;
+        try {
+            NTime = df.parse(newTime).getTime();
+            //从对象中拿到时间
+            OTime = df.parse(oldTime).getTime();
+            diff = (int) (Math.abs((NTime-OTime))/1000/60);
+        } catch (ParseException e) {
+        }
+
+        return diff;
+    }
+
+
+    /**
+     * 获取去年同一时间
+     * @return
+     */
+
+    public static String getLastYearCurrentDate(String date, String pattern){
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(parseStrtoDate(date, pattern));
+        cal.add(Calendar.YEAR, -1);
+        return sdf.format(cal.getTime());
+    }
+
+    /**
+     * @return 当天零点
+     */
+    public static Date today0am() {
+        Calendar day = Calendar.getInstance();
+        day.set(Calendar.HOUR_OF_DAY, 0);
+        day.set(Calendar.MINUTE, 0);
+        day.set(Calendar.SECOND, 0);
+        day.set(Calendar.MILLISECOND, 0);
+        return day.getTime();
+    }
+
+    /**
+     * 在指定时间上加指定的天数
+     *
+     * @param date
+     * @param day
+     * @return
+     */
+    public static Date addDays(Date date, int day) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.add(Calendar.DAY_OF_MONTH, day);
+        return cal.getTime();
+    }
+
+    /**
+     * 在指定的时间上加指定的月数
+     *
+     * @param date
+     * @param month
+     * @return
+     */
+    public static Date addMonths(Date date, int month) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.add(Calendar.MONTH, month);
+        return cal.getTime();
+    }
+
+    /**
+     * 在指定的时间上加指定的月数
+     *
+     * @param date
+     * @param year
+     * @return
+     */
+    public static Date addYears(Date date, int year) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.add(Calendar.YEAR, year);
+        return cal.getTime();
+    }
+
+    /**
+     * 在指定时间上加指定的小时
+     *
+     * @param date
+     * @param hour
+     * @return
+     */
+    public static Date addHours(Date date, int hour) {
+        return new Date(date.getTime() + hour * 3600 * 1000);
+    }
+
+    /**
+     * 在指定时间上加指定的分钟
+     *
+     * @param date
+     * @param m
+     * @return
+     */
+    public static Date addMinutes(Date date, int m) {
+        return new Date(date.getTime() + m * 60 * 1000);
+    }
+
+    /**
+     * 在指定时间上加指定的秒
+     *
+     * @param date
+     * @param s
+     * @return
+     */
+    public static Date addSeconds(Date date, int s) {
+        return new Date(date.getTime() + s * 1000);
+    }
+}

+ 359 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/DateUtils.java

@@ -0,0 +1,359 @@
+package com.gyee.power.fitting.common.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 日期操作工具类
+ */
+public class DateUtils {
+
+    private static final SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd");
+    private static final SimpleDateFormat sdfl = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    /**
+     * 日期转换-  String -> Date
+     *
+     * @param dateString 字符串时间
+     * @return Date类型信息
+     * @throws Exception 抛出异常
+     */
+    public static Date string2DateS(String dateString) throws Exception {
+        if (dateString == null) {
+            return null;
+        }
+        return sdfs.parse(dateString);
+    }
+
+    /**
+     * 日期转换-  String -> Date
+     *
+     * @param dateString 字符串时间
+     * @return Date类型信息
+     * @throws Exception 抛出异常
+     */
+    public static Date string2DateL(String dateString) {
+        if (dateString == null) {
+            return null;
+        }
+        Date parse = null;
+        try {
+            parse = sdfl.parse(dateString);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return parse;
+    }
+
+    /**
+     * 日期转换-  String -> Date
+     *
+     * @param dateString 字符串时间
+     * @param pattern    格式模板
+     * @return Date类型信息
+     * @throws Exception 抛出异常
+     */
+    public static Date string2Date(String dateString, String pattern) throws Exception {
+        if (dateString == null) {
+            return null;
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        Date date = sdf.parse(dateString);
+        return date;
+    }
+
+    /**
+     * 日期转换 Date -> String
+     *
+     * @param date Date类型信息
+     * @return 字符串时间
+     * @throws Exception 抛出异常
+     */
+    public static String date2StringS(Date date) {
+        if (date == null) {
+            return null;
+        }
+        return sdfs.format(date);
+    }
+
+    /**
+     * 日期转换 Date -> String
+     *
+     * @param date Date类型信息
+     * @return 字符串时间
+     * @throws Exception 抛出异常
+     */
+    public static String date2StringL(Date date) {
+        if (date == null) {
+            return null;
+        }
+        return sdfl.format(date);
+    }
+
+    /**
+     * 日期转换 Date -> String
+     *
+     * @param date    Date类型信息
+     * @param pattern 格式模板
+     * @return 字符串时间
+     * @throws Exception 抛出异常
+     */
+    public static String date2String(Date date, String pattern) {
+        if (date == null) {
+            return null;
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        String strDate = sdf.format(date);
+        return strDate;
+    }
+
+    /**
+     * 获取当前时间的0点
+     */
+    public static Calendar getZero(Calendar c) {
+        Calendar time = (Calendar) c.clone();
+        time.set(Calendar.HOUR_OF_DAY, 0);
+        time.set(Calendar.MINUTE, 0);
+        time.set(Calendar.SECOND, 0);
+        time.set(Calendar.MILLISECOND, 0);
+        return time;
+    }
+
+    /**
+     * 获取当前时间的最晚点
+     */
+    public static Calendar getNight(Calendar c) {
+        Calendar time = getZero(c);
+        time.add(Calendar.DATE, 1);
+        time.add(Calendar.MILLISECOND, -1);
+        return time;
+    }
+
+
+    /**
+     * 获取当前日期的本周一是几号
+     *
+     * @return 本周一的日期
+     */
+    public static Date getThisWeekMonday() {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        // 获得当前日期是一个星期的第几天
+        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
+        if (1 == dayWeek) {
+            cal.add(Calendar.DAY_OF_MONTH, -1);
+        }
+        // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一
+        cal.setFirstDayOfWeek(Calendar.MONDAY);
+        // 获得当前日期是一个星期的第几天
+        int day = cal.get(Calendar.DAY_OF_WEEK);
+        // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值
+        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
+        return cal.getTime();
+    }
+
+    /**
+     * 获取当前日期周的最后一天
+     *
+     * @return 当前日期周的最后一天
+     */
+    public static Date getSundayOfThisWeek() {
+        Calendar c = Calendar.getInstance();
+        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
+        if (dayOfWeek == 0) {
+            dayOfWeek = 7;
+        }
+        c.add(Calendar.DATE, -dayOfWeek + 7);
+        return c.getTime();
+    }
+
+    /**
+     * 根据日期区间获取月份列表
+     *
+     * @param minDate 开始时间
+     * @param maxDate 结束时间
+     * @return 月份列表
+     * @throws Exception
+     */
+    public static List<String> getMonthBetween(String minDate, String maxDate, String format) throws Exception {
+        ArrayList<String> result = new ArrayList<>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+
+        Calendar min = Calendar.getInstance();
+        Calendar max = Calendar.getInstance();
+
+        min.setTime(sdf.parse(minDate));
+        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
+
+        max.setTime(sdf.parse(maxDate));
+        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
+        SimpleDateFormat sdf2 = new SimpleDateFormat(format);
+
+        Calendar curr = min;
+        while (curr.before(max)) {
+            result.add(sdf2.format(curr.getTime()));
+            curr.add(Calendar.MONTH, 1);
+        }
+
+        return result;
+    }
+
+    /**
+     * 根据日期获取年度中的周索引
+     *
+     * @param date 日期
+     * @return 周索引
+     * @throws Exception
+     */
+    public static Integer getWeekOfYear(String date) throws Exception {
+        Date useDate = string2DateS(date);
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(useDate);
+        return cal.get(Calendar.WEEK_OF_YEAR);
+    }
+
+    /**
+     * 根据年份获取年中周列表
+     *
+     * @param year 年分
+     * @return 周列表
+     * @throws Exception
+     */
+    public static Map<Integer, String> getWeeksOfYear(String year) throws Exception {
+        Date useDate = string2Date(year, "yyyy");
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(useDate);
+        //获取年中周数量
+        int weeksCount = cal.getWeeksInWeekYear();
+        Map<Integer, String> mapWeeks = new HashMap<>(55);
+        for (int i = 0; i < weeksCount; i++) {
+            cal.get(Calendar.DAY_OF_YEAR);
+            mapWeeks.put(i + 1, date2StringS(getFirstDayOfWeek(cal.get(Calendar.YEAR), i)));
+        }
+        return mapWeeks;
+    }
+
+    /**
+     * 获取某年的第几周的开始日期
+     *
+     * @param year 年分
+     * @param week 周索引
+     * @return 开始日期
+     * @throws Exception
+     */
+    public static Date getFirstDayOfWeek(int year, int week) throws Exception {
+        Calendar c = new GregorianCalendar();
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, Calendar.JANUARY);
+        c.set(Calendar.DATE, 1);
+
+        Calendar cal = (GregorianCalendar) c.clone();
+        cal.add(Calendar.DATE, week * 7);
+
+        return getFirstDayOfWeek(cal.getTime());
+    }
+
+    /**
+     * 获取某年的第几周的结束日期
+     *
+     * @param year 年份
+     * @param week 周索引
+     * @return 结束日期
+     * @throws Exception
+     */
+    public static Date getLastDayOfWeek(int year, int week) throws Exception {
+        Calendar c = new GregorianCalendar();
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, Calendar.JANUARY);
+        c.set(Calendar.DATE, 1);
+
+        Calendar cal = (GregorianCalendar) c.clone();
+        cal.add(Calendar.DATE, week * 7);
+
+        return getLastDayOfWeek(cal.getTime());
+    }
+
+    /**
+     * 获取当前时间所在周的开始日期
+     *
+     * @param date 当前时间
+     * @return 开始时间
+     */
+    public static Date getFirstDayOfWeek(Date date) {
+        Calendar c = new GregorianCalendar();
+        c.setFirstDayOfWeek(Calendar.SUNDAY);
+        c.setTime(date);
+        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
+        return c.getTime();
+    }
+
+    /**
+     * 获取当前时间所在周的结束日期
+     *
+     * @param date 当前时间
+     * @return 结束日期
+     */
+    public static Date getLastDayOfWeek(Date date) {
+        Calendar c = new GregorianCalendar();
+        c.setFirstDayOfWeek(Calendar.SUNDAY);
+        c.setTime(date);
+        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
+        return c.getTime();
+    }
+
+    //获得上周一的日期
+    public static Date geLastWeekMonday(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(getThisWeekMonday(date));
+        cal.add(Calendar.DATE, -7);
+        return cal.getTime();
+    }
+
+    //获得本周一的日期
+    public static Date getThisWeekMonday(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        // 获得当前日期是一个星期的第几天
+        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
+        if (1 == dayWeek) {
+            cal.add(Calendar.DAY_OF_MONTH, -1);
+        }
+        // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一
+        cal.setFirstDayOfWeek(Calendar.MONDAY);
+        // 获得当前日期是一个星期的第几天
+        int day = cal.get(Calendar.DAY_OF_WEEK);
+        // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值
+        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
+        return cal.getTime();
+    }
+
+    //获得下周一的日期
+    public static Date getNextWeekMonday(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(getThisWeekMonday(date));
+        cal.add(Calendar.DATE, 7);
+        return cal.getTime();
+    }
+
+    //获得今天日期
+    public static Date getToday() {
+        return new Date();
+    }
+
+    //获得本月一日的日期
+    public static Date getFirstDay4ThisMonth() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.DAY_OF_MONTH, 1);
+        return calendar.getTime();
+    }
+
+    public static void main(String[] args) {
+        try {
+            System.out.println("本周一" + date2StringS(getThisWeekMonday()));
+            System.out.println("本月一日" + date2StringS(getFirstDay4ThisMonth()));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 256 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/FileUtil.java

@@ -0,0 +1,256 @@
+package com.gyee.power.fitting.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+@Slf4j
+public class FileUtil {
+
+    /**
+     * 写入文件
+     *
+     * @param fileName
+     * @param content
+     */
+    public static boolean writeFile(String fileName, String content) {
+        BufferedWriter bw = null;
+
+        try {
+            File file = new File(fileName);
+            if (!file.exists()) {
+                fileName = fileName.substring(0, fileName.lastIndexOf("\\"));
+                File file1 = new File(fileName);
+                file1.mkdirs();
+                file.createNewFile();
+            }
+
+
+            bw = new BufferedWriter(new FileWriter(file, true));
+
+            String[] list = content.split("\n");
+            for (int i = 0; i < list.length; i++) {
+                bw.write(list[i]);
+                bw.write("\n");
+                if (i % 1000 == 0)
+                    bw.flush();
+            }
+            bw.flush();
+        } catch (Exception e) {
+            log.error("writePowerData", e);
+            return false;
+        } finally {
+            try {
+                bw.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * 写入文件
+     *
+     * @param path
+     * @param fileName
+     * @param inputStream
+     */
+    public static void writeFile(String path, String fileName, InputStream inputStream) {
+        OutputStream os = null;
+        try {
+            byte[] bs = new byte[1024];
+            int len;
+
+            File file = new File(path);
+            if (!file.exists()) {
+                file.mkdirs();
+            }
+            os = new FileOutputStream(file.getPath() + File.separator + fileName);
+            // 开始读取
+            while ((len = inputStream.read(bs)) != -1) {
+                os.write(bs, 0, len);
+            }
+
+        } catch (IOException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        } finally {
+            // 完毕,关闭所有链接
+            try {
+                os.close();
+                inputStream.close();
+            } catch (IOException e) {
+                log.error(e.getMessage());
+            }
+        }
+    }
+
+
+    // String -> InputStream
+    public static InputStream convertStringToInputStream(String content) {
+
+        InputStream result = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
+        return result;
+
+    }
+
+    /**
+     * 读取文件
+     *
+     * @param fileName
+     * @param isAll    是否读取全部数据
+     * @return
+     */
+    public static List<String> readFile(String fileName, boolean isAll) {
+        List<String> list = new ArrayList<>();
+        BufferedReader reader = null;
+
+        try {
+            File file = new File(fileName);
+            reader = new BufferedReader(new FileReader(file));
+            String content = null;
+            int line = 0;
+            // 一次读入一行,直到读入null为文件结束
+            while ((content = reader.readLine()) != null) {
+                // 显示行号
+                list.add(content);
+                line++;
+                if (!isAll && line == 300)
+                    break;
+            }
+            reader.close();
+        } catch (IOException e) {
+            log.error(e.getMessage());
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e1) {
+                }
+            }
+        }
+
+        return list;
+    }
+
+
+    /**
+     * 加载文件
+     *
+     * @param fileName
+     * @return
+     */
+    public static void download(String fileName, HttpServletResponse response) {
+        FileInputStream fis = null;
+        BufferedInputStream bis = null;
+        try {
+            // 获取文件
+            File file = new File(fileName);
+            // 清空缓冲区,状态码和响应头(headers)
+            response.reset();
+            // 设置ContentType,响应内容为二进制数据流,编码为utf-8,此处设定的编码是文件内容的编码
+            response.setContentType("application/octet-stream;charset=utf-8");
+            // 以(Content-Disposition: attachment; filename="filename.jpg")格式设定默认文件名,设定utf编码,此处的编码是文件名的编码,使能正确显示中文文件名
+            response.setHeader("Content-Disposition", "attachment;fileName=" + file.getName() + ";filename*=utf-8''" + URLEncoder.encode(file.getName(), "utf-8"));
+
+            // 实现文件下载
+            byte[] buffer = new byte[1024];
+            fis = new FileInputStream(file);
+            bis = new BufferedInputStream(fis);
+            // 获取字节流
+            OutputStream os = response.getOutputStream();
+            int i = bis.read(buffer);
+            while (i != -1) {
+                os.write(buffer, 0, i);
+                i = bis.read(buffer);
+            }
+        } catch (Exception e) {
+            log.error("FileUtil--download", e);
+        } finally {
+            if (bis != null) {
+                try {
+                    bis.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @describe 压缩多个文件
+     * @author zfc
+     */
+    public static String zipFiles(List<File> srcFiles, File zipFile) {
+        // 判断压缩后的文件存在不,不存在则创建
+        if (!zipFile.exists()) {
+            try {
+                String fileName = zipFile.getAbsolutePath();
+                fileName = fileName.substring(0, fileName.lastIndexOf("\\"));
+                File file1 = new File(fileName);
+                file1.mkdirs();
+                zipFile.createNewFile();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        // 创建 FileOutputStream 对象
+        FileOutputStream fileOutputStream = null;
+        // 创建 ZipOutputStream
+        ZipOutputStream zipOutputStream = null;
+        // 创建 FileInputStream 对象
+        FileInputStream fileInputStream = null;
+
+        try {
+            // 实例化 FileOutputStream 对象
+            fileOutputStream = new FileOutputStream(zipFile);
+            // 实例化 ZipOutputStream 对象
+            zipOutputStream = new ZipOutputStream(fileOutputStream);
+            // 创建 ZipEntry 对象
+            ZipEntry zipEntry = null;
+            // 遍历源文件数组
+            for (int i = 0; i < srcFiles.size(); i++) {
+                // 将源文件数组中的当前文件读入 FileInputStream 流中
+                fileInputStream = new FileInputStream(srcFiles.get(i));
+                // 实例化 ZipEntry 对象,源文件数组中的当前文件
+                zipEntry = new ZipEntry(srcFiles.get(i).getName());
+                zipOutputStream.putNextEntry(zipEntry);
+                // 该变量记录每次真正读的字节个数
+                int len;
+                // 定义每次读取的字节数组
+                byte[] buffer = new byte[1024];
+                while ((len = fileInputStream.read(buffer)) > 0) {
+                    zipOutputStream.write(buffer, 0, len);
+                }
+            }
+            zipOutputStream.closeEntry();
+            zipOutputStream.close();
+            fileInputStream.close();
+            fileOutputStream.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return zipFile.getAbsolutePath();
+    }
+
+}

+ 26 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/JudeSystem.java

@@ -0,0 +1,26 @@
+package com.gyee.power.fitting.common.util;
+
+
+/**
+ * 判断当前系统
+ */
+public class JudeSystem {
+
+    public static boolean isLinux() {
+        return System.getProperty("os.name").toLowerCase().contains("linux");
+    }
+
+    public static boolean isWindows() {
+        return System.getProperty("os.name").toLowerCase().contains("windows");
+    }
+
+    public static String judgeSystem() {
+        if (isLinux()) {
+            return "linux";
+        } else if (isWindows()) {
+            return "windows";
+        } else {
+            return "other system";
+        }
+    }
+}

+ 109 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/NumberUtil.java

@@ -0,0 +1,109 @@
+package com.gyee.power.fitting.common.util;
+
+
+import java.math.BigDecimal;
+
+/**
+ * 数字转换中文
+ */
+public class NumberUtil {
+
+    private NumberUtil() { }
+
+    /**
+     * 中文数字
+     */
+    private static final String[] CN_NUM = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
+    /**
+     * 中文数字单位
+     */
+    private static final String[] CN_UNIT = {"", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千"};
+    /**
+     * 特殊字符:负
+     */
+    private static final String CN_NEGATIVE = "负";
+    /**
+     * 特殊字符:点
+     */
+    private static final String CN_POINT = "点";
+    /**
+     * int 转 中文数字
+     * 支持到int最大值
+     *
+     * @param intNum 要转换的整型数
+     * @return 中文数字
+     */
+    public static String int2chineseNum(int intNum) {
+        StringBuffer sb = new StringBuffer();
+        boolean isNegative = false;
+        if (intNum < 0) {
+            isNegative = true;
+            intNum *= -1;
+        }
+        int count = 0;
+        while(intNum > 0) {
+            sb.insert(0, CN_NUM[intNum % 10] + CN_UNIT[count]);
+            intNum = intNum / 10;
+            count++;
+        }
+        if (isNegative)
+            sb.insert(0, CN_NEGATIVE);
+        return sb.toString().replaceAll("零[千百十]", "零").replaceAll("零+万", "万")
+                .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
+                .replaceAll("零+", "零").replaceAll("零$", "");
+    }
+    /**
+     * bigDecimal 转 中文数字
+     * 整数部分只支持到int的最大值
+     *
+     * @param bigDecimalNum 要转换的BigDecimal数
+     * @return 中文数字
+     */
+    public static String bigDecimal2chineseNum(BigDecimal bigDecimalNum) {
+        if (bigDecimalNum == null)
+            return CN_NUM[0];
+        StringBuffer sb = new StringBuffer();
+        //将小数点后面的零给去除
+        String numStr = bigDecimalNum.abs().stripTrailingZeros().toPlainString();
+        String[] split = numStr.split("\\.");
+        String integerStr = int2chineseNum(Integer.parseInt(split[0]));
+        sb.append(integerStr);
+        //如果传入的数有小数,则进行切割,将整数与小数部分分离
+        if (split.length == 2) {
+            //有小数部分
+            sb.append(CN_POINT);
+            String decimalStr = split[1];
+            char[] chars = decimalStr.toCharArray();
+            for (int i = 0; i < chars.length; i++) {
+                int index = Integer.parseInt(String.valueOf(chars[i]));
+                sb.append(CN_NUM[index]);
+            }
+        }
+        //判断传入数字为正数还是负数
+        int signum = bigDecimalNum.signum();
+        if (signum == -1) {
+            sb.insert(0, CN_NEGATIVE);
+        }
+        return sb.toString();
+    }
+
+    public static String toNum(int num){
+        String interval = "";
+        switch(num){
+            case 1:
+                interval = "一秒";
+                break;
+            case 60:
+                interval = "一分钟";
+                break;
+            case 600:
+                interval = "十分钟";
+                break;
+            default:
+                interval = "一分钟";
+        }
+
+        return interval;
+    }
+
+}

+ 62 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/PowerFittingUtil.java

@@ -0,0 +1,62 @@
+package com.gyee.power.fitting.common.util;
+
+import com.gyee.power.fitting.common.constants.Constants;
+import com.gyee.power.fitting.model.Powerfittinganalysis;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class PowerFittingUtil {
+
+    /**
+     * 功率曲线拟合数据  tree
+     * @return
+     */
+    public static List<Object> powerDataTree(List<Powerfittinganalysis> list, String type){
+        /**多层分组**/
+        Map<String, Map<String, Map<String, List<Powerfittinganalysis>>>> map = list.stream().
+                collect(Collectors.groupingBy(Powerfittinganalysis::getInterval, TreeMap::new,
+                        Collectors.groupingBy(Powerfittinganalysis::getTime,
+                                Collectors.groupingBy(Powerfittinganalysis::getStationcn, TreeMap::new, Collectors.toList()))));
+        //map.values().stream().sorted(Comparator.comparing(s -> s.get)).collect(Collectors.toList());
+        List<Object> result = new ArrayList<>();
+        map.forEach((k, v) -> {
+            List<Object> l1 = new ArrayList<>();
+            Map<String, Object> map1 = new TreeMap<>();
+
+            map.get(k).forEach((k1, v1) -> {
+                List<Object> l2 = new ArrayList<>();
+                Map<String, Object> map2 = new HashMap<>();
+                map.get(k).get(k1).forEach((k2, v2) -> {
+                    Map<String, Object> map3 = new HashMap<>();
+                    map3.put("id", SnowFlakeUtil.generateId());
+                    map3.put("label", k2);
+                    map3.put("children", v2.stream().sorted(Comparator.comparing(Powerfittinganalysis::getWindturbine)));
+                    l2.add(map3);
+                });
+
+                map2.put("id", SnowFlakeUtil.generateId());
+                map2.put("label", k1);
+                map2.put("children", l2);
+                l1.add(map2);
+            });
+
+            map1.put("id", SnowFlakeUtil.generateId());
+            map1.put("label", k);
+            map1.put("children", l1);
+            result.add(map1);
+        });
+
+        Map<String, Object> mp = new HashMap<>();
+        mp.put("id", SnowFlakeUtil.generateId());
+        mp.put("label", type.equals(Constants.DATA_PREPARE) ? "数据准备" :
+                type.equals(Constants.DATA_PROCESS) ? "数据预处理" : type.equals(Constants.DATA_FITTING) ? "功率曲线拟合" : "数据");
+        mp.put("children", result);
+
+        List<Object> ls = new ArrayList<>();
+        ls.add(mp);
+
+        return ls;
+    }
+
+}

+ 162 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/SnowFlakeUtil.java

@@ -0,0 +1,162 @@
+package com.gyee.power.fitting.common.util;
+
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class SnowFlakeUtil {
+
+    // ==============================Fields===========================================
+    /** 开始时间截 (2015-01-01) */
+    private final long twepoch = 1420041600000L;
+
+    /** 机器id所占的位数 */
+    private final long workerIdBits = 5L;
+
+    /** 数据标识id所占的位数 */
+    private final long datacenterIdBits = 5L;
+
+    /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /** 支持的最大数据标识id,结果是31 */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /** 序列在id中占的位数 */
+    private final long sequenceBits = 12L;
+
+    /** 机器ID向左移12位 */
+    private final long workerIdShift = sequenceBits;
+
+    /** 数据标识id向左移17位(12+5) */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /** 时间截向左移22位(5+5+12) */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /** 工作机器ID(0~31) */
+    private long workerId;
+
+    /** 数据中心ID(0~31) */
+    private long datacenterId;
+
+    /** 毫秒内序列(0~4095) */
+    private long sequence = 0L;
+
+    /** 上次生成ID的时间截 */
+    private long lastTimestamp = -1L;
+
+    //==============================Constructors=====================================
+    /**
+     * 构造函数
+     * @param workerId 工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public SnowFlakeUtil(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+        //移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+
+    private static SnowFlakeUtil idWorker = null;
+
+    public static String generateId() {
+        if (idWorker == null)
+            idWorker = new SnowFlakeUtil(0, 0);
+
+        return String.valueOf(idWorker.nextId());
+//        for (int i = 0; i < 1000; i++) {
+//            long id = idWorker.nextId();
+//            System.out.println(Long.toBinaryString(id));
+//            System.out.println(id);
+//        }
+    }
+    public static Long generateIdL() {
+        if (idWorker == null)
+            idWorker = new SnowFlakeUtil(0, 0);
+
+        return idWorker.nextId();
+//        for (int i = 0; i < 1000; i++) {
+//            long id = idWorker.nextId();
+//            System.out.println(Long.toBinaryString(id));
+//            System.out.println(id);
+//        }
+    }
+}

+ 45 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/TokenGenerator.java

@@ -0,0 +1,45 @@
+package com.gyee.power.fitting.common.util;
+
+import java.security.MessageDigest;
+import java.util.UUID;
+
+public class TokenGenerator {
+
+    private TokenGenerator(){}
+
+    public static String generateValue() {
+        return generateValue(UUID.randomUUID().toString());
+    }
+
+    private static final char[] hexCode = "asdfghjkqwert4841632128".toCharArray();
+
+    private static String toHexString(byte[] data) {
+        if (data == null) {
+            return null;
+        }
+        StringBuilder r = new StringBuilder(data.length * 2);
+        for (byte b : data) {
+            r.append(hexCode[(b >> 4) & 0xF]);
+            r.append(hexCode[(b & 0xF)]);
+        }
+        return r.toString();
+    }
+
+    /**
+     * 生成Token
+     * @param param
+     * @return
+     */
+    private static String generateValue(String param) {
+        try {
+            MessageDigest algorithm = MessageDigest.getInstance("MD5");
+            algorithm.reset();
+            algorithm.update(param.getBytes());
+            byte[] messageDigest = algorithm.digest();
+            return toHexString(messageDigest);
+        } catch (Exception e) {
+            throw new RuntimeException("生成Token失败");
+        }
+    }
+
+}

+ 60 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/agc/AgcDeviateController.java

@@ -0,0 +1,60 @@
+package com.gyee.power.fitting.controller.agc;
+
+import com.gyee.power.fitting.common.config.GyeeConfig;
+import com.gyee.power.fitting.model.agc.AgcDeviateTag;
+import com.gyee.power.fitting.service.custom.agc.AgcDeviateService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 获取各个场站AGC偏差分析数据
+ */
+@RestController
+@RequestMapping("/agc")
+public class AgcDeviateController {
+    @Resource
+    private AgcDeviateService agcDeviateService;
+    @Resource
+    private GyeeConfig gyeeConfig;
+
+    /**
+     * 获取偏差信息
+     *
+     * @param startTs  开始时间
+     * @param endTs    结束时间
+     * @param id       场站id
+     * @param interval 时间间隔
+     * @return
+     */
+    @GetMapping("/deviate")
+    public Map<String, AgcDeviateTag> getData(@RequestParam(value = "startTs") long startTs,
+                                              @RequestParam(value = "endTs") long endTs,
+                                              @RequestParam(value = "id") String id,
+                                              @RequestParam(value = "interval", defaultValue = "60", required = false) int interval) {
+        List<AgcDeviateTag> ls = new ArrayList<>();
+        if (gyeeConfig.isOffLine()) {
+            ls = agcDeviateService.getAgcDeviateTagsOffline(id, startTs, endTs, interval);
+        } else {
+            ls = agcDeviateService.getAgcDeviateTags(id, startTs, endTs, interval);
+        }
+        return ls.stream().collect(Collectors.toMap(AgcDeviateTag::getName, f -> f));
+    }
+
+    /**
+     * 获取配置
+     *
+     * @return
+     */
+    @GetMapping("/config")
+    public Object getAgcConifg() {
+        return agcDeviateService.getConfig();
+    }
+}

+ 23 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/base/CurveFittingController.java

@@ -0,0 +1,23 @@
+package com.gyee.power.fitting.controller.base;
+
+import com.gyee.power.fitting.common.feign.IAdapterService;
+import com.gyee.power.fitting.service.Windturbinetestingpointai2Service;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@RestController("curvefitting")
+public class CurveFittingController {
+    @Resource
+    private Windturbinetestingpointai2Service windturbinetestingpointai2Service;
+    @Resource
+    private IAdapterService iAdapterService;
+
+    @GetMapping("/")
+    private void get(@RequestParam("wtid") String wtid){
+        wtid = "HZJ01_01";
+        windturbinetestingpointai2Service.getZlTag(wtid);
+    }
+}

+ 70 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/base/WindInfoController.java

@@ -0,0 +1,70 @@
+package com.gyee.power.fitting.controller.base;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.common.spring.InitialRunner;
+import com.gyee.power.fitting.model.Line;
+import com.gyee.power.fitting.model.Project;
+import com.gyee.power.fitting.model.Windpowerstation;
+import com.gyee.power.fitting.model.Windturbine;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 场站风机等基础数据
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("/base")
+public class WindInfoController {
+
+    @GetMapping("station")
+    public JSONObject getStation() {
+        List<Windpowerstation> list = InitialRunner.wpList;
+        return JsonResult.successData(ResultCode.SUCCESS, list);
+    }
+
+    @GetMapping("windturbine")
+    public JSONObject getWindTurbine(String stationId) {
+        List<Windturbine> list = InitialRunner.wpMap.get(stationId);
+        return JsonResult.successData(ResultCode.SUCCESS, list);
+    }
+
+    @GetMapping("/gfstation")
+    public JSONObject getGFStation() {
+        List<Windpowerstation> list = InitialRunner.gfwpList;
+        return JsonResult.successData(ResultCode.SUCCESS, list);
+    }
+
+    @GetMapping("/inverter")
+    public JSONObject getInverter(String stationId) {
+        List<Windturbine> list = InitialRunner.gfwpMap.get(stationId);
+        return JsonResult.successData(ResultCode.SUCCESS, list);
+    }
+
+    @GetMapping("project")
+    public JSONObject getProject(String stationId) {
+        List<Project> list = InitialRunner.projectList.stream().filter(f -> f.getWindpowerstationid().equals(stationId)).collect(Collectors.toList());
+        return JsonResult.successData(ResultCode.SUCCESS, list);
+    }
+
+    @GetMapping("line")
+    public JSONObject getLine(String projectId) {
+        List<Line> list = new ArrayList<>();
+        String[] projects = projectId.split(",");
+        Map<String, List<Line>> map = InitialRunner.lineList.stream().collect(Collectors.groupingBy(Line::getProjectid));
+        for (String project : projects){
+            if (map.get(project).size() > 0)
+                list.addAll(map.get(project));
+        }
+        return JsonResult.successData(ResultCode.SUCCESS, list);
+    }
+}

+ 140 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/DataFittingController.java

@@ -0,0 +1,140 @@
+package com.gyee.power.fitting.controller.fj;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.model.Powerfittinganalysis;
+import com.gyee.power.fitting.model.custom.PowerPointData;
+import com.gyee.power.fitting.service.custom.curve.DataFittingService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 功率曲线拟合
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("/power/fitting")
+public class DataFittingController {
+
+    @Resource
+    private DataFittingService fittingService;
+
+
+    /**
+     * 数据拟合
+     * @param ids    数据预处理id
+     * @param maxs
+     * @param mins
+     * @param maxp
+     * @param minp
+     * @param dimension 多项式
+     * @param mode  拟合方式  0:单台拟合  1:合并拟合  2:同名拟合
+     * @return
+     */
+    @GetMapping("/data")
+    public JSONObject dataFitting(@RequestParam(value = "ids",  required = false) String ids,
+                                  @RequestParam(value = "maxs",  required = false) Double maxs,
+                                  @RequestParam(value = "mins",  required = false) Double mins,
+                                  @RequestParam(value = "maxp",  required = false) Double maxp,
+                                  @RequestParam(value = "minp",  required = false) Double minp,
+                                  @RequestParam(value = "dimension",  required = false) Integer dimension,
+                                  @RequestParam(value = "mode",  required = false) Integer mode){
+        if (ids.isEmpty())
+            return JsonResult.error(ResultCode.PARAM_IS_BLANK);
+
+        Powerfittinganalysis obj = fittingService.dataFitting(ids, maxs, mins, maxp, minp, dimension, mode);
+        return JsonResult.successData(ResultCode.SUCCESS, obj);
+    }
+
+
+    /** 文件 tree
+     * @return
+     */
+    @GetMapping("tree")
+    public JSONObject dataFIttingTree(){
+        List<Object> result = fittingService.dataFittingTree();
+        return JsonResult.successData(ResultCode.SUCCESS, result);
+    }
+
+
+    /**
+     * file 文件数据展示
+     * @param id
+     * @return
+     */
+    @GetMapping("show")
+    public JSONObject dataFittingShow(String id){
+        Map<String, Object> result = fittingService.dataFittingShow(id);
+        return JsonResult.successData(ResultCode.SUCCESS, result);
+    }
+
+
+    /**
+     * 读取曲线,散点等数据
+     * @param id  拟合好的数据ID
+     * @return
+     */
+    @GetMapping("curve")
+    public JSONObject dataFittingCurve(String id){
+        Map<String, Object> result = fittingService.dataFittingCurve(id);
+        return JsonResult.successData(ResultCode.SUCCESS, result);
+    }
+
+
+    /**
+     * 通过key获取原始数据
+     * 对应前端的圈选功能
+     * @param yk  有用点的key
+     * @param wk  无用点的key
+     * @return
+     */
+    @GetMapping("filter")
+    public JSONObject dataFittingFilter(String yk, String wk){
+        List<PowerPointData> list = fittingService.dataOrigin(yk, wk);
+        return JsonResult.successData(ResultCode.SUCCESS, list);
+    }
+
+
+    /**
+     * 保存拟合的功率曲线数据
+     * @param ids 曲线拟合的ids
+     * @return
+     */
+    @GetMapping("curve/save")
+    public JSONObject dataCurveSave(String ids){
+        fittingService.curveSave(ids);
+        return JsonResult.success(ResultCode.SUCCESS);
+    }
+
+
+    /**
+     * 获取多风机的拟合曲线功率
+     * @param ids  拟合好的数据ID
+     * @return
+     */
+    @GetMapping("line")
+    public JSONObject dataFittingLine(String ids){
+        Object o = fittingService.dataFittingLine(ids);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+
+    /**
+     * 获取多风机的运行时间
+     * 不运行时间  3-5m风速运行时间   5-10m风速运行时间   10-12m风速运行时间   12-25m风速运行时间
+     * 到达切入风速但未运行的时间
+     * @param ids  拟合好的数据ID
+     * @return
+     */
+    @GetMapping("time")
+    public JSONObject dataFittingYXTime(String ids){
+        Object o = fittingService.dataFittingTime(ids);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+}

+ 83 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/DataPrepareController.java

@@ -0,0 +1,83 @@
+package com.gyee.power.fitting.controller.fj;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.common.util.FileUtil;
+import com.gyee.power.fitting.model.Powerfittinganalysis;
+import com.gyee.power.fitting.service.PowerfittinganalysisService;
+import com.gyee.power.fitting.service.custom.curve.DataPrepareService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+
+/**
+ * 功率曲线拟合  数据准备
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("/power/prepare")
+public class DataPrepareController {
+
+    @Autowired
+    private DataPrepareService prepareService;
+    @Autowired
+    private PowerfittinganalysisService powerService;
+
+
+    /**
+     * 数据准备  golden-file
+     * @param station
+     * @param wtIds
+     * @param st
+     * @param et
+     * @param interval
+     * @return
+     */
+    @GetMapping("data")
+    public JSONObject dataPrepare(String station, String wtIds, Long st,
+                                  Long et, Integer interval){
+        if (station.isEmpty() || wtIds.isEmpty())
+            return JsonResult.error(ResultCode.PARAM_NOT_COMPLETE);
+
+        String[] points = wtIds.split(",");
+        prepareService.dataPrepare(station, Arrays.asList(points), st, et, interval);
+
+        return JsonResult.error(ResultCode.SUCCESS_DATA_PREPARE);
+    }
+
+    /** 文件 tree
+     * @return
+     */
+    @GetMapping("tree")
+    public JSONObject dataPrepareTree(){
+        List<Object> result = prepareService.dataPrepareTree();
+        return JsonResult.successData(ResultCode.SUCCESS, result);
+    }
+
+
+    /**
+     * file 文件数据展示前500行
+     * @param id
+     * @return
+     */
+    @GetMapping("show")
+    public JSONObject dataPrepareShow(String id){
+        Map<String, Object> result = prepareService.dataPrepareShow(id);
+        return JsonResult.successData(ResultCode.SUCCESS, result);
+    }
+
+
+    /**
+     * file 下载
+     * @return
+     */
+    @GetMapping("download")
+    public void dataPrepareDownload(HttpServletResponse response, @RequestParam(value = "id", required = false) String id){
+        Powerfittinganalysis obj = powerService.selectItemById(id);
+        FileUtil.download(obj.getPath(), response);
+    }
+}

+ 106 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/DataProcessController.java

@@ -0,0 +1,106 @@
+package com.gyee.power.fitting.controller.fj;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.common.util.FileUtil;
+import com.gyee.power.fitting.model.Powerfittinganalysis;
+import com.gyee.power.fitting.service.PowerfittinganalysisService;
+import com.gyee.power.fitting.service.custom.curve.DataProcessService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 功率曲线拟合  数据预处理
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("/power/process")
+public class DataProcessController {
+
+    @Autowired
+    private PowerfittinganalysisService powerService;
+    @Autowired
+    private DataProcessService processService;
+
+
+    /**
+     * 数据预处理
+     * @param ids       预处理数据的ID  自定义
+     * @param maxs     最大风速
+     * @param mins     最小风速
+     * @param maxp     最大功率
+     * @param minp     最小功率
+     * @param isfbw    非并网
+     * @param isfhl    非合理值
+     * @param isbw     并网后10分钟
+     * @param istj     停机前10分钟
+     * @param isglpc   功率曲线偏差
+     * @param isqfh    是否欠符合
+     * @param qfhdj    欠符合等级
+     * @return
+     */
+    @GetMapping("data")
+    public JSONObject dataProcess(@RequestParam(value = "ids",  required = false) String ids,
+                                  @RequestParam(value = "maxs",  required = false) Double maxs,
+                                  @RequestParam(value = "mins",  required = false) Double mins,
+                                  @RequestParam(value = "maxp",  required = false) Double maxp,
+                                  @RequestParam(value = "minp",  required = false) Double minp,
+                                  @RequestParam(value = "isfbw",  required = false) Boolean isfbw,
+                                  @RequestParam(value = "isfhl",  required = false) Boolean isfhl,
+                                  @RequestParam(value = "isbw",  required = false) Boolean isbw,
+                                  @RequestParam(value = "istj",  required = false) Boolean istj,
+                                  @RequestParam(value = "isglpc",  required = false) Boolean isglpc,
+                                  @RequestParam(value = "isqfh",  required = false) Boolean isqfh,
+                                  @RequestParam(value = "qfhdj",  required = false) Integer qfhdj){
+
+        isfbw = isfbw == null ? false : isfbw;
+        isfhl = isfhl == null ? false : isfhl;
+        isbw = isbw == null ? false : isbw;
+        istj = istj == null ? false : istj;
+        isglpc = isglpc == null ? false : isglpc;
+        isqfh = isqfh == null ? false : isqfh;
+
+        String[] id = ids.split(",");
+        processService.dataProcess(Arrays.asList(id), maxs, mins, maxp, minp, isfbw, isfhl, isbw, istj, isglpc, isqfh, qfhdj);
+
+        return JsonResult.error(ResultCode.SUCCESS);
+    }
+
+    /** 文件 tree
+     * @return
+     */
+    @GetMapping("tree")
+    public JSONObject dataProcessTree(){
+        List<Object> result = processService.dataProcessTree();
+        return JsonResult.successData(ResultCode.SUCCESS, result);
+    }
+
+
+    /**
+     * file 文件数据展示前500行
+     * @param id
+     * @return
+     */
+    @GetMapping("show")
+    public JSONObject dataProcessShow(String id){
+        Map<String, Object> result = processService.dataProcessShow(id);
+        return JsonResult.successData(ResultCode.SUCCESS, result);
+    }
+
+    /**
+     * file 下载
+     * @return
+     */
+    @GetMapping("download")
+    public void dataProcessDownload(HttpServletResponse response, @RequestParam(value = "id", required = false) String id){
+        Powerfittinganalysis obj = powerService.selectItemById(id);
+        FileUtil.download(obj.getPath(), response);
+    }
+
+}

+ 61 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/DateOptionController.java

@@ -0,0 +1,61 @@
+package com.gyee.power.fitting.controller.fj;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.config.GyeeConfig;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.common.util.FileUtil;
+import com.gyee.power.fitting.model.Powerfittinganalysis;
+import com.gyee.power.fitting.service.PowerfittinganalysisService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 数据删除、下载...
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("/data/option")
+public class DateOptionController {
+
+    @Autowired
+    private GyeeConfig gyeeConfig;
+    @Autowired
+    private PowerfittinganalysisService powerfittinganalysisService;
+
+
+    /** 删除
+     * @return
+     */
+    @GetMapping("delete")
+    public JSONObject dataDelete(String ids){
+        powerfittinganalysisService.deleteList(ids);
+        return JsonResult.success(ResultCode.SUCCESS);
+    }
+
+
+    /**
+     * 文件压缩下载
+     * @return
+     */
+    @GetMapping("download")
+    public void dataProcessDownload(HttpServletResponse response, @RequestParam(value = "ids", required = false) String ids){
+        if (ids.isEmpty())
+            return;
+
+        List<Powerfittinganalysis> objs = powerfittinganalysisService.selectListByIds(ids);
+        List<String> list = objs.stream().map(p -> p.getPath()).collect(Collectors.toList());
+        List<File> files = list.stream().map(File::new).collect(Collectors.toList());
+
+        File zipFile = new File(gyeeConfig.getFilePathDownload()  + "\\" + objs.get(0).getStation() + "_" + System.currentTimeMillis() + ".zip");
+        // 调用压缩方法
+        String ps = FileUtil.zipFiles(files, zipFile);
+        FileUtil.download(ps, response);
+    }
+
+}

+ 69 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/FiveLossInfoController.java

@@ -0,0 +1,69 @@
+package com.gyee.power.fitting.controller.fj;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.common.util.DateUtil;
+import com.gyee.power.fitting.service.custom.fiveloss.FiveLossService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * 损失电量分析
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("/fjjxb")
+public class FiveLossInfoController {
+
+    @Resource
+    private FiveLossService fiveLossService;
+
+    @GetMapping("five/loss/cal")
+    public JSONObject fiveLossCal(String ids){
+        Map<String, Object> map = fiveLossService.fiveLossCalByZSGL(ids);
+        if (map.size() > 0)
+            return JsonResult.successData(ResultCode.SUCCESS, map);
+
+        return JsonResult.error(ResultCode.ERROR_MODEL);
+    }
+
+
+    /**
+     * 五损数据查询
+     * @param station
+     * @param project
+     * @param line
+     * @param st
+     * @param et
+     * @param type  1:场站  2:期次  3:线路
+     * @return
+     */
+    @GetMapping("index")
+    public JSONObject fiveLoss(String station, String project, String line, String st, String et, String type){
+        Date begin = DateUtil.parseStrtoDate(st, DateUtil.DATE_PATTERN);
+        Date end = DateUtil.parseStrtoDate(et, DateUtil.DATE_PATTERN);
+        List<String> projects = StringUtils.isEmpty(project) ? Collections.emptyList() : Arrays.asList(project.split(","));
+        List<String> lines = StringUtils.isEmpty(line) ? Collections.emptyList() : Arrays.asList(line.split(","));
+
+        Map<String, Object> map = fiveLossService.fiveLoss(station, projects, lines, begin, end, type);
+        return JsonResult.successData(ResultCode.SUCCESS, map);
+    }
+
+
+    /**
+     * 五损数据计算
+     * @return
+     */
+    @GetMapping("cal")
+    public JSONObject fiveCal(){
+        fiveLossService.fiveLossCal();
+        return JsonResult.success(ResultCode.SUCCESS);
+    }
+}

+ 58 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/PowerTemperatureController.java

@@ -0,0 +1,58 @@
+package com.gyee.power.fitting.controller.fj;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.service.custom.temperature.PowerTemperatureService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * 功率温度分析
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("/temperature")
+public class PowerTemperatureController {
+
+    @Resource
+    private PowerTemperatureService powerTemperatureService;
+
+    /***
+     * 与温度有关的额定功率
+     * @param ids  预处理数据的id
+     * @return
+     */
+    @GetMapping("rated/power")
+    public JSONObject ratedPower(String ids){
+        Object o = powerTemperatureService.ratedPower(ids);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+
+
+    /***
+     * 温度曲线分析
+     * @param id  预处理数据的id
+     * @return
+     */
+    @GetMapping("curve/analysis")
+    public JSONObject curveAnalysis(String id){
+        Object o = powerTemperatureService.curveAnalysis(id);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+
+    /**
+     * file 文件数据展示
+     * @param id
+     * @return
+     */
+    @GetMapping("show")
+    public JSONObject temperatureShow(String id){
+        Map<String, Object> result = powerTemperatureService.temperatureDataShow(id);
+        return JsonResult.successData(ResultCode.SUCCESS, result);
+    }
+}

+ 35 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/RatedPowerController.java

@@ -0,0 +1,35 @@
+package com.gyee.power.fitting.controller.fj;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.service.custom.ratedpower.RatedPowerService;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 额定功率分析
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("rated/power")
+public class RatedPowerController {
+
+    @Resource
+    private RatedPowerService ratedPowerService;
+
+    /***
+     * 额定功率分析
+     * @param ids
+     * @return
+     */
+    @GetMapping("")
+    public JSONObject ratedPowerAnalysis(String ids){
+        Object o = ratedPowerService.ratePowerAnalysis(ids);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+}

+ 78 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/fj/WindDirectionController.java

@@ -0,0 +1,78 @@
+package com.gyee.power.fitting.controller.fj;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.service.custom.windresource.AvgSpeedInfoService;
+import com.gyee.power.fitting.service.custom.windresource.RatioService;
+import com.gyee.power.fitting.service.custom.windresource.WindDirectionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+/**
+ * 风向玫瑰图
+ */
+@RestController
+@CrossOrigin
+@RequestMapping("/wind")
+public class WindDirectionController {
+
+    @Resource
+    private RatioService ratioService;
+    @Resource
+    private AvgSpeedInfoService avgSpeedInfoService;
+    @Resource
+    private WindDirectionService windDirectionService;
+
+    /***
+     * 风速风向玫瑰图
+     * @param ids  预处理数据的id
+     * @param mode 统计方式   0:单台统计   1:合并统计
+     * @return
+     */
+    @GetMapping("roses")
+    public JSONObject fsRoses(String ids, @RequestParam(value = "mode",  required = false) Integer mode){
+        mode = mode == null ? 0 : mode;
+        Object o = windDirectionService.fxRoses(ids, mode);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+
+    /***
+     * 风向频次玫瑰图
+     * @param ids  预处理数据的id
+     * @param mode 统计方式   0:单台统计   1:合并统计
+     * @return
+     */
+    @GetMapping("roses/count")
+    public JSONObject fxRoses(String ids, @RequestParam(value = "mode",  required = false) Integer mode){
+        mode = mode == null ? 0 : mode;
+        Object o = windDirectionService.fxCountRoses(ids, mode);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+
+    /**
+     * 对风偏差分析
+     * @param ids  预处理数据 ids
+     * @param mode 拟合方式  0:单台统计   1:合并统计
+     * @return
+     */
+    @GetMapping("deviation/ratio")
+    public JSONObject fsDeviationRatio(String ids, @RequestParam(value = "mode",  required = false) Integer mode){
+        mode = mode == null ? 0 : mode;
+        Object o = ratioService.windDeviationRatio(ids, mode);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+
+    /**
+     * 平均风速及毛容系数
+     * @param ids 预处理数据 ids
+     * @return
+     */
+    @GetMapping("avg/speed")
+    public JSONObject avgSpeedInfo(String ids){
+        Object o = avgSpeedInfoService.avgSpeedInfo(ids);
+        return JsonResult.successData(ResultCode.SUCCESS, o);
+    }
+}

+ 164 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/gf/PhotovoltaicController.java

@@ -0,0 +1,164 @@
+package com.gyee.power.fitting.controller.gf;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.power.fitting.common.result.JsonResult;
+import com.gyee.power.fitting.common.result.ResultCode;
+import com.gyee.power.fitting.model.anno.AnnotationTool;
+import com.gyee.power.fitting.model.anno.FixedVo;
+import com.gyee.power.fitting.model.custom.FjjxbVo;
+import com.gyee.power.fitting.model.custom.PhotovoltaicInfo;
+import com.gyee.power.fitting.model.custom.TableTitle;
+import com.gyee.power.fitting.service.impl.IvPvCurveFittingService;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@RestController("/photovol")
+public class PhotovoltaicController {
+
+    @Resource
+    private IvPvCurveFittingService curveFittingService;
+
+    @GetMapping("/filelist")
+    private JSONObject getFileList(@RequestParam("station") String station,
+                                   @RequestParam("inverters") List<String> inverters,
+                                   @RequestParam("startdate") long startdate,
+                                   @RequestParam("enddate") long enddate) {
+        List<String> fileList = curveFittingService.getFileList(station, inverters, startdate, enddate, false);
+        if (fileList == null) {
+            try {
+                curveFittingService.getDatas2File(station, startdate, enddate);
+                curveFittingService.standardPointCalculate2();
+            } catch (Exception e) {
+                return JsonResult.error(ResultCode.ERROR_FILE_NO);
+            }
+
+            fileList = curveFittingService.getFileList(station, inverters, startdate, enddate, true);
+        }
+        //Map<String, Object> table = curveFittingService.getTable(fileList.get(0));
+        //table.put("filelist", fileList);
+
+        List<Object> fileLists = curveFittingService.str2FileList(fileList);
+        return JsonResult.successData(ResultCode.SUCCESS, fileLists);
+    }
+
+    @GetMapping("/allfilelist")
+    private JSONObject getFileList() {
+        List<String> fileList = curveFittingService.getAllFileList();
+        List<Object> objects = curveFittingService.str2FileList(fileList);
+        return JsonResult.successData(ResultCode.SUCCESS, objects);
+    }
+
+    /**
+     * 单文件表格显示
+     *
+     * @param filename
+     * @return
+     */
+    @GetMapping("/datas")
+    private JSONObject getDatas(@RequestParam("filename") String filename) {
+        Map<String, Object> table = curveFittingService.getTable(filename);
+        return JsonResult.successData(ResultCode.SUCCESS, table);
+    }
+
+    //功率-时间曲线,根据条件,暂时不用
+    @GetMapping("/analysis/powertime")
+    private JSONObject powerTimeAnalysis(@RequestParam("station") String station,
+                                         @RequestParam("inverters") List<String> inverters,
+                                         @RequestParam("startdate") long startdate,
+                                         @RequestParam("enddate") long enddate) {
+        List<String> fileList = curveFittingService.getFileList(station, inverters, startdate, enddate, true);
+        Map<String, List<PhotovoltaicInfo>> infos = curveFittingService.calculatAnalysis(fileList);
+
+        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
+        String[] ss = {"station", "datetime", "T", "S", "actualP"};
+        List<String> strings = Arrays.asList(ss);
+        List<TableTitle> collect = fixedVos.stream().map(d -> new TableTitle(d.getName(), d.getDes())).collect(Collectors.toList());
+        collect = collect.stream().filter(c -> strings.contains(c.getKey())).collect(Collectors.toList());
+        TableTitle title = new TableTitle();
+        title.setKey("ideaP");
+        title.setDes("理论功率");
+        collect.add(title);
+
+        Map<String, Object> table = new HashMap<>();
+        table.put("title", collect);
+        table.put("data", infos);
+        return JsonResult.successData(ResultCode.SUCCESS, table);
+    }
+
+    //功率-时间曲线,根据文件
+    @GetMapping("/analysis/powertimefile")
+    private JSONObject powerTimeFile(@RequestParam("filelist") List<String> fileList) {
+        Map<String, List<PhotovoltaicInfo>> infos = curveFittingService.calculatAnalysis(fileList);
+
+        List<TableTitle> collect = curveFittingService.getTheoryTitel();
+
+        Map<String, Object> table = new HashMap<>();
+        table.put("title", collect);
+        table.put("data", infos);
+        return JsonResult.successData(ResultCode.SUCCESS, table);
+    }
+
+    @GetMapping("/test")
+    private void test() {
+        curveFittingService.standardPointCalculate2();
+    }
+
+    @GetMapping("/gfjxb")
+    public JSONObject gfjxb(@RequestParam("startdate") long startdate,
+                            @RequestParam("enddate") long enddate) {
+        List<FjjxbVo> voList = curveFittingService.getPhotovoltaicPerformanceList(startdate, enddate);
+        return JsonResult.successData(ResultCode.SUCCESS, voList);
+    }
+
+    //功率-光照-温度曲线
+    @PostMapping("/analysis/powerbeam")
+    private JSONObject powerBeamTemperature(@RequestBody JSONObject filename) {
+        List<String> strings = jsonObj2List(filename);
+        if (strings.size() > 450) return JsonResult.error(ResultCode.PARAM_NOT_VALID);
+        List<PhotovoltaicInfo> infos = curveFittingService.calculatFitting(strings);
+        List<double[]> b = curveFittingService.oneFileFitting(infos);
+        infos = infos.stream().filter(i -> i.getS() > 1).sorted(Comparator.comparing(PhotovoltaicInfo::getS)).collect(Collectors.toList());
+
+        List<double[]> a = new ArrayList<>();
+        for (PhotovoltaicInfo pi : infos) {
+
+            double[] scatter = new double[3];
+
+            scatter[0] = pi.getS();
+            scatter[1] = pi.getActualP();
+            scatter[2] = pi.getT();
+
+            a.add(scatter);
+        }
+
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("scatter", a);
+        map.put("curve", b);
+
+        return JsonResult.successData(ResultCode.SUCCESS, map);
+    }
+
+    //文件删除
+    @DeleteMapping("/delete/files")
+    private JSONObject deleteFiles(@RequestBody JSONObject filename) {
+        List<String> strings = jsonObj2List(filename);
+        int i = curveFittingService.deleteFiles(strings);
+        return JsonResult.successData(ResultCode.SUCCESS, "共删除" + i + "个文件,删除失败" + (strings.size() - i) + "个!");
+    }
+
+    private List<String> jsonObj2List(JSONObject filename) {
+        String fn = filename.getString("filename");
+        String[] split = fn.split(",");
+        return Arrays.asList(split);
+    }
+
+    @GetMapping("/export/files")
+    private void exportFiles(HttpServletResponse response, @RequestParam("filename") String filename) {
+        String[] split = filename.split(",");
+        curveFittingService.downFiles(Arrays.asList(split), response);
+    }
+}

+ 12 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/AgcDeviateMapper.java

@@ -0,0 +1,12 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.AgcDeviateModel;
+import org.apache.ibatis.annotations.Mapper;
+
+
+
+@Mapper
+public interface AgcDeviateMapper extends BaseMapper<AgcDeviateModel> {
+
+}

+ 18 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/EquipmentmodelMapper.java

@@ -0,0 +1,18 @@
+package com.gyee.power.fitting.mapper;
+
+import com.gyee.power.fitting.model.Equipmentmodel;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-08
+ */
+@Mapper
+public interface EquipmentmodelMapper extends BaseMapper<Equipmentmodel> {
+
+}

+ 17 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/LineMapper.java

@@ -0,0 +1,17 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Line;
+
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-02-03
+ */
+public interface LineMapper extends BaseMapper<Line> {
+
+}

+ 18 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/ModelpowerdetailsMapper.java

@@ -0,0 +1,18 @@
+package com.gyee.power.fitting.mapper;
+
+import com.gyee.power.fitting.model.Modelpowerdetails;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-08
+ */
+@Mapper
+public interface ModelpowerdetailsMapper extends BaseMapper<Modelpowerdetails> {
+
+}

+ 16 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PhotovoltaiccapacityMapper.java

@@ -0,0 +1,16 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Photovoltaiccapacity;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author gfhd
+ * @since 2022-12-13
+ */
+public interface PhotovoltaiccapacityMapper extends BaseMapper<Photovoltaiccapacity> {
+
+}

+ 18 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PhotovoltaicivMapper.java

@@ -0,0 +1,18 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Photovoltaiciv;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author gfhd
+ * @since 2022-12-13
+ */
+@Mapper
+public interface PhotovoltaicivMapper extends BaseMapper<Photovoltaiciv> {
+
+}

+ 18 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PowerfittinganalysisMapper.java

@@ -0,0 +1,18 @@
+package com.gyee.power.fitting.mapper;
+
+import com.gyee.power.fitting.model.Powerfittinganalysis;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-03
+ */
+@Mapper
+public interface PowerfittinganalysisMapper extends BaseMapper<Powerfittinganalysis> {
+
+}

+ 16 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PowerlossinfoMapper.java

@@ -0,0 +1,16 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Powerlossinfo;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-02-03
+ */
+public interface PowerlossinfoMapper extends BaseMapper<Powerlossinfo> {
+
+}

+ 16 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PowermodelMapper.java

@@ -0,0 +1,16 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Powermodel;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-02-21
+ */
+public interface PowermodelMapper extends BaseMapper<Powermodel> {
+
+}

+ 16 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/PowerwindinfoMapper.java

@@ -0,0 +1,16 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Powerwindinfo;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-03-03
+ */
+public interface PowerwindinfoMapper extends BaseMapper<Powerwindinfo> {
+
+}

+ 16 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/ProjectMapper.java

@@ -0,0 +1,16 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Project;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-02-03
+ */
+public interface ProjectMapper extends BaseMapper<Project> {
+
+}

+ 19 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/WindpowerstationMapper.java

@@ -0,0 +1,19 @@
+package com.gyee.power.fitting.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Windpowerstation;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-01
+ */
+@Mapper
+public interface WindpowerstationMapper extends BaseMapper<Windpowerstation> {
+
+}

+ 18 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/Windpowerstationtestingpoint2Mapper.java

@@ -0,0 +1,18 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Windpowerstationtestingpoint2;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author gfhd
+ * @since 2022-12-13
+ */
+@Mapper
+public interface Windpowerstationtestingpoint2Mapper extends BaseMapper<Windpowerstationtestingpoint2> {
+
+}

+ 19 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/WindturbineMapper.java

@@ -0,0 +1,19 @@
+package com.gyee.power.fitting.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Windturbine;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-01
+ */
+@Mapper
+public interface WindturbineMapper extends BaseMapper<Windturbine> {
+
+}

+ 18 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/Windturbinetestingpointai2Mapper.java

@@ -0,0 +1,18 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.Windturbinetestingpointai2;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-01
+ */
+@Mapper
+public interface Windturbinetestingpointai2Mapper extends BaseMapper<Windturbinetestingpointai2> {
+
+}

+ 92 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/AgcDeviateModel.java

@@ -0,0 +1,92 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+@TableName("controlsettings")
+public class AgcDeviateModel extends Model<AgcDeviateModel> {
+    /**
+     * 唯一ID
+     */
+    @Id
+    @Column(name = "ID")
+    private String id;
+    /**
+     * key
+     */
+    @Column(name = "KEY")
+    private String key;
+    /**
+     * 时间戳
+     */
+    @Column(name = "TIMESTAMP")
+    private Long timestamp;
+    /**
+     * 说明,描述
+     */
+    @Column(name = "DESCRIPTION")
+    private String description;
+    /**
+     * 值
+     */
+    @Column(name = "VALUE")
+    private String value;
+
+    /**
+     * 是否是备份
+     */
+    @Column(name = "BACKUP")
+    private boolean backup;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public boolean getBackup() {
+        return backup;
+    }
+
+    public void setBackup(boolean backup) {
+        this.backup = backup;
+    }
+
+}

+ 72 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Equipmentmodel.java

@@ -0,0 +1,72 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-08
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("EQUIPMENTMODEL")
+public class Equipmentmodel extends Model<Equipmentmodel> {
+
+    private static final long serialVersionUID=1L;
+
+      @TableId("ID")
+    private String id;
+
+    @TableField("CODE")
+    private String code;
+
+    @TableField("NAME")
+    private String name;
+
+    @TableField("DESCRIPTION")
+    private String description;
+
+    @TableField("POWERPRODUCTION")
+    private Double powerproduction;
+
+    @TableField("CUTINWINDSPEED")
+    private Double cutinwindspeed;
+
+    @TableField("RATEDWINDSPEED")
+    private Double ratedwindspeed;
+
+    @TableField("CUTOUTWINDSPEED")
+    private Double cutoutwindspeed;
+
+    @TableField("WINDTURBINEMANUFACTURERID")
+    private String windturbinemanufacturerid;
+
+    @TableField("PHOTO")
+    private String photo;
+
+    @TableField("UNIT")
+    private String unit;
+
+    //扫风面积
+    @TableField("SWEPTAREA")
+    private Double sweptarea;
+
+    @TableField("EQUIPMENTCATEGORY")
+    private String equipmentcategory;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 60 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Line.java

@@ -0,0 +1,60 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-02-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("LINE")
+public class Line extends Model<Line> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId("ID")
+    private String id;
+
+    @TableField("CODE")
+    private String code;
+
+    @TableField("NAME")
+    private String name;
+
+    @TableField("ANAME")
+    private String aname;
+
+    @TableField("PROJECTID")
+    private String projectid;
+
+    @TableField("ORDERNUM")
+    private String ordernum;
+
+    @TableField("CAPACITY")
+    private String capacity;
+
+    @TableField("CAPACITYUNIT")
+    private String capacityunit;
+
+    @TableField("QUANTITY")
+    private String quantity;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 47 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Modelpowerdetails.java

@@ -0,0 +1,47 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-08
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("MODELPOWERDETAILS")
+public class Modelpowerdetails extends Model<Modelpowerdetails> {
+
+    private static final long serialVersionUID=1L;
+
+      @TableId("ID")
+    private String id;
+
+    @TableField("MODELID")
+    private String modelid;
+
+    @TableField("SPEED")
+    private Double speed;
+
+    @TableField("THEORYPOWER")
+    private Double theorypower;
+
+    @TableField("ENSUREPOWER")
+    private Double ensurepower;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 78 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Photovoltaiccapacity.java

@@ -0,0 +1,78 @@
+package com.gyee.power.fitting.model;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author gfhd
+ * @since 2022-12-13
+ */
+public class Photovoltaiccapacity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String id;
+
+    private Short branchesnum;
+
+    private Integer platesnum;
+
+    private BigDecimal ratedcapacity;
+
+    private String stationid;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Short getBranchesnum() {
+        return branchesnum;
+    }
+
+    public void setBranchesnum(Short branchesnum) {
+        this.branchesnum = branchesnum;
+    }
+
+    public Integer getPlatesnum() {
+        return platesnum;
+    }
+
+    public void setPlatesnum(Integer platesnum) {
+        this.platesnum = platesnum;
+    }
+
+    public BigDecimal getRatedcapacity() {
+        return ratedcapacity;
+    }
+
+    public void setRatedcapacity(BigDecimal ratedcapacity) {
+        this.ratedcapacity = ratedcapacity;
+    }
+
+    public String getStationid() {
+        return stationid;
+    }
+
+    public void setStationid(String stationid) {
+        this.stationid = stationid;
+    }
+
+    @Override
+    public String toString() {
+        return "Photovoltaiccapacity{" +
+            "id = " + id +
+            ", branchesnum = " + branchesnum +
+            ", platesnum = " + platesnum +
+            ", ratedcapacity = " + ratedcapacity +
+            ", stationid = " + stationid +
+        "}";
+    }
+}

+ 77 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Photovoltaiciv.java

@@ -0,0 +1,77 @@
+package com.gyee.power.fitting.model;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author gfhd
+ * @since 2022-12-13
+ */
+public class Photovoltaiciv implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String id;
+
+    private String windturbineid;
+
+    private Short branchnum;
+
+    private String electric;
+
+    private String description;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getWindturbineid() {
+        return windturbineid;
+    }
+
+    public void setWindturbineid(String windturbineid) {
+        this.windturbineid = windturbineid;
+    }
+
+    public Short getBranchnum() {
+        return branchnum;
+    }
+
+    public void setBranchnum(Short branchnum) {
+        this.branchnum = branchnum;
+    }
+
+    public String getElectric() {
+        return electric;
+    }
+
+    public void setElectric(String electric) {
+        this.electric = electric;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public String toString() {
+        return "Photovoltaiciv{" +
+            "id = " + id +
+            ", windturbineid = " + windturbineid +
+            ", branchnum = " + branchnum +
+            ", electric = " + electric +
+            ", description = " + description +
+        "}";
+    }
+}

+ 93 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Powerfittinganalysis.java

@@ -0,0 +1,93 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("POWERFITTINGANALYSIS")
+public class Powerfittinganalysis extends Model<Powerfittinganalysis> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableField("ID")
+    private String id;
+
+    @TableField("STATION")
+    private String station;
+
+    @TableField("STATIONCN")
+    private String stationcn;
+
+    @TableField("WINDTURBINE")
+    private String windturbine;
+
+    @TableField("CODE")
+    private String code;
+
+    @TableField("INTERVAL")
+    private String interval;
+
+    @TableField("TIME")
+    private String time;
+
+    @TableField("PATH")
+    private String path;
+
+    @TableField("TYPE")
+    private String type;
+
+    @TableField("PROCESSID")
+    private String processid;
+
+    @TableField("CPAVG")
+    private Double cpavg;
+
+    @TableField("SPEEDAVG")
+    private Double speedavg;
+
+    @TableField("FREQUENCY")
+    private Double frequency;
+
+    @TableField("PCRATIO")
+    private Double pcratio;
+
+    @TableField("PC5RATIO")
+    private Double pc5ratio;
+
+    @TableField("PC10RATIO")
+    private Double pc10ratio;
+
+    @TableField("PC12RATIO")
+    private Double pc12ratio;
+
+    @TableField("PC25RATIO")
+    private Double pc25ratio;
+
+    @TableField("INTERP")
+    private Integer interp; //等间隔时间,单位:秒
+
+    @TableField("ISCAL")
+    private Integer iscal = 0;  //0-没有计算  1-已计算
+//
+//    @TableField("ISPROCESS")
+//    private Integer isprocess = 0;  //0-没有计算  1-已计算
+
+    @Override
+    protected Serializable pkVal() {
+        return null;
+    }
+
+}

+ 77 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Powerlossinfo.java

@@ -0,0 +1,77 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-02-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("POWERLOSSINFO")
+public class Powerlossinfo extends Model<Powerlossinfo> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableField("ID")
+    private String id;
+
+    @TableField("WINDTURBINEID")
+    private String windturbineid;
+
+    @TableField("PROJECTID")
+    private String projectid;
+
+    @TableField("LINEID")
+    private String lineid;
+
+    @TableField("STATIONID")
+    private String stationid;
+
+    @TableField("RECORDDATE")
+    private Date recorddate;
+
+    @TableField("GENECAPACITY")
+    private double genecapacity;
+
+    @TableField("THEROGENECAPACITY")
+    private double therogenecapacity;
+
+    @TableField("SPEED")
+    private double speed;
+
+    @TableField("DAYSLSSDL")
+    private double dayslssdl;
+
+    @TableField("DAYJHJXSSDL")
+    private double dayjhjxssdl;
+
+    @TableField("DAYFJHJXSSDL")
+    private double dayfjhjxssdl;
+
+    @TableField("DAYXDSSDL")
+    private double dayxdssdl;
+
+    @TableField("DAYXNSSDL")
+    private double dayxnssdl;
+
+    @TableField("DAYGZSSDL")
+    private double daygzssdl;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return null;
+    }
+
+}

+ 47 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Powermodel.java

@@ -0,0 +1,47 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 自算---------拟合功率
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-02-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("POWERMODEL")
+public class Powermodel extends Model<Powermodel> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableField("ID")
+    private String id;
+
+    @TableField("WINDTURBINEID")
+    private String windturbineid;
+
+    @TableField("SPEED")
+    private double speed;
+
+    @TableField("POWER")
+    private double power;
+
+    @TableField("MODEL")
+    private String model;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return null;
+    }
+
+}

+ 57 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Powerwindinfo.java

@@ -0,0 +1,57 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-03-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("POWERWINDINFO")
+public class Powerwindinfo extends Model<Powerwindinfo> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableField("ID")
+    private String id;
+
+    @TableField("STATION")
+    private String station;
+
+    @TableField("WINDTURBINE")
+    private String windturbine;
+
+    @TableField("TIME")
+    private String time;
+
+    /**
+     * 平均风速
+     */
+    @TableField("AVGSPEED")
+    private Double avgspeed;
+
+    /**
+     * 毛容系数
+     */
+    @TableField("MRXS")
+    private Double mrxs;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return null;
+    }
+
+}

+ 76 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Project.java

@@ -0,0 +1,76 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2023-02-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("PROJECT")
+public class Project extends Model<Project> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId("ID")
+    private String id;
+
+    @TableField("CODE")
+    private String code;
+
+    @TableField("NAME")
+    private String name;
+
+    @TableField("ANAME")
+    private String aname;
+
+    @TableField("WINDPOWERSTATIONID")
+    private String windpowerstationid;
+
+    @TableField("CAPACITY")
+    private String capacity;
+
+    @TableField("CAPACITYUNIT")
+    private String capacityunit;
+
+    @TableField("QUANTITY")
+    private String quantity;
+
+    @TableField("MODEL")
+    private String model;
+
+    @TableField("COMMISSIONDATE")
+    private LocalDate commissiondate;
+
+    @TableField("MASTERPHONE")
+    private String masterphone;
+
+    @TableField("SHIFTFOREMAN")
+    private String shiftforeman;
+
+    @TableField("SHIFTFOREMANPHONE")
+    private String shiftforemanphone;
+
+    @TableField("ORDERNUM")
+    private String ordernum;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 97 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Windpowerstation.java

@@ -0,0 +1,97 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import java.util.Date;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-01
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("WINDPOWERSTATION")
+public class Windpowerstation extends Model<Windpowerstation> {
+
+    private static final long serialVersionUID=1L;
+
+      @TableId("ID")
+    private String id;
+
+    @TableField("CODE")
+    private String code;
+
+    @TableField("NAME")
+    private String name;
+
+    @TableField("ADDRESS")
+    private String address;
+
+    @TableField("TELEPHONE")
+    private String telephone;
+
+    @TableField("CAPACITY")
+    private String capacity;
+
+    @TableField("CAPACITYUNIT")
+    private String capacityunit;
+
+    @TableField("QUANTITY")
+    private String quantity;
+
+    @TableField("ANAME")
+    private String aname;
+
+    @TableField("LONGITUDE")
+    private String longitude;
+
+    @TableField("LATITUDE")
+    private String latitude;
+
+    @TableField("PHOTO")
+    private String photo;
+
+    @TableField("COMPANYID")
+    private String companyid;
+
+    @TableField("SYSTEMMANUFACT")
+    private String systemmanufact;
+
+    @TableField("HEADFARM")
+    private String headfarm;
+
+    @TableField("HEADFARMPHONE")
+    private String headfarmphone;
+
+    @TableField("MODEL")
+    private String model;
+
+    @TableField("ORDERNUM")
+    private String ordernum;
+
+    @TableField("ALTITUDE")
+    private String altitude;
+
+    @TableField("HEIGHT")
+    private String height;
+
+//    @TableField("AQTS")
+//    private Date aqts;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 199 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Windpowerstationtestingpoint2.java

@@ -0,0 +1,199 @@
+package com.gyee.power.fitting.model;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author gfhd
+ * @since 2022-12-13
+ */
+public class Windpowerstationtestingpoint2 implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String code;
+
+    private String name;
+
+    private String model;
+
+    private String valueunit;
+
+    private String englishname;
+
+    private String typeid;
+
+    private String modelid;
+
+    private BigDecimal maxval;
+
+    private BigDecimal minval;
+
+    private BigDecimal reasonablemaxval;
+
+    private BigDecimal reasonableminval;
+
+    private String uniformcode;
+
+    private String shortid;
+
+    private String longid;
+
+    private String windpowerstationid;
+
+    private String realtimeid;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getModel() {
+        return model;
+    }
+
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    public String getValueunit() {
+        return valueunit;
+    }
+
+    public void setValueunit(String valueunit) {
+        this.valueunit = valueunit;
+    }
+
+    public String getEnglishname() {
+        return englishname;
+    }
+
+    public void setEnglishname(String englishname) {
+        this.englishname = englishname;
+    }
+
+    public String getTypeid() {
+        return typeid;
+    }
+
+    public void setTypeid(String typeid) {
+        this.typeid = typeid;
+    }
+
+    public String getModelid() {
+        return modelid;
+    }
+
+    public void setModelid(String modelid) {
+        this.modelid = modelid;
+    }
+
+    public BigDecimal getMaxval() {
+        return maxval;
+    }
+
+    public void setMaxval(BigDecimal maxval) {
+        this.maxval = maxval;
+    }
+
+    public BigDecimal getMinval() {
+        return minval;
+    }
+
+    public void setMinval(BigDecimal minval) {
+        this.minval = minval;
+    }
+
+    public BigDecimal getReasonablemaxval() {
+        return reasonablemaxval;
+    }
+
+    public void setReasonablemaxval(BigDecimal reasonablemaxval) {
+        this.reasonablemaxval = reasonablemaxval;
+    }
+
+    public BigDecimal getReasonableminval() {
+        return reasonableminval;
+    }
+
+    public void setReasonableminval(BigDecimal reasonableminval) {
+        this.reasonableminval = reasonableminval;
+    }
+
+    public String getUniformcode() {
+        return uniformcode;
+    }
+
+    public void setUniformcode(String uniformcode) {
+        this.uniformcode = uniformcode;
+    }
+
+    public String getShortid() {
+        return shortid;
+    }
+
+    public void setShortid(String shortid) {
+        this.shortid = shortid;
+    }
+
+    public String getLongid() {
+        return longid;
+    }
+
+    public void setLongid(String longid) {
+        this.longid = longid;
+    }
+
+    public String getWindpowerstationid() {
+        return windpowerstationid;
+    }
+
+    public void setWindpowerstationid(String windpowerstationid) {
+        this.windpowerstationid = windpowerstationid;
+    }
+
+    public String getRealtimeid() {
+        return realtimeid;
+    }
+
+    public void setRealtimeid(String realtimeid) {
+        this.realtimeid = realtimeid;
+    }
+
+    @Override
+    public String toString() {
+        return "Windpowerstationtestingpoint2{" +
+            "code = " + code +
+            ", name = " + name +
+            ", model = " + model +
+            ", valueunit = " + valueunit +
+            ", englishname = " + englishname +
+            ", typeid = " + typeid +
+            ", modelid = " + modelid +
+            ", maxval = " + maxval +
+            ", minval = " + minval +
+            ", reasonablemaxval = " + reasonablemaxval +
+            ", reasonableminval = " + reasonableminval +
+            ", uniformcode = " + uniformcode +
+            ", shortid = " + shortid +
+            ", longid = " + longid +
+            ", windpowerstationid = " + windpowerstationid +
+            ", realtimeid = " + realtimeid +
+        "}";
+    }
+}

+ 73 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Windturbine.java

@@ -0,0 +1,73 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import java.util.Date;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-01
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("WINDTURBINE")
+public class Windturbine extends Model<Windturbine> {
+
+    private static final long serialVersionUID=1L;
+
+      @TableId("ID")
+    private String id;
+
+    @TableField("CODE")
+    private String code;
+
+    @TableField("WINDPOWERSTATIONID")
+    private String windpowerstationid;
+
+    @TableField("LONGITUDE")
+    private String longitude;
+
+    @TableField("LATITUDE")
+    private String latitude;
+
+    @TableField("MODELID")
+    private String modelid;
+
+    @TableField("STATUS")
+    private String status;
+
+    @TableField("PROJECTID")
+    private String projectid;
+
+    @TableField("LINEID")
+    private String lineid;
+
+    @TableField("FIRSTINTEGRATEDTIME")
+    private String firstintegratedtime;
+
+    @TableField("PHOTO")
+    private String photo;
+
+    @TableField("NAME")
+    private String name;
+
+    @TableField("STANDARDID")
+    private String standardid;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 86 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/Windturbinetestingpointai2.java

@@ -0,0 +1,86 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author chenmh
+ * @since 2022-11-01
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("WINDTURBINETESTINGPOINTAI2")
+public class Windturbinetestingpointai2 extends Model<Windturbinetestingpointai2> {
+
+    private static final long serialVersionUID=1L;
+
+      @TableId("ID")
+    private String id;
+
+    @TableField("CODE")
+    private String code;
+
+    @TableField("NAME")
+    private String name;
+
+    @TableField("MODEL")
+    private String model;
+
+    @TableField("VALUEUNIT")
+    private String valueunit;
+
+    @TableField("ENGLISHNAME")
+    private String englishname;
+
+    @TableField("TYPEID")
+    private String typeid;
+
+    @TableField("MODELID")
+    private String modelid;
+
+    @TableField("MAXVAL")
+    private String maxval;
+
+    @TableField("MINVAL")
+    private String minval;
+
+    @TableField("REASONABLEMAXVAL")
+    private String reasonablemaxval;
+
+    @TableField("REASONABLEMINVAL")
+    private String reasonableminval;
+
+    @TableField("WINDTURBINEID")
+    private String windturbineid;
+
+    @TableField("UNIFORMCODE")
+    private String uniformcode;
+
+    @TableField("SHORTID")
+    private String shortid;
+
+    @TableField("LONGID")
+    private String longid;
+
+    @TableField("WINDPOWERSTATIONID")
+    private String windpowerstationid;
+
+    @TableField("REALTIMEID")
+    private String realtimeid;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 48 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/AgcDeviateConfig.java

@@ -0,0 +1,48 @@
+package com.gyee.power.fitting.model.agc;
+
+public class AgcDeviateConfig {
+
+    private String id;
+    /**
+     * 装机容量
+     */
+    private float installedCapacity;
+    /**
+     * 场站名称
+     */
+    private String title;
+
+    private AiPoints[] aiPoints;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public float getInstalledCapacity() {
+        return installedCapacity;
+    }
+
+    public void setInstalledCapacity(float installedCapacity) {
+        this.installedCapacity = installedCapacity;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public AiPoints[] getAiPoints() {
+        return aiPoints;
+    }
+
+    public void setAiPoints(AiPoints[] aiPoints) {
+        this.aiPoints = aiPoints;
+    }
+}

+ 33 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/AgcDeviateTag.java

@@ -0,0 +1,33 @@
+package com.gyee.power.fitting.model.agc;
+
+import java.util.List;
+
+/**
+ * agc曲线偏差数据
+ */
+public class AgcDeviateTag {
+    /**
+     * 数据点名称
+     */
+    private String name;
+    /**
+     * 数据值列表
+     */
+    private List<PointData> values;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<PointData> getValues() {
+        return values;
+    }
+
+    public void setValues(List<PointData> values) {
+        this.values = values;
+    }
+}

+ 56 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/AiPoints.java

@@ -0,0 +1,56 @@
+package com.gyee.power.fitting.model.agc;
+
+/**
+ * 从数据库的value里面取到需要的值
+ */
+public class AiPoints {
+
+    private String name;
+    /**
+     * 标签点
+     */
+    private String tag;
+    /**
+     * 倍率
+     */
+    private float multiplier;
+    /**
+     * 单位
+     */
+    private String unit;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        if (name == null) {
+            return;
+        }
+        this.name = name.replaceAll(":","");
+    }
+
+    public String getTag() {
+        return tag;
+    }
+
+    public void setTag(String tag) {
+        this.tag = tag;
+    }
+
+    public float getMultiplier() {
+        return multiplier;
+    }
+
+    public void setMultiplier(float multiplier) {
+        this.multiplier = multiplier;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+}

+ 35 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/PointData.java

@@ -0,0 +1,35 @@
+package com.gyee.power.fitting.model.agc;
+
+/**
+ * 测点数据
+ */
+public class PointData {
+    /**
+     * 时间戳
+     */
+    private long ts;
+    /**
+     * 数据
+     */
+    private double doubleValue;
+
+    public long getTs() {
+        return ts;
+    }
+
+    public void setTs(long ts) {
+        this.ts = ts;
+    }
+
+    public double getValue() {
+        return doubleValue;
+    }
+
+    public double getDoubleValue() {
+        return doubleValue;
+    }
+
+    public void setDoubleValue(double doubleValue) {
+        this.doubleValue = doubleValue;
+    }
+}

+ 76 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/anno/AnnotationTool.java

@@ -0,0 +1,76 @@
+package com.gyee.power.fitting.model.anno;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * 注解工具类,提供解析注解的方法
+ */
+public class AnnotationTool {
+
+    /**
+     * 获取打了Desc注解的字典属性列表
+     * @return 字典属性列表
+     */
+    public static <T> List<FixedVo> getFixedVoList(Class<T> c) {
+        if (c == null) {
+            return Collections.emptyList();
+        }
+        try {
+            T cls = c.newInstance();
+            Field[] fields = c.getDeclaredFields();
+            List<FixedVo> fixedVoList = new LinkedList<>();
+            for (Field field : fields) {
+                //使私有对象可以访问
+                field.setAccessible(true);
+                Desc desc = field.getAnnotation(Desc.class);
+                if (desc != null) {
+                    FixedVo vo = new FixedVo();
+                    vo.setKey(String.valueOf(field.get(cls)));
+                    vo.setName(field.getName());
+                    vo.setDes(desc.des());
+                    vo.setUniformCode(desc.uniformCode());
+                    vo.setRemark(desc.remark());
+                    fixedVoList.add(vo);
+                }
+            }
+            return fixedVoList;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * 通过反射获取值
+     * @param object
+     * @return
+     */
+    public static List<FixedVo> getValueList(Object object) {
+        if (object == null) {
+            return Collections.emptyList();
+        }
+        try {
+            Field[] fields = object.getClass().getDeclaredFields();
+            List<FixedVo> fixedVoList = new LinkedList<>();
+            for (Field field : fields) {
+                //使私有对象可以访问
+                field.setAccessible(true);
+                Desc desc = field.getAnnotation(Desc.class);
+                if (desc != null) {
+                    FixedVo vo = new FixedVo();
+                    Object o = field.get(object);
+                    vo.setKey(String.valueOf(o));
+                    vo.setRemark(desc.remark());
+                    fixedVoList.add(vo);
+                }
+            }
+            return fixedVoList;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Collections.emptyList();
+    }
+}

+ 22 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/anno/Desc.java

@@ -0,0 +1,22 @@
+package com.gyee.power.fitting.model.anno;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * 配置通过注解
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Desc {
+
+    String des();
+
+    String uniformCode() default "";
+
+    String remark () default "";
+
+}

+ 28 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/anno/FixedVo.java

@@ -0,0 +1,28 @@
+package com.gyee.power.fitting.model.anno;
+
+import lombok.Data;
+
+/**
+ * 与注解属性对应的类 @Desc
+ */
+@Data
+public class FixedVo {
+
+    public String key;
+    public String name;
+    public String des;
+    public String uniformCode;
+    public String remark;
+
+
+    @Override
+    public String toString() {
+        return "FixedVo{" +
+                "key='" + key + '\'' +
+                ", name='" + name + '\'' +
+                ", des='" + des + '\'' +
+                ", uniformCode='" + uniformCode + '\'' +
+                ", remark='" + remark + '\'' +
+                '}';
+    }
+}

+ 64 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/FjjxbVo.java

@@ -0,0 +1,64 @@
+package com.gyee.power.fitting.model.custom;
+
+import com.gyee.power.fitting.model.Powerlossinfo;
+import com.gyee.power.fitting.model.anno.Desc;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+@Data
+public class FjjxbVo implements ToData<List<Powerlossinfo>> {
+
+    private String id;
+    @Desc(des = "名称")
+    private String name;
+    @Desc(des = "理论发电量(万kWh)")
+    private double llfdl;
+    @Desc(des = "实际发电量(万kWh)")
+    private double sjfdl;
+    @Desc(des = "平均风速(m/s)")
+    private double speed;
+    @Desc(des = "计划检修(万kWh)")
+    private double fjhjx;
+    @Desc(des = "非计划检修(万kWh)")
+    private double jhjx;
+    @Desc(des = "受累(万kWh)")
+    private double sl;
+    @Desc(des = "限电(万kWh)")
+    private double xd;
+    @Desc(des = "性能(万kWh)")
+    private double xn;
+    @Desc(des = "风能利用率(%)")
+    private double fnlly;
+
+
+    @Override
+    public FjjxbVo toData(List<Powerlossinfo> ls) {
+        FjjxbVo vo = new FjjxbVo();
+
+        double fdl = ls.stream().mapToDouble(Powerlossinfo::getGenecapacity).sum();
+        double llfdl = ls.stream().mapToDouble(Powerlossinfo::getTherogenecapacity).sum();
+        double speed = ls.stream().mapToDouble(Powerlossinfo::getSpeed).average().getAsDouble();
+        double fjh = ls.stream().mapToDouble(Powerlossinfo::getDayfjhjxssdl).sum();
+        double jh = ls.stream().mapToDouble(Powerlossinfo::getDayjhjxssdl).sum();
+        double sl = ls.stream().mapToDouble(Powerlossinfo::getDayslssdl).sum();
+        double xd = ls.stream().mapToDouble(Powerlossinfo::getDayxdssdl).sum();
+        double xn = ls.stream().mapToDouble(Powerlossinfo::getDayxnssdl).sum();
+        vo.setLlfdl(new BigDecimal(llfdl / 10000).setScale(2, RoundingMode.CEILING).doubleValue());
+        vo.setSjfdl(new BigDecimal(fdl / 10000).setScale(2, RoundingMode.CEILING).doubleValue());
+        vo.setSpeed(new BigDecimal(speed).setScale(2, RoundingMode.CEILING).doubleValue());
+        vo.setFjhjx(new BigDecimal(fjh / 10000).setScale(2, RoundingMode.CEILING).doubleValue());
+        vo.setJhjx(new BigDecimal(jh / 10000).setScale(2, RoundingMode.CEILING).doubleValue());
+        vo.setSl(new BigDecimal(sl / 10000).setScale(2, RoundingMode.CEILING).doubleValue());
+        vo.setXd(new BigDecimal(xd / 10000).setScale(2, RoundingMode.CEILING).doubleValue());
+        vo.setXn(new BigDecimal(xn / 10000).setScale(2, RoundingMode.CEILING).doubleValue());
+        if (llfdl > 0)
+            vo.setFnlly(new BigDecimal((fdl / llfdl) * 100).setScale(2, RoundingMode.CEILING).doubleValue());
+        else
+            vo.setFnlly(82.35);
+
+        return vo;
+    }
+}

+ 35 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/LineCurveFitting.java

@@ -0,0 +1,35 @@
+package com.gyee.power.fitting.model.custom;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class LineCurveFitting {
+
+    public String name;
+    public List<Point> lines;
+    public List<Point> YLines;
+
+    public List<Point> point;
+    public List<Point> YPoint;
+
+    /// <summary>
+    /// 推力系数
+    /// </summary>
+    public List<Point> CpValue;
+    /// <summary>
+    /// 推力系数平均值
+    /// </summary>
+    public double CpAvg;
+    /// <summary>
+    /// 平均风速
+    /// </summary>
+    public double speed;
+
+    /// <summary>
+    /// 静风频率
+    /// </summary>
+    public double frequency;
+
+}

+ 63 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PhotovoltaicInfo.java

@@ -0,0 +1,63 @@
+package com.gyee.power.fitting.model.custom;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.gyee.power.fitting.model.anno.Desc;
+import lombok.Data;
+
+@Data
+public class PhotovoltaicInfo {
+
+    @Desc(des = "场站")
+    private String station;
+    @Desc(des = "逆变器")
+    private String inverter;
+    private String branch;//支路
+    private long time;//时间
+    @Desc(des = "时间")
+    private String datetime;
+    @Desc(des = "组件温度")
+    @JsonProperty("T")
+    private double T;
+    @Desc(des = "光照强度")
+    @JsonProperty("S")
+    private double S;
+
+    @Desc(des = "电流")
+    @JsonProperty("I")
+    private double I;
+    @Desc(des = "电压")
+    @JsonProperty("V")
+    private double V;
+    @JsonProperty("P")
+    private double P;
+    @Desc(des = "功率")
+    private double actualP;
+    private double ideaP;
+
+    @Desc(des = "A相电流")
+    @JsonProperty("aI")
+    private double aI;
+    @Desc(des = "A相电压")
+    @JsonProperty("aV")
+    private double aV;
+    @Desc(des = "B相电流")
+    @JsonProperty("bI")
+    private double bI;
+    @Desc(des = "B相电压")
+    @JsonProperty("bV")
+    private double bV;
+    @Desc(des = "C相电流")
+    @JsonProperty("cI")
+    private double cI;
+    @Desc(des = "C相电压")
+    @JsonProperty("cV")
+    private double cV;
+
+    /*public double getP() {
+        if (I != 0 && V != 0) {
+            return I * V;
+        } else {
+            return this.P;
+        }
+    }*/
+}

+ 16 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/Point.java

@@ -0,0 +1,16 @@
+package com.gyee.power.fitting.model.custom;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Point {
+
+    private double x;
+
+    private double y;
+
+}

+ 19 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PointVo.java

@@ -0,0 +1,19 @@
+package com.gyee.power.fitting.model.custom;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PointVo {
+
+    private double x;
+
+    private double y;
+
+    private double s;
+
+    private String k;
+}

+ 36 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PowerFittingData.java

@@ -0,0 +1,36 @@
+package com.gyee.power.fitting.model.custom;
+
+import com.gyee.power.fitting.model.anno.Desc;
+import lombok.Data;
+
+/**
+ * 拟合后对应的曲线 model
+ */
+@Data
+public class PowerFittingData {
+
+    public PowerFittingData(){}
+
+    public PowerFittingData(String[] str) {
+        if (str.length >= 2){
+            this.speed = Double.valueOf(str[0]);
+            this.nhdata = Double.valueOf(str[1]);
+            this.cpdata = ((double)((int)(Double.valueOf(str[2])*1000)))/1000;
+        }
+    }
+
+
+    //风速
+    @Desc(des = "风速", remark = "1")
+    private Double speed;
+    //拟合功率
+    @Desc(des = "拟合功率", remark = "1")
+    private Double nhdata;
+    //修正数据
+    @Desc(des = "修正功率", remark = "0")
+    private Double xzdata;
+    //cp值
+    @Desc(des = "Cp值", remark = "1")
+    private Double cpdata;
+
+}

+ 106 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PowerPointData.java

@@ -0,0 +1,106 @@
+package com.gyee.power.fitting.model.custom;
+
+import com.gyee.power.fitting.model.anno.Desc;
+import lombok.Data;
+
+import java.text.DecimalFormat;
+
+/**
+ * 数据准备的测点
+ * remark  0:表示该字段不在前端显示  1:表示该字段在前端显示
+ */
+@Data
+public class PowerPointData {
+
+    public PowerPointData(){}
+
+    public PowerPointData(String[] str, boolean isFilter){
+        DecimalFormat df = new DecimalFormat("0.00");
+        if (str.length >= 9){
+            this.time = str[0];
+            this.power = Double.valueOf(df.format(Double.valueOf(str[1])));
+            this.speed = Double.valueOf(df.format(Double.valueOf(str[2])));
+            this.rr = Double.valueOf(df.format(Double.valueOf(str[3])));
+            this.mxzt = Double.valueOf(str[4]).intValue();
+            this.dl = Double.valueOf(df.format(Double.valueOf(str[5])));
+            this.qfzt = Double.valueOf(str[6]).intValue();
+            this.fx = Double.valueOf(df.format(Double.valueOf(str[7])));
+            this.dfwc = Double.valueOf(df.format(Double.valueOf(str[8])));
+            this.angle = Double.valueOf(df.format(Double.valueOf(str[9])));
+            this.hjwd = Double.valueOf(df.format(Double.valueOf(str[10])));
+        }
+        if (isFilter)
+            this.filter = Integer.valueOf(str[str.length - 1]);
+    }
+
+    //时间
+    @Desc(des = "时间", remark = "1")
+    private String time = "1970-01-01 00:00:00";
+
+    //功率
+    @Desc(des = "功率", uniformCode = "AI130", remark = "1")
+    private double power = 0;
+
+    //风速
+    @Desc(des = "风速", uniformCode = "AI022", remark = "1")
+    private double speed = 0;
+
+    //转速
+    @Desc(des = "转速",  uniformCode = "AI128", remark = "1")
+    private double rr = 0;
+
+    //明细状态
+    // 0-待机  1-手动停机  2-正常发电  3-缺陷降出力  4-限电降出力  5-限电停机  6-故障停机
+    // 7-场内受累停机  8-检修停机  9-场内受累检修  10-电网受累  11-环境受累  12-风机离线
+    @Desc(des = "风机状态",  uniformCode = "ZTMX", remark = "1")
+    private int mxzt = 0;
+
+    //电量
+    @Desc(des = "电量",  uniformCode = "RFDL", remark = "1")
+    private double dl = 0;
+
+    //欠发状态
+    @Desc(des = "欠发状态",  uniformCode = "RSSQFZT", remark = "1")
+    private int qfzt = 0;
+
+    //风向
+    @Desc(des = "风向",  uniformCode = "AI008", remark = "1")
+    private double fx = 0;
+
+    //对风误差
+    @Desc(des = "对风误差",  uniformCode = "AI036", remark = "1")
+    private double dfwc = 0;
+
+    //偏航角度
+    @Desc(des = "偏航角度",  uniformCode = "AI034", remark = "1")
+    private double angle = 0;
+
+    @Desc(des = "环境温度",  uniformCode = "AI056", remark = "1")
+    private double hjwd = 0;
+
+    //是否过滤  0:不过滤 1:过滤
+    @Desc(des = "筛选", remark = "0")
+    private int filter = 0;
+
+    private String wtId;
+
+    @Override
+    public String toString() {
+        return "PowerPointData{" +
+                "time='" + time + '\'' +
+                ", power=" + power +
+                ", speed=" + speed +
+                ", rr=" + rr +
+                ", mxzt=" + mxzt +
+                ", dl=" + dl +
+                ", qfzt=" + qfzt +
+                ", fx=" + fx +
+                ", dfwc=" + dfwc +
+                ", angle=" + angle +
+                ", hjwd=" + hjwd +
+                ", filter=" + filter +
+                ", wtId='" + wtId + '\'' +
+                '}';
+    }
+}
+

+ 29 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PowerTemperatureData.java

@@ -0,0 +1,29 @@
+package com.gyee.power.fitting.model.custom;
+
+import com.gyee.power.fitting.model.anno.Desc;
+import lombok.Data;
+
+@Data
+public class PowerTemperatureData {
+
+    public PowerTemperatureData(){}
+
+    public PowerTemperatureData(String[] str) {
+        if (str.length >= 2){
+            this.speed = Double.valueOf(str[0]);
+            this.power = Double.valueOf(str[1]);
+            this.hjwd = Double.valueOf(str[2]);
+        }
+    }
+
+
+    //风速
+    @Desc(des = "风速", remark = "1")
+    private Double speed;
+    //功率
+    @Desc(des = "功率", remark = "1")
+    private Double power;
+    //温度
+    @Desc(des = "温度", remark = "1")
+    private Double hjwd;
+}

+ 0 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/TableTitle.java


Some files were not shown because too many files changed in this diff