mask更新 从sketch分割

This commit is contained in:
2024-09-19 09:50:56 +08:00
parent e2f8fb082c
commit 56679808e9
6 changed files with 236 additions and 13 deletions

View File

@@ -61,11 +61,19 @@ public interface DesignItemService extends IService<DesignItem> {
Long getCountByUserAndTime(String startTime, String endTime, List<Long> accountIds);
// todo delete
void classificationByGradientColor();
// todo delete
List<List<Long>> getHistoryLikeWithGradient();
void convertHistoryMaskWithoutGradient();
void updateMaskUrl();
// todo delete
void deleteNotFoundModelDesign();
// todo delete
void designSingleWithGradient(DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO);
}

View File

@@ -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.deleteByDesignPythonOutfitIdPhysical(designPythonOutfitId);
designPythonOutfitDetailService.deleteByDesignPythonOutfitIdLogical(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);
}