feat: cac后端

iec104
huangfeng 2 years ago
parent 899302566e
commit 8b34dd06fb

23
.gitignore vendored

@ -24,3 +24,26 @@
hs_err_pid*
replay_pid*
/build/
/logs/
target/
.idea/
*.iml
.classpath
.project
.settings/
.DS_Store
*~
packages/
**/dist/
/docker/snapshot/*.gz
.mvn/wrapper/*.jar
.factorypath
.vscode
.checkstyle
.externalToolBuilders
/test/plugin/dist
/test/plugin/workspace
/test/jacoco/classes
/test/jacoco/*.exec

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.17</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xydl</groupId>
<artifactId>cac-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cac-backend</name>
<description>cac-backend project for Spring Boot</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.7.11</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>5.7.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,26 @@
package com.xydl.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableSwagger2
@SpringBootApplication
@EnableCaching
public class CacBackendApplication {
@Bean(name = "passwordEncoder")
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
public static void main(String[] args) {
SpringApplication.run(CacBackendApplication.class, args);
}
}

@ -0,0 +1,62 @@
package com.xydl.demo.controller;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
@Slf4j
public abstract class BasicController {
protected Integer initPageNum(Integer pageNum) {
if (pageNum == null) {
pageNum = 1;
}
if (pageNum < 1) {
pageNum = 1;
}
return pageNum;
}
protected Integer initPageSize(Integer pageSize) {
if (pageSize == null) {
pageSize = 10;
}
if (pageSize < 1) {
pageSize = 1;
}
return pageSize;
}
/**
*
*
* @param request
* @return String
*/
protected String getUserEmail(HttpServletRequest request) {
return request.getHeader("email");
}
/**
*
*
* @param request
* @return String
*/
protected String getLoginMethod(HttpServletRequest request) {
return request.getHeader("login_method");
}
/**
* IP
*
* @param request
* @return String
*/
protected String getClientIp(HttpServletRequest request) {
if (request == null) {
return null;
}
return request.getHeader("client_ip");
}
}

@ -0,0 +1,80 @@
package com.xydl.demo.controller;
import com.xydl.demo.entity.NiecSensor;
import com.xydl.demo.model.ConditionModel;
import com.xydl.demo.model.Response;
import com.xydl.demo.model.SensorDetail;
import com.xydl.demo.service.NiecSensorService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@Api(tags = {"装置表相关接口"})
@RequestMapping("sensor")
public class NiecSensorController extends BasicController {
@Resource
NiecSensorService service;
@GetMapping("list")
@ApiOperation("查询列表")
public Response<Page<NiecSensor>> list(@ApiParam("页码") @RequestParam(value = "pageNum", required = false) Integer pageNum,
@ApiParam("每页数量") @RequestParam(value = "pageSize", required = false) Integer pageSize) {
pageNum = this.initPageNum(pageNum);
pageSize = this.initPageSize(pageSize);
try {
Page<NiecSensor> result = service.list(pageNum, pageSize);
return Response.success(result);
} catch (Exception ex) {
return Response.fail(ex.getMessage());
}
}
@GetMapping("listAll")
@ApiOperation("查询全部列表")
public Response<List<NiecSensor>> listAll() {
try {
List<NiecSensor> result = service.listAll();
return Response.success(result);
} catch (Exception ex) {
return Response.fail(ex.getMessage());
}
}
@GetMapping("getTree")
@ApiOperation("查询树")
public Response<List<NiecSensor>> getTree() {
try {
List<NiecSensor> result = service.getTree();
return Response.success(result);
} catch (Exception ex) {
return Response.fail(ex.getMessage());
}
}
@GetMapping("detail")
@ApiOperation("查询单个装置采集到的数据")
public Response<SensorDetail> getDetail(@Validated ConditionModel model) {
try {
if (model.getPageNum() != null || model.getPageSize() != null) {
model.setPageNum(this.initPageNum(model.getPageNum()));
model.setPageSize(this.initPageSize(model.getPageSize()));
}
SensorDetail result = service.getDetail(model);
return Response.success(result);
} catch (Exception ex) {
return Response.fail(ex.getMessage());
}
}
}

