ordering.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package sitecheck
  2. import (
  3. "sort"
  4. "github.com/0xJacky/Nginx-UI/query"
  5. "github.com/uozi-tech/cosy/logger"
  6. )
  7. // applyCustomOrdering applies custom ordering from database to sites
  8. func applyCustomOrdering(sites []*SiteInfo) []*SiteInfo {
  9. if len(sites) == 0 {
  10. return sites
  11. }
  12. // Get custom ordering from database
  13. sc := query.SiteConfig
  14. configs, err := sc.Find()
  15. if err != nil {
  16. logger.Errorf("Failed to get site configs for ordering: %v", err)
  17. // Fall back to default ordering
  18. return applyDefaultOrdering(sites)
  19. }
  20. // Create a map of URL to custom order
  21. orderMap := make(map[string]int)
  22. for _, config := range configs {
  23. orderMap[config.GetURL()] = config.CustomOrder
  24. }
  25. // Sort sites based on custom order, with fallback to default ordering
  26. sort.Slice(sites, func(i, j int) bool {
  27. orderI, hasOrderI := orderMap[sites[i].URL]
  28. orderJ, hasOrderJ := orderMap[sites[j].URL]
  29. // If both have custom order, use custom order
  30. if hasOrderI && hasOrderJ {
  31. return orderI < orderJ
  32. }
  33. // If only one has custom order, it comes first
  34. if hasOrderI && !hasOrderJ {
  35. return true
  36. }
  37. if !hasOrderI && hasOrderJ {
  38. return false
  39. }
  40. // If neither has custom order, use default ordering
  41. return defaultCompare(sites[i], sites[j])
  42. })
  43. return sites
  44. }
  45. // applyDefaultOrdering applies the default stable sorting
  46. func applyDefaultOrdering(sites []*SiteInfo) []*SiteInfo {
  47. sort.Slice(sites, func(i, j int) bool {
  48. return defaultCompare(sites[i], sites[j])
  49. })
  50. return sites
  51. }
  52. // defaultCompare implements the default site comparison logic
  53. func defaultCompare(a, b *SiteInfo) bool {
  54. // Primary sort: by status (online > checking > error > offline)
  55. statusPriority := map[string]int{
  56. "online": 4,
  57. "checking": 3,
  58. "error": 2,
  59. "offline": 1,
  60. }
  61. priorityA := statusPriority[a.Status]
  62. priorityB := statusPriority[b.Status]
  63. if priorityA != priorityB {
  64. return priorityA > priorityB
  65. }
  66. // Secondary sort: by response time (faster first, for online sites)
  67. if a.Status == "online" && b.Status == "online" {
  68. if a.ResponseTime != b.ResponseTime {
  69. return a.ResponseTime < b.ResponseTime
  70. }
  71. }
  72. // Tertiary sort: by name (alphabetical, stable)
  73. if a.Name != b.Name {
  74. return a.Name < b.Name
  75. }
  76. // Final sort: by URL (for complete stability)
  77. return a.URL < b.URL
  78. }