package scoring // completenessScore 层次完整度(20 分制):上衣+5 下装+5 鞋+5 配饰+5 func completenessScore(o CandidateOutfit) int { score := 0 for _, it := range o.Items { switch it.Category { case "上衣": score += 5 case "下装": score += 5 case "鞋": score += 5 case "配饰": score += 5 } } if o.HasOuterwear { score += 2 } if score > 20 { return 20 } return score } // styleScore 风格一致性(10 分制):命中用户偏好标签每项 +2 func styleScore(o CandidateOutfit, ctx ScoreContext) int { if len(ctx.StyleTags) == 0 { return 5 } score := 0 for _, it := range o.Items { for _, tag := range ctx.StyleTags { if tag != "" && it.StyleTags != "" && containsTag(it.StyleTags, tag) { score += 2 } } } if score > 10 { return 10 } return score } func containsTag(tags, tag string) bool { for _, t := range splitTags(tags) { if t == tag { return true } } return false } func splitTags(s string) []string { var out []string cur := "" for _, c := range s { if c == ',' || c == ',' || c == ' ' { if cur != "" { out = append(out, cur) cur = "" } continue } cur += string(c) } if cur != "" { out = append(out, cur) } return out }