图库洗词,导入分类最大限额

This commit is contained in:
liyj 2025-09-23 15:59:40 +08:00
parent 4699a7a90c
commit 1ae6a7a0aa
6 changed files with 5827 additions and 34 deletions

View File

@ -31,7 +31,7 @@ import static com.suisung.mall.common.utils.ProductTitleUtil.*;
public class JiebaUtils {
private static final Logger log = LoggerFactory.getLogger(JiebaUtils.class);
private final JiebaSegmenter segmenter = new JiebaSegmenter();
private static final JiebaSegmenter segmenter = new JiebaSegmenter();
// 中文保护标记不会被分割
private static final String PROTECT_START = "开始";
private static final String PROTECT_END = "结束";
@ -48,9 +48,9 @@ public class JiebaUtils {
private static final Pattern SPEC_REGEX = Pattern.compile("\\d+[a-zA-Z]+[*]\\d+"); // 匹配500L*10
private static final Pattern MIXED_REGEX = Pattern.compile("[a-zA-Z]+[-]?\\d+"); // 匹配RSCW-1949
private static final Pattern DIMENSION_REGEX = Pattern.compile("\\d+(?:\\\\.\\\\d+)?[\\u4e00-\\u9fa5a-zA-Z]+"); // 匹配维度如2.0*2.3
private static final Pattern UNIT_CHN_REGEX = Pattern.compile("([0-9零一二三四五六七八九十百千万亿]+|\\d*\\.?\\d+)\\s*(g|条|个|卷|kg|L)+\\*\\b");//匹配只有数字+单位的如牛油果2个
private static final Pattern UNIT_CHN_EVERY_REGEX = Pattern.compile("([0-9零一二三四五六七八九十百千万亿]+|\\d*\\.?\\d+)\\s*(g|条|个|卷|kg|L)+\\s*/([袋箱盒份条])");//匹配只有数字+单位的如牛油果2个
private static final Pattern UNIT_EVERY_REGEX = Pattern.compile("([0-9零一二三四五六七八九十百千万亿]+)([个条份根盒包])(?:\\s*([0-9]+)(g|克|ml|毫升)|\\s*/([袋箱盒份条]))");//匹配商品名称+数量+数量单位+重量的 如牛油果2个150克
private static final Pattern UNIT_CHN_REGEX = Pattern.compile("([0-9零一二三四五六七八九十百千万亿]+|\\d*\\.?\\d+)\\s*(g|条|个|卷|kg|L|KG)+\\*\\b");//匹配只有数字+单位的如牛油果2个
private static final Pattern UNIT_CHN_EVERY_REGEX = Pattern.compile("([0-9零一二三四五六七八九十百千万亿]+|\\d*\\.?\\d+)\\s*(g|条|个|卷|kg|L|KG|G)+\\s*/([袋箱盒份条])");//匹配只有数字+单位的如牛油果2个
private static final Pattern UNIT_EVERY_REGEX = Pattern.compile("([0-9零一二三四五六七八九十百千万亿]+)([个条份根盒包])(?:\\s*([0-9]+)(g|克|ml|毫升|G)|\\s*/([袋箱盒份条]))");//匹配商品名称+数量+数量单位+重量的 如牛油果2个150克
//private static final Pattern DIMENSION_REGEX = Pattern.compile("([\\u4e00-\\u9fa5]+)(\\d+\\.?\\d*\\*\\d+\\.?\\d*(?:米)?)([\\u4e00-\\u9fa5]+)");
private static final Map<String,Pattern> PROTECT_PATTERNS = new HashMap<String,Pattern>(){{
put(PROTECT_UNIT,UNIT_REGEX);
@ -64,10 +64,16 @@ public class JiebaUtils {
put("enDash","-");
put("start","\\*");
put("dot","\\.");
//put("qiuqiu","QQ");
}};
public static final Set<String> filterWords=Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
"","/","","","","","*","","","一级","木盒","特级","二级","条盒","礼盒","三级","整袋","塑料","","整件"
"","/","","","","","*","","","一级","木盒","特级","二级","条盒","礼盒","三级","整袋","塑料","","整件","润之华",
"纯正","非转","四级","非转基因","组合装","组合","巧克力口味","老酸奶味","外撒料","套餐","豪迪","片装"
)));
public static final Set<String> doubleSpecialShops=Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
"裤型"
)));
@ -190,6 +196,9 @@ public class JiebaUtils {
if(result.contains(".")){
result = result.replaceAll(spectialrestoreMap.get("dot"),"dot");
}
// if(result.contains("QQ")){
// result = result.replaceAll(spectialrestoreMap.get("qiuqiu"),"qiuqiu");
// }
return result;
}
@ -203,6 +212,7 @@ public class JiebaUtils {
token=token.replaceAll("enDash",spectialrestoreMap.get("enDash"));
token=token.replaceAll("start",spectialrestoreMap.get("start"));
token=token.replaceAll("dot",spectialrestoreMap.get("dot"));
// token=token.replaceAll("qiuqiu",spectialrestoreMap.get("qiuqiu"));
// 检查保护标记开始
if (token.contains(PROTECT_START)) {
inProtected = true;
@ -273,11 +283,12 @@ public class JiebaUtils {
* 搜索模式分词更细粒度字典分词+排除识别商品
*/
public static List<String> extractKeywords(String text) {
JiebaSegmenter segmenter = new JiebaSegmenter();
//JiebaSegmenter segmenter = new JiebaSegmenter();
loadUserDict();
String protectedText = protectPatterns(text);
log.info("protectedText: {}", protectedText);
List<String> tokens = segmenter.sentenceProcess(protectedText).stream()
List<String> tokens = segmenter.process(protectedText,JiebaSegmenter.SegMode.SEARCH).stream()
.map(token -> token.word)
//.filter(word -> word.length() > 1) // 过滤单字
// .sorted(Comparator.reverseOrder()) // 按词典词频降序
.distinct()
@ -292,6 +303,7 @@ public class JiebaUtils {
*/
public static Map<String,String> getShopDetails(String cleanProductName){
Map<String, String> fields = new HashMap<>(4);
//cleanProductName=cleanProductName.toLowerCase();
//分词
List<String> words = extractKeywords(cleanProductName);
// resultMap.put("productShortName",productName);
@ -307,15 +319,24 @@ public class JiebaUtils {
} else if (CATEGORY_LIBRARY.contains(word)) {
fields.putIfAbsent("category", word);
} else if (startsWithDigit(word)) {
for (String unit:UNITS){
if (word.contains(unit)) {
// for (String unit:UNITS){
// if (word.contains(unit)) {
fields.putIfAbsent("specs", word);
break;
//break;
// }
//}
//fields.putIfAbsent("specs", word.toLowerCase());
}else if(null!=getSpecialWords(word)&&noInclunde(word)){
String productShortName=fields.get("productShortName");
if(StringUtils.isEmpty(productShortName)){
fields.putIfAbsent("productShortName", word);
}else {
if(word.contains("剃须刀")){
fields.remove("productShortName");
fields.putIfAbsent("productShortName",word);
}
}
//fields.putIfAbsent("specs", word.toLowerCase());
}else if(SPECIAL_NAME.contains(word)){
fields.putIfAbsent("productShortName", word);
}else {
remainingWords.add(word);
}
@ -352,6 +373,29 @@ public class JiebaUtils {
return fields;
}
private static boolean noInclunde(String word){
for (String shopName:doubleSpecialShops){
if(word.contains(shopName)){
return false;
}
}
return true;
}
/**
* 查询特殊商品查询到了直接返回
* @param word
* @return
*/
private static String getSpecialWords(String word){
for (String special : SPECIAL_NAME) {
if (word.contains(special)) {
return special;
}
}
return null;
}
/**
* 倒叙匹查询配商品名称
* @param words
@ -425,7 +469,13 @@ public class JiebaUtils {
if (input == null || input.isEmpty()) {
return false;
}
return Character.isDigit(input.charAt(0));
for (String unit : UNITS) {
if (input.contains(unit)) {
return Character.isDigit(input.charAt(0));
}
}
return false;
}
/**
@ -474,7 +524,9 @@ public class JiebaUtils {
if (input.contains("*")) return true;
}
if (input.contains(word)) {
return true;
if(!(input.contains("豆沙包"))&&!(input.contains("粉条"))&&!(input.contains("豆皮条"))){
return true;
}
}
}
return false;
@ -483,20 +535,31 @@ public class JiebaUtils {
public static void main(String[] args) {
// JiebaUtils jiebaUtils = new JiebaUtils();
String text = "四海油彩米10Kg";
// String text = "新鲜牛肉饺子500g";
//String text = "优资莱水仙水润保湿多效BB霜50g+7g/套";
List<String> shopNames = Arrays.asList(
"湘亮牌茉莉花茶/袋"
);
System.out.println(shopNames.size());
for (String shopName : shopNames) {
Map<String,String> shopMap= JiebaUtils.getShopDetails(ProductTitleUtil.cleanTitle2(shopName));
System.out.println("商品全名称:"+shopName);
System.out.println(shopMap);
}
// String text = "新鲜牛肉饺子500g";
//String text = "志高1.8L电热水壶";
// String text = "单充数据线2m";
// String text = "雅安利2.0*2.3四件套";
// String text = "RSCW-1949剃须刀";
// System.out.println(cleanNumberAndDigit("双汇王中王火腿肠400G10*40g/包"));
//String text="六指鼠童袜001";
// List<String> words = JiebaUtils.extractKeywords(text);
//System.out.println(words);
Map<String,String> shopMap= JiebaUtils.getShopDetails(ProductTitleUtil.cleanTitle2(text));
System.out.println(shopMap);
// List<String> words = JiebaUtils.extractKeywords(text);
// System.out.println(words);
//
// Map<String,String> shopMap= JiebaUtils.getShopDetails(ProductTitleUtil.cleanTitle2(text));
// System.out.println(shopMap);
// List<String> list= new JiebaUtils().segmentForSearch("优资莱水仙水润保湿多效BB霜50g+7g/套");
// list.forEach(System.out::println);
}

View File

@ -27,7 +27,7 @@ public class ProductTitleUtil {
"赠品", "包邮", "新品", "热卖", "爆款", "推荐", "精选", "特惠", "清仓",
"正品", "原装", "官方", "正版", "品牌", "优质", "好用", "新款", "老款",
"", "", "", "", "[]", "()", "", "", "", "", "??", "?",
"袋装","盒装","","精品","加工","",""
"袋装","盒装","","精品","加工",""
)));
/**
@ -53,11 +53,40 @@ public class ProductTitleUtil {
Arrays.asList("华为", "苹果", "小米", "三星", "美的", "格力", "耐克", "阿迪达斯", "海尔","雀巢","伊利","蒙牛","达能","乐事","多力多滋","三只松鼠","良品铺子","可口可乐",
"农夫山泉","元气森林","红牛","雅诗兰黛","欧莱雅","玉兰油","科颜氏","宝洁","汰渍","帮宝适","联合利华","Unilever","含多芬","清扬","大窑","谢村桥牌阡糯","谢村桥牌阡",
"六个核桃","大豫竹","优乐多","安慕希","纳爱斯","舒客","宜轩", "蓝月亮","海尔","美的","松下","戴森","耐克","安踏","李宁","特仑苏","纯甄","安井","三全","哇哈哈",
"龙江家园","达利园","春光","妙芙","南星","利嘉旺","卡得福","泓一","爱乡亲","思念","得力","中雪","江南点心局","德庄","六指鼠","娃哈哈","开古","不二家","湘亮牌",
"依水塬","乌苏啤酒","阿尔卑斯", "瑞旗","振雷","中狗","宝视达","冷酸灵","骆驼","NIKE","PAMU","康师傅","信智利","双兔","安足莱","新博美","湘亮牌","忆江南","张骞牌",
"龙江家园","达利园","春光","妙芙","南星","利嘉旺","卡得福","泓一","爱乡亲","思念","得力","中雪","江南点心局","德庄","六指鼠","娃哈哈","开古","不二家",
"依水塬","乌苏啤酒","阿尔卑斯", "瑞旗","振雷","中狗","宝视达","冷酸灵","骆驼","NIKE","PAMU","康师傅","信智利","双兔","安足莱","新博美","忆江南","张骞牌",
"新博","创利","哈奇利","好口福","银鹭","开古","百事可乐","邛池","天旭牌","泗泉山","银狼","象芽王","拜将坛","健民","湘亮牌","周大黑","盛华牌","盛华","碗碗香","龙凤王",
"陕南健源","百州红","八度名苑","旭美","今麦郞","勇闯天涯","青岛","一起赢","元気森林","云南红茶","盈亮","树堂","乡糯香","汉中魏","金源","疆丝麦耘","四海油","亿家康",
"利民")
"利民","花的瑜伽","五得利","双正","五得利","稻花香","金沙河","周大黑","良华","京派","建兴","帆舟","鲁花","远征","长康","喜来","好人家","春溢香","定军","鹮宝","建兴",
"香满园","金龙鱼","秦百年","京晶泉","香纳兰","冀南","北极雪","御品","徐桥","卫丰","三全","食缘","优旺","暖堡","沁丰","鲤鱼","百合花","陕富","金琪","魅厨","锦鹮",
"华夏","开古","定军","金鼎","精恒瑞","惠相随","天麦然","汉家香","欣立","松花江","元宝","博凌","仙桃","裕谷","秦一","雪莲","五常","丰盛杰","泰丰","优滋香","泰香",
"优滋","忆米坊","城固","华山雪","汉乐宝","魅厨","汉乐宝","元宝牌","汉水源","亚冠","雪峰","宛康","汉花","汉祖香","双亚","汉民","良安","好面缘","鲁花","金元宝","中粮福",
"邦琪","邦淇","雪工","巧厨","胡姬花","道道全","桂花兴","百洋","老中街","家家宜","鲁三婆","雨润","亿嘉福","李老二","顶诺菲力","湾仔码头","豆沙包","千味央厨","木伦河",
"万香斋","科润","佳盛源","夏新星","优之源","米姥姥","鸿旺","比他好","孝感","绿秦","铁师傅","伊明","天山","露億","千碾水磨","志扬","花体","美棋","花体","久味佳","午子牌",
"帆舟","海天","尝乡味","合味尝","山江源","金都来","福爱佳","冠珠","阿一波","金涛","百钻","安琪","木伦河","喜香源","草原优","兴客坊","喜香源","千芝乐","米之世家","科润",
"誉名源","达优宝","达选宝","廖氏","廖锦记","佳尚锦轩","磨子桥","洞庭牧歌","剑蜀","佰香林","欢建","福满洲","杜专","享康","菽美","佰香林","三达","尚品","齐力","洞庭湖",
"正淳","蜀椒骄","张海椒","十斗香","小韦","菇丹北","濛金","紫香岛","森师傅","荣富","海之佳","福龙宇","阳平","阿一波","龙亿来","一竹","龙丝宴","永安","黔小妹","味致",
"嫩婆婆","菜厨","鑫凯龙","苕山","永旺","永顺","荣丰","乐家客","绿梦","老五世家","老干妈","明冠","老武世家","川老汇","鸿兴源","野蕨菜","饭扫光","德庄","二姐","庄稼汉",
"安琪","五里桥","秦玉龙","俊豪","国灿","紫林","张兴邦","德庄","德莊","易记","想想乐","玉盆","老檀香","黄花什锦","城东王","凌云","明旺","穆堂","呗呗香","延兴源","香宴坊",
"肥羊王","太太乐","兴磨坊","麻辣江湖","联厨","广中皇野","居来香","广中皇","居来","穆堂香","察尔汗","杨三友","阿宽","恒顺","西堡泉","吉香居","罗氏","秋霞","肥牛调料","双乐",
"味香源","厨优","旺丰","李锦记","汉百味","华多","蜀霸","蜀厨","坤儒","回味乐","成星","阳光","食全食美","旺嫂","两岸香","天一井","居味鲜","千椒红","六婆","家有椒妻","之趣郎",
"椒浓","火锅伴侣","佰味祥","秦祥源","秦百年","燕庄","嘛德","农家亲","乔家","天冠","海底捞","颖旺","优品家","自来牌","致旺","美亿天","味居","桥头","云味源","芝香堂","欧丽薇兰",
"天玉香牌","天缘","麻得倒","梗峪泉","中盐牌","承味居","香必居","康圣晶","茗荟堂","德发祥","菜司令","大咸德","宏林","祺发","辣安壹","大红九九","臻鲜","蜀味坊","晋香源","德咸",
"汉中","庭香","清真","美亿天","辣安壹","惠川","鑫佳瑶","钟氏","菜香园","佰盛客","每餐乐","佳仙","好味道","紫之鲜","黎氏褀","名权","慧川","惠川","李渔府","雪天","芋滋源",
"鑫萌","食厨","美餐乐","康荣","鑫萌","佰味祥","劲仔","熊猫","麻得亨","金竹轩","佳贝尔山椒","徐自来","李氏","山椒野菜","德有领","乌江","王守义","成星","香御庭","味大师","香御庭",
"味大师","李红亮","渝麦居","沧盐","厨邦","黎红","美味鲜","北固山","南德","莎麦","加加","豪吉","小砖头","保宁","孔师傅","甘竹牌","甘竹","王致和","鹃城牌","美乐富","惠通","周君记",
"国泰","0金标蚝油","优趣","亮晶晶","唯织精","美人鱼","宏兴","雨乡行","宠茜","珺琦","保护神","双针","天飞碰起","诗琪","伊步航","天竹","豪迪","亚豪","戈霓微","皓尔","雨思源","味织",
"欣之帆","宝丽姿","初曲","亚豪","奥美娇","蓝巨星","城健","未宸","岱娜佳人","蓝宝奇","圣千尔","佳乐靓","鑫亿竹","金叶竹","扬洋","美迹花仙子","哈贝熊","美迹","锦臣","小胖熊",
"望海竹","伊尔马","望海竹","纵派","傲天狼","贝昊","小倒杆","车马王者","韩翊","舒澳健","小飞象","欧派狮","雨乐缘","红羚羊","佐小加","迪诺米绮","迪诺米奇","凡申足","梦纳诗","卡婴梦",
"车马王者","欣丽美","步旺都","巴伯蕊","于思源","邦杰尔","宝利叶","冠味","馨喜玥","天堂","品秀缘","怡姿露","禾木","埼瑄","南极人","丝光棉","袖宝贝","爱鑫","金竹叶","群鑫","金叶子",
"袋鼠","俏芙蓉","丽蒂雅","舒宜","奥斯","春妮","足精灵","薰娜丝","追新族","嘉迈图","竹炭","羊驼","喜乐龙","达蒙莱","优织徕","优织来","佰仲","超华冠","超鑫","六星足","金帝利","嘉彩特",
"伯轩娜","祉辰","丝结缘","泽卡桶","晨光","唛克","浪莎","俏丽人","堡罗格","艾伦斯","艳飞林","健将","花花公子","鑫立竺","熏娜斯","天卓","佳绮利","墨金","大号包书皮","大号包书皮",
"牧人世家","雪岱婷","订书机","红双喜","科仕威","康宝鹿","健硕皮","韩羽","夏婷","欧丝浪","欧俐斯","铭展","缘伴","娅诗奈儿","帝皇邦","淑丝蔓","步旺都","蒂彪","瑝玛","英凯特",
"拉杆","拉杆","唐都","淘乐","型怡","纳萬嘉","莫代尔","燕梦姿","朵韵","娜一派","鸿爽","新宇文","美若欣","奥美芬","黛多芬","铁榔头","爱博雷斯","加兹尼","紫欣","恋情雪","贝尔威",
"珍岱妮","娜派","安巧娜","花时尚","欧都","贵人一族","豪尔思丹","洁婷","夫人当家","欣雅","奥莎","好太雅","楼康龙","艳狐狸","康美","鑫缘梅","铂金一朵","南桂坊","朗威","佳洁士","两面针",
"洁劲","贝诺","奥妙","雕牌","白猫","金纺","立白","妙管家","云南白药","华洋金芒芒","乐雪","钟薛高","好趣多","妙可蓝多","绿箭","秦李记","吉百氏","柏优园","欧扎克","星巴克","雀巢","香飘飘",
"双汇","合百客","旺旺","今麦郎","农夫山泉","喜之郎"
)
));
/**
* 品类词库初始化后不可变
@ -92,7 +121,31 @@ public class ProductTitleUtil {
//特殊商品
public static final Set<String> SPECIAL_NAME = Collections.unmodifiableSet(new HashSet<>(
Arrays.asList("水饺", "面条", "包子","卷纸","卫生纸","紫菜汤","猪肉包","叉烧包","香菇青菜包","面包","黑米","棒棒糖","梳子","谢村花雕","古秦洋精","通裕梨花",
"台式烤香肠")
"台式烤香肠","千碾水磨","梳子","菜籽油","妙脆滋甜筒","三全汤圆","糍粑","上海大馅馄饨","寿桃包","什锦菜","香脆油条","手抓饼","青豆虾仁/什锦虾仁","卡通鸭仔包",
"美式直著条","小汤圆","皮蛋","QQ面","菌汤包","鸡蛋","小豆","小米","","五里桥汤","火锅蘸料","火锅汤料","老汤火锅","食用盐","手工牛油","劲仔豆干","袋酱油",
"米椒","老卤料料","辣卤酱","榨菜","腌料","红豆薏米粉","三鲜菌汤火锅料","回锅肉","奥尔良腌料","黑芝麻糊","香辣牛肉酱","手撕素","自来牌","火锅底料","腐乳",
"黄豆酱","脆口萝卜","纯粮味精","老坛酸菜鱼调料","老抽酱油","生抽酱油","3D防滑钢丝袜","男士黑胶伞","雨伞","苹果礼盒","礼盒苹果","沙糖桔","冰糖橙","玥颖镇",
"巴碱水馍","铭展精","2508男袜","花童伞","套童伞","男士棉袜","花包边伞","7K伞","蜜梨礼盒","石榴礼盒","男袜","雨衣","","彩虹伞","格子伞","","15包","",
"","软抄","便利贴","作业本","大本本皮","书包","超人","油画棒","两用包","双面本","橡皮泥","彩铅","男凉拖","拖鞋","男棉鞋","棉拖","秋衣","洗碗巾","床单","被套",
"防晒衣","卫生巾","苏菲口袋魔法","湿巾","350超薄随心翻夜用","立体护围","棉柔","软抽","","饭勺","纸面巾","婴儿手口","超薄夜用","极薄轻盈","纸尿片","刮齿斗",
"牙签","安卓快冲","热水袋","烟缸","拖把","插板","拖把","切菜器","头灯","红对壶","套扫","扫把","剃须刀","方盘","吹风机","夹板","纸巾","垃圾袋","八角盘","暖身贴",
"浅盘","木柄勺","台灯","铭威蛋","环保袋","皂盒","牙具盒","水壶","粘钩","纸篓","蛙台扇","","","洗漱包","扑克数量盒","排插","竹筷","牙刷","刀片","刀架","漱口杯",
"刀头","双面胶","扑克塑料盒","三格调味盒","唇膏","蚊香液","bb霜","一次性手套","优资莱绿茶美人水保湿","优资莱白茶小玉瓶美白","优资莱玫瑰花茶美肌","百花萃红玫瑰鲜活保湿新肌",
"丁家宜维生素e乳","阿道夫洗护专研润肤乳","洗发水","草本舒缓花露水","阿道夫精油沐浴原液","黛维莉精油洗沐护","枪手电热蚊香片e型","清香剂","护发素","空气清新剂","护手霜","沐浴露",
"手霜","盘香","牙膏","云南三七花","空气清新剂","洗发露","杀虫气雾剂","蚊香","洗衣液","白猫漂水洗衣","香皂","洗衣粉","清洁剂","纸包手工皂","组合皂","雪糕","酸奶","手洗专用洗衣液",
"风味酸牛奶","乳酸菌原味","塑瓶甜牛奶","塑瓶纯牛奶","骨力牛奶","舒活牛奶","儿童成长牛奶","ad钙原味","谷粒多红谷","臻浓牛奶","益消风味发酵乳","锂电池","曼妥思动感粒方口香糖",
"牛奶条糖","口香糖","浓牛奶软条糖","糖条形糖原味牛奶硬糖","糖条形奶香曲奇硬糖","麻花","臻享白咖啡","枣花蜂蜜","威化巧克力","庄家味鸭腿","diy涂鸦糖果","水彩便签纸盒","手表盒",
"麻辣条","diy咕卡","芋泥乳酪包","奶瓶糖","南瓜酥","天神薯条原味","劲爽1倍半红烧","老母鸡汤袋面","1倍半红烧","1倍半酸菜五连包","1倍半酸菜面","酸辣粉","烤脖","酥脆薯条番",
"百草味坚果零食礼","百草味坚果零食礼盒","油泼辣子五连包","炭烧猪肉铺","嫩布丁","猴菇饼干礼盒","雪花杯棉花糖","鱼豆腐","牛奶糖","团团圆圆大礼包","鸭翅根","脆骨肠","一根脆骨",
"手撕蟹","手撕蟹柳","养生五谷好粥道礼盒","猴头菇礼盒","猪肉脯","牛肉丸","酸菜鱼","蛋黄卷","汤达人老母鸡五连包","儿童背包果冻","3d软糖草莓形","3d软糖薯条形","老坛酸菜牛肉",
"大食袋酸菜5连包","香仔一连q蛋","vc怡果樱花白桃味","卤香牛肉板面","鲜汤羊肉烩面","香锅地道辣面","饼干条巧克力酱","烤牛馍","鲜虾条","优乐美抹茶红豆味奶茶3连杯","西哥风情袋",
"qq糖草莓味","qq糖蓝莓","劲爽拉面酸菜五连包","qq糖青苹果味","大今野拉面老坛酸菜五连包","蜂蜜牛奶盒","qq糖可乐味","qq糖葡萄味","qq糖柑橘味","qq糖菠萝","qq糖水蜜桃","家庭号虾条",
"苏打气泡水","红油辣椒酱","元气豆腐","上品香辣牛肉面","1桶半酸豆角","1袋半酸豆角","果粒多礼盒","黄桃果肉果冻","1桶半酸菜","葱香排骨面","红烧牛肉面5连包","典酸辣牛肉五包入",
"红烧牛肉面","香辣牛肉面","酸辣牛肉面","油泼辣子牛肉面","牛肉汤面","波力海苔","小鸡面香辣味","奶香威化32条装","酸奶夹心威化16条装","达利园早餐包礼盒","达利园蔓越梅提子礼盒",
"彩豆糖","口笛糖","果汁糖","比克薯片","小面包礼盒","欧式蛋糕","瑞士卷","羊角面包","挑豆大礼包","好丽友果滋果姿","混合果汁饮料","君乐宝超值益生菌","混合果蔬汁饮料","苏打矿泉水",
"红牛礼盒装","旺仔牛奶","乳酸菌饮品","藤椒水煮鱼牛肉","维他命水","六个核桃","营养快线","ad钙草莓味","娃哈哈椰奶礼盒","脉动","火锅凉茶","乌鸡蛋礼盒","麻辣牛肉面","早餐牛奶饮品",
"利乐包谷粒早餐红谷牛奶饮品","1倍半酸辣","尖叫运动饮料","清花汾酒","老凤酒龙年富贵","好运福粽礼盒","曲奇饼干","雪花啤酒","趣多多","雀巢咖啡","优乐美奶茶","巴巴脆薯脆","手撕酸果条",
"巷果粒奶","娃哈哈锌多多礼盒","维多粒果冻","棉花泡泡糖","鸡尾酒味条糖","嘉士利果乐果","嘉士利香薄趣","鸡尾酒","劲酒礼盒","9度啤酒整件","干红葡萄酒","凯撒白啤")
));
static {
@ -207,8 +260,56 @@ public class ProductTitleUtil {
private static String normalizeUnit(String word) {
// word=word.toLowerCase();
word=word.replaceAll("","g");
if(word.contains("g力")){
word=word.replaceAll("g力","克力");
}
if(word.contains("Deoirsg")){
word=word.replaceAll("Deoirsg","Deoirs克");
}
if(word.contains("g拉绒")){
word=word.replaceAll("g拉绒","克拉绒");
}
if(word.contains("唛g")){
word=word.replaceAll("唛g","唛克");
}
if(word.contains("欧g")){
word=word.replaceAll("欧g","欧克");
}
if(word.contains("坦g")){
word=word.replaceAll("坦g","坦克");
}
if(word.contains("扑g")){
word=word.replaceAll("扑g","扑克");
}
if(word.contains("舒g")){
word=word.replaceAll("舒g","舒克");
}
if(word.contains("思g")){
word=word.replaceAll("思g","思克");
}
if(word.contains("派g")){
word=word.replaceAll("派g","派克");
}
if(word.contains("扎g")){
word=word.replaceAll("扎g","扎克");
}
if(word.contains("巴g")){
word=word.replaceAll("巴g","巴克");
}
if(word.contains("麦g")){
word=word.replaceAll("麦g","麦克");
}
if(word.contains("比g")){
word=word.replaceAll("比g","比克");
}
if(word.contains("g代")){
word=word.replaceAll("g代","克代");
}
word=word.replaceAll("毫升","ml");
word=word.replaceAll("","l");
if(word.contains("KG")){
word=word.replaceAll("KG","kg");
}
return word;
// java.util.regex.Matcher matcher = UNIT_PATTERN.matcher(word);
// return matcher.matches() ?

File diff suppressed because it is too large Load Diff

View File

@ -122,7 +122,7 @@ public interface SyncThirdDataService {
*
* @return
*/
Map<String, Double> getProductStockFromRedis();
Map<String, Double> getProductStockFromRedis(String storeId);
/**
* 下单或支付后批量累加减商品库存使用 Redis Hash 的原子自增操作保证并发安全

View File

@ -58,7 +58,7 @@ public class ShopSyncImportServiceImpl implements ShopSyncImportService {
@Autowired
private SyncStoreSpecsService syncStoreSpecsService;
private final int limitCnt = 100;
private final int limitCnt = 300;
@Override
public void downloadBrandTemplate(HttpServletResponse response) {

View File

@ -788,7 +788,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
// storeDataResultMap = sme.stream().filter(m -> !(m.getValue().equals((double) 0))).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
// }
Map<String, Double> storeDataResultMap = getProductStockFromRedis();
Map<String, Double> storeDataResultMap = getProductStockFromRedis(syncAppO.getStore_id());
return new ThirdApiRes().success("success", storeDataResultMap);
}
@ -812,10 +812,11 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
@Override
public Map<String, Double> getProductStockFromRedis() {
public Map<String, Double> getProductStockFromRedis(String storeId) {
try {
// Redis 获取 hash 结构的所有键值对
Map<Object, Object> redisHash = redisTemplate.opsForHash().entries(RedisKey.STOREDATARELEASE);
String key=RedisKey.STOREDATARELEASE+":"+storeId;
Map<Object, Object> redisHash = redisTemplate.opsForHash().entries(key);
if (redisHash == null || redisHash.isEmpty()) {
return Collections.emptyMap();
}
@ -865,8 +866,9 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
continue;
}
String itemId=productBase.getProduct_number();
String key=RedisKey.STOREDATARELEASE+":"+productBase.getStore_id();
// 使用 Redis HINCRBY 保证原子性和高性能
redisTemplate.opsForHash().increment(RedisKey.STOREDATARELEASE, itemId, itemQuaryty.doubleValue());
redisTemplate.opsForHash().increment(key, itemId, itemQuaryty.doubleValue());
} catch (Exception e) {
logger.error("库存累计失败productKey={}, delta={}, error={}", productKey, delta, e.getMessage(), e);
}