package processor import ( "strings" ) // Industry keywords for matching. Extensible via config in the future. var industryKeywords = map[string][]string{ "机场": { "机场", "节点", "订阅", "clash", "v2ray", "trojan", "shadowsocks", "ss/ssr", "翻墙", "梯子", "科学上网", "加速器", "proxy", "代理", }, "VPN": { "vpn", "VPN", "wireguard", "openvpn", }, } // TagAndGrade assigns industry_tag and level (Hot/Warm/Cold) to each merchant. func TagAndGrade(merchants []MergedMerchant) []TaggedMerchant { var result []TaggedMerchant for _, m := range merchants { tagged := TaggedMerchant{Merged: m} // Industry matching: check merchant_name + original_text text := strings.ToLower(m.Best.MerchantName + " " + m.Best.OriginalText) for industry, keywords := range industryKeywords { for _, kw := range keywords { if strings.Contains(text, strings.ToLower(kw)) { tagged.IndustryTag = industry break } } if tagged.IndustryTag != "" { break } } // Inherit from raw if no match found if tagged.IndustryTag == "" && m.Best.IndustryTag != "" { tagged.IndustryTag = m.Best.IndustryTag } // Level grading hasIndustry := tagged.IndustryTag != "" hasWebsiteOrEmail := m.Best.Website != "" || m.Best.Email != "" switch { case hasIndustry && hasWebsiteOrEmail: tagged.Level = "Hot" case hasIndustry: tagged.Level = "Warm" default: tagged.Level = "Cold" } result = append(result, tagged) } return result } // TaggedMerchant is the final output of the processor. type TaggedMerchant struct { Merged MergedMerchant IndustryTag string Level string // Hot / Warm / Cold }