This commit is contained in:
2025-11-05 15:42:44 +08:00
parent 41f338446d
commit 1116bddbc2
3 changed files with 131 additions and 3 deletions

View File

@@ -671,4 +671,100 @@ public class JDOrderController extends BaseController {
return AjaxResult.error("文本URL替换失败: " + e.getMessage());
}
}
/**
* 手动获取物流信息(用于调试)
* 如果订单的分销标识是F或PDD调用外部接口获取物流信息并记录
* 入参:{ orderId: 订单ID }
* 返回:接口返回的数据和记录状态
*/
@PostMapping("/fetchLogisticsManually")
public AjaxResult fetchLogisticsManually(@RequestBody Map<String, Object> body) {
try {
Long orderId = null;
if (body.get("orderId") != null) {
if (body.get("orderId") instanceof Number) {
orderId = ((Number) body.get("orderId")).longValue();
} else {
orderId = Long.parseLong(body.get("orderId").toString());
}
}
if (orderId == null) {
return AjaxResult.error("订单ID不能为空");
}
// 查询订单信息
JDOrder order = jdOrderService.selectJDOrderById(orderId);
if (order == null) {
return AjaxResult.error("订单不存在");
}
// 检查分销标识
String distributionMark = order.getDistributionMark();
if (distributionMark == null || (!distributionMark.equals("F") && !distributionMark.equals("PDD"))) {
return AjaxResult.error("该订单的分销标识不是F或PDD无需处理。当前分销标识: " + distributionMark);
}
// 检查物流链接
String logisticsLink = order.getLogisticsLink();
if (logisticsLink == null || logisticsLink.trim().isEmpty()) {
return AjaxResult.error("该订单暂无物流链接");
}
logger.info("手动获取物流信息 - 订单ID: {}, 订单号: {}, 分销标识: {}, 物流链接: {}",
orderId, order.getOrderId(), distributionMark, logisticsLink);
// 调用外部接口
String externalUrl = "http://192.168.8.88:5001/fetch_logistics?tracking_url=" +
java.net.URLEncoder.encode(logisticsLink, "UTF-8");
logger.info("调用外部接口 - URL: {}", externalUrl);
String result = "";
try {
result = HttpUtils.sendGet(externalUrl);
logger.info("外部接口返回 - 订单ID: {}, 订单号: {}, 返回数据: {}",
orderId, order.getOrderId(), result);
} catch (Exception e) {
logger.error("调用外部接口失败 - 订单ID: {}, 订单号: {}, 错误: {}",
orderId, order.getOrderId(), e.getMessage(), e);
return AjaxResult.error("调用外部接口失败: " + e.getMessage());
}
// 记录返回数据到日志文件方便debug
logger.info("========== 物流信息获取记录 ==========");
logger.info("订单ID: {}", orderId);
logger.info("订单号: {}", order.getOrderId());
logger.info("分销标识: {}", distributionMark);
logger.info("物流链接: {}", logisticsLink);
logger.info("请求URL: {}", externalUrl);
logger.info("返回数据: {}", result);
logger.info("=====================================");
// 解析返回结果
JSONObject responseData = new JSONObject();
responseData.put("orderId", orderId);
responseData.put("orderNo", order.getOrderId());
responseData.put("distributionMark", distributionMark);
responseData.put("logisticsLink", logisticsLink);
responseData.put("requestUrl", externalUrl);
try {
// 尝试解析为JSON
Object parsed = JSON.parse(result);
responseData.put("responseData", parsed);
responseData.put("responseRaw", result);
} catch (Exception e) {
// 如果不是JSON直接保存原始字符串
responseData.put("responseRaw", result);
logger.warn("返回数据不是有效的JSON格式: {}", result);
}
return AjaxResult.success(responseData);
} catch (Exception e) {
logger.error("手动获取物流信息异常", e);
return AjaxResult.error("获取物流信息失败: " + e.getMessage());
}
}
}

View File

@@ -56,11 +56,39 @@ public class TencentDocController extends BaseController {
/**
* OAuth回调 - 通过授权码获取访问令牌
* 根据腾讯文档官方文档https://docs.qq.com/open/document/app/oauth2/authorize.html
* 用户授权成功后腾讯文档会重定向到此回调地址并携带code和state参数
*/
@GetMapping("/oauth/callback")
public AjaxResult oauthCallback(@RequestParam("code") String code) {
public AjaxResult oauthCallback(@RequestParam("code") String code,
@RequestParam(value = "state", required = false) String state,
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "error_description", required = false) String errorDescription) {
try {
// 处理授权错误
if (error != null) {
log.error("腾讯文档授权失败 - error: {}, error_description: {}", error, errorDescription);
return AjaxResult.error("授权失败: " + (errorDescription != null ? errorDescription : error));
}
// 验证授权码
if (code == null || code.trim().isEmpty()) {
return AjaxResult.error("授权码不能为空");
}
log.info("收到腾讯文档授权回调 - code: {}, state: {}", code, state);
// 使用授权码换取access_token
JSONObject tokenInfo = tencentDocService.getAccessTokenByCode(code);
// 验证返回的token信息
if (tokenInfo == null || !tokenInfo.containsKey("access_token")) {
log.error("获取访问令牌失败 - 响应数据: {}", tokenInfo);
return AjaxResult.error("获取访问令牌失败,响应数据格式不正确");
}
log.info("成功获取访问令牌 - access_token: {}", tokenInfo.getString("access_token"));
return AjaxResult.success("授权成功", tokenInfo);
} catch (Exception e) {
log.error("OAuth回调处理失败", e);

View File

@@ -33,7 +33,7 @@ public class TencentDocServiceImpl implements ITencentDocService {
String redirectUri = tencentDocConfig.getRedirectUri();
String oauthUrl = tencentDocConfig.getOauthUrl();
// 构建授权URL
// 构建授权URL根据腾讯文档官方文档https://docs.qq.com/open/document/app/oauth2/authorize.html
StringBuilder authUrl = new StringBuilder();
authUrl.append(oauthUrl);
authUrl.append("?client_id=").append(appId);
@@ -44,7 +44,11 @@ public class TencentDocServiceImpl implements ITencentDocService {
authUrl.append("&redirect_uri=").append(redirectUri);
}
authUrl.append("&response_type=code");
authUrl.append("&scope=file.read_write");
authUrl.append("&scope=all"); // 根据官方文档scope固定为all
// 添加state参数用于防CSRF攻击可选但建议带上
String state = java.util.UUID.randomUUID().toString();
authUrl.append("&state=").append(state);
return authUrl.toString();
}