fix: 兼容档口货号括号与前导零 (#273)

This commit is contained in:
chengma
2026-08-18 17:20:50 +08:00
parent 8e58793a0b
commit 5e0cf95859
2 changed files with 161 additions and 8 deletions
+92 -8
View File
@@ -5,11 +5,11 @@ import (
"database/sql"
"encoding/json"
"fmt"
"regexp"
"sort"
"strconv"
"strings"
"time"
"unicode"
"cmautobuy/admin/model"
"cmautobuy/admin/repository"
@@ -419,19 +419,103 @@ func innerCodeStallMatches(stall string, item syb.DetailItem) bool {
if strings.Contains(blob, stall) {
return true
}
name, article, hasArticle := strings.Cut(stall, "#")
name, article, hasArticle := splitInnerCodeStall(stall)
if !hasArticle {
return false
}
name, article = strings.TrimSpace(name), strings.TrimSpace(article)
if article != "" {
if strings.Contains(blob, "#"+article) || strings.HasPrefix(item.ProductSpec, article+" ") || strings.HasPrefix(item.ProductSpec, article+",") {
if article == "" {
return name != "" && (strings.Contains(sku, name) || strings.Contains(variation, name))
}
// 纯数字货号容易在不同档口重复。只有候选也包含同一档口名称时,
// 才允许把 067 与 67 视为同一个货号;不能只凭短数字自动选商品。
if isInnerCodeNumericArticle(article) {
nameMatches := name != "" && (strings.Contains(sku, name) || strings.Contains(variation, name))
if !nameMatches {
return false
}
return innerCodeTextHasNumericArticle(sku, article) ||
innerCodeTextHasNumericArticle(variation, article) ||
innerCodeTextHasNumericArticle(item.ProductSpec, article)
}
return innerCodeTextHasExactArticle(sku, article) ||
innerCodeTextHasExactArticle(variation, article) ||
innerCodeTextHasExactArticle(item.ProductSpec, article)
}
// splitInnerCodeStall 从“档口名称#货号”取最后一个 #,避免档口名称本身含 # 时截错。
func splitInnerCodeStall(stall string) (name, article string, ok bool) {
stall = strings.TrimSpace(stall)
separator := strings.LastIndex(stall, "#")
if separator < 0 {
return stall, "", false
}
return strings.TrimSpace(stall[:separator]), strings.TrimSpace(stall[separator+1:]), true
}
func isInnerCodeNumericArticle(article string) bool {
if article == "" {
return false
}
for _, char := range article {
if !unicode.IsDigit(char) {
return false
}
}
return true
}
func innerCodeTextHasNumericArticle(text, article string) bool {
target := normalizeInnerCodeNumericArticle(article)
for _, token := range innerCodeArticleTokens(text) {
if isInnerCodeNumericArticle(token) && normalizeInnerCodeNumericArticle(token) == target {
return true
}
pattern := regexp.MustCompile(`(?:^|[#\-_/\s])` + regexp.QuoteMeta(article) + `(?:$|[#\-_/,\s])`)
return pattern.MatchString(sku) || pattern.MatchString(variation)
}
return name != "" && (strings.Contains(sku, name) || strings.Contains(variation, name))
return false
}
func normalizeInnerCodeNumericArticle(article string) string {
normalized := strings.TrimLeft(article, "0")
if normalized == "" {
return "0"
}
return normalized
}
func innerCodeTextHasExactArticle(text, article string) bool {
for _, token := range innerCodeArticleTokens(text) {
if token == article {
return true
}
}
return false
}
// innerCodeArticleTokens 只把连续字母或数字视为货号候选。
// `【】`、`#`、横线、空格等标点自然成为边界,因此能识别 `067【档口】`,
// 又不会把 `PDD256437` 中间的数字误认为独立货号。
func innerCodeArticleTokens(text string) []string {
tokens := make([]string, 0)
start := -1
runes := []rune(text)
for index, char := range runes {
if unicode.IsLetter(char) || unicode.IsDigit(char) {
if start < 0 {
start = index
}
continue
}
if start >= 0 {
tokens = append(tokens, string(runes[start:index]))
start = -1
}
}
if start >= 0 {
tokens = append(tokens, string(runes[start:]))
}
return tokens
}
func innerCodeRawText(value any) string {