增加gps定时任务
This commit is contained in:
parent
bb6acf7ced
commit
17892dc637
|
|
@ -80,7 +80,7 @@ public class MybatisPlusGenerator {
|
|||
|
||||
public static void main(String[] args) {
|
||||
|
||||
new MybatisPlusGenerator().generator("surv_transdata_flowmeter","surv_hisdata_flowmeter");//指标
|
||||
new MybatisPlusGenerator().generator("surv_gps_info","surv_gps_record","surv_vehicle_info");//指标
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.lanhai.constant;
|
||||
|
||||
public interface IotConstants {
|
||||
/** ------------------------------------------------------厂家识别码-----------------------------------------------------------*/
|
||||
/**
|
||||
* 萤石云访问
|
||||
*/
|
||||
|
|
@ -32,6 +33,24 @@ public interface IotConstants {
|
|||
*/
|
||||
String gcszxc_access = "gcszxc_access";
|
||||
|
||||
/**
|
||||
* 仁科应用
|
||||
*/
|
||||
String renke_access = "RenKe_access";
|
||||
|
||||
/**
|
||||
* 曲沃山东芯谷网络密钥
|
||||
*/
|
||||
String qwxgwl_access = "qwxgwl_access";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 曲沃山东优晟系统密钥
|
||||
*/
|
||||
String qwmeter_access = "qwmeter_access";
|
||||
/** ------------------------------------------------------厂家识别码-----------------------------------------------------------*/
|
||||
/** ------------------------------------------------------redis缓存头-----------------------------------------------------------*/
|
||||
/**
|
||||
* 新普惠应用
|
||||
*/
|
||||
|
|
@ -49,9 +68,48 @@ public interface IotConstants {
|
|||
String APPLICATION_RenKe = "RenKe";
|
||||
|
||||
/**
|
||||
* 仁科应用
|
||||
* 物联网配置缓存头
|
||||
*/
|
||||
String renke_access = "RenKe_access";
|
||||
String IOT_SURVCONFIG_CACHE = "surv:config:params";
|
||||
|
||||
|
||||
/** ------------------------------------------------------redis缓存头-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/** ------------------------------------------------------数据生成-----------------------------------------------------------*/
|
||||
/**
|
||||
* 生成数据标记
|
||||
*/
|
||||
String MARK_GENDATA = "GenData";
|
||||
|
||||
|
||||
/**
|
||||
* 真实数据标记
|
||||
*/
|
||||
String MARK_REALDATA = "RealTime";
|
||||
|
||||
/**
|
||||
* 规则类型 历史
|
||||
*/
|
||||
String RULE_HISTORY = "rule_history";
|
||||
|
||||
/**
|
||||
* 规则类型 预设
|
||||
*/
|
||||
String RULE_PRE = "rule_preset";
|
||||
|
||||
|
||||
/** ------------------------------------------------------数据生成-----------------------------------------------------------*/
|
||||
|
||||
/** ------------------------------------------------------物联网协议-----------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* 深圳帝馨gps协议
|
||||
*/
|
||||
String PROTOCOL_SZDXGPS = "szdx_gps_protocol";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 萤石云标准
|
||||
|
|
@ -100,10 +158,6 @@ public interface IotConstants {
|
|||
String qwxgwl_standard = "qwxgwl_standard";
|
||||
|
||||
|
||||
/**
|
||||
* 曲沃山东芯谷网络密钥
|
||||
*/
|
||||
String qwxgwl_access = "qwxgwl_access";
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -111,10 +165,7 @@ public interface IotConstants {
|
|||
*/
|
||||
String qwmeter_standard = "qwmeter_standard";
|
||||
|
||||
/**
|
||||
* 曲沃山东优晟系统密钥
|
||||
*/
|
||||
String qwmeter_access = "qwmeter_access";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -127,6 +178,15 @@ public interface IotConstants {
|
|||
*/
|
||||
String renke_standard = "RenKe_standard";
|
||||
|
||||
/**
|
||||
* 蓝海虚拟设备协议
|
||||
*/
|
||||
String lhviot_standard = "lhviot_standard";
|
||||
|
||||
|
||||
/** ------------------------------------------------------物联网协议-----------------------------------------------------------*/
|
||||
|
||||
/** ------------------------------------------------------业务逻辑-----------------------------------------------------------*/
|
||||
/**
|
||||
* 害虫目录
|
||||
*/
|
||||
|
|
@ -189,42 +249,10 @@ public interface IotConstants {
|
|||
*/
|
||||
String iot_device_guard = "guard";
|
||||
|
||||
/**
|
||||
* 物联网配置缓存头
|
||||
*/
|
||||
String IOT_SURVCONFIG_CACHE = "surv:config:params";
|
||||
|
||||
/**
|
||||
* 生成数据标记
|
||||
*/
|
||||
String MARK_GENDATA = "GenData";
|
||||
|
||||
|
||||
/**
|
||||
* 真实数据标记
|
||||
*/
|
||||
String MARK_REALDATA = "RealTime";
|
||||
|
||||
/**
|
||||
* 规则类型 历史
|
||||
*/
|
||||
String RULE_HISTORY = "rule_history";
|
||||
|
||||
/**
|
||||
* 规则类型 预设
|
||||
*/
|
||||
String RULE_PRE = "rule_preset";
|
||||
|
||||
|
||||
/**
|
||||
* 蓝海虚拟设备协议
|
||||
*/
|
||||
String lhviot_standard = "lhviot_standard";
|
||||
|
||||
|
||||
/**
|
||||
* mqtt连接协议
|
||||
*/
|
||||
String CONFIG_TYPE_MQTT = "mqtt";
|
||||
|
||||
/** ------------------------------------------------------业务逻辑-----------------------------------------------------------*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.lanhai.controller;
|
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gps信息 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/survGpsInfo")
|
||||
public class SurvGpsInfoController {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.lanhai.controller;
|
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gsp轨迹记录 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/survGpsRecord")
|
||||
public class SurvGpsRecordController {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.lanhai.controller;
|
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 车辆信息表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/survVehicleInfo")
|
||||
public class SurvVehicleInfoController {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
package com.lanhai.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gps信息
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class SurvGpsInfo extends Model<SurvGpsInfo> {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "ID", type = IdType.ID_WORKER_STR)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@TableField("GPS_NAME")
|
||||
private String gpsName;
|
||||
|
||||
/**
|
||||
* gps类型;vehicle=车辆
|
||||
*/
|
||||
@TableField("GPS_TYPE")
|
||||
private String gpsType;
|
||||
|
||||
|
||||
/**
|
||||
* 物联网协议编号
|
||||
*/
|
||||
@TableField("PROTOCOL_CODE")
|
||||
private String protocolCode;
|
||||
|
||||
/**
|
||||
* 连接密钥配置ID
|
||||
*/
|
||||
@TableField("SURV_CONFIG_ID")
|
||||
private String survConfigId;
|
||||
|
||||
/**
|
||||
* 牌照号
|
||||
*/
|
||||
@TableField("GPS_PLATE_NUMBER")
|
||||
private String gpsPlateNumber;
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
*/
|
||||
@TableField("GPS_DEVICE_ID")
|
||||
private String gpsDeviceId;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
@TableField("GPS_CODE")
|
||||
private String gpsCode;
|
||||
|
||||
/**
|
||||
* 设备识别码;用于回执时的鉴别,一般与GPS_DEVICE_ID相同
|
||||
*/
|
||||
@TableField("GPS_IDENT")
|
||||
private String gpsIdent;
|
||||
|
||||
/**
|
||||
* 是否在线;0=离线 1=在线静止 2=在线行驶
|
||||
*/
|
||||
@TableField("ONLINE_STATUS")
|
||||
private Integer onlineStatus;
|
||||
|
||||
/**
|
||||
* 速度
|
||||
*/
|
||||
@TableField("GPS_SPEED")
|
||||
private String gpsSpeed;
|
||||
|
||||
/**
|
||||
* 设防状态
|
||||
*/
|
||||
@TableField("DEFENCE_STATUS")
|
||||
private String defenceStatus;
|
||||
|
||||
/**
|
||||
* 定位时间
|
||||
*/
|
||||
@TableField("GPS_TIME")
|
||||
private String gpsTime;
|
||||
|
||||
/**
|
||||
* sim卡号
|
||||
*/
|
||||
@TableField("SIM_NUM")
|
||||
private String simNum;
|
||||
|
||||
/**
|
||||
* 设备型号
|
||||
*/
|
||||
@TableField("MAC_NAME")
|
||||
private String macName;
|
||||
|
||||
/**
|
||||
* 最后更新时间
|
||||
*/
|
||||
@TableField("LAST_UPD_TIME")
|
||||
private LocalDateTime lastUpdTime;
|
||||
|
||||
/**
|
||||
* 最后更新时间
|
||||
*/
|
||||
@TableField("LAST_SYNC_TIME")
|
||||
private LocalDateTime lastSyncTime;
|
||||
|
||||
/**
|
||||
* 设备备注
|
||||
*/
|
||||
@TableField("GPS_NOTES")
|
||||
private String gpsNotes;
|
||||
|
||||
/**
|
||||
* gsp状态;1=启用,0=禁用
|
||||
*/
|
||||
@TableField("GPS_STATUS")
|
||||
private Integer gpsStatus;
|
||||
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
@TableField("SORT_NO")
|
||||
private Integer sortNo;
|
||||
|
||||
/**
|
||||
* 租户号
|
||||
*/
|
||||
@TableField("TENANT_ID")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 乐观锁
|
||||
*/
|
||||
@TableField("RE_VISION")
|
||||
private Integer reVision;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@TableField("CREATE_BY")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("CREATE_TIME")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
@TableField("UPDATE_BY")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 逻辑删除
|
||||
*/
|
||||
@TableField("IS_DEL")
|
||||
private Integer isDel;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField("UPDATE_TIME")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 乐观锁
|
||||
*/
|
||||
@TableField("REVISION")
|
||||
private Integer revision;
|
||||
|
||||
|
||||
@Override
|
||||
protected Serializable pkVal() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
package com.lanhai.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gsp轨迹记录
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class SurvGpsRecord extends Model<SurvGpsRecord> {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "ID", type = IdType.ID_WORKER_STR)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* gpsid
|
||||
*/
|
||||
@TableField("GPS_ID")
|
||||
private String gpsId;
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
*/
|
||||
@TableField("GPS_DEVICE_ID")
|
||||
private String gpsDeviceId;
|
||||
|
||||
/**
|
||||
* 设备号
|
||||
*/
|
||||
@TableField("GPS_CODE")
|
||||
private String gpsCode;
|
||||
|
||||
/**
|
||||
* 设备识别码
|
||||
*/
|
||||
@TableField("GPS_IDENT")
|
||||
private String gpsIdent;
|
||||
|
||||
/**
|
||||
* 数据id
|
||||
*/
|
||||
@TableField("DATA_ID")
|
||||
private String dataId;
|
||||
|
||||
/**
|
||||
* 数据采集时间
|
||||
*/
|
||||
@TableField("DATA_DATE_TIME")
|
||||
private LocalDateTime dataDateTime;
|
||||
|
||||
/**
|
||||
* 设备定位时间
|
||||
*/
|
||||
@TableField("`SYS_TIME`")
|
||||
private String sys_time;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@TableField("`USER_NAME`")
|
||||
private String user_name;
|
||||
|
||||
/**
|
||||
* 经度;gps定位
|
||||
*/
|
||||
@TableField("`JINGDU`")
|
||||
private String jingdu;
|
||||
|
||||
/**
|
||||
* 纬度;gps定位
|
||||
*/
|
||||
@TableField("`WEIDU`")
|
||||
private String weidu;
|
||||
|
||||
/**
|
||||
* 基站经度;基站或wifi定位 使用此处经纬度
|
||||
*/
|
||||
@TableField("`LJINGDU`")
|
||||
private String ljingdu;
|
||||
|
||||
/**
|
||||
* 基站纬度;基站或wifi定位 使用此处经纬度
|
||||
*/
|
||||
@TableField("`LWEIDU`")
|
||||
private String lweidu;
|
||||
|
||||
/**
|
||||
* 数据更新时间;服务器接收时间
|
||||
*/
|
||||
@TableField("`DATETIME`")
|
||||
private String datetime;
|
||||
|
||||
/**
|
||||
* 设备心跳时间;信号时间
|
||||
*/
|
||||
@TableField("`HEART_TIME`")
|
||||
private String heart_time;
|
||||
|
||||
/**
|
||||
* 速度
|
||||
*/
|
||||
@TableField("`SU`")
|
||||
private String su;
|
||||
|
||||
/**
|
||||
* 状态组;如下表status
|
||||
*/
|
||||
@TableField("`STATUS`")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 方向
|
||||
*/
|
||||
@TableField("`HANGXIANG`")
|
||||
private String hangxiang;
|
||||
|
||||
/**
|
||||
* 设备编号;对应 GPS_CODE 设备号
|
||||
*/
|
||||
@TableField("`SIM_ID`")
|
||||
private String sim_id;
|
||||
|
||||
/**
|
||||
* 设备id;对应GPS_IDENT 识别码
|
||||
*/
|
||||
@TableField("`USER_ID`")
|
||||
private String user_id;
|
||||
|
||||
/**
|
||||
* 销售类型-无用途
|
||||
*/
|
||||
@TableField("`SALE_TYPE`")
|
||||
private String sale_type;
|
||||
|
||||
/**
|
||||
* 图标
|
||||
*/
|
||||
@TableField("`ICONTYPE`")
|
||||
private String iconType;
|
||||
|
||||
/**
|
||||
* 系统时间;当前时间
|
||||
*/
|
||||
@TableField("`SERVER_TIME`")
|
||||
private String server_time;
|
||||
|
||||
/**
|
||||
* 设备类型;例如A15
|
||||
*/
|
||||
@TableField("`PRODUCT_TYPE`")
|
||||
private String product_type;
|
||||
|
||||
/**
|
||||
* 到期时间;一般为204x年,2393798400000
|
||||
*/
|
||||
@TableField("`EXPIRE_DATE`")
|
||||
private String expire_date;
|
||||
|
||||
/**
|
||||
* 监控组ID
|
||||
*/
|
||||
@TableField("`GROUP_ID`")
|
||||
private String group_id;
|
||||
|
||||
/**
|
||||
* 信息组;如下表status
|
||||
*/
|
||||
@TableField("`STATENUMBER`")
|
||||
private String statenumber;
|
||||
|
||||
/**
|
||||
* 例如100
|
||||
*/
|
||||
@TableField("`ELECTRIC`")
|
||||
private String electric;
|
||||
|
||||
/**
|
||||
* 设备描述信息;例如 ICCID:通常存放一些设备上传的运行参数
|
||||
*/
|
||||
@TableField("`DESCRIBE`")
|
||||
private String describe;
|
||||
|
||||
/**
|
||||
* sim卡
|
||||
*/
|
||||
@TableField("`SIM`")
|
||||
private String sim;
|
||||
|
||||
/**
|
||||
* 精度误差;当值为10表示gps定位,无精度
|
||||
*/
|
||||
@TableField("`PRECISION`")
|
||||
private String precision;
|
||||
|
||||
/**
|
||||
* 是否关注
|
||||
*/
|
||||
@TableField("`ISFOLLOW`")
|
||||
private String isFollow;
|
||||
|
||||
/**
|
||||
* 车牌号
|
||||
*/
|
||||
@TableField("`PLATENUMBER`")
|
||||
private String plateNumber;
|
||||
|
||||
/**
|
||||
* 授权信息
|
||||
*/
|
||||
@TableField("`AUTH`")
|
||||
private String auth;
|
||||
|
||||
/**
|
||||
* 授权列表
|
||||
*/
|
||||
@TableField("`AUTHLIST`")
|
||||
private String authList;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
@TableField("`DEPTNAME`")
|
||||
private String deptname;
|
||||
|
||||
/**
|
||||
* 是否显示位置
|
||||
*/
|
||||
@TableField("`ISSHOWLOCATION`")
|
||||
private String IsShowLocation;
|
||||
|
||||
/**
|
||||
* 模板扩展
|
||||
*/
|
||||
@TableField("`TEMPEXT`")
|
||||
private String tempExt;
|
||||
|
||||
/**
|
||||
* 卡到期
|
||||
*/
|
||||
@TableField("`CARDEXPIRE`")
|
||||
private String cardExpire;
|
||||
|
||||
/**
|
||||
* 地理围栏ID
|
||||
*/
|
||||
@TableField("`POLYGONFENCE_ID`")
|
||||
private String polygonFence_id;
|
||||
|
||||
/**
|
||||
* 扩展信息
|
||||
*/
|
||||
@TableField("`EXTENDEDSTATE`")
|
||||
private String extendedState;
|
||||
|
||||
/**
|
||||
* 租户号
|
||||
*/
|
||||
@TableField("TENANT_ID")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 乐观锁
|
||||
*/
|
||||
@TableField("RE_VISION")
|
||||
private Integer reVision;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@TableField("CREATE_BY")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("CREATE_TIME")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
@TableField("UPDATE_BY")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 逻辑删除
|
||||
*/
|
||||
@TableField("IS_DEL")
|
||||
private Integer isDel;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField("UPDATE_TIME")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 乐观锁
|
||||
*/
|
||||
@TableField("REVISION")
|
||||
private Integer revision;
|
||||
|
||||
|
||||
@Override
|
||||
protected Serializable pkVal() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
package com.lanhai.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 车辆信息表
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class SurvVehicleInfo extends Model<SurvVehicleInfo> {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "ID", type = IdType.ID_WORKER_STR)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 车辆备注
|
||||
*/
|
||||
@TableField("VE_NOTES")
|
||||
private String veNotes;
|
||||
|
||||
/**
|
||||
* 驾驶员姓名
|
||||
*/
|
||||
@TableField("VE_DRIVER")
|
||||
private String veDriver;
|
||||
|
||||
/**
|
||||
* 车牌号
|
||||
*/
|
||||
@TableField("VE_PLATE")
|
||||
private String vePlate;
|
||||
|
||||
/**
|
||||
* 车辆类型;1=货车,2=卡车,3=农机
|
||||
*/
|
||||
@TableField("VE_TYPE")
|
||||
private String veType;
|
||||
|
||||
/**
|
||||
* 品牌
|
||||
*/
|
||||
@TableField("VE_BRAND")
|
||||
private String veBrand;
|
||||
|
||||
/**
|
||||
* 车型
|
||||
*/
|
||||
@TableField("VE_MODEL")
|
||||
private String veModel;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
@TableField("VE_PHONE")
|
||||
private String vePhone;
|
||||
|
||||
/**
|
||||
* 车辆说明
|
||||
*/
|
||||
@TableField("VE_DES")
|
||||
private String veDes;
|
||||
|
||||
/**
|
||||
* 车辆状态;1=可用,0=暂停
|
||||
*/
|
||||
@TableField("VE_STATUS")
|
||||
private Integer veStatus;
|
||||
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
@TableField("SORT_NO")
|
||||
private Integer sortNo;
|
||||
|
||||
/**
|
||||
* GPSid
|
||||
*/
|
||||
@TableField("GPS_ID")
|
||||
private String gpsId;
|
||||
|
||||
/**
|
||||
* 租户号
|
||||
*/
|
||||
@TableField("TENANT_ID")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 乐观锁
|
||||
*/
|
||||
@TableField("RE_VISION")
|
||||
private Integer reVision;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@TableField("CREATE_BY")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("CREATE_TIME")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
@TableField("UPDATE_BY")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 逻辑删除
|
||||
*/
|
||||
@TableField("IS_DEL")
|
||||
private Integer isDel;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField("UPDATE_TIME")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 乐观锁
|
||||
*/
|
||||
@TableField("REVISION")
|
||||
private Integer revision;
|
||||
|
||||
|
||||
@Override
|
||||
protected Serializable pkVal() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.lanhai.mapper;
|
||||
|
||||
import com.lanhai.entity.SurvGpsInfo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gps信息 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
public interface SurvGpsInfoMapper extends BaseMapper<SurvGpsInfo> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.lanhai.mapper;
|
||||
|
||||
import com.lanhai.entity.SurvGpsRecord;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gsp轨迹记录 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
public interface SurvGpsRecordMapper extends BaseMapper<SurvGpsRecord> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.lanhai.mapper;
|
||||
|
||||
import com.lanhai.entity.SurvVehicleInfo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 车辆信息表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
public interface SurvVehicleInfoMapper extends BaseMapper<SurvVehicleInfo> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?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="com.lanhai.mapper.SurvGpsInfoMapper">
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?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="com.lanhai.mapper.SurvGpsRecordMapper">
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?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="com.lanhai.mapper.SurvVehicleInfoMapper">
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.lanhai.o.iot.szdx;
|
||||
|
||||
import cn.hutool.json.JSONArray;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ResultDeviceData {
|
||||
|
||||
private ResultDeviceDataKeys key;
|
||||
private List<List<Object>> records;
|
||||
private List<String> groups;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.lanhai.o.iot.szdx;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ResultDeviceDataKeys {
|
||||
|
||||
private int sys_time;
|
||||
private int user_name;
|
||||
private int jingdu;
|
||||
private int weidu;
|
||||
private int ljingdu;
|
||||
private int lweidu;
|
||||
private int datetime;
|
||||
private int heart_time;
|
||||
private int su;
|
||||
private int status;
|
||||
private int hangxiang;
|
||||
private int sim_id;
|
||||
private int user_id;
|
||||
private int sale_type;
|
||||
private int iconType;
|
||||
private int server_time;
|
||||
private int product_type;
|
||||
private int expire_date;
|
||||
private int group_id;
|
||||
private int statenumber;
|
||||
private int electric;
|
||||
private int describe;
|
||||
private int sim;
|
||||
private int precision;
|
||||
private int isFollow;
|
||||
private int plateNumber;
|
||||
private int auth;
|
||||
private int authList;
|
||||
private int deptname;
|
||||
private int IsShowLocation;
|
||||
private int tempExt;
|
||||
private int cardExpire;
|
||||
private int polygonFence_id;
|
||||
private int extendedState;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.lanhai.service;
|
||||
|
||||
import com.lanhai.entity.SurvGpsInfo;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gps信息 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
public interface ISurvGpsInfoService extends IService<SurvGpsInfo> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.lanhai.service;
|
||||
|
||||
import com.lanhai.entity.SurvGpsRecord;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gsp轨迹记录 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
public interface ISurvGpsRecordService extends IService<SurvGpsRecord> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.lanhai.service;
|
||||
|
||||
import com.lanhai.entity.SurvVehicleInfo;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 车辆信息表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
public interface ISurvVehicleInfoService extends IService<SurvVehicleInfo> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.lanhai.service.Impl;
|
||||
|
||||
import com.lanhai.entity.SurvGpsInfo;
|
||||
import com.lanhai.mapper.SurvGpsInfoMapper;
|
||||
import com.lanhai.service.ISurvGpsInfoService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gps信息 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Service
|
||||
public class SurvGpsInfoServiceImpl extends ServiceImpl<SurvGpsInfoMapper, SurvGpsInfo> implements ISurvGpsInfoService {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.lanhai.service.Impl;
|
||||
|
||||
import com.lanhai.entity.SurvGpsRecord;
|
||||
import com.lanhai.mapper.SurvGpsRecordMapper;
|
||||
import com.lanhai.service.ISurvGpsRecordService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gsp轨迹记录 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Service
|
||||
public class SurvGpsRecordServiceImpl extends ServiceImpl<SurvGpsRecordMapper, SurvGpsRecord> implements ISurvGpsRecordService {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.lanhai.service.Impl;
|
||||
|
||||
import com.lanhai.entity.SurvVehicleInfo;
|
||||
import com.lanhai.mapper.SurvVehicleInfoMapper;
|
||||
import com.lanhai.service.ISurvVehicleInfoService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 车辆信息表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author ${author}
|
||||
* @since 2026-07-30
|
||||
*/
|
||||
@Service
|
||||
public class SurvVehicleInfoServiceImpl extends ServiceImpl<SurvVehicleInfoMapper, SurvVehicleInfo> implements ISurvVehicleInfoService {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.lanhai.task;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.lanhai.constant.IotConstants;
|
||||
import com.lanhai.constant.PollutionConstants;
|
||||
import com.lanhai.entity.*;
|
||||
import com.lanhai.o.iot.task.DataExamineConfig;
|
||||
import com.lanhai.o.iot.task.DataExamineDetail;
|
||||
import com.lanhai.service.*;
|
||||
import com.lanhai.util.SzDxUtils;
|
||||
import com.xxl.job.core.context.XxlJobHelper;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据校验任务
|
||||
*/
|
||||
//@Component
|
||||
@Slf4j
|
||||
@Component
|
||||
public class GpsRecordTask {
|
||||
@Autowired
|
||||
private ISurvGpsInfoService gpsInfoService;
|
||||
|
||||
@XxlJob("GpsRecordTask")
|
||||
public void TaskHandler() throws Exception{
|
||||
try{
|
||||
XxlJobHelper.log("====================GPS记录任务开始====================");
|
||||
log.warn("====================GPS记录任务开始====================");
|
||||
List<SurvGpsInfo> gpsInfoList = gpsInfoService
|
||||
.lambdaQuery()
|
||||
.eq(SurvGpsInfo::getGpsStatus, 1)
|
||||
.list();
|
||||
|
||||
XxlJobHelper.log("查询到待执行的GpsInfo数量为:" + gpsInfoList.size());
|
||||
log.warn("查询到待执行的GpsInfo数量为:" + gpsInfoList.size());
|
||||
List<String> updIdList = new ArrayList<>();
|
||||
if(!gpsInfoList.isEmpty()){
|
||||
for (SurvGpsInfo survGpsInfo : gpsInfoList) {
|
||||
switch (survGpsInfo.getProtocolCode()){
|
||||
case IotConstants.PROTOCOL_SZDXGPS:
|
||||
boolean b = SzDxUtils.processDeviceData(survGpsInfo);
|
||||
if(b){
|
||||
updIdList.add(survGpsInfo.getId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
XxlJobHelper.log("需要更新的GpsInfo数量为:" + updIdList.size());
|
||||
log.warn("需要更新的GpsInfo数量为:" + updIdList.size());
|
||||
if(!updIdList.isEmpty()){
|
||||
List<SurvGpsInfo> updGpsInfoList = new ArrayList<>();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
for (String id : updIdList) {
|
||||
SurvGpsInfo updGpsInfo = new SurvGpsInfo();
|
||||
updGpsInfo.setId(id);
|
||||
updGpsInfo.setLastSyncTime(now);
|
||||
updGpsInfoList.add(updGpsInfo);
|
||||
}
|
||||
gpsInfoService.updateBatchById(updGpsInfoList);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
XxlJobHelper.log("===================GPS记录任务完成=====================");
|
||||
log.warn("===================GPS记录任务完成=====================");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
package com.lanhai.util;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.lanhai.entity.SurvConfig;
|
||||
import com.lanhai.entity.SurvDeviceDeploy;
|
||||
import com.lanhai.o.vo.HttpResponseVo;
|
||||
import com.lanhai.o.vo.VOIotAccess;
|
||||
import com.lanhai.service.ISurvSurvConfigService;
|
||||
import com.xxl.job.core.context.XxlJobHelper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* IoT厂家工具类(模板)
|
||||
* <p>
|
||||
* 使用方式:复制此类,改类名,改下面4个常量,按需修改各方法
|
||||
*/
|
||||
@Slf4j
|
||||
public class PlainIotUtils {
|
||||
|
||||
// ==================== 改这里 ====================
|
||||
private static final String PROVIDER_CODE = "xxx";
|
||||
private static final String PROVIDER_NAME = "XXX厂家";
|
||||
private static final String ACCESS_CODE = "XXX_ACCESS";
|
||||
private static final String DOMAIN = "https://api.xxx.com";
|
||||
|
||||
// ==================== 常量 ====================
|
||||
private static final String TOKEN_KEY_PREFIX = "iot:token:";
|
||||
private static final String TOKEN_EXPIRE_PREFIX = "iot:token:expire:";
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private static final RedisTemplate<String, String> redisTemplate = SpringContextUtil.getBean(StringRedisTemplate.class);
|
||||
private static final ISurvSurvConfigService configService = SpringContextUtil.getBean(ISurvSurvConfigService.class);
|
||||
|
||||
// ============================================================
|
||||
// 公开方法
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 获取Token(对外入口,含缓存逻辑)
|
||||
*
|
||||
* @param deploy 设备部署信息
|
||||
* @return Token
|
||||
*/
|
||||
public String getToken(SurvDeviceDeploy deploy) {
|
||||
VOIotAccess access = getAccess(deploy);
|
||||
if (access == null) {
|
||||
log.warn("{}: 设备{}密钥未配置", PROVIDER_NAME, deploy.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
// 1. 查缓存
|
||||
String token = getAppToken(PROVIDER_CODE, access.getAppId());
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
return token;
|
||||
}
|
||||
|
||||
// 2. 缓存失效,远程获取
|
||||
log.warn("{}: 缓存失效,重新获取Token", PROVIDER_NAME);
|
||||
token = fetchToken(access);
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
return token;
|
||||
}
|
||||
|
||||
log.error("{}: Token获取最终失败", PROVIDER_NAME);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备实时数据
|
||||
*/
|
||||
public JSONObject getDeviceData(SurvDeviceDeploy deploy) {
|
||||
String token = getToken(deploy);
|
||||
if (StringUtils.isBlank(token)) {
|
||||
log.warn("{}: 设备{}获取Token失败", PROVIDER_NAME, deploy.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
String url = DOMAIN + "/api/device/data";
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("Authorization", token);
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("deviceAddrs", deploy.getDeployCode());
|
||||
params.put("rc", UUID.randomUUID().toString().replace("-", ""));
|
||||
|
||||
String result = HttpReqestUtils.getExchangeImgs(url, params, headers);
|
||||
XxlJobHelper.log("========= {} 实时数据返回: {} =========", PROVIDER_NAME, result);
|
||||
log.info("{} 实时数据返回: {}", PROVIDER_NAME, result);
|
||||
|
||||
if (StringUtils.isNotBlank(result)) {
|
||||
return JSONUtil.toBean(result, JSONObject.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 缓存方法(可复用)
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 从缓存获取Token
|
||||
*
|
||||
* @param providerCode 厂家代号
|
||||
* @param appKey 应用AppKey
|
||||
* @return Token,不存在或已过期返回null
|
||||
*/
|
||||
public static String getAppToken(String providerCode, String appKey) {
|
||||
if (StringUtils.isAnyBlank(providerCode, appKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String tokenKey = TOKEN_KEY_PREFIX + providerCode + ":" + appKey;
|
||||
String expireKey = TOKEN_EXPIRE_PREFIX + providerCode + ":" + appKey;
|
||||
|
||||
// 检查key是否存在
|
||||
if (Boolean.FALSE.equals(redisTemplate.hasKey(tokenKey))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String token = CommonToolUtils.getString(redisTemplate.opsForValue().get(tokenKey), "");
|
||||
String expireTimeStr = CommonToolUtils.getString(redisTemplate.opsForValue().get(expireKey), "");
|
||||
|
||||
if (StringUtils.isAnyBlank(token, expireTimeStr)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 检查是否过期
|
||||
try {
|
||||
LocalDateTime expireTime = LocalDateTime.parse(expireTimeStr, FORMATTER);
|
||||
if (LocalDateTime.now().isBefore(expireTime)) {
|
||||
log.debug("{}: 命中缓存Token", providerCode);
|
||||
return token;
|
||||
}
|
||||
} catch (DateTimeParseException e) {
|
||||
log.warn("Token过期时间解析失败: providerCode={}, expireTimeStr={}", providerCode, expireTimeStr, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存Token
|
||||
*
|
||||
* @param providerCode 厂家代号
|
||||
* @param appKey 应用AppKey
|
||||
* @param token Token值
|
||||
* @param expireTime 过期时间(格式:yyyy-MM-dd HH:mm:ss)
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean setAppToken(String providerCode, String appKey, String token, String expireTime) {
|
||||
if (StringUtils.isAnyBlank(providerCode, appKey, token, expireTime)) {
|
||||
log.warn("setAppToken参数不完整");
|
||||
return false;
|
||||
}
|
||||
|
||||
String tokenKey = TOKEN_KEY_PREFIX + providerCode + ":" + appKey;
|
||||
String expireKey = TOKEN_EXPIRE_PREFIX + providerCode + ":" + appKey;
|
||||
|
||||
redisTemplate.opsForValue().set(tokenKey, token);
|
||||
redisTemplate.opsForValue().set(expireKey, expireTime);
|
||||
|
||||
log.info("Token缓存成功: providerCode={}, appKey={}, expireTime={}", providerCode, appKey, expireTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 私有方法
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 获取应用凭证
|
||||
*/
|
||||
private VOIotAccess getAccess(SurvDeviceDeploy deploy) {
|
||||
if (deploy == null) {
|
||||
log.warn("getAccess: deploy为null");
|
||||
return null;
|
||||
}
|
||||
|
||||
SurvConfig config = null;
|
||||
|
||||
// 优先使用设备绑定的配置
|
||||
if (StringUtils.isNotBlank(deploy.getSurvConfigId())) {
|
||||
config = configService.getConfigById(deploy.getSurvConfigId());
|
||||
} else {
|
||||
// 否则按租户+对接识别码查询
|
||||
config = configService.getOneByTypeWithTenant(deploy.getTenantId(), ACCESS_CODE);
|
||||
}
|
||||
|
||||
if (config == null) {
|
||||
log.warn("未找到配置: tenantId={}, configId={}, accessCode={}",
|
||||
deploy.getTenantId(), deploy.getSurvConfigId(), ACCESS_CODE);
|
||||
return null;
|
||||
}
|
||||
|
||||
VOIotAccess access = new VOIotAccess();
|
||||
access.setAppId(config.getConfigKey());
|
||||
access.setAppSecret(config.getConfigValue());
|
||||
return access;
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程获取Token并缓存
|
||||
*/
|
||||
private String fetchToken(VOIotAccess access) {
|
||||
if (access == null || StringUtils.isAnyBlank(access.getAppId(), access.getAppSecret())) {
|
||||
log.warn("fetchToken: 凭证不完整");
|
||||
return null;
|
||||
}
|
||||
|
||||
String url = DOMAIN + "/api/getToken";
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("loginName", access.getAppId());
|
||||
params.put("password", access.getAppSecret());
|
||||
|
||||
HttpResponseVo response = HttpReqestUtils.getExchange(url, params, new HashMap<>());
|
||||
|
||||
if (!response.isOk()) {
|
||||
log.error("{} Token请求失败: httpCode", PROVIDER_NAME);
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject respJson = response.getData();
|
||||
if (respJson == null) {
|
||||
log.error("{} Token响应为空", PROVIDER_NAME);
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject data = respJson.getJSONObject("data");
|
||||
if (data == null) {
|
||||
log.error("{} Token响应data为空, response={}", PROVIDER_NAME, respJson);
|
||||
return null;
|
||||
}
|
||||
|
||||
String token = data.getString("token");
|
||||
Long expireSeconds = data.getLong("expiration");
|
||||
|
||||
if (StringUtils.isBlank(token)) {
|
||||
log.error("{} Token获取失败: {}", PROVIDER_NAME, respJson.getString("msg"));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expireSeconds == null || expireSeconds <= 0) {
|
||||
log.warn("{} Token过期时间为空或无效,使用默认2小时", PROVIDER_NAME);
|
||||
expireSeconds = 7200L;
|
||||
}
|
||||
|
||||
// 缓存Token
|
||||
String expireTimeStr = LocalDateTime.now().plusSeconds(expireSeconds).format(FORMATTER);
|
||||
setAppToken(PROVIDER_CODE, access.getAppId(), token, expireTimeStr);
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,327 @@
|
|||
package com.lanhai.util;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.lanhai.entity.SurvConfig;
|
||||
import com.lanhai.entity.SurvDeviceDeploy;
|
||||
import com.lanhai.entity.SurvGpsInfo;
|
||||
import com.lanhai.entity.SurvGpsRecord;
|
||||
import com.lanhai.o.iot.szdx.ResultDeviceData;
|
||||
import com.lanhai.o.iot.szdx.ResultDeviceDataKeys;
|
||||
import com.lanhai.o.vo.HttpResponseVo;
|
||||
import com.lanhai.o.vo.VOIotAccess;
|
||||
import com.lanhai.service.ISurvGpsRecordService;
|
||||
import com.lanhai.service.ISurvSurvConfigService;
|
||||
import com.xxl.job.core.context.XxlJobHelper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* IoT厂家工具类(模板)
|
||||
* <p>
|
||||
* 使用方式:复制此类,改类名,改下面4个常量,按需修改各方法
|
||||
*/
|
||||
@Slf4j
|
||||
public class SzDxUtils {
|
||||
|
||||
// ==================== 改这里 ====================
|
||||
private static final String PROVIDER_CODE = "DiXinSoft";
|
||||
private static final String PROVIDER_NAME = "深圳帝馨";
|
||||
private static final String ACCESS_CODE = "dxsoft_access";
|
||||
private static final String DOMAIN = "http://api.18gps.net/GetDateServices.asmx";
|
||||
|
||||
// ==================== 常量 ====================
|
||||
private static final String TOKEN_KEY_PREFIX = "iot:token:";
|
||||
private static final String TOKEN_EXPIRE_PREFIX = "iot:token:expire:";
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private static final RedisTemplate<String, String> redisTemplate = SpringContextUtil.getBean(StringRedisTemplate.class);
|
||||
private static final ISurvSurvConfigService configService = SpringContextUtil.getBean(ISurvSurvConfigService.class);
|
||||
private static final ISurvGpsRecordService gpsRecordService = SpringContextUtil.getBean(ISurvGpsRecordService.class);
|
||||
// ============================================================
|
||||
// 公开方法
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 获取Token(对外入口,含缓存逻辑)
|
||||
*
|
||||
* @param gpsInfo 设备部署信息
|
||||
* @return Token
|
||||
*/
|
||||
public static String getToken(SurvGpsInfo gpsInfo) {
|
||||
VOIotAccess access = getAccess(gpsInfo);
|
||||
if (access == null) {
|
||||
log.warn("{}: 设备{}密钥未配置", PROVIDER_NAME, gpsInfo.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
// 1. 查缓存
|
||||
String token = getAppToken(PROVIDER_CODE, access.getAppId());
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
return token;
|
||||
}
|
||||
|
||||
// 2. 缓存失效,远程获取
|
||||
log.warn("{}: 缓存失效,重新获取Token", PROVIDER_NAME);
|
||||
token = fetchToken(access);
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
return token;
|
||||
}
|
||||
|
||||
log.error("{}: Token获取最终失败", PROVIDER_NAME);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备实时数据
|
||||
*/
|
||||
public static ResultDeviceData getDeviceData(SurvGpsInfo gpsInfo) {
|
||||
String token = getToken(gpsInfo);
|
||||
if (StringUtils.isBlank(token)) {
|
||||
log.warn("{}: 设备{}获取Token失败", PROVIDER_NAME, gpsInfo.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
String url = DOMAIN + "/GetDate?mapType=GAODE&mds={mds}&method=getUserAndGpsInfoByIDsUtc&option=cn&user_id={user_id}";
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("mds", token);
|
||||
params.put("user_id", gpsInfo.getGpsDeviceId());
|
||||
|
||||
String result = HttpReqestUtils.getExchangeImgs(url, params, headers);
|
||||
//转utf-8编码
|
||||
result = new String(
|
||||
result.getBytes(StandardCharsets.ISO_8859_1),
|
||||
StandardCharsets.UTF_8
|
||||
);
|
||||
|
||||
XxlJobHelper.log("========= {} 实时数据返回: {} =========", PROVIDER_NAME, result);
|
||||
log.info("{} 实时数据返回: {}", PROVIDER_NAME, result);
|
||||
|
||||
if (StringUtils.isNotBlank(result)) {
|
||||
return JSONUtil.toBean(result, ResultDeviceData.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 缓存方法(可复用)
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 从缓存获取Token
|
||||
*
|
||||
* @param providerCode 厂家代号
|
||||
* @param appKey 应用AppKey
|
||||
* @return Token,不存在或已过期返回null
|
||||
*/
|
||||
public static String getAppToken(String providerCode, String appKey) {
|
||||
if (StringUtils.isAnyBlank(providerCode, appKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String tokenKey = TOKEN_KEY_PREFIX + providerCode + ":" + appKey;
|
||||
String expireKey = TOKEN_EXPIRE_PREFIX + providerCode + ":" + appKey;
|
||||
|
||||
// 检查key是否存在
|
||||
if (Boolean.FALSE.equals(redisTemplate.hasKey(tokenKey))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String token = CommonToolUtils.getString(redisTemplate.opsForValue().get(tokenKey), "");
|
||||
String expireTimeStr = CommonToolUtils.getString(redisTemplate.opsForValue().get(expireKey), "");
|
||||
|
||||
if (StringUtils.isAnyBlank(token, expireTimeStr)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 检查是否过期
|
||||
try {
|
||||
LocalDateTime expireTime = LocalDateTime.parse(expireTimeStr, FORMATTER);
|
||||
if (LocalDateTime.now().isBefore(expireTime)) {
|
||||
log.debug("{}: 命中缓存Token", providerCode);
|
||||
return token;
|
||||
}
|
||||
} catch (DateTimeParseException e) {
|
||||
log.warn("Token过期时间解析失败: providerCode={}, expireTimeStr={}", providerCode, expireTimeStr, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存Token
|
||||
*
|
||||
* @param providerCode 厂家代号
|
||||
* @param appKey 应用AppKey
|
||||
* @param token Token值
|
||||
* @param expireTime 过期时间(格式:yyyy-MM-dd HH:mm:ss)
|
||||
* @return 是否成功
|
||||
*/
|
||||
public static boolean setAppToken(String providerCode, String appKey, String token, String expireTime) {
|
||||
if (StringUtils.isAnyBlank(providerCode, appKey, token, expireTime)) {
|
||||
log.warn("setAppToken参数不完整");
|
||||
return false;
|
||||
}
|
||||
|
||||
String tokenKey = TOKEN_KEY_PREFIX + providerCode + ":" + appKey;
|
||||
String expireKey = TOKEN_EXPIRE_PREFIX + providerCode + ":" + appKey;
|
||||
|
||||
redisTemplate.opsForValue().set(tokenKey, token);
|
||||
redisTemplate.opsForValue().set(expireKey, expireTime);
|
||||
|
||||
log.info("Token缓存成功: providerCode={}, appKey={}, expireTime={}", providerCode, appKey, expireTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 私有方法
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 获取应用凭证
|
||||
*/
|
||||
private static VOIotAccess getAccess(SurvGpsInfo gpsInfo) {
|
||||
if (gpsInfo == null) {
|
||||
log.warn("getAccess: gpsInfo为null");
|
||||
return null;
|
||||
}
|
||||
|
||||
SurvConfig config = null;
|
||||
|
||||
// 优先使用设备绑定的配置
|
||||
config = configService.getConfigById(gpsInfo.getSurvConfigId());
|
||||
|
||||
if (config == null) {
|
||||
log.warn("未找到配置: tenantId={}, configId={}, accessCode={}",
|
||||
gpsInfo.getTenantId(), gpsInfo.getSurvConfigId(), ACCESS_CODE);
|
||||
return null;
|
||||
}
|
||||
|
||||
VOIotAccess access = new VOIotAccess();
|
||||
access.setAppId(config.getConfigKey());
|
||||
access.setAppSecret(config.getConfigValue());
|
||||
return access;
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程获取Token并缓存
|
||||
*/
|
||||
private static String fetchToken(VOIotAccess access) {
|
||||
if (access == null || StringUtils.isAnyBlank(access.getAppId(), access.getAppSecret())) {
|
||||
log.warn("fetchToken: 凭证不完整");
|
||||
return null;
|
||||
}
|
||||
|
||||
String url = DOMAIN + "/loginSystem?LoginName={loginName}&LoginPassword={password}&LoginType=ENTERPRISE&language=cn&timeZone=+08&apply=APP";
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("loginName", access.getAppId());
|
||||
params.put("password", access.getAppSecret());
|
||||
|
||||
String response = HttpReqestUtils.getExchangeImgs(url, params, new HashMap<>());
|
||||
|
||||
|
||||
|
||||
if (StringUtils.isBlank(response)) {
|
||||
log.error("{} Token响应为空", PROVIDER_NAME);
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject respJson = JSONObject.parseObject(response);
|
||||
|
||||
String token = respJson.getString("mds");
|
||||
Long expireSeconds = 20 * 60L;//20分钟有效期
|
||||
|
||||
if (StringUtils.isBlank(token)) {
|
||||
log.error("{} Token获取失败: {}", PROVIDER_NAME, respJson.getString("msg"));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expireSeconds == null || expireSeconds <= 0) {
|
||||
log.warn("{} Token过期时间为空或无效,使用默认20分钟", PROVIDER_NAME);
|
||||
expireSeconds = 20 * 60L;
|
||||
}
|
||||
|
||||
// 缓存Token
|
||||
String expireTimeStr = LocalDateTime.now().plusSeconds(expireSeconds).format(FORMATTER);
|
||||
setAppToken(PROVIDER_CODE, access.getAppId(), token, expireTimeStr);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
public static boolean processDeviceData(SurvGpsInfo survGpsInfo){
|
||||
boolean isSuccess = false;
|
||||
if(survGpsInfo != null){
|
||||
ResultDeviceData resultDeviceData = getDeviceData(survGpsInfo);
|
||||
if(resultDeviceData != null){
|
||||
if(resultDeviceData.getRecords()!=null){
|
||||
Field[] fields = ResultDeviceDataKeys.class.getDeclaredFields();
|
||||
List<Object> record = resultDeviceData.getRecords().get(0);
|
||||
SurvGpsRecord gpsRecord = new SurvGpsRecord();
|
||||
gpsRecord.setGpsDeviceId(survGpsInfo.getGpsDeviceId());
|
||||
gpsRecord.setGpsId(survGpsInfo.getId());
|
||||
gpsRecord.setGpsCode(survGpsInfo.getGpsCode());
|
||||
gpsRecord.setGpsIdent(survGpsInfo.getGpsIdent());
|
||||
gpsRecord.setTenantId(survGpsInfo.getTenantId());
|
||||
for (Field field : fields) {
|
||||
field.setAccessible(true);
|
||||
String fieldName = field.getName();
|
||||
try{
|
||||
Object keyNum = field.get(resultDeviceData.getKey());
|
||||
int keyNumInt = Integer.parseInt(keyNum.toString());
|
||||
Object value = record.get(keyNumInt);
|
||||
log.error("{}-获取值:{}",fieldName,value);
|
||||
XxlJobHelper.log("{}-获取值:{}",fieldName,value);
|
||||
String strVal = String.valueOf(value);
|
||||
if(fieldName.equals("sys_time")){//数据采集时间
|
||||
LocalDateTime sysTime = Instant.ofEpochMilli(Long.parseLong(strVal)).atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
gpsRecord.setDataDateTime(sysTime);
|
||||
gpsRecord.setDataId(gpsRecord.getGpsCode()+"_"+strVal);
|
||||
}
|
||||
|
||||
TUtil.setFieldValue(gpsRecord, fieldName, strVal);
|
||||
}catch ( Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
if(gpsRecord.getDataId()!=null){
|
||||
int checks = gpsRecordService.lambdaQuery()
|
||||
.eq(SurvGpsRecord::getDataId,gpsRecord.getDataId())
|
||||
.count();
|
||||
if(checks==0){
|
||||
gpsRecordService.save(gpsRecord);
|
||||
isSuccess = true;
|
||||
}else{
|
||||
log.error("==={}===设备:{}-{}==gps数据校验重复,数据id为{}====",PROVIDER_NAME,survGpsInfo.getGpsName(),survGpsInfo.getGpsCode(),gpsRecord.getDataId());
|
||||
XxlJobHelper.log("==={}===设备:{}-{}==gps数据校验重复,数据id为{}====",PROVIDER_NAME,survGpsInfo.getGpsName(),survGpsInfo.getGpsCode(),gpsRecord.getDataId());
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
log.error("==={}===设备:{}-{}==gps数据构造失败,数据id为空====",PROVIDER_NAME,survGpsInfo.getGpsName(),survGpsInfo.getGpsCode());
|
||||
XxlJobHelper.log("==={}===设备:{}-{}==gps数据构造失败,数据id为空====",PROVIDER_NAME,survGpsInfo.getGpsName(),survGpsInfo.getGpsCode());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return isSuccess;
|
||||
}
|
||||
}
|
||||
|
|
@ -38,18 +38,18 @@ spring:
|
|||
pathmatch:
|
||||
matching-strategy: ant_path_matcher #解决springboot高版本和swagger的集成问题
|
||||
|
||||
# redis:
|
||||
# port: 6379
|
||||
# host: 49.233.25.219
|
||||
# database: 10
|
||||
# password: zfs_123!
|
||||
# jedis:
|
||||
# pool:
|
||||
# min-idle: 0
|
||||
# max-idle: 10
|
||||
# max-wait: -1
|
||||
# max-active: 20
|
||||
# timeout: 1000
|
||||
redis:
|
||||
port: 6379
|
||||
host: 127.0.0.1
|
||||
database: 8
|
||||
password: 123456
|
||||
jedis:
|
||||
pool:
|
||||
min-idle: 0
|
||||
max-idle: 10
|
||||
max-wait: -1
|
||||
max-active: 20
|
||||
timeout: 1000
|
||||
|
||||
|
||||
mybatis-plus:
|
||||
|
|
@ -66,18 +66,18 @@ logging:
|
|||
|
||||
xxl:
|
||||
job:
|
||||
accessToken: lhzn.20241215
|
||||
accessToken: lhzn.20251111
|
||||
admin:
|
||||
addresses: http://192.168.0.4:10003/xxl-job-admin
|
||||
addresses: http://192.168.2.110:10003/xxl-job-admin
|
||||
executor:
|
||||
appname: jngjTask
|
||||
appname: fxTask
|
||||
address:
|
||||
ip:
|
||||
port: 10004
|
||||
logpath: /logs/xxl-job/jobhandler
|
||||
logretentiondays: 30
|
||||
mqtt:
|
||||
enabled: true
|
||||
enabled: false
|
||||
# 指定默认客户端名称(可选)
|
||||
default-client: broker1
|
||||
# 多客户端配置
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
spring:
|
||||
profiles:
|
||||
active: prod #
|
||||
active: local #
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue