From 6049334323c70e352888623285f0b7b07d18e8a6 Mon Sep 17 00:00:00 2001 From: Michael Chus Date: Sun, 24 May 2026 19:03:19 +0300 Subject: [PATCH] =?UTF-8?q?refactor:=20=D0=BF=D0=B5=D1=80=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D1=82=D1=8C=20=D0=BF=D0=BE=D1=80?= =?UTF-8?q?=D1=8F=D0=B4=D0=BE=D0=BA=20=D0=BA=D0=B0=D1=82=D0=B5=D0=B3=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=B9=20(MB=E2=86=92CPU=E2=86=92MEM=E2=86=92RAID?= =?UTF-8?q?=E2=86=92drives=E2=86=92GPU=E2=86=92NIC=E2=86=92HBA=E2=86=92PSU?= =?UTF-8?q?=E2=86=92ACC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SeedCategories теперь обновляет display_order у существующих записей, поэтому новый порядок применяется при следующем запуске без ручных миграций. MaxKnownDisplayOrder повышен до 200. Co-Authored-By: Claude Sonnet 4.6 --- cmd/qfs/main.go | 2 +- internal/models/category.go | 52 ++++++++++++++++++------------------- internal/models/models.go | 14 +++++++--- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/cmd/qfs/main.go b/cmd/qfs/main.go index de01a0c..ac31ca2 100644 --- a/cmd/qfs/main.go +++ b/cmd/qfs/main.go @@ -1720,7 +1720,7 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect respondError(c, http.StatusBadRequest, "vendor workspace file exceeds 1 GiB limit", errVendorImportTooLarge) return } - if !services.IsCFXMLWorkspace(data) && !services.IsInspurBOM(data) { + if !services.IsCFXMLWorkspace(data) && !services.IsQuoteForgeCSV(data) && !services.IsInspurBOM(data) { c.JSON(http.StatusBadRequest, gin.H{"error": "unsupported vendor export format"}) return } diff --git a/internal/models/category.go b/internal/models/category.go index ca970c4..d5cd238 100644 --- a/internal/models/category.go +++ b/internal/models/category.go @@ -13,32 +13,32 @@ func (Category) TableName() string { return "qt_categories" } -// DefaultCategories defines the standard categories with display order -// Order: BB, CPU, MEM, GPU, SSD, RAID, HBA, NIC, PSU, RISERS, ACC, and others +// DefaultCategories defines the standard categories with display order. +// Canonical order: MB, CPU, MEM, RAID, storage drives, PCIe GPU, PCIe NICs, HBA, PSU, accessories, other. +// Display orders use gaps of 10 to allow future insertions without renumbering. var DefaultCategories = []Category{ - {Code: "BB", Name: "Barebone", NameRu: "Шасси", DisplayOrder: 1, IsRequired: true}, - {Code: "CPU", Name: "Processor", NameRu: "Процессор", DisplayOrder: 2, IsRequired: true}, - {Code: "MEM", Name: "Memory", NameRu: "Оперативная память", DisplayOrder: 3, IsRequired: true}, - {Code: "GPU", Name: "Graphics Card", NameRu: "Видеокарта", DisplayOrder: 4}, - {Code: "SSD", Name: "SSD Storage", NameRu: "SSD накопитель", DisplayOrder: 5}, - {Code: "RAID", Name: "RAID Controller", NameRu: "RAID контроллер", DisplayOrder: 6}, - {Code: "HBA", Name: "HBA Adapter", NameRu: "HBA адаптер", DisplayOrder: 7}, - {Code: "NIC", Name: "Network Card", NameRu: "Сетевая карта", DisplayOrder: 8}, - {Code: "PSU", Name: "Power Supply", NameRu: "Блок питания", DisplayOrder: 9}, - {Code: "RISERS", Name: "Risers", NameRu: "Райзеры", DisplayOrder: 10}, - {Code: "ACC", Name: "Accessories", NameRu: "Аксессуары", DisplayOrder: 11}, - // Additional categories - {Code: "MB", Name: "Motherboard", NameRu: "Материнская плата", DisplayOrder: 12}, - {Code: "HDD", Name: "HDD Storage", NameRu: "HDD накопитель", DisplayOrder: 13}, - {Code: "HCA", Name: "HCA Adapter", NameRu: "HCA адаптер", DisplayOrder: 14}, - {Code: "DPU", Name: "DPU", NameRu: "DPU", DisplayOrder: 15}, - {Code: "M2", Name: "M.2 Storage", NameRu: "M.2 накопитель", DisplayOrder: 16}, - {Code: "EDSFF", Name: "EDSFF Storage", NameRu: "EDSFF накопитель", DisplayOrder: 17}, - {Code: "HHHL", Name: "HHHL Storage", NameRu: "HHHL накопитель", DisplayOrder: 18}, - {Code: "PS", Name: "Power Supply (Legacy)", NameRu: "Блок питания", DisplayOrder: 19}, - {Code: "CARD", Name: "Cards", NameRu: "Карты", DisplayOrder: 20}, + {Code: "MB", Name: "Motherboard", NameRu: "Материнская плата", DisplayOrder: 10}, + {Code: "CPU", Name: "Processor", NameRu: "Процессор", DisplayOrder: 20, IsRequired: true}, + {Code: "MEM", Name: "Memory", NameRu: "Оперативная память", DisplayOrder: 30, IsRequired: true}, + {Code: "RAID", Name: "RAID Controller", NameRu: "RAID контроллер", DisplayOrder: 40}, + {Code: "SSD", Name: "SSD Storage", NameRu: "SSD накопитель", DisplayOrder: 50}, + {Code: "HDD", Name: "HDD Storage", NameRu: "HDD накопитель", DisplayOrder: 51}, + {Code: "M2", Name: "M.2 Storage", NameRu: "M.2 накопитель", DisplayOrder: 52}, + {Code: "EDSFF", Name: "EDSFF Storage", NameRu: "EDSFF накопитель", DisplayOrder: 53}, + {Code: "HHHL", Name: "HHHL Storage", NameRu: "HHHL накопитель", DisplayOrder: 54}, + {Code: "GPU", Name: "Graphics Card", NameRu: "Видеокарта", DisplayOrder: 60}, + {Code: "NIC", Name: "Network Card", NameRu: "Сетевая карта", DisplayOrder: 70}, + {Code: "HCA", Name: "HCA Adapter", NameRu: "HCA адаптер", DisplayOrder: 71}, + {Code: "DPU", Name: "DPU", NameRu: "DPU", DisplayOrder: 72}, + {Code: "HBA", Name: "HBA Adapter", NameRu: "HBA адаптер", DisplayOrder: 80}, + {Code: "PSU", Name: "Power Supply", NameRu: "Блок питания", DisplayOrder: 90}, + {Code: "PS", Name: "Power Supply (Legacy)", NameRu: "Блок питания", DisplayOrder: 91}, + {Code: "ACC", Name: "Accessories", NameRu: "Аксессуары", DisplayOrder: 100}, + {Code: "RISERS", Name: "Risers", NameRu: "Райзеры", DisplayOrder: 101}, + {Code: "CARD", Name: "Cards", NameRu: "Карты", DisplayOrder: 110}, + {Code: "BB", Name: "Barebone", NameRu: "Шасси", DisplayOrder: 120, IsRequired: true}, } -// MaxKnownDisplayOrder is the highest display order for known categories -// New categories will get display order starting from this + 1 -const MaxKnownDisplayOrder = 100 +// MaxKnownDisplayOrder is the highest display order for known categories. +// New categories will get display order starting from this + 1. +const MaxKnownDisplayOrder = 200 diff --git a/internal/models/models.go b/internal/models/models.go index 7680633..b2aff1d 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -43,12 +43,18 @@ func Migrate(db *gorm.DB) error { return nil } -// SeedCategories inserts default categories if not exist +// SeedCategories upserts default categories, updating display_order on existing rows. func SeedCategories(db *gorm.DB) error { for _, cat := range DefaultCategories { - result := db.Where("code = ?", cat.Code).FirstOrCreate(&cat) - if result.Error != nil { - return result.Error + var existing Category + if err := db.Where("code = ?", cat.Code).First(&existing).Error; err != nil { + if err := db.Create(&cat).Error; err != nil { + return err + } + } else { + if err := db.Model(&existing).Update("display_order", cat.DisplayOrder).Error; err != nil { + return err + } } } return nil