diff --git a/src/main/java/com/ai/da/common/utils/FileUtil.java b/src/main/java/com/ai/da/common/utils/FileUtil.java index 43801af6..30f4018b 100644 --- a/src/main/java/com/ai/da/common/utils/FileUtil.java +++ b/src/main/java/com/ai/da/common/utils/FileUtil.java @@ -174,7 +174,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { URL url = new URL(path); return url.openStream(); } catch (IOException ioException) { - log.error("获取文件尺寸异常###{}###path##{}", ExceptionUtil.stacktraceToString(ioException), path); + log.error("获取源文件异常###{}###path##{}", ExceptionUtil.stacktraceToString(ioException), path); throw new BusinessException("get.file.failed"); } } diff --git a/src/main/java/com/ai/da/controller/GenerateController.java b/src/main/java/com/ai/da/controller/GenerateController.java index f1e633ad..8dbd4478 100644 --- a/src/main/java/com/ai/da/controller/GenerateController.java +++ b/src/main/java/com/ai/da/controller/GenerateController.java @@ -1,10 +1,7 @@ package com.ai.da.controller; import com.ai.da.common.response.Response; -import com.ai.da.model.dto.GenerateLikeDTO; -import com.ai.da.model.dto.GenerateModifyDTO; -import com.ai.da.model.dto.GenerateThroughImageTextDTO; -import com.ai.da.model.dto.ImageToSketchDTO; +import com.ai.da.model.dto.*; import com.ai.da.model.vo.*; import com.ai.da.service.GenerateService; import io.swagger.annotations.Api; @@ -12,6 +9,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.validation.Valid; @@ -87,7 +85,7 @@ public class GenerateController { @ApiOperation(value = "imageToSketch") @PostMapping("/imageToSketch") public Response imageToSketch(@Valid @RequestBody ImageToSketchDTO imageToSketchDTO) { - return Response.success(generateService.imageToSketch(imageToSketchDTO)); + return Response.success(generateService.imageToSketch(imageToSketchDTO, null, null)); } // modifySketch @@ -97,27 +95,47 @@ public class GenerateController { return Response.success(generateService.modifySketch(generateModifyDTO)); } - @ApiOperation(value = "请求poseTransform,异步获取结果") - @PostMapping("/poseTransform") + @ApiOperation(value = "请求进行姿势变换") + @GetMapping("/poseTransform") public Response poseTransform(@ApiParam("projectId") @RequestParam Long projectId, @ApiParam("productImage") @RequestParam String productImage, @ApiParam("poseId") @RequestParam int poseId) { return Response.success(generateService.poseTransform(projectId, productImage, poseId)); } - @ApiOperation(value = "获取pose transformation生成结果") - @PostMapping("/poseTransformResult") + @ApiOperation(value = "获取姿势变换生成结果") + @GetMapping("/poseTransformResult") public Response getPoseTransformationResults(@ApiParam("taskId") @RequestParam String taskId) { PoseTransformationVO generateResult = generateService.getPoseTransformationResult(taskId); return Response.success(generateResult); } - public Response modifyModelProportion(){ - return null; + @ApiOperation(value = "修改模特比例") + @PostMapping("/modifyProportion") + public Response modifyModelProportion(@Valid @RequestBody ModifyModelProportionDTO proportionDTO){ + String path = generateService.modifyModelProportion(proportionDTO); + return Response.success(path); } - public Response sketchReconstruction(){ - return null; + @ApiOperation(value = "拼贴图生成线稿") + @PostMapping("/genSketchRecon") + public Response sketchReconstructionGenerate(@Valid @RequestBody SketchReconstructionDTO sketchReconstructionDTO){ + GenerateResultVO generateResultVO = generateService.sketchReconstructionGenerate(sketchReconstructionDTO); + return Response.success(generateResultVO); + } + + @ApiOperation(value = "拼贴图画布保存") + @GetMapping("/saveReconCanvas") + public Response sketchReconstructionSave(@RequestParam("file") MultipartFile file, @RequestParam("projectId") Long projectId){ + generateService.sketchReconstructionSave(file, projectId); + return Response.success("success"); + } + + @ApiOperation(value = "获取拼贴图画布") + @GetMapping("/getReconCanvas") + public Response getSketchReconstruction(@RequestParam("projectId") Long projectId){ + SketchReconstructionVO sketchReconstruction = generateService.getSketchReconstruction(projectId); + return Response.success(sketchReconstruction); } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/Generate.java b/src/main/java/com/ai/da/mapper/primary/entity/Generate.java index 7a3157ab..ef5f6809 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/Generate.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/Generate.java @@ -85,6 +85,15 @@ public class Generate { */ private Long styleImageElementId; + /** + * 由拼贴图生成线稿的项目id + */ + private Long projectId; + /** + * 输入模型的拼贴图 + */ + private String inputImageUrl; + /** * 创建时间 */ diff --git a/src/main/java/com/ai/da/mapper/primary/entity/SketchReconstruction.java b/src/main/java/com/ai/da/mapper/primary/entity/SketchReconstruction.java index 24a46ea4..3ba957a3 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/SketchReconstruction.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/SketchReconstruction.java @@ -10,13 +10,11 @@ import lombok.EqualsAndHashCode; public class SketchReconstruction extends BaseEntity{ private Long projectId; + // 最后一次拼贴图生成的sketch + private String collageImgSketchUrl; - private Long elementId; - - // upload、library、generate - private String elementSource; - - private String path; + private Long generateDetailId; + private String canvasUrl; } diff --git a/src/main/java/com/ai/da/model/dto/ModifyModelProportionDTO.java b/src/main/java/com/ai/da/model/dto/ModifyModelProportionDTO.java new file mode 100644 index 00000000..499b9b51 --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/ModifyModelProportionDTO.java @@ -0,0 +1,68 @@ +package com.ai.da.model.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Data +@ApiModel("ModifyModelProportionDTO") +public class ModifyModelProportionDTO { + @ApiModelProperty("模特id") + @NotNull(message = "model id cannot be empty") + private Long id; + + @ApiModelProperty("Library || System") + @NotBlank(message = "model type cannot be empty") + private String type; + + @ApiModelProperty("top") + @NotNull(message = "top cannot be empty") + private Integer top; + + @ApiModelProperty("bottom") + @NotNull(message = "bottom cannot be empty") + private Integer bottom; + + @ApiModelProperty("stretch") + @NotNull(message = "stretch cannot be empty") + private Float stretch; + + @ApiModelProperty("模特minio地址") + @NotBlank(message = "modelPath type cannot be empty") + private String modelPath; + + @NotNull(message = "handLeft cannot be null") + @NotEmpty(message = "handLeft cannot be empty") + @ApiModelProperty("handLeft") + private Float[] handLeft; + + @NotNull(message = "handRight cannot be null") + @NotEmpty(message = "handRight cannot be empty") + @ApiModelProperty("handRight") + private Float[] handRight; + + @NotNull(message = "shoulderLeft cannot be null") + @NotEmpty(message = "shoulderLeft cannot be empty") + @ApiModelProperty("shoulderLeft") + private Float[] shoulderLeft; + + @NotNull(message = "shoulderRight cannot be null") + @NotEmpty(message = "shoulderRight cannot be empty") + @ApiModelProperty("shoulderRight") + private Float[] shoulderRight; + + @NotNull(message = "waistbandLeft cannot be null") + @NotEmpty(message = "waistbandLeft cannot be empty") + @ApiModelProperty("waistbandLeft") + private Float[] waistbandLeft; + + @NotNull(message = "waistbandRight cannot be null") + @NotEmpty(message = "waistbandRight cannot be empty") + @ApiModelProperty("waistbandRight") + private Float[] waistbandRight; + +} diff --git a/src/main/java/com/ai/da/model/dto/SketchReconstructionDTO.java b/src/main/java/com/ai/da/model/dto/SketchReconstructionDTO.java index ba665441..e44fd76c 100644 --- a/src/main/java/com/ai/da/model/dto/SketchReconstructionDTO.java +++ b/src/main/java/com/ai/da/model/dto/SketchReconstructionDTO.java @@ -1,32 +1,19 @@ package com.ai.da.model.dto; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; @Data +@ApiModel(value = "sketch拼贴") public class SketchReconstructionDTO { + + @ApiModelProperty("项目id") private Long projectId; + @ApiModelProperty("拼贴图的base64数据") private String collagePicture; - - private List elements; - - private MultipartFile file; - - // like到library时分类用 + // 识别衣服类型用 + @ApiModelProperty("性别") private String gender; - - private boolean Save; - - - @Data - public static class Element{ - private Long elementId; - - private String elementSource; - - private String path; - } } diff --git a/src/main/java/com/ai/da/model/vo/SketchReconstructionVO.java b/src/main/java/com/ai/da/model/vo/SketchReconstructionVO.java new file mode 100644 index 00000000..047d2d43 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/SketchReconstructionVO.java @@ -0,0 +1,15 @@ +package com.ai.da.model.vo; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +@Data +public class SketchReconstructionVO { + + private JSONObject canvasFile; + + private String collageSketchUrl; + + private boolean isLiked; + +} diff --git a/src/main/java/com/ai/da/python/PythonService.java b/src/main/java/com/ai/da/python/PythonService.java index 2ed86455..84aca510 100644 --- a/src/main/java/com/ai/da/python/PythonService.java +++ b/src/main/java/com/ai/da/python/PythonService.java @@ -3857,4 +3857,66 @@ public class PythonService { } } + public String modifyModelProportion(String mannequinPath, Float scale, String name, int top, int bottom) { + OkHttpClient client = new OkHttpClient().newBuilder() + .connectTimeout(30, TimeUnit.SECONDS) + .pingInterval(5, TimeUnit.SECONDS)//websocket轮训间隔(单位:秒) + .readTimeout(60, TimeUnit.SECONDS)//读取超时(单位:秒) + .writeTimeout(60, TimeUnit.SECONDS)//写入超时(单位:秒) + .build(); + + MediaType mediaType = MediaType.parse("application/json"); + Map content = Maps.newHashMap(); + // 模特的minio地址 + content.put("mannequins", mannequinPath); + // 缩放比 + content.put("scale", scale.toString()); + // 结果存放桶名 + content.put("bucket_name", "aida-users"); + // 模特名uuid + content.put("mannequin_name", name); + content.put("top", String.valueOf(top)); + content.put("bottom", String.valueOf(bottom)); + RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(content)); + + log.info("modifyModelProportion 请求地址: {},\n 参数:{}", accessPythonIp + ":" + accessPythonPort + "/api/mannequins_edit", JSON.toJSONString(content)); + Request request = new Request.Builder() + .url(accessPythonIp + ":" + accessPythonPort + "/api/mannequins_edit") + .method("POST", body) + .addHeader("Content-Type", "application/json") + .build(); + Response response = null; + try { + response = client.newCall(request).execute(); + } catch (IOException ioException) { + log.error("PythonService##modifyModelProportion异常###{}", ExceptionUtil.getThrowableList(ioException)); + throw new BusinessException("generate.interface.error"); + } + int responseCode = response.code(); + String bodyString; + try { + bodyString = response.body().string(); + if (responseCode != HttpURLConnection.HTTP_OK) { + // 基本不会有除200以外的code + log.info("modifyModelProportion 失败。 Response code {}", responseCode); + throw new BusinessException("modifyModelProportion 失败。 Response code " + responseCode); + } + JSONObject jsonObject = JSON.parseObject(bodyString); + if (response.isSuccessful() && jsonObject.get("msg").equals("OK!")) { + String modifiedModel = jsonObject.get("data").toString(); + log.info("modifyModelProportion 结果 : {}", modifiedModel); + return modifiedModel; + }else { + log.info("modifyModelProportion 失败。 Response code {}", responseCode); + throw new BusinessException("modifyModelProportion 失败。 Response code " + responseCode); + } + } catch (IOException e) { + log.error("modifyModelProportion 失败; error message => {}", e.getMessage()); + response.close(); + throw new BusinessException("generate.interface.error"); + } finally { + response.close(); + } + } + } diff --git a/src/main/java/com/ai/da/service/GenerateService.java b/src/main/java/com/ai/da/service/GenerateService.java index 1872314c..f86f70a0 100644 --- a/src/main/java/com/ai/da/service/GenerateService.java +++ b/src/main/java/com/ai/da/service/GenerateService.java @@ -2,12 +2,10 @@ package com.ai.da.service; import com.ai.da.mapper.primary.entity.Generate; import com.ai.da.mapper.primary.entity.GenerateDetail; -import com.ai.da.model.dto.GenerateLikeDTO; -import com.ai.da.model.dto.GenerateModifyDTO; -import com.ai.da.model.dto.GenerateThroughImageTextDTO; -import com.ai.da.model.dto.ImageToSketchDTO; +import com.ai.da.model.dto.*; import com.ai.da.model.vo.*; import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.web.multipart.MultipartFile; import java.util.List; import java.util.Map; @@ -44,7 +42,7 @@ public interface GenerateService extends IService { List> getCountByUserAndTime(String startTime, String endTime, List accountIdList); - GenerateResultVO imageToSketch(ImageToSketchDTO imageToSketchDTO); + GenerateResultVO imageToSketch(ImageToSketchDTO imageToSketchDTO, String collagePictureUrl, Long projectId); GenerateResultVO modifySketch(GenerateModifyDTO generateModifyDTO); @@ -53,4 +51,12 @@ public interface GenerateService extends IService { void processPoseTransformResult(String taskId, String gifUrl, String videoUrl, String imageUrl); PoseTransformationVO getPoseTransformationResult(String taskId); + + String modifyModelProportion(ModifyModelProportionDTO proportionDTO); + + GenerateResultVO sketchReconstructionGenerate(SketchReconstructionDTO sketchReconstructionDTO); + + String sketchReconstructionSave(MultipartFile multipartFile, Long projectId); + + SketchReconstructionVO getSketchReconstruction(Long projectId); } diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index e15ceebf..4750cd98 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -14,6 +14,8 @@ import com.ai.da.model.vo.*; import com.ai.da.python.PythonService; import com.ai.da.service.*; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; @@ -26,14 +28,17 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; import static com.ai.da.common.enums.CollectionLevel1TypeEnum.*; +import static com.ai.da.service.impl.UserLikeGroupServiceImpl.convert; @Slf4j @Service @@ -814,7 +819,7 @@ public class GenerateServiceImpl extends ServiceImpl i @Override @Transactional(rollbackFor = Exception.class) - public GenerateResultVO imageToSketch(ImageToSketchDTO imageToSketchDTO) { + public GenerateResultVO imageToSketch(ImageToSketchDTO imageToSketchDTO, String collagePictureUrl, Long projectId) { String bucket = userBucket; Long accountId = UserContext.getUserHolder().getId(); @@ -827,8 +832,13 @@ public class GenerateServiceImpl extends ServiceImpl i throw new BusinessException("remaining.credits.insufficient", ResultEnum.PROMPT.getCode()); } - CollectionElement collectionElement = collectionElementService.getById(imageToSketchDTO.getElementId()); - String imagePath = collectionElement.getUrl(); + String imagePath; + if (StringUtil.isNullOrEmpty(collagePictureUrl)){ + CollectionElement collectionElement = collectionElementService.getById(imageToSketchDTO.getElementId()); + imagePath = collectionElement.getUrl(); + }else { + imagePath = collagePictureUrl; + } log.info(minioUtil.getPreSignedUrl(imagePath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); String imageName = UUID.randomUUID().toString(); @@ -856,7 +866,9 @@ public class GenerateServiceImpl extends ServiceImpl i generate.setElementId(imageToSketchDTO.getElementId()); generate.setGenerateType("image"); generate.setSketchStyle(styleCode); - generate.setStyleImageElementId(imageToSketchDTO.getElementId()); + generate.setStyleImageElementId(imageToSketchDTO.getStyleImageId()); + generate.setProjectId(projectId); + generate.setInputImageUrl(collagePictureUrl); generate.setCreateDate(new Date()); baseMapper.insert(generate); @@ -1011,51 +1023,168 @@ public class GenerateServiceImpl extends ServiceImpl i } } + @Resource + private SysFileService sysFileService; + + @Resource + private LibraryModelPointService libraryModelPointService; + public String modifyModelProportion(ModifyModelProportionDTO proportionDTO){ + log.info("modifyModelProportion params: {}", proportionDTO); + String name; + String gender; + Library model = null; + Long accountId = UserContext.getUserHolder().getId(); + String uuid = UUID.randomUUID().toString(); + // 所有修改的图片都另存为,不覆盖原图 + if (proportionDTO.getType().equals("Library")){ + model = libraryService.getById(proportionDTO.getId()); + String url = model.getUrl(); + name = url.substring(url.indexOf("/") + 1, url.lastIndexOf("/")) + "/" + uuid; + gender = model.getLevel2Type(); + }else { + SysFileVO sysModel = sysFileService.getById(proportionDTO.getId()); + gender = sysModel.getLevel2Type(); + name = accountId + "/models/" + gender.toLowerCase() + "/" + uuid; + } + // 只需要将结果存入library + String modifiedModel = pythonService.modifyModelProportion(proportionDTO.getModelPath(), proportionDTO.getStretch(), name, proportionDTO.getTop(), proportionDTO.getBottom()); + List imagesWidthAndHeight = minioUtil.getImagesWidthAndHeight(modifiedModel); + + // 存储修改后的模特到个人library + model = new Library(); + model.setAccountId(accountId); + model.setLevel1Type(LibraryLevel1TypeEnum.MODELS.getRealName()); + model.setLevel2Type(gender); + model.setName(uuid); + model.setUrl(modifiedModel); + model.setMd5(MD5Utils.encryptFile(minioUtil.getPreSignedUrl(modifiedModel, 24 * 60),false)); + model.setWidth(imagesWidthAndHeight.get(0)); + model.setHigh(imagesWidthAndHeight.get(1)); + model.setCreateDate(new Date()); + libraryService.save(model); + + // 新建模特点位信息 + LibraryModelPoint libraryModelPoint = new LibraryModelPoint(); + libraryModelPoint.setModelType("Library"); + libraryModelPoint.setRelationId(model.getId()); + libraryModelPoint.setShoulderLeft(Arrays.toString(proportionDTO.getShoulderLeft())); + libraryModelPoint.setShoulderRight(Arrays.toString(proportionDTO.getShoulderRight())); + libraryModelPoint.setWaistbandLeft(Arrays.toString(proportionDTO.getWaistbandLeft())); + libraryModelPoint.setWaistbandRight(Arrays.toString(proportionDTO.getWaistbandRight())); + libraryModelPoint.setHandLeft(Arrays.toString(proportionDTO.getHandLeft())); + libraryModelPoint.setHandRight(Arrays.toString(proportionDTO.getHandRight())); + libraryModelPoint.setCreateDate(new Date()); + libraryModelPointService.save(libraryModelPoint); + return minioUtil.getPreSignedUrl(modifiedModel, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); + } + /** * String collagePicture(Base64) * List elements * File file * @return */ - public String sketchReconstruction(SketchReconstructionDTO sketchReconstructionDTO){ + @Transactional(rollbackFor = Exception.class) + public GenerateResultVO sketchReconstructionGenerate(SketchReconstructionDTO sketchReconstructionDTO){ Long accountId = UserContext.getUserHolder().getId(); // 1、线稿生成 String collagePictureBase64 = sketchReconstructionDTO.getCollagePicture(); String path = accountId + "/CollagePicture/" + UUID.randomUUID(); String minioPath = minioUtil.base64UploadToPath(collagePictureBase64, userBucket, path); - CollectionElement collectionElement = new CollectionElement(); - collectionElement.setAccountId(accountId); - collectionElement.setLevel1Type(SKETCH_BOARD.getRealName()); - collectionElement.setUrl(minioPath); - collectionElement.setMd5(MD5Utils.encryptFile(minioPath, false)); - collectionElement.setCreateDate(new Date()); - collectionElementService.save(collectionElement); - GenerateResultVO generateResultVO = imageToSketch(new ImageToSketchDTO(collectionElement.getId(), "2", sketchReconstructionDTO.getGender())); - // 2、以文件形式保存元素,同时还要将使用的元素单独存储 - if (sketchReconstructionDTO.isSave() && !sketchReconstructionDTO.getElements().isEmpty()){ - // 将使用的元素全部都保存到新建表 - // 先判断该project下有没有数据,无 --> 直接保存;有 --> 先删除,再保存 - QueryWrapper qw = new QueryWrapper<>(); - qw.eq("project_id", sketchReconstructionDTO.getProjectId()); - List sketchReconstructions = sketchReconstructionMapper.selectList(qw); - if (!sketchReconstructions.isEmpty()){ - sketchReconstructionMapper.delete(qw); - } - sketchReconstructionDTO.getElements().forEach(element -> { - SketchReconstruction sketchReconstruction = new SketchReconstruction(); - sketchReconstruction.setProjectId(sketchReconstructionDTO.getProjectId()); - sketchReconstruction.setElementId(element.getElementId()); - sketchReconstruction.setElementSource(element.getElementSource()); - sketchReconstruction.setPath(element.getPath()); - sketchReconstructionMapper.insert(sketchReconstruction); - }); + Long projectId = sketchReconstructionDTO.getProjectId(); - // 将画布文件上传到minio,地址保存到project表中 - String canvasPath = minioUtil.upload("aida-users", accountId + "/CollagePicture/CanvasFile", sketchReconstructionDTO.getFile()); + GenerateResultVO generateResultVO = imageToSketch(new ImageToSketchDTO(null, "2", sketchReconstructionDTO.getGender()), minioPath, projectId); + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("project_id", projectId); + SketchReconstruction sketchReconstruction = sketchReconstructionMapper.selectOne(qw); + + String url = generateResultVO.getUrl(); + // 找到路径的起始位置(从"://"之后查找第一个"/") + int pathStartIndex = url.indexOf("/", url.indexOf("://") + 3); + // 找到查询参数的起始位置("?" 的位置) + int queryStartIndex = url.indexOf("?"); + // 截取目标部分 + String targetPath = url.substring(pathStartIndex + 1, queryStartIndex); + + if (Objects.isNull(sketchReconstruction)){ + sketchReconstruction = new SketchReconstruction(); + sketchReconstruction.setProjectId(projectId); + sketchReconstruction.setCollageImgSketchUrl(targetPath); + sketchReconstruction.setGenerateDetailId(generateResultVO.getId()); + sketchReconstruction.setCreateTime(LocalDateTime.now()); + sketchReconstructionMapper.insert(sketchReconstruction); + }else { + sketchReconstruction.setCollageImgSketchUrl(targetPath); + sketchReconstruction.setGenerateDetailId(generateResultVO.getId()); + sketchReconstructionMapper.updateById(sketchReconstruction); + } + + return generateResultVO; + } + + public String sketchReconstructionSave(MultipartFile multipartFile, Long projectId){ + Long accountId = UserContext.getUserHolder().getId(); + // 元素都在画布上,不用额外保存 + String object = accountId + "/CollageSketchFile/" + projectId; + String canvasFilePath = minioUtil.upload("aida-users", object, multipartFile,null); + + // 将画布文件上传到minio,地址保存到project表中 + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("project_id", projectId).isNotNull("canvas_url").orderByDesc("id"); + SketchReconstruction sketchReconstruction = sketchReconstructionMapper.selectOne(qw); + if (Objects.isNull(sketchReconstruction)){ + sketchReconstruction = new SketchReconstruction(); + sketchReconstruction.setProjectId(projectId); + sketchReconstruction.setCanvasUrl(canvasFilePath); + sketchReconstruction.setCreateTime(LocalDateTime.now()); + sketchReconstructionMapper.insert(sketchReconstruction); + }else if (StringUtil.isNullOrEmpty(sketchReconstruction.getCanvasUrl())){ + sketchReconstruction.setCanvasUrl(canvasFilePath); + sketchReconstructionMapper.updateById(sketchReconstruction); } // 需要返回哪些信息呢? return null; } + + public SketchReconstructionVO getSketchReconstruction(Long projectId){ + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("project_id", projectId); + SketchReconstruction sketchReconstruction = sketchReconstructionMapper.selectOne(qw); + if (Objects.isNull(sketchReconstruction) || StringUtil.isNullOrEmpty(sketchReconstruction.getCanvasUrl())){ + return null; + } + + try { + InputStream download = minioUtil.download(sketchReconstruction.getCanvasUrl()); + String convert = convert(download); + JSONObject jsonObject = JSONObject.parseObject(convert); + JSONArray objects = jsonObject.getJSONArray("objects"); + for (int i = 0; i < objects.size(); i++) { + JSONObject jsonObject1 = objects.getJSONObject(i); + String type = jsonObject1.getString("type"); + if (type.equals("image")) { + String minioUrl = jsonObject1.getString("minioUrl"); + jsonObject1.put("src", minioUtil.getPreSignedUrl(minioUrl, 24 * 60)); + } + objects.set(i, jsonObject1); + } + jsonObject.put("objects", objects); + log.info(String.valueOf(jsonObject)); + + // 除返回jsonObject之外,还要返回最后一次生成的线稿图以及like状态 + SketchReconstructionVO vo = new SketchReconstructionVO(); + vo.setCanvasFile(jsonObject); + if (Objects.nonNull(sketchReconstruction.getGenerateDetailId())){ + GenerateDetail generateDetail = generateDetailMapper.selectById(sketchReconstruction.getGenerateDetailId()); + vo.setCollageSketchUrl(minioUtil.getPreSignedUrl(generateDetail.getUrl(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + vo.setLiked(generateDetail.getIsLike().equals((byte)1)); + } + return vo; + }catch (Exception e){ + return null; + } + } + }