|
|
|
@ -1,6 +1,21 @@
|
|
|
|
|
package com.ms.api.task;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
import java.util.concurrent.Executor;
|
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
import com.doudian.open.api.product_addV2.ProductAddV2Request;
|
|
|
|
|
import com.doudian.open.api.product_addV2.ProductAddV2Response;
|
|
|
|
@ -11,20 +26,50 @@ import com.doudian.open.api.product_addV2.param.RecruitInfo;
|
|
|
|
|
import com.doudian.open.api.product_detail.ProductDetailRequest;
|
|
|
|
|
import com.doudian.open.api.product_detail.ProductDetailResponse;
|
|
|
|
|
import com.doudian.open.api.product_detail.param.ProductDetailParam;
|
|
|
|
|
import com.doudian.open.api.product_getCatePropertyV2.data.DataItem;
|
|
|
|
|
import com.doudian.open.api.product_getCatePropertyV2.data.ProductGetCatePropertyV2Data;
|
|
|
|
|
import com.doudian.open.core.AccessToken;
|
|
|
|
|
import com.ms.api.biz.MoveService;
|
|
|
|
|
import com.ms.api.bo.MoveProductPublishToPicQueueBO;
|
|
|
|
|
import com.ms.api.bo.MoveShopSettingBO;
|
|
|
|
|
import com.ms.api.common.*;
|
|
|
|
|
import com.ms.api.consts.*;
|
|
|
|
|
import com.ms.api.common.E;
|
|
|
|
|
import com.ms.api.common.Ret;
|
|
|
|
|
import com.ms.api.common.StrObjMap;
|
|
|
|
|
import com.ms.api.common.StrStrMap;
|
|
|
|
|
import com.ms.api.common.TaskBaseService;
|
|
|
|
|
import com.ms.api.consts.AppConst;
|
|
|
|
|
import com.ms.api.consts.CommonConst;
|
|
|
|
|
import com.ms.api.consts.MoveConst;
|
|
|
|
|
import com.ms.api.consts.RedisKeyConst;
|
|
|
|
|
import com.ms.api.consts.StatusConst;
|
|
|
|
|
import com.ms.api.paas.RedisService;
|
|
|
|
|
import com.ms.api.paas.StorageService;
|
|
|
|
|
import com.ms.api.service.*;
|
|
|
|
|
import com.ms.api.service.DsRelateProductAnalysisOpOrderQueueService;
|
|
|
|
|
import com.ms.api.service.MaterialBizAuditStatusLogService;
|
|
|
|
|
import com.ms.api.service.MaterialBizQueueService;
|
|
|
|
|
import com.ms.api.service.MaterialBizToMaterialService;
|
|
|
|
|
import com.ms.api.service.MoveCollectTaskDetailService;
|
|
|
|
|
import com.ms.api.service.MoveCollectTaskService;
|
|
|
|
|
import com.ms.api.service.MoveProductLogService;
|
|
|
|
|
import com.ms.api.service.MoveProductPublishQueueService;
|
|
|
|
|
import com.ms.api.service.MoveProductPublishToPicQueueService;
|
|
|
|
|
import com.ms.api.service.ProductToDsItemService;
|
|
|
|
|
import com.ms.api.service.Shop1688DsAuthService;
|
|
|
|
|
import com.ms.api.service.ShopService;
|
|
|
|
|
import com.ms.api.tool.CommonTool;
|
|
|
|
|
import com.ms.api.tool.DsJsonRequestTemplate;
|
|
|
|
|
import com.ms.api.tool.SecurityTool;
|
|
|
|
|
import com.ms.api.util.MoveUtil;
|
|
|
|
|
import com.ms.dal.entity.*;
|
|
|
|
|
import com.ms.dal.entity.DsRelateProductAnalysisOpOrderQueue;
|
|
|
|
|
import com.ms.dal.entity.MaterialBizAuditStatusLog;
|
|
|
|
|
import com.ms.dal.entity.MaterialBizQueue;
|
|
|
|
|
import com.ms.dal.entity.MaterialBizToMaterial;
|
|
|
|
|
import com.ms.dal.entity.MoveCollectTaskDetail;
|
|
|
|
|
import com.ms.dal.entity.MoveProductLog;
|
|
|
|
|
import com.ms.dal.entity.MoveProductPublishToPicQueue;
|
|
|
|
|
import com.ms.dal.entity.ProductToDsItem;
|
|
|
|
|
import com.ms.dal.entity.Shop;
|
|
|
|
|
import com.ms.dal.entity.Shop1688DsAuth;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
@ -33,15 +78,6 @@ import org.springframework.context.annotation.Configuration;
|
|
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
import org.springframework.transaction.PlatformTransactionManager;
|
|
|
|
|
import org.springframework.transaction.TransactionStatus;
|
|
|
|
|
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.concurrent.Executor;
|
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
@ -254,7 +290,7 @@ public class ProcessMovePublishToPicTaskService extends TaskBaseService {
|
|
|
|
|
JSONObject productDetailBase = data.getJSONObject("productDetailBase");
|
|
|
|
|
JSONObject sourceProductData = data.getJSONObject("sourceProductData");
|
|
|
|
|
JSONObject moveBaseData = data.getJSONObject("moveBaseData");
|
|
|
|
|
JSONObject brandList = data.getJSONObject("brandList");
|
|
|
|
|
JSONArray brandList = data.getJSONArray("brandList");
|
|
|
|
|
AccessToken accessToken = getShopAccessToken(shopId);
|
|
|
|
|
// 检查详情图片数量和长度
|
|
|
|
|
productDetailBase.put("noteImgUrls", filterNoteImgUrls((String) productDetailBase.get("noteImgUrls")));
|
|
|
|
@ -298,7 +334,7 @@ public class ProcessMovePublishToPicTaskService extends TaskBaseService {
|
|
|
|
|
return mAccessToken;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Ret createProduct(JSONObject productDetailBase, JSONObject sourceProductData, MoveShopSettingBO condition, MoveProductPublishToPicQueueBO queueMsg, JSONObject moveBaseData, JSONObject brandList, AccessToken accessToken) {
|
|
|
|
|
private Ret createProduct(JSONObject productDetailBase, JSONObject sourceProductData, MoveShopSettingBO condition, MoveProductPublishToPicQueueBO queueMsg, JSONObject moveBaseData, JSONArray brandList, AccessToken accessToken) {
|
|
|
|
|
long shopId = queueMsg.getShopId();
|
|
|
|
|
Ret addRet = postDataToDdV2(productDetailBase, condition, queueMsg, moveBaseData, accessToken);
|
|
|
|
|
// TODO 几个方法的实现
|
|
|
|
@ -338,47 +374,80 @@ public class ProcessMovePublishToPicTaskService extends TaskBaseService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
private Ret rebuildAddRetReason(Ret addRet, JSONObject brandList, MoveShopSettingBO condition, String cid, AccessToken accessToken) {
|
|
|
|
|
|
|
|
|
|
// if (strpos($addRet['reason'], '请重新选择品牌') !== false || strpos($addRet['reason'], '该类目下无品牌') !== false || strpos($addRet['reason'], '品牌不属于该类目') !== false) {
|
|
|
|
|
// if (is_numeric($condition['brandId'])) {
|
|
|
|
|
// $brandMap = array_column($brandList, null, 'id');
|
|
|
|
|
// $brandId = $condition['brandId'];
|
|
|
|
|
// $brandName = $brandMap[$brandId]['brand_chinese_name'] ? $brandMap[$brandId]['brand_chinese_name'] : $brandMap[$brandId]['brand_english_name'];
|
|
|
|
|
// $addRet['reason'] = "当前类目无 $brandName 品牌权限,请前往店铺后台申请品牌,<a href=\"https://fxg.jinritemai.com/ffa/grs/qualification/list?type=2\" target=\"_blank\">立即申请</a>";
|
|
|
|
|
// return $addRet;
|
|
|
|
|
// } else if ($condition['brandId'] == MoveConst::brandEmpty) {
|
|
|
|
|
// $addRet['reason'] = '当前类目品牌必填,请前往店铺后台申请品牌,<a href="https://fxg.jinritemai.com/ffa/grs/qualification/list?type=2" target="_blank">立即申请</a><br>您在搬家配置设置“品牌留空”。若您已经申请品牌,请修改搬家配置,若没有申请品牌,请前往店铺后台申请品牌';
|
|
|
|
|
// return $addRet;
|
|
|
|
|
// } else if (empty($brandList)) {
|
|
|
|
|
// $addRet['reason'] = '当前类目品牌必填,请前往店铺后台申请品牌,<a href="https://fxg.jinritemai.com/ffa/grs/qualification/list?type=2" target="_blank">立即申请</a>';
|
|
|
|
|
// return $addRet;
|
|
|
|
|
// } else if (count($brandList)) {
|
|
|
|
|
// $brandNames = [];
|
|
|
|
|
// foreach ($brandList as $brand) {
|
|
|
|
|
// $brandNames[] = $brand['brand_chinese_name'] ? $brand['brand_chinese_name'] : $brand['brand_english_name'];
|
|
|
|
|
// }
|
|
|
|
|
// $addRet['reason'] = '当前类目无"'. implode(',', $brandNames) .'"品牌权限,请前往店铺后台申请品牌,<a href="https://fxg.jinritemai.com/ffa/grs/qualification/list?type=2" target="_blank">立即申请</a>';
|
|
|
|
|
// return $addRet;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (strpos($addRet['reason'], '没有品牌资质,非普通店商品请使用有资质的品牌') !== false) {
|
|
|
|
|
// return $this->rebuildAddRetBrandQualificationReason($addRet, $brandList, $cid, $accessToken);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (strpos($addRet['reason'], '颜色对应的规格值不能重复,请核对') !== false) {
|
|
|
|
|
// $addRet['reason'] = $addRet['reason'] . ',请检查是否包含特殊符号或违禁词(' . implode(',', MoveConst::getSpecialBanWordList()) . ')';
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (preg_match('/规格值含有敏感词(?::|:)\[([^\]]+)\]/', $addRet['reason'], $matchBanWord) || preg_match('/商品规格值描述“(.*)”不符合平台要求/', $addRet['reason'], $matchBanWord)) {
|
|
|
|
|
// $addRet['reason'] = $addRet['reason'] . ',并且过滤后会导致sku规格值重复,请检查并手动修改';
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return $addRet;
|
|
|
|
|
private Ret rebuildAddRetReason(Ret addRet, JSONArray brandList, MoveShopSettingBO condition, String cid, AccessToken accessToken) {
|
|
|
|
|
|
|
|
|
|
if (addRet.getReason().contains("请重新选择品牌") || addRet.getReason().contains("该类目下无品牌") || addRet.getReason().contains("品牌不属于该类目")) {
|
|
|
|
|
if (StringUtils.isNumeric(condition.getBrandId())) {
|
|
|
|
|
Map<String, JSONObject> brandMap = brandList.stream().filter(x -> ((JSONObject) x).containsKey("id")).collect(Collectors.toMap(x -> ((JSONObject) x).getString("id"), x -> (JSONObject) x, (v1, v2) -> v1));
|
|
|
|
|
JSONObject brand = brandMap.get(condition.getBrandId());
|
|
|
|
|
String brandName = brand.getString("brand_chinese_name") != null ? brand.getString("brand_chinese_name") : brand.getString("brand_english_name");
|
|
|
|
|
addRet.setReason("当前类目无 " + brandName + " 品牌权限,请前往店铺后台申请品牌,<a href=\"https://fxg.jinritemai.com/ffa/grs/qualification/list?type=2\" target=\"_blank\">立即申请</a>");
|
|
|
|
|
return addRet;
|
|
|
|
|
} else if (Objects.equals(condition.getBrandId(), MoveConst.brandEmpty)) {
|
|
|
|
|
addRet.setReason("当前类目品牌必填,请前往店铺后台申请品牌,<a href=\"https://fxg.jinritemai.com/ffa/grs/qualification/list?type=2\" target=\"_blank\">立即申请</a><br>您在搬家配置设置“品牌留空”。若您已经申请品牌,请修改搬家配置,若没有申请品牌,请前往店铺后台申请品牌");
|
|
|
|
|
return addRet;
|
|
|
|
|
} else if (brandList.isEmpty()) {
|
|
|
|
|
addRet.setReason("当前类目品牌必填,请前往店铺后台申请品牌,<a href=\"https://fxg.jinritemai.com/ffa/grs/qualification/list?type=2\" target=\"_blank\">立即申请</a>");
|
|
|
|
|
return addRet;
|
|
|
|
|
} else if (brandList.size() != 0) {
|
|
|
|
|
List<String> brandNames = brandList.stream().map(x -> {
|
|
|
|
|
JSONObject temp = (JSONObject) x;
|
|
|
|
|
return temp.containsKey("brand_chinese_name") ? temp.getString("brand_chinese_name") : temp.getString("brand_english_name");
|
|
|
|
|
}).collect(Collectors.toList());
|
|
|
|
|
addRet.setReason("当前类目无\"" + String.join(",", brandNames) + "\"品牌权限,请前往店铺后台申请品牌,<a href=\"https://fxg.jinritemai.com/ffa/grs/qualification/list?type=2\" target=\"_blank\">立即申请</a>");
|
|
|
|
|
return addRet;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addRet.getReason().contains("没有品牌资质,非普通店商品请使用有资质的品牌")) {
|
|
|
|
|
return rebuildAddRetBrandQualificationReason(addRet, brandList, cid, accessToken);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addRet.getReason().contains("颜色对应的规格值不能重复,请核对")) {
|
|
|
|
|
addRet.setReason(addRet.getReason() + ",请检查是否包含特殊符号或违禁词(" + String.join(",", MoveConst.getSpecialBanWordList()) + ")");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Matcher matcherBanWord = Pattern.compile("规格值含有敏感词(?::|:)\\[([^\\]]+)\\]").matcher(addRet.getReason());
|
|
|
|
|
Matcher matcherBanWordDescription = Pattern.compile("商品规格值描述“(.*)”不符合平台要求").matcher(addRet.getReason());
|
|
|
|
|
if (matcherBanWord.matches() || matcherBanWordDescription.matches()) {
|
|
|
|
|
addRet.setReason(addRet.getReason() + ",并且过滤后会导致sku规格值重复,请检查并手动修改");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return addRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Ret rebuildAddRetBrandQualificationReason(Ret addRet, JSONArray brandList, String cid, AccessToken accessToken) {
|
|
|
|
|
Ret categoryAttrRet = moveService.getCategoryAttrV2FromDd(cid, accessToken);
|
|
|
|
|
if (CommonTool.isFailRet(categoryAttrRet)) {
|
|
|
|
|
return addRet;
|
|
|
|
|
}
|
|
|
|
|
boolean isNeedCheckShopBrand = checkIsNeedShopBrand((ProductGetCatePropertyV2Data) categoryAttrRet.getData().get("data"));
|
|
|
|
|
if (!isNeedCheckShopBrand) {
|
|
|
|
|
return addRet;
|
|
|
|
|
}
|
|
|
|
|
if (!brandList.isEmpty()) {
|
|
|
|
|
addRet.setReason("当前商品发布的类目未申请品牌资质,请到店铺后台申请品牌资质,<a href=\"https://fxg.jinritemai.com/ffa/grs/qualification/brand-edit\" target=\"_blank\">前往申请</a>");
|
|
|
|
|
}
|
|
|
|
|
return addRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean checkIsNeedShopBrand(ProductGetCatePropertyV2Data data) {
|
|
|
|
|
List<DataItem> attrs = data.getData();
|
|
|
|
|
boolean isNeed = false;
|
|
|
|
|
for (DataItem attr : attrs) {
|
|
|
|
|
if (!"品牌".equals(attr.getPropertyName())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (ObjectUtil.isNotEmpty(attr.getRequired()) && attr.getRequired() != 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (ObjectUtil.isEmpty(attr.getOptions())) {
|
|
|
|
|
isNeed = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return isNeed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void deleteShopCategoryBrand(long shopId, JSONObject productDetailBase, Ret addRet) {
|
|
|
|
|
// if(CommonTool::isSuccessRet($addProductRet)) {
|
|
|
|
|
// return ;
|
|
|
|
@ -457,7 +526,6 @@ public class ProcessMovePublishToPicTaskService extends TaskBaseService {
|
|
|
|
|
return addRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private StrObjMap processAddProductError(long shopId, JSONObject productDetailBase, MoveShopSettingBO condition, MoveProductPublishToPicQueueBO queueMsg, JSONObject moveBaseData, String reason, int i, AccessToken accessToken) {
|
|
|
|
|
boolean dataIsChange = false;
|
|
|
|
|
//
|
|
|
|
@ -521,7 +589,7 @@ public class ProcessMovePublishToPicTaskService extends TaskBaseService {
|
|
|
|
|
|
|
|
|
|
String title = productData.getString("title");
|
|
|
|
|
if (!Objects.isNull(title)) {
|
|
|
|
|
param.setName(title.substring(0, Math.min(title.length(), 10)));
|
|
|
|
|
param.setName(title.substring(0, Math.min(title.length(), 10)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String mainImgUrls = productData.getString("mainImgUrls");
|
|
|
|
@ -590,7 +658,7 @@ public class ProcessMovePublishToPicTaskService extends TaskBaseService {
|
|
|
|
|
// Object productFormatNew = productData.get("productFormatNew");
|
|
|
|
|
// if (!Objects.isNull(productFormatNew)) {
|
|
|
|
|
// param.setProductFormatNew(JSON.toJSONString(productFormatNew));
|
|
|
|
|
param.setProductFormatNew("{\"631\":[{\"diy_type\":1,\"name\":\"嘻哈风\",\"value\":196227}],\"1467\":[{\"diy_type\":0,\"name\":\"59%-69%(含)\",\"value\":168368}],\"1551\":[{\"diy_type\":1,\"name\":\"超短裙\",\"value\":22064}],\"1687\":[{\"diy_type\":0,\"name\":\"改为具体的品牌,没有可以为空\",\"value\":0}],\"1878\":[{\"diy_type\":1,\"name\":\"高腰\",\"value\":16521}],\"2592\":[{\"diy_type\":1,\"name\":\"甜美\",\"value\":23925}],\"785\":[{\"diy_type\":0,\"name\":\"涤纶\",\"value\":25708}],\"813\":[{\"diy_type\":1,\"name\":\"X型\",\"value\":8017}],\"981\":[{\"diy_type\":1,\"name\":\"蛋糕裙\",\"value\":22253}]}");
|
|
|
|
|
param.setProductFormatNew("{\"631\":[{\"diy_type\":1,\"name\":\"嘻哈风\",\"value\":196227}],\"1467\":[{\"diy_type\":0,\"name\":\"59%-69%(含)\",\"value\":168368}],\"1551\":[{\"diy_type\":1,\"name\":\"超短裙\",\"value\":22064}],\"1687\":[{\"diy_type\":0,\"name\":\"改为具体的品牌,没有可以为空\",\"value\":0}],\"1878\":[{\"diy_type\":1,\"name\":\"高腰\",\"value\":16521}],\"2592\":[{\"diy_type\":1,\"name\":\"甜美\",\"value\":23925}],\"785\":[{\"diy_type\":0,\"name\":\"涤纶\",\"value\":25708}],\"813\":[{\"diy_type\":1,\"name\":\"X型\",\"value\":8017}],\"981\":[{\"diy_type\":1,\"name\":\"蛋糕裙\",\"value\":22253}]}");
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// Long deliveryDelayDay = productData.getLong("deliveryDelayDay");
|
|
|
|
|