| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- package com.chuanghai.ihotel.component;
- import com.chuanghai.ihotel.common.exception.BizCodeEnume;
- import com.chuanghai.ihotel.common.exception.RRException;
- import com.chuanghai.ihotel.config.WaterElectricConfig;
- import com.chuanghai.ihotel.constant.RedisKey;
- import com.chuanghai.ihotel.util.WaterElectricDataEncAndDecUtil;
- import com.chuanghai.ihotel.util.WaterElectricSignUtil;
- import com.fasterxml.jackson.databind.JsonNode;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.StringRedisTemplate;
- import org.springframework.http.HttpEntity;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.ResponseEntity;
- import org.springframework.stereotype.Component;
- import org.springframework.util.LinkedMultiValueMap;
- import org.springframework.util.MultiValueMap;
- import org.springframework.util.StringUtils;
- import org.springframework.web.client.RestTemplate;
- import java.time.LocalDateTime;
- import java.time.format.DateTimeFormatter;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.TimeUnit;
- /**
- * 水电服务
- */
- @Slf4j
- @Component
- public class WaterElectricComponent {
- private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
- @Autowired
- private StringRedisTemplate stringRedisTemplate;
- @Autowired
- private WaterElectricConfig waterElectricConfig;
- /**
- * 获取token
- * @return
- */
- public String queryToken() {
- String token = stringRedisTemplate.opsForValue().get(RedisKey.WATER_AND_ELECTRIC_SERVICE_TOKEN);
- if (StringUtils.hasText(token)) {
- return token;
- } else {
- Map<String, String> map = new HashMap<>();
- map.put("operatorSecret", waterElectricConfig.getOperatorSecret());
- try {
- JsonNode jsonNode = queryData("queryToken", map, null);
- String accessToken = jsonNode.get("accessToken").asText();
- long ttl = jsonNode.get("tokenAvailableTime").asLong();
- stringRedisTemplate.opsForValue().set(RedisKey.WATER_AND_ELECTRIC_SERVICE_TOKEN, accessToken, ttl, TimeUnit.SECONDS);
- return accessToken;
- } catch (Exception e) {
- throw new RRException(BizCodeEnume.THIRD_PARTY_SERVICE_CALL_FAILED, "请求水电接口-获取token异常");
- }
- }
- }
- /**
- * 获取电表实时数据
- * @param pointId
- * @return
- */
- public String queryPowerRealTimeData(String pointId) {
- Map<String, String> map = new HashMap<>();
- map.put("pointId", pointId);
- try {
- JsonNode jsonNode = queryData("queryPowerRealTimeData", map, queryToken());
- // {"bm": 1822.1, "dataTime": "", "frequency": "", "pointId": "", "status": 0}
- log.info("读取电表数据【{}】", jsonNode.toString());
- return jsonNode.get("bm").asText();
- } catch (Exception e) {
- throw new RRException(BizCodeEnume.THIRD_PARTY_SERVICE_CALL_FAILED, "请求水电接口-获取电表实时数据异常");
- }
- }
- /**
- * 获取电表实时数据
- * @param pointId
- * @return
- */
- public String queryLastHistoryCumulantInfo(String pointId) {
- Map<String, String> map = new HashMap<>();
- map.put("pointId", pointId);
- map.put("pointType", "2");
- try {
- JsonNode jsonNode = queryData("queryLastHistoryCumulantInfo", map, queryToken());
- log.info("读取水表数据【{}】", jsonNode.toString());
- return jsonNode.get("bm").asText();
- } catch (Exception e) {
- throw new RRException(BizCodeEnume.THIRD_PARTY_SERVICE_CALL_FAILED, "请求水电接口-获取电表实时数据异常");
- }
- }
- /**
- * 远程控制水电表
- * @param pointId
- * @param operType 1开、2关
- * @return
- */
- public JsonNode remoteDisconnect(String pointId, String operType) {
- Map<String, String> map = new HashMap<>();
- map.put("pointId", pointId);
- map.put("operType", operType);
- try {
- return queryData("remoteDisconnect", map, queryToken());
- } catch (Exception e) {
- throw new RRException(BizCodeEnume.THIRD_PARTY_SERVICE_CALL_FAILED, "请求水电接口-远程控制水电表异常");
- }
- }
- /**
- * 请求数据
- *
- * @param uri 请求接口url
- * @param paramMap 请求参数
- * @param token 请求token 获取token时该字段可以为空
- */
- private JsonNode queryData(String uri, Map<String, String> paramMap, String token) throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- // 加密data部分
- String encode = WaterElectricDataEncAndDecUtil.dataEncode(mapper.writeValueAsString(paramMap), waterElectricConfig.getDataSecret(), waterElectricConfig.getDataSecretIv());
- String seq = "0001";
- String timeStamp = DTF.format(LocalDateTime.now());
- MultiValueMap<String, String> requestMap = new LinkedMultiValueMap<>();
- requestMap.add("operatorId", waterElectricConfig.getOperatorId());
- requestMap.add("data", encode);
- requestMap.add("timeStamp", timeStamp);
- requestMap.add("seq", seq);
- // 为防止 + 在收发过程中被变成空格,将加密后的密文中的所有空格替换一下,需要签名的参数: operatorId + 加密后的data + 时间戳 + 自增序列
- String signSrc = waterElectricConfig.getOperatorId() + encode.replaceAll(" ", "+") + timeStamp + seq;
- String sig = WaterElectricSignUtil.sign(signSrc, waterElectricConfig.getSignKey());
- requestMap.add("sig", sig);
- RestTemplate restTemplate = new RestTemplate();
- HttpHeaders headers = new HttpHeaders();
- if (StringUtils.hasText(token)) {
- headers.add("token", token);
- }
- HttpEntity<MultiValueMap<String, String>> formEntity = new HttpEntity<>(requestMap, headers);
- log.info("=======开始请求数据=======");
- ResponseEntity<String> responseEntity = restTemplate.postForEntity(waterElectricConfig.getServiceHost() + uri, formEntity, String.class);
- log.info("=======请求成功===========");
- String body = responseEntity.getBody();
- JsonNode jsonNode = mapper.readTree(body);
- if (!"0".equals(jsonNode.get("ret").asText())) {
- log.error("接口请求失败,【{}】", body);
- }
- // 验签
- String dataS = jsonNode.get("data").asText().replaceAll(" ", "+");
- String resultSigStr = jsonNode.get("operatorId").asText()
- + dataS
- + jsonNode.get("msg").asText()
- + jsonNode.get("ret").asText();
- // 本地签名
- String localSign = WaterElectricSignUtil.sign(resultSigStr, waterElectricConfig.getSignKey());
- String remoteSign = jsonNode.get("sig").asText();
- if (!(StringUtils.hasText(remoteSign) && remoteSign.equals(localSign))) {
- log.error("接口验签失败,本地签名【{}】,远程签名【{}】", localSign, remoteSign);
- }
- String data = WaterElectricDataEncAndDecUtil.dataDecode(dataS, waterElectricConfig.getDataSecret(), waterElectricConfig.getDataSecretIv());
- if (!StringUtils.hasText(data)) {
- log.error("水电服务接口data解密失败");
- }
- JsonNode dataJson = mapper.readTree(data);
- return dataJson;
- }
- }
|