为模特和线稿设置性别
修改设置模特会增多问题 模型更换 设置可以切换男女兼容 TODO:扣除积分价格 转产品图模型未完成
This commit is contained in:
13
pom.xml
13
pom.xml
@@ -400,6 +400,19 @@
|
|||||||
<classifier>${javacpp.platform.linux-x86_64}</classifier>
|
<classifier>${javacpp.platform.linux-x86_64}</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.volcengine</groupId>
|
||||||
|
<artifactId>volcengine-java-sdk-ark-runtime</artifactId>
|
||||||
|
<version>LATEST</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Google 认证库 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.auth</groupId>
|
||||||
|
<artifactId>google-auth-library-oauth2-http</artifactId>
|
||||||
|
<version>LATEST</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- GIFEncoder 视频转gif-->
|
<!-- GIFEncoder 视频转gif-->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
42
src/main/java/com/ai/da/common/constant/ModelConstants.java
Normal file
42
src/main/java/com/ai/da/common/constant/ModelConstants.java
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package com.ai.da.common.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型相关常量类
|
||||||
|
* 用于存放 chooseModelAndPrompt 方法中的字符串常量
|
||||||
|
*/
|
||||||
|
public class ModelConstants {
|
||||||
|
|
||||||
|
// 类型常量
|
||||||
|
public static final String PRINTBOARD = "Printboard";
|
||||||
|
public static final String MOODBOARD = "Moodboard";
|
||||||
|
public static final String SKETCHBOARD = "Sketchboard";
|
||||||
|
|
||||||
|
// 模型级别常量
|
||||||
|
public static final String ADVANCED = "advanced";
|
||||||
|
public static final String HIGH = "high";
|
||||||
|
public static final String NORMAL = "normal";
|
||||||
|
|
||||||
|
// 模型名称常量
|
||||||
|
public static final String PRINTBOARD_ADVANCED_T2I = "qwen-image";
|
||||||
|
public static final String MOODBOARD_ADVANCED = "doubao-seedream-3-0-t2i-250415";
|
||||||
|
public static final String PRINTBOARD_HIGH_T2I = "doubao-seedream-3-0-t2i-250415";
|
||||||
|
public static final String PRINTBOARD_HIGH_I2I = "doubao-seededit-3-0-i2i-250628";
|
||||||
|
public static final String PRINTBOARD_ADVANCED_I2I = "doubao-seedream-4-0-250828";
|
||||||
|
public static final String IMAGEN_MODEL = "imagen-4.0-generate-001";
|
||||||
|
public static final String NANO_BANANA = "gemini-2.5-flash-image-preview";
|
||||||
|
public static final String LOCAL_MODEL = "local";
|
||||||
|
|
||||||
|
// 风格常量
|
||||||
|
public static final String PAINTING_STYLE = "Painting Style";
|
||||||
|
public static final String ILLUSTRATION_STYLE = "Illustration Style";
|
||||||
|
public static final String REAL_STYLE = "Real Style";
|
||||||
|
|
||||||
|
// 映射键
|
||||||
|
public static final String PROMPT = "prompt";
|
||||||
|
public static final String USE_MODEL = "UseModel";
|
||||||
|
|
||||||
|
// 防止实例化
|
||||||
|
private ModelConstants() {
|
||||||
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ public enum CreditsEventsEnum {
|
|||||||
MOOD_BOARD("MoodBoard","5"),
|
MOOD_BOARD("MoodBoard","5"),
|
||||||
SKETCH_BOARD("SketchBoard","5"),
|
SKETCH_BOARD("SketchBoard","5"),
|
||||||
TO_PRODUCT_IMAGE("ToProductImage","5"),
|
TO_PRODUCT_IMAGE("ToProductImage","5"),
|
||||||
TO_PRODUCT_IMAGE_FLUX("ToProductImageFlux","10"),
|
TO_PRODUCT_IMAGE_ADVANCED("ToProductImageAdvanced","10"),
|
||||||
RELIGHT("Relight","5"),
|
RELIGHT("Relight","5"),
|
||||||
RELIGHT_FLUX("RelightFlux","10"),
|
RELIGHT_FLUX("RelightFlux","10"),
|
||||||
QUESTIONNAIRE("Questionnaire","100"),
|
QUESTIONNAIRE("Questionnaire","100"),
|
||||||
@@ -51,6 +51,8 @@ public enum CreditsEventsEnum {
|
|||||||
OTHER("Other","5"),
|
OTHER("Other","5"),
|
||||||
|
|
||||||
WX_TEXT2IMG("WX_Text2Image", "5"),
|
WX_TEXT2IMG("WX_Text2Image", "5"),
|
||||||
|
QWEN_TEXT2IMG("QWEN_Text2Image", "5"),
|
||||||
|
DOUBAO_TEXT2IMG("Doubao_Text2Image", "5"),
|
||||||
WX_ANIMATION("WX_Animation", "30"),
|
WX_ANIMATION("WX_Animation", "30"),
|
||||||
FREEPIK_IMG2IMG("Freepik_img2img", "20"),
|
FREEPIK_IMG2IMG("Freepik_img2img", "20"),
|
||||||
FLUX_IMG2IMG("Flux_img2img","10"),
|
FLUX_IMG2IMG("Flux_img2img","10"),
|
||||||
|
|||||||
@@ -52,6 +52,12 @@ public class CollectionElement implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String level2Type;
|
private String level2Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 三级类型 目前只为线稿标注性别
|
||||||
|
*/
|
||||||
|
@TableField("level3_type")
|
||||||
|
private String level3Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 元素名(如果是颜色board 存潘通id+潘通名字 形式 ""11_mds")
|
* 元素名(如果是颜色board 存潘通id+潘通名字 形式 ""11_mds")
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -96,4 +96,6 @@ public interface GenerateService extends IService<Generate> {
|
|||||||
String getFluxResult(String taskId, String objectName);
|
String getFluxResult(String taskId, String objectName);
|
||||||
|
|
||||||
byte[] downloadVideoOrImage(String url);
|
byte[] downloadVideoOrImage(String url);
|
||||||
|
|
||||||
|
String createGoogleAsyncTask(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,4 +63,6 @@ public interface WorkspaceService extends IService<Workspace> {
|
|||||||
SaveOrUpdateProjectVO saveOrUpdateProject(ProjectDTO projectDTO);
|
SaveOrUpdateProjectVO saveOrUpdateProject(ProjectDTO projectDTO);
|
||||||
|
|
||||||
Long getByProjectId(Long projectId);
|
Long getByProjectId(Long projectId);
|
||||||
|
|
||||||
|
String getProjectSexById(Long projectId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.ai.da.python.vo.ImageSegmentation;
|
|||||||
import com.ai.da.service.*;
|
import com.ai.da.service.*;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
@@ -30,6 +31,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -55,6 +57,7 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementMapper, CollectionElement> implements CollectionElementService {
|
public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementMapper, CollectionElement> implements CollectionElementService {
|
||||||
@Resource
|
@Resource
|
||||||
private CollectionElementMapper collectionElementMapper;
|
private CollectionElementMapper collectionElementMapper;
|
||||||
@@ -79,6 +82,8 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
@Resource
|
@Resource
|
||||||
private MinioUtil minioUtil;
|
private MinioUtil minioUtil;
|
||||||
|
|
||||||
|
private WorkspaceService workspaceService;
|
||||||
|
|
||||||
@Value("${minio.bucketName.collectionElement}")
|
@Value("${minio.bucketName.collectionElement}")
|
||||||
private String collectionElement;
|
private String collectionElement;
|
||||||
@Value("${minio.bucketName.gradient}")
|
@Value("${minio.bucketName.gradient}")
|
||||||
@@ -201,6 +206,9 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
element.setLevel2Type(level2Type);
|
element.setLevel2Type(level2Type);
|
||||||
if (Objects.nonNull(uploadDTO.getProjectId())) {
|
if (Objects.nonNull(uploadDTO.getProjectId())) {
|
||||||
element.setProjectId(uploadDTO.getProjectId());
|
element.setProjectId(uploadDTO.getProjectId());
|
||||||
|
if (CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName().equals(element.getLevel1Type())) {
|
||||||
|
element.setLevel3Type(workspaceService.getProjectSexById(uploadDTO.getProjectId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// String linuxDomain = fileProperties.getLinuxDomain();
|
// String linuxDomain = fileProperties.getLinuxDomain();
|
||||||
// if (!StringUtils.isEmpty(linuxDomain)) {
|
// if (!StringUtils.isEmpty(linuxDomain)) {
|
||||||
@@ -392,55 +400,82 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证和处理设计集合元素
|
||||||
|
* <p>
|
||||||
|
* 功能说明:
|
||||||
|
* - 验证设计集合DTO中的各种元素(moodBoards、printBoards、sketchBoards等)
|
||||||
|
* - 处理渐变色彩板的base64图片上传到MinIO
|
||||||
|
* - 校验PIN数量限制(上衣、下衣、外套各不超过8个)
|
||||||
|
* - 验证模特信息和模板点位
|
||||||
|
* - 转换并整合来自library和generate的元素数据
|
||||||
|
*
|
||||||
|
* @param designDTO 设计集合DTO,包含所有设计元素信息
|
||||||
|
* @return ValidateElementVO 验证后的元素VO对象,包含处理后的所有元素数据
|
||||||
|
* @throws BusinessException 当数据验证失败时抛出业务异常
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ValidateElementVO validateElement(DesignCollectionDTO designDTO) {
|
public ValidateElementVO validateElement(DesignCollectionDTO designDTO) {
|
||||||
|
// 将设计DTO转换为验证元素VO对象
|
||||||
ValidateElementVO elementVO = CopyUtil.copyObject(designDTO, ValidateElementVO.class);
|
ValidateElementVO elementVO = CopyUtil.copyObject(designDTO, ValidateElementVO.class);
|
||||||
|
|
||||||
|
// 处理颜色板中的渐变色彩
|
||||||
List<CollectionColorDTO> colorBoards = elementVO.getColorBoards();
|
List<CollectionColorDTO> colorBoards = elementVO.getColorBoards();
|
||||||
for (CollectionColorDTO colorBoard : colorBoards) {
|
for (CollectionColorDTO colorBoard : colorBoards) {
|
||||||
if (Objects.nonNull(colorBoard.getGradient())) {
|
if (Objects.nonNull(colorBoard.getGradient())) {
|
||||||
|
// 解析base64格式的渐变图片数据
|
||||||
String colorImg = colorBoard.getGradient().getColorImg();
|
String colorImg = colorBoard.getGradient().getColorImg();
|
||||||
String[] parts = colorImg.split(",");
|
String[] parts = colorImg.split(",");
|
||||||
String imageType = parts[0].split("/")[1].split(";")[0];
|
String imageType = parts[0].split("/")[1].split(";")[0]; // 提取图片类型
|
||||||
String base64Data = parts[1];
|
String base64Data = parts[1]; // 提取base64数据
|
||||||
|
|
||||||
|
// 将base64图片上传到MinIO存储
|
||||||
String gradientMinioUrl = minioUtil.uploadImageFromBase64(gradientBucketName, base64Data, imageType);
|
String gradientMinioUrl = minioUtil.uploadImageFromBase64(gradientBucketName, base64Data, imageType);
|
||||||
colorBoard.setGradientMinioUrl(gradientMinioUrl);
|
colorBoard.setGradientMinioUrl(gradientMinioUrl);
|
||||||
colorBoard.getGradient().setColorImg(null);
|
colorBoard.getGradient().setColorImg(null); // 清空原始base64数据
|
||||||
colorBoard.setGradientString(JSON.toJSONString(colorBoard.getGradient()));
|
colorBoard.setGradientString(JSON.toJSONString(colorBoard.getGradient())); // 保存渐变配置JSON
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elementVO.setColorBoards(colorBoards);
|
elementVO.setColorBoards(colorBoards);
|
||||||
List<Long> usedElementIds = elementVO.getUsedElementIds();
|
|
||||||
List<CollectionElement> libraryCollectionElements = elementVO.getLibraryCollectionElements();
|
// 初始化用于收集各类元素的集合
|
||||||
List<CollectionElement> generateCollectionElements = elementVO.getGenerateCollectionElements();
|
List<Long> usedElementIds = elementVO.getUsedElementIds(); // 已使用的元素ID列表
|
||||||
//校验moodboard
|
List<CollectionElement> libraryCollectionElements = elementVO.getLibraryCollectionElements(); // 来自library的元素
|
||||||
|
List<CollectionElement> generateCollectionElements = elementVO.getGenerateCollectionElements(); // 来自generate的元素
|
||||||
|
// ========== 校验和处理moodBoards(情绪板) ==========
|
||||||
if (CollectionUtil.isNotEmpty(designDTO.getMoodBoards())) {
|
if (CollectionUtil.isNotEmpty(designDTO.getMoodBoards())) {
|
||||||
//校验designType
|
// 校验designType字段是否有效
|
||||||
validateDesignType(designDTO.getMoodBoards(), "moodBoards");
|
validateDesignType(designDTO.getMoodBoards(), "moodBoards");
|
||||||
|
|
||||||
|
// 提取类型为COLLECTION的moodBoard ID列表
|
||||||
List<Long> moodBoardIds = designDTO.getMoodBoards().stream()
|
List<Long> moodBoardIds = designDTO.getMoodBoards().stream()
|
||||||
.filter(f -> f.getDesignType().equals(DesignTypeEnum.COLLECTION.getRealName()))
|
.filter(f -> f.getDesignType().equals(DesignTypeEnum.COLLECTION.getRealName()))
|
||||||
.map(DesignCollectionElementDTO::getId)
|
.map(DesignCollectionElementDTO::getId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(moodBoardIds)) {
|
if (!CollectionUtils.isEmpty(moodBoardIds)) {
|
||||||
|
// 从数据库批量查询moodBoard元素
|
||||||
List<CollectionElement> MoodBoardElements = collectionElementMapper.selectBatchIds(moodBoardIds);
|
List<CollectionElement> MoodBoardElements = collectionElementMapper.selectBatchIds(moodBoardIds);
|
||||||
|
// 验证查询结果的完整性
|
||||||
if (CollectionUtil.isEmpty(MoodBoardElements) || MoodBoardElements.size() != moodBoardIds.size()) {
|
if (CollectionUtil.isEmpty(MoodBoardElements) || MoodBoardElements.size() != moodBoardIds.size()) {
|
||||||
throw new BusinessException("get.moodBoards.data.is.mismatch");
|
throw new BusinessException("get.moodBoards.data.is.mismatch");
|
||||||
}
|
}
|
||||||
elementVO.setMoodBoardElements(MoodBoardElements);
|
elementVO.setMoodBoardElements(MoodBoardElements);
|
||||||
usedElementIds.addAll(moodBoardIds);
|
usedElementIds.addAll(moodBoardIds); // 记录已使用的元素ID
|
||||||
}
|
}
|
||||||
//library
|
// 处理类型为LIBRARY的moodBoard元素
|
||||||
List<Long> libraryIds = designDTO.getMoodBoards().stream()
|
List<Long> libraryIds = designDTO.getMoodBoards().stream()
|
||||||
.filter(f -> f.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName()))
|
.filter(f -> f.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName()))
|
||||||
.map(DesignCollectionElementDTO::getId)
|
.map(DesignCollectionElementDTO::getId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(libraryIds)) {
|
if (!CollectionUtils.isEmpty(libraryIds)) {
|
||||||
List<Library> librarys = libraryService.getByIds(libraryIds);
|
List<Library> librarys = libraryService.getByIds(libraryIds);
|
||||||
//不校验了防止用户在library删除 对应不上
|
// 不严格校验,防止用户在library中删除元素导致对应不上
|
||||||
if (CollectionUtil.isNotEmpty(librarys)) {
|
if (CollectionUtil.isNotEmpty(librarys)) {
|
||||||
libraryCollectionElements.addAll(covertLibrarysToCollections(librarys, null));
|
libraryCollectionElements.addAll(covertLibrarysToCollections(librarys, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// generate
|
|
||||||
|
// 处理类型为GENERATE的moodBoard元素
|
||||||
List<Long> generateIds = designDTO.getMoodBoards().stream()
|
List<Long> generateIds = designDTO.getMoodBoards().stream()
|
||||||
.filter(o -> o.getDesignType().equals((DesignTypeEnum.GENERATE.getRealName())))
|
.filter(o -> o.getDesignType().equals((DesignTypeEnum.GENERATE.getRealName())))
|
||||||
.map(DesignCollectionElementDTO::getId)
|
.map(DesignCollectionElementDTO::getId)
|
||||||
@@ -452,38 +487,45 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 校验和处理printBoards(印花板) ==========
|
||||||
if (CollectionUtil.isNotEmpty(designDTO.getPrintBoards())) {
|
if (CollectionUtil.isNotEmpty(designDTO.getPrintBoards())) {
|
||||||
//校验designType
|
// 校验designType字段是否有效
|
||||||
validateDesignType(CopyUtil.copyList(designDTO.getPrintBoards(), DesignCollectionElementDTO.class), "printBoards");
|
validateDesignType(CopyUtil.copyList(designDTO.getPrintBoards(), DesignCollectionElementDTO.class), "printBoards");
|
||||||
|
|
||||||
|
// 提取类型为COLLECTION的printBoard ID列表
|
||||||
List<Long> printBoardIds = designDTO.getPrintBoards().stream()
|
List<Long> printBoardIds = designDTO.getPrintBoards().stream()
|
||||||
.filter(f -> f.getDesignType().equals(DesignTypeEnum.COLLECTION.getRealName()))
|
.filter(f -> f.getDesignType().equals(DesignTypeEnum.COLLECTION.getRealName()))
|
||||||
.map(DesignCollectionPrintElementDTO::getId)
|
.map(DesignCollectionPrintElementDTO::getId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(printBoardIds)) {
|
if (!CollectionUtils.isEmpty(printBoardIds)) {
|
||||||
//校验printboard
|
// 从数据库批量查询printBoard元素
|
||||||
List<CollectionElement> printBoardElements = collectionElementMapper.selectBatchIds(printBoardIds);
|
List<CollectionElement> printBoardElements = collectionElementMapper.selectBatchIds(printBoardIds);
|
||||||
|
// 验证查询结果的完整性
|
||||||
if (CollectionUtil.isEmpty(printBoardElements) || printBoardElements.size() != printBoardIds.size()) {
|
if (CollectionUtil.isEmpty(printBoardElements) || printBoardElements.size() != printBoardIds.size()) {
|
||||||
throw new BusinessException("get.printBoards.data.is.mismatch");
|
throw new BusinessException("get.printBoards.data.is.mismatch");
|
||||||
}
|
}
|
||||||
elementVO.setPrintBoardElements(printBoardElements);
|
elementVO.setPrintBoardElements(printBoardElements);
|
||||||
usedElementIds.addAll(printBoardIds);
|
usedElementIds.addAll(printBoardIds); // 记录已使用的元素ID
|
||||||
}
|
}
|
||||||
//library
|
// 处理类型为LIBRARY的printBoard元素
|
||||||
List<Long> libraryIds = designDTO.getPrintBoards().stream()
|
List<Long> libraryIds = designDTO.getPrintBoards().stream()
|
||||||
.filter(f -> f.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName()))
|
.filter(f -> f.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName()))
|
||||||
.map(DesignCollectionPrintElementDTO::getId)
|
.map(DesignCollectionPrintElementDTO::getId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(libraryIds)) {
|
if (!CollectionUtils.isEmpty(libraryIds)) {
|
||||||
List<Library> librarys = libraryService.getByIds(libraryIds);
|
List<Library> librarys = libraryService.getByIds(libraryIds);
|
||||||
//不校验了防止用户在library删除 对应不上
|
// 不严格校验,防止用户在library中删除元素导致对应不上
|
||||||
if (CollectionUtil.isNotEmpty(librarys)) {
|
if (CollectionUtil.isNotEmpty(librarys)) {
|
||||||
|
// 创建ID到printBoard元素的映射,用于保持元素属性
|
||||||
Map<Long, DesignCollectionPrintElementDTO> idToMap = designDTO.getPrintBoards()
|
Map<Long, DesignCollectionPrintElementDTO> idToMap = designDTO.getPrintBoards()
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(DesignCollectionPrintElementDTO::getId, v -> v));
|
.collect(Collectors.toMap(DesignCollectionPrintElementDTO::getId, v -> v));
|
||||||
libraryCollectionElements.addAll(covertLibrarysToPrintCollections(librarys, idToMap));
|
libraryCollectionElements.addAll(covertLibrarysToPrintCollections(librarys, idToMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// generate
|
|
||||||
|
// 处理类型为GENERATE的printBoard元素
|
||||||
List<Long> generateIds = designDTO.getPrintBoards().stream()
|
List<Long> generateIds = designDTO.getPrintBoards().stream()
|
||||||
.filter(o -> o.getDesignType().equals((DesignTypeEnum.GENERATE.getRealName())))
|
.filter(o -> o.getDesignType().equals((DesignTypeEnum.GENERATE.getRealName())))
|
||||||
.map(DesignCollectionPrintElementDTO::getId)
|
.map(DesignCollectionPrintElementDTO::getId)
|
||||||
@@ -491,6 +533,7 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
if (CollectionUtil.isNotEmpty(generateIds)) {
|
if (CollectionUtil.isNotEmpty(generateIds)) {
|
||||||
List<GenerateDetail> generateDetailList = generateDetailMapper.selectBatchIds(generateIds);
|
List<GenerateDetail> generateDetailList = generateDetailMapper.selectBatchIds(generateIds);
|
||||||
if (CollectionUtil.isNotEmpty(generateDetailList)) {
|
if (CollectionUtil.isNotEmpty(generateDetailList)) {
|
||||||
|
// 创建ID到printBoard元素的映射,用于保持元素属性
|
||||||
Map<Long, DesignCollectionPrintElementDTO> idToMap = designDTO.getPrintBoards()
|
Map<Long, DesignCollectionPrintElementDTO> idToMap = designDTO.getPrintBoards()
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(DesignCollectionPrintElementDTO::getId, v -> v));
|
.collect(Collectors.toMap(DesignCollectionPrintElementDTO::getId, v -> v));
|
||||||
@@ -498,33 +541,58 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 校验和处理sketchBoards(草图板) ==========
|
||||||
if (CollectionUtil.isNotEmpty(designDTO.getSketchBoards())) {
|
if (CollectionUtil.isNotEmpty(designDTO.getSketchBoards())) {
|
||||||
//校验PIN是否满足 上衣或者下衣必须不超过8
|
// 校验PIN数量限制:上衣、下衣、外套各不超过8个
|
||||||
long topNum = 0;
|
long topNum = 0;
|
||||||
long bottomNum = 0;
|
long bottomNum = 0;
|
||||||
long outerwearNum = 0;
|
long outerwearNum = 0;
|
||||||
|
//去掉与性别不符合的线稿元素 - 使用 Iterator 安全移除元素
|
||||||
|
Iterator<CollectionSketchDTO> sketchIterator = designDTO.getSketchBoards().iterator();
|
||||||
|
while (sketchIterator.hasNext()) {
|
||||||
|
CollectionSketchDTO sketchBoard = sketchIterator.next();
|
||||||
|
String level2Type = sketchBoard.getLevel2Type();
|
||||||
|
//判断性别和当前project性别是否一致,不一致则移除
|
||||||
|
String level3Type = collectionElementMapper.selectOne(new LambdaQueryWrapper<CollectionElement>().eq(CollectionElement::getId, sketchBoard.getSketchBoardId()).select(CollectionElement::getLevel3Type)).getLevel3Type();
|
||||||
|
if (!level3Type.equalsIgnoreCase(designDTO.getModelSex())) {
|
||||||
|
sketchIterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//再次判断草图板数量,如果为null,则跳出当前if
|
||||||
|
if (CollectionUtil.isNotEmpty(designDTO.getSketchBoards())) {
|
||||||
|
|
||||||
|
// 根据模特性别统计不同类型的PIN数量
|
||||||
if (designDTO.getModelSex().equals(Sex.FEMALE.getValue())) {
|
if (designDTO.getModelSex().equals(Sex.FEMALE.getValue())) {
|
||||||
|
// 女性模特:统计连衣裙和上衣类PIN数量
|
||||||
topNum = designDTO.getSketchBoards().stream()
|
topNum = designDTO.getSketchBoards().stream()
|
||||||
.filter(skecth -> skecth.getIsPin() == 1
|
.filter(skecth -> skecth.getIsPin() == 1
|
||||||
&& DesignPythonItem.DRESS_BLOUSE.contains(skecth.getLevel2Type())).count();
|
&& DesignPythonItem.DRESS_BLOUSE.contains(skecth.getLevel2Type())).count();
|
||||||
|
// 女性模特:统计裙子和裤子类PIN数量
|
||||||
bottomNum = designDTO.getSketchBoards().stream()
|
bottomNum = designDTO.getSketchBoards().stream()
|
||||||
.filter(skecth -> skecth.getIsPin() == 1
|
.filter(skecth -> skecth.getIsPin() == 1
|
||||||
&& DesignPythonItem.SKIRT_TROUSERS.contains(skecth.getLevel2Type())).count();
|
&& DesignPythonItem.SKIRT_TROUSERS.contains(skecth.getLevel2Type())).count();
|
||||||
} else if (designDTO.getModelSex().equals(Sex.MALE.getValue())) {
|
} else if (designDTO.getModelSex().equals(Sex.MALE.getValue())) {
|
||||||
|
// 男性模特:统计上衣类PIN数量
|
||||||
topNum = designDTO.getSketchBoards().stream()
|
topNum = designDTO.getSketchBoards().stream()
|
||||||
.filter(skecth -> skecth.getIsPin() == 1
|
.filter(skecth -> skecth.getIsPin() == 1
|
||||||
&& DesignPythonItem.TOPS.contains(skecth.getLevel2Type())).count();
|
&& DesignPythonItem.TOPS.contains(skecth.getLevel2Type())).count();
|
||||||
|
// 男性模特:统计下装类PIN数量
|
||||||
bottomNum = designDTO.getSketchBoards().stream()
|
bottomNum = designDTO.getSketchBoards().stream()
|
||||||
.filter(skecth -> skecth.getIsPin() == 1
|
.filter(skecth -> skecth.getIsPin() == 1
|
||||||
&& DesignPythonItem.BOTTOMS.contains(skecth.getLevel2Type())).count();
|
&& DesignPythonItem.BOTTOMS.contains(skecth.getLevel2Type())).count();
|
||||||
}
|
}
|
||||||
|
// 统计外套类PIN数量(男女通用)
|
||||||
outerwearNum = designDTO.getSketchBoards().stream()
|
outerwearNum = designDTO.getSketchBoards().stream()
|
||||||
.filter(skecth -> skecth.getIsPin() == 1
|
.filter(skecth -> skecth.getIsPin() == 1
|
||||||
&& DesignPythonItem.OUTWEAR.contains(skecth.getLevel2Type())).count();
|
&& DesignPythonItem.OUTWEAR.contains(skecth.getLevel2Type())).count();
|
||||||
|
|
||||||
|
// 验证PIN数量限制:每个类别不能超过8个
|
||||||
if (topNum > 8 || bottomNum > 8 || outerwearNum > 8) {
|
if (topNum > 8 || bottomNum > 8 || outerwearNum > 8) {
|
||||||
throw new BusinessException("the.number.of.PIN.top.or.bottom.or.outerwear.sketchBoard.cannot.be.more.than.8", ResultEnum.PROMPT.getCode());
|
throw new BusinessException("the.number.of.PIN.top.or.bottom.or.outerwear.sketchBoard.cannot.be.more.than.8", ResultEnum.PROMPT.getCode());
|
||||||
}
|
}
|
||||||
//校验designType
|
|
||||||
|
// 校验designType字段不能为空
|
||||||
Boolean result = designDTO.getSketchBoards().stream()
|
Boolean result = designDTO.getSketchBoards().stream()
|
||||||
.filter(mood -> StringUtils.isEmpty(mood.getDesignType()))
|
.filter(mood -> StringUtils.isEmpty(mood.getDesignType()))
|
||||||
.findFirst().isPresent();
|
.findFirst().isPresent();
|
||||||
@@ -532,35 +600,41 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
throw new BusinessException("sketchBoards.designType.cannot.be.empty");
|
throw new BusinessException("sketchBoards.designType.cannot.be.empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提取类型为COLLECTION的sketchBoard ID列表
|
||||||
List<Long> sketchBoardIds = designDTO.getSketchBoards().stream()
|
List<Long> sketchBoardIds = designDTO.getSketchBoards().stream()
|
||||||
.filter(f -> f.getDesignType().equals(DesignTypeEnum.COLLECTION.getRealName()))
|
.filter(f -> f.getDesignType().equals(DesignTypeEnum.COLLECTION.getRealName()))
|
||||||
.map(CollectionSketchDTO::getSketchBoardId)
|
.map(CollectionSketchDTO::getSketchBoardId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(sketchBoardIds)) {
|
if (!CollectionUtils.isEmpty(sketchBoardIds)) {
|
||||||
//校验sketchBoard
|
// 从数据库查询验证sketchBoard元素是否存在
|
||||||
List<CollectionElement> sketchBoardElements = collectionElementMapper.selectBatchIds(sketchBoardIds);
|
List<CollectionElement> sketchBoardElements = collectionElementMapper.selectBatchIds(sketchBoardIds);
|
||||||
if (CollectionUtil.isEmpty(sketchBoardElements) || sketchBoardElements.size() != sketchBoardIds.size()) {
|
if (CollectionUtil.isEmpty(sketchBoardElements) || sketchBoardElements.size() != sketchBoardIds.size()) {
|
||||||
throw new BusinessException("get.sketchBoards.data.is.mismatch");
|
throw new BusinessException("get.sketchBoards.data.is.mismatch");
|
||||||
}
|
}
|
||||||
|
// 设置验证通过的sketchBoard元素到结果对象
|
||||||
elementVO.setSketchBoardElements(sketchBoardElements);
|
elementVO.setSketchBoardElements(sketchBoardElements);
|
||||||
|
// 记录已使用的元素ID
|
||||||
usedElementIds.addAll(sketchBoardIds);
|
usedElementIds.addAll(sketchBoardIds);
|
||||||
}
|
}
|
||||||
//library
|
|
||||||
|
// 处理类型为LIBRARY的sketchBoard元素
|
||||||
List<Long> libraryIds = designDTO.getSketchBoards().stream()
|
List<Long> libraryIds = designDTO.getSketchBoards().stream()
|
||||||
.filter(f -> f.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName()))
|
.filter(f -> f.getDesignType().equals(DesignTypeEnum.LIBRARY.getRealName()))
|
||||||
.map(CollectionSketchDTO::getSketchBoardId)
|
.map(CollectionSketchDTO::getSketchBoardId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(libraryIds)) {
|
if (!CollectionUtils.isEmpty(libraryIds)) {
|
||||||
List<Library> librarys = libraryService.getByIds(libraryIds);
|
List<Library> librarys = libraryService.getByIds(libraryIds);
|
||||||
//不校验了防止用户在library删除 对应不上
|
// 不严格校验,防止用户在library中删除元素导致对应不上
|
||||||
if (CollectionUtil.isNotEmpty(librarys)) {
|
if (CollectionUtil.isNotEmpty(librarys)) {
|
||||||
|
// 创建ID到sketchBoard元素的映射,用于保持元素属性
|
||||||
Map<Long, CollectionSketchDTO> idToMap = designDTO.getSketchBoards()
|
Map<Long, CollectionSketchDTO> idToMap = designDTO.getSketchBoards()
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(CollectionSketchDTO::getSketchBoardId, v -> v));
|
.collect(Collectors.toMap(CollectionSketchDTO::getSketchBoardId, v -> v));
|
||||||
libraryCollectionElements.addAll(covertLibrarysToCollections(librarys, idToMap));
|
libraryCollectionElements.addAll(covertLibrarysToCollections(librarys, idToMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// generate
|
|
||||||
|
// 处理类型为GENERATE的sketchBoard元素
|
||||||
List<Long> generateIds = designDTO.getSketchBoards().stream()
|
List<Long> generateIds = designDTO.getSketchBoards().stream()
|
||||||
.filter(o -> o.getDesignType().equals((DesignTypeEnum.GENERATE.getRealName())))
|
.filter(o -> o.getDesignType().equals((DesignTypeEnum.GENERATE.getRealName())))
|
||||||
.map(CollectionSketchDTO::getSketchBoardId)
|
.map(CollectionSketchDTO::getSketchBoardId)
|
||||||
@@ -568,6 +642,7 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
if (CollectionUtil.isNotEmpty(generateIds)) {
|
if (CollectionUtil.isNotEmpty(generateIds)) {
|
||||||
List<GenerateDetail> generateDetailList = generateDetailMapper.selectBatchIds(generateIds);
|
List<GenerateDetail> generateDetailList = generateDetailMapper.selectBatchIds(generateIds);
|
||||||
if (CollectionUtil.isNotEmpty(generateDetailList)) {
|
if (CollectionUtil.isNotEmpty(generateDetailList)) {
|
||||||
|
// 创建ID到sketchBoard元素的映射,用于保持元素属性
|
||||||
Map<Long, CollectionSketchDTO> idToMap = designDTO.getSketchBoards()
|
Map<Long, CollectionSketchDTO> idToMap = designDTO.getSketchBoards()
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(CollectionSketchDTO::getSketchBoardId, v -> v));
|
.collect(Collectors.toMap(CollectionSketchDTO::getSketchBoardId, v -> v));
|
||||||
@@ -575,6 +650,7 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//校验marketingSketch
|
//校验marketingSketch
|
||||||
// 2023.12版本去掉了这个入参
|
// 2023.12版本去掉了这个入参
|
||||||
/* if (CollectionUtil.isNotEmpty(designDTO.getMarketingSketchs())) {
|
/* if (CollectionUtil.isNotEmpty(designDTO.getMarketingSketchs())) {
|
||||||
@@ -604,13 +680,17 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
//校验控制生成类型
|
|
||||||
|
// ========== 校验控制生成类型参数 ==========
|
||||||
|
// 验证singleOverall参数(单品/整体生成控制)
|
||||||
SingleOverallEnum singleOverall = SingleOverallEnum.of(designDTO.getSingleOverall());
|
SingleOverallEnum singleOverall = SingleOverallEnum.of(designDTO.getSingleOverall());
|
||||||
if (Objects.isNull(singleOverall)) {
|
if (Objects.isNull(singleOverall)) {
|
||||||
log.error("未知singleOverall param:{}", designDTO.getSingleOverall());
|
log.error("未知singleOverall param:{}", designDTO.getSingleOverall());
|
||||||
log.info("入参 designDTO => {}", designDTO);
|
log.info("入参 designDTO => {}", designDTO);
|
||||||
throw new BusinessException("unknown.parameter.singleOverall");
|
throw new BusinessException("unknown.parameter.singleOverall");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果是单品生成模式,需要验证switchCategory参数
|
||||||
if (SingleOverallEnum.SINGLE.equals(singleOverall)) {
|
if (SingleOverallEnum.SINGLE.equals(singleOverall)) {
|
||||||
SwitchCategoryEnum switchCategory = SwitchCategoryEnum.of(designDTO.getSwitchCategory());
|
SwitchCategoryEnum switchCategory = SwitchCategoryEnum.of(designDTO.getSwitchCategory());
|
||||||
if (Objects.isNull(switchCategory)) {
|
if (Objects.isNull(switchCategory)) {
|
||||||
@@ -619,36 +699,57 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
throw new BusinessException("unknown.parameter.switchCategory");
|
throw new BusinessException("unknown.parameter.switchCategory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 校验模特
|
|
||||||
|
// ========== 校验和处理模特信息 ==========
|
||||||
if (!CollectionUtils.isEmpty(designDTO.getMannequins())) {
|
if (!CollectionUtils.isEmpty(designDTO.getMannequins())) {
|
||||||
|
// 处理多个模特的情况 - 使用 Iterator 安全移除元素
|
||||||
List<DesignLibraryModelPointVO> designLibraryModelPointVOList = new ArrayList<>();
|
List<DesignLibraryModelPointVO> designLibraryModelPointVOList = new ArrayList<>();
|
||||||
for (MannequinDTO mannequin : designDTO.getMannequins()) {
|
Iterator<MannequinDTO> mannequinIterator = designDTO.getMannequins().iterator();
|
||||||
|
while (mannequinIterator.hasNext()) {
|
||||||
|
MannequinDTO mannequin = mannequinIterator.next();
|
||||||
if (mannequin.getType().equals("System")) {
|
if (mannequin.getType().equals("System")) {
|
||||||
|
// 处理系统模特
|
||||||
SysFileVO byId = sysFileService.getById(mannequin.getId());
|
SysFileVO byId = sysFileService.getById(mannequin.getId());
|
||||||
if (Objects.isNull(byId)) {
|
if (Objects.isNull(byId)) {
|
||||||
log.info("未知模特:{}:{}", mannequin.getId(), "System");
|
log.info("未知模特:{}:{}", mannequin.getId(), "System");
|
||||||
throw new BusinessException("model.not.found");
|
throw new BusinessException("model.not.found");
|
||||||
}
|
}
|
||||||
|
if (!designDTO.getModelSex().equalsIgnoreCase(byId.getLevel2Type())) {
|
||||||
|
mannequinIterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 注释:女性模特的风格设置(已禁用)
|
||||||
// if (!StringUtils.isEmpty(byId.getLevel3Type()) && byId.getLevel2Type().equals("Female")) {
|
// if (!StringUtils.isEmpty(byId.getLevel3Type()) && byId.getLevel2Type().equals("Female")) {
|
||||||
// elementVO.setStyle(byId.getLevel3Type());
|
// elementVO.setStyle(byId.getLevel3Type());
|
||||||
// }
|
// }
|
||||||
|
// 获取模特点位信息并计算模板点位
|
||||||
LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(byId.getId(), mannequin.getType());
|
LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(byId.getId(), mannequin.getType());
|
||||||
designLibraryModelPointVOList.add(calculateTemplatePointTemplate(modelPoint, 700, 320, byId.getUrl()));
|
designLibraryModelPointVOList.add(calculateTemplatePointTemplate(modelPoint, 700, 320, byId.getUrl()));
|
||||||
} else {
|
} else {
|
||||||
|
// 处理用户自定义模特
|
||||||
Library byId = libraryService.getById(mannequin.getId());
|
Library byId = libraryService.getById(mannequin.getId());
|
||||||
|
//如果当前模特性别和project模特性别不一致,则为此模特进行design
|
||||||
|
if (!designDTO.getModelSex().equalsIgnoreCase(byId.getLevel2Type())) {
|
||||||
|
mannequinIterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(byId.getId(), mannequin.getType());
|
LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(byId.getId(), mannequin.getType());
|
||||||
designLibraryModelPointVOList.add(calculateTemplatePointTemplate(modelPoint, byId.getHigh(), byId.getWidth(), byId.getUrl()));
|
designLibraryModelPointVOList.add(calculateTemplatePointTemplate(modelPoint, byId.getHigh(), byId.getWidth(), byId.getUrl()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elementVO.setMannequins(designLibraryModelPointVOList);
|
elementVO.setMannequins(designLibraryModelPointVOList);
|
||||||
} else {
|
} else {
|
||||||
|
// 处理单个模特的情况(通过templateId指定)
|
||||||
if (!StringUtils.isEmpty(designDTO.getModelType())) {
|
if (!StringUtils.isEmpty(designDTO.getModelType())) {
|
||||||
if (designDTO.getModelType().equals(ModelType.LIBRARY.getValue())) {
|
if (designDTO.getModelType().equals(ModelType.LIBRARY.getValue())) {
|
||||||
|
// 处理用户自定义模特
|
||||||
Library byId = libraryService.getById(designDTO.getTemplateId());
|
Library byId = libraryService.getById(designDTO.getTemplateId());
|
||||||
LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(byId.getId(), designDTO.getModelType());
|
LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(byId.getId(), designDTO.getModelType());
|
||||||
elementVO.setDesignLibraryModelPoint(calculateTemplatePointTemplate(modelPoint, byId.getHigh(), byId.getWidth(), byId.getUrl()));
|
elementVO.setDesignLibraryModelPoint(calculateTemplatePointTemplate(modelPoint, byId.getHigh(), byId.getWidth(), byId.getUrl()));
|
||||||
} else if (designDTO.getModelType().equals(ModelType.SYSTEM.getValue())) {
|
} else if (designDTO.getModelType().equals(ModelType.SYSTEM.getValue())) {
|
||||||
|
// 处理系统模特
|
||||||
SysFileVO byId = sysFileService.getById(designDTO.getTemplateId());
|
SysFileVO byId = sysFileService.getById(designDTO.getTemplateId());
|
||||||
|
// 设置女性模特的风格类型
|
||||||
if (Objects.nonNull(byId) && !StringUtils.isEmpty(byId.getLevel3Type()) && byId.getLevel2Type().equals("Female")) {
|
if (Objects.nonNull(byId) && !StringUtils.isEmpty(byId.getLevel3Type()) && byId.getLevel2Type().equals("Female")) {
|
||||||
elementVO.setStyle(byId.getLevel3Type());
|
elementVO.setStyle(byId.getLevel3Type());
|
||||||
}
|
}
|
||||||
@@ -657,17 +758,25 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 设置最终的验证结果参数 ==========
|
||||||
|
// 设置模特性别
|
||||||
elementVO.setModelSex(designDTO.getModelSex());
|
elementVO.setModelSex(designDTO.getModelSex());
|
||||||
|
// 设置请求ID列表(用于批量查询)
|
||||||
elementVO.setRequestIdList(designDTO.getRequestIdList());
|
elementVO.setRequestIdList(designDTO.getRequestIdList());
|
||||||
|
// 设置设计方案数量,默认为8个
|
||||||
if (null != designDTO.getDesignNum()) {
|
if (null != designDTO.getDesignNum()) {
|
||||||
elementVO.setDesignNum(designDTO.getDesignNum());
|
elementVO.setDesignNum(designDTO.getDesignNum());
|
||||||
} else {
|
} else {
|
||||||
elementVO.setDesignNum(8);
|
elementVO.setDesignNum(8);
|
||||||
}
|
}
|
||||||
|
// 设置品牌信息(如果存在)
|
||||||
if (null != designDTO.getBrandId()) {
|
if (null != designDTO.getBrandId()) {
|
||||||
elementVO.setBrandId(designDTO.getBrandId());
|
elementVO.setBrandId(designDTO.getBrandId()); // 设置品牌ID
|
||||||
elementVO.setBrandScale(designDTO.getBrandScale());
|
elementVO.setBrandScale(designDTO.getBrandScale()); // 设置品牌比例
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 返回验证结果对象
|
||||||
return elementVO;
|
return elementVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -362,20 +362,25 @@ public class DesignServiceImpl extends ServiceImpl<DesignMapper, Design> impleme
|
|||||||
Long designId = saveOne(designDTO, collectionId, userInfo.getId());
|
Long designId = saveOne(designDTO, collectionId, userInfo.getId());
|
||||||
//计算library
|
//计算library
|
||||||
// calculateLibraryAndSysFile(designDTO, elementVO, userInfo);
|
// calculateLibraryAndSysFile(designDTO, elementVO, userInfo);
|
||||||
//组装design入参
|
|
||||||
|
// ========== AI设计生成阶段 ==========
|
||||||
|
|
||||||
|
// 组装design入参 - 将业务参数转换为Python AI服务所需的格式
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
DesignPythonObjects pythonObjects = pythonService.covertDesignParam(designDTO.getSystemScale(),
|
DesignPythonObjects pythonObjects = pythonService.covertDesignParam(designDTO.getSystemScale(),
|
||||||
designDTO.getSingleOverall(), designDTO.getSwitchCategory(), elementVO, designDTO.getProcessId(), collectionIdParam);
|
designDTO.getSingleOverall(), designDTO.getSwitchCategory(), elementVO, designDTO.getProcessId(), collectionIdParam);
|
||||||
long endTime = System.currentTimeMillis();
|
long endTime = System.currentTimeMillis();
|
||||||
long totalTimeInSeconds = (endTime - startTime) / 1000;
|
long totalTimeInSeconds = (endTime - startTime) / 1000;
|
||||||
log.info("组装入参运行时间:" + totalTimeInSeconds + " 秒");
|
log.info("组装入参运行时间:" + totalTimeInSeconds + " 秒");
|
||||||
// pythonObjects增加image_id关联
|
|
||||||
|
// pythonObjects增加image_id关联 - 建立设计元素与图片的关联关系
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
relationImageIds(pythonObjects);
|
relationImageIds(pythonObjects);
|
||||||
endTime = System.currentTimeMillis();
|
endTime = System.currentTimeMillis();
|
||||||
totalTimeInSeconds = (endTime - startTime) / 1000;
|
totalTimeInSeconds = (endTime - startTime) / 1000;
|
||||||
log.info("增加image_id关联运行时间:" + totalTimeInSeconds + " 秒");
|
log.info("增加image_id关联运行时间:" + totalTimeInSeconds + " 秒");
|
||||||
//design
|
|
||||||
|
// design - 调用Python AI服务进行设计生成
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
String requestId = UUID.randomUUID().toString();
|
String requestId = UUID.randomUUID().toString();
|
||||||
pythonObjects.setRequestId(requestId);
|
pythonObjects.setRequestId(requestId);
|
||||||
@@ -383,10 +388,13 @@ public class DesignServiceImpl extends ServiceImpl<DesignMapper, Design> impleme
|
|||||||
endTime = System.currentTimeMillis();
|
endTime = System.currentTimeMillis();
|
||||||
totalTimeInSeconds = (endTime - startTime) / 1000;
|
totalTimeInSeconds = (endTime - startTime) / 1000;
|
||||||
log.info("design python端运行时间:" + totalTimeInSeconds + " 秒");
|
log.info("design python端运行时间:" + totalTimeInSeconds + " 秒");
|
||||||
//生成library
|
// ========== 后处理阶段 ==========
|
||||||
|
|
||||||
|
// 生成library - 根据设计元素生成设计库信息
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
generateLibrary(elementVO, designDTO.getTimeZone());
|
generateLibrary(elementVO, designDTO.getTimeZone());
|
||||||
//处理关联关系,修复element覆盖得情况
|
|
||||||
|
// 处理关联关系,修复element覆盖的情况(已注释)
|
||||||
// List<CollectionElement> relationElements = collectionElementService.getByOnlyCollectionId(collectionId);
|
// List<CollectionElement> relationElements = collectionElementService.getByOnlyCollectionId(collectionId);
|
||||||
// List<Long> relationElementIds = relationElements.stream().map(CollectionElement::getId).collect(Collectors.toList());
|
// List<Long> relationElementIds = relationElements.stream().map(CollectionElement::getId).collect(Collectors.toList());
|
||||||
// handleCollectionElementRelation(collectionId, null != collectionIdParam, relationElementIds);
|
// handleCollectionElementRelation(collectionId, null != collectionIdParam, relationElementIds);
|
||||||
@@ -394,7 +402,7 @@ public class DesignServiceImpl extends ServiceImpl<DesignMapper, Design> impleme
|
|||||||
totalTimeInSeconds = (endTime - startTime) / 1000;
|
totalTimeInSeconds = (endTime - startTime) / 1000;
|
||||||
log.info("处理关联关系运行时间:" + totalTimeInSeconds + " 秒");
|
log.info("处理关联关系运行时间:" + totalTimeInSeconds + " 秒");
|
||||||
|
|
||||||
|
// 构建设计上下文信息 - 保存设计过程中的关键参数和状态
|
||||||
Map<String, Object> context = new HashMap<>();
|
Map<String, Object> context = new HashMap<>();
|
||||||
context.put("pythonObjects", pythonObjects); // 转换后的 Python 请求参数
|
context.put("pythonObjects", pythonObjects); // 转换后的 Python 请求参数
|
||||||
context.put("designId", designId); // 设计 ID
|
context.put("designId", designId); // 设计 ID
|
||||||
@@ -404,11 +412,14 @@ public class DesignServiceImpl extends ServiceImpl<DesignMapper, Design> impleme
|
|||||||
context.put("singleOverall", designDTO.getSingleOverall()); // 其他设计参数
|
context.put("singleOverall", designDTO.getSingleOverall()); // 其他设计参数
|
||||||
context.put("requestIdList", elementVO.getRequestIdList());
|
context.put("requestIdList", elementVO.getRequestIdList());
|
||||||
|
|
||||||
// 将上下文存入全局设计上下文中
|
// 将上下文存入全局设计上下文中 - 用于后续异步查询和处理
|
||||||
designContext.put(requestId, context);
|
designContext.put(requestId, context);
|
||||||
|
|
||||||
//保存python返回信息;保存designItem和detail
|
// 保存python返回信息;保存designItem和detail(注释说明)
|
||||||
|
// 注意:实际的设计结果保存是通过异步回调方式处理的,这里只是准备阶段
|
||||||
// return savePythonDesignItemAndDetail(pythonObjects, designId, collectionId, userInfo, designDTO.getTimeZone(), responseJSONObject, designDTO.getSingleOverall());
|
// return savePythonDesignItemAndDetail(pythonObjects, designId, collectionId, userInfo, designDTO.getTimeZone(), responseJSONObject, designDTO.getSingleOverall());
|
||||||
|
|
||||||
|
// 返回请求ID - 客户端可以使用此ID查询设计进度和结果
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2904,6 +2915,7 @@ public class DesignServiceImpl extends ServiceImpl<DesignMapper, Design> impleme
|
|||||||
collectionElement.setAccountId(project.getAccountId());
|
collectionElement.setAccountId(project.getAccountId());
|
||||||
collectionElement.setProjectId(project.getId());
|
collectionElement.setProjectId(project.getId());
|
||||||
collectionElement.setLevel2Type(receiveCollectionElement.getLevel2Type());
|
collectionElement.setLevel2Type(receiveCollectionElement.getLevel2Type());
|
||||||
|
collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId()));
|
||||||
collectionElement.setName(split1[0]);
|
collectionElement.setName(split1[0]);
|
||||||
collectionElement.setUrl(url);
|
collectionElement.setUrl(url);
|
||||||
collectionElement.setHasPin((byte) 0);
|
collectionElement.setHasPin((byte) 0);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import cn.hutool.json.JSONObject;
|
|||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.ai.da.common.config.exception.BusinessException;
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
import com.ai.da.common.constant.CommonConstant;
|
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.context.UserContext;
|
||||||
import com.ai.da.common.enums.*;
|
import com.ai.da.common.enums.*;
|
||||||
import com.ai.da.common.response.ResultEnum;
|
import com.ai.da.common.response.ResultEnum;
|
||||||
@@ -28,16 +29,22 @@ import com.alibaba.dashscope.exception.ApiException;
|
|||||||
import com.alibaba.dashscope.exception.NoApiKeyException;
|
import com.alibaba.dashscope.exception.NoApiKeyException;
|
||||||
import com.alibaba.dashscope.utils.JsonUtils;
|
import com.alibaba.dashscope.utils.JsonUtils;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.google.auth.oauth2.GoogleCredentials;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.volcengine.ark.runtime.model.images.generation.GenerateImagesRequest;
|
||||||
|
import com.volcengine.ark.runtime.model.images.generation.ImagesResponse;
|
||||||
|
import com.volcengine.ark.runtime.service.ArkService;
|
||||||
import io.minio.errors.MinioException;
|
import io.minio.errors.MinioException;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import okhttp3.*;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
@@ -70,7 +77,7 @@ import java.util.regex.Pattern;
|
|||||||
import static com.ai.da.common.enums.CollectionLevel1TypeEnum.*;
|
import static com.ai.da.common.enums.CollectionLevel1TypeEnum.*;
|
||||||
import static com.ai.da.common.enums.CreditsEventsEnum.PATTERN;
|
import static com.ai.da.common.enums.CreditsEventsEnum.PATTERN;
|
||||||
import static com.ai.da.common.enums.CreditsEventsEnum.TO_PRODUCT_IMAGE;
|
import static com.ai.da.common.enums.CreditsEventsEnum.TO_PRODUCT_IMAGE;
|
||||||
import static com.ai.da.common.enums.CreditsEventsEnum.TO_PRODUCT_IMAGE_FLUX;
|
import static com.ai.da.common.enums.CreditsEventsEnum.TO_PRODUCT_IMAGE_ADVANCED;
|
||||||
import static com.ai.da.common.enums.WangXiangTaskStatusEnum.FAILED;
|
import static com.ai.da.common.enums.WangXiangTaskStatusEnum.FAILED;
|
||||||
import static com.ai.da.common.enums.WangXiangTaskStatusEnum.UNKNOWN_W;
|
import static com.ai.da.common.enums.WangXiangTaskStatusEnum.UNKNOWN_W;
|
||||||
|
|
||||||
@@ -159,6 +166,10 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
@Value("${ALIYUN_API_KEY}")
|
@Value("${ALIYUN_API_KEY}")
|
||||||
private String ALIYUN_API_KEY;
|
private String ALIYUN_API_KEY;
|
||||||
|
|
||||||
|
@Value("${DOUBAO_API_KEY}")
|
||||||
|
private String DOUBAO_API_KEY;
|
||||||
|
|
||||||
|
|
||||||
@Value("${FREEPIK_API_KEY}")
|
@Value("${FREEPIK_API_KEY}")
|
||||||
private String FREEPIK_API_KEY;
|
private String FREEPIK_API_KEY;
|
||||||
|
|
||||||
@@ -602,11 +613,354 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
return handleFluxPatternGeneration(generateDTO);
|
return handleFluxPatternGeneration(generateDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3、处理标准生成流程
|
String modelName = generateDTO.getModelName();
|
||||||
|
|
||||||
|
HashMap<String, String> modelAndPromptMap = chooseModelAndPrompt(generateDTO, modelName);
|
||||||
|
String useModel = modelAndPromptMap.get(ModelConstants.USE_MODEL);
|
||||||
|
String prompt = modelAndPromptMap.get(ModelConstants.PROMPT);
|
||||||
|
|
||||||
|
if (useModel != null) {
|
||||||
|
if (useModel.contains("doubao")) {
|
||||||
|
return handleDouBaoModelGeneration(generateDTO, useModel, prompt);
|
||||||
|
} else if (useModel.contains("qwen")) {
|
||||||
|
return handleQwenModelGeneration(generateDTO, useModel, prompt);
|
||||||
|
} else if (useModel.contains("imagen")) {
|
||||||
|
return handleImagenModelGeneration(generateDTO, useModel, prompt);
|
||||||
|
} else if (useModel.contains("gemini")) {
|
||||||
|
return handleNanoBananaModelGeneration(generateDTO, useModel, prompt);
|
||||||
|
} else if (ModelConstants.LOCAL_MODEL.equals(useModel)) {
|
||||||
return handleStandardGeneration(generateDTO);
|
return handleStandardGeneration(generateDTO);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return handleStandardGeneration(generateDTO);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============== 以下是辅助方法 ==============
|
// ============== 以下是辅助方法 ==============
|
||||||
|
private PrepareForGenerateVO handleImagenModelGeneration(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) {
|
||||||
|
// 校验积分是否足够
|
||||||
|
// validateCredits(CreditsEventsEnum.WX_TEXT2IMG);
|
||||||
|
// 创建生成任务
|
||||||
|
String taskId = null;
|
||||||
|
try {
|
||||||
|
taskId = createGoogleAsyncTask(generateDTO, useModel, prompt);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.WX_TEXT2IMG);
|
||||||
|
return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PrepareForGenerateVO handleNanoBananaModelGeneration(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) {
|
||||||
|
// 校验积分是否足够
|
||||||
|
// validateCredits(CreditsEventsEnum.WX_TEXT2IMG);
|
||||||
|
// 创建生成任务
|
||||||
|
String taskId = null;
|
||||||
|
try {
|
||||||
|
taskId = createGoogleAsyncTask(generateDTO, useModel, prompt);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.WX_TEXT2IMG);
|
||||||
|
return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createGoogleAsyncTask(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) {
|
||||||
|
// 从 resources 加载 JSON 文件
|
||||||
|
System.setProperty("https.proxyHost", "127.0.0.1");
|
||||||
|
System.setProperty("https.proxyPort", "10809");
|
||||||
|
String level1Type = generateDTO.getLevel1Type();
|
||||||
|
String level2Type = generateDTO.getLevel2Type();
|
||||||
|
Long userId = generateDTO.getUserId();
|
||||||
|
String gender = generateDTO.getGender();
|
||||||
|
|
||||||
|
|
||||||
|
boolean isUseImage;
|
||||||
|
String resultPath;
|
||||||
|
String uuid = UUID.randomUUID().toString();
|
||||||
|
if (Objects.isNull(generateDTO.getCollectionElementId())
|
||||||
|
|| StringUtil.isNullOrEmpty(generateDTO.getDesignType())) {
|
||||||
|
isUseImage = false;
|
||||||
|
} else {
|
||||||
|
isUseImage = true;
|
||||||
|
}
|
||||||
|
String model;
|
||||||
|
String finalImagePath = null;
|
||||||
|
if (isUseImage) {
|
||||||
|
String imagePath = geti2iImagePath(generateDTO);
|
||||||
|
|
||||||
|
// 只有当imagePath不为null时才获取图片的base64编码
|
||||||
|
if (imagePath != null) {
|
||||||
|
try {
|
||||||
|
finalImagePath = minioUtil.getImageAsBase64(imagePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("获取图片base64编码失败", e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultPath = userId + "/imageToSketch" + "/" + uuid;
|
||||||
|
model = ModelConstants.NANO_BANANA;
|
||||||
|
} else {
|
||||||
|
resultPath = userId + "/sketch" + "/" + uuid;
|
||||||
|
model = ModelConstants.IMAGEN_MODEL;
|
||||||
|
}
|
||||||
|
// 拼接 endpoint
|
||||||
|
String projectId = "aida-461108";
|
||||||
|
String location;
|
||||||
|
String endpoint;
|
||||||
|
|
||||||
|
|
||||||
|
JSONObject instanceObj = new JSONObject();
|
||||||
|
JSONObject parametersObj = new JSONObject();
|
||||||
|
JSONObject requestBody = new JSONObject();
|
||||||
|
|
||||||
|
if (isUseImage && finalImagePath != null) {
|
||||||
|
location = "global";
|
||||||
|
endpoint = String.format(
|
||||||
|
"https://aiplatform.googleapis.com/v1/projects/%s/locations/%s/publishers/google/models/%s:generateContent",
|
||||||
|
projectId, location, model
|
||||||
|
);
|
||||||
|
|
||||||
|
// 使用 gemini-2.5-flash-image-preview 模型时的请求体格式
|
||||||
|
// 创建图片部分
|
||||||
|
JSONObject imagePart = new JSONObject();
|
||||||
|
JSONObject inlineData = new JSONObject();
|
||||||
|
inlineData.set("mimeType", "image/png");
|
||||||
|
inlineData.set("data", finalImagePath);
|
||||||
|
imagePart.set("inlineData", inlineData);
|
||||||
|
|
||||||
|
// 创建文本部分
|
||||||
|
JSONObject textPart = new JSONObject();
|
||||||
|
textPart.set("text", prompt);
|
||||||
|
|
||||||
|
// 创建内容对象
|
||||||
|
JSONObject content = new JSONObject();
|
||||||
|
content.set("role", "user");
|
||||||
|
content.set("parts", Arrays.asList(imagePart, textPart));
|
||||||
|
|
||||||
|
// 设置 contents 数组
|
||||||
|
requestBody.set("contents", Arrays.asList(content));
|
||||||
|
|
||||||
|
// 设置 generationConfig
|
||||||
|
JSONObject generationConfig = new JSONObject();
|
||||||
|
// generationConfig.set("temperature", 1);
|
||||||
|
generationConfig.set("maxOutputTokens", 8192);
|
||||||
|
generationConfig.set("responseModalities", Arrays.asList("TEXT", "IMAGE"));
|
||||||
|
// generationConfig.set("topP", 0.95);
|
||||||
|
requestBody.set("generationConfig", generationConfig);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
location = "us-central1";
|
||||||
|
endpoint = String.format(
|
||||||
|
"https://%s-aiplatform.googleapis.com/v1/projects/%s/locations/%s/publishers/google/models/%s:predict",
|
||||||
|
location, projectId, location, model
|
||||||
|
);
|
||||||
|
// 使用 imagen 模型时的请求体格式
|
||||||
|
instanceObj.set("prompt", prompt);
|
||||||
|
|
||||||
|
// imagen 模型的参数
|
||||||
|
parametersObj.set("addWatermark", false);
|
||||||
|
parametersObj.set("sampleCount", 1);
|
||||||
|
|
||||||
|
// 构建完整的请求体
|
||||||
|
requestBody.set("instances", Arrays.asList(instanceObj));
|
||||||
|
requestBody.set("parameters", parametersObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
String jsonBody = requestBody.toString();
|
||||||
|
|
||||||
|
log.info("Google 请求入参:{}", jsonBody);
|
||||||
|
|
||||||
|
// 生成唯一的任务ID
|
||||||
|
String taskId = uuid + "-" + userId;
|
||||||
|
|
||||||
|
// 初始化Redis中的任务状态为"Executing"
|
||||||
|
String key = generateResultKey + ":" + taskId;
|
||||||
|
GenerateResultVO resultVO = new GenerateResultVO(taskId, null, null, "Executing");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(resultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
|
||||||
|
// 异步处理token获取和API调用
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
// 异步获取token
|
||||||
|
String tokenValue = null;
|
||||||
|
try (InputStream inputStream = GenerateServiceImpl.class.getClassLoader()
|
||||||
|
.getResourceAsStream("aida-461108-b4afaabebb84.json")) {
|
||||||
|
|
||||||
|
GoogleCredentials credentials = GoogleCredentials
|
||||||
|
.fromStream(inputStream)
|
||||||
|
.createScoped(Collections.singletonList("https://www.googleapis.com/auth/cloud-platform"));
|
||||||
|
|
||||||
|
credentials.refreshIfExpired();
|
||||||
|
tokenValue = credentials.getAccessToken().getTokenValue();
|
||||||
|
}
|
||||||
|
if (tokenValue == null) {
|
||||||
|
throw new RuntimeException("google token error");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步发送API请求
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.connectTimeout(30, TimeUnit.SECONDS) // 连接超时时间
|
||||||
|
.readTimeout(60, TimeUnit.SECONDS) // 读取超时时间
|
||||||
|
.writeTimeout(60, TimeUnit.SECONDS) // 写入超时时间
|
||||||
|
.build();
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(endpoint)
|
||||||
|
.addHeader("Authorization", "Bearer " + tokenValue)
|
||||||
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.post(RequestBody.create(MediaType.parse("application/json"), jsonBody))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
String result = response.body().string();
|
||||||
|
|
||||||
|
log.info("Google 响应结果:{}", result);
|
||||||
|
com.alibaba.fastjson.JSONObject jsonResponse = JSON.parseObject(result);
|
||||||
|
|
||||||
|
String base64Data = null;
|
||||||
|
|
||||||
|
//根据模型类别按照api取出结果
|
||||||
|
if (ModelConstants.NANO_BANANA.equals(useModel)) {
|
||||||
|
JSONArray candidates = jsonResponse.getJSONArray("candidates");
|
||||||
|
|
||||||
|
if (candidates != null && !candidates.isEmpty()) {
|
||||||
|
com.alibaba.fastjson.JSONObject candidate = candidates.getJSONObject(0);
|
||||||
|
com.alibaba.fastjson.JSONObject content = candidate.getJSONObject("content");
|
||||||
|
JSONArray parts = content.getJSONArray("parts");
|
||||||
|
|
||||||
|
// 遍历parts数组找到包含inlineData的对象
|
||||||
|
for (int i = 0; i < parts.size(); i++) {
|
||||||
|
com.alibaba.fastjson.JSONObject part = parts.getJSONObject(i);
|
||||||
|
if (part.containsKey("inlineData")) {
|
||||||
|
com.alibaba.fastjson.JSONObject inlineData = part.getJSONObject("inlineData");
|
||||||
|
base64Data = inlineData.getString("data");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ModelConstants.IMAGEN_MODEL.equals(useModel)) {
|
||||||
|
JSONArray predictions = jsonResponse.getJSONArray("predictions");
|
||||||
|
|
||||||
|
if (predictions != null && !predictions.isEmpty()) {
|
||||||
|
com.alibaba.fastjson.JSONObject prediction = predictions.getJSONObject(0);
|
||||||
|
base64Data = prediction.getString("bytesBase64Encoded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base64Data != null && !base64Data.isEmpty()) {
|
||||||
|
String minioPath = minioUtil.base64UploadToPath("data:image/png;base64," + base64Data, userBucket, resultPath);
|
||||||
|
// 生成成功,更新Redis状态和URL
|
||||||
|
GenerateResultVO successResultVO = new GenerateResultVO(taskId, null, minioPath, "Success");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(successResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
} else {
|
||||||
|
// 没有找到图像数据或数据为空,标记为失败
|
||||||
|
log.warn("Google generation response does not contain valid image data for taskId: {}", taskId);
|
||||||
|
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Google generation failed for taskId: {}", taskId, e);
|
||||||
|
// 生成失败,更新Redis状态
|
||||||
|
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
}
|
||||||
|
}, asyncTaskExecutor);
|
||||||
|
|
||||||
|
// 保存生成记录到数据库
|
||||||
|
Generate generate = new Generate(
|
||||||
|
userId,
|
||||||
|
taskId,
|
||||||
|
level1Type,
|
||||||
|
level2Type,
|
||||||
|
prompt,
|
||||||
|
"text(" + gender + ")",
|
||||||
|
useModel, // 记录使用的具体模型名称
|
||||||
|
new Date()
|
||||||
|
);
|
||||||
|
save(generate);
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param generateDTO
|
||||||
|
* @param modelName advanced high normal
|
||||||
|
*/
|
||||||
|
private HashMap<String, String> chooseModelAndPrompt(GenerateThroughImageTextDTO generateDTO, String modelName) {
|
||||||
|
HashMap<String, String> modelAndPromptMap = new HashMap<>();
|
||||||
|
boolean isUseImage;
|
||||||
|
if (Objects.isNull(generateDTO.getCollectionElementId())
|
||||||
|
|| StringUtil.isNullOrEmpty(generateDTO.getDesignType())) {
|
||||||
|
isUseImage = false;
|
||||||
|
} else {
|
||||||
|
isUseImage = true;
|
||||||
|
}
|
||||||
|
if (ModelConstants.PRINTBOARD.equals(generateDTO.getLevel1Type())) {
|
||||||
|
|
||||||
|
int firstCommaIndex = generateDTO.getText().indexOf(",");
|
||||||
|
|
||||||
|
String style = generateDTO.getText().substring(0, firstCommaIndex).trim();
|
||||||
|
|
||||||
|
String prompt = generateDTO.getText().substring(firstCommaIndex + 1).trim();
|
||||||
|
prompt = getPrintboardPrompt(style, prompt);
|
||||||
|
modelAndPromptMap.put(ModelConstants.PROMPT, prompt);
|
||||||
|
|
||||||
|
|
||||||
|
if (ModelConstants.ADVANCED.equals(modelName)) {
|
||||||
|
if (isUseImage) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.PRINTBOARD_ADVANCED_I2I);// i2i
|
||||||
|
} else {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.PRINTBOARD_ADVANCED_T2I);// t2i
|
||||||
|
}
|
||||||
|
} else if (ModelConstants.HIGH.equals(modelName)) {
|
||||||
|
if (isUseImage) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.PRINTBOARD_HIGH_I2I);// i2i
|
||||||
|
} else {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.PRINTBOARD_HIGH_T2I);// t2i
|
||||||
|
}
|
||||||
|
} else if (ModelConstants.NORMAL.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.LOCAL_MODEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (ModelConstants.MOODBOARD.equals(generateDTO.getLevel1Type())) {
|
||||||
|
String prompt = generateDTO.getText() + "high-resolution, ultra-detailed, realistic textures, perfect anatomy, cinematic lighting, 8k render, editorial photography style";
|
||||||
|
modelAndPromptMap.put(ModelConstants.PROMPT, prompt);
|
||||||
|
|
||||||
|
if (ModelConstants.ADVANCED.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.MOODBOARD_ADVANCED);
|
||||||
|
} else if (ModelConstants.HIGH.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.LOCAL_MODEL);
|
||||||
|
} else if (ModelConstants.NORMAL.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.LOCAL_MODEL);
|
||||||
|
}
|
||||||
|
} else if (ModelConstants.SKETCHBOARD.equals(generateDTO.getLevel1Type())) {
|
||||||
|
String prompt = generateDTO.getText() + "rules:front view sketch only,plain white background, single garment only, orthographic, centered on white background, borderless canvas, thin monochrome black line art.\n" +
|
||||||
|
" No clothes hanger, no fake clothes hanger, no human-related lines, no color fill, no words, no text, no black background, no boundary or frame.";
|
||||||
|
modelAndPromptMap.put(ModelConstants.PROMPT, prompt);
|
||||||
|
if (isUseImage) {
|
||||||
|
if (ModelConstants.ADVANCED.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.NANO_BANANA);
|
||||||
|
} else if (ModelConstants.HIGH.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.NANO_BANANA);
|
||||||
|
} else if (ModelConstants.NORMAL.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.LOCAL_MODEL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ModelConstants.ADVANCED.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.IMAGEN_MODEL);
|
||||||
|
} else if (ModelConstants.HIGH.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.IMAGEN_MODEL);
|
||||||
|
} else if (ModelConstants.NORMAL.equals(modelName)) {
|
||||||
|
modelAndPromptMap.put(ModelConstants.USE_MODEL, ModelConstants.LOCAL_MODEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return modelAndPromptMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参数校验
|
* 参数校验
|
||||||
@@ -621,6 +975,15 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
&& StringUtil.isNullOrEmpty(generateDTO.getLevel2Type())) {
|
&& StringUtil.isNullOrEmpty(generateDTO.getLevel2Type())) {
|
||||||
throw new BusinessException("level2Type.cannot.be.empty");
|
throw new BusinessException("level2Type.cannot.be.empty");
|
||||||
}
|
}
|
||||||
|
if (generateDTO.getLevel1Type().equals(PRINT_BOARD.getRealName())) {
|
||||||
|
int firstCommaIndex = generateDTO.getText().indexOf(",");
|
||||||
|
String style = generateDTO.getText().substring(0, firstCommaIndex).trim();
|
||||||
|
//如果style不等于painting style,illustration style,real style中的一种
|
||||||
|
if (!style.equals(ModelConstants.PAINTING_STYLE) && !style.equals(ModelConstants.ILLUSTRATION_STYLE) && !style.equals(ModelConstants.REAL_STYLE)) {
|
||||||
|
throw new BusinessException("style Parameter Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -643,6 +1006,168 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
|
return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PrepareForGenerateVO handleQwenModelGeneration(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) {
|
||||||
|
|
||||||
|
//TODO:校验积分是否足够
|
||||||
|
validateCredits(CreditsEventsEnum.QWEN_TEXT2IMG);
|
||||||
|
String taskId = createQwenAsyncTask(generateDTO, useModel, prompt);
|
||||||
|
// TODO:处理积分扣除
|
||||||
|
processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.QWEN_TEXT2IMG);
|
||||||
|
return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PrepareForGenerateVO handleDouBaoModelGeneration(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) {
|
||||||
|
//TODO:校验积分是否足够
|
||||||
|
validateCredits(CreditsEventsEnum.DOUBAO_TEXT2IMG);
|
||||||
|
String taskId = createDouBaoAsyncTask(generateDTO, useModel, prompt);
|
||||||
|
// TODO:处理积分扣除
|
||||||
|
processCreditDeduction(generateDTO.getUserId(), taskId, CreditsEventsEnum.DOUBAO_TEXT2IMG);
|
||||||
|
|
||||||
|
return new PrepareForGenerateVO(Collections.singletonList(taskId), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createQwenAsyncTask(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) {
|
||||||
|
|
||||||
|
String level1Type = generateDTO.getLevel1Type();
|
||||||
|
String level2Type = generateDTO.getLevel2Type();
|
||||||
|
|
||||||
|
Long userId = generateDTO.getUserId();
|
||||||
|
String gender = generateDTO.getGender();
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> parameters = new HashMap<>();
|
||||||
|
parameters.put("prompt_extend", false);
|
||||||
|
parameters.put("watermark", false);
|
||||||
|
ImageSynthesisParam param =
|
||||||
|
ImageSynthesisParam.builder()
|
||||||
|
.apiKey(ALIYUN_API_KEY)
|
||||||
|
.model(useModel)
|
||||||
|
.prompt(prompt)
|
||||||
|
.n(1)
|
||||||
|
.size("1328*1328")
|
||||||
|
.parameters(parameters)
|
||||||
|
.build();
|
||||||
|
log.info(param.toString());
|
||||||
|
|
||||||
|
ImageSynthesis imageSynthesis = new ImageSynthesis();
|
||||||
|
ImageSynthesisResult result = null;
|
||||||
|
try {
|
||||||
|
result = imageSynthesis.asyncCall(param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
String taskId = result.getOutput().getTaskId();
|
||||||
|
log.info("wx text2image 请求生成:{}, taskId:{}", JsonUtils.toJson(result), taskId);
|
||||||
|
|
||||||
|
Generate generate = new Generate(userId, taskId, level1Type, level2Type, prompt, "text(" + gender + ")", "qwen-image", new Date());
|
||||||
|
save(generate);
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createDouBaoAsyncTask(GenerateThroughImageTextDTO generateDTO, String useModel, String prompt) {
|
||||||
|
// 从DTO中获取基础参数
|
||||||
|
String level1Type = generateDTO.getLevel1Type();
|
||||||
|
String level2Type = generateDTO.getLevel2Type();
|
||||||
|
Long userId = generateDTO.getUserId();
|
||||||
|
String gender = generateDTO.getGender();
|
||||||
|
// 获取图片路径
|
||||||
|
String imagePath = geti2iImagePath(generateDTO);
|
||||||
|
String finalImagePath = null;
|
||||||
|
|
||||||
|
// 只有当imagePath不为null时才获取图片的base64编码
|
||||||
|
if (imagePath != null) {
|
||||||
|
try {
|
||||||
|
String imageAsBase64 = minioUtil.getImageAsBase64(imagePath);
|
||||||
|
finalImagePath = "data:image/png;base64," + imageAsBase64;
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("获取图片base64编码失败", e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成唯一的任务ID
|
||||||
|
String taskId = UUID.randomUUID().toString() + "-" + userId;
|
||||||
|
|
||||||
|
// 初始化Redis中的任务状态为"Executing"
|
||||||
|
String key = generateResultKey + ":" + taskId;
|
||||||
|
GenerateResultVO resultVO = new GenerateResultVO(taskId, null, null, "Executing");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(resultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
|
||||||
|
String finalImagePath1 = finalImagePath;
|
||||||
|
// 异步执行图像生成任务
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
|
||||||
|
Dispatcher dispatcher = new Dispatcher();
|
||||||
|
ArkService service = ArkService.builder().dispatcher(dispatcher).connectionPool(connectionPool).apiKey(DOUBAO_API_KEY).build();
|
||||||
|
|
||||||
|
// 根据是否有图片路径来构建请求
|
||||||
|
GenerateImagesRequest.Builder requestBuilder = GenerateImagesRequest.builder()
|
||||||
|
.watermark(false)
|
||||||
|
.model(useModel)
|
||||||
|
.prompt(prompt);
|
||||||
|
|
||||||
|
// 只有当finalImagePath不为null时才设置image参数
|
||||||
|
if (imagePath != null) {
|
||||||
|
requestBuilder.image(finalImagePath1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateImagesRequest generateRequest = requestBuilder.build();
|
||||||
|
|
||||||
|
ImagesResponse imagesResponse = service.generateImages(generateRequest);
|
||||||
|
String imageUrl = imagesResponse.getData().get(0).getUrl();
|
||||||
|
|
||||||
|
service.shutdownExecutor();
|
||||||
|
|
||||||
|
// 生成成功,更新Redis状态和URL
|
||||||
|
GenerateResultVO successResultVO = new GenerateResultVO(taskId, null, imageUrl, "Success");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(successResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
|
||||||
|
// 保存生成记录到数据库
|
||||||
|
Generate generate = new Generate(
|
||||||
|
userId,
|
||||||
|
taskId,
|
||||||
|
level1Type,
|
||||||
|
level2Type,
|
||||||
|
prompt,
|
||||||
|
"text(" + gender + ")",
|
||||||
|
useModel, // 记录使用的具体模型名称
|
||||||
|
new Date()
|
||||||
|
);
|
||||||
|
save(generate);
|
||||||
|
|
||||||
|
// TODO: 处理积分扣除逻辑
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Doubao image generation failed for taskId: {}", taskId, e);
|
||||||
|
// 生成失败,更新Redis状态
|
||||||
|
GenerateResultVO failResultVO = new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
redisUtil.addToString(key, new Gson().toJson(failResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getPrintboardPrompt(String style, String prompt) {
|
||||||
|
if ("Painting Style".equals(style)) {
|
||||||
|
prompt = "1.Requirements: Create a seamless, tiling fashion printboard pattern for apparel. The output must be stylish, contemporary, and suitable for real garment printing. Design pattern, seamless, highly detailed, elegant composition, visually balanced, professional textile print\n" +
|
||||||
|
"2.Core Theme: " + prompt + "\n" +
|
||||||
|
"3.Style: painting_style-The painting style refers to the overall approach, techniques, and artistic philosophy used in the artwork. For fashion designs that will be applied to printboards, it is important to define the unique stylistic elements that would translate well into wearable patterns.";
|
||||||
|
} else if ("Illustration Style".equals(style)) {
|
||||||
|
prompt = "1.Requirements: Create a seamless, tiling fashion printboard pattern for apparel. The output must be stylish, contemporary, and suitable for real garment printing. Design pattern, seamless, highly detailed, elegant composition, visually balanced, professional textile print\n" +
|
||||||
|
"2.Core Theme: " + prompt + "\n" +
|
||||||
|
"3.Style: illustration_style-Illustration style focuses on the visual storytellingaspect, often used to depict narratives, characters, or thematic concepts. Forfashion, this style can introduce vivid and artistic interpretations, often aligned with specific themes.";
|
||||||
|
} else if ("Real Style".equals(style)) {
|
||||||
|
prompt = "1.Requirements: Create a seamless, tiling fashion printboard pattern for apparel. The output must be stylish, contemporary, and suitable for real garment printing. Design pattern, seamless, highly detailed, elegant composition, visually balanced, professional textile print\n" +
|
||||||
|
"2.Core Theme: " + prompt + "\n" +
|
||||||
|
"3.Style: real_style-Real style in fashion is all about authenticity. It featuresnatural fabrics, simple cuts that mirror real life silhouettes, and colors inspired bythe everyday world, exuding a down-to-earth and genuine charm.";
|
||||||
|
}
|
||||||
|
return prompt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否为flux模型且类型为Pattern
|
* 判断是否为flux模型且类型为Pattern
|
||||||
*/
|
*/
|
||||||
@@ -660,7 +1185,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
validateCredits(CreditsEventsEnum.FLUX_IMG2IMG);
|
validateCredits(CreditsEventsEnum.FLUX_IMG2IMG);
|
||||||
|
|
||||||
// 获取图片路径
|
// 获取图片路径
|
||||||
String imagePath = getImagePathForFlux(generateDTO);
|
String imagePath = geti2iImagePath(generateDTO);
|
||||||
|
|
||||||
// 创建生成任务
|
// 创建生成任务
|
||||||
String taskId = flux(PATTERN, generateDTO.getText(), imagePath, false);
|
String taskId = flux(PATTERN, generateDTO.getText(), imagePath, false);
|
||||||
@@ -675,9 +1200,9 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取flux模型需要的图片路径
|
* 获取i2i需要传入模型的图片路径
|
||||||
*/
|
*/
|
||||||
private String getImagePathForFlux(GenerateThroughImageTextDTO generateDTO) {
|
private String geti2iImagePath(GenerateThroughImageTextDTO generateDTO) {
|
||||||
if (Objects.isNull(generateDTO.getCollectionElementId())
|
if (Objects.isNull(generateDTO.getCollectionElementId())
|
||||||
|| StringUtil.isNullOrEmpty(generateDTO.getDesignType())) {
|
|| StringUtil.isNullOrEmpty(generateDTO.getDesignType())) {
|
||||||
return null;
|
return null;
|
||||||
@@ -994,8 +1519,12 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
flag = false;
|
flag = false;
|
||||||
}
|
}
|
||||||
// 暂定万象每次生成1个
|
// 暂定万象每次生成1个
|
||||||
if (type.equals("wx")) {
|
if (type.equals("wx") || type.contains("qwen")) {
|
||||||
return Collections.singletonList(getAsyncTaskResult(taskId));
|
return Collections.singletonList(getAsyncTaskResult(taskId));
|
||||||
|
} else if (type.contains("imagen") || type.contains("gemini")) {
|
||||||
|
return Collections.singletonList(getGoogleAsyncResult(taskId));
|
||||||
|
} else if (type.contains("doubao")) {
|
||||||
|
return Collections.singletonList(getDoubaoAsyncResult(taskId));
|
||||||
} else if (type.equals("freepik")) {
|
} else if (type.equals("freepik")) {
|
||||||
results.add(generateResultVO);
|
results.add(generateResultVO);
|
||||||
continue;
|
continue;
|
||||||
@@ -2107,7 +2636,6 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void deleteGeneratedPose(Long projectId, Long id) {
|
public void deleteGeneratedPose(Long projectId, Long id) {
|
||||||
// 1. 权限校验
|
// 1. 权限校验
|
||||||
@@ -2163,7 +2691,6 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 万象专业版
|
* 万象专业版
|
||||||
* 1、MoodBoard t2i
|
* 1、MoodBoard t2i
|
||||||
@@ -2287,10 +2814,10 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
throw new BusinessException("Unknown generate task");
|
throw new BusinessException("Unknown generate task");
|
||||||
}
|
}
|
||||||
} else if (taskStatus.equals("PENDING") || taskStatus.equals("RUNNING")) {
|
} else if (taskStatus.equals("PENDING") || taskStatus.equals("RUNNING")) {
|
||||||
log.info("万象 异步接口返回生成状态为:{}", taskStatus);
|
log.info("阿里 异步接口返回生成状态为:{}", taskStatus);
|
||||||
return new GenerateResultVO(taskId, null, null, "Executing");
|
return new GenerateResultVO(taskId, null, null, "Executing");
|
||||||
} else {
|
} else {
|
||||||
log.warn("万象 异步接口返回生成状态为:{}", taskStatus);
|
log.warn("阿里 异步接口返回生成状态为:{}", taskStatus);
|
||||||
return new GenerateResultVO(taskId, null, null, "Fail");
|
return new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
}
|
}
|
||||||
} catch (ApiException | NoApiKeyException e) {
|
} catch (ApiException | NoApiKeyException e) {
|
||||||
@@ -2301,6 +2828,140 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GenerateResultVO getGoogleAsyncResult(String taskId) {
|
||||||
|
// 1. 从 Redis 获取当前任务状态
|
||||||
|
String key = generateResultKey + ":" + taskId;
|
||||||
|
String redisResult = redisUtil.getFromString(key);
|
||||||
|
|
||||||
|
if (StringUtil.isNullOrEmpty(redisResult)) {
|
||||||
|
// Redis 中没有该任务记录,可能任务已过期或 taskId 无效
|
||||||
|
return new GenerateResultVO(taskId, null, null, "Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateResultVO cachedResult = new Gson().fromJson(redisResult, GenerateResultVO.class);
|
||||||
|
|
||||||
|
// 2. 如果任务还在执行中,直接返回当前状态
|
||||||
|
if ("Executing".equals(cachedResult.getStatus())) {
|
||||||
|
// 这里可以添加额外的检查逻辑,比如检查是否执行超时
|
||||||
|
// 如果需要,可以从 Doubao API 查询实际状态
|
||||||
|
return cachedResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 如果任务已经完成(成功或失败),直接返回结果
|
||||||
|
if ("Success".equals(cachedResult.getStatus())) {
|
||||||
|
List<Generate> generates = selectListByUniqueId(taskId);
|
||||||
|
String url = cachedResult.getUrl();
|
||||||
|
|
||||||
|
String path = null;
|
||||||
|
if (!generates.isEmpty()) {
|
||||||
|
Generate generate = generates.get(0);
|
||||||
|
Long accountId = generate.getAccountId();
|
||||||
|
|
||||||
|
|
||||||
|
// 3、生成结果保存到db
|
||||||
|
GenerateDetail generateDetail = new GenerateDetail();
|
||||||
|
generateDetail.setGenerateId(generate.getId());
|
||||||
|
generateDetail.setUrl(url);
|
||||||
|
generateDetail.setMd5(MD5Utils.encryptFile(minioUtil.getPreSignedUrl(url, 24 * 60), false));
|
||||||
|
generateDetail.setCreateDate(LocalDateTime.now());
|
||||||
|
generateDetailMapper.insert(generateDetail);
|
||||||
|
// 4、扣积分
|
||||||
|
Boolean flag = creditsService.taskCreditsDeduction(accountId, taskId);
|
||||||
|
if (flag) creditsService.updateChangedCredits(String.valueOf(generate.getAccountId()), taskId);
|
||||||
|
|
||||||
|
GenerateResultVO generateResultVO = new GenerateResultVO(taskId, generateDetail.getId(), minioUtil.getPreSignedUrl(url, 24 * 60), "Success");
|
||||||
|
if (generate.getLevel1Type().equals(SKETCH_BOARD.getRealName())) {
|
||||||
|
String gender = extractGender(generate.getGenerateType());
|
||||||
|
if (!StringUtil.isNullOrEmpty(gender)) {
|
||||||
|
String clothCategory = pythonService.getClothCategory(url, gender);
|
||||||
|
generateResultVO.setCategory(clothCategory);
|
||||||
|
} else {
|
||||||
|
log.warn("未提取到性别");
|
||||||
|
}
|
||||||
|
} else if (generate.getLevel1Type().equals(PRINT_BOARD.getRealName())) {
|
||||||
|
Generate generateRecord = selectByUniqueId(taskId);
|
||||||
|
generateResultVO.setCategory(generateRecord.getLevel2Type());
|
||||||
|
}
|
||||||
|
return generateResultVO;
|
||||||
|
} else {
|
||||||
|
throw new BusinessException("Unknown generate task");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 其他状态(如 Unknown),返回默认失败
|
||||||
|
return new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenerateResultVO getDoubaoAsyncResult(String taskId) {
|
||||||
|
// 1. 从 Redis 获取当前任务状态
|
||||||
|
String key = generateResultKey + ":" + taskId;
|
||||||
|
String redisResult = redisUtil.getFromString(key);
|
||||||
|
|
||||||
|
if (StringUtil.isNullOrEmpty(redisResult)) {
|
||||||
|
// Redis 中没有该任务记录,可能任务已过期或 taskId 无效
|
||||||
|
return new GenerateResultVO(taskId, null, null, "Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateResultVO cachedResult = new Gson().fromJson(redisResult, GenerateResultVO.class);
|
||||||
|
|
||||||
|
// 2. 如果任务还在执行中,直接返回当前状态
|
||||||
|
if ("Executing".equals(cachedResult.getStatus())) {
|
||||||
|
// 这里可以添加额外的检查逻辑,比如检查是否执行超时
|
||||||
|
// 如果需要,可以从 Doubao API 查询实际状态
|
||||||
|
return cachedResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 如果任务已经完成(成功或失败),直接返回结果
|
||||||
|
if ("Success".equals(cachedResult.getStatus())) {
|
||||||
|
List<Generate> generates = selectListByUniqueId(taskId);
|
||||||
|
String url = cachedResult.getUrl();
|
||||||
|
|
||||||
|
String path = null;
|
||||||
|
if (!generates.isEmpty()) {
|
||||||
|
Generate generate = generates.get(0);
|
||||||
|
Long accountId = generate.getAccountId();
|
||||||
|
|
||||||
|
// 1、下载图片
|
||||||
|
// InputStream inputStream = downloadImageFromAliyun(url);
|
||||||
|
byte[] bytes = downloadVideoOrImage(url);
|
||||||
|
// 2、上传图片到minio保存
|
||||||
|
String objectName = accountId + "/" + generate.getLevel1Type().toLowerCase() + "/" + taskId + ".png";
|
||||||
|
minioUtil.uploadToMinio(bytes, userBucket, objectName, "image/png");
|
||||||
|
path = userBucket + "/" + objectName;
|
||||||
|
// 3、生成结果保存到db
|
||||||
|
GenerateDetail generateDetail = new GenerateDetail();
|
||||||
|
generateDetail.setGenerateId(generate.getId());
|
||||||
|
generateDetail.setUrl(path);
|
||||||
|
generateDetail.setMd5(MD5Utils.encryptFile(minioUtil.getPreSignedUrl(path, 24 * 60), false));
|
||||||
|
generateDetail.setCreateDate(LocalDateTime.now());
|
||||||
|
generateDetailMapper.insert(generateDetail);
|
||||||
|
// 4、扣积分
|
||||||
|
Boolean flag = creditsService.taskCreditsDeduction(accountId, taskId);
|
||||||
|
if (flag) creditsService.updateChangedCredits(String.valueOf(generate.getAccountId()), taskId);
|
||||||
|
|
||||||
|
GenerateResultVO generateResultVO = new GenerateResultVO(taskId, generateDetail.getId(), minioUtil.getPreSignedUrl(path, 24 * 60), "Success");
|
||||||
|
if (generate.getLevel1Type().equals(SKETCH_BOARD.getRealName())) {
|
||||||
|
String gender = extractGender(generate.getGenerateType());
|
||||||
|
if (!StringUtil.isNullOrEmpty(gender)) {
|
||||||
|
String clothCategory = pythonService.getClothCategory(path, gender);
|
||||||
|
generateResultVO.setCategory(clothCategory);
|
||||||
|
} else {
|
||||||
|
log.warn("未提取到性别");
|
||||||
|
}
|
||||||
|
} else if (generate.getLevel1Type().equals(PRINT_BOARD.getRealName())) {
|
||||||
|
Generate generateRecord = selectByUniqueId(taskId);
|
||||||
|
generateResultVO.setCategory(generateRecord.getLevel2Type());
|
||||||
|
}
|
||||||
|
return generateResultVO;
|
||||||
|
} else {
|
||||||
|
throw new BusinessException("Unknown generate task");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 其他状态(如 Unknown),返回默认失败
|
||||||
|
return new GenerateResultVO(taskId, null, null, "Fail");
|
||||||
|
}
|
||||||
|
|
||||||
private static final String IMAGE_DETECT = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-detect";
|
private static final String IMAGE_DETECT = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-detect";
|
||||||
private static final String TEMPLATE_ID_GEN = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-template-generation/";
|
private static final String TEMPLATE_ID_GEN = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-template-generation/";
|
||||||
private static final String GET_ASYNC_RESULT = "https://dashscope.aliyuncs.com/api/v1/tasks/";
|
private static final String GET_ASYNC_RESULT = "https://dashscope.aliyuncs.com/api/v1/tasks/";
|
||||||
@@ -2796,7 +3457,11 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
!StringUtil.isNullOrEmpty(generate.getModelName()) &&
|
!StringUtil.isNullOrEmpty(generate.getModelName()) &&
|
||||||
(generate.getModelName().equals("wx")
|
(generate.getModelName().equals("wx")
|
||||||
|| generate.getModelName().equals("freepik")
|
|| generate.getModelName().equals("freepik")
|
||||||
|| generate.getModelName().equals("flux"))) {
|
|| generate.getModelName().equals("flux")
|
||||||
|
|| generate.getModelName().contains("qwen")
|
||||||
|
|| generate.getModelName().contains("imagen")
|
||||||
|
|| generate.getModelName().contains("gemini")
|
||||||
|
|| generate.getModelName().contains("doubao"))) {
|
||||||
return generate.getModelName();
|
return generate.getModelName();
|
||||||
} else {
|
} else {
|
||||||
return "local";
|
return "local";
|
||||||
@@ -2832,7 +3497,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
case IMAGE_TO_SKETCH_FLUX:
|
case IMAGE_TO_SKETCH_FLUX:
|
||||||
prompt = "generate the sketch of the image, simple line, ultra high quality";
|
prompt = "generate the sketch of the image, simple line, ultra high quality";
|
||||||
break;
|
break;
|
||||||
case TO_PRODUCT_IMAGE_FLUX:
|
case TO_PRODUCT_IMAGE_ADVANCED:
|
||||||
prompt = "change the image to real style, ultra high quality, 8k";
|
prompt = "change the image to real style, ultra high quality, 8k";
|
||||||
if (childStyle) prompt = prompt + ", Children's face";
|
if (childStyle) prompt = prompt + ", Children's face";
|
||||||
break;
|
break;
|
||||||
@@ -2864,7 +3529,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
if (!StringUtil.isNullOrEmpty(imagePath)) {
|
if (!StringUtil.isNullOrEmpty(imagePath)) {
|
||||||
try {
|
try {
|
||||||
String imageAsBase64 = null;
|
String imageAsBase64 = null;
|
||||||
if (func.equals(TO_PRODUCT_IMAGE_FLUX)) {
|
if (func.equals(TO_PRODUCT_IMAGE_ADVANCED)) {
|
||||||
imageAsBase64 = addWhiteBackground(imagePath);
|
imageAsBase64 = addWhiteBackground(imagePath);
|
||||||
}
|
}
|
||||||
if (StringUtil.isNullOrEmpty(imageAsBase64)) {
|
if (StringUtil.isNullOrEmpty(imageAsBase64)) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.ai.da.service.impl;
|
|||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import com.ai.da.common.config.exception.BusinessException;
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
import com.ai.da.common.constant.CommonConstant;
|
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.context.UserContext;
|
||||||
import com.ai.da.common.enums.CollectionLevel1TypeEnum;
|
import com.ai.da.common.enums.CollectionLevel1TypeEnum;
|
||||||
import com.ai.da.common.enums.CreditsEventsEnum;
|
import com.ai.da.common.enums.CreditsEventsEnum;
|
||||||
@@ -405,9 +406,9 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public List<ToProductImageResultVO> toProduct(ToProductImageDTO toProductImageDTO) {
|
public List<ToProductImageResultVO> toProduct(ToProductImageDTO toProductImageDTO) {
|
||||||
// 判断用户当前积分是否够本次生成消耗
|
// 判断用户当前积分是否够本次生成消耗
|
||||||
boolean fluxTask = !StringUtil.isNullOrEmpty(toProductImageDTO.getModelName())
|
boolean nanoBananaTask = !StringUtil.isNullOrEmpty(toProductImageDTO.getModelName())
|
||||||
&& toProductImageDTO.getModelName().equals("flux");
|
&& toProductImageDTO.getModelName().equals(ModelConstants.ADVANCED)||toProductImageDTO.getModelName().equals(ModelConstants.HIGH);
|
||||||
CreditsEventsEnum creditsEventsEnum = fluxTask ? CreditsEventsEnum.TO_PRODUCT_IMAGE_FLUX : CreditsEventsEnum.TO_PRODUCT_IMAGE;
|
CreditsEventsEnum creditsEventsEnum = nanoBananaTask ? CreditsEventsEnum.TO_PRODUCT_IMAGE_ADVANCED : CreditsEventsEnum.TO_PRODUCT_IMAGE;
|
||||||
Boolean preDeduction = creditsService.creditsPreDeduction(creditsEventsEnum, toProductImageDTO.getToProductImageVOList().size());
|
Boolean preDeduction = creditsService.creditsPreDeduction(creditsEventsEnum, toProductImageDTO.getToProductImageVOList().size());
|
||||||
if (!preDeduction) {
|
if (!preDeduction) {
|
||||||
throw new BusinessException("Your remaining credits are insufficient for this generation. Please recharge.", ResultEnum.WARNING.getCode());
|
throw new BusinessException("Your remaining credits are insufficient for this generation. Please recharge.", ResultEnum.WARNING.getCode());
|
||||||
@@ -487,12 +488,29 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR");
|
sb.append(",high quality clothing details,").append(prompt).append(",8K realistic,HDR");
|
||||||
}
|
}
|
||||||
ToProductImageResultVO toProductImageResult = new ToProductImageResultVO();
|
ToProductImageResultVO toProductImageResult = new ToProductImageResultVO();
|
||||||
if (fluxTask){
|
if (nanoBananaTask){
|
||||||
if (childFlag){
|
if (childFlag){
|
||||||
sb.append(", Children's face");
|
sb.append(", Children's face");
|
||||||
}
|
}
|
||||||
taskId = generateService.flux(CreditsEventsEnum.TO_PRODUCT_IMAGE_FLUX, sb.toString(), tDesignPythonOutfit.getDesignUrl(), childFlag);
|
// 使用Google nanobanana模型
|
||||||
toProductImageResult.setModelName("flux");
|
GenerateThroughImageTextDTO generateDTO = new GenerateThroughImageTextDTO();
|
||||||
|
generateDTO.setUserId(userHolder.getId());
|
||||||
|
generateDTO.setLevel1Type("Product");
|
||||||
|
generateDTO.setLevel2Type("ToProduct");
|
||||||
|
generateDTO.setGender("unisex");
|
||||||
|
generateDTO.setCollectionElementId(tDesignPythonOutfit.getId());
|
||||||
|
generateDTO.setDesignType("DesignOutfit");
|
||||||
|
try {
|
||||||
|
//使用nano banana用这个提示词
|
||||||
|
String nanoPrompt = "Change the input image to the real image. Full length portrait, match the clothing size, clothing style, " +
|
||||||
|
"patterns, and fabric texture from the reference image, replicate garment design details precisely, " +
|
||||||
|
"maintain original color scheme, high fidelity to reference attire, realistic lighting, detailed fabric rendering.";
|
||||||
|
taskId = generateService.createGoogleAsyncTask(generateDTO, ModelConstants.NANO_BANANA, nanoPrompt);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Google nanobanana generation failed", e);
|
||||||
|
throw new BusinessException("Generation failed, please try again");
|
||||||
|
}
|
||||||
|
toProductImageResult.setModelName("nanobanana");
|
||||||
toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue());
|
toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue());
|
||||||
} else {
|
} else {
|
||||||
// 走模型
|
// 走模型
|
||||||
@@ -547,9 +565,26 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageVO.getElementId());
|
ToProductElement toProductElement = toProductElementMapper.selectById(toProductImageVO.getElementId());
|
||||||
ToProductImageResultVO toProductImageResult = new ToProductImageResultVO();
|
ToProductImageResultVO toProductImageResult = new ToProductImageResultVO();
|
||||||
|
|
||||||
if (fluxTask){
|
if (nanoBananaTask){
|
||||||
taskId = generateService.flux(creditsEventsEnum, sb.toString(), toProductElement.getUrl(), childFlag);
|
// 使用Google nanobanana模型
|
||||||
toProductImageResult.setModelName("flux");
|
GenerateThroughImageTextDTO generateDTO = new GenerateThroughImageTextDTO();
|
||||||
|
generateDTO.setUserId(userHolder.getId());
|
||||||
|
generateDTO.setLevel1Type("Product");
|
||||||
|
generateDTO.setLevel2Type("ToProduct");
|
||||||
|
generateDTO.setGender("unisex");
|
||||||
|
generateDTO.setCollectionElementId(toProductElement.getId());
|
||||||
|
generateDTO.setDesignType("ProductElement");
|
||||||
|
try {
|
||||||
|
//使用nano banana用这个提示词
|
||||||
|
String nanoPrompt = "Change the input image to the real image. Full length portrait, match the clothing size, clothing style, " +
|
||||||
|
"patterns, and fabric texture from the reference image, replicate garment design details precisely, " +
|
||||||
|
"maintain original color scheme, high fidelity to reference attire, realistic lighting, detailed fabric rendering.";
|
||||||
|
taskId = generateService.createGoogleAsyncTask(generateDTO, ModelConstants.NANO_BANANA, nanoPrompt);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Google nanobanana generation failed", e);
|
||||||
|
throw new BusinessException("Generation failed, please try again");
|
||||||
|
}
|
||||||
|
toProductImageResult.setModelName("nanobanana");
|
||||||
toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue());
|
toProductImageResult.setResultType(CollectionType.TO_PRODUCT_IMAGE.getValue());
|
||||||
} else {
|
} else {
|
||||||
// 走模型
|
// 走模型
|
||||||
@@ -2533,6 +2568,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
collectionElement.setProjectId(projectId);
|
collectionElement.setProjectId(projectId);
|
||||||
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName());
|
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName());
|
||||||
collectionElement.setLevel2Type(board.getLevel2Type());
|
collectionElement.setLevel2Type(board.getLevel2Type());
|
||||||
|
collectionElement.setLevel3Type(workspaceService.getProjectSexById(projectId));
|
||||||
collectionElement.setName(library.getName());
|
collectionElement.setName(library.getName());
|
||||||
collectionElement.setUrl(library.getUrl());
|
collectionElement.setUrl(library.getUrl());
|
||||||
collectionElement.setHasPin(board.getIsPin());
|
collectionElement.setHasPin(board.getIsPin());
|
||||||
@@ -2546,6 +2582,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
collectionElement.setProjectId(projectId);
|
collectionElement.setProjectId(projectId);
|
||||||
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName());
|
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName());
|
||||||
collectionElement.setLevel2Type(board.getLevel2Type());
|
collectionElement.setLevel2Type(board.getLevel2Type());
|
||||||
|
collectionElement.setLevel3Type(workspaceService.getProjectSexById(projectId));
|
||||||
// collectionElement.setName(generateDetail.get());
|
// collectionElement.setName(generateDetail.get());
|
||||||
collectionElement.setUrl(generateDetail.getUrl());
|
collectionElement.setUrl(generateDetail.getUrl());
|
||||||
collectionElement.setHasPin(board.getIsPin());
|
collectionElement.setHasPin(board.getIsPin());
|
||||||
@@ -2566,6 +2603,9 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
collectionElement.setLevel2Type(board.getLevel2Type());
|
collectionElement.setLevel2Type(board.getLevel2Type());
|
||||||
collectionElement.setHasPin(board.getIsPin());
|
collectionElement.setHasPin(board.getIsPin());
|
||||||
collectionElement.setUpdateDate(new Date());
|
collectionElement.setUpdateDate(new Date());
|
||||||
|
if (CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName().equals(collectionElement.getLevel1Type())){
|
||||||
|
collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId()));
|
||||||
|
}
|
||||||
collectionElementMapper.updateById(collectionElement);
|
collectionElementMapper.updateById(collectionElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2675,6 +2715,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
collectionElement.setAccountId(accountId);
|
collectionElement.setAccountId(accountId);
|
||||||
collectionElement.setProjectId(projectId);
|
collectionElement.setProjectId(projectId);
|
||||||
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName());
|
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName());
|
||||||
|
collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId()));
|
||||||
// collectionElement.setLevel2Type(board.getLevel2Type());
|
// collectionElement.setLevel2Type(board.getLevel2Type());
|
||||||
collectionElement.setName(sysFile.getName());
|
collectionElement.setName(sysFile.getName());
|
||||||
collectionElement.setUrl(sysFile.getUrl());
|
collectionElement.setUrl(sysFile.getUrl());
|
||||||
@@ -2695,6 +2736,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
collectionElement.setAccountId(accountId);
|
collectionElement.setAccountId(accountId);
|
||||||
collectionElement.setProjectId(projectId);
|
collectionElement.setProjectId(projectId);
|
||||||
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName());
|
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName());
|
||||||
|
collectionElement.setLevel3Type(workspaceService.getProjectSexById(project.getId()));
|
||||||
// collectionElement.setLevel2Type(board.getLevel2Type());
|
// collectionElement.setLevel2Type(board.getLevel2Type());
|
||||||
collectionElement.setName(library.getName());
|
collectionElement.setName(library.getName());
|
||||||
collectionElement.setUrl(library.getUrl());
|
collectionElement.setUrl(library.getUrl());
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.ai.da.service.impl;
|
|||||||
import com.ai.da.common.config.exception.BusinessException;
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
import com.ai.da.common.context.UserContext;
|
import com.ai.da.common.context.UserContext;
|
||||||
import com.ai.da.common.enums.CollectionLevel1TypeEnum;
|
import com.ai.da.common.enums.CollectionLevel1TypeEnum;
|
||||||
|
import com.ai.da.common.enums.CollectionLevel2TypeEnum;
|
||||||
import com.ai.da.common.enums.LibraryLevel1TypeEnum;
|
import com.ai.da.common.enums.LibraryLevel1TypeEnum;
|
||||||
import com.ai.da.common.response.PageBaseResponse;
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
import com.ai.da.common.response.ResultEnum;
|
import com.ai.da.common.response.ResultEnum;
|
||||||
@@ -16,6 +17,7 @@ import com.ai.da.model.enums.*;
|
|||||||
import com.ai.da.model.vo.*;
|
import com.ai.da.model.vo.*;
|
||||||
import com.ai.da.service.SysFileService;
|
import com.ai.da.service.SysFileService;
|
||||||
import com.ai.da.service.WorkspaceService;
|
import com.ai.da.service.WorkspaceService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
@@ -717,16 +719,20 @@ public class WorkspaceServiceImpl extends ServiceImpl<WorkspaceMapper, Workspace
|
|||||||
if (projectDTO.getProcess().equals(DesignProcess.SERIES_DESIGN.name()) || projectDTO.getProcess().equals(DesignProcess.SKETCH_COLLAGE_PROCESS.name())) {
|
if (projectDTO.getProcess().equals(DesignProcess.SERIES_DESIGN.name()) || projectDTO.getProcess().equals(DesignProcess.SKETCH_COLLAGE_PROCESS.name())) {
|
||||||
if (!workspaceNew.getAgeGroup().equals(workspace.getAgeGroup()) || !workspaceNew.getSex().equals(workspace.getSex())) {
|
if (!workspaceNew.getAgeGroup().equals(workspace.getAgeGroup()) || !workspaceNew.getSex().equals(workspace.getSex())) {
|
||||||
// 性别变更 清理sketch及模特
|
// 性别变更 清理sketch及模特
|
||||||
deleteMannequinByProjectId(projectId);
|
// deleteMannequinByProjectId(projectId);
|
||||||
if (!workspaceNew.getSex().equals(workspace.getSex())) {
|
if (!workspaceNew.getSex().equals(workspace.getSex())) {
|
||||||
deleteSketchByProjectId(projectId);
|
// deleteSketchByProjectId(projectId);
|
||||||
}
|
|
||||||
}
|
LambdaQueryWrapper<CollectionElement> queryWrapper = new LambdaQueryWrapper<CollectionElement>().eq(CollectionElement::getProjectId, projectId)
|
||||||
|
.eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.MODEL.getRealName())
|
||||||
|
.eq(CollectionElement::getLevel3Type, workspaceNew.getSex());
|
||||||
|
if (collectionElementMapper.selectCount(queryWrapper) == 0){
|
||||||
SysFile sysFile = sysFileService.getOneBySex(projectDTO.getStyleId(), projectDTO.getWorkspace().getSex(), projectDTO.getWorkspace().getAgeGroup());
|
SysFile sysFile = sysFileService.getOneBySex(projectDTO.getStyleId(), projectDTO.getWorkspace().getSex(), projectDTO.getWorkspace().getAgeGroup());
|
||||||
CollectionElement collectionElement = new CollectionElement();
|
CollectionElement collectionElement = new CollectionElement();
|
||||||
collectionElement.setAccountId(userInfo.getId());
|
collectionElement.setAccountId(userInfo.getId());
|
||||||
collectionElement.setProjectId(projectId);
|
collectionElement.setProjectId(projectId);
|
||||||
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName());
|
collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName());
|
||||||
|
collectionElement.setLevel3Type(projectDTO.getWorkspace().getSex());
|
||||||
collectionElement.setName(sysFile.getName());
|
collectionElement.setName(sysFile.getName());
|
||||||
collectionElement.setUrl(sysFile.getUrl());
|
collectionElement.setUrl(sysFile.getUrl());
|
||||||
collectionElement.setMd5(sysFile.getMd5());
|
collectionElement.setMd5(sysFile.getMd5());
|
||||||
@@ -739,6 +745,11 @@ public class WorkspaceServiceImpl extends ServiceImpl<WorkspaceMapper, Workspace
|
|||||||
collectionElementRelModel.setRelationType("System");
|
collectionElementRelModel.setRelationType("System");
|
||||||
collectionElementRelModelMapper.insert(collectionElementRelModel);
|
collectionElementRelModelMapper.insert(collectionElementRelModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
workspaceNew.setId(workspace.getId());
|
workspaceNew.setId(workspace.getId());
|
||||||
workspace.setUpdateTime(LocalDateTime.now());
|
workspace.setUpdateTime(LocalDateTime.now());
|
||||||
workspaceMapper.updateById(workspaceNew);
|
workspaceMapper.updateById(workspaceNew);
|
||||||
@@ -857,6 +868,17 @@ public class WorkspaceServiceImpl extends ServiceImpl<WorkspaceMapper, Workspace
|
|||||||
return workspaceList.get(0).getId();
|
return workspaceList.get(0).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProjectSexById(Long projectId) {
|
||||||
|
LambdaQueryWrapper<Workspace> workspaceLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
workspaceLambdaQueryWrapper.eq(Workspace::getProjectId, projectId).select(Workspace::getSex);
|
||||||
|
Workspace workspace = workspaceMapper.selectOne(workspaceLambdaQueryWrapper);
|
||||||
|
if (workspace != null) {
|
||||||
|
return workspace.getSex();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<File> getPNGFiles(String directoryPath) {
|
public static List<File> getPNGFiles(String directoryPath) {
|
||||||
List<File> pngFiles = new ArrayList<>();
|
List<File> pngFiles = new ArrayList<>();
|
||||||
File directory = new File(directoryPath);
|
File directory = new File(directoryPath);
|
||||||
|
|||||||
13
src/main/resources/aida-461108-b4afaabebb84.json
Normal file
13
src/main/resources/aida-461108-b4afaabebb84.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"type": "service_account",
|
||||||
|
"project_id": "aida-461108",
|
||||||
|
"private_key_id": "b4afaabebb84da24502b318a5fa175f1dc5c096a",
|
||||||
|
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCmk7LKrp8g9yD1\nWmF+mY2qHCEZ/5aIx6QRh0QoVPBL7Yi7ce009QxaE8fu8+QMgg8l3xMreXvgpt56\noFnVwpFusLjSdjgoFluElM2hYxXlO9q8cbBoU2nehOBLLJzGzkodT7xu/BOjNvKC\n//aTbjtJyk8Kj+ENa0/dPaUZs/PCtQqpAu8ag5nXrordVWfO0K25EjeYyoba35zk\nPp2fBi8KALZZI5Xfd2z9++K0K2mWWIMJic30idHvquj0WxlTRK2Pq8BmJXCQpJIi\nQ5E4egue16BfKjrF0Kxkpqd1RmdlEmaSKbbkZXe2z4jg0qknESRFOmRy8C3LnaB2\nHHJWLYM3AgMBAAECggEACUdroOQJSTTQSS/iWRhZ+S0yoC10nTnsZxg527qfiBs7\nOqB7WNqC+Ew8dDsca6CdvLuoaGDkCFJDTQwRn66u8JOM4sG4bxiPuzBEJBv45EQT\n8zCsuvhVNWgBdoPjAnq19jFdixvPnDqQrRYaY4FdxsaA5f24c57pW/xLGMYawLBt\n9RJZSuWmJdzKG1i5W8a8+4f/seNtuo2MtXU3mPJZPqRWPXTAZeaQPM/57ZQ+kzig\nOkAbQZNRmt1yPCjPCQD8vc8yCBMmjus/rlHXD/L7okYUlVZkob5I3FBrLl+ZyIXS\nqxEsBLBwRW3w8WbX+ZSVciQ72JK68W7LnOHSAENmAQKBgQDgBTCqp87KGLWVPb8w\nK+s1Sfh+nM3M4AlbLdcGBs1JCoddF6pAeY4wpf/ow1Tm4rqEuCYzMClPwxvkue+D\nY7lCQgy2FK3ahUzn8oVmvEPD/YPAojDSY3bH0lquHuS6oVKk834JUykButaAU3XY\nvUGNQuKdLKAeQRT8Q6um4m+EYQKBgQC+Wz6nYESKH6GiNnuFTH8hIkThPlbi4wua\nU1kGnPKe3ouE4zRLfPwQ6RRf1slQ/2hFLOatiTLYUgZWZQeBPSWp2EjYcOSzob+7\n11+KqeIRCD5DKxgf0cjJdihK9AM639OKlH2NvZ2507TksdeTPDzdaOMLwLWKexP5\nlYrdob0ulwKBgD81t7Gvf83Ogw4FSjkRa2Cx6ofvPrKcVIeBu7ZbnPkLG37M+qEO\nq2xWqorG8uHi/7YLL9wprr5u0yQKwuZT8SYc9PE7jIKoMjcQW0vNu2FF2zMzkIsM\nvatMU4Hl/awbcPJSMjH3YQ635WZ4Jjxtyl1NjhvDR7rBqmYzwe9o3QaBAoGANhPB\n1tbYYczepDCKIrI6o3US0FJfaJFLqInpDqHjoxJh3FyXbKKTEVLFwPxJsML+IjjB\nR6dkVGPo/P4yhZqTao7REvvvXMCksX5b3A6q9F+9IGPLtK5qNiFlDPYJPN59QC8z\nA+NMPZBRIW8MaP2B5Px5E8upRy/z2sGK86+RCP0CgYATGs75F97q+Zf8q+Pe3Nsb\ngqmhLoI3PZUSWgBcQgNF4nyCZceUrEl72wKO/NWLgxqQPtlra187ce69g7qARHLb\ntHq80nb0f7lil74B6+OlyNNO1htWA90fmGR2s16Mt0BwJRT+/EFuNqbJIUSLxKiW\nqlXBUbmHHzamo5DPYL8S/w==\n-----END PRIVATE KEY-----\n",
|
||||||
|
"client_email": "aida-239@aida-461108.iam.gserviceaccount.com",
|
||||||
|
"client_id": "103102077955178349079",
|
||||||
|
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
"token_uri": "https://oauth2.googleapis.com/token",
|
||||||
|
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||||
|
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/aida-239%40aida-461108.iam.gserviceaccount.com",
|
||||||
|
"universe_domain": "googleapis.com"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user