Browse Source

增加设备属性

xusl 1 năm trước cách đây
mục cha
commit
0bfae634c6
31 tập tin đã thay đổi với 1477 bổ sung86 xóa
  1. 9 3
      backend/pom.xml
  2. 35 0
      backend/src/main/java/com/jiayue/pfr/backenum/ActionResetEnum.java
  3. 124 0
      backend/src/main/java/com/jiayue/pfr/backenum/EquipmentTypeEnum.java
  4. 8 0
      backend/src/main/java/com/jiayue/pfr/config/ProtocolConfig.java
  5. 253 0
      backend/src/main/java/com/jiayue/pfr/controller/di/EquipmentAttributeController.java
  6. 2 0
      backend/src/main/java/com/jiayue/pfr/dto/FmDataBeanDto.java
  7. 41 0
      backend/src/main/java/com/jiayue/pfr/entity/BizYaoData.java
  8. 71 0
      backend/src/main/java/com/jiayue/pfr/entity/EquipmentAttribute.java
  9. 1 3
      backend/src/main/java/com/jiayue/pfr/job/GetFmJob.java
  10. 17 0
      backend/src/main/java/com/jiayue/pfr/mapper/alg/BizYaoDataMapper.java
  11. 22 0
      backend/src/main/java/com/jiayue/pfr/mapper/di/EquipmentAttributeMapper.java
  12. 71 0
      backend/src/main/java/com/jiayue/pfr/protocol/agc/Master104ForAgcApplication.java
  13. 21 0
      backend/src/main/java/com/jiayue/pfr/service/alg/BizYaoDataService.java
  14. 0 23
      backend/src/main/java/com/jiayue/pfr/service/alg/FrequencyServiceImpl.java
  15. 47 0
      backend/src/main/java/com/jiayue/pfr/service/alg/impl/BizYaoDataServiceImpl.java
  16. 22 0
      backend/src/main/java/com/jiayue/pfr/service/alg/listener/AgcEvent.java
  17. 94 0
      backend/src/main/java/com/jiayue/pfr/service/alg/listener/AgcLockListener.java
  18. 18 8
      backend/src/main/java/com/jiayue/pfr/service/alg/listener/CoreAlgListener.java
  19. 24 0
      backend/src/main/java/com/jiayue/pfr/service/alg/listener/EmsUploadListener.java
  20. 1 1
      backend/src/main/java/com/jiayue/pfr/service/alg/listener/GetFmEvent.java
  21. 10 2
      backend/src/main/java/com/jiayue/pfr/service/alg/listener/SendFmSocketListener.java
  22. 70 0
      backend/src/main/java/com/jiayue/pfr/service/di/EquipmentAttributeService.java
  23. 102 0
      backend/src/main/java/com/jiayue/pfr/service/di/impl/EquipmentAttributeServiceImpl.java
  24. 0 22
      backend/src/main/java/com/jiayue/pfr/util/SecurityContextUtil.java
  25. 0 10
      backend/src/main/java/com/jiayue/pfr/util/SecurityValidate.java
  26. 1 1
      backend/src/main/resources/application.yml
  27. 1 2
      ui/README.md
  28. 397 0
      ui/src/views/dataexchange/equipmentAttribute/index.vue
  29. 7 3
      ui/src/views/largeScreen/index.vue
  30. 2 2
      ui/vue.config.js
  31. 6 6
      ui/yarn.lock

+ 9 - 3
backend/pom.xml

@@ -14,7 +14,13 @@
     <version>1.0.0</version>
 
     <name>backend</name>
-
+    <repositories>
+        <repository>
+            <id>jiayue-releases</id>
+            <name>嘉越云仓库</name>
+            <url>http://49.4.68.219:8888/repository/jiayue-releases/</url>
+        </repository>
+    </repositories>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <java.version>1.8</java.version>
@@ -175,8 +181,8 @@
         </dependency>
         <dependency>
             <groupId>wei.yigulu</groupId>
-            <artifactId>protocol-iec104</artifactId>
-            <version>2.4.23</version>
+            <artifactId>protocol-all</artifactId>
+            <version>2.3.16</version>
         </dependency>
         <dependency>
             <groupId>com.github.whvcse</groupId>

+ 35 - 0
backend/src/main/java/com/jiayue/pfr/backenum/ActionResetEnum.java

@@ -0,0 +1,35 @@
+package com.jiayue.pfr.backenum;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+* 动作、复归枚举
+*
+* @author xsl
+* @since 2023/06/06
+*/
+@Getter
+@AllArgsConstructor
+public enum ActionResetEnum {
+    /**
+     * 大写字母
+     */
+    ACTION("0", "动作"),
+    /**
+     * 小写字母
+     */
+    RESET("1", "复归");
+
+    private String code;
+    private String message;
+
+    public static ActionResetEnum getByName(String name) {
+        for (ActionResetEnum type : values()) {
+            if (type.name().equals(name)) {
+                return type;
+            }
+        }
+        return null;
+    }
+}

+ 124 - 0
backend/src/main/java/com/jiayue/pfr/backenum/EquipmentTypeEnum.java

@@ -0,0 +1,124 @@
+package com.jiayue.pfr.backenum;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 设备数据对象类型枚举
+ * lastModify
+ * 2020.3.26  修唯   枚举名修改,新增发电站类型,删除各种功率,设备数,开机容量等类型
+ *
+ * @author zzy
+ * @version 1.0
+ * @since 2019/8/19 8:59
+ */
+@Getter
+@AllArgsConstructor
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum EquipmentTypeEnum {
+
+    /**
+     * 场站也视为设备类型的一种
+     */
+    POWERSTATION(0, "发电站"),
+    WEATHERSTATION(1, "气象站"),
+    INVERTER(2, "逆变器"),
+    WINDTOWER(3, "测风塔"),
+    WINDTURBINE(4, "风机"),
+    FORECASTDATA(5, "预测数据"),
+    BOOSTERSTATION(6, "升压站"),
+    AGC_AVC(7, "AGC_AVC"),
+    BWD(8, "并网点"),
+    CYB(9, "厂用变"),
+    JDX(10, "集电线"),
+    SYZMX(11, "升压站母线"),
+    WGBC(12, "无功补偿"),
+    DLQ(13, "断路器"),
+    DZ(14, "刀闸"),
+    JDDZ(15, "接地刀闸"),
+    DXFDJ(16, "等效发电机"),
+    QBB(17, "启备变"),
+    LLB(18, "联络变"),
+    FZ(19, "方阵"),
+    XB(20,"箱变"),
+    ALL_SKY_CAMERA(21,"全天空成像仪");
+
+    private Integer code;
+    private String message;
+
+
+    /**
+     * 附属设备
+     */
+    public static final List<EquipmentTypeEnum> SUBSIDIARY_EQUIPMENT_TYPE = Arrays.asList(
+            EquipmentTypeEnum.JDX,//并网点
+            EquipmentTypeEnum.BWD,//并网点
+            EquipmentTypeEnum.CYB,//厂用变
+            EquipmentTypeEnum.SYZMX,//升压站母线
+            EquipmentTypeEnum.WGBC,//"无功补偿
+            EquipmentTypeEnum.DLQ,//"断路器
+            EquipmentTypeEnum.DZ,//"刀闸
+            EquipmentTypeEnum.JDDZ,//"接地刀闸
+            EquipmentTypeEnum.DXFDJ,//"等效发电机
+            EquipmentTypeEnum.QBB,//"启备变
+            EquipmentTypeEnum.LLB,//"联络变
+            EquipmentTypeEnum.FZ,//方阵
+            EquipmentTypeEnum.XB,//箱变
+            EquipmentTypeEnum.ALL_SKY_CAMERA //全天空成像仪
+    );
+
+
+    public static EquipmentTypeEnum valueOf(Integer code) {
+        switch (code) {
+            case 0:
+                return POWERSTATION;
+            case 1:
+                return WEATHERSTATION;
+            case 2:
+                return INVERTER;
+            case 3:
+                return WINDTOWER;
+            case 4:
+                return WINDTURBINE;
+            case 5:
+                return FORECASTDATA;
+            case 6:
+                return BOOSTERSTATION;
+            case 7:
+                return AGC_AVC;
+            case 8:
+                return BWD;
+            case 9:
+                return CYB;
+            case 10:
+                return JDX;
+            case 11:
+                return SYZMX;
+            case 12:
+                return WGBC;
+            case 13:
+                return DLQ;
+            case 14:
+                return DZ;
+            case 15:
+                return JDDZ;
+            case 16:
+                return DXFDJ;
+            case 17:
+                return QBB;
+            case 18:
+                return LLB;
+            case 19:
+                return FZ;
+            case 20:
+                return XB;
+            case 21:
+                return ALL_SKY_CAMERA;
+        }
+        return null;
+    }
+}

