소스 검색

新增负载分析接口

fuyuchuan 1 주 전
부모
커밋
9bd7149688

+ 21 - 6
fiveep-controller/src/main/java/com/bizmatics/controller/web/SiteController.java

@@ -1,12 +1,13 @@
 package com.bizmatics.controller.web;
 
-
 import com.bizmatics.common.core.bean.ApiResult;
+import com.bizmatics.common.core.bean.CommonPage;
 import com.bizmatics.model.*;
 import com.bizmatics.service.SiteService;
 import com.bizmatics.service.aop.BusinessType;
 import com.bizmatics.service.aop.Log;
 import com.bizmatics.service.vo.DeviceCountVO;
+import com.bizmatics.service.vo.SiteLoadAnalysisVO;
 import com.bizmatics.service.vo.SiteVO;
 import com.bizmatics.service.vo.SiteVOT;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -61,7 +62,7 @@ public class SiteController {
     @GetMapping("list2")
     public ApiResult<List<SiteTwo>> list2(@RequestParam(required = false) String name,
                                           @RequestParam(required = false) Integer stationAreaId) {
-        return ApiResult.success(siteService.list2(name,stationAreaId));
+        return ApiResult.success(siteService.list2(name, stationAreaId));
     }
 
     /**
@@ -106,9 +107,9 @@ public class SiteController {
     @Log(title = "站点管理-基础信息", businessType = BusinessType.INSERT)
     @PostMapping("siteAdd")
     public ApiResult<Void> siteAdd(@RequestBody SiteVOT siteVOT) {
-        if (siteVOT.getId()==0){
+        if (siteVOT.getId() == 0) {
             siteService.siteAdd(siteVOT);
-        }else {
+        } else {
             siteService.siteUpdate(siteVOT);
         }
         return ApiResult.success();
@@ -122,7 +123,7 @@ public class SiteController {
     @Log(title = "站点管理-基础信息", businessType = BusinessType.DELETE)
     @GetMapping("siteDel")
     public ApiResult<Void> siteDel(@RequestParam(required = false) String id) {
-            siteService.sitedel(id);
+        siteService.sitedel(id);
         return ApiResult.success();
     }
 
@@ -142,7 +143,7 @@ public class SiteController {
      * @return
      */
     @GetMapping("sitelist")
-    public ApiResult<List<Map<String,Object>>> sitelist(@RequestParam(required = false) String name){
+    public ApiResult<List<Map<String, Object>>> sitelist(@RequestParam(required = false) String name) {
         return ApiResult.success(siteService.sitelist(name));
     }
 
@@ -167,5 +168,19 @@ public class SiteController {
     public ApiResult<List<Route>> dynamicPropertiesDroplist() {
         return ApiResult.success(siteService.routeDroplist());
     }
+
+    /**
+     * 站点管理-基础信息-站点负载分析
+     * @param siteId 站点ID
+     * @param pageNum 页码
+     * @param pageSize 每页数量
+     * @return 负载分析数据
+     */
+    @GetMapping("siteLoadAnalysis")
+    public ApiResult<CommonPage<SiteLoadAnalysisVO>> siteLoadAnalysis(@RequestParam(value = "siteId") Integer siteId,
+                                                                      @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+                                                                      @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
+        return ApiResult.success(siteService.siteLoadAnalysis(siteId, pageNum, pageSize));
+    }
 }
 

+ 14 - 21
fiveep-controller/src/main/resources/application-prod.properties

@@ -21,7 +21,7 @@ spring.datasource.dynamic.datasource.usky-power.url=jdbc:mysql://usky-cloud-mysq
 #spring.datasource.dynamic.datasource.usky-power.url=jdbc:mysql://101.133.214.75:3306/usky-electricity?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
 spring.datasource.dynamic.datasource.usky-power.username=usky
 spring.datasource.dynamic.datasource.usky-power.password=Yt#75Usky
-spring.datasource.dynamic.druid.initial-size=5                                                                       
+spring.datasource.dynamic.druid.initial-size=5
 spring.datasource.dynamic.druid.min-idle=5
 spring.datasource.dynamic.druid.max-active=30
 spring.datasource.dynamic.druid.max-wait=60000
@@ -63,13 +63,10 @@ spring.jackson.parser.allow-single-quotes=true
 # gzip
 server.compression.enabled=true
 server.compression.mime-types=application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
-
-
 #https://blog.csdn.net/haohaifeng002/article/details/102887921
 spring.elasticsearch.rest.uris=http://124.71.174.104:9200
 spring.elasticsearch.rest.username=
 spring.elasticsearch.rest.password=
-
 # ehcache
 spring.cache.ehcache.enabled=true
 spring.cache.ehcache.config=classpath:ehcache.xml
@@ -84,23 +81,19 @@ spring.redis.jedis.pool.max-active=1000
 spring.redis.jedis.pool.max-idle=300
 spring.redis.jedis.pool.min-idle=5
 spring.redis.jedis.pool.max-wait=1000
-
 # token
-token.header: accessToken
-token.secret: abcdefghijklmnopqrstuvwxyz
-token.expireTime: 144
-
+token.header:accessToken
+token.secret:abcdefghijklmnopqrstuvwxyz
+token.expireTime:144
 # xss
-xss.enabled: true
-xss.excludes: /system/notice
-xss.urlPatterns: /system/*,/monitor/*,/tool/*
-
+xss.enabled:true
+xss.excludes:/system/notice
+xss.urlPatterns:/system/*,/monitor/*,/tool/*
 # project
-wj.name: yq
-wj.version: 3.6.0
-wj.copyrightYear: 2021
-wj.demoEnabled: true
-wj.addressEnabled: false
-wj.captchaType: math
-
-spring.messages.basename= i18n/messages
+wj.name:yq
+wj.version:3.6.0
+wj.copyrightYear:2021
+wj.demoEnabled:true
+wj.addressEnabled:false
+wj.captchaType:math
+spring.messages.basename=i18n/messages

+ 43 - 5
fiveep-controller/src/main/resources/application-test.properties

@@ -1,8 +1,10 @@
 debug=true
 spring.main.lazy-initialization=false
 spring.main.allow-bean-definition-overriding=true
+#temp.basedir=/usr/local/service/usky-power/uskyfile
+temp.basedir=E:/uskyfile
 # application
-server.port=8008
+server.port=8011
 # mybatis-plus
 mybatis-plus.mapper-locations=classpath*:mapper/**/*.xml
 mybatis-plus.configuration.lazy-loading-enabled=true
@@ -16,10 +18,13 @@ mybatis.refresh.sleep-seconds=20
 # datasource
 spring.autoconfigure.exclude=com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
 spring.datasource.dynamic.primary=mast
-spring.datasource.dynamic.datasource.mast.url=jdbc:mysql://localhost:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
-spring.datasource.dynamic.datasource.mast.username=root
-spring.datasource.dynamic.datasource.mast.password=
-spring.datasource.dynamic.druid.initial-size=5                                                                       
+#spring.datasource.dynamic.datasource.mast.url=jdbc:mysql://usky-cloud-mysql:3306/usky-electricity?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
+#spring.datasource.dynamic.datasource.mast.username=root
+#spring.datasource.dynamic.datasource.mast.password=yt123456
+spring.datasource.dynamic.datasource.mast.url=jdbc:mysql://101.133.214.75:3306/usky-electricity?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
+spring.datasource.dynamic.datasource.mast.username=usky
+spring.datasource.dynamic.datasource.mast.password=Yt#75Usky
+spring.datasource.dynamic.druid.initial-size=5
 spring.datasource.dynamic.druid.min-idle=5
 spring.datasource.dynamic.druid.max-active=30
 spring.datasource.dynamic.druid.max-wait=60000
@@ -61,3 +66,36 @@ spring.jackson.parser.allow-single-quotes=true
 # gzip
 server.compression.enabled=true
 server.compression.mime-types=application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
+# ehcache
+spring.cache.ehcache.enabled=true
+spring.cache.ehcache.config=classpath:ehcache.xml
+# redis
+spring.cache.redis.enabled=true
+spring.redis.database=0
+#spring.redis.host=124.71.174.104
+spring.redis.host=usky-cloud-redis
+#spring.redis.port=6880
+spring.redis.port=6379
+#spring.redis.password=usky@208
+spring.redis.password=123456
+spring.redis.timeout=10000
+spring.redis.jedis.pool.max-active=1000
+spring.redis.jedis.pool.max-idle=300
+spring.redis.jedis.pool.min-idle=5
+spring.redis.jedis.pool.max-wait=1000
+# token
+token.header:accessToken
+token.secret:abcdefghijklmnopqrstuvwxyz
+token.expireTime:144
+# xss
+xss.enabled:true
+xss.excludes:/system/notice
+xss.urlPatterns:/system/*,/monitor/*,/tool/*
+# project
+wj.name:yq
+wj.version:3.6.0
+wj.copyrightYear:2021
+wj.demoEnabled:true
+wj.addressEnabled:false
+wj.captchaType:math
+spring.messages.basename=i18n/messages

+ 1 - 1
fiveep-controller/src/main/resources/application.properties

@@ -1,5 +1,5 @@
 # common
-spring.profiles.active=dev
+spring.profiles.active=test
 spring.application.name=usky-power
 spring.main.banner-mode=off
 mybatis-plus.global-config.banner=false

+ 7 - 2
fiveep-model/src/main/java/com/bizmatics/model/DeviceList.java

@@ -13,7 +13,7 @@ import java.util.Date;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
  * @author ya
@@ -24,7 +24,7 @@ import java.util.Date;
 @Accessors(chain = true)
 public class DeviceList implements Serializable {
 
-    private static final long serialVersionUID=1L;
+    private static final long serialVersionUID = 1L;
 
     /**
      * 设备信息表ID
@@ -114,4 +114,9 @@ public class DeviceList implements Serializable {
      * 电能质量分析
      */
     private String qualityAnalysis;
+
+    /**
+     * 上报时间
+     */
+    private LocalDateTime dateTime;
 }

+ 0 - 2
fiveep-model/src/main/java/com/bizmatics/model/HtAnalogData.java

@@ -1,9 +1,7 @@
 package com.bizmatics.model;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import java.time.LocalDate;
 import com.baomidou.mybatisplus.annotation.TableId;
-import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
 import java.io.Serializable;
 import java.util.Date;

+ 7 - 7
fiveep-persistence/src/main/java/com/bizmatics/persistence/mapper/HtAnalogDataMapper.java

@@ -3,12 +3,10 @@ package com.bizmatics.persistence.mapper;
 import com.bizmatics.common.mvc.base.CrudMapper;
 import com.bizmatics.model.Device;
 import com.bizmatics.model.HtAnalogData;
-import com.bizmatics.model.vo.ContextualDataVo;
-import com.bizmatics.model.vo.HtAnalogDataOneVo;
-import com.bizmatics.model.vo.HtAnalogDataVo;
-import com.bizmatics.model.vo.SingleLoopReportVo;
+import com.bizmatics.model.vo.*;
 import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 import org.springframework.stereotype.Repository;
 
 import java.util.Date;
@@ -132,9 +130,9 @@ public interface HtAnalogDataMapper extends CrudMapper<HtAnalogData> {
                                              @Param("table") String table);
 
     List<HtAnalogData> getDemandAnalysisList1(@Param("deviceCode") String deviceCode,
-                                             @Param("startTime") String startTime,
-                                             @Param("endTime") String endTime,
-                                             @Param("table") String table);
+                                              @Param("startTime") String startTime,
+                                              @Param("endTime") String endTime,
+                                              @Param("table") String table);
 
     List<HtAnalogDataOneVo> energyUseListOne(@Param("deviceCode") String deviceCode,
                                              @Param("startTime") String startTime,
@@ -178,4 +176,6 @@ public interface HtAnalogDataMapper extends CrudMapper<HtAnalogData> {
                                            @Param("startTime") String startTime,
                                            @Param("endTime") String endTime,
                                            @Param("table") String table);
+
+    List<HtAnalogData> getP(@Param("deviceCodes") List<String> deviceCodes);
 }

+ 2 - 1
fiveep-persistence/src/main/resources/mapper/mysql/DeviceMapper.xml

@@ -76,10 +76,11 @@
 
     <select id="DeviceList" resultType="com.bizmatics.model.DeviceList">
         SELECT
-        a.*, b.device_status
+        a.*, b.device_status, c.rated_voltage, c.rated_current
         FROM
         device AS a
         JOIN device_status AS b ON a.device_code = b.device_code
+        JOIN device_attribute AS c ON a.device_code = c.monitor_device_code
         <where>
             a.enable =1
             <if test="siteId != null and siteId != 0">

+ 22 - 7
fiveep-persistence/src/main/resources/mapper/mysql/HtAnalogDataMapper.xml

@@ -1336,18 +1336,18 @@
 
     <select id="getDemandAnalysisList" resultType="com.bizmatics.model.HtAnalogData">
         SELECT
-            *
+        *
         FROM
-            ${table}
+        ${table}
         WHERE
-            deviceName = #{deviceCode}
+        deviceName = #{deviceCode}
         <if test="endTime != null and startTime != null and endTime != '' and startTime != ''">
             AND freezingTime BETWEEN #{startTime}
             AND #{endTime}
         </if>
 
         GROUP BY
-            freezingTime
+        freezingTime
     </select>
 
 
@@ -1537,13 +1537,28 @@
 
     <select id="getHtAnalogDataList" resultType="com.bizmatics.model.HtAnalogData">
         SELECT
-            *
+        *
         FROM
-            ${table}
+        ${table}
         WHERE
-            deviceName = #{deviceCode}
+        deviceName = #{deviceCode}
         <if test="endTime != null and startTime != null and endTime != '' and startTime != ''">
             and dataTime BETWEEN #{startTime} and #{endTime}
         </if>
     </select>
+
+    <select id="getP" resultType="com.bizmatics.model.HtAnalogData">
+        SELECT t.deviceName, t.p, t.dataTime
+        FROM ht_analog_data t
+        INNER JOIN (
+        SELECT deviceName, MAX(id) AS max_id
+        FROM ht_analog_data
+        WHERE deviceName IN
+        <foreach item="item" collection="deviceCodes" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        GROUP BY deviceName
+        ) latest ON t.deviceName = latest.deviceName AND t.id = latest.max_id
+    </select>
+
 </mapper>

+ 2 - 1
fiveep-service/src/main/java/com/bizmatics/service/HtAnalogDataService.java

@@ -106,5 +106,6 @@ public interface HtAnalogDataService extends CrudService<HtAnalogData> {
 
     SingleLoopReportOneVo SingleLoopReportData(String deviceCode, Date time, int type);
 
-
+    // 获取设备三相总有功功率值
+    List<HtAnalogData> getP(List<String> deviceCode);
 }

+ 11 - 3
fiveep-service/src/main/java/com/bizmatics/service/SiteService.java

@@ -1,8 +1,10 @@
 package com.bizmatics.service;
 
+import com.bizmatics.common.core.bean.CommonPage;
 import com.bizmatics.model.*;
 import com.bizmatics.common.mvc.base.CrudService;
 import com.bizmatics.service.vo.DeviceCountVO;
+import com.bizmatics.service.vo.SiteLoadAnalysisVO;
 import com.bizmatics.service.vo.SiteVO;
 import com.bizmatics.service.vo.SiteVOT;
 import org.apache.ibatis.annotations.Param;
@@ -41,7 +43,7 @@ public interface SiteService extends CrudService<Site> {
      * @param stationAreaId
      * @return
      */
-    List<SiteTwo> list2(String name,Integer stationAreaId);
+    List<SiteTwo> list2(String name, Integer stationAreaId);
 
     /**
      * 查看站点列表
@@ -59,8 +61,6 @@ public interface SiteService extends CrudService<Site> {
     List<SiteVO> siteAndStatusList(String name);
 
 
-
-
     /**
      * 查看站点详情
      * @param siteId
@@ -79,6 +79,7 @@ public interface SiteService extends CrudService<Site> {
     List<TemplateData> getSite(@Param("id") String id);
 
     void siteUpdate(@Param("id") SiteVOT siteVOT);
+
     void sitedel(@Param("id") String id);
 
     /**
@@ -91,5 +92,12 @@ public interface SiteService extends CrudService<Site> {
     List<DeviceAnalogVariableList> dynamicPropertiesDroplist(Integer siteId, Integer dataArea);
 
     List<Route> routeDroplist();
+
+    /**
+     * 站点负载分析
+     * @param siteId 站点id
+     * @return 站点负载分析
+     */
+    CommonPage<SiteLoadAnalysisVO> siteLoadAnalysis(Integer siteId, Integer pageNum, Integer pageSize);
 }
 

+ 14 - 16
fiveep-service/src/main/java/com/bizmatics/service/config/SecurityConfig.java

@@ -21,18 +21,17 @@ import org.springframework.web.filter.CorsFilter;
 
 /**
  * spring security配置
- * 
+ *
  * @author yq
  */
 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
