@@ -23,6 +23,8 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject ;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper ;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl ;
import com.fasterxml.jackson.databind.ObjectMapper ;
import com.fasterxml.jackson.databind.SerializationFeature ;
import com.google.common.collect.Lists ;
import com.mysql.cj.util.StringUtils ;
import io.netty.util.internal.StringUtil ;
@@ -34,12 +36,14 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional ;
import javax.annotation.Resource ;
import java.io.File ;
import java.io.IOException ;
import java.time.LocalDate ;
import java.time.LocalDateTime ;
import java.time.ZoneId ;
import java.time.format.DateTimeFormatter ;
import java.util.* ;
import java.util.concurrent.atomic.AtomicInteger ;
import java.util.stream.Collectors ;
/**
@@ -924,6 +928,7 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
}
}
// todo delete
// 将历史like的design, 按有无渐变色将design_item_id、design_python_outfit_id分为两个数组
public void classificationByGradientColor ( ) {
List < List < Long > > noGradientList = new ArrayList < > ( ) ;
@@ -980,8 +985,10 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
log . info ( " 按是否使用了渐变色对历史like进行分类 执行时长:{}毫秒 " , end - start ) ;
// 3、将分类好的数据存入redis中
redisUtil. addToStringList( RedisUtil. NO_GRADIENT, noGradientList) ;
redisUtil. addToStringList( RedisUtil. WITH_GRADIENT, withGradientList) ;
// redisUtil. addToStringList( RedisUtil. NO_GRADIENT, noGradientList) ;
// redisUtil. addToStringList( RedisUtil. WITH_GRADIENT, withGradientList) ;
redisUtil . addToStringList ( RedisUtil . NO_GRADIENT_MASK , noGradientList ) ;
redisUtil . addToStringList ( RedisUtil . WITH_GRADIENT_MASK , withGradientList ) ;
log . info ( " 从t_user_like表, 通过渐变色分类, 完成, 其中总like量为: {}, 没有使用渐变色的like量为: {}, 使用了渐变色的like量为: {} " , userLikes . size ( ) , noGradientList . size ( ) , withGradientList . size ( ) ) ;
log . info ( " 使用了渐变色的like: {} " , withGradientList ) ;
@@ -990,17 +997,93 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
}
// todo delete
public List < List < Long > > getHistoryLikeWithGradient ( ) {
return redisUtil . getFromStringList ( RedisUtil . WITH_GRADIENT ) ;
}
// todo 1、新增一个字段 用于记录历史like的design中 没有新的mask的design
// 2、获取design detail时, 当其design_item_id和design_python_outfit_id在like中时, 重新调用design, 并更新标志字段
@Resource
private UserLikeMapper userLikeMapper ;
@Override
public void convertHistoryMaskWithoutGradient ( ) {
// 1、获取全部需要转换的designOutfitId
// 1、获取t_user_like表中design_item_id不为-1的所有design_item_id, design_outfit_id
QueryWrapper < UserLike > queryWrapper = new QueryWrapper < > ( ) ;
queryWrapper . ne ( " design_item_id " , - 1 )
. ne ( " converted " , 1 )
. groupBy ( Arrays . asList ( " design_outfit_id " , " design_item_id " ) ) . select ( " design_item_id " , " design_outfit_id " ) ;
List < UserLike > userLikes = userLikeMapper . selectList ( queryWrapper ) ;
// List<Map<String, Object>> userLikes = userLikeMapper.selectMaps(queryWrapper);
log . info ( " userLike 总数 : {} " , userLikes . size ( ) ) ;
// 用于存储结果
List < String [ ] > pairs = new ArrayList < > ( ) ;
AtomicInteger count = new AtomicInteger ( ) ;
// 2、查询指定designOutfitId对应的mask
userLikes . forEach ( item - > {
// 存储数据,按前缀分组
Map < Integer , Map < String , String > > groupedData = new HashMap < > ( ) ;
Long designItemId = item . getDesignItemId ( ) ;
Long designOutfitId = item . getDesignOutfitId ( ) ;
// Long designItemId = (long)item.get("design_item_id");
// Long designOutfitId = (long)item.get("design_outfit_id");
List < TDesignPythonOutfitDetail > designPythonOutfitDetails = designPythonOutfitDetailService . getDetailByDesignPythonOutfitId ( designOutfitId ) ;
List < DesignItemDetail > designItemDetails = designItemDetailService . selectByDesignItemId ( designItemId ) ;
designItemDetailService . setDesignItemDetailPriority ( designItemDetails ) ;
Map < Integer , String > designItemPath = designItemDetails . stream ( )
. collect ( Collectors . toMap (
DesignItemDetail : : getPriority , // key: category 转为小写
DesignItemDetail : : getPath // value: path 字段
) ) ;
// 遍历列表,拿出每个种类的前后片
designPythonOutfitDetails . forEach ( designPythonOutfitDetail - > {
String imageCategory = designPythonOutfitDetail . getImageCategory ( ) ;
String maskPath = designPythonOutfitDetail . getMaskUrl ( ) ;
Integer priority = Math . abs ( designPythonOutfitDetail . getPriority ( ) ) ;
// 提取前缀和后缀
if ( imageCategory . contains ( " _ " ) ) {
String [ ] parts = imageCategory . split ( " _ " ) ;
// String prefix = parts[0];
String suffix = parts [ 1 ] ;
// 初始化前缀组
groupedData . putIfAbsent ( priority , new HashMap < > ( ) ) ;
groupedData . get ( priority ) . put ( suffix , maskPath ) ;
}
} ) ;
// 查找成对的front和back
for ( Map . Entry < Integer , Map < String , String > > entry : groupedData . entrySet ( ) ) {
Map < String , String > suffixes = entry . getValue ( ) ;
if ( suffixes . containsKey ( " front " ) & & suffixes . containsKey ( " back " ) ) {
String frontMask = suffixes . get ( " front " ) ;
String backMask = suffixes . get ( " back " ) ;
pairs . add ( new String [ ] { designItemPath . get ( entry . getKey ( ) ) , frontMask , backMask , frontMask } ) ;
}
}
log . info ( " 总数 count + current : {} + {} = {} " , count , groupedData . size ( ) , count . get ( ) + groupedData . size ( ) ) ;
count . addAndGet ( groupedData . size ( ) ) ;
} ) ;
// 将结果写入JSON文件
ObjectMapper objectMapper = new ObjectMapper ( ) ;
objectMapper . enable ( SerializationFeature . INDENT_OUTPUT ) ; // 格式化JSON输出
try {
// 写入JSON文件
objectMapper . writeValue ( new File ( " mask_pairs.json " ) , pairs ) ;
log . info ( " 待合成mask的数量: {} " , pairs . size ( ) ) ;
System . out . println ( " 数据已成功写入mask_pairs.json文件 " ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
/*
// 查询用户like过的design 且没有使用渐变色的 design_item_id和design_python_outfit_id
List<List<Long>> historyLikeWithoutGradient = redisUtil.getFromStringList(RedisUtil.NO_GRADIENT);
@@ -1009,6 +1092,7 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
long start = System.currentTimeMillis();
int count = 0;
try {
List<List<Long>> errorConvertedList = new ArrayList<>();
for (int i = 45; i < 50; i++){
List<Long> userLikeMap = historyLikeWithoutGradient.get(i);
log.info("test 替换mask{}", userLikeMap.toString());
@@ -1025,6 +1109,7 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
UserLikeGroup userLikeGroup = userLikeGroupService.getById(userLikeList.get(0).getUserLikeGroupId());
if (userLikeGroup == null) {
log.error("在t_user_like_group表中找不到id为: {} 的记录", userLikeList.get(0).getUserLikeGroupId());
errorConvertedList.add(Arrays.asList(designItemId, designOutfitId));
continue;
}
@@ -1040,6 +1125,7 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO = convertToDesignSingleIncludeLayersDTO(detail, accountId);
if (Objects.isNull(designSingleIncludeLayersDTO)){
log.error("cannot find model. designItemId: {}, designOutfitId : {}", designItemId, designOutfitId);
errorConvertedList.add(Arrays.asList(designItemId, designOutfitId));
continue;
}
long endConvert = System.currentTimeMillis();
@@ -1062,24 +1148,100 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
log.info("designItemId: {}, designOutfitId : {} mask替换完成", designItemId, designOutfitId);
count++;
}
} catch ( BusinessException e ) {
List<List<Long>> errorConverted = redisUtil.getFromStringList(RedisUtil.ERROR_CONVERTED);
errorConverted.addAll(errorConvertedList);
redisUtil.addToStringList(RedisUtil.ERROR_CONVERTED, errorConverted);
}catch (Exception e){
log.error("mask convert error : {}", e.getMessage());
e.printStackTrace();
}
long end = System.currentTimeMillis();
log. info ( " convert mask 成功 {}条 执行时长:{}毫秒" , count , end - start ) ;
log.info(" convert mask 成功 {}条 执行时长:{}毫秒", count, end - start);*/
}
@Transactional ( rollbackFor = Exception . class )
public void updateMaskUrl ( ) {
QueryWrapper < UserLike > queryWrapper = new QueryWrapper < > ( ) ;
queryWrapper . ne ( " design_item_id " , - 1 )
. ne ( " converted " , 1 )
. groupBy ( Arrays . asList ( " design_outfit_id " , " design_item_id " ) ) . select ( " design_item_id " , " design_outfit_id " ) ;
List < UserLike > userLikes = userLikeMapper . selectList ( queryWrapper ) ;
log . info ( " userLike 总数 : {} " , userLikes . size ( ) ) ;
ArrayList < TDesignPythonOutfitDetail > tDesignPythonOutfitDetails = new ArrayList < > ( ) ;
// 2、查询指定designOutfitId对应的mask
userLikes . forEach ( item - > {
Long designOutfitId = item . getDesignOutfitId ( ) ;
// 存储以front结尾的mask路径
Map < String , String > frontMaskMap = new HashMap < > ( ) ;
HashMap < String , Long > backMaskIdMap = new HashMap < > ( ) ;
List < TDesignPythonOutfitDetail > designPythonOutfitDetails = designPythonOutfitDetailService . getDetailByDesignPythonOutfitId ( designOutfitId ) ;
// 遍历列表,拿出每个种类的前后片
designPythonOutfitDetails . forEach ( designPythonOutfitDetail - > {
String imageCategory = designPythonOutfitDetail . getImageCategory ( ) ;
String maskUrl = designPythonOutfitDetail . getMaskUrl ( ) ;
// 检查是否以'front'结尾
if ( imageCategory . endsWith ( " front " ) ) {
String maskPath = maskUrl . replace ( " aida-clothing " , " test " ) ;
String prefix = imageCategory . substring ( 0 , imageCategory . lastIndexOf ( " _ " ) ) ;
if ( backMaskIdMap . containsKey ( prefix ) ) {
TDesignPythonOutfitDetail tDesignPythonOutfitDetail = new TDesignPythonOutfitDetail ( ) ;
tDesignPythonOutfitDetail . setMaskUrl ( maskPath ) ;
tDesignPythonOutfitDetail . setUpdateDate ( LocalDateTime . now ( ) ) ;
tDesignPythonOutfitDetail . setId ( backMaskIdMap . get ( prefix ) ) ;
tDesignPythonOutfitDetails . add ( tDesignPythonOutfitDetail ) ;
} else {
frontMaskMap . put ( prefix , maskPath ) ;
}
TDesignPythonOutfitDetail tDesignPythonOutfitDetail = new TDesignPythonOutfitDetail ( ) ;
tDesignPythonOutfitDetail . setMaskUrl ( maskPath ) ;
tDesignPythonOutfitDetail . setUpdateDate ( LocalDateTime . now ( ) ) ;
tDesignPythonOutfitDetail . setId ( designPythonOutfitDetail . getId ( ) ) ;
tDesignPythonOutfitDetails . add ( tDesignPythonOutfitDetail ) ;
}
if ( imageCategory . endsWith ( " back " ) ) {
String prefix = imageCategory . substring ( 0 , imageCategory . lastIndexOf ( " _ " ) ) ;
if ( frontMaskMap . containsKey ( prefix ) ) {
// 更新back的mask路径为front的mask路径
String frontMaskPath = frontMaskMap . get ( prefix ) ;
TDesignPythonOutfitDetail tDesignPythonOutfitDetail = new TDesignPythonOutfitDetail ( ) ;
tDesignPythonOutfitDetail . setMaskUrl ( frontMaskPath ) ;
tDesignPythonOutfitDetail . setUpdateDate ( LocalDateTime . now ( ) ) ;
tDesignPythonOutfitDetail . setId ( designPythonOutfitDetail . getId ( ) ) ;
tDesignPythonOutfitDetails . add ( tDesignPythonOutfitDetail ) ;
} else {
backMaskIdMap . put ( prefix , designPythonOutfitDetail . getId ( ) ) ;
}
}
} ) ;
} ) ;
log . info ( " 更新总数:{} " , tDesignPythonOutfitDetails . size ( ) ) ;
designPythonOutfitDetailService . updateBatchById ( tDesignPythonOutfitDetails ) ;
log . info ( " 更新完成 " ) ;
}
// todo delete
private List < UserLike > getUserLikeByDesignItemId ( Long designItemId , Long designOutfitId ) {
QueryWrapper < UserLike > queryWrapper = new QueryWrapper < > ( ) ;
queryWrapper . eq ( " design_item_id " , designItemId )
. eq ( " design_outfit_id " , designOutfitId ) ;
queryWrapper . eq ( " design_item_id " , designItemId ) ;
if ( ! Objects . isNull ( designOutfitId ) ) {
queryWrapper . eq ( " design_outfit_id " , designOutfitId ) ;
}
return userLikeMapper . selectList ( queryWrapper ) ;
}
// todo delete
public DesignSingleIncludeLayersDTO convertToDesignSingleIncludeLayersDTO ( DesignItemDetailVO designItemDetailVO , Long userId ) {
DesignSingleIncludeLayersDTO resp = new DesignSingleIncludeLayersDTO ( ) ;
@@ -1216,12 +1378,13 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
// 数据替换完成即可,不需要返回数据
}
// todo delete
private void saveDesignSingleItemDetailAndLayersCopy ( Long designId , Long designItemId , Long userId
, JSONObject outfit , List < DesignSingleItemDTO > designSingleItemDTOList ) {
// 6、删除designPythonOutfitDetail表中原始的图层信息( 物理删除)
Long designPythonOutfitId = designPythonOutfitService . getByDesignItemId ( designItemId ) . getId ( ) ;
designPythonOutfitDetailService . deleteByDesignPythonOutfitIdPhys ical ( designPythonOutfitId ) ;
designPythonOutfitDetailService . deleteByDesignPythonOutfitIdLog ical ( designPythonOutfitId ) ;
// 7、将新生成的图层信息存入designPythonOutfitDetail表
JSONArray layers = outfit . getJSONArray ( " layers " ) ;
@@ -1233,6 +1396,7 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
designPythonOutfitDetailService . saveBatch ( list ) ;
}
// todo delete
public void deleteNotFoundModelDesign ( ) {
// 查询在user_like的design_item_detail中使用了找不到的model的design_item_id,design_outfit_id有哪些
List < Map < String , Long > > historyLikeWithoutModel = userLikeMapper . getHistoryLikeWithoutModel ( ) ;
@@ -1258,7 +1422,38 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
redisUtil . addToStringList ( RedisUtil . NO_GRADIENT , noGradientList ) ;
}
public void designSingleWithGradient ( ) {
// todo delete
public void designSingleWithGradient ( DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO ) {
// 1、查询当前design对应mask是否完成了转换
Long designItemId = designSingleIncludeLayersDTO . getDesignItemId ( ) ;
List < UserLike > userLikeList = getUserLikeByDesignItemId ( designItemId , null ) ;
Long designOutfitId = userLikeList . get ( 0 ) . getDesignOutfitId ( ) ;
// 如果已经替换了新的mask则直接跳过
if ( userLikeList . get ( 0 ) . getConverted ( ) = = 1 ) {
log . info ( " designItemId: {}, designOutfitId : {} mask已替换 " , designItemId , designOutfitId ) ;
return ;
}
UserLikeGroup userLikeGroup = userLikeGroupService . getById ( userLikeList . get ( 0 ) . getUserLikeGroupId ( ) ) ;
if ( userLikeGroup = = null ) {
log . error ( " 在t_user_like_group表中找不到id为: {} 的记录 " , userLikeList . get ( 0 ) . getUserLikeGroupId ( ) ) ;
return ;
}
// 查询design_item_id和design_python_outfit_id对应的accountId
Long accountId = userLikeGroup . getAccountId ( ) ;
// 2、执行designSingle
designSingleIncludeLayers ( designSingleIncludeLayersDTO , accountId ) ;
// 5、完成转换的mask, 标志字段置为1
for ( UserLike item : userLikeList ) {
UserLike userLike = new UserLike ( ) ;
userLike . setId ( item . getId ( ) ) ;
userLike . setConverted ( 1 ) ;
userLikeMapper . updateById ( userLike ) ;
}
log . info ( " designItemId: {}, designOutfitId : {} mask替换完成 " , designItemId , designOutfitId ) ;
}