+ 8 - 0
backend/src/main/java/com/jiayue/pfr/config/ProtocolConfig.java

@@ -3,6 +3,7 @@ package com.jiayue.pfr.config;
 import com.jiayue.pfr.protocol.frequency.FmRtuMasterBuilder;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import wei.yigulu.iec104.nettyconfig.Iec104MasterBuilder;
 
 /**
  * 协议配置
@@ -21,4 +22,11 @@ public class ProtocolConfig {
         fmRtuMasterBuilder.setBaudRate(115200);
         fmRtuMasterBuilder.createByUnBlock();
     }
+
+    @Bean
+    public Iec104MasterBuilder iec104MasterBuilder() {
+        Iec104MasterBuilder simpleMasterBuilder=new Iec104MasterBuilder("127.0.0.1",2404);
+        simpleMasterBuilder.createByUnBlock();
+        return simpleMasterBuilder;
+    }
 }

+ 253 - 0
backend/src/main/java/com/jiayue/pfr/controller/di/EquipmentAttributeController.java

@@ -0,0 +1,253 @@
+package com.jiayue.pfr.controller.di;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jiayue.pfr.backenum.EquipmentTypeEnum;
+import com.jiayue.pfr.constant.CustomException;
+import com.jiayue.pfr.entity.EquipmentAttribute;
+import com.jiayue.pfr.service.di.EquipmentAttributeService;
+import com.jiayue.pfr.util.SaResultRefit;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 设备属性类的对外http接口
+ *
+ * @author 修唯xiuwei
+ * @version 3.0
+ */
+@Slf4j
+@RequestMapping("dataExchange")
+@RestController
+public class EquipmentAttributeController {
+
+  /**
+   * 设备属性服务
+   */
+  @Autowired
+  EquipmentAttributeService equipmentAttributeService;
+//  @Autowired ProtocolGatherDataPointService protocolGatherDataPointService;
+//  /**
+//   * 设备信息服务
+//   */
+//  @Autowired
+//  EquipmentInfoService equipmentInfoService;
+//  @Autowired
+//  ElectricFieldService electricFieldService;
+
+  /**
+   * 根据条件查询设备属性
+   *
+   * @param equipmentAttribute 设备实体
+   * @return ResponseVO 统一返回值
+   */
+  @GetMapping(value = "equipmentAttribute")
+  public SaResultRefit get(@RequestBody EquipmentAttribute equipmentAttribute) {
+    return SaResultRefit.data(equipmentAttributeService.get(equipmentAttribute));
+  }
+
+  /**
+   * 根据设备类型查设备属性
+   *
+   * @param equipmentType 设备类型
+   * @return ResponseVO 统一返回值
+   */
+  @GetMapping(value = "getByEquipmentType/{equipmentType}")
+  public SaResultRefit getByEquipmentType(@PathVariable String equipmentType) {
+    if (!StringUtils.isNotBlank(equipmentType)) {
+      return SaResultRefit.errorTips("必须传入设备类型");
+    }
+    EquipmentTypeEnum dataObjectTypeEnum;
+    try {
+      int i = Integer.parseInt(equipmentType);
+      dataObjectTypeEnum = EquipmentTypeEnum.valueOf(i);
+    } catch (NumberFormatException e) {
+      dataObjectTypeEnum = EquipmentTypeEnum.valueOf(equipmentType);
+    }
+    return SaResultRefit.data(equipmentAttributeService.getByEquipmentType(dataObjectTypeEnum));
+  }
+
+//  /**
+//   * 获取到所有的设备信息
+//   *
+//   * @return ResponseVO 统一返回值
+//   */
+//  @GetMapping(value = "equipmentInfo")
+//  public SaResultRefit getAllEquipmentInfo() {
+//    List list = new ArrayList();
+//    List<AbstractEquipmentInfo> info = equipmentInfoService.getAllEquipmentInfo();
+//    for (int i = 0; i < info.size(); i++) {
+//      list.add(info.get(i));
+//    }
+//    ElectricField electricFields = electricFieldService.get();
+//    HashMap map = new HashMap();
+//    map.put("id", electricFields.getStationCode());
+//    map.put("name", electricFields.getName());
+//    map.put("code", 0);
+//    list.add(map);
+//    return SaResultRefit.data(list);
+//  }
+
+  /**
+   * 得到所有
+   * 所有设备属性
+   *
+   * @return {@link SaResultRefit}
+   */
+  @GetMapping(value = "getAll")
+  public SaResultRefit getAll() {
+    try {
+      return SaResultRefit.data(this.equipmentAttributeService.getAll());
+    } catch (Exception e) {
+      e.printStackTrace();
+      log.error("查询异常");
+      return SaResultRefit.errorTips("查询异常");
+    }
+  }
+  /**
+   * 分页
+   * 所有设备属性
+   *
+   * @return {@link SaResultRefit}
+   */
+  @GetMapping(value = "getAllByPage/{page}/{size}")
+  public SaResultRefit getAllByPage(@PathVariable("page") Integer page, @PathVariable("size") Integer size) {
+    try {
+      QueryWrapper<EquipmentAttribute> wrapper = new QueryWrapper<>();
+      Page<EquipmentAttribute> result = equipmentAttributeService.page(new Page<>(page, size), wrapper);
+      return SaResultRefit.data(result);
+    } catch (Exception e) {
+      e.printStackTrace();
+      log.error("查询异常");
+      return SaResultRefit.errorTips("查询异常");
+    }
+  }
+
+//  /**
+//   * 获取设备信息
+//   * 根据设备类型找设备
+//   *
+//   * @param equipmentType 设备类型
+//   * @return {@link SaResultRefit}
+//   * @throws CustomException 业务异常
+//   */
+//  @GetMapping(value = "equipmentInfo/{equipmentType}")
+//  public SaResultRefit getEquipmentInfo(@PathVariable String equipmentType) throws CustomException {
+//    if (!StringUtils.isNotBlank(equipmentType)) {
+//      return SaResultRefit.errorTips("必须传入设备类型");
+//    }
+//    EquipmentTypeEnum type;
+//    try {
+//      int i = Integer.parseInt(equipmentType);
+//      type = EquipmentTypeEnum.valueOf(i);
+//    } catch (NumberFormatException e) {
+//      type = EquipmentTypeEnum.valueOf(equipmentType);
+//    }
+//    try {
+//      return SaResultRefit.data(equipmentInfoService.findByEqType(type));
+//    } catch (Exception e) {
+//      e.printStackTrace();
+//      log.error("查询异常");
+//      return SaResultRefit.errorTips("查询异常");
+//    }
+//  }
+
+  /**
+   * 获取设备类型状态枚举
+   * @return
+   */
+  @GetMapping("/getEquipmentTypeEnum")
+  public SaResultRefit getEquipmentTypeEnum(){
+    List list = new ArrayList<>();
+    for (EquipmentTypeEnum equipmentTypeEnum : EquipmentTypeEnum.values()) {
+      Map map = new HashMap();
+      if(!equipmentTypeEnum.getCode().equals(5)){
+        map.put("value",equipmentTypeEnum.name());
+        map.put("label",equipmentTypeEnum.getMessage());
+        map.put("code",equipmentTypeEnum.getCode());
+        list.add(map);
+      }
+    }
+    return SaResultRefit.data(list);
+  }
+
+
+  /**
+   * 获取设备类型状态枚举
+   * @return
+   */
+  @GetMapping("/getSubsidiaryEquipmentTypeEnum")
+  public SaResultRefit getSubsidiaryEquipmentTypeEnum(){
+    List list = new ArrayList<>();
+    for (EquipmentTypeEnum equipmentTypeEnum : EquipmentTypeEnum.SUBSIDIARY_EQUIPMENT_TYPE) {
+      Map map = new HashMap();
+      if(!equipmentTypeEnum.getCode().equals(5)){
+        map.put("value",equipmentTypeEnum.name());
+        map.put("label",equipmentTypeEnum.getMessage());
+        map.put("code",equipmentTypeEnum.getCode());
+        list.add(map);
+      }
+    }
+    return SaResultRefit.data(list);
+  }
+
+  /**
+   * 根据设备类型查设备属性 分页
+   *
+   * @param equipmentType 设备类型
+   * @return ResponseVO 统一返回值
+   */
+  @GetMapping(value = "/{equipmentType}/{page}/{size}")
+  public SaResultRefit findByEquipmentType(@PathVariable String equipmentType,@PathVariable Integer page,@PathVariable Integer size) {
+    try {
+      QueryWrapper<EquipmentAttribute> wrapper = new QueryWrapper<>();
+      if (StringUtils.isNotEmpty(equipmentType)) {
+        wrapper.eq("equipment_type", equipmentType);
+      }
+      Page<EquipmentAttribute> result = equipmentAttributeService.page(new Page<>(page, size), wrapper);
+      return SaResultRefit.data(result);
+    } catch (Exception e) {
+      e.printStackTrace();
+      log.error("查询异常");
+      return SaResultRefit.errorTips("查询异常");
+    }
+  }
+
+  @GetMapping(value = "/dataPointById/{id}")
+  public SaResultRefit dataPointById(@PathVariable Integer id) {
+//    ProtocolGatherDataPoint protocolGatherDataPoint = new ProtocolGatherDataPoint();
+//    EquipmentAttribute equipmentAttribute = new EquipmentAttribute();
+//    equipmentAttribute.setId(id);
+//    protocolGatherDataPoint.setEquipmentAttribute(equipmentAttribute);
+//    List<ProtocolGatherDataPoint> list = protocolGatherDataPointService.get(protocolGatherDataPoint);
+    List list = new ArrayList();
+    return SaResultRefit.data(list);
+  }
+
+  @PostMapping(value = "/saveEquipmentAttribute")
+  public SaResultRefit saveEquipmentAttribute(@RequestBody EquipmentAttribute equipmentAttribute){
+    equipmentAttributeService.saveOrUpdateEquipmentAttribute(equipmentAttribute);
+    return SaResultRefit.data(1);
+  }
+  @PostMapping(value = "/UpdateEquipmentAttribute")
+  public SaResultRefit UpdateEquipmentAttribute(@RequestBody EquipmentAttribute equipmentAttribute){
+    equipmentAttributeService.saveOrUpdateEquipmentAttribute(equipmentAttribute);
+    return SaResultRefit.data(1);
+  }
+  /*
+   * 删除
+   * */
+  @PostMapping("/delete/{id}")
+  public SaResultRefit delete(@PathVariable String id) throws CustomException {
+    equipmentAttributeService.delete(Integer.parseInt(id));
+    return SaResultRefit.data(1);
+  }
+}

