南岐GPS三方接口对接
This commit is contained in:
+214
@@ -0,0 +1,214 @@
|
||||
package com.linke.thirdParty.application.server;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.linke.thirdParty.domain.departInterfaceInfo.repository.todo.SysDepartInterfaceInfoDo;
|
||||
import com.linke.thirdParty.infrastructure.dict.NanqiGpsConstant;
|
||||
import com.linke.thirdParty.interfaces.vo.gps.NanqiGpsLocationVO;
|
||||
import com.mhd.common.core.domain.po.thirdparty.SysDepartInterfaceInfoPo;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.utils.HttpClientUtil;
|
||||
import com.mhd.common.redis.service.RedisService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 南岐车联网GPS平台 对接应用服务
|
||||
*
|
||||
* <p>提供两个接口:</p>
|
||||
* <ol>
|
||||
* <li>login:登录获取 sessionId,并缓存到 Redis</li>
|
||||
* <li>queryByPlate:根据车牌号+sessionId 查询车辆实时定位</li>
|
||||
* </ol>
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class NanqiGpsApplicationService {
|
||||
|
||||
@Autowired
|
||||
private SysDepartInterfaceInfoApplicationService interfaceInfoApplicationService;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* 南岐登录账号
|
||||
*/
|
||||
private String userId = NanqiGpsConstant.DEFAULT_USER_ID;
|
||||
|
||||
/**
|
||||
* 南岐登录密码(明文)
|
||||
*/
|
||||
private String password = NanqiGpsConstant.DEFAULT_PASSWORD;
|
||||
|
||||
/**
|
||||
* 从三方接口配置表读取南岐配置(interfaceType = nanqi_gps),未配置则使用默认值
|
||||
*/
|
||||
private void getBaseInfo() {
|
||||
SysDepartInterfaceInfoDo sysDepartInterfaceInfoDo = new SysDepartInterfaceInfoDo();
|
||||
sysDepartInterfaceInfoDo.setInterfaceType(NanqiGpsConstant.INTERFACE_TYPE);
|
||||
List<SysDepartInterfaceInfoPo> sysDepartInterfaceInfoPos = interfaceInfoApplicationService.queryList1(sysDepartInterfaceInfoDo);
|
||||
if (sysDepartInterfaceInfoPos == null || sysDepartInterfaceInfoPos.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (SysDepartInterfaceInfoPo info : sysDepartInterfaceInfoPos) {
|
||||
String key = info.getInterfaceTypeKey();
|
||||
String value = info.getInterfaceTypeValue();
|
||||
if ("userId".equals(key)) {
|
||||
userId = value;
|
||||
} else if ("password".equals(key)) {
|
||||
password = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录获取 sessionId(若 Redis 已有有效 sessionId 则直接复用)
|
||||
*
|
||||
* @return sessionId
|
||||
*/
|
||||
public String login() {
|
||||
return getSessionId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有效 sessionId:优先从 Redis 取,取不到则调用登录接口重新获取
|
||||
*
|
||||
* @return sessionId
|
||||
*/
|
||||
public String getSessionId() {
|
||||
String cacheKey = NanqiGpsConstant.SESSION_ID_KEY;
|
||||
String sessionId = redisService.getCacheObject(cacheKey);
|
||||
if (sessionId != null && !sessionId.isEmpty()) {
|
||||
return sessionId;
|
||||
}
|
||||
// 重新登录
|
||||
getBaseInfo();
|
||||
sessionId = doLogin(userId, password, NanqiGpsConstant.LOGIN_TYPE_USER);
|
||||
if (sessionId != null && !sessionId.isEmpty()) {
|
||||
redisService.setCacheObject(cacheKey, sessionId, NanqiGpsConstant.SESSION_ID_EXPIRE_SECONDS, TimeUnit.SECONDS);
|
||||
}
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动刷新 sessionId(强制重新登录,忽略缓存)
|
||||
*
|
||||
* @return sessionId
|
||||
*/
|
||||
public String refreshSessionId() {
|
||||
redisService.deleteObject(NanqiGpsConstant.SESSION_ID_KEY);
|
||||
return getSessionId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行南岐登录接口
|
||||
*
|
||||
* @param loginUserId 登录账号
|
||||
* @param loginPassword 登录密码(明文)
|
||||
* @param loginType user-用户 car-车辆/人员
|
||||
* @return sessionId
|
||||
*/
|
||||
private String doLogin(String loginUserId, String loginPassword, String loginType) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("userId", loginUserId);
|
||||
// 密码需要 MD5 32 位小写加密
|
||||
String md5Pwd = DigestUtils.md5DigestAsHex(loginPassword.getBytes()).toLowerCase();
|
||||
params.put("password", md5Pwd);
|
||||
params.put("loginType", loginType == null ? NanqiGpsConstant.LOGIN_TYPE_USER : loginType);
|
||||
params.put("loginWay", NanqiGpsConstant.DEFAULT_LOGIN_WAY);
|
||||
params.put("loginLang", NanqiGpsConstant.DEFAULT_LOGIN_LANG);
|
||||
|
||||
String result = HttpClientUtil.doGet(NanqiGpsConstant.LOGIN_URL, params);
|
||||
log.info("南岐GPS登录返回: {}", result);
|
||||
JSONObject json = JSON.parseObject(result);
|
||||
if (json == null) {
|
||||
throw new ServiceException("南岐GPS登录接口无响应");
|
||||
}
|
||||
Integer rspCode = json.getInteger("rspCode");
|
||||
if (rspCode == null || rspCode != 1) {
|
||||
throw new ServiceException("南岐GPS登录失败:" + json.getString("rspDesc"));
|
||||
}
|
||||
return json.getString("sessionId");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据车牌号查询车辆实时定位
|
||||
*
|
||||
* @param carPlate 车牌号
|
||||
* @return 车辆定位信息
|
||||
*/
|
||||
public NanqiGpsLocationVO queryByPlate(String carPlate) {
|
||||
if (carPlate == null || carPlate.trim().isEmpty()) {
|
||||
throw new ServiceException("车牌号不能为空");
|
||||
}
|
||||
String sessionId = getSessionId();
|
||||
if (sessionId == null || sessionId.isEmpty()) {
|
||||
throw new ServiceException("获取南岐GPS sessionId失败");
|
||||
}
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("carPlate", carPlate.trim());
|
||||
params.put("sessionId", sessionId);
|
||||
|
||||
String result = HttpClientUtil.doGet(NanqiGpsConstant.GET_GPS_URL, params);
|
||||
log.info("南岐GPS查询车辆[{}]返回: {}", carPlate, result);
|
||||
JSONObject json = JSON.parseObject(result);
|
||||
if (json == null) {
|
||||
throw new ServiceException("南岐GPS查询接口无响应");
|
||||
}
|
||||
Integer rspCode = json.getInteger("rspCode");
|
||||
if (rspCode == null || rspCode != 1) {
|
||||
// 可能是 sessionId 失效,尝试刷新后重试一次
|
||||
String newSessionId = refreshSessionId();
|
||||
params.put("sessionId", newSessionId);
|
||||
result = HttpClientUtil.doGet(NanqiGpsConstant.GET_GPS_URL, params);
|
||||
json = JSON.parseObject(result);
|
||||
if (json == null || !Integer.valueOf(1).equals(json.getInteger("rspCode"))) {
|
||||
throw new ServiceException("南岐GPS查询失败:" + (json == null ? "" : json.getString("rspDesc")));
|
||||
}
|
||||
}
|
||||
|
||||
NanqiGpsLocationVO vo = new NanqiGpsLocationVO();
|
||||
vo.setRspCode(json.getInteger("rspCode"));
|
||||
vo.setRspDesc(json.getString("rspDesc"));
|
||||
|
||||
JSONArray list = json.getJSONArray("list");
|
||||
if (list != null && !list.isEmpty()) {
|
||||
JSONObject loc = list.getJSONObject(0);
|
||||
vo.setCarId(loc.getString("carId"));
|
||||
vo.setCarPlate(loc.getString("carPlate"));
|
||||
vo.setCarName(loc.getString("carName"));
|
||||
vo.setTeamId(loc.getString("teamId"));
|
||||
vo.setTeamName(loc.getString("teamName"));
|
||||
vo.setTime(loc.getString("time"));
|
||||
vo.setLng(loc.getBigDecimal("lng"));
|
||||
vo.setLat(loc.getBigDecimal("lat"));
|
||||
vo.setSpeed(loc.getBigDecimal("speed"));
|
||||
vo.setDrct(loc.getString("drct"));
|
||||
vo.setMile(loc.getString("mile"));
|
||||
vo.setPreMile(loc.getString("preMile"));
|
||||
vo.setSatl(loc.getString("satl"));
|
||||
vo.setSgn(loc.getString("sgn"));
|
||||
vo.setAddr(loc.getString("addr"));
|
||||
vo.setState(loc.getString("state"));
|
||||
vo.setStateCn(loc.getString("stateCn"));
|
||||
vo.setDrvName(loc.getString("drvName"));
|
||||
vo.setDrvPhone(loc.getString("drvPhone"));
|
||||
vo.setCarType(loc.getString("carType"));
|
||||
vo.setExpState(loc.getString("expState"));
|
||||
vo.setExpTime(loc.getString("expTime"));
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
Vendored
+64
@@ -0,0 +1,64 @@
|
||||
package com.linke.thirdParty.infrastructure.dict;
|
||||
|
||||
/**
|
||||
* 南岐车联网GPS平台 接口常量
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
public class NanqiGpsConstant {
|
||||
|
||||
/**
|
||||
* 三方接口配置表 interfaceType(对应 sys_depart_interface_info 表)
|
||||
*/
|
||||
public static final String INTERFACE_TYPE = "nanqi_gps";
|
||||
|
||||
/**
|
||||
* 登录接口地址(第一接口)
|
||||
*/
|
||||
public static final String LOGIN_URL = "http://iov.yotugo.com/gps-web/api/login.jsp";
|
||||
|
||||
/**
|
||||
* 车辆定位查询接口地址(第二接口)
|
||||
*/
|
||||
public static final String GET_GPS_URL = "http://iov.yotugo.com/gps-web/api/get_gps_r_plate.jsp";
|
||||
|
||||
/**
|
||||
* 登录账号(默认值,可被 sys_depart_interface_info 配置覆盖,key 为 userId)
|
||||
*/
|
||||
public static final String DEFAULT_USER_ID = "zhnanqi";
|
||||
|
||||
/**
|
||||
* 登录密码(默认值,明文,可被配置覆盖,key 为 password)
|
||||
*/
|
||||
public static final String DEFAULT_PASSWORD = "nq123456";
|
||||
|
||||
/**
|
||||
* 登录方式:默认 interface
|
||||
*/
|
||||
public static final String DEFAULT_LOGIN_WAY = "interface";
|
||||
|
||||
/**
|
||||
* 登录语言:默认中文
|
||||
*/
|
||||
public static final String DEFAULT_LOGIN_LANG = "zh_CN";
|
||||
|
||||
/**
|
||||
* 登录类型:car 表示按车辆/人员登录
|
||||
*/
|
||||
public static final String LOGIN_TYPE_CAR = "car";
|
||||
|
||||
/**
|
||||
* 登录类型:user 表示按用户登录
|
||||
*/
|
||||
public static final String LOGIN_TYPE_USER = "user";
|
||||
|
||||
/**
|
||||
* sessionId 缓存 key 前缀
|
||||
*/
|
||||
public static final String SESSION_ID_KEY = "nanqi_gps:sessionId:";
|
||||
|
||||
/**
|
||||
* sessionId 缓存时长(秒),默认 12 小时
|
||||
*/
|
||||
public static final long SESSION_ID_EXPIRE_SECONDS = 12 * 60 * 60L;
|
||||
}
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
package com.linke.thirdParty.interfaces.dto.gps;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 南岐GPS 登录入参
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("南岐GPS 登录入参")
|
||||
public class NanqiGpsLoginDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "登录用户/车牌号(loginType=user填用户ID,loginType=car填车牌号),为空时使用平台配置的账号", required = false)
|
||||
private String userId;
|
||||
|
||||
@ApiModelProperty(value = "登录密码(明文,内部会MD5小写加密),为空时使用平台配置的密码", required = false)
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty(value = "登录类型:user-用户 car-车辆/人员,默认car", required = false)
|
||||
private String loginType;
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.linke.thirdParty.interfaces.facade;
|
||||
|
||||
import com.linke.thirdParty.application.server.NanqiGpsApplicationService;
|
||||
import com.linke.thirdParty.interfaces.vo.gps.NanqiGpsLocationVO;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.web.domain.AjaxResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 南岐车联网GPS平台 接口
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/nanqiGps")
|
||||
@Api(tags = "南岐车联网GPS")
|
||||
@Slf4j
|
||||
public class NanqiGpsApi {
|
||||
|
||||
@Autowired
|
||||
private NanqiGpsApplicationService nanqiGpsApplicationService;
|
||||
|
||||
/**
|
||||
* 登录获取 sessionId
|
||||
*/
|
||||
@ApiOperation(value = "登录获取sessionId", notes = "登录获取南岐GPS平台sessionId(Redis缓存复用)")
|
||||
@GetMapping(value = "/login")
|
||||
public AjaxResult login() {
|
||||
try {
|
||||
String sessionId = nanqiGpsApplicationService.login();
|
||||
return AjaxResult.success("操作成功", sessionId);
|
||||
} catch (ServiceException e) {
|
||||
return AjaxResult.error(500, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("南岐GPS登录失败", e);
|
||||
return AjaxResult.error(500, "操作失败" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动刷新 sessionId
|
||||
*/
|
||||
@ApiOperation(value = "手动刷新sessionId", notes = "强制重新登录南岐GPS平台,忽略缓存")
|
||||
@GetMapping(value = "/refreshSessionId")
|
||||
public AjaxResult refreshSessionId() {
|
||||
try {
|
||||
String sessionId = nanqiGpsApplicationService.refreshSessionId();
|
||||
return AjaxResult.success("操作成功", sessionId);
|
||||
} catch (ServiceException e) {
|
||||
return AjaxResult.error(500, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("南岐GPS刷新sessionId失败", e);
|
||||
return AjaxResult.error(500, "操作失败" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据车牌号查询车辆实时定位
|
||||
*/
|
||||
@ApiOperation(value = "根据车牌号查询车辆实时定位", notes = "通过车牌号查询南岐GPS车辆实时定位")
|
||||
@GetMapping(value = "/queryByPlate")
|
||||
public AjaxResult queryByPlate(@RequestParam(value = "carPlate") String carPlate) {
|
||||
try {
|
||||
NanqiGpsLocationVO vo = nanqiGpsApplicationService.queryByPlate(carPlate);
|
||||
return AjaxResult.success("操作成功", vo);
|
||||
} catch (ServiceException e) {
|
||||
return AjaxResult.error(500, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("南岐GPS查询车辆[{}]定位失败", carPlate, e);
|
||||
return AjaxResult.error(500, "操作失败" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+92
@@ -0,0 +1,92 @@
|
||||
package com.linke.thirdParty.interfaces.vo.gps;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 南岐GPS 车辆定位信息 VO(对应文档 表1 常用字段)
|
||||
*
|
||||
* @author mhd
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("南岐GPS 车辆定位信息")
|
||||
public class NanqiGpsLocationVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("应答结果:1成功 0失败")
|
||||
private Integer rspCode;
|
||||
|
||||
@ApiModelProperty("应答描述")
|
||||
private String rspDesc;
|
||||
|
||||
@ApiModelProperty("车辆id")
|
||||
private String carId;
|
||||
|
||||
@ApiModelProperty("车牌号")
|
||||
private String carPlate;
|
||||
|
||||
@ApiModelProperty("车辆名")
|
||||
private String carName;
|
||||
|
||||
@ApiModelProperty("车队id")
|
||||
private String teamId;
|
||||
|
||||
@ApiModelProperty("车队名称")
|
||||
private String teamName;
|
||||
|
||||
@ApiModelProperty("定位时间")
|
||||
private String time;
|
||||
|
||||
@ApiModelProperty("经度(WGS84)")
|
||||
private BigDecimal lng;
|
||||
|
||||
@ApiModelProperty("纬度(WGS84)")
|
||||
private BigDecimal lat;
|
||||
|
||||
@ApiModelProperty("速度(千米/小时)")
|
||||
private BigDecimal speed;
|
||||
|
||||
@ApiModelProperty("方向 0~360")
|
||||
private String drct;
|
||||
|
||||
@ApiModelProperty("平台总里程(千米)")
|
||||
private String mile;
|
||||
|
||||
@ApiModelProperty("今日里程(千米)")
|
||||
private String preMile;
|
||||
|
||||
@ApiModelProperty("定位信号:0无 弱<=3 中<=6 强>6")
|
||||
private String satl;
|
||||
|
||||
@ApiModelProperty("通讯信号:0无 弱<=10 中<=20 强>20")
|
||||
private String sgn;
|
||||
|
||||
@ApiModelProperty("地理描述")
|
||||
private String addr;
|
||||
|
||||
@ApiModelProperty("车辆定位状态")
|
||||
private String state;
|
||||
|
||||
@ApiModelProperty("车辆状态文字")
|
||||
private String stateCn;
|
||||
|
||||
@ApiModelProperty("驾驶员")
|
||||
private String drvName;
|
||||
|
||||
@ApiModelProperty("驾驶员电话")
|
||||
private String drvPhone;
|
||||
|
||||
@ApiModelProperty("车辆类型")
|
||||
private String carType;
|
||||
|
||||
@ApiModelProperty("服务到期状态:1已到期 0未到期")
|
||||
private String expState;
|
||||
|
||||
@ApiModelProperty("服务期限")
|
||||
private String expTime;
|
||||
}
|
||||
Reference in New Issue
Block a user