@ -0,0 +1,96 @@
package com.xydl.demo.entity;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
/**
* @author huangfeng
* @date 2023-11-24
**/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "niec_points")
@ApiModel("IEC104-业务点表配置表")
public class NiecPoint {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "sadr")
private Integer sadr;
@Column(name = "site_id")
private Integer siteId;
@Column(name = "sensor_id")
private Integer sensorId;
@Column(name = "stype")
private Integer stype;
@Column(name = "main_equipment_type")
private String mainEquipmentType;
@Column(name = "name")
private String name;
@Column(name = "sub_tree_id")
private String subTreeId;
@Column(name = "sub_equipment_type")
private String subEquipmentType;
@Column(name = "gtype")
private String gtype;
@Column(name = "item_no")
private Integer itemNo;
@Column(name = "yx_bit")
private Integer yxBit;
@Column(name = "field")
private String field;
@Column(name = "filed_desc")
private String filedDesc;
@Column(name = "sno")
private Integer sno;
@Column(name = "isget")
private String isget;
@Column(name = "status")
private Integer status;
@Column(name = "unit")
private String unit;
@Column(name = "warnflag")
private String warnflag;
@Column(name = "thresholdfield")
private String thresholdfield;
@Column(name = "descr")
private String descr;
@Column(name = "d_time")
private Date dTime;
@Transient
private List<Object> data;
}

@ -0,0 +1,90 @@
package com.xydl.demo.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author huangfeng
* @date 2023-11-23
**/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "niec_sensors")
@ApiModel("装置表")
public class NiecSensor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "parent_id")
private Integer parentId;
@Column(name = "site_id")
private Integer siteId;
@Column(name = "sensor_code")
private String sensorCode;
@Column(name = "equipment_id")
private String equipmentId;
@Column(name = "system_code")
private String systemCode;
@Column(name = "name")
private String name;
@Column(name = "dev_id")
private Integer devId;
@Column(name = "grp_no")
private Integer grpNo;
@Column(name = "phase")
private String phase;
@Column(name = "status")
private Integer status;
@Column(name = "equipment_type")
private String equipmentType;
@Column(name = "table_name")
private String tableName;
@Column(name = "devid_field_name")
private String devidFieldName;
@Column(name = "dtime_field_name")
private String dtimeFieldName;
@Column(name = "one_dtime")
private Integer oneDtime;
@Column(name = "create_time")
private Date createTime;
@Transient
private List<NiecSensor> children;
public void addChild(NiecSensor item) {
if (children == null) {
children = new ArrayList<>();
}
children.add(item);
}
}

@ -0,0 +1,31 @@
package com.xydl.demo.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("查询条件")
public class ConditionModel {
@ApiModelProperty("开始时间")
private Date startTime;
@ApiModelProperty("结束时间")
private Date endTime;
@ApiModelProperty("id")
private Integer id;
@ApiModelProperty("页码")
Integer pageNum;
@ApiModelProperty("每页数量")
Integer pageSize;
}

@ -0,0 +1,32 @@
package com.xydl.demo.model;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class Response<T> implements Serializable {
private boolean success;
private String errorMsg;
private T data;
public Response(T data) {
this.success = true;
this.data = data;
}
public Response(boolean success, String message) {
this.success = success;
this.errorMsg = message;
}
public static <T> Response<T> success(T data) {
return new Response<>(data);
}
public static <T> Response<T> fail(String message) {
return new Response<>(false, message);
}
}

@ -0,0 +1,22 @@
package com.xydl.demo.model;
import com.xydl.demo.entity.NiecPoint;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class SensorDetail {
@ApiModelProperty("点表配置")
private List<NiecPoint> points;
@ApiModelProperty("数据")
private List<Map<String, Object>> content;
@ApiModelProperty("总数量")
private Long total;
@ApiModelProperty("页码")
Integer pageNum;
@ApiModelProperty("每页数量")
Integer pageSize;
}

@ -0,0 +1,12 @@
package com.xydl.demo.repository;
import com.xydl.demo.entity.NiecPoint;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface NiecPointRepository extends JpaRepository<NiecPoint, Integer>, JpaSpecificationExecutor<NiecPoint> {
}

@ -0,0 +1,15 @@
package com.xydl.demo.repository;
import com.xydl.demo.entity.NiecSensor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface NiecSensorRepository extends JpaRepository<NiecSensor, Integer>, JpaSpecificationExecutor<NiecSensor> {
Page<NiecSensor> findByPhase(String keyword, Pageable pageable);
}

@ -0,0 +1,9 @@
package com.xydl.demo.service;
import com.xydl.demo.entity.NiecPoint;
import java.util.List;
public interface NiecPointService {
List<NiecPoint> getList(Integer sensorId, Integer stype);
}

@ -0,0 +1,18 @@
package com.xydl.demo.service;
import com.xydl.demo.entity.NiecSensor;
import com.xydl.demo.model.ConditionModel;
import com.xydl.demo.model.SensorDetail;
import org.springframework.data.domain.Page;
import java.util.List;
public interface NiecSensorService {
List<NiecSensor> listAll();
Page<NiecSensor> list(int pageNum, int pageSize);
List<NiecSensor> getTree();
SensorDetail getDetail(ConditionModel model) throws Exception;
}

@ -0,0 +1,38 @@
package com.xydl.demo.service.impl;
import com.xydl.demo.entity.NiecPoint;
import com.xydl.demo.entity.NiecSensor;
import com.xydl.demo.repository.NiecPointRepository;
import com.xydl.demo.repository.NiecSensorRepository;
import com.xydl.demo.service.NiecPointService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import java.util.List;
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class NiecPointServiceImpl implements NiecPointService {
@Resource
NiecPointRepository repository;
@Override
public List<NiecPoint> getList(Integer sensorId, Integer stype) {
Specification<NiecPoint> specification = (root, query, builder) -> {
Predicate predicate = builder.conjunction();
predicate.getExpressions().add(builder.equal(root.get("sensorId"), sensorId));
predicate.getExpressions().add(builder.equal(root.get("stype"), stype));
return predicate;
};
List<NiecPoint> list = repository.findAll(specification, Sort.by("field"));
return list;
}
}

