170 lines
7.0 KiB
Go
170 lines
7.0 KiB
Go
package access
|
|
|
|
import "strings"
|
|
|
|
const (
|
|
ModuleDevices = "devices"
|
|
ModulePDDProducts = "pdd_products"
|
|
ModuleShopeeProducts = "shopee_products"
|
|
ModuleSYBProducts = "syb_products"
|
|
ModuleSYBShops = "syb_shops"
|
|
ModuleSYBSyncRuns = "syb_sync_runs"
|
|
ModuleSYBInnerCodes = "syb_inner_codes"
|
|
ModuleCollectionRules = "collection_rules"
|
|
ModulePurchaseRules = "purchase_rules"
|
|
ModuleCollectionTasks = "collection_tasks"
|
|
ModulePurchaseTasks = "purchase_tasks"
|
|
ModuleAIMatching = "ai_matching"
|
|
)
|
|
|
|
// ModuleDefinition is the single source of truth shared by menu migration,
|
|
// role protection and the Web dynamic-route migration. APIs are derived from
|
|
// AdminAPIs so the permission matrix remains the authoritative API inventory.
|
|
type ModuleDefinition struct {
|
|
Key string
|
|
Title string
|
|
Path string
|
|
RouteName string
|
|
Component string
|
|
Icon string
|
|
Sort int
|
|
PurchaserDefault bool
|
|
PurchaserHardHidden bool
|
|
APIs []APIPermission
|
|
}
|
|
|
|
const (
|
|
MenuGroupCollectionPurchase = "collection_purchase"
|
|
MenuGroupCollectionManagement = "collection_management"
|
|
)
|
|
|
|
// MenuGroupDefinition describes the two structural navigation groups used by
|
|
// Admin. ModuleKeys is ordered and therefore also defines child menu sorting.
|
|
type MenuGroupDefinition struct {
|
|
Key string
|
|
MenuName string
|
|
Title string
|
|
Path string
|
|
Icon string
|
|
Sort int
|
|
ModuleKeys []string
|
|
}
|
|
|
|
var goAutoMenuGroupMetadata = []MenuGroupDefinition{
|
|
{
|
|
Key: MenuGroupCollectionPurchase,
|
|
MenuName: "GoAutoCollectionPurchase",
|
|
Title: "采集采购",
|
|
Path: "/collection-purchase",
|
|
Icon: "shopping",
|
|
Sort: 50,
|
|
ModuleKeys: []string{
|
|
ModuleSYBProducts,
|
|
ModuleSYBSyncRuns,
|
|
ModuleSYBInnerCodes,
|
|
ModuleShopeeProducts,
|
|
ModulePDDProducts,
|
|
ModuleCollectionTasks,
|
|
ModulePurchaseTasks,
|
|
},
|
|
},
|
|
{
|
|
Key: MenuGroupCollectionManagement,
|
|
MenuName: "GoAutoCollectionManagement",
|
|
Title: "采采管理",
|
|
Path: "/collection-management",
|
|
Icon: "system",
|
|
Sort: 51,
|
|
ModuleKeys: []string{
|
|
ModuleSYBShops,
|
|
ModuleCollectionRules,
|
|
ModulePurchaseRules,
|
|
ModuleDevices,
|
|
ModuleAIMatching,
|
|
},
|
|
},
|
|
}
|
|
|
|
var goAutoModuleMetadata = []ModuleDefinition{
|
|
{Key: ModuleDevices, Title: "设备列表", Path: "/devices", RouteName: "GoAutoDeviceList", Component: "/goauto/devices/index", Icon: "monitor", Sort: 50, PurchaserDefault: true},
|
|
{Key: ModulePDDProducts, Title: "PDD 商品", Path: "/pdd-products", RouteName: "GoAutoPddProducts", Component: "/goauto/pdd-products/index", Icon: "shopping", Sort: 51, PurchaserDefault: true},
|
|
{Key: ModuleShopeeProducts, Title: "虾皮商品", Path: "/shopee-products", RouteName: "GoAutoShopeeProducts", Component: "/goauto/shopee-products/index", Icon: "goods", Sort: 52, PurchaserDefault: true},
|
|
{Key: ModuleSYBProducts, Title: "SYB 商品", Path: "/syb-products", RouteName: "GoAutoSybProducts", Component: "/goauto/syb-products/index", Icon: "tickets", Sort: 53, PurchaserDefault: true},
|
|
{Key: ModuleSYBShops, Title: "SYB 店铺", Path: "/syb-shops", RouteName: "GoAutoSybShops", Component: "/goauto/syb-shops/index", Icon: "shopping", Sort: 54, PurchaserDefault: true},
|
|
{Key: ModuleSYBSyncRuns, Title: "SYB 同步记录", Path: "/syb-sync-runs", RouteName: "GoAutoSybSyncRuns", Component: "/goauto/syb-sync-runs/index", Icon: "time", Sort: 55, PurchaserDefault: true},
|
|
{Key: ModuleSYBInnerCodes, Title: "档口入库码", Path: "/syb-inner-codes", RouteName: "GoAutoSybInnerCodes", Component: "/goauto/syb-inner-codes/index", Icon: "list", Sort: 56, PurchaserDefault: true},
|
|
{Key: ModuleCollectionRules, Title: "采集规则", Path: "/collection-rules", RouteName: "GoAutoCollectionRules", Component: "/goauto/collection-rules/index", Icon: "code", Sort: 57, PurchaserDefault: true},
|
|
{Key: ModulePurchaseRules, Title: "采购规则", Path: "/purchase-rules", RouteName: "GoAutoPurchaseRules", Component: "/goauto/purchase-rules/index", Icon: "setting", Sort: 58, PurchaserHardHidden: true},
|
|
{Key: ModuleCollectionTasks, Title: "采集任务", Path: "/collection-tasks", RouteName: "GoAutoCollectionTasks", Component: "/goauto/collection-tasks/index", Icon: "list", Sort: 59, PurchaserDefault: true},
|
|
{Key: ModulePurchaseTasks, Title: "采购管理", Path: "/purchase-tasks", RouteName: "GoAutoPurchaseTasks", Component: "/goauto/purchase-tasks/index", Icon: "shopping", Sort: 60, PurchaserDefault: true},
|
|
{Key: ModuleAIMatching, Title: "AI 规格匹配", Path: "/ai-matching-settings", RouteName: "GoAutoAiMatchingSettings", Component: "/goauto/ai-matching-settings/index", Icon: "setting", Sort: 61, PurchaserHardHidden: true},
|
|
}
|
|
|
|
// GoAutoModules returns independent copies so callers cannot mutate the
|
|
// process-wide permission metadata.
|
|
func GoAutoModules() []ModuleDefinition {
|
|
modules := make([]ModuleDefinition, len(goAutoModuleMetadata))
|
|
copy(modules, goAutoModuleMetadata)
|
|
for index := range modules {
|
|
for _, permission := range AdminAPIs {
|
|
if moduleKeyForAPI(permission.Path) == modules[index].Key {
|
|
modules[index].APIs = append(modules[index].APIs, permission)
|
|
}
|
|
}
|
|
}
|
|
return modules
|
|
}
|
|
|
|
// GoAutoMenuGroups returns deep copies so callers cannot change global menu
|
|
// ordering while building migrations or permission trees.
|
|
func GoAutoMenuGroups() []MenuGroupDefinition {
|
|
groups := make([]MenuGroupDefinition, len(goAutoMenuGroupMetadata))
|
|
copy(groups, goAutoMenuGroupMetadata)
|
|
for index := range groups {
|
|
groups[index].ModuleKeys = append([]string(nil), goAutoMenuGroupMetadata[index].ModuleKeys...)
|
|
}
|
|
return groups
|
|
}
|
|
|
|
func moduleKeyForAPI(path string) string {
|
|
switch {
|
|
case strings.HasPrefix(path, "/api/admin/v1/devices"):
|
|
return ModuleDevices
|
|
case strings.HasPrefix(path, "/api/admin/v1/agent-app-releases"):
|
|
return ModuleDevices
|
|
case strings.HasPrefix(path, "/api/admin/v1/pdd-product"):
|
|
return ModulePDDProducts
|
|
case strings.HasPrefix(path, "/api/admin/v1/shopee-products"):
|
|
return ModuleShopeeProducts
|
|
case strings.HasPrefix(path, "/api/admin/v1/syb-products/sync-runs"):
|
|
return ModuleSYBSyncRuns
|
|
case strings.HasPrefix(path, "/api/admin/v1/syb-products"):
|
|
return ModuleSYBProducts
|
|
case strings.HasPrefix(path, "/api/admin/v1/syb-shops"):
|
|
return ModuleSYBShops
|
|
case strings.HasPrefix(path, "/api/admin/v1/syb-inner-codes"):
|
|
return ModuleSYBInnerCodes
|
|
case strings.HasPrefix(path, "/api/admin/v1/collection-rules"):
|
|
return ModuleCollectionRules
|
|
case strings.HasPrefix(path, "/api/admin/v1/purchase-rules"):
|
|
return ModulePurchaseRules
|
|
case strings.HasPrefix(path, "/api/admin/v1/collection-tasks"):
|
|
return ModuleCollectionTasks
|
|
case strings.HasPrefix(path, "/api/admin/v1/purchase-tasks"):
|
|
return ModulePurchaseTasks
|
|
case strings.HasPrefix(path, "/api/admin/v1/ai-matching-settings"):
|
|
return ModuleAIMatching
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func ModuleByRouteName(routeName string) (ModuleDefinition, bool) {
|
|
for _, module := range GoAutoModules() {
|
|
if module.RouteName == routeName {
|
|
return module, true
|
|
}
|
|
}
|
|
return ModuleDefinition{}, false
|
|
}
|