基础数据上传到省厅汇聚

stwzhj
luyya 2026-03-19 09:22:32 +08:00
parent 8364d79d05
commit 45167e5874
12 changed files with 60 additions and 354 deletions

View File

@ -29,15 +29,20 @@
<version>${dynamic-ds.version}</version>
</dependency>
<!-- RuoYi Common Log -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>stwzhj-common-log</artifactId>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>stwzhj-common-dict</artifactId>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
@ -50,7 +55,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -16,7 +16,7 @@ public class DeviceSyncConfig {
/**
* - info_source
*/
private String infoSource = "3418";
private String infoSource = "3416";
/**
*

View File

@ -26,14 +26,7 @@ public class Device implements AbstractGpsEntity, Serializable {
@Column(name = "device_code")
private String deviceCode;
/**
* <option value="1"></option>
* <option value="2"></option>
* <option value="3">PDT</option>
* <option value="4"></option>
* <option value="5"></option>
* <option value="6"></option>
*/
@Column(name = "device_type")
private String deviceType;
@ -52,19 +45,19 @@ public class Device implements AbstractGpsEntity, Serializable {
/**
*
*/
@Column(name = "policeNo")
@Column(name = "police_no")
private String policeNo;
/**
*
*/
@Column(name = "policeName")
@Column(name = "police_name")
private String policeName;
/**
*
*/
@Column(name = "phoneNum")
@Column(name = "phone_num")
private String phoneNum;
/**

View File

@ -1,129 +0,0 @@
package org.dromara.basetost.handler;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import org.dromara.basetost.entity.AbstractGpsEntity;
import org.dromara.basetost.entity.Device;
import org.dromara.basetost.entity.DictData;
import org.dromara.basetost.repository.DictDataRepository;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.system.api.domain.bo.RemoteDeviceBo;
import org.dromara.system.api.domain.bo.RemoteDeviceToStBo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.*;
/**
* <p>description: </p>
*
* @author chenle
* @date 2022-08-05 16:48
*/
@Component
public abstract class AbstractAsyncHandler {
private Logger logger = LoggerFactory.getLogger(AsyncHandler.class);
@Autowired
AsyncHandler asyncHandler;
@Autowired
DictDataRepository dictDataRepository;
private String lastUpdateTime;
public boolean saveBaseToST(){
try {
// lastUpdateTime = PathUtil.getValueFromProperties("lastUpdateTime");
lastUpdateTime = "2024-11-23 11:20:32";
}catch (Exception e){
logger.info("lastUpdateTime={},lastUpdateTimeError={}",lastUpdateTime,e.getMessage());
return false;
}
List<Device> data = getGpsInfoByTime(lastUpdateTime);
logger.info("dataSize={}",data.size());
if(CollectionUtils.isEmpty(data)){
logger.info("此时无数据={}",lastUpdateTime);
return true;
}
requestToData2es(data);
return true;
}
private void requestToData2es(List<Device> data){
String infoSource = "3418";
// bo.setInfoSource(PathUtil.getValueFromProperties("infoSource"));
boolean b = true;
int size = data.size();
for (AbstractGpsEntity datum : data) {
Device device = (Device) datum;
DictData dictData = dictDataRepository.findDictDataByDictTypeAndDictLabel("device_type_tost", String.valueOf(device.getDeviceType()));
String dictValue = null;
if(!Objects.isNull(dictData)){
dictValue = dictData.getDictValue();
}
if(StringUtils.isEmpty(dictValue)){
dictValue = "99";
}
device.setDeviceType(dictValue);
}
int forCount = size / 50;
for (int i = 0; i <= forCount; i++) {
List<Device> singleList = new ArrayList<>();
int fromIndex = i * 50;
int endIndex = (i == forCount ? size: (i+1)*50);
singleList = data.subList(fromIndex,endIndex);
// BeanUtil.copyToList(singleList, RemoteDeviceBo.class)
List<RemoteDeviceBo> list = new ArrayList<>();
// bo.setDeviceBoList();
boolean singleB = asyncHandler.saveGpsAsync(infoSource,BeanUtil.copyToList(singleList, RemoteDeviceBo.class));
if(!singleB){
b = false;
}
}
if(b){
AbstractGpsEntity abstractGpsEntity = data.get(size - 1);
Device lastDevice = (Device) abstractGpsEntity;
resetUpdateTime(lastDevice.getUpdateTime());
}
}
private void resetUpdateTime(Date gpsTime) {
try {
lastUpdateTime = DateUtil.format(gpsTime,"yyyy-MM-dd HH:mm:ss");
// PathUtil.updateProperties("lastUpdateTime",lastUpdateTime,"ruansi.properties");
}catch (Exception e){
logger.info("lastTime reset error"+e.getMessage());
e.printStackTrace();
}
}
protected Device produceGpsInfo(AbstractGpsEntity gpsInfo){
return null;
};
protected boolean checkNullOrEmpty(AbstractGpsEntity gpsInfo) {
return false;
};
protected abstract List<Device> getGpsInfoByTime(String lastUpdateTime);
}

View File

@ -1,44 +0,0 @@
package org.dromara.basetost.handler;
import org.dromara.common.core.domain.R;
import org.dromara.system.api.RemoteDeviceService;
import org.dromara.system.api.domain.bo.RemoteDeviceBo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* <p>description: </p>
*
* @author chenle
* @date 2021-09-29 9:34
*/
@Component
public class AsyncHandler {
private Logger logger = LoggerFactory.getLogger(AsyncHandler.class);
private RemoteDeviceService deviceService;
// @Async(value = "myCacheExecutor")
boolean saveGpsAsync(String infoSource, List<RemoteDeviceBo> list) {
R response = deviceService.saveDeviceToSt(infoSource,list);
if(Objects.isNull(response) || Objects.isNull(response.getCode())){
assert response != null;
logger.info("返回null,message={}",response.getMsg());
return false;
}
if(200 == response.getCode()){
logger.info("success");
}else{
logger.info("fail,message={},data={}",response.getMsg(),response.getData());
return false;
}
return true;
}
}

View File

@ -1,42 +0,0 @@
package org.dromara.basetost.handler;
import cn.hutool.core.date.DateUtil;
import org.dromara.basetost.entity.AbstractGpsEntity;
import org.dromara.basetost.entity.Device;
import org.dromara.basetost.repository.DeviceRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* <p>description: </p>
*
* @author chenle
* @date 2022-08-05 17:32
*/
@Component("pdthandler")
public class PDTHandler extends AbstractAsyncHandler {
private Logger logger = LoggerFactory.getLogger(AbstractAsyncHandler.class);
@Autowired
DeviceRepository deviceRepository;
public PDTHandler() {
super();
}
@Override
protected List<Device> getGpsInfoByTime(String lastUpdateTime) {
return deviceRepository.findDeviceByUpdateTimeAfterOrderByUpdateTimeAsc(DateUtil.parse(lastUpdateTime));
// return deviceRepository.findDeviceByUpdateTimeAfterOrderByUpdateTimeAsc(lastUpdateTime);
}
}

View File

@ -1,90 +0,0 @@
package org.dromara.basetost.handler;
/**
* <p>description: </p>
*
* @author chenle
* @date 2022-08-05 12:00
*/
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import org.dromara.basetost.response.MyBusinessException;
import org.dromara.common.core.utils.StringUtils;
import java.io.*;
import java.util.Objects;
import java.util.Properties;
public class PathUtil {
static String outpath = System.getProperty("user.dir")+File.separator+"conf"+File.separator;//先读取config目录的没有再加载classpath的
private static Properties getProperties(String fileName) {
try {
Properties properties = new Properties();
InputStream in = new FileInputStream(new File(outpath + fileName));
properties.load(in);
return properties;
} catch (IOException e) {
try {
Properties properties = new Properties();
InputStream in = PathUtil.class.getClassLoader().getResourceAsStream(fileName);//默认加载classpath的
if(Objects.isNull(in)){
return null;
}
properties.load(in);
return properties;
} catch (IOException es) {
return null;
}
}
}
/**
* properties
*
*
* @param keyname
* @param keyvalue
*/
public static void updateProperties( String keyname, String keyvalue, String fileName) throws IOException {
// 调用 Hashtable 的方法 put使用 getProperty 方法提供并行性。
// 强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
Properties props = PathUtil.getProperties(fileName);
OutputStream fos = new FileOutputStream(outpath + fileName);
props.setProperty(keyname, keyvalue);
// 以适合使用 load 方法加载到 Properties 表中的格式,
// 将此 Properties 表中的属性列表(键和元素对)写入输出流
props.store(fos, "Update '" + keyname + "' value");
}
public static String getValueFromProperties(String propertiesName) {
Properties properties = PathUtil.getProperties("ruansi.properties");
if(Objects.isNull(properties)){
throw new MyBusinessException("jar包所在文件夹下conf子目录下缺少[ruansi.properties] 文件,请新建");
}
String lastUpdateTime = properties.getProperty(propertiesName);
if(StringUtils.isEmpty(lastUpdateTime)){
throw new MyBusinessException("[ruansi.properties]文件内缺少["+propertiesName+"]属性");
}
//checkTimeFormatter(lastUpdateTime);
return lastUpdateTime;
}
private static void checkTimeFormatter(String lastUpdateTime) {
try {
DateTime parse = DateUtil.parse(lastUpdateTime, "yyyy-MM-dd HH:mm:ss");
}catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
}

View File

@ -20,6 +20,8 @@ public interface DeviceRepository extends JpaRepository<Device, Integer>, JpaSpe
*/
Device findByDeviceCodeAndInfoSource(String deviceCode, String infoSource);
/**
*
* @param infoSource

View File

@ -3,10 +3,16 @@ package org.dromara.basetost.repository;
import org.dromara.basetost.entity.DictData;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface DictDataRepository extends JpaRepository<DictData, Long>, JpaSpecificationExecutor<DictData> {
DictData findDictDataByDictTypeAndDictLabel(String dictType, String dictLabel);
@Query(value = "SELECT * FROM sys_dict_data WHERE dict_type = :dictType AND dict_label = :dictLabel",
nativeQuery = true)
DictData findByNativeSQL(@Param("dictType") String dictType, @Param("dictLabel") String dictLabel);
/**
*
* @param dictType

View File

@ -1,9 +1,7 @@
package org.dromara.basetost.schedule;
import org.dromara.basetost.handler.AbstractAsyncHandler;
import org.dromara.basetost.service.DeviceSyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -16,20 +14,10 @@ import org.springframework.stereotype.Component;
@Component
public class BaseToSTSchedule {
@Autowired
@Qualifier(value = "pdthandler")
private AbstractAsyncHandler abstractAsyncHandler;
@Autowired
private DeviceSyncService deviceSyncService;
/**
*
*/
@Scheduled(cron = "${devicecorn:0/30 * * * * ?}")
public void sendToSt() {
abstractAsyncHandler.saveBaseToST();
}
/**
*

View File

@ -54,7 +54,6 @@ public class DeviceSyncService {
*
*/
@DS("target")
@Transactional(rollbackFor = Exception.class)
public void syncDevices() {
logger.info("开始同步设备数据infoSource: {}", deviceSyncConfig.getInfoSource());
@ -140,25 +139,32 @@ public class DeviceSyncService {
*
* @param sourceDevices
*/
@DS("source")
private void mapDeviceTypes(List<SourceDevice> sourceDevices) {
for (SourceDevice sourceDevice : sourceDevices) {
String sourceDeviceType = sourceDevice.getDeviceType();
if (sourceDeviceType == null || sourceDeviceType.isEmpty()) {
continue;
}
DataSourceContextHolder.setDataSource("source");
try {
for (SourceDevice sourceDevice : sourceDevices) {
String sourceDeviceType = sourceDevice.getDeviceType();
if (sourceDeviceType == null || sourceDeviceType.isEmpty()) {
continue;
}
// 从字典表查询设备类型映射
// dict_value是源表的device_type值dict_label是目标表的device_type值
DictData dictData = dictDataRepository.findDictDataByDictTypeAndDictLabel(
// 从字典表查询设备类型映射
// dict_value是源表的device_type值dict_label是目标表的device_type值
DictData dictData = dictDataRepository.findByNativeSQL(
deviceSyncConfig.getDictType(), sourceDeviceType);
String targetDeviceType = "99"; // 默认值为"99"(其他)
if (!Objects.isNull(dictData) && dictData.getDictValue() != null) {
targetDeviceType = dictData.getDictValue();
}
String targetDeviceType = "99"; // 默认值为"99"(其他)
if (!Objects.isNull(dictData) && dictData.getDictValue() != null) {
targetDeviceType = dictData.getDictValue();
sourceDevice.setDeviceType(targetDeviceType);
}
sourceDevice.setDeviceType(targetDeviceType);
logger.info("已处理完类型转换数据:{}",sourceDevices.size());
}finally {
DataSourceContextHolder.clearDataSource();
}
}
/**
@ -166,7 +172,6 @@ public class DeviceSyncService {
* @param sourceDevices
*/
@DS("target")
@Transactional(rollbackFor = Exception.class)
public void syncDevicesToTarget(List<SourceDevice> sourceDevices) {
if (CollectionUtils.isEmpty(sourceDevices)) {
return;

View File

@ -8,9 +8,6 @@ spring:
application:
# 应用名称
name: stwzhj-basetost
profiles:
# 环境配置
active: dev
datasource:
dynamic:
primary: target #设置默认数据源为目标数据库
@ -29,12 +26,14 @@ spring:
password: ycgis
driver-class-name: org.postgresql.Driver
jpa:
show-sql: true
show-sql: false
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
properties:
hibernate:
format_sql: true # 格式化 SQL便于阅读
use_sql_comments: true # 添加注释,显示这是什么操作
dialect: org.hibernate.dialect.PostgreSQLDialect
# 设备数据同步配置
@ -52,3 +51,16 @@ device-sync:
# 定时任务cron表达式
cron: 0 0/10 * * * ?
# 日志配置
logging:
level:
org.springframework: warn
org.mybatis.spring.mapper: error
org.springframework.context.support.PostProcessorRegistrationDelegate: error
# JPA 日志配置
org.hibernate.SQL: debug
org.hibernate.orm.jdbc.bind: trace # Hibernate 6
# 如果你还在使用 Hibernate 5取消下面的注释
# org.hibernate.type.descriptor.sql.BasicBinder: trace
config: classpath:logback-plus.xml