package handler import ( "strconv" "gotest/internal/model" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // tableRegistry 映射前端模块名 → GORM 模型(用于通用 CRUD) var tableRegistry = map[string]interface{}{ // 企业模块 "enterprise_company": &model.Company{}, "enterprise_news": &model.EnterpriseNews{}, "enterprise_services": &model.EnterpriseService{}, "enterprise_team": &model.TeamMember{}, // 电商模块 "shop_products": &model.Product{}, "shop_categories": &model.ProductCategory{}, // 外卖模块 "food_restaurants": &model.Restaurant{}, "food_categories": &model.RestaurantCategory{}, "food_menu_items": &model.MenuItem{}, "food_menu_categories": &model.MenuCategory{}, // 游戏模块 "game_games": &model.Game{}, "game_categories": &model.GameCategory{}, // 应用模块 "app_apps": &model.App{}, "app_categories": &model.AppCategory{}, // 音乐模块 "music_songs": &model.Song{}, "music_categories": &model.MusicCategory{}, } // tableLabels 模块中文标签(用于前端展示) var tableLabels = map[string]string{ "enterprise_company": "企业信息", "enterprise_news": "企业新闻", "enterprise_services": "企业服务", "enterprise_team": "团队成员", "shop_products": "商品管理", "shop_categories": "商品分类", "food_restaurants": "餐厅管理", "food_categories": "餐厅分类", "food_menu_items": "菜品管理", "food_menu_categories": "菜品分类", "game_games": "游戏管理", "game_categories": "游戏分类", "app_apps": "应用管理", "app_categories": "应用分类", "music_songs": "歌曲管理", "music_categories": "音乐分类", } // tablesWithSort 拥有 sort 列的表(用于排序) var tablesWithSort = map[string]bool{ "enterprise_services": true, "enterprise_team": true, "shop_products": true, "shop_categories": true, "food_restaurants": true, "food_categories": true, "food_menu_items": true, "food_menu_categories": true, "game_games": true, "game_categories": true, "app_apps": true, "app_categories": true, "music_songs": true, "music_categories": true, } // tablesWithName 拥有 name 列的表(用于关键词搜索) var tablesWithName = map[string]bool{ "enterprise_company": true, "enterprise_team": true, "enterprise_services": false, // 有 title 无 name "enterprise_news": false, "shop_products": true, "shop_categories": true, "food_restaurants": true, "food_categories": true, "food_menu_items": true, "food_menu_categories": true, "game_games": true, "game_categories": true, "app_apps": true, "app_categories": true, "music_songs": false, // 有 title 无 name "music_categories": true, } // tablesWithTitle 拥有 title 列的表(用于关键词搜索) var tablesWithTitle = map[string]bool{ "enterprise_news": true, "enterprise_services": true, "music_songs": true, } // tablesWithStatus 拥有 status 列的表(用于状态过滤) var tablesWithStatus = map[string]bool{ "enterprise_news": true, "shop_products": true, "food_restaurants": true, "food_menu_items": true, "game_games": true, "app_apps": true, "music_songs": true, } // DashboardHandler 管理后台仪表盘处理器(通用 CRUD + 统计) type DashboardHandler struct { db *gorm.DB } // NewDashboardHandler 创建仪表盘处理器 func NewDashboardHandler(db *gorm.DB) *DashboardHandler { return &DashboardHandler{db: db} } // GetStats 获取仪表盘统计数据 GET /api/v1/admin/dashboard/stats func (h *DashboardHandler) GetStats(c *gin.Context) { stats := gin.H{} // 用户统计 var userCount int64 h.db.Model(&model.User{}).Count(&userCount) stats["users"] = userCount // 各业务模块统计 for table, modelType := range tableRegistry { var count int64 h.db.Model(modelType).Count(&count) stats[table] = count } // 按业务线分组 grouped := gin.H{ "enterprise": gin.H{ "label": "企业官网", "items": gin.H{ "company": stats["enterprise_company"], "news": stats["enterprise_news"], "services": stats["enterprise_services"], "team": stats["enterprise_team"], }, }, "shop": gin.H{ "label": "跨境电商", "items": gin.H{ "products": stats["shop_products"], "categories": stats["shop_categories"], }, }, "food": gin.H{ "label": "外卖平台", "items": gin.H{ "restaurants": stats["food_restaurants"], "categories": stats["food_categories"], "menu_items": stats["food_menu_items"], "menu_categories": stats["food_menu_categories"], }, }, "game": gin.H{ "label": "游戏平台", "items": gin.H{ "games": stats["game_games"], "categories": stats["game_categories"], }, }, "app": gin.H{ "label": "应用商店", "items": gin.H{ "apps": stats["app_apps"], "categories": stats["app_categories"], }, }, "music": gin.H{ "label": "音乐平台", "items": gin.H{ "songs": stats["music_songs"], "categories": stats["music_categories"], }, }, } Success(c, gin.H{ "total_counts": stats, "grouped": grouped, "tables": getTableList(), }) } // getTableList 返回所有可管理的表列表 func getTableList() []gin.H { list := make([]gin.H, 0, len(tableRegistry)) for key := range tableRegistry { list = append(list, gin.H{ "key": key, "label": tableLabels[key], }) } return list } // ListItems 通用列表查询 GET /api/v1/admin/dashboard/:table func (h *DashboardHandler) ListItems(c *gin.Context) { table := c.Param("table") modelType, ok := tableRegistry[table] if !ok { FailBadRequest(c, "无效的数据表: "+table) return } page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) keyword := c.Query("keyword") status := c.Query("status") if page < 1 { page = 1 } if pageSize < 1 || pageSize > 100 { pageSize = 20 } offset := (page - 1) * pageSize query := h.db.Model(modelType) // 关键词搜索(根据表实际拥有的列动态构建条件) if keyword != "" { hasName := tablesWithName[table] hasTitle := tablesWithTitle[table] switch { case hasName && hasTitle: query = query.Where("name LIKE ? OR title LIKE ?", "%"+keyword+"%", "%"+keyword+"%") case hasName: query = query.Where("name LIKE ?", "%"+keyword+"%") case hasTitle: query = query.Where("title LIKE ?", "%"+keyword+"%") } } // 状态过滤(仅对拥有 status 列的表生效) if status != "" && tablesWithStatus[table] { query = query.Where("status = ?", status) } var total int64 query.Count(&total) // 排序:有 sort 列的表按 sort ASC, id DESC;否则按 id DESC orderClause := "id DESC" if tablesWithSort[table] { orderClause = "sort ASC, id DESC" } var results []map[string]interface{} if err := query.Order(orderClause).Offset(offset).Limit(pageSize).Find(&results).Error; err != nil { FailInternal(c, "查询失败: "+err.Error()) return } Success(c, gin.H{ "list": results, "total": total, "page": page, "page_size": pageSize, }) } // CreateItem 通用创建 POST /api/v1/admin/dashboard/:table func (h *DashboardHandler) CreateItem(c *gin.Context) { table := c.Param("table") modelType, ok := tableRegistry[table] if !ok { FailBadRequest(c, "无效的数据表: "+table) return } var body map[string]interface{} if err := c.ShouldBindJSON(&body); err != nil { FailBadRequest(c, "参数解析失败") return } if err := h.db.Model(modelType).Create(&body).Error; err != nil { FailBadRequest(c, "创建失败: "+err.Error()) return } Success(c, body) } // UpdateItem 通用更新 PUT /api/v1/admin/dashboard/:table/:id func (h *DashboardHandler) UpdateItem(c *gin.Context) { table := c.Param("table") modelType, ok := tableRegistry[table] if !ok { FailBadRequest(c, "无效的数据表: "+table) return } id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { FailBadRequest(c, "无效的 ID") return } var body map[string]interface{} if err := c.ShouldBindJSON(&body); err != nil { FailBadRequest(c, "参数解析失败") return } // 移除不允许更新的字段 delete(body, "id") delete(body, "created_at") if err := h.db.Model(modelType).Where("id = ?", id).Updates(body).Error; err != nil { FailBadRequest(c, "更新失败: "+err.Error()) return } SuccessMsg(c, "更新成功") } // DeleteItem 通用删除 DELETE /api/v1/admin/dashboard/:table/:id func (h *DashboardHandler) DeleteItem(c *gin.Context) { table := c.Param("table") modelType, ok := tableRegistry[table] if !ok { FailBadRequest(c, "无效的数据表: "+table) return } id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { FailBadRequest(c, "无效的 ID") return } if err := h.db.Model(modelType).Where("id = ?", id).Delete(nil).Error; err != nil { FailBadRequest(c, "删除失败: "+err.Error()) return } SuccessMsg(c, "删除成功") }