+ 2 - 0
backend/src/main/java/com/jiayue/pfr/dto/FmDataBeanDto.java

@@ -10,4 +10,6 @@ public class FmDataBeanDto {
     private BigDecimal f=BigDecimal.valueOf(-99);
     //功率
     private BigDecimal activePower=BigDecimal.valueOf(-99);
+    //装机容量
+    private BigDecimal capacity=BigDecimal.valueOf(-99);
 }

+ 41 - 0
backend/src/main/java/com/jiayue/pfr/entity/BizYaoData.java

@@ -0,0 +1,41 @@
+package com.jiayue.pfr.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 遥数据
+ *
+ * @author jy
+ * @since 2023/11/14
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class BizYaoData extends BaseEntity {
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 一次调频动作 0:无动作 1:调频
+     */
+    private String action;
+    /**
+     * AGC闭锁 0:闭锁 1:开锁
+     */
+    private String agcLock;
+    /**
+     * 修正前负荷指令
+     */
+    private String correctBeforeLoad;
+    /**
+     * 修正后负荷指令
+     */
+    private String correctAfterLoad;
+    /**
+     * 当前时刻有功
+     */
+    private String activePower;
+}

+ 71 - 0
backend/src/main/java/com/jiayue/pfr/entity/EquipmentAttribute.java

@@ -0,0 +1,71 @@
+package com.jiayue.pfr.entity;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.jiayue.pfr.backenum.EquipmentTypeEnum;
+import lombok.Data;
+
+
+/**
+ * 各个装备的属性值提取出来
+ *
+ * @author 修唯xiuwei
+ * @version 3.0
+ */
+@Data
+public class EquipmentAttribute {
+
+    /**
+     * Id
+     */
+    @TableId(type = IdType.AUTO)
+    Integer id;
+
+    /**
+     * 属性的定义
+     */
+    String explanation;
+
+
+    /**
+     * 属性所对应的的类的属性
+     */
+    String fieldName;
+
+
+    /**
+     * 计量单位
+     */
+    String measurementUnits;
+
+
+    /**
+     * Equipment type
+     */
+    @EnumValue
+    EquipmentTypeEnum equipmentType;
+
+    /**
+     * 场站标识
+     */
+
+    private String stationCode;
+
+    /**
+     * 字段类型
+     */
+    private EquipmentAttributeTypeEnum equipmentAttributeTypeEnum;
+
+    enum EquipmentAttributeTypeEnum{
+        /**
+         * INVARIANT 固定字段 不可修改的
+         * SPARE 备用字段
+         * CUSTOM 自定义字段
+         */
+         INVARIANT,SPARE,CUSTOM
+    }
+
+
+
+}

+ 1 - 3
backend/src/main/java/com/jiayue/pfr/job/GetFmJob.java

@@ -1,13 +1,11 @@
 package com.jiayue.pfr.job;
 
-import cn.hutool.json.JSONUtil;
 import com.jiayue.pfr.constant.CacheConstants;
 import com.jiayue.pfr.dto.FmDataBeanDto;
 import com.jiayue.pfr.protocol.frequency.DataBean;
 import com.jiayue.pfr.protocol.frequency.DataBeanPacker;
-import com.jiayue.pfr.service.alg.GetFmEvent;
+import com.jiayue.pfr.service.alg.listener.GetFmEvent;
 import com.jiayue.pfr.service.cmf.SysParameterService;
-import com.jiayue.pfr.service.di.WebSocketServer;
 import org.apache.commons.lang3.time.DateFormatUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

+ 17 - 0
backend/src/main/java/com/jiayue/pfr/mapper/alg/BizYaoDataMapper.java

@@ -0,0 +1,17 @@
+package com.jiayue.pfr.mapper.alg;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.pfr.entity.BizYaoData;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ *  遥数据Mapper
+ *
+ * @author xsl
+ * @since 2023-03-17
+ */
+@Mapper
+public interface BizYaoDataMapper extends BaseMapper<BizYaoData> {
+
+}

+ 22 - 0
backend/src/main/java/com/jiayue/pfr/mapper/di/EquipmentAttributeMapper.java

@@ -0,0 +1,22 @@
+package com.jiayue.pfr.mapper.di;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.pfr.backenum.EquipmentTypeEnum;
+import com.jiayue.pfr.entity.EquipmentAttribute;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ *  遥数据Mapper
+ *
+ * @author xsl
+ * @since 2023-03-17
+ */
+@Mapper
+public interface EquipmentAttributeMapper extends BaseMapper<EquipmentAttribute> {
+    List<EquipmentAttribute> findAllByEquipmentType(EquipmentTypeEnum equipmentTypeEnum);
+
+    List<EquipmentAttribute> findAllByEquipmentAttribute(EquipmentAttribute equipmentAttribute);
+}

+ 71 - 0
backend/src/main/java/com/jiayue/pfr/protocol/agc/Master104ForAgcApplication.java