@ -0,0 +1,150 @@
package com.xydl.demo.service.impl;
import com.xydl.demo.entity.NiecPoint;
import com.xydl.demo.entity.NiecSensor;
import com.xydl.demo.model.ConditionModel;
import com.xydl.demo.model.SensorDetail;
import com.xydl.demo.repository.NiecSensorRepository;
import com.xydl.demo.service.NiecPointService;
import com.xydl.demo.service.NiecSensorService;
import com.xydl.demo.service.impl.NiecPointServiceImpl;
import com.xydl.demo.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class NiecSensorServiceImpl implements NiecSensorService {
@Resource
NiecSensorRepository repository;
@Resource
NiecPointService pointService;
@Resource
private JdbcTemplate jdbcTemplate;
@Override
public List<NiecSensor> listAll() {
List<NiecSensor> list = repository.findAll();
return list;
}
@Override
public Page<NiecSensor> list(int pageNum, int pageSize) {
PageRequest request = PageRequest.of(pageNum, pageSize);
Page<NiecSensor> result = repository.findAll(request);
return result;
}
@Override
public List<NiecSensor> getTree() {
List<NiecSensor> list = this.listAll();
List<NiecSensor> result = new ArrayList<>();
for (NiecSensor item : list) {
boolean done = false;
if (item.getParentId() != null) {
for (NiecSensor parent : list) {
if (parent.getId().intValue() == item.getParentId().intValue()) {
if (StringUtils.isNotBlank(item.getTableName())) {
parent.addChild(item);
}
done = true;
break;
}
}
}
if (!done) {
result.add(item);
}
}
return result;
}
@Override
public SensorDetail getDetail(ConditionModel model) throws Exception {
Optional<NiecSensor> optional = repository.findById(model.getId());
if (!optional.isPresent()) {
throw new Exception("未找到该装置");
}
NiecSensor sensor = optional.get();
if (StringUtils.isBlank(sensor.getDtimeFieldName())) {
throw new Exception("该装置缺少采样时间字段名信息");
}
if (StringUtils.isBlank(sensor.getTableName())) {
throw new Exception("该装置缺少table_name信息");
}
if (StringUtils.isBlank(sensor.getDevidFieldName())) {
throw new Exception("该装置缺少sensor_id的字段名信息");
}
if (sensor.getDevId() == null) {
throw new Exception("该装置缺少dev_id信息");
}
List<NiecPoint> points = pointService.getList(sensor.getId(), 2);
if (CollectionUtils.isEmpty(points)) {
throw new Exception("该装置缺少业务点表配置信息");
}
SensorDetail result = this.getData(sensor, points, model);
return result;
}
public SensorDetail getData(NiecSensor sensor, List<NiecPoint> points, ConditionModel model) {
SensorDetail result = new SensorDetail();
List<NiecPoint> pointList = new ArrayList<>();
String sqlFrom = " FROM " + sensor.getTableName();
String sqlWhere = " WHERE " + sensor.getDevidFieldName() + "=" + sensor.getDevId();
if (model.getStartTime() != null) {
sqlWhere = sqlWhere + " AND " + sensor.getDtimeFieldName() + " >= '" + DateUtil.format(model.getStartTime()) + "'";
}
if (model.getEndTime() != null) {
sqlWhere = sqlWhere + " AND " + sensor.getDtimeFieldName() + " < '" + DateUtil.format(model.getEndTime()) + "'";
}
String sqlOrder = " ORDER BY " + sensor.getDtimeFieldName() + " DESC";
String sqlLimit = "";
if (model.getPageNum() != null && model.getPageSize() != null) {
result.setPageNum(model.getPageNum());
result.setPageSize(model.getPageSize());
sqlLimit = String.format(" LIMIT %d,%d", (model.getPageNum() - 1) * model.getPageSize(), model.getPageSize());
}
String sqlSelect = "SELECT DATE_FORMAT(" + sensor.getDtimeFieldName() + ", '%Y-%m-%d %H:%i:%s') as acquisitionTime";
for (NiecPoint point : points) {
if (StringUtils.isNotBlank(point.getField())) {
sqlSelect = sqlSelect + ", " + point.getField();
pointList.add(point);
}
}
String sqlCount = "SELECT count(*)" + sqlFrom + sqlWhere;
String sql = sqlSelect + sqlFrom + sqlWhere + sqlOrder + sqlLimit;
log.info(sql);
Long count = jdbcTemplate.queryForObject(sqlCount, Long.class);
List<Map<String, Object>> content = jdbcTemplate.queryForList(sql);
for (NiecPoint point : pointList) {
List<Object> dataList = new ArrayList<>();
for (Map<String, Object> item : content) {
Object value = item.get(point.getField());
dataList.add(value);
}
point.setData(dataList);
}
result.setTotal(count);
result.setPoints(pointList);
result.setContent(content);
return result;
}
}

@ -0,0 +1,83 @@
package com.xydl.demo.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
public final static String defaultDatePattern = "yyyy-MM-dd HH:mm:ss";
/**
* date pattern
*/
public static String getDatePattern() {
return defaultDatePattern;
}
/**
* 使FormatDate
*/
public static String format(Date date) {
return format(date, getDatePattern());
}
/**
* 使FormatDate
*/
public static String format(Date date, String pattern) {
String returnValue = "";
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
returnValue = df.format(date);
}
return (returnValue);
}
/**
* 使Date
*/
public static Date parse(String strDate) throws ParseException {
return parse(strDate, getDatePattern());
}
/**
* 使FormatDate
*/
public static Date parse(String strDate, String pattern) throws ParseException {
SimpleDateFormat df = new SimpleDateFormat(pattern);
return df.parse(strDate);
}
public static Date getTodayZero() throws ParseException {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String str = df.format(new Date());
return df.parse(str);
}
public static Date getMonthZero() throws ParseException {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
String str = df.format(new Date());
return df.parse(str);
}
/**
* (n)
*/
public static Date addDay(Date date, int n) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, n);
return cal.getTime();
}
public static Date addMonth(Date date, int n) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.MONTH, n);
return cal.getTime();
}
}

@ -0,0 +1,22 @@
server:
port: 8099
servlet:
context-path: /
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://127.0.0.1:3306/iec104?charset=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
url: jdbc:mysql://192.168.50.200:3306/iec104?charset=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
jpa:
show-sql: true
mvc:
format:
date: yyyy-MM-dd HH:mm:ss
pathmatch:
matching-strategy: ant_path_matcher
Loading…
Cancel
Save