282 lines
7.0 KiB
Go
282 lines
7.0 KiB
Go
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": "音乐分类",
|
||
}
|
||
|
||
// 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)
|
||
|
||
// 关键词搜索(按 name 或 title 字段)
|
||
if keyword != "" {
|
||
query = query.Where("name LIKE ? OR title LIKE ?", "%"+keyword+"%", "%"+keyword+"%")
|
||
}
|
||
|
||
// 状态过滤
|
||
if status != "" {
|
||
query = query.Where("status = ?", status)
|
||
}
|
||
|
||
var total int64
|
||
query.Count(&total)
|
||
|
||
var results []map[string]interface{}
|
||
if err := query.Order("sort ASC, id DESC").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, "删除成功")
|
||
}
|