This commit is contained in:
xuelijun
2026-01-21 15:40:03 +08:00
parent f9a1c21bee
commit 7bb698c9c0
3 changed files with 97 additions and 217 deletions

View File

@@ -3,6 +3,7 @@ package com.tem.bocai.service.impl;
import com.tem.bocai.service.LoginService;
import com.tem.bocai.util.LotteryDataPipeline;
import com.tem.bocai.util.LotteryWebMagicCrawler;
import com.tem.bocai.util.TokenCacheService;
import org.springframework.stereotype.Service;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
@@ -38,6 +39,8 @@ public class LoginServiceImpl implements LoginService {
private static final int MAX_RETRY = 5;
@Autowired
private Tesseract tesseract;
@Autowired
private TokenCacheService tokenCacheService;
@Override
public String loginAutomatic(String username, String password, String loginUrl, Integer winNum, Integer loseNum) {
@@ -46,6 +49,7 @@ public class LoginServiceImpl implements LoginService {
System.out.println("\n=== 第 " + attempt + " 次尝试 ===");
try {
token = attemptLogin();
tokenCacheService.saveToken(token);
if (token != null && !token.isEmpty()) {
// 2. 创建爬虫实例传入token
LotteryWebMagicCrawler crawler = new LotteryWebMagicCrawler(token);
@@ -88,6 +92,7 @@ public class LoginServiceImpl implements LoginService {
System.out.println("\n=== 第 " + attempt + " 次尝试 ===");
try {
token = attemptLogin();
if (token != null && !token.isEmpty()) {
return token;
}

View File

@@ -1,217 +0,0 @@
package com.tem.bocai.util;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class TokenCacheManager {
private static final String CACHE_FILE_PATH = "token_cache.json";
private static final long TOKEN_EXPIRE_TIME = 1140000; // 19分钟过期毫秒 1140000 = 19 * 60 * 1000
private final ObjectMapper objectMapper = new ObjectMapper();
/**
* 保存token到缓存文件
*/
public void saveToken(String token) {
try {
Map<String, Object> cacheData = new HashMap<>();
cacheData.put("token", token);
cacheData.put("timestamp", System.currentTimeMillis());
cacheData.put("expireTime", TOKEN_EXPIRE_TIME);
cacheData.put("expireMinutes", 19); // 记录过期分钟数
String json = objectMapper.writeValueAsString(cacheData);
Files.write(Paths.get(CACHE_FILE_PATH), json.getBytes());
System.out.println("Token已保存到缓存文件: " + CACHE_FILE_PATH);
System.out.println("Token将在19分钟后过期");
} catch (IOException e) {
System.err.println("保存token缓存失败: " + e.getMessage());
}
}
/**
* 从缓存文件读取token
*/
public String readToken() {
try {
File cacheFile = new File(CACHE_FILE_PATH);
if (!cacheFile.exists()) {
System.out.println("缓存文件不存在");
return null;
}
String json = new String(Files.readAllBytes(Paths.get(CACHE_FILE_PATH)));
Map<String, Object> cacheData = objectMapper.readValue(json, Map.class);
String token = (String) cacheData.get("token");
Long timestamp = (Long) cacheData.get("timestamp");
if (!StringUtils.hasText(token) || timestamp == null) {
System.out.println("缓存数据不完整");
return null;
}
// 检查token是否过期
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - timestamp;
if (elapsedTime > TOKEN_EXPIRE_TIME) {
long expiredSeconds = (elapsedTime - TOKEN_EXPIRE_TIME) / 1000;
System.out.println("Token已过期 " + expiredSeconds + "");
return null;
}
// 计算剩余时间
long remainingTime = TOKEN_EXPIRE_TIME - elapsedTime;
long remainingMinutes = remainingTime / 60000;
long remainingSeconds = (remainingTime % 60000) / 1000;
System.out.println("从缓存读取token剩余有效时间: " +
remainingMinutes + "" + remainingSeconds + "");
return token;
} catch (IOException e) {
System.err.println("读取token缓存失败: " + e.getMessage());
return null;
}
}
/**
* 清除token缓存
*/
public void clearToken() {
try {
File cacheFile = new File(CACHE_FILE_PATH);
if (cacheFile.exists()) {
Files.delete(Paths.get(CACHE_FILE_PATH));
System.out.println("Token缓存已清除");
}
} catch (IOException e) {
System.err.println("清除token缓存失败: " + e.getMessage());
}
}
/**
* 检查token是否存在且有效
*/
public boolean hasValidToken() {
return readToken() != null;
}
/**
* 检查token是否即将过期例如5分钟内过期
*/
public boolean isTokenExpiringSoon(int warningMinutes) {
try {
File cacheFile = new File(CACHE_FILE_PATH);
if (!cacheFile.exists()) {
return false;
}
String json = new String(Files.readAllBytes(Paths.get(CACHE_FILE_PATH)));
Map<String, Object> cacheData = objectMapper.readValue(json, Map.class);
Long timestamp = (Long) cacheData.get("timestamp");
if (timestamp == null) {
return false;
}
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - timestamp;
long remainingTime = TOKEN_EXPIRE_TIME - elapsedTime;
// 检查是否在指定分钟内过期
return remainingTime > 0 && remainingTime <= (warningMinutes * 60000);
} catch (Exception e) {
return false;
}
}
/**
* 获取token信息用于调试
*/
public Map<String, Object> getTokenInfo() {
try {
File cacheFile = new File(CACHE_FILE_PATH);
if (!cacheFile.exists()) {
return null;
}
String json = new String(Files.readAllBytes(Paths.get(CACHE_FILE_PATH)));
Map<String, Object> cacheData = objectMapper.readValue(json, Map.class);
Long timestamp = (Long) cacheData.get("timestamp");
if (timestamp != null) {
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - timestamp;
long remainingTime = TOKEN_EXPIRE_TIME - elapsedTime;
cacheData.put("savedTime", new Date(timestamp).toString());
cacheData.put("elapsedTime", formatTime(elapsedTime));
cacheData.put("remainingTime", formatTime(remainingTime));
cacheData.put("isValid", remainingTime > 0);
cacheData.put("expireMinutes", 19);
// 添加过期警告
if (remainingTime > 0) {
if (remainingTime <= 300000) { // 5分钟内过期
cacheData.put("warning", "Token将在5分钟内过期建议刷新");
} else if (remainingTime <= 600000) { // 10分钟内过期
cacheData.put("warning", "Token将在10分钟内过期");
}
}
}
return cacheData;
} catch (Exception e) {
return null;
}
}
/**
* 格式化时间显示
*/
private String formatTime(long millis) {
if (millis <= 0) {
return "已过期";
}
long minutes = millis / 60000;
long seconds = (millis % 60000) / 1000;
if (minutes > 0) {
return minutes + "" + seconds + "";
} else {
return seconds + "";
}
}
/**
* 获取token过期时间配置
*/
public static long getTokenExpireTime() {
return TOKEN_EXPIRE_TIME;
}
/**
* 获取token过期分钟数
*/
public static int getTokenExpireMinutes() {
return (int) (TOKEN_EXPIRE_TIME / 60000);
}
}

View File

@@ -0,0 +1,92 @@
package com.tem.bocai.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import java.util.concurrent.Callable;
@Service
public class TokenCacheService {
private static final String TOKEN_CACHE_NAME = "tokenCache";
private static final String TOKEN_KEY = "login_token";
private static final String TOKEN_INFO_KEY = "token_info";
@Autowired
private CacheManager tokenCacheManager;
/**
* 保存token到缓存
*/
public void saveToken(String token) {
Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME);
if (cache != null) {
cache.put(TOKEN_KEY, token);
System.out.println("Token已保存到内存缓存");
}
}
/**
* 从缓存获取token
*/
public String getToken() {
Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME);
if (cache != null) {
return cache.get(TOKEN_KEY, String.class);
}
return null;
}
/**
* 从缓存获取token如果不存在则通过回调函数获取
*/
public String getToken(Callable<String> tokenLoader) {
Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME);
if (cache != null) {
return cache.get(TOKEN_KEY, tokenLoader);
}
return null;
}
/**
* 清除token缓存
*/
public void clearToken() {
Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME);
if (cache != null) {
cache.evict(TOKEN_KEY);
System.out.println("Token已从内存缓存清除");
}
}
/**
* 检查是否有有效token
*/
public boolean hasValidToken() {
return getToken() != null;
}
/**
* 保存token相关信息
*/
public void saveTokenInfo(String key, Object value) {
Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME);
if (cache != null) {
cache.put(TOKEN_INFO_KEY + "_" + key, value);
}
}
/**
* 获取token相关信息
*/
public <T> T getTokenInfo(String key, Class<T> type) {
Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME);
if (cache != null) {
return cache.get(TOKEN_INFO_KEY + "_" + key, type);
}
return null;
}
}