From 98ea6004b4ce73fd44d9ecac41d679c3eb1217c8 Mon Sep 17 00:00:00 2001 From: xupei Date: Wed, 18 Jun 2025 14:19:45 +0800 Subject: [PATCH 1/3] =?UTF-8?q?TASK:=20=E6=96=B0=E5=A2=9Epose=20transfer?= =?UTF-8?q?=E6=A8=A1=E7=89=B9=E5=A7=BF=E5=8A=BF=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ai/da/common/enums/PoseEnum.java | 72 +++++++++++++++++++ .../com/ai/da/common/utils/RedisUtil.java | 2 - .../da/service/impl/GenerateServiceImpl.java | 28 ++++---- 3 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/ai/da/common/enums/PoseEnum.java diff --git a/src/main/java/com/ai/da/common/enums/PoseEnum.java b/src/main/java/com/ai/da/common/enums/PoseEnum.java new file mode 100644 index 00000000..713e791e --- /dev/null +++ b/src/main/java/com/ai/da/common/enums/PoseEnum.java @@ -0,0 +1,72 @@ +package com.ai.da.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@AllArgsConstructor +@Getter +public enum PoseEnum { + + POSE_1(1L, "aida-sys-image/pose/pose-1.mp4", "aida-sys-image/pose/pose-1.gif", "aida-sys-image/pose/pose-1-first_frame.jpeg", "AACT.8090e67b.-E3pujumEfCbDTI_rjSH-A.LwIlGT3j"), + POSE_2(2L, "aida-sys-image/pose/pose-2.mp4", "aida-sys-image/pose/pose-2.gif", "aida-sys-image/pose/pose-2-first_frame.jpeg", "AACT.8090e67b.TwJLxEv3EfCbDTI_rjSH-A.IOQZCYhf"), + POSE_3(3L, "aida-sys-image/pose/pose-3.mp4", "aida-sys-image/pose/pose-3.gif", "aida-sys-image/pose/pose-3-first_frame.jpeg", "AACT.8090e67b.gd3OCkv4EfCxyZo8eQGF2Q.qMm-a1XI"), + POSE_4(4L, "aida-sys-image/pose/pose-4.mp4", "aida-sys-image/pose/pose-4.gif", "aida-sys-image/pose/pose-4-first_frame.jpeg", "AACT.8090e67b.AUDnuEwDEfCEHBaRJeW4dg.rlx36xEY"), + POSE_5(5L, "aida-sys-image/pose/pose-5.mp4", "aida-sys-image/pose/pose-5.gif", "aida-sys-image/pose/pose-5-first_frame.jpeg", "AACT.8090e67b.G8BvkEwEEfCxyZo8eQGF2Q.fo4ryrgR"), + POSE_6(6L, "aida-sys-image/pose/pose-6.mp4", "aida-sys-image/pose/pose-6.gif", "aida-sys-image/pose/pose-6-first_frame.jpeg", "AACT.8090e67b.yBIPnEwEEfCxyZo8eQGF2Q.boSFwTG9"); + + + private final Long id; + + private final String videoPath; + + private final String gifPath; + + private final String firstFramePath; + + private final String templateId; + + private static final List> PROPERTY_LIST; + + static { + PROPERTY_LIST = Arrays.stream(values()) + .map(PoseEnum::toMap) + .collect(Collectors.toList()); + } + + private static final Map BY_ID = Arrays.stream(values()) + .collect(Collectors.toMap(PoseEnum::getId, Function.identity())); + + private static final Map BY_VIDEO_PATH = Arrays.stream(values()) + .collect(Collectors.toMap(PoseEnum::getVideoPath, Function.identity())); + + private static final List VIDEO_PATH = Arrays.stream(values()) + .map(PoseEnum::getVideoPath).collect(Collectors.toList()); + + public static PoseEnum getById(Long id) { + return BY_ID.get(id); + } + + public static PoseEnum getByVideoPath(String videoPath) { + return BY_VIDEO_PATH.get(videoPath); + } + + private Map toMap() { + Map map = new HashMap<>(); + map.put("id", String.valueOf(id)); + map.put("gif", gifPath); + map.put("firstFrame", firstFramePath); + return map; + } + + public static List> getPropertyList() { + return new ArrayList<>(PROPERTY_LIST); // 返回副本以保证不可变性 + } + + public static List getVideoList() { + return new ArrayList<>(VIDEO_PATH); // 返回副本以保证不可变性 + } +} diff --git a/src/main/java/com/ai/da/common/utils/RedisUtil.java b/src/main/java/com/ai/da/common/utils/RedisUtil.java index 72d70588..e65366ee 100644 --- a/src/main/java/com/ai/da/common/utils/RedisUtil.java +++ b/src/main/java/com/ai/da/common/utils/RedisUtil.java @@ -498,8 +498,6 @@ public class RedisUtil { public final static String STRIPE_EXCEPTION_LOG = "StripeException:"; - public final static String ANIMATE_ANYONE_TEMPLATE_ID = "AnimateAnyoneTemplateId:"; - public void batchDeleteKeysWithSamePrefix(String prefix){ Set keys = redisTemplate.keys(prefix + "*"); assert keys != null; diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index 0a220a8e..dfe4dd30 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -1416,13 +1416,12 @@ public class GenerateServiceImpl extends ServiceImpl i } public List> getAllPose(){ - String posePath = "aida-sys-image/pose/pose-1.gif"; - String firstFramePath = "aida-sys-image/pose/pose-1-first_frame.jpeg"; - HashMap resp = new HashMap<>(); - // todo 以后要返回poseId - resp.put("gif", minioUtil.getPreSignedUrl(posePath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - resp.put("firstFrame", minioUtil.getPreSignedUrl(firstFramePath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - return Arrays.asList(resp); + List> propertyList = PoseEnum.getPropertyList(); + propertyList.forEach(item -> { + item.put("gif", minioUtil.getPreSignedUrl(item.get("gif"), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + item.put("firstFrame", minioUtil.getPreSignedUrl(item.get("firstFrame"), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + }); + return propertyList; } @Override @@ -1687,13 +1686,13 @@ public class GenerateServiceImpl extends ServiceImpl i // 轮询配置 private static final int MAX_RETRIES = 30; // 最大重试次数 - private static final int POLL_INTERVAL = 2000; // 轮询间隔(毫秒) + private static final int POLL_INTERVAL = 20000; // 轮询间隔(毫秒) public String getVideoTemplateId(String videoPath){ - String key = RedisUtil.ANIMATE_ANYONE_TEMPLATE_ID + videoPath; - String templateId = redisUtil.getFromString(key); + boolean contains = PoseEnum.getVideoList().contains(videoPath); - if (StringUtil.isNullOrEmpty(templateId)){ + String templateId; + if (!contains){ String videoUrl = minioUtil.getPreSignedUrl(videoPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); JSONObject requestBody = new JSONObject(); requestBody.set("model", "animate-anyone-template-gen2"); @@ -1703,8 +1702,8 @@ public class GenerateServiceImpl extends ServiceImpl i requestBody.set("input", input); requestBody.set("parameters", parameters); - String resp = sendRequestUtil.sendPost(TEMPLATE_ID_GEN, requestBody.toString()); - + log.info("获取pose的模板id 请求数据:{}", requestBody); + String resp = sendRequestUtil.sendAliYunPostAsync(TEMPLATE_ID_GEN, requestBody.toString()); if (StringUtil.isNullOrEmpty(resp)){ throw new BusinessException("请求获取video template id失败"); } @@ -1719,7 +1718,8 @@ public class GenerateServiceImpl extends ServiceImpl i throw new BusinessException("获取动作模板失败"); } // templateId = "AACT.8090e67b.-E3pujumEfCbDTI_rjSH-A.LwIlGT3j"; - redisUtil.addToString(key, templateId); + } else { + templateId = PoseEnum.getByVideoPath(videoPath).getTemplateId(); } return templateId; From 161bba896cbf29533fd47bf07a44428317fd6496 Mon Sep 17 00:00:00 2001 From: xupei Date: Thu, 19 Jun 2025 14:08:25 +0800 Subject: [PATCH 2/3] =?UTF-8?q?BUGFIX:=20=E8=8E=B7=E5=8F=96=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E4=BB=BB=E5=8A=A1=E7=BB=93=E6=9E=9C=E6=8A=A5=E9=94=99?= =?UTF-8?q?=EF=BC=88=E8=8E=B7=E5=8F=96=E6=A8=A1=E5=9E=8B=E5=90=8D=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=A9=BA=E6=8C=87=E9=92=88=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index dfe4dd30..97c495e5 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -2042,7 +2042,9 @@ public class GenerateServiceImpl extends ServiceImpl i && func.equals(CreditsEventsEnum.POSE_TRANSFORMATION.getValue())){ List poseTransformations = poseTransformationMapper.selectList( new QueryWrapper().eq("unique_id", taskId)); - if (!poseTransformations.isEmpty() && poseTransformations.get(0).getModelName().equals("wx")){ + if (!poseTransformations.isEmpty() + && !StringUtil.isNullOrEmpty(poseTransformations.get(0).getModelName()) + && poseTransformations.get(0).getModelName().equals("wx")){ return "wx"; }else { return "local"; From 0fd1ddcde1e975b5a6c00ea82127864b288ad6b5 Mon Sep 17 00:00:00 2001 From: xupei Date: Thu, 19 Jun 2025 14:56:18 +0800 Subject: [PATCH 3/3] =?UTF-8?q?TASK:=201=E3=80=81LLM=E5=AF=B9=E8=AF=9D?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=A4=E4=B8=AA=E5=B7=A5=E5=85=B7=EF=BC=8C?= =?UTF-8?q?=E6=9F=A5=E6=89=BEsketch=E5=92=8C=E4=BF=AE=E6=94=B9=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=8F=82=E6=95=B0=202=E3=80=81=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=8E=B7=E5=8F=96=E6=9C=80=E6=96=B0=E7=9A=84?= =?UTF-8?q?minio=E5=9B=BE=E7=89=87=E9=A2=84=E8=A7=88=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../da/controller/ThirdPartyController.java | 11 +++ .../da/mapper/primary/entity/Workspace.java | 4 +- .../ai/da/service/impl/LLMServiceImpl.java | 94 +++++++++++++++++-- 3 files changed, 102 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/ai/da/controller/ThirdPartyController.java b/src/main/java/com/ai/da/controller/ThirdPartyController.java index 40cdaf42..f0779f81 100644 --- a/src/main/java/com/ai/da/controller/ThirdPartyController.java +++ b/src/main/java/com/ai/da/controller/ThirdPartyController.java @@ -1,6 +1,8 @@ package com.ai.da.controller; +import com.ai.da.common.constant.CommonConstant; import com.ai.da.common.response.Response; +import com.ai.da.common.utils.MinioUtil; import com.ai.da.mapper.primary.entity.GoogleUser; import com.ai.da.model.dto.*; import com.ai.da.model.vo.AccountLoginVO; @@ -35,6 +37,9 @@ public class ThirdPartyController { @Resource private DesignService designService; + @Resource + private MinioUtil minioUtil; + /*@ApiOperation(value = "Add user information") @PostMapping("/addUser") public Response addUser(@Valid @RequestBody AccountAddDTO accountAddDTO) { @@ -153,4 +158,10 @@ public class ThirdPartyController { public Response receiveDesignParams(@Valid @RequestBody ReceiveDesignParam receiveDesignParam) { return Response.success(designService.receiveDesignParams(receiveDesignParam)); } + + @ApiOperation(value = "刷新minio预签名地址") + @GetMapping("/refreshMinioUrl") + public Response refreshMinioUrl(@RequestParam("path") String path){ + return Response.success(minioUtil.getPreSignedUrl(path, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + } } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/Workspace.java b/src/main/java/com/ai/da/mapper/primary/entity/Workspace.java index c3714550..b2b16d2b 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/Workspace.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/Workspace.java @@ -44,7 +44,9 @@ public class Workspace implements Serializable { */ @ApiModelProperty(value = "用户ID") private Long accountId; - + /** + * 年龄段 Adult || Child + */ private String ageGroup; /** * 性别 diff --git a/src/main/java/com/ai/da/service/impl/LLMServiceImpl.java b/src/main/java/com/ai/da/service/impl/LLMServiceImpl.java index 75111708..24a182ac 100644 --- a/src/main/java/com/ai/da/service/impl/LLMServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/LLMServiceImpl.java @@ -1,5 +1,6 @@ package com.ai.da.service.impl; +import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.constant.CommonConstant; import com.ai.da.common.context.UserContext; import com.ai.da.common.enums.CollectionLevel1TypeEnum; @@ -20,11 +21,16 @@ import com.ai.da.python.PythonService; import com.ai.da.service.DesignService; import com.ai.da.service.LLMService; import com.ai.da.service.SysFileService; +import com.ai.da.service.WorkspaceService; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.text.StringEscapeUtils; +import org.checkerframework.checker.units.qual.C; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -71,6 +77,8 @@ public class LLMServiceImpl implements LLMService { private CollectionElementMapper collectionElementMapper; @Resource private CollectionElementRelModelMapper collectionElementRelModelMapper; + @Value("${minio.bucketName.sysImage}") + private String sysImage; @Override public SseEmitter stream(String prompt, Long projectParamId, String fileUrl, List imageUrlList, String token, Boolean enableThinking, String process) { @@ -78,12 +86,12 @@ public class LLMServiceImpl implements LLMService { executor.submit(() -> { try { - boolean validate = jwtTokenHelper.validateToken(token); + boolean validate = jwtTokenHelper.validateToken(token); // if (validate) { AuthPrincipalVo principal = jwtTokenHelper.parserToUser(token); Long accountId = principal.getId(); - String url = "http://18.167.251.121:10002/chat-stream"; -// String url = "http://10.1.1.240:1013/chat-stream"; +// String url = "http://18.167.251.121:10002/chat-stream"; + String url = "http://10.1.1.240:1013/chat-stream"; HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); @@ -222,10 +230,12 @@ public class LLMServiceImpl implements LLMService { @Override public SseEmitter streamNew(String prompt, Long projectParamId, String fileUrl, List imageUrlList, String token, Boolean enableThinking, String process) { SseEmitter emitter = new SseEmitter(0L); // 永不超时 + List designTools = Arrays.asList("moodboard", "printboard", "generate_color_code", "sketchboard"); executor.submit(() -> { try { - boolean validate = jwtTokenHelper.validateToken(token); +// boolean validate = jwtTokenHelper.validateToken(token); + boolean validate = true; if (validate) { AuthPrincipalVo principal = jwtTokenHelper.parserToUser(token); Long accountId = principal.getId(); @@ -327,7 +337,9 @@ public class LLMServiceImpl implements LLMService { } String toolsName = json.getString("tools_name"); JSONObject toolsData = json.getJSONObject("content"); - if (Objects.nonNull(toolsName) && !toolsName.equals("design_control_signal") && !toolsName.equals("generate_project_info")) { + /*&& !toolsName.equals("design_control_signal") + && !toolsName.equals("generate_project_info")*/ + if (Objects.nonNull(toolsName) && designTools.contains(toolsName)) { boolean color = true; ReceiveDesignParam receiveDesignParam = JSONObject.parseObject(JSONObject.toJSONString(toolsData), ReceiveDesignParam.class); receiveDesignParam.setProjectId(projectId); @@ -353,6 +365,11 @@ public class LLMServiceImpl implements LLMService { systemImage.setContent(JSONObject.toJSONString(receiveDesignParam.getReceiveCollectionElementList())); systemImage.setAccountId(accountId); chatMessageMapper.insert(systemImage); + } else if (Objects.nonNull(toolsName) && toolsName.equals("search_sketch_img")) { + json.put("content", processSearchSketchToolCon(toolsData)); + } else if (Objects.nonNull(toolsName) + && toolsName.equals("update_project_info")) { + updateProjectParams(projectId, toolsData); } emitter.send(json.toJSONString()); } @@ -367,7 +384,6 @@ public class LLMServiceImpl implements LLMService { } } } - emitter.complete(); } catch (Exception e) { System.out.println("走进异常"); @@ -378,6 +394,72 @@ public class LLMServiceImpl implements LLMService { return emitter; } + private String processSearchSketchToolCon(JSONObject content){ + // content内容 "{\"sketch_list\": [\"\\\\female\\\\blouse\\\\blouse_645.jpg\", \"\\\\female\\\\dress\\\\0902004968.jpg\"]}" + JSONArray sketchList = content.getJSONArray("sketch_list"); + if (sketchList.isEmpty()){ + return null; + } + ArrayList dataList = new ArrayList<>(); + sketchList.forEach(sketch -> { + ReceiveCollectionElement receiveCollectionElement = new ReceiveCollectionElement(); + receiveCollectionElement.setUrl((String) sketch); + receiveCollectionElement.setMinioUrl(minioUtil.getPreSignedUrl(sysImage + "/images" + sketch, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + dataList.add(receiveCollectionElement); + }); + ReceiveDesignParam receiveDesignParam = new ReceiveDesignParam(); + receiveDesignParam.setReceiveCollectionElementList(dataList); + return JSONArray.toJSONString(receiveDesignParam); + } + + @Resource + private WorkspaceService workspaceService; + private String updateProjectParams(Long projectId, JSONObject jsonObject){ + // 1. 获取 project_info 并转换为 List> + List> projectInfoList = (List>) jsonObject.get("project_info"); + + Long workspaceId = workspaceService.getByProjectId(projectId); + if (Objects.isNull(workspaceId)){ + throw new BusinessException("未知projectId"); + } + Workspace workspace = workspaceService.getBaseMapper().selectOne(new QueryWrapper().eq("project_id", projectId)); + if (!projectInfoList.isEmpty()){ + projectInfoList.forEach(info -> + info.forEach((key, value) -> { + switch (key){ + case "project_name": + Project project = projectMapper.selectById(projectId); + project.setName(value); + project.setUpdateTime(LocalDateTime.now()); + projectMapper.updateById(project); + break; + case "ageGroup": + workspace.setAgeGroup(value); + break; + case "gender": + workspace.setSex(value); + break; + case "position": + workspace.setPosition(value); + break; + case "style": + QueryWrapper