Commit 8ed3fd93 by Jony.L

Merge remote-tracking branch 'origin/develop' into develop

# Conflicts:
#	computility-module-external/src/main/java/com/luhu/computility/module/external/controller/openapi/service/OpenApiService.java
#	computility-module-external/src/main/java/com/luhu/computility/module/external/controller/openapi/service/OpenApiServiceImpl.java
#	computility-server/src/main/resources/application.yaml
parents a4583428 1b47cb9f
......@@ -149,11 +149,34 @@ public class HttpUtils {
* @return 请求结果
*/
public static String post(String url, Map<String, String> headers, String requestBody) {
try (HttpResponse response = HttpRequest.post(url)
.addHeaders(headers)
Map<String, String> safeHeaders = headers == null ? new java.util.HashMap<>() : headers;
HttpResponse response = null;
try {
response = HttpRequest.post(url)
.addHeaders(safeHeaders)
.setFollowRedirects(true)
.body(requestBody)
.execute();
// Manually follow 30x if not auto-followed
if (isRedirect(response)) {
String location = response.header("Location");
if (StrUtil.isNotBlank(location)) {
String newUrl = resolveRedirectUrl(url, location);
try (HttpResponse redirected = HttpRequest.post(newUrl)
.addHeaders(safeHeaders)
.setFollowRedirects(true)
.body(requestBody)
.execute()) {
return redirected.body();
}
}
}
return response.body();
} finally {
if (response != null) {
response.close();
}
}
}
......@@ -167,34 +190,76 @@ public class HttpUtils {
* @return 请求结果
*/
public static String get(String url, Map<String, String> headers) {
try (HttpResponse response = HttpRequest.get(url)
.addHeaders(headers)
Map<String, String> safeHeaders = headers == null ? new java.util.HashMap<>() : headers;
HttpResponse response = null;
try {
response = HttpRequest.get(url)
.addHeaders(safeHeaders)
.setFollowRedirects(true)
.execute();
if (isRedirect(response)) {
String location = response.header("Location");
if (StrUtil.isNotBlank(location)) {
String newUrl = resolveRedirectUrl(url, location);
try (HttpResponse redirected = HttpRequest.get(newUrl)
.addHeaders(safeHeaders)
.setFollowRedirects(true)
.execute()) {
return redirected.body();
}
}
}
return response.body();
} finally {
if (response != null) {
response.close();
}
}
}
public static String postIncludeImage(String url, Map<String, String> headers, Map<String, Object> formMaps) {
try (HttpResponse response = openApiPost(url)
.addHeaders(headers)
Map<String, String> safeHeaders = headers == null ? new java.util.HashMap<>() : headers;
HttpResponse response = null;
try {
response = openApiPost(url)
.addHeaders(safeHeaders)
.setFollowRedirects(true)
.form(formMaps)
.execute();
if (isRedirect(response)) {
String location = response.header("Location");
if (StrUtil.isNotBlank(location)) {
String newUrl = resolveRedirectUrl(url, location);
try (HttpResponse redirected = openApiPost(newUrl)
.addHeaders(safeHeaders)
.setFollowRedirects(true)
.form(formMaps)
//.form(fileName, file) // 上传文件,"fileName"是接口中定义的字段名
.execute()) {
return redirected.body();
}
}
}
return response.body();
} finally {
if (response != null) {
response.close();
}
}
}
public static HttpRequest openApiPost(String url) {
return HttpRequest.post(url)
.setReadTimeout(300000);
.setReadTimeout(300000)
.setFollowRedirects(true);
}
public static String get(String url, Map<String, String> headers, Map<String, String> queryParams) {
try {
// 构建查询参数字符串
StringBuilder queryBuilder = new StringBuilder();
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
if (queryBuilder.length() > 0) {
......@@ -205,17 +270,36 @@ public class HttpUtils {
.append(entry.getValue());
}
// 拼接完整的 URL
String fullUrl = url;
if (queryBuilder.length() > 0) {
fullUrl += "?" + queryBuilder.toString();
fullUrl += "?" + queryBuilder;
}
// 发送 GET 请求并返回响应体
try (HttpResponse response = HttpRequest.get(fullUrl)
.addHeaders(headers)
Map<String, String> safeHeaders = headers == null ? new java.util.HashMap<>() : headers;
HttpResponse response = null;
try {
response = HttpRequest.get(fullUrl)
.addHeaders(safeHeaders)
.setFollowRedirects(true)
.execute();
if (isRedirect(response)) {
String location = response.header("Location");
if (StrUtil.isNotBlank(location)) {
String newUrl = resolveRedirectUrl(fullUrl, location);
try (HttpResponse redirected = HttpRequest.get(newUrl)
.addHeaders(safeHeaders)
.setFollowRedirects(true)
.execute()) {
return redirected.body();
}
}
}
return response.body();
} finally {
if (response != null) {
response.close();
}
}
} catch (Exception e) {
e.printStackTrace();
......@@ -223,5 +307,24 @@ public class HttpUtils {
}
}
private static boolean isRedirect(HttpResponse response) {
if (response == null) return false;
int status = response.getStatus();
return status == 301 || status == 302 || status == 303 || status == 307 || status == 308;
}
private static String resolveRedirectUrl(String baseUrl, String location) {
if (StrUtil.startWithIgnoreCase(location, "http://") || StrUtil.startWithIgnoreCase(location, "https://")) {
return location;
}
// Relative redirect; resolve against baseUrl
try {
java.net.URI base = java.net.URI.create(baseUrl);
return base.resolve(location).toString();
} catch (Exception ignore) {
return location;
}
}
}
......@@ -26,6 +26,7 @@ import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
......@@ -82,6 +83,9 @@ public class ApiSignatureAspect {
//查询appId对应的Secret
String appId = request.getHeader(signature.appId());
if (StringUtils.isEmpty(appId)) {
throw new ServiceException(INVALID_APPID);
}
AppCredentialRespDTO appCredentialRespDTO = appCredentialApi.getAppSecretByAppid(appId);
if (!ObjectUtil.isEmpty(appCredentialRespDTO)) {
Assert.notNull(appCredentialRespDTO.getAppId(), "[appId({})] 找不到对应的 appSecret", appId);
......
......@@ -30,4 +30,8 @@ public class AiGeneratedFileSaveReqVO {
private String coverImage;
@Schema(description = "进度消息")
private String message;
}
......@@ -9,6 +9,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import me.zhyd.oauth.log.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -77,12 +78,13 @@ public class OpenApiController {
@RequestParam(value = "sourceImageUrl", required = false) String sourceImageUrl,
@RequestPart(value = "targetImage", required = false) MultipartFile targetImage,
@RequestParam(value = "targetImageUrl", required = false) String targetImageUrl) {
Log.error("ai换脸-图片换脸");
return openApiService.faceImageGenerate(sourceImage, sourceImageUrl, targetImage, targetImageUrl);
}
@ApiAccessLog
@GetMapping("/view-image")
@PostMapping("/view-image")
@Operation(summary = "根据promptId取换脸后的图", description = "根据promptId取换脸后的图")
@ApiSignature
public CommonResult<ViewSourceRespDTO> viewImage(@RequestBody ViewImageReqDTO viewImageReqDTO){
......@@ -105,7 +107,7 @@ public class OpenApiController {
@ApiAccessLog
@GetMapping("/view-video")
@PostMapping("/view-video")
@Operation(summary = "根据promptId取最后生成的视频", description = "根据promptId取最后生成的视频")
@ApiSignature
public CommonResult<ViewSourceRespDTO> viewVideo(@RequestBody ViewVideoReqDTO viewVideoReqDTO){
......
......@@ -61,7 +61,7 @@ public interface OpenApiService {
SseEmitter zhipuMultiStreamChat(ZhipuConversationReqDTO zhipuConversationReqDTO);
String getSourceUrl(String promptId, Integer type);
String getSourceUrl(Integer id, String promptId, Integer type);
}
......@@ -50,6 +50,7 @@ import com.luhu.computility.module.external.eums.DictDataConstants;
import com.luhu.computility.module.external.eums.DictTypeConstants;
import com.luhu.computility.module.external.service.file.AiGeneratedFileService;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.log.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
......@@ -127,6 +128,10 @@ public class OpenApiServiceImpl implements OpenApiService {
@Value("${swap-face.glm-multi-stream-chat}")
private String zhipuMultiStreamChat;
@Value("${swap-face.download-image}")
private String downloadFile;
@Autowired
private SSEService sseService;
......@@ -315,8 +320,11 @@ public class OpenApiServiceImpl implements OpenApiService {
.setUrl(aiGeneratedFileDO.getUrl())
.setCoverImage(aiGeneratedFileDO.getUrl() + videoSuffix));
} else {
String errorMsg = aiGeneratedFileDO.getMessage();
if (aiGeneratedFileDO.getStatus() == 1 && StringUtils.isEmpty(errorMsg)) {
errorMsg = "视频流正在创建";
}
Integer errorCode = GlobalResponseCodeConstants.BEING_GENERATED.getCode();
String errorMsg = GlobalResponseCodeConstants.INVALID_SERIAL_NUMBER.getMsg();
return error(errorCode, errorMsg);
}
} else {
......@@ -576,7 +584,7 @@ public class OpenApiServiceImpl implements OpenApiService {
@Override
public String getSourceUrl(String promptId, Integer type) {
public String getSourceUrl(Integer id, String promptId, Integer type) {
try {
Map<String, String> queryParams = new HashMap<>();
queryParams.put("promptId", promptId);
......@@ -587,10 +595,21 @@ public class OpenApiServiceImpl implements OpenApiService {
result = HttpUtils.get(viewImageUrl, null, queryParams);
}
CommonResult<ViewSourceRespDTO> viewVideoRespDTOCommonResult = handleJsonObjectResult(result, ViewSourceRespDTO.class);
aiGeneratedFileService.updateAiGeneratedFile(new AiGeneratedFileSaveReqVO()
.setId(id)
.setMessage(viewVideoRespDTOCommonResult.getMsg()));
if (viewVideoRespDTOCommonResult.getCode() == 10001) {
Log.error("换脸工作流还在进行,请稍后再试");
} else if (viewVideoRespDTOCommonResult.getCode() == 0) {
return viewVideoRespDTOCommonResult.getData().getUrl();
} else {
return null;
}
}catch (Exception e) {
return "获资源地址异常";
Log.error("换脸获资源地址异常:" + e.toString());
return null;
}
return null;
}
@Override
......
......@@ -60,4 +60,9 @@ public class AiGeneratedFileDO extends BaseDO {
*/
private String coverImage;
/**
* 进度消息
*/
private String message;
}
......@@ -14,6 +14,7 @@ import com.luhu.computility.module.external.controller.openapi.service.OpenApiSe
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.service.file.AiGeneratedFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
......@@ -37,6 +38,9 @@ public class UpdateAiGeneratedFileStatusJob implements JobHandler {
private OpenApiService openApiService;
@Value("${swap-face.download-image}")
private String downloadImage;
@Override
@TenantIgnore
public String execute(String param) {
......@@ -44,7 +48,7 @@ public class UpdateAiGeneratedFileStatusJob implements JobHandler {
int num = 0;
if (!CollectionUtil.isEmpty(aiGeneratedFileList)){
for (AiGeneratedFileDO aiGeneratedFileDO : aiGeneratedFileList) {
String originalUrl = openApiService.getSourceUrl(aiGeneratedFileDO.getPromptId(), aiGeneratedFileDO.getType());
String originalUrl = openApiService.getSourceUrl(aiGeneratedFileDO.getId(), aiGeneratedFileDO.getPromptId(), aiGeneratedFileDO.getType());
if (!ObjectUtil.isEmpty(originalUrl)) {
aiGeneratedFileService.updateAiGeneratedFile(new AiGeneratedFileSaveReqVO()
.setId(aiGeneratedFileDO.getId())
......
......@@ -8,8 +8,8 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
* @Date 2025/8/4
* @注释
*/
public class Test {
public class PasswordGenerated {
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("a123456"));
System.out.println(new BCryptPasswordEncoder().encode("ljq002"));
}
}
......@@ -168,9 +168,9 @@ computility:
captcha:
enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试;
pay:
order-notify-url: https://phslgld.hnluchuan.com/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
refund-notify-url: https://phslgld.hnluchuan.com/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
transfer-notify-url: https://phslgld.hnluchuan.com/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址
order-notify-url: https://ric.admin.lijinqi.com/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
refund-notify-url: https://ric.admin.lijinqi.com/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
transfer-notify-url: https://ric.admin.lijinqi.com/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址
wpgj-pay:
# WPGJ旺铺聚合支付配置
# organiz-no: 105549
......@@ -178,8 +178,8 @@ computility:
# mer-code: K20241200111267
# term-code: 1011215692596
# api-url: https://stg5-qr.wpgjcs.com/industrial/payment/dynamic
# notify-url-compute: https://phslgld.hnluchuan.com/admin-api/compute/wpgj/notify # 算力资源模块WPGJ回调地址
# notify-url-api: https://phslgld.hnluchuan.com/admin-api/apihub/wpgj/notify # APIHub模块WPGJ回调地址
# notify-url-compute: https://ric.admin.lijinqi.com/admin-api/compute/wpgj/notify # 算力资源模块WPGJ回调地址
# notify-url-api: https://ric.admin.lijinqi.com/admin-api/apihub/wpgj/notify # APIHub模块WPGJ回调地址
# sign-key: 07714583f82b4db8b675b32cd5e0969743 # WPGJ回调签名密钥(测试用,实际需要向WPGJ确认)
# public-key: |
# -----BEGIN PUBLIC KEY-----
......@@ -209,8 +209,8 @@ computility:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDF7YNor7LvSq1GLB7P592FKoxwFJfOLHibMtFQ2wTRDCiCufYuEoRWzm6mbpRQXauzaqfdwWfjlHbBXDJ2jx/CWawwfOmLHb6KHpdRgBV4OgbSW7Z+3WL8d2kTsc8GMRl7exJtw+vxhQM+sN8ny2zFSrsJKgEtjHAtKQmNgoXMA33xyfN3MbjoPu8okMftXpc4th+uf+LxyX1CCpc7egscNKcEqlFmekt36WJ4UcWLB6Cw4tZbd7IYaqTrFNNtmPi47D5YG0CW0ko8lJajOW61BjTS1X5lh4EUnX03+02YZwB2eOG4lZC/W/NiU7tc0xin7JjubgUTaePWsRInA0CnAgMBAAECggEAON2FbLVWFnQBFnEkpRz7wv+3e5gfCUgzmnteMfnLB3iTxwNAnHoLdZk3py+MAw72fsS81/RyMat89w7THMcAG+mBlCi/PI3eKXaiiPLguDsLrLJW21olz11LXjIuxZujs5tnbwvkJO7PQNq2Mou6g3B2Dir4TarUq9TnfrWqVTOFz8j7/g0Ha+FY8w2BqYw1APbwAJnNHqJylKIw3IM4UcusF5zbZRnqvd3BKF2bRVzv51FdMeSSEPtMKN7atUAiv5PLJiGXPiuM4s6DcMqo8kA3si3eFZrZT8V7gwR1sqv0S+8m5N2NqbzSsuuVBAMnId4H/q75UcPUfMGDWXNsoQKBgQD1UkQTV3hTpwU6QHYuASDde9aT+DMaHTC7PxMK1uTLnxt3udErV8gZBPUf7iwn9RsLxNAyh6I5iRvcpiAcZngG8qq/sCncupe/Jl1T0XxauvoWo5FMmKrr/ilFQJcqUdcvKz6Ztqj02ljDf5WvD2ZPT9FnYgl4kqK+vjEMUMsusQKBgQDOix445F0SalDZdgNljNNpGOfad3mrOda5yO22NGy4cFvm7ionYHVe19R/zUKe8hbEQpgsYfhb5E4nq6kIDxIm5enmLWfAj7aC5aiwghB60Ydk3XcDUpDr51U3PS4Y7WBeJoMhmTOPPw1uuuptKox9krdw816ib+BA3U2KC5Yq1wKBgCO09KmoCqCKZ+1hopHxohn6w3HIJ4/+fbBTbu8d9jFZGENl7XcUkNBrc05ReWXbfDNLU053hXpAZajJGVVo6MGCIq5B8uXo1tuAtwbTL/l4y5vt9OEkO4Sb+t/UlewX+20nKzZuassw2Mij0mKnqCmVIZKdp2lAVqXSwwra26gRAoGAGZC+vOwHWTAvsbsZ0IgN4wRiLnh7ZuZR3c0xH0x96JZ/yaXRMe6OmJ6+ftM5W9M7Xi+gBl5aD4XC5sYotganiIkM2qDkJsGjJbCnoLF4uLsWtzVydcbSiWCo+51nB07ajszVjmMYLrLvRrV8LucFXMW8Tw7Qt+qBJ4Y9AslMXSECgYEArOeQJ2Pkw12dyGENrtETTUbZsKanO8ptoZ+PUguzQQA8OVlRbRfKRUVgUvNniVi6MPILMkpdpVOrh8nCfDo6okN7jV0FasCq172ZsjItg3LuuaZHthaTt2R61ms6lpxS8EBPuL72/IcQRKyfPMbZDF2dbT4oS7OMF+KKHMuqxFE=
-----END PRIVATE KEY-----
notify-url-compute: https://phslgld.hnluchuan.com/admin-api/compute/wpgj/notify # 算力资源模块WPGJ回调地址
notify-url-api: https://phslgld.hnluchuan.com/admin-api/apihub/wpgj/notify # APIHub模块WPGJ回调地址
notify-url-compute: https://ric.admin.lijinqi.com/admin-api/compute/wpgj/notify # 算力资源模块WPGJ回调地址
notify-url-api: https://ric.admin.lijinqi.com/admin-api/apihub/wpgj/notify # APIHub模块WPGJ回调地址
access-log: # 访问日志的配置项
enable: true
demo: false # 开启演示模式
......
......@@ -59,9 +59,9 @@ spring:
#username: root
#password: 159357 # D7kaJdNdLsjzXGhD
url: jdbc:mysql://43.139.100.220:13306/new_computility?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://42.192.64.253:13306/new_computility?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: D7kaJdNdLsjzXGhD
password: Lhkj666888.
# url: jdbc:mysql://8.136.9.68:3306/new_computility?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
# username: root
......
......@@ -390,11 +390,11 @@ digital-human-zhuxi:
token: Basic emh1eGlAdHhnOndBSmNETDRMZVZ3QjlhdlV1OVJN
similar-image:
base-url: https://218.77.58.42:18088/
base-url: http://218.77.58.42:18088
match-mage: ${similar-image.base-url}/matchImage
swap-face:
base-url: http://218.77.58.42:18088/
base-url: http://218.77.58.42:18088
upload-image: ${swap-face.base-url}/uploadFaceSwapImage
create-video-stream: ${swap-face.base-url}/reActorFaceSwap
view-video: ${swap-face.base-url}/viewVideo
......@@ -404,6 +404,7 @@ swap-face:
AIQA-chat: ${swap-face.base-url}/v1/AIQA-chat
AIQA-stream-chat: ${swap-face.base-url}/v1/AIQA-stream-chat
aliyun-stream-chat: ${swap-face.base-url}/v1/aliyun-ai-chat
download-image: ${swap-face.base-url}/downloadImage?promptId=
glm-stream-chat: ${swap-face.base-url}/chat/stream
glm-multi-stream-chat: ${swap-face.base-url}/chat/multi-stream
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment