@@ -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 ( ) ) ;
// 数据替换完成即可,不需要返回数据
}
}