平台修改意见20251120-新增设备点位清单上传接口
This commit is contained in:
@ -70,6 +70,10 @@ public class EmsPointMatch extends BaseEntity
|
||||
@Excel(name = "点位是否需要区分多设备:0-不需要 1-需要")
|
||||
private Long needDiffDeviceId;
|
||||
|
||||
/** 设备唯一标识符 */
|
||||
@Excel(name = "设备唯一标识符")
|
||||
private String deviceId;
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
@ -208,6 +212,14 @@ public class EmsPointMatch extends BaseEntity
|
||||
return needDiffDeviceId;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
@ -230,6 +242,7 @@ public class EmsPointMatch extends BaseEntity
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.append("deviceId", getDeviceId())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
package com.xzzn.ems.domain.vo;
|
||||
|
||||
import com.xzzn.common.annotation.Excel;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 点位清单上传参数
|
||||
*/
|
||||
public class DevicePointMatchVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 点位匹配字段 */
|
||||
@Excel(name = "点位匹配字段")
|
||||
private String matchField;
|
||||
|
||||
/** 数据点位 */
|
||||
@Excel(name = "数据点位")
|
||||
private String dataPoint;
|
||||
|
||||
/** 数据点位名称 */
|
||||
@Excel(name = "数据点位名称")
|
||||
private String dataPointName;
|
||||
|
||||
/** 数据单位 */
|
||||
@Excel(name = "数据单位")
|
||||
private String dataUnit;
|
||||
//
|
||||
// /** 数据点位来源设备 */
|
||||
// @Excel(name = "数据点位来源设备")
|
||||
// private String dataDevice;
|
||||
|
||||
/** 寄存器地址 */
|
||||
@Excel(name = "寄存器地址")
|
||||
private String ipAddress;
|
||||
|
||||
/** 错误信息 */
|
||||
@Excel(name = "错误信息")
|
||||
private String errorMsg;
|
||||
|
||||
public String getMatchField() {
|
||||
return matchField;
|
||||
}
|
||||
|
||||
public void setMatchField(String matchField) {
|
||||
this.matchField = matchField;
|
||||
}
|
||||
|
||||
public String getDataPoint() {
|
||||
return dataPoint;
|
||||
}
|
||||
|
||||
public void setDataPoint(String dataPoint) {
|
||||
this.dataPoint = dataPoint;
|
||||
}
|
||||
|
||||
public String getDataPointName() {
|
||||
return dataPointName;
|
||||
}
|
||||
|
||||
public void setDataPointName(String dataPointName) {
|
||||
this.dataPointName = dataPointName;
|
||||
}
|
||||
|
||||
public String getDataUnit() {
|
||||
return dataUnit;
|
||||
}
|
||||
|
||||
public void setDataUnit(String dataUnit) {
|
||||
this.dataUnit = dataUnit;
|
||||
}
|
||||
|
||||
// public String getDataDevice() {
|
||||
// return dataDevice;
|
||||
// }
|
||||
//
|
||||
// public void setDataDevice(String dataDevice) {
|
||||
// this.dataDevice = dataDevice;
|
||||
// }
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
public void setErrorMsg(String errorMsg) {
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.xzzn.ems.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 上传设备点位清单请求参数
|
||||
*/
|
||||
public class ImportPointDataRequest {
|
||||
|
||||
/** 站点id */
|
||||
@NotBlank(message = "站点ID不能为空")
|
||||
private String siteId;
|
||||
/** 设备id */
|
||||
@NotBlank(message = "设备ID不能为空")
|
||||
private String deviceId;
|
||||
/** 设备类型 */
|
||||
@NotBlank(message = "设备类型不能为空")
|
||||
private String deviceCategory;
|
||||
/** 上传点位清单文件 */
|
||||
@NotNull(message = "点位清单文件不能为空")
|
||||
private MultipartFile file;
|
||||
|
||||
public String getSiteId() {
|
||||
return siteId;
|
||||
}
|
||||
|
||||
public void setSiteId(String siteId) {
|
||||
this.siteId = siteId;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public String getDeviceCategory() {
|
||||
return deviceCategory;
|
||||
}
|
||||
|
||||
public void setDeviceCategory(String deviceCategory) {
|
||||
this.deviceCategory = deviceCategory;
|
||||
}
|
||||
|
||||
public MultipartFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(MultipartFile file) {
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.xzzn.ems.enums;
|
||||
|
||||
import com.xzzn.ems.domain.EmsAmmeterData;
|
||||
import com.xzzn.ems.domain.EmsBatteryCluster;
|
||||
import com.xzzn.ems.domain.EmsBatteryData;
|
||||
import com.xzzn.ems.domain.EmsBatteryGroup;
|
||||
import com.xzzn.ems.domain.EmsBatteryStack;
|
||||
import com.xzzn.ems.domain.EmsCoolingData;
|
||||
import com.xzzn.ems.domain.EmsPcsBranchData;
|
||||
import com.xzzn.ems.domain.EmsPcsData;
|
||||
import com.xzzn.ems.domain.EmsXfData;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备匹配表枚举类
|
||||
*/
|
||||
public enum DeviceMatchTable
|
||||
{
|
||||
PCS("PCS", "ems_pcs_data", EmsPcsData.class),
|
||||
BRANCH("BRANCH", "ems_pcs_branch_data", EmsPcsBranchData.class),
|
||||
STACK("STACK", "ems_battery_stack", EmsBatteryStack.class),
|
||||
CLUSTER("CLUSTER", "ems_battery_cluster", EmsBatteryCluster.class),
|
||||
BATTERY("BATTERY", "ems_battery_data", EmsBatteryData.class),
|
||||
AMMETER("AMMETER", "ems_ammeter_data", EmsAmmeterData.class),
|
||||
COOLING("COOLING", "ems_cooling_data", EmsCoolingData.class),
|
||||
DH("DH", "ems_dh_data", EmsBatteryData.class),
|
||||
XF("XF", "ems_xf_data", EmsXfData.class),
|
||||
BATTERY_GROUP("BATTERY_GROUP", "ems_battery_group", EmsBatteryGroup.class);
|
||||
|
||||
private final String code;
|
||||
private final String matchTable;
|
||||
|
||||
private final Class<?> matchTableClass;
|
||||
|
||||
DeviceMatchTable(String code, String matchTable, Class<?> matchTableClass)
|
||||
{
|
||||
this.code = code;
|
||||
this.matchTable = matchTable;
|
||||
this.matchTableClass = matchTableClass;
|
||||
}
|
||||
|
||||
public String getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMatchTable() {
|
||||
return matchTable;
|
||||
}
|
||||
|
||||
public Class<?> getMatchTableClass() {
|
||||
return matchTableClass;
|
||||
}
|
||||
|
||||
// 缓存code与matchTable的映射(优化查询效率)
|
||||
private static final Map<String, String> DEVICE_MATCH_TABLE_MAP = new HashMap<>();
|
||||
|
||||
// 缓存table与实体类的映射(优化查询效率)
|
||||
private static final Map<String, Class<?>> TABLE_TO_CLASS_MAP = new HashMap<>();
|
||||
|
||||
// 静态块初始化缓存
|
||||
static {
|
||||
for (DeviceMatchTable category : DeviceMatchTable.values()) {
|
||||
DEVICE_MATCH_TABLE_MAP.put(category.code, category.matchTable);
|
||||
TABLE_TO_CLASS_MAP.put(category.matchTable, category.matchTableClass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 通过code获取matchTable的方法
|
||||
public static String getMatchTableByCode(String code) {
|
||||
return DEVICE_MATCH_TABLE_MAP.get(code); // 从缓存中直接获取,效率高
|
||||
}
|
||||
|
||||
// 通过table获取实体类的方法
|
||||
public static Class<?> getClassByTable(String matchTable) {
|
||||
return TABLE_TO_CLASS_MAP.get(matchTable); // 从缓存中直接获取,效率高
|
||||
}
|
||||
|
||||
}
|
||||
@ -140,4 +140,8 @@ public interface EmsPointMatchMapper
|
||||
|
||||
// 根据站点,设备类别,点位,获取唯一数据
|
||||
public EmsPointMatch getUniquePoint(@Param("siteId")String siteId, @Param("deviceCategory")String deviceCategory, @Param("dataPoint")String dataPoint);
|
||||
|
||||
EmsPointMatch getOnePointMatch(@Param("siteId") String siteId, @Param("deviceId") String deviceId, @Param("deviceCategory") String deviceCategory, @Param("dataPoint") String dataPoint);
|
||||
|
||||
List<EmsPointMatch> getDevicePointMatchList(@Param("siteId") String siteId, @Param("deviceId") String deviceId, @Param("deviceCategory") String deviceCategory);
|
||||
}
|
||||
|
||||
@ -3,6 +3,8 @@ package com.xzzn.ems.service;
|
||||
import java.util.List;
|
||||
|
||||
import com.xzzn.ems.domain.EmsPointMatch;
|
||||
import com.xzzn.ems.domain.vo.DevicePointMatchVo;
|
||||
import com.xzzn.ems.domain.vo.ImportPointDataRequest;
|
||||
|
||||
/**
|
||||
* 点位匹配Service接口
|
||||
@ -29,4 +31,6 @@ public interface IEmsPointMatchService
|
||||
* @return
|
||||
*/
|
||||
public String importPoint(List<EmsPointMatch> userList, boolean updateSupport, String operName);
|
||||
|
||||
public List<DevicePointMatchVo> importDataByDevice(ImportPointDataRequest request, String operName);
|
||||
}
|
||||
|
||||
@ -1,15 +1,33 @@
|
||||
package com.xzzn.ems.service.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.xzzn.common.constant.RedisKeyConstants;
|
||||
import com.xzzn.common.core.redis.RedisCache;
|
||||
import com.xzzn.common.exception.ServiceException;
|
||||
import com.xzzn.common.utils.StringUtils;
|
||||
import com.xzzn.common.utils.bean.BeanValidators;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.xzzn.common.utils.poi.ExcelUtil;
|
||||
import com.xzzn.ems.domain.vo.DevicePointMatchVo;
|
||||
import com.xzzn.ems.domain.vo.ImportPointDataRequest;
|
||||
import com.xzzn.ems.enums.DeviceMatchTable;
|
||||
import com.xzzn.ems.mapper.EmsPointMatchMapper;
|
||||
import com.xzzn.ems.domain.EmsPointMatch;
|
||||
import com.xzzn.ems.service.IEmsPointMatchService;
|
||||
import com.xzzn.ems.utils.MatchTableUtils;
|
||||
|
||||
import javax.validation.Validator;
|
||||
|
||||
@ -22,10 +40,13 @@ import javax.validation.Validator;
|
||||
@Service
|
||||
public class EmsPointMatchServiceImpl implements IEmsPointMatchService
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(EmsPointMatchServiceImpl.class);
|
||||
@Autowired
|
||||
private EmsPointMatchMapper emsPointMatchMapper;
|
||||
@Autowired
|
||||
protected Validator validator;
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 查询点位匹配列表
|
||||
@ -92,5 +113,89 @@ public class EmsPointMatchServiceImpl implements IEmsPointMatchService
|
||||
return successMsg.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<DevicePointMatchVo> importDataByDevice(ImportPointDataRequest request, String operName) {
|
||||
ExcelUtil<DevicePointMatchVo> util = new ExcelUtil<>(DevicePointMatchVo.class);
|
||||
List<DevicePointMatchVo> pointMatchList = new ArrayList<>();
|
||||
MultipartFile file = request.getFile();
|
||||
if (file.isEmpty()) {
|
||||
throw new ServiceException("点位清单文件不能为空");
|
||||
}
|
||||
try {
|
||||
pointMatchList = util.importExcel(file.getInputStream());
|
||||
} catch (IOException e) {
|
||||
log.info("点位清单导入失败:{}", e.getMessage());
|
||||
throw new ServiceException("点位清单导入失败!");
|
||||
}
|
||||
if (CollectionUtils.isEmpty(pointMatchList)) {
|
||||
throw new ServiceException("导入用户数据不能为空!");
|
||||
}
|
||||
|
||||
String siteId = request.getSiteId();
|
||||
String deviceId = request.getDeviceId();
|
||||
String deviceCategory = request.getDeviceCategory();
|
||||
List<DevicePointMatchVo> errorList = new ArrayList<>();
|
||||
for (DevicePointMatchVo pointMatch : pointMatchList) {
|
||||
try {
|
||||
//校验点位清单文件内容
|
||||
if (validDevicePointMatch(pointMatch, errorList)) {
|
||||
continue;
|
||||
}
|
||||
EmsPointMatch savePoint = new EmsPointMatch();
|
||||
BeanUtils.copyProperties(pointMatch, savePoint);
|
||||
savePoint.setSiteId(siteId);
|
||||
savePoint.setDeviceId(deviceId);
|
||||
savePoint.setDeviceCategory(deviceCategory);
|
||||
savePoint.setMatchTable(DeviceMatchTable.getMatchTableByCode(deviceCategory));
|
||||
savePoint.setPointName(MatchTableUtils.getFieldAnnotation(DeviceMatchTable.getClassByTable(savePoint.getMatchTable()), StringUtils.toCamelCase(savePoint.getMatchField())));
|
||||
savePoint.setCreateBy(operName);
|
||||
savePoint.setUpdateBy(operName);
|
||||
// 验证点位是否存在
|
||||
EmsPointMatch dbPoint = emsPointMatchMapper.getOnePointMatch(siteId, deviceId, deviceCategory, pointMatch.getDataPoint());
|
||||
if (StringUtils.isNull(dbPoint)) {
|
||||
emsPointMatchMapper.insertEmsPointMatch(savePoint);
|
||||
} else {
|
||||
emsPointMatchMapper.updateEmsPointMatch(savePoint);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.info("点位清单导入失败:{}", e.getMessage());
|
||||
throw new ServiceException("点位清单导入失败!");
|
||||
}
|
||||
}
|
||||
// 同步到Redis
|
||||
syncToRedis(siteId, deviceId, deviceCategory);
|
||||
return errorList;
|
||||
}
|
||||
|
||||
private boolean validDevicePointMatch(DevicePointMatchVo pointMatch, List<DevicePointMatchVo> errorList) {
|
||||
StringBuilder errorMsg = new StringBuilder();
|
||||
if (StringUtils.isBlank(pointMatch.getMatchField())) {
|
||||
errorMsg.append("点位匹配字段不能为空;");
|
||||
}
|
||||
if (StringUtils.isBlank(pointMatch.getDataPoint())) {
|
||||
errorMsg.append("数据点位不能为空;");
|
||||
}
|
||||
if (StringUtils.isBlank(pointMatch.getDataPointName())) {
|
||||
errorMsg.append("数据点位名称不能为空;");
|
||||
}
|
||||
// if (StringUtils.isBlank(pointMatch.getDataDevice())) {
|
||||
// errorMsg.append("数据点位来源设备不能为空;");
|
||||
// }
|
||||
if (errorMsg.length() > 0) {
|
||||
pointMatch.setErrorMsg(errorMsg.toString());
|
||||
errorList.add(pointMatch);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void syncToRedis(String siteId, String deviceId, String deviceCategory) {
|
||||
// 同步到Redis
|
||||
String pointMatchKey = RedisKeyConstants.POINT_MATCH + deviceCategory + "_" + siteId + "_" + deviceId;
|
||||
List<EmsPointMatch> pointMatchData = emsPointMatchMapper.getDevicePointMatchList(siteId, deviceId, deviceCategory);
|
||||
// log.info("同步点位匹配数据到Redis key:{} data:{}", pointMatchKey, pointMatchData);
|
||||
redisCache.setCacheObject(pointMatchKey, pointMatchData);
|
||||
log.info("点位匹配数据同步完成 data:{}", JSON.toJSONString(redisCache.getCacheObject(pointMatchKey)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package com.xzzn.ems.utils;
|
||||
|
||||
import com.xzzn.common.annotation.Excel;
|
||||
import com.xzzn.common.utils.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 匹配表工具类
|
||||
*/
|
||||
public class MatchTableUtils {
|
||||
|
||||
/**
|
||||
* 获取字段注解信息
|
||||
*/
|
||||
public static String getFieldAnnotation(Class<?> clazz, String filedName)
|
||||
{
|
||||
List<Field> tempFields = new ArrayList<>();
|
||||
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
|
||||
for (Field field : tempFields) {
|
||||
if (StringUtils.equals(filedName, field.getName()) && field.isAnnotationPresent(Excel.class))
|
||||
{
|
||||
Excel column = field.getAnnotation(Excel.class);
|
||||
return column.name();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user