76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
// internal/utils/matching.go
|
|
package utils
|
|
|
|
|
|
|
|
// CalculateMatchScore calculates match score between two items
|
|
func CalculateMatchScore(item1, item2 map[string]interface{}) float64 {
|
|
nameScore := 0.0
|
|
descScore := 0.0
|
|
|
|
// 1. Name Matching (Bobot 50%)
|
|
if name1, ok1 := item1["name"].(string); ok1 {
|
|
if name2, ok2 := item2["name"].(string); ok2 {
|
|
nameScore = CalculateStringSimilarity(name1, name2) * 100
|
|
}
|
|
}
|
|
|
|
// 2. Description/Secret Matching (Bobot 50%)
|
|
// Cek apakah ada secret_details, jika tidak pakai description
|
|
text1 := ""
|
|
if val, ok := item1["secret_details"].(string); ok && val != "" {
|
|
text1 = val
|
|
} else if val, ok := item1["description"].(string); ok {
|
|
text1 = val
|
|
}
|
|
|
|
text2 := ""
|
|
if val, ok := item2["secret_details"].(string); ok && val != "" {
|
|
text2 = val
|
|
} else if val, ok := item2["description"].(string); ok {
|
|
text2 = val
|
|
}
|
|
|
|
if text1 != "" && text2 != "" {
|
|
descScore = CalculateStringSimilarity(text1, text2) * 100
|
|
}
|
|
|
|
// Total Score = Rata-rata dari keduanya
|
|
totalScore := (nameScore * 0.5) + (descScore * 0.5)
|
|
|
|
return totalScore
|
|
}
|
|
|
|
// MatchItems matches items based on criteria
|
|
func MatchItems(lostItem, foundItems []map[string]interface{}, threshold float64) []map[string]interface{} {
|
|
var matches []map[string]interface{}
|
|
|
|
if len(lostItem) == 0 || len(foundItems) == 0 {
|
|
return matches
|
|
}
|
|
|
|
lost := lostItem[0]
|
|
|
|
for _, found := range foundItems {
|
|
score := CalculateMatchScore(lost, found)
|
|
if score >= threshold {
|
|
match := make(map[string]interface{})
|
|
match["item"] = found
|
|
match["score"] = score
|
|
match["level"] = getMatchLevel(score)
|
|
matches = append(matches, match)
|
|
}
|
|
}
|
|
|
|
return matches
|
|
}
|
|
|
|
// getMatchLevel returns match level based on score
|
|
func getMatchLevel(score float64) string {
|
|
if score >= 70 {
|
|
return "high"
|
|
} else if score >= 50 {
|
|
return "medium"
|
|
}
|
|
return "low"
|
|
} |