mask替换相关接口--未完善版,暂存

This commit is contained in:
2024-09-06 12:34:36 +08:00
parent d23ac82b1b
commit 969d7586fc
11 changed files with 454 additions and 2 deletions

View File

@@ -5,6 +5,7 @@ import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.DesignItemService;
import com.ai.da.service.DesignService;
import com.ai.da.service.UserLikeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@@ -14,6 +15,8 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@Api(tags = "design Detail模块")
@@ -77,4 +80,19 @@ public class DesignDetailController {
public Response<ComposeLayersVO> editPositionAndScale(@Valid @RequestBody EditLayersPositionAndScaleVO positionAndScaleVO) throws IOException {
return Response.success(designItemService.editLayersPositionAndScale(positionAndScaleVO));
}
@ApiOperation(value = "mask数据兼容")
@PostMapping("/convertWithoutGradient")
public Response<String> convertHistoryMaskWithoutGradient(){
designItemService.convertHistoryMaskWithoutGradient();
return Response.success("success");
}
@Resource
private UserLikeService userLikeService;
@ApiOperation(value = "获取历史like中包含有渐变色的design")
@PostMapping("/getHistoryLikeWithGradient")
public Response<List<Map<String, Long>>> getHistoryLikeWithGradient(){
return Response.success(userLikeService.getHistoryLikeWithGradient());
}
}

View File

@@ -3,6 +3,9 @@ package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.UserLike;
import java.util.List;
import java.util.Map;
/**
* Mapper 接口
*
@@ -11,4 +14,8 @@ import com.ai.da.mapper.primary.entity.UserLike;
*/
public interface UserLikeMapper extends CommonMapper<UserLike> {
List<Map<String, Long>> getHistoryLikeWithoutGradient();
List<Map<String, Long>> getHistoryLikeWithGradient();
}

View File

@@ -59,4 +59,9 @@ public class UserLike implements Serializable {
* 更新时间
*/
private Date updateDate;
/**
* design对应的mask是否已替换为最新的
*/
private Integer converted;
}

View File

@@ -59,4 +59,10 @@ public class DesignSingleItemDTO implements Serializable {
@ApiModelProperty("衣服上的装饰")
private DesignSinglePrintDTO trims;
@ApiModelProperty("标注后的mask 的base64")
private String maskUrl;
@ApiModelProperty("mask 的minio地址")
private String maskMinioUrl;
}

View File

