|
@@ -0,0 +1,235 @@
|
|
|
|
|
+package org.dromara.external.handler.impl;
|
|
|
|
|
+
|
|
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
|
|
+import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
|
|
+import org.dromara.external.api.zhongche.domain.GoodsImportItem;
|
|
|
|
|
+import org.dromara.external.api.zhongche.domain.bo.GoodsImportBo;
|
|
|
|
|
+import org.dromara.external.api.zhongche.domain.vo.GoodsImportVo;
|
|
|
|
|
+import org.dromara.external.controller.zhongche.ZhongChePullController;
|
|
|
|
|
+import org.dromara.external.domain.ExternalProduct;
|
|
|
|
|
+import org.dromara.external.domain.ExternalProductCategory;
|
|
|
|
|
+import org.dromara.external.domain.vo.ExternalProductVo;
|
|
|
|
|
+import org.dromara.external.handler.ProductPushStrategy;
|
|
|
|
|
+import org.dromara.external.mapper.ExternalProductMapper;
|
|
|
|
|
+import org.dromara.external.service.IExternalProductCategoryService;
|
|
|
|
|
+import org.dromara.product.api.RemoteProductService;
|
|
|
|
|
+import org.dromara.product.api.domain.ProductVo;
|
|
|
|
|
+import org.dromara.product.api.domain.zhongche.dto.ProductAggregateDto;
|
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+@Component("zhongchePushStrategy")
|
|
|
|
|
+@RequiredArgsConstructor
|
|
|
|
|
+public class ZhongChePushStrategy implements ProductPushStrategy {
|
|
|
|
|
+
|
|
|
|
|
+ @DubboReference
|
|
|
|
|
+ private final RemoteProductService remoteProductService;
|
|
|
|
|
+
|
|
|
|
|
+ private final ZhongChePullController zhongChePullController;
|
|
|
|
|
+
|
|
|
|
|
+ private final ExternalProductMapper externalProductMapper;
|
|
|
|
|
+
|
|
|
|
|
+ private final IExternalProductCategoryService externalProductCategoryService;
|
|
|
|
|
+
|
|
|
|
|
+ private final ObjectMapper objectMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void push(List<ExternalProduct> products) {
|
|
|
|
|
+ String username = "admin";
|
|
|
|
|
+ List<ExternalProductVo> productVoList = new ArrayList<>();
|
|
|
|
|
+ for (ExternalProduct product : products) {
|
|
|
|
|
+ ExternalProductVo vo = BeanUtil.toBean(product, ExternalProductVo.class);
|
|
|
|
|
+ productVoList.add(vo);
|
|
|
|
|
+ }
|
|
|
|
|
+ productVoList.forEach(item -> {
|
|
|
|
|
+ ExternalProductVo externalProductVo = BeanUtil.toBean(item, ExternalProductVo.class);
|
|
|
|
|
+ ProductVo productDetail = remoteProductService.getProductDetail(item.getProductId());
|
|
|
|
|
+ BeanUtil.copyProperties(productDetail, item);
|
|
|
|
|
+ item.setId(externalProductVo.getId());
|
|
|
|
|
+ item.setProductStatus(externalProductVo.getProductStatus());
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 收集所有 externalCategoryId
|
|
|
|
|
+ Set<Long> categoryIds = productVoList.stream()
|
|
|
|
|
+ .map(ExternalProductVo::getExternalCategoryId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ if (!categoryIds.isEmpty()) {
|
|
|
|
|
+ List<ExternalProductCategory> categoryList =
|
|
|
|
|
+ externalProductCategoryService.listByIds(categoryIds);
|
|
|
|
|
+
|
|
|
|
|
+ // 转成 Map <id, name>
|
|
|
|
|
+ Map<Long, String> categoryMap = categoryList.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(
|
|
|
|
|
+ ExternalProductCategory::getId,
|
|
|
|
|
+ ExternalProductCategory::getCategoryName
|
|
|
|
|
+ ));
|
|
|
|
|
+
|
|
|
|
|
+ // 回填分类名称
|
|
|
|
|
+ productVoList.forEach(item -> {
|
|
|
|
|
+ String categoryName =
|
|
|
|
|
+ categoryMap.get(item.getExternalCategoryId());
|
|
|
|
|
+ item.setStandardCatalogName(categoryName);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ List<Long> productIds = productVoList.stream()
|
|
|
|
|
+ .map(ExternalProductVo::getProductId)
|
|
|
|
|
+ .filter(Objects::nonNull) // 过滤空ID,避免远程调用报错
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ //远程调用获取ProductAggregateDto列表
|
|
|
|
|
+ final Map<Long, ProductAggregateDto> productAggregateMap = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ if (!CollectionUtils.isEmpty(productIds)) {
|
|
|
|
|
+ List<ProductAggregateDto> productAggregateList =
|
|
|
|
|
+ remoteProductService.getProductInfo(productIds);
|
|
|
|
|
+
|
|
|
|
|
+ if (!CollectionUtils.isEmpty(productAggregateList)) {
|
|
|
|
|
+ productAggregateMap.putAll(
|
|
|
|
|
+ productAggregateList.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(
|
|
|
|
|
+ ProductAggregateDto::getProductId,
|
|
|
|
|
+ dto -> dto,
|
|
|
|
|
+ (existing, replacement) -> existing
|
|
|
|
|
+ ))
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<GoodsImportItem> batchGoods = new ArrayList<>();
|
|
|
|
|
+ productVoList.forEach(item -> {
|
|
|
|
|
+ GoodsImportItem goodsImportItem = new GoodsImportItem();
|
|
|
|
|
+ goodsImportItem.setGoodsId(item.getProductId().toString());
|
|
|
|
|
+ goodsImportItem.setCatalogId(item.getBottomCategoryId().toString());
|
|
|
|
|
+ goodsImportItem.setCatalogName(item.getCategoryName());
|
|
|
|
|
+ goodsImportItem.setStandardCatalogId(item.getExternalCategoryId().toString());
|
|
|
|
|
+ goodsImportItem.setStandardCatalogName(item.getStandardCatalogName());
|
|
|
|
|
+ //这里有英文有中文混合,需要处理
|
|
|
|
|
+ String brandName = item.getBrandName();
|
|
|
|
|
+ if (isChinese(brandName)) {
|
|
|
|
|
+ goodsImportItem.setBrandName(brandName);
|
|
|
|
|
+ } else if (isEnglish(brandName)) {
|
|
|
|
|
+ goodsImportItem.setBrandNameEn(brandName);
|
|
|
|
|
+ }
|
|
|
|
|
+ goodsImportItem.setName(item.getItemName());
|
|
|
|
|
+ goodsImportItem.setDsPrice(item.getMarketPrice());
|
|
|
|
|
+ goodsImportItem.setPrice(item.getMemberPrice());
|
|
|
|
|
+ //第三方价格
|
|
|
|
|
+ goodsImportItem.setThirdPrice(item.getExternalPrice());
|
|
|
|
|
+ goodsImportItem.setUnit(item.getUnitName());
|
|
|
|
|
+ //TODO库存
|
|
|
|
|
+ goodsImportItem.setStock(productAggregateMap.get(item.getProductId()).getStock());
|
|
|
|
|
+ //图片
|
|
|
|
|
+ String rawImageStr = item.getProductImage();
|
|
|
|
|
+ List<String> imageList = new ArrayList<>();
|
|
|
|
|
+ if (StringUtils.isNotBlank(rawImageStr)) {
|
|
|
|
|
+ String[] imagePaths = rawImageStr.split(",");
|
|
|
|
|
+ for (String path : imagePaths) {
|
|
|
|
|
+ String trimedPath = path.trim();
|
|
|
|
|
+ if (StringUtils.isNotBlank(trimedPath)) {
|
|
|
|
|
+ imageList.add(trimedPath);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ String barImgUrlsJson;
|
|
|
|
|
+ try {
|
|
|
|
|
+ barImgUrlsJson = objectMapper.writeValueAsString(imageList);
|
|
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
|
|
+ barImgUrlsJson = "[]";
|
|
|
|
|
+ }
|
|
|
|
|
+ goodsImportItem.setBarImgUrls(barImgUrlsJson);
|
|
|
|
|
+ //TODO商品描述
|
|
|
|
|
+ goodsImportItem.setDescription(productAggregateMap.get(item.getProductId()).getDescription());
|
|
|
|
|
+ //TODO商品规格 默认 颜色:白色
|
|
|
|
|
+ goodsImportItem.setProperties("{\"颜色\":\"白色\"}");
|
|
|
|
|
+ //TODO是否自营
|
|
|
|
|
+ goodsImportItem.setIsSelfOperated(item.getIsSelf());
|
|
|
|
|
+ //税率
|
|
|
|
|
+ goodsImportItem.setTax(item.getTaxRate());
|
|
|
|
|
+ //TODO税收编码 默认填1
|
|
|
|
|
+ goodsImportItem.setTaxCode("1");
|
|
|
|
|
+
|
|
|
|
|
+ batchGoods.add(goodsImportItem);
|
|
|
|
|
+ });
|
|
|
|
|
+ GoodsImportBo bo = new GoodsImportBo();
|
|
|
|
|
+ bo.setAccount(username);
|
|
|
|
|
+ bo.setGoods(batchGoods);
|
|
|
|
|
+ GoodsImportVo goodsImportVo = zhongChePullController.egoodsImport(bo);
|
|
|
|
|
+ if (goodsImportVo.getResult() == 1) {
|
|
|
|
|
+ externalProductMapper.update(
|
|
|
|
|
+ Wrappers.lambdaUpdate(ExternalProduct.class)
|
|
|
|
|
+ .set(ExternalProduct::getPushStatus, 1)
|
|
|
|
|
+ .in(ExternalProduct::getId, productIds)
|
|
|
|
|
+ );
|
|
|
|
|
+ } else {
|
|
|
|
|
+ externalProductMapper.update(
|
|
|
|
|
+ Wrappers.lambdaUpdate(ExternalProduct.class)
|
|
|
|
|
+ .set(ExternalProduct::getPushStatus, 3)
|
|
|
|
|
+ .set(ExternalProduct::getRemark, goodsImportVo.getMessage())
|
|
|
|
|
+ .in(ExternalProduct::getId, productIds)
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // --------------------- 核心判断方法 ---------------------
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断字符串是否包含中文汉字(核心判断逻辑)
|
|
|
|
|
+ * @param str 待判断字符串
|
|
|
|
|
+ * @return true=包含中文,false=不包含
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean isChinese(String str) {
|
|
|
|
|
+ // 匹配任意中文字符(Unicode 中文编码范围)
|
|
|
|
|
+ return str.matches(".*[\\u4e00-\\u9fa5]+.*");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断字符串是否为纯英文(字母、数字、空格、常见标点)
|
|
|
|
|
+ * @param str 待判断字符串
|
|
|
|
|
+ * @return true=纯英文/数字,false=包含其他字符
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean isEnglish(String str) {
|
|
|
|
|
+ // 匹配字母、数字、空格、横线、点、下划线(可根据业务扩展)
|
|
|
|
|
+ return str.matches("[a-zA-Z0-9 \\-\\.\\_]+");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /*public static void main(String[] args) {
|
|
|
|
|
+ String username = "admin";
|
|
|
|
|
+ List<GoodsImportItem> batchGoods = new ArrayList<>();
|
|
|
|
|
+ GoodsImportItem item = new GoodsImportItem();
|
|
|
|
|
+ item.setGoodsId("362031");
|
|
|
|
|
+ item.setCatalogId("13012");
|
|
|
|
|
+ item.setCatalogName("原装墨盒");
|
|
|
|
|
+ item.setStandardCatalogId("1750717233748832257");
|
|
|
|
|
+ item.setStandardCatalogName("铁圈装订机耗材");
|
|
|
|
|
+ item.setBrandName("得力");
|
|
|
|
|
+ item.setName("得力");
|
|
|
|
|
+ item.setDsPrice(new BigDecimal(41));
|
|
|
|
|
+ item.setPrice(new BigDecimal(34));
|
|
|
|
|
+ item.setUnit("个");
|
|
|
|
|
+ item.setStock(100);
|
|
|
|
|
+ item.setBarImgUrls("[\"https://img1.com\",\"https://img2.com\"]");
|
|
|
|
|
+ item.setDescription("得力商品");
|
|
|
|
|
+ item.setProperties("{\"颜色\":\"红色\",\"尺寸\":\"XL\",\"材质\":\"棉|涤纶\"}");
|
|
|
|
|
+ item.setIsSelfOperated(1);
|
|
|
|
|
+ item.setTax(new BigDecimal(0.05));
|
|
|
|
|
+ item.setTaxCode("123456");
|
|
|
|
|
+ batchGoods.add(item);
|
|
|
|
|
+ GoodsImportBo bo = new GoodsImportBo();
|
|
|
|
|
+ bo.setAccount(username);
|
|
|
|
|
+ bo.setGoods(batchGoods);
|
|
|
|
|
+ ZhongChePullController zhongChePullController = new ZhongChePullController();
|
|
|
|
|
+ GoodsImportVo resp = zhongChePullController.egoodsImport(bo);
|
|
|
|
|
+ System.out.println(resp);
|
|
|
|
|
+ }*/
|
|
|
|
|
+}
|