From b0095e26a7515949a0bf8e0581021d2ab8bf73c6 Mon Sep 17 00:00:00 2001 From: xupei <1779019091@qq.com> Date: Fri, 29 Sep 2023 13:59:38 +0800 Subject: [PATCH] =?UTF-8?q?design=20detail=20=E6=96=B0=E5=A2=9E=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3--=E7=BC=96=E8=BE=91=E5=9B=BE=E5=B1=82=E7=9A=84?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E3=80=81=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../da/controller/DesignDetailController.java | 7 +- .../java/com/ai/da/mapper/entity/SysFile.java | 2 - .../entity/TDesignPythonOutfitDetail.java | 5 ++ .../ai/da/model/dto/DesignSingleItemDTO.java | 3 +- .../com/ai/da/model/vo/ComposeLayersVO.java | 21 +++++ .../model/vo/DesignItemClothesDetailVO.java | 5 +- .../da/model/vo/DesignItemOthersDetailVO.java | 5 +- .../ai/da/model/vo/DesignPythonOutfitVO.java | 5 ++ .../com/ai/da/model/vo/DesignSinglePrint.java | 6 +- .../com/ai/da/model/vo/DesignSingleVO.java | 5 +- .../vo/EditLayersPositionAndScaleVO.java | 15 ++++ .../java/com/ai/da/python/PythonService.java | 52 +++++++++-- .../da/python/vo/DesignPythonItemPrint.java | 1 - .../da/python/vo/OutfitDetailPythonItem.java | 33 +++++++ .../com/ai/da/service/DesignItemService.java | 3 + .../service/impl/DesignItemServiceImpl.java | 87 +++++++++++++++++-- .../ai/da/service/impl/DesignServiceImpl.java | 11 ++- 17 files changed, 235 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/ai/da/model/vo/ComposeLayersVO.java create mode 100644 src/main/java/com/ai/da/model/vo/EditLayersPositionAndScaleVO.java create mode 100644 src/main/java/com/ai/da/python/vo/OutfitDetailPythonItem.java diff --git a/src/main/java/com/ai/da/controller/DesignDetailController.java b/src/main/java/com/ai/da/controller/DesignDetailController.java index c4dd00e2..679de905 100644 --- a/src/main/java/com/ai/da/controller/DesignDetailController.java +++ b/src/main/java/com/ai/da/controller/DesignDetailController.java @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; +import java.io.IOException; @Api(tags = "design Detail模块") @@ -68,5 +69,9 @@ public class DesignDetailController { return response; } - + @ApiOperation(value = "编辑图层大小和位置") + @PostMapping("/editLayers") + public Response editPositionAndScale(@Valid @RequestBody EditLayersPositionAndScaleVO positionAndScaleVO) throws IOException { + return Response.success(designItemService.editLayersPositionAndScale(positionAndScaleVO)); + } } diff --git a/src/main/java/com/ai/da/mapper/entity/SysFile.java b/src/main/java/com/ai/da/mapper/entity/SysFile.java index c5363ad4..5072ab10 100644 --- a/src/main/java/com/ai/da/mapper/entity/SysFile.java +++ b/src/main/java/com/ai/da/mapper/entity/SysFile.java @@ -67,8 +67,6 @@ public class SysFile implements Serializable { */ private Date updateDate; - private Integer isCopy; - public SysFile() { } diff --git a/src/main/java/com/ai/da/mapper/entity/TDesignPythonOutfitDetail.java b/src/main/java/com/ai/da/mapper/entity/TDesignPythonOutfitDetail.java index 570898e0..0b0e71af 100644 --- a/src/main/java/com/ai/da/mapper/entity/TDesignPythonOutfitDetail.java +++ b/src/main/java/com/ai/da/mapper/entity/TDesignPythonOutfitDetail.java @@ -71,6 +71,11 @@ public class TDesignPythonOutfitDetail implements Serializable { */ @ApiModelProperty(value = "位置") private String position; + /** + * 图层缩放大小 + */ + @ApiModelProperty(value = "图层缩放大小") + private String scale; /** * 用户ID */ diff --git a/src/main/java/com/ai/da/model/dto/DesignSingleItemDTO.java b/src/main/java/com/ai/da/model/dto/DesignSingleItemDTO.java index 8eac3859..fcb4f920 100644 --- a/src/main/java/com/ai/da/model/dto/DesignSingleItemDTO.java +++ b/src/main/java/com/ai/da/model/dto/DesignSingleItemDTO.java @@ -16,8 +16,7 @@ public class DesignSingleItemDTO { @ApiModelProperty("生成item实际对应的类型 有:outwear,dress,blouse,skirt,trousers Shoes Hairstyle Earring") private String type; - @NotBlank(message = "path cannot be empty!") - @ApiModelProperty("对应的图片的绝对路径") + @ApiModelProperty("对应的图片的minIO路径") private String path; @NotBlank(message = "color cannot be empty!") diff --git a/src/main/java/com/ai/da/model/vo/ComposeLayersVO.java b/src/main/java/com/ai/da/model/vo/ComposeLayersVO.java new file mode 100644 index 00000000..209c5e3a --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/ComposeLayersVO.java @@ -0,0 +1,21 @@ +package com.ai.da.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel("编辑图层位置大小,合成图层") +public class ComposeLayersVO { + + @ApiModelProperty("designItemId") + private Long designItemId; + + @ApiModelProperty("图层信息") + private List layers; + + @ApiModelProperty("合成图") + private String designItemUrl; +} diff --git a/src/main/java/com/ai/da/model/vo/DesignItemClothesDetailVO.java b/src/main/java/com/ai/da/model/vo/DesignItemClothesDetailVO.java index c1cdd7c2..b6caf8d1 100644 --- a/src/main/java/com/ai/da/model/vo/DesignItemClothesDetailVO.java +++ b/src/main/java/com/ai/da/model/vo/DesignItemClothesDetailVO.java @@ -23,9 +23,12 @@ public class DesignItemClothesDetailVO { @ApiModelProperty("上传时候对应的类型,一级类型 Moodboard Printboard Sketchboard MarketingSketch Colorboard") private String level1Type; - @ApiModelProperty("对应的图片的绝对路径") + @ApiModelProperty("对应的图片路径") private String path; + @ApiModelProperty("对应图片minIO路径") + private String minIOPath; + @ApiModelProperty(" 颜色 存 RGB值 中间空格分隔 比如 58 58 169") // private String color; private PantoneVO color; diff --git a/src/main/java/com/ai/da/model/vo/DesignItemOthersDetailVO.java b/src/main/java/com/ai/da/model/vo/DesignItemOthersDetailVO.java index f68d6081..95fd96e1 100644 --- a/src/main/java/com/ai/da/model/vo/DesignItemOthersDetailVO.java +++ b/src/main/java/com/ai/da/model/vo/DesignItemOthersDetailVO.java @@ -17,9 +17,12 @@ public class DesignItemOthersDetailVO { @ApiModelProperty("对应的类型 有Hairstyle Earring Body") private String type; - @ApiModelProperty("对应的图片的绝对路径") + @ApiModelProperty("对应的图片路径") private String path; + @ApiModelProperty("对应图片minIO路径") + private String minIOPath; + @ApiModelProperty(" 颜色 存 RGB值 中间空格分隔 比如 58 58 169") // private String color; private PantoneVO color; diff --git a/src/main/java/com/ai/da/model/vo/DesignPythonOutfitVO.java b/src/main/java/com/ai/da/model/vo/DesignPythonOutfitVO.java index 69456abe..ad3a37c1 100644 --- a/src/main/java/com/ai/da/model/vo/DesignPythonOutfitVO.java +++ b/src/main/java/com/ai/da/model/vo/DesignPythonOutfitVO.java @@ -42,4 +42,9 @@ public class DesignPythonOutfitVO { */ @ApiModelProperty(value = "位置") private List position; + /** + * 图层缩放比例 + */ + @ApiModelProperty(value = "缩放比例") + private Float scale = 1.0f; } diff --git a/src/main/java/com/ai/da/model/vo/DesignSinglePrint.java b/src/main/java/com/ai/da/model/vo/DesignSinglePrint.java index 2cd5b2ec..d945fc4f 100644 --- a/src/main/java/com/ai/da/model/vo/DesignSinglePrint.java +++ b/src/main/java/com/ai/da/model/vo/DesignSinglePrint.java @@ -15,6 +15,9 @@ public class DesignSinglePrint { @ApiModelProperty("印花url") private String path; + @ApiModelProperty("印花minIO路径") + private String minIOPath; + @ApiModelProperty("印花位置") private List location; @@ -38,8 +41,9 @@ public class DesignSinglePrint { this.scale = scale; } - public DesignSinglePrint(String path, List location, Double scale, Double angle, Integer priority) { + public DesignSinglePrint(String path, String minIOPath, List location, Double scale, Double angle, Integer priority) { this.path = path; + this.minIOPath = minIOPath; this.location = location; this.scale = scale; this.angle = angle; diff --git a/src/main/java/com/ai/da/model/vo/DesignSingleVO.java b/src/main/java/com/ai/da/model/vo/DesignSingleVO.java index 7843cd90..058eac8c 100644 --- a/src/main/java/com/ai/da/model/vo/DesignSingleVO.java +++ b/src/main/java/com/ai/da/model/vo/DesignSingleVO.java @@ -8,11 +8,10 @@ import java.util.List; @Data public class DesignSingleVO { + @ApiModelProperty("designItemId") private Long designItemId; - /** - * 全身图 - */ + @ApiModelProperty("全身图") private String designItemUrl; diff --git a/src/main/java/com/ai/da/model/vo/EditLayersPositionAndScaleVO.java b/src/main/java/com/ai/da/model/vo/EditLayersPositionAndScaleVO.java new file mode 100644 index 00000000..2efe5be8 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/EditLayersPositionAndScaleVO.java @@ -0,0 +1,15 @@ +package com.ai.da.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel("编辑图层的位置、大小") +public class EditLayersPositionAndScaleVO { + @ApiModelProperty("layers") + private ComposeLayersVO layers; + + @ApiModelProperty("时区") + private String timeZone; +} diff --git a/src/main/java/com/ai/da/python/PythonService.java b/src/main/java/com/ai/da/python/PythonService.java index 15cd732b..791f660f 100644 --- a/src/main/java/com/ai/da/python/PythonService.java +++ b/src/main/java/com/ai/da/python/PythonService.java @@ -1404,7 +1404,7 @@ public class PythonService { location.add(priority - 1, p.getLocation()); scale.add(priority - 1,p.getScale()); angle.add(priority - 1,p.getAngle()); - paths.add(priority - 1,p.getPath()); + paths.add(priority - 1,p.getMinIOPath()); } // log.info("本次print打点locations###{}###fileVO{}", p.getLocation(), JSON.toJSONString(fileVO)); }); @@ -1697,7 +1697,7 @@ public class PythonService { throw new BusinessException("Generate Exception! Code : " + jsonObject.get("code")); } - public String sendPostToModel(Map content,String portAndRoute,String functionName){ + public Response sendPostToModel(String content,String portAndRoute,String functionName){ OkHttpClient client = new OkHttpClient().newBuilder() .connectTimeout(30, TimeUnit.SECONDS) @@ -1706,26 +1706,26 @@ public class PythonService { .writeTimeout(60, TimeUnit.SECONDS)//写入超时(单位:秒) .build(); MediaType mediaType = MediaType.parse("application/json"); - RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(content)); + RequestBody body = RequestBody.create(mediaType, content); Request request = new Request.Builder() - .url(accessPythonIp + ":" + portAndRoute) + .url("http://18.167.251.121" + ":" + portAndRoute) .method("POST", body) .addHeader("Authorization", "Basic YWlkbGFiOjEyMw==") .addHeader("Content-Type", "application/json") .build(); Response response = null; - String bodyString = null; +// String bodyString = null; try { - log.info(functionName + "请求入参content###{}", JSON.toJSONString(content)); + log.info(functionName + "请求入参content###{}", content); response = client.newCall(request).execute(); - bodyString = response.body().string(); +// bodyString = response.body().string(); } catch (IOException ioException) { log.error("PythonService##"+ functionName +"异常###{}", ExceptionUtil.getThrowableList(ioException)); } - return bodyString; + return response; } - private static List setGenerateImageList(JSONObject jsonObject){ + private List setGenerateImageList(JSONObject jsonObject){ List imageUrlList = JSONObject.parseArray(jsonObject.get("list").toString(),String.class); if (imageUrlList.isEmpty()){ log.error("PythonService##generateSketchOrPrint异常###{}","diffusion response list is null"); @@ -1735,4 +1735,38 @@ public class PythonService { return imageUrlList; } + + public String composeLayers(List layersDetail) throws IOException { + HashMap> layers = new HashMap<>(); + HashMap>> content = new HashMap<>(); + layers.put("layers", layersDetail); + content.put("0",layers); + String jsonString = JSON.toJSONString(content, SerializerFeature.WriteNullStringAsEmpty); + + // todo 添加限流 + Response response = this.sendPostToModel(jsonString, "9991/api/preview_control", "composeLayers"); + // todo 结束限流 + + String bodyString; + // 生成失败 + if (Objects.isNull(response) || Objects.isNull(response.body())) { + log.error("PythonService##composeLayers异常###{}", "response or body is empty!"); + throw new BusinessException("generate exception!"); + }else { + bodyString = response.body().string(); + } + JSONObject jsonObject = JSON.parseObject(bodyString); + Boolean result = JSON.parseObject(JSON.toJSONString(response)).getBoolean("successful"); + if (result && jsonObject.get("msg").equals("OK!")) { + return getCompositeImage(jsonObject.getJSONObject("code")); + } + log.info("composeLayers 失败###{}", jsonObject); + //生成失败 + throw new BusinessException("composeLayers Exception!"); + } + + private String getCompositeImage(JSONObject jsonObject){ + JSONObject item0 = jsonObject.getJSONObject("0"); + return item0.getString("synthesis_url"); + } } diff --git a/src/main/java/com/ai/da/python/vo/DesignPythonItemPrint.java b/src/main/java/com/ai/da/python/vo/DesignPythonItemPrint.java index 26a1a55f..dc4cb05e 100644 --- a/src/main/java/com/ai/da/python/vo/DesignPythonItemPrint.java +++ b/src/main/java/com/ai/da/python/vo/DesignPythonItemPrint.java @@ -46,7 +46,6 @@ public class DesignPythonItemPrint { return IfSingle; } - // todo public DesignPythonItemPrint(String singlePath, String level1Type, Float scale, Boolean ifSingle) { this.path = singlePath; this.level1Type = level1Type; diff --git a/src/main/java/com/ai/da/python/vo/OutfitDetailPythonItem.java b/src/main/java/com/ai/da/python/vo/OutfitDetailPythonItem.java new file mode 100644 index 00000000..92c1f7e8 --- /dev/null +++ b/src/main/java/com/ai/da/python/vo/OutfitDetailPythonItem.java @@ -0,0 +1,33 @@ +package com.ai.da.python.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class OutfitDetailPythonItem { + + private String image_category; + + private List position; + + private List image_size; + + private Float scale; + + private String image_url; + + private String mask_url; + + public OutfitDetailPythonItem() { + } + + public OutfitDetailPythonItem(String image_category, List position, List image_size, Float scale, String image_url, String mask_url) { + this.image_category = image_category; + this.position = position; + this.image_size = image_size; + this.scale = scale; + this.image_url = image_url; + this.mask_url = mask_url; + } +} diff --git a/src/main/java/com/ai/da/service/DesignItemService.java b/src/main/java/com/ai/da/service/DesignItemService.java index 4a1525f2..5b511adb 100644 --- a/src/main/java/com/ai/da/service/DesignItemService.java +++ b/src/main/java/com/ai/da/service/DesignItemService.java @@ -6,6 +6,7 @@ import com.ai.da.model.dto.DesignSingleIncludeLayersDTO; import com.ai.da.model.vo.*; import com.baomidou.mybatisplus.extension.service.IService; +import java.io.IOException; import java.util.List; /** @@ -47,4 +48,6 @@ public interface DesignItemService extends IService { DesignSingleVO designSingleIncludeLayers(DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO); + ComposeLayersVO editLayersPositionAndScale(EditLayersPositionAndScaleVO positionAndScaleVO) throws IOException; + } diff --git a/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java b/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java index 5dbcf493..30082302 100644 --- a/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java @@ -10,15 +10,10 @@ import com.ai.da.common.utils.DateUtil; import com.ai.da.common.utils.MinioUtil; import com.ai.da.mapper.DesignItemMapper; import com.ai.da.mapper.entity.*; -import com.ai.da.model.dto.DesignSingleDTO; -import com.ai.da.model.dto.DesignSingleIncludeLayersDTO; -import com.ai.da.model.dto.DesignSingleItemDTO; -import com.ai.da.model.dto.DesignSinglePrintDTO; +import com.ai.da.model.dto.*; import com.ai.da.model.vo.*; import com.ai.da.python.PythonService; -import com.ai.da.python.vo.DesignPythonItem; -import com.ai.da.python.vo.DesignPythonItemPrint; -import com.ai.da.python.vo.DesignPythonObjects; +import com.ai.da.python.vo.*; import com.ai.da.service.*; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; @@ -26,11 +21,14 @@ import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.common.collect.Lists; +import io.netty.util.internal.StringUtil; import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.units.qual.A; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import javax.annotation.Resource; +import java.io.IOException; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; @@ -356,6 +354,7 @@ public class DesignItemServiceImpl extends ServiceImpl { + TDesignPythonOutfitDetail detail = designPythonOutfitDetailService.getById(layer.getId()); + Assert.notNull(detail,layer.getImageCategory() + " layer does not exists!"); + + layer.setImageUrl(detail.getImageUrl()); + layer.setMaskUrl(detail.getMaskUrl()); + }); + + // 3、组装python入参 + List outfitDetailPythonItems = convertToOutfitDetailPythonItemList(designItemLayer.getLayers()); + + // 4、合成图层 + String synthesisUrl = pythonService.composeLayers(outfitDetailPythonItems); + designItemLayer.setDesignItemUrl(minioUtil.splitThenGetPreviewUrl(synthesisUrl,480)); + + // 5、更新数据库,根据designItemId更新designItemUrl + designItem.setUpdateDate(DateUtil.getByTimeZone(positionAndScaleVO.getTimeZone())); + designItem.setDesignUrl(synthesisUrl); + designItem.setId(designItemLayer.getDesignItemId()); + updateById(designItem); + + // 6、将图层信息position和scale更新到t_design_python_outfit_detail表 + ArrayList details = new ArrayList<>(); + designItemLayer.getLayers().forEach(layer -> { + TDesignPythonOutfitDetail layerDetail = new TDesignPythonOutfitDetail(); + layerDetail.setPosition(layer.getPosition().toString()); + layerDetail.setScale(layer.getScale().toString()); + layerDetail.setId(layer.getId()); + details.add(layerDetail); + }); + designPythonOutfitDetailService.updateBatchById(details); + + // 7、返回图层及合成图信息 + designItemLayer.getLayers().forEach(layer -> { + ArrayList imageSize = new ArrayList<>(); + for (int i = 0; i < layer.getImageSize().size(); i++) { + imageSize.add((long) (layer.getImageSize().get(i) * layer.getScale())); + } + layer.setImageSize(imageSize); + if (!StringUtil.isNullOrEmpty(layer.getImageUrl())){ + layer.setImageUrl(minioUtil.splitThenGetPreviewUrl(layer.getImageUrl(),480)); + } + if (!StringUtil.isNullOrEmpty(layer.getMaskUrl())){ + layer.setMaskUrl(minioUtil.splitThenGetPreviewUrl(layer.getMaskUrl(),480)); + } + }); + return designItemLayer; + } + private DesignSingleVO assembleDesignSingleResponse(Long designItemId,String designItemUrl, List designSingleItemDTOList, List layersObject){ @@ -440,6 +497,8 @@ public class DesignItemServiceImpl extends ServiceImpl convertToOutfitDetailPythonItemList(List layers){ + ArrayList composeLayerPythonItem = new ArrayList<>(); + layers.forEach(layer -> { + composeLayerPythonItem.add(new OutfitDetailPythonItem(layer.getImageCategory(), + layer.getPosition(), + layer.getImageSize(), + layer.getScale(), + layer.getImageUrl(), + layer.getMaskUrl())); + }); + return composeLayerPythonItem; + } } diff --git a/src/main/java/com/ai/da/service/impl/DesignServiceImpl.java b/src/main/java/com/ai/da/service/impl/DesignServiceImpl.java index d515408e..170b1a13 100644 --- a/src/main/java/com/ai/da/service/impl/DesignServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/DesignServiceImpl.java @@ -837,6 +837,8 @@ public class DesignServiceImpl extends ServiceImpl impleme .collect(Collectors.toList()); response.setClothes(CopyUtil.copyList(filterDetail,DesignItemClothesDetailVO.class,(o,d)->{ d.setId(o.getId()); + d.setPath(minIoUtil.splitThenGetPreviewUrl(o.getPath(),480)); + d.setMinIOPath(o.getPath()); d.setLevel1Type(converTypeToLevel1(o.getType())); // 根据designItemDetailId获取印花 List prints = designItemDetailPrintService.getByDesignItemDetailId(o.getId()); @@ -860,6 +862,8 @@ public class DesignServiceImpl extends ServiceImpl impleme .collect(Collectors.toList()); response.setOthers(CopyUtil.copyList(filterDetail2, DesignItemOthersDetailVO.class, (o, d) -> { d.setId(o.getBusinessId()); + d.setPath(minIoUtil.splitThenGetPreviewUrl(o.getPath(),480)); + d.setMinIOPath(o.getPath()); d.setPrintObject(new DesignPythonItemPrint()); })); return editDesignItemLayer(flag,designPythonOutfit, @@ -992,7 +996,8 @@ public class DesignServiceImpl extends ServiceImpl impleme designSinglePrint.setAngle(detailPrint.getAngle()); designSinglePrint.setPriority(detailPrint.getPriority()); } - designSinglePrint.setPath(detailPrint.getPath()); + designSinglePrint.setPath(minIoUtil.splitThenGetPreviewUrl(detailPrint.getPath(),480)); + designSinglePrint.setMinIOPath(detailPrint.getPath()); designSinglePrint.setScale(detailPrint.getScale()); prints.add(designSinglePrint); }else { @@ -1000,7 +1005,9 @@ public class DesignServiceImpl extends ServiceImpl impleme designSinglePrintDTO.setIfSingle(Boolean.TRUE); designItemDetailPrints.forEach(print -> { if (print.getSingleOrOverall().equals("single")){ - prints.add(new DesignSinglePrint(print.getPath(), + prints.add(new DesignSinglePrint( + minIoUtil.splitThenGetPreviewUrl(print.getPath(),480), + print.getPath(), JSONArray.parseArray(print.getPosition(),Double.class), print.getScale(), print.getAngle(),