diff --git a/src/main/java/com/ai/da/common/utils/RedisUtil.java b/src/main/java/com/ai/da/common/utils/RedisUtil.java index fd6fb3e6..968bdab8 100644 --- a/src/main/java/com/ai/da/common/utils/RedisUtil.java +++ b/src/main/java/com/ai/da/common/utils/RedisUtil.java @@ -1,10 +1,13 @@ package com.ai.da.common.utils; +import com.ai.da.model.dto.ProgressDTO; import com.ai.da.python.vo.DesignPythonObject; +import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; @@ -14,6 +17,7 @@ import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.Duration; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -500,4 +504,23 @@ public class RedisUtil { redisTemplate.delete(keys); } } + + public void setTaskProgressDTO(String taskId, ProgressDTO dto) { + String key = "task:progress:" + taskId; + redisTemplate.opsForValue().set(key, JSON.toJSONString(dto), Duration.ofDays(1)); + } + + public ProgressDTO getTaskProgressDTO(String taskId) { + String key = "task:progress:" + taskId; + String json = redisTemplate.opsForValue().get(key); + if (StringUtils.isBlank(json)) { + return new ProgressDTO(0, 0, false); + } + try { + return JSON.parseObject(json, ProgressDTO.class); + } catch (Exception e) { + log.warn("任务进度解析失败 key={}, json={}", key, json); + return new ProgressDTO(0, 0, false); + } + } } diff --git a/src/main/java/com/ai/da/controller/SavedCollectionController.java b/src/main/java/com/ai/da/controller/SavedCollectionController.java index d507f849..f9f1c738 100644 --- a/src/main/java/com/ai/da/controller/SavedCollectionController.java +++ b/src/main/java/com/ai/da/controller/SavedCollectionController.java @@ -259,12 +259,24 @@ public class SavedCollectionController { return Response.success(userLikeGroupService.productImageInitialize(productImageInitializeDTO)); } + @ApiOperation(value = "getInitializeProgress") + @PostMapping("/getInitializeProgress") + public Response getInitializeProgress(@Valid @RequestBody ProductImageInitializeDTO productImageInitializeDTO) { + return Response.success(userLikeGroupService.getInitializeProgress(productImageInitializeDTO)); + } + @ApiOperation(value = "brandDNASaveOrUpdate") @PostMapping("/brandDNASaveOrUpdate") public Response brandDNASaveOrUpdate(@Valid @RequestBody BrandDNADTO brandDNADTO) { return Response.success(userLikeGroupService.brandDNASaveOrUpdate(brandDNADTO)); } + @ApiOperation(value = "brandDNADelete") + @PostMapping("/brandDNADelete") + public Response brandDNADelete(@Valid @RequestBody BrandDNADTO brandDNADTO) { + return Response.success(userLikeGroupService.brandDNADelete(brandDNADTO)); + } + @ApiOperation(value = "brandDNAPage") @PostMapping("/brandDNAPage") public Response> brandDNAPage(@Valid @RequestBody BrandDNAQueryDTO brandDNAQueryDTO) { diff --git a/src/main/java/com/ai/da/model/dto/ProgressDTO.java b/src/main/java/com/ai/da/model/dto/ProgressDTO.java new file mode 100644 index 00000000..c61731f9 --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/ProgressDTO.java @@ -0,0 +1,15 @@ +package com.ai.da.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ProgressDTO { + private int total; + private int current; + private boolean error; +} + diff --git a/src/main/java/com/ai/da/service/ProductImageService.java b/src/main/java/com/ai/da/service/ProductImageService.java new file mode 100644 index 00000000..4fc0024d --- /dev/null +++ b/src/main/java/com/ai/da/service/ProductImageService.java @@ -0,0 +1,8 @@ +package com.ai.da.service; + +import com.ai.da.model.dto.ProgressDTO; + +public interface ProductImageService { + void asyncInitialize(Long brandId); + double getInitializeProgress(Long brandId); +} diff --git a/src/main/java/com/ai/da/service/UserLikeGroupService.java b/src/main/java/com/ai/da/service/UserLikeGroupService.java index f96de208..68127f49 100644 --- a/src/main/java/com/ai/da/service/UserLikeGroupService.java +++ b/src/main/java/com/ai/da/service/UserLikeGroupService.java @@ -76,6 +76,8 @@ public interface UserLikeGroupService extends IService { Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO); + double getInitializeProgress(ProductImageInitializeDTO productImageInitializeDTO); + IPage getPage(ProjectQueryDTO projectQueryDTO); ModuleChooseVO getModuleContent(ProjectDTO projectDTO); @@ -105,4 +107,6 @@ public interface UserLikeGroupService extends IService { String downloadZip(Long threeDSimpleId, String sizeType, String size, HttpServletResponse response) throws MinioException, IOException; Boolean delete(Long projectId); + + Boolean brandDNADelete(BrandDNADTO brandDNADTO); } diff --git a/src/main/java/com/ai/da/service/impl/ProductImageServiceImpl.java b/src/main/java/com/ai/da/service/impl/ProductImageServiceImpl.java new file mode 100644 index 00000000..7d9cca08 --- /dev/null +++ b/src/main/java/com/ai/da/service/impl/ProductImageServiceImpl.java @@ -0,0 +1,151 @@ +package com.ai.da.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.ai.da.common.utils.RedisUtil; +import com.ai.da.mapper.primary.BrandRelLibraryMapper; +import com.ai.da.mapper.primary.LibraryMapper; +import com.ai.da.mapper.primary.ProductImageAttributeMapper; +import com.ai.da.mapper.primary.entity.BrandRelLibrary; +import com.ai.da.mapper.primary.entity.Library; +import com.ai.da.mapper.primary.entity.ProductImageAttribute; +import com.ai.da.mapper.secondary.entity.AttributeRecognitionJSON; +import com.ai.da.model.dto.ProgressDTO; +import com.ai.da.python.PythonService; +import com.ai.da.service.ProductImageService; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +public class ProductImageServiceImpl implements ProductImageService { + + @Autowired + private BrandRelLibraryMapper brandRelLibraryMapper; + + @Autowired + private LibraryMapper libraryMapper; + + @Autowired + private ProductImageAttributeMapper productImageAttributeMapper; + + @Autowired + private PythonService pythonService; + + @Resource + private RedisUtil redisUtil; + + @Async + @Override + public void asyncInitialize(Long brandId) { + String progressKey = String.valueOf(brandId); + ProgressDTO progressDTO = new ProgressDTO(0, 0, false); + redisUtil.setTaskProgressDTO(progressKey, progressDTO); + + try { + List brandRelLibraries = brandRelLibraryMapper.selectList( + new QueryWrapper().lambda().eq(BrandRelLibrary::getBrandId, brandId) + ); + Set libraryIds = brandRelLibraries.stream().map(BrandRelLibrary::getLibraryId).collect(Collectors.toSet()); + + progressDTO.setTotal(libraryIds.size()); + + int current = 0; + for (Long libraryId : libraryIds) { + Library library = libraryMapper.selectById(libraryId); + String url = library.getUrl(); + + JSONObject result = pythonService.segProduct(url); + JSONArray data = result.getJSONArray("data"); + for (int i = 0; i < data.size(); i++) { + JSONObject obj = data.getJSONObject(i); + JSONObject attribute = obj.getJSONObject("attribute"); + AttributeRecognitionJSON attrJSON = attribute.toJavaObject(AttributeRecognitionJSON.class); + ProductImageAttribute attr = toAttrDict(attrJSON); + attr.setLibraryId(libraryId); + productImageAttributeMapper.insert(attr); + } + + // 更新当前进度 + current++; + progressDTO.setCurrent(current); + redisUtil.setTaskProgressDTO(progressKey, progressDTO); + } + + } catch (Exception e) { +// log.error("初始化失败", e); + redisUtil.setTaskProgressDTO(progressKey, new ProgressDTO(0, 0, true)); + } + } + + + @Override + public double getInitializeProgress(Long brandId) { + ProgressDTO dto = redisUtil.getTaskProgressDTO(String.valueOf(brandId)); + if (dto.getTotal() == 0 || dto.isError()) return 0.0; + return (dto.getCurrent() * 1.0 / dto.getTotal()); + } + + private ProductImageAttribute toAttrDict(AttributeRecognitionJSON attrDictJSON) { + ProductImageAttribute attributeRetrieval = new ProductImageAttribute(); + + // 处理 imgName + if (CollectionUtil.isNotEmpty(attrDictJSON.getImgName()) && attrDictJSON.getImgName().get(0) != null) { + attributeRetrieval.setImgName(attrDictJSON.getImgName().get(0)); + } + // 处理 length + if (CollectionUtil.isNotEmpty(attrDictJSON.getLength()) && attrDictJSON.getLength().get(0) != null) { + attributeRetrieval.setLength(attrDictJSON.getLength().get(0)); + } + // 处理 sleeveLength + if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveLength()) && attrDictJSON.getSleeveLength().get(0) != null) { + attributeRetrieval.setSleeveLength(attrDictJSON.getSleeveLength().get(0)); + } + // 处理 sleeveShape + if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveShape()) && attrDictJSON.getSleeveShape().get(0) != null) { + attributeRetrieval.setSleeveShape(attrDictJSON.getSleeveShape().get(0)); + } + // 处理 sleeveShoulder + if (CollectionUtil.isNotEmpty(attrDictJSON.getSleeveShoulder()) && attrDictJSON.getSleeveShoulder().get(0) != null) { + attributeRetrieval.setSleeveShoulder(attrDictJSON.getSleeveShoulder().get(0)); + } + // 处理 neckline + if (CollectionUtil.isNotEmpty(attrDictJSON.getNeckline()) && attrDictJSON.getNeckline().get(0) != null) { + attributeRetrieval.setNeckline(attrDictJSON.getNeckline().get(0)); + } + // 处理 collar + if (CollectionUtil.isNotEmpty(attrDictJSON.getCollar()) && attrDictJSON.getCollar().get(0) != null) { + attributeRetrieval.setCollar(attrDictJSON.getCollar().get(0)); + } + // 处理 design + if (CollectionUtil.isNotEmpty(attrDictJSON.getDesign()) && attrDictJSON.getDesign().get(0) != null) { + attributeRetrieval.setDesign(attrDictJSON.getDesign().get(0)); + } + // 处理 silhouette + if (CollectionUtil.isNotEmpty(attrDictJSON.getSilhouette()) && attrDictJSON.getSilhouette().get(0) != null) { + attributeRetrieval.setSilhouette(attrDictJSON.getSilhouette().get(0)); + } + // 处理 type + if (CollectionUtil.isNotEmpty(attrDictJSON.getType()) && attrDictJSON.getType().get(0) != null) { + attributeRetrieval.setType(attrDictJSON.getType().get(0)); + } + // 处理 openingType + if (CollectionUtil.isNotEmpty(attrDictJSON.getOpeningType()) && attrDictJSON.getOpeningType().get(0) != null) { + attributeRetrieval.setOpeningType(attrDictJSON.getOpeningType().get(0)); + } + // 处理 subtype + if (CollectionUtil.isNotEmpty(attrDictJSON.getSubtype()) && attrDictJSON.getSubtype().get(0) != null) { + attributeRetrieval.setSubtype(attrDictJSON.getSubtype().get(0)); + } + + return attributeRetrieval; + } +} + diff --git a/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java b/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java index d61325b8..19acb2ce 100644 --- a/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java @@ -129,6 +129,8 @@ public class UserLikeGroupServiceImpl extends ServiceImpl brandRelLibraryQueryWrapper = new QueryWrapper<>(); - brandRelLibraryQueryWrapper.lambda().eq(BrandRelLibrary::getBrandId, brandId); - List brandRelLibraries = brandRelLibraryMapper.selectList(brandRelLibraryQueryWrapper); - Set collect = brandRelLibraries.stream().map(BrandRelLibrary::getLibraryId).collect(Collectors.toSet()); + productImageService.asyncInitialize(productImageInitializeDTO.getBrandId()); + return true; + } - AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); - accountService.getById(authPrincipalVo.getId()); + @Override + public double getInitializeProgress(ProductImageInitializeDTO productImageInitializeDTO) { - for (Long libraryId : collect) { - Library library = libraryMapper.selectById(libraryId); - String url = library.getUrl(); - String gender = library.getLevel2Type(); - - // 提取sketch - JSONObject jsonObject = pythonService.segProduct(url); - JSONArray data = jsonObject.getJSONArray("data"); - for (int i = 0; i < data.size(); i++) { - JSONObject jsonObject1 = data.getJSONObject(i); - JSONObject attribute = jsonObject1.getJSONObject("attribute"); - AttributeRecognitionJSON attrDictJSON = attribute.toJavaObject(AttributeRecognitionJSON.class); - ProductImageAttribute productImageAttribute = toAttrDict(attrDictJSON); - productImageAttribute.setLibraryId(library.getId()); - productImageAttributeMapper.insert(productImageAttribute); - } - } - return null; + return productImageService.getInitializeProgress(productImageInitializeDTO.getBrandId()); } private ProductImageAttribute toAttrDict(AttributeRecognitionJSON attrDictJSON) { @@ -2184,4 +2167,10 @@ public class UserLikeGroupServiceImpl extends ServiceImpl