-public class SecurityConfig extends WebSecurityConfigurerAdapter
-{
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
     /**
      * 自定义用户认证逻辑
      */
     @Autowired
     private UserDetailsServiceImpl userDetailsService;
-    
+
     /**
      * 认证失败处理类
      */
@@ -50,13 +49,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Autowired
     private JwtAuthenticationTokenFilter authenticationTokenFilter;
-    
+
     /**
      * 跨域过滤器
      */
     @Autowired
     private CorsFilter corsFilter;
-    
+
     /**
      * 解决 无法直接注入 AuthenticationManager
      *
@@ -65,8 +64,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Bean
     @Override
-    public AuthenticationManager authenticationManagerBean() throws Exception
-    {
+    public AuthenticationManager authenticationManagerBean() throws Exception {
         return super.authenticationManagerBean();
     }
 
@@ -86,8 +84,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * authenticated       |   用户登录后可访问
      */
     @Override
-    protected void configure(HttpSecurity httpSecurity) throws Exception
-    {
+    protected void configure(HttpSecurity httpSecurity) throws Exception {
         httpSecurity
                 // CSRF禁用,因为不使用session
                 .csrf().disable()
@@ -98,7 +95,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 过滤请求
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/register", "/captchaImage","/getLoginStyle","/sysTenantConfig/getTenantConfig","/aliWeather").anonymous()
+                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
+                .antMatchers("/login", "/register", "/captchaImage", "/getLoginStyle", "/sysTenantConfig/getTenantConfig", "/aliWeather").anonymous()
+                // "/site/siteLoadAnalysis"
                 .antMatchers(
                         HttpMethod.GET,
                         "/",
@@ -121,7 +120,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .headers().frameOptions().disable();
         httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
         // 添加JWT filter
-        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
+        httpSecurity.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
+                .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
         // 添加CORS filter
         httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
         httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
@@ -131,8 +131,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * 强散列哈希加密实现
      */
     @Bean
-    public BCryptPasswordEncoder bCryptPasswordEncoder()
-    {
+    public BCryptPasswordEncoder bCryptPasswordEncoder() {
         return new BCryptPasswordEncoder();
     }
 
@@ -140,8 +139,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * 身份认证接口
      */
     @Override
-    protected void configure(AuthenticationManagerBuilder auth) throws Exception
-    {
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
     }
 }

+ 4 - 5
fiveep-service/src/main/java/com/bizmatics/service/config/security/handle/AuthenticationEntryPointImpl.java

@@ -16,19 +16,18 @@ import java.io.Serializable;
 
 /**
  * 认证失败处理类 返回未授权
- * 
+ *
  * @author yq
  */
 @Component
-public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable
-{
+public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable {
     private static final long serialVersionUID = -8970718410437077606L;
 
     @Override
     public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
-            throws IOException
-    {
+            throws IOException {
         String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI());
+        System.err.println("认证失败 - URI: " + request.getRequestURI() + ", 异常: " + e.getMessage());
         ServletUtils.renderString(response, JsonUtils.toJson(ApiResult.error("401", msg)));
     }
 }

+ 45 - 37
fiveep-service/src/main/java/com/bizmatics/service/impl/HtAnalogDataServiceImpl.java

@@ -22,6 +22,7 @@ import com.bizmatics.service.util.FieldEscapeUtils;
 import com.bizmatics.service.util.SecurityUtils;
 import com.bizmatics.service.vo.*;
 import com.fasterxml.jackson.core.type.TypeReference;
+import org.apache.ibatis.annotations.Select;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -60,6 +61,8 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
     private SiteDynamicPropertiesService siteDynamicPropertiesService;
     @Autowired
     private DeviceAttributeService deviceAttributeService;
+    @Autowired
+    private HtAnalogDataMapper htAnalogDataMapper;
 
     @Override
     public HadCountVO selectCount() {
@@ -99,7 +102,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         List<Object> dates = new ArrayList<>();
         dates.add("00:00:00");
         for (int i = 2; i < 24; i += 2) {
-            //结束时间
+            // 结束时间
             Date hours = DateUtils.setHours(startTime, i);
             startTime = hours;
             dates.add(DateUtils.getTime(hours));
@@ -128,7 +131,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
             List<Object> dates = new ArrayList<>();
             dates.add("00:00:00");
             for (int i = 2; i < 24; i += 2) {
-                //结束时间
+                // 结束时间
                 Date hours = DateUtils.setHours(startTime, i);
                 objects.add(0.0);
                 startTime = hours;
@@ -166,11 +169,11 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
     public HadCountVO getCountBySite(Integer siteId) {
         Integer userId = SecurityUtils.getLoginUser().getUser().getUserId().intValue();
         Date date = new Date();
-        //当日开始时间
+        // 当日开始时间
         Date firstDayOfDate = DateUtils.getDayStartTime(date);
-        //当月开始时间
+        // 当月开始时间
         Date firstDayOfMonth = DateUtils.getFirstDayOfMonth(date);
-        //当年开始时间
+        // 当年开始时间
         Date firstDayOfYear = DateUtils.getBeginDayOfYear(date);
         HadCountVO hadCountVO = new HadCountVO();
         hadCountVO.setDayCount(hadSiteStaticService.getCount(userId, DateUtils.getDayStartTime(date), date, siteId));
@@ -304,7 +307,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
     public List<RealScoreVO> rtRealScore(String deviceCode, Date startTime, Date endTime) {
         SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
-        //查询设备
+        // 查询设备
         LambdaQueryWrapper<Device> deviceQuery = Wrappers.lambdaQuery();
         deviceQuery.eq(Device::getDeviceCode, deviceCode);
         Device device = deviceService.getOne(deviceQuery);
@@ -318,7 +321,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         }
         List<HtAnalogData> list = baseMapper.getDemandAnalysisList(deviceCode, formatter.format(startTime), formatter.format(endTime), table);
 
-        //查询sd
+        // 查询sd
         LambdaQueryWrapper<SiteDynamicProperties> sdQuery = Wrappers.lambdaQuery();
         sdQuery.eq(SiteDynamicProperties::getSiteId, device.getSiteId());
         SiteDynamicProperties siteDynamicProperties = siteDynamicPropertiesService.getOne(sdQuery);
@@ -395,25 +398,25 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
             deviceAnalogVariableList.setVariableCoding(dataManagementOneVO.getDisplayField().get(i).split("_")[0] + "_" + dataManagementOneVO.getDisplayField().get(i).split("_")[1]);
             variableCodingList.add(deviceAnalogVariableList);
         }
-        //通信设备编号
+        // 通信设备编号
         Set set = new HashSet();
         List<DataManagementVO> newList = new ArrayList();
         set.addAll(dataManagementVOList);
         newList.addAll(set);
 
-        //显示的字段名
+        // 显示的字段名
         Set set1 = new HashSet();
         List<String> list = new ArrayList();
         set1.addAll(newListOne);
         list.addAll(set1);
 
-        //监控ID
+        // 监控ID
         Set set2 = new HashSet();
         List<String> monitor_list = new ArrayList();
         set2.addAll(newListTwo);
         monitor_list.addAll(set2);
 
-        //查询字段
+        // 查询字段
         Set set3 = new HashSet();
         List<String> fieldDisplayOne = new ArrayList();
         set3.addAll(fieldDisplay);
@@ -444,15 +447,15 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         List<ContextualDataVo> yearOnYearList3 = new ArrayList<>();
         if (fieldDisplayOne183.size() > 0) {
             List<String> fieldDisplayList = FieldEscapeUtils.getSyllable(type, valueCalculation, fieldDisplayOne183);
-            yearOnYearList1 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_data", 0,type);
+            yearOnYearList1 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_data", 0, type);
         }
         if (fieldDisplayOne171.size() > 0) {
             List<String> fieldDisplayList = FieldEscapeUtils.getSyllable(type, valueCalculation, fieldDisplayOne171);
-            yearOnYearList2 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_171_data", 0,type);
+            yearOnYearList2 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_171_data", 0, type);
         }
         if (fieldDisplayOne173.size() > 0) {
             List<String> fieldDisplayList = FieldEscapeUtils.getSyllable(type, valueCalculation, fieldDisplayOne173);
-            yearOnYearList3 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_173_data", 0,type);
+            yearOnYearList3 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_173_data", 0, type);
         }
         List<ContextualDataVo> yearOnYearList4 = Stream.of(yearOnYearList1, yearOnYearList2).flatMap(Collection::stream).distinct().collect(Collectors.toList());
         List<ContextualDataVo> yearOnYearList = Stream.of(yearOnYearList3, yearOnYearList4).flatMap(Collection::stream).distinct().collect(Collectors.toList());
@@ -658,15 +661,15 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         List<ContextualDataVo> yearOnYearList3 = new ArrayList<>();
         if (fieldDisplayOne183.size() > 0) {
             List<String> fieldDisplayList = FieldEscapeUtils.getSyllable(type, valueCalculation, fieldDisplayOne183);
-            yearOnYearList1 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_data", 0,type);
+            yearOnYearList1 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_data", 0, type);
         }
         if (fieldDisplayOne171.size() > 0) {
             List<String> fieldDisplayList = FieldEscapeUtils.getSyllable(type, valueCalculation, fieldDisplayOne171);
-            yearOnYearList2 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_171_data", 0,type);
+            yearOnYearList2 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_171_data", 0, type);
         }
         if (fieldDisplayOne173.size() > 0) {
             List<String> fieldDisplayList = FieldEscapeUtils.getSyllable(type, valueCalculation, fieldDisplayOne173);
-            yearOnYearList3 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_173_data", 0,type);
+            yearOnYearList3 = baseMapper.getYearOnYearThree(newList, dataManagementOneVO.getStartTime(), dataManagementOneVO.getEndTime(), variableCodingList, fieldDisplayList, "ht_analog_173_data", 0, type);
         }
         List<ContextualDataVo> yearOnYearList4 = Stream.of(yearOnYearList1, yearOnYearList2).flatMap(Collection::stream).distinct().collect(Collectors.toList());
         List<ContextualDataVo> currentPeriodRingRatioList = Stream.of(yearOnYearList3, yearOnYearList4).flatMap(Collection::stream).distinct().collect(Collectors.toList());
@@ -1100,7 +1103,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         checkList.add(SingleLoopReportList.get(0).getAvgIa());
         checkList.add(SingleLoopReportList.get(0).getAvgIb());
         checkList.add(SingleLoopReportList.get(0).getAvgIc());
-        //电流不平衡(平均)
+        // 电流不平衡(平均)
         Double AvgElBalun = checkBalun(checkList) * 100;
         singleLoopReportOneVo.setAvgElBalun(Double.valueOf(df.format(AvgElBalun)));
         if (AvgElBalun < 15) {
@@ -1113,7 +1116,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         checkList.add(SingleLoopReportList.get(0).getMaxIa());
         checkList.add(SingleLoopReportList.get(0).getMaxIb());
         checkList.add(SingleLoopReportList.get(0).getMaxIc());
-        //电流不平衡(最大)
+        // 电流不平衡(最大)
         Double MaxElBalun = checkBalun(checkList) * 100;
         singleLoopReportOneVo.setMaxElBalun(Double.valueOf(df.format(MaxElBalun)));
         if (MaxElBalun < 15) {
@@ -1126,7 +1129,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         checkList.add(SingleLoopReportList.get(0).getMinIa());
         checkList.add(SingleLoopReportList.get(0).getMinIb());
         checkList.add(SingleLoopReportList.get(0).getMinIc());
-        //电流不平衡(最小)
+        // 电流不平衡(最小)
         Double MinElBalun = checkBalun(checkList) * 100;
         singleLoopReportOneVo.setMinElBalun(Double.valueOf(df.format(MinElBalun)));
         if (MinElBalun < 15) {
@@ -1144,7 +1147,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         checkList.add(SingleLoopReportList.get(0).getAvgUa());
         checkList.add(SingleLoopReportList.get(0).getAvgUb());
         checkList.add(SingleLoopReportList.get(0).getAvgUc());
-        //电压不平衡(平均)
+        // 电压不平衡(平均)
         Double AvgVtBalun = checkBalun(checkList) * 100;
         singleLoopReportOneVo.setAvgVtBalun(Double.valueOf(df.format(AvgVtBalun)));
         if (AvgVtBalun < 15) {
@@ -1157,7 +1160,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         checkList.add(SingleLoopReportList.get(0).getMaxUa());
         checkList.add(SingleLoopReportList.get(0).getMaxUb());
         checkList.add(SingleLoopReportList.get(0).getMaxUc());
-        //电压不平衡(最大)
+        // 电压不平衡(最大)
         Double MaxVtBalun = checkBalun(checkList) * 100;
         singleLoopReportOneVo.setMaxVtBalun(Double.valueOf(df.format(MaxVtBalun)));
         if (MaxVtBalun < 15) {
@@ -1170,7 +1173,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         checkList.add(SingleLoopReportList.get(0).getMinUa());
         checkList.add(SingleLoopReportList.get(0).getMinUb());
         checkList.add(SingleLoopReportList.get(0).getMinUc());
-        //电压不平衡(最小)
+        // 电压不平衡(最小)
         Double MinVtBalun = checkBalun(checkList) * 100;
         singleLoopReportOneVo.setMinVtBalun(Double.valueOf(df.format(MinVtBalun)));
         if (MinVtBalun < 15) {
@@ -1189,7 +1192,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         double voltageLevel = Double.parseDouble(singleLoopReportOneVo.getVoltageLevel());
         double voltageLevelWanting = voltageLevel / 100 * 7;
 
-        //A相电压合格率(平均)
+        // A相电压合格率(平均)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getAvgUa());
         checkList.add(voltageLevel);
@@ -1200,7 +1203,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setAvgUaStatus(false);
         }
-        //B相电压合格率(平均)
+        // B相电压合格率(平均)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getAvgUb());
         checkList.add(voltageLevel);
@@ -1211,7 +1214,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setAvgUbStatus(false);
         }
-        //C相电压合格率(平均)
+        // C相电压合格率(平均)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getAvgUc());
         checkList.add(voltageLevel);
@@ -1222,7 +1225,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setAvgUcStatus(false);
         }
-        //A相电压合格率(最大)
+        // A相电压合格率(最大)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getMaxUa());
         checkList.add(voltageLevel);
@@ -1233,7 +1236,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setMaxUaStatus(false);
         }
-        //B相电压合格率(最大)
+        // B相电压合格率(最大)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getMaxUb());
         checkList.add(voltageLevel);
@@ -1244,7 +1247,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setMaxUbStatus(false);
         }
-        //C相电压合格率(最大)
+        // C相电压合格率(最大)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getMaxUc());
         checkList.add(voltageLevel);
@@ -1255,7 +1258,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setMaxUcStatus(false);
         }
-        //A相电压合格率(最小)
+        // A相电压合格率(最小)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getMinUa());
         checkList.add(voltageLevel);
@@ -1266,7 +1269,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setMinUaStatus(false);
         }
-        //B相电压合格率(最小)
+        // B相电压合格率(最小)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getMinUb());
         checkList.add(voltageLevel);
@@ -1277,7 +1280,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setMinUbStatus(false);
         }
-        //C相电压合格率(最小)
+        // C相电压合格率(最小)
         checkList.clear();
         checkList.add(SingleLoopReportList.get(0).getMinUc());
         checkList.add(voltageLevel);
@@ -1308,7 +1311,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         }
 
 
-        //频率(平均)
+        // 频率(平均)
         Double cAvgF = 0.00;
         if (SingleLoopReportList.get(0).getAvgF() >= 50) {
             cAvgF = Double.valueOf(df.format(SingleLoopReportList.get(0).getAvgF() - 50.00));
@@ -1321,7 +1324,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setAvgFStatus(false);
         }
-        //频率(最大)
+        // 频率(最大)
         Double cMaxF = 0.00;
         if (SingleLoopReportList.get(0).getAvgF() >= 50) {
             cMaxF = Double.valueOf(df.format(SingleLoopReportList.get(0).getMaxF() - 50.00));
@@ -1334,7 +1337,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         } else {
             singleLoopReportOneVo.setMaxFStatus(false);
         }
-        //频率(最小)
+        // 频率(最小)
         Double cMinF = 0.00;
         if (SingleLoopReportList.get(0).getAvgF() >= 50) {
             cMinF = Double.valueOf(df.format(SingleLoopReportList.get(0).getMinF() - 50.00));
@@ -1406,7 +1409,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
                 checkList.add(RtAnalogDataList.get(i).getIa());
                 checkList.add(RtAnalogDataList.get(i).getIb());
                 checkList.add(RtAnalogDataList.get(i).getIc());
-                //电流不平衡
+                // 电流不平衡
                 Double ElBalun = checkBalun(checkList);
                 if (ElBalun < 0.15) {
                     OverrunElBalun++;
@@ -1416,7 +1419,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
                 checkList.add(RtAnalogDataList.get(i).getUa());
                 checkList.add(RtAnalogDataList.get(i).getUb());
                 checkList.add(RtAnalogDataList.get(i).getUc());
-                //电压不平衡
+                // 电压不平衡
                 Double VtBalunQ = checkBalun(checkList);
                 if (VtBalunQ < 0.15) {
                     OverrunVtBalun++;
@@ -1466,4 +1469,9 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
         return Arith.div(Arith.sub(max, min), max);
     }
 
+    // 获取设备三相总有功功率值
+    @Override
+    public List<HtAnalogData> getP(List<String> deviceCodes) {
+        return htAnalogDataMapper.getP(deviceCodes);
+    }
 }

+ 166 - 13
fiveep-service/src/main/java/com/bizmatics/service/impl/SiteServiceImpl.java

@@ -3,7 +3,9 @@ package com.bizmatics.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.bizmatics.common.core.bean.CommonPage;
 import com.bizmatics.common.core.exception.BusinessException;
+import com.bizmatics.common.core.util.Arith;
 import com.bizmatics.common.core.util.BeanMapperUtils;
 import com.bizmatics.common.mvc.base.AbstractCrudService;
 import com.bizmatics.model.*;
@@ -18,9 +20,11 @@ import com.bizmatics.service.*;
 import com.bizmatics.service.enums.DeviceStatusCode;
 import com.bizmatics.service.util.SecurityUtils;
 import com.bizmatics.service.vo.DeviceCountVO;
+import com.bizmatics.service.vo.SiteLoadAnalysisVO;
 import com.bizmatics.service.vo.SiteVO;
 import com.bizmatics.service.vo.SiteVOT;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -58,6 +62,8 @@ public class SiteServiceImpl extends AbstractCrudService<SiteMapper, Site> imple
     private RouteService routeService;
     @Autowired
     private SysUserMapper userMapper;
+    @Autowired
+    private HtAnalogDataService htAnalogDataService;
 
     @Override
     public DeviceCountVO selectCount() {
@@ -79,18 +85,18 @@ public class SiteServiceImpl extends AbstractCrudService<SiteMapper, Site> imple
             throw new BusinessException("无此租户,请联系管理员");
         }
         List<Site> siteList = new ArrayList<>();
-        if (tenantDaya.get(0).getUserType().equals("01")){
+        if (tenantDaya.get(0).getUserType().equals("01")) {
             siteList = baseMapper.listOne(name, tenantDaya.get(0).getTenantId());
-        }else if (tenantDaya.get(0).getUserType().equals("00")){
+        } else if (tenantDaya.get(0).getUserType().equals("00")) {
             siteList = baseMapper.list(userId, name, tenantDaya.get(0).getTenantId());
         }
         return siteList;
     }
 
     @Override
-    public List<SiteTwo> list2(String name,Integer stationAreaId) {
+    public List<SiteTwo> list2(String name, Integer stationAreaId) {
         Integer userId = SecurityUtils.getLoginUser().getUser().getUserId().intValue();
-        return baseMapper.list2(userId, name,stationAreaId);
+        return baseMapper.list2(userId, name, stationAreaId);
     }
 
     @Override
@@ -238,10 +244,10 @@ public class SiteServiceImpl extends AbstractCrudService<SiteMapper, Site> imple
         if (tenantDaya.size() < 0) {
             throw new BusinessException("无此租户,请联系管理员");
         }
-        if (tenantDaya.get(0).getUserType().equals("01")){
-            grouping_list = baseMapper.GroupingList(name, null,tenantDaya.get(0).getTenantId());
-            site_list = baseMapper.SitelistOne(name,tenantDaya.get(0).getTenantId());
-            site_grouping_list = baseMapper.SiteGroupinglist(0, name,tenantDaya.get(0).getTenantId());
+        if (tenantDaya.get(0).getUserType().equals("01")) {
+            grouping_list = baseMapper.GroupingList(name, null, tenantDaya.get(0).getTenantId());
+            site_list = baseMapper.SitelistOne(name, tenantDaya.get(0).getTenantId());
+            site_grouping_list = baseMapper.SiteGroupinglist(0, name, tenantDaya.get(0).getTenantId());
             if (grouping_list.size() > 0) {
                 for (int i = 0; i < grouping_list.size(); i++) {
                     GroupingList grouping_list_one = (GroupingList) grouping_list.get(i);
@@ -280,18 +286,18 @@ public class SiteServiceImpl extends AbstractCrudService<SiteMapper, Site> imple
                     list1.add(map3);
                 }
             }
-        }else if (tenantDaya.get(0).getUserType().equals("00")){
+        } else if (tenantDaya.get(0).getUserType().equals("00")) {
             List<GroupingList> grouping_list_one = null;
             List<GroupingList> grouping_list_two = null;
-            site_list = baseMapper.Sitelist(userId, name,tenantDaya.get(0).getTenantId());
-            grouping_list_one = baseMapper.GroupingListOne(name, userId,tenantDaya.get(0).getTenantId());
+            site_list = baseMapper.Sitelist(userId, name, tenantDaya.get(0).getTenantId());
+            grouping_list_one = baseMapper.GroupingListOne(name, userId, tenantDaya.get(0).getTenantId());
             grouping_list_two = baseMapper.GroupingListTwo(user.getUserName());
 //            合并list
             grouping_list = Stream.of(grouping_list_one, grouping_list_two).flatMap(Collection::stream).collect(Collectors.toList());
-            //排序
+            // 排序
             List<GroupingList> dateListMap = grouping_list;
 //            Map<Integer, List<GroupingList>> dateListMap  = grouping_list.stream().collect(Collectors.groupingBy(GroupingList::getId,TreeMap::new,Collectors.toList())).descendingMap();
-            site_grouping_list = baseMapper.SiteGroupinglist(userId, name,tenantDaya.get(0).getTenantId());
+            site_grouping_list = baseMapper.SiteGroupinglist(userId, name, tenantDaya.get(0).getTenantId());
 
             if (dateListMap.size() > 0) {
                 for (int i = 0; i < dateListMap.size(); i++) {
@@ -352,4 +358,151 @@ public class SiteServiceImpl extends AbstractCrudService<SiteMapper, Site> imple
         List<Route> list = routeService.list(routeLambdaQueryWrapper);
         return list;
     }
+
+    @Override
+    public CommonPage<SiteLoadAnalysisVO> siteLoadAnalysis(Integer siteId, Integer pageNum, Integer pageSize) {
+        List<SiteLoadAnalysisVO> records = new ArrayList<>();
+        LambdaQueryWrapper<Site> siteQuery = Wrappers.lambdaQuery();
+        siteQuery.eq(Site::getId, siteId);
+        Site site = baseMapper.selectOne(siteQuery);
+        log.info("站点信息:{}", site);
+        if (site == null) {
+            return new CommonPage<>();
+        }
+
+        // 站点动态属性查询
+        LambdaQueryWrapper<SiteDynamicProperties> siteDynamicPropertiesQuery = Wrappers.lambdaQuery();
+        siteDynamicPropertiesQuery.eq(SiteDynamicProperties::getSiteId, siteId);
+        SiteDynamicProperties siteDynamicProperties = siteDynamicPropertiesService.getOne(siteDynamicPropertiesQuery);
+        log.info("站点动态属性信息:{}", siteDynamicProperties);
+        if (siteDynamicProperties == null) {
+            log.error("站点{}动态属性不存在", siteId);
+        }
+
+        // 存入接口返回
+        SiteLoadAnalysisVO siteLoadAnalysisVO = new SiteLoadAnalysisVO();
+        siteLoadAnalysisVO.setId(site.getId());
+        siteLoadAnalysisVO.setName(site.getSiteName());
+        // 额定容量=装机容量
+        siteLoadAnalysisVO.setRatedCapacity(Double.valueOf(site.getInstalledCapacity()));
+        // 额定电压
+        try {
+            siteLoadAnalysisVO.setRatedVoltage(StringUtils.isBlank(siteDynamicProperties.getVoltageLevel()) ? 0.0 : Double.parseDouble(siteDynamicProperties.getVoltageLevel()) / 1000.0);
+        } catch (NumberFormatException e) {
+            log.error("站点{}  电压等级(单位:V)格式转换错误{} ,已重置为0.0", siteDynamicProperties.getSiteId(), e);
+            siteLoadAnalysisVO.setRatedVoltage(0.0);
+        }
+        // 先插入部分站点信息
+        records.add(0, siteLoadAnalysisVO);
+
+        List<DeviceList> deviceList = deviceService.deviceList(String.valueOf(siteId));
+        log.info("设备信息list:{}", deviceList);
+
+        // 类型为1的设备为站点的有功功率(总和)
+        List<DeviceList> typeOneDevices = new ArrayList<>();
+        List<DeviceList> typeOtherDevices = new ArrayList<>();
+        List<String> deviceCodeList = new ArrayList<>();
+        // Map<String, Double> pMap = new HashMap<>();
+        Double p = 0.0;
+
+        if (!deviceList.isEmpty()) {
+            for (DeviceList device : deviceList) {
+                String deviceType = device.getDeviceType();
+                if ("1".equals(deviceType)) {
+                    typeOneDevices.add(device);
+                } else if (!"2".equals(deviceType)) {
+                    typeOtherDevices.add(device);
+                }
+                deviceCodeList.add(device.getDeviceCode());
+            }
+        } else {
+            log.error("站点{}无设备", siteId);
+            return new CommonPage<>(records, records.size(), pageSize, pageNum);
+        }
+
+        // pMap = (htAnalogDataService.getP(deviceCodeList)).stream().collect(Collectors.toMap(HtAnalogData::getDeviceName, HtAnalogData::getP));
+        List<HtAnalogData> pList = htAnalogDataService.getP(deviceCodeList);
+        if (pList.isEmpty()) {
+            log.error("站点{},设备编号{} 无有功功率数据", siteId, deviceCodeList);
+            for (DeviceList device : deviceList) {
+                SiteLoadAnalysisVO deviceLoadAnalysis = new SiteLoadAnalysisVO();
+                deviceLoadAnalysis.setName(device.getDeviceName());
+                deviceLoadAnalysis.setId(null);
+                deviceLoadAnalysis.setCode(device.getDeviceCode());
+                deviceLoadAnalysis.setRatedCapacity(0.0);
+                deviceLoadAnalysis.setRatedVoltage(0.0);
+                deviceLoadAnalysis.setP(0.0);
+                deviceLoadAnalysis.setLoadRate(0.0);
+                deviceLoadAnalysis.setDataTime(null);
+                records.add(deviceLoadAnalysis);
+            }
+            return new CommonPage<>(records, records.size(), pageSize, pageNum);
+        }
+        for (DeviceList device : deviceList) {
+            log.info("设备信息:{}", device);
+            SiteLoadAnalysisVO deviceLoadAnalysis = new SiteLoadAnalysisVO();
+            deviceLoadAnalysis.setId(device.getId());
+            deviceLoadAnalysis.setName(device.getDeviceName());
+            deviceLoadAnalysis.setCode(device.getDeviceCode());
+            double ratedCapacity = device.getRatedCurrent() * device.getRatedVoltage();
+            log.info("额定容量:{}", ratedCapacity);
+            deviceLoadAnalysis.setRatedCapacity(ratedCapacity);
+            deviceLoadAnalysis.setRatedVoltage(device.getRatedVoltage());
+
+            Date dateTime = pList.stream()
+                    .filter(ht -> ht.getDeviceName().equals(device.getDeviceCode()))
+                    .findFirst()
+                    .map(HtAnalogData::getDataTime)
+                    .orElse(null);
+            deviceLoadAnalysis.setDataTime(dateTime);
+
+            // deviceLoadAnalysis.setP(pMap.get(device.getDeviceCode()));
+
+            Double m = pList.stream()
+                    .filter(ht -> ht.getDeviceName().equals(device.getDeviceCode()))
+                    .findFirst()
+                    .map(HtAnalogData::getP)
+                    .orElse(0.0);
+            deviceLoadAnalysis.setP(m);
+
+            if (ratedCapacity != 0.0) {
+                deviceLoadAnalysis.setLoadRate(Arith.div(m, ratedCapacity, 3));
+            } else {
+                deviceLoadAnalysis.setLoadRate(0.0);
+            }
+            records.add(deviceLoadAnalysis);
+        }
+
+        // 没有的话则是其他类型的总和(类型2 视频监控除外)
+        if (!typeOneDevices.isEmpty()) {
+            for (DeviceList device : typeOneDevices) {
+                Double m = pList.stream()
+                        .filter(ht -> ht.getDeviceName().equals(device.getDeviceCode()))
+                        .findFirst()
+                        .map(HtAnalogData::getP)
+                        .orElse(0.0);
+                p += m;
+            }
+        } else {
+            for (DeviceList device : typeOtherDevices) {
+                Double m = pList.stream()
+                        .filter(ht -> ht.getDeviceName().equals(device.getDeviceCode()))
+                        .findFirst()
+                        .map(HtAnalogData::getP)
+                        .orElse(0.0);
+                p += m;
+            }
+        }
+        records.get(0).setP(p);
+
+        // 负载率
+        if (records.get(0).getRatedCapacity() != 0.0) {
+            records.get(0).setLoadRate(Arith.div(p, records.get(0).getRatedCapacity(), 3));
+        } else {
+            records.get(0).setLoadRate(0.0);
+        }
+
+        return new CommonPage<>(records, records.size(), pageNum, pageSize);
+    }
+
 }

+ 62 - 0
fiveep-service/src/main/java/com/bizmatics/service/vo/SiteLoadAnalysisVO.java

@@ -0,0 +1,62 @@
+package com.bizmatics.service.vo;
+
+import com.bizmatics.service.config.CustomerDoubleSerialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/7/1
+ */
+@Data
+public class SiteLoadAnalysisVO {
+
+    /**
+     * 名称(站点名、设备名)
+     */
+    private String name;
+
+    /**
+     * id(站点id、设备id)
+     */
+    private Integer id;
+
+    /**
+     * 编号(设备code)
+     */
+    private String code;
+
+    /**
+     * 额定容量(单位kVA)
+     *(站点=装机容量installed_capacity;设备=额定电压(kV)rated_voltage × 额定电流(A)rated_current)
+     */
+    @JsonSerialize(using = CustomerDoubleSerialize.class)
+    // 保留两位小数
+    private Double ratedCapacity;
+
+    /**
+     * 额定电压 (单位kV)
+     */
+    @JsonSerialize(using = CustomerDoubleSerialize.class)
+    private Double ratedVoltage;
+
+    /**
+     * 有功功率(kW)
+     */
+    private Double p;
+
+    /**
+     * 负载率(%)
+     */
+    @JsonSerialize(using = CustomerDoubleSerialize.class)
+    private Double loadRate;
+
+    /**
+     * 上报时间
+     */
+    private Date dataTime;
+}