@@ -2662,7 +2662,8 @@ public class PythonService {
designSingleItem.getScale(),
designSingleItem.getPriority(),
minioPath,
gradientString));
gradientString,
designSingleItem.getMaskUrl()));
});
@@ -2684,7 +2685,7 @@ public class PythonService {
DesignPythonItemPrint printOverall = new DesignPythonItemPrint();
printToPython.setSingle(printSingle);
printToPython.setOverall(printOverall);
if (printObject.isEmpty()){
if (Objects.isNull(printObject) || printObject.isEmpty()){
return printToPython;
}

View File

@@ -82,6 +82,10 @@ public class DesignPythonItem {
* 图层优先级
*/
private Integer priority;
/**
* 标注过的mask
*/
private String seg_mask_url;
public static List<String> OUTWEAR_DRESS_BLOUSE = Arrays.asList(CollectionLevel2TypeEnum.OUTWEAR.getRealName(),
CollectionLevel2TypeEnum.DRESS.getRealName(), CollectionLevel2TypeEnum.BLOUSE.getRealName());
@@ -134,6 +138,24 @@ public class DesignPythonItem {
this.gradientString = gradientString;
}
public DesignPythonItem(String type, String path, String color, PrintToPython print, Long businessId,
Long image_id, List<Long> offset, Float[] resize_scale, Integer priority, String gradient,
String gradientString, String seg_mask_url) {
this.type = type;
this.path = path;
this.color = color;
this.print = print;
// this.icon = icon;
this.businessId = businessId;
this.image_id = image_id;
this.offset = offset;
this.resize_scale = resize_scale;
this.priority = priority;
this.gradient = gradient;
this.gradientString = gradientString;
this.seg_mask_url = seg_mask_url;
}
public DesignPythonItem(String type, String path, String color, PrintToPython print, String icon, Long businessId, Long image_id) {
this.type = type;
this.path = path;

View File

@@ -60,4 +60,6 @@ public interface DesignItemService extends IService<DesignItem> {
List<DesignItem> selectDesignIdById(List<Long> designItemIdList);
Long getCountByUserAndTime(String startTime, String endTime, List<Long> accountIds);
void convertHistoryMaskWithoutGradient();
}

View File

@@ -5,6 +5,7 @@ import com.ai.da.model.vo.UserLikeVO;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* 服务类
@@ -25,4 +26,6 @@ public interface UserLikeService extends IService<UserLike> {
void updateDate(Long designItemId,String timeZone);
List<UserLike> getUserLikeList(Long id);
List<Map<String, Long>> getHistoryLikeWithGradient();
}

View File

@@ -10,6 +10,7 @@ import com.ai.da.common.enums.SingleOverallEnum;
import com.ai.da.common.enums.SysFileLevel2TypeEnum;
import com.ai.da.common.utils.*;
import com.ai.da.mapper.primary.DesignItemMapper;
import com.ai.da.mapper.primary.UserLikeMapper;
import com.ai.da.mapper.primary.entity.*;
import com.ai.da.model.dto.*;
import com.ai.da.model.enums.ModelType;
@@ -82,6 +83,9 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
@Value("${minio.bucketName.modifiedSketch}")
private String modifiedSketchBucket;
@Value("${minio.bucketName.clothing}")
private String clothingBucket;
@Override
public Long saveOne(DesignItem designItem) {
if (designItemMapper.insertDesignItem(designItem) <= 0) {
@@ -435,6 +439,11 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
log.info("set sketchString为空便于日志打印");
i.setSketchString(null);
}
// 标注过的mask
if (!StringUtil.isNullOrEmpty(i.getMaskUrl())){
log.info("set labelingMask为空便于日志打印");
i.setMaskUrl(null);
}
});
log.info("designSingle request入参 ==> " + JSONObject.toJSONString(clone));
@@ -488,6 +497,9 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
// 所以这里选择使用system或collection相同的地址只是放在不同的桶这样能保证图片服务器上,类似的sketch不会存在很多
sketchBase64ToPath(designSingleIncludeLayersDTO);
// todo 将标注后的mask上传到minio,并将minio地址传给python端
maskBase64ToPath(designSingleIncludeLayersDTO);
// 组装入参
DesignPythonObjects objects = pythonService.covertDesignSingleParam(
designSingleIncludeLayersDTO, design.getSingleOverall(), design.getSwitchCategory(), designLibraryModelPointVO);
@@ -569,6 +581,27 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
});
}
private void maskBase64ToPath(DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO){
designSingleIncludeLayersDTO.getDesignSingleItemDTOList().forEach(item -> {
// 如果sketch截图不为空则将该截图上传并替换path
if (!StringUtil.isNullOrEmpty(item.getMaskUrl())){
// 由于前端不好处理这块所以当mask没有做任何修改的时候仍然会传原始mask的minio地址
if (!item.getMaskUrl().startsWith("data:image") && item.getMaskUrl().startsWith("https://")){
// 当没有修改mask时还是用之前的mask地址
item.setMaskUrl(item.getMaskMinioUrl());
}else {
// 将原图地址作为修改后的图片地址,放在不同的桶
String path = minioUtil.base64UploadToPath(item.getMaskUrl(), clothingBucket, "labelingMask/" + UUID.randomUUID());
if (StringUtil.isNullOrEmpty(path)){
log.error("标注的mask图片上传失败");
throw new BusinessException("image.modify.failed");
}
item.setMaskUrl(path);
}
}
});
}
@Override
public Map<String, String> setTypeAndUndividedLayer(JSONArray layers){
HashMap<String, String> categoryAndLayer = new HashMap<>();
@@ -875,4 +908,229 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
return 0L;
}
}
// todo 1、新增一个字段 用于记录历史like的design中 没有新的mask的design
// 2、获取design detail时当其design_item_id和design_python_outfit_id在like中时重新调用design并更新标志字段
@Resource
private UserLikeMapper userLikeMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void convertHistoryMaskWithoutGradient(){
// 查询用户like过的design 且没有使用渐变色的 design_item_id和design_python_outfit_id
List<Map<String, Long>> historyLikeWithoutGradient = userLikeMapper.getHistoryLikeWithoutGradient();
log.info("historyLikeWithoutGradient total count : {}", historyLikeWithoutGradient.size());
// 遍历list
// 先试一下刷新10条需要花费的时间
/*Map<String, Long> userLikeMap = historyLikeWithoutGradient.get(0);
log.info("test 替换mask" + userLikeMap.toString());
// 查每个design_item_id和design_python_outfit_id的detail
DesignItemDetailVO detail = designService.detail(userLikeMap.get("design_outfit_id"), userLikeMap.get("design_item_id"));
Long accountId = userLikeMap.get("account_id");
// 组装参数
DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO = convertToDesignSingleIncludeLayersDTO(detail, accountId);
if (Objects.isNull(designSingleIncludeLayersDTO)){
throw new BusinessException("cannot find model");
}
// 调用design single
designSingleIncludeLayers(designSingleIncludeLayersDTO, accountId);
// 标志字段置为1
UserLike userLike = new UserLike();
userLike.setId(userLikeMap.get("id"));
userLike.setConverted(1);
userLikeMapper.updateById(userLike);*/
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++){
try {
Map<String, Long> userLikeMap = historyLikeWithoutGradient.get(0);
log.info("test 替换mask" + userLikeMap.toString());
Long designItemId = userLikeMap.get("design_item_id");
Long designOutfitId = userLikeMap.get("design_outfit_id");
// 查每个design_item_id和design_python_outfit_id的detail
DesignItemDetailVO detail = designService.detail(designOutfitId, designItemId);
Long accountId = userLikeMap.get("account_id");
// 组装参数
DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO = convertToDesignSingleIncludeLayersDTO(detail, accountId);
if (Objects.isNull(designSingleIncludeLayersDTO)){
throw new BusinessException("cannot find model. designItemId: " + designItemId + "designOutfitId : " + designOutfitId );
}
// 调用design single
designSingleIncludeLayers(designSingleIncludeLayersDTO, accountId);
// 标志字段置为1
UserLike userLike = new UserLike();
userLike.setId(userLikeMap.get("id"));
userLike.setConverted(1);
userLikeMapper.updateById(userLike);
}catch (BusinessException e){
log.error("mask convert error : {}", e.getMessage());
}
}
long end = System.currentTimeMillis();
log.info("convert mask ,10条 执行时长:" + (end - start) + "毫秒");
}
public DesignSingleIncludeLayersDTO convertToDesignSingleIncludeLayersDTO(DesignItemDetailVO designItemDetailVO, Long userId){
DesignSingleIncludeLayersDTO resp = new DesignSingleIncludeLayersDTO();
Long designItemId = designItemDetailVO.getDesignItemId();
String gender ;
String modelPath = designItemDetailVO.getOthers().get(0).getMinIOPath();
List<SysFileVO> modelSysFile = sysFileService.getByUrlList(Collections.singletonList(modelPath));
if (modelSysFile.isEmpty()){
log.error("cannot find model 【{}】 in t_sys_file ", modelPath);
return null;
}else {
gender = modelSysFile.get(0).getLevel2Type();
}
resp.setDesignItemId(designItemId);
resp.setGender(gender);
resp.setIsPreview(Boolean.FALSE);
resp.setProcessId(String.valueOf(userId));
resp.setTimeZone("Etc/GMT-8");
List<DesignSingleItemDTO> designSingleItemDTOS = new ArrayList<>();
resp.setDesignSingleItemDTOList(designSingleItemDTOS);
designItemDetailVO.getClothes().forEach(cloth -> {
DesignSingleItemDTO itemDTO = CopyUtil.copyObject(cloth, DesignSingleItemDTO.class);
itemDTO.setChanged(Boolean.FALSE);
itemDTO.setDesignType("Library");
itemDTO.setPath(cloth.getMinIOPath());
PantoneVO color = cloth.getColor();
String colorString = color.getR() + " " + color.getG() + " " + color.getB();
itemDTO.setColor(colorString);
if (cloth.getLayersObject().isEmpty()){
itemDTO.setOffset(Arrays.asList(0L,0L));
itemDTO.setScale(new Float[]{1.0f,1.0f});
}else {
DesignPythonOutfitVO designPythonOutfitVO = cloth.getLayersObject().get(0);
itemDTO.setOffset(designPythonOutfitVO.getOffset());
itemDTO.setScale(designPythonOutfitVO.getScale());
}
// 统一设置mask为null,不用旧版mask
itemDTO.setMaskMinioUrl(null);
designSingleItemDTOS.add(itemDTO);
});
return resp;
}
// temp 用于处理历史like的design没有新的mask的问题
public void designSingleIncludeLayers(DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO, Long userId) {
// 记录入参 base64数据太长所以这里去掉
DesignSingleIncludeLayersDTO clone = SerializationUtils.clone(designSingleIncludeLayersDTO);
clone.getDesignSingleItemDTOList().forEach( i -> {
// 渐变色
if (!Objects.isNull(i.getGradient()) && !StringUtil.isNullOrEmpty(i.getGradient().getColorImg())){
log.info("set gradient colorImage为空便于日志打印");
i.getGradient().setColorImg(null);
}
// 画笔修改过的sketch
if (!StringUtil.isNullOrEmpty(i.getSketchString())){
log.info("set sketchString为空便于日志打印");
i.setSketchString(null);
}
// 标注过的mask
if (!StringUtil.isNullOrEmpty(i.getMaskUrl())){
log.info("set labelingMask为空便于日志打印");
i.setMaskUrl(null);
}else {
// todo 允许为空吗?
// throw new BusinessException("labeling mask cannot be empty");
}
});
log.info("designSingle request入参 ==> " + JSONObject.toJSONString(clone));
// Long userId = UserContext.getUserHolder().getId();
DesignItem designItem = selectById(designSingleIncludeLayersDTO.getDesignItemId());
if (Objects.isNull(designItem)) {
throw new BusinessException("designItem.not.found");
}
Design design = designService.getById(designItem.getDesignId());
if (Objects.isNull(design)) {
throw new BusinessException("design.not.found");
}
DesignLibraryModelPointVO designLibraryModelPointVO = null;
// 设置模特
if (Objects.nonNull(design.getTemplateId())) {
String modelUrl;
Integer high;
Integer width;
if (design.getModelType().equals(ModelType.SYSTEM.getValue())) {
SysFileVO sysFile = sysFileService.getById(design.getTemplateId());
if (Objects.isNull(sysFile)) {
throw new BusinessException("model.not.found");
}
modelUrl = sysFile.getUrl();
high = 700;
width = 320;
} else if (design.getModelType().equals(ModelType.LIBRARY.getValue())){
Library libFile = libraryService.getById(design.getTemplateId());
if (Objects.isNull(libFile)) {
throw new BusinessException("model.not.found");
}
modelUrl = libFile.getUrl();
high = libFile.getHigh();
width = libFile.getWidth();
}else {
throw new BusinessException("unknown.modelType");
}
LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(design.getTemplateId(), design.getModelType());
if (Objects.isNull(modelPoint)) {
throw new BusinessException("modelPoint.not.found");
}
designLibraryModelPointVO = collectionElementService.calculateTemplatePoint(modelPoint, high, width, modelUrl);
}
// 画笔修改的sketch截图 上传后替换path
// 由于用户在系统或自己上传sketch的基础上修改过的衣服再次修改后第一次修改的衣服不会回到某个池子被再次利用
// 所以这里选择使用system或collection相同的地址只是放在不同的桶这样能保证图片服务器上,类似的sketch不会存在很多
sketchBase64ToPath(designSingleIncludeLayersDTO);
// todo 将标注后的mask上传到minio,并将minio地址传给python端
// maskBase64ToPath(designSingleIncludeLayersDTO);
// 组装入参
DesignPythonObjects objects = pythonService.covertDesignSingleParam(
designSingleIncludeLayersDTO, design.getSingleOverall(), design.getSwitchCategory(), designLibraryModelPointVO);
// design
JSONObject jsonObject = pythonService.designNew(objects);
// preview -> 不存数据库 submit -> 存数据库
List<TDesignPythonOutfitDetail> tDesignPythonOutfitDetails;
JSONObject data = jsonObject.getJSONObject("data");
if (data == null) {
throw new BusinessException("python response data is null");
}
JSONObject outfit = data.getJSONObject("0");
JSONArray layers = outfit.getJSONArray("layers");
Map<String, String> categoryAndUndividedLayer = setTypeAndUndividedLayer(layers);
// 直接更新及保存图层信息全部走submit 不走preview
saveDesignSingleItemDetailAndLayers(objects, design.getId(), designSingleIncludeLayersDTO.getDesignItemId()
, userId, outfit, designSingleIncludeLayersDTO.getTimeZone()
, designSingleIncludeLayersDTO.getDesignSingleItemDTOList()
, categoryAndUndividedLayer);
// 如果当前item被like过需要更新t_user_like表和t_user_like_group表
// - 这里因为处理的都是like过的所以都需要更新
updateUserLikeDate(designSingleIncludeLayersDTO.getDesignItemId(),designSingleIncludeLayersDTO.getTimeZone());
// 数据替换完成即可,不需要返回数据
}
}

View File

@@ -16,7 +16,10 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 服务实现类
@@ -88,4 +91,21 @@ public class UserLikeServiceImpl extends ServiceImpl<UserLikeMapper, UserLike> i
return userLikeMapper.selectList(qw);
}
@Override
public List<Map<String, Long>> getHistoryLikeWithGradient(){
List<Map<String, Long>> historyLikeWithGradient = baseMapper.getHistoryLikeWithGradient();
return historyLikeWithGradient.stream()
.map(map -> {
Map<String, Long> newMap = new HashMap<>();
if (map.containsKey("design_item_id")) {
newMap.put("designItemId", map.get("design_item_id"));
}
if (map.containsKey("design_outfit_id")) {
newMap.put("designPythonOutfitId", map.get("design_outfit_id"));
}
return newMap;
})
.collect(Collectors.toList());
}
}