update 充电桩数据同步到JCPP

This commit is contained in:
Guoqs
2026-01-05 13:41:12 +08:00
parent 62f455fe70
commit 30ec68abb1
3 changed files with 258 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
package com.jsowell.pile.jcpp.service;
/**
* JCPP 认证服务接口
*
* @author jsowell
*/
public interface IJcppAuthService {
/**
* 获取 JCPP 访问令牌
* 如果 Redis 中有缓存且未过期,直接返回
* 否则调用登录接口获取新的 token
*
* @return 访问令牌
*/
String getAccessToken();
/**
* 清除缓存的令牌(用于强制刷新)
*/
void clearToken();
}

View File

@@ -0,0 +1,124 @@
package com.jsowell.pile.jcpp.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.jsowell.pile.jcpp.service.IJcppAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.TimeUnit;
/**
* JCPP 认证服务实现
*
* @author jsowell
*/
@Slf4j
@Service
public class JcppAuthServiceImpl implements IJcppAuthService {
private static final String JCPP_TOKEN_KEY = "jcpp:auth:token";
private static final long TOKEN_EXPIRE_MINUTES = 30L;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RestTemplate restTemplate;
@Value("${jcpp.sync.api-url:http://localhost:8180/api/sync}")
private String jcppApiUrl;
@Value("${jcpp.auth.username:sanbing}")
private String username;
@Value("${jcpp.auth.password:password123}")
private String password;
/**
* 获取 JCPP 访问令牌
*/
@Override
public String getAccessToken() {
// 1. 尝试从 Redis 获取缓存的 token
String cachedToken = stringRedisTemplate.opsForValue().get(JCPP_TOKEN_KEY);
if (cachedToken != null && !cachedToken.isEmpty()) {
log.debug("使用缓存的 JCPP token");
return cachedToken;
}
// 2. 缓存中没有,调用登录接口获取新的 token
log.info("缓存中没有 token调用登录接口获取");
String token = login();
// 3. 将 token 缓存到 Redis有效期 30 分钟
if (token != null && !token.isEmpty()) {
stringRedisTemplate.opsForValue().set(JCPP_TOKEN_KEY, token, TOKEN_EXPIRE_MINUTES, TimeUnit.MINUTES);
log.info("JCPP token 已缓存,有效期 {} 分钟", TOKEN_EXPIRE_MINUTES);
}
return token;
}
/**
* 清除缓存的令牌
*/
@Override
public void clearToken() {
stringRedisTemplate.delete(JCPP_TOKEN_KEY);
log.info("已清除缓存的 JCPP token");
}
/**
* 调用 JCPP 登录接口
*/
private String login() {
// 构建登录 URL从 api-url 中提取基础 URL
String baseUrl = jcppApiUrl.replace("/api/sync", "");
String loginUrl = baseUrl + "/api/auth/login";
try {
// 构建请求体
JSONObject requestBody = new JSONObject();
requestBody.put("username", username);
requestBody.put("password", password);
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(requestBody.toJSONString(), headers);
log.info("调用 JCPP 登录接口: {}", loginUrl);
// 发送请求
ResponseEntity<String> response = restTemplate.postForEntity(loginUrl, entity, String.class);
if (response.getStatusCode() == HttpStatus.OK) {
// 解析响应,提取 token
JSONObject responseBody = JSON.parseObject(response.getBody());
String token = responseBody.getString("token");
if (token != null && !token.isEmpty()) {
log.info("JCPP 登录成功,获取到 token");
return token;
} else {
log.error("JCPP 登录响应中没有 token: {}", response.getBody());
throw new RuntimeException("登录响应中没有 token");
}
} else {
log.error("JCPP 登录失败,状态码: ", response.getStatusCode());
throw new RuntimeException("登录失败,状态码: " + response.getStatusCode());
}
} catch (Exception e) {
log.error("调用 JCPP 登录接口异常", e);
throw new RuntimeException("登录失败: " + e.getMessage(), e);
}
}
}