This commit is contained in:
2025-11-05 22:47:06 +08:00
parent 2335361160
commit cddfde34df
6 changed files with 465 additions and 9 deletions

View File

@@ -37,11 +37,14 @@ public class TencentDocController extends BaseController {
@Autowired
private RedisCache redisCache;
@Autowired
private com.ruoyi.jarvis.service.ITencentDocTokenService tencentDocTokenService;
/** Redis key前缀用于存储上次处理的最大行数 */
private static final String LAST_PROCESSED_ROW_KEY_PREFIX = "tendoc:last_row:";
/**
* 获取授权URL
* 获取授权URL用于手动授权获取token后通过setToken接口保存
*/
@GetMapping("/authUrl")
public AjaxResult getAuthUrl() {
@@ -54,6 +57,56 @@ public class TencentDocController extends BaseController {
}
}
/**
* 手动设置访问令牌用于首次授权后保存token
*/
@PostMapping("/setToken")
public AjaxResult setToken(@RequestBody Map<String, Object> params) {
try {
String accessToken = (String) params.get("accessToken");
String refreshToken = (String) params.get("refreshToken");
Integer expiresIn = params.get("expiresIn") != null ?
Integer.valueOf(params.get("expiresIn").toString()) : 7200;
if (accessToken == null || accessToken.trim().isEmpty()) {
return AjaxResult.error("accessToken不能为空");
}
// 通过反射调用setToken方法
if (tencentDocTokenService instanceof com.ruoyi.jarvis.service.impl.TencentDocTokenServiceImpl) {
((com.ruoyi.jarvis.service.impl.TencentDocTokenServiceImpl) tencentDocTokenService)
.setToken(accessToken, refreshToken, expiresIn);
return AjaxResult.success("访问令牌已保存");
} else {
return AjaxResult.error("Token服务类型不支持");
}
} catch (Exception e) {
log.error("设置访问令牌失败", e);
return AjaxResult.error("设置访问令牌失败: " + e.getMessage());
}
}
/**
* 获取当前token状态
*/
@GetMapping("/tokenStatus")
public AjaxResult getTokenStatus() {
try {
String token;
try {
token = tencentDocTokenService.getValidAccessToken();
return AjaxResult.success("访问令牌有效", new JSONObject().fluentPut("hasToken", true)
.fluentPut("token", token.substring(0, Math.min(20, token.length())) + "..."));
} catch (Exception e) {
return AjaxResult.success("访问令牌无效", new JSONObject().fluentPut("hasToken", false)
.fluentPut("message", e.getMessage()));
}
} catch (Exception e) {
log.error("获取token状态失败", e);
return AjaxResult.error("获取token状态失败: " + e.getMessage());
}
}
/**
* OAuth回调 - 通过授权码获取访问令牌
* 根据腾讯文档官方文档https://docs.qq.com/open/document/app/oauth2/authorize.html
@@ -87,9 +140,25 @@ public class TencentDocController extends BaseController {
return AjaxResult.error("获取访问令牌失败,响应数据格式不正确");
}
log.info("成功获取访问令牌 - access_token: {}", tokenInfo.getString("access_token"));
String accessToken = tokenInfo.getString("access_token");
String refreshToken = tokenInfo.getString("refresh_token");
Integer expiresIn = tokenInfo.getIntValue("expires_in");
return AjaxResult.success("授权成功", tokenInfo);
log.info("成功获取访问令牌 - access_token: {}", accessToken);
// 自动保存token到后端
try {
if (tencentDocTokenService instanceof com.ruoyi.jarvis.service.impl.TencentDocTokenServiceImpl) {
((com.ruoyi.jarvis.service.impl.TencentDocTokenServiceImpl) tencentDocTokenService)
.setToken(accessToken, refreshToken, expiresIn);
log.info("访问令牌已自动保存到后端缓存");
}
} catch (Exception e) {
log.error("保存访问令牌失败", e);
// 即使保存失败也返回token信息
}
return AjaxResult.success("授权成功,访问令牌已自动保存", tokenInfo);
} catch (Exception e) {
log.error("OAuth回调处理失败", e);
return AjaxResult.error("授权失败: " + e.getMessage());
@@ -282,11 +351,20 @@ public class TencentDocController extends BaseController {
/**
* 根据单号填充物流链接 - 读取表格数据,根据单号查询订单系统中的物流链接,并填充到表格
* 优化:记录上次处理的最大行数,每次从最大行数-100开始读取避免重复处理历史数据
* 自动获取和管理访问令牌,无需前端传递
*/
@PostMapping("/fillLogisticsByOrderNo")
public AjaxResult fillLogisticsByOrderNo(@RequestBody Map<String, Object> params) {
try {
String accessToken = (String) params.get("accessToken");
// 自动获取有效的访问令牌
String accessToken;
try {
accessToken = tencentDocTokenService.getValidAccessToken();
} catch (Exception e) {
log.error("获取访问令牌失败", e);
return AjaxResult.error("获取访问令牌失败: " + e.getMessage() + "。请先完成授权或检查配置。");
}
String fileId = (String) params.get("fileId");
String sheetId = (String) params.get("sheetId");