wangchaoxu 1 year ago
commit 5d84ea78f6

@ -1,5 +1,6 @@
package com.ms.api.biz;
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@ -16,10 +17,13 @@ import com.doudian.open.api.product_getProductUpdateRule.data.NormalRule;
import com.doudian.open.api.product_getProductUpdateRule.data.ProductGetProductUpdateRuleData;
import com.doudian.open.api.product_getProductUpdateRule.param.ProductGetProductUpdateRuleParam;
import com.doudian.open.core.AccessToken;
import com.ms.api.bo.AttributeBO;
import com.ms.api.bo.CateAttributeResultBO;
import com.ms.api.bo.MoveProductPublishQueueBO;
import com.ms.api.bo.MoveShopSettingBO;
import com.ms.api.common.ApiResult;
import com.ms.api.common.Ret;
import com.ms.api.common.StrObjMap;
import com.ms.api.consts.MoveConst;
import com.ms.api.tool.CommonTool;
import com.ms.api.util.DdRequestUtil;
@ -98,7 +102,6 @@ public class MoveService {
//当天发的值为9999
deliveryDelayDay = 9999;
}
// TODO 抖店规则匹配 回头处理
ProductGetProductUpdateRuleParam param = new ProductGetProductUpdateRuleParam();
if (productDetailBase.containsKey("categoryLeafId") && productDetailBase.get("categoryLeafId") instanceof Number) {
param.setCategoryId(productDetailBase.getLong("categoryLeafId"));

@ -0,0 +1,19 @@
package com.ms.api.bo;
import lombok.Data;
import java.util.List;
@Data
public class AttributeBO {
private String propertyName;
private int propertyId;
private int required;
private List<Option> options;
@Data
public static class Option {
private int value;
private String name;
}
}

@ -0,0 +1,18 @@
package com.ms.api.bo;
import lombok.Data;
import java.util.Map;
@Data
public class CateAttributeResultBO {
private Map<Integer, String> cateBrandMap;
private boolean isBrandReq;
private int brandAid;
public CateAttributeResultBO(Map<Integer, String> cateBrandMap, boolean isBrandReq, int brandAid) {
this.cateBrandMap = cateBrandMap;
this.isBrandReq = isBrandReq;
this.brandAid = brandAid;
}
}

@ -48,12 +48,7 @@ public abstract class TaskBaseService implements TaskHandler {
}
public void runTask() {
ThreadPoolTaskExecutor mTaskPool = (ThreadPoolTaskExecutor) getTaskPool();
if(mTaskPool.getActiveCount() == mTaskPool.getCorePoolSize()){
log.info("线程池【"+mTaskPool.getThreadNamePrefix()+"】已满,不再执行任务");
return;
}
if(isPoolFull()){ return;}
execute();
}
@ -61,12 +56,7 @@ public abstract class TaskBaseService implements TaskHandler {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try{
ThreadPoolTaskExecutor mTaskPool = (ThreadPoolTaskExecutor) getTaskPool();
if(mTaskPool.getActiveCount() == mTaskPool.getCorePoolSize()){
log.info("线程池【"+mTaskPool.getThreadNamePrefix()+"】已满,不再执行任务");
return;
}
if(isPoolFull()){ return;}
execute();
transactionManager.commit(status);
}catch (Throwable e){
@ -75,6 +65,15 @@ public abstract class TaskBaseService implements TaskHandler {
}
}
private boolean isPoolFull(){
ThreadPoolTaskExecutor mTaskPool = (ThreadPoolTaskExecutor) getTaskPool();
if(mTaskPool.getActiveCount() == mTaskPool.getCorePoolSize()){
log.info("线程池【"+mTaskPool.getThreadNamePrefix()+"】已满,不再执行任务");
return true;
}
return false;
}
public void execute(){
// 如果需要循环执行这边可以加个while(true), 配合休息策略
// 循环加载try外层这样内部有异常不会影响下次执行

@ -39,6 +39,14 @@ public class MoveConst {
public static final int MOVE_PUBLISH_TO_PIC_QUQUE_AGAIN_WAIT_MAIN_IMG_PIC_AUDIT_PASS = 9899;
public static final int MOVE_PUBLISH_TO_PIC_QUQUE_AGAIN_WAIT_NOTE_IMG_PIC_AUDIT_PASS = 9897;
public static final String attrInputTypeText = "text";
public static final String attrInputTypeSelect = "select";
public static final String attrInputTypeSearch = "search";
public static final String attrInputTypeMultiSelect = "multi_select";
public static final String attrInputTypeTimeFrame = "timeframe";
public static final String attrInputTypeTimeRange = "timerange";
public static final String attrInputTypeTimestamp = "timestamp";
public static final int baseMarketPriceTypeDdPrice = 1;
public static final int maxMarketPrice = 9999999; // 划线价最高9999999.99(单位元)

@ -1,5 +1,6 @@
package com.ms.api.spi.move;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@ -11,8 +12,10 @@ import com.ms.api.common.R;
import com.ms.api.common.Ret;
import com.ms.api.common.SPIBaseService;
import com.ms.api.dto.move.SearchDSProductCatTreeRequestDTO;
import com.ms.api.paas.StorageService;
import com.ms.api.tool.DsJsonRequestTemplate;
import com.ms.api.common.UniqueKeyMultiValueMap;
import com.ms.api.tool.MoveTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
@ -20,10 +23,7 @@ import org.springframework.util.MultiValueMap;
import java.io.*;
import java.net.URL;
import java.sql.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
*
@ -37,6 +37,9 @@ public class SearchDSProductCatTreeService extends SPIBaseService implements Ext
@Autowired
private DsJsonRequestTemplate dsJsonRequestTemplate;
@Autowired
private StorageService storageService;
@Override
public BaseResponse<Ret> handle(BaseRequest<SearchDSProductCatTreeRequestDTO> req) {
// ----参数校验----
@ -47,32 +50,35 @@ public class SearchDSProductCatTreeService extends SPIBaseService implements Ext
// ----业务处理----
HashMap<String, Object> params = new HashMap<>();
String res = null;
String strList = "";
JSONObject str = null;
JSONObject data = null;
JSONObject resObj = null;
String tosPath = MoveTool.getAllProductCatTreeOssPath();
List<Object> arrayData = null;
try {
log.info("/getSimpleProductCatTree.txt");
String resourceFileName = "/getSimpleProductCatTree.txt"; // 注意路径的开头是一个斜杠
ClassLoader classLoader = SearchDSProductCatTreeService.class.getClassLoader();
URL resource = classLoader.getResource("getSimpleProductCatTree.txt");
log.info("路径是:" + resource.getPath());
try (InputStream is = InputStream.class.getResourceAsStream(resourceFileName);
BufferedReader reader = new BufferedReader(new InputStreamReader(resource.openStream(), "utf-8"))) {
String line;
while ((line = reader.readLine()) != null) {
strList = strList + line;
}
str = JSONObject.parseObject(strList);
data = str.getJSONObject("data");
arrayData = new ArrayList<>(data.values());
} catch (IOException e) {
log.error("strerror:" + e.getMessage());
e.printStackTrace();
Ret getTosContentRet = storageService.getContent(tosPath);
if (getTosContentRet.getResult().equals("success")) {
arrayData = JSONObject.parseArray(getTosContentRet.getData().get("data").toString());
log.info(arrayData.toString() + "111111");
} else {
try {
res = dsJsonRequestTemplate.execute("/move/search_ds_product_cat_tree", params);
log.info(res);
resObj = JSON.parseObject(res);
if (resObj.get("result").equals("success")) {
JSONObject cateTree = resObj.getJSONObject("cateTree");
arrayData = new ArrayList<>(cateTree.values());
try {
storageService.uploadContent(tosPath, JSONObject.toJSONString(arrayData));
} catch (Exception e) {
log.error("商品类目TOS写入操作过程异常", e);
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("strerror2:" + e);
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("strerror2:" + e);
log.error("商品类目TOS读取操作过程异常", e);
}
Map<String, Object> result = new HashMap<>();
result.put("data", arrayData.toString());

@ -1,22 +1,5 @@
package com.ms.api.task;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
@ -36,55 +19,22 @@ import com.doudian.open.api.material_getFolderInfo.MaterialGetFolderInfoResponse
import com.doudian.open.api.material_getFolderInfo.data.ChildFolderItem;
import com.doudian.open.api.material_getFolderInfo.data.MaterialGetFolderInfoData;
import com.doudian.open.api.material_getFolderInfo.param.MaterialGetFolderInfoParam;
import com.doudian.open.api.product_getCatePropertyV2.ProductGetCatePropertyV2Request;
import com.doudian.open.api.product_getCatePropertyV2.ProductGetCatePropertyV2Response;
import com.doudian.open.api.product_getCatePropertyV2.data.DataItem;
import com.doudian.open.api.product_getCatePropertyV2.data.OptionsItem;
import com.doudian.open.api.product_getCatePropertyV2.param.ProductGetCatePropertyV2Param;
import com.doudian.open.core.AccessToken;
import com.ms.api.biz.MoveService;
import com.ms.api.bo.CategoryBO;
import com.ms.api.bo.MoveProductPublishQueueBO;
import com.ms.api.bo.MoveShopSettingBO;
import com.ms.api.common.ApiResult;
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.CommonConst;
import com.ms.api.consts.MaterialConst;
import com.ms.api.consts.MoveConst;
import com.ms.api.consts.RedisKeyConst;
import com.ms.api.consts.StatusConst;
import com.ms.api.bo.*;
import com.ms.api.common.*;
import com.ms.api.consts.*;
import com.ms.api.paas.RedisService;
import com.ms.api.paas.StorageService;
import com.ms.api.service.CategoryShopService;
import com.ms.api.service.MaterialAuditStatusBufferService;
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.MoveProductPublishQueueService;
import com.ms.api.service.MoveProductPublishToPicQueueService;
import com.ms.api.service.MoveShopSettingService;
import com.ms.api.service.RsyncCategoryQueueService;
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.ImageTool;
import com.ms.api.tool.MoveTool;
import com.ms.api.tool.SecurityTool;
import com.ms.api.service.*;
import com.ms.api.tool.*;
import com.ms.api.util.DdRequestUtil;
import com.ms.dal.entity.Category;
import com.ms.dal.entity.CategoryShop;
import com.ms.dal.entity.MaterialAuditStatusBuffer;
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.MoveProductPublishQueue;
import com.ms.dal.entity.MoveProductPublishToPicQueue;
import com.ms.dal.entity.RsyncCategoryQueue;
import com.ms.dal.entity.Shop;
import com.ms.dal.entity.Shop1688DsAuth;
import com.ms.dal.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -94,6 +44,15 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* move_product_publish_queue
*/
@ -945,15 +904,12 @@ public class ProcessProductPublishTaskService extends TaskBaseService {
JSONObject skus = buildFastModeAddSkuMinPriceSku(queueMsg.getIsFastMode(), moveBaseData.getJSONObject("skus"), queueMsg.getCondition().getPrice(), defaultColorImg);
moveBaseData.put("skus", skus);
if (queueMsg.getIsFastMode() != 0) {
//todo condition 参数缺失过多
Ret processSkuAliasRet = replaceAndDeleteSkuName(moveBaseData, (JSONObject) JSONObject.toJSON(condition));
if (CommonTool.isFailRet(processSkuAliasRet)) {
log.info("replaceAndDeleteSkuName ret {}", processSkuAliasRet.getReason());
return processSkuAliasRet;
}
//todo condition 参数缺失过多
Ret processSkuAliasRet = replaceAndDeleteSkuName(moveBaseData, (JSONObject) JSONObject.toJSON(condition));
if (CommonTool.isFailRet(processSkuAliasRet)) {
log.info("replaceAndDeleteSkuName ret {}", processSkuAliasRet.getReason());
return processSkuAliasRet;
}
StrObjMap buildRet = buildProductSkuInfos(moveBaseData, queueMsg, queueMsg.getItemNum());
StrObjMap skuList = (StrObjMap) buildRet.get("skuList");
StrObjMap updateSkuMinPriceInfo = (StrObjMap) buildRet.get("updateSkuMinPriceInfo");
@ -965,10 +921,23 @@ public class ProcessProductPublishTaskService extends TaskBaseService {
if (CommonTool.isFailRet(matchBrandRet)) {
return matchBrandRet;
}
productDetailBase.put("standardBrandId", matchBrandRet.getData().get("brandId"));
String standardBrandId = (String) matchBrandRet.getData().get("brandId");
productDetailBase.put("standardBrandId", standardBrandId);
brandName = (String) (matchBrandRet.getData().get("brandName"));
moveBaseData.put("brandName", brandName);
// 从抖店获取的类目属性
Ret categoryAttrRet = getCategoryAttrV2FromDd(cid, accessToken);
if (CommonTool.isFailRet(categoryAttrRet)) {
return categoryAttrRet;
}
JSONObject sourceAttrs = moveBaseData.getJSONObject("sourceAttrs");
List<DataItem> attributes = (List<DataItem>) categoryAttrRet.getData();
String title = productDetailBase.getString("title");
List<List<StrObjMap>> productFormatNew = buildProductAttrs(attributes, sourceAttrs, title);
productFormatNew = attachBrand2ProductFormatNew(standardBrandId, brandName, productFormatNew);
productDetailBase.put("productFormatNew", productFormatNew);
Ret ret = CommonTool.successResult();
StrObjMap returnData = new StrObjMap();
returnData.put("productDetailBase", productDetailBase);
@ -1055,6 +1024,575 @@ public class ProcessProductPublishTaskService extends TaskBaseService {
return title;
}
private List<List<StrObjMap>> attachBrand2ProductFormatNew(String standardBrandId, String brandName, List<List<StrObjMap>> productFormatNew) {
StrObjMap brandMap = new StrObjMap();
brandMap.put("name", brandName);
brandMap.put("diy_type", 0);
brandMap.put("value", standardBrandId);
List<StrObjMap> brandList = new ArrayList<>();
brandList.add(brandMap);
productFormatNew.add(1687, brandList);
return productFormatNew;
}
private List<List<StrObjMap>> buildProductAttrs(List<DataItem> attributes, JSONObject sourceAttrs, String title) {
List<List<StrObjMap>> result = new ArrayList<>();
for (DataItem attribute : attributes) {
result.add(matchSourceAttr(attribute, sourceAttrs, title));
}
return result;
}
private Ret getCategoryAttrV2FromDd(String cid, AccessToken accessToken) {
if (StringUtils.isBlank(cid)) {
return CommonTool.failResult("参数错误");
}
// TODO存取添加缓存
// $accessTokenSecret = md5($accessToken);
// if ($useCache && ($cache = $this->getCategoryAttrV2FromCache($cid, $accessTokenSecret))) {
// return CommonTool::successResult($cache);
// }
ProductGetCatePropertyV2Request request = new ProductGetCatePropertyV2Request();
ProductGetCatePropertyV2Param param = request.getParam();
param.setCategoryLeafId(Long.valueOf(cid));
ProductGetCatePropertyV2Response response = request.execute(accessToken);
Ret checkRet = CommonTool.checkDdApiRetStatus(response);
if (CommonTool.isFailRet(checkRet)) {
return checkRet;
}
// $this->setCategoryAttrV2Cache($cid, $ret['data'], $accessTokenSecret);
return CommonTool.successResult("data", response.getData());
}
private List<StrObjMap> matchSourceAttr(DataItem attribute, JSONObject sourceAttrs, String title) {
List<StrObjMap> matchAttr;
if (attribute.getType().equals(MoveConst.attrInputTypeText)) {
matchAttr = matchProductAttributesByInput(attribute, sourceAttrs);
} else if (attribute.getType().equals(MoveConst.attrInputTypeMultiSelect)) {
matchAttr = matchProductAttributesByMultiSelect(attribute, sourceAttrs, title);
} else if (attribute.getType().equals(MoveConst.attrInputTypeTimeFrame) || attribute.getType().equals(MoveConst.attrInputTypeTimeRange) || attribute.getType().equals(MoveConst.attrInputTypeTimestamp)) {
matchAttr = matchProductAttributesByTimeframe(attribute, sourceAttrs, attribute.getType());
} else {
matchAttr = matchProductAttributesByOption(attribute, sourceAttrs, title);
}
return matchAttr;
}
public List<StrObjMap> matchProductAttributesByOption(DataItem attribute, JSONObject sourceAttrs, String title) {
boolean isReq = CommonTool.isTrue(attribute.getRequired().intValue());
int matchPercent = isReq ? 80 : 100;
TreeMap<Double, Object> matchVids = new TreeMap<>(Collections.reverseOrder());
Map<String, String> matchSourceAttrs = new HashMap<>();
double maxPercent = -1;
String maxMatchAttrValue = attribute.getOptions().get(0).getValue();
StrObjMap sourceValueMap = searchSourceValue(sourceAttrs, attribute.getPropertyName());
String sourceValue = (String) sourceValueMap.get("sourceValue");
sourceValue = getDefaultValueByAttrName(attribute.getPropertyName(), sourceValue);
if (sourceValue != null && !sourceValue.isEmpty()) {
List<String> sourceValueList = splitMultiValueList(sourceValue);
sourceValueList.add(0, sourceValue);
Set<String> uniqueSourceValues = new HashSet<>(sourceValueList);
for (OptionsItem attValue : attribute.getOptions()) {
for (String sv : uniqueSourceValues) {
double percent = getSimilarPercent(attValue.getName(), sv);
if (percent >= matchPercent) {
matchVids.put(percent, attValue.getValue());
matchSourceAttrs.put(attribute.getPropertyName(), sourceValue);
}
if (percent > maxPercent) {
maxMatchAttrValue = attValue.getValue();
maxPercent = percent;
}
}
}
} else {
for (OptionsItem attValue : attribute.getOptions()) {
for (Map.Entry<String, Object> sourceAttr : sourceAttrs.entrySet()) {
List<String> sourceValueList = splitMultiValueList((String) sourceAttr.getValue());
for (String sv : sourceValueList) {
double percent = getSimilarPercent(attValue.getName(), sv);
if (percent >= matchPercent) {
matchVids.put(percent, attValue.getValue());
matchSourceAttrs.put(sourceAttr.getKey(), (String) sourceAttr.getValue());
}
if (percent > maxPercent) {
maxMatchAttrValue = attValue.getValue();
maxPercent = percent;
}
}
}
}
}
if (matchVids.isEmpty()) {
for (OptionsItem attValue : attribute.getOptions()) {
String name = attValue.getName();
if ((title.contains(name) && (name.length() > 1)) || (CommonTool.checkHasOtherKeyword(name) && !name.toLowerCase().contains("海外"))) {
matchVids.put(0D, attValue.getValue());
}
}
}
if (isReq && matchVids.isEmpty()) {
if ("产地".equals(attribute.getPropertyName())) {
for (OptionsItem attValue : attribute.getOptions()) {
if ((attValue.getName()).contains("中国")) {
matchVids.put(0D, attValue.getValue());
break;
}
}
} else if ("面料材质成分含量".equals(attribute.getPropertyName())) {
Pattern pattern = Pattern.compile("(\\d{2})%.*?(\\d{2}|以上|以下)");
for (OptionsItem attValue : attribute.getOptions()) {
Matcher matcher = pattern.matcher((String) attValue.getName());
if (matcher.find()) {
List<Integer> percentages = new ArrayList<>();
for (int i = 1; i <= matcher.groupCount(); i++) {
String value = matcher.group(i);
if ("以下".equals(value)) {
percentages.add(0);
} else if ("以上".equals(value)) {
percentages.add(100);
} else {
percentages.add(Integer.parseInt(value));
}
}
Collections.sort(percentages);
// TODO
// if (sourceValue > percentages.get(0) && sourceValue <= percentages.get(1)) {
// matchVids.put(0D, attValue.getValue());
// break;
// }
}
}
}
}
if (isReq && matchVids.isEmpty()) {
matchVids.put(0D, maxMatchAttrValue);
}
StrObjMap matchAttr = null;
if (!matchVids.isEmpty()) {
Object vid = matchVids.lastKey();
matchAttr = new StrObjMap();
matchAttr.put("name", getValueNameFromAttrOptions(vid, attribute.getOptions()));
matchAttr.put("diy_type", 0);
matchAttr.put("value", vid);
}
if (matchSourceAttrs != null && !matchSourceAttrs.isEmpty()) {
sourceAttrs.keySet().removeAll(matchSourceAttrs.keySet());
}
return matchAttr != null ? Collections.singletonList(matchAttr) : null;
}
public String getValueNameFromAttrOptions(Object valId, List<OptionsItem> options) {
for (OptionsItem option : options) {
if (option.getValue().equals(valId)) {
return option.getName();
}
}
return null;
}
private List<StrObjMap> matchProductAttributesByTimeframe(DataItem attribute, JSONObject sourceAttrs, String type) {
boolean isReq = CommonTool.isTrue(attribute.getRequired().intValue());
StrObjMap sourceValueMap = searchSourceValue(sourceAttrs, attribute.getPropertyName());
String sourceValue = (String) sourceValueMap.get("sourceValue");
double matchMaxPercent = (Double) sourceValueMap.get("matchMaxPercent");
if (!checkInputPropertyMatchPercent(attribute.getPropertyName(), matchMaxPercent)) {
sourceValue = null;
}
String[] rules = {",", "至"};
for (String rule : rules) {
if (sourceValue.contains(rule)) {
String[] timeframe = sourceValue.split(rule);
String startTime = CommonTool.unifiedDateFormat(timeframe[0].trim(), "Y-m-d");
String endTime = CommonTool.unifiedDateFormat(timeframe[1].trim(), "Y-m-d");
if (startTime != null && endTime != null) {
List<StrObjMap> arrs = new ArrayList<>();
arrs.add(createTimeframeEntry(startTime));
arrs.add(createTimeframeEntry(endTime));
return type.equals(MoveConst.attrInputTypeTimestamp) ? new ArrayList<StrObjMap>() {{
add(arrs.get(0));
}} : arrs;
}
}
}
sourceValue = CommonTool.unifiedDateFormat(sourceValue, "Y-m-d");
if (sourceValue == null || sourceValue.isEmpty()) {
sourceValue = "";
}
if (isReq && sourceValue.isEmpty()) {
sourceValue = getMockSourceAttrValue((String) attribute.getPropertyName());
}
StrObjMap arr = createTimeframeEntry(sourceValue);
return type.equals(MoveConst.attrInputTypeTimestamp) ? new ArrayList<StrObjMap>() {{
add(arr);
}} : new ArrayList<StrObjMap>() {{
add(arr);
add(arr);
}};
}
private StrObjMap createTimeframeEntry(String dateValue) {
StrObjMap entry = new StrObjMap();
entry.put("name", dateValue);
entry.put("diy_type", 0);
entry.put("value", 0);
return entry;
}
public List<StrObjMap> matchProductAttributesByMultiSelect(DataItem attribute, JSONObject sourceAttrs, String title) {
boolean isReq = CommonTool.isTrue(attribute.getRequired().intValue());
int matchPercent = isReq ? 80 : 100;
Map<Long, OptionsItem> matchVids = new HashMap<>();
Map<String, String> matchSourceAttrs = new HashMap<>();
double maxPercent = -1;
List<OptionsItem> options = attribute.getOptions();
OptionsItem maxMatchAttr = options.get(0);
StrObjMap searchResult = searchSourceValue(sourceAttrs, attribute.getPropertyName());
String sourceValue = (String) searchResult.get("sourceValue");
sourceValue = getDefaultValueByAttrName(attribute.getPropertyName(), sourceValue);
if (sourceValue != null && !sourceValue.isEmpty()) {
List<String> sourceValueList = splitMultiValueList(sourceValue);
for (OptionsItem attValue : options) {
for (String sv : sourceValueList) {
if (sv.equals(attValue.getName())) {
matchVids.put(attValue.getValueId(), attValue);
matchSourceAttrs.put(attribute.getPropertyName(), sourceValue);
}
}
}
if (matchVids.size() >= attribute.getMultiSelectMax() || matchVids.size() >= 1) {
matchVids = new LinkedHashMap<>(CommonTool.sliceMap(matchVids, attribute.getMultiSelectMax().intValue()));
// TODO
//return finishMatch(matchVids, matchSourceAttrs);
}
for (OptionsItem attValue : options) {
for (String sv : sourceValueList) {
double percent = getSimilarPercent(attValue.getName(), sv);
if (percent >= matchPercent) {
matchVids.put(attValue.getValueId(), attValue);
matchSourceAttrs.put(attribute.getPropertyName(), sourceValue);
}
if (percent > maxPercent) {
maxMatchAttr = attValue;
maxPercent = percent;
}
}
}
} else {
for (OptionsItem attValue : options) {
for (Map.Entry sourceAttr : sourceAttrs.entrySet()) {
List<String> sourceValueList = splitMultiValueList((String) sourceAttr.getValue());
for (String sv : sourceValueList) {
double percent = getSimilarPercent((String) attValue.getName(), sv);
if (percent >= matchPercent) {
matchVids.put(attValue.getValueId(), attValue);
matchSourceAttrs.put(String.valueOf(sourceAttr.getKey()), (String) sourceAttr.getValue());
}
if (percent > maxPercent) {
maxMatchAttr = attValue;
maxPercent = percent;
}
}
}
}
}
if (matchVids.isEmpty()) {
for (OptionsItem attValue : options) {
if (title.contains(attValue.getName()) || CommonTool.checkHasOtherKeyword((String) attValue.getName())) {
matchVids.put((Long) attValue.getValueId(), attValue);
}
}
}
List<StrObjMap> matchAttrList = new ArrayList<>();
if (isReq && matchVids.isEmpty()) {
//TODO 这里没有字段
//matchVids.put((Integer) maxMatchAttr.get("attrValueID"), maxMatchAttr);
}
for (OptionsItem matchVid : matchVids.values()) {
StrObjMap matchAttr = new StrObjMap();
matchAttr.put("name", matchVid.getName());
matchAttr.put("diy_type", 0);
matchAttr.put("value", matchVid.getValue());
matchAttrList.add(matchAttr);
}
return matchAttrList.subList(0, attribute.getMultiSelectMax().intValue());
}
private List<String> splitMultiValueList(String sourceValue) {
sourceValue = sourceValue.trim();
List<String> sourceValueList = splitAndFilter(sourceValue, ",");
if (sourceValueList.size() == 1) {
sourceValueList = splitAndFilter(sourceValue, "");
}
if (sourceValueList.size() == 1) {
sourceValueList = splitAndFilter(sourceValue, " ");
}
if (sourceValueList.size() == 1) {
sourceValueList = splitAndFilter(sourceValue, "、");
}
if (sourceValueList.size() == 1) {
sourceValueList = splitAndFilter(sourceValue, "/");
}
return sourceValueList;
}
private List<String> splitAndFilter(String value, String delimiter) {
return Arrays.stream(value.split(delimiter)).map(String::trim).filter(str -> !str.isEmpty()).collect(Collectors.toList());
}
private List<StrObjMap> matchProductAttributesByInput(DataItem attribute, JSONObject sourceAttrs) {
List<Map<String, Object>> matchSourceAttrs = new ArrayList<>();
boolean isReq = CommonTool.isTrue(attribute.getRequired().intValue());
StrObjMap result = searchSourceValue(sourceAttrs, attribute.getPropertyName());
String sourceValue = (String) result.get("sourceValue");
double matchMaxPercent = (Double) result.get("matchMaxPercent");
if (!checkInputPropertyMatchPercent(attribute.getPropertyName(), matchMaxPercent)) {
sourceValue = null;
}
sourceValue = getDefaultValueByAttrName(attribute.getPropertyName(), sourceValue);
if (sourceValue == null && !isReq) {
return null;
}
sourceValue = CommonTool.clearAliasSpechars(sourceValue);
sourceValue = sourceValue.replace(' ', ' ');
if (isReq && sourceValue.isEmpty()) {
sourceValue = getMockSourceAttrValue(attribute.getPropertyName());
}
if (!"品牌".equals(attribute.getPropertyName())) {
sourceValue = sourceValue.replace("/", "\\").replace("*", "x");
}
if ("保质期".equals(attribute.getPropertyName()) && sourceValue != null) {
// 正则表达式的作用: 1. 保质期的单位统一为天 2. 保质期的数字统一为整数
Pattern pattern = Pattern.compile("(\\d+).+([天月年])");
Matcher matcher = pattern.matcher(sourceValue);
if (matcher.find()) {
sourceValue = matcher.group(1) + matcher.group(2);
} else if (Integer.parseInt(sourceValue) >= 30) {
sourceValue += "天";
} else if (sourceValue.toLowerCase().contains("长期")) {
sourceValue = "3年";
}
}
if (!matchSourceAttrs.isEmpty()) {
if (sourceAttrs.containsKey(attribute.getPropertyName())) {
sourceAttrs.remove(attribute.getPropertyName());
} else {
for (String key : sourceAttrs.keySet()) {
sourceAttrs.remove(key);
}
}
}
if (sourceValue != null) {
StrObjMap matchAttr = new StrObjMap();
matchAttr.put("name", sourceValue);
matchAttr.put("diy_type", 0);
matchAttr.put("value", 0);
return Collections.singletonList(matchAttr);
}
return null;
}
private String getMockSourceAttrValue(String name) {
Map<String, String> mockNameArray = new HashMap<>();
mockNameArray.put("加工周期", "1");
mockNameArray.put("主面料成分的含量", "1");
mockNameArray.put("特殊用途化妆品证号", "国妆特字G20150536");
mockNameArray.put("计量单位", "件");
mockNameArray.put("生产日期", LocalDate.now().toString());
String defaultValue = "";
return mockNameArray.getOrDefault(name, defaultValue);
}
private String getDefaultValueByAttrName(String propertyName, String sourceValue) {
if (!sourceValue.isEmpty()) {
return sourceValue;
}
String[] defaultAttrName = {"专利", "是否属于礼品", "进口", "是否跨境货源"};
for (String temp : defaultAttrName) {
if (propertyName.contains(temp)) {
return "否";
}
}
return "";
}
private boolean checkInputPropertyMatchPercent(String propertyName, double matchMaxPercent) {
int minPercent = 100;
String[] needExactMatchArray = {"认证编号"};
for (String text : needExactMatchArray) {
if (propertyName.contains(text) && matchMaxPercent < minPercent) {
return false;
}
}
return true;
}
private StrObjMap searchSourceValue(JSONObject sourceAttrs, String parName) {
StrObjMap objMap = new StrObjMap();
String sourceValue = sourceAttrs.getString(parName);
if (sourceValue != null && !sourceValue.isEmpty()) {
objMap.put("sourceValue", sourceValue);
objMap.put("matchMaxPercent", 100);
return objMap;
}
List<String> similarNameArr = new ArrayList<>();
String similarNameArrStr = getSourceAttrsSimilarName(parName);
similarNameArr.add(similarNameArrStr);
for (String similarName : similarNameArr) {
sourceValue = sourceAttrs.getString(similarName);
if (sourceValue != null && !sourceValue.isEmpty()) {
objMap.put("sourceValue", sourceValue);
objMap.put("matchMaxPercent", 100);
}
}
double maxPercent = -1;
String[] parNames = parName.split("/");
for (String newParName : parNames) {
sourceValue = sourceAttrs.getString(newParName);
if (sourceValue != null && !sourceValue.isEmpty()) {
break;
}
for (Map.Entry<String, Object> entry : sourceAttrs.entrySet()) {
if (entry.getKey().toLowerCase().contains(newParName.toLowerCase())) {
double percent = getSimilarPercent(entry.getKey(), newParName);
if (percent > maxPercent) {
sourceValue = (String) entry.getValue();
maxPercent = percent;
}
}
}
if (sourceValue != null && !sourceValue.isEmpty()) {
break;
}
}
if (sourceValue != null && !sourceValue.isEmpty()) {
objMap.put("sourceValue", sourceValue);
objMap.put("matchMaxPercent", maxPercent);
return objMap;
}
for (Map.Entry<String, Object> entry : sourceAttrs.entrySet()) {
String[] tempSourceAttrNames = entry.getKey().split("/");
for (String tempSourceAttrName : tempSourceAttrNames) {
if (parName.toLowerCase().contains(tempSourceAttrName.toLowerCase())) {
double percent = getSimilarPercent(tempSourceAttrName, parName);
if (percent > maxPercent) {
sourceValue = (String) entry.getValue();
maxPercent = percent;
}
}
}
}
objMap.put("sourceValue", sourceValue);
objMap.put("matchMaxPercent", maxPercent);
return objMap;
}
private String getSourceAttrsSimilarName(String parName) {
Map<String, String> similarArray = new HashMap<>();
similarArray.put("CCC证书编号", "3C认证证书编号");
similarArray.put("上市年份季节", "上市时间");
similarArray.put("面料材质成分含量", "主面料成分的含量");
return similarArray.containsKey(parName) ? similarArray.get(parName) : parName;
}
private double getSimilarPercent(String first, String second) {
List<String> noArr = Arrays.asList("无", "否");
if (noArr.contains(first) && noArr.contains(second)) {
return 100.0;
}
List<String> replace = Arrays.asList("(", ")", "", "");
double percent1 = getJaroWinklerDistance(first, second);
double percent2 = getJaroWinklerDistance(first, replaceAll(second, replace, ""));
double percent3 = getJaroWinklerDistance(replaceAll(first, replace, ""), second);
double percent4 = getJaroWinklerDistance(replaceAll(first, replace, ""), replaceAll(second, replace, ""));
return 100.0 * Math.max(Math.max(percent1, percent2), Math.max(percent3, percent4));
}
private double getJaroWinklerDistance(String first, String second) {
return StringUtils.getJaroWinklerDistance(first, second);
}
private String replaceAll(String input, List<String> patterns, String replacement) {
for (String pattern : patterns) {
input = input.replace(pattern, replacement);
}
return input;
}
// TODO 暂时没用到
public CateAttributeResultBO getCateBrandMapAndIsBrandReqAndBrandAid(List<AttributeBO> cateAttributes) {
Map<Integer, String> cateBrandMap = new HashMap<>();
boolean isBrandReq = false;
int brandAid = 0;
for (AttributeBO attribute : cateAttributes) {
String currAttrName = attribute.getPropertyName();
if ("品牌".equals(currAttrName)) {
brandAid = attribute.getPropertyId();
isBrandReq = CommonTool.isTrue(attribute.getRequired());
for (AttributeBO.Option option : attribute.getOptions()) {
cateBrandMap.put(option.getValue(), option.getName());
}
}
}
return new CateAttributeResultBO(cateBrandMap, isBrandReq, brandAid);
}
private StrObjMap buildProductSkuInfos(JSONObject moveBaseData, MoveProductPublishQueueBO queueMsg, String itemNum) {
MoveShopSettingBO condition = queueMsg.getCondition();
moveBaseData = rebuildProductSkuMap(moveBaseData, condition);
@ -1416,7 +1954,7 @@ public class ProcessProductPublishTaskService extends TaskBaseService {
imgUrls = filterImgUrlArgs(imgUrls);
imgUrls = checkImageHeightAndSegmentationImage(imgUrls);
if (!imgUrls.isEmpty()) {
return String.join("\\|", imgUrls);
return String.join("|", imgUrls);
} else {
return productImgList.remove(0);
}
@ -1497,42 +2035,7 @@ public class ProcessProductPublishTaskService extends TaskBaseService {
}
private List<String> extractImgUrls(String input) {
List<String> matchUrls = new ArrayList<>();
String pattern1 = "background\\s*=\\s*(?:'|\\\")\\s*([^<>]*)(?:'|\\\")\\s*";
Pattern p1 = Pattern.compile(pattern1, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m1 = p1.matcher(input);
while (m1.find()) {
matchUrls.add(m1.group(1));
}
String pattern2 = "background\\s*:\\s*url\\((?:'|\\\"|)([^<>]*)(?:'|\\\"|)\\)";
Pattern p2 = Pattern.compile(pattern2, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m2 = p2.matcher(input);
while (m2.find()) {
matchUrls.add(m2.group(1));
}
String pattern3 = "src\\s*=\\s*[\"|'](.*)[\"|']";
Pattern p3 = Pattern.compile(pattern3, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m3 = p3.matcher(input);
while (m3.find()) {
if (m3.group(1).matches(".*(?<!/)$")) {
matchUrls.add(m3.group(1));
}
}
List<String> newImgUrls = new ArrayList<>();
for (String originUrl : matchUrls) {
if (originUrl.endsWith(".mp4")) {
continue;
}
if (originUrl.startsWith("http")) {
newImgUrls.add(originUrl);
} else {
newImgUrls.add("http:" + originUrl);
}
}
List<String> newImgUrls = CommonTool.getUrlsFromHtml(input);
return new ArrayList<>(new HashSet<>(newImgUrls));
}
@ -1616,31 +2119,6 @@ public class ProcessProductPublishTaskService extends TaskBaseService {
return getMoveBaseDataRet;
}
private void archiveMoveDetailExtDataToOss(long shopId, long moveCollectTaskDetailId, Object sourceAttrs) {
// if (!($logObj instanceof ZcLog)) {
// $logObj = Zc::getLog('move/archive_move_collect_task_detail_ext', ZcLog::INFO);
// }
// $onlyReadDb = empty($sourceAttrs);
// $taskDetailExt = $this->getMoveCollectTaskDetailExt($shopId, $moveCollectTaskDetailId, $onlyReadDb);
// if (empty($taskDetailExt)) {
// return CommonTool::successResult();
// }
//
// if (!empty($sourceAttrs)) {
// $taskDetailExt['source_attrs'] = $sourceAttrs;
// }
//
// $saveOssRet = $this->saveMoveProductAndSkusToOss($shopId, $moveCollectTaskDetailId, $taskDetailExt);
// if (CommonTool::isFailRet($saveOssRet)) {
// $logObj->info("archiveMoveDetailExtDataToOss saveMoveProductAndSkusToOss shopId[{$shopId}] mctdId[{$moveCollectTaskDetailId}] archiveMoveDetailData " . print_r($taskDetailExt, true) . '\n ret : ' . print_r($saveOssRet, true));
// return $saveOssRet;
// }
//
// $delRet = $this->delMoveTaskCollectTaskDetailExtById($moveCollectTaskDetailId, $shopId);
// $logObj->info("del task detail ext data [{$delRet}]");
// return CommonTool::successResult();
}
private Ret getMoveBaseData(MoveProductPublishQueueBO queueMsg, JSONObject sourceProductData) {
sourceProductData.remove("proxyCenterRespData");
log.info("get sourceProductData: " + JSON.toJSONString(sourceProductData));
@ -1654,97 +2132,6 @@ public class ProcessProductPublishTaskService extends TaskBaseService {
return CommonTool.successResult("moveBaseData", moveBaseData);
}
private Ret buildMatchCateCidParam(long shopId) {
Map<Long, Category> mProductLastCateMap = getAllLeafProductCatList(shopId);
Map<Long, CategoryBO> productLastCateMap = buildProductLastCatesMap(mProductLastCateMap);
// StrObjMap allRewriteCidRules = getAllRewriteCidRules(false);
// StrObjMap productLastCatesNameListMap = buildProductLastCatesNameListMap(productLastCateMap, allRewriteCidRules);
StrObjMap sourceCategoryMap = getSourceCategoryMap(shopId);
StrObjMap params = new StrObjMap();
params.put("productLastCateMap", productLastCateMap);
// params.put("productLastCatesNameListMap", productLastCatesNameListMap);
params.put("sourceCategoryMap", sourceCategoryMap);
return CommonTool.successResult("params", params);
}
private StrObjMap getSourceCategoryMap(long shopId) {
// $redisKey = RedisKeyConst::getSourceCategoryMapKey($shopId);
// $sourceCategoryMap = $this->redis->get($redisKey);
// if ($sourceCategoryMap) {
// return unserialize($sourceCategoryMap);
// }
//
// $authShopIds = [$shopId];
// list($matchSourceCategoryMap, $blackSourceCategoryMap) = $this->sourceCategoryService->getSourceCategoryMapByShopIds($authShopIds);
//
// $sourceCategoryMap = [
// 'matchSourceCategoryMap' => $matchSourceCategoryMap,
// 'blackSourceCategoryMap' => $blackSourceCategoryMap,
// ];
// $this->redis->setex($redisKey, 3600 * 24, serialize($sourceCategoryMap));
// return $sourceCategoryMap;
return null;
}
/**
*
*
* @param productLastCateMap
* @param allRewriteCidRules
* @return
*/
private StrObjMap buildProductLastCatesNameListMap(Map<Long, CategoryBO> productLastCateMap, StrObjMap allRewriteCidRules) {
// $lastCatesNameList = array();
// foreach ($productLastCatesList as $lastCate) {
// $cid = $lastCate['cid'];
//// if ($allRewriteCidRules[$cid]) {
//// continue;
//// }
// $multiKeywords = false;
// $name = strtolower($lastCate['name']);
// $nameList = explode('/', $name);
// if (count($nameList) > 1) {
// $multiKeywords = true;
// $nameList[] = $name;
// $nameList = array_unique($nameList);
// }
//
// $nameListCopy = $nameList;
// foreach ($nameListCopy as $name) {
// $nameFilterMan = trim(str_ireplace(['男士', '男式'], '', $name));
// if (!empty($nameFilterMan)) {
// $nameList[] = $nameFilterMan;
// }
// $nameFilterWoman = trim(str_ireplace(['女士', '女式'], '', $name));
// if (!empty($nameFilterWoman)) {
// $nameList[] = $nameFilterWoman;
// }
// }
//
// $nameList = array_unique($nameList);
// foreach ($nameList as $name) {
// if ($multiKeywords && mb_strlen($name) === 1) {
// continue;
// }
// $lastCatesNameList[$name][] = $lastCate;
// }
// }
// //按照字数多少排序,确保字数多的先匹配
// $names = array_keys($lastCatesNameList);
// usort($names, function($name1, $name2) {
// return (mb_strlen($name1) > mb_strlen($name2)) ? -1 : 1;
// });
//
// $sortLastCatesNameList = array();
// foreach ($names as $name) {
// $sortLastCatesNameList[$name] = $lastCatesNameList[$name];
// }
//
// return $sortLastCatesNameList;
return null;
}
private Map<Long, CategoryBO> buildProductLastCatesMap(Map<Long, Category> productCateList) {
Map<Long, CategoryBO> productLastCatesList = new HashMap<>();
productCateList.forEach((cid, category) -> {
@ -1918,8 +2305,7 @@ public class ProcessProductPublishTaskService extends TaskBaseService {
if (StrUtil.isBlank(taskDetail.getNotes())) {
return CommonTool.failResult("商品描述必填~~");
}
} else if (sourceProductData.getString("notes") == null || sourceProductData.getString("notes").isEmpty() &&
taskDetail.getCondition().getDesc().getString("descCopyType").equals(MoveConst.descCopyTypeCopy)) {
} else if (sourceProductData.getString("notes") == null || sourceProductData.getString("notes").isEmpty() && taskDetail.getCondition().getDesc().getString("descCopyType").equals(MoveConst.descCopyTypeCopy)) {
return CommonTool.failResult("商品描述必填~~");
}

@ -3,11 +3,15 @@ package com.ms.api.tool;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.crypto.Cipher;
@ -587,6 +591,26 @@ public class CommonTool {
return Arrays.stream(array).collect(Collectors.toList());
}
public static boolean isTrue(int input) {
return input == 1;
}
/**
* htmlurl
* @param input
* @return
*/
public static List<String> getUrlsFromHtml(String input) {
List<String> matchUrls = new ArrayList<>();
Pattern pattern = Pattern.compile("<img[^>]*src=[\"']([^\"']+)[\"'][^>]*>");
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
matchUrls.add(matcher.group(1));
}
return matchUrls;
}
public static void main(String[] args) {
System.out.println(splitWithComma("6921394317136631525|6921399584322230185|6921393247513351270|6921412710844995353"));
@ -606,4 +630,60 @@ public class CommonTool {
}
return num;
}
public static String clearAliasSpechars(String subject) {
subject = subject.replace("", "(")
.replace("", ")")
.replace("—", "-")
.replace("", "-")
.replace("×", "x");
String filterSubject = subject.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5\\s@#\\\\$%&+\\-\\/\\\\\\\\_()=.*!]", "");
return filterSubject.isEmpty()? subject : filterSubject;
}
public static <K, V> Map<K, V> sliceMap(Map<K, V> inputMap, int count) {
Map<K, V> resultMap = new LinkedHashMap<>();
int i = 0;
for (Map.Entry<K, V> entry : inputMap.entrySet()) {
if (i++ == count) break;
resultMap.put(entry.getKey(), entry.getValue());
}
return resultMap;
}
public static String unifiedDateFormat(String date, String format) {
try {
LocalDate parsedDate = LocalDate.parse(date);
return parsedDate.format(DateTimeFormatter.ofPattern(format));
} catch (DateTimeParseException e) {
DateTimeFormatter originalFormat = null;
if (date.contains(".")) {
originalFormat = DateTimeFormatter.ofPattern("yyyy.MM.dd");
} else if (date.contains("年") && date.contains("月") && date.contains("日")) {
originalFormat = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
}
if (originalFormat != null) {
try {
LocalDate parsedDate = LocalDate.parse(date, originalFormat);
return parsedDate.format(DateTimeFormatter.ofPattern(format));
} catch (DateTimeParseException ex) {
}
}
}
return null;
}
public static boolean checkHasOtherKeyword(String word) {
if (word.contains("其它") || word.contains("其他") || word.contains("通用")) {
return true;
} else {
return false;
}
}
}

@ -5,4 +5,7 @@ public class MoveTool {
public static String getAllLeafProductCatListOssPath(long shopId) {
return "move/batch/allLeafProductCatList_" + shopId + ".txt";
}
public static String getAllProductCatTreeOssPath() {
return "move/batch/getSimpleProductCatTree.txt";
}
}

@ -6,14 +6,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @Author: laixw
* @Date: 2023/8/22
*/
@SpringBootApplication(scanBasePackages = {"com.ms","com.jinritemai"})
@MapperScan("com.ms.dal.mapper")
@EnableAsync
@EnableScheduling
//@EnableScheduling
public class MsApplication {
public static void main(String[] args) {

@ -0,0 +1,104 @@
package com.ms.test;
import com.ms.api.consts.CommonConst;
import com.ms.api.tool.CommonTool;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GetUrlFromHtmlTest {
public List<String> extractImgUrls(String input) {
List<String> matchUrls = new ArrayList<>();
String pattern1 = "background\\s*=\\s*(?:'|\\\")\\s*([^<>]*)(?:'|\\\")\\s*";
Pattern p1 = Pattern.compile(pattern1, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m1 = p1.matcher(input);
while (m1.find()) {
matchUrls.add(m1.group(1));
}
String pattern2 = "background\\s*:\\s*url\\((?:'|\\\"|)([^<>]*)(?:'|\\\"|)\\)";
Pattern p2 = Pattern.compile(pattern2, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m2 = p2.matcher(input);
while (m2.find()) {
matchUrls.add(m2.group(1));
}
String pattern3 = "src\\s*=\\s*[\"|'](.*)[\"|']";
Pattern p3 = Pattern.compile(pattern3, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m3 = p3.matcher(input);
while (m3.find()) {
if (m3.group(1).matches(".*(?<!/)$")) {
matchUrls.add(m3.group(1));
}
}
List<String> newImgUrls = new ArrayList<>();
for (String originUrl : matchUrls) {
if (originUrl.endsWith(".mp4")) {
continue;
}
if (originUrl.startsWith("http")) {
newImgUrls.add(originUrl);
} else {
newImgUrls.add("http:" + originUrl);
}
}
return new ArrayList<>(new HashSet<>(newImgUrls));
}
public static void main(String[] args) {
String input = "<div id=\"offer-template-0\"></div><p style=\"text-align: center;\"><span style=\"color: #ff0000;font-size: 26.0pt;\"><img alt=\"im2Ti/iky9QSPhtB9FO7xmy5X0TG5V9u3RvN\" src=\"https://cbu01.alicdn.com/img/ibank/O1CN01Jo7k0u29J7QfgSnqO_!!995828046-0-cib.jpg\" alt=\"IMG_1266(20210611-082535)_副本\"/><br/>乌龙铁观音茶叶(<span style=\"color: #000000;\">实图拍摄</span>)还有更多中低档茶叶量大可直接联系掌柜</span></p>\n" +
"<p style=\"text-align: center;\"><span style=\"color: #ff0000;font-size: 12.0pt;\"> <strong>厂家直销乌龙茶中低档安溪铁观音1725铁观音青茶花香味</strong></span></p>\n" +
"<p style=\"text-align: left;\"><span style=\"color: #ff0000;font-size: 12.0pt;\"><strong> 茶农师傅经典制作的新茶上市,减少中间环节,</strong><strong>其每道制作工艺由经验丰富老茶师亲手筛选、炒制、层层把关、严格控制. 观其形-外观紧结、沉重、呈沙绿色察其色-汤色清澈、淡黄微绿闻其香-浓韵、观音韵、带有兰花香品其味-鲜纯、浓爽、音韵明显、回甘较久!价格实惠产地货源!不可多得哦!</strong></span></p>\n" +
"<p style=\"text-align: left;\"><span style=\"color: #ff0000;font-size: 12.0pt;\">主要特点:</span></p>\n" +
"<p style=\"text-align: left;\"><span style=\"color: #ff0000;font-size: 12.0pt;\">【茶树新】铁观音茶树更新,滋味就更鲜、更甘醇。</span></p>\n" +
"<div style=\"text-align: center;\">\n" +
"<p style=\"text-align: left;\"><span style=\"color: #ff0000;font-size: 12.0pt;\">【手工】严格按照传统手工制作,干茶砂绿色明显,因走水充分汤色黄绿、明亮;汤味滑、活、厚,香气浓郁、观音韵明显,回味甘甜,口齿留香;叶底色黄绿,有光泽,底片柔软。</span></p>\n" +
"<p style=\"text-align: center;\"><span style=\"color: #000000;font-size: 22.0pt;font-family: simhei;\">实图拍摄,盗图必究</span></p>\n" +
"</div>\n" +
"<p style=\"text-align: center;\"><span><img src=\"https://cbu01.alicdn.com/img/ibank/2014/672/647/1390746276_1412110255.jpg\" alt=\"12\" width=\"751\" height=\"697\"/></span></p>\n" +
"<p> </p>\n" +
"<p><img style=\"display: block;margin-left: auto;margin-right: auto;\" src=\"https://cbu01.alicdn.com/img/ibank/2014/201/792/1390297102_1412110255.jpg\" alt=\"undefined\" width=\"749\" height=\"696\"/></p>\n" +
"<p><br/><img style=\"display: block;margin-left: auto;margin-right: auto;\" src=\"https://cbu01.alicdn.com/img/ibank/2016/710/774/2794477017_1412110255.jpg\" alt=\"124\" width=\"752\" height=\"752\"/></p>\n" +
"<p style=\"text-align: center;\"> <img src=\"https://cbu01.alicdn.com/img/ibank/2017/694/637/3871736496_1412110255.jpg\" alt=\"5715fc48N4af9cb31\" width=\"751\" height=\"751\"/> <img src=\"https://cbu01.alicdn.com/img/ibank/2018/977/697/8940796779_1412110255.jpg\" alt=\"IMG_0598\" width=\"751\" height=\"755\"/></p>\n" +
"<p style=\"text-align: center;\"><img src=\"https://cbu01.alicdn.com/img/ibank/2017/022/100/3970001220_1983945663.jpg\" alt=\"undefined\"/></p>\n" +
"<p style=\"text-align: center;\"><img src=\"https://cbu01.alicdn.com/img/ibank/2017/881/400/3970004188_1983945663.jpg\" alt=\"undefined\"/></p>\n" +
"<p style=\"text-align: center;\"><img style=\"line-height: 1.5;\" src=\"https://cbu01.alicdn.com/img/ibank/2017/682/100/3970001286_1983945663.jpg\" alt=\"undefined\"/></p>\n" +
"<p style=\"text-align: center;\"><img src=\"https://cbu01.alicdn.com/img/ibank/2017/844/798/3972897448_1983945663.jpg\" alt=\"undefined\"/><span style=\"line-height: 1.5;\">   </span> <img src=\"https://cbu01.alicdn.com/img/ibank/2018/766/300/8901003667_1412110255.jpg\" alt=\"IMG_3730\" width=\"790\" height=\"790\"/></p>\n" +
"<p style=\"text-align: center;\"><span style=\"color: #ff0000;font-size: 24.0pt;\">小泡真空包装袋随市场更新而更换,介意的亲们请备注</span></p>\n" +
"<p style=\"text-align: center;\"><span style=\"color: #ff0000;font-size: 24.0pt;\"><img src=\"https://cbu01.alicdn.com/img/ibank/2018/125/635/10218536521_1412110255.jpg\" alt=\"undefined\" width=\"790\" height=\"526.6666666666666\"/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2018/240/875/10218578042_1412110255.jpg\" alt=\"undefined\" width=\"790\" height=\"526.6666666666666\"/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2018/727/466/10194664727_1412110255.jpg\" alt=\"undefined\" width=\"790\" height=\"526.6666666666666\"/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2018/346/125/10218521643_1412110255.jpg\" alt=\"undefined\" width=\"790\" height=\"526.6666666666666\"/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2018/734/155/10218551437_1412110255.jpg\" alt=\"undefined\" width=\"790\" height=\"526.6666666666666\"/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2018/547/780/10167087745_1412110255.jpg\" alt=\"undefined\" width=\"790\" height=\"526.6666666666666\"/><br/>礼盒规格38*29*10厘米</span></p>\n" +
"<p style=\"text-align: center;\"><span style=\"font-family: simhei;font-size: 15.0pt;\">挑完梗后真空包装,使用全自动真空包装,茶叶不落地,干净卫生</span></p>\n" +
"<p style=\"text-align: center;\"><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2014/300/296/1390692003_1412110255.jpg\" alt=\"机器\" width=\"750\" height=\"562\"/><br/><br/></p>\n" +
"<p style=\"text-align: center;\"><img src=\"https://cbu01.alicdn.com/img/ibank/2013/649/894/816498946_1412110255.jpg\" alt=\"20130412_120307\" width=\"750\" height=\"562\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2013/058/994/816499850_1412110255.jpg\" alt=\"20130415_113407\" width=\"750\" height=\"1000\"/></p>\n" +
"<p style=\"text-align: center;\"> </p>\n" +
"<p style=\"text-align: center;\"> <img src=\"https://cbu01.alicdn.com/img/ibank/2018/316/448/8940844613_1412110255.jpg\" alt=\"IMG_1127_副本\" width=\"752\" height=\"790\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2018/820/400/8921004028_1412110255.jpg\" alt=\"IMG_1128_副本\" width=\"753\" height=\"790\"/><br/><br/></p>\n" +
"<p style=\"text-align: center;\"><span><img src=\"https://cbu01.alicdn.com/img/ibank/2018/337/630/8901036733_1412110255.jpg\" alt=\"IMG_1012\" width=\"752\" height=\"1412\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/O1CN01qeSC8m29J7Qhhp5mE_!!995828046-0-cib.jpg\" alt=\"undefined\" width=\"790\" height=\"1223.2482394366198\"/><br/><br/></span></p>\n" +
"<p style=\"text-align: center;\"><img style=\"display: block;margin-left: auto;margin-right: auto;\" src=\"https://cbu01.alicdn.com/img/ibank/2012/554/070/546070455_1412110255.jpg\" width=\"752\" height=\"590\"/></p>\n" +
"<p style=\"text-align: center;\"> </p>\n" +
"<p style=\"text-align: center;\"><img style=\"display: block;margin-left: auto;margin-right: auto;\" src=\"https://cbu01.alicdn.com/img/ibank/2012/274/070/546070472_1412110255.jpg\" width=\"742\" height=\"553\"/></p>\n" +
"<p style=\"text-align: center;\"> </p>\n" +
"<p style=\"text-align: center;\"><img style=\"display: block;margin-left: auto;margin-right: auto;\" src=\"https://cbu01.alicdn.com/img/ibank/2013/120/951/761159021_1412110255.jpg\" alt=\"茶季忙时\" width=\"750\" height=\"499\"/></p>\n" +
"<p style=\"text-align: center;\"><br/><img style=\"display: block;margin-left: auto;margin-right: auto;\" src=\"https://cbu01.alicdn.com/img/ibank/2013/620/951/761159026_1412110255.jpg\" alt=\"茶季忙时\" width=\"750\" height=\"499\"/><br/><img style=\"display: block;margin-left: auto;margin-right: auto;\" src=\"https://cbu01.alicdn.com/img/ibank/2013/230/951/761159032_1412110255.jpg\" alt=\"茶季忙时\" width=\"750\" height=\"499\"/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2013/450/951/761159054_1412110255.jpg\" alt=\"茶季忙时\" width=\"748\" height=\"498\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2013/340/951/761159043_1412110255.jpg\" alt=\"茶季忙时\" width=\"750\" height=\"499\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2016/687/693/3038396786_1412110255.jpg\" alt=\"dbb44aed2e738bd4615cb861a18b87\" width=\"753\" height=\"503\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2016/631/816/3037618136_1412110255.jpg\" alt=\"mmexport1462243402203\" width=\"758\" height=\"748\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2016/611/819/3039918116_1412110255.jpg\" alt=\"mmexport1462243413897\" width=\"758\" height=\"567\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2013/370/951/761159073_1412110255.jpg\" alt=\"茶季忙时\" width=\"751\" height=\"555\"/><br/><br/><img src=\"https://cbu01.alicdn.com/img/ibank/2016/181/039/3039930181_1412110255.jpg\" alt=\"mmexport1461107560050\" width=\"747\" height=\"622\"/><br/><br/></p>\n" +
"<p style=\"text-align: left;\" align=\"left\"><span style=\"font-size: 12.0pt;\"><strong>邮资说明:</strong></span></p>\n" +
"<p style=\"text-align: left;\"><span style=\"font-size: 12.0pt;\"> </span></p>\n" +
"<p style=\"text-align: left;\" align=\"left\"><span style=\"font-size: 12.0pt;\">为了保证运输安全包装都外加一个PVC硬盒/纸箱为了增加效率统一采用快递一般3天内到达优先使用快递快递不能到达的地方使用EMS运费算法详细见报价单<br/>☆ 可随时查询定单运送情况:订单有快递跟踪记录也可直接联系掌柜查询。<br/>☆也可以备注需要发什么快递</span></p>";
GetUrlFromHtmlTest test = new GetUrlFromHtmlTest();
List<String> urlsA = test.extractImgUrls(input);
List<String> urlsB = CommonTool.getUrlsFromHtml(input);
for (String url : urlsA) {
System.out.println(url);
}
System.out.println("============================");
for (String url : urlsB) {
System.out.println(url);
}
}
}
Loading…
Cancel
Save