北京暂降10月出差开发版本
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package com.njcn.product.event.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.RedisPassword;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.util.StringUtils;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-10-28
|
||||
* @Description:
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class RedisConfig {
|
||||
|
||||
@Value("${spring.redis.host:localhost}")
|
||||
private String host;
|
||||
|
||||
@Value("${spring.redis.port:6379}")
|
||||
private int port;
|
||||
|
||||
@Value("${spring.redis.password:}")
|
||||
private String password;
|
||||
|
||||
@Value("${spring.redis.database:0}")
|
||||
private int database;
|
||||
|
||||
@Value("${spring.redis.timeout:5000}")
|
||||
private int timeout;
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
|
||||
|
||||
// 为了开发方便,一般直接使用<String,object>
|
||||
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
// 用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
|
||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
// 指定要序列化的域(field,get,set),访问修饰符(public,private,protected)
|
||||
//解决Java 8 date/time type java.time.Instant not supported
|
||||
objectMapper.registerModule(new JavaTimeModule());
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
objectMapper.registerModule(new SimpleModule().addDeserializer(Instant.class, new RedisInstantDateDeserializer()));
|
||||
|
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
|
||||
// key采用string的序列化方式
|
||||
redisTemplate.setKeySerializer(stringRedisSerializer);
|
||||
// value序列化方式采用jackson
|
||||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
|
||||
// hash的key采用string的序列化方式
|
||||
redisTemplate.setHashKeySerializer(stringRedisSerializer);
|
||||
// hash的value序列化方式采用jackson
|
||||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JedisConnectionFactory redisConnectionFactory() {
|
||||
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
|
||||
config.setHostName(host);
|
||||
config.setPort(port);
|
||||
config.setDatabase(database);
|
||||
if (StringUtils.hasText(password)) {
|
||||
config.setPassword(RedisPassword.of(password));
|
||||
}
|
||||
|
||||
JedisClientConfiguration.JedisClientConfigurationBuilder builder = JedisClientConfiguration.builder();
|
||||
builder.connectTimeout(Duration.ofMillis(timeout));
|
||||
builder.readTimeout(Duration.ofMillis(timeout));
|
||||
|
||||
// 使用连接池
|
||||
JedisPoolConfig poolConfig = new JedisPoolConfig();
|
||||
poolConfig.setMaxTotal(20);
|
||||
poolConfig.setMaxIdle(8);
|
||||
poolConfig.setMinIdle(2);
|
||||
poolConfig.setMaxWaitMillis(8000);
|
||||
poolConfig.setTestOnBorrow(true);
|
||||
poolConfig.setTestWhileIdle(true);
|
||||
poolConfig.setTimeBetweenEvictionRunsMillis(30000);
|
||||
|
||||
builder.usePooling().poolConfig(poolConfig);
|
||||
|
||||
return new JedisConnectionFactory(config, builder.build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager cacheManager(RedisConnectionFactory factory) {
|
||||
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
|
||||
.entryTtl(Duration.ofHours(1))
|
||||
.disableCachingNullValues();
|
||||
|
||||
return RedisCacheManager.builder(factory)
|
||||
.cacheDefaults(config)
|
||||
.transactionAware()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.njcn.product.event.config;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-07-25
|
||||
* @Description:
|
||||
*/
|
||||
@Component
|
||||
public class RedisInstantDateDeserializer extends StdDeserializer<Instant> {
|
||||
|
||||
public RedisInstantDateDeserializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
|
||||
protected RedisInstantDateDeserializer(Class<?> vc) {
|
||||
super(vc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
String text = p.getValueAsString();
|
||||
return DateUtil.parse(text, DatePattern.NORM_DATETIME_PATTERN).toInstant().plusMillis(TimeUnit.HOURS.toMillis(8));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package com.njcn.product.event.config;
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-10-28
|
||||
* @Description:
|
||||
*/
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Redis 工具类 - 基于 RedisTemplate
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RedisUtil {
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
// ==================== 通用操作 ====================
|
||||
|
||||
/**
|
||||
* 设置缓存
|
||||
*/
|
||||
public void saveByKey(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis set操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存带过期时间
|
||||
*/
|
||||
public void setex(String key, Object value, long time, TimeUnit timeUnit) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, timeUnit);
|
||||
} else {
|
||||
saveByKey(key, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Redis setex操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存
|
||||
*/
|
||||
public Object get(String key) {
|
||||
try {
|
||||
return key != null ? redisTemplate.opsForValue().get(key) : null;
|
||||
} catch (Exception e) {
|
||||
log.error("Redis get操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象 - 你在代码中使用的方法
|
||||
*/
|
||||
public Object getObjectByKey(String key) {
|
||||
return get(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取value为字符串的
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public String getRawValue(String key) {
|
||||
return redisTemplate.execute((RedisCallback<String>) connection -> {
|
||||
byte[] data = connection.get(key.getBytes());
|
||||
return data == null ? null : new String(data, StandardCharsets.UTF_8);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*/
|
||||
public void deleteKeysByString(String... keys) {
|
||||
try {
|
||||
if (keys != null && keys.length > 0) {
|
||||
if (keys.length == 1) {
|
||||
redisTemplate.delete(keys[0]);
|
||||
} else {
|
||||
redisTemplate.delete(CollectionUtils.arrayToList(keys));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Redis del操作失败", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置过期时间
|
||||
*/
|
||||
public boolean expire(String key, long time, TimeUnit timeUnit) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.expire(key, time, timeUnit);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("Redis expire操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取过期时间
|
||||
*/
|
||||
public long getExpire(String key, TimeUnit timeUnit) {
|
||||
try {
|
||||
return redisTemplate.getExpire(key, timeUnit);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis getExpire操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断key是否存在
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hasKey操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Hash 操作 ====================
|
||||
|
||||
public void hset(String key, String item, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hset操作失败 key: {}, item: {}", key, item, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public Object hget(String key, String item) {
|
||||
try {
|
||||
return redisTemplate.opsForHash().get(key, item);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hget操作失败 key: {}, item: {}", key, item, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Object, Object> hgetall(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hgetall操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 其他常用操作 ====================
|
||||
|
||||
/**
|
||||
* 递增
|
||||
*/
|
||||
public long incr(String key, long delta) {
|
||||
try {
|
||||
return redisTemplate.opsForValue().increment(key, delta);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis incr操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递减
|
||||
*/
|
||||
public long decr(String key, long delta) {
|
||||
try {
|
||||
return redisTemplate.opsForValue().increment(key, -delta);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis decr操作失败 key: {}", key, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.njcn.product.event.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-10-23
|
||||
* @Description: 线程池配置
|
||||
*/
|
||||
@Configuration
|
||||
public class ThreadPoolConfig {
|
||||
|
||||
@Bean("smsTaskExecutor")
|
||||
public ThreadPoolTaskExecutor smsTaskExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(3); // 核心线程数
|
||||
executor.setMaxPoolSize(10); // 最大线程数
|
||||
executor.setQueueCapacity(100); // 队列容量
|
||||
executor.setKeepAliveSeconds(30); // 空闲线程存活时间
|
||||
executor.setThreadNamePrefix("sms-sender-"); // 线程名前缀
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
public class AppConfig {
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate(); // 基础配置
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,510 @@
|
||||
package com.njcn.product.event.dataTransmit;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.njcn.product.event.devcie.mapper.PqGdCompanyMapper;
|
||||
import com.njcn.product.event.devcie.mapper.PqLinedetailMapper;
|
||||
import com.njcn.product.event.devcie.pojo.dto.LedgerBaseInfoDTO;
|
||||
import com.njcn.product.event.devcie.pojo.po.PqGdCompany;
|
||||
import com.njcn.product.event.devcie.pojo.po.PqLinedetail;
|
||||
import com.njcn.product.event.transientes.mapper.*;
|
||||
import com.njcn.product.event.transientes.pojo.dto.UpLoadEvent;
|
||||
import com.njcn.product.event.transientes.pojo.dto.UpLoadUserDTO;
|
||||
import com.njcn.product.event.transientes.pojo.dto.UserLegerDTO;
|
||||
import com.njcn.product.event.transientes.pojo.dto.UserLineAssDTO;
|
||||
import com.njcn.product.event.transientes.pojo.po.*;
|
||||
import com.njcn.product.event.transientes.service.PqsEventDetailStatusService;
|
||||
import com.njcn.product.event.transientes.utils.OssFileStorageUtils;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-10-20
|
||||
* @Description: 暂降事件同步
|
||||
*/
|
||||
@Service
|
||||
@EnableScheduling
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class DataSynchronization {
|
||||
|
||||
private final PqsEventdetailMapper pqsEventdetailMapper;
|
||||
|
||||
private final PqsEventDetailStatusService pqsEventDetailStatusService;
|
||||
|
||||
private final OssFileStorageUtils ossFileStorageUtils;
|
||||
private final PqLinedetailMapper pqLinedetailMapper;
|
||||
|
||||
private final PqUserLineAssMapper pqUserLineAssMapper;
|
||||
private final PqUserLedgerMapper pqUserLedgerMapper;
|
||||
private final PqsDicTreeMapper pqsDicTreeMapper;
|
||||
private final PqGdCompanyMapper pqGdCompanyMapper;
|
||||
|
||||
private final RedisUtil redisUtil;
|
||||
// 文件配置
|
||||
@Value("${business.wavePath}")
|
||||
private String sourceWaveDir;
|
||||
|
||||
@Value("${business.targetPath}")
|
||||
private String targetPath;
|
||||
|
||||
@Value("${business.syncinterval}")
|
||||
private Integer syncinterval;
|
||||
|
||||
@Value("${business.failsyncinterval}")
|
||||
private Integer failsyncinterval;
|
||||
|
||||
|
||||
|
||||
private volatile boolean syncEventFlag = false;
|
||||
private volatile boolean syncFailFlag = false;
|
||||
|
||||
|
||||
private final static String NAME_KEY = "LineCache:";
|
||||
|
||||
/**
|
||||
* 定时执行的同步任务
|
||||
*/
|
||||
@Scheduled(cron = "${business.eventCronExpression}")
|
||||
@Transactional
|
||||
public void syncPqsEventdetails() {
|
||||
// 防止任务并发执行
|
||||
if (syncEventFlag) {
|
||||
log.warn("同步任务正在执行中,跳过本次调度");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
syncEventFlag = true;
|
||||
log.info("=== 开始暂降事件波形文件同步任务 ===");
|
||||
|
||||
|
||||
// 同步最近N天的事件,因为存在事件补招,延迟的原因,采用大范围扫描
|
||||
LocalDateTime end = LocalDateTime.now();
|
||||
LocalDateTime start = end.minusMinutes(syncinterval);
|
||||
syncEvents(start, end);
|
||||
|
||||
log.info("=== 同步任务完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("同步任务执行失败", e);
|
||||
} finally {
|
||||
syncEventFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(cron = "${business.failCronExpression}")
|
||||
@Transactional
|
||||
public void syncFail() {
|
||||
// 防止任务并发执行
|
||||
if (syncFailFlag) {
|
||||
log.warn("同步任务正在执行中,跳过本次调度");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
syncFailFlag = true;
|
||||
log.info("=== 开始暂降事件波形文件同步任务 ===");
|
||||
|
||||
|
||||
// 同步最近N天的事件,因为存在事件补招,延迟的原因,采用大范围扫描
|
||||
LocalDateTime end = LocalDateTime.now();
|
||||
LocalDateTime start = end.minusMinutes(failsyncinterval);
|
||||
synFailEvents(start, end);
|
||||
|
||||
log.info("=== 同步任务完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("同步任务执行失败", e);
|
||||
} finally {
|
||||
syncFailFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(cron = "${business.userCronExpression}")
|
||||
@Transactional
|
||||
public void syncUser() throws Exception {
|
||||
|
||||
log.info("=== 开始重要敏感用户同步任务 ===");
|
||||
|
||||
|
||||
|
||||
|
||||
String exportDirName = "/pq_user/pq_user.json";
|
||||
UpLoadUserDTO result = new UpLoadUserDTO();
|
||||
QueryWrapper<PqUserLedgerPO> pqUserLedgerPOQueryWrapper = new QueryWrapper<>();
|
||||
pqUserLedgerPOQueryWrapper.lambda().eq(PqUserLedgerPO::getIsShow,1);
|
||||
List<PqUserLedgerPO> pqUserLedgerPOS = pqUserLedgerMapper.selectList(pqUserLedgerPOQueryWrapper);
|
||||
if(!CollectionUtils.isEmpty(pqUserLedgerPOS)){
|
||||
List<String> showIds =new ArrayList<>();
|
||||
List<UserLegerDTO> userLegerDTOList =new ArrayList<>();
|
||||
List<PqsDicTreePO> pqsDicTreePOS = pqsDicTreeMapper.selectList(new LambdaQueryWrapper<>());
|
||||
Map<String, PqsDicTreePO> pqsDicTreePOMap = pqsDicTreePOS.stream().collect(Collectors.toMap(PqsDicTreePO::getId, Function.identity()));
|
||||
List<PqGdCompany> pqGdCompanyList = pqGdCompanyMapper.selectList(null);
|
||||
Map<Long, PqGdCompany> gdMap = pqGdCompanyList.stream().collect(Collectors.toMap(PqGdCompany::getGdIndex, Function.identity()));
|
||||
pqUserLedgerPOS.forEach(temp->{
|
||||
showIds.add(temp.getId());
|
||||
UserLegerDTO userLegerDTO = new UserLegerDTO();
|
||||
userLegerDTO.setId(temp.getId());
|
||||
userLegerDTO.setPowerSupplyArea(gdMap.get(Long.valueOf(temp.getPowerSupplyArea())).getName());
|
||||
userLegerDTO.setCustomerName(temp.getCustomerName());
|
||||
userLegerDTO.setElectricityAddress(temp.getElectricityAddress());
|
||||
userLegerDTO.setBigObjType(pqsDicTreePOMap.get(temp.getBigObjType()).getName());
|
||||
userLegerDTO.setSmallObjType(pqsDicTreePOMap.get(temp.getSmallObjType()).getName());
|
||||
|
||||
userLegerDTOList.add(userLegerDTO);
|
||||
});
|
||||
|
||||
QueryWrapper<PqUserLineAssPO> userLineAssPOQueryWrapper = new QueryWrapper<>();
|
||||
userLineAssPOQueryWrapper.lambda().in(PqUserLineAssPO::getUserIndex,showIds);
|
||||
List<PqUserLineAssPO> pqUserLineAssPOS = pqUserLineAssMapper.selectList(userLineAssPOQueryWrapper);
|
||||
List<UserLineAssDTO> userLineAssDTOS = pqUserLineAssPOS.stream().map(temp -> {
|
||||
UserLineAssDTO userLineAssDTO = new UserLineAssDTO();
|
||||
BeanUtils.copyProperties(temp, userLineAssDTO);
|
||||
return userLineAssDTO;
|
||||
}).collect(Collectors.toList());
|
||||
result.setUserList(userLegerDTOList);
|
||||
result.setAssList(userLineAssDTOS);
|
||||
|
||||
|
||||
ossFileStorageUtils.uploadObjectAsJsonStream(result,exportDirName);
|
||||
log.info("=== 结束重要敏感用户同步任务 ===");
|
||||
|
||||
}else {
|
||||
log.info("=== 暂无重要敏感用户 ===");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void synFailEvents(LocalDateTime start, LocalDateTime end) throws Exception {
|
||||
log.info("=== 开始同步同步失败事件任务 ===");
|
||||
|
||||
// 创建导出目录
|
||||
String filePath = start.toLocalDate().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
|
||||
String fileName = end.format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN));
|
||||
|
||||
String exportDirName = String.format("%s/%s/%s.json","/event", filePath,"bz_"+fileName);
|
||||
// 查询失败的暂降事件
|
||||
LambdaQueryWrapper<PqsEventDetailStatusPO> statusPOLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
statusPOLambdaQueryWrapper.between(PqsEventDetailStatusPO::getEventTime,start,end);
|
||||
List<PqsEventDetailStatusPO> hasList = pqsEventDetailStatusService.list(statusPOLambdaQueryWrapper);
|
||||
Map<String, PqsEventDetailStatusPO> pqsEventDetailStatusPOMap = hasList.stream().collect(Collectors.toMap(PqsEventDetailStatusPO::getEventDetailId, Function.identity()));
|
||||
// 查询事件
|
||||
LambdaQueryWrapper<PqsEventdetail> pqsEventdetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
pqsEventdetailLambdaQueryWrapper.between(PqsEventdetail::getCreateTime,start,end);
|
||||
List<PqsEventdetail> unsyncedEvents = pqsEventdetailMapper.selectList(pqsEventdetailLambdaQueryWrapper);
|
||||
List<String> tempEvetIds = unsyncedEvents.stream().map(PqsEventdetail::getEventdetailIndex).collect(Collectors.toList());
|
||||
//查询日志
|
||||
List<String> allEventIds = hasList.stream().map(PqsEventDetailStatusPO::getEventDetailId).collect(Collectors.toList());
|
||||
List<String> unSyncIds = tempEvetIds.stream().filter(temp -> !allEventIds.contains(temp)).collect(Collectors.toList());
|
||||
|
||||
List<String> failIds = hasList.stream().filter(temp -> temp.getRetryCount() <= 2 && temp.getSyncStatus() == 0).map(PqsEventDetailStatusPO::getEventDetailId).collect(Collectors.toList());
|
||||
unSyncIds.addAll(failIds);
|
||||
List<UpLoadEvent> result = new ArrayList<>();
|
||||
|
||||
if(!CollectionUtils.isEmpty(unSyncIds)){
|
||||
List<String> eventIds = unSyncIds.stream().distinct().collect(Collectors.toList());
|
||||
|
||||
LambdaQueryWrapper<PqsEventdetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
if (eventIds.size() > 1000) {
|
||||
List<List<String>> splitList = CollUtil.split(eventIds, 1000);
|
||||
lambdaQueryWrapper.and(ew -> {
|
||||
for (int i = 0; i < splitList.size(); i++) {
|
||||
List<String> batch = splitList.get(i);
|
||||
if (i == 0) {
|
||||
ew.in(PqsEventdetail::getEventdetailIndex, batch); // 第一个条件不加 or
|
||||
} else {
|
||||
ew.or().in(PqsEventdetail::getEventdetailIndex, batch); // 后续条件加 or
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
lambdaQueryWrapper.in(PqsEventdetail::getEventdetailIndex, eventIds);
|
||||
}
|
||||
List<PqsEventdetail> pqsEventdetails = pqsEventdetailMapper.selectList(lambdaQueryWrapper);
|
||||
Map<String, PqsEventdetail> pqsEventdetailMap = pqsEventdetails.stream().collect(Collectors.toMap(PqsEventdetail::getEventdetailIndex, Function.identity()));
|
||||
|
||||
List<LedgerBaseInfoDTO> ledgerBaseInfoDTOS = (List<LedgerBaseInfoDTO>)redisUtil.getObjectByKey(NAME_KEY + StrUtil.DASHED+"LedgerBaseInfoDTO");
|
||||
Map<Integer, LedgerBaseInfoDTO> LedgerBaseInfoDTOMap = ledgerBaseInfoDTOS.stream().collect(Collectors.toMap(LedgerBaseInfoDTO::getLineId, Function.identity()));
|
||||
List<PqLinedetail> pqLinedetails = pqLinedetailMapper.selectList(null);
|
||||
Map<Integer, PqLinedetail> lineDetailMap = pqLinedetails.stream().collect(Collectors.toMap(PqLinedetail::getLineIndex, Function.identity()));
|
||||
|
||||
unSyncIds.forEach(temp->{
|
||||
PqsEventdetail pqsEventdetail = pqsEventdetailMap.get(temp);
|
||||
|
||||
if(pqsEventDetailStatusPOMap.containsKey(temp)){
|
||||
PqsEventDetailStatusPO pqsEventDetailStatusPO = pqsEventDetailStatusPOMap.get(temp);
|
||||
pqsEventDetailStatusPO.setRetryCount(pqsEventDetailStatusPO.getRetryCount()+1);
|
||||
if(Objects.nonNull(pqsEventdetail.getWavename())||pqsEventDetailStatusPO.getRetryCount()>2){
|
||||
pqsEventDetailStatusPO.setSyncStatus(1);
|
||||
pqsEventDetailStatusPO.setWaveFlag(0);
|
||||
UpLoadEvent upLoadEvent = new UpLoadEvent();
|
||||
upLoadEvent.setEventdetail_index(pqsEventdetail.getEventdetailIndex());
|
||||
upLoadEvent.setLineid(pqsEventdetail.getLineid());
|
||||
upLoadEvent.setTimeid(LocalDateTimeUtil.format(pqsEventdetail.getTimeid(),DatePattern.NORM_DATETIME_PATTERN));
|
||||
upLoadEvent.setMs(pqsEventdetail.getMs());
|
||||
upLoadEvent.setDescribe(pqsEventdetail.getDescribe());
|
||||
upLoadEvent.setWavetype(pqsEventdetail.getWavetype());
|
||||
upLoadEvent.setPersisttime(pqsEventdetail.getPersisttime());
|
||||
upLoadEvent.setEventvalue(pqsEventdetail.getEventvalue());
|
||||
upLoadEvent.setEventreason(pqsEventdetail.getEventreason());
|
||||
upLoadEvent.setEventtype(pqsEventdetail.getEventtype());
|
||||
LedgerBaseInfoDTO ledgerBaseInfoDTO = LedgerBaseInfoDTOMap.get(pqsEventdetail.getLineid());
|
||||
upLoadEvent.setGdname(ledgerBaseInfoDTO.getGdName());
|
||||
upLoadEvent.setBdname(ledgerBaseInfoDTO.getBusBarName());
|
||||
upLoadEvent.setPointname(ledgerBaseInfoDTO.getLineName());
|
||||
upLoadEvent.setIp(ledgerBaseInfoDTO.getIp());
|
||||
upLoadEvent.setPt(ledgerBaseInfoDTO.getPt());
|
||||
upLoadEvent.setCt(ledgerBaseInfoDTO.getCt());
|
||||
upLoadEvent.setPtType(lineDetailMap.get(pqsEventdetail.getLineid()).getPttype());
|
||||
upLoadEvent.setIp(ledgerBaseInfoDTO.getIp());
|
||||
if(Objects.nonNull(pqsEventdetail.getWavename())){
|
||||
pqsEventDetailStatusPO.setWaveFlag(1);
|
||||
|
||||
upLoadEvent.setWavePath(ledgerBaseInfoDTO.getIp()+"/"+pqsEventdetail.getWavename());
|
||||
}
|
||||
result.add(upLoadEvent);
|
||||
}
|
||||
pqsEventDetailStatusService.saveOrUpdate(pqsEventDetailStatusPO);
|
||||
|
||||
}else{
|
||||
PqsEventDetailStatusPO pqsEventDetailStatusPO = new PqsEventDetailStatusPO();
|
||||
pqsEventDetailStatusPO.setEventDetailId(pqsEventdetail.getEventdetailIndex());
|
||||
pqsEventDetailStatusPO.setEventTime(pqsEventdetail.getTimeid());
|
||||
pqsEventDetailStatusPO.setSyncTime(LocalDateTime.now());
|
||||
pqsEventDetailStatusPO.setRemark("");
|
||||
pqsEventDetailStatusPO.setRetryCount(0);
|
||||
|
||||
if(StringUtils.isEmpty(pqsEventdetail.getWavename())){
|
||||
pqsEventDetailStatusPO.setSyncStatus(0);
|
||||
pqsEventDetailStatusPO.setWaveFlag(0);
|
||||
}else {
|
||||
UpLoadEvent upLoadEvent = new UpLoadEvent();
|
||||
upLoadEvent.setEventdetail_index(pqsEventdetail.getEventdetailIndex());
|
||||
upLoadEvent.setLineid(pqsEventdetail.getLineid());
|
||||
upLoadEvent.setTimeid(LocalDateTimeUtil.format(pqsEventdetail.getTimeid(),DatePattern.NORM_DATETIME_PATTERN));
|
||||
upLoadEvent.setMs(pqsEventdetail.getMs());
|
||||
upLoadEvent.setDescribe(pqsEventdetail.getDescribe());
|
||||
upLoadEvent.setWavetype(pqsEventdetail.getWavetype());
|
||||
upLoadEvent.setPersisttime(pqsEventdetail.getPersisttime());
|
||||
upLoadEvent.setEventvalue(pqsEventdetail.getEventvalue());
|
||||
upLoadEvent.setEventreason(pqsEventdetail.getEventreason());
|
||||
upLoadEvent.setEventtype(pqsEventdetail.getEventtype());
|
||||
LedgerBaseInfoDTO ledgerBaseInfoDTO = LedgerBaseInfoDTOMap.get(pqsEventdetail.getLineid());
|
||||
upLoadEvent.setGdname(ledgerBaseInfoDTO.getGdName());
|
||||
upLoadEvent.setBdname(ledgerBaseInfoDTO.getBusBarName());
|
||||
upLoadEvent.setPointname(ledgerBaseInfoDTO.getLineName());
|
||||
upLoadEvent.setIp(ledgerBaseInfoDTO.getIp());
|
||||
upLoadEvent.setPt(ledgerBaseInfoDTO.getPt());
|
||||
upLoadEvent.setCt(ledgerBaseInfoDTO.getCt());
|
||||
upLoadEvent.setPtType(lineDetailMap.get(pqsEventdetail.getLineid()).getPttype());
|
||||
upLoadEvent.setWavePath(ledgerBaseInfoDTO.getIp()+"/"+pqsEventdetail.getWavename());
|
||||
result.add(upLoadEvent);
|
||||
pqsEventDetailStatusPO.setSyncStatus(1);
|
||||
pqsEventDetailStatusPO.setWaveFlag(1);
|
||||
|
||||
|
||||
}
|
||||
pqsEventDetailStatusService.saveOrUpdate(pqsEventDetailStatusPO);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
if(!CollectionUtils.isEmpty(result)){
|
||||
//上传Json
|
||||
ossFileStorageUtils.uploadObjectAsJsonStream(result,exportDirName);
|
||||
//上传波形文件
|
||||
result.forEach(temp->{
|
||||
if(Objects.nonNull(temp.getWavePath())){
|
||||
// String uploadLocalFile1 =sourceWaveDir+"/"+temp.getWavePath()+".dat";
|
||||
String uploadLocalFile2 =sourceWaveDir+"/"+temp.getWavePath()+".DAT";
|
||||
// String uploadLocalFile3 =sourceWaveDir+"/"+temp.getWavePath()+".cfg";
|
||||
String uploadLocalFile4 =sourceWaveDir+"/"+temp.getWavePath()+".CFG";
|
||||
String uploadLocalFile5 =sourceWaveDir+"/"+temp.getWavePath()+".HDR";
|
||||
// String uploadLocalFile6 =sourceWaveDir+"/"+temp.getWavePath()+".hdr";
|
||||
// ossFileStorageUtils.uploadLocalFile(uploadLocalFile1, targetPath+"/"+temp.getIp());
|
||||
ossFileStorageUtils.uploadLocalFile(uploadLocalFile2, targetPath+"/"+temp.getIp());
|
||||
// ossFileStorageUtils.uploadLocalFile(uploadLocalFile3, targetPath+"/"+temp.getIp());
|
||||
ossFileStorageUtils.uploadLocalFile(uploadLocalFile4, targetPath+"/"+temp.getIp());
|
||||
ossFileStorageUtils.uploadLocalFile(uploadLocalFile5, targetPath+"/"+temp.getIp());
|
||||
// ossFileStorageUtils.uploadLocalFile(uploadLocalFile6, targetPath+"/"+temp.getIp());
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 同步指定时间范围内的事件
|
||||
*/
|
||||
public void syncEvents(LocalDateTime startTime, LocalDateTime endTime) throws Exception {
|
||||
// 创建导出目录
|
||||
String filePath = endTime.toLocalDate().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
|
||||
String fileName = startTime.format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN));
|
||||
|
||||
String exportDirName = String.format("%s/%s/%s.json","/event", filePath,fileName);
|
||||
|
||||
// 查询未同步的事件
|
||||
LambdaQueryWrapper<PqsEventdetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.between(PqsEventdetail::getCreateTime,startTime,endTime);
|
||||
List<PqsEventdetail> unsyncedEvents = pqsEventdetailMapper.selectList(lambdaQueryWrapper);
|
||||
log.info("查询到 " + unsyncedEvents.size() + " 个暂降事件");
|
||||
if(CollUtil.isEmpty(unsyncedEvents)){
|
||||
return ;
|
||||
}
|
||||
|
||||
// // 查询已经存在记录的暂降事件
|
||||
// LambdaQueryWrapper<PqsEventDetailStatusPO> statusPOLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// statusPOLambdaQueryWrapper.between(PqsEventDetailStatusPO::getEventTime,startTime,endTime);
|
||||
// List<PqsEventDetailStatusPO> hasList = pqsEventDetailStatusMapper.selectList(statusPOLambdaQueryWrapper);
|
||||
|
||||
// log.info("查询到 " + hasList.size() + "条已存在记录事件");
|
||||
// //成功或者重试超过2次的时间id
|
||||
// List<String> successEventDetailIds = hasList.stream().filter(it->it.getWaveFlag() == 1||it.getRetryCount()>2).map(PqsEventDetailStatusPO::getEventDetailId).collect(Collectors.toList());
|
||||
//
|
||||
//
|
||||
// //排除已经成功的事件
|
||||
// if(CollUtil.isNotEmpty(successEventDetailIds)){
|
||||
// unsyncedEvents = unsyncedEvents.stream().filter(it->!successEventDetailIds.contains(it.getEventdetailIndex())).collect(Collectors.toList());
|
||||
// }
|
||||
List<LedgerBaseInfoDTO> ledgerBaseInfoDTOS = (List<LedgerBaseInfoDTO>)redisUtil.getObjectByKey(NAME_KEY + StrUtil.DASHED+"LedgerBaseInfoDTO");
|
||||
Map<Integer, LedgerBaseInfoDTO> LedgerBaseInfoDTOMap = ledgerBaseInfoDTOS.stream().collect(Collectors.toMap(LedgerBaseInfoDTO::getLineId, Function.identity()));
|
||||
|
||||
List<PqLinedetail> pqLinedetails = pqLinedetailMapper.selectList(null);
|
||||
Map<Integer, PqLinedetail> lineDetailMap = pqLinedetails.stream().collect(Collectors.toMap(PqLinedetail::getLineIndex, Function.identity()));
|
||||
List<UpLoadEvent> result = new ArrayList<>();
|
||||
List<PqsEventDetailStatusPO> logs = new ArrayList<>();
|
||||
|
||||
for (PqsEventdetail unsyncedEvent : unsyncedEvents) {
|
||||
|
||||
PqsEventDetailStatusPO pqsEventDetailStatusPO = new PqsEventDetailStatusPO();
|
||||
pqsEventDetailStatusPO.setEventDetailId(unsyncedEvent.getEventdetailIndex());
|
||||
pqsEventDetailStatusPO.setEventTime(unsyncedEvent.getTimeid());
|
||||
pqsEventDetailStatusPO.setSyncTime(LocalDateTime.now());
|
||||
pqsEventDetailStatusPO.setRemark("");
|
||||
pqsEventDetailStatusPO.setRetryCount(0);
|
||||
|
||||
if(StringUtils.isEmpty(unsyncedEvent.getWavename())){
|
||||
pqsEventDetailStatusPO.setSyncStatus(0);
|
||||
pqsEventDetailStatusPO.setWaveFlag(0);
|
||||
}else {
|
||||
UpLoadEvent upLoadEvent = new UpLoadEvent();
|
||||
upLoadEvent.setEventdetail_index(unsyncedEvent.getEventdetailIndex());
|
||||
upLoadEvent.setLineid(unsyncedEvent.getLineid());
|
||||
upLoadEvent.setTimeid(LocalDateTimeUtil.format(unsyncedEvent.getTimeid(),DatePattern.NORM_DATETIME_PATTERN));
|
||||
upLoadEvent.setMs(unsyncedEvent.getMs());
|
||||
upLoadEvent.setDescribe(unsyncedEvent.getDescribe());
|
||||
upLoadEvent.setWavetype(unsyncedEvent.getWavetype());
|
||||
upLoadEvent.setPersisttime(unsyncedEvent.getPersisttime());
|
||||
upLoadEvent.setEventvalue(unsyncedEvent.getEventvalue());
|
||||
upLoadEvent.setEventreason(unsyncedEvent.getEventreason());
|
||||
upLoadEvent.setEventtype(unsyncedEvent.getEventtype());
|
||||
LedgerBaseInfoDTO ledgerBaseInfoDTO = LedgerBaseInfoDTOMap.get(unsyncedEvent.getLineid());
|
||||
upLoadEvent.setGdname(ledgerBaseInfoDTO.getGdName());
|
||||
upLoadEvent.setBdname(ledgerBaseInfoDTO.getBusBarName());
|
||||
upLoadEvent.setPointname(ledgerBaseInfoDTO.getLineName());
|
||||
upLoadEvent.setIp(ledgerBaseInfoDTO.getIp());
|
||||
upLoadEvent.setPt(ledgerBaseInfoDTO.getPt());
|
||||
upLoadEvent.setCt(ledgerBaseInfoDTO.getCt());
|
||||
upLoadEvent.setPtType(lineDetailMap.get(unsyncedEvent.getLineid()).getPttype());
|
||||
upLoadEvent.setWavePath(ledgerBaseInfoDTO.getIp()+"/"+unsyncedEvent.getWavename());
|
||||
result.add(upLoadEvent);
|
||||
pqsEventDetailStatusPO.setSyncStatus(1);
|
||||
pqsEventDetailStatusPO.setWaveFlag(1);
|
||||
|
||||
|
||||
}
|
||||
pqsEventDetailStatusService.saveOrUpdate(pqsEventDetailStatusPO);
|
||||
logs.add(pqsEventDetailStatusPO);
|
||||
|
||||
}
|
||||
if(!CollectionUtils.isEmpty(result)){
|
||||
//上传Json
|
||||
ossFileStorageUtils.uploadObjectAsJsonStream(result,exportDirName);
|
||||
//上传波形文件
|
||||
result.forEach(temp->{
|
||||
// String uploadLocalFile1 =sourceWaveDir+"/"+temp.getWavePath()+".dat";
|
||||
String uploadLocalFile2 =sourceWaveDir+"/"+temp.getWavePath()+".DAT";
|
||||
// String uploadLocalFile3 =sourceWaveDir+"/"+temp.getWavePath()+".cfg";
|
||||
String uploadLocalFile4 =sourceWaveDir+"/"+temp.getWavePath()+".CFG";
|
||||
String uploadLocalFile5 =sourceWaveDir+"/"+temp.getWavePath()+".HDR";
|
||||
// String uploadLocalFile6 =sourceWaveDir+"/"+temp.getWavePath()+".hdr";
|
||||
// ossFileStorageUtils.uploadLocalFile(uploadLocalFile1, targetPath+"/"+temp.getIp());
|
||||
ossFileStorageUtils.uploadLocalFile(uploadLocalFile2, targetPath+"/"+temp.getIp());
|
||||
// ossFileStorageUtils.uploadLocalFile(uploadLocalFile3, targetPath+"/"+temp.getIp());
|
||||
ossFileStorageUtils.uploadLocalFile(uploadLocalFile4, targetPath+"/"+temp.getIp());
|
||||
ossFileStorageUtils.uploadLocalFile(uploadLocalFile5, targetPath+"/"+temp.getIp());
|
||||
// ossFileStorageUtils.uploadLocalFile(uploadLocalFile6, targetPath+"/"+temp.getIp());
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取波形类型描述
|
||||
*/
|
||||
private String getWaveTypeDesc(Integer waveType) {
|
||||
if (waveType == null) return "未知";
|
||||
|
||||
switch (waveType) {
|
||||
case 1: return "电压暂降";
|
||||
case 2: return "电压暂升";
|
||||
case 3: return "电压中断";
|
||||
case 4: return "电压波动";
|
||||
default: return "未知类型(" + waveType + ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
package com.njcn.product.event.dataTransmit;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.njcn.product.event.transientes.mapper.PqsEventDetailStatusMapper;
|
||||
import com.njcn.product.event.transientes.mapper.PqsEventdetailMapper;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsEventDetailStatusPO;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsEventdetail;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-10-20
|
||||
* @Description: 暂降事件同步
|
||||
*/
|
||||
@Service
|
||||
@EnableScheduling
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class dataSynchronization {
|
||||
|
||||
private final PqsEventdetailMapper pqsEventdetailMapper;
|
||||
|
||||
private final PqsEventDetailStatusMapper pqsEventDetailStatusMapper;
|
||||
|
||||
// 文件配置
|
||||
@Value("${business.wavePath}")
|
||||
private String sourceWaveDir;
|
||||
|
||||
@Value("${business.exportBaseDir}")
|
||||
private String exportBaseDir;
|
||||
|
||||
// 定时任务配置
|
||||
// 默认每2小时执行一次
|
||||
private String cronExpression = "0 0 */2 * * ?";
|
||||
|
||||
private volatile boolean isRunning = false;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 定时执行的同步任务
|
||||
*/
|
||||
@Scheduled(cron = "${sag.sync.cronExpression}")
|
||||
@Transactional
|
||||
public void syncPqsEventdetails() {
|
||||
// 防止任务并发执行
|
||||
if (isRunning) {
|
||||
log.warn("同步任务正在执行中,跳过本次调度");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
isRunning = true;
|
||||
log.info("=== 开始暂降事件波形文件同步任务 ===");
|
||||
|
||||
// 初始化
|
||||
initialize();
|
||||
|
||||
// 同步最近N天的事件,因为存在事件补招,延迟的原因,采用大范围扫描
|
||||
LocalDateTime end = LocalDateTime.now();
|
||||
LocalDateTime start = end.minusHours(24);
|
||||
syncEvents(start, end);
|
||||
|
||||
log.info("=== 同步任务完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("同步任务执行失败", e);
|
||||
} finally {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化操作
|
||||
*/
|
||||
private void initialize() throws Exception {
|
||||
// 检查目录
|
||||
checkDirectories();
|
||||
|
||||
// 检查同步状态表
|
||||
checkSyncStatusTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步指定时间范围内的事件
|
||||
*/
|
||||
public void syncEvents(LocalDateTime startTime, LocalDateTime endTime) throws Exception {
|
||||
// 创建导出目录
|
||||
String startStr = startTime.format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN));
|
||||
String endStr = startTime.format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN));
|
||||
|
||||
String exportDirName = String.format("%s_%s.json", startStr,endStr);
|
||||
Path exportDir = Paths.get(exportBaseDir, exportDirName);
|
||||
Files.createDirectories(exportDir);
|
||||
log.info("创建导出目录: " + exportDir.toAbsolutePath());
|
||||
|
||||
// 查询未同步的事件
|
||||
LambdaQueryWrapper<PqsEventdetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.between(PqsEventdetail::getTimeid,startTime,endTime);
|
||||
List<PqsEventdetail> unsyncedEvents = pqsEventdetailMapper.selectList(lambdaQueryWrapper);
|
||||
log.info("查询到 " + unsyncedEvents.size() + " 个暂降事件");
|
||||
if(CollUtil.isEmpty(unsyncedEvents)){
|
||||
return ;
|
||||
}
|
||||
|
||||
// 查询已经存在记录的暂降事件
|
||||
LambdaQueryWrapper<PqsEventDetailStatusPO> statusPOLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
statusPOLambdaQueryWrapper.between(PqsEventDetailStatusPO::getEventTime,startTime,endTime);
|
||||
List<PqsEventDetailStatusPO> hasList = pqsEventDetailStatusMapper.selectList(statusPOLambdaQueryWrapper);
|
||||
log.info("查询到 " + hasList.size() + "条已存在记录事件");
|
||||
//波形文件失败的事件id
|
||||
List<String> waveFailEventDetailIds = hasList.stream().filter(it->it.getWaveFlag() == 0).map(PqsEventDetailStatusPO::getEventDetailId).collect(Collectors.toList());
|
||||
|
||||
|
||||
//排除已经成功的事件
|
||||
if(CollUtil.isNotEmpty(hasList)){
|
||||
List<String> hasIds = hasList.stream().map(PqsEventDetailStatusPO::getEventDetailId).collect(Collectors.toList());
|
||||
unsyncedEvents = unsyncedEvents.stream().filter(it->!hasIds.contains(it.getEventdetailIndex())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
//对为上传的事件进行上传操作
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查必要的目录是否存在
|
||||
*/
|
||||
private void checkDirectories() throws IOException {
|
||||
// 检查源目录
|
||||
Path sourceDir = Paths.get(sourceWaveDir);
|
||||
if (!Files.exists(sourceDir)) {
|
||||
throw new IOException("源波形文件目录不存在: " + sourceDir);
|
||||
}
|
||||
|
||||
// 检查导出基础目录
|
||||
Path exportDir = Paths.get(exportBaseDir);
|
||||
if (!Files.exists(exportDir)) {
|
||||
Files.createDirectories(exportDir);
|
||||
log.info("创建导出基础目录: " + exportDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查同步状态表是否存在
|
||||
*/
|
||||
private void checkSyncStatusTable() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出单个事件
|
||||
*/
|
||||
private void exportSingleEvent(Path exportDir, PqsEventdetail event) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成事件信息文件
|
||||
*/
|
||||
private void generateEventInfoFile(Path eventDir, PqsEventdetail event) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成同步报告
|
||||
*/
|
||||
private void generateSyncReport(Path exportDir, int totalEvents, int successCount, int failureCount) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新事件同步状态
|
||||
*/
|
||||
private void updateSyncStatus(PqsEventdetail event, int status, String errorMessage) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取波形类型描述
|
||||
*/
|
||||
private String getWaveTypeDesc(Integer waveType) {
|
||||
if (waveType == null) return "未知";
|
||||
|
||||
switch (waveType) {
|
||||
case 1: return "电压暂降";
|
||||
case 2: return "电压暂升";
|
||||
case 3: return "电压中断";
|
||||
case 4: return "电压波动";
|
||||
default: return "未知类型(" + waveType + ")";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务运行状态
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,12 +3,13 @@ package com.njcn.product.event.devcie.config;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.product.event.devcie.mapper.PqLineMapper;
|
||||
import com.njcn.product.event.devcie.pojo.dto.LedgerBaseInfoDTO;
|
||||
import com.njcn.product.event.devcie.pojo.po.PqLine;
|
||||
import com.njcn.product.event.devcie.pojo.po.PqsDeptsline;
|
||||
import com.njcn.product.event.devcie.service.PqsDeptslineService;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsDepts;
|
||||
import com.njcn.product.event.transientes.service.PqsDeptsService;
|
||||
import com.njcn.redis.utils.RedisUtil;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -70,6 +71,20 @@ public class PqlineCache {
|
||||
|
||||
List<PqsDepts> deptsList = pqsDeptsService.lambdaQuery().eq(PqsDepts::getState,1).list();
|
||||
redisUtil.saveByKey(NAME_KEY + StrUtil.DASHED+"AllDept",deptsList);
|
||||
List<Integer> collect = pqLines.stream().map(PqLine::getLineIndex).collect(Collectors.toList());
|
||||
List<LedgerBaseInfoDTO> ledgerBaseInfoDTOS = new ArrayList<>();
|
||||
|
||||
if(collect.size()>1000){
|
||||
List<List<Integer>> listIds = CollUtil.split(collect,1000);
|
||||
for(List<Integer> itemIds : listIds){
|
||||
List<LedgerBaseInfoDTO> temp =pqLineMapper.getBaseLineInfo(itemIds);
|
||||
ledgerBaseInfoDTOS.addAll(temp);
|
||||
}
|
||||
}else {
|
||||
List<LedgerBaseInfoDTO> temp =pqLineMapper.getBaseLineInfo(collect);
|
||||
ledgerBaseInfoDTOS.addAll(temp);
|
||||
}
|
||||
redisUtil.saveByKey(NAME_KEY + StrUtil.DASHED+"LedgerBaseInfoDTO",ledgerBaseInfoDTOS);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
|
||||
@@ -4,12 +4,13 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.product.event.devcie.mapper.PqDeviceMapper;
|
||||
import com.njcn.product.event.devcie.mapper.PqLineMapper;
|
||||
import com.njcn.product.event.devcie.pojo.dto.LedgerBaseInfoDTO;
|
||||
import com.njcn.product.event.devcie.pojo.po.PqLine;
|
||||
import com.njcn.product.event.devcie.pojo.po.PqsDeptsline;
|
||||
import com.njcn.product.event.devcie.service.PqsDeptslineService;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsDepts;
|
||||
import com.njcn.product.event.transientes.service.PqsDeptsService;
|
||||
import com.njcn.redis.utils.RedisUtil;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
@@ -74,6 +75,20 @@ public class LineCacheJob {
|
||||
|
||||
List<PqsDepts> deptsList = pqsDeptsService.lambdaQuery().eq(PqsDepts::getState,1).list();
|
||||
redisUtil.saveByKey(NAME_KEY + StrUtil.DASHED+"AllDept",deptsList);
|
||||
List<Integer> collect = pqLines.stream().map(PqLine::getLineIndex).collect(Collectors.toList());
|
||||
List<LedgerBaseInfoDTO> ledgerBaseInfoDTOS = new ArrayList<>();
|
||||
|
||||
if(collect.size()>1000){
|
||||
List<List<Integer>> listIds = CollUtil.split(collect,1000);
|
||||
for(List<Integer> itemIds : listIds){
|
||||
List<LedgerBaseInfoDTO> temp =pqLineMapper.getBaseLineInfo(itemIds);
|
||||
ledgerBaseInfoDTOS.addAll(temp);
|
||||
}
|
||||
}else {
|
||||
List<LedgerBaseInfoDTO> temp =pqLineMapper.getBaseLineInfo(collect);
|
||||
ledgerBaseInfoDTOS.addAll(temp);
|
||||
}
|
||||
redisUtil.saveByKey(NAME_KEY + StrUtil.DASHED+"LedgerBaseInfoDTO",ledgerBaseInfoDTOS);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
PQ_SUBVOLTAGE.SCALE,
|
||||
pq_device.dev_index devId,
|
||||
pq_device.name devName,
|
||||
pq_device.ip ip,
|
||||
pq_line.pt1/pq_line.pt2 pt,
|
||||
pq_line.ct1/pq_line.ct2 ct,
|
||||
pq_device.Status runFlag,
|
||||
PQ_SUBSTATION.sub_index stationId,
|
||||
PQ_SUBSTATION.name stationName,
|
||||
@@ -74,6 +77,9 @@ where 1=1
|
||||
PQ_SUBVOLTAGE.SCALE,
|
||||
pq_device.dev_index devId,
|
||||
pq_device.name devName,
|
||||
pq_device.ip ip,
|
||||
pq_line.pt1/pq_line.pt2 pt,
|
||||
pq_line.ct1/pq_line.ct2 ct,
|
||||
pq_device.Status runFlag,
|
||||
PQ_SUBSTATION.sub_index stationId,
|
||||
PQ_SUBSTATION.name stationName
|
||||
|
||||
@@ -35,7 +35,9 @@ public class LedgerBaseInfoDTO {
|
||||
private Integer runFlag=0;
|
||||
|
||||
private Integer eventCount;
|
||||
private String ip;
|
||||
|
||||
|
||||
private int pt;
|
||||
private int ct;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.njcn.product.event.devcie.pojo.dto;
|
||||
|
||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Date: 2025/10/23 上午 10:58【需求编号】
|
||||
*
|
||||
* @author clam
|
||||
* @version V1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class LedgerExcelDTO {
|
||||
@Excel(name = "供电公司", width = 20)
|
||||
private String gdName;
|
||||
|
||||
@Excel(name = "变电站", width = 20)
|
||||
private String stationName;
|
||||
@Excel(name = "装置", width = 20)
|
||||
|
||||
private String devName;
|
||||
@Excel(name = "母线", width = 20)
|
||||
private String busBarName;
|
||||
|
||||
|
||||
@Excel(name = "监测点", width = 20)
|
||||
|
||||
private String lineName;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Excel(name = "用户", width = 50)
|
||||
|
||||
private String objName;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import com.njcn.product.event.report.utils.WordTemplate;
|
||||
import com.njcn.product.event.transientes.pojo.param.LargeScreenCountParam;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsDepts;
|
||||
import com.njcn.product.event.transientes.service.PqsDeptsService;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.njcn.product.event.transientes.pojo.param.LargeScreenCountParam;
|
||||
import com.njcn.product.event.transientes.pojo.po.*;
|
||||
import com.njcn.product.event.transientes.service.CommGeneralService;
|
||||
import com.njcn.product.event.transientes.service.MsgEventConfigService;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
@@ -40,6 +41,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.Stream;
|
||||
@@ -73,6 +75,8 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
|
||||
private final ObjectMapper mapper = new ObjectMapper();
|
||||
// @Value("${business.wordTemplatePath}")
|
||||
// private String wordTemplatePath;
|
||||
private final RedisUtil redisUtil;
|
||||
private final static String NAME_KEY = "LineCache:";
|
||||
|
||||
@Override
|
||||
public void exportWordReport(HttpServletResponse response, ReportExportParam param) {
|
||||
@@ -115,20 +119,23 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
|
||||
|
||||
List<PqsEventdetail> pqsEventdetailList = pqsEventdetailMapper.selectList(lambdaQueryWrapper);
|
||||
if(CollUtil.isNotEmpty(pqsEventdetailList)) {
|
||||
List<LedgerBaseInfoDTO> ledgerBaseInfoDTOS = (List<LedgerBaseInfoDTO>)redisUtil.getObjectByKey(NAME_KEY + StrUtil.DASHED+"LedgerBaseInfoDTO");
|
||||
Map<Integer, LedgerBaseInfoDTO> LedgerBaseInfoDTOMap = ledgerBaseInfoDTOS.stream().collect(Collectors.toMap(LedgerBaseInfoDTO::getLineId, Function.identity()));
|
||||
|
||||
List<Map<String, Object>> eventTemplateList = new ArrayList<>();
|
||||
for (int i = 0; i < pqsEventdetailList.size(); i++) {
|
||||
PqsEventdetail pqsEventdetail = pqsEventdetailList.get(i);
|
||||
EventTemplate eventTemplate = new EventTemplate();
|
||||
eventTemplate.setSno(i + 1);
|
||||
eventTemplate.setTimeId(pqsEventdetail.getTimeid().format(DatePattern.NORM_DATETIME_FORMATTER) + "." + pqsEventdetail.getMs());
|
||||
List<LedgerBaseInfoDTO> baseLineInfo = pqLineMapper.getBaseLineInfo(Stream.of(pqsEventdetailList.get(i).getLineid()).collect(Collectors.toList()));
|
||||
eventTemplate.setOrgName(baseLineInfo.get(0).getGdName());
|
||||
eventTemplate.setSubName(baseLineInfo.get(0).getStationName());
|
||||
eventTemplate.setBusName(baseLineInfo.get(0).getBusBarName());
|
||||
eventTemplate.setScale(pqsDicDataMap.get(baseLineInfo.get(0).getScale()).getDicName());
|
||||
LedgerBaseInfoDTO baseLineInfo = LedgerBaseInfoDTOMap.get(pqsEventdetail.getLineid());
|
||||
eventTemplate.setOrgName(baseLineInfo.getGdName());
|
||||
eventTemplate.setSubName(baseLineInfo.getStationName());
|
||||
eventTemplate.setBusName(baseLineInfo.getBusBarName());
|
||||
eventTemplate.setScale(pqsDicDataMap.get(baseLineInfo.getScale()).getDicName());
|
||||
eventTemplate.setDuration(String.format("%.3f", pqsEventdetail.getPersisttime() / 1000));
|
||||
eventTemplate.setResidualVoltage(String.format("%.2f", pqsEventdetail.getEventvalue() * 100));
|
||||
eventTemplate.setUserName(baseLineInfo.get(0).getObjName());
|
||||
eventTemplate.setUserName(baseLineInfo.getObjName());
|
||||
Map<String, Object> eventMap = mapper.convertValue(eventTemplate, Map.class);
|
||||
|
||||
eventTemplateList.add(eventMap);
|
||||
@@ -177,10 +184,15 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
|
||||
|
||||
bjReportDTO.setObjTypeList(treeStr);
|
||||
bjReportDTO.setAffectedUserCount(pqUserLedgerPOList.size());
|
||||
log.info(LocalDateTime.now()+"组装公共参数结束");
|
||||
|
||||
areaAssemble(bjReportDTO, param, pqsDicDataMap);
|
||||
log.info(LocalDateTime.now()+"组装特别参数结束");
|
||||
|
||||
}
|
||||
|
||||
Map<String,Object> map = mapper.convertValue(bjReportDTO,Map.class);
|
||||
log.info(LocalDateTime.now()+"开始组装word模版");
|
||||
|
||||
WordTemplate.generateWordDownload("template/bj_report.docx", response, bjReportDTO.getDateFormat()+"重要敏感用户电压暂降事件监测情况.docx", map);
|
||||
log.info(LocalDateTime.now()+"结束导出word报告");
|
||||
@@ -200,6 +212,10 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
|
||||
List<String> areaContentList = new ArrayList<>();
|
||||
List<Map<String,Object>> eventTemplateList = new ArrayList<>();
|
||||
|
||||
List<LedgerBaseInfoDTO> ledgerBaseInfoDTOS = (List<LedgerBaseInfoDTO>)redisUtil.getObjectByKey(NAME_KEY + StrUtil.DASHED+"LedgerBaseInfoDTO");
|
||||
Map<Integer, LedgerBaseInfoDTO> LedgerBaseInfoDTOMap = ledgerBaseInfoDTOS.stream().collect(Collectors.toMap(LedgerBaseInfoDTO::getLineId, Function.identity()));
|
||||
|
||||
|
||||
List<Map<String, Object>> finalEventTemplateList = eventTemplateList;
|
||||
param.getDeptList().forEach(deptId->{
|
||||
String deptName = deptMap.get(deptId);
|
||||
@@ -253,6 +269,9 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
|
||||
|
||||
if(!CollectionUtils.isEmpty(lineIds)){
|
||||
List<PqUserLineAssPO> pqUserLineAssPOS = pqUserLineAssMapper.selectList(new LambdaQueryWrapper<PqUserLineAssPO>().in(PqUserLineAssPO::getLineIndex,lineIds));
|
||||
if(CollectionUtils.isEmpty(pqUserLineAssPOS)){
|
||||
userContext ="不涉及半导体及重点关注用户。";
|
||||
}else {
|
||||
List<String> userIds = pqUserLineAssPOS.stream().map(PqUserLineAssPO::getUserIndex).distinct().collect(Collectors.toList());
|
||||
|
||||
LambdaQueryWrapper<PqUserLedgerPO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
@@ -285,19 +304,19 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
|
||||
for (int i = 0; i < pqsEventdetailList.size(); i++) {
|
||||
PqsEventdetail pqsEventdetail = pqsEventdetailList.get(i);
|
||||
|
||||
List<LedgerBaseInfoDTO> baseLineInfo = pqLineMapper.getBaseLineInfo(Stream.of(pqsEventdetailList.get(i).getLineid()).collect(Collectors.toList()));
|
||||
if(Objects.isNull(baseLineInfo.get(0).getObjName())){
|
||||
LedgerBaseInfoDTO baseLineInfo = LedgerBaseInfoDTOMap.get(pqsEventdetail.getLineid());
|
||||
if(Objects.isNull(baseLineInfo.getObjName())){
|
||||
continue;
|
||||
}
|
||||
String[] split = baseLineInfo.get(0).getObjName().split(";");
|
||||
String[] split = baseLineInfo.getObjName().split(";");
|
||||
for (int i1 = 0; i1 < split.length; i1++) {
|
||||
if(companyNameList.contains(split[i1])){
|
||||
EventTemplate eventTemplate = new EventTemplate();
|
||||
eventTemplate.setTimeId(pqsEventdetail.getTimeid().format(DatePattern.NORM_DATETIME_FORMATTER)+"."+pqsEventdetail.getMs());
|
||||
eventTemplate.setOrgName(baseLineInfo.get(0).getGdName());
|
||||
eventTemplate.setSubName(baseLineInfo.get(0).getStationName());
|
||||
eventTemplate.setBusName(baseLineInfo.get(0).getBusBarName());
|
||||
eventTemplate.setScale(pqsDicDataMap.get(baseLineInfo.get(0).getScale()).getDicName());
|
||||
eventTemplate.setOrgName(baseLineInfo.getGdName());
|
||||
eventTemplate.setSubName(baseLineInfo.getStationName());
|
||||
eventTemplate.setBusName(baseLineInfo.getBusBarName());
|
||||
eventTemplate.setScale(pqsDicDataMap.get(baseLineInfo.getScale()).getDicName());
|
||||
eventTemplate.setDuration(String.format("%.3f",pqsEventdetail.getPersisttime()/1000));
|
||||
eventTemplate.setResidualVoltage(String.format("%.2f",pqsEventdetail.getEventvalue()*100));
|
||||
eventTemplate.setUserName(split[i1]);
|
||||
@@ -332,6 +351,8 @@ public class EasyPoiWordExportServiceImpl implements EasyPoiWordExportService {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}else {
|
||||
userContext ="不涉及半导体及重点关注用户。";
|
||||
}
|
||||
|
||||
@@ -3,9 +3,10 @@ package com.njcn.product.event.transientes.controller;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.date.TimeInterval;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.SM3;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
@@ -20,17 +21,16 @@ import com.njcn.product.event.devcie.pojo.po.PqsDeptsline;
|
||||
import com.njcn.product.event.devcie.service.PqsDeptslineService;
|
||||
import com.njcn.product.event.transientes.mapper.PqUserLedgerMapper;
|
||||
import com.njcn.product.event.transientes.mapper.PqUserLineAssMapper;
|
||||
import com.njcn.product.event.transientes.pojo.dto.MsgDTO;
|
||||
import com.njcn.product.event.transientes.mapper.PqsEventdetailMapper;
|
||||
import com.njcn.product.event.transientes.pojo.dto.SmsResponseDTO;
|
||||
import com.njcn.product.event.transientes.pojo.dto.SmsSendDTO;
|
||||
import com.njcn.product.event.transientes.pojo.dto.UpLoadEvent;
|
||||
import com.njcn.product.event.transientes.pojo.param.MonitorTerminalParam;
|
||||
import com.njcn.product.event.transientes.pojo.param.SimulationMsgParam;
|
||||
import com.njcn.product.event.transientes.pojo.po.*;
|
||||
import com.njcn.product.event.transientes.service.*;
|
||||
import com.njcn.product.event.transientes.service.impl.MsgEventInfoServiceImpl;
|
||||
import com.njcn.product.event.transientes.utils.SmsUtils;
|
||||
import com.njcn.product.event.transientes.websocket.WebSocketServer;
|
||||
import com.njcn.redis.utils.RedisUtil;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
@@ -39,15 +39,12 @@ import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -66,9 +63,9 @@ import static com.njcn.product.event.transientes.pojo.constant.RedisConstant.RED
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class EventGateController extends BaseController {
|
||||
private final MsgEventInfoServiceImpl msgEventInfoServiceImpl;
|
||||
private final PqUserLineAssMapper pqUserLineAssMapper;
|
||||
private final PqUserLedgerMapper pqUserLedgerMapper;
|
||||
private final PqsEventdetailMapper pqsEventdetailMapper;
|
||||
@Value("${SYS_TYPE_ZT}")
|
||||
private String sysTypeZt;
|
||||
|
||||
@@ -95,6 +92,8 @@ public class EventGateController extends BaseController {
|
||||
|
||||
private final SmsUtils smsUtils;
|
||||
|
||||
private final ThreadPoolTaskExecutor smsTaskExecutor;
|
||||
|
||||
|
||||
@OperateInfo
|
||||
@GetMapping("/eventMsg")
|
||||
@@ -102,7 +101,7 @@ public class EventGateController extends BaseController {
|
||||
@ApiImplicitParam(name = "eventMsg", value = "暂态事件json字符", required = true)
|
||||
public HttpResult<Object> eventMsg(@RequestParam("msg") String msg) {
|
||||
String methodDescribe = getMethodDescribe("eventMsg");
|
||||
log.info("收到前置推送暂降事件:"+msg);
|
||||
log.info("收到前置推送暂降事件,事件详情:" + msg);
|
||||
|
||||
JSONObject jsonObject;
|
||||
try {
|
||||
@@ -113,28 +112,34 @@ public class EventGateController extends BaseController {
|
||||
|
||||
if (msgEventConfigService.getEventType().contains(jsonObject.get("wavetype").toString())
|
||||
&& Float.parseFloat(jsonObject.get("eventvalue").toString()) <= msgEventConfigService.getEventValue()
|
||||
&& (Float.parseFloat(jsonObject.get("persisttime").toString())*1000) >= msgEventConfigService.getEventDuration()) {
|
||||
&& (Float.parseFloat(jsonObject.get("persisttime").toString()) * 1000) >= msgEventConfigService.getEventDuration()) {
|
||||
//过滤重要暂降事件
|
||||
Integer lineId = Integer.valueOf(jsonObject.get("lineid").toString());
|
||||
List<PqUserLineAssPO> assList = pqUserLineAssMapper.selectList(new LambdaQueryWrapper<PqUserLineAssPO>().eq(PqUserLineAssPO::getLineIndex,lineId));
|
||||
List<PqUserLineAssPO> assList = pqUserLineAssMapper.selectList(new LambdaQueryWrapper<PqUserLineAssPO>().eq(PqUserLineAssPO::getLineIndex, lineId));
|
||||
|
||||
String str ="/";
|
||||
if(CollUtil.isNotEmpty(assList)){
|
||||
String str;
|
||||
if (CollUtil.isNotEmpty(assList)) {
|
||||
List<String> userIds = assList.stream().map(PqUserLineAssPO::getUserIndex).distinct().collect(Collectors.toList());
|
||||
List<PqUserLedgerPO> poList = pqUserLedgerMapper.selectList(new LambdaQueryWrapper<PqUserLedgerPO>().select(PqUserLedgerPO::getId,PqUserLedgerPO::getCustomerName).in(PqUserLedgerPO::getId,userIds));
|
||||
str = poList.stream().map(PqUserLedgerPO::getCustomerName).collect(Collectors.joining(StrUtil.COMMA));
|
||||
List<PqUserLedgerPO> poList = pqUserLedgerMapper.selectList(new LambdaQueryWrapper<PqUserLedgerPO>().select(PqUserLedgerPO::getId, PqUserLedgerPO::getCustomerName).in(PqUserLedgerPO::getId, userIds));
|
||||
str = poList.stream().map(PqUserLedgerPO::getCustomerName).collect(Collectors.joining(";"));
|
||||
} else {
|
||||
str = "/";
|
||||
}
|
||||
|
||||
List<PqsDepts> deptsList = (List<PqsDepts>)redisUtil.getObjectByKey(REDIS_DEPT_INDEX+ StrUtil.DASHED+"AllDept");
|
||||
Map<String,PqsDepts> deptsMap = deptsList.stream().collect(Collectors.toMap(PqsDepts::getDeptsIndex,dept->dept));
|
||||
List<PqsDepts> deptsList = (List<PqsDepts>) redisUtil.getObjectByKey(REDIS_DEPT_INDEX + StrUtil.DASHED + "AllDept");
|
||||
Map<String, PqsDepts> deptsMap = deptsList.stream().collect(Collectors.toMap(PqsDepts::getDeptsIndex, dept -> dept));
|
||||
|
||||
List<PqsDeptsline> deptslineList = pqsDeptslineService.lambdaQuery().eq(PqsDeptsline::getLineIndex,lineId).list();
|
||||
List<PqsDeptsline> deptslineList = pqsDeptslineService.lambdaQuery().eq(PqsDeptsline::getLineIndex, lineId).list();
|
||||
List<String> deptIds = deptslineList.stream().map(PqsDeptsline::getDeptsIndex).collect(Collectors.toList());
|
||||
Set<String> set =getAllParentIdsWithChildrenBatch(deptIds,deptsMap);
|
||||
jsonObject.putOpt("objName",str);
|
||||
Set<String> set = getAllParentIdsWithChildrenBatch(deptIds, deptsMap);
|
||||
jsonObject.putOpt("objName", str);
|
||||
jsonObject.putOpt("dept", String.join(StrUtil.COMMA, set));
|
||||
|
||||
webSocketServer.sendMessageToAll(jsonObject.toString());
|
||||
|
||||
smsTaskExecutor.execute(() -> {
|
||||
sendMessage(jsonObject, str);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -178,15 +183,15 @@ public class EventGateController extends BaseController {
|
||||
//下面一行代码正式环境需要放开
|
||||
jsonObject = test();
|
||||
|
||||
if (msgEventConfigService.getEventType().contains(jsonObject.get("wavetype").toString()) &&Float.parseFloat(jsonObject.get("eventvalue").toString()) <= msgEventConfigService.getEventValue()) {
|
||||
if (msgEventConfigService.getEventType().contains(jsonObject.get("wavetype").toString()) && Float.parseFloat(jsonObject.get("eventvalue").toString()) <= msgEventConfigService.getEventValue()) {
|
||||
webSocketServer.sendMessageToAll(jsonObject.toString());
|
||||
|
||||
//开始发送短信
|
||||
try {
|
||||
sendMessage(jsonObject);
|
||||
}catch (Exception e){
|
||||
sendMessage(jsonObject, "/");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("短信组装发送失败!失败原因{}",e.getMessage());
|
||||
log.error("短信组装发送失败!失败原因{}", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -235,7 +240,7 @@ public class EventGateController extends BaseController {
|
||||
Integer wave = random.nextInt(2);
|
||||
|
||||
|
||||
Double per = (double)random.nextInt(5000);
|
||||
Double per = (double) random.nextInt(5000);
|
||||
|
||||
double minV = 0.1;
|
||||
double maxV = 0.9;
|
||||
@@ -279,15 +284,57 @@ public class EventGateController extends BaseController {
|
||||
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@PostMapping("/simulationSend")
|
||||
@GetMapping("/phoneSend")
|
||||
@ApiOperation("模拟发送短信")
|
||||
public HttpResult<WaveDataDTO> simulationSend(@RequestBody @Validated SimulationMsgParam param) {
|
||||
public HttpResult<String> simulationSend(@RequestParam("id") String id) {
|
||||
|
||||
String methodDescribe = getMethodDescribe("simulationSend");
|
||||
|
||||
PqsEventdetail pqsEventdetail = pqsEventdetailMapper.selectOne(new LambdaQueryWrapper<PqsEventdetail>().eq(PqsEventdetail::getEventdetailIndex, id));
|
||||
UpLoadEvent upLoadEvent = new UpLoadEvent();
|
||||
upLoadEvent.setEventdetail_index(pqsEventdetail.getEventdetailIndex());
|
||||
upLoadEvent.setMs(pqsEventdetail.getMs());
|
||||
upLoadEvent.setBdname("测试电站");
|
||||
upLoadEvent.setLineid(pqsEventdetail.getLineid());
|
||||
upLoadEvent.setTimeid(LocalDateTimeUtil.format(pqsEventdetail.getTimeid(),DatePattern.NORM_DATETIME_PATTERN));
|
||||
upLoadEvent.setWavetype(pqsEventdetail.getWavetype());
|
||||
upLoadEvent.setPersisttime(pqsEventdetail.getPersisttime());
|
||||
upLoadEvent.setEventvalue(pqsEventdetail.getEventvalue());
|
||||
upLoadEvent.setEventreason("");
|
||||
upLoadEvent.setEventtype(pqsEventdetail.getEventtype());
|
||||
upLoadEvent.setPointname("测试监测点");
|
||||
upLoadEvent.setGdname("测试供电公司");
|
||||
JSONObject jsonObject = new JSONObject(upLoadEvent);
|
||||
|
||||
sendMessage(jsonObject, "/");
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
||||
}
|
||||
|
||||
|
||||
private void sendMessage(JSONObject jsonObject){
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@GetMapping("/simpleTest")
|
||||
@ApiOperation("模拟发送简单测试短信")
|
||||
public HttpResult<Object> simpleTest() {
|
||||
String methodDescribe = getMethodDescribe("simulationSend");
|
||||
List<SmsSendDTO.ItemInner> msgDTOList = new ArrayList<>();
|
||||
SmsSendDTO.ItemInner msgDTO = new SmsSendDTO.ItemInner();
|
||||
msgDTO.setCustomMsgID(IdUtil.simpleUUID());
|
||||
msgDTO.setContent("test");
|
||||
msgDTO.setTo("18815508963");
|
||||
msgDTOList.add(msgDTO);
|
||||
List<SmsResponseDTO.SmsItem> result = smsUtils.sendSmSToUser(msgDTOList);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
|
||||
private void sendMessage(JSONObject jsonObject, String objStr) {
|
||||
|
||||
try {
|
||||
|
||||
|
||||
TimeInterval timeInterval = new TimeInterval();
|
||||
log.info("-------------------------开始执行短信发送逻辑{}",System.currentTimeMillis());
|
||||
|
||||
Integer lineId = Integer.valueOf(jsonObject.get("lineid").toString());
|
||||
List<PqsDeptsline> pqLineDept = pqsDeptslineService.lambdaQuery().eq(PqsDeptsline::getLineIndex, lineId).eq(PqsDeptsline::getSystype, sysTypeZt).list();
|
||||
Set<String> deptIds = pqLineDept.stream().map(PqsDeptsline::getDeptsIndex).collect(Collectors.toSet());
|
||||
@@ -298,7 +345,7 @@ public class EventGateController extends BaseController {
|
||||
//当前事件未找到用户信息,判断为不需要发送短信用户
|
||||
return;
|
||||
}
|
||||
List<PqsUser> pqsUserList = pqsUserService.lambdaQuery().select(PqsUser::getUserIndex,PqsUser::getPhone,PqsUser::getName).in(PqsUser::getUserIndex, pqsUserSetList.stream().map(PqsUserSet::getUserIndex).collect(Collectors.toList())).list();
|
||||
List<PqsUser> pqsUserList = pqsUserService.lambdaQuery().select(PqsUser::getUserIndex, PqsUser::getPhone, PqsUser::getName).in(PqsUser::getUserIndex, pqsUserSetList.stream().map(PqsUserSet::getUserIndex).collect(Collectors.toList())).list();
|
||||
List<String> userIds = pqsUserList.stream().map(PqsUser::getUserIndex).collect(Collectors.toList());
|
||||
List<PqsUserSet> poList = pqsUserSetList.stream().filter(it -> userIds.contains(it.getUserIndex())).collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(poList)) {
|
||||
@@ -306,25 +353,37 @@ public class EventGateController extends BaseController {
|
||||
List<LedgerBaseInfoDTO> list = pqLineMapper.getBaseLineInfo(Stream.of(lineId).collect(Collectors.toList()));
|
||||
LedgerBaseInfoDTO ledgerBaseInfoDTO = list.get(0);
|
||||
BigDecimal bigDecimal = new BigDecimal(jsonObject.get("eventvalue").toString()).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
|
||||
stringBuilder.append(".").append(jsonObject.get("ms").toString()).append(", ").append(ledgerBaseInfoDTO.getStationName()).append(ledgerBaseInfoDTO.getLineName())
|
||||
.append("发生暂降事件,事件特征幅值").append(bigDecimal).append("%,持续时间:").append(jsonObject.get("persisttime").toString()).append("S");
|
||||
//TODO 发送短信
|
||||
// System.out.println(stringBuilder);
|
||||
stringBuilder.append(".").append(jsonObject.get("ms").toString()).append(",").append(ledgerBaseInfoDTO.getStationName()).append(ledgerBaseInfoDTO.getLineName())
|
||||
.append("发生暂降事件,事件特征幅值").append(bigDecimal).append("%,持续时间:").append(jsonObject.get("persisttime").toString()).append("S;影响用户:");
|
||||
|
||||
|
||||
if ("/".equals(objStr)) {
|
||||
stringBuilder.append("/");
|
||||
} else {
|
||||
stringBuilder.append(objStr);
|
||||
}
|
||||
|
||||
String message;
|
||||
if (stringBuilder.length() > 500) {
|
||||
message = stringBuilder.substring(0, 490).concat(";详情请登录电压暂降监测平台查看。");
|
||||
} else {
|
||||
message = stringBuilder.toString();
|
||||
}
|
||||
|
||||
List<MsgEventInfo> resultList = new ArrayList<>();
|
||||
List<MsgDTO> msgDTOList = new ArrayList<>();
|
||||
List<SmsSendDTO.ItemInner> msgDTOList = new ArrayList<>();
|
||||
for (PqsUser user : pqsUserList) {
|
||||
String msgId = IdUtil.simpleUUID();
|
||||
|
||||
MsgDTO dto = new MsgDTO();
|
||||
dto.setMessage(stringBuilder.toString());
|
||||
dto.setPhone(user.getPhone());
|
||||
SmsSendDTO.ItemInner dto = new SmsSendDTO.ItemInner();
|
||||
dto.setContent(message);
|
||||
dto.setTo(user.getPhone());
|
||||
dto.setCustomMsgID(msgId);
|
||||
msgDTOList.add(dto);
|
||||
|
||||
MsgEventInfo msgEventInfo = new MsgEventInfo();
|
||||
msgEventInfo.setMsgIndex(msgId);
|
||||
msgEventInfo.setMsgContent(stringBuilder.toString());
|
||||
msgEventInfo.setMsgContent(message);
|
||||
msgEventInfo.setPhone(user.getPhone());
|
||||
msgEventInfo.setUserId(user.getUserIndex());
|
||||
msgEventInfo.setUserName(user.getName());
|
||||
@@ -336,16 +395,22 @@ public class EventGateController extends BaseController {
|
||||
}
|
||||
|
||||
List<SmsResponseDTO.SmsItem> result = smsUtils.sendSmSToUser(msgDTOList);
|
||||
Map<String,SmsResponseDTO.SmsItem> stringSmsItemMap = result.stream().collect(Collectors.toMap(SmsResponseDTO.SmsItem::getCustomMsgID,Function.identity()));
|
||||
Map<String, SmsResponseDTO.SmsItem> stringSmsItemMap = result.stream().collect(Collectors.toMap(SmsResponseDTO.SmsItem::getCustomMsgID, Function.identity()));
|
||||
|
||||
resultList.forEach(item->{
|
||||
if(stringSmsItemMap.containsKey(item.getMsgIndex())){
|
||||
resultList.forEach(item -> {
|
||||
if (stringSmsItemMap.containsKey(item.getMsgIndex())) {
|
||||
SmsResponseDTO.SmsItem smsItem = stringSmsItemMap.get(item.getMsgIndex());
|
||||
item.setSendResult(Objects.equals(smsItem.getCode(),"0")?1:0);
|
||||
item.setSendResult(Objects.equals(smsItem.getCode(), "0") ? 1 : 0);
|
||||
}
|
||||
});
|
||||
msgEventInfoService.saveBatch(resultList);
|
||||
}
|
||||
|
||||
log.info("{}-------------短信发送执行结束,执行时长{}s",System.currentTimeMillis(), timeInterval.intervalSecond());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("---------短信发送异常,异常信息", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,9 +421,7 @@ public class EventGateController extends BaseController {
|
||||
return "token";
|
||||
}
|
||||
|
||||
private boolean apiSend(){
|
||||
|
||||
|
||||
private boolean apiSend() {
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.njcn.product.event.transientes.controller;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.product.event.dataTransmit.DataSynchronization;
|
||||
import com.njcn.product.event.devcie.pojo.dto.DeviceDTO;
|
||||
import com.njcn.product.event.transientes.pojo.param.LargeScreenCountParam;
|
||||
import com.njcn.product.event.transientes.pojo.param.MessageEventFeedbackParam;
|
||||
@@ -18,6 +22,7 @@ import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -274,5 +279,27 @@ public class LargeScreenCountController extends BaseController {
|
||||
Page<EventDetailVO> result = largeScreenCountService.userEventList(largeScreenCountParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@PostMapping("/exportLineData")
|
||||
@ApiOperation("导出台账数据数据")
|
||||
public void exportEventData() {
|
||||
largeScreenCountService.exportLineData();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private DataSynchronization synchronization;
|
||||
|
||||
@GetMapping("sycnEvent")
|
||||
public boolean sycnEvent(@RequestParam("startDateTime") String startDateTime,@RequestParam("endDateTime") String endDateTime) throws Exception {
|
||||
synchronization.syncEvents(LocalDateTimeUtil.parse(startDateTime, DatePattern.NORM_DATETIME_PATTERN),LocalDateTimeUtil.parse(endDateTime, DatePattern.NORM_DATETIME_PATTERN));
|
||||
return true;
|
||||
}
|
||||
|
||||
@GetMapping("sycnUser")
|
||||
public boolean sycnUser() throws Exception {
|
||||
synchronization.syncUser();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.njcn.product.event.transientes.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.product.event.dataTransmit.DataSynchronization;
|
||||
import com.njcn.product.event.transientes.pojo.param.PqUserLedgerParam;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqUserLedgerPO;
|
||||
import com.njcn.product.event.transientes.service.PqUserLedgerService;
|
||||
@@ -22,6 +23,8 @@ public class PqUserLedgerController {
|
||||
@Autowired
|
||||
private PqUserLedgerService pqUserLedgerService;
|
||||
|
||||
|
||||
|
||||
// 添加记录
|
||||
@PostMapping("addLedger")
|
||||
public boolean addLedger(@RequestBody PqUserLedgerParam ledgerParam) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import java.util.zip.ZipOutputStream;
|
||||
@RequiredArgsConstructor
|
||||
public class ScheduledEvent implements SchedulingConfigurer {
|
||||
|
||||
@Value("${}")
|
||||
private final String cronStr = "";
|
||||
// @Value("${}")
|
||||
private final String cronStr = "0 0 */2 * * ?";
|
||||
|
||||
// 源文件夹路径
|
||||
private final String sourceFolderPath = "D:\\";
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.njcn.product.event.transientes.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Date: 2025/10/22 上午 10:37【需求编号】
|
||||
*
|
||||
* @author clam
|
||||
* @version V1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class UpLoadEvent {
|
||||
|
||||
/**
|
||||
* eventdetail_index : d4963f8f-201f-443f-b293-dda8ef870ee6
|
||||
* lineid : 1591
|
||||
* timeid : 2025-10-09 13:25:14
|
||||
* ms : 509
|
||||
* describe :
|
||||
* wavetype : 1
|
||||
* persisttime : 23.000
|
||||
* eventvalue : 0.6
|
||||
* eventreason :
|
||||
* eventtype :
|
||||
* gdname :
|
||||
* bdname : 110kV皇后店变
|
||||
* pointname : 232待用
|
||||
* wavePath : 192.168.1.102/3_20240515_163022_349
|
||||
*/
|
||||
|
||||
private String eventdetail_index;
|
||||
private Integer lineid;
|
||||
private String timeid;
|
||||
private BigDecimal ms;
|
||||
private String describe;
|
||||
private Integer wavetype;
|
||||
private Double persisttime;
|
||||
private Double eventvalue;
|
||||
private String eventreason;
|
||||
private String eventtype;
|
||||
private String gdname;
|
||||
private String bdname;
|
||||
private String pointname;
|
||||
private String wavePath;
|
||||
private String ip;
|
||||
|
||||
private int pt;
|
||||
private int ct;
|
||||
private int ptType;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.njcn.product.event.transientes.pojo.dto;
|
||||
|
||||
import com.njcn.product.event.transientes.pojo.po.PqUserLedgerPO;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqUserLineAssPO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Date: 2025/10/28 下午 2:32【需求编号】
|
||||
*
|
||||
* @author clam
|
||||
* @version V1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class UpLoadUserDTO {
|
||||
private List<UserLegerDTO> userList;
|
||||
private List<UserLineAssDTO> assList;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.njcn.product.event.transientes.pojo.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Date: 2025/10/28 下午 2:47【需求编号】
|
||||
*
|
||||
* @author clam
|
||||
* @version V1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class UserLegerDTO {
|
||||
|
||||
|
||||
private String id;
|
||||
|
||||
private String powerSupplyArea;
|
||||
|
||||
private String customerName;
|
||||
|
||||
private String electricityAddress;
|
||||
|
||||
private String bigObjType;
|
||||
|
||||
private String smallObjType;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.njcn.product.event.transientes.pojo.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Date: 2025/10/28 下午 2:49【需求编号】
|
||||
*
|
||||
* @author clam
|
||||
* @version V1.0.0
|
||||
*/
|
||||
@Data
|
||||
public class UserLineAssDTO {
|
||||
|
||||
private String userIndex;
|
||||
|
||||
private Integer lineIndex;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.njcn.product.event.transientes.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -13,18 +14,19 @@ import java.util.Date;
|
||||
* @Description: 暂降事件同步记录
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "PQS_EVENTDETAIL_STATUS")
|
||||
public class PqsEventDetailStatusPO {
|
||||
|
||||
@TableId(value = "EVENT_DETAIL_ID")
|
||||
private String eventDetailId;
|
||||
|
||||
@TableField(value = "EVENT_TIME")
|
||||
private Date eventTime;
|
||||
private LocalDateTime eventTime;
|
||||
|
||||
@TableField(value = "WAVE_FLAG")
|
||||
private int waveFlag;
|
||||
|
||||
@TableField(value = "SYNC_STATUE")
|
||||
@TableField(value = "SYNC_STATUS")
|
||||
private int syncStatus;
|
||||
|
||||
@TableField(value = "SYNC_TIME")
|
||||
|
||||
@@ -96,6 +96,10 @@ public class PqsEventdetail {
|
||||
@TableField(value = "NOTICE_FLAG")
|
||||
private Integer noticeFlag;
|
||||
|
||||
@TableField(value = "CREATE_TIME")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer eventSeverity;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.njcn.product.event.transientes.security;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.product.event.transientes.utils.JwtUtil;
|
||||
import com.njcn.redis.utils.RedisUtil;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.njcn.product.event.transientes.mapper.PqsUserMapper;
|
||||
import com.njcn.product.event.transientes.mapper.PqsUserSetMapper;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsUser;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsUserSet;
|
||||
import com.njcn.redis.utils.RedisUtil;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
@@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.product.event.devcie.pojo.po.PqsDeptsline;
|
||||
import com.njcn.product.event.devcie.service.PqsDeptslineService;
|
||||
import com.njcn.product.event.transientes.pojo.param.LargeScreenCountParam;
|
||||
import com.njcn.redis.utils.RedisUtil;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -64,4 +64,6 @@ public interface LargeScreenCountService {
|
||||
Page<DeviceDTO> devicePage(LargeScreenCountParam largeScreenCountParam);
|
||||
|
||||
Page<EventDetailVO> userEventList(LargeScreenCountParam largeScreenCountParam);
|
||||
|
||||
void exportLineData();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.njcn.product.event.transientes.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsEventDetailStatusPO;
|
||||
|
||||
/**
|
||||
* CN_Product
|
||||
*
|
||||
* @author cdf
|
||||
* @date 2025/10/24
|
||||
*/
|
||||
public interface PqsEventDetailStatusService extends IService<PqsEventDetailStatusPO> {
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.njcn.product.event.transientes.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.*;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@@ -14,6 +15,7 @@ import com.beust.ah.A;
|
||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.product.event.config.RedisUtil;
|
||||
import com.njcn.product.event.devcie.mapper.*;
|
||||
import com.njcn.product.event.devcie.pojo.dto.*;
|
||||
import com.njcn.product.event.devcie.pojo.po.*;
|
||||
@@ -31,10 +33,11 @@ import com.njcn.product.event.transientes.pojo.vo.*;
|
||||
import com.njcn.product.event.devcie.service.*;
|
||||
import com.njcn.product.event.transientes.service.*;
|
||||
import com.njcn.product.event.devcie.service.PqsDeptslineService;
|
||||
import com.njcn.redis.utils.RedisUtil;
|
||||
import com.njcn.web.factory.PageFactory;
|
||||
import com.njcn.web.utils.ExcelUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -1670,5 +1673,22 @@ public class LargeScreenCountServiceImpl implements LargeScreenCountService {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportLineData() {
|
||||
List<LedgerExcelDTO> ledgerExcelDTOList;
|
||||
List<LedgerBaseInfoDTO> ledgerBaseInfoDTOS = (List<LedgerBaseInfoDTO>)redisUtil.getObjectByKey(NAME_KEY + StrUtil.DASHED+"LedgerBaseInfoDTO");
|
||||
ledgerExcelDTOList = ledgerBaseInfoDTOS.stream().map(temp->{
|
||||
LedgerExcelDTO ledgerExcelDTO = new LedgerExcelDTO();
|
||||
BeanUtils.copyProperties(temp,ledgerExcelDTO);
|
||||
return ledgerExcelDTO;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtil.isEmpty(ledgerExcelDTOList)) {
|
||||
ExcelUtil.exportExcel("台账数据.xls", "台账数据", LedgerExcelDTO.class, new ArrayList<>());
|
||||
} else {
|
||||
ExcelUtil.exportExcel("台账数据.xls", "台账数据", LedgerExcelDTO.class, ledgerExcelDTOList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.njcn.product.event.transientes.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.product.event.transientes.mapper.PqsEventDetailStatusMapper;
|
||||
import com.njcn.product.event.transientes.pojo.po.PqsEventDetailStatusPO;
|
||||
import com.njcn.product.event.transientes.service.PqsEventDetailStatusService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* CN_Product
|
||||
*PqsEventDetailStatusPO
|
||||
* @author cdf
|
||||
* @date 2025/10/24
|
||||
*/
|
||||
@Service
|
||||
public class PqsEventDetailStatusServiceImpl extends ServiceImpl<PqsEventDetailStatusMapper, PqsEventDetailStatusPO> implements PqsEventDetailStatusService {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
package com.njcn.product.event.transientes.utils;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.OSSException;
|
||||
import com.aliyun.oss.model.*;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-10-21
|
||||
* @Description:
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class OssFileStorageUtils {
|
||||
|
||||
|
||||
@Value("${aliyun.oss.endpoint}")
|
||||
private String endpoint="oss-cn-beijing.aliyuncs.com";
|
||||
|
||||
@Value("${aliyun.oss.accessKeyId}")
|
||||
private String accessKeyId="LTAI5tQYuyu1PpiCdeM74PT6";
|
||||
|
||||
@Value("${aliyun.oss.accessKeySecret}")
|
||||
private String accessKeySecret="vTGHcQOCF9u7w9FL3HAHJO1oufVWru";
|
||||
|
||||
@Value("${aliyun.oss.bucketName}")
|
||||
private String bucketName= "cn-comtrade";
|
||||
|
||||
@Value("${aliyun.oss.basePath:pqmm}")
|
||||
private String basePath;
|
||||
|
||||
|
||||
private OSS ossClient;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
// 初始化 OSS 客户端
|
||||
this.ossClient = new OSSClientBuilder().build(
|
||||
endpoint,
|
||||
accessKeyId,
|
||||
accessKeySecret
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象直接以JSON流的形式上传到OSS
|
||||
*
|
||||
* @param object 要上传的Java对象
|
||||
* @param objectName 在OSS上保存的路径和文件名 (例如: "data/user001.json")
|
||||
* @throws IOException
|
||||
*/
|
||||
public void uploadObjectAsJsonStream(Object object, String objectName) throws IOException {
|
||||
// 创建OSSClient实例。
|
||||
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||
// 使用try-with-resources确保ByteArrayInputStream被关闭
|
||||
ByteArrayInputStream inputStream = convertObjectToJsonStream(object);
|
||||
try {
|
||||
// 创建上传请求。
|
||||
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, basePath+objectName, inputStream);
|
||||
// 可选:设置对象元信息,如Content-Type
|
||||
// ObjectMetadata metadata = new ObjectMetadata();
|
||||
// metadata.setContentType("application/json");
|
||||
// putObjectRequest.setMetadata(metadata);
|
||||
|
||||
// 执行上传。
|
||||
ossClient.putObject(putObjectRequest);
|
||||
System.out.println("JSON对象已直接上传至OSS: " + objectName);
|
||||
} finally {
|
||||
inputStream.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传本地文件到阿里云OSS
|
||||
*
|
||||
* @param localFilePath 本地文件的完整路径
|
||||
* @return 文件在OSS上的访问URL
|
||||
*/
|
||||
public String uploadLocalFile(String localFilePath,String targetPath) {
|
||||
File file = new File(localFilePath);
|
||||
if (!file.exists()) {
|
||||
log.info("本地波形文件不存在"+localFilePath );
|
||||
return null;
|
||||
}
|
||||
// 生成唯一的文件名,防止覆盖:cite[5]:cite[8]
|
||||
String originalFileName = file.getName();
|
||||
originalFileName = basePath+targetPath+"/"+originalFileName;
|
||||
|
||||
try {
|
||||
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, originalFileName, file);
|
||||
// 执行上传
|
||||
ossClient.putObject(putObjectRequest);
|
||||
// 生成文件的访问URL:cite[7]:cite[8]
|
||||
String fileUrl = "https://" + bucketName + "." + endpoint + "/" + originalFileName;
|
||||
log.info("文件上传成功,访问地址: {}", fileUrl);
|
||||
return fileUrl;
|
||||
} catch (OSSException oe) {
|
||||
log.error("OSS服务异常: {}", oe.getErrorMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("文件上传失败: ", e);
|
||||
}
|
||||
// 在实际项目中,可以考虑抛出自定义异常
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Java对象序列化为JSON字节流
|
||||
*
|
||||
* @param object Java对象
|
||||
* @return 包含JSON数据的ByteArrayInputStream
|
||||
* @throws IOException
|
||||
*/
|
||||
private ByteArrayInputStream convertObjectToJsonStream(Object object) throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
// 将对象序列化为JSON字节数组
|
||||
byte[] jsonBytes = objectMapper.writeValueAsBytes(object);
|
||||
// 返回字节数组输入流
|
||||
return new ByteArrayInputStream(jsonBytes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件流到OSS
|
||||
*
|
||||
* @param inputStream 文件输入流
|
||||
* @param fileName 文件名
|
||||
* @param contentType 文件类型
|
||||
* @return 文件访问URL
|
||||
*/
|
||||
public String uploadFileStream(InputStream inputStream, String fileName, String contentType) {
|
||||
if (inputStream == null) {
|
||||
throw new IllegalArgumentException("文件输入流不能为空");
|
||||
}
|
||||
|
||||
if (fileName == null || fileName.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("文件名不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 生成唯一文件名
|
||||
String fileExtension = getFileExtension(fileName);
|
||||
String uniqueFileName = UUID.randomUUID().toString() + fileExtension;
|
||||
|
||||
// 构建文件路径
|
||||
String filePath = basePath + "/" + uniqueFileName;
|
||||
|
||||
// 上传文件
|
||||
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filePath, inputStream);
|
||||
|
||||
// 设置文件元数据
|
||||
ObjectMetadata metadata = new ObjectMetadata();
|
||||
metadata.setContentType(contentType);
|
||||
putObjectRequest.setMetadata(metadata);
|
||||
|
||||
// 执行上传
|
||||
PutObjectResult result = ossClient.putObject(putObjectRequest);
|
||||
|
||||
// 关闭输入流
|
||||
inputStream.close();
|
||||
|
||||
// 返回文件访问URL
|
||||
return getFileUrl(filePath);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("文件上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件到OSS
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 文件访问URL
|
||||
*/
|
||||
public String uploadFile(MultipartFile file) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new IllegalArgumentException("上传文件不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 生成唯一文件名
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String fileExtension = getFileExtension(originalFilename);
|
||||
String uniqueFileName = UUID.randomUUID() + fileExtension;
|
||||
|
||||
// 构建文件路径
|
||||
String filePath = basePath + "/" + uniqueFileName;
|
||||
|
||||
// 上传文件
|
||||
InputStream inputStream = file.getInputStream();
|
||||
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filePath, inputStream);
|
||||
|
||||
// 设置文件元数据
|
||||
ObjectMetadata metadata = new ObjectMetadata();
|
||||
metadata.setContentLength(file.getSize());
|
||||
metadata.setContentType(file.getContentType());
|
||||
putObjectRequest.setMetadata(metadata);
|
||||
|
||||
// 执行上传
|
||||
PutObjectResult result = ossClient.putObject(putObjectRequest);
|
||||
|
||||
// 关闭输入流
|
||||
inputStream.close();
|
||||
|
||||
// 返回文件访问URL
|
||||
return getFileUrl(filePath);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("文件上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件到指定目录
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @param directory 目录路径
|
||||
* @return 文件访问URL
|
||||
*/
|
||||
public String uploadFileToDirectory(MultipartFile file, String directory) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new IllegalArgumentException("上传文件不能为空");
|
||||
}
|
||||
|
||||
if (directory == null || directory.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("目录路径不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 生成唯一文件名
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String fileExtension = getFileExtension(originalFilename);
|
||||
String uniqueFileName = UUID.randomUUID().toString() + fileExtension;
|
||||
|
||||
// 构建文件路径
|
||||
String filePath = directory + "/" + uniqueFileName;
|
||||
|
||||
// 上传文件
|
||||
InputStream inputStream = file.getInputStream();
|
||||
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filePath, inputStream);
|
||||
|
||||
// 设置文件元数据
|
||||
ObjectMetadata metadata = new ObjectMetadata();
|
||||
metadata.setContentLength(file.getSize());
|
||||
metadata.setContentType(file.getContentType());
|
||||
putObjectRequest.setMetadata(metadata);
|
||||
|
||||
// 执行上传
|
||||
PutObjectResult result = ossClient.putObject(putObjectRequest);
|
||||
|
||||
// 关闭输入流
|
||||
inputStream.close();
|
||||
|
||||
// 返回文件访问URL
|
||||
return getFileUrl(filePath);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("文件上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除OSS上的文件
|
||||
*
|
||||
* @param fileUrl 文件URL
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
public boolean deleteFile(String fileUrl) {
|
||||
if (fileUrl == null || fileUrl.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("文件URL不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 从URL中提取文件路径
|
||||
String filePath = extractFilePathFromUrl(fileUrl);
|
||||
|
||||
// 检查文件是否存在
|
||||
if (ossClient.doesObjectExist(bucketName, filePath)) {
|
||||
// 删除文件
|
||||
ossClient.deleteObject(bucketName, filePath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("文件删除失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件访问URL
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 文件访问URL
|
||||
*/
|
||||
public String getFileUrl(String filePath) {
|
||||
if (filePath == null || filePath.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("文件路径不能为空");
|
||||
}
|
||||
|
||||
// 构建文件URL
|
||||
return "https://" + bucketName + "." + endpoint + "/" + filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取带签名的临时URL(默认1小时有效期)
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 带签名的临时URL
|
||||
*/
|
||||
public String getSignedUrl(String filePath) {
|
||||
return getSignedUrl(filePath, 3600);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取带签名的临时URL
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param expirationSeconds 过期时间(秒)
|
||||
* @return 带签名的临时URL
|
||||
*/
|
||||
public String getSignedUrl(String filePath, int expirationSeconds) {
|
||||
if (filePath == null || filePath.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("文件路径不能为空");
|
||||
}
|
||||
|
||||
if (expirationSeconds <= 0) {
|
||||
throw new IllegalArgumentException("过期时间必须大于0");
|
||||
}
|
||||
|
||||
try {
|
||||
// 设置URL过期时间
|
||||
Date expiration = new Date(System.currentTimeMillis() + expirationSeconds * 1000L);
|
||||
|
||||
// 生成签名URL
|
||||
URL url = ossClient.generatePresignedUrl(bucketName, filePath, expiration);
|
||||
|
||||
return url.toString();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("生成签名URL失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件信息
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 文件信息
|
||||
*/
|
||||
public ObjectMetadata getFileMetadata(String filePath) {
|
||||
if (filePath == null || filePath.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("文件路径不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
return ossClient.getObjectMetadata(bucketName, filePath);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("获取文件信息失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文件是否存在
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 是否存在
|
||||
*/
|
||||
public boolean doesFileExist(String filePath) {
|
||||
if (filePath == null || filePath.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return ossClient.doesObjectExist(bucketName, filePath);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 文件输入流
|
||||
*/
|
||||
public InputStream downloadFile(String filePath) {
|
||||
if (filePath == null || filePath.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("文件路径不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, filePath);
|
||||
OSSObject ossObject = ossClient.getObject(getObjectRequest);
|
||||
return ossObject.getObjectContent();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("文件下载失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建目录
|
||||
*
|
||||
* @param directoryPath 目录路径
|
||||
*/
|
||||
public void createDirectory(String directoryPath) {
|
||||
if (directoryPath == null || directoryPath.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("目录路径不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 目录必须以"/"结尾
|
||||
String normalizedPath = directoryPath.endsWith("/") ? directoryPath : directoryPath + "/";
|
||||
|
||||
// 创建目录
|
||||
ObjectMetadata metadata = new ObjectMetadata();
|
||||
metadata.setContentLength(0);
|
||||
InputStream emptyContent = new ByteArrayInputStream(new byte[0]);
|
||||
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, normalizedPath, emptyContent, metadata);
|
||||
ossClient.putObject(putObjectRequest);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("创建目录失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取文件扩展名
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 文件扩展名
|
||||
*/
|
||||
private String getFileExtension(String fileName) {
|
||||
if (fileName == null || fileName.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
int lastIndexOfDot = fileName.lastIndexOf(".");
|
||||
if (lastIndexOfDot == -1) {
|
||||
return "";
|
||||
}
|
||||
return fileName.substring(lastIndexOfDot);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从URL中提取文件路径
|
||||
*
|
||||
* @param fileUrl 文件URL
|
||||
* @return 文件路径
|
||||
*/
|
||||
private String extractFilePathFromUrl(String fileUrl) {
|
||||
String prefix = "https://" + bucketName + "." + endpoint + "/";
|
||||
if (fileUrl.startsWith(prefix)) {
|
||||
return fileUrl.substring(prefix.length());
|
||||
}
|
||||
return fileUrl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,12 @@ import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.crypto.digest.SM3;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.product.event.transientes.pojo.dto.MsgDTO;
|
||||
import com.njcn.product.event.transientes.pojo.dto.SmsResponseDTO;
|
||||
import com.njcn.product.event.transientes.pojo.dto.SmsSendDTO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -28,10 +30,11 @@ import java.util.List;
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class SmsUtils {
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
@Value("${smsServer.info}")
|
||||
private String smsServer;
|
||||
@@ -43,25 +46,19 @@ public class SmsUtils {
|
||||
private String password;
|
||||
|
||||
|
||||
public List<SmsResponseDTO.SmsItem> sendSmSToUser(List<MsgDTO> msgDTOList) {
|
||||
public List<SmsResponseDTO.SmsItem> sendSmSToUser(List<SmsSendDTO.ItemInner> temList) {
|
||||
SmsSendDTO smsSendDTO = new SmsSendDTO();
|
||||
smsSendDTO.setServiceCode("101001101");
|
||||
smsSendDTO.setServiceCode("01001101");
|
||||
smsSendDTO.setAccount(account);
|
||||
|
||||
String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN));
|
||||
String sm3Hash = new SM3().digestHex(account + password + nowTime);
|
||||
smsSendDTO.setToken(sm3Hash);
|
||||
smsSendDTO.setTs(nowTime);
|
||||
|
||||
List<SmsSendDTO.ItemInner> temList = new ArrayList<>();
|
||||
for (MsgDTO dto : msgDTOList) {
|
||||
SmsSendDTO.ItemInner inner = new SmsSendDTO.ItemInner();
|
||||
inner.setTo(dto.getPhone());
|
||||
inner.setContent(dto.getMessage());
|
||||
temList.add(inner);
|
||||
}
|
||||
smsSendDTO.setItems(temList);
|
||||
|
||||
log.info("短信请求实体{}", smsSendDTO);
|
||||
|
||||
String url = smsServer + "/sms/msg";
|
||||
try {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
@@ -76,26 +73,25 @@ public class SmsUtils {
|
||||
);
|
||||
// 处理响应
|
||||
return handleSmsResponse(response);
|
||||
} catch (RestClientException e) {
|
||||
} catch (Exception e) {
|
||||
log.error("短信接口调用失败", e);
|
||||
throw new RuntimeException("短信发送异常", e);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<SmsResponseDTO.SmsItem> handleSmsResponse(ResponseEntity<SmsResponseDTO> response) {
|
||||
if (response.getStatusCode() == HttpStatus.OK) {
|
||||
SmsResponseDTO smsResponse = response.getBody();
|
||||
if (smsResponse != null && "0".equals(smsResponse.getCode())) {
|
||||
log.info("短信发送成功,batchId: {}", smsResponse.getBatchId());
|
||||
log.info("短信发送成功,batchId: {},发送条数{}", smsResponse.getBatchId(),smsResponse.getItems().size());
|
||||
return smsResponse.getItems();
|
||||
} else {
|
||||
log.error("短信发送失败: {}", (smsResponse != null ? smsResponse.getMessage() : "API 返回异常"));
|
||||
throw new BusinessException("调用短信服务失败");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
} else {
|
||||
log.error("HTTP 请求失败,状态码: {}", response.getStatusCode());
|
||||
throw new BusinessException("调用短信服务失败");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,16 +43,24 @@ spring:
|
||||
host: localhost
|
||||
port: 6379
|
||||
timeout: 5000
|
||||
lettuce:
|
||||
jedis:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-active: 20
|
||||
max-wait: 8000
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
|
||||
min-idle: 2
|
||||
test-on-borrow: true # 借出连接时验证
|
||||
test-on-return: true # 归还连接时验证
|
||||
test-while-idle: true # 空闲时验证
|
||||
|
||||
smsServer:
|
||||
info: http://22.33.194.50:18096
|
||||
netInfo: http://22.33.191.206:18096
|
||||
account: sms
|
||||
password: aaa
|
||||
account: xbjbpt
|
||||
password: WLv8w071
|
||||
aliyun:
|
||||
oss:
|
||||
endpoint: oss-cn-beijing.aliyuncs.com
|
||||
accessKeyId: LTAI5tQYuyu1PpiCdeM74PT6
|
||||
accessKeySecret: vTGHcQOCF9u7w9FL3HAHJO1oufVWru
|
||||
bucketName: cn-comtrade
|
||||
|
||||
@@ -45,16 +45,26 @@ spring:
|
||||
port: 16379
|
||||
password: "Pqsadmin@#1qaz"
|
||||
timeout: 5000
|
||||
lettuce:
|
||||
jedis:
|
||||
pool:
|
||||
max-active: 20
|
||||
max-wait: 8000
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
min-idle: 2
|
||||
test-on-borrow: true # 借出连接时验证
|
||||
test-on-return: true # 归还连接时验证
|
||||
test-while-idle: true # 空闲时验证
|
||||
|
||||
|
||||
smsServer:
|
||||
info: http://22.33.194.49:18095
|
||||
netInfo: http://20.33.234.143:18095
|
||||
account: sms
|
||||
password: aaa
|
||||
info: http://22.33.194.50:18096
|
||||
netInfo: http://22.33.191.206:18096
|
||||
account: xbjbpt
|
||||
password: WLv8w071
|
||||
|
||||
aliyun:
|
||||
oss:
|
||||
endpoint: http://oss-bj-yz-a.ops.sgmc.sgcc.com.cn/
|
||||
accessKeyId: LKIyxAYe0yI8EqL8
|
||||
accessKeySecret: H2UgWI6RdacGGGJAxLsTNj8Qa4oX2e
|
||||
bucketName: sjzt-fjghsjcc-pro
|
||||
|
||||
@@ -8,7 +8,7 @@ spring:
|
||||
application:
|
||||
name: event_smart
|
||||
profiles:
|
||||
active: dev
|
||||
active: prod
|
||||
|
||||
|
||||
#mybatis配置信息
|
||||
@@ -38,9 +38,13 @@ db:
|
||||
business:
|
||||
#处理波形数据位置
|
||||
wavePath: D://Comtrade
|
||||
|
||||
targetPath: /pqmonitor
|
||||
exportBaseDir: D://exportComtrade
|
||||
cronExpression:
|
||||
eventCronExpression: 0 9 0/1 * * ?
|
||||
failCronExpression: 0 16 0/1 * * ?
|
||||
userCronExpression: 0 5 0/1 * * ?
|
||||
syncinterval: 60
|
||||
failsyncinterval: 1440
|
||||
#wavePath: /usr/local/comtrade
|
||||
#处理临时数据
|
||||
tempPath: D://file
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
|
||||
|
||||
<!--日志输出格式-->
|
||||
<property name="log.pattern"
|
||||
value="|-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%level} ${log.projectName} -- %t %logger{100}.%M ==> %m%n${Log_EXCEPTION_CONVERSION_WORD:-%ec}}}"/>
|
||||
<property name="log.pattern" value="|-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%level} ${log.projectName} -- %t %logger{100}.%M ==> %m%n${Log_EXCEPTION_CONVERSION_WORD:-%ec}}"/>
|
||||
<property name="log.maxHistory" value="30"/>
|
||||
<!-- 控制台输出(可选) -->
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
|
||||
Reference in New Issue
Block a user