@@ -0,0 +1,71 @@
+package com.jiayue.pfr.protocol.agc;
+
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.ShortFloatCommand;
+import wei.yigulu.iec104.asdudataframe.TotalSummonType;
+import wei.yigulu.iec104.asdudataframe.typemodel.IecDataInterface;
+import wei.yigulu.iec104.nettyconfig.Iec104MasterBuilder;
+import wei.yigulu.iec104.util.CommandWaiter;
+import wei.yigulu.iec104.util.SendAndReceiveNumUtil;
+import wei.yigulu.iec104.util.SendCommandHelper;
+
+/**
+ * 104主站调用AGC
+ *
+ * @author jy
+ * @since 2023/11/17
+ */
+@Service
+public class Master104ForAgcApplication {
+//    @Autowired
+//    Iec104MasterBuilder iec104MasterBuilder;
+
+    public void Master104ForAgcApplication(){
+
+
+        //创建总召唤类型I帧
+        TotalSummonType totalSummonType=new TotalSummonType();
+        //反向生成asdu
+        Asdu asdu = totalSummonType.generateBack();
+        //配置总召唤发送原因
+        asdu.setNot(6);
+        //配置公共地址位
+        asdu.setCommonAddress(1);
+        Apdu apdu=new Apdu().setAsdu(asdu);
+        try {
+//            iec104MasterBuilder.sendFrameToOpposite(apdu.encode());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+
+
+//        ShortFloatCommand command = new ShortFloatCommand(dataAddress, value);
+//        Apdu apdu = new Apdu();
+//        Asdu asdu = command.generateBack();
+//        asdu.setCommonAddress(commonAddress);
+//        asdu.setOriginatorAddress(sourceAddress);
+//        asdu.getCot().setNot(6);
+//        apdu.setAsdu(asdu);
+//        SendAndReceiveNumUtil.sendIFrame(apdu, masterBuilder.getFuture().channel(), masterBuilder.getLog());
+//        CommandWaiter commandWaiter = new CommandWaiter(masterBuilder.getFuture().channel().id(), apdu, dataAddress);
+//        commandWaiters.add(commandWaiter);
+//
+//        IecDataInterface data;
+//        try {
+//            data = commandWaiter.get();
+//        } catch (Exception var14) {
+//            throw var14;
+//        } finally {
+//            commandWaiters.remove(commandWaiter);
+//        }
+
+
+
+
+    }
+}

+ 21 - 0
backend/src/main/java/com/jiayue/pfr/service/alg/BizYaoDataService.java

@@ -0,0 +1,21 @@
+package com.jiayue.pfr.service.alg;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.pfr.entity.BizYaoData;
+/**
+* 遥数据接口
+* @author xsl
+* @date 2023/2/16
+*/
+public interface BizYaoDataService extends IService<BizYaoData> {
+    /**
+     * 查询遥数据
+     * @return BizYaoData
+     */
+    BizYaoData queryCache();
+    /**
+     * 修改系统参数
+     * @return BizYaoData
+     */
+    BizYaoData update(BizYaoData bizYaoData);
+}

+ 0 - 23
backend/src/main/java/com/jiayue/pfr/service/alg/FrequencyServiceImpl.java

@@ -1,23 +0,0 @@
-package com.jiayue.pfr.service.alg;
-
-import org.springframework.stereotype.Service;
-
-import java.math.BigDecimal;
-
-/**
- * 频率服务类
- *
- * @author xsl
- * @since 2023/10/27
- */
-@Service
-public class FrequencyServiceImpl {
-
-    private BigDecimal activeFrequencyFormula(){
-
-
-
-
-        return null;
-    }
-}

+ 47 - 0
backend/src/main/java/com/jiayue/pfr/service/alg/impl/BizYaoDataServiceImpl.java

@@ -0,0 +1,47 @@
+package com.jiayue.pfr.service.alg.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.pfr.entity.BizYaoData;
+import com.jiayue.pfr.mapper.alg.BizYaoDataMapper;
+import com.jiayue.pfr.service.alg.BizYaoDataService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+* 遥数据服务类
+* @author xsl
+* @date 2023/2/16
+*/
+@Service
+public class BizYaoDataServiceImpl extends ServiceImpl<BizYaoDataMapper, BizYaoData> implements BizYaoDataService {
+    @Autowired
+    BizYaoDataMapper bizYaoDataMapper;
+
+    /**
+     * 查询遥数据
+     * @return BizYaoData
+     */
+    @Cacheable(cacheNames = "pfrcache", key = "'bizyaodata'")
+    public BizYaoData queryCache(){
+        LambdaQueryWrapper<BizYaoData> queryWrapper = new LambdaQueryWrapper<>();
+        BizYaoData bizYaoData = bizYaoDataMapper.selectOne(queryWrapper);
+        return bizYaoData;
+    }
+
+    /**
+     * 修改系统参数
+     * @return BizYaoData
+     */
+    @Transactional(propagation = Propagation.SUPPORTS)
+    @CachePut(cacheNames = "pfrcache", key = "'bizyaodata'")
+    public BizYaoData update(BizYaoData bizYaoData) {
+        bizYaoDataMapper.updateById(bizYaoData);
+        return bizYaoData;
+    }
+}

+ 22 - 0
backend/src/main/java/com/jiayue/pfr/service/alg/listener/AgcEvent.java

@@ -0,0 +1,22 @@
+package com.jiayue.pfr.service.alg.listener;
+
+import com.jiayue.pfr.dto.FmDataBeanDto;
+import com.jiayue.pfr.entity.BizYaoData;
+import lombok.Getter;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * AGC事件
+ *
+ * @author jy
+ * @since 2023/11/14
+ */
+public class AgcEvent  extends ApplicationEvent {
+    @Getter
+    private final BizYaoData bizYaoData;
+
+    public AgcEvent(Object source, BizYaoData bizYaoData) {
+        super(source);
+        this.bizYaoData = bizYaoData;
+    }
+}

+ 94 - 0
backend/src/main/java/com/jiayue/pfr/service/alg/listener/AgcLockListener.java

@@ -0,0 +1,94 @@
+package com.jiayue.pfr.service.alg.listener;
+
+import com.jiayue.pfr.backenum.ActionResetEnum;
+import com.jiayue.pfr.entity.BizYaoData;
+import com.jiayue.pfr.service.alg.BizYaoDataService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.SingleBooleanCommand;
+import wei.yigulu.iec104.asdudataframe.typemodel.IeSingleBooleanCommand;
+import wei.yigulu.iec104.asdudataframe.typemodel.IecDataInterface;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+import wei.yigulu.iec104.nettyconfig.Iec104MasterBuilder;
+import wei.yigulu.iec104.util.CommandWaiter;
+import wei.yigulu.iec104.util.SendAndReceiveNumUtil;
+import wei.yigulu.iec104.util.SendCommandHelper;
+
+/**
+ * 给AGC闭锁
+ *
+ * @author jy
+ * @since 2023/11/14
+ */
+@Component
+public class AgcLockListener implements ApplicationListener<AgcEvent> {
+    private static final Logger fLogger = LoggerFactory.getLogger("FLogger");
+
+    @Autowired
+    BizYaoDataService bizYaoDataService;
+//    @Autowired
+//    Iec104MasterBuilder iec104MasterBuilder;
+
+    @Async
+    @Override
+    public void onApplicationEvent(AgcEvent agcEvent) {
+        Object obj = agcEvent.getSource();
+        BizYaoData bizYaoData = agcEvent.getBizYaoData();
+        if (obj.toString().equals(ActionResetEnum.ACTION.getCode())){
+            // 动作
+            fLogger.info("给AGC闭锁开始");
+
+            SingleBooleanCommand command = new SingleBooleanCommand();
+            Apdu apdu = new Apdu();
+            Asdu asdu = command.generateBack();
+            asdu.setCommonAddress(1);
+            asdu.getCot().setNot(6);
+            asdu.getVsq().setSq(0);
+            asdu.getVsq().setNum(1);
+            asdu.setOriginatorAddress(0);
+            command.setAddresses(new InformationBodyAddress(25089));
+            command.setVal(new IeSingleBooleanCommand(true));
+
+            apdu.setAsdu(asdu);
+
+//            CommandWaiter commandWaiter = new CommandWaiter(iec104MasterBuilder.getFuture().channel().id(), apdu, command.getAddresses().getAddress());
+
+            // 接收闭锁回复?
+
+
+//            SendAndReceiveNumUtil.sendIFrame(apdu, iec104MasterBuilder.getFuture().channel(), iec104MasterBuilder.getLog());
+//            CommandWaiter commandWaiter = new CommandWaiter(iec104MasterBuilder.getFuture().channel().id(), apdu, dataAddress);
+//            commandWaiters.add(commandWaiter);
+//
+//            IecDataInterface data;
+//            try {
+//                data = commandWaiter.get();
+//            } catch (Exception var14) {
+//                throw var14;
+//            } finally {
+//                commandWaiters.remove(commandWaiter);
+//            }
+
+
+
+
+            bizYaoData.setAgcLock("0");
+            bizYaoData.setAction("0");
+            bizYaoDataService.update(bizYaoData);
+            fLogger.info("给AGC闭锁结束");
+        }
+        else if (obj.toString().equals(ActionResetEnum.RESET.getCode())){
+            // 复归
+            bizYaoData.setAgcLock("1");
+            bizYaoData.setAction("1");
+            bizYaoDataService.update(bizYaoData);
+            fLogger.info("AGC解锁");
+        }
+    }
+}

+ 18 - 8
backend/src/main/java/com/jiayue/pfr/service/alg/CoreAlgListener.java → backend/src/main/java/com/jiayue/pfr/service/alg/listener/CoreAlgListener.java

@@ -1,15 +1,17 @@
-package com.jiayue.pfr.service.alg;
+package com.jiayue.pfr.service.alg.listener;
 
-import cn.hutool.json.JSONUtil;
+import com.jiayue.pfr.backenum.ActionResetEnum;
 import com.jiayue.pfr.constant.CacheConstants;
 import com.jiayue.pfr.dto.FmDataBeanDto;
 import com.jiayue.pfr.dto.SagFormulaDto;
+import com.jiayue.pfr.entity.BizYaoData;
+import com.jiayue.pfr.service.alg.BizYaoDataService;
 import com.jiayue.pfr.service.cmf.SysParameterService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.ApplicationListener;
-import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
@@ -27,35 +29,43 @@ public class CoreAlgListener implements ApplicationListener<GetFmEvent> {
 
     @Autowired
     SysParameterService sysParameterService;
+    @Autowired
+    ApplicationEventPublisher applicationEventPublisher;
+    @Autowired
+    BizYaoDataService bizYaoDataService;
 
     @Async
     @Override
     public void onApplicationEvent(GetFmEvent getFmEvent) {
         // 判断一次调频是否投入/退出
         String ieSignal = sysParameterService.queryByKey("ieSignal","ON");
+
+
         if ("ON".equals(ieSignal)){
             // 投入,获取最新频率
             FmDataBeanDto fmDataBeanDto = getFmEvent.getFmDataBeanDto();
             if (fmDataBeanDto.getF().compareTo(new BigDecimal("-99"))!=0){
                 SagFormulaDto sagFormulaDto = genSagFormulaAttr(fmDataBeanDto);
+                BizYaoData bizYaoData = bizYaoDataService.queryCache();
                 // 判断频率是否超死区
                 if (!"".equals(sagFormulaDto.getFmDisturb())){
-                    if ("OFF".equals(CacheConstants.fmAct)){
-                        CacheConstants.fmAct = "ON";
+                    // 判断是否有过动作信号
+                    if ("1".equals(bizYaoData.getAction())){
                         // 计算有功-频率下垂公式=>∆P
                         BigDecimal dtp = sagFormulaCal(sagFormulaDto,fmDataBeanDto);
                         // 给AGC闭锁调用104
-
+                        applicationEventPublisher.publishEvent(new AgcEvent(ActionResetEnum.ACTION.getCode(),bizYaoData));
                         // 上传PMU、EMS数据
                         fLogger.info("超出死区频率:"+sagFormulaDto.getDb()+ " 当前频率:"+fmDataBeanDto.getF()+" 时间:"+fmDataBeanDto.getTime());
                     }
                 }
                 else{
                     // 判断是否有过动作信号
-                    if ("ON".equals(CacheConstants.fmAct)){
+                    if ("0".equals(bizYaoData.getAction())){
                         fLogger.info("频率恢复,当前频率:"+fmDataBeanDto.getF()+" 时间:"+fmDataBeanDto.getTime());
+                        applicationEventPublisher.publishEvent(new AgcEvent(ActionResetEnum.RESET.getCode(),bizYaoData));
                         // 做复归通知,AGC和PMU
-                        CacheConstants.fmAct = "OFF";
+//                        CacheConstants.fmAct = "OFF";
                     }
                 }
             }

+ 24 - 0
backend/src/main/java/com/jiayue/pfr/service/alg/listener/EmsUploadListener.java

@@ -0,0 +1,24 @@
+package com.jiayue.pfr.service.alg.listener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * EMS上传
+ *
+ * @author jy
+ * @since 2023/11/14
+ */
+@Component
+public class EmsUploadListener implements ApplicationListener<AgcEvent> {
+    private static final Logger fLogger = LoggerFactory.getLogger("FLogger");
+
+    @Async
+    @Override
+    public void onApplicationEvent(AgcEvent agcEvent) {
+//        fLogger.info("EMS上传");
+    }
+}

+ 1 - 1
backend/src/main/java/com/jiayue/pfr/service/alg/GetFmEvent.java → backend/src/main/java/com/jiayue/pfr/service/alg/listener/GetFmEvent.java

@@ -1,4 +1,4 @@
-package com.jiayue.pfr.service.alg;
+package com.jiayue.pfr.service.alg.listener;
 
 import com.jiayue.pfr.dto.FmDataBeanDto;
 import lombok.Getter;

+ 10 - 2
backend/src/main/java/com/jiayue/pfr/service/alg/SendFmSocketListener.java → backend/src/main/java/com/jiayue/pfr/service/alg/listener/SendFmSocketListener.java

@@ -1,15 +1,17 @@
-package com.jiayue.pfr.service.alg;
+package com.jiayue.pfr.service.alg.listener;
 
 import cn.hutool.json.JSONUtil;
+import com.jiayue.pfr.service.cmf.SysParameterService;
 import com.jiayue.pfr.service.di.WebSocketServer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationListener;
-import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 
 /**
  * 发送频率给前端监听
@@ -20,10 +22,16 @@ import java.io.IOException;
 @Component
 public class SendFmSocketListener implements ApplicationListener<GetFmEvent> {
     private static final Logger fLogger = LoggerFactory.getLogger("FLogger");
+
+    @Autowired
+    SysParameterService sysParameterService;
+
     @Async
     @Override
     public void onApplicationEvent(GetFmEvent getFmEvent) {
         try {
+            String capacity = sysParameterService.queryByKey("capacity","300");
+            getFmEvent.getFmDataBeanDto().setCapacity(new BigDecimal(capacity));
             WebSocketServer.sendInfo(JSONUtil.toJsonStr(getFmEvent.getFmDataBeanDto()));
         } catch (IOException e) {
             throw new RuntimeException(e);

+ 70 - 0
backend/src/main/java/com/jiayue/pfr/service/di/EquipmentAttributeService.java

@@ -0,0 +1,70 @@
+package com.jiayue.pfr.service.di;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.pfr.backenum.EquipmentTypeEnum;
+import com.jiayue.pfr.entity.EquipmentAttribute;
+
+
+import java.util.List;
+
+/**
+ * 装置的状态描述表的操作service类
+ *
+ * @author 修唯xiuwei
+ * @version 3.0
+ */
+public interface EquipmentAttributeService  extends IService<EquipmentAttribute> {
+
+
+
+	/**
+	 * 获取某类设备的状态数据描述属性
+	 * 查询设备属性by设备类型
+	 *
+	 * @param dataObjectTypeEnum 设备类型
+	 * @return EquipmentAttribute 设备属性
+	 */
+	public List<EquipmentAttribute> getByEquipmentType(EquipmentTypeEnum dataObjectTypeEnum);
+
+
+	/**
+	 * 查找符合条件的设备属性
+	 *
+	 * @param equipmentAttribute 设备属性
+	 * @return EquipmentAttribute 设备属性列表
+	 */
+	public List<EquipmentAttribute> get(EquipmentAttribute equipmentAttribute);
+
+	/**
+	 * 查所有的设备属性
+	 *
+	 * @return EquipmentAttribute 设备属性列表
+	 */
+	public List<EquipmentAttribute> getAll();
+
+//	/**
+//	 *  分页查询
+//	 */
+//	public Page getAllByPage(Integer page, Integer size);
+
+//	/**
+//	 * 获取某类设备的状态数据描述属性
+//	 * 查询设备属性by设备类型
+//	 * 分页
+//	 *
+//	 * @param equipmentType 设备类型
+//	 * @return EquipmentAttribute 设备属性
+//	 */
+//	public Page<EquipmentAttribute> findByEquipmentType(String equipmentType, Integer page, Integer size);
+
+	/**
+	 * 保存
+	 */
+	public void saveOrUpdateEquipmentAttribute(EquipmentAttribute equipmentAttribute);
+
+	/**
+	 * 删除
+	 * */
+	public void delete(Integer id);
+}

+ 102 - 0
backend/src/main/java/com/jiayue/pfr/service/di/impl/EquipmentAttributeServiceImpl.java

@@ -0,0 +1,102 @@
+package com.jiayue.pfr.service.di.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.pfr.backenum.EquipmentTypeEnum;
+import com.jiayue.pfr.entity.EquipmentAttribute;
+import com.jiayue.pfr.mapper.di.EquipmentAttributeMapper;
+import com.jiayue.pfr.service.di.EquipmentAttributeService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 装置的状态描述表的操作service类
+ *
+ * @author 修唯xiuwei
+ * @version 3.0
+ */
+@Service
+public class EquipmentAttributeServiceImpl extends ServiceImpl<EquipmentAttributeMapper, EquipmentAttribute> implements EquipmentAttributeService {
+
+	/**
+	 * 操作仓库
+	 */
+	@Autowired
+	EquipmentAttributeMapper equipmentAttributeMapper;
+
+	/**
+	 * 获取某类设备的状态数据描述属性
+	 * 查询设备属性by设备类型
+	 *
+	 * @param dataObjectTypeEnum 设备类型
+	 * @return EquipmentAttribute 设备属性
+	 */
+	public List<EquipmentAttribute> getByEquipmentType(EquipmentTypeEnum dataObjectTypeEnum) {
+		QueryWrapper<EquipmentAttribute> wrapper = new QueryWrapper<>();
+		wrapper.eq("equipment_type", dataObjectTypeEnum);
+		return equipmentAttributeMapper.selectList(wrapper);
+//		return this.equipmentAttributeMapper.findAllByEquipmentType(dataObjectTypeEnum);
+	}
+
+
+	/**
+	 * 查找符合条件的设备属性
+	 *
+	 * @param equipmentAttribute 设备属性
+	 * @return EquipmentAttribute 设备属性列表
+	 */
+	public List<EquipmentAttribute> get(EquipmentAttribute equipmentAttribute) {
+		return this.equipmentAttributeMapper.findAllByEquipmentAttribute(equipmentAttribute);
+	}
+
+	/**
+	 * 查所有的设备属性
+	 *
+	 * @return EquipmentAttribute 设备属性列表
+	 */
+	public List<EquipmentAttribute> getAll() {
+		return this.list();
+	}
+
+//	/**
+//	 *  分页查询
+//	 */
+//	public Page getAllByPage(Integer page, Integer size) {
+//		Pageable pageable = PageRequest.of(page - 1, size);
+//		Page equipmentAttributePage = equipmentAttributeRepository.findAll(pageable);
+//		return equipmentAttributePage;
+//	}
+
+//	/**
+//	 * 获取某类设备的状态数据描述属性
+//	 * 查询设备属性by设备类型
+//	 * 分页
+//	 *
+//	 * @param equipmentType 设备类型
+//	 * @return EquipmentAttribute 设备属性
+//	 */
+//	public Page<EquipmentAttribute> findByEquipmentType(String equipmentType, Integer page, Integer size) {
+//		Pageable pageable = PageRequest.of(page - 1, size);
+//		EquipmentTypeEnum equipmentTypeEnum = EquipmentTypeEnum.valueOf(equipmentType);
+//		Page<EquipmentAttribute> equipmentAttributePage = equipmentAttributeRepository.findAllByEquipmentType(equipmentTypeEnum, pageable);
+//		return equipmentAttributePage;
+//	}
+
+	/**
+	 * 保存
+	 */
+	public void saveOrUpdateEquipmentAttribute(EquipmentAttribute equipmentAttribute) {
+		this.saveOrUpdate(equipmentAttribute);
+	}
+
+	/**
+	 * 删除
+	 * */
+	public void delete(Integer id) {
+		this.removeById(id);
+	}
+}

+ 0 - 22
backend/src/main/java/com/jiayue/pfr/util/SecurityContextUtil.java

@@ -1,22 +0,0 @@
-package com.jiayue.pfr.util;
-
-/**
-* SecurityContext获取
-*
-* @author xsl
-* @since 2023/03/14
-*/
-public class SecurityContextUtil {
-    /**
-     * 获取当前系统用户
-     * @return
-     */
-//    public static SysUser getSysUser(){
-////        if (SecurityContextHolder.getContext().getAuthentication()==null){
-////            SysUser sysUser = new SysUser();
-////            sysUser.setUsername("system");
-////            return sysUser;
-////        }
-////        return (SysUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-//    }
-}

+ 0 - 10
backend/src/main/java/com/jiayue/pfr/util/SecurityValidate.java

@@ -1,10 +0,0 @@
-package com.jiayue.pfr.util;
-/**
-* sql注入,路径操作,http响应拦截,日志伪造验证类
-*
-* @author xsl
-* @since 2023/05/12
-*/
-public class SecurityValidate {
-
-}

+ 1 - 1
backend/src/main/resources/application.yml

@@ -24,7 +24,7 @@ spring:
       stat-view-servlet.enabled: false
     driver-class-name: com.mysql.cj.jdbc.Driver
     type: com.alibaba.druid.pool.DruidDataSource
-    url: jdbc:mysql://localhost:3307/pfr?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://localhost:3306/pfr?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
     username: JY[15a0b9e58aef5b73fbbc12ce85ab5046b22a703e45019dbf7dd7041c8c60ea061cca717220548d86baa4cab57ebcc42db62172178c4cc299f243cfe7a3550e3b367284368dc3a183b350b92b810da5b2030a647aaede5baf735c6dcc77700a5325773e91]
     password: JY[bbe20dde79320dfbe7bca925e07c57c13d079c72f1547fb97023020262a339f2a293e466cfc9ee9f0cb7c139bdcb78bccdf0fe9090a3da72a09f645873af6a7696c286540112c2d0f634a15ed013827d078b6edd6afc45df94278d5cd0da622a2c88f5e52b4ad5b7ab]
 

+ 1 - 2
ui/README.md

@@ -1,2 +1 @@
-# ssi【State security inspection】
-国密安全检测
+# pfr 一次调频

+ 397 - 0
ui/src/views/dataexchange/equipmentAttribute/index.vue

@@ -0,0 +1,397 @@
+<template>
+  <div style="padding-left: 30px">
+    <div style="margin-top: 0.5%;margin-bottom: 0.2%">
+      <span style="font-weight: bold">设备类型:</span>
+      <vxe-select v-model="equipmentType" placeholder="请选择设备类型" style="width: 10%" clearable>
+        <vxe-option v-for="item in equipmentTypeEnum" :key="item.value" :value="item.value" :label="item.label" />
+      </vxe-select>
+      <div style="display: inline-block">
+        <vxe-toolbar>
+          <template v-slot:buttons>
+            <vxe-button status="primary" @click="search()">查询</vxe-button>
+            <vxe-button status="primary" icon="fa fa-plus" @click="insertEvent()">新增</vxe-button>
+          </template>
+        </vxe-toolbar>
+      </div>
+    </div>
+    <vxe-table
+      ref="xTable"
+      border
+      stripe
+      resizable
+      show-overflow
+      keep-source
+      max-height="800"
+      align="center"
+      :edit-rules="rules"
+      :loading="loading"
+      :data="tableData"
+      :edit-config="{trigger: 'manual', mode: 'row',autoClear: false}"
+    >
+      <vxe-table-column type="checkbox" width="60px" />
+      <vxe-table-column field="id" title="Id" sortable />
+      <vxe-table-column
+        field="explanation"
+        title="设备属性名称"
+        width="20%"
+        :edit-render="{name: '$input', props: {type: 'text',disabled: explanationDisabled}}"
+      />
+      <vxe-table-column
+        field="fieldName"
+        title="字段名称"
+        width="20%"
+        :edit-render="{name: '$input', props: {type: 'text',disabled: fieldNameDisabled}}"
+      />
+      <vxe-table-column
+        field="measurementUnits"
+        title="单位"
+        :edit-render="{name: '$input', props: {type: 'text',disabled: unitsDisabled}}"
+      />
+      <vxe-table-column
+        field="equipmentType"
+        title="设备类型"
+        :edit-render="{name: '$select', options: equipmentTypeEnum, props: {disabled: equipmentDisabled}}"
+        :filters="this.equipmentTypeEnum"
+        :filter-multiple="false"
+      />
+      <vxe-table-column
+        field="equipmentAttributeTypeEnum"
+        title="字段类型"
+        :formatter="formateEquipmentTypeEnum"
+        :edit-render="{name: '$select', options: equipmentAttributeTypeEnum, props: {disabled: equipmentAttributeDisabled}}"
+        :filters="this.equipmentAttributeTypeEnum"
+        :filter-multiple="false"
+        :filter-method="filterMethod"
+      />
+      <vxe-table-column title="操作" width="150">
+        <template v-slot="{ row }">
+          <template v-if="$refs.xTable.isActiveByRow(row)">
+            <vxe-button
+              status="success"
+              style="padding: 3px 4px 3px 4px;margin: 2px;"
+              size="mini"
+              icon="el-icon-edit"
+              @click="findByEquipmentType(row)"
+            >保存
+            </vxe-button>
+            <vxe-button
+              class="cancel-btn"
+              icon="el-icon-refresh"
+              status="warning"
+              style="padding: 3px 4px 3px 4px;margin: 2px;"
+              size="mini"
+              @click="cancelRowEvent(row)"
+            >取消
+            </vxe-button>
+          </template>
+          <template v-else>
+            <div style="display: flex;justify-content: space-around">
+              <vxe-button status="primary" size="mini" @click="editRowEvent(row)">编辑</vxe-button>
+              <div v-if="row.equipmentAttributeTypeEnum == 'INVARIANT' || row.equipmentAttributeTypeEnum == 'SPARE' || row.equipmentAttributeTypeEnum == null">
+                <vxe-button status="info" size="mini" disabled>删除</vxe-button>
+              </div>
+              <div v-else>
+                <vxe-button status="danger" size="mini" @click="removeEvent(row)">删除</vxe-button>
+              </div>
+            </div>
+          </template>
+        </template>
+      </vxe-table-column>
+    </vxe-table>
+    <vxe-pager
+      perfect
+      :current-page.sync="currentPage"
+      :page-size.sync="pageSize"
+      :total="totalResult"
+      :layouts="['PrevJump', 'PrevPage', 'JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']"
+      @page-change="handlePageChangeNo"
+    />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'Index',
+  data() {
+    const checkExplanation = (rule, value, callback) => {
+      var s6 = this.modData
+      for (let i = 0; i < s6.length; i++) {
+        if (this.saveFlag === 1) {
+          // 新增
+          if ((value == s6[i].explanation)) {
+            callback(new Error('设备属性名称不能重复'))
+          }
+        } else {
+          if (this.modId != s6[i].id) {
+            if ((value == s6[i].explanation)) {
+              callback(new Error('设备属性名称不能重复'))
+            }
+          }
+        }
+      }
+      callback()
+    }
+    const checkFieldName = (rule, value, callback) => {
+      var s6 = this.modData
+      for (let i = 0; i < s6.length; i++) {
+        if (this.saveFlag === 1) {
+          // 新增
+          if ((value == s6[i].fieldName)) {
+            callback(new Error('字段名称不能重复'))
+          }
+        } else {
+          if (this.modId != s6[i].id) {
+            if ((value == s6[i].fieldName)) {
+              callback(new Error('字段名称不能重复'))
+            }
+          }
+        }
+      }
+      callback()
+    }
+    return {
+      loading: false,
+      explanationDisabled: false,
+      fieldNameDisabled: false,
+      unitsDisabled: false,
+      equipmentDisabled: false,
+      equipmentAttributeDisabled: false,
+      saveFlag: 1,
+      equipmentType: '',
+      tableData: [],
+      allData: [],
+      modData: [],
+      modId: '',
+      equipmentTypeEnum: [],
+      equipmentAttributeTypeEnum: [{ value: 'INVARIANT', label: '固定字段' }, { value: 'SPARE', label: '备用字段' }, { value: 'CUSTOM', label: '自定义字段' }],
+      currentPage: 1,
+      pageSize: 10,
+      totalResult: 0,
+      rules: {
+        explanation: [
+          { required: true, validator: checkExplanation }
+        ],
+        fieldName: [
+          { required: true, validator: checkFieldName }
+        ]
+      }
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      Promise.all([this.getEquipmentTypeEnum(), this.getAllData()]).then((res) => {
+        this.equipmentTypeEnum = res[0]
+        this.allData = res[1]
+        this.$nextTick(() => {
+          this.get()
+          this.updateEquipmentTypeFilterEvent()
+        })
+      })
+    },
+    get() {
+      this.loading = true
+      this.$axios.get('dataExchange/getAllByPage/' + this.currentPage + '/' + this.pageSize).then((res) => {
+        this.currentPage = res.data.current
+        this.pageSize = res.data.size
+        this.totalResult = res.data.total
+        this.tableData = res.data.records
+        for (var i = 0; i < this.tableData.length; i++) {
+          const item = this.equipmentTypeEnum.find(item => item.label === this.tableData[i].equipmentType.message)
+          this.tableData[i].equipmentType = item.value
+        }
+        this.loading = false
+      })
+      //   .catch((error) => {
+      //   this.loading = false
+      //   this.$message.error('查询设备属性错误:' + error)
+      // })
+    },
+    getEquipmentTypeEnum() {
+      const axios = this.$axios
+      return new Promise(function(resolve, reject) {
+        axios.get('dataExchange/getEquipmentTypeEnum').then(res => {
+          resolve(res.data)
+        })
+      })
+    },
+    getAllData() {
+      const axios = this.$axios
+      return new Promise(function(resolve, reject) {
+        axios.get('dataExchange/getAll').then(res => {
+          resolve(res.data)
+        })
+      })
+    },
+    findByEquipmentType(row) {
+      const item = this.equipmentTypeEnum.find(item => item.value === row.equipmentType)
+      var EquipmentTypeCode = item ? item.code : ''
+      this.$axios.get('dataExchange/getByEquipmentType/' + EquipmentTypeCode).then((res) => {
+        this.modData = res.data
+        this.editSave(row)
+      })
+    },
+    search() {
+      this.loading = true
+      if (this.equipmentType === null || this.equipmentType === '') {
+        this.get()
+      } else {
+        this.$axios.get('dataExchange/' + this.equipmentType + '/' + this.currentPage + '/' + this.pageSize).then((res) => {
+          this.currentPage = res.data.current
+          this.pageSize = res.data.size
+          this.totalResult = res.data.total
+          this.tableData = res.data.records
+          for (var i = 0; i < this.tableData.length; i++) {
+            const item = this.equipmentTypeEnum.find(item => item.label === this.tableData[i].equipmentType.message)
+            this.tableData[i].equipmentType = item.value
+          }
+          this.loading = false
+          // console.log(res.data)
+        })
+      }
+    },
+    editSave(row) {
+      this.$refs.xTable.validate(this.$refs.xTable.getCurrentRecord(), valid => {
+        if (valid) {
+          if (this.saveFlag === 1) {
+            this.$axios.post('/dataExchange/saveEquipmentAttribute/', row).then((res) => {
+              if (res.data === 1) {
+                this.$message.success(`保存${row.explanation}属性成功`)
+              } else {
+                this.$message.error(`保存${row.explanation}属性失败`)
+              }
+              this.init()
+            }).catch((error) => {
+              this.$message.error(`保存操作失败:` + error)
+            })
+          } else {
+            this.$axios.post('/dataExchange/UpdateEquipmentAttribute/', row).then((res) => {
+              if (res.data === 1) {
+                this.$message.success(`修改${row.explanation}属性成功`)
+              } else {
+                this.$message.error(`修改${row.explanation}属性失败`)
+              }
+              this.init()
+            }).catch((error) => {
+              this.$message.error(`修改操作失败:` + error)
+            })
+          }
+        } else {
+          this.$message.error('校验不通过')
+        }
+      })
+    },
+    insertEvent() {
+      this.saveFlag = 1
+      this.explanationDisabled = false
+      this.fieldNameDisabled = false
+      this.unitsDisabled = false
+      this.equipmentDisabled = false
+      this.equipmentAttributeDisabled = true
+      this.$refs.xTable.insert({ equipmentAttributeTypeEnum: 'CUSTOM' }).then(({ row }) => this.$refs.xTable.setActiveRow(row))
+    },
+    editRowEvent(row) {
+      this.modId = row.id
+      this.saveFlag = 2
+      this.equipmentAttributeDisabled = true
+      if (row.equipmentAttributeTypeEnum === 'INVARIANT' || row.equipmentAttributeTypeEnum === null) {
+        this.explanationDisabled = true
+        this.fieldNameDisabled = true
+        this.unitsDisabled = false
+        this.equipmentDisabled = true
+      } else if (row.equipmentAttributeTypeEnum === 'SPARE') {
+        this.explanationDisabled = false
+        this.fieldNameDisabled = true
+        this.unitsDisabled = false
+        this.equipmentDisabled = true
+      } else {
+        this.explanationDisabled = false
+        this.fieldNameDisabled = false
+        this.unitsDisabled = false
+        this.equipmentDisabled = false
+      }
+      this.$refs.xTable.setActiveRow(row)
+    },
+    removeEvent(row) {
+      this.$axios.get('/dataExchange/dataPointById/' + row.id).then((res) => {
+        if (res.data.length > 0) {
+          this.$message.warning(`${row.explanation}属性已经配置点表不可删除`)
+        } else {
+          this.$XModal.confirm('您确定要删除该数据?').then(type => {
+            if (type === 'confirm') {
+              this.$axios.post('/dataExchange/delete/' + row.id).then((res) => {
+                if (res.data === 1) {
+                  this.$message.success(`删除${row.explanation}属性成功`)
+                  this.$refs.xTable.remove(row)
+                } else {
+                  this.$message.error(`删除${row.explanation}属性失败`)
+                }
+              }).catch((error) => {
+                this.$message.error(`删除操作失败:` + error)
+              })
+            }
+          })
+        }
+      })
+    },
+    cancelRowEvent(row) {
+      const xTable = this.$refs.xTable
+      if (row.id == undefined) {
+        xTable.clearActived().then(() => {
+          xTable.remove(row)
+        })
+      } else {
+        xTable.clearActived().then(() => {
+          // 还原行数据
+          xTable.revertData(row)
+        })
+      }
+    },
+    // 转换文件类型协议
+    formateEquipmentTypeEnum({ cellValue }) {
+      if (cellValue === null) {
+        return '固定字段'
+      }
+      const item = this.equipmentAttributeTypeEnum.find(item => item.value === cellValue)
+      return item ? item.label : ''
+    },
+    // 过滤条件赋值,重新处理
+    updateEquipmentTypeFilterEvent() {
+      var data = []
+      for (var i = 0; i < this.equipmentTypeEnum.length; i++) {
+        data.push({ value: this.equipmentTypeEnum[i].value, label: this.equipmentTypeEnum[i].label })
+      }
+      const xTable = this.$refs.xTable
+      const column = xTable.getColumnByField('equipmentType')
+      // 修改筛选列表,并默认设置为选中状态
+      xTable.setFilter(column, data)
+      // 修改条件之后,需要手动调用 updateData 处理表格数据
+      xTable.updateData()
+    },
+    filterMethod({ value, row, column }) {
+      if (value === 'INVARIANT' || value === null) {
+        return row.equipmentAttributeTypeEnum === 'INVARIANT' || row.equipmentAttributeTypeEnum === null
+      } else if (value === 'SPARE') {
+        return row.equipmentAttributeTypeEnum === 'SPARE'
+      } else {
+        return row.equipmentAttributeTypeEnum === 'CUSTOM'
+      }
+    },
+    handlePageChangeNo({ currentPage, pageSize }) {
+      this.currentPage = currentPage
+      this.pageSize = pageSize
+      if (this.equipmentType != '') {
+        this.search()
+      } else {
+        this.get()
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 7 - 3
ui/src/views/largeScreen/index.vue

@@ -209,7 +209,7 @@ export default {
         ]
       }
 
-      this.fmOption.yAxis[0].max=300
+      // this.fmOption.yAxis[0].max=300
       this.chart.setOption(this.fmOption,true)
     },
     push() {
@@ -283,10 +283,12 @@ export default {
       // 存入频率数组
       this.fms.push({name: tempFm.time, value: [tempFm.time, tempFm.f]})
       this.activePower.push({name: tempFm.time, value: [tempFm.time, tempFm.activePower]})
-      if (this.fms.length>600){
+
+      if (this.fms.length>604){
         this.fms.shift()
         this.activePower.shift()
       }
+
       // 对时间轴最大最小时间更新
         this.fmMaxTime=tempFm.time
         let tempTime=new Date(tempFm.time)
@@ -294,11 +296,13 @@ export default {
 
         this.fmOption.xAxis.min=this.fmMinTime
         this.fmOption.xAxis.max=this.fmMaxTime
-
+        this.fmOption.yAxis[0].max=tempFm.capacity
         this.fmOption.series[0].data=this.activePower
         this.fmOption.series[1].data=this.fms
         this.chart.setOption(this.fmOption,true)
 
+
+
         this.rtForm.fm = tempFm.f
         this.rtForm.act = tempFm.activePower
     },

+ 2 - 2
ui/vue.config.js

@@ -13,7 +13,7 @@ const name = defaultSettings.title || 'vue Admin Template' // page title
 // For example, Mac: sudo npm run
 // You can change the port by the following methods:
 // port = 9528 npm run dev OR npm run dev --port = 9528
-const port = process.env.port || process.env.npm_config_port || 9527 // dev port
+const port = process.env.port || process.env.npm_config_port || 9528 // dev port
 
 const Version = new Date().getTime()
 // All configuration item explanations can be find in https://cli.vuejs.org/config/
@@ -39,7 +39,7 @@ module.exports = {
     }
   },
   devServer: {
-    port: port,
+    port: 9528,
     open: false,
     overlay: {
       warnings: false,

+ 6 - 6
ui/yarn.lock

@@ -7505,17 +7505,17 @@
     "postcss" "^7.0.0"
     "uniqs" "^2.0.0"
 
-"postcss-value-parser@^3.0.0":
+"postcss-value-parser@^3.0.0", "postcss-value-parser@^3.2.3":
   "integrity" "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ=="
   "resolved" "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz"
   "version" "3.3.1"
 
-"postcss-value-parser@^3.2.3":
-  "integrity" "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ=="
-  "resolved" "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz"
-  "version" "3.3.1"
+"postcss-value-parser@^4.0.2":
+  "integrity" "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
+  "resolved" "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
+  "version" "4.2.0"
 
-"postcss-value-parser@^4.0.2", "postcss-value-parser@^4.1.0":
+"postcss-value-parser@^4.1.0":
   "integrity" "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
   "resolved" "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
   "version" "4.2.0"