宣城新版位置汇聚
parent
692c2a31bd
commit
86666b8a04
|
|
@ -4,8 +4,15 @@ import org.dromara.common.core.domain.R;
|
|||
import org.dromara.data2es.api.domain.RemoteGpsInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public interface RemoteDataToEsService {
|
||||
|
||||
R saveDataBatch(List<RemoteGpsInfo> gpsInfoList);
|
||||
|
||||
R saveData(RemoteGpsInfo gpsInfo) throws Exception;
|
||||
|
||||
R updateOnlineStatusBatch(List<RemoteGpsInfo> gpsInfoList);
|
||||
|
||||
R updateOnlineStatus(RemoteGpsInfo gpsInfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ public class RemoteGpsInfo implements Serializable {
|
|||
* 类型
|
||||
*/
|
||||
private String deviceType;
|
||||
private String latitude;
|
||||
private String longitude;
|
||||
private String lat;
|
||||
private String lng;
|
||||
//方向
|
||||
private String orientation;
|
||||
//高程
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
package org.dromara.system.api;
|
||||
|
||||
import org.dromara.system.api.domain.bo.RemoteDeptBo;
|
||||
import org.dromara.system.api.domain.vo.RemoteDeptVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门服务
|
||||
*
|
||||
|
|
@ -15,4 +20,6 @@ public interface RemoteDeptService {
|
|||
*/
|
||||
String selectDeptNameByIds(String deptIds);
|
||||
|
||||
List<RemoteDeptVo> selectDept(RemoteDeptBo bo);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
package org.dromara.system.api.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 部门业务对象 sys_dept
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class RemoteDeptBo implements Serializable {
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
private String deptId;
|
||||
|
||||
/**
|
||||
* 父部门ID
|
||||
*/
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 部门类别编码
|
||||
*/
|
||||
private String deptCategory;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
private Integer orderNum;
|
||||
|
||||
/**
|
||||
* 负责人
|
||||
*/
|
||||
private Long leader;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 部门状态(0正常 1停用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
private String fullName;
|
||||
|
||||
}
|
||||
|
|
@ -87,6 +87,8 @@ public class RemoteDeviceBo implements Serializable {
|
|||
|
||||
private String updateTime;
|
||||
|
||||
private String[] zzjgdms;
|
||||
|
||||
/**
|
||||
* 备注字段2
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
package org.dromara.system.api.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 部门视图对象 sys_dept
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@Data
|
||||
public class RemoteDeptVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
private String deptId;
|
||||
|
||||
/**
|
||||
* 父部门id
|
||||
*/
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 父部门名称
|
||||
*/
|
||||
private String parentName;
|
||||
|
||||
/**
|
||||
* 祖级列表
|
||||
*/
|
||||
private String ancestors;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 部门类别编码
|
||||
*/
|
||||
private String deptCategory;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
private Integer orderNum;
|
||||
|
||||
/**
|
||||
* 负责人ID
|
||||
*/
|
||||
private Long leader;
|
||||
|
||||
/**
|
||||
* 负责人
|
||||
*/
|
||||
private String leaderName;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 部门状态(0正常 1停用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
private Integer allCount;
|
||||
|
||||
private Integer onlineCount;
|
||||
|
||||
private String fullName;
|
||||
|
||||
}
|
||||
|
|
@ -130,6 +130,8 @@ public class LoginUser implements Serializable {
|
|||
*/
|
||||
private String deviceType;
|
||||
|
||||
private String manageDeptId;
|
||||
|
||||
/**
|
||||
* 获取登录id
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ server:
|
|||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: stwzhj-auth
|
||||
name: wzhj-auth
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: @profiles.active@
|
||||
|
|
|
|||
|
|
@ -21,8 +21,12 @@ public class RedisConstants {
|
|||
|
||||
public static final long REDIS_ONLINE_USER_NEVER_EXPIRE = -1;
|
||||
|
||||
public static final long REDIS_NEVER_EXPIRE = 0L;
|
||||
|
||||
public static final long FIVE_MINUTES_REDIS_ONLINE_USER_EXPIRE_TIME = 60 * 5;
|
||||
|
||||
public static final String ONLINE_USERS_TEN = "ten:online_users:";
|
||||
|
||||
|
||||
public static String getUserTokenKey(String token) {
|
||||
return CCL_CODING_SSO_TOKEN + token;
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@ public enum DataScopeType {
|
|||
/**
|
||||
* 部门数据权限
|
||||
*/
|
||||
DEPT("3", " #{#deptName} = #{#user.deptId} ", " 1 = 0 "),
|
||||
DEPT("3", " #{#deptName} = #{#user.manageDeptId} ", " 1 = 0 "),
|
||||
|
||||
/**
|
||||
* 部门及以下数据权限
|
||||
*/
|
||||
DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} )", " 1 = 0 "),
|
||||
DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.manageDeptId )} )", " 1 = 0 "),
|
||||
|
||||
/**
|
||||
* 仅本人数据权限
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package org.dromara.common.redis.utils;
|
||||
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.core.utils.RedisConstants;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.redisson.api.*;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
|
@ -345,6 +347,29 @@ public class RedisUtils {
|
|||
return rSet.add(data);
|
||||
}
|
||||
|
||||
public static <T> void set(final String key, String data,long time) {
|
||||
if (time > 0){
|
||||
CLIENT.getBucket(key).set(data, time, TimeUnit.SECONDS);
|
||||
}else {
|
||||
CLIENT.getBucket(key).set(data);
|
||||
}
|
||||
|
||||
/*RSet<T> rSet = CLIENT.getSet(key);
|
||||
if (time > 0){
|
||||
rSet.expireAsync(time,TimeUnit.SECONDS);
|
||||
}
|
||||
return rSet.add(data);*/
|
||||
}
|
||||
|
||||
public static <T> void del(final String key) {
|
||||
CLIENT.getBucket(key).delete();
|
||||
/*RSet<T> rSet = CLIENT.getSet(key);
|
||||
if (time > 0){
|
||||
rSet.expireAsync(time,TimeUnit.SECONDS);
|
||||
}
|
||||
return rSet.add(data);*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册Set监听器
|
||||
* <p>
|
||||
|
|
@ -669,24 +694,25 @@ public class RedisUtils {
|
|||
* @param pattern 模糊匹配的模式,例如 "user:*"
|
||||
* @return 匹配到的 key 和 value 对
|
||||
*/
|
||||
public Map<String, String> getMatchingKeysAndValues(String pattern) {
|
||||
public static List<JSONObject> getMatchingKeysAndValues(String pattern) {
|
||||
RKeys rKeys = CLIENT.getKeys();
|
||||
Iterable<String> keysIterable = rKeys.getKeysByPattern(pattern); // 获取匹配的 key
|
||||
|
||||
// 获取匹配的键值对
|
||||
RMap<String, String> map = CLIENT.getMap("myMap");
|
||||
Map<String, String> result = new java.util.HashMap<>();
|
||||
|
||||
List<JSONObject> list = new ArrayList<>();
|
||||
// RBatch batch = CLIENT.createBatch();
|
||||
// 批量获取这些key的值
|
||||
for (String key : keysIterable) {
|
||||
String value = map.get(key); // 获取每个 key 对应的 value
|
||||
JSONObject jsonObject = JSONUtil.parseObj(value);
|
||||
list.add(jsonObject);
|
||||
if (null != value){
|
||||
JSONObject jsonObject = JSONUtil.parseObj(value);
|
||||
list.add(jsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -719,12 +745,10 @@ public class RedisUtils {
|
|||
/*
|
||||
* 批量插入GEO数据
|
||||
* */
|
||||
/*public static void batchGeoAdd(Map<String, GeoEntry> entryMap){
|
||||
RGeo<RMap<String, String>> geo = CLIENT.getGeo("myGeo");
|
||||
Map<String, GeoEntry> entries = new HashMap<>();
|
||||
entries.put("place1", new GeoEntry(13.361389, 38.115556, "Palermo"));
|
||||
entries.put("place2", new GeoEntry(15.087269, 37.502669, "Catania"));
|
||||
geo.p(entries);
|
||||
}*/
|
||||
public static long geoAdd(Double lng,Double lat,String member){
|
||||
RGeo<String> geo = CLIENT.getGeo(RedisConstants.ONLINE_USERS_GEO);
|
||||
long count1 = geo.add(lng, lat, member);
|
||||
return count1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public class LoginHelper {
|
|||
public static final String USER_NAME_KEY = "userName";
|
||||
public static final String DEPT_KEY = "deptId";
|
||||
public static final String DEPT_NAME_KEY = "deptName";
|
||||
|
||||
public static final String MANAGE_DEPT__KEY = "manageDeptId";
|
||||
public static final String DEPT_CATEGORY_KEY = "deptCategory";
|
||||
public static final String CLIENT_KEY = "clientid";
|
||||
|
||||
|
|
@ -53,6 +55,7 @@ public class LoginHelper {
|
|||
.setExtra(USER_KEY, loginUser.getUserId())
|
||||
.setExtra(USER_NAME_KEY, loginUser.getUsername())
|
||||
.setExtra(DEPT_KEY, loginUser.getDeptId())
|
||||
.setExtra(MANAGE_DEPT__KEY,loginUser.getManageDeptId())
|
||||
.setExtra(DEPT_NAME_KEY, loginUser.getDeptName())
|
||||
.setExtra(DEPT_CATEGORY_KEY, loginUser.getDeptCategory())
|
||||
);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public class GlobalCacheRequestFilter implements GlobalFilter, Ordered {
|
|||
if (!WebFluxUtils.isJsonRequest(exchange)) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
return ServerWebExchangeUtils.cacheRequestBody(exchange, (serverHttpRequest) -> {
|
||||
if (serverHttpRequest == exchange.getRequest()) {
|
||||
return chain.filter(exchange);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ server:
|
|||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: stwzhj-gateway
|
||||
name: wzhj-gateway
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: @profiles.active@
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@
|
|||
<module>stwzhj-consumer</module>
|
||||
<module>stwzhj-location</module>
|
||||
<module>stwzhj-dataToGas</module>
|
||||
<module>wzhj-webscoket</module>
|
||||
<module>wzhj-extract</module>
|
||||
<module>wzhj-udp</module>
|
||||
</modules>
|
||||
|
||||
<artifactId>stwzhj-modules</artifactId>
|
||||
|
|
|
|||
|
|
@ -92,12 +92,12 @@ public class ConsumerWorker {
|
|||
logger.info("deviceCode:{} is null or is too long ",deviceCode);
|
||||
return;
|
||||
}
|
||||
String latitude = esGpsInfo.getLatitude();
|
||||
String latitude = esGpsInfo.getLat();
|
||||
if(StringUtils.isEmpty(latitude) || "0.0".equals(latitude)){
|
||||
logger.info("latitude:{} is null or is zero ",latitude);
|
||||
return;
|
||||
}
|
||||
String longitude = esGpsInfo.getLongitude();
|
||||
String longitude = esGpsInfo.getLng();
|
||||
if(StringUtils.isEmpty(longitude) || "0.0".equals(longitude)){
|
||||
logger.info("longitude:{} is null or is zero ",longitude);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class ElasticsearchConfig {
|
|||
RestClientBuilder builder = RestClient.builder(httpHost);
|
||||
// 设置用户名、密码
|
||||
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
|
||||
// credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
|
||||
// 连接延时配置
|
||||
builder.setRequestConfigCallback(requestConfigBuilder -> {
|
||||
requestConfigBuilder.setConnectTimeout(connectTimeOut);
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ public class KafkaConfig {
|
|||
// private String kafkaServers = "140.168.2.31:21007,140.168.2.32:21007,140.168.2.33:21007";
|
||||
// private String kafkaServers = "53.208.61.105:6667,53.208.61.106:6667,53.208.61.107:6667";//六安GA网
|
||||
// private String kafkaServers = "34.72.62.93:9092";//六安视频网
|
||||
// private String kafkaServers = "127.0.0.1:9092";//本地
|
||||
private String kafkaServers = "53.207.8.71:9092,53.193.3.15:9092,53.160.0.237:9092,53.104.56.58:9092,53.128.22.61:9092";//省厅 马伟提供
|
||||
private String kafkaServers = "127.0.0.1:9092";//本地
|
||||
// private String kafkaServers = "53.238.79.4:9092,53.238.79.5:9092,53.238.79.6:9092";//省厅 马伟提供
|
||||
|
||||
private String groupId = "ruansiProducer";
|
||||
|
||||
|
|
@ -128,9 +128,9 @@ public class KafkaConfig {
|
|||
// props.put(kerberosDomainName, "hadoop.hadoop.com");
|
||||
//设置自定义的分区策略类,默认不传key,是粘性分区,尽量往一个分区中发消息。如果key不为null,则默认是按照key的hashcode与 partition的取余来决定哪个partition
|
||||
//props.put("partitioner.class","com.kafka.myparitioner.CidPartitioner");
|
||||
props.put(securityProtocol, "SASL_PLAINTEXT");
|
||||
/*props.put(securityProtocol, "SASL_PLAINTEXT");
|
||||
props.put("sasl.jaas.config", "org.apache.kafka.common.security.scram.ScramLoginModule required username=\"zkxc\" password=\"zkxcKafka07252023\";");
|
||||
props.put("sasl.mechanism", "SCRAM-SHA-256");
|
||||
props.put("sasl.mechanism", "SCRAM-SHA-256");*/
|
||||
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
|
||||
// KafkaProducer producer = new KafkaProducer<>(props);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,11 +32,6 @@ public class DataToEsController extends BaseController {
|
|||
public R saveGpsInfo(@RequestBody EsGpsInfoVO2 esGpsInfo ){
|
||||
R apiResponse = new R<>();
|
||||
try {
|
||||
if(StringUtils.isBlank(esGpsInfo.getInfoSource())){
|
||||
apiResponse.setCode(500);
|
||||
apiResponse.setMsg("infoSource为空");
|
||||
return apiResponse;
|
||||
}
|
||||
boolean offer = linkedBlockingDeque.offer(esGpsInfo);
|
||||
apiResponse = R.ok(offer);
|
||||
} catch (Exception e) {
|
||||
|
|
@ -87,16 +82,15 @@ public class DataToEsController extends BaseController {
|
|||
EsGpsInfoVO2 esGpsInfo = new EsGpsInfoVO2();
|
||||
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
esGpsInfo.setDeviceCode("34153800001320000101");
|
||||
esGpsInfo.setDeviceType("05");
|
||||
esGpsInfo.setInfoSource("3401");
|
||||
esGpsInfo.setDeviceCode("34180201001310000071");
|
||||
esGpsInfo.setDeviceType("5");
|
||||
esGpsInfo.setGpsTime(new Date());
|
||||
|
||||
esGpsInfo.setLatitude("31.1" + (a + i));
|
||||
esGpsInfo.setLongitude("117.2" + (b + i));
|
||||
esGpsInfo.setZzjgdm("340100000000");
|
||||
esGpsInfo.setZzjgmc("合肥市公安局");
|
||||
esGpsInfo.setCarNum("霍邱看守所01");
|
||||
esGpsInfo.setLat("30.68" + (a + i));
|
||||
esGpsInfo.setLng("118.40" + (b + i));
|
||||
esGpsInfo.setZzjgdm("341802400000");
|
||||
esGpsInfo.setZzjgmc("宣州分局济川派出所");
|
||||
esGpsInfo.setPoliceName("057486_郭超");
|
||||
saveGpsInfo(esGpsInfo);
|
||||
//gpsService.saveData(map);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
package org.dromara.data2es.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2023-03-22 9:51
|
||||
*/
|
||||
@Data
|
||||
@TableName("td_ds_qinwu")
|
||||
public class DSQinwuEntity {
|
||||
private int id;
|
||||
private String category;
|
||||
private String linkId;//外部系统id
|
||||
private String imei;
|
||||
private boolean majorPersonTerminal;
|
||||
private boolean majorVehicleTerminal;
|
||||
private String name;
|
||||
private String orgId;
|
||||
private String orgName;
|
||||
private String type;
|
||||
//时间戳
|
||||
private Date updateTime;
|
||||
private String policeNumber;
|
||||
|
||||
private String policeName;
|
||||
}
|
||||
|
|
@ -15,8 +15,8 @@ public class EsGpsInfo implements Serializable {
|
|||
*/
|
||||
private String deviceCode;
|
||||
private String deviceType;
|
||||
private String latitude;
|
||||
private String longitude;
|
||||
private String lat;
|
||||
private String lng;
|
||||
//方向
|
||||
private String orientation;
|
||||
//高程
|
||||
|
|
@ -28,7 +28,6 @@ public class EsGpsInfo implements Serializable {
|
|||
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date gpsTime;
|
||||
//3401 ,3402 地市代码
|
||||
private String infoSource;
|
||||
|
||||
private Integer online;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
package org.dromara.data2es.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2023-03-20 11:53
|
||||
*/
|
||||
@Data
|
||||
public class DSResponse {
|
||||
|
||||
/**
|
||||
* msg : Success
|
||||
* ret : ok
|
||||
* dataStore : [{"category":"SCZD","id":"SCZD","imei":"SCZD","majorPersonTerminal":false,"majorVehicleTerminal":false,"name":"SCZD","orgId":"SCZD","orgName":"SCZD","type":"SCZD"}]
|
||||
*/
|
||||
|
||||
private String msg;
|
||||
private String ret;
|
||||
private List<DataStoreBean> dataStore;
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getRet() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void setRet(String ret) {
|
||||
this.ret = ret;
|
||||
}
|
||||
|
||||
public List<DataStoreBean> getDataStore() {
|
||||
return dataStore;
|
||||
}
|
||||
|
||||
public void setDataStore(List<DataStoreBean> dataStore) {
|
||||
this.dataStore = dataStore;
|
||||
}
|
||||
|
||||
public static class DataStoreBean {
|
||||
/**
|
||||
* category : SCZD
|
||||
* id : SCZD
|
||||
* imei : SCZD
|
||||
* majorPersonTerminal : false
|
||||
* majorVehicleTerminal : false
|
||||
* name : SCZD
|
||||
* orgId : SCZD
|
||||
* orgName : SCZD
|
||||
* type : SCZD
|
||||
*/
|
||||
|
||||
private String category;
|
||||
private String id;
|
||||
private String imei;
|
||||
private boolean majorPersonTerminal;
|
||||
private boolean majorVehicleTerminal;
|
||||
private String name;
|
||||
|
||||
private String personName;
|
||||
|
||||
private String orgId;
|
||||
private String orgName;
|
||||
private String type;
|
||||
private String policeNumber;
|
||||
//时间戳
|
||||
private String updateTime;
|
||||
|
||||
public String getPoliceNumber() {
|
||||
return policeNumber;
|
||||
}
|
||||
|
||||
public void setPoliceNumber(String policeNumber) {
|
||||
this.policeNumber = policeNumber;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getImei() {
|
||||
return imei;
|
||||
}
|
||||
|
||||
public void setImei(String imei) {
|
||||
this.imei = imei;
|
||||
}
|
||||
|
||||
public boolean isMajorPersonTerminal() {
|
||||
return majorPersonTerminal;
|
||||
}
|
||||
|
||||
public void setMajorPersonTerminal(boolean majorPersonTerminal) {
|
||||
this.majorPersonTerminal = majorPersonTerminal;
|
||||
}
|
||||
|
||||
public boolean isMajorVehicleTerminal() {
|
||||
return majorVehicleTerminal;
|
||||
}
|
||||
|
||||
public void setMajorVehicleTerminal(boolean majorVehicleTerminal) {
|
||||
this.majorVehicleTerminal = majorVehicleTerminal;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPersonName() {
|
||||
return personName;
|
||||
}
|
||||
|
||||
public void setPersonName(String personName) {
|
||||
this.personName = personName;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getOrgName() {
|
||||
return orgName;
|
||||
}
|
||||
|
||||
public void setOrgName(String orgName) {
|
||||
this.orgName = orgName;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
public String getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(String updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package org.dromara.data2es.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import org.dromara.data2es.domain.EsGpsInfo;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-10-11 15:14
|
||||
*/
|
||||
@Data
|
||||
public class EsGpsInfoVO3 extends EsGpsInfo {
|
||||
|
||||
private static final long serialVersionUID = -4252583194984423318L;
|
||||
|
||||
private String zzjgdm;
|
||||
private String zzjgmc;
|
||||
private String policeNo;
|
||||
private String policeName;
|
||||
private String phoneNum;
|
||||
private String carNum;
|
||||
//勤务Id,DS公司自己系统内有deviceCode 和 勤务ID 的关联,可以直接使用这个id
|
||||
//其他公司没有这个关联关系,所以还需要上面的policeNo和policeName等信息用于展示
|
||||
private String linkId;
|
||||
private String typeOfDevice;
|
||||
|
||||
}
|
||||
|
|
@ -24,4 +24,19 @@ public class RemoteDataToEsServiceImpl implements RemoteDataToEsService {
|
|||
public R saveDataBatch(List<RemoteGpsInfo> gpsInfoList) {
|
||||
return gpsService.saveDataBatch(BeanUtil.copyToList(gpsInfoList, EsGpsInfoVO2.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public R saveData(RemoteGpsInfo gpsInfo) throws Exception {
|
||||
return gpsService.saveData(BeanUtil.toBean(gpsInfo, EsGpsInfoVO2.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public R updateOnlineStatusBatch(List<RemoteGpsInfo> gpsInfoList) {
|
||||
return gpsService.updateOnlineStatusBatch(BeanUtil.copyToList(gpsInfoList, EsGpsInfoVO2.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public R updateOnlineStatus(RemoteGpsInfo gpsInfo) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.dromara.data2es.controller.DataToEsController;
|
|||
import org.dromara.data2es.domain.EsGpsInfo;
|
||||
import org.dromara.data2es.domain.EsGpsInfoVO2;
|
||||
import org.dromara.data2es.service.IGpsService;
|
||||
import org.dromara.data2es.service.StoreDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
|
@ -31,6 +32,9 @@ public class DataInsertBatchHandler implements CommandLineRunner {
|
|||
@Autowired
|
||||
IGpsService gpsService;
|
||||
|
||||
@Autowired
|
||||
StoreDataService storeDataService;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
|
||||
|
|
@ -45,6 +49,7 @@ public class DataInsertBatchHandler implements CommandLineRunner {
|
|||
log.info("batch size={}", list.size());
|
||||
if(CollectionUtil.isNotEmpty(list)) {
|
||||
gpsService.saveDataBatch(list);
|
||||
storeDataService.saveDataByPersonTypeBatch(list);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("缓存队列批量消费异常:{}", e.getMessage());
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@ package org.dromara.data2es.handler;
|
|||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dromara.common.core.utils.RedisConstants;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.dromara.data2es.controller.DataToEsController;
|
||||
import org.dromara.data2es.domain.EsGpsInfoVO2;
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -19,6 +22,7 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
|
|
@ -27,6 +31,7 @@ import java.util.Objects;
|
|||
* @date 2021-11-08 16:40
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RedisExpireListener extends KeyExpirationEventMessageListener {
|
||||
|
||||
@Autowired
|
||||
|
|
@ -49,22 +54,39 @@ public class RedisExpireListener extends KeyExpirationEventMessageListener {
|
|||
String expireKey = message.toString();
|
||||
if(StringUtils.isNotEmpty(expireKey) &&
|
||||
expireKey.startsWith(RedisConstants.ORG_CODE_PRE)){
|
||||
String[] split = expireKey.split(":");
|
||||
EsGpsInfoVO2 esGpsInfoVO2 = new EsGpsInfoVO2();
|
||||
esGpsInfoVO2.setDeviceType(split[2]);
|
||||
esGpsInfoVO2.setDeviceCode(split[3]);
|
||||
String zzjgdm = split[1];
|
||||
String deviceType = split[2];
|
||||
String deviceCode = split[3];
|
||||
if(StringUtils.isNotEmpty(zzjgdm)) {
|
||||
JSONObject object = RedisUtils.getBucket(RedisConstants.ONLINE_USERS + zzjgdm + ":"
|
||||
+ deviceType+":"+deviceCode);
|
||||
handleExpiredEvent(expireKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleExpiredEvent(String expiredKey) {
|
||||
RedissonClient redisson = RedisUtils.getClient();
|
||||
RLock lock = redisson.getLock("LOCK:" + expiredKey);
|
||||
try {
|
||||
if (lock.tryLock(0, 30, TimeUnit.SECONDS)) {
|
||||
// 实际业务逻辑
|
||||
String[] split = expiredKey.split(":");
|
||||
|
||||
String deviceType = split[2];
|
||||
String deviceCode = split[3];
|
||||
if ("5".equals(deviceType) || "9".equals(deviceType) || "8".equals(deviceType) || "7".equals(deviceType)){
|
||||
return;
|
||||
}
|
||||
log.error("redis key expired:key={}",expiredKey);
|
||||
JSONObject object = RedisUtils.getBucket(RedisConstants.ONLINE_USERS + deviceType+":"+deviceCode);
|
||||
if (Objects.isNull(object)) {
|
||||
log.info("redis key={},Object=null,deviceType={},deviceCode={}", expiredKey,deviceType,deviceCode);
|
||||
return;
|
||||
}
|
||||
EsGpsInfoVO2 gpsInfo = BeanUtil.toBean(object, EsGpsInfoVO2.class);
|
||||
gpsInfo.setGpsTime(new Date());
|
||||
gpsInfo.setOnline(0);
|
||||
dataToEsController.saveGpsInfo(gpsInfo);
|
||||
log.info("redis key expired:key={}", expiredKey);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
logger.info("redis key expired:key={}", expireKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,19 @@ package org.dromara.data2es.handler;
|
|||
* es redis kafka
|
||||
* */
|
||||
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONPObject;
|
||||
import com.alibaba.fastjson2.util.JSONObject1O;
|
||||
import jodd.util.StringUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dromara.common.core.utils.RedisConstants;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.dromara.data2es.domain.EsGpsInfo;
|
||||
import org.dromara.data2es.domain.EsGpsInfoVO2;
|
||||
import org.dromara.data2es.domain.vo.EsGpsInfoVO3;
|
||||
import org.dromara.data2es.service.IGpsService;
|
||||
import org.dromara.data2es.util.ConfigConstants;
|
||||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
|
|
@ -57,12 +62,9 @@ public class RequestHandler {
|
|||
|
||||
String deviceType = esGpsInfoVO2.getDeviceType();
|
||||
if(StringUtil.isEmpty(deviceType)){
|
||||
deviceType = "99";
|
||||
}
|
||||
String infoSource = esGpsInfoVO2.getInfoSource();
|
||||
if(StringUtils.isEmpty(infoSource)){
|
||||
infoSource = "other";
|
||||
deviceType = "6";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该条记录的基本信息推送给第三方使用
|
||||
*/
|
||||
|
|
@ -76,7 +78,6 @@ public class RequestHandler {
|
|||
//kafkaProducer.send(esGpsInfoVO2, ConfigConstants.KAFKA_TOPIC_SEND_PRE+"."+deviceType);
|
||||
//地市的kafka数据,如接收地市某个设备的数据可以对接此kafka topic
|
||||
//todo 暂时隐藏
|
||||
kafkaTemplate.send(ConfigConstants.KAFKA_TOPIC_SEND_PRE+"."+infoSource+"."+deviceType,JSON.toJSONString(esGpsInfoVO2));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -130,4 +131,100 @@ public class RequestHandler {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* 在线用户存入
|
||||
* @param esGpsInfoVo2
|
||||
*/
|
||||
@Async
|
||||
public void redisOnlineUser(EsGpsInfoVO2 esGpsInfoVo2){
|
||||
//todo 存储的value应该改为 esGpsInfoVo2为后面大屏展示提供数据
|
||||
if(null == esGpsInfoVo2){
|
||||
logger.error("redis存入对象为空");
|
||||
return;
|
||||
}
|
||||
|
||||
Date gpsTime = esGpsInfoVo2.getGpsTime();
|
||||
String jsonValue = JSONUtil.toJsonStr(esGpsInfoVo2);
|
||||
if(!Objects.isNull(gpsTime)){
|
||||
|
||||
//设置永不过期,便于前端查询设备的最后位置 ----2022年9月15日
|
||||
|
||||
long betweenS = DateUtil.between(gpsTime, new Date(), DateUnit.SECOND);
|
||||
//过期时间应该是20分钟减去设备定位时间与当前时间的差值,比如设备已经比当前时间晚15分钟了,那么设备的过期时间应该只剩5分钟了
|
||||
long onlineTime = 60*10 - betweenS;
|
||||
|
||||
String deviceCode = esGpsInfoVo2.getDeviceCode();
|
||||
String deviceType = esGpsInfoVo2.getDeviceType();
|
||||
//设置永不过期,便于前端查询设备的最后位置 ----2022年9月15日
|
||||
RedisUtils.set(RedisConstants.ONLINE_USERS +
|
||||
deviceType
|
||||
+ ":" + deviceCode, jsonValue, RedisConstants.REDIS_NEVER_EXPIRE);
|
||||
logger.error("redis存入,deviceCode={}",deviceCode);
|
||||
|
||||
//地理位置空间查询
|
||||
long b = RedisUtils.geoAdd(Double.valueOf(esGpsInfoVo2.getLng()),
|
||||
Double.valueOf(esGpsInfoVo2.getLat()), deviceCode +"#"+ deviceType);
|
||||
|
||||
if(onlineTime > 0) {
|
||||
//设置一个过期时间,方便key自动过期监听,设置离线 [RedisExpireListener]
|
||||
RedisUtils.set(RedisConstants.ONLINE_USERS_TEN +
|
||||
deviceType
|
||||
+ ":" + deviceCode, jsonValue, onlineTime);
|
||||
|
||||
|
||||
|
||||
}
|
||||
//方便根据组织机构计算数量
|
||||
|
||||
String zzjgdm = esGpsInfoVo2.getZzjgdm();
|
||||
if(esGpsInfoVo2.getOnline() == 1) {
|
||||
if(StringUtils.isNotBlank(zzjgdm)) {
|
||||
RedisUtils.set(RedisConstants.ORG_CODE_ONLINE_DEVICES + esGpsInfoVo2.getDeviceType() + ":"
|
||||
+ zzjgdm + ":" + esGpsInfoVo2.getDeviceCode(), jsonValue, RedisConstants.REDIS_NEVER_EXPIRE);
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
if(StringUtils.isNotBlank(zzjgdm)) {
|
||||
//如果是离线的情况,那么就清除这个在线的
|
||||
RedisUtils.del(RedisConstants.ORG_CODE_ONLINE_DEVICES + esGpsInfoVo2.getDeviceType() + ":"
|
||||
+ zzjgdm + ":" + esGpsInfoVo2.getDeviceCode());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 单独存入
|
||||
* @param esGpsInfo
|
||||
*/
|
||||
@Async
|
||||
public void redisOnlineUserByPerson(EsGpsInfo esGpsInfo){
|
||||
EsGpsInfoVO3 esGpsInfoVO3 = (EsGpsInfoVO3) esGpsInfo;
|
||||
String jsonValue = JSONUtil.toJsonStr(esGpsInfoVO3);
|
||||
Date gpsTime = esGpsInfoVO3.getGpsTime();
|
||||
if(!Objects.isNull(gpsTime)){
|
||||
|
||||
//设置永不过期,便于前端查询设备的最后位置 ----2022年9月15日
|
||||
RedisUtils.set(RedisConstants.ONLINE_USERS +
|
||||
esGpsInfoVO3.getDeviceType()
|
||||
+ ":" + esGpsInfoVO3.getDeviceCode(), jsonValue, RedisConstants.REDIS_NEVER_EXPIRE);
|
||||
|
||||
//设置一个10分钟过期的。然后用redis监听、监听过期的数据然后重新发送到kafka
|
||||
RedisUtils.set(RedisConstants.ONLINE_USERS_TEN +
|
||||
esGpsInfoVO3.getDeviceType()
|
||||
+ ":" + esGpsInfoVO3.getDeviceCode(), jsonValue, 60*10);
|
||||
long b = RedisUtils.geoAdd( Double.valueOf(esGpsInfoVO3.getLng()), Double.valueOf(esGpsInfoVO3.getLat()), esGpsInfoVO3.getDeviceCode()+"#"+esGpsInfoVO3.getDeviceType());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package org.dromara.data2es.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.dromara.data2es.domain.DSQinwuEntity;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
*/
|
||||
@Repository
|
||||
public interface DSQinwuMapper extends BaseMapper<DSQinwuEntity> {
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
package org.dromara.data2es.mapper;
|
||||
|
||||
public class TDeviceMapper {
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
package org.dromara.data2es.schedule;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dromara.data2es.domain.DSQinwuEntity;
|
||||
import org.dromara.data2es.domain.vo.DSResponse;
|
||||
import org.dromara.data2es.service.DSQinwuService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
* DS勤务人员和设备关系数据抽取
|
||||
* @author chenle
|
||||
* @date 2023-03-21 17:37
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class BaseDataSchedule {
|
||||
|
||||
|
||||
private String lastUpdateTime;
|
||||
|
||||
private String preUrl = "http://53.238.84.10:28080/ds-portal-web";
|
||||
|
||||
@Autowired
|
||||
DSQinwuService dsQinwuService;
|
||||
|
||||
@Value("${ruansi.ruansi-kafka.send-to-third-enabled}")
|
||||
private boolean sendToThirdEnabled;
|
||||
|
||||
@Value("${ruansi.ruansi-kafka.start-update-time}")
|
||||
private String startUpdateTime;
|
||||
|
||||
@Value("${ruansi.ruansi-kafka.ds-preurl}")
|
||||
private String dsPreurl;
|
||||
/**
|
||||
* 娱特单位抽取
|
||||
*/
|
||||
// @Scheduled(cron = "0/30 * * * * ?")
|
||||
public void updateDsQw(){
|
||||
if(StringUtils.isBlank(lastUpdateTime)){
|
||||
DSQinwuEntity qinwu = dsQinwuService.lastOne();
|
||||
lastUpdateTime = DateUtil.formatDateTime(qinwu.getUpdateTime());
|
||||
}
|
||||
String suffixUrl = "/v1/terminal/updateTime-terminal";
|
||||
DSResponse dsResponse = requestList(lastUpdateTime, suffixUrl);
|
||||
List<DSResponse.DataStoreBean> dataStores = dsResponse.getDataStore();
|
||||
if(CollectionUtils.isEmpty(dataStores)){
|
||||
log.info("没有可更新的设备");
|
||||
return;
|
||||
}
|
||||
log.info("updateTime={},deviceSize={}",lastUpdateTime,dataStores.size());
|
||||
|
||||
List<DSQinwuEntity> newDeviceList = generateEntityList(dataStores);
|
||||
// List<DSQinwuEntity> newDeviceList = generateEntityList2(dataStores);
|
||||
if(CollectionUtils.isEmpty(newDeviceList)){
|
||||
log.info("未查询到设备newDeviceList = null");
|
||||
return;
|
||||
}
|
||||
int count = dsQinwuService.saveOrUpdate(newDeviceList);
|
||||
log.info("更新或插入的count={}",count);
|
||||
if(count == newDeviceList.size()){ //如果有一个失败的情况出现,那么更新时间就不变
|
||||
DSQinwuEntity qinwu = dsQinwuService.lastOne();
|
||||
Date updateTime = qinwu.getUpdateTime();
|
||||
lastUpdateTime = DateUtil.formatDateTime(updateTime);
|
||||
log.info("timestamp={},lastUpdateTime={}",updateTime,lastUpdateTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造数据库实体list
|
||||
* @param dataStores ds系统列表
|
||||
* @return 自己系统数据库列表
|
||||
*/
|
||||
private List<DSQinwuEntity> generateEntityList(List<DSResponse.DataStoreBean> dataStores) {
|
||||
List<DSQinwuEntity> newDeviceList = new ArrayList<>();
|
||||
for (DSResponse.DataStoreBean dataStoreBean : dataStores) {
|
||||
String deviceCode = dataStoreBean.getImei();
|
||||
String policeName = dataStoreBean.getName();
|
||||
String type = dataStoreBean.getType();//类型 PDT、ZFJLY等
|
||||
if(StringUtils.isBlank(deviceCode) || StringUtils.isBlank(policeName) || StringUtils.isBlank(type)){
|
||||
log.info("deviceCode、policeName、type有一个为空,deviceCode={}",deviceCode);
|
||||
continue;
|
||||
}
|
||||
|
||||
DSQinwuEntity entity = new DSQinwuEntity();
|
||||
// BeanUtil.copyProperties(dataStoreBean,com.ruansee.common_kafka.entity,"id","updateTime");
|
||||
entity.setCategory(dataStoreBean.getCategory());
|
||||
entity.setLinkId(dataStoreBean.getId());
|
||||
entity.setImei(dataStoreBean.getImei());
|
||||
entity.setMajorPersonTerminal(dataStoreBean.isMajorPersonTerminal());
|
||||
entity.setMajorVehicleTerminal(dataStoreBean.isMajorVehicleTerminal());
|
||||
entity.setOrgId(dataStoreBean.getOrgId());
|
||||
entity.setOrgName(dataStoreBean.getOrgName());
|
||||
entity.setName(dataStoreBean.getName());
|
||||
entity.setType(dataStoreBean.getType());
|
||||
entity.setPoliceNumber(dataStoreBean.getPoliceNumber());
|
||||
entity.setPoliceName(dataStoreBean.getPersonName());
|
||||
|
||||
try {
|
||||
entity.setUpdateTime(DateUtil.date(Long.valueOf(dataStoreBean.getUpdateTime())));
|
||||
}catch (Exception e){
|
||||
log.info("时间转换错误,msg={}",e.getMessage());
|
||||
continue;
|
||||
}
|
||||
newDeviceList.add(entity);
|
||||
}
|
||||
return newDeviceList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造数据库实体list
|
||||
* @param dataStores ds系统列表
|
||||
* @return 自己系统数据库列表
|
||||
*/
|
||||
private List<DSQinwuEntity> generateEntityList2(List<DSResponse.DataStoreBean> dataStores) {
|
||||
List<DSQinwuEntity> newDeviceList = new ArrayList<>();
|
||||
for (int i =1;i<100;i++) {
|
||||
|
||||
DSQinwuEntity entity = new DSQinwuEntity();
|
||||
|
||||
entity.setCategory("123");
|
||||
entity.setLinkId("asdasdsasd");
|
||||
entity.setImei("12343435345" + new Random(100).nextInt());
|
||||
entity.setMajorPersonTerminal(false);
|
||||
entity.setMajorVehicleTerminal(false);
|
||||
entity.setOrgId("341100000000");
|
||||
entity.setOrgName("滁州市公安局");
|
||||
entity.setName("张三");
|
||||
entity.setType("PDT");
|
||||
|
||||
try {
|
||||
entity.setUpdateTime(DateUtil.date(System.currentTimeMillis()));
|
||||
}catch (Exception e){
|
||||
log.info("时间转换错误,msg={}",e.getMessage());
|
||||
continue;
|
||||
}
|
||||
newDeviceList.add(entity);
|
||||
}
|
||||
return newDeviceList;
|
||||
}
|
||||
|
||||
private DSResponse requestList(String updateTime, String suffixUrl) {
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
map.put("updateTime",updateTime);
|
||||
String content = HttpUtil.get(dsPreurl + suffixUrl, map);
|
||||
DSResponse dsResponse = JSONUtil.toBean(content, DSResponse.class);
|
||||
return dsResponse;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ public class GpsTaskTest {
|
|||
IGpsService gpsService;
|
||||
|
||||
|
||||
@Scheduled(cron = "0/10 * * * * ?")
|
||||
// @Scheduled(cron = "0/10 * * * * ?")
|
||||
public void produceGps() throws InvocationTargetException, IllegalAccessException, ExecutionException, InterruptedException {
|
||||
int a = 10000;
|
||||
int b = 20000;
|
||||
|
|
@ -45,9 +45,9 @@ public class GpsTaskTest {
|
|||
map.put("gpsTime",new Date());
|
||||
map.put("locationDesc","合肥市公安局");
|
||||
|
||||
esGpsInfo.setLatitude("31.3" + (a + i));
|
||||
esGpsInfo.setLat("31.3" + (a + i));
|
||||
map.put("lat","31." + (a + i));
|
||||
esGpsInfo.setLongitude("117.2" + (b + i));
|
||||
esGpsInfo.setLng("117.2" + (b + i));
|
||||
map.put("lng","117." + (b + i));
|
||||
//gpsService.saveData(map);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
package org.dromara.data2es.schedule;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-05-18 18:23
|
||||
*/
|
||||
|
||||
public class RedisOnlineUserSchedule {
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.dromara.data2es.service;
|
||||
|
||||
import org.dromara.data2es.domain.DSQinwuEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2023-03-22 12:16
|
||||
*/
|
||||
public interface DSQinwuService {
|
||||
|
||||
DSQinwuEntity checkExist(DSQinwuEntity dsQinwuEntity);
|
||||
|
||||
DSQinwuEntity lastOne();
|
||||
|
||||
int saveOrUpdate(List<DSQinwuEntity> deviceList);
|
||||
}
|
||||
|
|
@ -14,4 +14,10 @@ public interface IGpsService {
|
|||
|
||||
R saveDataBatch(List<EsGpsInfoVO2> esGpsInfoVO2s);
|
||||
|
||||
R saveData(EsGpsInfoVO2 esGpsInfoVO2) throws ExecutionException, InterruptedException;
|
||||
|
||||
R updateOnlineStatusBatch(List<EsGpsInfoVO2> esGpsInfoVO2s);
|
||||
|
||||
R updateOnlineStatus(EsGpsInfoVO2 gpsInfoVO2);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package org.dromara.data2es.service;
|
||||
|
||||
|
||||
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.data2es.domain.EsGpsInfo;
|
||||
import org.dromara.data2es.domain.EsGpsInfoVO2;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
* 2023年3月13日 新增加一类数据,发送给DS使用
|
||||
* @author chenle
|
||||
* @date 2021-05-14 16:44
|
||||
*/
|
||||
public interface StoreDataService {
|
||||
R saveDataByPersonType(EsGpsInfo esGpsInfo);
|
||||
|
||||
R saveDataByPersonTypeBatch(List<EsGpsInfoVO2> esGpsInfo) throws InvocationTargetException, IllegalAccessException, ExecutionException, InterruptedException;
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package org.dromara.data2es.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.data2es.domain.DSQinwuEntity;
|
||||
import org.dromara.data2es.mapper.DSQinwuMapper;
|
||||
import org.dromara.data2es.service.DSQinwuService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2023-03-22 12:18
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class DSQinwuServiceImpl implements DSQinwuService {
|
||||
|
||||
@Autowired
|
||||
DSQinwuMapper dsQinwuMapper;
|
||||
|
||||
@Override
|
||||
public DSQinwuEntity checkExist(DSQinwuEntity dsQinwuEntity) {
|
||||
LambdaQueryWrapper<DSQinwuEntity> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(DSQinwuEntity::getImei, dsQinwuEntity.getImei());
|
||||
lqw.eq(DSQinwuEntity::getType, dsQinwuEntity.getType());
|
||||
DSQinwuEntity entity = dsQinwuMapper.selectOne(lqw);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DSQinwuEntity lastOne() {
|
||||
LambdaQueryWrapper<DSQinwuEntity> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.orderByDesc(DSQinwuEntity::getUpdateTime);
|
||||
lqw.last("limit 1");
|
||||
DSQinwuEntity entity = dsQinwuMapper.selectOne(lqw);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int saveOrUpdate(List<DSQinwuEntity> deviceList) {
|
||||
|
||||
int insertCount = 0;
|
||||
int updatedCount = 0;
|
||||
|
||||
for (DSQinwuEntity newEntity : deviceList) {
|
||||
|
||||
DSQinwuEntity oldEntity = checkExist(newEntity);
|
||||
if (Objects.isNull(oldEntity)) {
|
||||
int insert = dsQinwuMapper.insert(newEntity);
|
||||
if (insert > 0) {
|
||||
insertCount++;
|
||||
}
|
||||
} else {
|
||||
int compare = DateUtil.compare(oldEntity.getUpdateTime(), newEntity.getUpdateTime());
|
||||
//数据库的已存在设备的更新日期大于新来设备的更新日期,以最新日期为准,不更新此条设备。
|
||||
if(compare >= 0){
|
||||
updatedCount++;
|
||||
continue;
|
||||
}
|
||||
newEntity.setId(oldEntity.getId());
|
||||
int update = dsQinwuMapper.updateById(newEntity);
|
||||
if (update > 0) {
|
||||
updatedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (insertCount+updatedCount);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,9 @@ import cn.hutool.core.bean.BeanUtil;
|
|||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
|
|
@ -18,6 +19,7 @@ import org.dromara.data2es.domain.entity.GpsInfoEntity;
|
|||
import org.dromara.data2es.exception.MyBusinessException;
|
||||
import org.dromara.data2es.handler.RequestHandler;
|
||||
import org.dromara.data2es.service.IGpsService;
|
||||
import org.dromara.data2es.service.StoreDataService;
|
||||
import org.dromara.system.api.RemoteDeviceService;
|
||||
import org.dromara.system.api.domain.vo.RemoteDeviceVo;
|
||||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
|
|
@ -35,12 +37,15 @@ import org.elasticsearch.rest.RestStatus;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
||||
@RequiredArgsConstructor
|
||||
|
|
@ -50,8 +55,8 @@ public class GpsServiceImpl implements IGpsService {
|
|||
@Autowired
|
||||
private RestHighLevelClient restHighLevelClient;
|
||||
|
||||
@DubboReference
|
||||
private RemoteDeviceService deviceService;
|
||||
@Autowired
|
||||
StoreDataService storeDataService;
|
||||
|
||||
private final RequestHandler requestHandler;
|
||||
|
||||
|
|
@ -65,10 +70,10 @@ public class GpsServiceImpl implements IGpsService {
|
|||
double lng ;
|
||||
double lat ;
|
||||
try {
|
||||
lng = Double.parseDouble(esGpsInfo.getLongitude());
|
||||
lat = Double.parseDouble(esGpsInfo.getLatitude());
|
||||
lng = Double.parseDouble(esGpsInfo.getLng());
|
||||
lat = Double.parseDouble(esGpsInfo.getLat());
|
||||
}catch (NumberFormatException e){
|
||||
throw new MyBusinessException("经纬度转double异常,经度为:"+esGpsInfo.getLongitude() +"纬度为"+esGpsInfo.getLatitude());
|
||||
throw new MyBusinessException("经纬度转double异常,经度为:"+esGpsInfo.getLng() +"纬度为"+esGpsInfo.getLat());
|
||||
}
|
||||
|
||||
gpsInfoEntity.setLocation(new Double[]{lng,lat});
|
||||
|
|
@ -105,68 +110,149 @@ public class GpsServiceImpl implements IGpsService {
|
|||
List<String> deleteKeys = new ArrayList<>();
|
||||
BulkRequest bulkRequest = new BulkRequest();
|
||||
for (EsGpsInfoVO2 info : list) {
|
||||
if(StringUtils.isBlank(info.getInfoSource())){
|
||||
logger.info("infoSource 为空");
|
||||
|
||||
//设置地市zzjgdm
|
||||
info = getInfo(info);
|
||||
if (Objects.isNull(info)) {
|
||||
logger.error("redis中的Object=null,deviceType={},deviceCode={}",info.getDeviceType(),info.getDeviceCode());
|
||||
continue;
|
||||
}
|
||||
//设置地市zzjgdm
|
||||
info = getInfoByInfoSource(info);
|
||||
//redis
|
||||
buildRedisMap(info,onlineUserDataMap,orgCodeDataMap,deleteKeys);
|
||||
// buildRedisMap(info,onlineUserDataMap,orgCodeDataMap,deleteKeys);
|
||||
// logger.error("接收数据={},deviceCode={},gpsTime={}",info,info.getDeviceCode(),info.getGpsTime());
|
||||
IndexRequest indexRequest = buildEsIndexRequest(info);
|
||||
bulkRequest.add(indexRequest);
|
||||
|
||||
// 发送到 kafka
|
||||
requestHandler.sendToKafka(info);
|
||||
//地市版本没用批量插入
|
||||
requestHandler.redisOnlineUser(info);
|
||||
}
|
||||
|
||||
requestHandler.redisOnlineUserBatch(onlineUserDataMap, RedisConstants.REDIS_ONLINE_USER_NEVER_EXPIRE);
|
||||
requestHandler.redisOnlineUserBatch(orgCodeDataMap, 600);
|
||||
// requestHandler.redisOnlineUserBatch(onlineUserDataMap, RedisConstants.REDIS_ONLINE_USER_NEVER_EXPIRE);
|
||||
// requestHandler.redisOnlineUserBatch(orgCodeDataMap, 600);
|
||||
// requestHandler.batchPut(onlineUserDataMap);
|
||||
// requestHandler.batchPutWithExpire(orgCodeDataMap,600);
|
||||
requestHandler.redisDeleteBatch(deleteKeys);
|
||||
// requestHandler.redisDeleteBatch(deleteKeys);
|
||||
|
||||
requestHandler.esRealBulkSave(bulkRequest);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public R saveData(EsGpsInfoVO2 info) throws ExecutionException, InterruptedException{
|
||||
//设置地市zzjgdm
|
||||
info = getInfo(info);
|
||||
IndexRequest indexRequest = buildEsIndexRequest(info);
|
||||
//存es
|
||||
CompletableFuture<EsGpsInfo> esFuture = doRequest(info);
|
||||
|
||||
/**
|
||||
* 获取基本信息(主要是组织机构) 不查库 否者对库压力过大
|
||||
* @param esGpsInfo
|
||||
* @return
|
||||
*/
|
||||
private EsGpsInfoVO2 getInfoByInfoSource(EsGpsInfo esGpsInfo) {
|
||||
EsGpsInfoVO2 esGpsInfoVO2 = new EsGpsInfoVO2();
|
||||
BeanUtil.copyProperties(esGpsInfo,esGpsInfoVO2);
|
||||
JSONObject object = RedisUtils.getBucket("deviceInfo:"+esGpsInfo.getInfoSource()+":"+esGpsInfo.getDeviceCode());
|
||||
// RemoteDeviceVo vo = deviceService.getDeviceInfo(esGpsInfoVO2.getDeviceCode(),esGpsInfoVO2.getInfoSource());
|
||||
if (null != object){
|
||||
RemoteDeviceVo vo = BeanUtil.toBean(object,RemoteDeviceVo.class);
|
||||
esGpsInfoVO2.setZzjgdm(vo.getZzjgdm());
|
||||
esGpsInfoVO2.setZzjgmc(vo.getZzjgmc());
|
||||
esGpsInfoVO2.setPoliceName(vo.getPoliceName());
|
||||
esGpsInfoVO2.setPoliceNo(vo.getPoliceNo());
|
||||
esGpsInfoVO2.setCarNum(vo.getCarNum());
|
||||
String deviceType = vo.getDeviceType();
|
||||
if(StringUtils.isNotBlank(deviceType)){
|
||||
deviceType = deviceType.replaceAll("\"", "");
|
||||
if(deviceType.charAt(0) == '0' && deviceType.length() > 1){
|
||||
deviceType = deviceType.substring(1);
|
||||
if(deviceType.equals("1")){
|
||||
deviceType = "2";
|
||||
}
|
||||
}
|
||||
// 发送到 kafka
|
||||
requestHandler.sendToKafka(info);
|
||||
//地市版本没用批量插入
|
||||
requestHandler.redisOnlineUser(info);
|
||||
//发送到勤务
|
||||
storeDataService.saveDataByPersonType(info);
|
||||
|
||||
CompletableFuture.allOf(esFuture);
|
||||
EsGpsInfo esGpsInfo1 = esFuture.get();
|
||||
if(Objects.isNull(esGpsInfo1)){
|
||||
return R.fail(-1,"保存失败");
|
||||
}else{
|
||||
return R.ok("保存成功");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public R updateOnlineStatusBatch(List<EsGpsInfoVO2> list) {
|
||||
logger.error("下线设备数量={}",list.size());
|
||||
int num = 0;
|
||||
for (EsGpsInfo originEsGpsInfo : list) {
|
||||
String deviceCode = originEsGpsInfo.getDeviceCode();
|
||||
String deviceType = originEsGpsInfo.getDeviceType();
|
||||
// DeviceEntityV2 de = deviceService.checkDeviceExists(info);
|
||||
Object o = RedisUtils.getBucket(RedisConstants.ONLINE_USERS + deviceType+":" + deviceCode);
|
||||
if (Objects.isNull(o)) {
|
||||
logger.error("redis中的Object=null,deviceType={},deviceCode={}",deviceType,deviceCode);
|
||||
continue;
|
||||
}
|
||||
esGpsInfoVO2.setDeviceType(deviceType);
|
||||
}else {
|
||||
esGpsInfoVO2.setDeviceType("99");
|
||||
esGpsInfoVO2.setZzjgdm(esGpsInfo.getInfoSource()+"00000000");
|
||||
JSONObject o1 = (JSONObject) o;
|
||||
String json = o1.toJSONString();
|
||||
EsGpsInfoVO2 esGpsInfoVO2 = JSON.parseObject(json, EsGpsInfoVO2.class);
|
||||
//更新在线状态和时间,经纬度不变
|
||||
esGpsInfoVO2.setOnline(originEsGpsInfo.getOnline());
|
||||
|
||||
if(!Objects.isNull(originEsGpsInfo.getGpsTime())) {
|
||||
esGpsInfoVO2.setGpsTime(originEsGpsInfo.getGpsTime());
|
||||
}
|
||||
|
||||
EsGpsInfoVO2 esGpsInfo = new EsGpsInfoVO2();
|
||||
esGpsInfo.setOnline(esGpsInfoVO2.getOnline());
|
||||
esGpsInfo.setGpsTime(esGpsInfoVO2.getGpsTime());
|
||||
esGpsInfo.setLat(esGpsInfoVO2.getLat());
|
||||
esGpsInfo.setLng(esGpsInfoVO2.getLng());
|
||||
esGpsInfo.setHeight(esGpsInfoVO2.getHeight());
|
||||
esGpsInfo.setDeltaH(esGpsInfoVO2.getDeltaH());
|
||||
esGpsInfo.setOrientation(esGpsInfoVO2.getOrientation());
|
||||
esGpsInfo.setSpeed(esGpsInfoVO2.getSpeed());
|
||||
esGpsInfo.setDeviceType(esGpsInfoVO2.getDeviceType());
|
||||
esGpsInfo.setDeviceCode(esGpsInfoVO2.getDeviceCode());
|
||||
try {
|
||||
saveData(esGpsInfo);
|
||||
num++;
|
||||
// storeDataService.saveDataByPersonType(esGpsInfo);
|
||||
} catch (Exception e) {
|
||||
num--;
|
||||
logger.error(e.getMessage());
|
||||
// return response.error(500,e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
logger.error("update status,设备数量={}",num);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public R updateOnlineStatus(EsGpsInfoVO2 gpsInfoVO2) {
|
||||
String deviceCode = gpsInfoVO2.getDeviceCode();
|
||||
String deviceType = gpsInfoVO2.getDeviceType();
|
||||
// DeviceEntityV2 de = deviceService.checkDeviceExists(info);
|
||||
Object o = RedisUtils.getBucket(RedisConstants.ONLINE_USERS + deviceType + ":" + deviceCode);
|
||||
if (Objects.isNull(o)) {
|
||||
logger.error("redis中的Object=null,deviceType={},deviceCode={}", deviceType, deviceCode);
|
||||
return null;
|
||||
}
|
||||
JSONObject o1 = (JSONObject) o;
|
||||
String json = o1.toJSONString();
|
||||
EsGpsInfoVO2 esGpsInfoVO2 = JSON.parseObject(json, EsGpsInfoVO2.class);
|
||||
//更新在线状态和时间,经纬度不变
|
||||
esGpsInfoVO2.setOnline(gpsInfoVO2.getOnline());
|
||||
|
||||
if (!Objects.isNull(gpsInfoVO2.getGpsTime())) {
|
||||
esGpsInfoVO2.setGpsTime(gpsInfoVO2.getGpsTime());
|
||||
}
|
||||
|
||||
EsGpsInfoVO2 esGpsInfo = new EsGpsInfoVO2();
|
||||
esGpsInfo.setOnline(esGpsInfoVO2.getOnline());
|
||||
esGpsInfo.setGpsTime(esGpsInfoVO2.getGpsTime());
|
||||
esGpsInfo.setLat(esGpsInfoVO2.getLat());
|
||||
esGpsInfo.setLng(esGpsInfoVO2.getLng());
|
||||
esGpsInfo.setHeight(esGpsInfoVO2.getHeight());
|
||||
esGpsInfo.setDeltaH(esGpsInfoVO2.getDeltaH());
|
||||
esGpsInfo.setOrientation(esGpsInfoVO2.getOrientation());
|
||||
esGpsInfo.setSpeed(esGpsInfoVO2.getSpeed());
|
||||
esGpsInfo.setDeviceType(esGpsInfoVO2.getDeviceType());
|
||||
esGpsInfo.setDeviceCode(esGpsInfoVO2.getDeviceCode());
|
||||
try {
|
||||
return saveData(esGpsInfo);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage());
|
||||
return R.fail(e.getMessage());
|
||||
// return response.error(500,e.getMessage());
|
||||
}
|
||||
|
||||
return esGpsInfoVO2;
|
||||
}
|
||||
|
||||
private IndexRequest buildEsIndexRequest(EsGpsInfo esGpsInfo) {
|
||||
|
|
@ -179,7 +265,7 @@ public class GpsServiceImpl implements IGpsService {
|
|||
* @param
|
||||
*/
|
||||
private String checkIndexExist() {
|
||||
String todayIndexName = "rs_gpsinfo"+ LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
String todayIndexName = "gpsinfo"+ LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
CreateIndexRequest createIndexRequest ;
|
||||
if(!existsIndex(todayIndexName)){
|
||||
logger.error("进入了exist");
|
||||
|
|
@ -247,10 +333,10 @@ public class GpsServiceImpl implements IGpsService {
|
|||
double lng ;
|
||||
double lat ;
|
||||
try {
|
||||
lng = Double.parseDouble(esGpsInfo.getLongitude());
|
||||
lat = Double.parseDouble(esGpsInfo.getLatitude());
|
||||
lng = Double.parseDouble(esGpsInfo.getLng());
|
||||
lat = Double.parseDouble(esGpsInfo.getLat());
|
||||
}catch (NumberFormatException e){
|
||||
throw new MyBusinessException("经纬度转double异常,经度为:"+esGpsInfo.getLongitude() +"纬度为"+esGpsInfo.getLatitude());
|
||||
throw new MyBusinessException("经纬度转double异常,经度为:"+esGpsInfo.getLng() +"纬度为"+esGpsInfo.getLat());
|
||||
}
|
||||
|
||||
gpsInfoEntity.setLocation(new Double[]{lng,lat});
|
||||
|
|
@ -283,9 +369,7 @@ public class GpsServiceImpl implements IGpsService {
|
|||
}
|
||||
String jsonValue = JSONUtil.toJsonStr(esGpsInfoVo2);
|
||||
|
||||
String onlineUsersKey = RedisConstants.ONLINE_USERS +
|
||||
zzjgdm + ":" + deviceType +
|
||||
":" + deviceCode;
|
||||
String onlineUsersKey = RedisConstants.ONLINE_USERS + deviceType + ":" + deviceCode;
|
||||
onlineUserDataMap.put(onlineUsersKey, jsonValue);
|
||||
//todo 省厅左侧只需要展示到市级以及区县级数量,所以需要查询出该单位的上级单位进行存储。
|
||||
//如:key = "org_code:340800260000:deviceType:deviceCode 安庆交通警察支队
|
||||
|
|
@ -304,6 +388,67 @@ public class GpsServiceImpl implements IGpsService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Async
|
||||
public CompletableFuture<EsGpsInfo> doRequest(EsGpsInfoVO2 esGpsInfo){
|
||||
EsGpsInfo entity = createEntity(esGpsInfo);
|
||||
|
||||
return CompletableFuture.completedFuture(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取基本信息(主要是组织机构)
|
||||
* @param esGpsInfo
|
||||
* @return
|
||||
*/
|
||||
private EsGpsInfoVO2 getInfo(EsGpsInfo esGpsInfo) {
|
||||
RemoteDeviceVo deviceEntityV2 = new RemoteDeviceVo();
|
||||
String deviceCode = esGpsInfo.getDeviceCode();
|
||||
String deviceType = esGpsInfo.getDeviceType();
|
||||
/*if(StringUtils.isEmpty(deviceCode) || StringUtils.isEmpty(deviceType)){
|
||||
logger.error("deviceCode or deviceType = null{},{}",deviceCode,deviceType);
|
||||
return null;
|
||||
}*/
|
||||
deviceEntityV2.setDeviceCode(deviceCode);
|
||||
deviceEntityV2.setDeviceType(deviceType);
|
||||
RemoteDeviceVo deviceEntityV21 = BeanUtil.toBean(RedisUtils.getBucket("deviceInfo:" + deviceType+":"+deviceCode), RemoteDeviceVo.class) ;
|
||||
if(Objects.isNull(deviceEntityV21)){
|
||||
logger.error("库里没有这个数据,deviceCode={}",deviceCode);
|
||||
return null;
|
||||
}
|
||||
EsGpsInfoVO2 esGpsInfoVO2 = new EsGpsInfoVO2();
|
||||
BeanUtil.copyProperties(esGpsInfo,esGpsInfoVO2);
|
||||
if(!Objects.isNull(deviceEntityV21)){
|
||||
deviceType = deviceEntityV21.getDeviceType()+"";
|
||||
esGpsInfoVO2.setDeviceType(deviceEntityV21.getDeviceType()+"");
|
||||
esGpsInfoVO2.setZzjgdm(deviceEntityV21.getZzjgdm());
|
||||
esGpsInfoVO2.setZzjgmc(deviceEntityV21.getZzjgmc());
|
||||
esGpsInfoVO2.setPoliceNo(deviceEntityV21.getPoliceNo());
|
||||
esGpsInfoVO2.setPoliceName(deviceEntityV21.getPoliceName());
|
||||
esGpsInfoVO2.setCarNum(deviceEntityV21.getCarNum());
|
||||
esGpsInfoVO2.setPhoneNum(deviceEntityV21.getPhoneNum());
|
||||
}
|
||||
String lat = esGpsInfo.getLat();
|
||||
String lng = esGpsInfo.getLng();
|
||||
|
||||
//如果定位是0的话 ,则上传最后一次有定位的坐标,如果最后一次是0的话,那就上传0
|
||||
boolean nonLatLng = isNonLatLng(lat, lng);
|
||||
if(nonLatLng){
|
||||
Object o = RedisUtils.getBucket(RedisConstants.ONLINE_USERS + deviceType + ":" + deviceCode);
|
||||
if(!Objects.isNull(o)) {
|
||||
com.alibaba.fastjson.JSONObject o1 = (JSONObject) o;
|
||||
String json = o1.toJSONString();
|
||||
EsGpsInfoVO2 esGpsInfoVO3 = JSON.parseObject(json, EsGpsInfoVO2.class);
|
||||
String lat1 = esGpsInfoVO3.getLat();
|
||||
String lng1 = esGpsInfoVO3.getLng();
|
||||
esGpsInfoVO2.setLat(lat1);
|
||||
esGpsInfoVO2.setLng(lng1);
|
||||
}
|
||||
|
||||
}
|
||||
return esGpsInfoVO2;
|
||||
}
|
||||
|
||||
private void generateMappingRequest(CreateIndexRequest createIndexRequest) {
|
||||
XContentBuilder builder = null;
|
||||
try {
|
||||
|
|
@ -352,5 +497,16 @@ public class GpsServiceImpl implements IGpsService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断一个定位是否是0的方法
|
||||
* @param lat
|
||||
* @param lng
|
||||
* @return
|
||||
*/
|
||||
private boolean isNonLatLng(String lat, String lng) {
|
||||
return StringUtils.isBlank(lat) || StringUtils.isBlank(lng)
|
||||
|| "0".equals(lat) || "0".equals(lng)
|
||||
|| "0.0".equals(lat) || "0.0".equals(lng);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,238 @@
|
|||
package org.dromara.data2es.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.utils.RedisConstants;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.dromara.data2es.domain.DSQinwuEntity;
|
||||
import org.dromara.data2es.domain.EsGpsInfo;
|
||||
import org.dromara.data2es.domain.EsGpsInfoVO2;
|
||||
import org.dromara.data2es.domain.vo.EsGpsInfoVO3;
|
||||
import org.dromara.data2es.handler.RequestHandler;
|
||||
import org.dromara.data2es.mapper.DSQinwuMapper;
|
||||
import org.dromara.data2es.service.StoreDataService;
|
||||
import org.dromara.data2es.util.ConfigConstants;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-05-14 16:45
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class StoreDataServiceImpl implements StoreDataService {
|
||||
|
||||
@Autowired
|
||||
RequestHandler requestHandler;
|
||||
|
||||
|
||||
@Autowired
|
||||
private KafkaTemplate<String, String> kafkaTemplate;
|
||||
|
||||
@Autowired
|
||||
DSQinwuMapper dsQinwuDao;
|
||||
|
||||
/**
|
||||
* 从定位数据中单独列出一类数据,发送给持有该设备的人。这个关系从DS公司获取“勤务排班”关系
|
||||
* @param esGpsInfo
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R saveDataByPersonType(EsGpsInfo esGpsInfo) {
|
||||
if(Objects.isNull(esGpsInfo)){
|
||||
log.error("esGpsInfo 实体为null");
|
||||
return R.fail(500,"esGpsInfo 实体为null");
|
||||
}
|
||||
String deviceType = esGpsInfo.getDeviceType();
|
||||
//即不是PDT手台也不是执法记录仪
|
||||
if(!"3".equals(deviceType) && !"5".equals(deviceType) && !"1".equals(deviceType) && !"4".equals(deviceType)){
|
||||
//log.error("不是记录仪或者手台,不需要处理,deviceType={}",deviceType);
|
||||
return R.fail(200,"type not 1 3 4 5,deviceType="+deviceType);
|
||||
}
|
||||
//获取勤务排班信息
|
||||
EsGpsInfoVO3 info = getInfo(esGpsInfo);
|
||||
if(Objects.isNull(info)){
|
||||
log.error("未找到勤务排班信息,deviceCode={},deviceType={}",esGpsInfo.getDeviceCode(),esGpsInfo.getDeviceType());
|
||||
return R.fail(500,"未找到勤务排班信息,deviceCode={}"+esGpsInfo.getDeviceCode());
|
||||
}
|
||||
|
||||
//发送到kafka
|
||||
kafkaTemplate.send( ConfigConstants.KAFKA_TOPIC_SEND_PRE+"."+info.getDeviceType(), JSON.toJSONString(info));
|
||||
//存入到redis
|
||||
requestHandler.redisOnlineUserByPerson(info);
|
||||
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public R saveDataByPersonTypeBatch(List<EsGpsInfoVO2> list) throws InvocationTargetException, IllegalAccessException, ExecutionException, InterruptedException {
|
||||
for (EsGpsInfo esGpsInfo : list) {
|
||||
saveDataByPersonType(esGpsInfo);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取勤务排班信息
|
||||
* @param esGpsInfo
|
||||
* @return
|
||||
*/
|
||||
private EsGpsInfoVO3 getInfo(EsGpsInfo esGpsInfo) {
|
||||
EsGpsInfoVO3 esGpsInfoVO3 = new EsGpsInfoVO3();
|
||||
BeanUtil.copyProperties(esGpsInfo, esGpsInfoVO3);
|
||||
/**
|
||||
* 1、如果记录仪有数据,就以记录仪的为准,pdt的数据过来了,就忽略
|
||||
* 2、如果记录仪没数据,就以pdt的为准
|
||||
*/
|
||||
String deviceType = esGpsInfo.getDeviceType();
|
||||
if("5".equals(deviceType)){
|
||||
EsGpsInfoVO3 zfjly = setVO3(esGpsInfo.getDeviceCode(), "ZFJLY", esGpsInfoVO3);
|
||||
if(!Objects.isNull(zfjly)) {
|
||||
// zfjly.setTypeOfDevice("5");
|
||||
if ("XLC".equals(zfjly.getTypeOfDevice())){
|
||||
zfjly.setTypeOfDevice("8");
|
||||
}else if ("BKQ".equals(zfjly.getTypeOfDevice())){
|
||||
zfjly.setTypeOfDevice("7");
|
||||
}else {
|
||||
zfjly.setTypeOfDevice("5");
|
||||
}
|
||||
}
|
||||
return zfjly;
|
||||
}
|
||||
if("3".equals(deviceType)){
|
||||
//pdt设备
|
||||
EsGpsInfoVO3 pdt = setVO3(esGpsInfo.getDeviceCode(), "PDT", esGpsInfoVO3);
|
||||
if(!Objects.isNull(pdt)) {
|
||||
pdt.setTypeOfDevice("3");
|
||||
}
|
||||
return pdt;
|
||||
}
|
||||
if("1".equals(deviceType)){
|
||||
//pdt设备
|
||||
EsGpsInfoVO3 djj = setVO3(esGpsInfo.getDeviceCode(), "DJJ", esGpsInfoVO3);
|
||||
if(!Objects.isNull(djj)) {
|
||||
djj.setTypeOfDevice("1");
|
||||
}
|
||||
return djj;
|
||||
}
|
||||
if("4".equals(deviceType)){
|
||||
//警务通设备
|
||||
EsGpsInfoVO3 pdt = setVO3(esGpsInfo.getDeviceCode(), "JWT", esGpsInfoVO3);
|
||||
if(!Objects.isNull(pdt)) {
|
||||
pdt.setTypeOfDevice("4");
|
||||
}
|
||||
return pdt;
|
||||
}
|
||||
/*if("2".equals(deviceType)){
|
||||
//北斗设备
|
||||
EsGpsInfoVO3 pdt = setVO3(esGpsInfo.getDeviceCode(), "XLC", esGpsInfoVO3);
|
||||
if(!Objects.isNull(pdt)) {
|
||||
pdt.setTypeOfDevice("2");
|
||||
}
|
||||
return pdt;
|
||||
}
|
||||
*/
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private EsGpsInfoVO3 setVO3(String deviceCode,String deviceType, EsGpsInfoVO3 esGpsInfoVO3) {
|
||||
LambdaQueryWrapper<DSQinwuEntity> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(DSQinwuEntity::getImei,deviceCode);
|
||||
if (!"ZFJLY".equals(deviceType)){
|
||||
lqw.eq(DSQinwuEntity::getType,deviceType);
|
||||
}
|
||||
DSQinwuEntity dsQinwuEntity = dsQinwuDao.selectOne(lqw);
|
||||
if(Objects.isNull(dsQinwuEntity)){
|
||||
return null;
|
||||
}
|
||||
if ("PDT".equals(deviceType) && jlyLatLng(dsQinwuEntity) && jwtLatLng(dsQinwuEntity)){
|
||||
log.error("该警员记录仪或警务通设备最近有坐标回传,警号={}",dsQinwuEntity.getPoliceNumber());
|
||||
return null;
|
||||
}
|
||||
if ("JWT".equals(deviceType) && jlyLatLng(dsQinwuEntity)){
|
||||
log.error("该警员记录仪设备最近有坐标回传,警号={}",dsQinwuEntity.getPoliceNumber());
|
||||
return null;
|
||||
}
|
||||
esGpsInfoVO3.setPoliceName(dsQinwuEntity.getPoliceName());
|
||||
if ("XLC".equals(dsQinwuEntity.getType())){
|
||||
esGpsInfoVO3.setCarNum(dsQinwuEntity.getName());
|
||||
}
|
||||
esGpsInfoVO3.setZzjgdm(dsQinwuEntity.getOrgId());
|
||||
esGpsInfoVO3.setZzjgmc(dsQinwuEntity.getOrgName());
|
||||
//ds勤务绑定系统的id,对于其他系统来说可不用
|
||||
esGpsInfoVO3.setLinkId(dsQinwuEntity.getLinkId());
|
||||
//最后设置为101,即勤务需要的deviceType
|
||||
esGpsInfoVO3.setDeviceType("9");
|
||||
esGpsInfoVO3.setTypeOfDevice(dsQinwuEntity.getType());
|
||||
|
||||
esGpsInfoVO3.setPoliceNo(dsQinwuEntity.getPoliceNumber());
|
||||
return esGpsInfoVO3;
|
||||
}
|
||||
|
||||
private boolean jlyLatLng(DSQinwuEntity dsQinwuEntity){
|
||||
LambdaQueryWrapper<DSQinwuEntity> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(DSQinwuEntity::getPoliceNumber,dsQinwuEntity.getPoliceNumber());
|
||||
lqw.eq(DSQinwuEntity::getType,"ZFJLY");
|
||||
lqw.orderByDesc(DSQinwuEntity::getUpdateTime).last("limit 1");
|
||||
|
||||
DSQinwuEntity qinwu = dsQinwuDao.selectOne(lqw);
|
||||
if (null == qinwu){
|
||||
return false;
|
||||
}
|
||||
Object obj = RedisUtils.getBucket(RedisConstants.ONLINE_USERS + "9:" + qinwu.getImei());
|
||||
if (null == obj){
|
||||
return false;
|
||||
}else {
|
||||
// 如需按照gps最新时间来判断 可在这添加逻辑
|
||||
|
||||
EsGpsInfoVO3 esGpsInfoVO3 = BeanUtil.toBean(obj.toString(),EsGpsInfoVO3.class);
|
||||
if (DateUtil.between(new Date(),esGpsInfoVO3.getGpsTime(), DateUnit.SECOND)>120){
|
||||
return false;
|
||||
}else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean jwtLatLng(DSQinwuEntity dsQinwuEntity){
|
||||
LambdaQueryWrapper<DSQinwuEntity> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(DSQinwuEntity::getPoliceNumber,dsQinwuEntity.getPoliceNumber());
|
||||
lqw.eq(DSQinwuEntity::getType,"JWT");
|
||||
lqw.orderByDesc(DSQinwuEntity::getUpdateTime).last("limit 1");
|
||||
|
||||
DSQinwuEntity qinwu = dsQinwuDao.selectOne(lqw);
|
||||
if (null == qinwu){
|
||||
return false;
|
||||
}
|
||||
Object obj = RedisUtils.getBucket(RedisConstants.ONLINE_USERS + "9:" + qinwu.getImei());
|
||||
if (null == obj){
|
||||
return false;
|
||||
}else {
|
||||
EsGpsInfoVO3 esGpsInfoVO3 = BeanUtil.toBean(obj.toString(),EsGpsInfoVO3.class);
|
||||
if (DateUtil.between(new Date(),esGpsInfoVO3.getGpsTime(), DateUnit.SECOND)>120){
|
||||
return false;
|
||||
}else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,5 +3,5 @@ package org.dromara.data2es.util;
|
|||
public class ConfigConstants {
|
||||
public static final String HTTP_HEADER_AUTH_TOKEN = "Auth-Token";
|
||||
|
||||
public static final String KAFKA_TOPIC_SEND_PRE = "rs_topic.send";
|
||||
public static final String KAFKA_TOPIC_SEND_PRE = "topic.send";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ server:
|
|||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: stwzhj-data2es
|
||||
name: wzhj-data2es
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: @profiles.active@
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
package org.dromara.data2gs.service;
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
package org.dromara.location.controller;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
|
|
@ -14,6 +16,7 @@ import org.dromara.system.api.domain.vo.RemoteDeviceVo;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
|
@ -32,6 +35,11 @@ public class LocationController {
|
|||
@DubboReference
|
||||
private RemoteDeviceService deviceService;
|
||||
|
||||
|
||||
//判断回传离当前多少秒
|
||||
@Value("${location.pointtime}")
|
||||
private Integer pointTime;
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(LocationController.class);
|
||||
|
||||
|
||||
|
|
@ -47,6 +55,10 @@ public class LocationController {
|
|||
key = keys +"*";
|
||||
}
|
||||
List<JSONObject> list = new ArrayList<>();
|
||||
String times = ""; //用来判断是否需要最新数据
|
||||
if (null != params.get("times")){
|
||||
times = params.get("times").toString();
|
||||
}
|
||||
if (null != params.get("type")){
|
||||
String type = params.get("type").toString();
|
||||
key = keys + "*:[" +type+"]:*";
|
||||
|
|
@ -54,9 +66,23 @@ public class LocationController {
|
|||
key = keys + params.get("deptId").toString() + "*:["+type+"]:*"; // key值为 online_users:2022-04-20:3401*:[01,02]:*
|
||||
}
|
||||
|
||||
}else {
|
||||
key = keys +"*";
|
||||
}
|
||||
list = RedisUtils.searchAndGetKeysValues(key);
|
||||
list.removeAll(Collections.singleton(null));
|
||||
if ("1".equals(times)){
|
||||
List<Object> nearList = new ArrayList<>();
|
||||
for (Object o : list) {
|
||||
JSONObject object = JSONUtil.parseObj(o);
|
||||
Integer online = object.getInt("online");
|
||||
Long gpstime = object.getLong("gpsTime");
|
||||
if (1 == online && DateUtil.between(new Date(gpstime),new Date(), DateUnit.SECOND)<pointTime){
|
||||
nearList.add(o);
|
||||
}
|
||||
}
|
||||
return R.ok(nearList);
|
||||
}
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
|
|
@ -66,6 +92,10 @@ public class LocationController {
|
|||
if(CollectionUtils.isEmpty(params)){
|
||||
return R.fail("参数不能为空");
|
||||
}
|
||||
String times = ""; //用来判断是否需要最新数据
|
||||
if (null != params.get("times")){
|
||||
times = params.get("times").toString();
|
||||
}
|
||||
String zzjgdms = "";
|
||||
List<Object> dlist = new ArrayList<>();
|
||||
if (null != params.get("type")){ //类型不为空时 查询Redis数据
|
||||
|
|
@ -92,6 +122,18 @@ public class LocationController {
|
|||
}
|
||||
}
|
||||
JSONArray.toJSONString(dlist);
|
||||
if ("1".equals(times)){
|
||||
List<Object> nearList = new ArrayList<>();
|
||||
for (Object o : dlist) {
|
||||
JSONObject object = JSONUtil.parseObj(o);
|
||||
Integer online = object.getInt("online");
|
||||
Long gpstime = object.getLong("gpsTime");
|
||||
if (1 == online && DateUtil.between(new Date(gpstime),new Date(), DateUnit.SECOND)<pointTime){
|
||||
nearList.add(o);
|
||||
}
|
||||
}
|
||||
return R.ok(nearList);
|
||||
}
|
||||
return R.ok(dlist);
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +243,26 @@ public class LocationController {
|
|||
|
||||
}
|
||||
|
||||
@PostMapping("/getTdeviceList")
|
||||
public R getTdeviceList(@RequestBody Map<String,Object> params){
|
||||
if(CollectionUtils.isEmpty(params)){
|
||||
return R.fail(-1,"参数不能为空");
|
||||
}
|
||||
RemoteDeviceBo device = new RemoteDeviceBo();
|
||||
device.setValid(1);
|
||||
if (null != params.get("deviceType")){
|
||||
device.setDeviceType(params.get("deviceType").toString());
|
||||
}
|
||||
if (null != params.get("zzjgdm") && !"341800000000".equals(params.get("zzjgdm").toString())){
|
||||
String[] zzjgdms = params.get("zzjgdm").toString().split(",");
|
||||
device.setZzjgdms(zzjgdms);
|
||||
}
|
||||
|
||||
List<RemoteDeviceVo> list = deviceService.deviceList(device);
|
||||
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
|
||||
public String deptIdSub(String zzjgdm){
|
||||
if (zzjgdm.endsWith("0000000000")){ // 省厅 即全部
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ server:
|
|||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: stwzhj-location
|
||||
name: wzhj-location
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: @profiles.active@
|
||||
|
|
|
|||
|
|
@ -127,6 +127,18 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<!--配置不需要压缩的文件-->
|
||||
<nonFilteredFileExtensions>
|
||||
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>xls</nonFilteredFileExtension>
|
||||
</nonFilteredFileExtensions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ import org.dromara.common.core.domain.R;
|
|||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.system.api.model.LoginUser;
|
||||
import org.dromara.system.domain.SysUser;
|
||||
import org.dromara.system.domain.bo.SysDeptBo;
|
||||
import org.dromara.system.domain.vo.SysDeptVo;
|
||||
import org.dromara.system.service.ISysDeptService;
|
||||
|
|
@ -44,7 +47,8 @@ public class SysDeptController extends BaseController {
|
|||
|
||||
@GetMapping("/deviceDept/{deviceType}")
|
||||
public R<List<SysDeptVo>> deviceDpet(@PathVariable(value = "deviceType", required = false) String deviceType) {
|
||||
List<SysDeptVo> depts = deptService.deviceStatics(deviceType);
|
||||
LoginUser user = LoginHelper.getLoginUser();
|
||||
List<SysDeptVo> depts = deptService.deviceStatics(deviceType,user.getManageDeptId());
|
||||
return R.ok(depts);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class SysUserController extends BaseController {
|
|||
@PostMapping("/export")
|
||||
public void export(SysUserBo user, HttpServletResponse response) {
|
||||
List<SysUserExportVo> list = userService.selectUserExportList(user);
|
||||
ExcelUtil.exportExcel(list, "用户数据", SysUserExportVo.class, response);
|
||||
ExcelUtil.exportExcel(list, "user", SysUserExportVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
package org.dromara.system.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import org.dromara.common.excel.core.ExcelResult;
|
||||
import org.dromara.system.domain.vo.SysUserImportVo;
|
||||
import org.dromara.system.domain.vo.TDeviceExportVo;
|
||||
import org.dromara.system.domain.vo.TDeviceImportVo;
|
||||
import org.dromara.system.listener.SysUserImportListener;
|
||||
import org.dromara.system.listener.TDeviceImportListener;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
|
|
@ -21,6 +29,7 @@ import org.dromara.system.domain.vo.TDeviceVo;
|
|||
import org.dromara.system.domain.bo.TDeviceBo;
|
||||
import org.dromara.system.service.ITDeviceService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* device
|
||||
|
|
@ -53,8 +62,32 @@ public class TDeviceController extends BaseController {
|
|||
@Log(title = "device", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(TDeviceBo bo, HttpServletResponse response) {
|
||||
List<TDeviceVo> list = tDeviceService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "device", TDeviceVo.class, response);
|
||||
List<TDeviceExportVo> list = tDeviceService.selectDeviceExportList(bo);
|
||||
ExcelUtil.exportExcel(list, "device", TDeviceExportVo.class, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取导入模板
|
||||
*/
|
||||
@PostMapping("/importTemplate")
|
||||
public void importTemplate(HttpServletResponse response) {
|
||||
ExcelUtil.exportExcel(new ArrayList<>(), "设备数据", TDeviceImportVo.class, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导入数据
|
||||
*
|
||||
* @param file 导入文件
|
||||
* @param updateSupport 是否更新已存在数据
|
||||
*/
|
||||
@Log(title = "设备管理", businessType = BusinessType.IMPORT)
|
||||
@SaCheckPermission("system:device:import")
|
||||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
|
||||
ExcelResult<TDeviceImportVo> result = ExcelUtil.importExcel(file.getInputStream(), TDeviceImportVo.class, new TDeviceImportListener(updateSupport));
|
||||
return R.ok(result.getAnalysis());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -77,4 +77,6 @@ public class SysDept extends TenantEntity {
|
|||
*/
|
||||
private String ancestors;
|
||||
|
||||
private String fullName;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,8 @@ public class SysUser extends TenantEntity {
|
|||
*/
|
||||
private String remark;
|
||||
|
||||
private String manageDeptId;
|
||||
|
||||
|
||||
public SysUser(Long userId) {
|
||||
this.userId = userId;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ public class TDevice {
|
|||
/**
|
||||
* 外部系统设备编号建议21位
|
||||
*/
|
||||
@MppMultiId
|
||||
private String deviceCode;
|
||||
|
||||
/**
|
||||
|
|
@ -38,12 +37,6 @@ public class TDevice {
|
|||
*/
|
||||
private String deviceType;
|
||||
|
||||
private String sbpp;
|
||||
|
||||
private String sbxh;
|
||||
|
||||
@MppMultiId
|
||||
private String infoSource;
|
||||
|
||||
/**
|
||||
* 组织机构代码
|
||||
|
|
@ -92,25 +85,11 @@ public class TDevice {
|
|||
*/
|
||||
private String remark2;
|
||||
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createTime;
|
||||
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateTime;
|
||||
|
||||
private String lrdwdm;
|
||||
|
||||
private String lrdwmc;
|
||||
|
||||
private String lrrxm;
|
||||
|
||||
private String lrrsfzh;
|
||||
|
||||
private String xgdwdm;
|
||||
|
||||
private String xgdwmc;
|
||||
|
||||
private String xgrxm;
|
||||
|
||||
private String xgrsfzh;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,4 +73,6 @@ public class SysDeptBo extends BaseEntity {
|
|||
*/
|
||||
private String status;
|
||||
|
||||
private String fullName;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,6 +108,8 @@ public class SysUserBo extends BaseEntity {
|
|||
*/
|
||||
private String excludeUserIds;
|
||||
|
||||
private String manageDeptId;
|
||||
|
||||
public SysUserBo(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ public class TDeviceBo extends BaseEntity {
|
|||
@NotBlank(message = "设备编号不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String deviceCode;
|
||||
|
||||
@NotBlank(message = "地市编码不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String infoSource;
|
||||
|
||||
/**
|
||||
|
|
@ -93,21 +92,8 @@ public class TDeviceBo extends BaseEntity {
|
|||
*/
|
||||
private String remark2;
|
||||
|
||||
private String lrdwdm;
|
||||
private String[] zzjgdms;
|
||||
|
||||
private String lrdwmc;
|
||||
|
||||
private String lrrxm;
|
||||
|
||||
private String lrrsfzh;
|
||||
|
||||
private String xgdwdm;
|
||||
|
||||
private String xgdwmc;
|
||||
|
||||
private String xgrxm;
|
||||
|
||||
private String xgrsfzh;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,8 +99,10 @@ public class SysDeptVo implements Serializable {
|
|||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
private Integer co;
|
||||
private Integer allCount;
|
||||
|
||||
private String online;
|
||||
private Integer onlineCount;
|
||||
|
||||
private String fullName;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ public class SysUserVo implements Serializable {
|
|||
*/
|
||||
private Date createTime;
|
||||
|
||||
private String manageDeptId;
|
||||
/**
|
||||
* 部门名
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
package org.dromara.system.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class TDeviceExportVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ExcelProperty(value = "设备编号")
|
||||
private String deviceCode;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
@ExcelProperty(value = "设备类型")
|
||||
@ExcelDictFormat(dictType = "zd_device_type")
|
||||
private String deviceType;
|
||||
|
||||
/**
|
||||
* 组织机构代码
|
||||
*/
|
||||
@ExcelProperty(value = "组织机构代码")
|
||||
private String zzjgdm;
|
||||
|
||||
/**
|
||||
* 组织机构名称
|
||||
*/
|
||||
@ExcelProperty(value = "组织机构名称")
|
||||
private String zzjgmc;
|
||||
|
||||
/**
|
||||
* 警号(若有)
|
||||
*/
|
||||
@ExcelProperty(value = "警号", converter = ExcelDictConvert.class)
|
||||
private String policeNo;
|
||||
|
||||
/**
|
||||
* 姓名(若有)
|
||||
*/
|
||||
@ExcelProperty(value = "警员姓名", converter = ExcelDictConvert.class)
|
||||
private String policeName;
|
||||
|
||||
/**
|
||||
* 联系电话(若有)
|
||||
*/
|
||||
@ExcelProperty(value = "电话号码", converter = ExcelDictConvert.class)
|
||||
private String phoneNum;
|
||||
|
||||
/**
|
||||
* 车牌号(若有)
|
||||
*/
|
||||
@ExcelProperty(value = "车牌号", converter = ExcelDictConvert.class)
|
||||
private String carNum;
|
||||
|
||||
@ExcelProperty(value = "证件号码", converter = ExcelDictConvert.class)
|
||||
private String cardNum;
|
||||
|
||||
/**
|
||||
* 0无效,1有效
|
||||
*/
|
||||
@ExcelProperty(value = "有效性")
|
||||
@ExcelDictFormat(readConverterExp = "1=有效,0=无效")
|
||||
private Integer valid;
|
||||
|
||||
/**
|
||||
* 备注字段1
|
||||
*/
|
||||
@ExcelProperty(value = "备注字段1")
|
||||
private String remark1;
|
||||
|
||||
/**
|
||||
* 备注字段2
|
||||
*/
|
||||
@ExcelProperty(value = "备注字段2")
|
||||
private String remark2;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package org.dromara.system.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class TDeviceImportVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ExcelProperty(value = "设备编号")
|
||||
private String deviceCode;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
@ExcelProperty(value = "设备类型", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "zd_device_type")
|
||||
private String deviceType;
|
||||
|
||||
/**
|
||||
* 组织机构代码
|
||||
*/
|
||||
@ExcelProperty(value = "组织机构代码")
|
||||
private String zzjgdm;
|
||||
|
||||
/**
|
||||
* 组织机构名称
|
||||
*/
|
||||
@ExcelProperty(value = "组织机构名称")
|
||||
private String zzjgmc;
|
||||
|
||||
/**
|
||||
* 警号(若有)
|
||||
*/
|
||||
@ExcelProperty(value = "警号")
|
||||
private String policeNo;
|
||||
|
||||
/**
|
||||
* 姓名(若有)
|
||||
*/
|
||||
@ExcelProperty(value = "警员姓名")
|
||||
private String policeName;
|
||||
|
||||
/**
|
||||
* 联系电话(若有)
|
||||
*/
|
||||
@ExcelProperty(value = "电话号码")
|
||||
private String phoneNum;
|
||||
|
||||
/**
|
||||
* 车牌号(若有)
|
||||
*/
|
||||
@ExcelProperty(value = "车牌号")
|
||||
private String carNum;
|
||||
|
||||
@ExcelProperty(value = "证件号码")
|
||||
private String cardNum;
|
||||
|
||||
/**
|
||||
* 0无效,1有效
|
||||
*/
|
||||
@ExcelProperty(value = "有效性", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(dictType = "zd_device_status")
|
||||
private String valid;
|
||||
|
||||
/**
|
||||
* 备注字段1
|
||||
*/
|
||||
@ExcelProperty(value = "备注字段1")
|
||||
private String remark1;
|
||||
|
||||
/**
|
||||
* 备注字段2
|
||||
*/
|
||||
@ExcelProperty(value = "备注字段2")
|
||||
private String remark2;
|
||||
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ public class TDeviceVo implements Serializable {
|
|||
/**
|
||||
* 外部系统设备编号建议21位
|
||||
*/
|
||||
@ExcelProperty(value = "外部系统设备编号建议21位")
|
||||
@ExcelProperty(value = "设备编码")
|
||||
private String deviceCode;
|
||||
|
||||
// 警号、姓名、车牌号组合字段
|
||||
|
|
@ -49,13 +49,6 @@ public class TDeviceVo implements Serializable {
|
|||
@ExcelProperty(value = "设备类型")
|
||||
private String deviceType;
|
||||
|
||||
|
||||
private String sbpp;
|
||||
|
||||
private String sbxh;
|
||||
|
||||
private String infoSource;
|
||||
|
||||
/**
|
||||
* 组织机构代码
|
||||
*/
|
||||
|
|
@ -121,21 +114,4 @@ public class TDeviceVo implements Serializable {
|
|||
|
||||
private String updateTime;
|
||||
|
||||
private String lrdwdm;
|
||||
|
||||
private String lrdwmc;
|
||||
|
||||
private String lrrxm;
|
||||
|
||||
private String lrrsfzh;
|
||||
|
||||
private String xgdwdm;
|
||||
|
||||
private String xgdwmc;
|
||||
|
||||
private String xgrxm;
|
||||
|
||||
private String xgrsfzh;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
package org.dromara.system.dubbo;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import org.dromara.system.api.RemoteDeptService;
|
||||
import org.dromara.system.api.domain.bo.RemoteDeptBo;
|
||||
import org.dromara.system.api.domain.vo.RemoteDeptVo;
|
||||
import org.dromara.system.domain.bo.SysDeptBo;
|
||||
import org.dromara.system.domain.vo.SysDeptVo;
|
||||
import org.dromara.system.service.ISysDeptService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门服务
|
||||
*
|
||||
|
|
@ -28,4 +36,10 @@ public class RemoteDeptServiceImpl implements RemoteDeptService {
|
|||
public String selectDeptNameByIds(String deptIds) {
|
||||
return sysDeptService.selectDeptNameByIds(deptIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RemoteDeptVo> selectDept(RemoteDeptBo bo) {
|
||||
List<SysDeptVo> vos = sysDeptService.selectDeptList(BeanUtil.toBean(bo, SysDeptBo.class));
|
||||
return BeanUtil.copyToList(vos, RemoteDeptVo.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,6 +253,7 @@ public class RemoteUserServiceImpl implements RemoteUserService {
|
|||
loginUser.setTenantId(userVo.getTenantId());
|
||||
loginUser.setUserId(userVo.getUserId());
|
||||
loginUser.setDeptId(userVo.getDeptId());
|
||||
loginUser.setManageDeptId(userVo.getManageDeptId());
|
||||
loginUser.setUsername(userVo.getUserName());
|
||||
loginUser.setNickname(userVo.getNickName());
|
||||
loginUser.setPassword(userVo.getPassword());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
package org.dromara.system.listener;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.event.AnalysisEventListener;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.core.utils.ValidatorUtils;
|
||||
import org.dromara.common.excel.core.ExcelListener;
|
||||
import org.dromara.common.excel.core.ExcelResult;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.system.domain.bo.TDeviceBo;
|
||||
import org.dromara.system.domain.vo.TDeviceImportVo;
|
||||
import org.dromara.system.domain.vo.TDeviceVo;
|
||||
import org.dromara.system.service.ITDeviceService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class TDeviceImportListener extends AnalysisEventListener<TDeviceImportVo> implements ExcelListener<TDeviceImportVo> {
|
||||
|
||||
private final ITDeviceService deviceService;
|
||||
|
||||
private final Boolean isUpdateSupport;
|
||||
|
||||
|
||||
private int successNum = 0;
|
||||
private int failureNum = 0;
|
||||
private final StringBuilder successMsg = new StringBuilder();
|
||||
private final StringBuilder failureMsg = new StringBuilder();
|
||||
|
||||
public TDeviceImportListener(Boolean isUpdateSupport) {
|
||||
this.deviceService = SpringUtils.getBean(ITDeviceService.class);
|
||||
this.isUpdateSupport = isUpdateSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(TDeviceImportVo deviceImportVo, AnalysisContext context) {
|
||||
TDeviceVo deviceVo = this.deviceService.queryByDeviceCode(deviceImportVo.getDeviceCode());
|
||||
try {
|
||||
// 验证是否存在这个设备
|
||||
if (ObjectUtil.isNull(deviceVo)) {
|
||||
TDeviceBo deviceBo = BeanUtil.toBean(deviceImportVo, TDeviceBo.class);
|
||||
ValidatorUtils.validate(deviceBo);
|
||||
deviceService.insertByBo(deviceBo);
|
||||
successNum++;
|
||||
successMsg.append("<br/>").append(successNum).append("、设备 ").append(deviceBo.getDeviceCode()).append(" 导入成功");
|
||||
} else if (isUpdateSupport) {
|
||||
Long id = deviceVo.getId();
|
||||
TDeviceBo deviceBo = BeanUtil.toBean(deviceVo, TDeviceBo.class);
|
||||
deviceBo.setId(id);
|
||||
ValidatorUtils.validate(deviceBo);
|
||||
deviceService.updateByBo(deviceBo);
|
||||
successNum++;
|
||||
successMsg.append("<br/>").append(successNum).append("、设备 ").append(deviceImportVo.getDeviceCode()).append(" 更新成功");
|
||||
} else {
|
||||
failureNum++;
|
||||
failureMsg.append("<br/>").append(failureNum).append("、设备 ").append(deviceImportVo.getDeviceCode()).append(" 已存在");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failureNum++;
|
||||
String msg = "<br/>" + failureNum + "、设备 " + HtmlUtil.cleanHtmlTag(deviceImportVo.getDeviceCode()) + " 导入失败:";
|
||||
String message = e.getMessage();
|
||||
if (e instanceof ConstraintViolationException cvException) {
|
||||
message = StreamUtils.join(cvException.getConstraintViolations(), ConstraintViolation::getMessage, ", ");
|
||||
}
|
||||
failureMsg.append(msg).append(message);
|
||||
log.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterAllAnalysed(AnalysisContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExcelResult<TDeviceImportVo> getExcelResult() {
|
||||
return new ExcelResult<TDeviceImportVo>() {
|
||||
|
||||
@Override
|
||||
public String getAnalysis() {
|
||||
if (failureNum > 0) {
|
||||
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
|
||||
throw new ServiceException(failureMsg.toString());
|
||||
} else {
|
||||
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
|
||||
}
|
||||
return successMsg.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TDeviceImportVo> getList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getErrorList() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -45,4 +45,6 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
|
|||
|
||||
List<SysDeptVo> deviceStatics(@Param("deviceType") String deviceType);
|
||||
|
||||
List<SysDeptVo> deviceStaticsByDeptId(@Param("deviceType")String deviceType, @Param("deptId")String deptId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
package org.dromara.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.dromara.common.mybatis.annotation.DataColumn;
|
||||
import org.dromara.common.mybatis.annotation.DataPermission;
|
||||
import org.dromara.system.domain.TDevice;
|
||||
import org.dromara.system.domain.bo.TDeviceBo;
|
||||
import org.dromara.system.domain.vo.DeviceStaticsVo;
|
||||
import org.dromara.system.domain.vo.TDeviceExportVo;
|
||||
import org.dromara.system.domain.vo.TDeviceVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
|
|
@ -17,4 +25,14 @@ public interface TDeviceMapper extends BaseMapperPlus<TDevice, TDeviceVo> {
|
|||
|
||||
List<DeviceStaticsVo> countByDs();
|
||||
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "zzjgdm")
|
||||
})
|
||||
List<TDeviceExportVo> selectDeviceExportList(@Param(Constants.WRAPPER) Wrapper<TDevice> queryWrapper);
|
||||
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "zzjgdm")
|
||||
})
|
||||
Page<TDeviceVo> selectPageDevicetList(@Param("page") Page<TDevice> page, @Param(Constants.WRAPPER) Wrapper<TDevice> queryWrapper);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ public class DeviceRedisSchedule {
|
|||
redisService.insertBatch(BeanUtil.copyToList(jlist, DeviceRedis.class));
|
||||
}
|
||||
|
||||
// @Scheduled(cron = "0 0 0/1 * * ?")
|
||||
@PostConstruct
|
||||
@Scheduled(cron = "0 0 0/1 * * ?")
|
||||
public void handleDeviceInfoToRedis(){
|
||||
if (null == lastUpdateTime || "".equals(lastUpdateTime)){
|
||||
log.error("lastUpdateTime=null");
|
||||
|
|
@ -61,7 +62,7 @@ public class DeviceRedisSchedule {
|
|||
for (TDeviceVo vo : list) {
|
||||
String jsonValue = JSONUtil.toJsonStr(vo);
|
||||
|
||||
String infoKey = "deviceInfo:" + vo.getInfoSource()+":"+vo.getDeviceCode();
|
||||
String infoKey = "deviceInfo:" + vo.getDeviceType()+":"+vo.getDeviceCode();
|
||||
deviceInfoDataMap.put(infoKey, jsonValue);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,5 +137,5 @@ public interface ISysDeptService {
|
|||
* */
|
||||
List<SysDeptVo> getDsList();
|
||||
|
||||
List<SysDeptVo> deviceStatics(String deviceType);
|
||||
List<SysDeptVo> deviceStatics(String deviceType,String manageDeptId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.dromara.system.service;
|
|||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.system.domain.TDevice;
|
||||
import org.dromara.system.domain.vo.DeviceStaticsVo;
|
||||
import org.dromara.system.domain.vo.TDeviceExportVo;
|
||||
import org.dromara.system.domain.vo.TDeviceVo;
|
||||
import org.dromara.system.domain.bo.TDeviceBo;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
|
@ -78,4 +79,8 @@ public interface ITDeviceService {
|
|||
Long countByCondition(TDeviceBo bo);
|
||||
|
||||
R saveDeviceToSt(String infoSource,List<TDevice> list);
|
||||
|
||||
TDeviceVo queryByDeviceCode(String deviceCode);
|
||||
|
||||
List<TDeviceExportVo> selectDeviceExportList(TDeviceBo bo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ public class SysDeptServiceImpl implements ISysDeptService {
|
|||
lqw.eq(StringUtils.isNotBlank(bo.getParentId()), SysDept::getParentId, bo.getParentId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getDeptName()), SysDept::getDeptName, bo.getDeptName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getFullName()), SysDept::getFullName, bo.getFullName());
|
||||
lqw.orderByAsc(SysDept::getAncestors);
|
||||
lqw.orderByAsc(SysDept::getParentId);
|
||||
lqw.orderByAsc(SysDept::getOrderNum);
|
||||
|
|
@ -349,7 +350,22 @@ public class SysDeptServiceImpl implements ISysDeptService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<SysDeptVo> deviceStatics(String deviceType) {
|
||||
public List<SysDeptVo> deviceStatics(String deviceType,String manageDeptId) {
|
||||
if(!manageDeptId.equals("341800000000")){
|
||||
String subManageId = manageDeptId.substring(0,findLastNonZeroIndex(manageDeptId) + 1);
|
||||
return baseMapper.deviceStaticsByDeptId(deviceType,subManageId);
|
||||
|
||||
}
|
||||
return baseMapper.deviceStatics(deviceType);
|
||||
}
|
||||
|
||||
public int findLastNonZeroIndex(String str) {
|
||||
// 从字符串末尾开始向前查找
|
||||
for (int i = str.length() - 1; i >= 0; i--) {
|
||||
if (str.charAt(i) != '0') {
|
||||
return i; // 返回最后一个不为0的字符的下标
|
||||
}
|
||||
}
|
||||
return -1; // 如果没有找到不为0的字符,返回-1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.dromara.system.service.impl;
|
|||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
|
|
@ -14,6 +15,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.system.api.RemoteDataScopeService;
|
||||
import org.dromara.system.domain.vo.DeviceStaticsVo;
|
||||
import org.dromara.system.domain.vo.TDeviceExportVo;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.dromara.system.domain.bo.TDeviceBo;
|
||||
import org.dromara.system.domain.vo.TDeviceVo;
|
||||
|
|
@ -62,8 +64,9 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
*/
|
||||
@Override
|
||||
public TableDataInfo<TDeviceVo> queryPageList(TDeviceBo bo, PageQuery pageQuery) {
|
||||
bo.setValid(1);
|
||||
LambdaQueryWrapper<TDevice> lqw = buildQueryWrapper(bo);
|
||||
Page<TDeviceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
Page<TDeviceVo> result = baseMapper.selectPageDevicetList(pageQuery.build(), lqw);
|
||||
List<TDeviceVo> list = result.getRecords();
|
||||
for (TDeviceVo vo : list) {
|
||||
if ("".equals(vo.getPoliceName()) || null == vo.getPoliceName()){
|
||||
|
|
@ -91,7 +94,28 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
@Override
|
||||
public List<TDeviceVo> queryList(TDeviceBo bo) {
|
||||
LambdaQueryWrapper<TDevice> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
List<TDeviceVo> list = baseMapper.selectVoList(lqw);
|
||||
for (TDeviceVo vo : list) {
|
||||
if ("".equals(vo.getPoliceName()) || null == vo.getPoliceName()){
|
||||
vo.setDeviceName(vo.getCarNum());
|
||||
}
|
||||
if("".equals(vo.getCarNum()) || null == vo.getCarNum()){
|
||||
if (!"".equals(vo.getPoliceNo()) && null != vo.getPoliceNo()){
|
||||
vo.setDeviceName(vo.getPoliceNo()+"-"+vo.getPoliceName());
|
||||
}else {
|
||||
vo.setDeviceName(vo.getPoliceName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TDeviceExportVo> selectDeviceExportList(TDeviceBo bo) {
|
||||
LambdaQueryWrapper<TDevice> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectDeviceExportList(lqw);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -119,8 +143,8 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
lqw.inSql(TDevice::getZzjgdm,depts);
|
||||
}
|
||||
}
|
||||
lqw.in(null != bo.getZzjgdms() && bo.getZzjgdms().length>0,TDevice::getZzjgdm,bo.getZzjgdms());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getZzjgmc()), TDevice::getZzjgmc, bo.getZzjgmc());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getInfoSource()), TDevice::getInfoSource, bo.getInfoSource());
|
||||
lqw.and(StringUtils.isNotBlank(bo.getPoliceName()),wrapper -> wrapper.like(TDevice::getPoliceNo, bo.getPoliceName())
|
||||
.or().like(TDevice::getPoliceName, bo.getPoliceName()).or().like(TDevice::getCarNum, bo.getPoliceName()));
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getPhoneNum()), TDevice::getPhoneNum, bo.getPhoneNum());
|
||||
|
|
@ -143,6 +167,8 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
public Boolean insertByBo(TDeviceBo bo) {
|
||||
TDevice add = MapstructUtils.convert(bo, TDevice.class);
|
||||
validEntityBeforeSave(add);
|
||||
add.setCreateTime(DateUtil.now());
|
||||
add.setUpdateTime(DateUtil.now());
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
|
|
@ -159,6 +185,7 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
@Override
|
||||
public Boolean updateByBo(TDeviceBo bo) {
|
||||
TDevice update = MapstructUtils.convert(bo, TDevice.class);
|
||||
update.setUpdateTime(DateUtil.now());
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
|
@ -182,7 +209,11 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
LambdaUpdateWrapper<TDevice> luw = new LambdaUpdateWrapper<>();
|
||||
luw.set(TDevice::getValid,0);
|
||||
luw.set(TDevice::getUpdateTime,DateUtil.now());
|
||||
luw.in(TDevice::getId,ids);
|
||||
return baseMapper.update(luw) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -191,7 +222,7 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
// 先根据 field1 和 field2 查询出已存在的记录
|
||||
List<TDevice> existingEntities = baseMapper.selectList(new QueryWrapper<TDevice>()
|
||||
.in("device_code", list.stream().map(TDevice::getDeviceCode).collect(Collectors.toList()))
|
||||
.in("info_source", list.stream().map(TDevice::getInfoSource).collect(Collectors.toList())));
|
||||
.in("device_type", list.stream().map(TDevice::getDeviceType).collect(Collectors.toList())));
|
||||
|
||||
// 找到需要更新的记录
|
||||
List<TDevice> toUpdate = new ArrayList<>();
|
||||
|
|
@ -201,7 +232,7 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
for (TDevice entity : list) {
|
||||
boolean exists = false;
|
||||
for (TDevice existingEntity : existingEntities) {
|
||||
if (entity.getDeviceCode().equals(existingEntity.getDeviceCode()) && entity.getInfoSource().equals(existingEntity.getInfoSource())) {
|
||||
if (entity.getDeviceCode().equals(existingEntity.getDeviceCode()) && entity.getDeviceType().equals(existingEntity.getDeviceType())) {
|
||||
entity.setId(existingEntity.getId()); // 设置 ID 以便更新
|
||||
toUpdate.add(entity);
|
||||
exists = true;
|
||||
|
|
@ -259,7 +290,6 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
errorList.add(deviceEntityV2);
|
||||
continue;
|
||||
}
|
||||
deviceEntityV2.setInfoSource(infoSource);
|
||||
try {
|
||||
TDevice oldEntity = checkDeviceExists(deviceEntityV2);
|
||||
if (Objects.isNull(oldEntity)) {
|
||||
|
|
@ -299,7 +329,7 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
public TDevice checkDeviceExists(TDevice deviceEntityV2) {
|
||||
QueryWrapper<TDevice> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("device_code", deviceEntityV2.getDeviceCode());
|
||||
queryWrapper.eq("info_source", deviceEntityV2.getInfoSource());
|
||||
queryWrapper.eq("info_source", deviceEntityV2.getDeviceType());
|
||||
TDevice deviceEntity1 = baseMapper.selectOne(queryWrapper);
|
||||
return deviceEntity1;
|
||||
}
|
||||
|
|
@ -314,4 +344,11 @@ public class TDeviceServiceImpl implements ITDeviceService {
|
|||
return matcher.matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TDeviceVo queryByDeviceCode(String deviceCode) {
|
||||
QueryWrapper<TDevice> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("device_code", deviceCode);
|
||||
TDeviceVo vo = baseMapper.selectVoOne(queryWrapper);
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ server:
|
|||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: stwzhj-system
|
||||
name: wzhj-system
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: @profiles.active@
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@
|
|||
#{entity.deviceCode},#{entity.deviceType},#{entity.online},#{entity.zzjgdm}
|
||||
)
|
||||
</foreach>
|
||||
ON conflict(device_code,device_type) do update set
|
||||
(online,zzjgdm) =(EXCLUDED.online,EXCLUDED.zzjgdm)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
device_type = VALUES(device_type),
|
||||
online = VALUES(online),
|
||||
zzjgdm = VALUES(zzjgdm)
|
||||
</insert>
|
||||
|
||||
<!-- 全省各类设备总数、在线数 -->
|
||||
|
|
|
|||
|
|
@ -36,108 +36,197 @@
|
|||
<!-- 各机构设备在线总数 参数deviceType -->
|
||||
<select id="deviceStatics" parameterType="String" resultMap="SysDeptResult">
|
||||
select * from (
|
||||
-- 安徽省
|
||||
SELECT '0' dept_id,'安徽省' dept_name, '-1' parent_id,COALESCE(td.co,0) co,COALESCE(rd.online,0) online FROM
|
||||
sys_dept d
|
||||
LEFT JOIN
|
||||
-- 全省 各设备总数
|
||||
(SELECT substr(zzjgdm, 1, 2) dept_id,count(*) co from (SELECT * FROM t_device
|
||||
<where>valid = 1
|
||||
<if test="
|
||||
deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
|
||||
</where>
|
||||
) r
|
||||
GROUP BY substr(zzjgdm,1, 2) HAVING substr(zzjgdm,1,2) is not null ) td
|
||||
on substr(d.dept_id,1,2) = td.dept_id
|
||||
LEFT JOIN
|
||||
-- 全省 各设备在线数
|
||||
(SELECT substr(zzjgdm, 1, 2) dept_id,count(*) online from (SELECT * FROM t_device_redis
|
||||
<where>
|
||||
online = '1'
|
||||
<if test="deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
|
||||
</where>
|
||||
) r
|
||||
GROUP BY substr(zzjgdm,1, 2) ) rd
|
||||
on substr(d.dept_id,1,2) = rd.dept_id
|
||||
WHERE d.dept_id = '340000000000'
|
||||
union
|
||||
-- 市局机构
|
||||
SELECT d.dept_id,short_name dept_name,parent_id,COALESCE(td.co,0) co,COALESCE(rd.online,0) online FROM
|
||||
sys_dept d
|
||||
LEFT JOIN
|
||||
-- 市局 各设备总数
|
||||
(SELECT substr(zzjgdm, 1, 4) dept_id,count(*) co from (SELECT * FROM t_device
|
||||
<where>
|
||||
valid = 1
|
||||
<if test="deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
|
||||
</where>
|
||||
) r
|
||||
GROUP BY substr(zzjgdm,1, 4) HAVING substr(zzjgdm,1,4) is not null ) td
|
||||
on substr(d.dept_id,1,4) = td.dept_id
|
||||
LEFT JOIN
|
||||
-- 市局 各设备在线数
|
||||
(SELECT substr(zzjgdm, 1, 4) dept_id,count(*) online from (SELECT * FROM t_device_redis
|
||||
<where>
|
||||
online = '1'
|
||||
<if test="deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
|
||||
</where>
|
||||
) r
|
||||
GROUP BY substr(zzjgdm,1, 4) ) rd
|
||||
on substr(d.dept_id,1,4) = rd.dept_id
|
||||
WHERE d.parent_id = '0'
|
||||
union
|
||||
--分局
|
||||
SELECT d.dept_id,short_name dept_name,parent_id,COALESCE(td.co,0) co,COALESCE(rd.online,0) online FROM
|
||||
sys_dept d
|
||||
LEFT JOIN
|
||||
-- 分局 各设备总数
|
||||
(SELECT substr(zzjgdm, 1, 6) dept_id,count(*) co from (SELECT * FROM t_device
|
||||
<where>
|
||||
valid = 1
|
||||
<if test="deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
|
||||
</where>
|
||||
) r
|
||||
GROUP BY substr(zzjgdm,1, 6) HAVING substr(zzjgdm,1,6) is not null ) td
|
||||
on substr(d.dept_id,1,6) = td.dept_id
|
||||
LEFT JOIN
|
||||
-- 分局 各设备在线数
|
||||
(SELECT substr(zzjgdm, 1, 6) dept_id,count(*) online from (SELECT * FROM t_device_redis
|
||||
<where>
|
||||
online = '1'
|
||||
<if test="deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
|
||||
</where>
|
||||
) r
|
||||
GROUP BY substr(zzjgdm,1, 6) ) rd
|
||||
on substr(d.dept_id,1,6) = rd.dept_id
|
||||
WHERE d.type = 1
|
||||
union
|
||||
--支队 机关
|
||||
SELECT d.dept_id,short_name dept_name,parent_id,COALESCE(td.co,0) co,COALESCE(rd.online,0) online FROM
|
||||
sys_dept d
|
||||
<!--市局数量-->
|
||||
select dept_id as deptId,short_name as deptName,parent_id as parentId,(select count(1) from t_device_redis
|
||||
where online =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
) as onlineCount,
|
||||
(select count(1) from t_device
|
||||
where valid =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
) as allCount from sys_dept d
|
||||
where parent_id = '0'
|
||||
|
||||
union
|
||||
<!--支队数量-->
|
||||
select dept_id,short_name,parent_id,IFNULL(onlineCount,0) as onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select SUBSTRING(zzjgdm,1,8) as zzjgdm ,count(*) as onlineCount from t_device_redis
|
||||
where online =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by SUBSTRING(zzjgdm,1,8)) o
|
||||
on SUBSTRING(d.dept_id,1,8) = SUBSTRING(o.zzjgdm,1,8)
|
||||
LEFT JOIN
|
||||
-- 支队 机关 各设备总数
|
||||
(SELECT substr(zzjgdm, 1, 8) dept_id,count(*) co from (SELECT * FROM t_device
|
||||
<where>
|
||||
valid = 1
|
||||
<if test="deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
|
||||
</where>
|
||||
) r
|
||||
GROUP BY substr(zzjgdm,1, 8) HAVING substr(zzjgdm,1,8) is not null ) td
|
||||
on substr(d.dept_id,1,8) = td.dept_id
|
||||
LEFT JOIN
|
||||
-- 支队 机关 各设备在线数
|
||||
(SELECT substr(zzjgdm, 1, 8) dept_id,count(*) online from (SELECT * FROM t_device_redis
|
||||
<where>
|
||||
online = '1'
|
||||
<if test="deviceType != null and deviceType != ''"> and device_type = #{deviceType}</if>
|
||||
</where>
|
||||
) r
|
||||
GROUP BY substr(zzjgdm,1, 8) ) rd
|
||||
on substr(d.dept_id,1,8) = rd.dept_id
|
||||
WHERE (length(d.ancestors) - length(translate(d.ancestors,',',''))+1) = 3 and d.type = 2
|
||||
(select substring(zzjgdm,1,8) as zzjgdm ,count(*) as allCount from t_device
|
||||
where valid =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by SUBSTRING(zzjgdm,1,8)) a
|
||||
on SUBSTRING(d.dept_id,1,8) = SUBSTRING(a.zzjgdm,1,8)
|
||||
where `status` = '0' and del_flag =0 and parent_id = '341800000000' and dept_id like '341800%'
|
||||
|
||||
union
|
||||
|
||||
<!--分局数量-->
|
||||
select dept_id,short_name,parent_id,IFNULL(onlineCount,0) as onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select SUBSTRING(zzjgdm,1,6) as zzjgdm ,count(*) as onlineCount from t_device_redis
|
||||
where online =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by SUBSTRING(zzjgdm,1,6)) o
|
||||
on SUBSTRING(d.dept_id,1,6) = SUBSTRING(o.zzjgdm,1,6)
|
||||
LEFT JOIN
|
||||
(select substring(zzjgdm,1,6) as zzjgdm ,count(*) as allCount from t_device
|
||||
where valid =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by SUBSTRING(zzjgdm,1,6)) a
|
||||
on SUBSTRING(d.dept_id,1,6) = SUBSTRING(a.zzjgdm,1,6)
|
||||
where `status` = '0' and del_flag =0 and parent_id = '341800000000' and dept_id not like '341800%'
|
||||
|
||||
union
|
||||
<!--派出所等三级四级机构-->
|
||||
select dept_id as deptId,short_name as deptName,parent_id as parentId,IFNULL(onlineCount,0) as onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select SUBSTRING(zzjgdm,1,8) as zzjgdm ,count(*) as onlineCount from t_device_redis
|
||||
where online =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by SUBSTRING(zzjgdm,1,8)) o
|
||||
on SUBSTRING(d.dept_id,1,8) = SUBSTRING(o.zzjgdm,1,8)
|
||||
LEFT JOIN
|
||||
(select substring(zzjgdm,1,8) as zzjgdm ,count(*) as allCount from t_device
|
||||
where valid = 1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by SUBSTRING(zzjgdm,1,8)) a
|
||||
on SUBSTRING(d.dept_id,1,8) = SUBSTRING(a.zzjgdm,1,8)
|
||||
where `status` = '0' and del_flag =0 and parent_id != '341800000000' and dept_id not like '341800%' and dept_id like '%0000'
|
||||
<!--大队等三级四级机构-->
|
||||
UNION
|
||||
select dept_id as deptId,short_name as deptName,parent_id as parentId,IFNULL(onlineCount,0) as onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select SUBSTRING(zzjgdm,1,10) as zzjgdm ,count(*) as onlineCount from t_device_redis
|
||||
where online =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by SUBSTRING(zzjgdm,1,10)) o
|
||||
on SUBSTRING(d.dept_id,1,10) = SUBSTRING(o.zzjgdm,1,10)
|
||||
LEFT JOIN
|
||||
(select substring(zzjgdm,1,10) as zzjgdm ,count(*) as allCount from t_device
|
||||
where valid = 1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by SUBSTRING(zzjgdm,1,10)) a
|
||||
on SUBSTRING(d.dept_id,1,10) = SUBSTRING(a.zzjgdm,1,10)
|
||||
where `status` = '0' and del_flag =0 and parent_id != '341800000000' and parent_id != '0' and dept_id like '341800%' and dept_id like '%00'
|
||||
|
||||
union
|
||||
<!--四级机构-->
|
||||
select dept_id as deptId,dept_name as deptName,parent_id,IFNULL(onlineCount,0) onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select zzjgdm ,count(*) as onlineCount from t_device_redis
|
||||
where online =1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by zzjgdm) o
|
||||
on d.dept_id = o.zzjgdm
|
||||
LEFT JOIN
|
||||
(select zzjgdm as zzjgdm ,count(*) as allCount from t_device
|
||||
where valid = 1
|
||||
<if test="deviceType != null and deviceType != ''">
|
||||
and device_type = #{deviceType}
|
||||
</if>
|
||||
group by zzjgdm) a
|
||||
on d.dept_id = a.zzjgdm
|
||||
where `status` = '0' and del_flag =0 and LENGTH(ancestors) = 40
|
||||
) a
|
||||
order by a.dept_id asc
|
||||
order by a.deptId asc
|
||||
</select>
|
||||
|
||||
<select id="deviceStaticsByDeptId" resultMap="SysDeptResult">
|
||||
select * from (
|
||||
<!--市局数量-->
|
||||
select dept_id as deptId,short_name as deptName,parent_id as parentId,(select count(1) from t_device_redis where online =1 and device_type=#{deviceType}) as onlineCount,
|
||||
(select count(1) from t_device where device_type=#{deviceType} and valid =1) as allCount from sys_dept d
|
||||
where parent_id = '0'
|
||||
|
||||
union
|
||||
<!--支队数量-->
|
||||
select dept_id,short_name,parent_id,IFNULL(onlineCount,0) as onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select SUBSTRING(zzjgdm,1,8) as zzjgdm ,count(*) as onlineCount from t_device_redis where online =1 and device_type = #{deviceType} group by SUBSTRING(zzjgdm,1,8)) o
|
||||
on SUBSTRING(d.dept_id,1,8) = SUBSTRING(o.zzjgdm,1,8)
|
||||
LEFT JOIN
|
||||
(select substring(zzjgdm,1,8) as zzjgdm ,count(*) as allCount from t_device where device_type = #{deviceType} and valid =1 group by SUBSTRING(zzjgdm,1,8)) a
|
||||
on SUBSTRING(d.dept_id,1,8) = SUBSTRING(a.zzjgdm,1,8)
|
||||
where `status` = '0' and del_flag =0 and parent_id = '340100000000' and dept_id like '340100%'
|
||||
|
||||
union
|
||||
|
||||
<!--分局数量-->
|
||||
select dept_id,short_name,parent_id,IFNULL(onlineCount,0) as onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select SUBSTRING(zzjgdm,1,6) as zzjgdm ,count(*) as onlineCount from t_device_redis where online =1 and device_type = #{deviceType} group by SUBSTRING(zzjgdm,1,6)) o
|
||||
on SUBSTRING(d.dept_id,1,6) = SUBSTRING(o.zzjgdm,1,6)
|
||||
LEFT JOIN
|
||||
(select substring(zzjgdm,1,6) as zzjgdm ,count(*) as allCount from t_device where device_type = #{deviceType} and valid =1 group by SUBSTRING(zzjgdm,1,6)) a
|
||||
on SUBSTRING(d.dept_id,1,6) = SUBSTRING(a.zzjgdm,1,6)
|
||||
where `status` = '0' and del_flag =0 and parent_id = '340100000000' and dept_id not like '340100%'
|
||||
|
||||
union
|
||||
<!--派出所等三级四级机构-->
|
||||
select dept_id as deptId,short_name as deptName,parent_id as parentId,IFNULL(onlineCount,0) as onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select SUBSTRING(zzjgdm,1,8) as zzjgdm ,count(*) as onlineCount from t_device_redis where online =1 and device_type = #{deviceType} group by SUBSTRING(zzjgdm,1,8)) o
|
||||
on SUBSTRING(d.dept_id,1,8) = SUBSTRING(o.zzjgdm,1,8)
|
||||
LEFT JOIN
|
||||
(select substring(zzjgdm,1,8) as zzjgdm ,count(*) as allCount from t_device where device_type = #{deviceType} and valid = 1 group by SUBSTRING(zzjgdm,1,8)) a
|
||||
on SUBSTRING(d.dept_id,1,8) = SUBSTRING(a.zzjgdm,1,8)
|
||||
where `status` = '0' and del_flag =0 and parent_id != '340100000000' and dept_id not like '340100%' and dept_id like '%0000'
|
||||
<!--大队等三级四级机构-->
|
||||
UNION
|
||||
select dept_id as deptId,short_name as deptName,parent_id as parentId,IFNULL(onlineCount,0) as onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select SUBSTRING(zzjgdm,1,10) as zzjgdm ,count(*) as onlineCount from t_device_redis where online =1 and device_type = #{deviceType} group by SUBSTRING(zzjgdm,1,10)) o
|
||||
on SUBSTRING(d.dept_id,1,10) = SUBSTRING(o.zzjgdm,1,10)
|
||||
LEFT JOIN
|
||||
(select substring(zzjgdm,1,10) as zzjgdm ,count(*) as allCount from t_device where device_type = #{deviceType} and valid = 1 group by SUBSTRING(zzjgdm,1,10)) a
|
||||
on SUBSTRING(d.dept_id,1,10) = SUBSTRING(a.zzjgdm,1,10)
|
||||
where `status` = '0' and del_flag =0 and parent_id != '340100000000' and parent_id != '0' and dept_id like '340100%' and dept_id like '%00'
|
||||
|
||||
union
|
||||
<!--四级机构-->
|
||||
select dept_id as deptId,dept_name as deptName,parent_id,IFNULL(onlineCount,0) onlineCount,IFNULL(allCount,0) as allCount from sys_dept d
|
||||
left JOIN
|
||||
(select zzjgdm ,count(*) as onlineCount from t_device_redis where online =1 and device_type = #{deviceType} group by zzjgdm) o
|
||||
on d.dept_id = o.zzjgdm
|
||||
LEFT JOIN
|
||||
(select zzjgdm as zzjgdm ,count(*) as allCount from t_device where device_type = #{deviceType} and valid = 1 group by zzjgdm) a
|
||||
on d.dept_id = a.zzjgdm
|
||||
where `status` = '0' and del_flag =0 and LENGTH(ancestors) = 40
|
||||
) count_temp
|
||||
<where>
|
||||
<if test="deptId != null and deptId != ''">
|
||||
and deptId like concat('%',#{deptId},'%')
|
||||
</if>
|
||||
</where>
|
||||
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,31 @@
|
|||
<resultMap id="deviceStaticsResult" type="org.dromara.system.domain.vo.DeviceStaticsVo">
|
||||
|
||||
</resultMap>
|
||||
<resultMap id="DeviceExportResult" type="org.dromara.system.domain.vo.TDeviceExportVo">
|
||||
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="DevicetResult" type="org.dromara.system.domain.vo.TDeviceVo">
|
||||
|
||||
</resultMap>
|
||||
|
||||
|
||||
<select id="countByDs" resultMap="deviceStaticsResult">
|
||||
SELECT SUBSTR(zzjgdm,1,4) zzjgdm,count(*) co from t_device GROUP BY SUBSTR(zzjgdm,1,4) HAVING SUBSTR(zzjgdm,1,4) is not null
|
||||
</select>
|
||||
|
||||
<select id="selectDeviceExportList" resultMap="DeviceExportResult">
|
||||
select u.device_code, u.device_type, u.zzjgdm, u.zzjgmc, u.police_no, u.police_name, u.phone_num, u.car_num, u.valid,
|
||||
u.remark1, u.remark2, u.card_num, u.create_time, u.update_time
|
||||
from t_device u
|
||||
${ew.getCustomSqlSegment}
|
||||
</select>
|
||||
|
||||
<select id="selectPageDevicetList" resultMap="DevicetResult">
|
||||
select u.id,u.device_code, u.device_type, u.zzjgdm, u.zzjgmc, u.police_no, u.police_name, u.phone_num, u.car_num, u.valid,
|
||||
u.remark1, u.remark2, u.card_num, u.create_time, u.update_time
|
||||
from t_device u
|
||||
${ew.getCustomSqlSegment}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-modules</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>wzhj-extract</artifactId>
|
||||
|
||||
<description>
|
||||
wzhj-extract 数据抽取服务
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-nacos</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RuoYi Common Log -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-log</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-dict</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-doc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-seata</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-idempotent</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-translation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-sensitive</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-encrypt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RuoYi Api System -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-api-system</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-api-resource</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-api-data2es</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.dromara.extract;
|
||||
|
||||
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* 系统模块
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EnableDubbo
|
||||
@EnableScheduling
|
||||
@SpringBootApplication
|
||||
public class WzhjExtractApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication application = new SpringApplication(WzhjExtractApplication.class);
|
||||
application.setApplicationStartup(new BufferingApplicationStartup(2048));
|
||||
application.run(args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 数据抽取模块启动成功 ლ(´ڡ`ლ)゙ ");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
lastUpdateTime=2020-06-05 11:40:00
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
package org.dromara.extract.controller;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.dromara.data2es.api.RemoteDataToEsService;
|
||||
import org.dromara.data2es.api.domain.RemoteGpsInfo;
|
||||
import org.dromara.extract.domain.EsGpsInfo;
|
||||
import org.dromara.extract.exception.MyBusinessException;
|
||||
import org.dromara.extract.service.ITDeviceGpsService;
|
||||
import org.dromara.extract.util.PathUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
public class DeviceGPSController {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(DeviceGPSController.class);
|
||||
|
||||
@Autowired
|
||||
ITDeviceGpsService deviceGpsService;
|
||||
|
||||
@DubboReference
|
||||
RemoteDataToEsService dataToEsService;
|
||||
|
||||
|
||||
|
||||
private String lastUpdateTime = "2024-06-05 11:40:00";
|
||||
|
||||
@RequestMapping("/maxId")
|
||||
public String getMaxId(){
|
||||
return lastUpdateTime;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@RequestMapping("/getMaxGcTime")
|
||||
public String getMaxGcTime(){
|
||||
EsGpsInfo info = deviceGpsService.selectBDGCMaxTime();
|
||||
return DateUtil.formatDateTime(info.getGpsTime());
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0/30 * * * * ?")
|
||||
@Async
|
||||
public void bdgcGps(){
|
||||
if(StringUtils.isBlank(lastUpdateTime)){
|
||||
try {
|
||||
lastUpdateTime = getLastUpdateTimeFromProperties();
|
||||
}catch (Exception e){
|
||||
logger.info("lastUpdateTime={},lastUpdateTimeError={}",lastUpdateTime,e.getMessage());
|
||||
}
|
||||
}
|
||||
// Date date = DateUtil.parseDateTime(lastUpdateTime);
|
||||
EsGpsInfo gpsInfo = new EsGpsInfo();
|
||||
gpsInfo.setGpsTime(DateUtil.parseDateTime(lastUpdateTime));
|
||||
Instant start = Instant.now();
|
||||
// some code
|
||||
List<EsGpsInfo> list = deviceGpsService.selectBDGCGPS(gpsInfo);
|
||||
Instant finish = Instant.now();
|
||||
long timeElapsed = Duration.between(start, finish).toMillis();
|
||||
logger.info("查询耗时:"+timeElapsed);
|
||||
logger.info("数据大小size"+list.size());
|
||||
Date nowDate = new Date();
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
EsGpsInfo info = list.get(i);
|
||||
if(i == 0){
|
||||
lastUpdateTime = DateUtil.formatDateTime(info.getGpsTime());
|
||||
// resetUpdateTime(info.getId()+"");
|
||||
}
|
||||
if (DateUtil.between(nowDate,info.getGpsTime(),DateUnit.MINUTE) > 30){
|
||||
info.setOnline("0");
|
||||
}else {
|
||||
info.setOnline("1");
|
||||
}
|
||||
// dataToEsService.saveGps(info);
|
||||
// kafkaProducer.sendByObj(info,"car_gps_xuancheng");
|
||||
}
|
||||
ArrayList<EsGpsInfo> collect = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
|
||||
new TreeSet<>(Comparator.comparing(EsGpsInfo::getDeviceCode))), ArrayList::new));
|
||||
logger.info("去重前size={},去重后size={}",list.size(),collect.size());
|
||||
// List<RemoteGpsInfo> remoteGpsInfos = new ArrayList<>();
|
||||
// remoteGpsInfos.add()
|
||||
dataToEsService.saveDataBatch(BeanUtil.copyToList(collect,RemoteGpsInfo.class));
|
||||
Instant end = Instant.now();
|
||||
long timeEnd = Duration.between(finish, end).toMillis();
|
||||
logger.info("方法执行逻辑耗时:"+timeEnd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void resetUpdateTime(String lastUpdateTime) {
|
||||
try {
|
||||
// lastUpdateTime = DateUtil.format(gpsTime,"yyyy-MM-dd HH:mm:ss");
|
||||
PathUtil.updateProperties(PathUtil.getProperties("ruansi.properties"),"lastUpdateTime",lastUpdateTime,"ruansi.properties");
|
||||
}catch (Exception e){
|
||||
logger.info("lastTime reset error"+e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String getLastUpdateTimeFromProperties() {
|
||||
Properties properties = PathUtil.getProperties("ruansi.properties");
|
||||
if(Objects.isNull(properties)){
|
||||
throw new MyBusinessException("jar包所在文件夹下conf子目录下缺少[ruansi.properties] 文件,请新建");
|
||||
}
|
||||
String lastUpdateTime = properties.getProperty("lastUpdateTime");
|
||||
if(StringUtils.isEmpty(lastUpdateTime)){
|
||||
throw new MyBusinessException("[ruansi.properties]文件内缺少[lastUpdateTime]属性");
|
||||
}
|
||||
// checkTimeFormatter(lastUpdateTime);
|
||||
return lastUpdateTime;
|
||||
}
|
||||
|
||||
private void checkTimeFormatter(String lastUpdateTime) {
|
||||
try {
|
||||
DateTime parse = DateUtil.parse(lastUpdateTime, "yyyy-MM-dd HH:mm:ss");
|
||||
}catch (Exception e){
|
||||
throw new MyBusinessException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package org.dromara.extract.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
* gps定位信息(es表)
|
||||
* @author chenle
|
||||
* @date 2021-05-14 9:39
|
||||
*/
|
||||
@Data
|
||||
public class EsGpsInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7455495841680488351L;
|
||||
|
||||
private Long id;
|
||||
/**
|
||||
* 唯一码(外部系统)合肥版本不需要 21位id,
|
||||
* 到时候上传省厅的时候 需要在kafka发送端处理,生成一个省厅需要的21位id
|
||||
*/
|
||||
private String deviceCode;
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private String deviceType;
|
||||
private String lat;
|
||||
private String lng;
|
||||
//方向
|
||||
private String orientation;
|
||||
//高程
|
||||
private String height;
|
||||
//精度
|
||||
private String deltaH;
|
||||
private String speed;
|
||||
|
||||
|
||||
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date gpsTime;
|
||||
|
||||
private String online;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package org.dromara.extract.exception;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-06-07 10:56
|
||||
*/
|
||||
public class MyBusinessException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String msg;
|
||||
private int code = 500;
|
||||
|
||||
public MyBusinessException(String msg) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public MyBusinessException(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public MyBusinessException(String msg, int code) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public MyBusinessException(String msg, int code, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package org.dromara.extract.mapper;
|
||||
|
||||
|
||||
|
||||
import org.dromara.extract.domain.EsGpsInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface DeviceGpsMapper {
|
||||
|
||||
List<EsGpsInfo> selectPDTGPS(EsGpsInfo esGpsInfo);
|
||||
|
||||
List<EsGpsInfo> selectYDJWGPS(EsGpsInfo esGpsInfo);
|
||||
|
||||
List<EsGpsInfo> selectBDGCGPS(EsGpsInfo esGpsInfo);
|
||||
|
||||
EsGpsInfo selectBDGCMaxTime();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package org.dromara.extract.service;
|
||||
|
||||
|
||||
|
||||
import org.dromara.extract.domain.EsGpsInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ITDeviceGpsService {
|
||||
|
||||
List<EsGpsInfo> selectBDGCGPS(EsGpsInfo esGpsInfo);
|
||||
|
||||
EsGpsInfo selectBDGCMaxTime();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package org.dromara.extract.service.impl;
|
||||
|
||||
|
||||
|
||||
import org.dromara.extract.domain.EsGpsInfo;
|
||||
import org.dromara.extract.mapper.DeviceGpsMapper;
|
||||
import org.dromara.extract.service.ITDeviceGpsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class TDeviceGpsServiceImpl implements ITDeviceGpsService {
|
||||
|
||||
@Autowired
|
||||
DeviceGpsMapper deviceMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public List<EsGpsInfo> selectBDGCGPS(EsGpsInfo esGpsInfo) {
|
||||
return deviceMapper.selectBDGCGPS(esGpsInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EsGpsInfo selectBDGCMaxTime() {
|
||||
return deviceMapper.selectBDGCMaxTime();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package org.dromara.extract.util;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2022-08-05 12:00
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class PathUtil {
|
||||
|
||||
static String outpath = System.getProperty("user.dir")+File.separator+"conf"+File.separator;//先读取config目录的,没有再加载classpath的
|
||||
|
||||
|
||||
public static Properties getProperties(String fileName) {
|
||||
System.out.println("文件路径:"+outpath);
|
||||
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的
|
||||
properties.load(in);
|
||||
return properties;
|
||||
} catch (IOException es) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 更新properties文件的键值对
|
||||
* 如果该主键已经存在,更新该主键的值;
|
||||
* 如果该主键不存在,则插件一对键值。
|
||||
* @param keyname 键名
|
||||
* @param keyvalue 键值
|
||||
*/
|
||||
public static void updateProperties(Properties props,String keyname,String keyvalue,String fileName) throws IOException {
|
||||
|
||||
// 调用 Hashtable 的方法 put,使用 getProperty 方法提供并行性。
|
||||
// 强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
|
||||
OutputStream fos = new FileOutputStream(outpath + fileName);
|
||||
props.setProperty(keyname, keyvalue);
|
||||
// 以适合使用 load 方法加载到 Properties 表中的格式,
|
||||
// 将此 Properties 表中的属性列表(键和元素对)写入输出流
|
||||
props.store(fos, "Update '" + keyname + "' value");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 9216
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: wzhj-extract
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: @profiles.active@
|
||||
|
||||
--- # nacos 配置
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
# nacos 服务地址
|
||||
server-addr: @nacos.server@
|
||||
username: @nacos.username@
|
||||
password: @nacos.password@
|
||||
discovery:
|
||||
# 注册组
|
||||
group: @nacos.discovery.group@
|
||||
namespace: ${spring.profiles.active}
|
||||
config:
|
||||
# 配置组
|
||||
group: @nacos.config.group@
|
||||
namespace: ${spring.profiles.active}
|
||||
config:
|
||||
import:
|
||||
- optional:nacos:application-common.yml
|
||||
- optional:nacos:datasource.yml
|
||||
- optional:nacos:${spring.application.name}.yml
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
Spring Boot Version: ${spring-boot.version}
|
||||
Spring Application Name: ${spring.application.name}
|
||||
_ _
|
||||
(_) | |
|
||||
_ __ _ _ ___ _ _ _ ______ ___ _ _ ___ | |_ ___ _ __ ___
|
||||
| '__|| | | | / _ \ | | | || ||______|/ __|| | | |/ __|| __| / _ \| '_ ` _ \
|
||||
| | | |_| || (_) || |_| || | \__ \| |_| |\__ \| |_ | __/| | | | | |
|
||||
|_| \__,_| \___/ \__, ||_| |___/ \__, ||___/ \__| \___||_| |_| |_|
|
||||
__/ | __/ |
|
||||
|___/ |___/
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="logs/${project.artifactId}" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="console.log.pattern"
|
||||
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${console.log.pattern}</pattern>
|
||||
<charset>utf-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<include resource="logback-common.xml" />
|
||||
|
||||
<include resource="logback-logstash.xml" />
|
||||
|
||||
<!-- 开启 skywalking 日志收集 -->
|
||||
<include resource="logback-skylog.xml" />
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
</configuration>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.dromara.extract.mapper.DeviceGpsMapper">
|
||||
|
||||
<resultMap type="org.dromara.extract.domain.EsGpsInfo" id="DeviceResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="deltaH" column="deltaH" />
|
||||
<result property="deviceCode" column="deviceCode" />
|
||||
<result property="deviceType" column="deviceType" />
|
||||
<result property="gpsTime" column="gpsTime" />
|
||||
<result property="height" column="height" />
|
||||
<result property="lat" column="lat" />
|
||||
<result property="lng" column="lng" />
|
||||
<result property="orientation" column="orientation" />
|
||||
<result property="speed" column="speed" />
|
||||
<result property="zzjgdm" column="zzjgdm" />
|
||||
<result property="online" column="is_online" />
|
||||
</resultMap>
|
||||
|
||||
<select id="selectPDTGPS" parameterType="org.dromara.extract.domain.EsGpsInfo" resultMap="DeviceResult">
|
||||
select u_id deviceCode,'3' deviceType, x lat, y lng, time gpsTime,nvl(p.is_alive,0) is_online from t_location t left join t_pdtuser p
|
||||
on t.u_id = p.user_no
|
||||
<where>
|
||||
<if test="gpsTime != null "> and time >= #{gpsTime}</if>
|
||||
</where>
|
||||
order by time desc
|
||||
</select>
|
||||
|
||||
<select id="selectYDJWGPS" parameterType="org.dromara.extract.domain.EsGpsInfo" resultMap="DeviceResult">
|
||||
select userid deviceCode,'4' deviceType, lng lng, lat lat, gpstime gpsTime from v_device_status
|
||||
<where>
|
||||
<if test="gpsTime != null "> and to_date(gpstime,'yyyy-mm-dd,hh24:mi:ss') >= #{gpsTime}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectBDGCGPS" parameterType="org.dromara.extract.domain.EsGpsInfo" resultMap="DeviceResult">
|
||||
select id, deviceCode,deviceType,lng,lat, gpsTime, speed from (
|
||||
select id, gpsid deviceCode,'2' deviceType, longitude lng, latitude lat, DATE_FORMAT(time,'%Y-%m-%d %H:%i:%s') gpsTime, speed speed from vehicle_trajectory
|
||||
<where>
|
||||
<if test="gpsTime != null "> and time > #{gpsTime}</if>
|
||||
</where>
|
||||
) a group by deviceCode
|
||||
order by gpsTime desc limit 100
|
||||
</select>
|
||||
|
||||
<select id="selectBDGCMaxTime" resultMap="DeviceResult">
|
||||
select id, gpsid deviceCode,'2' deviceType, longitude lng, latitude lat, DATE_FORMAT(time,'%Y-%m-%d %H:%i:%s') gpsTime, speed speed from vehicle_trajectory
|
||||
order by time desc limit 1
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-modules</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>wzhj-udp</artifactId>
|
||||
|
||||
<description>
|
||||
wzhj-udp UDP数据接收服务
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-nacos</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RuoYi Common Log -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-log</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-dict</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-doc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-seata</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-idempotent</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-translation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-sensitive</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-encrypt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-common-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RuoYi Api System -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-api-system</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-api-resource</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>stwzhj-api-data2es</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.dromara.udp;
|
||||
|
||||
|
||||
import org.redisson.spring.starter.RedissonAutoConfiguration;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
@EnableScheduling
|
||||
public class WzhjUdpReceiverTlApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(WzhjUdpReceiverTlApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package org.dromara.udp.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
public class AsyncConfiguration {
|
||||
|
||||
/*@Bean("taskExecutor")
|
||||
public Executor taskExecutor(){
|
||||
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
|
||||
taskExecutor.setCorePoolSize(8);
|
||||
taskExecutor.setMaxPoolSize(20);
|
||||
taskExecutor.setQueueCapacity(Integer.MAX_VALUE);
|
||||
taskExecutor.setKeepAliveSeconds(60);
|
||||
taskExecutor.setThreadNamePrefix("zfjly--");
|
||||
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
taskExecutor.setAwaitTerminationSeconds(60);
|
||||
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
return taskExecutor;
|
||||
}*/
|
||||
|
||||
@Bean("taskExecutor")
|
||||
public ThreadPoolTaskExecutor taskExecutor(){
|
||||
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
|
||||
taskExecutor.setCorePoolSize(4);
|
||||
taskExecutor.setMaxPoolSize(10);
|
||||
taskExecutor.setQueueCapacity(20);
|
||||
taskExecutor.setKeepAliveSeconds(60);
|
||||
taskExecutor.setThreadNamePrefix("zfjly--");
|
||||
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
taskExecutor.setAwaitTerminationSeconds(60);
|
||||
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
return taskExecutor;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,252 @@
|
|||
package org.dromara.udp.config;
|
||||
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.time.DateUtils;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.data2es.api.RemoteDataToEsService;
|
||||
import org.dromara.data2es.api.domain.RemoteGpsInfo;
|
||||
import org.dromara.udp.exception.MyBusinessException;
|
||||
import org.dromara.udp.utils.BitConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-07-13 8:45
|
||||
*/
|
||||
@EnableAsync
|
||||
@Component
|
||||
public class AsyncUtils {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(AsyncUtils.class);
|
||||
|
||||
@DubboReference
|
||||
RemoteDataToEsService dataEsService;
|
||||
|
||||
|
||||
/**
|
||||
* 保存data
|
||||
* @param bytes
|
||||
* @throws ParseException
|
||||
*/
|
||||
@Async(value = "taskExecutor")
|
||||
public void saveData(byte[] bytes) throws Exception {
|
||||
//logger.info("当前线程名={}",Thread.currentThread().getName());
|
||||
RemoteGpsInfo esGpsInfo = parseBytes(bytes);
|
||||
esGpsInfo.setDeviceType("3");
|
||||
//和redis过期监听时间一定要一致
|
||||
if (DateUtil.between(new Date(),esGpsInfo.getGpsTime(),DateUnit.MINUTE)> 10){
|
||||
esGpsInfo.setOnline(0);
|
||||
}else {
|
||||
esGpsInfo.setOnline(1);
|
||||
}
|
||||
logger.error(esGpsInfo.toString());
|
||||
R response = dataEsService.saveData(esGpsInfo);
|
||||
//logger.error("位置信息接口={},失败信息={},失败设备={}",response.getCode(),response.getMessage(),esGpsInfo.getDeviceId());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AA--10101010 10101010 2^15+2^13+2^11+2^9 + 170=
|
||||
* @param bytes 待解析的字节数组
|
||||
*/
|
||||
private RemoteGpsInfo parseBytes(byte[] bytes) throws ParseException {
|
||||
|
||||
checkHeaderByte(bytes);
|
||||
|
||||
byte[] copyByte = Arrays.copyOfRange(bytes, 10, 4+256);
|
||||
byte[] gpsIdBytes = Arrays.copyOf(copyByte, 20);
|
||||
//String gpsId = singleByteToString(gpsIdBytes);
|
||||
String gpsId = String.copyValueOf(getChars(gpsIdBytes)).trim();
|
||||
int le =gpsId.length();
|
||||
if(StringUtils.isEmpty(gpsId)){
|
||||
throw new MyBusinessException("gpsId 不符合规范,gpsId为:"+gpsId);
|
||||
}
|
||||
logger.error("gpsid:"+gpsId);
|
||||
byte[] lonBytes = Arrays.copyOfRange(copyByte, 20, 28);
|
||||
long lon = BitConverter.byteArrayToLong(lonBytes,true);
|
||||
double lonD = Double.longBitsToDouble(lon);
|
||||
logger.error("lon:"+lonD);
|
||||
//lat
|
||||
byte[] latBytes = Arrays.copyOfRange(copyByte, 28, 36);
|
||||
long lat = BitConverter.byteArrayToLong(latBytes,true);
|
||||
double latD = Double.longBitsToDouble(lat);
|
||||
logger.error("lat:"+latD);
|
||||
|
||||
long speed = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 36,38),true);
|
||||
logger.error("speed:"+speed);
|
||||
|
||||
long angle = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 38, 40), true);
|
||||
long height = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 40, 42), true);
|
||||
long jingdu = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 42, 44), true);
|
||||
logger.error("angle:"+angle);
|
||||
logger.error("height:"+height);
|
||||
logger.error("jingdu:"+jingdu);
|
||||
|
||||
long year = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 44, 46), false);
|
||||
//月日时分秒
|
||||
byte[] sfm = Arrays.copyOfRange(copyByte, 46, 51);
|
||||
String time = singleByteToString2(sfm);
|
||||
logger.error("time:"+year+time);
|
||||
|
||||
return BuilderEsGpsInfo(gpsId, lonD, latD, speed, angle, height, jingdu, (year + time));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建EsgpsInfo对象
|
||||
* @param gpsId 000340100000000001000001
|
||||
* @param lonD 经度
|
||||
* @param latD 纬度
|
||||
* @param speed 速度
|
||||
* @param angle 方向
|
||||
* @param height 高度
|
||||
* @param jingdu 经度
|
||||
* @param time 20210616123208
|
||||
*/
|
||||
private RemoteGpsInfo BuilderEsGpsInfo(String gpsId, double lonD, double latD, long speed,
|
||||
long angle, long height, long jingdu, String time) throws ParseException {
|
||||
RemoteGpsInfo gpsInfo = new RemoteGpsInfo();
|
||||
gpsInfo.setDeviceCode(parseGpsId(gpsId));
|
||||
gpsInfo.setDeviceType(parseDeviceType(gpsId));
|
||||
gpsInfo.setLat(String.valueOf(latD));
|
||||
gpsInfo.setLng(String.valueOf(lonD));
|
||||
gpsInfo.setOrientation(String.valueOf(angle));
|
||||
gpsInfo.setHeight(String.valueOf(height));
|
||||
gpsInfo.setDeltaH(String.valueOf(jingdu));
|
||||
gpsInfo.setSpeed(String.valueOf(speed));
|
||||
gpsInfo.setGpsTime(parseGpsTime(time));
|
||||
|
||||
return gpsInfo;
|
||||
}
|
||||
|
||||
private Date parseGpsTime(String time) throws ParseException {
|
||||
if(StringUtils.isEmpty(time)){
|
||||
throw new MyBusinessException("时间为空");
|
||||
}
|
||||
Date date = DateUtils.parseDate(time, new String[]{"yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss"});
|
||||
return date;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析出城市前缀3401
|
||||
* @param gpsId 000340100000000001000001
|
||||
* @return cityCode
|
||||
*/
|
||||
private String parseCityCode(String gpsId) {
|
||||
checkGpsId(gpsId);
|
||||
return gpsId.substring(3,7);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析出设备类型
|
||||
* @param gpsId
|
||||
* @return
|
||||
*/
|
||||
private String parseDeviceType(String gpsId) {
|
||||
checkGpsId(gpsId);
|
||||
return gpsId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回deviceSn,和parseGpsId一样的值
|
||||
* @param gpsId 000340100000000001000001
|
||||
* @return deviceSn
|
||||
*/
|
||||
private String parseDeviceSn(String gpsId) {
|
||||
return parseGpsId(gpsId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析gpsId 去除前面的 000
|
||||
* @param gpsId 000340100000000001000001
|
||||
* @return gpsId
|
||||
*/
|
||||
private String parseGpsId(String gpsId) {
|
||||
checkGpsId(gpsId);
|
||||
return gpsId;
|
||||
}
|
||||
|
||||
private void checkGpsId(String gpsId) {
|
||||
if(gpsId.length() != 8){
|
||||
throw new MyBusinessException("gpsId为空");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkHeaderByte(byte[] bytes) {
|
||||
byte first = bytes[0];
|
||||
byte second = bytes[2];
|
||||
//校验标准头
|
||||
int aa = 0xAA;
|
||||
int cc = 0xCC;
|
||||
int ff = 0xff;
|
||||
if((first & ff) != aa){
|
||||
throw new MyBusinessException("头文件校验错误,你的字节数组第一位为:"+Integer.toHexString(first & ff)+",应该为:AA");
|
||||
}
|
||||
if((second & ff) != cc){
|
||||
throw new MyBusinessException("头文件校验错误,你的字节数组第三位为:"+Integer.toHexString(cc & ff)+",应该为:CC");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ss 要转换前的byte数组
|
||||
* @return 拼接后的字符串 小于0的在前面补0
|
||||
*/
|
||||
private String singleByteToString(byte[] ss) {
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
|
||||
for (byte b : ss) {
|
||||
String v = (int) b +"";
|
||||
if (v.length() < 2) {
|
||||
v = v + "0";
|
||||
}
|
||||
ret.append(v);
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
private String singleByteToString2(byte[] ss) {
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
|
||||
for (byte b : ss) {
|
||||
String v = (int) b +"";
|
||||
if (v.length() < 2) {
|
||||
v = "0" + v ;
|
||||
}
|
||||
ret.append(v);
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
private char[] getChars (byte[] bytes) {
|
||||
Charset cs = Charset.forName ("UTF-8");
|
||||
ByteBuffer bb = ByteBuffer.allocate (bytes.length);
|
||||
bb.put (bytes);
|
||||
bb.flip ();
|
||||
CharBuffer cb = cs.decode (bb);
|
||||
|
||||
return cb.array();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package org.dromara.udp.config;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.udp.utils.IPUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-12-30 9:53
|
||||
*/
|
||||
public class UrlInterceptor implements HandlerInterceptor {
|
||||
|
||||
private List whiteUrls;
|
||||
|
||||
public UrlInterceptor(String whiteUrl) {
|
||||
String[] urlArray = whiteUrl.split(",");
|
||||
whiteUrls = CollectionUtils.arrayToList(urlArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
//过滤ip,若用户在白名单内,则放行
|
||||
String ipAddress= IPUtils.getRealIP(request);
|
||||
|
||||
if(StringUtils.isEmpty(ipAddress)){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!whiteUrls.contains(ipAddress)){
|
||||
R error = R.fail("ip not allowed");
|
||||
handleResponse(error,response);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleResponse(R r, HttpServletResponse response) {
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||
PrintWriter printWriter = null;
|
||||
try {
|
||||
printWriter = response.getWriter();
|
||||
printWriter.write(JSON.toJSONString(r));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
if(!Objects.isNull(printWriter)){
|
||||
printWriter.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package org.dromara.udp.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-12-30 10:03
|
||||
*/
|
||||
//@Configuration
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
|
||||
@Value("${ruansi.whiteUrl}")
|
||||
private String whiteUrl;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new UrlInterceptor(whiteUrl));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
package org.dromara.udp.controller;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-12-17 10:54
|
||||
*/
|
||||
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import org.apache.commons.lang.time.DateUtils;
|
||||
import org.dromara.data2es.api.domain.RemoteGpsInfo;
|
||||
import org.dromara.udp.config.AsyncUtils;
|
||||
import org.dromara.udp.exception.MyBusinessException;
|
||||
import org.dromara.udp.utils.BitConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-07-12 9:30
|
||||
*/
|
||||
@Component
|
||||
public class OriginalUdpReceiver implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(OriginalUdpReceiver.class);
|
||||
|
||||
private static final char[] HEX_CHARS = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||
@Resource
|
||||
private ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
@Autowired
|
||||
private AsyncUtils asyncUtils;
|
||||
|
||||
|
||||
/*private static OriginalUdpReceiver originalUdpReceiver;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
originalUdpReceiver = this;
|
||||
}*/
|
||||
|
||||
private static final int MAX_UDP_DATA_SIZE = 64*1024;
|
||||
|
||||
/*@Override
|
||||
public void run(String... args) throws Exception {
|
||||
//System.out.println( Arrays.toString(args));
|
||||
//new Thread(new UDPProcess("192.168.10.14",9909)).start();
|
||||
//原生方式启动
|
||||
System.out.println("原生方式启动");
|
||||
Executors.newSingleThreadExecutor().execute(new UDPProcess("10.20.80.8",Integer.parseInt("10013")));
|
||||
// Executors.newSingleThreadExecutor().execute(new UDPProcess("53.1.237.83",8082));
|
||||
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
logger.info("原生方式启动");
|
||||
try {
|
||||
// Executors.newSingleThreadExecutor().execute(new UDPProcess("53.238.79.4",Integer.parseInt("10013")));
|
||||
Executors.newSingleThreadExecutor().execute(new UDPProcess("localhost",Integer.parseInt("10013")));
|
||||
} catch (SocketException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class UDPProcess implements Runnable {
|
||||
DatagramSocket socket = null;
|
||||
|
||||
UDPProcess(String ip, final int port) throws SocketException {
|
||||
|
||||
socket = new DatagramSocket(new InetSocketAddress(ip,port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
while (true) {
|
||||
byte[] buffer = new byte[MAX_UDP_DATA_SIZE];
|
||||
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
||||
try {
|
||||
socket.receive(packet);
|
||||
byte[] data = packet.getData();
|
||||
|
||||
String unSendData = new String(buffer,0,data.length);
|
||||
//String sendData = bytes2hexStr(data);
|
||||
logger.error("接收到了数据:"+data);
|
||||
asyncUtils.saveData(data);
|
||||
/*taskExecutor.execute(() -> {
|
||||
try {
|
||||
saveData(data);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});*/
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveData(byte[] bytes) throws ParseException {
|
||||
//logger.info("当前线程名={}",Thread.currentThread().getName());
|
||||
RemoteGpsInfo esGpsInfo = parseBytes(bytes);
|
||||
if (DateUtil.between(new Date(),esGpsInfo.getGpsTime(),DateUnit.MINUTE)> 10){
|
||||
esGpsInfo.setOnline(0);
|
||||
}else {
|
||||
esGpsInfo.setOnline(1);
|
||||
}
|
||||
//ApiResponse response = dataEsService.saveGps(esGpsInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String bytes2hex(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String tmp;
|
||||
sb.append("[");
|
||||
for (byte b : bytes) {
|
||||
// 将每个字节与0xFF进行与运算,然后转化为10进制,然后借助于Integer再转化为16进制
|
||||
tmp = Integer.toHexString(0xFF & b);
|
||||
if (tmp.length() == 1) {
|
||||
tmp = "0" + tmp;//只有一位的前面补个0
|
||||
}
|
||||
sb.append(tmp).append(" ");//每个字节用空格断开
|
||||
}
|
||||
sb.delete(sb.length() - 1, sb.length());//删除最后一个字节后面对于的空格
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* AA--10101010 10101010 2^15+2^13+2^11+2^9 + 170=
|
||||
* @param bytes 待解析的字节数组
|
||||
*/
|
||||
private RemoteGpsInfo parseBytes(byte[] bytes) throws ParseException {
|
||||
|
||||
checkHeaderByte(bytes);
|
||||
|
||||
byte[] copyByte = Arrays.copyOfRange(bytes, 10, 4+256);
|
||||
byte[] gpsIdBytes = Arrays.copyOf(copyByte, 10);
|
||||
String gpsId = singleByteToString(gpsIdBytes);
|
||||
if(org.apache.commons.lang.StringUtils.isEmpty(gpsId) || gpsId.length() != 20){
|
||||
throw new MyBusinessException("gpsId 不符合规范,gpsId为:"+gpsId);
|
||||
}
|
||||
logger.error(gpsId);
|
||||
byte[] lonBytes = Arrays.copyOfRange(copyByte, 10, 18);
|
||||
long lon = BitConverter.byteArrayToLong(lonBytes,true);
|
||||
double lonD = Double.longBitsToDouble(lon);
|
||||
logger.error("lon:"+lonD);
|
||||
//lat
|
||||
byte[] latBytes = Arrays.copyOfRange(copyByte, 18, 26);
|
||||
long lat = BitConverter.byteArrayToLong(latBytes,true);
|
||||
double latD = Double.longBitsToDouble(lat);
|
||||
logger.error("lat:"+latD);
|
||||
|
||||
long speed = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 26,28),true);
|
||||
logger.error("speed:"+speed);
|
||||
|
||||
long angle = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 28, 30), true);
|
||||
long height = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 30, 32), true);
|
||||
long jingdu = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 32, 34), true);
|
||||
logger.error("angle:"+angle);
|
||||
logger.error("height:"+height);
|
||||
logger.error("jingdu:"+jingdu);
|
||||
|
||||
long year = BitConverter.byteArrayToShort(Arrays.copyOfRange(copyByte, 34, 36), true);
|
||||
//月日时分秒
|
||||
byte[] sfm = Arrays.copyOfRange(copyByte, 36, 41);
|
||||
String time = singleByteToString(sfm);
|
||||
logger.error("time:"+year+time);
|
||||
|
||||
return BuilderEsGpsInfo(gpsId, lonD, latD, speed, angle, height, jingdu, (year + time));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建EsgpsInfo对象
|
||||
* @param gpsId 000340100000000001000001
|
||||
* @param lonD 经度
|
||||
* @param latD 纬度
|
||||
* @param speed 速度
|
||||
* @param angle 方向
|
||||
* @param height 高度
|
||||
* @param jingdu 经度
|
||||
* @param time 20210616123208
|
||||
*/
|
||||
private RemoteGpsInfo BuilderEsGpsInfo(String gpsId, double lonD, double latD, long speed,
|
||||
long angle, long height, long jingdu, String time) throws ParseException {
|
||||
RemoteGpsInfo gpsInfo = new RemoteGpsInfo();
|
||||
gpsInfo.setDeviceCode(parseGpsId(gpsId));
|
||||
gpsInfo.setDeviceType(parseDeviceType(gpsId));
|
||||
gpsInfo.setLat(String.valueOf(latD));
|
||||
gpsInfo.setLng(String.valueOf(lonD));
|
||||
gpsInfo.setOrientation(String.valueOf(angle));
|
||||
gpsInfo.setHeight(String.valueOf(height));
|
||||
gpsInfo.setDeltaH(String.valueOf(jingdu));
|
||||
gpsInfo.setSpeed(String.valueOf(speed));
|
||||
gpsInfo.setGpsTime(parseGpsTime(time));
|
||||
|
||||
return gpsInfo;
|
||||
}
|
||||
|
||||
private Date parseGpsTime(String time) throws ParseException {
|
||||
if(org.apache.commons.lang.StringUtils.isEmpty(time)){
|
||||
throw new MyBusinessException("时间为空");
|
||||
}
|
||||
Date date = DateUtils.parseDate(time, new String[]{"yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss"});
|
||||
return date;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析出城市前缀3401
|
||||
* @param gpsId 000340100000000001000001
|
||||
* @return cityCode
|
||||
*/
|
||||
private String parseCityCode(String gpsId) {
|
||||
checkGpsId(gpsId);
|
||||
return gpsId.substring(3,7);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析出设备类型
|
||||
* @param gpsId
|
||||
* @return
|
||||
*/
|
||||
private String parseDeviceType(String gpsId) {
|
||||
checkGpsId(gpsId);
|
||||
return gpsId.substring(17,18);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回deviceSn,和parseGpsId一样的值
|
||||
* @param gpsId 000340100000000001000001
|
||||
* @return deviceSn
|
||||
*/
|
||||
private String parseDeviceSn(String gpsId) {
|
||||
return parseGpsId(gpsId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析gpsId 去除前面的 000
|
||||
* @param gpsId 000340100000000001000001
|
||||
* @return gpsId
|
||||
*/
|
||||
private String parseGpsId(String gpsId) {
|
||||
checkGpsId(gpsId);
|
||||
return gpsId.substring(3);
|
||||
}
|
||||
|
||||
private void checkGpsId(String gpsId) {
|
||||
if(gpsId.length() != 20){
|
||||
throw new MyBusinessException("gpsId为空");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkHeaderByte(byte[] bytes) {
|
||||
byte first = bytes[0];
|
||||
byte second = bytes[2];
|
||||
//校验标准头
|
||||
int aa = 0xAA;
|
||||
int cc = 0xCC;
|
||||
int ff = 0xff;
|
||||
if((first & ff) != aa){
|
||||
throw new MyBusinessException("头文件校验错误,你的字节数组第一位为:"+Integer.toHexString(first & ff)+",应该为:AA");
|
||||
}
|
||||
if((second & ff) != cc){
|
||||
throw new MyBusinessException("头文件校验错误,你的字节数组第三位为:"+Integer.toHexString(cc & ff)+",应该为:CC");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ss 要转换前的byte数组
|
||||
* @return 拼接后的字符串 小于0的在前面补0
|
||||
*/
|
||||
private String singleByteToString(byte[] ss) {
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
|
||||
for (byte b : ss) {
|
||||
String v = (int) b +"";
|
||||
if (v.length() < 2) {
|
||||
v = v + "0";
|
||||
}
|
||||
ret.append(v);
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String bytes2hexStr(byte[] bytes) {
|
||||
int len = bytes.length;
|
||||
if (len==0) {
|
||||
return null;
|
||||
}
|
||||
char[] cbuf = new char[len*2];
|
||||
for (int i=0; i<len; i++) {
|
||||
int x = i*2;
|
||||
cbuf[x] = HEX_CHARS[(bytes[i] >>> 4) & 0xf];
|
||||
cbuf[x+1] = HEX_CHARS[bytes[i] & 0xf];
|
||||
}
|
||||
return new String(cbuf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package org.dromara.udp.domain;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2022-03-11 11:58
|
||||
*/
|
||||
public class Gps {
|
||||
|
||||
private double wgLat;
|
||||
private double wgLon;
|
||||
public Gps(double wgLat, double wgLon) {
|
||||
setWgLat(wgLat);
|
||||
setWgLon(wgLon);
|
||||
}
|
||||
public double getWgLat() {
|
||||
return wgLat;
|
||||
}
|
||||
public void setWgLat(double wgLat) {
|
||||
this.wgLat = wgLat;
|
||||
}
|
||||
public double getWgLon() {
|
||||
return wgLon;
|
||||
}
|
||||
public void setWgLon(double wgLon) {
|
||||
this.wgLon = wgLon;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return wgLat + "," + wgLon;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package org.dromara.udp.exception;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-06-07 10:56
|
||||
*/
|
||||
public class MyBusinessException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String msg;
|
||||
private int code = 500;
|
||||
|
||||
public MyBusinessException(String msg) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public MyBusinessException(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public MyBusinessException(String msg, int code) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public MyBusinessException(String msg, int code, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
package org.dromara.udp.utils;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-01-13 18:44
|
||||
*/
|
||||
public class BitConverter {
|
||||
|
||||
public static short ToInt16(byte[] bytes, int offset) {
|
||||
short result = (short) ((int)bytes[offset]&0xff);
|
||||
result |= ((int)bytes[offset+1]&0xff) << 8;
|
||||
return (short) (result & 0xffff);
|
||||
}
|
||||
public static int ToUInt16(byte[] bytes, int offset) {
|
||||
int result = (int)bytes[offset+1]&0xff;
|
||||
result |= ((int)bytes[offset]&0xff) << 8;
|
||||
return result & 0xffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* 大端模式
|
||||
* @param bytes
|
||||
* @param offset
|
||||
* @return
|
||||
*/
|
||||
public static int ToInt32(byte[] bytes, int offset) {
|
||||
int result = (int)bytes[offset]&0xff;
|
||||
result |= ((int)bytes[offset+1]&0xff) << 8;
|
||||
result |= ((int)bytes[offset+2]&0xff) << 16;
|
||||
result |= ((int)bytes[offset+3]&0xff) << 24;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小端模式
|
||||
* @param bytes
|
||||
* @param offset
|
||||
* @return
|
||||
*/
|
||||
public static int ToInt32Reverse(byte[] bytes, int offset) {
|
||||
int result = ((int)bytes[offset]&0xff) << 24;
|
||||
result |= ((int)bytes[offset+1]&0xff) << 16;
|
||||
result |= ((int)bytes[offset+2]&0xff) << 8;
|
||||
result |= ((int)bytes[offset+3]&0xff) ;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static long ToUInt32(byte[] bytes, int offset) {
|
||||
long result = (int)bytes[offset]&0xff;
|
||||
result |= ((int)bytes[offset+1]&0xff) << 8;
|
||||
result |= ((int)bytes[offset+2]&0xff) << 16;
|
||||
result |= ((int)bytes[offset+3]&0xff) << 24;
|
||||
return result & 0xFFFFFFFFL;
|
||||
}
|
||||
public static long ToInt64(byte[] buffer,int offset) {
|
||||
long values = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
values <<= 8; values |= (buffer[offset+i] & 0xFF);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static long ToInt64Reverse(byte[] bytes, int offset) {
|
||||
long result = 0;
|
||||
for (int i = 0; i <= 56; i += 8) {
|
||||
result |= ((int)bytes[offset++]&0xff) << 56 - i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static long ToUInt64(byte[] bytes, int offset) {
|
||||
long result = 0;
|
||||
for (int i = 0; i <= 56; i += 8) {
|
||||
result |= ((int)bytes[offset++]&0xff) << i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static float ToFloat(byte[] bs, int index) {
|
||||
return Float.intBitsToFloat(ToInt32(bs, index));
|
||||
}
|
||||
public static double ToDouble(byte[] arr,int offset) {
|
||||
return Double.longBitsToDouble(ToUInt64(arr, offset));
|
||||
}
|
||||
public static boolean ToBoolean(byte[] bytes,int offset) {
|
||||
return (bytes[offset]==0x00)? false:true;
|
||||
}
|
||||
|
||||
public static byte[] GetBytes(short value) {
|
||||
byte[] bytes = new byte[2];
|
||||
bytes[0] = (byte) (value & 0xff);
|
||||
bytes[1] = (byte) ((value & 0xff00) >> 8);
|
||||
return bytes;
|
||||
}
|
||||
public static byte[] GetBytes(int value) {
|
||||
byte[] bytes = new byte[4];
|
||||
bytes[0] = (byte) ((value)&0xFF); //最低位
|
||||
bytes[1] = (byte) ((value >> 8)&0xFF);
|
||||
bytes[2] = (byte) ((value >> 16)&0xFF);
|
||||
bytes[3] = (byte) ((value >>> 24)); //最高位,无符号右移
|
||||
return bytes;
|
||||
}
|
||||
public static byte[] GetBytes(long values) {
|
||||
byte[] buffer = new byte[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int offset = 64 - (i + 1) * 8;
|
||||
buffer[i] = (byte)((values >> offset) & 0xff);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
public static byte[] GetBytes(float value) {
|
||||
return GetBytes(Float.floatToIntBits(value));
|
||||
}
|
||||
public static byte[] GetBytes(double val) {
|
||||
long value = Double.doubleToLongBits(val);
|
||||
return GetBytes(value);
|
||||
}
|
||||
public static byte[] GetBytes(boolean value) {
|
||||
return new byte[]{(byte)(value? 1:0)};
|
||||
}
|
||||
|
||||
public static byte IntToByte(int x) {
|
||||
return (byte) x;
|
||||
}
|
||||
public static int ByteToInt(byte b) {
|
||||
return b & 0xFF;
|
||||
}
|
||||
public static char ToChar(byte[] bs,int offset) {
|
||||
return (char) (((bs[offset] & 0xFF) << 8) | (bs[offset+1] & 0xFF));
|
||||
}
|
||||
public static byte[] GetBytes(char value) {
|
||||
byte[] b = new byte[2];
|
||||
b[0] = (byte) ((value & 0xFF00) >> 8);
|
||||
b[1] = (byte) (value & 0xFF);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static byte[] Concat(byte[]... bs) {
|
||||
int len = 0,idx=0;
|
||||
for(byte[] b:bs)len+=b.length;
|
||||
byte[] buffer = new byte[len];
|
||||
for(byte[] b:bs) {
|
||||
System.arraycopy(b,0, buffer, idx, b.length);
|
||||
idx+=b.length;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
long a = 123456;
|
||||
byte[] b1=GetBytes(a);
|
||||
long b= ToInt64(b1, 0);
|
||||
System.out.println(b);
|
||||
}
|
||||
|
||||
public static byte[] flipEndian(byte[] data) {
|
||||
if (data == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
byte[] newData = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
newData[data.length - i - 1] = data[i];
|
||||
}
|
||||
|
||||
return newData;
|
||||
}
|
||||
|
||||
public static long byteArrayToLong(byte[] bytes,boolean isLittle) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(8);
|
||||
buffer.put(bytes, 0, bytes.length);
|
||||
buffer.flip();
|
||||
if(isLittle){
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
return buffer.getLong();
|
||||
}
|
||||
|
||||
public static long byteArrayToShort(byte[] bytes,boolean isLittle) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(2);
|
||||
buffer.put(bytes, 0, bytes.length);
|
||||
buffer.flip();
|
||||
if(isLittle){
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
return buffer.getShort();
|
||||
}
|
||||
|
||||
public static long byteArrayToInt(byte[] bytes,boolean isLittle) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4);
|
||||
buffer.put(bytes, 0, bytes.length);
|
||||
buffer.flip();
|
||||
if(isLittle){
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
return buffer.getInt();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将字节数组转为long<br>
|
||||
* 如果input为null,或offset指定的剩余数组长度不足8字节则抛出异常
|
||||
* @param input
|
||||
* @param offset 起始偏移量
|
||||
* @param littleEndian 输入数组是否小端模式
|
||||
* @return
|
||||
*/
|
||||
public static long longFrom8Bytes(byte[] input, int offset, boolean littleEndian) {
|
||||
long value = 0;
|
||||
// 循环读取每个字节通过移位运算完成long的8个字节拼装
|
||||
for (int count = 0; count < 8; ++count) {
|
||||
int shift = (littleEndian ? count : (7 - count)) << 3;
|
||||
value |= ((long) 0xff << shift) & ((long) input[offset + count] << shift);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字节数组到double的转换.
|
||||
*/
|
||||
public static double getDouble(byte[] b) {
|
||||
long m;
|
||||
m = b[0];
|
||||
m &= 0xff;
|
||||
m |= ((long) b[1] << 8);
|
||||
m &= 0xffff;
|
||||
m |= ((long) b[2] << 16);
|
||||
m &= 0xffffff;
|
||||
m |= ((long) b[3] << 24);
|
||||
m &= 0xffffffffl;
|
||||
m |= ((long) b[4] << 32);
|
||||
m &= 0xffffffffffl;
|
||||
m |= ((long) b[5] << 40);
|
||||
m &= 0xffffffffffffl;
|
||||
m |= ((long) b[6] << 48);
|
||||
m &= 0xffffffffffffffl;
|
||||
m |= ((long) b[7] << 56);
|
||||
return Double.longBitsToDouble(m);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package org.dromara.udp.utils;
|
||||
|
||||
|
||||
import org.dromara.udp.domain.Gps;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2022-03-14 14:43
|
||||
*/
|
||||
public class ConvertTool {
|
||||
public static final String BAIDU_LBS_TYPE = "bd09ll";
|
||||
public static double pi = 3.1415926535897932384626;
|
||||
public static double a = 6378245.0;
|
||||
public static double ee = 0.00669342162296594323;
|
||||
/**
|
||||
* * 火星坐标系 (GCJ-02) to 84
|
||||
* * @param lon * @param lat * @return
|
||||
*/
|
||||
public static Gps gcj_To_Gps84(double lat, double lon) {
|
||||
Gps gps = transform(lat, lon);
|
||||
double lontitude = lon * 2 - gps.getWgLon();
|
||||
double latitude = lat * 2 - gps.getWgLat();
|
||||
return new Gps(latitude, lontitude);
|
||||
}
|
||||
public static Gps transform(double lat, double lon) {
|
||||
|
||||
double dLat = transformLat(lon - 105.0, lat - 35.0);
|
||||
double dLon = transformLon(lon - 105.0, lat - 35.0);
|
||||
double radLat = lat / 180.0 * pi;
|
||||
double magic = Math.sin(radLat);
|
||||
magic = 1 - ee * magic * magic;
|
||||
double sqrtMagic = Math.sqrt(magic);
|
||||
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
|
||||
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
|
||||
double mgLat = lat + dLat;
|
||||
double mgLon = lon + dLon;
|
||||
return new Gps(mgLat, mgLon);
|
||||
}
|
||||
|
||||
public static double transformLat(double x, double y) {
|
||||
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
|
||||
+ 0.2 * Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static double transformLon(double x, double y) {
|
||||
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
|
||||
* Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
|
||||
* pi)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package org.dromara.udp.utils;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-12-30 9:54
|
||||
*/
|
||||
|
||||
|
||||
public class IPUtils {
|
||||
/**
|
||||
* 获取用户真实IP地址,不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
|
||||
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值
|
||||
*
|
||||
* @return ip
|
||||
*/
|
||||
public static String getRealIP(HttpServletRequest request) {
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
|
||||
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
|
||||
if( ip.indexOf(",")!=-1 ){
|
||||
ip = ip.split(",")[0];
|
||||
}
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
System.out.println("Proxy-Client-IP ip: " + ip);
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
System.out.println("WL-Proxy-Client-IP ip: " + ip);
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
System.out.println("HTTP_CLIENT_IP ip: " + ip);
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip);
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Real-IP");
|
||||
System.out.println("X-Real-IP ip: " + ip);
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
System.out.println("getRemoteAddr ip: " + ip);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
package org.dromara.udp.utils;
|
||||
|
||||
|
||||
import org.dromara.udp.domain.Gps;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2022-03-11 11:58
|
||||
*/
|
||||
public class LocationConvert {
|
||||
|
||||
public static double pi = 3.1415926535897932384626 * 3000.0 / 180.0; //此处注意 pi = 派 * 3000 / 180 ;
|
||||
public static double a = 6378245.0;
|
||||
public static double ee = 0.00669342162296594323;
|
||||
/**
|
||||
* 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return
|
||||
* 谷歌转地球
|
||||
* */
|
||||
public static Gps gcj_To_Gps84(double lat, double lon) {
|
||||
Gps gps = transform(lat, lon);
|
||||
double lontitude = lon * 2 - gps.getWgLon();
|
||||
double latitude = lat * 2 - gps.getWgLat();
|
||||
return new Gps(latitude, lontitude);
|
||||
}
|
||||
|
||||
public static Gps GPS84ToGCJ02(double lon, double lat) {
|
||||
double dLat = transformLat(lon - 105.0, lat - 35.0);
|
||||
double dLon = transformLon(lon - 105.0, lat - 35.0);
|
||||
double radLat = lat / 180.0 * pi;
|
||||
double magic = Math.sin(radLat);
|
||||
magic = 1 - ee * magic * magic;
|
||||
double sqrtMagic = Math.sqrt(magic);
|
||||
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
|
||||
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
|
||||
double mgLat = lat + dLat;
|
||||
double mgLon = lon + dLon;
|
||||
return new Gps(mgLon, mgLat);
|
||||
}
|
||||
|
||||
public static Gps transform(double lat, double lon) {
|
||||
|
||||
double dLat = transformLat(lon - 105.0, lat - 35.0);
|
||||
double dLon = transformLon(lon - 105.0, lat - 35.0);
|
||||
double radLat = lat / 180.0 * pi;
|
||||
double magic = Math.sin(radLat);
|
||||
magic = 1 - ee * magic * magic;
|
||||
double sqrtMagic = Math.sqrt(magic);
|
||||
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
|
||||
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
|
||||
double mgLat = lat + dLat;
|
||||
double mgLon = lon + dLon;
|
||||
return new Gps(mgLat, mgLon);
|
||||
}
|
||||
|
||||
/**
|
||||
* (BD-09)-->84
|
||||
* 百度转地球
|
||||
* @param bd_lat
|
||||
* @param bd_lon
|
||||
* @return
|
||||
*/
|
||||
public static Gps bd09_To_Gps84(double bd_lat, double bd_lon) {
|
||||
|
||||
Gps gcj02 = bd09_To_Gcj02(bd_lat, bd_lon);
|
||||
Gps map84 = gcj_To_Gps84(gcj02.getWgLat(),
|
||||
gcj02.getWgLon());
|
||||
return map84;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param
|
||||
* 百度转谷歌
|
||||
*/
|
||||
public static Gps bd09_To_Gcj02(double bd_lat, double bd_lon) {
|
||||
double x = bd_lon - 0.0065, y = bd_lat - 0.006;
|
||||
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
|
||||
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
|
||||
double gg_lon = z * Math.cos(theta);
|
||||
double gg_lat = z * Math.sin(theta);
|
||||
return new Gps(gg_lat, gg_lon);
|
||||
}
|
||||
|
||||
public static double transformLat(double x, double y) {
|
||||
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
|
||||
+ 0.2 * Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static double transformLon(double x, double y) {
|
||||
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
|
||||
* Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
|
||||
* pi)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
HashMap<String, String> dto = new HashMap<>(2);
|
||||
String latitude = dto.put("Latitude", "31.739913");
|
||||
String longtide = dto.put("Longtide", "116.475212");
|
||||
//Gps gps = gcj_To_Gps84(Double.valueOf("31.739913"), Double.valueOf("116.475212"));
|
||||
// Gps gps = gcj_To_Gps84(Double.valueOf("31.736539"), Double.valueOf("116.476364"));
|
||||
//Longtide,value=116.47661293112877;Latitude,value=31.736592029405035
|
||||
Gps gps = ConvertTool.gcj_To_Gps84(Double.valueOf("31.736539"), Double.valueOf("116.476364"));
|
||||
latitude = String.valueOf(gps.getWgLat());
|
||||
longtide = String.valueOf(gps.getWgLon());
|
||||
dto.put("Latitude",latitude);
|
||||
dto.put("Longtide",longtide);
|
||||
Set<Map.Entry<String, String>> entries = dto.entrySet();
|
||||
for (Map.Entry<String, String> entry : entries) {
|
||||
System.out.println("key="+entry.getKey()+",value="+entry.getValue());;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package org.dromara.udp.utils;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>description: </p>
|
||||
*
|
||||
* @author chenle
|
||||
* @date 2021-01-13 18:00
|
||||
*/
|
||||
public class Util {
|
||||
// double转换为byte[8]数组
|
||||
public static byte[] getByteArray(double d) {
|
||||
long longbits = Double.doubleToLongBits(d);
|
||||
return getByteArray(longbits);
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间转double
|
||||
* @param date 时间基准 1899年12月30日 --- 1970年1月1日
|
||||
* @return 返回值类似:43322.3770190278
|
||||
*/
|
||||
public static double date2Double(Date date){
|
||||
|
||||
long localOffset = date.getTimezoneOffset()*60000;
|
||||
double dd = (double)(date.getTime()-localOffset)/ 24 / 3600 / 1000 + 25569.0000000;
|
||||
DecimalFormat df = new DecimalFormat("#.0000000000");//先默认保留10位小数
|
||||
|
||||
return Double.valueOf(df.format(dd));
|
||||
}
|
||||
|
||||
/**
|
||||
* double 转 Date 时间
|
||||
* @param dVal
|
||||
*/
|
||||
public static Date doubleToDate(Double dVal){
|
||||
Date oDate = new Date();
|
||||
@SuppressWarnings("deprecation")
|
||||
long localOffset = oDate.getTimezoneOffset() * 60000; //系统时区偏移 1900/1/1 到 1970/1/1 的 25569 天
|
||||
oDate.setTime((long) ((dVal - 25569) * 24 * 3600 * 1000 + localOffset));
|
||||
|
||||
return oDate;
|
||||
}
|
||||
|
||||
public static Date str2Date(String str) {
|
||||
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//小写的mm表示的是分钟
|
||||
try {
|
||||
return sdf.parse(str);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue