package sensitivewordmod import ( "strings" "91porn-server/common/log" ) // LoadEnabledTerms 加载启用状态的敏感词词条。 // DB 失败时降级返回空切片,调用方应视为"词库为空,不命中",避免阻塞业务流程。 func LoadEnabledTerms() []string { enabled := StatusEnabled list, err := FindAll(&ListReq{Status: &enabled}) if err != nil { log.Error("sensitivewordmod LoadEnabledTerms fail", log.E(err)) return nil } out := make([]string, 0, len(list)) for _, w := range list { if w.Word != "" { out = append(out, w.Word) } } return out } // MatchHits 对单个文本做 substring 命中检测,返回去重后的命中词。 // 与 skd/service/contentreviewser/matcher.findHits 行为一致。 func MatchHits(input string, terms []string) []string { if input == "" || len(terms) == 0 { return nil } seen := make(map[string]struct{}) hits := make([]string, 0) for _, t := range terms { if t == "" { continue } if _, ok := seen[t]; ok { continue } if strings.Contains(input, t) { seen[t] = struct{}{} hits = append(hits, t) } } return hits } // FormatHitDetail 把三类字段的命中拼成 "标题命中 XX 内容命中 YY 富文本命中 ZZ"。 // 任一字段未命中则该段省略;全部为空时返回空串。 func FormatHitDetail(titleHits, contentHits, richHits []string) string { parts := make([]string, 0, 3) if len(titleHits) > 0 { parts = append(parts, "标题命中 "+strings.Join(titleHits, "、")) } if len(contentHits) > 0 { parts = append(parts, "内容命中 "+strings.Join(contentHits, "、")) } if len(richHits) > 0 { parts = append(parts, "富文本命中 "+strings.Join(richHits, "、")) } return strings.Join(parts, " ") }