103 lines
2.3 KiB
Go
103 lines
2.3 KiB
Go
// internal/utils/matching.go
|
|
package utils
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// CalculateMatchScore calculates match score between two items
|
|
func CalculateMatchScore(item1, item2 map[string]interface{}) float64 {
|
|
totalScore := 0.0
|
|
maxScore := 0.0
|
|
|
|
// Name matching (30%)
|
|
maxScore += 30
|
|
if name1, ok1 := item1["name"].(string); ok1 {
|
|
if name2, ok2 := item2["name"].(string); ok2 {
|
|
similarity := CalculateStringSimilarity(name1, name2)
|
|
totalScore += similarity * 30
|
|
}
|
|
}
|
|
|
|
// Category matching (20%)
|
|
maxScore += 20
|
|
if cat1, ok1 := item1["category"].(string); ok1 {
|
|
if cat2, ok2 := item2["category"].(string); ok2 {
|
|
if strings.EqualFold(cat1, cat2) {
|
|
totalScore += 20
|
|
}
|
|
}
|
|
}
|
|
|
|
// Color matching (15%)
|
|
if color1, ok1 := item1["color"].(string); ok1 {
|
|
if color1 != "" {
|
|
maxScore += 15
|
|
if color2, ok2 := item2["color"].(string); ok2 {
|
|
if strings.Contains(strings.ToLower(color2), strings.ToLower(color1)) {
|
|
totalScore += 15
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Location matching (20%)
|
|
if loc1, ok1 := item1["location"].(string); ok1 {
|
|
if loc1 != "" {
|
|
maxScore += 20
|
|
if loc2, ok2 := item2["location"].(string); ok2 {
|
|
similarity := CalculateStringSimilarity(loc1, loc2)
|
|
totalScore += similarity * 20
|
|
}
|
|
}
|
|
}
|
|
|
|
// Description matching (15%)
|
|
maxScore += 15
|
|
if desc1, ok1 := item1["description"].(string); ok1 {
|
|
if desc2, ok2 := item2["description"].(string); ok2 {
|
|
similarity := CalculateStringSimilarity(desc1, desc2)
|
|
totalScore += similarity * 15
|
|
}
|
|
}
|
|
|
|
if maxScore == 0 {
|
|
return 0
|
|
}
|
|
|
|
return (totalScore / maxScore) * 100
|
|
}
|
|
|
|
// 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"
|
|
} |