197 lines
7.6 KiB
Java
197 lines
7.6 KiB
Java
package com.designhub.service;
|
||
|
||
import com.designhub.dto.ExternalAssetDTO;
|
||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.http.*;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.web.client.RestTemplate;
|
||
|
||
/**
|
||
* 第三方素材API服务
|
||
* 用于查询外部素材系统的任务完成状态和下载链接
|
||
*/
|
||
@Slf4j
|
||
@Service
|
||
@RequiredArgsConstructor
|
||
public class ExternalAssetService {
|
||
|
||
private final SystemConfigService systemConfigService;
|
||
private final RestTemplate restTemplate;
|
||
private final ObjectMapper objectMapper;
|
||
|
||
/**
|
||
* 查询任务素材
|
||
* @param taskNo 任务编号
|
||
* @return 素材信息,包含下载链接
|
||
*/
|
||
public ExternalAssetDTO queryAssets(String taskNo) {
|
||
String apiUrl = systemConfigService.getConfigValue("external_asset_api_url");
|
||
String apiKey = systemConfigService.getConfigValue("external_asset_api_key");
|
||
|
||
if (apiUrl == null || apiUrl.isEmpty()) {
|
||
log.warn("第三方素材API地址未配置");
|
||
ExternalAssetDTO result = new ExternalAssetDTO();
|
||
result.setSuccess(false);
|
||
ExternalAssetDTO.ErrorInfo error = new ExternalAssetDTO.ErrorInfo();
|
||
error.setCode("CONFIG_ERROR");
|
||
error.setMessage("第三方素材API未配置");
|
||
result.setError(error);
|
||
return result;
|
||
}
|
||
|
||
if (apiKey == null || apiKey.isEmpty()) {
|
||
log.warn("第三方素材API Key未配置");
|
||
ExternalAssetDTO result = new ExternalAssetDTO();
|
||
result.setSuccess(false);
|
||
ExternalAssetDTO.ErrorInfo error = new ExternalAssetDTO.ErrorInfo();
|
||
error.setCode("CONFIG_ERROR");
|
||
error.setMessage("第三方素材API Key未配置");
|
||
result.setError(error);
|
||
return result;
|
||
}
|
||
|
||
try {
|
||
// 构建请求URL
|
||
String url = apiUrl.endsWith("/") ? apiUrl : apiUrl + "/";
|
||
url = url + "product-assets?taskNo=" + taskNo;
|
||
|
||
log.info("查询第三方素材API: {}", url);
|
||
|
||
// 构建请求头
|
||
HttpHeaders headers = new HttpHeaders();
|
||
headers.set("X-API-Key", apiKey);
|
||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||
|
||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
||
|
||
// 发送请求
|
||
ResponseEntity<String> response = restTemplate.exchange(
|
||
url,
|
||
HttpMethod.GET,
|
||
entity,
|
||
String.class
|
||
);
|
||
|
||
log.info("第三方素材API响应状态: {}", response.getStatusCode());
|
||
log.debug("第三方素材API响应内容: {}", response.getBody());
|
||
|
||
if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
|
||
return objectMapper.readValue(response.getBody(), ExternalAssetDTO.class);
|
||
} else {
|
||
ExternalAssetDTO result = new ExternalAssetDTO();
|
||
result.setSuccess(false);
|
||
ExternalAssetDTO.ErrorInfo error = new ExternalAssetDTO.ErrorInfo();
|
||
error.setCode("REQUEST_FAILED");
|
||
error.setMessage("请求失败: " + response.getStatusCode());
|
||
result.setError(error);
|
||
return result;
|
||
}
|
||
|
||
} catch (Exception e) {
|
||
log.error("调用第三方素材API失败", e);
|
||
ExternalAssetDTO result = new ExternalAssetDTO();
|
||
result.setSuccess(false);
|
||
ExternalAssetDTO.ErrorInfo error = new ExternalAssetDTO.ErrorInfo();
|
||
error.setCode("EXCEPTION");
|
||
error.setMessage("调用API失败: " + e.getMessage());
|
||
result.setError(error);
|
||
return result;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查任务素材是否完成
|
||
* @param taskNo 任务编号
|
||
* @return 下载链接(如果完成),否则返回null
|
||
*/
|
||
public String checkTaskCompletion(String taskNo) {
|
||
ExternalAssetDTO result = queryAssets(taskNo);
|
||
|
||
if (result.isSuccess() && result.getData() != null) {
|
||
ExternalAssetDTO.DownloadUrls urls = result.getData().getDownloadUrls();
|
||
if (urls != null && urls.getAll() != null && !urls.getAll().isEmpty()) {
|
||
log.info("任务 {} 素材已完成,下载链接: {}", taskNo, urls.getAll());
|
||
return urls.getAll();
|
||
}
|
||
}
|
||
|
||
log.info("任务 {} 素材未完成或查询失败", taskNo);
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 测试API连接
|
||
* @return 测试结果
|
||
*/
|
||
public boolean testConnection() {
|
||
String apiUrl = systemConfigService.getConfigValue("external_asset_api_url");
|
||
String apiKey = systemConfigService.getConfigValue("external_asset_api_key");
|
||
|
||
if (apiUrl == null || apiUrl.isEmpty() || apiKey == null || apiKey.isEmpty()) {
|
||
log.warn("第三方素材API配置不完整");
|
||
return false;
|
||
}
|
||
|
||
try {
|
||
// 测试连接(使用正确格式的测试任务号)
|
||
String url = apiUrl.endsWith("/") ? apiUrl : apiUrl + "/";
|
||
url = url + "product-assets?taskNo=TASK000000000000";
|
||
|
||
log.info("测试第三方素材API连接: {}", url);
|
||
|
||
HttpHeaders headers = new HttpHeaders();
|
||
headers.set("X-API-Key", apiKey);
|
||
|
||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
||
|
||
ResponseEntity<String> response = restTemplate.exchange(
|
||
url,
|
||
HttpMethod.GET,
|
||
entity,
|
||
String.class
|
||
);
|
||
|
||
log.info("测试连接响应状态: {}", response.getStatusCode());
|
||
|
||
// 只要能收到响应(无论是404还是200),说明连接正常
|
||
return response.getStatusCode().is2xxSuccessful() ||
|
||
response.getStatusCode() == HttpStatus.NOT_FOUND;
|
||
|
||
} catch (org.springframework.web.client.HttpClientErrorException e) {
|
||
// HTTP 4xx 错误
|
||
log.info("测试连接HTTP错误: {} - {}", e.getStatusCode(), e.getResponseBodyAsString());
|
||
|
||
// 400 Bad Request 但是包含业务错误码(如TASK_NOT_FOUND, INVALID_TASK_NO)
|
||
// 说明API连接正常,只是参数不对
|
||
if (e.getStatusCode() == HttpStatus.BAD_REQUEST) {
|
||
String body = e.getResponseBodyAsString();
|
||
if (body.contains("TASK_NOT_FOUND") || body.contains("INVALID_TASK_NO")) {
|
||
log.info("API连接正常,测试任务号不存在或格式不对(这是正常的)");
|
||
return true;
|
||
}
|
||
}
|
||
|
||
// 404 Not Found 也说明连接正常
|
||
if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||
log.info("API连接正常,任务不存在(这是正常的)");
|
||
return true;
|
||
}
|
||
|
||
// 401/403 认证错误
|
||
if (e.getStatusCode() == HttpStatus.UNAUTHORIZED ||
|
||
e.getStatusCode() == HttpStatus.FORBIDDEN) {
|
||
log.error("API密钥无效或权限不足");
|
||
return false;
|
||
}
|
||
|
||
return false;
|
||
} catch (Exception e) {
|
||
log.error("测试第三方素材API连接失败: {}", e.getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|