diff --git a/.gitea/workflows/develop_3.1_MS_build_manual.yaml b/.gitea/workflows/develop_3.1_MS_build_manual.yaml index 2b88d049..51753117 100644 --- a/.gitea/workflows/develop_3.1_MS_build_manual.yaml +++ b/.gitea/workflows/develop_3.1_MS_build_manual.yaml @@ -102,7 +102,7 @@ jobs: - ./temp:/temp - ./uploads:/temp/uploads ports: - - '10090:5567' + - '10090:5566' restart: always EOF # 验证docker-compose.yml生成 diff --git a/src/main/java/com/ai/da/common/constant/CommonConstant.java b/src/main/java/com/ai/da/common/constant/CommonConstant.java index 9f7ac8bc..cdc86d3e 100644 --- a/src/main/java/com/ai/da/common/constant/CommonConstant.java +++ b/src/main/java/com/ai/da/common/constant/CommonConstant.java @@ -10,7 +10,7 @@ public class CommonConstant { // 单位 秒 两天过期 public static final Long CREDITS_EXPIRE_TIME = 2 * 24 * 60 * 60L; // 单位 分钟 - public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60; + public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60 * 7; // 单位 秒 一天过期 in redis public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L; // 单位 秒 7天过期 diff --git a/src/main/java/com/ai/da/common/utils/MinioUtil.java b/src/main/java/com/ai/da/common/utils/MinioUtil.java index d13c9eb4..b15fdf2f 100644 --- a/src/main/java/com/ai/da/common/utils/MinioUtil.java +++ b/src/main/java/com/ai/da/common/utils/MinioUtil.java @@ -14,6 +14,7 @@ import io.netty.util.internal.StringUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -41,6 +42,9 @@ public class MinioUtil { @Autowired private MinioClient minioClient; + @Value("${minio.endpoint}") + private String endpoint; + /** * 获取MinIO客户端实例 */ @@ -958,6 +962,166 @@ public class MinioUtil { } } + /** + * 检测字符串是否为预签名URL + * 通过检查URL中是否包含minio endpoint来判断 + * + * @param str 待检测的字符串 + * @return true表示是预签名URL,false表示不是 + */ + public boolean isPresignedUrl(String str) { + if (str == null || str.isEmpty()) { + return false; + } + try { + // 检查字符串是否是一个有效的URL + URL url = new URL(str); + String host = url.getHost(); + // 获取endpoint中的主机部分(去掉http://或https://) + String endpointHost = endpoint; + if (endpointHost.startsWith("http://")) { + endpointHost = endpointHost.substring(7); + } else if (endpointHost.startsWith("https://")) { + endpointHost = endpointHost.substring(8); + } + // 去掉端口号 + if (endpointHost.contains(":")) { + endpointHost = endpointHost.substring(0, endpointHost.indexOf(":")); + } + // 检查URL的host是否与endpoint的host匹配 + return host.equals(endpointHost); + } catch (Exception e) { + // 不是有效的URL + return false; + } + } + + /** + * 检测字符串是否为MinIO逻辑路径(bucketName/objectName格式) + * 逻辑路径特点: + * 1. 包含 "/"(桶名和对象名之间的分隔符) + * 2. 不是完整的URL(不以http://或https://开头) + * 3. 路径中没有查询参数 + * + * @param str 待检测的字符串 + * @return true表示是MinIO逻辑路径,false表示不是 + */ + public boolean isMinioLogicalPath(String str) { + if (str == null || str.isEmpty()) { + return false; + } + // 必须是字符串 + if (!(str instanceof String)) { + return false; + } + String trimStr = str.trim(); + // 不应该以http://或https://开头 + if (trimStr.startsWith("http://") || trimStr.startsWith("https://")) { + return false; + } + // 应该包含 "/"(bucket/object格式) + if (!trimStr.contains("/")) { + return false; + } + // 不应该包含空格或特殊字符 + if (trimStr.contains(" ") || trimStr.contains("\n") || trimStr.contains("\t")) { + return false; + } + return true; + } + + /** + * 将预签名URL转换为逻辑路径 + * + * @param presignedUrl 预签名URL + * @return 逻辑路径(格式:bucketName/objectName) + */ + public String getLogicalPathFromPresignedUrl(String presignedUrl) { + try { + // 解析URL + URL url = new URL(presignedUrl); + + // 获取路径部分(去掉开头的/) + String path = url.getPath(); + if (path.startsWith("/")) { + path = path.substring(1); + } + + // 路径格式为 bucketName/objectName + // Minio路径中可能包含多个/,需要正确分割 + int firstSlashIndex = path.indexOf("/"); + if (firstSlashIndex <= 0) { + throw new MinioException("预签名URL路径格式无效,应包含桶名和对象名: " + presignedUrl); + } + + String bucketName = path.substring(0, firstSlashIndex); + String objectName = path.substring(firstSlashIndex + 1); + +// log.info("预签名URL转换成功,桶名: {}, 对象名: {}", bucketName, objectName); + return bucketName + "/" + objectName; + } catch (Exception e) { + log.error("预签名URL解析失败: {}", e.getMessage(), e); + throw new BusinessException("system.error"); + } + } + + + /** + * 处理MinIO资源(预签名URL或逻辑路径),统一生成预签名URL + * + * @param resource 预签名URL或逻辑路径 + * @param expires 过期时间(秒) + * @return 新的预签名URL + */ + public String processMinioResource(String resource, int expires) { + try { + String logicalPath; + if (isPresignedUrl(resource)) { + // 是预签名URL,解析为逻辑路径 + logicalPath = getLogicalPathFromPresignedUrl(resource); + } else if (isMinioLogicalPath(resource)) { + // 本身就是逻辑路径 + logicalPath = resource.trim(); + } else { + // 不认识的内容,直接返回原始值 + log.warn("未识别的MinIO资源格式: {}", resource); + return resource; + } + + // 统一生成预签名URL + return getPreSignedUrl(logicalPath, expires); + } catch (Exception e) { + log.error("处理MinIO资源失败: {}, error: {}", resource, e.getMessage(), e); + // 如果失败,返回原始内容 + return resource; + } + } + + /** + * 将任意MinIO URL转换为逻辑路径 + * 检测URL类型并转换为逻辑路径返回 + * + * @param url 预签名URL或逻辑路径 + * @return 逻辑路径(格式:bucketName/objectName) + * @throws MinioException 如果不是有效的MinIO资源 + */ + public String convertToLogicalPath(String url) { + if (url == null || url.isEmpty()) { + throw new BusinessException("url.cannot.be.empty"); + } + if (isMinioLogicalPath(url)) { + // 本身就是逻辑路径,直接返回 + return url.trim(); + } else if (isPresignedUrl(url)) { + // 是预签名URL,转换为逻辑路径 + return getLogicalPathFromPresignedUrl(url); + } else { + // 不认识的内容,抛出异常 + throw new BusinessException("无法识别的MinIO资源格式: " + url + ",请提供有效的预签名URL或逻辑路径"); + } + } + + } diff --git a/src/main/java/com/ai/da/seller/DesignUrlsDTO.java b/src/main/java/com/ai/da/seller/DesignUrlsDTO.java new file mode 100644 index 00000000..2ac17a03 --- /dev/null +++ b/src/main/java/com/ai/da/seller/DesignUrlsDTO.java @@ -0,0 +1,31 @@ +package com.ai.da.seller; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import java.util.List; + +/** + * 设计URLs DTO + */ +@Data +@Schema(description = "设计URLs数据传输对象") +public class DesignUrlsDTO { + + /** + * 设计项ID + */ + @Schema(description = "设计项ID", example = "1") + private Long designItemId; + + /** + * TO_PRODUCT_IMAGE类型的URL列表 + */ + @Schema(description = "TO_PRODUCT_IMAGE类型的URL列表") + private List toProductImageUrls; + + /** + * DesignItemDetail的path列表 + */ + @Schema(description = "DesignItemDetail的path列表") + private List clothes; +} diff --git a/src/main/java/com/ai/da/seller/SellerController.java b/src/main/java/com/ai/da/seller/SellerController.java new file mode 100644 index 00000000..0e2eeb89 --- /dev/null +++ b/src/main/java/com/ai/da/seller/SellerController.java @@ -0,0 +1,44 @@ +package com.ai.da.seller; + +import com.ai.da.common.response.Response; +import com.ai.da.service.UserLikeGroupService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import java.util.ArrayList; +import java.util.List; + +/** + * Seller Controller + */ +@RestController +@RequestMapping("/api/seller") +@RequiredArgsConstructor +@Tag(name = "Seller", description = "Seller相关接口") +public class SellerController { + + private final UserLikeGroupService userLikeGroupService; + + /** + * 根据designItemId列表获取设计相关的URL列表 + * @param designItemIds designItemId列表 + * @return 设计URLs DTO列表 + */ + @GetMapping("/sketchDetail") + @Operation(summary = "获取设计相关URL列表", description = "根据designItemId列表获取设计相关的URL列表,包括TO_PRODUCT_IMAGE类型的URL和DesignItemDetail的path列表") + public Response> getDesignUrlsByDesignItemIds( + @Parameter(description = "设计项ID列表", required = true, example = "1,2,3") + @RequestParam List designItemIds) { + List designUrlsDTOList = new ArrayList<>(); + for (Long designItemId : designItemIds) { + DesignUrlsDTO designUrlsDTO = userLikeGroupService.getToProductImageUrlsByDesignItemId(designItemId); + designUrlsDTOList.add(designUrlsDTO); + } + return Response.success(designUrlsDTOList); + } +} diff --git a/src/main/java/com/ai/da/service/UserLikeGroupService.java b/src/main/java/com/ai/da/service/UserLikeGroupService.java index 61ea9f5f..c9b2c3a3 100644 --- a/src/main/java/com/ai/da/service/UserLikeGroupService.java +++ b/src/main/java/com/ai/da/service/UserLikeGroupService.java @@ -1,124 +1,132 @@ -package com.ai.da.service; - -import com.ai.da.common.response.PageBaseResponse; -import com.ai.da.mapper.primary.entity.*; -import com.ai.da.model.dto.*; -import com.ai.da.model.vo.*; -import com.alibaba.fastjson.JSONObject; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.service.IService; -import io.minio.errors.MinioException; -import org.springframework.web.multipart.MultipartFile; - -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.List; - -/** - * 服务类 - * - * @author yanglei - * @since 2022-09-11 - */ -public interface UserLikeGroupService extends IService { - - void deleteUserGroup(Long userGroupId); - - HistoryUpdateVO updateUserGroupName(Long userGroupId, String userGroupName, String timeZone); - - Long insertUserGroup(Long userId, Long collectionId, String timeZone, Long projectId); - - /** - * choose - * - * @param userGroupId - * @return - */ - UserLikeChooseVO choose(Long userGroupId); - - ProjectChooseVO choose(ProjectDTO projectDTO); - - UserLikeGroup getByProjectId(Long projectId); - - void deleteTrialData(Long id); - - void updateDate(Long id, String timeZone); - - Long exportSave(MultipartFile file, Long projectId, String module, Long designItemDetailId); - - List toProduct(ToProductImageDTO toProductImageDTO); - - void toProduct(String taskId); - - ToProductElementVO toProductImageElementUpload(MultipartFile file, Long projectId, String type); - - CollectionSort productImageLike(ProductImageLikeDTO productImageLikeDTO); - - List getToProductImageResultList(List taskIdList); - - JSONObject exportSearch(ExportSearchDTO exportSearchDTO); - - CanvasElementUpload canvasElementUpload(MultipartFile file); - - List productImageLikeList(ToProductImageDTO toProductImageDTO); - - Boolean productImageUnLike(ProductImageLikeDTO productImageLikeDTO); - - void relight(String taskId); - - List relight(ToProductImageDTO toProductImageDTO); - - List getRelightResult(List taskIdList); - - void deleteToProductRelightResult(Long id, Long projectId, String type); - - String likeHistoryRelSketch(); - - String download(); - - Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO); - - InitializeProgressVO getInitializeProgress(ProductImageInitializeDTO productImageInitializeDTO); - - IPage getPage(ProjectQueryDTO projectQueryDTO); - - ModuleChooseVO getModuleContent(ProjectDTO projectDTO); - - ModuleChooseVO saveModuleContent(ModuleSaveDTO moduleSaveDTO); - - QueryLibraryPageVO getMannequinDetail(MannequinDTO mannequinDTO); - - BrandLogoUploadVO brandLogoUpload(MultipartFile file); - - Boolean brandDNASaveOrUpdate(BrandDNADTO brandDNADTO); - - LibraryUpdateVo brandDNAUpload(MultipartFile file, Long brandId) throws IOException; - - PageBaseResponse brandDNAPage(BrandDNAQueryDTO brandDNAQueryDTO); - - BrandDNAGenerateVO brandDNAGenerate(String prompt); - - IPage getThreeDLayoutPage(ThreeDLayoutQueryDTO threeDLayoutQueryDTO); - - ThreeDVO getLayoutDetail(Long threeDSimpleId); - - ThreeDSizeVO getThreeDSize(Long threeDSimpleId); - - void getThreeDGlb(Long threeDSimpleId, HttpServletResponse response) throws MinioException, IOException; - - String downloadZip(Long threeDSimpleId, String sizeType, String size, HttpServletResponse response) throws MinioException, IOException; - - Boolean delete(Long projectId); - - Boolean brandDNADelete(BrandDNADTO brandDNADTO); - - void toProductBatch(String taskId, String url, String progress) throws InterruptedException; - - void relightBatch(String taskId, String url, String progress); - - Boolean collectionLikeUpdate(CollectionLikeUpdateDTO collectionLikeUpdateDTO); - - Boolean toProductImageElementDelete(Long id); - - ToProductElementVO convertRelightElement(Long id); -} +package com.ai.da.service; + +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.mapper.primary.entity.*; +import com.ai.da.model.dto.*; +import com.ai.da.model.vo.*; +import com.ai.da.seller.DesignUrlsDTO; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import io.minio.errors.MinioException; +import org.springframework.web.multipart.MultipartFile; + +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * 服务类 + * + * @author yanglei + * @since 2022-09-11 + */ +public interface UserLikeGroupService extends IService { + + void deleteUserGroup(Long userGroupId); + + HistoryUpdateVO updateUserGroupName(Long userGroupId, String userGroupName, String timeZone); + + Long insertUserGroup(Long userId, Long collectionId, String timeZone, Long projectId); + + /** + * choose + * + * @param userGroupId + * @return + */ + UserLikeChooseVO choose(Long userGroupId); + + ProjectChooseVO choose(ProjectDTO projectDTO); + + UserLikeGroup getByProjectId(Long projectId); + + void deleteTrialData(Long id); + + void updateDate(Long id, String timeZone); + + Long exportSave(MultipartFile file, Long projectId, String module, Long designItemDetailId); + + List toProduct(ToProductImageDTO toProductImageDTO); + + void toProduct(String taskId); + + ToProductElementVO toProductImageElementUpload(MultipartFile file, Long projectId, String type); + + CollectionSort productImageLike(ProductImageLikeDTO productImageLikeDTO); + + List getToProductImageResultList(List taskIdList); + + JSONObject exportSearch(ExportSearchDTO exportSearchDTO); + + CanvasElementUpload canvasElementUpload(MultipartFile file); + + List productImageLikeList(ToProductImageDTO toProductImageDTO); + + Boolean productImageUnLike(ProductImageLikeDTO productImageLikeDTO); + + void relight(String taskId); + + List relight(ToProductImageDTO toProductImageDTO); + + List getRelightResult(List taskIdList); + + void deleteToProductRelightResult(Long id, Long projectId, String type); + + String likeHistoryRelSketch(); + + String download(); + + Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO); + + InitializeProgressVO getInitializeProgress(ProductImageInitializeDTO productImageInitializeDTO); + + IPage getPage(ProjectQueryDTO projectQueryDTO); + + ModuleChooseVO getModuleContent(ProjectDTO projectDTO); + + ModuleChooseVO saveModuleContent(ModuleSaveDTO moduleSaveDTO); + + QueryLibraryPageVO getMannequinDetail(MannequinDTO mannequinDTO); + + BrandLogoUploadVO brandLogoUpload(MultipartFile file); + + Boolean brandDNASaveOrUpdate(BrandDNADTO brandDNADTO); + + LibraryUpdateVo brandDNAUpload(MultipartFile file, Long brandId) throws IOException; + + PageBaseResponse brandDNAPage(BrandDNAQueryDTO brandDNAQueryDTO); + + BrandDNAGenerateVO brandDNAGenerate(String prompt); + + IPage getThreeDLayoutPage(ThreeDLayoutQueryDTO threeDLayoutQueryDTO); + + ThreeDVO getLayoutDetail(Long threeDSimpleId); + + ThreeDSizeVO getThreeDSize(Long threeDSimpleId); + + void getThreeDGlb(Long threeDSimpleId, HttpServletResponse response) throws MinioException, IOException; + + String downloadZip(Long threeDSimpleId, String sizeType, String size, HttpServletResponse response) throws MinioException, IOException; + + Boolean delete(Long projectId); + + Boolean brandDNADelete(BrandDNADTO brandDNADTO); + + void toProductBatch(String taskId, String url, String progress) throws InterruptedException; + + void relightBatch(String taskId, String url, String progress); + + Boolean collectionLikeUpdate(CollectionLikeUpdateDTO collectionLikeUpdateDTO); + + Boolean toProductImageElementDelete(Long id); + + ToProductElementVO convertRelightElement(Long id); + + /** + * 根据designItemId获取TO_PRODUCT_IMAGE类型的URL列表和DesignItemDetail的path列表 + * @param designItemId designItemId + * @return 包含TO_PRODUCT_IMAGE类型的URL列表和DesignItemDetail的path列表的对象 + */ + DesignUrlsDTO getToProductImageUrlsByDesignItemId(Long designItemId); +} diff --git a/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java b/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java index 7758064d..3b83ddf7 100644 --- a/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java @@ -1,3465 +1,3547 @@ -package com.ai.da.service.impl; - -import cn.hutool.core.collection.CollectionUtil; -import com.ai.da.common.config.exception.BusinessException; -import com.ai.da.common.constant.CommonConstant; -import com.ai.da.common.constant.ModelConstants; -import com.ai.da.common.context.UserContext; -import com.ai.da.common.enums.CollectionLevel1TypeEnum; -import com.ai.da.common.enums.CreditsEventsEnum; -import com.ai.da.common.enums.DesignTypeEnum; -import com.ai.da.common.enums.LibraryLevel1TypeEnum; -import com.ai.da.common.response.PageBaseResponse; -import com.ai.da.common.response.ResultEnum; -import com.ai.da.common.utils.*; -import com.ai.da.mapper.primary.*; -import com.ai.da.mapper.primary.entity.*; -import com.ai.da.mapper.primary.entity.Collection; -import com.ai.da.mapper.secondary.AttributeRetrievalMapper; -import com.ai.da.mapper.secondary.entity.AttributeRecognitionJSON; -import com.ai.da.model.dto.*; -import com.ai.da.model.enums.CollectionType; -import com.ai.da.model.enums.Module; -import com.ai.da.model.vo.*; -import com.ai.da.python.PythonService; -import com.ai.da.service.*; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; - -import java.util.Comparator; - -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.google.common.base.Function; -import com.google.gson.Gson; -import io.minio.errors.MinioException; -import io.netty.util.internal.StringUtil; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.multipart.MultipartFile; - -import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletResponse; -import java.io.*; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.*; -import java.util.stream.Collectors; - -/** - * 服务实现类 - * - * @author yanglei - * @since 2022-09-30 - */ -@Slf4j -@Service -@RequiredArgsConstructor -public class UserLikeGroupServiceImpl extends ServiceImpl implements UserLikeGroupService { - private final UserLikeGroupMapper userLikeGroupMapper; - private final AccountMapper accountMapper; - private final CollectionService collectionService; - private final UserLikeService userLikeService; - private final WorkspaceService workspaceService; - private final UserLikeMapper userLikeMapper; - private final MinioUtil minioUtil; - private final TDesignPythonOutfitMapper designPythonOutfitMapper; - private final DesignMapper designMapper; - private final MoodboardPositionService moodboardPositionService; - private final SysFileMapper sysFileMapper; - private final LibraryMapper libraryMapper; - private final GenerateDetailMapper generateDetailMapper; - private final PortfolioMapper portfolioMapper; - private final TagsMapper tagsMapper; - private final DesignItemDetailService designItemDetailService; - private final CollectionElementMapper collectionElementMapper; - private final AttributeRetrievalMapper attributeRetrievalMapper; - private final ProductImageAttributeMapper productImageAttributeMapper; - private final CollectionSortMapper collectionSortMapper; - private final ClassificationService classificationService; - // private ProjectMapper projectMapper; - private final ProjectService projectService; - private final LibraryModelPointMapper libraryModelPointMapper; - private final LibraryService libraryService; - private final BrandDNAMapper brandDNAMapper; - private final BrandRelLibraryMapper brandRelLibraryMapper; - private final ThreeDLayoutMapper threeDLayoutMapper; - private final ThreeDPatternLayoutMapper threeDPatternLayoutMapper; - private final ThreeDDetailMapper threeDDetailMapper; - private final ThreeDSimpleMapper threeDSimpleMapper; - private final ThreeDModuleMapper threeDModuleMapper; - private final ProductImageService productImageService; - private final CollectionElementRelModelMapper collectionElementRelModelMapper; - private final CollectionSortService collectionSortService; - private final GenerateService generateService; - private final ToProductElementMapper toProductElementMapper; - private final ToProductImageRecordMapper toProductImageRecordMapper; - private final ToProductImageResultMapper toProductImageResultMapper; - private final ToProductImageResultService toProductImageResultService; - private final CloudTaskMapper cloudTaskMapper; - private final PythonService pythonService; - private final CreditsService creditsService; - private final PoseTransformationMapper poseTransformationMapper; - private final ExportFileMapper exportFileMapper; - private final DesignItemDetailCanvasMapper designItemDetailCanvasMapper; - @Value("${redis.key.generateResult}") - private String generateResultKey; - - @Override - public void deleteUserGroup(Long userGroupId) { - UserLikeGroup group = getById(userGroupId); - if (Objects.isNull(group)) { - throw new BusinessException("history.not.found"); - } - userLikeGroupMapper.deleteById(userGroupId); - } - - @Override - public HistoryUpdateVO updateUserGroupName(Long userGroupId, String userGroupName, String timeZone) { - UserLikeGroup group = getById(userGroupId); - if (Objects.isNull(group)) { - throw new BusinessException("history.not.found"); - } - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("id", userGroupId); - UserLikeGroup userLikeGroup = new UserLikeGroup(); - userLikeGroup.setName(userGroupName); - userLikeGroup.setUpdateDate(DateUtil.getByTimeZone(timeZone)); - log.info("跟新group名字###{}###时间是###{}", userLikeGroup.getUpdateDate(), TimeZone.getDefault()); - userLikeGroupMapper.update(userLikeGroup, queryWrapper); - return new HistoryUpdateVO(userLikeGroup.getName(), userLikeGroup.getUpdateDate().getTime()); - } - -// public static void main(String[] args) { -// System.out.println(TimeZone.getDefault()); -// Date kolkata =DateUtil.getByTimeZone("Asia/Kolkata"); -// Date shanghai =DateUtil.getByTimeZone("Asia/Shanghai"); -// System.out.println(kolkata); -// System.out.println(shanghai); -// System.out.println(kolkata.getTime()); -// System.out.println(shanghai.getTime()); -// System.out.println(kolkata.getTime() == shanghai.getTime()); -// } - - private List selectByUserId(Long userId) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("accountId", userId); - return userLikeGroupMapper.selectList(queryWrapper); - } - - @Override - public Long insertUserGroup(Long userId, Long collectionId, String timeZone, Long projectId) { - UserLikeGroup userLikeGroup = new UserLikeGroup(); - //默认当前时间 - userLikeGroup.setName(DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS)); - userLikeGroup.setCreateDate(DateUtil.getByTimeZone(timeZone)); - userLikeGroup.setUpdateDate(DateUtil.getByTimeZone(timeZone)); - userLikeGroup.setAccountId(userId); - userLikeGroup.setCollectionId(collectionId); - userLikeGroup.setOriginal(1); - userLikeGroup.setProjectId(projectId); - userLikeGroupMapper.insertUserLikeGroup(userLikeGroup); - return userLikeGroup.getId(); - } - - @Override - public UserLikeChooseVO choose(Long userGroupId) { - UserLikeGroup group = getById(userGroupId); - if (Objects.isNull(group)) { - throw new BusinessException("history.not.found"); - } - List userLikeVOS = userLikeService.getGroupDetail(userGroupId); - String sex = null; - - QueryWrapper userLikeSortQw = new QueryWrapper<>(); - userLikeSortQw.lambda().eq(CollectionSort::getUserLikeGroupId, userGroupId); - List userLikeSortList = collectionSortMapper.selectList(userLikeSortQw); - if (CollectionUtil.isEmpty(userLikeSortList)) { - Integer sort = 1; - for (UserLikeVO userLikeVO : userLikeVOS) { - CollectionSort userLikeSort = new CollectionSort(); - userLikeSort.setUserLikeId(userLikeVO.getId()); - userLikeSort.setUserLikeGroupId(userGroupId); - userLikeSort.setSort(sort); - collectionSortMapper.insert(userLikeSort); - sort++; - } - } - - userLikeVOS.forEach(o -> { - TDesignPythonOutfit tDesignPythonOutfit1 = designPythonOutfitMapper.selectById(o.getDesignOutfitId()); - o.setUrl(tDesignPythonOutfit1.getDesignUrl()); - if (o.getUrl().contains("/")) { - int index = o.getUrl().lastIndexOf("/"); - o.setPictureName(o.getUrl().substring(index + 1)); - } - o.setDesignOutfitUrl(minioUtil.getPreSignedUrl(o.getUrl(), 24 * 60)); - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(TDesignPythonOutfit::getDesignItemId, o.getDesignItemId()); - List tDesignPythonOutfits = designPythonOutfitMapper.selectList(qw); - if (CollectionUtil.isNotEmpty(tDesignPythonOutfits)) { - TDesignPythonOutfit tDesignPythonOutfit = tDesignPythonOutfits.get(0); - o.setDesignOutfitId(tDesignPythonOutfit.getId()); - } - - QueryWrapper userLikeSortQueryWrapper = new QueryWrapper<>(); - userLikeSortQueryWrapper.lambda().eq(CollectionSort::getUserLikeId, o.getId()); - List userLikeSorts = collectionSortMapper.selectList(userLikeSortQueryWrapper); - if (CollectionUtil.isNotEmpty(userLikeSorts)) { - CollectionSort userLikeSort = userLikeSorts.get(0); - o.setSort(userLikeSort.getSort()); - o.setUserLikeSortId(userLikeSort.getId()); - } - }); - UserLikeCollectionVO userLikeCollection = collectionService.chooseCollection(group.getCollectionId()); - Integer beenPublished = 0; - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(Portfolio::getUserLikeGroupSourceId, userGroupId); - List portfolios = portfolioMapper.selectList(qw); -// Portfolio portfolio = new Portfolio(); - PortfolioDTO portfolioDTO = new PortfolioDTO(); - if (CollectionUtil.isNotEmpty(portfolios)) { -// portfolio = portfolios.get(0); - portfolioDTO = CopyUtil.copyObject(portfolios.get(0), PortfolioDTO.class); - beenPublished = 1; - portfolioDTO.setTagsDTO(tagsMapper.getTagByPortfolioId(portfolioDTO.getId())); - } - return new UserLikeChooseVO(userGroupId, userLikeVOS, userLikeCollection, sex, beenPublished, portfolioDTO); - } - - @Override - public ProjectChooseVO choose(ProjectDTO projectDTO) { - - Project project = projectService.getById(projectDTO.getId()); - - Long workspaceId = workspaceService.getByProjectId(project.getId()); - WorkspaceVO workspaceVO = new WorkspaceVO(); - if (null != workspaceId) { - workspaceVO = workspaceService.getByIdForProject(workspaceId); - } - - String process = project.getProcess(); - String name = project.getName(); - - UserLikeGroup userLikeGroup = userLikeService.getUserLikeGroupByProjectId(project.getId()); - Long collectionId = null; - if (Objects.nonNull(userLikeGroup)) { - Collection collection = collectionService.getById(userLikeGroup.getCollectionId()); - if (Objects.nonNull(collection)) { - collectionId = collection.getId(); - } - } - - Integer beenPublished = 0; - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(Portfolio::getProjectId, projectDTO.getId()); - List portfolios = portfolioMapper.selectList(qw); -// Portfolio portfolio = new Portfolio(); - PortfolioDTO portfolioDTO = new PortfolioDTO(); - if (CollectionUtil.isNotEmpty(portfolios)) { -// portfolio = portfolios.get(0); - portfolioDTO = CopyUtil.copyObject(portfolios.get(0), PortfolioDTO.class); - beenPublished = 1; - portfolioDTO.setTagsDTO(tagsMapper.getTagByPortfolioId(portfolioDTO.getId())); - } - - return new ProjectChooseVO(projectDTO.getId(), name, workspaceVO, process, collectionId, beenPublished, portfolioDTO); - } - - @Override - public UserLikeGroup getByProjectId(Long projectId) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(UserLikeGroup::getProjectId, projectId); - List userLikeGroupList = userLikeGroupMapper.selectList(qw); - if (CollectionUtil.isEmpty(userLikeGroupList)) { - return null; - } - return userLikeGroupList.get(0); - } - - @Override - public void deleteTrialData(Long userId) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(UserLikeGroup::getAccountId, userId); - List userLikeGroupIdList = userLikeGroupMapper.selectList(qw).stream() - .map(UserLikeGroup::getId) - .collect(Collectors.toList()); - userLikeGroupMapper.delete(qw); - if (CollectionUtil.isNotEmpty(userLikeGroupIdList)) { - QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); - userLikeQueryWrapper.lambda().in(UserLike::getUserLikeGroupId, userLikeGroupIdList); - userLikeMapper.delete(userLikeQueryWrapper); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateDate(Long id, String timeZone) { - UpdateWrapper uw = new UpdateWrapper<>(); - uw.eq("id", id); - uw.set("update_date", DateUtil.getByTimeZone(timeZone)); - - baseMapper.update(null, uw); - } - - @Override - public Long exportSave(MultipartFile file, Long projectId, String module, Long designItemDetailId) { - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - if (Objects.isNull(projectId) && !module.equals("designItemDetail")) { - log.warn("用户 {} 保存 {} 模块的画布时, projectId为空", userHolder.getId(), module); - throw new BusinessException("project.id.cannot.be.empty", ResultEnum.PROMPT.getCode()); - } - - QueryWrapper qw = new QueryWrapper<>(); - List exportFiles = null; - if (Objects.nonNull(projectId)) { - qw.lambda().eq(ExportFile::getProjectId, projectId); - qw.lambda().eq(ExportFile::getModule, module); - exportFiles = exportFileMapper.selectList(qw); - } else if (Objects.nonNull(designItemDetailId)) { - DesignItemDetailCanvas designItemDetailCanvas = designItemDetailService.getDIDCByDesignItemDetailId(designItemDetailId); - if (Objects.nonNull(designItemDetailCanvas) && Objects.nonNull(designItemDetailCanvas.getExportFileId())) { - qw.lambda().eq(ExportFile::getId, designItemDetailCanvas.getExportFileId()); - qw.lambda().eq(ExportFile::getModule, module); - exportFiles = exportFileMapper.selectList(qw); - } - } -// String upload = minioUtil.upload("aida-users", userHolder.getId() + "/exportFile", file); - - ExportFile exportFile = null; - if (CollectionUtil.isNotEmpty(exportFiles)) { - exportFile = exportFiles.get(0); - // 更新画布信息时,只重新上传图片,不用修改数据库url - String url = exportFile.getUrl(); - String path = url.substring(url.indexOf("/") + 1); - minioUtil.upload("aida-users", path, file, null); -// exportFile.setUrl(upload); -// exportFileMapper.updateById(exportFile); - } else { - String upload = minioUtil.upload("aida-users", userHolder.getId() + "/exportFile", file); - exportFile = new ExportFile(); - exportFile.setProjectId(projectId); - exportFile.setModule(module); - exportFile.setUrl(upload); - exportFileMapper.insert(exportFile); - if (Objects.nonNull(designItemDetailId)) { - designItemDetailService.saveDesignItemDetailCanvas(designItemDetailId, exportFile.getId()); - } - } - return exportFile.getId(); - } - - /** - * 产品图像生成方法 - * 根据输入的设计元素和参数,生成对应的产品图像 - * - * @param toProductImageDTO 产品图像生成请求参数 - * @return 生成的产品图像结果列表 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public List toProduct(ToProductImageDTO toProductImageDTO) { - // 判断是否使用(高级模型) - boolean advanced = !StringUtil.isNullOrEmpty(toProductImageDTO.getModelName()) - && toProductImageDTO.getModelName().equals(ModelConstants.ADVANCED); - - // 根据模型类型选择对应的积分消耗事件 - CreditsEventsEnum creditsEventsEnum = advanced ? CreditsEventsEnum.TO_PRODUCT_IMAGE_ADVANCED : CreditsEventsEnum.TO_PRODUCT_IMAGE; - - // 预扣除积分,检查用户积分是否足够本次生成消耗 - Boolean preDeduction = creditsService.creditsPreDeduction(creditsEventsEnum, toProductImageDTO.getToProductImageVOList().size()); - if (!preDeduction) { - throw new BusinessException("remaining.credits.insufficient", ResultEnum.WARNING.getCode()); - } - - // 获取当前登录用户信息 - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - - // 获取项目ID并查找对应的用户喜欢组 - Long projectId = toProductImageDTO.getProjectId(); - UserLikeGroup userLikeGroup = getByProjectId(projectId); - Long userLikeGroupId = null; - - // 创建产品图像记录对象,用于记录本次生成任务的基本信息 - ToProductImageRecord toProductImageRecord = new ToProductImageRecord(); - toProductImageRecord.setProjectId(projectId); - if (Objects.nonNull(userLikeGroup)) { - userLikeGroupId = userLikeGroup.getId(); - toProductImageRecord.setUserLikeGroupId(userLikeGroupId); - } - - String prompt = toProductImageDTO.getPrompt(); - String advancedPrompt = buildAdvancedPrompt(projectId, prompt); - // 初始化基础提示词,确保生成高质量的真实图像 - StringBuilder sb = new StringBuilder("The best quality, masterpiece, real image."); - if (!StringUtil.isNullOrEmpty(prompt) && !advanced) { - // 调用Python服务进行提示词翻译(中文转英文等) - prompt = pythonService.promptTranslate(prompt); - - // 检查翻译后的提示词长度,限制在180个单词以内 - String[] words = prompt.split("\\s+"); - if (words.length > 180) { - throw new BusinessException("Please keep your input text under 200 words. Thanks!"); - } - } - - // 设置记录创建时间并保存原始提示词 - toProductImageRecord.setCreateTime(LocalDateTime.now()); - if (!StringUtils.isEmpty(toProductImageDTO.getPrompt())) { - toProductImageRecord.setPrompt(toProductImageDTO.getPrompt()); - } - // 将产品图像记录插入数据库 - toProductImageRecordMapper.insert(toProductImageRecord); - - // 初始化结果列表 - List result = new ArrayList<>(); - // 判断是否为儿童年龄组,用于后续生成不同的提示词 - boolean childFlag = !StringUtil.isNullOrEmpty(toProductImageDTO.getAgeGroup()) - && toProductImageDTO.getAgeGroup().equals("Child"); - // 循环计数器,用于生成唯一的任务ID - int i = 0; - -// else { -// s = "best quality, masterpiece. detailed, high-res, simple background, studio photography, extremely detailed, updo, detailed face, face, close-up, HDR, UHD, 8K realistic, Highly detailed, simple background, Studio lighting"; -// } - // 遍历所有需要生成的产品图像元素 - for (ToProductImageVO toProductImageVO : toProductImageDTO.getToProductImageVOList()) { - String taskId; - // 处理设计服装类型的元素 - if (toProductImageVO.getElementType().equals("DesignOutfit")) { - // 生成唯一的任务ID,包含UUID、序号和用户ID - taskId = UUID.randomUUID() + "-" + i + "-" + userHolder.getId(); - // 根据元素ID查询设计Python服装信息 - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageVO.getElementId()); - - // 获取设计项目ID并查询相关的设计项目详情 - Long designItemId = tDesignPythonOutfit.getDesignItemId(); - QueryWrapper designItemDetailQueryWrapper = new QueryWrapper<>(); - designItemDetailQueryWrapper.lambda().eq(DesignItemDetail::getDesignItemId, designItemId); - designItemDetailQueryWrapper.lambda().ne(DesignItemDetail::getType, "Body"); // 排除身体部分 - List designItemDetails = designItemDetailService.list(designItemDetailQueryWrapper); - // 将设计项目的类型拼接成字符串(如:Tops,Bottoms) - String collect = designItemDetails.stream().map(DesignItemDetail::getType).collect(Collectors.joining(",")); - - // 获取设计ID并查询设计信息 - Long designId = tDesignPythonOutfit.getDesignId(); - Design design = designMapper.selectById(designId); - // 默认产品类型为整体 - String productType = "overall"; - // 根据设计的单品/整体属性决定产品类型和提示词构建方式 - if (design.getSingleOverall().equals("single")) { - // 单品设计:直接使用服装类型 - productType = "single"; - sb.append(collect); - } else { - // 整体设计:根据服装类型和年龄组添加人物描述 - if (collect.contains("Tops") && childFlag) { - sb.append("a handsome boy,"); // 儿童上装 - 男孩 - } else if (collect.contains("Tops") && !childFlag) { - sb.append("a handsome man,"); // 成人上装 - 男性 - } else if (childFlag) { - sb.append("a beautiful girl,"); // 儿童其他 - 女孩 - } else { - sb.append("a beautiful woman,"); // 成人其他 - 女性 - } -// sb.append("wearing ").append(collect); - } - // 根据是否有自定义提示词来完善最终的提示词 - if (StringUtils.isEmpty(prompt)) { - // 无自定义提示词:使用默认的高质量服装细节描述 - sb.append(",high quality clothing details,8K realistic,HDR"); - } else { - // 有自定义提示词:结合用户提示词和高质量描述 - sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR"); - } - // 创建产品图像结果对象 - ToProductImageResultVO toProductImageResult = new ToProductImageResultVO(); - // 根据是否使用flux模型选择不同的生成方式 - if (advanced) { - // 使用flux高级模型 - if (childFlag) { - sb.append(", Children's face"); // 儿童面部特征 - } - taskId = generateService.toProductAsyncTask(tDesignPythonOutfit.getDesignUrl(), ModelConstants.NANO_BANANA, advancedPrompt); - toProductImageResult.setModelName(toProductImageDTO.getModelName()); - toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue()); - } else { - // 使用本地Python模型 - if (childFlag) { - sb.append(", (Children's face:1.3)"); // 儿童面部特征(权重1.3) - } - // 调用Python服务生成产品图像 - pythonService.toProductImage(tDesignPythonOutfit.getDesignUrl(), taskId, sb.toString(), toProductImageDTO.getImageStrength(), productType); -// toProductImageResult.setModelName("local"); // 注释掉的本地模型标记 - } - - // 设置产品图像结果的基本信息 - toProductImageResult.setElementId(tDesignPythonOutfit.getId()); // 关联的设计服装ID - toProductImageResult.setElementType("DesignOutfit"); // 元素类型:设计服装 - toProductImageResult.setCreateTime(LocalDateTime.now()); // 创建时间 - toProductImageResult.setToProductImageRecordId(toProductImageRecord.getId()); // 关联的记录ID -// toProductImageResult.setUrl(productImageUrl); // 生成的图像URL(暂时注释) - toProductImageResult.setIsLike(0); // 默认未点赞 - toProductImageResult.setTaskId(taskId); // 任务ID - toProductImageResult.setProjectId(projectId); // 项目ID - if (userLikeGroupId != null) { - toProductImageResult.setUserLikeGroupId(userLikeGroupId); // 用户喜欢组ID - } - toProductImageResult.setImageStrength(toProductImageDTO.getImageStrength()); // 图像强度 - toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue()); // 结果类型 - toProductImageResult.setStatus("Pending"); // 状态:待处理 - // 将结果插入数据库 - toProductImageResultMapper.insert(toProductImageResult); -// toProductImageResult.setUrl(minioUtil.getPresignedUrl(toProductImageResult.getUrl(), 24 * 60)); - // 处理默认点赞逻辑 - if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && toProductImageDTO.getIsDefaultLike()) { - // 如果设置了默认点赞,则自动添加到用户喜欢列表 - CollectionSort collectionSort = addToProductLike(toProductImageVO.getParentId(), toProductImageResult.getId(), toProductImageDTO.getProjectId()); - // 重新排序:根据用户指定的排序位置调整 - Integer reSort = collectionSortService.rearrangeChildSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), - toProductImageVO.getParentId(), toProductImageVO.getUserLikeSortId()); - // 设置排序信息到结果对象中 - toProductImageResult.setSort(Objects.isNull(reSort) ? Objects.isNull(collectionSort) ? null : collectionSort.getSort() : reSort); - toProductImageResult.setParentId(toProductImageVO.getParentId()); // 父级ID - toProductImageResult.setUserLikeSortId(Objects.isNull(collectionSort) ? null : collectionSort.getId()); // 排序记录ID - } else if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && Objects.nonNull(toProductImageVO.getParentId())) { - // 不默认点赞但有父级ID的情况 - toProductImageResult.setParentId(toProductImageVO.getParentId()); - // 注释:原本计划添加到collectionSort表中,但当前未实现 -// designService.addCollectionSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), toProductImageDTO.getProjectId(), toProductImageVO.getParentId()); - } - // 将处理完的结果添加到返回列表中 - result.add(toProductImageResult); - } else { - // 处理ProductElement类型的元素 - // 根据是否有自定义提示词来构建最终提示词 - if (StringUtils.isEmpty(prompt)) { - sb.append(",high quality clothing details,8K realistic,HDR"); - } else { - sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR"); - } - - // 生成唯一的任务ID - taskId = UUID.randomUUID() + "-" + i + "-" + userHolder.getId(); - // 查询产品元素信息 - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageVO.getElementId()); - // 创建产品图像结果对象 - ToProductImageResultVO toProductImageResult = new ToProductImageResultVO(); - - // 根据是否使用高级模型选择不同的图像生成方式 - if (advanced) { - // 使用模型生成图像 - taskId = generateService.toProductAsyncTask(toProductElement.getUrl(), ModelConstants.NANO_BANANA, advancedPrompt); - toProductImageResult.setModelName(toProductImageDTO.getModelName()); // 设置模型名称 - toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue()); // 设置结果类型 - } else { - // 使用本地Python模型生成图像 - if (childFlag) { - // 如果是儿童年龄组,添加儿童面部特征提示 - sb.append(", (Children's face:1.3)"); - } - // 调用Python服务生成产品图像 - pythonService.toProductImage(toProductElement.getUrl(), taskId, sb.toString(), toProductImageDTO.getImageStrength(), "overall"); -// toProductImageResult.setModelName("local"); // 本地模型名称(已注释) - } - // 设置产品图像结果的基本信息 - toProductImageResult.setElementId(toProductElement.getId()); // 关联的产品元素ID - toProductImageResult.setElementType("ProductElement"); // 元素类型:产品元素 - toProductImageResult.setCreateTime(LocalDateTime.now()); // 创建时间 - toProductImageResult.setToProductImageRecordId(toProductImageRecord.getId()); // 关联的记录ID -// toProductImageResult.setUrl(productImageUrl); // 生成的图像URL(暂时注释) - toProductImageResult.setIsLike(0); // 默认未点赞 - toProductImageResult.setTaskId(taskId); // 任务ID - toProductImageResult.setProjectId(projectId); // 项目ID - if (userLikeGroupId != null) { - toProductImageResult.setUserLikeGroupId(userLikeGroupId); // 用户喜欢组ID - } - toProductImageResult.setImageStrength(toProductImageDTO.getImageStrength()); // 图像强度 - toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue()); // 结果类型 - toProductImageResult.setStatus("Pending"); // 状态:待处理 - // 将结果插入数据库 - toProductImageResultMapper.insert(toProductImageResult); -// toProductImageResult.setUrl(minioUtil.getPresignedUrl(toProductImageResult.getUrl(), 24 * 60)); - // 处理默认点赞逻辑 - if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && toProductImageDTO.getIsDefaultLike()) { - // 如果设置了默认点赞,则自动添加到用户喜欢列表 - CollectionSort collectionSort = addToProductLike(toProductImageVO.getParentId(), toProductImageResult.getId(), toProductImageDTO.getProjectId()); - // 重新排序:根据用户指定的排序位置调整 - Integer reSort = collectionSortService.rearrangeChildSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), - toProductImageVO.getParentId(), toProductImageVO.getUserLikeSortId()); - // 设置排序信息到结果对象中 - toProductImageResult.setSort(Objects.isNull(reSort) ? Objects.isNull(collectionSort) ? null : collectionSort.getSort() : reSort); - toProductImageResult.setParentId(toProductImageVO.getParentId()); // 父级ID - toProductImageResult.setUserLikeSortId(Objects.isNull(collectionSort) ? null : collectionSort.getId()); // 排序记录ID - } else if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && Objects.nonNull(toProductImageVO.getParentId())) { - // 不默认点赞但有父级ID的情况 - toProductImageResult.setParentId(toProductImageVO.getParentId()); - // 注释:原本计划添加到collectionSort表中,但当前未实现 -// designService.addCollectionSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), toProductImageDTO.getProjectId(), toProductImageVO.getParentId()); - } - // 将处理完的结果添加到返回列表中 - result.add(toProductImageResult); - } - i++; // 循环计数器递增 - sb = new StringBuilder("The best quality, masterpiece, real image."); // 重置提示词构建器 - // 添加需要扣除的积分到预扣除区 - creditsService.addRecordToCreditsDeduction(userHolder.getId(), taskId, creditsEventsEnum); - // 添加积分扣除记录到数据库 - creditsService.preInsert(userHolder.getId(), creditsEventsEnum.getName(), taskId, Boolean.TRUE, null); - } - // 更新项目更新时间,记录最后一次操作时间 - projectService.modifyProjectUpdateTime(toProductImageDTO.getProjectId()); - // 返回生成的产品图像结果列表 - return result; - } - - private CollectionSort addToProductLike(Long parentId, Long toProductImageResultId, Long projectId) { - if (Objects.nonNull(parentId) && !parentId.equals(0L)) { - return productImageLike(new ProductImageLikeDTO(Collections.singletonList(toProductImageResultId), - projectId, parentId)); - } - return null; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void toProduct(String taskId) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ToProductImageResult::getTaskId, taskId); - List toProductImageResults = toProductImageResultMapper.selectList(qw); - if (CollectionUtil.isNotEmpty(toProductImageResults)) { - ToProductImageResult toProductImageResultOne = toProductImageResults.get(0); - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResultOne.getToProductImageRecordId()); - String prompt = toProductImageRecord.getPrompt(); - StringBuilder sb = new StringBuilder("The best quality, masterpiece, real image."); - if (!StringUtil.isNullOrEmpty(prompt)) { - prompt = pythonService.promptTranslate(prompt); - } - String elementType = toProductImageResultOne.getElementType(); - if (elementType.equals("DesignOutfit")) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultOne.getElementId()); - Long designItemId = tDesignPythonOutfit.getDesignItemId(); - QueryWrapper designItemDetailQueryWrapper = new QueryWrapper<>(); - designItemDetailQueryWrapper.lambda().eq(DesignItemDetail::getDesignItemId, designItemId); - designItemDetailQueryWrapper.lambda().ne(DesignItemDetail::getType, "Body"); - List designItemDetails = designItemDetailService.list(designItemDetailQueryWrapper); - String collect = designItemDetails.stream().map(DesignItemDetail::getType).collect(Collectors.joining(",")); - - Long designId = tDesignPythonOutfit.getDesignId(); - Design design = designMapper.selectById(designId); - String productType = "overall"; - if (design.getSingleOverall().equals("single")) { - productType = "single"; - sb.append(collect); - } else { - if (collect.contains("Tops")) { - sb.append("a handsome man,"); - } else { - sb.append("a beautiful women,"); - } - sb.append("wearing ").append(collect); - } - if (StringUtils.isEmpty(prompt)) { - sb.append(",high quality clothing details,8K realistic,HDR"); - } else { - sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR"); - } - // 走模型 - pythonService.toProductImage(tDesignPythonOutfit.getDesignUrl(), taskId, sb.toString(), toProductImageResultOne.getImageStrength(), "single"); - } else { - if (StringUtils.isEmpty(prompt)) { - sb.append(",high quality clothing details,8K realistic,HDR"); - } else { - sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR"); - } - - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultOne.getElementId()); - // 走模型 - pythonService.toProductImage(toProductElement.getUrl(), taskId, sb.toString(), toProductImageResultOne.getImageStrength(), "single"); - } - - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public ToProductElementVO toProductImageElementUpload(MultipartFile file, Long projectId, String type) { - if (null == file || StringUtils.isEmpty(file.getOriginalFilename())) { - throw new BusinessException("file.cannot.be.empty"); - } -// if (projectId == null) { -// throw new BusinessException("projectId.cannot.be.empty"); -// } - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - String bucketName = "aida-users"; - String minioUrl = minioUtil.upload(bucketName, userHolder.getId() + "/toProductImageElement", file); - ToProductElement toProductElement = new ToProductElement(); - toProductElement.setUrl(minioUrl); -// toProductElement.setUserLikeGroupId(userLikeGroupId); - toProductElement.setProjectId(projectId); - toProductElement.setCreateTime(LocalDateTime.now()); - toProductElement.setFrameType(type); - toProductElementMapper.insert(toProductElement); - ToProductElementVO toProductElementVO = CopyUtil.copyObject(toProductElement, ToProductElementVO.class); - toProductElementVO.setMinioUrl(toProductElementVO.getUrl()); - toProductElementVO.setUrl(minioUtil.getPreSignedUrl(toProductElementVO.getUrl(), 24 * 60)); - return toProductElementVO; - } - - @Override - public CollectionSort productImageLike(ProductImageLikeDTO dto) { - List resultIds = dto.getToProductImageResultId(); - ToProductImageResult result = toProductImageResultMapper.selectById(resultIds.get(0)); - CollectionSort collectionSort = null; - boolean updatedFlag = false; - - Long parentId = dto.getCollectionSortParentId(); - if (parentId == null) { - return null; - } - - // 统一处理两种类型 - CollectionType collectionType = "Relight".equals(result.getResultType()) - ? CollectionType.RELIGHT - : CollectionType.TO_PRODUCT_IMAGE; - - collectionSort = collectionSortService.getUserLikeSortByUserLikeId( - result.getId(), collectionType.getValue(), dto.getProjectId(), parentId); - - if (Objects.isNull(collectionSort)) { - collectionSort = collectionSortService.addCollectionSort( - result.getId(), collectionType.getValue(), dto.getProjectId(), parentId); - updatedFlag = true; - } - - if (updatedFlag) { - updateLikeStatus(resultIds); - projectService.modifyProjectUpdateTime(dto.getProjectId()); - } - - return collectionSort; - } - - private void updateLikeStatus(List resultIds) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().in(ToProductImageResult::getId, resultIds); - - ToProductImageResult updateEntity = new ToProductImageResult(); - updateEntity.setIsLike(1); - toProductImageResultMapper.update(updateEntity, qw); - } - - @Resource - private RedisUtil redisUtil; - @Value("${redis.key.toProductImageResultKey}") - private String toProductImageResultKey; - @Value("${redis.key.relightResultKey}") - private String relightResultKey; - - /** - * 获取产品图像生成结果列表 - * 根据任务ID列表查询对应的产品图像生成结果,支持flux模型和传统Python模型两种处理方式 - * - * @param taskIdList 任务ID列表,用于查询对应的产品图像生成结果 - * @return 返回MagicToolResultVO列表,包含图像生成结果的详细信息(URL、状态、元素信息等) - * @throws BusinessException 当源图像不存在或任务不存在时抛出业务异常 - */ - @Override - public List getToProductImageResultList(List taskIdList) { - // 初始化结果列表和状态收集集合 - List results = new ArrayList<>(); - Set collect = new HashSet<>(); - - // 遍历每个任务ID,处理对应的产品图像生成结果 - taskIdList.forEach(taskId -> { - // 根据任务ID查询产品图像生成结果记录 - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ToProductImageResult::getTaskId, taskId); - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(qw); - if (Objects.isNull(toProductImageResult)) { - throw new BusinessException("source.image.does.not.exist"); - } - - // 查询产品图像记录,获取提示词等信息 - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); - if (Objects.isNull(toProductImageRecord)) { - throw new BusinessException("This task does not exist."); - } - - if (!StringUtil.isNullOrEmpty(toProductImageResult.getModelName()) && toProductImageResult.getModelName().equals(ModelConstants.ADVANCED)) { - // 获取项目信息,用于构建文件路径和积分扣除 - Project project = projectService.getById(toProductImageResult.getProjectId()); - if (Objects.isNull(project)) { - throw new BusinessException("unknown project"); - } - - // 获取flux模型生成结果 - String redisResult; - if (toProductImageResult.getStatus().equals("Success") && !StringUtil.isNullOrEmpty(toProductImageResult.getUrl())) { - // 如果已经有成功的结果URL,直接使用 - redisResult = toProductImageResult.getUrl(); - } else { - String key = generateResultKey + ":" + taskId; - redisResult = redisUtil.getFromString(key); - } - - GenerateResultVO cachedResult = new Gson().fromJson(redisResult, GenerateResultVO.class); - - - // 根据flux结果状态进行不同处理 - if (StringUtil.isNullOrEmpty(redisResult)) { - // 如果结果为空,标记为失败状态 - toProductImageResult.setStatus("Fail"); - toProductImageResultMapper.updateById(toProductImageResult); - collectionSortMapper.delete(new QueryWrapper().lambda().eq(CollectionSort::getRelationId, toProductImageResult.getId())); - results.add(new MagicToolResultVO(taskId, "Fail")); - } else if ("Pending".equals(cachedResult.getStatus()) || "Fail".equals(cachedResult.getStatus())) { - // 如果结果为失败或待处理状态,更新状态并返回对应结果 - toProductImageResult.setStatus(cachedResult.getStatus()); - toProductImageResultMapper.updateById(toProductImageResult); - if (cachedResult.getStatus().equals("Fail")) { - collectionSortMapper.delete(new QueryWrapper().lambda().eq(CollectionSort::getRelationId, toProductImageResult.getId())); - } - String errorMessage = cachedResult.getUrl(); - if (errorMessage != null) { - results.add(new MagicToolResultVO(taskId, cachedResult.getStatus(), errorMessage)); - } else { - results.add(new MagicToolResultVO(taskId, cachedResult.getStatus())); - } - } else { - // 如果结果成功,处理flux结果并构建返回对象 - results.add(processNanoBananaResult(cachedResult.getUrl(), toProductImageResult, taskId, toProductImageRecord.getPrompt())); - // 执行积分扣除操作 - Boolean flag = creditsService.taskCreditsDeduction(project.getAccountId(), taskId); - if (flag) creditsService.updateChangedCredits(String.valueOf(project.getAccountId()), taskId); - } - - // 如果任务失败,将积分预扣除记录移除 - if (toProductImageResult.getStatus().equals("Fail")) { - creditsService.deleteCreditsDeduction(project.getAccountId(), taskId); - } - - // flux模型处理完成,跳过后续的Redis缓存处理逻辑 - return; - } - - // 非flux模型的处理逻辑:从Redis缓存获取结果 - String key = toProductImageResultKey + ":" + taskId; - MagicToolResultVO magicToolResultVO = new Gson().fromJson(redisUtil.getFromString(key), MagicToolResultVO.class); - - // 如果从Redis获取到结果且URL不为空,则构建返回对象 - if (!Objects.isNull(magicToolResultVO) && !StringUtil.isNullOrEmpty(magicToolResultVO.getUrl())) { - String url = magicToolResultVO.getUrl(); - // 检查是否为无效图片(白色图片表示生成失败) - if (url.substring(url.lastIndexOf("/") + 1).equals("white_image.jpg")) { - magicToolResultVO.setStatus("Invalid"); - } else { - // 设置预签名URL和相关属性 - magicToolResultVO.setUrl(minioUtil.getPreSignedUrl(url, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - magicToolResultVO.setResultType(toProductImageResult.getResultType()); - magicToolResultVO.setElementId(toProductImageResult.getElementId()); - magicToolResultVO.setElementType(toProductImageResult.getElementType()); - magicToolResultVO.setDirection(toProductImageResult.getDirection()); - magicToolResultVO.setBrightenValue(toProductImageResult.getBrightenValue()); - magicToolResultVO.setImageStrength(toProductImageResult.getImageStrength()); - magicToolResultVO.setPrompt(toProductImageRecord.getPrompt()); - - // 根据元素类型设置源图片URL和父ID - if (toProductImageResult.getElementType().equals("ProductElement")) { - // 处理ProductElement类型:获取产品元素信息 - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); - - // 获取ProductElement的父ID - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } else { - // 处理DesignOutfit类型:获取设计服装信息 - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); - - // 通过DesignOutfit查找对应的UserLike记录,获取父ID - QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); - userLikeQueryWrapper.lambda().eq(UserLike::getDesignOutfitId, tDesignPythonOutfit.getId()); - List userLikeList = userLikeMapper.selectList(userLikeQueryWrapper); - if (!CollectionUtils.isEmpty(userLikeList)) { - UserLike userLike = userLikeList.get(0); - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(userLike.getId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } - } - } - // 将构建好的结果对象添加到返回列表 -// results.add(magicToolResultVO); - } else if (Objects.isNull(magicToolResultVO)) { - // 如果Redis中没有结果对象,创建执行中状态的结果对象 - magicToolResultVO = new MagicToolResultVO(taskId, "Executing"); -// results.add(magicToolResultVO); - }/* else { - // 如果Redis中有结果对象但URL为空,直接添加到返回列表 - results.add(magicToolResultVO); - }*/ - - // 收集任务状态用于统计 - if (!StringUtil.isNullOrEmpty(magicToolResultVO.getStatus())) collect.add(magicToolResultVO.getStatus()); - results.add(magicToolResultVO); - }); - - // 返回所有任务的处理结果列表 - return results; - } - - private MagicToolResultVO processNanoBananaResult(String resultImgMinioPath, ToProductImageResult toProductImageResult, String taskId, String prompt) { - // 如果任务状态不是成功且URL为空,则更新任务状态和URL - if (!toProductImageResult.getStatus().equals("Success") - && StringUtil.isNullOrEmpty(toProductImageResult.getUrl())) { - toProductImageResult.setStatus("Success"); - toProductImageResult.setUrl(resultImgMinioPath); - toProductImageResultMapper.updateById(toProductImageResult); - } - - // 创建返回结果对象并设置基本信息 - MagicToolResultVO magicToolResultVO = CopyUtil.copyObject(toProductImageResult, MagicToolResultVO.class); - magicToolResultVO.setTaskId(taskId); - magicToolResultVO.setId(toProductImageResult.getId()); - // 设置Flux生成图片的预签名URL(使用系统配置的过期时间) - magicToolResultVO.setUrl(minioUtil.getPreSignedUrl(resultImgMinioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - magicToolResultVO.setStatus("Success"); - magicToolResultVO.setResultType(toProductImageResult.getResultType()); - magicToolResultVO.setElementId(toProductImageResult.getElementId()); - magicToolResultVO.setElementType(toProductImageResult.getElementType()); - magicToolResultVO.setPrompt(prompt); - - // 根据元素类型设置源图片URL和父ID - if (toProductImageResult.getElementType().equals("ProductElement")) { - // 处理产品元素类型:获取产品元素信息并设置源图片URL - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); - - // 通过CollectionSort服务获取父ID - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } else if (toProductImageResult.getElementType().equals("DesignOutfit")) { - // 处理设计服装类型:获取设计服装信息并设置源图片URL - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); - - // 通过设计服装ID查找对应的用户喜欢记录,获取父ID - QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); - userLikeQueryWrapper.lambda().eq(UserLike::getDesignOutfitId, tDesignPythonOutfit.getId()); - List userLikeList = userLikeMapper.selectList(userLikeQueryWrapper); - if (!CollectionUtils.isEmpty(userLikeList)) { - UserLike userLike = userLikeList.get(0); - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(userLike.getId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } - } else if (toProductImageResult.getElementType().equals("ToProductImage")) { - // 处理转产品图像类型:获取转产品图像信息并设置源图片URL - ToProductImageResult toProductImage = toProductImageResultMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductImage.getUrl(), 24 * 60)); - - // 直接通过元素ID和类型获取父ID - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } - -// Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getId(), toProductImageResult.getResultType()); -// magicToolResultVO.setParentId(parentId); - return magicToolResultVO; - } - - /** - * 处理Flux模型生成的结果,构建返回给前端的结果对象 - * - * @param fluxImgMinioPath Flux生成的图片在Minio中的路径 - * @param toProductImageResult 产品图像生成结果记录 - * @param taskId 任务ID - * @param prompt 生成提示词 - * @return MagicToolResultVO 构建好的魔法工具结果对象 - */ - private MagicToolResultVO processFluxResult(String fluxImgMinioPath, ToProductImageResult toProductImageResult, String taskId, String prompt) { - // 如果任务状态不是成功且URL为空,则更新任务状态和URL - if (!toProductImageResult.getStatus().equals("Success") - && StringUtil.isNullOrEmpty(toProductImageResult.getUrl())) { - toProductImageResult.setStatus("Success"); - toProductImageResult.setUrl(fluxImgMinioPath); - toProductImageResultMapper.updateById(toProductImageResult); - } - - // 创建返回结果对象并设置基本信息 - MagicToolResultVO magicToolResultVO = CopyUtil.copyObject(toProductImageResult, MagicToolResultVO.class); - magicToolResultVO.setTaskId(taskId); - magicToolResultVO.setId(toProductImageResult.getId()); - // 设置Flux生成图片的预签名URL(使用系统配置的过期时间) - magicToolResultVO.setUrl(minioUtil.getPreSignedUrl(fluxImgMinioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - magicToolResultVO.setStatus("Success"); - magicToolResultVO.setResultType(toProductImageResult.getResultType()); - magicToolResultVO.setElementId(toProductImageResult.getElementId()); - magicToolResultVO.setElementType(toProductImageResult.getElementType()); - magicToolResultVO.setPrompt(prompt); - - // 根据元素类型设置源图片URL和父ID - if (toProductImageResult.getElementType().equals("ProductElement")) { - // 处理产品元素类型:获取产品元素信息并设置源图片URL - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); - - // 通过CollectionSort服务获取父ID - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } else if (toProductImageResult.getElementType().equals("DesignOutfit")) { - // 处理设计服装类型:获取设计服装信息并设置源图片URL - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); - - // 通过设计服装ID查找对应的用户喜欢记录,获取父ID - QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); - userLikeQueryWrapper.lambda().eq(UserLike::getDesignOutfitId, tDesignPythonOutfit.getId()); - List userLikeList = userLikeMapper.selectList(userLikeQueryWrapper); - if (!CollectionUtils.isEmpty(userLikeList)) { - UserLike userLike = userLikeList.get(0); - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(userLike.getId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } - } else if (toProductImageResult.getElementType().equals("ToProductImage")) { - // 处理转产品图像类型:获取转产品图像信息并设置源图片URL - ToProductImageResult toProductImage = toProductImageResultMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductImage.getUrl(), 24 * 60)); - - // 直接通过元素ID和类型获取父ID - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } - -// Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getId(), toProductImageResult.getResultType()); -// magicToolResultVO.setParentId(parentId); - return magicToolResultVO; - } - - @Override - public JSONObject exportSearch(ExportSearchDTO exportSearchDTO) { - QueryWrapper qw = new QueryWrapper<>(); - if (Objects.nonNull(exportSearchDTO.getProjectId())) { - qw.lambda().eq(ExportFile::getProjectId, exportSearchDTO.getProjectId()); - } else if (Objects.nonNull(exportSearchDTO.getId())) { - qw.lambda().eq(ExportFile::getId, exportSearchDTO.getId()); - } - qw.lambda().eq(ExportFile::getModule, exportSearchDTO.getModule()); - List exportFiles = exportFileMapper.selectList(qw); - if (CollectionUtil.isNotEmpty(exportFiles)) { - try { - InputStream download = minioUtil.download(exportFiles.get(0).getUrl()); - String convert = convert(download); - JSONObject jsonObject = JSONObject.parseObject(convert); - - JSONObject canvas = jsonObject.getJSONObject("canvas"); - if (Objects.nonNull(canvas)) { - JSONArray objectJSONArrayLevel1 = canvas.getJSONArray("objects"); - for (int i = 0; i < objectJSONArrayLevel1.size(); i++) { - JSONObject jsonObjectLevel1 = objectJSONArrayLevel1.getJSONObject(i); - String type = jsonObjectLevel1.getString("type"); - if (type.equals("image")) { - String minioUrl = jsonObjectLevel1.getString("minioUrl"); - if (!StringUtil.isNullOrEmpty(minioUrl)) - jsonObjectLevel1.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); - } - if (type.equals("group")) { - JSONArray objectJSONArrayLevel2 = jsonObjectLevel1.getJSONArray("objects"); - for (int j = 0; j < objectJSONArrayLevel2.size(); j++) { - JSONObject jsonObjectLevel2 = objectJSONArrayLevel2.getJSONObject(j); - String typeGroup = jsonObjectLevel2.getString("type"); - if (typeGroup.equals("image") && !StringUtil.isNullOrEmpty(jsonObjectLevel2.getString("minioUrl"))) { - String minioUrl = jsonObjectLevel2.getString("minioUrl"); - jsonObjectLevel2.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); - } - objectJSONArrayLevel2.set(j, jsonObjectLevel2); - } - jsonObjectLevel1.put("objects", objectJSONArrayLevel2); - } - /*if (type.equals("rect")) { - JSONObject custom = jsonObjectLevel1.getJSONObject("custom"); - if (custom.getString("type").equals("init")) { - String minioUrl = jsonObjectLevel1.getString("minioUrl"); - if (!StringUtils.isEmpty(minioUrl)) { - JSONObject fill = jsonObjectLevel1.getJSONObject("fill"); - fill.put("source", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); - jsonObjectLevel1.put("fill", fill); - } - } - }*/ - objectJSONArrayLevel1.set(i, jsonObjectLevel1); - } - canvas.put("objects", objectJSONArrayLevel1); - jsonObject.put("canvas", canvas); - } else { - JSONArray objectJSONArrayLevel1 = jsonObject.getJSONArray("objects"); - for (int i = 0; i < objectJSONArrayLevel1.size(); i++) { - JSONObject jsonObjectLevel1 = objectJSONArrayLevel1.getJSONObject(i); - String type = jsonObjectLevel1.getString("type"); - if (type.equals("image")) { - String minioUrl = jsonObjectLevel1.getString("minioUrl"); - if (!StringUtil.isNullOrEmpty(minioUrl)) - jsonObjectLevel1.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); - } - if (type.equals("group")) { - JSONArray objectJSONArrayLevel2 = jsonObjectLevel1.getJSONArray("objects"); - for (int j = 0; j < objectJSONArrayLevel2.size(); j++) { - JSONObject jsonObjectLevel2 = objectJSONArrayLevel2.getJSONObject(j); - String typeGroup = jsonObjectLevel2.getString("type"); - if (typeGroup.equals("image") && !StringUtil.isNullOrEmpty(jsonObjectLevel2.getString("minioUrl"))) { - String minioUrl = jsonObjectLevel2.getString("minioUrl"); - jsonObjectLevel2.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); - } - objectJSONArrayLevel2.set(j, jsonObjectLevel2); - } - jsonObjectLevel1.put("objects", objectJSONArrayLevel2); - } - /*if (type.equals("rect")) { - JSONObject custom = jsonObjectLevel1.getJSONObject("custom"); - if (custom.getString("type").equals("init")) { - String minioUrl = jsonObjectLevel1.getString("minioUrl"); - if (!StringUtils.isEmpty(minioUrl)) { - JSONObject fill = jsonObjectLevel1.getJSONObject("fill"); - fill.put("source", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); - jsonObjectLevel1.put("fill", fill); - } - } - }*/ - objectJSONArrayLevel1.set(i, jsonObjectLevel1); - } - jsonObject.put("objects", objectJSONArrayLevel1); - } - return jsonObject; - } catch (Exception e) { - log.error(e.getMessage()); - return null; - } - } else { - return null; - } - } - - @Override - public CanvasElementUpload canvasElementUpload(MultipartFile file) { - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - CanvasElementUpload canvasElementUpload = new CanvasElementUpload(); - String url = minioUtil.upload("aida-users", userHolder.getId() + "/canvasElementUpload", file); - canvasElementUpload.setUrl(url); - canvasElementUpload.setMinioUrl(minioUtil.getPreSignedUrl(url, 24 * 60)); - return canvasElementUpload; - } - - @Override - public List productImageLikeList(ToProductImageDTO toProductImageDTO) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ToProductImageResult::getIsLike, 1); - - Long projectId = toProductImageDTO.getProjectId(); -// UserLikeGroup userLikeGroup = getByProjectId(projectId); -// Long userLikeGroupId = null; - - qw.lambda().eq(ToProductImageResult::getProjectId, projectId); - List toProductImageResults = toProductImageResultMapper.selectList(qw); - for (ToProductImageResult toProductImageResult : toProductImageResults) { - toProductImageResult.setUrl(minioUtil.getPreSignedUrl(toProductImageResult.getUrl(), 24 * 60)); - } - List toProductImageResultVOS = CopyUtil.copyList(toProductImageResults, ToProductImageResultVO.class); - for (ToProductImageResultVO toProductImageResultVO : toProductImageResultVOS) { - if (toProductImageResultVO.getElementType().equals("ProductElement")) { - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); - } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); - } else { - ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductImageResult1.getUrl(), 24 * 60)); - } - } - // 更新项目更新时间 - projectService.modifyProjectUpdateTime(toProductImageDTO.getProjectId()); - return toProductImageResultVOS; - } - - @Override - public Boolean productImageUnLike(ProductImageLikeDTO productImageLikeDTO) { - List toProductImageResultId = productImageLikeDTO.getToProductImageResultId(); - if (!CollectionUtils.isEmpty(toProductImageResultId)) { - Long toProductImageId = toProductImageResultId.get(0); - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(toProductImageId); - toProductImageResult.setIsLike(0); - toProductImageResultMapper.updateById(toProductImageResult); - if (toProductImageResult.getResultType().equals(CollectionType.RELIGHT.getValue())) { - if (null != productImageLikeDTO.getCollectionSortParentId()) { - collectionSortService.deleteCollectionSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), productImageLikeDTO.getProjectId(), productImageLikeDTO.getCollectionSortParentId()); - } - } else { - if (null != productImageLikeDTO.getCollectionSortParentId()) { - collectionSortService.deleteCollectionSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), productImageLikeDTO.getProjectId(), productImageLikeDTO.getCollectionSortParentId()); - } - } - } - // 更新项目更新时间 - projectService.modifyProjectUpdateTime(productImageLikeDTO.getProjectId()); - return Boolean.TRUE; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void relight(String taskId) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ToProductImageResult::getTaskId, taskId); - List toProductImageResults = toProductImageResultMapper.selectList(qw); - if (CollectionUtil.isNotEmpty(toProductImageResults)) { - ToProductImageResult toProductImageResultOne = toProductImageResults.get(0); - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResultOne.getToProductImageRecordId()); - String prompt = toProductImageRecord.getPrompt(); - - // 翻译 - String s = ""; - if (!StringUtil.isNullOrEmpty(prompt)) { - s = pythonService.promptTranslate(prompt); - } else { - s = "Snow moutain, snowy day, natural light"; - } - String elementType = toProductImageResultOne.getElementType(); - if (elementType.equals("ToProductImage")) { - ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultOne.getElementId()); - String relightType = "overall"; - if (toProductImageResult1.getElementType().equals("DesignOutfit")) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult1.getElementId()); - Long designId = tDesignPythonOutfit.getDesignId(); - Design design = designMapper.selectById(designId); - if (design.getSingleOverall().equals("single")) { - relightType = "single"; - } - } - - // 走模型 - pythonService.relight(toProductImageResult1.getUrl(), taskId, s, toProductImageResultOne.getDirection(), "single"); - } else { - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultOne.getElementId()); - // 走模型 - pythonService.relight(toProductElement.getUrl(), taskId, s, toProductImageResultOne.getDirection(), "single"); - } - - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public List relight(ToProductImageDTO toProductImageDTO) { - // 判断用户当前积分是否够本次生成消耗 - boolean fluxTask = !StringUtil.isNullOrEmpty(toProductImageDTO.getModelName()) - && toProductImageDTO.getModelName().equals("flux"); - CreditsEventsEnum creditsEventsEnum = fluxTask ? CreditsEventsEnum.RELIGHT_FLUX : CreditsEventsEnum.RELIGHT; - Boolean preDeduction = creditsService.creditsPreDeduction(creditsEventsEnum, toProductImageDTO.getToProductImageVOList().size()); - if (!preDeduction) { - throw new BusinessException("remaining.credits.insufficient", ResultEnum.WARNING.getCode()); - } - - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - Long projectId = toProductImageDTO.getProjectId(); - UserLikeGroup userLikeGroup = getByProjectId(projectId); - Long userLikeGroupId = null; - - ToProductImageRecord toProductImageRecord = new ToProductImageRecord(); - toProductImageRecord.setProjectId(projectId); - if (Objects.nonNull(userLikeGroup)) { - userLikeGroupId = userLikeGroup.getId(); - toProductImageRecord.setUserLikeGroupId(userLikeGroupId); - } - - // 翻译 - String prompt = toProductImageDTO.getPrompt(); - String s = ""; - if (!StringUtil.isNullOrEmpty(prompt)) { - s = pythonService.promptTranslate(prompt); - } else { -// s = "Snow moutain, snowy day, natural light"; - s = "Street, natural light"; - } - // 对输入文本进行长度限制 - String[] words = prompt.split("\\s+"); - if (words.length > 200) { - throw new BusinessException("Please keep your input text under 200 words. Thanks!"); - } - - toProductImageRecord.setCreateTime(LocalDateTime.now()); - if (!StringUtils.isEmpty(toProductImageDTO.getPrompt())) { - toProductImageRecord.setPrompt(toProductImageDTO.getPrompt()); - } - toProductImageRecordMapper.insert(toProductImageRecord); - - List result = new ArrayList<>(); - - int i = 0; - - for (ToProductImageVO toProductImageVO : toProductImageDTO.getToProductImageVOList()) { - String taskId = UUID.randomUUID() + "-" + i + "-" + userHolder.getId(); - i++; - if (toProductImageVO.getElementType().equals("ToProductImage")) { - ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageVO.getElementId()); - String relightType = "overall"; - if (toProductImageResult1.getElementType().equals("DesignOutfit")) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult1.getElementId()); - Long designId = tDesignPythonOutfit.getDesignId(); - Design design = designMapper.selectById(designId); - if (design.getSingleOverall().equals("single")) { - relightType = "single"; - } - } - - ToProductImageResultVO toProductImageResult = new ToProductImageResultVO(); - if (fluxTask) { - taskId = generateService.flux(creditsEventsEnum, s, toProductImageResult1.getUrl(), false); - toProductImageResult.setModelName("flux"); - toProductImageResult.setResultType(CollectionType.RELIGHT.getValue()); - } else { - // 走模型 - pythonService.relight(toProductImageResult1.getUrl(), taskId, s, toProductImageDTO.getDirection(), relightType); - } - toProductImageResult.setElementId(toProductImageResult1.getId()); - toProductImageResult.setElementType("ToProductImage"); - toProductImageResult.setCreateTime(LocalDateTime.now()); - toProductImageResult.setToProductImageRecordId(toProductImageRecord.getId()); -// toProductImageResult.setUrl(productImageUrl); - toProductImageResult.setIsLike(0); - toProductImageResult.setTaskId(taskId); - toProductImageResult.setProjectId(projectId); - if (null != userLikeGroupId) { - toProductImageResult.setUserLikeGroupId(userLikeGroupId); - } - if (toProductImageDTO.getBrightenValue() != null) { - toProductImageResult.setBrightenValue(toProductImageDTO.getBrightenValue()); - } - toProductImageResult.setDirection(toProductImageDTO.getDirection()); - toProductImageResult.setResultType(CollectionType.RELIGHT.getValue()); - toProductImageResult.setStatus("Pending"); - toProductImageResultMapper.insert(toProductImageResult); -// toProductImageResult.setUrl(minioUtil.getPresignedUrl(toProductImageResult.getUrl(), 24 * 60)); - // 先判断是否需要默认like - if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && toProductImageDTO.getIsDefaultLike()) { - // 满足条件情况下默认添加到like - CollectionSort collectionSort = addToProductLike(toProductImageVO.getParentId(), toProductImageResult.getId(), toProductImageDTO.getProjectId()); - // 重新排序 - Integer reSort = collectionSortService.rearrangeChildSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), - toProductImageVO.getParentId(), toProductImageVO.getUserLikeSortId()); - // 将生成结果的排序返回 - toProductImageResult.setSort(Objects.isNull(reSort) ? Objects.isNull(collectionSort) ? null : collectionSort.getSort() : reSort); - toProductImageResult.setParentId(toProductImageVO.getParentId()); - toProductImageResult.setUserLikeSortId(Objects.isNull(collectionSort) ? null : collectionSort.getId()); - } else if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && Objects.nonNull(toProductImageVO.getParentId())) { - toProductImageResult.setParentId(toProductImageVO.getParentId()); - // 默认不添加到like,但是需要有parentId,所以这里添加到collectionSort表中 -// designService.addCollectionSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), toProductImageDTO.getProjectId(), toProductImageVO.getParentId()); - } - result.add(toProductImageResult); - } else { - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageVO.getElementId()); - ToProductImageResultVO toProductImageResult = new ToProductImageResultVO(); - if (fluxTask) { - taskId = generateService.flux(CreditsEventsEnum.RELIGHT_FLUX, s, toProductElement.getUrl(), false); - toProductImageResult.setModelName("flux"); - toProductImageResult.setResultType(CollectionType.RELIGHT.getValue()); - } else { - // 走模型 - pythonService.relight(toProductElement.getUrl(), taskId, s, toProductImageDTO.getDirection(), "overall"); - } - toProductImageResult.setElementId(toProductElement.getId()); - toProductImageResult.setElementType("ProductElement"); - toProductImageResult.setCreateTime(LocalDateTime.now()); - toProductImageResult.setToProductImageRecordId(toProductImageRecord.getId()); -// toProductImageResult.setUrl(productImageUrl); - toProductImageResult.setIsLike(0); - toProductImageResult.setTaskId(taskId); - toProductImageResult.setProjectId(projectId); - if (null != userLikeGroupId) { - toProductImageResult.setUserLikeGroupId(userLikeGroupId); - } - if (toProductImageDTO.getBrightenValue() != null) { - toProductImageResult.setBrightenValue(toProductImageDTO.getBrightenValue()); - } - toProductImageResult.setDirection(toProductImageDTO.getDirection()); - toProductImageResult.setResultType(CollectionType.RELIGHT.getValue()); - toProductImageResult.setStatus("Pending"); - toProductImageResultMapper.insert(toProductImageResult); -// toProductImageResult.setUrl(minioUtil.getPresignedUrl(toProductImageResult.getUrl(), 24 * 60)); - // 先判断是否需要默认like - if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && toProductImageDTO.getIsDefaultLike()) { - // 满足条件情况下默认添加到like - CollectionSort collectionSort = addToProductLike(toProductImageVO.getParentId(), toProductImageResult.getId(), toProductImageDTO.getProjectId()); - // 重新排序 - Integer reSort = collectionSortService.rearrangeChildSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), - toProductImageVO.getParentId(), toProductImageVO.getUserLikeSortId()); - // 将生成结果的排序返回 - toProductImageResult.setSort(Objects.isNull(reSort) ? Objects.isNull(collectionSort) ? null : collectionSort.getSort() : reSort); - toProductImageResult.setParentId(toProductImageVO.getParentId()); - toProductImageResult.setUserLikeSortId(Objects.isNull(collectionSort) ? null : collectionSort.getId()); - } else if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && Objects.nonNull(toProductImageVO.getParentId())) { - toProductImageResult.setParentId(toProductImageVO.getParentId()); - // 默认不添加到like,但是需要有parentId,所以这里添加到collectionSort表中 -// designService.addCollectionSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), toProductImageDTO.getProjectId(), toProductImageVO.getParentId()); - } - result.add(toProductImageResult); - } - // 添加需要扣除的积分到预扣除区 - creditsService.addRecordToCreditsDeduction(userHolder.getId(), taskId, creditsEventsEnum); - // 添加积分扣除记录到db - creditsService.preInsert(userHolder.getId(), creditsEventsEnum.getName(), taskId, Boolean.TRUE, null); - } - // 更新项目更新时间 - projectService.modifyProjectUpdateTime(toProductImageDTO.getProjectId()); - return result; - } - - @Override - public List getRelightResult(List taskIdList) { - List results = new ArrayList<>(); - Set collect = new HashSet<>(); - taskIdList.forEach(taskId -> { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ToProductImageResult::getTaskId, taskId); - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(qw); - if (Objects.isNull(toProductImageResult)) { - throw new BusinessException("source.image.does.not.exist"); - } - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); - if (Objects.isNull(toProductImageRecord)) { - throw new BusinessException("This task does not exist."); - } - // 判断当任务从哪个模型获取结果 - if (!StringUtil.isNullOrEmpty(toProductImageResult.getModelName()) - && toProductImageResult.getModelName().equals("flux")) { - Project project = projectService.getById(toProductImageResult.getProjectId()); - if (Objects.isNull(project)) { - throw new BusinessException("unknown project"); - } - String fluxResult; - if (toProductImageResult.getStatus().equals("Success") && !StringUtil.isNullOrEmpty(toProductImageResult.getUrl())) { - fluxResult = toProductImageResult.getUrl(); - } else { - String objectName = project.getAccountId() + "/relight_image/" + taskId + ".png"; - fluxResult = generateService.getFluxResult(taskId, objectName); - } - - if (StringUtil.isNullOrEmpty(fluxResult)) { - toProductImageResult.setStatus("Fail"); - toProductImageResultMapper.updateById(toProductImageResult); - if (toProductImageResult.getIsLike() != null && toProductImageResult.getIsLike() == 1) { - sortRank(toProductImageResult); - } - results.add(new MagicToolResultVO(taskId, "Fail")); - } else if (fluxResult.equals("Fail") || fluxResult.equals("Pending")) { - toProductImageResult.setStatus(fluxResult); - toProductImageResultMapper.updateById(toProductImageResult); - if (fluxResult.equals("Fail") && toProductImageResult.getIsLike() != null && toProductImageResult.getIsLike() == 1) { - sortRank(toProductImageResult); - } - results.add(new MagicToolResultVO(taskId, fluxResult)); - } else { - results.add(processFluxResult(fluxResult, toProductImageResult, taskId, toProductImageRecord.getPrompt())); - // 扣积分 - Boolean flag = creditsService.taskCreditsDeduction(project.getAccountId(), taskId); - if (flag) creditsService.updateChangedCredits(String.valueOf(project.getAccountId()), taskId); - } - // 将积分暂扣区的积分移除 - if (toProductImageResult.getStatus().equals("Fail")) { - creditsService.deleteCreditsDeduction(project.getAccountId(), taskId); - } - - return; - } - - String key = relightResultKey + ":" + taskId; - MagicToolResultVO magicToolResultVO = new Gson().fromJson(redisUtil.getFromString(key), MagicToolResultVO.class); - if (!Objects.isNull(magicToolResultVO) && !StringUtil.isNullOrEmpty(magicToolResultVO.getUrl())) { - String url = magicToolResultVO.getUrl(); - magicToolResultVO.setDirection(toProductImageResult.getDirection()); - magicToolResultVO.setBrightenValue(toProductImageResult.getBrightenValue()); - magicToolResultVO.setImageStrength(toProductImageResult.getImageStrength()); - magicToolResultVO.setPrompt(toProductImageRecord.getPrompt()); - if (url.substring(url.lastIndexOf("/") + 1).equals("white_image.jpg")) { - magicToolResultVO.setStatus("Invalid"); - } else { - magicToolResultVO.setUrl(minioUtil.getPreSignedUrl(url, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - - magicToolResultVO.setResultType(toProductImageResult.getResultType()); - magicToolResultVO.setElementId(toProductImageResult.getElementId()); - magicToolResultVO.setElementType(toProductImageResult.getElementType()); - if (toProductImageResult.getElementType().equals("ProductElement")) { - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); - } else { - ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResult.getElementId()); - magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductImageResult1.getUrl(), 24 * 60)); - } - Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); - magicToolResultVO.setParentId(parentId); - } - } else if (Objects.isNull(magicToolResultVO)) { - magicToolResultVO = new MagicToolResultVO(); - } - if (!StringUtil.isNullOrEmpty(magicToolResultVO.getStatus())) collect.add(magicToolResultVO.getStatus()); - results.add(magicToolResultVO); - }); - return results; - } - - /* - 重排Relight失败sort - */ - private void sortRank(ToProductImageResult toProductImageResult) { - LambdaQueryWrapper collectionSortLambdaQueryWrapper = new LambdaQueryWrapper<>(); - collectionSortLambdaQueryWrapper.eq(CollectionSort::getRelationId, toProductImageResult.getId()).orderByDesc(CollectionSort::getCreateTime).last("LIMIT 1"); - - List collectionSorts = collectionSortMapper.selectList(collectionSortLambdaQueryWrapper); - - if (!collectionSorts.isEmpty()) { - - collectionSortMapper.deleteById(collectionSorts.get(0)); - List collectionSorts1 = collectionSortMapper.selectList(new LambdaQueryWrapper().eq(CollectionSort::getParentId, collectionSorts.get(0).getParentId()).gt(CollectionSort::getSort, collectionSorts.get(0).getSort())); - if (!collectionSorts1.isEmpty()) { - for (CollectionSort collectionSort : collectionSorts1) { - collectionSort.setSort(collectionSort.getSort() - 1); - collectionSortMapper.updateById(collectionSort); - } - } - } - } - - public static String convert(InputStream inputStream) { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { - return reader.lines().collect(Collectors.joining("\n")); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - @Transactional(rollbackFor = Exception.class) - public void deleteToProductRelightResult(Long id, Long projectId, String type) { - // 1. 权限校验和删除主数据 - Long accountId = UserContext.getUserHolder().getId(); - Project project = projectService.getById(projectId); - if (!project.getAccountId().equals(accountId)) { - throw new IllegalArgumentException("项目不属于当前账号"); - } - - // 2. 删除主表数据 - UpdateWrapper wrapper = new UpdateWrapper<>(); - wrapper.lambda().eq(ToProductImageResult::getProjectId, projectId) - .eq(ToProductImageResult::getId, id).or().eq(ToProductImageResult::getElementId, id) - .set(ToProductImageResult::getIsDeleted, 1); - - int update = toProductImageResultMapper.update(null, wrapper); - log.info("删除 {} 结果, id={}, 影响行数={}", type, id, update); - - if (update == 0) { - return; // 未删除任何数据,直接返回 - } - - // 3. 查询所有被删除的排序项(按sort升序) - List deletedItems = collectionSortMapper.selectList( - new QueryWrapper() - .eq("project_id", projectId) - .eq("relation_id", id) - .eq("relation_type", type) - .orderByAsc("sort") - ); - - if (deletedItems.isEmpty()) return; - - // 4. 删除这些记录 - int deletedCount = collectionSortMapper.delete( - new QueryWrapper() - .eq("project_id", projectId) - .eq("relation_id", id) - .eq("relation_type", type) - ); - log.info("删除排序记录:id={}, type={}, 影响行数={}", id, type, deletedCount); - - // 5. 对每个被删除的sort值,单独调整后续记录 - for (CollectionSort deletedItem : deletedItems) { - collectionSortMapper.update( - null, - new UpdateWrapper() - .eq("project_id", projectId) - .gt("sort", deletedItem.getSort()) - .setSql("sort = sort - 1") // 每条SQL只减1 - ); - } - } - - @Override - public String likeHistoryRelSketch() { - QueryWrapper qw = new QueryWrapper<>(); - List userLikeGroups = userLikeGroupMapper.selectList(qw); - List>> result = new ArrayList<>(); - - for (UserLikeGroup userLikeGroup : userLikeGroups) { - Long accountId = userLikeGroup.getAccountId(); - Long collectionId = userLikeGroup.getCollectionId(); - - // 提前转换为Set以提高contains的效率 - List collectionElements = getCollectionElementsByCollectionId(collectionId); - Set urlSet = collectionElements.stream() - .map(CollectionElement::getUrl) - .collect(Collectors.toSet()); - - List userLikes = getUserLikesByGroupId(userLikeGroup.getId()); - - for (UserLike userLike : userLikes) { - List> userLikeSketchList = new ArrayList<>(); - List designItemDetails = getDesignItemDetails(userLike.getDesignItemId()); - - for (DesignItemDetail designItemDetail : designItemDetails) { - Map sketch = new HashMap<>(); - String path = designItemDetail.getPath(); - - // 下载路径到本地 -// if (!StringUtils.isEmpty(path)) { -// String bucketName = minioUtil.getBucketNameFromPath(path); -// String objectName = minioUtil.getObjectNameFromPath(path); -// String localBasePath = "C:\\workspace\\fileData\\minio"; -// String localFilePath = Paths.get(localBasePath, path).toString(); -// -// // 检查文件是否已经存在,避免重复下载 -// File localFile = new File(localFilePath); -// if (!localFile.exists()) { -// minioUtil.downloadMinioObjectToLocal(bucketName, objectName, localFilePath); -// } else { -// log.info("File already exists, skipping download: {}", localFilePath); -// } -// } - - Long designId = designItemDetail.getDesignId(); - Design design = designMapper.selectById(designId); - if (null == design) { - continue; - } - if (design.getSingleOverall().equals("single")) { - continue; - } - if (design.getModelType().equals("System")) { - SysFile sysFile = sysFileMapper.selectById(design.getTemplateId()); - if (null == sysFile) { - continue; - } - sketch.put("sex", sysFile.getLevel2Type().equals("Male") ? "Male" : "Female"); - } else { - Library library = libraryMapper.selectById(design.getTemplateId()); - if (null == library) { - continue; - } - sketch.put("sex", library.getLevel2Type().equals("Female") ? "Female" : "Male"); - } - - sketch.put("type", designItemDetail.getType()); - sketch.put("path", path); - sketch.put("beSelected", urlSet.contains(path)); - sketch.put("accountId", accountId); - - if (path.contains("aida-sys-image/images/")) { - String replace = path.replace("aida-sys-image/images/", ""); - String style = getStyleByUrl(replace); - if (!StringUtils.isEmpty(style)) { - sketch.put("style", style); - } - } - userLikeSketchList.add(sketch); - } - if (CollectionUtil.isNotEmpty(userLikeSketchList)) { - result.add(userLikeSketchList); - } - } - } - - // 将结果以美观的JSON形式保存到文件中 - saveResultAsPrettyJson(result, "C:\\Users\\10233\\Desktop\\result.json"); - - return null; - } - - @Override - public String download() { - // 下载 aida-collection-element bucket 下所有 Sketchboard 文件夹内容 -// String sketchboardLocalPath = "C:\\workspace\\fileData\\minio"; -// minioUtil.downloadSketchboardDirectories(sketchboardLocalPath); -// -// // 下载整个 aida-users bucket -// String aidaUsersLocalPath = "C:\\workspace\\fileData\\minio"; -// minioUtil.downloadEntireBucket("aida-users", aidaUsersLocalPath); - return null; - } - - // 提取公共方法 - private List getCollectionElementsByCollectionId(Long collectionId) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(CollectionElement::getCollectionId, collectionId) - .eq(CollectionElement::getLevel1Type, "Sketchboard"); - return collectionElementMapper.selectList(qw); - } - - private List getUserLikesByGroupId(Long groupId) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(UserLike::getUserLikeGroupId, groupId); - return userLikeMapper.selectList(qw); - } - - private List getDesignItemDetails(Long designItemId) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(DesignItemDetail::getDesignItemId, designItemId) - .ne(DesignItemDetail::getType, "Body"); - return designItemDetailService.list(qw); - } - - private void saveResultAsPrettyJson(List>> result, String filePath) { - // 使用一个 Map 将结果存储为字符串键 - Map resultMap = new HashMap<>(); - resultMap.put("data", result); - - try (FileWriter file = new FileWriter(filePath)) { - // 使用 JSONObject 将转换后的 Map 转为 JSON - JSONObject jsonObject = new JSONObject(resultMap); - // 格式化输出为美观的 JSON - file.write(JSON.toJSONString(jsonObject, SerializerFeature.PrettyFormat)); - } catch (IOException e) { - e.printStackTrace(); - } - } - - - private String getStyleByUrl(String replace) { - String[] split = replace.split("/"); - String tableName = getTableName(split); - if (StringUtils.isEmpty(tableName)) { - return null; - } else { - replace = split[1] + "/" + split[2]; - return attributeRetrievalMapper.getStyleByUrl(replace, tableName); - } - } - - private String getTableName(String[] split) { - switch (split[0]) { - case "female": { - switch (split[1]) { - case "blouse": { - return "female_top"; - } - case "trousers": { - return "female_pants"; - } - case "skirt": { - return "female_skirt"; - } - case "outwear": { - return "female_outwear"; - } - case "dress": { - return "female_dress"; - } - default: { - return null; - } - } - } - case "male": { - switch (split[1]) { - case "top": { - return "male_top"; - } - case "bottom": { - return "male_bottom"; - } - case "outwear": { - return "male_outwear"; - } - default: { - return null; - } - } - } - default: { - return null; - } - } - } - - @Override - public Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO) { - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - productImageService.asyncInitialize(productImageInitializeDTO.getBrandId(), userHolder); - return true; - } - - @Override - public InitializeProgressVO getInitializeProgress(ProductImageInitializeDTO productImageInitializeDTO) { - InitializeProgressVO vo = new InitializeProgressVO(); - -// QueryWrapper<> - - ProgressDTO dto = redisUtil.getTaskProgressDTO(String.valueOf(productImageInitializeDTO.getBrandId())); - - if (Objects.isNull(dto)) { - vo.setAnalyzed(false); - return vo; - } - vo.setAnalyzed(true); - vo.setComputeTime(dto.getComputeTime()); - if (dto.getTotal() == 0 || dto.isError()) { - vo.setPercent(0.0); - return vo; - } - vo.setPercent(dto.getCurrent() * 1.0 / dto.getTotal()); - return vo; - } - - private ProductImageAttribute toAttrDict(AttributeRecognitionJSON attrDictJSON) { - ProductImageAttribute attributeRetrieval = new ProductImageAttribute(); - - // 处理 imgName -// if (CollectionUtil.isNotEmpty(attrDictJSON.getImgName()) && attrDictJSON.getImgName().get(0) != null) { -// attributeRetrieval.setImgName(attrDictJSON.getImgName().get(0)); -// } - // 处理 length - if (CollectionUtil.isNotEmpty(attrDictJSON.getLength()) && attrDictJSON.getLength().get(0) != null) { - attributeRetrieval.setLength(attrDictJSON.getLength().get(0)); - } - // 处理 sleeveLength - if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveLength()) && attrDictJSON.getSleeveLength().get(0) != null) { - attributeRetrieval.setSleeveLength(attrDictJSON.getSleeveLength().get(0)); - } - // 处理 sleeveShape - if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveShape()) && attrDictJSON.getSleeveShape().get(0) != null) { - attributeRetrieval.setSleeveShape(attrDictJSON.getSleeveShape().get(0)); - } - // 处理 sleeveShoulder - if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveShoulder()) && attrDictJSON.getSleeveShoulder().get(0) != null) { - attributeRetrieval.setSleeveShoulder(attrDictJSON.getSleeveShoulder().get(0)); - } - // 处理 neckline - if (CollectionUtil.isNotEmpty(attrDictJSON.getNeckline()) && attrDictJSON.getNeckline().get(0) != null) { - attributeRetrieval.setNeckline(attrDictJSON.getNeckline().get(0)); - } - // 处理 collar - if (CollectionUtil.isNotEmpty(attrDictJSON.getCollar()) && attrDictJSON.getCollar().get(0) != null) { - attributeRetrieval.setCollar(attrDictJSON.getCollar().get(0)); - } - // 处理 design - if (CollectionUtil.isNotEmpty(attrDictJSON.getDesign()) && attrDictJSON.getDesign().get(0) != null) { - attributeRetrieval.setDesign(attrDictJSON.getDesign().get(0)); - } - // 处理 silhouette - if (CollectionUtil.isNotEmpty(attrDictJSON.getSilhouette()) && attrDictJSON.getSilhouette().get(0) != null) { - attributeRetrieval.setSilhouette(attrDictJSON.getSilhouette().get(0)); - } - // 处理 type - if (CollectionUtil.isNotEmpty(attrDictJSON.getType()) && attrDictJSON.getType().get(0) != null) { - attributeRetrieval.setType(attrDictJSON.getType().get(0)); - } - // 处理 openingType - if (CollectionUtil.isNotEmpty(attrDictJSON.getOpeningType()) && attrDictJSON.getOpeningType().get(0) != null) { - attributeRetrieval.setOpeningType(attrDictJSON.getOpeningType().get(0)); - } - // 处理 subtype - if (CollectionUtil.isNotEmpty(attrDictJSON.getSubtype()) && attrDictJSON.getSubtype().get(0) != null) { - attributeRetrieval.setSubtype(attrDictJSON.getSubtype().get(0)); - } - - return attributeRetrieval; - } - -// private ProductImageAttribute toAttrDict(AttributeRecognitionJSON attrDictJSON) { -// ProductImageAttribute attributeRetrieval = new ProductImageAttribute(); - - /// / attributeRetrieval.setImgName(attrDictJSON.getImgName().get(0)); - /// / attributeRetrieval.setLength(attrDictJSON.getLength().get(0)); - /// / attributeRetrieval.setSleeveLength(attrDictJSON.getSleeveLength().get(0)); - /// / attributeRetrieval.setSleeveShape(attrDictJSON.getSleeveShape().get(0)); - /// / attributeRetrieval.setSleeveShoulder(attrDictJSON.getSleeveShoulder().get(0)); - /// / attributeRetrieval.setNeckline(attrDictJSON.getNeckline().get(0)); - /// / attributeRetrieval.setCollar(attrDictJSON.getCollar().get(0)); -// if (CollectionUtil.isNotEmpty(attrDictJSON.getDesign()) && attrDictJSON.getDesign().get(0) != null) { -// attributeRetrieval.setDesign(attrDictJSON.getDesign().get(0)); -// } -// if (CollectionUtil.isNotEmpty(attrDictJSON.getSilhouette()) && attrDictJSON.getSilhouette().get(0) != null) { -// attributeRetrieval.setSilhouette(attrDictJSON.getSilhouette().get(0)); -// } -// if (CollectionUtil.isNotEmpty(attrDictJSON.getType()) && attrDictJSON.getType().get(0) != null) { -// attributeRetrieval.setType(attrDictJSON.getType().get(0)); -// } -// if (CollectionUtil.isNotEmpty(attrDictJSON.getSubtype()) && attrDictJSON.getSubtype().get(0) != null) { -// attributeRetrieval.setSubtype(attrDictJSON.getSubtype().get(0)); -// } -// if (CollectionUtil.isNotEmpty(attrDictJSON.getOpeningType()) && attrDictJSON.getOpeningType().get(0) != null) { -// attributeRetrieval.setOpeningType(attrDictJSON.getOpeningType().get(0)); -// } -// return attributeRetrieval; -// } - @Override - public IPage getPage(ProjectQueryDTO query) { - AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); - // 分页数据 - QueryWrapper queryWrapper = new QueryWrapper<>(); - - queryWrapper.eq("account_id", authPrincipalVo.getId()); - if (Objects.nonNull(query.getId())) { - queryWrapper.eq("id", query.getId()); - } -// queryWrapper.isNull("parent_id"); - if (!StringUtils.isEmpty(query.getProjectName())) { - queryWrapper.like("name", query.getProjectName()); - } - if (Objects.nonNull(query.getStartDate())) { - queryWrapper.ge("update_time", new Date(query.getStartDate())); - } - if (Objects.nonNull(query.getEndDate())) { - queryWrapper.le("update_time", new Date(query.getEndDate())); - } - if (Objects.nonNull(query.getProcess()) && !query.getProcess().isEmpty()) { -// if (!StringUtils.isEmpty(query.getProcess())) { - // todo 获取历史列表,允许传入多个类型 - queryWrapper.in("process", query.getProcess()); -// queryWrapper.eq("process", query.getProcess()); - } - // 新增分类过滤 - if (CollectionUtil.isNotEmpty(query.getClassificationIdList())) { - List projectIdList = new ArrayList<>(); - if (query.getIntersection() == 0) { - for (Long classificationId : query.getClassificationIdList()) { - projectIdList.addAll(classificationService.getLibraryIdListByClassificationId(classificationId)); - } - if (CollectionUtil.isNotEmpty(projectIdList)) { - queryWrapper.in("id", projectIdList); - } else { - return new Page<>(); - } - } else { - for (int i = 0; i < query.getClassificationIdList().size(); i++) { - List historyIdListByClassificationId = classificationService.getLibraryIdListByClassificationId(query.getClassificationIdList().get(i)); - if (i == 0) { - projectIdList.addAll(historyIdListByClassificationId); - } else { - projectIdList.retainAll(historyIdListByClassificationId); - } - if (CollectionUtil.isEmpty(projectIdList)) { - return new Page<>(); - } - } - queryWrapper.in("id", projectIdList); - } - } - if (query.getAsc() != null && query.getAsc() == 1) { - queryWrapper.orderByAsc("update_time"); - } else { - queryWrapper.orderByDesc("update_time"); - } - IPage page = projectService.page( - new Page<>(query.getPage(), query.getSize()), queryWrapper); - if (CollectionUtils.isEmpty(page.getRecords())) { - return new Page<>(); - } - Set projectIdSet = page.getRecords().stream().map(Project::getId).collect(Collectors.toSet()); - QueryWrapper userLikeGroupQueryWrapper = new QueryWrapper<>(); - userLikeGroupQueryWrapper.lambda().in(UserLikeGroup::getProjectId, projectIdSet); - List userLikeGroups = userLikeGroupMapper.selectList(userLikeGroupQueryWrapper); - - Map> groupDetailMap = new HashMap<>(); - - if (CollectionUtil.isNotEmpty(userLikeGroups)) { - List groupIds = userLikeGroups.stream().map(UserLikeGroup::getId).collect(Collectors.toList()); - List groupDetails = userLikeService.getGroupDetails(groupIds); - - groupDetailMap = groupDetails.stream() - .collect(Collectors.groupingBy(UserLikeVO::getUserLikeGroupId)); - } - - Account account = accountMapper.selectById(authPrincipalVo.getId()); - Map> finalGroupDetailMap = groupDetailMap; - IPage convert = page.convert((Function) project -> { - if (project != null) { - - ProjectVO projectVO = CopyUtil.copyObject(project, ProjectVO.class); - if(project.getOriginal() == 0){ - //非原创 - projectVO.setOriginalAccountName(accountMapper.selectById(project.getOriginalAccountId()).getUserName()); - projectVO.setOriginalPortfolioName(portfolioMapper.getByIdAll(project.getOriginalPortfolioId()).getPortfolioName()); - } - // 用于排序的时间 - LocalDateTime orderTime = Objects.isNull(project.getUpdateTime()) ? project.getCreateTime() : project.getUpdateTime(); - projectVO.setUpdateDate(orderTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); - - QueryWrapper userLikeGroupQueryWrapper1 = new QueryWrapper<>(); - userLikeGroupQueryWrapper1.lambda().eq(UserLikeGroup::getProjectId, projectVO.getId()); - UserLikeGroup userLikeGroup = userLikeGroupMapper.selectOne(userLikeGroupQueryWrapper1); - if (Objects.nonNull(userLikeGroup)) { - UserLikeGroupVO userLikeGroupVO = CopyUtil.copyObject(userLikeGroup, UserLikeGroupVO.class); - userLikeGroupVO.setAuthor(account.getUserName()); - //count 和detail - if (finalGroupDetailMap.keySet().contains(userLikeGroupVO.getId())) { - List details = finalGroupDetailMap.get(userLikeGroupVO.getId()); - for (UserLikeVO detail : details) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(detail.getDesignOutfitId()); - detail.setUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); - } - userLikeGroupVO.setGroupDetails(details); - userLikeGroupVO.setSketchCount(CollectionUtils.isEmpty(details) ? 0 : details.size()); - } else { - userLikeGroupVO.setSketchCount(0); - } -// if (userLikeGroupVO.getOriginal() == 0) { -// userLikeGroupVO.setOriginalAccountName(accountMapper.selectById(userLikeGroupVO.getOriginalAccountId()).getUserName()); -// Portfolio byId = portfolioMapper.getByIdAll(userLikeGroupVO.getOriginalPortfolioId()); -// if (Objects.nonNull(byId)) { -// String portfolioName = byId.getPortfolioName(); -// userLikeGroupVO.setOriginalPortfolioName(portfolioName); -// } -// } - projectVO.setUserLikeGroupVO(userLikeGroupVO); - } - return projectVO; - } - return null; - }); - return convert; - } - - - @Override - public ModuleChooseVO getModuleContent(ProjectDTO projectDTO) { - ModuleChooseVO moduleChooseVO = new ModuleChooseVO(); - moduleChooseVO.setProjectId(projectDTO.getId()); -// UserLikeCollectionVO userLikeCollectionVO = new UserLikeCollectionVO(); - LambdaQueryWrapper projectLambdaQueryWrapper = new LambdaQueryWrapper<>(); - projectLambdaQueryWrapper.select(Project::getAccountId).eq(Project::getId, projectDTO.getId()); - Project project = projectService.getOne(projectLambdaQueryWrapper); - - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - // 判空处理 - if (project != null && project.getAccountId() != null) { - queryWrapper.eq(CollectionElement::getAccountId, project.getAccountId()); - } - queryWrapper.eq(CollectionElement::getProjectId, projectDTO.getId()); - - List allCollectionElements = collectionElementMapper.selectList(queryWrapper); - - for (String module : projectDTO.getModuleList()) { - if (module.equals(Module.colorBoard.name())) { - List collectionElements = allCollectionElements.stream() - .filter(element -> CollectionLevel1TypeEnum.COLOR_BOARD.getRealName().equals(element.getLevel1Type())) - .collect(Collectors.toList()); - moduleChooseVO.setColorBoard(collectionService.resolveColorBoard(collectionElements)); - } else if (module.equals(Module.moodBoard.name())) { - MoodBoardModuleChooseVO moodBoardModuleChooseVO = new MoodBoardModuleChooseVO(); - - List collectionElements = allCollectionElements.stream() - .filter(element -> CollectionLevel1TypeEnum.MOOD_BOARD.getRealName().equals(element.getLevel1Type())) - .collect(Collectors.toList()); - - List list = new ArrayList<>(); - for (CollectionElement collectionElement : collectionElements) { - if (null != collectionElement.getIsCompositeImage() && collectionElement.getIsCompositeImage() == 1) { - moodBoardModuleChooseVO.setMoodTemplateId(String.valueOf(collectionElement.getId())); - moodBoardModuleChooseVO.setMoodTemplateName(collectionElement.getName()); - moodBoardModuleChooseVO.setMoodTemplateUrl(getMinioUrl(collectionElement.getUrl())); - - String moodboardPositionString = collectionService.getMoodboardPositionString(collectionElement.getId()); - if (!StringUtils.isEmpty(moodboardPositionString)) { - moodBoardModuleChooseVO.setMoodboardPosition(moodboardPositionString); - } - continue; - } - CollectionElementVO collectionElementVO = CopyUtil.copyObject(collectionElement, CollectionElementVO.class); - collectionElementVO.setDesignType(DesignTypeEnum.COLLECTION.getRealName()); - String url = collectionElement.getUrl(); - collectionElementVO.setOriginalUrl(url); - if (minioUtil.doesObjectExist(url)) { - collectionElementVO.setUrl(getMinioUrl(url)); - } - if (minioUtil.doesObjectExist(collectionElementVO.getOriginalUrl())) { - list.add(collectionElementVO); - } - } - moodBoardModuleChooseVO.setMoodBoards(list); - moduleChooseVO.setMoodBoard(moodBoardModuleChooseVO); - } else if (module.equals(Module.printBoard.name())) { - - List collectionElements = allCollectionElements.stream() - .filter(element -> CollectionLevel1TypeEnum.PRINT_BOARD.getRealName().equals(element.getLevel1Type())) - .collect(Collectors.toList()); - List list = new ArrayList<>(); - - for (CollectionElement collectionElement : collectionElements) { - CollectionElementVO collectionElementVO = CopyUtil.copyObject(collectionElement, CollectionElementVO.class); - collectionElementVO.setIsPin(collectionElement.getHasPin()); - collectionElementVO.setDesignType(DesignTypeEnum.COLLECTION.getRealName()); - String url = collectionElement.getUrl(); - collectionElementVO.setOriginalUrl(url); - if (minioUtil.doesObjectExist(url)) { - collectionElementVO.setUrl(getMinioUrl(url)); - } - if (minioUtil.doesObjectExist(collectionElementVO.getOriginalUrl())) { - list.add(collectionElementVO); - } - } - moduleChooseVO.setPrintBoard(list); - } else if (module.equals(Module.sketchBoard.name())) { - - List collectionElements = allCollectionElements.stream() - .filter(element -> CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName().equals(element.getLevel1Type())) - .collect(Collectors.toList()); - List list = new ArrayList<>(); - - for (CollectionElement collectionElement : collectionElements) { - CollectionElementVO collectionElementVO = CopyUtil.copyObject(collectionElement, CollectionElementVO.class); - collectionElementVO.setIsPin(collectionElement.getHasPin()); - collectionElementVO.setDesignType(DesignTypeEnum.COLLECTION.getRealName()); - String url = collectionElement.getUrl(); - collectionElementVO.setOriginalUrl(url); - if (minioUtil.doesObjectExist(url)) { - collectionElementVO.setUrl(getMinioUrl(url)); - if (url.contains(".")) { - String[] split = url.split("\\."); - collectionElementVO.setUrlWithWhiteSide(getMinioUrl(split[0] + "-show." + split[1])); - } else { - collectionElementVO.setUrlWithWhiteSide(getMinioUrl(url + "-show")); - } - } - if (minioUtil.doesObjectExist(collectionElementVO.getOriginalUrl())) { - list.add(collectionElementVO); - } - } - List voList = new ArrayList<>(); - for (CollectionElement collectionElement : collectionElements) { - CollectionSketchVO vo = CopyUtil.copyObject(collectionElement, CollectionSketchVO.class); - String url = collectionElement.getUrl(); - if (url.contains(".")) { - String[] split = url.split("\\."); - vo.setUrlWithWhiteSide(getMinioUrl(split[0] + "-show." + split[1], true)); - } else { - vo.setUrlWithWhiteSide(getMinioUrl(url + "-show", true)); - } - vo.setIsPin(collectionElement.getHasPin()); - vo.setLevel2Type(collectionElement.getLevel2Type()); - vo.setDesignType("Collection"); - vo.setSketchBoardId(collectionElement.getId()); - voList.add(vo); - } - voList.sort(Comparator.comparing(CollectionSketchVO::getSketchBoardId)); - moduleChooseVO.setBoundingBox(voList); - moduleChooseVO.setSketchBoard(list); - } else if (module.equals(Module.design.name())) { - DesignModuleChooseVO vo = new DesignModuleChooseVO(); - QueryWrapper userLikeSortQueryWrapper = new QueryWrapper<>(); - userLikeSortQueryWrapper.lambda().eq(CollectionSort::getProjectId, projectDTO.getId()); - userLikeSortQueryWrapper.lambda().isNull(CollectionSort::getParentId); - userLikeSortQueryWrapper.lambda().eq(CollectionSort::getRelationType, CollectionType.DESIGN.getValue()); - userLikeSortQueryWrapper.lambda().orderByAsc(CollectionSort::getSort); - List userLikeSortList = collectionSortMapper.selectList(userLikeSortQueryWrapper); - - if (CollectionUtils.isEmpty(userLikeSortList)) { - moduleChooseVO.setDesign(vo); - } else { - List list = new ArrayList<>(); - - for (CollectionSort collectionSort : userLikeSortList) { - UserLike userLike = userLikeMapper.selectById(collectionSort.getRelationId()); - UserLikeVO o = CopyUtil.copyObject(userLike, UserLikeVO.class); - TDesignPythonOutfit tDesignPythonOutfit1 = designPythonOutfitMapper.selectById(o.getDesignOutfitId()); - o.setUrl(tDesignPythonOutfit1.getDesignUrl()); - if (o.getUrl().contains("/")) { - int index = o.getUrl().lastIndexOf("/"); - o.setPictureName(o.getUrl().substring(index + 1)); - } - o.setDesignOutfitUrl(getMinioUrl(o.getUrl())); - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(TDesignPythonOutfit::getDesignItemId, o.getDesignItemId()); - List tDesignPythonOutfits = designPythonOutfitMapper.selectList(qw); - if (CollectionUtil.isNotEmpty(tDesignPythonOutfits)) { - TDesignPythonOutfit tDesignPythonOutfit = tDesignPythonOutfits.get(0); - o.setDesignOutfitId(tDesignPythonOutfit.getId()); - } - - o.setSort(collectionSort.getSort()); - o.setUserLikeSortId(collectionSort.getId()); - o.setRelationType(collectionSort.getRelationType()); - o.setCollectionType(CollectionType.DESIGN.getValue()); - o.setResultType(CollectionType.DESIGN.getValue()); - QueryWrapper childCollectionQw = new QueryWrapper<>(); - childCollectionQw.lambda().eq(CollectionSort::getParentId, collectionSort.getId()); - childCollectionQw.lambda().orderByAsc(CollectionSort::getSort); - List childSortList = collectionSortMapper.selectList(childCollectionQw); - List childList = new ArrayList<>(); - // 收集需要删除的失败记录ID,用于后续统一清理并重新排序 - List failedSortIds = new ArrayList<>(); - for (CollectionSort userLikeSort : childSortList) { - if (userLikeSort.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue())) { - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); - if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { - failedSortIds.add(userLikeSort.getId()); - log.info("【获取内容】TO_PRODUCT_IMAGE结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId()); - continue; - } - toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl())); - ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class); - - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); - if (Objects.isNull(toProductImageRecord)) { - log.warn("toProductRecord不存在,projectId:{}, toProductImageResultId:{}", projectDTO.getId(), toProductImageResult.getId()); - continue; - } - toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt()); - - if (toProductImageResultVO.getElementType().equals("ProductElement")) { - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl())); - } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl())); - } else { - ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl())); - } - toProductImageResultVO.setCollectionType(CollectionType.TO_PRODUCT_IMAGE.getValue()); - toProductImageResultVO.setSort(userLikeSort.getSort()); - toProductImageResultVO.setUserLikeSortId(userLikeSort.getId()); - toProductImageResultVO.setRelationType(userLikeSort.getRelationType()); - toProductImageResultVO.setParentId(userLikeSort.getParentId()); - childList.add(toProductImageResultVO); - } else if (userLikeSort.getRelationType().equals(CollectionType.RELIGHT.getValue())) { - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); - if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { - failedSortIds.add(userLikeSort.getId()); - log.info("【获取内容】RELIGHT结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId()); - continue; - } - toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl())); - ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class); - - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); - if (Objects.isNull(toProductImageRecord)) { - log.warn("toProductRecord不存在,projectId:{}, toProductImageResultId:{}", projectDTO.getId(), toProductImageResult.getId()); - continue; - } - toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt()); - - if (toProductImageResultVO.getElementType().equals("ProductElement")) { - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl())); - } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl())); - } else { - ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl())); - } - toProductImageResultVO.setCollectionType(CollectionType.RELIGHT.getValue()); - toProductImageResultVO.setSort(userLikeSort.getSort()); - toProductImageResultVO.setUserLikeSortId(userLikeSort.getId()); - toProductImageResultVO.setRelationType(userLikeSort.getRelationType()); - toProductImageResultVO.setParentId(userLikeSort.getParentId()); - childList.add(toProductImageResultVO); - } else if (userLikeSort.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) { - PoseTransformation item = poseTransformationMapper.selectById(userLikeSort.getRelationId()); - if (isGenerateTaskFailed(item.getTaskStatus(), item.getCreateTime())) { - failedSortIds.add(userLikeSort.getId()); - log.info("【获取内容】POSE_TRANSFORM结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId()); - continue; - } - PoseTransformationVO poseTransformationVO = new PoseTransformationVO(); - poseTransformationVO.setId(item.getId()); - poseTransformationVO.setTaskId(item.getUniqueId()); - poseTransformationVO.setProductImage(getMinioUrl(item.getProductImage())); - poseTransformationVO.setLastFrameProductImage(getMinioUrl(item.getLastFrameProductImage())); - poseTransformationVO.setPrompt(item.getPrompt()); - poseTransformationVO.setGifUrl(getMinioUrl(item.getGifUrl())); - poseTransformationVO.setVideoUrl(getMinioUrl(item.getVideoUrl())); - poseTransformationVO.setFirstFrameUrl(getMinioUrl(item.getFirstFrameUrl())); - poseTransformationVO.setIsLiked(item.getIsLiked()); - poseTransformationVO.setCollectionType(CollectionType.POSE_TRANSFORM.getValue()); - poseTransformationVO.setSort(userLikeSort.getSort()); - poseTransformationVO.setUserLikeSortId(userLikeSort.getId()); - poseTransformationVO.setRelationType(userLikeSort.getRelationType()); - poseTransformationVO.setResultType(CollectionType.POSE_TRANSFORM.getValue()); - poseTransformationVO.setParentId(userLikeSort.getParentId()); - poseTransformationVO.setModelName(item.getModelName()); - poseTransformationVO.setPoseId(item.getPoseId()); - poseTransformationVO.setStatus(item.getTaskStatus()); - childList.add(poseTransformationVO); - } - } - // 统一处理失败的记录:从collection_sort表中删除失败的记录,并重新排序 - if (CollectionUtil.isNotEmpty(failedSortIds)) { - Long parentId = collectionSort.getId(); - Long projectId = projectDTO.getId(); - log.info("【获取内容】检测到{}条失败记录需要清理,parentId={}, projectId={}", failedSortIds.size(), parentId, projectId); - for (Long failedSortId : failedSortIds) { - CollectionSort failedRecord = collectionSortMapper.selectById(failedSortId); - if (failedRecord != null) { - String relationType = failedRecord.getRelationType(); - Long relationId = failedRecord.getRelationId(); - collectionSortService.deleteCollectionSort(relationId, relationType, projectId, parentId); - log.info("【获取内容】已删除失败记录,relationId={}, relationType={}", relationId, relationType); - } - } - // 重新查询子列表,获取更新后的排序 - childSortList = collectionSortMapper.selectList(childCollectionQw); - // 重新构建childList,使用更新后的sort值 - childList = new ArrayList<>(); - for (CollectionSort userLikeSort : childSortList) { - if (userLikeSort.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue())) { - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); - if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { - continue; - } - toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl())); - ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class); - - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); - if (Objects.isNull(toProductImageRecord)) { - continue; - } - toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt()); - - if (toProductImageResultVO.getElementType().equals("ProductElement")) { - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl())); - } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl())); - } else { - ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl())); - } - toProductImageResultVO.setCollectionType(CollectionType.TO_PRODUCT_IMAGE.getValue()); - toProductImageResultVO.setSort(userLikeSort.getSort()); - toProductImageResultVO.setUserLikeSortId(userLikeSort.getId()); - toProductImageResultVO.setRelationType(userLikeSort.getRelationType()); - toProductImageResultVO.setParentId(userLikeSort.getParentId()); - childList.add(toProductImageResultVO); - } else if (userLikeSort.getRelationType().equals(CollectionType.RELIGHT.getValue())) { - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); - if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { - continue; - } - toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl())); - ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class); - - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); - if (Objects.isNull(toProductImageRecord)) { - continue; - } - toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt()); - - if (toProductImageResultVO.getElementType().equals("ProductElement")) { - ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl())); - } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { - TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl())); - } else { - ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); - toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl())); - } - toProductImageResultVO.setCollectionType(CollectionType.RELIGHT.getValue()); - toProductImageResultVO.setSort(userLikeSort.getSort()); - toProductImageResultVO.setUserLikeSortId(userLikeSort.getId()); - toProductImageResultVO.setRelationType(userLikeSort.getRelationType()); - toProductImageResultVO.setParentId(userLikeSort.getParentId()); - childList.add(toProductImageResultVO); - } else if (userLikeSort.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) { - PoseTransformation item = poseTransformationMapper.selectById(userLikeSort.getRelationId()); - if (isGenerateTaskFailed(item.getTaskStatus(), item.getCreateTime())) { - continue; - } - PoseTransformationVO poseTransformationVO = new PoseTransformationVO(); - poseTransformationVO.setId(item.getId()); - poseTransformationVO.setTaskId(item.getUniqueId()); - poseTransformationVO.setProductImage(getMinioUrl(item.getProductImage())); - poseTransformationVO.setLastFrameProductImage(getMinioUrl(item.getLastFrameProductImage())); - poseTransformationVO.setPrompt(item.getPrompt()); - poseTransformationVO.setGifUrl(getMinioUrl(item.getGifUrl())); - poseTransformationVO.setVideoUrl(getMinioUrl(item.getVideoUrl())); - poseTransformationVO.setFirstFrameUrl(getMinioUrl(item.getFirstFrameUrl())); - poseTransformationVO.setIsLiked(item.getIsLiked()); - poseTransformationVO.setCollectionType(CollectionType.POSE_TRANSFORM.getValue()); - poseTransformationVO.setSort(userLikeSort.getSort()); - poseTransformationVO.setUserLikeSortId(userLikeSort.getId()); - poseTransformationVO.setRelationType(userLikeSort.getRelationType()); - poseTransformationVO.setResultType(CollectionType.POSE_TRANSFORM.getValue()); - poseTransformationVO.setParentId(userLikeSort.getParentId()); - poseTransformationVO.setModelName(item.getModelName()); - poseTransformationVO.setPoseId(item.getPoseId()); - poseTransformationVO.setStatus(item.getTaskStatus()); - childList.add(poseTransformationVO); - } - } - log.info("【获取内容】失败记录清理完成,重新排序后childList.size={}", childList.size()); - } - o.setChildList(childList); - - list.add(o); - } - vo.setUserLikeDetails(list); - } - - UserLikeGroup group = getByProjectId(projectDTO.getId()); - if (Objects.nonNull(group)) { - Long userGroupId = group.getId(); - vo.setUserGroupId(userGroupId); - } - moduleChooseVO.setDesign(vo); - } else if (module.equals(Module.canvas.name())) { - CavasModuleChooseVO vo = new CavasModuleChooseVO(); - - UserLikeGroup userLikeGroup = getByProjectId(projectDTO.getId()); - - Integer beenPublished = 0; - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(Portfolio::getUserLikeGroupSourceId, userLikeGroup.getId()); - List portfolios = portfolioMapper.selectList(qw); - - PortfolioDTO portfolioDTO = new PortfolioDTO(); - if (CollectionUtil.isNotEmpty(portfolios)) { - - portfolioDTO = CopyUtil.copyObject(portfolios.get(0), PortfolioDTO.class); - beenPublished = 1; - portfolioDTO.setTagsDTO(tagsMapper.getTagByPortfolioId(portfolioDTO.getId())); - } - vo.setBeenPublished(beenPublished); - vo.setPortfolioDTO(portfolioDTO); - moduleChooseVO.setCanvas(vo); - } else if (module.equals(Module.toProduct.name()) || module.equals(Module.relight.name())) { - Long projectId = projectDTO.getId(); - String resultType = module.equals(Module.toProduct.name()) ? "ToProductImage" : "Relight"; - - // 查询所有结果(包括喜欢和不喜欢的) - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda() - .eq(ToProductImageResult::getProjectId, projectId) - .eq(ToProductImageResult::getResultType, resultType); - - List allResults = toProductImageResultMapper.selectList(qw); - - // 准备返回对象 - ToProductOrRelightVO resultVO = new ToProductOrRelightVO(); - - // 处理URL转换和分类 - List likedList = new ArrayList<>(); - List normalList = new ArrayList<>(); - - for (ToProductImageResult result : allResults) { - // 转换URL - result.setUrl(getMinioUrl(result.getUrl())); - // 复制到VO对象 - ToProductImageResultVO vo = CopyUtil.copyObject(result, ToProductImageResultVO.class); - // 设置sourceUrl - setSourceUrl(vo); - // 设置prompt - ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(result.getToProductImageRecordId()); - if (Objects.nonNull(toProductImageRecord)) { - vo.setPrompt(toProductImageRecord.getPrompt()); - } - vo.setParentId(toProductImageResultService.getUnlikedResultParentId(result, null)); - // 按isLike分类 - if (result.getIsLike() != null && result.getIsLike() == 1) { - likedList.add(vo); - } else { - normalList.add(vo); - } - } - // 设置结果 - resultVO.setLikedList(likedList); - resultVO.setList(normalList); - - // 根据模块设置返回结果 - if (module.equals(Module.toProduct.name())) { - moduleChooseVO.setToProduct(resultVO); - } else { - moduleChooseVO.setRelight(resultVO); - } - } else if (module.equals(Module.deReconstruction.name())) { - SketchReconstructionVO sketchReconstruction = generateService.getSketchReconstruction(projectDTO.getId()); - moduleChooseVO.setDeReconstruction(sketchReconstruction); - } else if (module.equals(Module.poseTransfer.name())) { - List likedList = generateService.getPoseTransformationResult(null, projectDTO.getId(), true); - List list = generateService.getPoseTransformationResult(null, projectDTO.getId(), false); - PoseTransferVO vo = new PoseTransferVO(); - vo.setLikedList(likedList); - vo.setList(list); - moduleChooseVO.setPoseTransfer(vo); - } else if (module.equals(Module.patternMaking3D.name())) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ThreeDModule::getProjectId, projectDTO.getId()); - List threeDModules = threeDModuleMapper.selectList(qw); - if (CollectionUtil.isNotEmpty(threeDModules)) { - ThreeDModule threeDModule = threeDModules.get(0); - if (null != threeDModule.getThreeDSimpleId()) { - ThreeDModuleVO threeDModuleVO = CopyUtil.copyObject(threeDModule, ThreeDModuleVO.class); - if (null != threeDModule.getCollectionElementId()) { - CollectionElement collectionElement = collectionElementMapper.selectById(threeDModule.getCollectionElementId()); - if (Objects.nonNull(collectionElement)) { - threeDModuleVO.setPrintMinioUrl(getMinioUrl(collectionElement.getUrl())); - } - } -// if (!StringUtils.isEmpty(threeDModuleVO.getPrintMinioUrl())) { -// threeDModuleVO.setPrintMinioUrl(minioUtil.getPreSignedUrl(threeDModuleVO.getPrintMinioUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); -// } - moduleChooseVO.setPatternMaking3D(threeDModuleVO); - } - } - } else if (module.equals(Module.mannequin.name())) { - List collectionElements = allCollectionElements.stream() - .filter(element -> CollectionLevel1TypeEnum.MODEL.getRealName().equals(element.getLevel1Type())) - .collect(Collectors.toList()); - List list = new ArrayList<>(); - if (CollectionUtil.isNotEmpty(collectionElements)) { - for (CollectionElement collectionElement : collectionElements) { - CollectionElementVO collectionElementVO = CopyUtil.copyObject(collectionElement, CollectionElementVO.class); - CollectionElementRelModel relModel = getCollectionElementRelModel(collectionElementVO.getId()); - collectionElementVO.setUrl(getMinioUrl(collectionElementVO.getUrl())); - collectionElementVO.setMannequinRelationId(relModel.getRelationId()); - collectionElementVO.setMannequinRelationType(relModel.getRelationType()); - collectionElementVO.setCollectionId(collectionElement.getId()); - list.add(collectionElementVO); - } - } - moduleChooseVO.setMannequin(list); - } else if (module.equals(Module.uploadElement.name())) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ToProductElement::getProjectId, projectDTO.getId()); - List toProductElements = toProductElementMapper.selectList(qw); - for (ToProductElement toProductElement : toProductElements) { - toProductElement.setUrl(getMinioUrl(toProductElement.getUrl())); - } - moduleChooseVO.setUploadElement(toProductElements); - } - } - return moduleChooseVO; - } - - private String getMinioUrl(String minioPath) { - if (!StringUtil.isNullOrEmpty(minioPath)) { - return minioUtil.getPreSignedUrl(minioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); - } - return null; - } - - private String getMinioUrl(String minioPath, boolean resetCatch) { - if (!StringUtil.isNullOrEmpty(minioPath)) { - return minioUtil.getPreSignedUrl(minioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME, resetCatch); - } - return null; - } - - // 提取出的公共方法 - private void setSourceUrl(ToProductImageResultVO vo) { - if (vo.getElementType().equals("ProductElement")) { - ToProductElement element = toProductElementMapper.selectById(vo.getElementId()); - vo.setSourceUrl(getMinioUrl(element.getUrl())); - } else if (vo.getElementType().equals("DesignOutfit")) { - TDesignPythonOutfit outfit = designPythonOutfitMapper.selectById(vo.getElementId()); - vo.setSourceUrl(getMinioUrl(outfit.getDesignUrl())); - } else { - ToProductImageResult result = toProductImageResultMapper.selectById(vo.getElementId()); - vo.setSourceUrl(getMinioUrl(result.getUrl())); - } - } - - private CollectionElementRelModel getCollectionElementRelModel(Long id) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(CollectionElementRelModel::getCollectionElementId, id); - CollectionElementRelModel collectionElementRelModel = collectionElementRelModelMapper.selectOne(qw); - return collectionElementRelModel; - } - - private boolean isGenerateTaskFailed(String taskStatus, LocalDateTime createTime) { - // 1. 先判断TaskStatus字段是否有值;若有值且为Fail,则失败 - if (!StringUtil.isNullOrEmpty(taskStatus)) { - return "Fail".equals(taskStatus); - } - // 2. 若taskStatus无值,判断记录创建时间距离现在是否超过1小时 - if (createTime == null) { - // 如果创建时间为null,视为失败(根据业务需求决定) - return true; - } - // 计算当前时间与创建时间的差值 - Duration duration = Duration.between(createTime, LocalDateTime.now()); - // 判断是否超过1小时(3600秒) - return duration.toHours() >= 1; - } - - - @Override - @Transactional - public ModuleChooseVO saveModuleContent(ModuleSaveDTO moduleSaveDTO) { - ModuleChooseVO result = new ModuleChooseVO(); - Long accountId = UserContext.getUserHolder().getId(); - Long projectId = moduleSaveDTO.getProjectId(); - Project project = projectService.getById(projectId); - - boolean boundingBox = false; - if (Objects.nonNull(moduleSaveDTO.getMoodBoard())) { - MoodBoardModuleSaveDTO moodBoard = moduleSaveDTO.getMoodBoard(); - if (moodBoard.getMoodTemplateId() != null) { - // moodboard合成图存储 - CollectionElement compositeImage = collectionElementMapper.selectById(moodBoard.getMoodTemplateId()); - if (compositeImage.getProjectId() == null) { - compositeImage.setProjectId(moduleSaveDTO.getProjectId()); - compositeImage.setIsCompositeImage(1); - collectionElementMapper.updateById(compositeImage); - if (!StringUtils.isEmpty(moodBoard.getMoodboardPosition())) { - // 合成图位置信息通过collectElementId关联(旧逻辑通过collectionId关联) - moodboardPositionService.parseMoodboardPosition(moodBoard.getMoodboardPosition(), compositeImage.getId()); - } - } - } - List moodBoards = moodBoard.getMoodBoards(); - if (Objects.nonNull(moodBoards)) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(CollectionElement::getProjectId, projectId); - qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.MOOD_BOARD.getRealName()); - if (moodBoard.getMoodTemplateId() != null) { - qw.lambda().ne(CollectionElement::getId, moodBoard.getMoodTemplateId()); - } -// qw.lambda().ne(CollectionElement::getCollectionId, 0); - List collectionElements = collectionElementMapper.selectList(qw); - Set old = collectionElements.stream().map(CollectionElement::getId).collect(Collectors.toSet()); - - for (DesignCollectionElementDTO board : moodBoards) { - if (board.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName())) { - Library library = libraryMapper.selectById(board.getId()); - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MOOD_BOARD.getRealName()); - collectionElement.setName(library.getName()); - collectionElement.setUrl(library.getUrl()); - collectionElement.setHasPin((byte) 0); - collectionElement.setMd5(library.getMd5()); - collectionElement.setCreateDate(new Date()); - collectionElementMapper.insert(collectionElement); - } else if (board.getDesignType().equals(DesignTypeEnum.GENERATE.getRealName())) { - GenerateDetail generateDetail = generateDetailMapper.selectById(board.getId()); - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MOOD_BOARD.getRealName()); -// collectionElement.setName(generateDetail.get()); - collectionElement.setUrl(generateDetail.getUrl()); - collectionElement.setHasPin((byte) 0); - collectionElement.setMd5(generateDetail.getMd5()); - collectionElement.setCreateDate(new Date()); - collectionElementMapper.insert(collectionElement); - } else { - if (old.contains(board.getId())) { - old.remove(board.getId()); - } else { - CollectionElement collectionElement = collectionElementMapper.selectById(board.getId()); - collectionElement.setProjectId(projectId); - collectionElementMapper.updateById(collectionElement); - } - } - } - if (!CollectionUtils.isEmpty(old)) { - collectionElementMapper.deleteBatchIds(old); - } - } - } - if (Objects.nonNull(moduleSaveDTO.getPrintBoard())) { - List printBoards = moduleSaveDTO.getPrintBoard(); - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(CollectionElement::getProjectId, projectId); - qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.PRINT_BOARD.getRealName()); - List collectionElements = collectionElementMapper.selectList(qw); - Set old = collectionElements.stream().map(CollectionElement::getId).collect(Collectors.toSet()); - - for (DesignCollectionPrintElementDTO board : printBoards) { - if (board.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName())) { - Library library = libraryMapper.selectById(board.getId()); - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.PRINT_BOARD.getRealName()); - collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setName(library.getName()); - collectionElement.setUrl(library.getUrl()); - collectionElement.setHasPin(board.getIsPin()); - collectionElement.setMd5(library.getMd5()); - collectionElement.setCreateDate(new Date()); - collectionElementMapper.insert(collectionElement); - } else if (board.getDesignType().equals(DesignTypeEnum.GENERATE.getRealName())) { - GenerateDetail generateDetail = generateDetailMapper.selectById(board.getId()); - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.PRINT_BOARD.getRealName()); - collectionElement.setLevel2Type(board.getLevel2Type()); -// collectionElement.setName(generateDetail.get()); - collectionElement.setUrl(generateDetail.getUrl()); - collectionElement.setHasPin(board.getIsPin()); - collectionElement.setMd5(generateDetail.getMd5()); - collectionElement.setCreateDate(new Date()); - collectionElementMapper.insert(collectionElement); - } else { - if (old.contains(board.getId())) { - CollectionElement collectionElement = collectionElementMapper.selectById(board.getId()); - collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setHasPin(board.getIsPin()); - collectionElement.setUpdateDate(new Date()); - collectionElementMapper.updateById(collectionElement); - old.remove(board.getId()); - } else { - CollectionElement collectionElement = collectionElementMapper.selectById(board.getId()); - collectionElement.setProjectId(projectId); - collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setHasPin(board.getIsPin()); - collectionElement.setUpdateDate(new Date()); - collectionElementMapper.updateById(collectionElement); - } - } - } - if (!CollectionUtils.isEmpty(old)) { - collectionElementMapper.deleteBatchIds(old); - } - } - if (Objects.nonNull(moduleSaveDTO.getColorBoard())) { - List colorBoards = moduleSaveDTO.getColorBoard(); - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(CollectionElement::getProjectId, projectId); - qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.COLOR_BOARD.getRealName()); - List collectionElements = collectionElementMapper.selectList(qw); - Set old = collectionElements.stream().map(CollectionElement::getId).collect(Collectors.toSet()); - - for (CollectionColorDTO board : colorBoards) { - if (Objects.nonNull(board.getId()) && old.contains(Long.valueOf(board.getId()))) { - // ??? - old.remove(Long.valueOf(board.getId())); - } else { - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.COLOR_BOARD.getRealName()); - collectionElement.setName(board.getName()); - collectionElement.setHasPin((byte) 0); - collectionElement.setColorRgb(board.getRgbValue()); - collectionElement.setMd5("0"); - // 渐变色 - if (!Objects.isNull(board.getGradient()) && !StringUtil.isNullOrEmpty(board.getGradient().getColorImg())) { - board.getGradient().setColorImg(null); - } - collectionElement.setGradientString(JSON.toJSONString(board.getGradient())); - collectionElement.setCreateDate(new Date()); - collectionElementMapper.insert(collectionElement); - } - } - if (!CollectionUtils.isEmpty(old)) { - collectionElementMapper.deleteBatchIds(old); - } - } - if (Objects.nonNull(moduleSaveDTO.getSketchBoard())) { - boundingBox = true; - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(CollectionElement::getProjectId, projectId); - qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName()); - List collectionElements = collectionElementMapper.selectList(qw); - Set old = collectionElements.stream().map(CollectionElement::getId).collect(Collectors.toSet()); - List sketchBoards = moduleSaveDTO.getSketchBoard(); - for (CollectionSketchDTO board : sketchBoards) { - if (board.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName())) { - Library library = libraryMapper.selectById(board.getSketchBoardId()); - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName()); - collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setLevel3Type(workspaceService.getProjectSexById(projectId)); - collectionElement.setName(library.getName()); - collectionElement.setUrl(library.getUrl()); - collectionElement.setHasPin(board.getIsPin()); - collectionElement.setMd5(library.getMd5()); - collectionElement.setCreateDate(new Date()); - collectionElementMapper.insert(collectionElement); - } else if (board.getDesignType().equals(DesignTypeEnum.GENERATE.getRealName())) { - GenerateDetail generateDetail = generateDetailMapper.selectById(board.getSketchBoardId()); - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName()); - collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setLevel3Type(workspaceService.getProjectSexById(projectId)); -// collectionElement.setName(generateDetail.get()); - collectionElement.setUrl(generateDetail.getUrl()); - collectionElement.setHasPin(board.getIsPin()); - collectionElement.setMd5(generateDetail.getMd5()); - collectionElement.setCreateDate(new Date()); - collectionElementMapper.insert(collectionElement); - } else { - if (old.contains(board.getSketchBoardId())) { - CollectionElement collectionElement = collectionElementMapper.selectById(board.getSketchBoardId()); - collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setHasPin(board.getIsPin()); - collectionElement.setUpdateDate(new Date()); - collectionElementMapper.updateById(collectionElement); - old.remove(board.getSketchBoardId()); - } else { - CollectionElement collectionElement = collectionElementMapper.selectById(board.getSketchBoardId()); - collectionElement.setProjectId(projectId); - collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setHasPin(board.getIsPin()); - collectionElement.setUpdateDate(new Date()); - if (CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName().equals(collectionElement.getLevel1Type())) { - collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId())); - } - collectionElementMapper.updateById(collectionElement); - } - } - } - if (!CollectionUtils.isEmpty(old)) { - collectionElementMapper.deleteBatchIds(old); - } - } - if (Objects.nonNull(moduleSaveDTO.getPatternMaking3D())) { - PatternMaking3DDTO patternMaking3D = moduleSaveDTO.getPatternMaking3D(); - - QueryWrapper threeDModuleQueryWrapper = new QueryWrapper<>(); - threeDModuleQueryWrapper.lambda().eq(ThreeDModule::getProjectId, projectId); - List threeDModuleList = threeDModuleMapper.selectList(threeDModuleQueryWrapper); - - if (CollectionUtils.isEmpty(threeDModuleList)) { - ThreeDModule threeDModule = new ThreeDModule(); - threeDModule.setProjectId(projectId); - threeDModule.setThreeDSimpleId(patternMaking3D.getThreeDSimpleId()); - threeDModule.setX(patternMaking3D.getX()); - threeDModule.setY(patternMaking3D.getY()); -// threeDModule.setPrintMinioUrl(patternMaking3D.getPrintMinioUrl()); - threeDModule.setCollectionElementId(patternMaking3D.getCollectionElementId()); - threeDModuleMapper.insert(threeDModule); - } else { - ThreeDModule threeDModule = threeDModuleList.get(0); -// if (!Objects.equals(patternMaking3D.getThreeDSimpleId(), threeDModule.getThreeDSimpleId())) { -// -// } - threeDModule.setThreeDSimpleId(patternMaking3D.getThreeDSimpleId()); - threeDModule.setX(patternMaking3D.getX()); - threeDModule.setY(patternMaking3D.getY()); -// threeDModule.setPrintMinioUrl(patternMaking3D.getPrintMinioUrl()); - threeDModule.setCollectionElementId(patternMaking3D.getCollectionElementId()); - threeDModuleMapper.updateById(threeDModule); - } - } - if (CollectionUtil.isNotEmpty(moduleSaveDTO.getMannequin())) { - // 目前已有的模特 - List collectionElementRelModels = collectionElementMapper.selectByProject(projectId); - // 入参中的模特 - List mannequin = moduleSaveDTO.getMannequin(); - - // 新增的模特只有id,没有collectionElementId - List inputMannequinIds = mannequin.stream().map(MannequinDTO::getId).collect(Collectors.toList()); - // 既有id又有collectionElementId的,为保持原状的模特(都没有的且又存在于数据库的,即为被删除的模特) - List inputCollectionElementIds = mannequin.stream().map(MannequinDTO::getCollectionElementId).collect(Collectors.toList()); - - // 创建relationId到Model的映射 - Map relationIdToModelMap = collectionElementRelModels.stream() - .collect(Collectors.toMap( - CollectionElementRelModel::getRelationId, - java.util.function.Function.identity(), - (existing, replacement) -> existing - )); - // 创建collectionElementId到Model的映射 - Map collectionElementToModelMap = collectionElementRelModels.stream() - .collect(Collectors.toMap( - CollectionElementRelModel::getCollectionElementId, - java.util.function.Function.identity(), - (existing, replacement) -> existing - )); - List newReletionIds = new ArrayList<>(); - List toBeDeletedCollectionElementIds = new ArrayList<>(); - - if (collectionElementRelModels.isEmpty()) { - // 如果原本没有记录,所有输入的Mannequin都是新的 - newReletionIds = inputMannequinIds; - } else { - // 获取db中所有的relationId集合 - Set relationIds = relationIdToModelMap.keySet(); - // 获取db中所有的collectionElementId集合 - Set collectionElementIds = collectionElementToModelMap.keySet(); - - // 1. 找出需要删除的:collectionElementIds中有但inputCollectionElementIds中没有的 - toBeDeletedCollectionElementIds = collectionElementIds.stream() - .filter(id -> !inputCollectionElementIds.contains(id)) - .collect(Collectors.toList()); - - // 2. 找出新增的:inputMannequinId中有但relationIds中没有的(一定程度避免重复) - newReletionIds = inputMannequinIds.stream() - .filter(id -> !relationIds.contains(id)) - .collect(Collectors.toList()); - } - - if (!toBeDeletedCollectionElementIds.isEmpty()) { - /*Set toBeDeletedElementIdList = toBeDeletedCollectionElementIds.stream() - .map(relationIdToModelMap::get) // 获取对应的Model - .filter(Objects::nonNull) // 过滤掉可能为null的情况 - .map(CollectionElementRelModel::getCollectionElementId) // 提取collectionElementId - .collect(Collectors.toSet());*/ - collectionElementMapper.deleteBatchIds(toBeDeletedCollectionElementIds); - // 删除关联关系 - deleteByCollectionElementIdList(toBeDeletedCollectionElementIds); - } - - for (MannequinDTO dto : mannequin) { - if (newReletionIds.isEmpty()) { - break; - } else if (!newReletionIds.contains(dto.getId())) { - continue; - } - if (dto.getType().equals("System")) { - SysFile sysFile = sysFileMapper.selectById(dto.getId()); - - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName()); - collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId())); -// collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setName(sysFile.getName()); - collectionElement.setUrl(sysFile.getUrl()); -// collectionElement.setHasPin(board.getIsPin()); - collectionElement.setMd5(sysFile.getMd5()); - collectionElement.setCreateDate(new Date()); - collectionElement.setHasPin((byte) 0); - collectionElementMapper.insert(collectionElement); - CollectionElementRelModel collectionElementRelModel = new CollectionElementRelModel(); - collectionElementRelModel.setCollectionElementId(collectionElement.getId()); - collectionElementRelModel.setRelationId(dto.getId()); - collectionElementRelModel.setRelationType("System"); - collectionElementRelModelMapper.insert(collectionElementRelModel); - } else if (dto.getType().equals("Library")) { - Library library = libraryMapper.selectById(dto.getId()); - - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setProjectId(projectId); - collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName()); - collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId())); -// collectionElement.setLevel2Type(board.getLevel2Type()); - collectionElement.setName(library.getName()); - collectionElement.setUrl(library.getUrl()); -// collectionElement.setHasPin(board.getIsPin()); - collectionElement.setMd5(library.getMd5()); - collectionElement.setCreateDate(new Date()); - collectionElement.setHasPin((byte) 0); - collectionElementMapper.insert(collectionElement); - CollectionElementRelModel collectionElementRelModel = new CollectionElementRelModel(); - collectionElementRelModel.setCollectionElementId(collectionElement.getId()); - collectionElementRelModel.setRelationId(dto.getId()); - collectionElementRelModel.setRelationType("Library"); - collectionElementRelModelMapper.insert(collectionElementRelModel); - - } - } - } - if (boundingBox) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName()); - qw.lambda().eq(CollectionElement::getProjectId, projectId); - List collectionElements = collectionElementMapper.selectList(qw); - - List voList = new ArrayList<>(); - for (CollectionElement collectionElement : collectionElements) { - CollectionSketchVO vo = CopyUtil.copyObject(collectionElement, CollectionSketchVO.class); - String url = collectionElement.getUrl(); - libraryService.processSketchBoards(url, collectionElement.getLevel2Type()); - if (url.contains(".")) { - String[] split = url.split("\\."); - vo.setUrlWithWhiteSide(minioUtil.getPreSignedUrl(split[0] + "-show." + split[1], 24 * 60, true)); - } else { - vo.setUrlWithWhiteSide(minioUtil.getPreSignedUrl(url + "-show", 24 * 60, true)); - } - vo.setIsPin(collectionElement.getHasPin()); - vo.setLevel2Type(collectionElement.getLevel2Type()); - vo.setDesignType("Collection"); - vo.setSketchBoardId(collectionElement.getId()); - voList.add(vo); - } - voList.sort(Comparator.comparing(CollectionSketchVO::getSketchBoardId)); - result.setBoundingBox(voList); - } - project.setUpdateTime(LocalDateTime.now()); - projectService.updateById(project); - return result; - } - - private void deleteByCollectionElementIdList(java.util.Collection old) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().in(CollectionElementRelModel::getCollectionElementId, old); - collectionElementRelModelMapper.delete(qw); - } - - @Override - public QueryLibraryPageVO getMannequinDetail(MannequinDTO mannequinDTO) { - QueryLibraryPageVO vo = new QueryLibraryPageVO(); - if (mannequinDTO.getType().equals("System")) { - SysFile sysFile = sysFileMapper.selectById(mannequinDTO.getId()); - vo.setDesignType("System"); - vo.setLevel1Type(sysFile.getLevel1Type()); - vo.setLevel2Type(sysFile.getLevel2Type()); - vo.setName(sysFile.getName()); - vo.setMinIOPath(minioUtil.getPreSignedUrl(sysFile.getUrl(), 24 * 60)); - } else { - Library library = libraryMapper.selectById(mannequinDTO.getId()); - vo.setDesignType("Library"); - vo.setLevel1Type(library.getLevel1Type()); - vo.setLevel2Type(library.getLevel2Type()); - vo.setName(library.getName()); - vo.setMinIOPath(minioUtil.getPreSignedUrl(library.getUrl(), 24 * 60)); - } - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(LibraryModelPoint::getRelationId, mannequinDTO.getId()); - qw.lambda().eq(LibraryModelPoint::getModelType, mannequinDTO.getType()); - List libraryModelPoints = libraryModelPointMapper.selectList(qw); - if (CollectionUtil.isEmpty(libraryModelPoints)) { - throw new BusinessException("No model doting information available."); - } - LibraryModelPoint libraryModelPoint = libraryModelPoints.get(0); - LibraryModelPointVO libraryModelPointVO = CopyUtil.copyObject(libraryModelPoint, LibraryModelPointVO.class); - libraryModelPointVO.setTemplateId(libraryModelPoint.getId()); - libraryModelPointVO.setHandLeft(JSON.parseObject(libraryModelPoint.getHandLeft(), List.class)); - libraryModelPointVO.setHandRight(JSON.parseObject(libraryModelPoint.getHandRight(), List.class)); - libraryModelPointVO.setShoulderRight(JSON.parseObject(libraryModelPoint.getShoulderRight(), List.class)); - libraryModelPointVO.setShoulderLeft(JSON.parseObject(libraryModelPoint.getShoulderLeft(), List.class)); - libraryModelPointVO.setWaistbandRight(JSON.parseObject(libraryModelPoint.getWaistbandRight(), List.class)); - libraryModelPointVO.setWaistbandLeft(JSON.parseObject(libraryModelPoint.getWaistbandLeft(), List.class)); - - vo.setLibraryModelPoint(libraryModelPointVO); - return vo; - } - - @Override - public BrandLogoUploadVO brandLogoUpload(MultipartFile file) { - BrandLogoUploadVO vo = new BrandLogoUploadVO(); - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - String path = userHolder.getId().toString() + "/brandLogo"; - vo.setBrandLogo(minioUtil.upload("aida-users", path, file)); - vo.setMinioUrl(minioUtil.getPreSignedUrl(vo.getBrandLogo(), 24 * 60)); - return vo; -// return null; - } - - @Override - public Boolean brandDNASaveOrUpdate(BrandDNADTO brandDNADTO) { - if (brandDNADTO.getId() != null) { - BrandDNA brandDNA = CopyUtil.copyObject(brandDNADTO, BrandDNA.class); - brandDNA.setUpdateTime(LocalDateTime.now()); - brandDNAMapper.updateById(brandDNA); - } else { - BrandDNA brandDNA = CopyUtil.copyObject(brandDNADTO, BrandDNA.class); - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - brandDNA.setAccountId(userHolder.getId()); - brandDNA.setCreateTime(LocalDateTime.now()); - brandDNAMapper.insert(brandDNA); - } - return Boolean.TRUE; - } - - @Override - public LibraryUpdateVo brandDNAUpload(MultipartFile file, Long brandId) throws IOException { - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - String path = userHolder.getId().toString() + "/brandLogo"; - String upload = minioUtil.upload("aida-users", path, file); - Library library = new Library(); - library.setAccountId(userHolder.getId()); - library.setLevel1Type(LibraryLevel1TypeEnum.BRAND_DNA.getRealName()); - library.setName(file.getOriginalFilename()); - library.setUrl(upload); - library.setMd5(MD5Utils.encryptFile(file.getInputStream())); - library.setCreateDate(new Date()); - libraryMapper.insert(library); - - BrandRelLibrary brandRelLibrary = new BrandRelLibrary(); - brandRelLibrary.setLibraryId(library.getId()); - brandRelLibrary.setBrandId(brandId); - brandRelLibraryMapper.insert(brandRelLibrary); - - LibraryUpdateVo vo = CopyUtil.copyObject(library, LibraryUpdateVo.class); - vo.setMinIOPath(minioUtil.getPreSignedUrl(vo.getUrl(), 24 * 60)); - - return vo; - } - - @Override - public PageBaseResponse brandDNAPage(BrandDNAQueryDTO brandDNAQueryDTO) { - AuthPrincipalVo userHolder = UserContext.getUserHolder(); - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(BrandDNA::getAccountId, userHolder.getId()); - IPage page = brandDNAMapper.selectPage(new Page<>(brandDNAQueryDTO.getPage(), brandDNAQueryDTO.getSize()), qw); - IPage convert = page.convert((Function) brand -> { - if (Objects.nonNull(brand)) { - BrandDNAVO brandDNAVO = CopyUtil.copyObject(brand, BrandDNAVO.class); - brandDNAVO.setMinioUrl(minioUtil.getPreSignedUrl(brandDNAVO.getBrandLogo(), 24 * 60)); - return brandDNAVO; - } - return null; - }); - return PageBaseResponse.success(convert); - } - - @Override - public BrandDNAGenerateVO brandDNAGenerate(String prompt) { - BrandDNAGenerateVO vo = new BrandDNAGenerateVO(); - JSONObject jsonObject = pythonService.brandDNAGenerate(prompt); - JSONObject data = jsonObject.getJSONObject("data"); - vo.setBrandSlogan(data.getString("brand_slogan")); - vo.setBrandName(data.getString("brand_name")); - vo.setBrandLogo(data.getString("brand_logo")); - vo.setMinioUrl(minioUtil.getPreSignedUrl(vo.getBrandLogo(), 24 * 60)); - return vo; - } - - @Override - public IPage getThreeDLayoutPage(ThreeDLayoutQueryDTO query) { -// AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); -// Long workspaceServiceByProjectId = workspaceService.getByProjectId(query.getProjectId()); -// Workspace byId = workspaceService.getById(workspaceServiceByProjectId); - // 分页数据 - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.lambda().eq(ThreeDLayout::getType, "front"); - queryWrapper.lambda().eq(ThreeDLayout::getGender, query.getSex().toLowerCase()); - IPage page = threeDLayoutMapper.selectPage( - new Page<>(query.getPage(), query.getSize()), queryWrapper); - if (CollectionUtils.isEmpty(page.getRecords())) { - return new Page<>(); - } - - IPage convert = page.convert((Function) threeDLayout -> { - if (threeDLayout != null) { - ThreeDLayoutVO threeDLayoutVO = CopyUtil.copyObject(threeDLayout, ThreeDLayoutVO.class); - threeDLayoutVO.setUrl(minioUtil.getPreSignedUrl(threeDLayoutVO.getUrl(), 24 * 60)); - return threeDLayoutVO; - } - return null; - }); - return convert; - } - - @Override - public ThreeDVO getLayoutDetail(Long threeDSimpleId) { - ThreeDVO result = new ThreeDVO(); - - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ThreeDLayout::getThreeDSimpleId, threeDSimpleId); - List threeDLayoutList = threeDLayoutMapper.selectList(qw); - for (ThreeDLayout threeDLayout : threeDLayoutList) { - threeDLayout.setUrl(minioUtil.getPreSignedUrl(threeDLayout.getUrl(), 24 * 60)); - } - result.setThreeDLayoutList(threeDLayoutList); - - QueryWrapper threeDPatternLayoutQueryWrapper = new QueryWrapper<>(); - threeDPatternLayoutQueryWrapper.lambda().eq(ThreeDPatternLayout::getThreeDSimpleId, threeDSimpleId); - List threeDPatternLayoutList = threeDPatternLayoutMapper.selectList(threeDPatternLayoutQueryWrapper); - if (CollectionUtil.isNotEmpty(threeDPatternLayoutList)) { - ThreeDPatternLayout threeDPatternLayout = threeDPatternLayoutList.get(0); -// threeDPatternLayout.setUrl(minioUtil.getPreSignedUrl(threeDPatternLayout.getUrl(), 24 * 60)); - result.setThreeDPatternLayoutUrl(minioUtil.getPreSignedUrl(threeDPatternLayout.getUrl(), 24 * 60)); - } - ThreeDSimple threeDSimple = threeDSimpleMapper.selectById(threeDSimpleId); - result.setThreeDSimpleUrl(minioUtil.getPreSignedUrl(threeDSimple.getUrl(), 24 * 60)); - return result; - } - - @Override - public ThreeDSizeVO getThreeDSize(Long threeDSimpleId) { - ThreeDSizeVO result = new ThreeDSizeVO(); - QueryWrapper threeDDetailQueryWrapper = new QueryWrapper<>(); - threeDDetailQueryWrapper.lambda().eq(ThreeDDetail::getThreeDSimpleId, threeDSimpleId); - List threeDDetailList = threeDDetailMapper.selectList(threeDDetailQueryWrapper); - if (CollectionUtil.isNotEmpty(threeDDetailList)) { - // 以 sizeType 分组 - Map> sizeTypeMap = new HashMap<>(); - for (ThreeDDetail detail : threeDDetailList) { - sizeTypeMap - .computeIfAbsent(detail.getSizeType(), k -> new ArrayList<>()) - .add(detail.getSize()); - } - result.setSizeTypeMap(sizeTypeMap); - } - return result; - } - - @Override - public void getThreeDGlb(Long threeDSimpleId, HttpServletResponse response) throws MinioException, IOException { - ThreeDSimple threeDSimple = threeDSimpleMapper.selectById(threeDSimpleId); - if (ObjectUtils.isAllFieldNull(threeDSimple)) { - throw new BusinessException("3D file is not exist"); - } - InputStream inputStream = minioUtil.download(threeDSimple.getUrl()); - - // 设置响应头 - response.setContentType("model/gltf-binary"); // 确保 MIME 类型正确 - response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); - String fileName = threeDSimple.getName(); - if (!fileName.toLowerCase().endsWith(".glb")) { - fileName += ".glb"; - } - response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString())); - // 将文件内容写入响应输出流 - try { - byte[] buffer = new byte[8192]; - int bytesRead; - while ((bytesRead = inputStream.read(buffer)) != -1) { - response.getOutputStream().write(buffer, 0, bytesRead); - } - inputStream.close(); - response.getOutputStream().flush(); - } catch (Exception e) { - throw new RuntimeException("Failed to get 3D .glb file", e); - } - } - - @Override - public String downloadZip(Long threeDSimpleId, String sizeType, String size, HttpServletResponse response) throws MinioException, IOException { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ThreeDDetail::getThreeDSimpleId, threeDSimpleId); - qw.lambda().eq(ThreeDDetail::getSizeType, sizeType); - qw.lambda().eq(ThreeDDetail::getSize, size); - ThreeDDetail threeDDetail = threeDDetailMapper.selectOne(qw); - if (ObjectUtils.isAllFieldNull(threeDDetail)) { - throw new BusinessException("3D file is not exist"); - } - return minioUtil.getPreSignedUrl(threeDDetail.getUrl(), 24 * 60); - -// // 设置响应头 -// response.setContentType("application/zip"); // 确保 ZIP 格式 -// response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); -// String fileName = threeDDetail.getName(); -// if (!fileName.toLowerCase().endsWith(".zip")) { -// fileName += ".zip"; -// } -// response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString())); -// -// // 将文件内容写入响应输出流 -// try { -// byte[] buffer = new byte[8192]; -// int bytesRead; -// while ((bytesRead = inputStream.read(buffer)) != -1) { -// response.getOutputStream().write(buffer, 0, bytesRead); -// } -// inputStream.close(); -// response.getOutputStream().flush(); -// } catch (Exception e) { -// throw new RuntimeException("Failed to download ZIP file", e); -// } - } - - @Override - public Boolean delete(Long projectId) { - projectService.removeById(projectId); - return Boolean.TRUE; - } - - @Override - public Boolean brandDNADelete(BrandDNADTO brandDNADTO) { - brandDNAMapper.deleteById(brandDNADTO.getId()); - return Boolean.TRUE; - } - - @Override - @Transactional(isolation = Isolation.SERIALIZABLE) - public void toProductBatch(String taskId, String url, String progress) throws InterruptedException { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ToProductImageResult::getTaskId, taskId); - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(qw); - if (Objects.nonNull(toProductImageResult)) { - toProductImageResult.setUrl(url); - toProductImageResult.setStatus("Success"); - toProductImageResultMapper.updateById(toProductImageResult); - String taskIdBatch = toProductImageResult.getTaskIdBatch(); - log.info("toProductImage云生成 batchTaskId:" + taskIdBatch + " 完成数+1"); - - CloudTask task = cloudTaskMapper.selectForUpdate(taskIdBatch); - log.info("排查完成数量" + task.getCompletedNum()); - task.setCompletedNum(task.getCompletedNum() + 1); - cloudTaskMapper.updateById(task); - - String key = toProductImageResultKey + ":" + taskId; - String imageName = url.substring(url.lastIndexOf("/") + 1); - String status = imageName.equals("white_image.jpg") ? "Invalid" : "Success"; - GenerateResultVO generateResultVO = new GenerateResultVO(taskId, toProductImageResult.getId(), url, status, null); - redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); - - /*Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1)); - if (!status.equals("Invalid")) { - // 4、扣除积分 - Boolean b = creditsService.taskCreditsDeduction(accountId, taskId); - // 3、记录积分变更 - if (b) creditsService.updateChangedCredits(String.valueOf(accountId), taskId); - }*/ - } - - } - - @Override - @Transactional - public void relightBatch(String taskId, String url, String progress) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(ToProductImageResult::getTaskId, taskId); - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(qw); - if (Objects.nonNull(toProductImageResult)) { - if (toProductImageResult.getBrightenValue() != null && toProductImageResult.getBrightenValue() != 1.0) { - pythonService.bright(url, toProductImageResult.getBrightenValue()); - } - toProductImageResult.setUrl(url); -// toProductImageResult.setResultType("Relight"); - toProductImageResult.setStatus("Success"); - toProductImageResultMapper.updateById(toProductImageResult); - - String taskIdBatch = toProductImageResult.getTaskIdBatch(); -// QueryWrapper cloudTaskQueryWrapper = new QueryWrapper<>(); -// cloudTaskQueryWrapper.lambda().eq(CloudTask::getTaskId, taskIdBatch); -// CloudTask cloudTask = cloudTaskMapper.selectOne(cloudTaskQueryWrapper); -// if (Objects.nonNull(cloudTask)) { -// if (cloudTask.getCompletedNum() == null) { -// cloudTask.setCompletedNum(1); -// }else { -// cloudTask.setCompletedNum(cloudTask.getCompletedNum() + 1); -// } -// if (progress.equals("OK")) { -// cloudTask.setStatus(1); -// cloudTask.setCompletedNum(cloudTask.getNums()); -// } -// cloudTaskMapper.updateById(cloudTask); -// } - cloudTaskMapper.increaseCompletedNum(taskIdBatch); - - String key = relightResultKey + ":" + taskId; - String imageName = url.substring(url.lastIndexOf("/") + 1); - String status = imageName.equals("white_image.jpg") ? "Invalid" : "Success"; - GenerateResultVO generateResultVO = new GenerateResultVO(taskId, toProductImageResult.getId(), url, status, null); - redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); - - /*Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1)); - if (!status.equals("Invalid")) { - // 4、扣除积分 - Boolean b = creditsService.taskCreditsDeduction(accountId, taskId); - // 3、记录积分变更 - if (b) creditsService.updateChangedCredits(String.valueOf(accountId), taskId); - }*/ - } - } - - @Override - @Transactional - public Boolean collectionLikeUpdate(CollectionLikeUpdateDTO collectionLikeUpdateDTO) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(CollectionSort::getRelationId, collectionLikeUpdateDTO.getOldRelationId()); - qw.lambda().eq(CollectionSort::getRelationType, collectionLikeUpdateDTO.getRelationType()); - CollectionSort collectionSort = collectionSortMapper.selectOne(qw); -// Long relationIdOld = collectionSort.getRelationId(); - collectionSort.setRelationId(collectionLikeUpdateDTO.getRelationId()); - collectionSortMapper.updateById(collectionSort); - if (collectionLikeUpdateDTO.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue()) || collectionLikeUpdateDTO.getRelationType().equals(CollectionType.RELIGHT.getValue())) { - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(collectionLikeUpdateDTO.getRelationId()); - toProductImageResult.setIsLike(1); - toProductImageResultMapper.updateById(toProductImageResult); - ToProductImageResult toProductImageResultOld = toProductImageResultMapper.selectById(collectionLikeUpdateDTO.getOldRelationId()); - toProductImageResultOld.setIsLike(0); - toProductImageResultMapper.updateById(toProductImageResultOld); - } else if (collectionLikeUpdateDTO.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) { - PoseTransformation poseTransformation = poseTransformationMapper.selectById(collectionLikeUpdateDTO.getRelationId()); - poseTransformation.setIsLiked((byte) 1); - poseTransformationMapper.updateById(poseTransformation); - PoseTransformation poseTransformationOld = poseTransformationMapper.selectById(collectionLikeUpdateDTO.getOldRelationId()); - poseTransformationOld.setIsLiked((byte) 0); - poseTransformationMapper.updateById(poseTransformationOld); - } - return Boolean.TRUE; - } - - @Override - public Boolean toProductImageElementDelete(Long id) { - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper - .set("project_id", null) // 显式设置 NULL - .eq("id", id); // 指定条件 - toProductElementMapper.update(null, updateWrapper); - return Boolean.TRUE; - } - - @Override - public ToProductElementVO convertRelightElement(Long id) { - ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(id); - - ToProductElement toProductElement = new ToProductElement(); - toProductElement.setUrl(toProductImageResult.getUrl()); -// toProductElement.setUserLikeGroupId(userLikeGroupId); - toProductElement.setProjectId(toProductImageResult.getProjectId()); - toProductElement.setCreateTime(LocalDateTime.now()); - toProductElementMapper.insert(toProductElement); - ToProductElementVO toProductElementVO = CopyUtil.copyObject(toProductElement, ToProductElementVO.class); - toProductElementVO.setMinioUrl(toProductElementVO.getUrl()); - toProductElementVO.setUrl(minioUtil.getPreSignedUrl(toProductElementVO.getUrl(), 24 * 60)); - return toProductElementVO; - } - - private String buildAdvancedPrompt(Long projectId, String prompt) { - String process = projectService.getById(projectId).getProcess(); - String ageGroup = null; - if (!"TO_PRODUCT_IMAGE".equals(process)) { - //高级工具转产品图不需要这个字段 - ageGroup = workspaceService.getWSByProjectId(projectId).getAgeGroup(); - } - String suffixCommon = "Pay attention to the size of the garment, the print, and the fabric texture, real photo, 8K, HDR, DOF, soft lighting, high detail, high quality, Do not return the original image."; - String suffixModelAdult = "Transform this image into a real model standing," + suffixCommon; - String suffixModelChild = "Transform this image into a real child model standing," + suffixCommon; - if ("SINGLE_DESIGN".equals(process) && "Adult".equals(ageGroup)) { - if (StringUtil.isNullOrEmpty(prompt)) { - return "Transform this image into a real garment showing in the white studio: garment on invisible mannequin" + suffixCommon; - } else { - return prompt + suffixCommon; - } - } else if ("SINGLE_DESIGN".equals(process) && "Child".equals(ageGroup)) { - if (StringUtil.isNullOrEmpty(prompt)) { - return "Transform this image into a real child model stand and wear this garment, in the white studio, facing camera, standing posture." + suffixCommon; - } else { - return prompt + suffixCommon; - } - } else if ("SERIES_DESIGN".equals(process) && "Adult".equals(ageGroup)) { - if (StringUtil.isNullOrEmpty(prompt)) { - return "in the white studio, facing camera, standing posture." + suffixModelAdult; - } else { - return prompt + suffixModelAdult; - } - } else if ("SERIES_DESIGN".equals(process) && "Child".equals(ageGroup)) { - if (StringUtil.isNullOrEmpty(prompt)) { - return "in the white studio, facing camera, standing posture." + suffixModelChild + "\n"; - } else { - return prompt + suffixModelChild; - } - } else if ("TO_PRODUCT_IMAGE".equals(process)) { - if (StringUtil.isNullOrEmpty(prompt)) { - throw new BusinessException("Please enter the prompt."); - } else { - return prompt + suffixCommon; - } - } else { - return "Transform this image into a realistic, studio-quality photograph." + "Pay attention to the size of the garment, the print, and the fabric texture. the white background. 8K, HDR, DOF, soft lighting" + ", high detail, high quality,Do not return the original image"; - } - } -} +package com.ai.da.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.ai.da.common.config.exception.BusinessException; +import com.ai.da.common.constant.CommonConstant; +import com.ai.da.common.constant.ModelConstants; +import com.ai.da.common.context.UserContext; +import com.ai.da.common.enums.CollectionLevel1TypeEnum; +import com.ai.da.common.enums.CreditsEventsEnum; +import com.ai.da.common.enums.DesignTypeEnum; +import com.ai.da.common.enums.LibraryLevel1TypeEnum; +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.common.response.ResultEnum; +import com.ai.da.common.utils.*; +import com.ai.da.mapper.primary.*; +import com.ai.da.mapper.primary.entity.*; +import com.ai.da.mapper.primary.entity.Collection; +import com.ai.da.mapper.secondary.AttributeRetrievalMapper; +import com.ai.da.mapper.secondary.entity.AttributeRecognitionJSON; +import com.ai.da.model.dto.*; +import com.ai.da.model.enums.CollectionType; +import com.ai.da.model.enums.Module; +import com.ai.da.model.vo.*; +import com.ai.da.python.PythonService; +import com.ai.da.service.*; +import com.ai.da.seller.DesignUrlsDTO; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + +import java.util.Comparator; +import java.util.ArrayList; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.base.Function; +import com.google.gson.Gson; +import io.minio.errors.MinioException; +import io.netty.util.internal.StringUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + +import static com.ai.da.common.enums.LayersPriorityEnum.BODY; + +/** + * 服务实现类 + * + * @author yanglei + * @since 2022-09-30 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class UserLikeGroupServiceImpl extends ServiceImpl implements UserLikeGroupService { + + /** + * 根据CollectionSort ID获取TO_PRODUCT_IMAGE类型的URL列表 + * @param collectionSortId CollectionSort ID + * @return TO_PRODUCT_IMAGE类型的URL列表 + */ + private List getToProductImageUrlsByCollectionSortId(Long collectionSortId) { + List toProductImageUrls = new ArrayList<>(); + + // 查询子记录中的TO_PRODUCT_IMAGE类型 + QueryWrapper childCollectionQw = new QueryWrapper<>(); + childCollectionQw.lambda().eq(CollectionSort::getParentId, collectionSortId); + childCollectionQw.lambda().eq(CollectionSort::getRelationType, CollectionType.TO_PRODUCT_IMAGE.getValue()); + childCollectionQw.lambda().orderByAsc(CollectionSort::getSort); + List childSortList = collectionSortMapper.selectList(childCollectionQw); + + for (CollectionSort userLikeSort : childSortList) { + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); + if (toProductImageResult != null && !isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { + String url = toProductImageResult.getUrl(); + toProductImageUrls.add(minioUtil.processMinioResource(url, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + } + } + + return toProductImageUrls; + } + + /** + * 根据designItemId获取TO_PRODUCT_IMAGE类型的URL列表和DesignItemDetail的path列表 + * @param designItemId designItemId + * @return 包含TO_PRODUCT_IMAGE类型的URL列表和DesignItemDetail的path列表的对象 + */ + public DesignUrlsDTO getToProductImageUrlsByDesignItemId(Long designItemId) { + DesignUrlsDTO designUrlsDTO = new DesignUrlsDTO(); + designUrlsDTO.setDesignItemId(designItemId); + List toProductImageUrls = new ArrayList<>(); + List designItemDetailPaths = new ArrayList<>(); + + // 根据designItemId查询UserLike + QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); + userLikeQueryWrapper.lambda().eq(UserLike::getDesignItemId, designItemId); + UserLike userLike = userLikeMapper.selectOne(userLikeQueryWrapper); + + if (userLike != null) { + // 根据UserLike的ID查询CollectionSort + QueryWrapper collectionSortQueryWrapper = new QueryWrapper<>(); + collectionSortQueryWrapper.lambda().eq(CollectionSort::getRelationId, userLike.getId()); + collectionSortQueryWrapper.lambda().eq(CollectionSort::getRelationType, CollectionType.DESIGN.getValue()); + CollectionSort collectionSort = collectionSortMapper.selectOne(collectionSortQueryWrapper); + + if (collectionSort != null) { + // 获取TO_PRODUCT_IMAGE类型的URL列表 + toProductImageUrls = getToProductImageUrlsByCollectionSortId(collectionSort.getId()); + } + } + + // 查询DesignItemDetail表,排除type为"Body"的数据 + QueryWrapper designItemDetailQueryWrapper = new QueryWrapper<>(); + designItemDetailQueryWrapper.lambda().eq(DesignItemDetail::getDesignItemId, designItemId); + designItemDetailQueryWrapper.lambda().ne(DesignItemDetail::getType, BODY.getType()); + List designItemDetails = designItemDetailMapper.selectList(designItemDetailQueryWrapper); + + for (DesignItemDetail designItemDetail : designItemDetails) { + // 判断当前用户是否是DesignItemDetail的创建者 + if (!Objects.equals(designItemDetail.getAccountId(), UserContext.getUserHolder().getId())){ + throw new BusinessException("unknown.authentication.operation.type"); + } + if (designItemDetail.getPath() != null) { + designItemDetailPaths.add(minioUtil.processMinioResource(designItemDetail.getPath(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + } + } + + designUrlsDTO.setToProductImageUrls(toProductImageUrls); + designUrlsDTO.setClothes(designItemDetailPaths); + return designUrlsDTO; + } + + private final UserLikeGroupMapper userLikeGroupMapper; + private final AccountMapper accountMapper; + private final CollectionService collectionService; + private final UserLikeService userLikeService; + private final WorkspaceService workspaceService; + private final UserLikeMapper userLikeMapper; + private final MinioUtil minioUtil; + private final TDesignPythonOutfitMapper designPythonOutfitMapper; + private final DesignMapper designMapper; + private final MoodboardPositionService moodboardPositionService; + private final SysFileMapper sysFileMapper; + private final LibraryMapper libraryMapper; + private final GenerateDetailMapper generateDetailMapper; + private final PortfolioMapper portfolioMapper; + private final TagsMapper tagsMapper; + private final DesignItemDetailService designItemDetailService; + private final DesignItemDetailMapper designItemDetailMapper; + private final CollectionElementMapper collectionElementMapper; + private final AttributeRetrievalMapper attributeRetrievalMapper; + private final ProductImageAttributeMapper productImageAttributeMapper; + private final CollectionSortMapper collectionSortMapper; + private final ClassificationService classificationService; + // private ProjectMapper projectMapper; + private final ProjectService projectService; + private final LibraryModelPointMapper libraryModelPointMapper; + private final LibraryService libraryService; + private final BrandDNAMapper brandDNAMapper; + private final BrandRelLibraryMapper brandRelLibraryMapper; + private final ThreeDLayoutMapper threeDLayoutMapper; + private final ThreeDPatternLayoutMapper threeDPatternLayoutMapper; + private final ThreeDDetailMapper threeDDetailMapper; + private final ThreeDSimpleMapper threeDSimpleMapper; + private final ThreeDModuleMapper threeDModuleMapper; + private final ProductImageService productImageService; + private final CollectionElementRelModelMapper collectionElementRelModelMapper; + private final CollectionSortService collectionSortService; + private final GenerateService generateService; + private final ToProductElementMapper toProductElementMapper; + private final ToProductImageRecordMapper toProductImageRecordMapper; + private final ToProductImageResultMapper toProductImageResultMapper; + private final ToProductImageResultService toProductImageResultService; + private final CloudTaskMapper cloudTaskMapper; + private final PythonService pythonService; + private final CreditsService creditsService; + private final PoseTransformationMapper poseTransformationMapper; + private final ExportFileMapper exportFileMapper; + private final DesignItemDetailCanvasMapper designItemDetailCanvasMapper; + @Value("${redis.key.generateResult}") + private String generateResultKey; + + @Override + public void deleteUserGroup(Long userGroupId) { + UserLikeGroup group = getById(userGroupId); + if (Objects.isNull(group)) { + throw new BusinessException("history.not.found"); + } + userLikeGroupMapper.deleteById(userGroupId); + } + + @Override + public HistoryUpdateVO updateUserGroupName(Long userGroupId, String userGroupName, String timeZone) { + UserLikeGroup group = getById(userGroupId); + if (Objects.isNull(group)) { + throw new BusinessException("history.not.found"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("id", userGroupId); + UserLikeGroup userLikeGroup = new UserLikeGroup(); + userLikeGroup.setName(userGroupName); + userLikeGroup.setUpdateDate(DateUtil.getByTimeZone(timeZone)); + log.info("跟新group名字###{}###时间是###{}", userLikeGroup.getUpdateDate(), TimeZone.getDefault()); + userLikeGroupMapper.update(userLikeGroup, queryWrapper); + return new HistoryUpdateVO(userLikeGroup.getName(), userLikeGroup.getUpdateDate().getTime()); + } + +// public static void main(String[] args) { +// System.out.println(TimeZone.getDefault()); +// Date kolkata =DateUtil.getByTimeZone("Asia/Kolkata"); +// Date shanghai =DateUtil.getByTimeZone("Asia/Shanghai"); +// System.out.println(kolkata); +// System.out.println(shanghai); +// System.out.println(kolkata.getTime()); +// System.out.println(shanghai.getTime()); +// System.out.println(kolkata.getTime() == shanghai.getTime()); +// } + + private List selectByUserId(Long userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("accountId", userId); + return userLikeGroupMapper.selectList(queryWrapper); + } + + @Override + public Long insertUserGroup(Long userId, Long collectionId, String timeZone, Long projectId) { + UserLikeGroup userLikeGroup = new UserLikeGroup(); + //默认当前时间 + userLikeGroup.setName(DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS)); + userLikeGroup.setCreateDate(DateUtil.getByTimeZone(timeZone)); + userLikeGroup.setUpdateDate(DateUtil.getByTimeZone(timeZone)); + userLikeGroup.setAccountId(userId); + userLikeGroup.setCollectionId(collectionId); + userLikeGroup.setOriginal(1); + userLikeGroup.setProjectId(projectId); + userLikeGroupMapper.insertUserLikeGroup(userLikeGroup); + return userLikeGroup.getId(); + } + + @Override + public UserLikeChooseVO choose(Long userGroupId) { + UserLikeGroup group = getById(userGroupId); + if (Objects.isNull(group)) { + throw new BusinessException("history.not.found"); + } + List userLikeVOS = userLikeService.getGroupDetail(userGroupId); + String sex = null; + + QueryWrapper userLikeSortQw = new QueryWrapper<>(); + userLikeSortQw.lambda().eq(CollectionSort::getUserLikeGroupId, userGroupId); + List userLikeSortList = collectionSortMapper.selectList(userLikeSortQw); + if (CollectionUtil.isEmpty(userLikeSortList)) { + Integer sort = 1; + for (UserLikeVO userLikeVO : userLikeVOS) { + CollectionSort userLikeSort = new CollectionSort(); + userLikeSort.setUserLikeId(userLikeVO.getId()); + userLikeSort.setUserLikeGroupId(userGroupId); + userLikeSort.setSort(sort); + collectionSortMapper.insert(userLikeSort); + sort++; + } + } + + userLikeVOS.forEach(o -> { + TDesignPythonOutfit tDesignPythonOutfit1 = designPythonOutfitMapper.selectById(o.getDesignOutfitId()); + o.setUrl(tDesignPythonOutfit1.getDesignUrl()); + if (o.getUrl().contains("/")) { + int index = o.getUrl().lastIndexOf("/"); + o.setPictureName(o.getUrl().substring(index + 1)); + } + o.setDesignOutfitUrl(minioUtil.getPreSignedUrl(o.getUrl(), 24 * 60)); + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(TDesignPythonOutfit::getDesignItemId, o.getDesignItemId()); + List tDesignPythonOutfits = designPythonOutfitMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(tDesignPythonOutfits)) { + TDesignPythonOutfit tDesignPythonOutfit = tDesignPythonOutfits.get(0); + o.setDesignOutfitId(tDesignPythonOutfit.getId()); + } + + QueryWrapper userLikeSortQueryWrapper = new QueryWrapper<>(); + userLikeSortQueryWrapper.lambda().eq(CollectionSort::getUserLikeId, o.getId()); + List userLikeSorts = collectionSortMapper.selectList(userLikeSortQueryWrapper); + if (CollectionUtil.isNotEmpty(userLikeSorts)) { + CollectionSort userLikeSort = userLikeSorts.get(0); + o.setSort(userLikeSort.getSort()); + o.setUserLikeSortId(userLikeSort.getId()); + } + }); + UserLikeCollectionVO userLikeCollection = collectionService.chooseCollection(group.getCollectionId()); + Integer beenPublished = 0; + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(Portfolio::getUserLikeGroupSourceId, userGroupId); + List portfolios = portfolioMapper.selectList(qw); +// Portfolio portfolio = new Portfolio(); + PortfolioDTO portfolioDTO = new PortfolioDTO(); + if (CollectionUtil.isNotEmpty(portfolios)) { +// portfolio = portfolios.get(0); + portfolioDTO = CopyUtil.copyObject(portfolios.get(0), PortfolioDTO.class); + beenPublished = 1; + portfolioDTO.setTagsDTO(tagsMapper.getTagByPortfolioId(portfolioDTO.getId())); + } + return new UserLikeChooseVO(userGroupId, userLikeVOS, userLikeCollection, sex, beenPublished, portfolioDTO); + } + + @Override + public ProjectChooseVO choose(ProjectDTO projectDTO) { + + Project project = projectService.getById(projectDTO.getId()); + + Long workspaceId = workspaceService.getByProjectId(project.getId()); + WorkspaceVO workspaceVO = new WorkspaceVO(); + if (null != workspaceId) { + workspaceVO = workspaceService.getByIdForProject(workspaceId); + } + + String process = project.getProcess(); + String name = project.getName(); + + UserLikeGroup userLikeGroup = userLikeService.getUserLikeGroupByProjectId(project.getId()); + Long collectionId = null; + if (Objects.nonNull(userLikeGroup)) { + Collection collection = collectionService.getById(userLikeGroup.getCollectionId()); + if (Objects.nonNull(collection)) { + collectionId = collection.getId(); + } + } + + Integer beenPublished = 0; + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(Portfolio::getProjectId, projectDTO.getId()); + List portfolios = portfolioMapper.selectList(qw); +// Portfolio portfolio = new Portfolio(); + PortfolioDTO portfolioDTO = new PortfolioDTO(); + if (CollectionUtil.isNotEmpty(portfolios)) { +// portfolio = portfolios.get(0); + portfolioDTO = CopyUtil.copyObject(portfolios.get(0), PortfolioDTO.class); + beenPublished = 1; + portfolioDTO.setTagsDTO(tagsMapper.getTagByPortfolioId(portfolioDTO.getId())); + } + + return new ProjectChooseVO(projectDTO.getId(), name, workspaceVO, process, collectionId, beenPublished, portfolioDTO); + } + + @Override + public UserLikeGroup getByProjectId(Long projectId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(UserLikeGroup::getProjectId, projectId); + List userLikeGroupList = userLikeGroupMapper.selectList(qw); + if (CollectionUtil.isEmpty(userLikeGroupList)) { + return null; + } + return userLikeGroupList.get(0); + } + + @Override + public void deleteTrialData(Long userId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(UserLikeGroup::getAccountId, userId); + List userLikeGroupIdList = userLikeGroupMapper.selectList(qw).stream() + .map(UserLikeGroup::getId) + .collect(Collectors.toList()); + userLikeGroupMapper.delete(qw); + if (CollectionUtil.isNotEmpty(userLikeGroupIdList)) { + QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); + userLikeQueryWrapper.lambda().in(UserLike::getUserLikeGroupId, userLikeGroupIdList); + userLikeMapper.delete(userLikeQueryWrapper); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateDate(Long id, String timeZone) { + UpdateWrapper uw = new UpdateWrapper<>(); + uw.eq("id", id); + uw.set("update_date", DateUtil.getByTimeZone(timeZone)); + + baseMapper.update(null, uw); + } + + @Override + public Long exportSave(MultipartFile file, Long projectId, String module, Long designItemDetailId) { + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + if (Objects.isNull(projectId) && !module.equals("designItemDetail")) { + log.warn("用户 {} 保存 {} 模块的画布时, projectId为空", userHolder.getId(), module); + throw new BusinessException("project.id.cannot.be.empty", ResultEnum.PROMPT.getCode()); + } + + QueryWrapper qw = new QueryWrapper<>(); + List exportFiles = null; + if (Objects.nonNull(projectId)) { + qw.lambda().eq(ExportFile::getProjectId, projectId); + qw.lambda().eq(ExportFile::getModule, module); + exportFiles = exportFileMapper.selectList(qw); + } else if (Objects.nonNull(designItemDetailId)) { + DesignItemDetailCanvas designItemDetailCanvas = designItemDetailService.getDIDCByDesignItemDetailId(designItemDetailId); + if (Objects.nonNull(designItemDetailCanvas) && Objects.nonNull(designItemDetailCanvas.getExportFileId())) { + qw.lambda().eq(ExportFile::getId, designItemDetailCanvas.getExportFileId()); + qw.lambda().eq(ExportFile::getModule, module); + exportFiles = exportFileMapper.selectList(qw); + } + } +// String upload = minioUtil.upload("aida-users", userHolder.getId() + "/exportFile", file); + + ExportFile exportFile = null; + if (CollectionUtil.isNotEmpty(exportFiles)) { + exportFile = exportFiles.get(0); + // 更新画布信息时,只重新上传图片,不用修改数据库url + String url = exportFile.getUrl(); + String path = url.substring(url.indexOf("/") + 1); + minioUtil.upload("aida-users", path, file, null); +// exportFile.setUrl(upload); +// exportFileMapper.updateById(exportFile); + } else { + String upload = minioUtil.upload("aida-users", userHolder.getId() + "/exportFile", file); + exportFile = new ExportFile(); + exportFile.setProjectId(projectId); + exportFile.setModule(module); + exportFile.setUrl(upload); + exportFileMapper.insert(exportFile); + if (Objects.nonNull(designItemDetailId)) { + designItemDetailService.saveDesignItemDetailCanvas(designItemDetailId, exportFile.getId()); + } + } + return exportFile.getId(); + } + + /** + * 产品图像生成方法 + * 根据输入的设计元素和参数,生成对应的产品图像 + * + * @param toProductImageDTO 产品图像生成请求参数 + * @return 生成的产品图像结果列表 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public List toProduct(ToProductImageDTO toProductImageDTO) { + // 判断是否使用(高级模型) + boolean advanced = !StringUtil.isNullOrEmpty(toProductImageDTO.getModelName()) + && toProductImageDTO.getModelName().equals(ModelConstants.ADVANCED); + + // 根据模型类型选择对应的积分消耗事件 + CreditsEventsEnum creditsEventsEnum = advanced ? CreditsEventsEnum.TO_PRODUCT_IMAGE_ADVANCED : CreditsEventsEnum.TO_PRODUCT_IMAGE; + + // 预扣除积分,检查用户积分是否足够本次生成消耗 + Boolean preDeduction = creditsService.creditsPreDeduction(creditsEventsEnum, toProductImageDTO.getToProductImageVOList().size()); + if (!preDeduction) { + throw new BusinessException("remaining.credits.insufficient", ResultEnum.WARNING.getCode()); + } + + // 获取当前登录用户信息 + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + + // 获取项目ID并查找对应的用户喜欢组 + Long projectId = toProductImageDTO.getProjectId(); + UserLikeGroup userLikeGroup = getByProjectId(projectId); + Long userLikeGroupId = null; + + // 创建产品图像记录对象,用于记录本次生成任务的基本信息 + ToProductImageRecord toProductImageRecord = new ToProductImageRecord(); + toProductImageRecord.setProjectId(projectId); + if (Objects.nonNull(userLikeGroup)) { + userLikeGroupId = userLikeGroup.getId(); + toProductImageRecord.setUserLikeGroupId(userLikeGroupId); + } + + String prompt = toProductImageDTO.getPrompt(); + String advancedPrompt = buildAdvancedPrompt(projectId, prompt); + // 初始化基础提示词,确保生成高质量的真实图像 + StringBuilder sb = new StringBuilder("The best quality, masterpiece, real image."); + if (!StringUtil.isNullOrEmpty(prompt) && !advanced) { + // 调用Python服务进行提示词翻译(中文转英文等) + prompt = pythonService.promptTranslate(prompt); + + // 检查翻译后的提示词长度,限制在180个单词以内 + String[] words = prompt.split("\\s+"); + if (words.length > 180) { + throw new BusinessException("Please keep your input text under 200 words. Thanks!"); + } + } + + // 设置记录创建时间并保存原始提示词 + toProductImageRecord.setCreateTime(LocalDateTime.now()); + if (!StringUtils.isEmpty(toProductImageDTO.getPrompt())) { + toProductImageRecord.setPrompt(toProductImageDTO.getPrompt()); + } + // 将产品图像记录插入数据库 + toProductImageRecordMapper.insert(toProductImageRecord); + + // 初始化结果列表 + List result = new ArrayList<>(); + // 判断是否为儿童年龄组,用于后续生成不同的提示词 + boolean childFlag = !StringUtil.isNullOrEmpty(toProductImageDTO.getAgeGroup()) + && toProductImageDTO.getAgeGroup().equals("Child"); + // 循环计数器,用于生成唯一的任务ID + int i = 0; + +// else { +// s = "best quality, masterpiece. detailed, high-res, simple background, studio photography, extremely detailed, updo, detailed face, face, close-up, HDR, UHD, 8K realistic, Highly detailed, simple background, Studio lighting"; +// } + // 遍历所有需要生成的产品图像元素 + for (ToProductImageVO toProductImageVO : toProductImageDTO.getToProductImageVOList()) { + String taskId; + // 处理设计服装类型的元素 + if (toProductImageVO.getElementType().equals("DesignOutfit")) { + // 生成唯一的任务ID,包含UUID、序号和用户ID + taskId = UUID.randomUUID() + "-" + i + "-" + userHolder.getId(); + // 根据元素ID查询设计Python服装信息 + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageVO.getElementId()); + + // 获取设计项目ID并查询相关的设计项目详情 + Long designItemId = tDesignPythonOutfit.getDesignItemId(); + QueryWrapper designItemDetailQueryWrapper = new QueryWrapper<>(); + designItemDetailQueryWrapper.lambda().eq(DesignItemDetail::getDesignItemId, designItemId); + designItemDetailQueryWrapper.lambda().ne(DesignItemDetail::getType, "Body"); // 排除身体部分 + List designItemDetails = designItemDetailService.list(designItemDetailQueryWrapper); + // 将设计项目的类型拼接成字符串(如:Tops,Bottoms) + String collect = designItemDetails.stream().map(DesignItemDetail::getType).collect(Collectors.joining(",")); + + // 获取设计ID并查询设计信息 + Long designId = tDesignPythonOutfit.getDesignId(); + Design design = designMapper.selectById(designId); + // 默认产品类型为整体 + String productType = "overall"; + // 根据设计的单品/整体属性决定产品类型和提示词构建方式 + if (design.getSingleOverall().equals("single")) { + // 单品设计:直接使用服装类型 + productType = "single"; + sb.append(collect); + } else { + // 整体设计:根据服装类型和年龄组添加人物描述 + if (collect.contains("Tops") && childFlag) { + sb.append("a handsome boy,"); // 儿童上装 - 男孩 + } else if (collect.contains("Tops") && !childFlag) { + sb.append("a handsome man,"); // 成人上装 - 男性 + } else if (childFlag) { + sb.append("a beautiful girl,"); // 儿童其他 - 女孩 + } else { + sb.append("a beautiful woman,"); // 成人其他 - 女性 + } +// sb.append("wearing ").append(collect); + } + // 根据是否有自定义提示词来完善最终的提示词 + if (StringUtils.isEmpty(prompt)) { + // 无自定义提示词:使用默认的高质量服装细节描述 + sb.append(",high quality clothing details,8K realistic,HDR"); + } else { + // 有自定义提示词:结合用户提示词和高质量描述 + sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR"); + } + // 创建产品图像结果对象 + ToProductImageResultVO toProductImageResult = new ToProductImageResultVO(); + // 根据是否使用flux模型选择不同的生成方式 + if (advanced) { + // 使用flux高级模型 + if (childFlag) { + sb.append(", Children's face"); // 儿童面部特征 + } + taskId = generateService.toProductAsyncTask(tDesignPythonOutfit.getDesignUrl(), ModelConstants.NANO_BANANA, advancedPrompt); + toProductImageResult.setModelName(toProductImageDTO.getModelName()); + toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue()); + } else { + // 使用本地Python模型 + if (childFlag) { + sb.append(", (Children's face:1.3)"); // 儿童面部特征(权重1.3) + } + // 调用Python服务生成产品图像 + pythonService.toProductImage(tDesignPythonOutfit.getDesignUrl(), taskId, sb.toString(), toProductImageDTO.getImageStrength(), productType); +// toProductImageResult.setModelName("local"); // 注释掉的本地模型标记 + } + + // 设置产品图像结果的基本信息 + toProductImageResult.setElementId(tDesignPythonOutfit.getId()); // 关联的设计服装ID + toProductImageResult.setElementType("DesignOutfit"); // 元素类型:设计服装 + toProductImageResult.setCreateTime(LocalDateTime.now()); // 创建时间 + toProductImageResult.setToProductImageRecordId(toProductImageRecord.getId()); // 关联的记录ID +// toProductImageResult.setUrl(productImageUrl); // 生成的图像URL(暂时注释) + toProductImageResult.setIsLike(0); // 默认未点赞 + toProductImageResult.setTaskId(taskId); // 任务ID + toProductImageResult.setProjectId(projectId); // 项目ID + if (userLikeGroupId != null) { + toProductImageResult.setUserLikeGroupId(userLikeGroupId); // 用户喜欢组ID + } + toProductImageResult.setImageStrength(toProductImageDTO.getImageStrength()); // 图像强度 + toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue()); // 结果类型 + toProductImageResult.setStatus("Pending"); // 状态:待处理 + // 将结果插入数据库 + toProductImageResultMapper.insert(toProductImageResult); +// toProductImageResult.setUrl(minioUtil.getPresignedUrl(toProductImageResult.getUrl(), 24 * 60)); + // 处理默认点赞逻辑 + if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && toProductImageDTO.getIsDefaultLike()) { + // 如果设置了默认点赞,则自动添加到用户喜欢列表 + CollectionSort collectionSort = addToProductLike(toProductImageVO.getParentId(), toProductImageResult.getId(), toProductImageDTO.getProjectId()); + // 重新排序:根据用户指定的排序位置调整 + Integer reSort = collectionSortService.rearrangeChildSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), + toProductImageVO.getParentId(), toProductImageVO.getUserLikeSortId()); + // 设置排序信息到结果对象中 + toProductImageResult.setSort(Objects.isNull(reSort) ? Objects.isNull(collectionSort) ? null : collectionSort.getSort() : reSort); + toProductImageResult.setParentId(toProductImageVO.getParentId()); // 父级ID + toProductImageResult.setUserLikeSortId(Objects.isNull(collectionSort) ? null : collectionSort.getId()); // 排序记录ID + } else if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && Objects.nonNull(toProductImageVO.getParentId())) { + // 不默认点赞但有父级ID的情况 + toProductImageResult.setParentId(toProductImageVO.getParentId()); + // 注释:原本计划添加到collectionSort表中,但当前未实现 +// designService.addCollectionSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), toProductImageDTO.getProjectId(), toProductImageVO.getParentId()); + } + // 将处理完的结果添加到返回列表中 + result.add(toProductImageResult); + } else { + // 处理ProductElement类型的元素 + // 根据是否有自定义提示词来构建最终提示词 + if (StringUtils.isEmpty(prompt)) { + sb.append(",high quality clothing details,8K realistic,HDR"); + } else { + sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR"); + } + + // 生成唯一的任务ID + taskId = UUID.randomUUID() + "-" + i + "-" + userHolder.getId(); + // 查询产品元素信息 + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageVO.getElementId()); + // 创建产品图像结果对象 + ToProductImageResultVO toProductImageResult = new ToProductImageResultVO(); + + // 根据是否使用高级模型选择不同的图像生成方式 + if (advanced) { + // 使用模型生成图像 + taskId = generateService.toProductAsyncTask(toProductElement.getUrl(), ModelConstants.NANO_BANANA, advancedPrompt); + toProductImageResult.setModelName(toProductImageDTO.getModelName()); // 设置模型名称 + toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue()); // 设置结果类型 + } else { + // 使用本地Python模型生成图像 + if (childFlag) { + // 如果是儿童年龄组,添加儿童面部特征提示 + sb.append(", (Children's face:1.3)"); + } + // 调用Python服务生成产品图像 + pythonService.toProductImage(toProductElement.getUrl(), taskId, sb.toString(), toProductImageDTO.getImageStrength(), "overall"); +// toProductImageResult.setModelName("local"); // 本地模型名称(已注释) + } + // 设置产品图像结果的基本信息 + toProductImageResult.setElementId(toProductElement.getId()); // 关联的产品元素ID + toProductImageResult.setElementType("ProductElement"); // 元素类型:产品元素 + toProductImageResult.setCreateTime(LocalDateTime.now()); // 创建时间 + toProductImageResult.setToProductImageRecordId(toProductImageRecord.getId()); // 关联的记录ID +// toProductImageResult.setUrl(productImageUrl); // 生成的图像URL(暂时注释) + toProductImageResult.setIsLike(0); // 默认未点赞 + toProductImageResult.setTaskId(taskId); // 任务ID + toProductImageResult.setProjectId(projectId); // 项目ID + if (userLikeGroupId != null) { + toProductImageResult.setUserLikeGroupId(userLikeGroupId); // 用户喜欢组ID + } + toProductImageResult.setImageStrength(toProductImageDTO.getImageStrength()); // 图像强度 + toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue()); // 结果类型 + toProductImageResult.setStatus("Pending"); // 状态:待处理 + // 将结果插入数据库 + toProductImageResultMapper.insert(toProductImageResult); +// toProductImageResult.setUrl(minioUtil.getPresignedUrl(toProductImageResult.getUrl(), 24 * 60)); + // 处理默认点赞逻辑 + if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && toProductImageDTO.getIsDefaultLike()) { + // 如果设置了默认点赞,则自动添加到用户喜欢列表 + CollectionSort collectionSort = addToProductLike(toProductImageVO.getParentId(), toProductImageResult.getId(), toProductImageDTO.getProjectId()); + // 重新排序:根据用户指定的排序位置调整 + Integer reSort = collectionSortService.rearrangeChildSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), + toProductImageVO.getParentId(), toProductImageVO.getUserLikeSortId()); + // 设置排序信息到结果对象中 + toProductImageResult.setSort(Objects.isNull(reSort) ? Objects.isNull(collectionSort) ? null : collectionSort.getSort() : reSort); + toProductImageResult.setParentId(toProductImageVO.getParentId()); // 父级ID + toProductImageResult.setUserLikeSortId(Objects.isNull(collectionSort) ? null : collectionSort.getId()); // 排序记录ID + } else if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && Objects.nonNull(toProductImageVO.getParentId())) { + // 不默认点赞但有父级ID的情况 + toProductImageResult.setParentId(toProductImageVO.getParentId()); + // 注释:原本计划添加到collectionSort表中,但当前未实现 +// designService.addCollectionSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), toProductImageDTO.getProjectId(), toProductImageVO.getParentId()); + } + // 将处理完的结果添加到返回列表中 + result.add(toProductImageResult); + } + i++; // 循环计数器递增 + sb = new StringBuilder("The best quality, masterpiece, real image."); // 重置提示词构建器 + // 添加需要扣除的积分到预扣除区 + creditsService.addRecordToCreditsDeduction(userHolder.getId(), taskId, creditsEventsEnum); + // 添加积分扣除记录到数据库 + creditsService.preInsert(userHolder.getId(), creditsEventsEnum.getName(), taskId, Boolean.TRUE, null); + } + // 更新项目更新时间,记录最后一次操作时间 + projectService.modifyProjectUpdateTime(toProductImageDTO.getProjectId()); + // 返回生成的产品图像结果列表 + return result; + } + + private CollectionSort addToProductLike(Long parentId, Long toProductImageResultId, Long projectId) { + if (Objects.nonNull(parentId) && !parentId.equals(0L)) { + return productImageLike(new ProductImageLikeDTO(Collections.singletonList(toProductImageResultId), + projectId, parentId)); + } + return null; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void toProduct(String taskId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ToProductImageResult::getTaskId, taskId); + List toProductImageResults = toProductImageResultMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(toProductImageResults)) { + ToProductImageResult toProductImageResultOne = toProductImageResults.get(0); + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResultOne.getToProductImageRecordId()); + String prompt = toProductImageRecord.getPrompt(); + StringBuilder sb = new StringBuilder("The best quality, masterpiece, real image."); + if (!StringUtil.isNullOrEmpty(prompt)) { + prompt = pythonService.promptTranslate(prompt); + } + String elementType = toProductImageResultOne.getElementType(); + if (elementType.equals("DesignOutfit")) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultOne.getElementId()); + Long designItemId = tDesignPythonOutfit.getDesignItemId(); + QueryWrapper designItemDetailQueryWrapper = new QueryWrapper<>(); + designItemDetailQueryWrapper.lambda().eq(DesignItemDetail::getDesignItemId, designItemId); + designItemDetailQueryWrapper.lambda().ne(DesignItemDetail::getType, "Body"); + List designItemDetails = designItemDetailService.list(designItemDetailQueryWrapper); + String collect = designItemDetails.stream().map(DesignItemDetail::getType).collect(Collectors.joining(",")); + + Long designId = tDesignPythonOutfit.getDesignId(); + Design design = designMapper.selectById(designId); + String productType = "overall"; + if (design.getSingleOverall().equals("single")) { + productType = "single"; + sb.append(collect); + } else { + if (collect.contains("Tops")) { + sb.append("a handsome man,"); + } else { + sb.append("a beautiful women,"); + } + sb.append("wearing ").append(collect); + } + if (StringUtils.isEmpty(prompt)) { + sb.append(",high quality clothing details,8K realistic,HDR"); + } else { + sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR"); + } + // 走模型 + pythonService.toProductImage(tDesignPythonOutfit.getDesignUrl(), taskId, sb.toString(), toProductImageResultOne.getImageStrength(), "single"); + } else { + if (StringUtils.isEmpty(prompt)) { + sb.append(",high quality clothing details,8K realistic,HDR"); + } else { + sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR"); + } + + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultOne.getElementId()); + // 走模型 + pythonService.toProductImage(toProductElement.getUrl(), taskId, sb.toString(), toProductImageResultOne.getImageStrength(), "single"); + } + + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public ToProductElementVO toProductImageElementUpload(MultipartFile file, Long projectId, String type) { + if (null == file || StringUtils.isEmpty(file.getOriginalFilename())) { + throw new BusinessException("file.cannot.be.empty"); + } +// if (projectId == null) { +// throw new BusinessException("projectId.cannot.be.empty"); +// } + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + String bucketName = "aida-users"; + String minioUrl = minioUtil.upload(bucketName, userHolder.getId() + "/toProductImageElement", file); + ToProductElement toProductElement = new ToProductElement(); + toProductElement.setUrl(minioUrl); +// toProductElement.setUserLikeGroupId(userLikeGroupId); + toProductElement.setProjectId(projectId); + toProductElement.setCreateTime(LocalDateTime.now()); + toProductElement.setFrameType(type); + toProductElementMapper.insert(toProductElement); + ToProductElementVO toProductElementVO = CopyUtil.copyObject(toProductElement, ToProductElementVO.class); + toProductElementVO.setMinioUrl(toProductElementVO.getUrl()); + toProductElementVO.setUrl(minioUtil.getPreSignedUrl(toProductElementVO.getUrl(), 24 * 60)); + return toProductElementVO; + } + + @Override + public CollectionSort productImageLike(ProductImageLikeDTO dto) { + List resultIds = dto.getToProductImageResultId(); + ToProductImageResult result = toProductImageResultMapper.selectById(resultIds.get(0)); + CollectionSort collectionSort = null; + boolean updatedFlag = false; + + Long parentId = dto.getCollectionSortParentId(); + if (parentId == null) { + return null; + } + + // 统一处理两种类型 + CollectionType collectionType = "Relight".equals(result.getResultType()) + ? CollectionType.RELIGHT + : CollectionType.TO_PRODUCT_IMAGE; + + collectionSort = collectionSortService.getUserLikeSortByUserLikeId( + result.getId(), collectionType.getValue(), dto.getProjectId(), parentId); + + if (Objects.isNull(collectionSort)) { + collectionSort = collectionSortService.addCollectionSort( + result.getId(), collectionType.getValue(), dto.getProjectId(), parentId); + updatedFlag = true; + } + + if (updatedFlag) { + updateLikeStatus(resultIds); + projectService.modifyProjectUpdateTime(dto.getProjectId()); + } + + return collectionSort; + } + + private void updateLikeStatus(List resultIds) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().in(ToProductImageResult::getId, resultIds); + + ToProductImageResult updateEntity = new ToProductImageResult(); + updateEntity.setIsLike(1); + toProductImageResultMapper.update(updateEntity, qw); + } + + @Resource + private RedisUtil redisUtil; + @Value("${redis.key.toProductImageResultKey}") + private String toProductImageResultKey; + @Value("${redis.key.relightResultKey}") + private String relightResultKey; + + /** + * 获取产品图像生成结果列表 + * 根据任务ID列表查询对应的产品图像生成结果,支持flux模型和传统Python模型两种处理方式 + * + * @param taskIdList 任务ID列表,用于查询对应的产品图像生成结果 + * @return 返回MagicToolResultVO列表,包含图像生成结果的详细信息(URL、状态、元素信息等) + * @throws BusinessException 当源图像不存在或任务不存在时抛出业务异常 + */ + @Override + public List getToProductImageResultList(List taskIdList) { + // 初始化结果列表和状态收集集合 + List results = new ArrayList<>(); + Set collect = new HashSet<>(); + + // 遍历每个任务ID,处理对应的产品图像生成结果 + taskIdList.forEach(taskId -> { + // 根据任务ID查询产品图像生成结果记录 + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ToProductImageResult::getTaskId, taskId); + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(qw); + if (Objects.isNull(toProductImageResult)) { + throw new BusinessException("source.image.does.not.exist"); + } + + // 查询产品图像记录,获取提示词等信息 + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); + if (Objects.isNull(toProductImageRecord)) { + throw new BusinessException("This task does not exist."); + } + + if (!StringUtil.isNullOrEmpty(toProductImageResult.getModelName()) && toProductImageResult.getModelName().equals(ModelConstants.ADVANCED)) { + // 获取项目信息,用于构建文件路径和积分扣除 + Project project = projectService.getById(toProductImageResult.getProjectId()); + if (Objects.isNull(project)) { + throw new BusinessException("unknown project"); + } + + // 获取flux模型生成结果 + String redisResult; + if (toProductImageResult.getStatus().equals("Success") && !StringUtil.isNullOrEmpty(toProductImageResult.getUrl())) { + // 如果已经有成功的结果URL,直接使用 + redisResult = toProductImageResult.getUrl(); + } else { + String key = generateResultKey + ":" + taskId; + redisResult = redisUtil.getFromString(key); + } + + GenerateResultVO cachedResult = new Gson().fromJson(redisResult, GenerateResultVO.class); + + + // 根据flux结果状态进行不同处理 + if (StringUtil.isNullOrEmpty(redisResult)) { + // 如果结果为空,标记为失败状态 + toProductImageResult.setStatus("Fail"); + toProductImageResultMapper.updateById(toProductImageResult); + collectionSortMapper.delete(new QueryWrapper().lambda().eq(CollectionSort::getRelationId, toProductImageResult.getId())); + results.add(new MagicToolResultVO(taskId, "Fail")); + } else if ("Pending".equals(cachedResult.getStatus()) || "Fail".equals(cachedResult.getStatus())) { + // 如果结果为失败或待处理状态,更新状态并返回对应结果 + toProductImageResult.setStatus(cachedResult.getStatus()); + toProductImageResultMapper.updateById(toProductImageResult); + if (cachedResult.getStatus().equals("Fail")) { + collectionSortMapper.delete(new QueryWrapper().lambda().eq(CollectionSort::getRelationId, toProductImageResult.getId())); + } + String errorMessage = cachedResult.getUrl(); + if (errorMessage != null) { + results.add(new MagicToolResultVO(taskId, cachedResult.getStatus(), errorMessage)); + } else { + results.add(new MagicToolResultVO(taskId, cachedResult.getStatus())); + } + } else { + // 如果结果成功,处理flux结果并构建返回对象 + results.add(processNanoBananaResult(cachedResult.getUrl(), toProductImageResult, taskId, toProductImageRecord.getPrompt())); + // 执行积分扣除操作 + Boolean flag = creditsService.taskCreditsDeduction(project.getAccountId(), taskId); + if (flag) creditsService.updateChangedCredits(String.valueOf(project.getAccountId()), taskId); + } + + // 如果任务失败,将积分预扣除记录移除 + if (toProductImageResult.getStatus().equals("Fail")) { + creditsService.deleteCreditsDeduction(project.getAccountId(), taskId); + } + + // flux模型处理完成,跳过后续的Redis缓存处理逻辑 + return; + } + + // 非flux模型的处理逻辑:从Redis缓存获取结果 + String key = toProductImageResultKey + ":" + taskId; + MagicToolResultVO magicToolResultVO = new Gson().fromJson(redisUtil.getFromString(key), MagicToolResultVO.class); + + // 如果从Redis获取到结果且URL不为空,则构建返回对象 + if (!Objects.isNull(magicToolResultVO) && !StringUtil.isNullOrEmpty(magicToolResultVO.getUrl())) { + String url = magicToolResultVO.getUrl(); + // 检查是否为无效图片(白色图片表示生成失败) + if (url.substring(url.lastIndexOf("/") + 1).equals("white_image.jpg")) { + magicToolResultVO.setStatus("Invalid"); + } else { + // 设置预签名URL和相关属性 + magicToolResultVO.setUrl(minioUtil.getPreSignedUrl(url, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + magicToolResultVO.setResultType(toProductImageResult.getResultType()); + magicToolResultVO.setElementId(toProductImageResult.getElementId()); + magicToolResultVO.setElementType(toProductImageResult.getElementType()); + magicToolResultVO.setDirection(toProductImageResult.getDirection()); + magicToolResultVO.setBrightenValue(toProductImageResult.getBrightenValue()); + magicToolResultVO.setImageStrength(toProductImageResult.getImageStrength()); + magicToolResultVO.setPrompt(toProductImageRecord.getPrompt()); + + // 根据元素类型设置源图片URL和父ID + if (toProductImageResult.getElementType().equals("ProductElement")) { + // 处理ProductElement类型:获取产品元素信息 + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); + + // 获取ProductElement的父ID + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } else { + // 处理DesignOutfit类型:获取设计服装信息 + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); + + // 通过DesignOutfit查找对应的UserLike记录,获取父ID + QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); + userLikeQueryWrapper.lambda().eq(UserLike::getDesignOutfitId, tDesignPythonOutfit.getId()); + List userLikeList = userLikeMapper.selectList(userLikeQueryWrapper); + if (!CollectionUtils.isEmpty(userLikeList)) { + UserLike userLike = userLikeList.get(0); + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(userLike.getId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } + } + } + // 将构建好的结果对象添加到返回列表 +// results.add(magicToolResultVO); + } else if (Objects.isNull(magicToolResultVO)) { + // 如果Redis中没有结果对象,创建执行中状态的结果对象 + magicToolResultVO = new MagicToolResultVO(taskId, "Executing"); +// results.add(magicToolResultVO); + }/* else { + // 如果Redis中有结果对象但URL为空,直接添加到返回列表 + results.add(magicToolResultVO); + }*/ + + // 收集任务状态用于统计 + if (!StringUtil.isNullOrEmpty(magicToolResultVO.getStatus())) collect.add(magicToolResultVO.getStatus()); + results.add(magicToolResultVO); + }); + + // 返回所有任务的处理结果列表 + return results; + } + + private MagicToolResultVO processNanoBananaResult(String resultImgMinioPath, ToProductImageResult toProductImageResult, String taskId, String prompt) { + // 如果任务状态不是成功且URL为空,则更新任务状态和URL + if (!toProductImageResult.getStatus().equals("Success") + && StringUtil.isNullOrEmpty(toProductImageResult.getUrl())) { + toProductImageResult.setStatus("Success"); + toProductImageResult.setUrl(resultImgMinioPath); + toProductImageResultMapper.updateById(toProductImageResult); + } + + // 创建返回结果对象并设置基本信息 + MagicToolResultVO magicToolResultVO = CopyUtil.copyObject(toProductImageResult, MagicToolResultVO.class); + magicToolResultVO.setTaskId(taskId); + magicToolResultVO.setId(toProductImageResult.getId()); + // 设置Flux生成图片的预签名URL(使用系统配置的过期时间) + magicToolResultVO.setUrl(minioUtil.getPreSignedUrl(resultImgMinioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + magicToolResultVO.setStatus("Success"); + magicToolResultVO.setResultType(toProductImageResult.getResultType()); + magicToolResultVO.setElementId(toProductImageResult.getElementId()); + magicToolResultVO.setElementType(toProductImageResult.getElementType()); + magicToolResultVO.setPrompt(prompt); + + // 根据元素类型设置源图片URL和父ID + if (toProductImageResult.getElementType().equals("ProductElement")) { + // 处理产品元素类型:获取产品元素信息并设置源图片URL + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); + + // 通过CollectionSort服务获取父ID + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } else if (toProductImageResult.getElementType().equals("DesignOutfit")) { + // 处理设计服装类型:获取设计服装信息并设置源图片URL + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); + + // 通过设计服装ID查找对应的用户喜欢记录,获取父ID + QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); + userLikeQueryWrapper.lambda().eq(UserLike::getDesignOutfitId, tDesignPythonOutfit.getId()); + List userLikeList = userLikeMapper.selectList(userLikeQueryWrapper); + if (!CollectionUtils.isEmpty(userLikeList)) { + UserLike userLike = userLikeList.get(0); + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(userLike.getId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } + } else if (toProductImageResult.getElementType().equals("ToProductImage")) { + // 处理转产品图像类型:获取转产品图像信息并设置源图片URL + ToProductImageResult toProductImage = toProductImageResultMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductImage.getUrl(), 24 * 60)); + + // 直接通过元素ID和类型获取父ID + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } + +// Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getId(), toProductImageResult.getResultType()); +// magicToolResultVO.setParentId(parentId); + return magicToolResultVO; + } + + /** + * 处理Flux模型生成的结果,构建返回给前端的结果对象 + * + * @param fluxImgMinioPath Flux生成的图片在Minio中的路径 + * @param toProductImageResult 产品图像生成结果记录 + * @param taskId 任务ID + * @param prompt 生成提示词 + * @return MagicToolResultVO 构建好的魔法工具结果对象 + */ + private MagicToolResultVO processFluxResult(String fluxImgMinioPath, ToProductImageResult toProductImageResult, String taskId, String prompt) { + // 如果任务状态不是成功且URL为空,则更新任务状态和URL + if (!toProductImageResult.getStatus().equals("Success") + && StringUtil.isNullOrEmpty(toProductImageResult.getUrl())) { + toProductImageResult.setStatus("Success"); + toProductImageResult.setUrl(fluxImgMinioPath); + toProductImageResultMapper.updateById(toProductImageResult); + } + + // 创建返回结果对象并设置基本信息 + MagicToolResultVO magicToolResultVO = CopyUtil.copyObject(toProductImageResult, MagicToolResultVO.class); + magicToolResultVO.setTaskId(taskId); + magicToolResultVO.setId(toProductImageResult.getId()); + // 设置Flux生成图片的预签名URL(使用系统配置的过期时间) + magicToolResultVO.setUrl(minioUtil.getPreSignedUrl(fluxImgMinioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + magicToolResultVO.setStatus("Success"); + magicToolResultVO.setResultType(toProductImageResult.getResultType()); + magicToolResultVO.setElementId(toProductImageResult.getElementId()); + magicToolResultVO.setElementType(toProductImageResult.getElementType()); + magicToolResultVO.setPrompt(prompt); + + // 根据元素类型设置源图片URL和父ID + if (toProductImageResult.getElementType().equals("ProductElement")) { + // 处理产品元素类型:获取产品元素信息并设置源图片URL + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); + + // 通过CollectionSort服务获取父ID + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } else if (toProductImageResult.getElementType().equals("DesignOutfit")) { + // 处理设计服装类型:获取设计服装信息并设置源图片URL + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); + + // 通过设计服装ID查找对应的用户喜欢记录,获取父ID + QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); + userLikeQueryWrapper.lambda().eq(UserLike::getDesignOutfitId, tDesignPythonOutfit.getId()); + List userLikeList = userLikeMapper.selectList(userLikeQueryWrapper); + if (!CollectionUtils.isEmpty(userLikeList)) { + UserLike userLike = userLikeList.get(0); + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(userLike.getId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } + } else if (toProductImageResult.getElementType().equals("ToProductImage")) { + // 处理转产品图像类型:获取转产品图像信息并设置源图片URL + ToProductImageResult toProductImage = toProductImageResultMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductImage.getUrl(), 24 * 60)); + + // 直接通过元素ID和类型获取父ID + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } + +// Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getId(), toProductImageResult.getResultType()); +// magicToolResultVO.setParentId(parentId); + return magicToolResultVO; + } + + @Override + public JSONObject exportSearch(ExportSearchDTO exportSearchDTO) { + QueryWrapper qw = new QueryWrapper<>(); + if (Objects.nonNull(exportSearchDTO.getProjectId())) { + qw.lambda().eq(ExportFile::getProjectId, exportSearchDTO.getProjectId()); + } else if (Objects.nonNull(exportSearchDTO.getId())) { + qw.lambda().eq(ExportFile::getId, exportSearchDTO.getId()); + } + qw.lambda().eq(ExportFile::getModule, exportSearchDTO.getModule()); + List exportFiles = exportFileMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(exportFiles)) { + try { + InputStream download = minioUtil.download(exportFiles.get(0).getUrl()); + String convert = convert(download); + JSONObject jsonObject = JSONObject.parseObject(convert); + + JSONObject canvas = jsonObject.getJSONObject("canvas"); + if (Objects.nonNull(canvas)) { + JSONArray objectJSONArrayLevel1 = canvas.getJSONArray("objects"); + for (int i = 0; i < objectJSONArrayLevel1.size(); i++) { + JSONObject jsonObjectLevel1 = objectJSONArrayLevel1.getJSONObject(i); + String type = jsonObjectLevel1.getString("type"); + if (type.equals("image")) { + String minioUrl = jsonObjectLevel1.getString("minioUrl"); + if (!StringUtil.isNullOrEmpty(minioUrl)) + jsonObjectLevel1.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); + } + if (type.equals("group")) { + JSONArray objectJSONArrayLevel2 = jsonObjectLevel1.getJSONArray("objects"); + for (int j = 0; j < objectJSONArrayLevel2.size(); j++) { + JSONObject jsonObjectLevel2 = objectJSONArrayLevel2.getJSONObject(j); + String typeGroup = jsonObjectLevel2.getString("type"); + if (typeGroup.equals("image") && !StringUtil.isNullOrEmpty(jsonObjectLevel2.getString("minioUrl"))) { + String minioUrl = jsonObjectLevel2.getString("minioUrl"); + jsonObjectLevel2.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); + } + objectJSONArrayLevel2.set(j, jsonObjectLevel2); + } + jsonObjectLevel1.put("objects", objectJSONArrayLevel2); + } + /*if (type.equals("rect")) { + JSONObject custom = jsonObjectLevel1.getJSONObject("custom"); + if (custom.getString("type").equals("init")) { + String minioUrl = jsonObjectLevel1.getString("minioUrl"); + if (!StringUtils.isEmpty(minioUrl)) { + JSONObject fill = jsonObjectLevel1.getJSONObject("fill"); + fill.put("source", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); + jsonObjectLevel1.put("fill", fill); + } + } + }*/ + objectJSONArrayLevel1.set(i, jsonObjectLevel1); + } + canvas.put("objects", objectJSONArrayLevel1); + jsonObject.put("canvas", canvas); + } else { + JSONArray objectJSONArrayLevel1 = jsonObject.getJSONArray("objects"); + for (int i = 0; i < objectJSONArrayLevel1.size(); i++) { + JSONObject jsonObjectLevel1 = objectJSONArrayLevel1.getJSONObject(i); + String type = jsonObjectLevel1.getString("type"); + if (type.equals("image")) { + String minioUrl = jsonObjectLevel1.getString("minioUrl"); + if (!StringUtil.isNullOrEmpty(minioUrl)) + jsonObjectLevel1.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); + } + if (type.equals("group")) { + JSONArray objectJSONArrayLevel2 = jsonObjectLevel1.getJSONArray("objects"); + for (int j = 0; j < objectJSONArrayLevel2.size(); j++) { + JSONObject jsonObjectLevel2 = objectJSONArrayLevel2.getJSONObject(j); + String typeGroup = jsonObjectLevel2.getString("type"); + if (typeGroup.equals("image") && !StringUtil.isNullOrEmpty(jsonObjectLevel2.getString("minioUrl"))) { + String minioUrl = jsonObjectLevel2.getString("minioUrl"); + jsonObjectLevel2.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); + } + objectJSONArrayLevel2.set(j, jsonObjectLevel2); + } + jsonObjectLevel1.put("objects", objectJSONArrayLevel2); + } + /*if (type.equals("rect")) { + JSONObject custom = jsonObjectLevel1.getJSONObject("custom"); + if (custom.getString("type").equals("init")) { + String minioUrl = jsonObjectLevel1.getString("minioUrl"); + if (!StringUtils.isEmpty(minioUrl)) { + JSONObject fill = jsonObjectLevel1.getJSONObject("fill"); + fill.put("source", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); + jsonObjectLevel1.put("fill", fill); + } + } + }*/ + objectJSONArrayLevel1.set(i, jsonObjectLevel1); + } + jsonObject.put("objects", objectJSONArrayLevel1); + } + return jsonObject; + } catch (Exception e) { + log.error(e.getMessage()); + return null; + } + } else { + return null; + } + } + + @Override + public CanvasElementUpload canvasElementUpload(MultipartFile file) { + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + CanvasElementUpload canvasElementUpload = new CanvasElementUpload(); + String url = minioUtil.upload("aida-users", userHolder.getId() + "/canvasElementUpload", file); + canvasElementUpload.setUrl(url); + canvasElementUpload.setMinioUrl(minioUtil.getPreSignedUrl(url, 24 * 60)); + return canvasElementUpload; + } + + @Override + public List productImageLikeList(ToProductImageDTO toProductImageDTO) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ToProductImageResult::getIsLike, 1); + + Long projectId = toProductImageDTO.getProjectId(); +// UserLikeGroup userLikeGroup = getByProjectId(projectId); +// Long userLikeGroupId = null; + + qw.lambda().eq(ToProductImageResult::getProjectId, projectId); + List toProductImageResults = toProductImageResultMapper.selectList(qw); + for (ToProductImageResult toProductImageResult : toProductImageResults) { + toProductImageResult.setUrl(minioUtil.getPreSignedUrl(toProductImageResult.getUrl(), 24 * 60)); + } + List toProductImageResultVOS = CopyUtil.copyList(toProductImageResults, ToProductImageResultVO.class); + for (ToProductImageResultVO toProductImageResultVO : toProductImageResultVOS) { + if (toProductImageResultVO.getElementType().equals("ProductElement")) { + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); + } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); + } else { + ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductImageResult1.getUrl(), 24 * 60)); + } + } + // 更新项目更新时间 + projectService.modifyProjectUpdateTime(toProductImageDTO.getProjectId()); + return toProductImageResultVOS; + } + + @Override + public Boolean productImageUnLike(ProductImageLikeDTO productImageLikeDTO) { + List toProductImageResultId = productImageLikeDTO.getToProductImageResultId(); + if (!CollectionUtils.isEmpty(toProductImageResultId)) { + Long toProductImageId = toProductImageResultId.get(0); + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(toProductImageId); + toProductImageResult.setIsLike(0); + toProductImageResultMapper.updateById(toProductImageResult); + if (toProductImageResult.getResultType().equals(CollectionType.RELIGHT.getValue())) { + if (null != productImageLikeDTO.getCollectionSortParentId()) { + collectionSortService.deleteCollectionSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), productImageLikeDTO.getProjectId(), productImageLikeDTO.getCollectionSortParentId()); + } + } else { + if (null != productImageLikeDTO.getCollectionSortParentId()) { + collectionSortService.deleteCollectionSort(toProductImageResult.getId(), CollectionType.TO_PRODUCT_IMAGE.getValue(), productImageLikeDTO.getProjectId(), productImageLikeDTO.getCollectionSortParentId()); + } + } + } + // 更新项目更新时间 + projectService.modifyProjectUpdateTime(productImageLikeDTO.getProjectId()); + return Boolean.TRUE; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void relight(String taskId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ToProductImageResult::getTaskId, taskId); + List toProductImageResults = toProductImageResultMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(toProductImageResults)) { + ToProductImageResult toProductImageResultOne = toProductImageResults.get(0); + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResultOne.getToProductImageRecordId()); + String prompt = toProductImageRecord.getPrompt(); + + // 翻译 + String s = ""; + if (!StringUtil.isNullOrEmpty(prompt)) { + s = pythonService.promptTranslate(prompt); + } else { + s = "Snow moutain, snowy day, natural light"; + } + String elementType = toProductImageResultOne.getElementType(); + if (elementType.equals("ToProductImage")) { + ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultOne.getElementId()); + String relightType = "overall"; + if (toProductImageResult1.getElementType().equals("DesignOutfit")) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult1.getElementId()); + Long designId = tDesignPythonOutfit.getDesignId(); + Design design = designMapper.selectById(designId); + if (design.getSingleOverall().equals("single")) { + relightType = "single"; + } + } + + // 走模型 + pythonService.relight(toProductImageResult1.getUrl(), taskId, s, toProductImageResultOne.getDirection(), "single"); + } else { + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultOne.getElementId()); + // 走模型 + pythonService.relight(toProductElement.getUrl(), taskId, s, toProductImageResultOne.getDirection(), "single"); + } + + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public List relight(ToProductImageDTO toProductImageDTO) { + // 判断用户当前积分是否够本次生成消耗 + boolean fluxTask = !StringUtil.isNullOrEmpty(toProductImageDTO.getModelName()) + && toProductImageDTO.getModelName().equals("flux"); + CreditsEventsEnum creditsEventsEnum = fluxTask ? CreditsEventsEnum.RELIGHT_FLUX : CreditsEventsEnum.RELIGHT; + Boolean preDeduction = creditsService.creditsPreDeduction(creditsEventsEnum, toProductImageDTO.getToProductImageVOList().size()); + if (!preDeduction) { + throw new BusinessException("remaining.credits.insufficient", ResultEnum.WARNING.getCode()); + } + + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + Long projectId = toProductImageDTO.getProjectId(); + UserLikeGroup userLikeGroup = getByProjectId(projectId); + Long userLikeGroupId = null; + + ToProductImageRecord toProductImageRecord = new ToProductImageRecord(); + toProductImageRecord.setProjectId(projectId); + if (Objects.nonNull(userLikeGroup)) { + userLikeGroupId = userLikeGroup.getId(); + toProductImageRecord.setUserLikeGroupId(userLikeGroupId); + } + + // 翻译 + String prompt = toProductImageDTO.getPrompt(); + String s = ""; + if (!StringUtil.isNullOrEmpty(prompt)) { + s = pythonService.promptTranslate(prompt); + } else { +// s = "Snow moutain, snowy day, natural light"; + s = "Street, natural light"; + } + // 对输入文本进行长度限制 + String[] words = prompt.split("\\s+"); + if (words.length > 200) { + throw new BusinessException("Please keep your input text under 200 words. Thanks!"); + } + + toProductImageRecord.setCreateTime(LocalDateTime.now()); + if (!StringUtils.isEmpty(toProductImageDTO.getPrompt())) { + toProductImageRecord.setPrompt(toProductImageDTO.getPrompt()); + } + toProductImageRecordMapper.insert(toProductImageRecord); + + List result = new ArrayList<>(); + + int i = 0; + + for (ToProductImageVO toProductImageVO : toProductImageDTO.getToProductImageVOList()) { + String taskId = UUID.randomUUID() + "-" + i + "-" + userHolder.getId(); + i++; + if (toProductImageVO.getElementType().equals("ToProductImage")) { + ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageVO.getElementId()); + String relightType = "overall"; + if (toProductImageResult1.getElementType().equals("DesignOutfit")) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResult1.getElementId()); + Long designId = tDesignPythonOutfit.getDesignId(); + Design design = designMapper.selectById(designId); + if (design.getSingleOverall().equals("single")) { + relightType = "single"; + } + } + + ToProductImageResultVO toProductImageResult = new ToProductImageResultVO(); + if (fluxTask) { + taskId = generateService.flux(creditsEventsEnum, s, toProductImageResult1.getUrl(), false); + toProductImageResult.setModelName("flux"); + toProductImageResult.setResultType(CollectionType.RELIGHT.getValue()); + } else { + // 走模型 + pythonService.relight(toProductImageResult1.getUrl(), taskId, s, toProductImageDTO.getDirection(), relightType); + } + toProductImageResult.setElementId(toProductImageResult1.getId()); + toProductImageResult.setElementType("ToProductImage"); + toProductImageResult.setCreateTime(LocalDateTime.now()); + toProductImageResult.setToProductImageRecordId(toProductImageRecord.getId()); +// toProductImageResult.setUrl(productImageUrl); + toProductImageResult.setIsLike(0); + toProductImageResult.setTaskId(taskId); + toProductImageResult.setProjectId(projectId); + if (null != userLikeGroupId) { + toProductImageResult.setUserLikeGroupId(userLikeGroupId); + } + if (toProductImageDTO.getBrightenValue() != null) { + toProductImageResult.setBrightenValue(toProductImageDTO.getBrightenValue()); + } + toProductImageResult.setDirection(toProductImageDTO.getDirection()); + toProductImageResult.setResultType(CollectionType.RELIGHT.getValue()); + toProductImageResult.setStatus("Pending"); + toProductImageResultMapper.insert(toProductImageResult); +// toProductImageResult.setUrl(minioUtil.getPresignedUrl(toProductImageResult.getUrl(), 24 * 60)); + // 先判断是否需要默认like + if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && toProductImageDTO.getIsDefaultLike()) { + // 满足条件情况下默认添加到like + CollectionSort collectionSort = addToProductLike(toProductImageVO.getParentId(), toProductImageResult.getId(), toProductImageDTO.getProjectId()); + // 重新排序 + Integer reSort = collectionSortService.rearrangeChildSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), + toProductImageVO.getParentId(), toProductImageVO.getUserLikeSortId()); + // 将生成结果的排序返回 + toProductImageResult.setSort(Objects.isNull(reSort) ? Objects.isNull(collectionSort) ? null : collectionSort.getSort() : reSort); + toProductImageResult.setParentId(toProductImageVO.getParentId()); + toProductImageResult.setUserLikeSortId(Objects.isNull(collectionSort) ? null : collectionSort.getId()); + } else if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && Objects.nonNull(toProductImageVO.getParentId())) { + toProductImageResult.setParentId(toProductImageVO.getParentId()); + // 默认不添加到like,但是需要有parentId,所以这里添加到collectionSort表中 +// designService.addCollectionSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), toProductImageDTO.getProjectId(), toProductImageVO.getParentId()); + } + result.add(toProductImageResult); + } else { + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageVO.getElementId()); + ToProductImageResultVO toProductImageResult = new ToProductImageResultVO(); + if (fluxTask) { + taskId = generateService.flux(CreditsEventsEnum.RELIGHT_FLUX, s, toProductElement.getUrl(), false); + toProductImageResult.setModelName("flux"); + toProductImageResult.setResultType(CollectionType.RELIGHT.getValue()); + } else { + // 走模型 + pythonService.relight(toProductElement.getUrl(), taskId, s, toProductImageDTO.getDirection(), "overall"); + } + toProductImageResult.setElementId(toProductElement.getId()); + toProductImageResult.setElementType("ProductElement"); + toProductImageResult.setCreateTime(LocalDateTime.now()); + toProductImageResult.setToProductImageRecordId(toProductImageRecord.getId()); +// toProductImageResult.setUrl(productImageUrl); + toProductImageResult.setIsLike(0); + toProductImageResult.setTaskId(taskId); + toProductImageResult.setProjectId(projectId); + if (null != userLikeGroupId) { + toProductImageResult.setUserLikeGroupId(userLikeGroupId); + } + if (toProductImageDTO.getBrightenValue() != null) { + toProductImageResult.setBrightenValue(toProductImageDTO.getBrightenValue()); + } + toProductImageResult.setDirection(toProductImageDTO.getDirection()); + toProductImageResult.setResultType(CollectionType.RELIGHT.getValue()); + toProductImageResult.setStatus("Pending"); + toProductImageResultMapper.insert(toProductImageResult); +// toProductImageResult.setUrl(minioUtil.getPresignedUrl(toProductImageResult.getUrl(), 24 * 60)); + // 先判断是否需要默认like + if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && toProductImageDTO.getIsDefaultLike()) { + // 满足条件情况下默认添加到like + CollectionSort collectionSort = addToProductLike(toProductImageVO.getParentId(), toProductImageResult.getId(), toProductImageDTO.getProjectId()); + // 重新排序 + Integer reSort = collectionSortService.rearrangeChildSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), + toProductImageVO.getParentId(), toProductImageVO.getUserLikeSortId()); + // 将生成结果的排序返回 + toProductImageResult.setSort(Objects.isNull(reSort) ? Objects.isNull(collectionSort) ? null : collectionSort.getSort() : reSort); + toProductImageResult.setParentId(toProductImageVO.getParentId()); + toProductImageResult.setUserLikeSortId(Objects.isNull(collectionSort) ? null : collectionSort.getId()); + } else if (Objects.nonNull(toProductImageDTO.getIsDefaultLike()) && Objects.nonNull(toProductImageVO.getParentId())) { + toProductImageResult.setParentId(toProductImageVO.getParentId()); + // 默认不添加到like,但是需要有parentId,所以这里添加到collectionSort表中 +// designService.addCollectionSort(toProductImageResult.getId(), CollectionType.RELIGHT.getValue(), toProductImageDTO.getProjectId(), toProductImageVO.getParentId()); + } + result.add(toProductImageResult); + } + // 添加需要扣除的积分到预扣除区 + creditsService.addRecordToCreditsDeduction(userHolder.getId(), taskId, creditsEventsEnum); + // 添加积分扣除记录到db + creditsService.preInsert(userHolder.getId(), creditsEventsEnum.getName(), taskId, Boolean.TRUE, null); + } + // 更新项目更新时间 + projectService.modifyProjectUpdateTime(toProductImageDTO.getProjectId()); + return result; + } + + @Override + public List getRelightResult(List taskIdList) { + List results = new ArrayList<>(); + Set collect = new HashSet<>(); + taskIdList.forEach(taskId -> { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ToProductImageResult::getTaskId, taskId); + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(qw); + if (Objects.isNull(toProductImageResult)) { + throw new BusinessException("source.image.does.not.exist"); + } + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); + if (Objects.isNull(toProductImageRecord)) { + throw new BusinessException("This task does not exist."); + } + // 判断当任务从哪个模型获取结果 + if (!StringUtil.isNullOrEmpty(toProductImageResult.getModelName()) + && toProductImageResult.getModelName().equals("flux")) { + Project project = projectService.getById(toProductImageResult.getProjectId()); + if (Objects.isNull(project)) { + throw new BusinessException("unknown project"); + } + String fluxResult; + if (toProductImageResult.getStatus().equals("Success") && !StringUtil.isNullOrEmpty(toProductImageResult.getUrl())) { + fluxResult = toProductImageResult.getUrl(); + } else { + String objectName = project.getAccountId() + "/relight_image/" + taskId + ".png"; + fluxResult = generateService.getFluxResult(taskId, objectName); + } + + if (StringUtil.isNullOrEmpty(fluxResult)) { + toProductImageResult.setStatus("Fail"); + toProductImageResultMapper.updateById(toProductImageResult); + if (toProductImageResult.getIsLike() != null && toProductImageResult.getIsLike() == 1) { + sortRank(toProductImageResult); + } + results.add(new MagicToolResultVO(taskId, "Fail")); + } else if (fluxResult.equals("Fail") || fluxResult.equals("Pending")) { + toProductImageResult.setStatus(fluxResult); + toProductImageResultMapper.updateById(toProductImageResult); + if (fluxResult.equals("Fail") && toProductImageResult.getIsLike() != null && toProductImageResult.getIsLike() == 1) { + sortRank(toProductImageResult); + } + results.add(new MagicToolResultVO(taskId, fluxResult)); + } else { + results.add(processFluxResult(fluxResult, toProductImageResult, taskId, toProductImageRecord.getPrompt())); + // 扣积分 + Boolean flag = creditsService.taskCreditsDeduction(project.getAccountId(), taskId); + if (flag) creditsService.updateChangedCredits(String.valueOf(project.getAccountId()), taskId); + } + // 将积分暂扣区的积分移除 + if (toProductImageResult.getStatus().equals("Fail")) { + creditsService.deleteCreditsDeduction(project.getAccountId(), taskId); + } + + return; + } + + String key = relightResultKey + ":" + taskId; + MagicToolResultVO magicToolResultVO = new Gson().fromJson(redisUtil.getFromString(key), MagicToolResultVO.class); + if (!Objects.isNull(magicToolResultVO) && !StringUtil.isNullOrEmpty(magicToolResultVO.getUrl())) { + String url = magicToolResultVO.getUrl(); + magicToolResultVO.setDirection(toProductImageResult.getDirection()); + magicToolResultVO.setBrightenValue(toProductImageResult.getBrightenValue()); + magicToolResultVO.setImageStrength(toProductImageResult.getImageStrength()); + magicToolResultVO.setPrompt(toProductImageRecord.getPrompt()); + if (url.substring(url.lastIndexOf("/") + 1).equals("white_image.jpg")) { + magicToolResultVO.setStatus("Invalid"); + } else { + magicToolResultVO.setUrl(minioUtil.getPreSignedUrl(url, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + + magicToolResultVO.setResultType(toProductImageResult.getResultType()); + magicToolResultVO.setElementId(toProductImageResult.getElementId()); + magicToolResultVO.setElementType(toProductImageResult.getElementType()); + if (toProductImageResult.getElementType().equals("ProductElement")) { + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductElement.getUrl(), 24 * 60)); + } else { + ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResult.getElementId()); + magicToolResultVO.setSourceUrl(minioUtil.getPreSignedUrl(toProductImageResult1.getUrl(), 24 * 60)); + } + Long parentId = collectionSortService.getParentIdByElementIdAndElementType(toProductImageResult.getElementId(), toProductImageResult.getElementType()); + magicToolResultVO.setParentId(parentId); + } + } else if (Objects.isNull(magicToolResultVO)) { + magicToolResultVO = new MagicToolResultVO(); + } + if (!StringUtil.isNullOrEmpty(magicToolResultVO.getStatus())) collect.add(magicToolResultVO.getStatus()); + results.add(magicToolResultVO); + }); + return results; + } + + /* + 重排Relight失败sort + */ + private void sortRank(ToProductImageResult toProductImageResult) { + LambdaQueryWrapper collectionSortLambdaQueryWrapper = new LambdaQueryWrapper<>(); + collectionSortLambdaQueryWrapper.eq(CollectionSort::getRelationId, toProductImageResult.getId()).orderByDesc(CollectionSort::getCreateTime).last("LIMIT 1"); + + List collectionSorts = collectionSortMapper.selectList(collectionSortLambdaQueryWrapper); + + if (!collectionSorts.isEmpty()) { + + collectionSortMapper.deleteById(collectionSorts.get(0)); + List collectionSorts1 = collectionSortMapper.selectList(new LambdaQueryWrapper().eq(CollectionSort::getParentId, collectionSorts.get(0).getParentId()).gt(CollectionSort::getSort, collectionSorts.get(0).getSort())); + if (!collectionSorts1.isEmpty()) { + for (CollectionSort collectionSort : collectionSorts1) { + collectionSort.setSort(collectionSort.getSort() - 1); + collectionSortMapper.updateById(collectionSort); + } + } + } + } + + public static String convert(InputStream inputStream) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { + return reader.lines().collect(Collectors.joining("\n")); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + @Transactional(rollbackFor = Exception.class) + public void deleteToProductRelightResult(Long id, Long projectId, String type) { + // 1. 权限校验和删除主数据 + Long accountId = UserContext.getUserHolder().getId(); + Project project = projectService.getById(projectId); + if (!project.getAccountId().equals(accountId)) { + throw new IllegalArgumentException("项目不属于当前账号"); + } + + // 2. 删除主表数据 + UpdateWrapper wrapper = new UpdateWrapper<>(); + wrapper.lambda().eq(ToProductImageResult::getProjectId, projectId) + .eq(ToProductImageResult::getId, id).or().eq(ToProductImageResult::getElementId, id) + .set(ToProductImageResult::getIsDeleted, 1); + + int update = toProductImageResultMapper.update(null, wrapper); + log.info("删除 {} 结果, id={}, 影响行数={}", type, id, update); + + if (update == 0) { + return; // 未删除任何数据,直接返回 + } + + // 3. 查询所有被删除的排序项(按sort升序) + List deletedItems = collectionSortMapper.selectList( + new QueryWrapper() + .eq("project_id", projectId) + .eq("relation_id", id) + .eq("relation_type", type) + .orderByAsc("sort") + ); + + if (deletedItems.isEmpty()) return; + + // 4. 删除这些记录 + int deletedCount = collectionSortMapper.delete( + new QueryWrapper() + .eq("project_id", projectId) + .eq("relation_id", id) + .eq("relation_type", type) + ); + log.info("删除排序记录:id={}, type={}, 影响行数={}", id, type, deletedCount); + + // 5. 对每个被删除的sort值,单独调整后续记录 + for (CollectionSort deletedItem : deletedItems) { + collectionSortMapper.update( + null, + new UpdateWrapper() + .eq("project_id", projectId) + .gt("sort", deletedItem.getSort()) + .setSql("sort = sort - 1") // 每条SQL只减1 + ); + } + } + + @Override + public String likeHistoryRelSketch() { + QueryWrapper qw = new QueryWrapper<>(); + List userLikeGroups = userLikeGroupMapper.selectList(qw); + List>> result = new ArrayList<>(); + + for (UserLikeGroup userLikeGroup : userLikeGroups) { + Long accountId = userLikeGroup.getAccountId(); + Long collectionId = userLikeGroup.getCollectionId(); + + // 提前转换为Set以提高contains的效率 + List collectionElements = getCollectionElementsByCollectionId(collectionId); + Set urlSet = collectionElements.stream() + .map(CollectionElement::getUrl) + .collect(Collectors.toSet()); + + List userLikes = getUserLikesByGroupId(userLikeGroup.getId()); + + for (UserLike userLike : userLikes) { + List> userLikeSketchList = new ArrayList<>(); + List designItemDetails = getDesignItemDetails(userLike.getDesignItemId()); + + for (DesignItemDetail designItemDetail : designItemDetails) { + Map sketch = new HashMap<>(); + String path = designItemDetail.getPath(); + + // 下载路径到本地 +// if (!StringUtils.isEmpty(path)) { +// String bucketName = minioUtil.getBucketNameFromPath(path); +// String objectName = minioUtil.getObjectNameFromPath(path); +// String localBasePath = "C:\\workspace\\fileData\\minio"; +// String localFilePath = Paths.get(localBasePath, path).toString(); +// +// // 检查文件是否已经存在,避免重复下载 +// File localFile = new File(localFilePath); +// if (!localFile.exists()) { +// minioUtil.downloadMinioObjectToLocal(bucketName, objectName, localFilePath); +// } else { +// log.info("File already exists, skipping download: {}", localFilePath); +// } +// } + + Long designId = designItemDetail.getDesignId(); + Design design = designMapper.selectById(designId); + if (null == design) { + continue; + } + if (design.getSingleOverall().equals("single")) { + continue; + } + if (design.getModelType().equals("System")) { + SysFile sysFile = sysFileMapper.selectById(design.getTemplateId()); + if (null == sysFile) { + continue; + } + sketch.put("sex", sysFile.getLevel2Type().equals("Male") ? "Male" : "Female"); + } else { + Library library = libraryMapper.selectById(design.getTemplateId()); + if (null == library) { + continue; + } + sketch.put("sex", library.getLevel2Type().equals("Female") ? "Female" : "Male"); + } + + sketch.put("type", designItemDetail.getType()); + sketch.put("path", path); + sketch.put("beSelected", urlSet.contains(path)); + sketch.put("accountId", accountId); + + if (path.contains("aida-sys-image/images/")) { + String replace = path.replace("aida-sys-image/images/", ""); + String style = getStyleByUrl(replace); + if (!StringUtils.isEmpty(style)) { + sketch.put("style", style); + } + } + userLikeSketchList.add(sketch); + } + if (CollectionUtil.isNotEmpty(userLikeSketchList)) { + result.add(userLikeSketchList); + } + } + } + + // 将结果以美观的JSON形式保存到文件中 + saveResultAsPrettyJson(result, "C:\\Users\\10233\\Desktop\\result.json"); + + return null; + } + + @Override + public String download() { + // 下载 aida-collection-element bucket 下所有 Sketchboard 文件夹内容 +// String sketchboardLocalPath = "C:\\workspace\\fileData\\minio"; +// minioUtil.downloadSketchboardDirectories(sketchboardLocalPath); +// +// // 下载整个 aida-users bucket +// String aidaUsersLocalPath = "C:\\workspace\\fileData\\minio"; +// minioUtil.downloadEntireBucket("aida-users", aidaUsersLocalPath); + return null; + } + + // 提取公共方法 + private List getCollectionElementsByCollectionId(Long collectionId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionElement::getCollectionId, collectionId) + .eq(CollectionElement::getLevel1Type, "Sketchboard"); + return collectionElementMapper.selectList(qw); + } + + private List getUserLikesByGroupId(Long groupId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(UserLike::getUserLikeGroupId, groupId); + return userLikeMapper.selectList(qw); + } + + private List getDesignItemDetails(Long designItemId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(DesignItemDetail::getDesignItemId, designItemId) + .ne(DesignItemDetail::getType, "Body"); + return designItemDetailService.list(qw); + } + + private void saveResultAsPrettyJson(List>> result, String filePath) { + // 使用一个 Map 将结果存储为字符串键 + Map resultMap = new HashMap<>(); + resultMap.put("data", result); + + try (FileWriter file = new FileWriter(filePath)) { + // 使用 JSONObject 将转换后的 Map 转为 JSON + JSONObject jsonObject = new JSONObject(resultMap); + // 格式化输出为美观的 JSON + file.write(JSON.toJSONString(jsonObject, SerializerFeature.PrettyFormat)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + private String getStyleByUrl(String replace) { + String[] split = replace.split("/"); + String tableName = getTableName(split); + if (StringUtils.isEmpty(tableName)) { + return null; + } else { + replace = split[1] + "/" + split[2]; + return attributeRetrievalMapper.getStyleByUrl(replace, tableName); + } + } + + private String getTableName(String[] split) { + switch (split[0]) { + case "female": { + switch (split[1]) { + case "blouse": { + return "female_top"; + } + case "trousers": { + return "female_pants"; + } + case "skirt": { + return "female_skirt"; + } + case "outwear": { + return "female_outwear"; + } + case "dress": { + return "female_dress"; + } + default: { + return null; + } + } + } + case "male": { + switch (split[1]) { + case "top": { + return "male_top"; + } + case "bottom": { + return "male_bottom"; + } + case "outwear": { + return "male_outwear"; + } + default: { + return null; + } + } + } + default: { + return null; + } + } + } + + @Override + public Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO) { + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + productImageService.asyncInitialize(productImageInitializeDTO.getBrandId(), userHolder); + return true; + } + + @Override + public InitializeProgressVO getInitializeProgress(ProductImageInitializeDTO productImageInitializeDTO) { + InitializeProgressVO vo = new InitializeProgressVO(); + +// QueryWrapper<> + + ProgressDTO dto = redisUtil.getTaskProgressDTO(String.valueOf(productImageInitializeDTO.getBrandId())); + + if (Objects.isNull(dto)) { + vo.setAnalyzed(false); + return vo; + } + vo.setAnalyzed(true); + vo.setComputeTime(dto.getComputeTime()); + if (dto.getTotal() == 0 || dto.isError()) { + vo.setPercent(0.0); + return vo; + } + vo.setPercent(dto.getCurrent() * 1.0 / dto.getTotal()); + return vo; + } + + private ProductImageAttribute toAttrDict(AttributeRecognitionJSON attrDictJSON) { + ProductImageAttribute attributeRetrieval = new ProductImageAttribute(); + + // 处理 imgName +// if (CollectionUtil.isNotEmpty(attrDictJSON.getImgName()) && attrDictJSON.getImgName().get(0) != null) { +// attributeRetrieval.setImgName(attrDictJSON.getImgName().get(0)); +// } + // 处理 length + if (CollectionUtil.isNotEmpty(attrDictJSON.getLength()) && attrDictJSON.getLength().get(0) != null) { + attributeRetrieval.setLength(attrDictJSON.getLength().get(0)); + } + // 处理 sleeveLength + if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveLength()) && attrDictJSON.getSleeveLength().get(0) != null) { + attributeRetrieval.setSleeveLength(attrDictJSON.getSleeveLength().get(0)); + } + // 处理 sleeveShape + if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveShape()) && attrDictJSON.getSleeveShape().get(0) != null) { + attributeRetrieval.setSleeveShape(attrDictJSON.getSleeveShape().get(0)); + } + // 处理 sleeveShoulder + if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveShoulder()) && attrDictJSON.getSleeveShoulder().get(0) != null) { + attributeRetrieval.setSleeveShoulder(attrDictJSON.getSleeveShoulder().get(0)); + } + // 处理 neckline + if (CollectionUtil.isNotEmpty(attrDictJSON.getNeckline()) && attrDictJSON.getNeckline().get(0) != null) { + attributeRetrieval.setNeckline(attrDictJSON.getNeckline().get(0)); + } + // 处理 collar + if (CollectionUtil.isNotEmpty(attrDictJSON.getCollar()) && attrDictJSON.getCollar().get(0) != null) { + attributeRetrieval.setCollar(attrDictJSON.getCollar().get(0)); + } + // 处理 design + if (CollectionUtil.isNotEmpty(attrDictJSON.getDesign()) && attrDictJSON.getDesign().get(0) != null) { + attributeRetrieval.setDesign(attrDictJSON.getDesign().get(0)); + } + // 处理 silhouette + if (CollectionUtil.isNotEmpty(attrDictJSON.getSilhouette()) && attrDictJSON.getSilhouette().get(0) != null) { + attributeRetrieval.setSilhouette(attrDictJSON.getSilhouette().get(0)); + } + // 处理 type + if (CollectionUtil.isNotEmpty(attrDictJSON.getType()) && attrDictJSON.getType().get(0) != null) { + attributeRetrieval.setType(attrDictJSON.getType().get(0)); + } + // 处理 openingType + if (CollectionUtil.isNotEmpty(attrDictJSON.getOpeningType()) && attrDictJSON.getOpeningType().get(0) != null) { + attributeRetrieval.setOpeningType(attrDictJSON.getOpeningType().get(0)); + } + // 处理 subtype + if (CollectionUtil.isNotEmpty(attrDictJSON.getSubtype()) && attrDictJSON.getSubtype().get(0) != null) { + attributeRetrieval.setSubtype(attrDictJSON.getSubtype().get(0)); + } + + return attributeRetrieval; + } + +// private ProductImageAttribute toAttrDict(AttributeRecognitionJSON attrDictJSON) { +// ProductImageAttribute attributeRetrieval = new ProductImageAttribute(); + + /// / attributeRetrieval.setImgName(attrDictJSON.getImgName().get(0)); + /// / attributeRetrieval.setLength(attrDictJSON.getLength().get(0)); + /// / attributeRetrieval.setSleeveLength(attrDictJSON.getSleeveLength().get(0)); + /// / attributeRetrieval.setSleeveShape(attrDictJSON.getSleeveShape().get(0)); + /// / attributeRetrieval.setSleeveShoulder(attrDictJSON.getSleeveShoulder().get(0)); + /// / attributeRetrieval.setNeckline(attrDictJSON.getNeckline().get(0)); + /// / attributeRetrieval.setCollar(attrDictJSON.getCollar().get(0)); +// if (CollectionUtil.isNotEmpty(attrDictJSON.getDesign()) && attrDictJSON.getDesign().get(0) != null) { +// attributeRetrieval.setDesign(attrDictJSON.getDesign().get(0)); +// } +// if (CollectionUtil.isNotEmpty(attrDictJSON.getSilhouette()) && attrDictJSON.getSilhouette().get(0) != null) { +// attributeRetrieval.setSilhouette(attrDictJSON.getSilhouette().get(0)); +// } +// if (CollectionUtil.isNotEmpty(attrDictJSON.getType()) && attrDictJSON.getType().get(0) != null) { +// attributeRetrieval.setType(attrDictJSON.getType().get(0)); +// } +// if (CollectionUtil.isNotEmpty(attrDictJSON.getSubtype()) && attrDictJSON.getSubtype().get(0) != null) { +// attributeRetrieval.setSubtype(attrDictJSON.getSubtype().get(0)); +// } +// if (CollectionUtil.isNotEmpty(attrDictJSON.getOpeningType()) && attrDictJSON.getOpeningType().get(0) != null) { +// attributeRetrieval.setOpeningType(attrDictJSON.getOpeningType().get(0)); +// } +// return attributeRetrieval; +// } + @Override + public IPage getPage(ProjectQueryDTO query) { + AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); + // 分页数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + + queryWrapper.eq("account_id", authPrincipalVo.getId()); + if (Objects.nonNull(query.getId())) { + queryWrapper.eq("id", query.getId()); + } +// queryWrapper.isNull("parent_id"); + if (!StringUtils.isEmpty(query.getProjectName())) { + queryWrapper.like("name", query.getProjectName()); + } + if (Objects.nonNull(query.getStartDate())) { + queryWrapper.ge("update_time", new Date(query.getStartDate())); + } + if (Objects.nonNull(query.getEndDate())) { + queryWrapper.le("update_time", new Date(query.getEndDate())); + } + if (Objects.nonNull(query.getProcess()) && !query.getProcess().isEmpty()) { +// if (!StringUtils.isEmpty(query.getProcess())) { + // todo 获取历史列表,允许传入多个类型 + queryWrapper.in("process", query.getProcess()); +// queryWrapper.eq("process", query.getProcess()); + } + // 新增分类过滤 + if (CollectionUtil.isNotEmpty(query.getClassificationIdList())) { + List projectIdList = new ArrayList<>(); + if (query.getIntersection() == 0) { + for (Long classificationId : query.getClassificationIdList()) { + projectIdList.addAll(classificationService.getLibraryIdListByClassificationId(classificationId)); + } + if (CollectionUtil.isNotEmpty(projectIdList)) { + queryWrapper.in("id", projectIdList); + } else { + return new Page<>(); + } + } else { + for (int i = 0; i < query.getClassificationIdList().size(); i++) { + List historyIdListByClassificationId = classificationService.getLibraryIdListByClassificationId(query.getClassificationIdList().get(i)); + if (i == 0) { + projectIdList.addAll(historyIdListByClassificationId); + } else { + projectIdList.retainAll(historyIdListByClassificationId); + } + if (CollectionUtil.isEmpty(projectIdList)) { + return new Page<>(); + } + } + queryWrapper.in("id", projectIdList); + } + } + if (query.getAsc() != null && query.getAsc() == 1) { + queryWrapper.orderByAsc("update_time"); + } else { + queryWrapper.orderByDesc("update_time"); + } + IPage page = projectService.page( + new Page<>(query.getPage(), query.getSize()), queryWrapper); + if (CollectionUtils.isEmpty(page.getRecords())) { + return new Page<>(); + } + Set projectIdSet = page.getRecords().stream().map(Project::getId).collect(Collectors.toSet()); + QueryWrapper userLikeGroupQueryWrapper = new QueryWrapper<>(); + userLikeGroupQueryWrapper.lambda().in(UserLikeGroup::getProjectId, projectIdSet); + List userLikeGroups = userLikeGroupMapper.selectList(userLikeGroupQueryWrapper); + + Map> groupDetailMap = new HashMap<>(); + + if (CollectionUtil.isNotEmpty(userLikeGroups)) { + List groupIds = userLikeGroups.stream().map(UserLikeGroup::getId).collect(Collectors.toList()); + List groupDetails = userLikeService.getGroupDetails(groupIds); + + groupDetailMap = groupDetails.stream() + .collect(Collectors.groupingBy(UserLikeVO::getUserLikeGroupId)); + } + + Account account = accountMapper.selectById(authPrincipalVo.getId()); + Map> finalGroupDetailMap = groupDetailMap; + IPage convert = page.convert((Function) project -> { + if (project != null) { + + ProjectVO projectVO = CopyUtil.copyObject(project, ProjectVO.class); + if(project.getOriginal() == 0){ + //非原创 + projectVO.setOriginalAccountName(accountMapper.selectById(project.getOriginalAccountId()).getUserName()); + projectVO.setOriginalPortfolioName(portfolioMapper.getByIdAll(project.getOriginalPortfolioId()).getPortfolioName()); + } + // 用于排序的时间 + LocalDateTime orderTime = Objects.isNull(project.getUpdateTime()) ? project.getCreateTime() : project.getUpdateTime(); + projectVO.setUpdateDate(orderTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + + QueryWrapper userLikeGroupQueryWrapper1 = new QueryWrapper<>(); + userLikeGroupQueryWrapper1.lambda().eq(UserLikeGroup::getProjectId, projectVO.getId()); + UserLikeGroup userLikeGroup = userLikeGroupMapper.selectOne(userLikeGroupQueryWrapper1); + if (Objects.nonNull(userLikeGroup)) { + UserLikeGroupVO userLikeGroupVO = CopyUtil.copyObject(userLikeGroup, UserLikeGroupVO.class); + userLikeGroupVO.setAuthor(account.getUserName()); + //count 和detail + if (finalGroupDetailMap.keySet().contains(userLikeGroupVO.getId())) { + List details = finalGroupDetailMap.get(userLikeGroupVO.getId()); + for (UserLikeVO detail : details) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(detail.getDesignOutfitId()); + detail.setUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60)); + } + userLikeGroupVO.setGroupDetails(details); + userLikeGroupVO.setSketchCount(CollectionUtils.isEmpty(details) ? 0 : details.size()); + } else { + userLikeGroupVO.setSketchCount(0); + } +// if (userLikeGroupVO.getOriginal() == 0) { +// userLikeGroupVO.setOriginalAccountName(accountMapper.selectById(userLikeGroupVO.getOriginalAccountId()).getUserName()); +// Portfolio byId = portfolioMapper.getByIdAll(userLikeGroupVO.getOriginalPortfolioId()); +// if (Objects.nonNull(byId)) { +// String portfolioName = byId.getPortfolioName(); +// userLikeGroupVO.setOriginalPortfolioName(portfolioName); +// } +// } + projectVO.setUserLikeGroupVO(userLikeGroupVO); + } + return projectVO; + } + return null; + }); + return convert; + } + + + @Override + public ModuleChooseVO getModuleContent(ProjectDTO projectDTO) { + ModuleChooseVO moduleChooseVO = new ModuleChooseVO(); + moduleChooseVO.setProjectId(projectDTO.getId()); +// UserLikeCollectionVO userLikeCollectionVO = new UserLikeCollectionVO(); + LambdaQueryWrapper projectLambdaQueryWrapper = new LambdaQueryWrapper<>(); + projectLambdaQueryWrapper.select(Project::getAccountId).eq(Project::getId, projectDTO.getId()); + Project project = projectService.getOne(projectLambdaQueryWrapper); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + // 判空处理 + if (project != null && project.getAccountId() != null) { + queryWrapper.eq(CollectionElement::getAccountId, project.getAccountId()); + } + queryWrapper.eq(CollectionElement::getProjectId, projectDTO.getId()); + + List allCollectionElements = collectionElementMapper.selectList(queryWrapper); + + for (String module : projectDTO.getModuleList()) { + if (module.equals(Module.colorBoard.name())) { + List collectionElements = allCollectionElements.stream() + .filter(element -> CollectionLevel1TypeEnum.COLOR_BOARD.getRealName().equals(element.getLevel1Type())) + .collect(Collectors.toList()); + moduleChooseVO.setColorBoard(collectionService.resolveColorBoard(collectionElements)); + } else if (module.equals(Module.moodBoard.name())) { + MoodBoardModuleChooseVO moodBoardModuleChooseVO = new MoodBoardModuleChooseVO(); + + List collectionElements = allCollectionElements.stream() + .filter(element -> CollectionLevel1TypeEnum.MOOD_BOARD.getRealName().equals(element.getLevel1Type())) + .collect(Collectors.toList()); + + List list = new ArrayList<>(); + for (CollectionElement collectionElement : collectionElements) { + if (null != collectionElement.getIsCompositeImage() && collectionElement.getIsCompositeImage() == 1) { + moodBoardModuleChooseVO.setMoodTemplateId(String.valueOf(collectionElement.getId())); + moodBoardModuleChooseVO.setMoodTemplateName(collectionElement.getName()); + moodBoardModuleChooseVO.setMoodTemplateUrl(getMinioUrl(collectionElement.getUrl())); + + String moodboardPositionString = collectionService.getMoodboardPositionString(collectionElement.getId()); + if (!StringUtils.isEmpty(moodboardPositionString)) { + moodBoardModuleChooseVO.setMoodboardPosition(moodboardPositionString); + } + continue; + } + CollectionElementVO collectionElementVO = CopyUtil.copyObject(collectionElement, CollectionElementVO.class); + collectionElementVO.setDesignType(DesignTypeEnum.COLLECTION.getRealName()); + String url = collectionElement.getUrl(); + collectionElementVO.setOriginalUrl(url); + if (minioUtil.doesObjectExist(url)) { + collectionElementVO.setUrl(getMinioUrl(url)); + } + if (minioUtil.doesObjectExist(collectionElementVO.getOriginalUrl())) { + list.add(collectionElementVO); + } + } + moodBoardModuleChooseVO.setMoodBoards(list); + moduleChooseVO.setMoodBoard(moodBoardModuleChooseVO); + } else if (module.equals(Module.printBoard.name())) { + + List collectionElements = allCollectionElements.stream() + .filter(element -> CollectionLevel1TypeEnum.PRINT_BOARD.getRealName().equals(element.getLevel1Type())) + .collect(Collectors.toList()); + List list = new ArrayList<>(); + + for (CollectionElement collectionElement : collectionElements) { + CollectionElementVO collectionElementVO = CopyUtil.copyObject(collectionElement, CollectionElementVO.class); + collectionElementVO.setIsPin(collectionElement.getHasPin()); + collectionElementVO.setDesignType(DesignTypeEnum.COLLECTION.getRealName()); + String url = collectionElement.getUrl(); + collectionElementVO.setOriginalUrl(url); + if (minioUtil.doesObjectExist(url)) { + collectionElementVO.setUrl(getMinioUrl(url)); + } + if (minioUtil.doesObjectExist(collectionElementVO.getOriginalUrl())) { + list.add(collectionElementVO); + } + } + moduleChooseVO.setPrintBoard(list); + } else if (module.equals(Module.sketchBoard.name())) { + + List collectionElements = allCollectionElements.stream() + .filter(element -> CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName().equals(element.getLevel1Type())) + .collect(Collectors.toList()); + List list = new ArrayList<>(); + + for (CollectionElement collectionElement : collectionElements) { + CollectionElementVO collectionElementVO = CopyUtil.copyObject(collectionElement, CollectionElementVO.class); + collectionElementVO.setIsPin(collectionElement.getHasPin()); + collectionElementVO.setDesignType(DesignTypeEnum.COLLECTION.getRealName()); + String url = collectionElement.getUrl(); + collectionElementVO.setOriginalUrl(url); + if (minioUtil.doesObjectExist(url)) { + collectionElementVO.setUrl(getMinioUrl(url)); + if (url.contains(".")) { + String[] split = url.split("\\."); + collectionElementVO.setUrlWithWhiteSide(getMinioUrl(split[0] + "-show." + split[1])); + } else { + collectionElementVO.setUrlWithWhiteSide(getMinioUrl(url + "-show")); + } + } + if (minioUtil.doesObjectExist(collectionElementVO.getOriginalUrl())) { + list.add(collectionElementVO); + } + } + List voList = new ArrayList<>(); + for (CollectionElement collectionElement : collectionElements) { + CollectionSketchVO vo = CopyUtil.copyObject(collectionElement, CollectionSketchVO.class); + String url = collectionElement.getUrl(); + if (url.contains(".")) { + String[] split = url.split("\\."); + vo.setUrlWithWhiteSide(getMinioUrl(split[0] + "-show." + split[1], true)); + } else { + vo.setUrlWithWhiteSide(getMinioUrl(url + "-show", true)); + } + vo.setIsPin(collectionElement.getHasPin()); + vo.setLevel2Type(collectionElement.getLevel2Type()); + vo.setDesignType("Collection"); + vo.setSketchBoardId(collectionElement.getId()); + voList.add(vo); + } + voList.sort(Comparator.comparing(CollectionSketchVO::getSketchBoardId)); + moduleChooseVO.setBoundingBox(voList); + moduleChooseVO.setSketchBoard(list); + } else if (module.equals(Module.design.name())) { + DesignModuleChooseVO vo = new DesignModuleChooseVO(); + QueryWrapper userLikeSortQueryWrapper = new QueryWrapper<>(); + userLikeSortQueryWrapper.lambda().eq(CollectionSort::getProjectId, projectDTO.getId()); + userLikeSortQueryWrapper.lambda().isNull(CollectionSort::getParentId); + userLikeSortQueryWrapper.lambda().eq(CollectionSort::getRelationType, CollectionType.DESIGN.getValue()); + userLikeSortQueryWrapper.lambda().orderByAsc(CollectionSort::getSort); + List userLikeSortList = collectionSortMapper.selectList(userLikeSortQueryWrapper); + + if (CollectionUtils.isEmpty(userLikeSortList)) { + moduleChooseVO.setDesign(vo); + } else { + List list = new ArrayList<>(); + + for (CollectionSort collectionSort : userLikeSortList) { + UserLike userLike = userLikeMapper.selectById(collectionSort.getRelationId()); + UserLikeVO o = CopyUtil.copyObject(userLike, UserLikeVO.class); + TDesignPythonOutfit tDesignPythonOutfit1 = designPythonOutfitMapper.selectById(o.getDesignOutfitId()); + o.setUrl(tDesignPythonOutfit1.getDesignUrl()); + if (o.getUrl().contains("/")) { + int index = o.getUrl().lastIndexOf("/"); + o.setPictureName(o.getUrl().substring(index + 1)); + } + o.setDesignOutfitUrl(getMinioUrl(o.getUrl())); + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(TDesignPythonOutfit::getDesignItemId, o.getDesignItemId()); + List tDesignPythonOutfits = designPythonOutfitMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(tDesignPythonOutfits)) { + TDesignPythonOutfit tDesignPythonOutfit = tDesignPythonOutfits.get(0); + o.setDesignOutfitId(tDesignPythonOutfit.getId()); + } + + o.setSort(collectionSort.getSort()); + o.setUserLikeSortId(collectionSort.getId()); + o.setRelationType(collectionSort.getRelationType()); + o.setCollectionType(CollectionType.DESIGN.getValue()); + o.setResultType(CollectionType.DESIGN.getValue()); + QueryWrapper childCollectionQw = new QueryWrapper<>(); + childCollectionQw.lambda().eq(CollectionSort::getParentId, collectionSort.getId()); + childCollectionQw.lambda().orderByAsc(CollectionSort::getSort); + List childSortList = collectionSortMapper.selectList(childCollectionQw); + List childList = new ArrayList<>(); + // 收集需要删除的失败记录ID,用于后续统一清理并重新排序 + List failedSortIds = new ArrayList<>(); + for (CollectionSort userLikeSort : childSortList) { + if (userLikeSort.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue())) { + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); + if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { + failedSortIds.add(userLikeSort.getId()); + log.info("【获取内容】TO_PRODUCT_IMAGE结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId()); + continue; + } + toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl())); + ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class); + + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); + if (Objects.isNull(toProductImageRecord)) { + log.warn("toProductRecord不存在,projectId:{}, toProductImageResultId:{}", projectDTO.getId(), toProductImageResult.getId()); + continue; + } + toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt()); + + if (toProductImageResultVO.getElementType().equals("ProductElement")) { + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl())); + } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl())); + } else { + ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl())); + } + toProductImageResultVO.setCollectionType(CollectionType.TO_PRODUCT_IMAGE.getValue()); + toProductImageResultVO.setSort(userLikeSort.getSort()); + toProductImageResultVO.setUserLikeSortId(userLikeSort.getId()); + toProductImageResultVO.setRelationType(userLikeSort.getRelationType()); + toProductImageResultVO.setParentId(userLikeSort.getParentId()); + childList.add(toProductImageResultVO); + } else if (userLikeSort.getRelationType().equals(CollectionType.RELIGHT.getValue())) { + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); + if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { + failedSortIds.add(userLikeSort.getId()); + log.info("【获取内容】RELIGHT结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId()); + continue; + } + toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl())); + ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class); + + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); + if (Objects.isNull(toProductImageRecord)) { + log.warn("toProductRecord不存在,projectId:{}, toProductImageResultId:{}", projectDTO.getId(), toProductImageResult.getId()); + continue; + } + toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt()); + + if (toProductImageResultVO.getElementType().equals("ProductElement")) { + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl())); + } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl())); + } else { + ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl())); + } + toProductImageResultVO.setCollectionType(CollectionType.RELIGHT.getValue()); + toProductImageResultVO.setSort(userLikeSort.getSort()); + toProductImageResultVO.setUserLikeSortId(userLikeSort.getId()); + toProductImageResultVO.setRelationType(userLikeSort.getRelationType()); + toProductImageResultVO.setParentId(userLikeSort.getParentId()); + childList.add(toProductImageResultVO); + } else if (userLikeSort.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) { + PoseTransformation item = poseTransformationMapper.selectById(userLikeSort.getRelationId()); + if (isGenerateTaskFailed(item.getTaskStatus(), item.getCreateTime())) { + failedSortIds.add(userLikeSort.getId()); + log.info("【获取内容】POSE_TRANSFORM结果失败,relationId={},即将从collection_sort中删除", userLikeSort.getRelationId()); + continue; + } + PoseTransformationVO poseTransformationVO = new PoseTransformationVO(); + poseTransformationVO.setId(item.getId()); + poseTransformationVO.setTaskId(item.getUniqueId()); + poseTransformationVO.setProductImage(getMinioUrl(item.getProductImage())); + poseTransformationVO.setLastFrameProductImage(getMinioUrl(item.getLastFrameProductImage())); + poseTransformationVO.setPrompt(item.getPrompt()); + poseTransformationVO.setGifUrl(getMinioUrl(item.getGifUrl())); + poseTransformationVO.setVideoUrl(getMinioUrl(item.getVideoUrl())); + poseTransformationVO.setFirstFrameUrl(getMinioUrl(item.getFirstFrameUrl())); + poseTransformationVO.setIsLiked(item.getIsLiked()); + poseTransformationVO.setCollectionType(CollectionType.POSE_TRANSFORM.getValue()); + poseTransformationVO.setSort(userLikeSort.getSort()); + poseTransformationVO.setUserLikeSortId(userLikeSort.getId()); + poseTransformationVO.setRelationType(userLikeSort.getRelationType()); + poseTransformationVO.setResultType(CollectionType.POSE_TRANSFORM.getValue()); + poseTransformationVO.setParentId(userLikeSort.getParentId()); + poseTransformationVO.setModelName(item.getModelName()); + poseTransformationVO.setPoseId(item.getPoseId()); + poseTransformationVO.setStatus(item.getTaskStatus()); + childList.add(poseTransformationVO); + } + } + // 统一处理失败的记录:从collection_sort表中删除失败的记录,并重新排序 + if (CollectionUtil.isNotEmpty(failedSortIds)) { + Long parentId = collectionSort.getId(); + Long projectId = projectDTO.getId(); + log.info("【获取内容】检测到{}条失败记录需要清理,parentId={}, projectId={}", failedSortIds.size(), parentId, projectId); + for (Long failedSortId : failedSortIds) { + CollectionSort failedRecord = collectionSortMapper.selectById(failedSortId); + if (failedRecord != null) { + String relationType = failedRecord.getRelationType(); + Long relationId = failedRecord.getRelationId(); + collectionSortService.deleteCollectionSort(relationId, relationType, projectId, parentId); + log.info("【获取内容】已删除失败记录,relationId={}, relationType={}", relationId, relationType); + } + } + // 重新查询子列表,获取更新后的排序 + childSortList = collectionSortMapper.selectList(childCollectionQw); + // 重新构建childList,使用更新后的sort值 + childList = new ArrayList<>(); + for (CollectionSort userLikeSort : childSortList) { + if (userLikeSort.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue())) { + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); + if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { + continue; + } + toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl())); + ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class); + + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); + if (Objects.isNull(toProductImageRecord)) { + continue; + } + toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt()); + + if (toProductImageResultVO.getElementType().equals("ProductElement")) { + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl())); + } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl())); + } else { + ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl())); + } + toProductImageResultVO.setCollectionType(CollectionType.TO_PRODUCT_IMAGE.getValue()); + toProductImageResultVO.setSort(userLikeSort.getSort()); + toProductImageResultVO.setUserLikeSortId(userLikeSort.getId()); + toProductImageResultVO.setRelationType(userLikeSort.getRelationType()); + toProductImageResultVO.setParentId(userLikeSort.getParentId()); + childList.add(toProductImageResultVO); + } else if (userLikeSort.getRelationType().equals(CollectionType.RELIGHT.getValue())) { + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(userLikeSort.getRelationId()); + if (isGenerateTaskFailed(toProductImageResult.getStatus(), toProductImageResult.getCreateTime())) { + continue; + } + toProductImageResult.setUrl(getMinioUrl(toProductImageResult.getUrl())); + ToProductImageResultVO toProductImageResultVO = CopyUtil.copyObject(toProductImageResult, ToProductImageResultVO.class); + + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(toProductImageResult.getToProductImageRecordId()); + if (Objects.isNull(toProductImageRecord)) { + continue; + } + toProductImageResultVO.setPrompt(toProductImageRecord.getPrompt()); + + if (toProductImageResultVO.getElementType().equals("ProductElement")) { + ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(toProductElement.getUrl())); + } else if ((toProductImageResultVO.getElementType().equals("DesignOutfit"))) { + TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(tDesignPythonOutfit.getDesignUrl())); + } else { + ToProductImageResult toProductImageResult1 = toProductImageResultMapper.selectById(toProductImageResultVO.getElementId()); + toProductImageResultVO.setSourceUrl(getMinioUrl(toProductImageResult1.getUrl())); + } + toProductImageResultVO.setCollectionType(CollectionType.RELIGHT.getValue()); + toProductImageResultVO.setSort(userLikeSort.getSort()); + toProductImageResultVO.setUserLikeSortId(userLikeSort.getId()); + toProductImageResultVO.setRelationType(userLikeSort.getRelationType()); + toProductImageResultVO.setParentId(userLikeSort.getParentId()); + childList.add(toProductImageResultVO); + } else if (userLikeSort.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) { + PoseTransformation item = poseTransformationMapper.selectById(userLikeSort.getRelationId()); + if (isGenerateTaskFailed(item.getTaskStatus(), item.getCreateTime())) { + continue; + } + PoseTransformationVO poseTransformationVO = new PoseTransformationVO(); + poseTransformationVO.setId(item.getId()); + poseTransformationVO.setTaskId(item.getUniqueId()); + poseTransformationVO.setProductImage(getMinioUrl(item.getProductImage())); + poseTransformationVO.setLastFrameProductImage(getMinioUrl(item.getLastFrameProductImage())); + poseTransformationVO.setPrompt(item.getPrompt()); + poseTransformationVO.setGifUrl(getMinioUrl(item.getGifUrl())); + poseTransformationVO.setVideoUrl(getMinioUrl(item.getVideoUrl())); + poseTransformationVO.setFirstFrameUrl(getMinioUrl(item.getFirstFrameUrl())); + poseTransformationVO.setIsLiked(item.getIsLiked()); + poseTransformationVO.setCollectionType(CollectionType.POSE_TRANSFORM.getValue()); + poseTransformationVO.setSort(userLikeSort.getSort()); + poseTransformationVO.setUserLikeSortId(userLikeSort.getId()); + poseTransformationVO.setRelationType(userLikeSort.getRelationType()); + poseTransformationVO.setResultType(CollectionType.POSE_TRANSFORM.getValue()); + poseTransformationVO.setParentId(userLikeSort.getParentId()); + poseTransformationVO.setModelName(item.getModelName()); + poseTransformationVO.setPoseId(item.getPoseId()); + poseTransformationVO.setStatus(item.getTaskStatus()); + childList.add(poseTransformationVO); + } + } + log.info("【获取内容】失败记录清理完成,重新排序后childList.size={}", childList.size()); + } + o.setChildList(childList); + + list.add(o); + } + vo.setUserLikeDetails(list); + } + + UserLikeGroup group = getByProjectId(projectDTO.getId()); + if (Objects.nonNull(group)) { + Long userGroupId = group.getId(); + vo.setUserGroupId(userGroupId); + } + moduleChooseVO.setDesign(vo); + } else if (module.equals(Module.canvas.name())) { + CavasModuleChooseVO vo = new CavasModuleChooseVO(); + + UserLikeGroup userLikeGroup = getByProjectId(projectDTO.getId()); + + Integer beenPublished = 0; + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(Portfolio::getUserLikeGroupSourceId, userLikeGroup.getId()); + List portfolios = portfolioMapper.selectList(qw); + + PortfolioDTO portfolioDTO = new PortfolioDTO(); + if (CollectionUtil.isNotEmpty(portfolios)) { + + portfolioDTO = CopyUtil.copyObject(portfolios.get(0), PortfolioDTO.class); + beenPublished = 1; + portfolioDTO.setTagsDTO(tagsMapper.getTagByPortfolioId(portfolioDTO.getId())); + } + vo.setBeenPublished(beenPublished); + vo.setPortfolioDTO(portfolioDTO); + moduleChooseVO.setCanvas(vo); + } else if (module.equals(Module.toProduct.name()) || module.equals(Module.relight.name())) { + Long projectId = projectDTO.getId(); + String resultType = module.equals(Module.toProduct.name()) ? "ToProductImage" : "Relight"; + + // 查询所有结果(包括喜欢和不喜欢的) + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda() + .eq(ToProductImageResult::getProjectId, projectId) + .eq(ToProductImageResult::getResultType, resultType); + + List allResults = toProductImageResultMapper.selectList(qw); + + // 准备返回对象 + ToProductOrRelightVO resultVO = new ToProductOrRelightVO(); + + // 处理URL转换和分类 + List likedList = new ArrayList<>(); + List normalList = new ArrayList<>(); + + for (ToProductImageResult result : allResults) { + // 转换URL + result.setUrl(getMinioUrl(result.getUrl())); + // 复制到VO对象 + ToProductImageResultVO vo = CopyUtil.copyObject(result, ToProductImageResultVO.class); + // 设置sourceUrl + setSourceUrl(vo); + // 设置prompt + ToProductImageRecord toProductImageRecord = toProductImageRecordMapper.selectById(result.getToProductImageRecordId()); + if (Objects.nonNull(toProductImageRecord)) { + vo.setPrompt(toProductImageRecord.getPrompt()); + } + vo.setParentId(toProductImageResultService.getUnlikedResultParentId(result, null)); + // 按isLike分类 + if (result.getIsLike() != null && result.getIsLike() == 1) { + likedList.add(vo); + } else { + normalList.add(vo); + } + } + // 设置结果 + resultVO.setLikedList(likedList); + resultVO.setList(normalList); + + // 根据模块设置返回结果 + if (module.equals(Module.toProduct.name())) { + moduleChooseVO.setToProduct(resultVO); + } else { + moduleChooseVO.setRelight(resultVO); + } + } else if (module.equals(Module.deReconstruction.name())) { + SketchReconstructionVO sketchReconstruction = generateService.getSketchReconstruction(projectDTO.getId()); + moduleChooseVO.setDeReconstruction(sketchReconstruction); + } else if (module.equals(Module.poseTransfer.name())) { + List likedList = generateService.getPoseTransformationResult(null, projectDTO.getId(), true); + List list = generateService.getPoseTransformationResult(null, projectDTO.getId(), false); + PoseTransferVO vo = new PoseTransferVO(); + vo.setLikedList(likedList); + vo.setList(list); + moduleChooseVO.setPoseTransfer(vo); + } else if (module.equals(Module.patternMaking3D.name())) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ThreeDModule::getProjectId, projectDTO.getId()); + List threeDModules = threeDModuleMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(threeDModules)) { + ThreeDModule threeDModule = threeDModules.get(0); + if (null != threeDModule.getThreeDSimpleId()) { + ThreeDModuleVO threeDModuleVO = CopyUtil.copyObject(threeDModule, ThreeDModuleVO.class); + if (null != threeDModule.getCollectionElementId()) { + CollectionElement collectionElement = collectionElementMapper.selectById(threeDModule.getCollectionElementId()); + if (Objects.nonNull(collectionElement)) { + threeDModuleVO.setPrintMinioUrl(getMinioUrl(collectionElement.getUrl())); + } + } +// if (!StringUtils.isEmpty(threeDModuleVO.getPrintMinioUrl())) { +// threeDModuleVO.setPrintMinioUrl(minioUtil.getPreSignedUrl(threeDModuleVO.getPrintMinioUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); +// } + moduleChooseVO.setPatternMaking3D(threeDModuleVO); + } + } + } else if (module.equals(Module.mannequin.name())) { + List collectionElements = allCollectionElements.stream() + .filter(element -> CollectionLevel1TypeEnum.MODEL.getRealName().equals(element.getLevel1Type())) + .collect(Collectors.toList()); + List list = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(collectionElements)) { + for (CollectionElement collectionElement : collectionElements) { + CollectionElementVO collectionElementVO = CopyUtil.copyObject(collectionElement, CollectionElementVO.class); + CollectionElementRelModel relModel = getCollectionElementRelModel(collectionElementVO.getId()); + collectionElementVO.setUrl(getMinioUrl(collectionElementVO.getUrl())); + collectionElementVO.setMannequinRelationId(relModel.getRelationId()); + collectionElementVO.setMannequinRelationType(relModel.getRelationType()); + collectionElementVO.setCollectionId(collectionElement.getId()); + list.add(collectionElementVO); + } + } + moduleChooseVO.setMannequin(list); + } else if (module.equals(Module.uploadElement.name())) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ToProductElement::getProjectId, projectDTO.getId()); + List toProductElements = toProductElementMapper.selectList(qw); + for (ToProductElement toProductElement : toProductElements) { + toProductElement.setUrl(getMinioUrl(toProductElement.getUrl())); + } + moduleChooseVO.setUploadElement(toProductElements); + } + } + return moduleChooseVO; + } + + private String getMinioUrl(String minioPath) { + if (!StringUtil.isNullOrEmpty(minioPath)) { + return minioUtil.getPreSignedUrl(minioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); + } + return null; + } + + private String getMinioUrl(String minioPath, boolean resetCatch) { + if (!StringUtil.isNullOrEmpty(minioPath)) { + return minioUtil.getPreSignedUrl(minioPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME, resetCatch); + } + return null; + } + + // 提取出的公共方法 + private void setSourceUrl(ToProductImageResultVO vo) { + if (vo.getElementType().equals("ProductElement")) { + ToProductElement element = toProductElementMapper.selectById(vo.getElementId()); + vo.setSourceUrl(getMinioUrl(element.getUrl())); + } else if (vo.getElementType().equals("DesignOutfit")) { + TDesignPythonOutfit outfit = designPythonOutfitMapper.selectById(vo.getElementId()); + vo.setSourceUrl(getMinioUrl(outfit.getDesignUrl())); + } else { + ToProductImageResult result = toProductImageResultMapper.selectById(vo.getElementId()); + vo.setSourceUrl(getMinioUrl(result.getUrl())); + } + } + + private CollectionElementRelModel getCollectionElementRelModel(Long id) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionElementRelModel::getCollectionElementId, id); + CollectionElementRelModel collectionElementRelModel = collectionElementRelModelMapper.selectOne(qw); + return collectionElementRelModel; + } + + private boolean isGenerateTaskFailed(String taskStatus, LocalDateTime createTime) { + // 1. 先判断TaskStatus字段是否有值;若有值且为Fail,则失败 + if (!StringUtil.isNullOrEmpty(taskStatus)) { + return "Fail".equals(taskStatus); + } + // 2. 若taskStatus无值,判断记录创建时间距离现在是否超过1小时 + if (createTime == null) { + // 如果创建时间为null,视为失败(根据业务需求决定) + return true; + } + // 计算当前时间与创建时间的差值 + Duration duration = Duration.between(createTime, LocalDateTime.now()); + // 判断是否超过1小时(3600秒) + return duration.toHours() >= 1; + } + + + @Override + @Transactional + public ModuleChooseVO saveModuleContent(ModuleSaveDTO moduleSaveDTO) { + ModuleChooseVO result = new ModuleChooseVO(); + Long accountId = UserContext.getUserHolder().getId(); + Long projectId = moduleSaveDTO.getProjectId(); + Project project = projectService.getById(projectId); + + boolean boundingBox = false; + if (Objects.nonNull(moduleSaveDTO.getMoodBoard())) { + MoodBoardModuleSaveDTO moodBoard = moduleSaveDTO.getMoodBoard(); + if (moodBoard.getMoodTemplateId() != null) { + // moodboard合成图存储 + CollectionElement compositeImage = collectionElementMapper.selectById(moodBoard.getMoodTemplateId()); + if (compositeImage.getProjectId() == null) { + compositeImage.setProjectId(moduleSaveDTO.getProjectId()); + compositeImage.setIsCompositeImage(1); + collectionElementMapper.updateById(compositeImage); + if (!StringUtils.isEmpty(moodBoard.getMoodboardPosition())) { + // 合成图位置信息通过collectElementId关联(旧逻辑通过collectionId关联) + moodboardPositionService.parseMoodboardPosition(moodBoard.getMoodboardPosition(), compositeImage.getId()); + } + } + } + List moodBoards = moodBoard.getMoodBoards(); + if (Objects.nonNull(moodBoards)) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionElement::getProjectId, projectId); + qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.MOOD_BOARD.getRealName()); + if (moodBoard.getMoodTemplateId() != null) { + qw.lambda().ne(CollectionElement::getId, moodBoard.getMoodTemplateId()); + } +// qw.lambda().ne(CollectionElement::getCollectionId, 0); + List collectionElements = collectionElementMapper.selectList(qw); + Set old = collectionElements.stream().map(CollectionElement::getId).collect(Collectors.toSet()); + + for (DesignCollectionElementDTO board : moodBoards) { + if (board.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName())) { + Library library = libraryMapper.selectById(board.getId()); + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MOOD_BOARD.getRealName()); + collectionElement.setName(library.getName()); + collectionElement.setUrl(library.getUrl()); + collectionElement.setHasPin((byte) 0); + collectionElement.setMd5(library.getMd5()); + collectionElement.setCreateDate(new Date()); + collectionElementMapper.insert(collectionElement); + } else if (board.getDesignType().equals(DesignTypeEnum.GENERATE.getRealName())) { + GenerateDetail generateDetail = generateDetailMapper.selectById(board.getId()); + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MOOD_BOARD.getRealName()); +// collectionElement.setName(generateDetail.get()); + collectionElement.setUrl(generateDetail.getUrl()); + collectionElement.setHasPin((byte) 0); + collectionElement.setMd5(generateDetail.getMd5()); + collectionElement.setCreateDate(new Date()); + collectionElementMapper.insert(collectionElement); + } else { + if (old.contains(board.getId())) { + old.remove(board.getId()); + } else { + CollectionElement collectionElement = collectionElementMapper.selectById(board.getId()); + collectionElement.setProjectId(projectId); + collectionElementMapper.updateById(collectionElement); + } + } + } + if (!CollectionUtils.isEmpty(old)) { + collectionElementMapper.deleteBatchIds(old); + } + } + } + if (Objects.nonNull(moduleSaveDTO.getPrintBoard())) { + List printBoards = moduleSaveDTO.getPrintBoard(); + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionElement::getProjectId, projectId); + qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.PRINT_BOARD.getRealName()); + List collectionElements = collectionElementMapper.selectList(qw); + Set old = collectionElements.stream().map(CollectionElement::getId).collect(Collectors.toSet()); + + for (DesignCollectionPrintElementDTO board : printBoards) { + if (board.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName())) { + Library library = libraryMapper.selectById(board.getId()); + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.PRINT_BOARD.getRealName()); + collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setName(library.getName()); + collectionElement.setUrl(library.getUrl()); + collectionElement.setHasPin(board.getIsPin()); + collectionElement.setMd5(library.getMd5()); + collectionElement.setCreateDate(new Date()); + collectionElementMapper.insert(collectionElement); + } else if (board.getDesignType().equals(DesignTypeEnum.GENERATE.getRealName())) { + GenerateDetail generateDetail = generateDetailMapper.selectById(board.getId()); + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.PRINT_BOARD.getRealName()); + collectionElement.setLevel2Type(board.getLevel2Type()); +// collectionElement.setName(generateDetail.get()); + collectionElement.setUrl(generateDetail.getUrl()); + collectionElement.setHasPin(board.getIsPin()); + collectionElement.setMd5(generateDetail.getMd5()); + collectionElement.setCreateDate(new Date()); + collectionElementMapper.insert(collectionElement); + } else { + if (old.contains(board.getId())) { + CollectionElement collectionElement = collectionElementMapper.selectById(board.getId()); + collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setHasPin(board.getIsPin()); + collectionElement.setUpdateDate(new Date()); + collectionElementMapper.updateById(collectionElement); + old.remove(board.getId()); + } else { + CollectionElement collectionElement = collectionElementMapper.selectById(board.getId()); + collectionElement.setProjectId(projectId); + collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setHasPin(board.getIsPin()); + collectionElement.setUpdateDate(new Date()); + collectionElementMapper.updateById(collectionElement); + } + } + } + if (!CollectionUtils.isEmpty(old)) { + collectionElementMapper.deleteBatchIds(old); + } + } + if (Objects.nonNull(moduleSaveDTO.getColorBoard())) { + List colorBoards = moduleSaveDTO.getColorBoard(); + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionElement::getProjectId, projectId); + qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.COLOR_BOARD.getRealName()); + List collectionElements = collectionElementMapper.selectList(qw); + Set old = collectionElements.stream().map(CollectionElement::getId).collect(Collectors.toSet()); + + for (CollectionColorDTO board : colorBoards) { + if (Objects.nonNull(board.getId()) && old.contains(Long.valueOf(board.getId()))) { + // ??? + old.remove(Long.valueOf(board.getId())); + } else { + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.COLOR_BOARD.getRealName()); + collectionElement.setName(board.getName()); + collectionElement.setHasPin((byte) 0); + collectionElement.setColorRgb(board.getRgbValue()); + collectionElement.setMd5("0"); + // 渐变色 + if (!Objects.isNull(board.getGradient()) && !StringUtil.isNullOrEmpty(board.getGradient().getColorImg())) { + board.getGradient().setColorImg(null); + } + collectionElement.setGradientString(JSON.toJSONString(board.getGradient())); + collectionElement.setCreateDate(new Date()); + collectionElementMapper.insert(collectionElement); + } + } + if (!CollectionUtils.isEmpty(old)) { + collectionElementMapper.deleteBatchIds(old); + } + } + if (Objects.nonNull(moduleSaveDTO.getSketchBoard())) { + boundingBox = true; + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionElement::getProjectId, projectId); + qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName()); + List collectionElements = collectionElementMapper.selectList(qw); + Set old = collectionElements.stream().map(CollectionElement::getId).collect(Collectors.toSet()); + List sketchBoards = moduleSaveDTO.getSketchBoard(); + for (CollectionSketchDTO board : sketchBoards) { + if (board.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName())) { + Library library = libraryMapper.selectById(board.getSketchBoardId()); + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName()); + collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setLevel3Type(workspaceService.getProjectSexById(projectId)); + collectionElement.setName(library.getName()); + collectionElement.setUrl(library.getUrl()); + collectionElement.setHasPin(board.getIsPin()); + collectionElement.setMd5(library.getMd5()); + collectionElement.setCreateDate(new Date()); + collectionElementMapper.insert(collectionElement); + } else if (board.getDesignType().equals(DesignTypeEnum.GENERATE.getRealName())) { + GenerateDetail generateDetail = generateDetailMapper.selectById(board.getSketchBoardId()); + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName()); + collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setLevel3Type(workspaceService.getProjectSexById(projectId)); +// collectionElement.setName(generateDetail.get()); + collectionElement.setUrl(generateDetail.getUrl()); + collectionElement.setHasPin(board.getIsPin()); + collectionElement.setMd5(generateDetail.getMd5()); + collectionElement.setCreateDate(new Date()); + collectionElementMapper.insert(collectionElement); + } else { + if (old.contains(board.getSketchBoardId())) { + CollectionElement collectionElement = collectionElementMapper.selectById(board.getSketchBoardId()); + collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setHasPin(board.getIsPin()); + collectionElement.setUpdateDate(new Date()); + collectionElementMapper.updateById(collectionElement); + old.remove(board.getSketchBoardId()); + } else { + CollectionElement collectionElement = collectionElementMapper.selectById(board.getSketchBoardId()); + collectionElement.setProjectId(projectId); + collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setHasPin(board.getIsPin()); + collectionElement.setUpdateDate(new Date()); + if (CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName().equals(collectionElement.getLevel1Type())) { + collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId())); + } + collectionElementMapper.updateById(collectionElement); + } + } + } + if (!CollectionUtils.isEmpty(old)) { + collectionElementMapper.deleteBatchIds(old); + } + } + if (Objects.nonNull(moduleSaveDTO.getPatternMaking3D())) { + PatternMaking3DDTO patternMaking3D = moduleSaveDTO.getPatternMaking3D(); + + QueryWrapper threeDModuleQueryWrapper = new QueryWrapper<>(); + threeDModuleQueryWrapper.lambda().eq(ThreeDModule::getProjectId, projectId); + List threeDModuleList = threeDModuleMapper.selectList(threeDModuleQueryWrapper); + + if (CollectionUtils.isEmpty(threeDModuleList)) { + ThreeDModule threeDModule = new ThreeDModule(); + threeDModule.setProjectId(projectId); + threeDModule.setThreeDSimpleId(patternMaking3D.getThreeDSimpleId()); + threeDModule.setX(patternMaking3D.getX()); + threeDModule.setY(patternMaking3D.getY()); +// threeDModule.setPrintMinioUrl(patternMaking3D.getPrintMinioUrl()); + threeDModule.setCollectionElementId(patternMaking3D.getCollectionElementId()); + threeDModuleMapper.insert(threeDModule); + } else { + ThreeDModule threeDModule = threeDModuleList.get(0); +// if (!Objects.equals(patternMaking3D.getThreeDSimpleId(), threeDModule.getThreeDSimpleId())) { +// +// } + threeDModule.setThreeDSimpleId(patternMaking3D.getThreeDSimpleId()); + threeDModule.setX(patternMaking3D.getX()); + threeDModule.setY(patternMaking3D.getY()); +// threeDModule.setPrintMinioUrl(patternMaking3D.getPrintMinioUrl()); + threeDModule.setCollectionElementId(patternMaking3D.getCollectionElementId()); + threeDModuleMapper.updateById(threeDModule); + } + } + if (CollectionUtil.isNotEmpty(moduleSaveDTO.getMannequin())) { + // 目前已有的模特 + List collectionElementRelModels = collectionElementMapper.selectByProject(projectId); + // 入参中的模特 + List mannequin = moduleSaveDTO.getMannequin(); + + // 新增的模特只有id,没有collectionElementId + List inputMannequinIds = mannequin.stream().map(MannequinDTO::getId).collect(Collectors.toList()); + // 既有id又有collectionElementId的,为保持原状的模特(都没有的且又存在于数据库的,即为被删除的模特) + List inputCollectionElementIds = mannequin.stream().map(MannequinDTO::getCollectionElementId).collect(Collectors.toList()); + + // 创建relationId到Model的映射 + Map relationIdToModelMap = collectionElementRelModels.stream() + .collect(Collectors.toMap( + CollectionElementRelModel::getRelationId, + java.util.function.Function.identity(), + (existing, replacement) -> existing + )); + // 创建collectionElementId到Model的映射 + Map collectionElementToModelMap = collectionElementRelModels.stream() + .collect(Collectors.toMap( + CollectionElementRelModel::getCollectionElementId, + java.util.function.Function.identity(), + (existing, replacement) -> existing + )); + List newReletionIds = new ArrayList<>(); + List toBeDeletedCollectionElementIds = new ArrayList<>(); + + if (collectionElementRelModels.isEmpty()) { + // 如果原本没有记录,所有输入的Mannequin都是新的 + newReletionIds = inputMannequinIds; + } else { + // 获取db中所有的relationId集合 + Set relationIds = relationIdToModelMap.keySet(); + // 获取db中所有的collectionElementId集合 + Set collectionElementIds = collectionElementToModelMap.keySet(); + + // 1. 找出需要删除的:collectionElementIds中有但inputCollectionElementIds中没有的 + toBeDeletedCollectionElementIds = collectionElementIds.stream() + .filter(id -> !inputCollectionElementIds.contains(id)) + .collect(Collectors.toList()); + + // 2. 找出新增的:inputMannequinId中有但relationIds中没有的(一定程度避免重复) + newReletionIds = inputMannequinIds.stream() + .filter(id -> !relationIds.contains(id)) + .collect(Collectors.toList()); + } + + if (!toBeDeletedCollectionElementIds.isEmpty()) { + /*Set toBeDeletedElementIdList = toBeDeletedCollectionElementIds.stream() + .map(relationIdToModelMap::get) // 获取对应的Model + .filter(Objects::nonNull) // 过滤掉可能为null的情况 + .map(CollectionElementRelModel::getCollectionElementId) // 提取collectionElementId + .collect(Collectors.toSet());*/ + collectionElementMapper.deleteBatchIds(toBeDeletedCollectionElementIds); + // 删除关联关系 + deleteByCollectionElementIdList(toBeDeletedCollectionElementIds); + } + + for (MannequinDTO dto : mannequin) { + if (newReletionIds.isEmpty()) { + break; + } else if (!newReletionIds.contains(dto.getId())) { + continue; + } + if (dto.getType().equals("System")) { + SysFile sysFile = sysFileMapper.selectById(dto.getId()); + + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName()); + collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId())); +// collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setName(sysFile.getName()); + collectionElement.setUrl(sysFile.getUrl()); +// collectionElement.setHasPin(board.getIsPin()); + collectionElement.setMd5(sysFile.getMd5()); + collectionElement.setCreateDate(new Date()); + collectionElement.setHasPin((byte) 0); + collectionElementMapper.insert(collectionElement); + CollectionElementRelModel collectionElementRelModel = new CollectionElementRelModel(); + collectionElementRelModel.setCollectionElementId(collectionElement.getId()); + collectionElementRelModel.setRelationId(dto.getId()); + collectionElementRelModel.setRelationType("System"); + collectionElementRelModelMapper.insert(collectionElementRelModel); + } else if (dto.getType().equals("Library")) { + Library library = libraryMapper.selectById(dto.getId()); + + CollectionElement collectionElement = new CollectionElement(); + collectionElement.setAccountId(accountId); + collectionElement.setProjectId(projectId); + collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName()); + collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId())); +// collectionElement.setLevel2Type(board.getLevel2Type()); + collectionElement.setName(library.getName()); + collectionElement.setUrl(library.getUrl()); +// collectionElement.setHasPin(board.getIsPin()); + collectionElement.setMd5(library.getMd5()); + collectionElement.setCreateDate(new Date()); + collectionElement.setHasPin((byte) 0); + collectionElementMapper.insert(collectionElement); + CollectionElementRelModel collectionElementRelModel = new CollectionElementRelModel(); + collectionElementRelModel.setCollectionElementId(collectionElement.getId()); + collectionElementRelModel.setRelationId(dto.getId()); + collectionElementRelModel.setRelationType("Library"); + collectionElementRelModelMapper.insert(collectionElementRelModel); + + } + } + } + if (boundingBox) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName()); + qw.lambda().eq(CollectionElement::getProjectId, projectId); + List collectionElements = collectionElementMapper.selectList(qw); + + List voList = new ArrayList<>(); + for (CollectionElement collectionElement : collectionElements) { + CollectionSketchVO vo = CopyUtil.copyObject(collectionElement, CollectionSketchVO.class); + String url = collectionElement.getUrl(); + libraryService.processSketchBoards(url, collectionElement.getLevel2Type()); + if (url.contains(".")) { + String[] split = url.split("\\."); + vo.setUrlWithWhiteSide(minioUtil.getPreSignedUrl(split[0] + "-show." + split[1], 24 * 60, true)); + } else { + vo.setUrlWithWhiteSide(minioUtil.getPreSignedUrl(url + "-show", 24 * 60, true)); + } + vo.setIsPin(collectionElement.getHasPin()); + vo.setLevel2Type(collectionElement.getLevel2Type()); + vo.setDesignType("Collection"); + vo.setSketchBoardId(collectionElement.getId()); + voList.add(vo); + } + voList.sort(Comparator.comparing(CollectionSketchVO::getSketchBoardId)); + result.setBoundingBox(voList); + } + project.setUpdateTime(LocalDateTime.now()); + projectService.updateById(project); + return result; + } + + private void deleteByCollectionElementIdList(java.util.Collection old) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().in(CollectionElementRelModel::getCollectionElementId, old); + collectionElementRelModelMapper.delete(qw); + } + + @Override + public QueryLibraryPageVO getMannequinDetail(MannequinDTO mannequinDTO) { + QueryLibraryPageVO vo = new QueryLibraryPageVO(); + if (mannequinDTO.getType().equals("System")) { + SysFile sysFile = sysFileMapper.selectById(mannequinDTO.getId()); + vo.setDesignType("System"); + vo.setLevel1Type(sysFile.getLevel1Type()); + vo.setLevel2Type(sysFile.getLevel2Type()); + vo.setName(sysFile.getName()); + vo.setMinIOPath(minioUtil.getPreSignedUrl(sysFile.getUrl(), 24 * 60)); + } else { + Library library = libraryMapper.selectById(mannequinDTO.getId()); + vo.setDesignType("Library"); + vo.setLevel1Type(library.getLevel1Type()); + vo.setLevel2Type(library.getLevel2Type()); + vo.setName(library.getName()); + vo.setMinIOPath(minioUtil.getPreSignedUrl(library.getUrl(), 24 * 60)); + } + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(LibraryModelPoint::getRelationId, mannequinDTO.getId()); + qw.lambda().eq(LibraryModelPoint::getModelType, mannequinDTO.getType()); + List libraryModelPoints = libraryModelPointMapper.selectList(qw); + if (CollectionUtil.isEmpty(libraryModelPoints)) { + throw new BusinessException("No model doting information available."); + } + LibraryModelPoint libraryModelPoint = libraryModelPoints.get(0); + LibraryModelPointVO libraryModelPointVO = CopyUtil.copyObject(libraryModelPoint, LibraryModelPointVO.class); + libraryModelPointVO.setTemplateId(libraryModelPoint.getId()); + libraryModelPointVO.setHandLeft(JSON.parseObject(libraryModelPoint.getHandLeft(), List.class)); + libraryModelPointVO.setHandRight(JSON.parseObject(libraryModelPoint.getHandRight(), List.class)); + libraryModelPointVO.setShoulderRight(JSON.parseObject(libraryModelPoint.getShoulderRight(), List.class)); + libraryModelPointVO.setShoulderLeft(JSON.parseObject(libraryModelPoint.getShoulderLeft(), List.class)); + libraryModelPointVO.setWaistbandRight(JSON.parseObject(libraryModelPoint.getWaistbandRight(), List.class)); + libraryModelPointVO.setWaistbandLeft(JSON.parseObject(libraryModelPoint.getWaistbandLeft(), List.class)); + + vo.setLibraryModelPoint(libraryModelPointVO); + return vo; + } + + @Override + public BrandLogoUploadVO brandLogoUpload(MultipartFile file) { + BrandLogoUploadVO vo = new BrandLogoUploadVO(); + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + String path = userHolder.getId().toString() + "/brandLogo"; + vo.setBrandLogo(minioUtil.upload("aida-users", path, file)); + vo.setMinioUrl(minioUtil.getPreSignedUrl(vo.getBrandLogo(), 24 * 60)); + return vo; +// return null; + } + + @Override + public Boolean brandDNASaveOrUpdate(BrandDNADTO brandDNADTO) { + if (brandDNADTO.getId() != null) { + BrandDNA brandDNA = CopyUtil.copyObject(brandDNADTO, BrandDNA.class); + brandDNA.setUpdateTime(LocalDateTime.now()); + brandDNAMapper.updateById(brandDNA); + } else { + BrandDNA brandDNA = CopyUtil.copyObject(brandDNADTO, BrandDNA.class); + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + brandDNA.setAccountId(userHolder.getId()); + brandDNA.setCreateTime(LocalDateTime.now()); + brandDNAMapper.insert(brandDNA); + } + return Boolean.TRUE; + } + + @Override + public LibraryUpdateVo brandDNAUpload(MultipartFile file, Long brandId) throws IOException { + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + String path = userHolder.getId().toString() + "/brandLogo"; + String upload = minioUtil.upload("aida-users", path, file); + Library library = new Library(); + library.setAccountId(userHolder.getId()); + library.setLevel1Type(LibraryLevel1TypeEnum.BRAND_DNA.getRealName()); + library.setName(file.getOriginalFilename()); + library.setUrl(upload); + library.setMd5(MD5Utils.encryptFile(file.getInputStream())); + library.setCreateDate(new Date()); + libraryMapper.insert(library); + + BrandRelLibrary brandRelLibrary = new BrandRelLibrary(); + brandRelLibrary.setLibraryId(library.getId()); + brandRelLibrary.setBrandId(brandId); + brandRelLibraryMapper.insert(brandRelLibrary); + + LibraryUpdateVo vo = CopyUtil.copyObject(library, LibraryUpdateVo.class); + vo.setMinIOPath(minioUtil.getPreSignedUrl(vo.getUrl(), 24 * 60)); + + return vo; + } + + @Override + public PageBaseResponse brandDNAPage(BrandDNAQueryDTO brandDNAQueryDTO) { + AuthPrincipalVo userHolder = UserContext.getUserHolder(); + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(BrandDNA::getAccountId, userHolder.getId()); + IPage page = brandDNAMapper.selectPage(new Page<>(brandDNAQueryDTO.getPage(), brandDNAQueryDTO.getSize()), qw); + IPage convert = page.convert((Function) brand -> { + if (Objects.nonNull(brand)) { + BrandDNAVO brandDNAVO = CopyUtil.copyObject(brand, BrandDNAVO.class); + brandDNAVO.setMinioUrl(minioUtil.getPreSignedUrl(brandDNAVO.getBrandLogo(), 24 * 60)); + return brandDNAVO; + } + return null; + }); + return PageBaseResponse.success(convert); + } + + @Override + public BrandDNAGenerateVO brandDNAGenerate(String prompt) { + BrandDNAGenerateVO vo = new BrandDNAGenerateVO(); + JSONObject jsonObject = pythonService.brandDNAGenerate(prompt); + JSONObject data = jsonObject.getJSONObject("data"); + vo.setBrandSlogan(data.getString("brand_slogan")); + vo.setBrandName(data.getString("brand_name")); + vo.setBrandLogo(data.getString("brand_logo")); + vo.setMinioUrl(minioUtil.getPreSignedUrl(vo.getBrandLogo(), 24 * 60)); + return vo; + } + + @Override + public IPage getThreeDLayoutPage(ThreeDLayoutQueryDTO query) { +// AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); +// Long workspaceServiceByProjectId = workspaceService.getByProjectId(query.getProjectId()); +// Workspace byId = workspaceService.getById(workspaceServiceByProjectId); + // 分页数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(ThreeDLayout::getType, "front"); + queryWrapper.lambda().eq(ThreeDLayout::getGender, query.getSex().toLowerCase()); + IPage page = threeDLayoutMapper.selectPage( + new Page<>(query.getPage(), query.getSize()), queryWrapper); + if (CollectionUtils.isEmpty(page.getRecords())) { + return new Page<>(); + } + + IPage convert = page.convert((Function) threeDLayout -> { + if (threeDLayout != null) { + ThreeDLayoutVO threeDLayoutVO = CopyUtil.copyObject(threeDLayout, ThreeDLayoutVO.class); + threeDLayoutVO.setUrl(minioUtil.getPreSignedUrl(threeDLayoutVO.getUrl(), 24 * 60)); + return threeDLayoutVO; + } + return null; + }); + return convert; + } + + @Override + public ThreeDVO getLayoutDetail(Long threeDSimpleId) { + ThreeDVO result = new ThreeDVO(); + + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ThreeDLayout::getThreeDSimpleId, threeDSimpleId); + List threeDLayoutList = threeDLayoutMapper.selectList(qw); + for (ThreeDLayout threeDLayout : threeDLayoutList) { + threeDLayout.setUrl(minioUtil.getPreSignedUrl(threeDLayout.getUrl(), 24 * 60)); + } + result.setThreeDLayoutList(threeDLayoutList); + + QueryWrapper threeDPatternLayoutQueryWrapper = new QueryWrapper<>(); + threeDPatternLayoutQueryWrapper.lambda().eq(ThreeDPatternLayout::getThreeDSimpleId, threeDSimpleId); + List threeDPatternLayoutList = threeDPatternLayoutMapper.selectList(threeDPatternLayoutQueryWrapper); + if (CollectionUtil.isNotEmpty(threeDPatternLayoutList)) { + ThreeDPatternLayout threeDPatternLayout = threeDPatternLayoutList.get(0); +// threeDPatternLayout.setUrl(minioUtil.getPreSignedUrl(threeDPatternLayout.getUrl(), 24 * 60)); + result.setThreeDPatternLayoutUrl(minioUtil.getPreSignedUrl(threeDPatternLayout.getUrl(), 24 * 60)); + } + ThreeDSimple threeDSimple = threeDSimpleMapper.selectById(threeDSimpleId); + result.setThreeDSimpleUrl(minioUtil.getPreSignedUrl(threeDSimple.getUrl(), 24 * 60)); + return result; + } + + @Override + public ThreeDSizeVO getThreeDSize(Long threeDSimpleId) { + ThreeDSizeVO result = new ThreeDSizeVO(); + QueryWrapper threeDDetailQueryWrapper = new QueryWrapper<>(); + threeDDetailQueryWrapper.lambda().eq(ThreeDDetail::getThreeDSimpleId, threeDSimpleId); + List threeDDetailList = threeDDetailMapper.selectList(threeDDetailQueryWrapper); + if (CollectionUtil.isNotEmpty(threeDDetailList)) { + // 以 sizeType 分组 + Map> sizeTypeMap = new HashMap<>(); + for (ThreeDDetail detail : threeDDetailList) { + sizeTypeMap + .computeIfAbsent(detail.getSizeType(), k -> new ArrayList<>()) + .add(detail.getSize()); + } + result.setSizeTypeMap(sizeTypeMap); + } + return result; + } + + @Override + public void getThreeDGlb(Long threeDSimpleId, HttpServletResponse response) throws MinioException, IOException { + ThreeDSimple threeDSimple = threeDSimpleMapper.selectById(threeDSimpleId); + if (ObjectUtils.isAllFieldNull(threeDSimple)) { + throw new BusinessException("3D file is not exist"); + } + InputStream inputStream = minioUtil.download(threeDSimple.getUrl()); + + // 设置响应头 + response.setContentType("model/gltf-binary"); // 确保 MIME 类型正确 + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); + String fileName = threeDSimple.getName(); + if (!fileName.toLowerCase().endsWith(".glb")) { + fileName += ".glb"; + } + response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString())); + // 将文件内容写入响应输出流 + try { + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + response.getOutputStream().write(buffer, 0, bytesRead); + } + inputStream.close(); + response.getOutputStream().flush(); + } catch (Exception e) { + throw new RuntimeException("Failed to get 3D .glb file", e); + } + } + + @Override + public String downloadZip(Long threeDSimpleId, String sizeType, String size, HttpServletResponse response) throws MinioException, IOException { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ThreeDDetail::getThreeDSimpleId, threeDSimpleId); + qw.lambda().eq(ThreeDDetail::getSizeType, sizeType); + qw.lambda().eq(ThreeDDetail::getSize, size); + ThreeDDetail threeDDetail = threeDDetailMapper.selectOne(qw); + if (ObjectUtils.isAllFieldNull(threeDDetail)) { + throw new BusinessException("3D file is not exist"); + } + return minioUtil.getPreSignedUrl(threeDDetail.getUrl(), 24 * 60); + +// // 设置响应头 +// response.setContentType("application/zip"); // 确保 ZIP 格式 +// response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); +// String fileName = threeDDetail.getName(); +// if (!fileName.toLowerCase().endsWith(".zip")) { +// fileName += ".zip"; +// } +// response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString())); +// +// // 将文件内容写入响应输出流 +// try { +// byte[] buffer = new byte[8192]; +// int bytesRead; +// while ((bytesRead = inputStream.read(buffer)) != -1) { +// response.getOutputStream().write(buffer, 0, bytesRead); +// } +// inputStream.close(); +// response.getOutputStream().flush(); +// } catch (Exception e) { +// throw new RuntimeException("Failed to download ZIP file", e); +// } + } + + @Override + public Boolean delete(Long projectId) { + projectService.removeById(projectId); + return Boolean.TRUE; + } + + @Override + public Boolean brandDNADelete(BrandDNADTO brandDNADTO) { + brandDNAMapper.deleteById(brandDNADTO.getId()); + return Boolean.TRUE; + } + + @Override + @Transactional(isolation = Isolation.SERIALIZABLE) + public void toProductBatch(String taskId, String url, String progress) throws InterruptedException { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ToProductImageResult::getTaskId, taskId); + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(qw); + if (Objects.nonNull(toProductImageResult)) { + toProductImageResult.setUrl(url); + toProductImageResult.setStatus("Success"); + toProductImageResultMapper.updateById(toProductImageResult); + String taskIdBatch = toProductImageResult.getTaskIdBatch(); + log.info("toProductImage云生成 batchTaskId:" + taskIdBatch + " 完成数+1"); + + CloudTask task = cloudTaskMapper.selectForUpdate(taskIdBatch); + log.info("排查完成数量" + task.getCompletedNum()); + task.setCompletedNum(task.getCompletedNum() + 1); + cloudTaskMapper.updateById(task); + + String key = toProductImageResultKey + ":" + taskId; + String imageName = url.substring(url.lastIndexOf("/") + 1); + String status = imageName.equals("white_image.jpg") ? "Invalid" : "Success"; + GenerateResultVO generateResultVO = new GenerateResultVO(taskId, toProductImageResult.getId(), url, status, null); + redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); + + /*Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1)); + if (!status.equals("Invalid")) { + // 4、扣除积分 + Boolean b = creditsService.taskCreditsDeduction(accountId, taskId); + // 3、记录积分变更 + if (b) creditsService.updateChangedCredits(String.valueOf(accountId), taskId); + }*/ + } + + } + + @Override + @Transactional + public void relightBatch(String taskId, String url, String progress) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(ToProductImageResult::getTaskId, taskId); + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectOne(qw); + if (Objects.nonNull(toProductImageResult)) { + if (toProductImageResult.getBrightenValue() != null && toProductImageResult.getBrightenValue() != 1.0) { + pythonService.bright(url, toProductImageResult.getBrightenValue()); + } + toProductImageResult.setUrl(url); +// toProductImageResult.setResultType("Relight"); + toProductImageResult.setStatus("Success"); + toProductImageResultMapper.updateById(toProductImageResult); + + String taskIdBatch = toProductImageResult.getTaskIdBatch(); +// QueryWrapper cloudTaskQueryWrapper = new QueryWrapper<>(); +// cloudTaskQueryWrapper.lambda().eq(CloudTask::getTaskId, taskIdBatch); +// CloudTask cloudTask = cloudTaskMapper.selectOne(cloudTaskQueryWrapper); +// if (Objects.nonNull(cloudTask)) { +// if (cloudTask.getCompletedNum() == null) { +// cloudTask.setCompletedNum(1); +// }else { +// cloudTask.setCompletedNum(cloudTask.getCompletedNum() + 1); +// } +// if (progress.equals("OK")) { +// cloudTask.setStatus(1); +// cloudTask.setCompletedNum(cloudTask.getNums()); +// } +// cloudTaskMapper.updateById(cloudTask); +// } + cloudTaskMapper.increaseCompletedNum(taskIdBatch); + + String key = relightResultKey + ":" + taskId; + String imageName = url.substring(url.lastIndexOf("/") + 1); + String status = imageName.equals("white_image.jpg") ? "Invalid" : "Success"; + GenerateResultVO generateResultVO = new GenerateResultVO(taskId, toProductImageResult.getId(), url, status, null); + redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); + + /*Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1)); + if (!status.equals("Invalid")) { + // 4、扣除积分 + Boolean b = creditsService.taskCreditsDeduction(accountId, taskId); + // 3、记录积分变更 + if (b) creditsService.updateChangedCredits(String.valueOf(accountId), taskId); + }*/ + } + } + + @Override + @Transactional + public Boolean collectionLikeUpdate(CollectionLikeUpdateDTO collectionLikeUpdateDTO) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionSort::getRelationId, collectionLikeUpdateDTO.getOldRelationId()); + qw.lambda().eq(CollectionSort::getRelationType, collectionLikeUpdateDTO.getRelationType()); + CollectionSort collectionSort = collectionSortMapper.selectOne(qw); +// Long relationIdOld = collectionSort.getRelationId(); + collectionSort.setRelationId(collectionLikeUpdateDTO.getRelationId()); + collectionSortMapper.updateById(collectionSort); + if (collectionLikeUpdateDTO.getRelationType().equals(CollectionType.TO_PRODUCT_IMAGE.getValue()) || collectionLikeUpdateDTO.getRelationType().equals(CollectionType.RELIGHT.getValue())) { + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(collectionLikeUpdateDTO.getRelationId()); + toProductImageResult.setIsLike(1); + toProductImageResultMapper.updateById(toProductImageResult); + ToProductImageResult toProductImageResultOld = toProductImageResultMapper.selectById(collectionLikeUpdateDTO.getOldRelationId()); + toProductImageResultOld.setIsLike(0); + toProductImageResultMapper.updateById(toProductImageResultOld); + } else if (collectionLikeUpdateDTO.getRelationType().equals(CollectionType.POSE_TRANSFORM.getValue())) { + PoseTransformation poseTransformation = poseTransformationMapper.selectById(collectionLikeUpdateDTO.getRelationId()); + poseTransformation.setIsLiked((byte) 1); + poseTransformationMapper.updateById(poseTransformation); + PoseTransformation poseTransformationOld = poseTransformationMapper.selectById(collectionLikeUpdateDTO.getOldRelationId()); + poseTransformationOld.setIsLiked((byte) 0); + poseTransformationMapper.updateById(poseTransformationOld); + } + return Boolean.TRUE; + } + + @Override + public Boolean toProductImageElementDelete(Long id) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper + .set("project_id", null) // 显式设置 NULL + .eq("id", id); // 指定条件 + toProductElementMapper.update(null, updateWrapper); + return Boolean.TRUE; + } + + @Override + public ToProductElementVO convertRelightElement(Long id) { + ToProductImageResult toProductImageResult = toProductImageResultMapper.selectById(id); + + ToProductElement toProductElement = new ToProductElement(); + toProductElement.setUrl(toProductImageResult.getUrl()); +// toProductElement.setUserLikeGroupId(userLikeGroupId); + toProductElement.setProjectId(toProductImageResult.getProjectId()); + toProductElement.setCreateTime(LocalDateTime.now()); + toProductElementMapper.insert(toProductElement); + ToProductElementVO toProductElementVO = CopyUtil.copyObject(toProductElement, ToProductElementVO.class); + toProductElementVO.setMinioUrl(toProductElementVO.getUrl()); + toProductElementVO.setUrl(minioUtil.getPreSignedUrl(toProductElementVO.getUrl(), 24 * 60)); + return toProductElementVO; + } + + private String buildAdvancedPrompt(Long projectId, String prompt) { + String process = projectService.getById(projectId).getProcess(); + String ageGroup = null; + if (!"TO_PRODUCT_IMAGE".equals(process)) { + //高级工具转产品图不需要这个字段 + ageGroup = workspaceService.getWSByProjectId(projectId).getAgeGroup(); + } + String suffixCommon = "Pay attention to the size of the garment, the print, and the fabric texture, real photo, 8K, HDR, DOF, soft lighting, high detail, high quality, Do not return the original image."; + String suffixModelAdult = "Transform this image into a real model standing," + suffixCommon; + String suffixModelChild = "Transform this image into a real child model standing," + suffixCommon; + if ("SINGLE_DESIGN".equals(process) && "Adult".equals(ageGroup)) { + if (StringUtil.isNullOrEmpty(prompt)) { + return "Transform this image into a real garment showing in the white studio: garment on invisible mannequin" + suffixCommon; + } else { + return prompt + suffixCommon; + } + } else if ("SINGLE_DESIGN".equals(process) && "Child".equals(ageGroup)) { + if (StringUtil.isNullOrEmpty(prompt)) { + return "Transform this image into a real child model stand and wear this garment, in the white studio, facing camera, standing posture." + suffixCommon; + } else { + return prompt + suffixCommon; + } + } else if ("SERIES_DESIGN".equals(process) && "Adult".equals(ageGroup)) { + if (StringUtil.isNullOrEmpty(prompt)) { + return "in the white studio, facing camera, standing posture." + suffixModelAdult; + } else { + return prompt + suffixModelAdult; + } + } else if ("SERIES_DESIGN".equals(process) && "Child".equals(ageGroup)) { + if (StringUtil.isNullOrEmpty(prompt)) { + return "in the white studio, facing camera, standing posture." + suffixModelChild + "\n"; + } else { + return prompt + suffixModelChild; + } + } else if ("TO_PRODUCT_IMAGE".equals(process)) { + if (StringUtil.isNullOrEmpty(prompt)) { + throw new BusinessException("Please enter the prompt."); + } else { + return prompt + suffixCommon; + } + } else { + return "Transform this image into a realistic, studio-quality photograph." + "Pay attention to the size of the garment, the print, and the fabric texture. the white background. 8K, HDR, DOF, soft lighting" + ", high detail, high quality,Do not return the original image"; + } + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0ffbd62b..ef976e1c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -5,7 +5,7 @@ # ============================================================ server: - port: 5567 + port: 5566 spring: application: diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 3e045acd..3ce6037f 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -111,6 +111,7 @@ waistbandRight.cannot.be.empty=waistbandRight cannot be empty. handLeft.cannot.be.empty=handLeft cannot be empty. handRight.cannot.be.empty=handRight cannot be empty. id.cannot.be.empty=id cannot be empty. +url.cannot.be.empty=url cannot be empty. type.cannot.be.empty=type cannot be empty. color.cannot.be.empty=color cannot be empty. generateDetailId.cannot.be.empty=generateDetailId cannot be empty. diff --git a/src/main/resources/messages_zh.properties b/src/main/resources/messages_zh.properties index f60b9270..ece30b1e 100644 --- a/src/main/resources/messages_zh.properties +++ b/src/main/resources/messages_zh.properties @@ -110,6 +110,7 @@ waistbandRight.cannot.be.empty=waistbandRight不能为空。 handLeft.cannot.be.empty=handLeft不能为空。 handRight.cannot.be.empty=handRight不能为空。 id.cannot.be.empty=id不能为空。 +url.cannot.be.empty=url不能为空。 type.cannot.be.empty=type不能为空。 color.cannot.be.empty=color不能为空。 generateDetailId.cannot.be.empty=generateDetailId不能为空。