diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/GtAndFhbBizController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/GtAndFhbBizController.java index 4f51b32dd..5e631415b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/GtAndFhbBizController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/GtAndFhbBizController.java @@ -1,6 +1,8 @@ package com.ruoyi.web.controller.xkt.migartion; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.redis.RedisCache; @@ -8,21 +10,28 @@ import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.web.controller.xkt.migartion.vo.GtAndFHBCompareDownloadVO; +import com.ruoyi.web.controller.xkt.migartion.vo.GtAndFHBInitVO; import com.ruoyi.web.controller.xkt.migartion.vo.fhb.FhbProdVO; +import com.ruoyi.web.controller.xkt.migartion.vo.gt.GtCateVO; import com.ruoyi.web.controller.xkt.migartion.vo.gt.GtProdSkuVO; +import com.ruoyi.xkt.domain.*; +import com.ruoyi.xkt.enums.EProductStatus; +import com.ruoyi.xkt.enums.ListingType; +import com.ruoyi.xkt.mapper.*; import com.ruoyi.xkt.service.shipMaster.IShipMasterService; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.ObjectUtils; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; import java.net.URLEncoder; +import java.time.LocalDate; import java.util.*; import java.util.stream.Collectors; @@ -38,23 +47,47 @@ public class GtAndFhbBizController extends BaseController { final IShipMasterService shipMasterService; final RedisCache redisCache; + final StoreProductColorMapper prodColorMapper; + final StoreProductColorSizeMapper prodColorSizeMapper; + final StoreProductMapper storeProdMapper; + final StoreProductStockMapper prodStockMapper; + final StoreCustomerMapper storeCusMapper; + final StoreCustomerProductDiscountMapper storeCusProdDiscMapper; + final StoreColorMapper storeColorMapper; + final StoreMapper storeMapper; + final StoreProductServiceMapper prodSvcMapper; + final StoreProductCategoryAttributeMapper prodCateAttrMapper; // TODO 档口注册的时候,会创建现金客户,在插入客户时,需要注意 // TODO 档口注册的时候,会创建现金客户,在插入客户时,需要注意 // TODO 档口注册的时候,会创建现金客户,在插入客户时,需要注意 + // TODO 上传到ES之后还需要确认 + // TODO 上传到ES之后还需要确认 + + // TODO 上传到图搜服务器之后还要确认 + // TODO 上传到图搜服务器之后还要确认 + + + @PreAuthorize("@ss.hasAnyRoles('admin,general_admin')") + @PutMapping("/sync-pic/{storeId}") + public void syncToEsAndPicSearch(@PathVariable("storeId") Long storeId) { + // 同步主图 到 图搜 服务器 + + + } + + @PreAuthorize("@ss.hasAnyRoles('admin,general_admin')") @PutMapping("/compare/{userId}/{supplierId}") public void compare(HttpServletResponse response, @PathVariable("userId") Integer userId, @PathVariable("supplierId") Integer supplierId) throws UnsupportedEncodingException { Map> multiSaleSameGoMap = new HashMap<>(); Map> multiOffSaleSameGoMap = new HashMap<>(); - Map> multiSameFMap = new HashMap<>(); + Map> multiSameFhbMap = new HashMap<>(); List doubleRunSaleBasicList = ObjectUtils.defaultIfNull(redisCache .getCacheObject(CacheConstants.MIGRATION_GT_SALE_BASIC_KEY + userId), new ArrayList<>()); - Map articleNoColorMap = doubleRunSaleBasicList.stream() - .collect(Collectors.groupingBy( - GtProdSkuVO::getArticle_number, + Map articleNoColorMap = doubleRunSaleBasicList.stream().collect(Collectors.groupingBy(GtProdSkuVO::getArticle_number, Collectors.collectingAndThen(Collectors.mapping(GtProdSkuVO::getColor, Collectors.toList()), list -> "(" + list.stream().distinct().collect(Collectors.joining(",")) + ")"))); List doubleRunSaleArtNoList = doubleRunSaleBasicList.stream().map(GtProdSkuVO::getArticle_number) @@ -81,12 +114,10 @@ public class GtAndFhbBizController extends BaseController { multiOffSaleSameGoMap.put(cleanArtNo, existList); }); - // 查看ShipMaster 这边有多少相似的货号 + // 查看Fhb 这边有多少相似的货号 List shipMasterProdList = ObjectUtils.defaultIfNull(redisCache .getCacheObject(CacheConstants.MIGRATION_SUPPLIER_PROD_KEY + supplierId), new ArrayList<>()); - Map shipMasterArticleNoColorMap = shipMasterProdList.stream() - .collect(Collectors.groupingBy( - FhbProdVO.SMIVO::getArtNo, + Map shipMasterArticleNoColorMap = shipMasterProdList.stream().collect(Collectors.groupingBy(FhbProdVO.SMIVO::getArtNo, Collectors.collectingAndThen(Collectors.mapping(FhbProdVO.SMIVO::getColor, Collectors.toList()), list -> "(" + list.stream().distinct().collect(Collectors.joining(",")) + ")"))); List shipArtNoList = shipMasterProdList.stream().map(FhbProdVO.SMIVO::getArtNo) @@ -94,9 +125,9 @@ public class GtAndFhbBizController extends BaseController { shipArtNoList.forEach(artNo -> { // 只保留核心连续的数字,去除其他所有符号 String cleanArtNo = this.extractCoreArticleNumber(artNo); - List existList = multiSameFMap.containsKey(cleanArtNo) ? multiSameFMap.get(cleanArtNo) : new ArrayList<>(); + List existList = multiSameFhbMap.containsKey(cleanArtNo) ? multiSameFhbMap.get(cleanArtNo) : new ArrayList<>(); existList.add(artNo + shipMasterArticleNoColorMap.get(artNo)); - multiSameFMap.put(cleanArtNo, existList); + multiSameFhbMap.put(cleanArtNo, existList); }); // 清洗数据之后,GO平台和FHB平台 货号一致的,按照这种来展示: GT => [Z1110(黑色,黑色绒里,棕色,棕色绒里)] <= 清洗后的货号 => [Z1110(黑色,黑色绒里,棕色,棕色绒里)] <= FHB @@ -105,9 +136,9 @@ public class GtAndFhbBizController extends BaseController { // 清洗后,相同货号映射 List matchArtNoList = new ArrayList<>(); Set commonArtNos = new HashSet<>(multiSaleSameGoMap.keySet()); - commonArtNos.retainAll(multiSameFMap.keySet()); + commonArtNos.retainAll(multiSameFhbMap.keySet()); commonArtNos.forEach(artNo -> { - final String sameArtNo = "GT => " + multiSaleSameGoMap.get(artNo) + " <= " + artNo + " => " + multiSameFMap.get(artNo) + " <= FHB"; + final String sameArtNo = "GT => " + multiSaleSameGoMap.get(artNo) + " <= " + artNo + " => " + multiSameFhbMap.get(artNo) + " <= FHB"; matchArtNoList.add(sameArtNo); }); // 输出货号清洗后相同的货号 @@ -132,13 +163,13 @@ public class GtAndFhbBizController extends BaseController { System.err.println("============ ShipMaster 去掉公共的、下架的 独有的key ============"); // 获取ShipMaster独有的key 去掉公共的、去掉下架的商品 - Set onlyInFMap = new HashSet<>(multiSameFMap.keySet()); + Set onlyInFMap = new HashSet<>(multiSameFhbMap.keySet()); onlyInFMap.removeAll(commonArtNos); onlyInFMap.removeAll(multiOffSaleSameGoMap.keySet()); if (CollectionUtils.isNotEmpty(onlyInFMap)) { onlyInFMap.forEach(x -> { - matchArtNoList.addAll(multiSameFMap.get(x)); - System.out.println(multiSameFMap.get(x)); + matchArtNoList.addAll(multiSameFhbMap.get(x)); + System.out.println(multiSameFhbMap.get(x)); }); } @@ -153,39 +184,352 @@ public class GtAndFhbBizController extends BaseController { } + /** + * 步骤1: 准备数据,新建颜色; + * 步骤2: GT 和 FHB 货号对应关系,然后直接copy 对应的属性关系 + * // a. 商品与颜色对应关系 + * // b. 商品颜色尺码 + 价格 对应关系 + * // c. 库存初始化 + * 步骤3: 准备数据,新建客户 + * 步骤4: 客户与货号的优惠关系 + * 步骤5: 批量创建数据到ES服务器 + * + */ @PreAuthorize("@ss.hasAnyRoles('admin,general_admin')") - @PutMapping("/save/{userId}/{supplierId}") - public void autoSaveToDB(@PathVariable("userId") Integer userId, @PathVariable("supplierId") Integer supplierId) throws UnsupportedEncodingException { + @PutMapping("/save") + public void initToDB(@Validated @RequestBody GtAndFHBInitVO initVO) { + final Store store = Optional.ofNullable(this.storeMapper.selectOne(new LambdaQueryWrapper() + .eq(Store::getId, initVO.getStoreId()).eq(Store::getDelFlag, Constants.UNDELETED))) + .orElseThrow(() -> new ServiceException("档口不存在!", HttpStatus.ERROR)); // 步骤1: 准备数据,新建颜色 - - // 步骤2: 准备数据,新建客户 - - // 步骤3: GT 和 FHB 货号对应关系,然后直接copy 对应的属性关系 + Map storeColorMap = this.initStoreColorList(initVO.getStoreId(), initVO.getSupplierId()); + // 步骤2: GT 和 FHB 货号对应关系,然后直接copy 对应的属性关系 // a. 商品与颜色对应关系 - // b. 库存初始化 - // c. 商品颜色尺码对应关系 - // d. 同步到ES中 ?? 这步还不能做 因为没有 商品主图 - // e. + // b. 商品颜色尺码 + 价格 对应关系 + // c. 库存初始化 + this.initStoreProdList(initVO, storeColorMap); + + + + // 步骤3: 准备数据,新建客户 // 步骤4: 客户与货号的优惠关系 - // 步骤5: 货号的初始库存 + // 步骤x: 查看有哪些货号价格是有多个的,单独设置差异的价格 + // 步骤5: 批量创建数据到ES服务器 } + /** + * 初始化档口商品列表 + * @param storeColorMap 档口颜色map + */ + private void initStoreProdList(GtAndFHBInitVO initVO, Map storeColorMap) { + // 步骤2: GT 和 FHB 货号对应关系,然后直接copy 对应的属性关系 + // a. 商品与颜色对应关系 + // b. 商品颜色尺码 + 价格 对应关系 + // c. 库存初始化 + Map> multiSaleSameGoMap = new HashMap<>(); + Map> multiOffSaleSameGoMap = new HashMap<>(); + Map> multiSameFhbMap = new HashMap<>(); + List gtSaleBasicList = ObjectUtils.defaultIfNull(redisCache + .getCacheObject(CacheConstants.MIGRATION_GT_SALE_BASIC_KEY + initVO.getUserId()), new ArrayList<>()); + // 查看double_run 在售的商品 这边有多少相似的货号 + gtSaleBasicList.stream().map(GtProdSkuVO::getArticle_number).distinct().forEach(article_number -> { + // 只保留核心连续的数字,去除其他所有符号 + String cleanArtNo = this.extractCoreArticleNumber(article_number); + List existList = multiSaleSameGoMap.containsKey(cleanArtNo) ? multiSaleSameGoMap.get(cleanArtNo) : new ArrayList<>(); + existList.add(article_number); + multiSaleSameGoMap.put(cleanArtNo, existList); + }); + + // 查看double_run 下架的商品有多少相似的货号 + List gtOffSaleBasicList = ObjectUtils.defaultIfNull(redisCache + .getCacheObject(CacheConstants.MIGRATION_GT_OFF_SALE_BASIC_KEY + initVO.getUserId()), new ArrayList<>()); + gtOffSaleBasicList.stream().map(GtProdSkuVO::getArticle_number).distinct().forEach(article_number -> { + // 只保留核心连续的数字,去除其他所有符号 + String cleanArtNo = this.extractCoreArticleNumber(article_number); + List existList = multiOffSaleSameGoMap.containsKey(cleanArtNo) ? multiOffSaleSameGoMap.get(cleanArtNo) : new ArrayList<>(); + existList.add(article_number); + multiOffSaleSameGoMap.put(cleanArtNo, existList); + }); + + // 查看Fhb 这边有多少相似的货号 + List fhbProdList = ObjectUtils.defaultIfNull(redisCache + .getCacheObject(CacheConstants.MIGRATION_SUPPLIER_PROD_KEY + initVO.getSupplierId()), new ArrayList<>()); + // Fhb按照颜色分类 + Map> fhbProdGroupMap = fhbProdList.stream().collect(Collectors.groupingBy(FhbProdVO.SMIVO::getArtNo)); + fhbProdList.stream().map(FhbProdVO.SMIVO::getArtNo).distinct().forEach(artNo -> { + // 只保留核心连续的数字,去除其他所有符号 + String cleanArtNo = this.extractCoreArticleNumber(artNo); + List existList = multiSameFhbMap.containsKey(cleanArtNo) ? multiSameFhbMap.get(cleanArtNo) : new ArrayList<>(); + existList.add(artNo); + multiSameFhbMap.put(cleanArtNo, existList); + }); + + // 商品所有的分类 + List artNoCateList = redisCache.getCacheObject(CacheConstants.MIGRATION_GT_SALE_CATE_KEY + initVO.getUserId()); + if (CollectionUtils.isEmpty(artNoCateList)) { + throw new ServiceException("GT商品分类为空!", HttpStatus.ERROR); + } + Map artNoCateMap = artNoCateList.stream().collect(Collectors.toMap(GtCateVO::getArticle_number, x -> x)); + // gt按照货号分组 + Map> gtSaleGroupMap = gtSaleBasicList.stream().collect(Collectors.groupingBy(GtProdSkuVO::getArticle_number)); - /** - * 提取货号中的核心数字部分 - * 例如: z1104 -> 1104, z1087高 -> 1087, z1003-1 -> 1003, 922- -> 922, -8072 -> 8072 - * - * @param articleNumber 货号 - * @return 核心数字部分 - */ + System.err.println("============ 两边系统“一致”的货号 ============"); + // 清洗后,相同货号映射 + Set commonArtNos = new HashSet<>(multiSaleSameGoMap.keySet()); + commonArtNos.retainAll(multiSameFhbMap.keySet()); + // 待导入的商品 + List storeProdList = new ArrayList<>(); + // 当天 + final Date voucherDate = java.sql.Date.valueOf(LocalDate.now()); + // 所有商品的类目属性map key gt的product_id value StoreProductCategoryAttribute + Map prodAttrMap = new HashMap<>(); + commonArtNos.stream() + // 过滤掉需要特殊处理的货号 + .filter(artNo -> !initVO.getExcludeArtNoList().contains(artNo)) + .forEach(cleanArtNo -> { + // 获取GT匹配的商品中的第一个商品 + List gtMatchSkuList = this.getGtFirstSku(multiSaleSameGoMap, gtSaleGroupMap, cleanArtNo); + // 商品分类 + final GtCateVO gtCateVO = Optional.ofNullable(artNoCateMap.get(gtMatchSkuList.get(0).getArticle_number())) + .orElseThrow(() -> new ServiceException("没有GT商品分类!", HttpStatus.ERROR)); + // 初始化档口商品 + StoreProduct storeProd = new StoreProduct().setStoreId(initVO.getStoreId()).setProdCateId(gtCateVO.getBuju_cate_id()) + .setProdArtNum(cleanArtNo).setProdTitle(gtMatchSkuList.get(0).getCharacters()).setListingWay(ListingType.RIGHT_NOW.getValue()) + .setVoucherDate(voucherDate).setProdStatus(EProductStatus.ON_SALE.getValue()).setRecommendWeight(0L).setSaleWeight(0L).setPopularityWeight(0L); + // 提前设置档口商品的类目属性 + this.preMatchAttr(gtMatchSkuList.get(0).getProduct_id(), initVO.getUserId(), prodAttrMap); + storeProdList.add(storeProd); + }); + this.storeProdMapper.insert(storeProdList); + // 货号map + Map prodArtNumMap = storeProdList.stream().collect(Collectors.toMap(StoreProduct::getId, StoreProduct::getProdArtNum)); + + // 商品所有颜色 尺码 颜色库存初始化 + List prodColorList = new ArrayList<>(); + List prodColorSizeList = new ArrayList<>(); + List prodSvcList = new ArrayList<>(); + List prodAttrList = new ArrayList<>(); + storeProdList.forEach(storeProd -> { + // FHB匹配的货号 + List fhbMatchArtNoList = multiSameFhbMap.get(storeProd.getProdArtNum()); + // 获取GT匹配的商品sku列表 + List gtMatchSkuList = this.getGtFirstSku(multiSaleSameGoMap, gtSaleGroupMap, storeProd.getProdArtNum()); + // 当前货号在GT的所有尺码,作为标准尺码 + List gtStandardSizeList = gtMatchSkuList.stream().map(GtProdSkuVO::getSize).collect(Collectors.toList()); + // 先获取最低价格,然后给所有颜色和尺码添加初始值,之后再来单独改,这是最方便的方式了 + final BigDecimal minPrice = gtMatchSkuList.stream().map(GtProdSkuVO::getPrice).min(Comparator.comparing(x -> x)) + .orElseThrow(() -> new ServiceException("没有GT商品价格!", HttpStatus.ERROR)); + fhbMatchArtNoList.forEach(fhbArtNo -> { + List fhbMatchSkuList = fhbProdGroupMap.get(fhbArtNo); + for (int i = 0; i < fhbMatchSkuList.size(); i++) { + StoreColor storeColor = Optional.ofNullable(storeColorMap.get(fhbMatchSkuList.get(i).getColor())) + .orElseThrow(() -> new ServiceException("没有FHB商品颜色!" + fhbArtNo, HttpStatus.ERROR)); + // 该商品的颜色 + prodColorList.add(new StoreProductColor().setStoreId(storeProd.getStoreId()).setStoreProdId(storeProd.getId()) + .setColorName(storeColor.getColorName()).setStoreColorId(storeColor.getId()).setProdStatus(EProductStatus.ON_SALE.getValue())); + // 该颜色所有的尺码 + for (int j = 0; j < Constants.SIZE_LIST.size(); j++) { + // FHB系统条码前缀 + final String otherSnPrefix = fhbMatchSkuList.get(i).getSupplierId() + String.format("%05d", fhbMatchSkuList.get(i).getSupplierSkuId()); + prodColorSizeList.add(new StoreProductColorSize().setSize(Constants.SIZE_LIST.get(j)).setStoreColorId(storeColor.getId()) + .setStoreProdId(storeProd.getId()).setPrice(minPrice).setOtherSnPrefix(otherSnPrefix).setNextSn(0) + .setStandard(gtStandardSizeList.contains(Constants.SIZE_LIST.get(j)) ? 1 : 0)); + } + } + }); + + // 初始化商品服务承诺 + prodSvcList.add(new StoreProductService().setStoreProdId(storeProd.getId()).setCustomRefund("0") + .setThirtyDayRefund("0").setOneBatchSale("1").setRefundWithinThreeDay("0")); + + // 初始化商品的类目属性 + StoreProductCategoryAttribute cateAttr = Optional.ofNullable(prodAttrMap.get(gtMatchSkuList.get(0).getProduct_id())) + .orElseThrow(() -> new ServiceException("没有GT商品类目属性!" + storeProd.getProdArtNum(), HttpStatus.ERROR)); + prodAttrList.add(cateAttr); + + }); + // 插入商品颜色及颜色对应的尺码,档口服务承诺 + this.prodColorMapper.insert(prodColorList); + this.prodColorSizeMapper.insert(prodColorSizeList); + this.prodSvcMapper.insert(prodSvcList); + this.prodCateAttrMapper.insert(prodAttrList); + + // 还要更新步橘系统的条码前缀 + prodColorSizeList.forEach(x -> x.setSnPrefix(initVO.getStoreId() + String.format("%08d", x.getId()))); + this.prodColorSizeMapper.updateById(prodColorSizeList); + + // 商品颜色对应的库存初始化 + List prodStockList = prodColorList.stream().map(color -> new StoreProductStock().setStoreId(color.getStoreId()) + .setStoreProdId(color.getStoreProdId()).setProdArtNum(prodArtNumMap.get(color.getStoreProdId())) + .setStoreProdColorId(color.getId()).setStoreColorId(color.getStoreColorId()).setColorName(color.getColorName())) + .collect(Collectors.toList()); + this.prodStockMapper.insert(prodStockList); + } + + /** + * 提前匹配类目属性 + * @param product_id GT商品ID + * @param userId GT用户ID + * @param prodAttrMap 类目属性 + */ + private void preMatchAttr(Integer product_id, Integer userId, Map prodAttrMap) { + // 类目属性 + Map attrMap = redisCache.getCacheMap(CacheConstants.MIGRATION_GT_SALE_ATTR_KEY + userId + "_" + product_id); + if (MapUtils.isEmpty(attrMap)) { + return; + } + // 将attrMap 的 key 映射到系统中 + StoreProductCategoryAttribute prodAttr = new StoreProductCategoryAttribute(); + // 1. 帮面材质 + if (attrMap.containsKey(Constants.UPPER_MATERIAL_NAME)) { + prodAttr.setUpperMaterial(attrMap.get(Constants.UPPER_MATERIAL_NAME)); + } + // 2. 靴筒内里材质 + if (attrMap.containsKey(Constants.SHAFT_LINING_MATERIAL_NAME)) { + prodAttr.setShaftLiningMaterial(attrMap.get(Constants.SHAFT_LINING_MATERIAL_NAME)); + } + // 3. 靴筒面材质 + if (attrMap.containsKey(Constants.SHAFT_MATERIAL_NAME)) { + prodAttr.setShaftMaterial(attrMap.get(Constants.SHAFT_MATERIAL_NAME)); + } + // 4. 鞋面内里材质 + if (attrMap.containsKey(Constants.SHOE_UPPER_LINING_MATERIAL_NAME)) { + prodAttr.setShoeUpperLiningMaterial(attrMap.get(Constants.SHOE_UPPER_LINING_MATERIAL_NAME)); + } + // 5. 靴款品名 + if (attrMap.containsKey(Constants.SHOE_STYLE_NAME)) { + prodAttr.setShoeStyleName(attrMap.get(Constants.SHOE_STYLE_NAME)); + } + // 6. 筒高 + if (attrMap.containsKey(Constants.SHAFT_HEIGHT_NAME)) { + prodAttr.setShaftHeight(attrMap.get(Constants.SHAFT_HEIGHT_NAME)); + } + // 7. 鞋垫材质 + if (attrMap.containsKey(Constants.INSOLE_MATERIAL_NAME)) { + prodAttr.setInsoleMaterial(attrMap.get(Constants.INSOLE_MATERIAL_NAME)); + } + // 8. 上市季节年份 + if (attrMap.containsKey(Constants.RELEASE_YEAR_SEASON_NAME)) { + prodAttr.setReleaseYearSeason(attrMap.get(Constants.RELEASE_YEAR_SEASON_NAME)); + } + // 9. 后跟高 + if (attrMap.containsKey(Constants.HEEL_HEIGHT_NAME)) { + prodAttr.setHeelHeight(attrMap.get(Constants.HEEL_HEIGHT_NAME)); + } + // 10. 跟底款式 + if (attrMap.containsKey(Constants.HEEL_TYPE_NAME)) { + prodAttr.setHeelType(attrMap.get(Constants.HEEL_TYPE_NAME)); + } + // 11. 鞋头款式 + if (attrMap.containsKey(Constants.TOE_STYLE_NAME)) { + prodAttr.setToeStyle(attrMap.get(Constants.TOE_STYLE_NAME)); + } + // 12. 适合季节 + if (attrMap.containsKey(Constants.SUITABLE_SEASON_NAME)) { + prodAttr.setSuitableSeason(attrMap.get(Constants.SUITABLE_SEASON_NAME)); + } + // 13. 开口深度 + if (attrMap.containsKey(Constants.COLLAR_DEPTH_NAME)) { + prodAttr.setCollarDepth(attrMap.get(Constants.COLLAR_DEPTH_NAME)); + } + // 14. 鞋底材质 + if (attrMap.containsKey(Constants.OUTSOLE_MATERIAL_NAME)) { + prodAttr.setOutsoleMaterial(attrMap.get(Constants.OUTSOLE_MATERIAL_NAME)); + } + // 15. 风格 + if (attrMap.containsKey(Constants.STYLE_NAME)) { + prodAttr.setStyle(attrMap.get(Constants.STYLE_NAME)); + } + // 16. 款式 + if (attrMap.containsKey(Constants.DESIGN_NAME)) { + prodAttr.setDesign(attrMap.get(Constants.DESIGN_NAME)); + } + // 17. 皮质特征 + if (attrMap.containsKey(Constants.LEATHER_FEATURES_NAME)) { + prodAttr.setLeatherFeatures(attrMap.get(Constants.LEATHER_FEATURES_NAME)); + } + // 18. 制作工艺 + if (attrMap.containsKey(Constants.MANUFACTURING_PROCESS_NAME)) { + prodAttr.setManufacturingProcess(attrMap.get(Constants.MANUFACTURING_PROCESS_NAME)); + } + // 19. 图案 + if (attrMap.containsKey(Constants.PATTERN_NAME)) { + prodAttr.setPattern(attrMap.get(Constants.PATTERN_NAME)); + } + // 20. 闭合方式 + if (attrMap.containsKey(Constants.CLOSURE_TYPE_NAME)) { + prodAttr.setClosureType(attrMap.get(Constants.CLOSURE_TYPE_NAME)); + } + // 21. 适用场景 + if (attrMap.containsKey(Constants.OCCASION_NAME)) { + prodAttr.setOccasion(attrMap.get(Constants.OCCASION_NAME)); + } + // 22. 厚薄 + if (attrMap.containsKey(Constants.THICKNESS_NAME)) { + prodAttr.setThickness(attrMap.get(Constants.THICKNESS_NAME)); + } + // 23. 流行元素 + if (attrMap.containsKey(Constants.FASHION_ELEMENTS_NAME)) { + prodAttr.setFashionElements(attrMap.get(Constants.FASHION_ELEMENTS_NAME)); + } + // 24. 适用对象 + if (attrMap.containsKey(Constants.SUITABLE_PERSON_NAME)) { + prodAttr.setSuitablePerson(attrMap.get(Constants.SUITABLE_PERSON_NAME)); + } + prodAttrMap.put(product_id, prodAttr); + } + + /** + * 取GT匹配的多个货号中的第一个商品 + * @param multiSaleSameGoMap + * @param gtSaleGroupMap + * @param cleanArtNo + * @return + */ + private List getGtFirstSku(Map> multiSaleSameGoMap, Map> gtSaleGroupMap, String cleanArtNo) { + // GT匹配的货号 + List gtMatchArtNoList = multiSaleSameGoMap.get(cleanArtNo); + // 逻辑:如果FHB有多个货号,则都要加到系统中来,因为要扫描条码;如果GT有多个,则只取第一个,匹配相关的属性 + List gtMatchSkuList = gtSaleGroupMap.get(gtMatchArtNoList.get(0)); + return gtMatchSkuList; + } + + + /** + * 初始化档口颜色 + * + * @param storeId 档口ID + * @param supplierId 供应商ID + */ + private Map initStoreColorList(Long storeId, Integer supplierId) { + List gtColorList = this.redisCache.getCacheObject(CacheConstants.MIGRATION_SUPPLIER_PROD_COLOR_KEY + supplierId); + if (CollectionUtils.isEmpty(gtColorList)) { + throw new ServiceException("没有颜色数据!", HttpStatus.ERROR); + } + List storeColorList = new ArrayList<>(); + for (int i = 0; i < gtColorList.size(); i++) { + storeColorList.add(new StoreColor().setStoreId(storeId).setColorName(gtColorList.get(i)).setOrderNum(i + 1)); + } + this.storeColorMapper.insert(storeColorList); + return storeColorList.stream().collect(Collectors.toMap(StoreColor::getColorName, x -> x)); + } + + + /** + * 提取货号中的核心数字部分 + * 例如: z1104 -> 1104, z1087高 -> 1087, z1003-1 -> 1003, 922- -> 922, -8072 -> 8072 + * + * @param articleNumber 货号 + * @return 核心数字部分 + */ private String extractCoreArticleNumber(String articleNumber) { if (articleNumber == null || articleNumber.isEmpty()) { return ""; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/GtController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/GtController.java index 8f3cfccdc..22ee47e10 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/GtController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/GtController.java @@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; +import java.math.BigDecimal; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -53,7 +54,7 @@ public class GtController extends BaseController { List cacheList = ObjectUtils.defaultIfNull(redisCache .getCacheObject(CacheConstants.MIGRATION_GT_SALE_BASIC_KEY + userId), new ArrayList<>()); artNoList.forEach(artNoInfo -> { - artNoInfo.getSkus().forEach(x -> x.setColor(this.decodeUnicode(x.getColor())) + artNoInfo.getSkus().forEach(x -> x.setColor(this.decodeUnicode(x.getColor())).setCharacters(artNoInfo.getCharacters()) .setArticle_number(artNoInfo.getArticle_number()).setProduct_id(artNoInfo.getId())); cacheList.addAll(artNoInfo.getSkus()); }); @@ -152,6 +153,19 @@ public class GtController extends BaseController { System.err.println(k + ":" + v); }); + // cacheList 按照货号分组,获取所有价格,价格去重 + Map> artNoPriceMap = cacheList.stream().collect(Collectors.groupingBy( + GtProdSkuVO::getArticle_number, Collectors.mapping(GtProdSkuVO::getPrice, Collectors.toSet()))); + artNoPriceMap.forEach((k, v) -> { + System.out.println(k + ":" + v); + if (v.size() > 1) { + System.err.println(k + ":" + v); + } + }); + +// Map> artNoPriceMap = + + // TODO 如何对比?? return R.ok(); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/vo/GtAndFHBInitVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/vo/GtAndFHBInitVO.java new file mode 100644 index 000000000..0e3efc888 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/vo/GtAndFHBInitVO.java @@ -0,0 +1,28 @@ +package com.ruoyi.web.controller.xkt.migartion.vo; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel +@Data +@Accessors(chain = true) +public class GtAndFHBInitVO { + + private Integer userId; + private Integer supplierId; + private Long storeId; + // 大小码加价金额 0 or other + private BigDecimal addOverPrice; + // GT 和 发货宝 能匹配但因 两边颜色冲突,需要手动处理的货号 + private List excludeArtNoList; + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/vo/gt/GtProdSkuVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/vo/gt/GtProdSkuVO.java index 0350f617d..f1764076b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/vo/gt/GtProdSkuVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/migartion/vo/gt/GtProdSkuVO.java @@ -17,6 +17,7 @@ public class GtProdSkuVO { private String article_number; private String color; private Integer size; + private String characters; private BigDecimal weight; private BigDecimal price; diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 7f0a9f77d..0f9c26403 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -192,6 +192,11 @@ public class Constants public static final Integer SIZE_41 = 41; public static final Integer SIZE_42 = 42; public static final Integer SIZE_43 = 43; + + // 系统所有的尺码 + public static final List SIZE_LIST = new ArrayList<>(Arrays + .asList(SIZE_30, SIZE_31, SIZE_32, SIZE_33, SIZE_34, SIZE_35, SIZE_36, SIZE_37, SIZE_38, SIZE_39, SIZE_40, SIZE_41, SIZE_42, SIZE_43)); + /** * 平台内部账户ID */ @@ -318,63 +323,82 @@ public class Constants public static final BigDecimal ALI_SERVICE_FEE_RATE = BigDecimal.valueOf(0.006); public static final String UPPER_MATERIAL = "upperMaterial"; + public static final String UPPER_MATERIAL_NAME = "帮面材质"; public static final String SHAFT_LINING_MATERIAL = "shaftLiningMaterial"; + public static final String SHAFT_LINING_MATERIAL_NAME = "靴筒内里材质"; public static final String SHAFT_MATERIAL = "shaftMaterial"; + public static final String SHAFT_MATERIAL_NAME = "靴筒面材质"; public static final String SHOE_UPPER_LINING_MATERIAL = "shoeUpperLiningMaterial"; + public static final String SHOE_UPPER_LINING_MATERIAL_NAME = "鞋面内里材质"; public static final String SHOE_STYLE_NAME = "shoeStyleName"; + public static final String SHOE_STYLE_NAME_NAME = "靴款品名"; public static final String SHAFT_HEIGHT = "shaftHeight"; - - - + public static final String SHAFT_HEIGHT_NAME = "筒高"; public static final String INSOLE_MATERIAL = "insoleMaterial"; + public static final String INSOLE_MATERIAL_NAME = "鞋垫材质"; public static final String RELEASE_YEAR_SEASON = "releaseYearSeason"; + public static final String RELEASE_YEAR_SEASON_NAME = "上市季节年份"; public static final String HEEL_HEIGHT = "heelHeight"; + public static final String HEEL_HEIGHT_NAME = "后跟高"; public static final String HEEL_TYPE = "heelType"; + public static final String HEEL_TYPE_NAME = "跟底款式"; public static final String TOE_STYLE = "toeStyle"; + public static final String TOE_STYLE_NAME = "鞋头款式"; public static final String SUITABLE_SEASON = "suitableSeason"; + public static final String SUITABLE_SEASON_NAME = "适合季节"; public static final String COLLAR_DEPTH = "collarDepth"; + public static final String COLLAR_DEPTH_NAME = "开口深度"; public static final String OUTSOLE_MATERIAL = "outsoleMaterial"; + public static final String OUTSOLE_MATERIAL_NAME = "鞋底材质"; public static final String STYLE = "style"; + public static final String STYLE_NAME = "风格"; public static final String DESIGN = "design"; + public static final String DESIGN_NAME = "款式"; public static final String LEATHER_FEATURES = "leatherFeatures"; + public static final String LEATHER_FEATURES_NAME = "皮质特征"; public static final String MANUFACTURING_PROCESS = "manufacturingProcess"; + public static final String MANUFACTURING_PROCESS_NAME = "制作工艺"; public static final String PATTERN = "pattern"; + public static final String PATTERN_NAME = "图案"; public static final String CLOSURE_TYPE = "closureType"; + public static final String CLOSURE_TYPE_NAME = "闭合方式"; public static final String OCCASION = "occasion"; - public static final String SUITABLE_AGE = "suitableAge"; + public static final String OCCASION_NAME = "适用场景"; public static final String THICKNESS = "thickness"; + public static final String THICKNESS_NAME = "厚薄"; public static final String FASHION_ELEMENTS = "fashionElements"; + public static final String FASHION_ELEMENTS_NAME = "流行元素"; public static final String SUITABLE_PERSON = "suitablePerson"; + public static final String SUITABLE_PERSON_NAME = "适用对象"; /** * app 类目属性的key value匹配值 */ public static final Map CATE_RELATE_MAP = new ConcurrentHashMap() {{ - put(UPPER_MATERIAL, "帮面材质"); - put(SHAFT_LINING_MATERIAL, "靴筒内里材质"); - put(SHAFT_MATERIAL, "靴筒面材质"); - put(SHOE_UPPER_LINING_MATERIAL, "鞋面内里材质"); - put(SHOE_STYLE_NAME, "靴款品名"); - put(SHAFT_HEIGHT, "筒高"); - put(INSOLE_MATERIAL, "鞋垫材质"); - put(RELEASE_YEAR_SEASON, "上市季节年份"); - put(HEEL_HEIGHT, "后跟高"); - put(HEEL_TYPE, "跟底款式"); - put(TOE_STYLE, "鞋头款式"); - put(SUITABLE_SEASON, "适合季节"); - put(COLLAR_DEPTH, "开口深度"); - put(OUTSOLE_MATERIAL, "鞋底材质"); - put(STYLE, "风格"); - put(DESIGN, "款式"); - put(LEATHER_FEATURES, "皮质特征"); - put(MANUFACTURING_PROCESS, "制作工艺"); - put(PATTERN, "图案"); - put(CLOSURE_TYPE, "闭合方式"); - put(OCCASION, "适用场景"); - put(SUITABLE_AGE, "适用年龄"); - put(THICKNESS, "厚薄"); - put(FASHION_ELEMENTS, "流行元素"); - put(SUITABLE_PERSON, "适用对象"); + put(UPPER_MATERIAL, UPPER_MATERIAL_NAME); + put(SHAFT_LINING_MATERIAL, SHAFT_LINING_MATERIAL_NAME); + put(SHAFT_MATERIAL, SHAFT_MATERIAL_NAME); + put(SHOE_UPPER_LINING_MATERIAL, SHOE_UPPER_LINING_MATERIAL_NAME); + put(SHOE_STYLE_NAME, SHOE_STYLE_NAME_NAME); + put(SHAFT_HEIGHT, SHAFT_HEIGHT_NAME); + put(INSOLE_MATERIAL, INSOLE_MATERIAL_NAME); + put(RELEASE_YEAR_SEASON, RELEASE_YEAR_SEASON_NAME); + put(HEEL_HEIGHT, HEEL_HEIGHT_NAME); + put(HEEL_TYPE, HEEL_TYPE_NAME); + put(TOE_STYLE, TOE_STYLE_NAME); + put(SUITABLE_SEASON, SUITABLE_SEASON_NAME); + put(COLLAR_DEPTH, COLLAR_DEPTH_NAME); + put(OUTSOLE_MATERIAL, OUTSOLE_MATERIAL_NAME); + put(STYLE, STYLE_NAME); + put(DESIGN, DESIGN_NAME); + put(LEATHER_FEATURES, LEATHER_FEATURES_NAME); + put(MANUFACTURING_PROCESS, MANUFACTURING_PROCESS_NAME); + put(PATTERN, PATTERN_NAME); + put(CLOSURE_TYPE, CLOSURE_TYPE_NAME); + put(OCCASION, OCCASION_NAME); + put(THICKNESS, THICKNESS_NAME); + put(FASHION_ELEMENTS, FASHION_ELEMENTS_NAME); + put(SUITABLE_PERSON, SUITABLE_PERSON_NAME); }}; } diff --git a/sql/ry_20240629.sql b/sql/ry_20240629.sql index 215f16b8a..60b5c4834 100644 --- a/sql/ry_20240629.sql +++ b/sql/ry_20240629.sql @@ -3478,7 +3478,6 @@ CREATE TABLE `store_product_category_attribute` `pattern` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '图案', `closure_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '闭合方式', `occasion` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '适用场景', - `suitable_age` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '适用年龄', `thickness` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '厚薄', `fashion_elements` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '流行元素', `suitable_person` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '适用对象', diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/StoreProductCategoryAttribute.java b/xkt/src/main/java/com/ruoyi/xkt/domain/StoreProductCategoryAttribute.java index 358117692..f1c494da5 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/StoreProductCategoryAttribute.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/StoreProductCategoryAttribute.java @@ -116,10 +116,6 @@ public class StoreProductCategoryAttribute extends XktBaseEntity { * 适用场景 */ private String occasion; - /** - * 适用年龄 - */ - private String suitableAge; /** * 厚薄 */