基础数据上传到省厅汇聚
parent
8364d79d05
commit
45167e5874
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public class DeviceSyncConfig {
|
|||
/**
|
||||
* 信息来源标识 - 每个地市配置不同的info_source
|
||||
*/
|
||||
private String infoSource = "3418";
|
||||
private String infoSource = "3416";
|
||||
|
||||
/**
|
||||
* 设备类型映射字典类型
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -20,6 +20,8 @@ public interface DeviceRepository extends JpaRepository<Device, Integer>, JpaSpe
|
|||
*/
|
||||
Device findByDeviceCodeAndInfoSource(String deviceCode, String infoSource);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 查询指定信息来源的最新更新时间
|
||||
* @param infoSource 信息来源
|
||||
|
|
|
|||
|
|
@ -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 字典类型
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从源数据库同步设备数据
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue