package com.iailab.sdk.auth.client; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.ObjectMapper; import com.iailab.sdk.auth.client.common.exception.enums.GlobalErrorCodeConstants; import com.iailab.sdk.auth.client.common.pojo.CommonResult; import com.iailab.sdk.auth.client.common.pojo.PageResult; import com.iailab.sdk.auth.client.dto.ApiPointsValueQueryDTO; import com.iailab.sdk.auth.client.dto.StAlarmAndSuggestPageReqDTO; import com.iailab.sdk.auth.client.dto.StAlarmAndSuggestRespDTO; import com.iailab.sdk.auth.client.dto.TokenDTO; import com.iailab.sdk.auth.config.SdkAutoConfiguration; import com.iailab.sdk.auth.constants.SdkErrorCodeConstants; import com.iailab.sdk.util.http.IailabHttpUtils; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; import org.springframework.util.Assert; import org.springframework.util.Base64Utils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception; /** * @author Houzhongjian * @Description * @createTime 2025年02月18日 */ public class IailabClient { private static final RestTemplate restTemplate = new RestTemplate(); /** * 平台地址 */ public static String BASE_URL = SdkAutoConfiguration.BASE_URL; /** * 租户编号 */ public static Long TENANT_ID = SdkAutoConfiguration.TENANT_ID; /** * 客户端信息 */ private static String CLIENT_ID = SdkAutoConfiguration.CLIENT_ID; private static String CLIENT_SECRET = SdkAutoConfiguration.CLIENT_SECRET; private static String USERNAME = SdkAutoConfiguration.USERNAME; private static final String GRAND_TYPE = "client_credentials"; private static final String SCOPE = "user.read user.write"; private static final String CHARSET = "utf-8"; private static final IailabClient iailabClient = new IailabClient(); public static IailabClient getInstance() { return iailabClient; } // 鉴权token public static String accessToken; // 刷新token public static String refreshToken; // 鉴权token过期时间 public static Long expireTime; private static final String RESP_CODE = "code"; private static final String RESP_MSG = "msg"; private static final String RESP_DATA = "data"; /** * 用户名密码方式获取平台token */ public static synchronized TokenDTO authenticate() { System.out.println("登录获取平台token"); // 1.1 构建请求头 HttpHeaders headers = new HttpHeaders(); addClientHeader(headers); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); // 1.2 构建authenticate请求URL String authenticateUrl = BASE_URL + "/system/oauth2/token?" // 客户端模式的参数 + "&grant_type=" + GRAND_TYPE + "&username=" + USERNAME + "&scope=" + SCOPE; // 2. 执行请求 ResponseEntity> exchange = restTemplate.exchange( authenticateUrl, HttpMethod.POST, new HttpEntity<>(headers), new ParameterizedTypeReference>() { }); Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功"); Map authMap = exchange.getBody(); Object code = authMap.get("code"); if (SdkErrorCodeConstants.AUTH_BAD_CREDENTIALS.getCode().equals(code)) { throw exception(SdkErrorCodeConstants.AUTH_BAD_CREDENTIALS); } else if (SdkErrorCodeConstants.OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH.getCode().equals(code)) { throw exception(SdkErrorCodeConstants.OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH); } else if (SdkErrorCodeConstants.OAUTH2_CLIENT_CLIENT_SECRET_ERROR.getCode().equals(code)) { throw exception(SdkErrorCodeConstants.OAUTH2_CLIENT_CLIENT_SECRET_ERROR); } else if (SdkErrorCodeConstants.OAUTH2_CLIENT_NOT_EXISTS.getCode().equals(code)) { throw exception(SdkErrorCodeConstants.OAUTH2_CLIENT_NOT_EXISTS); } else if (SdkErrorCodeConstants.OAUTH2_CLIENT_DISABLE.getCode().equals(code)) { throw exception(SdkErrorCodeConstants.OAUTH2_CLIENT_DISABLE); } accessToken = authMap.get("access_token").toString(); refreshToken = authMap.get("refresh_token").toString(); expireTime = Long.valueOf(authMap.get("expires_time").toString()); return handleResponse(exchange); } public static synchronized TokenDTO refreshToken() throws Exception { System.out.println("刷新token"); // 1.1 构建请求头 HttpHeaders headers = new HttpHeaders(); addClientHeader(headers); // 1.2 构建authenticate请求URL String authenticateUrl = BASE_URL + "/system/auth/client-refresh-token?refreshToken=" + refreshToken + "&clientId=" + CLIENT_ID; // 2. 执行请求 ResponseEntity> exchange = restTemplate.exchange( authenticateUrl, HttpMethod.POST, new HttpEntity<>(headers), new ParameterizedTypeReference>() { }); Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功"); Map authMap = exchange.getBody(); //刷新token过期,重新获取token if (!ObjectUtils.isEmpty(authMap.get("code"))) { Integer code = Integer.valueOf(authMap.get("code").toString()); if (code == 401) { authenticate(); } else { throw exception(SdkErrorCodeConstants.AUTH_REFRESH_TOKEN_ERROR); } } else { accessToken = authMap.get("access_token").toString(); expireTime = Long.valueOf(authMap.get("expires_time").toString()); } return handleResponse(exchange); } /** * 平台http请求封装 * * @param method * @param url * @param params * @return * @throws Exception */ public static String doHttp(String method, String url, Map params) throws Exception { String response = null; String upperMethod = method.toUpperCase(); if ("GET".equals(upperMethod)) { response = IailabHttpUtils.doGet(url, params, CHARSET); } else if ("POST".equals(upperMethod)) { ObjectMapper objectMapper = new ObjectMapper(); response = IailabHttpUtils.doPost(url, objectMapper.writeValueAsString(params), CHARSET); } return response; } private static void addClientHeader(HttpHeaders headers) { // client 拼接,需要 BASE64 编码 String client = CLIENT_ID + ":" + CLIENT_SECRET; client = Base64Utils.encodeToString(client.getBytes(StandardCharsets.UTF_8)); headers.add("Authorization", "Basic " + client); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.set("tenant-id", TENANT_ID.toString()); } /** * 统一处理响应 * * @param response * @param * @return */ private static TokenDTO handleResponse(ResponseEntity response) { Assert.isTrue(response.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功"); System.out.println(response); TokenDTO authTokenDTO = new TokenDTO(); Map authMap = (Map) response.getBody(); authTokenDTO.setAccessToken(authMap.get("access_token").toString()); authTokenDTO.setRefreshToken(authMap.get("refresh_token").toString()); authTokenDTO.setExpiresTime(Long.valueOf(authMap.get("expires_time").toString())); return authTokenDTO; } public CommonResult handleHttp(String method, String url, Map params) { Object data = new Object(); String resp = null; try { String upperMethod = method.toUpperCase(); if ("GET".equals(upperMethod)) { resp = IailabHttpUtils.doGet(BASE_URL +url, params, CHARSET); } else if ("POST".equals(upperMethod)) { ObjectMapper objectMapper = new ObjectMapper(); resp = IailabHttpUtils.doPost(BASE_URL +url, objectMapper.writeValueAsString(params), CHARSET); } if (StringUtils.isEmpty(resp)) { return CommonResult.error(GlobalErrorCodeConstants.EMPTY_RESP); } JSONObject jsonObject = JSON.parseObject(resp); Integer respCode = jsonObject.getInteger(RESP_CODE); if (!GlobalErrorCodeConstants.SUCCESS.getCode().equals(respCode)) { CommonResult.error(respCode, jsonObject.getString(RESP_MSG)); } data = jsonObject.get(RESP_DATA); } catch (Exception ex) { ex.printStackTrace(); return CommonResult.error(GlobalErrorCodeConstants.UNKNOWN.getCode(), ex.getMessage()); } return CommonResult.success(data); } /** * 查询多个测点当前值 * * @param pointNos * @return */ public CommonResult> queryPointsRealValue(List pointNos) { Map data = new HashMap<>(); try { String url = BASE_URL + "/data/api/query-points/real-value"; String resp = IailabHttpUtils.doPost(url, JSON.toJSONString(pointNos), "UTF-8"); if (StringUtils.isEmpty(resp)) { return CommonResult.error(GlobalErrorCodeConstants.EMPTY_RESP); } JSONObject jsonObject = JSON.parseObject(resp); Integer respCode = jsonObject.getInteger(RESP_CODE); if (!GlobalErrorCodeConstants.SUCCESS.getCode().equals(respCode)) { CommonResult.error(respCode, jsonObject.getString(RESP_MSG)); } data = jsonObject.getJSONObject(RESP_DATA).toJavaObject(Map.class); } catch (Exception ex) { return CommonResult.error(GlobalErrorCodeConstants.UNKNOWN.getCode(), ex.getMessage()); } return CommonResult.success(data); } /** * 查询多个测点历史值 * * @param queryDto * @return */ public CommonResult>>> queryPointsHistoryValue(ApiPointsValueQueryDTO queryDto) { Map>> data = new HashMap<>(); try { String url = BASE_URL + "/data/api/query-points/history-value"; String resp = IailabHttpUtils.doPost(url, JSON.toJSONString(queryDto), "UTF-8"); if (StringUtils.isEmpty(resp)) { return CommonResult.error(GlobalErrorCodeConstants.EMPTY_RESP); } JSONObject jsonObject = JSON.parseObject(resp); Integer respCode = jsonObject.getInteger(RESP_CODE); if (!GlobalErrorCodeConstants.SUCCESS.getCode().equals(respCode)) { CommonResult.error(respCode, jsonObject.getString(RESP_MSG)); } data = jsonObject.getJSONObject(RESP_DATA).toJavaObject(Map.class); } catch (Exception ex) { return CommonResult.error(GlobalErrorCodeConstants.UNKNOWN.getCode(), ex.getMessage()); } return CommonResult.success(data); } /** * 获取预警信息和调度建议分页列表 * * @param reqVO * @return */ public CommonResult> getAlarmAndSuggestPage(StAlarmAndSuggestPageReqDTO reqVO) { PageResult data = new PageResult<>(); try { String url = BASE_URL + "/model/api/mcs/alarm-suggest/page"; String resp = IailabHttpUtils.doPost(url, JSON.toJSONString(reqVO), "UTF-8"); if (StringUtils.isEmpty(resp)) { return CommonResult.error(GlobalErrorCodeConstants.EMPTY_RESP); } JSONObject jsonObject = JSON.parseObject(resp); Integer respCode = jsonObject.getInteger(RESP_CODE); if (!GlobalErrorCodeConstants.SUCCESS.getCode().equals(respCode)) { CommonResult.error(respCode, jsonObject.getString(RESP_MSG)); } Long total = Long.parseLong(jsonObject.getJSONObject(RESP_DATA).get("total").toString()); List list = jsonObject.getJSONObject(RESP_DATA).getJSONArray("list").toJavaList(StAlarmAndSuggestRespDTO.class); data = new PageResult<>(list, total); } catch (Exception ex) { return CommonResult.error(GlobalErrorCodeConstants.UNKNOWN.getCode(), ex.getMessage()); } return CommonResult.success(data); } }