package controller import ( "net/http" "strconv" "gofaster/internal/auth/model" "gofaster/internal/auth/service" "gofaster/internal/shared/response" "github.com/gin-gonic/gin" "go.uber.org/zap" ) // MenuRouteController 菜单路由关联表控制器 type MenuRouteController struct { menuRouteService *service.MenuRouteService log *zap.Logger } // NewMenuRouteController 创建菜单路由关联表控制器 func NewMenuRouteController(menuRouteService *service.MenuRouteService, log *zap.Logger) *MenuRouteController { return &MenuRouteController{ menuRouteService: menuRouteService, log: log, } } // CreateMenuRoute 创建菜单路由关联 // @Summary 创建菜单路由关联 // @Description 创建菜单与路由的多对多关联关系 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param menuRoute body model.MenuRoute true "菜单路由关联信息" // @Success 200 {object} response.Response{data=model.MenuRoute} // @Failure 400 {object} response.Response // @Router /api/menu-routes [post] func (c *MenuRouteController) CreateMenuRoute(ctx *gin.Context) { var menuRoute model.MenuRoute if err := ctx.ShouldBindJSON(&menuRoute); err != nil { response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error()) return } if err := c.menuRouteService.CreateMenuRoute(&menuRoute); err != nil { response.Error(ctx, http.StatusInternalServerError, "创建菜单路由关联失败", err.Error()) return } response.Success(ctx, "创建菜单路由关联成功", menuRoute) } // CreateMenuRoutes 批量创建菜单路由关联 // @Summary 批量创建菜单路由关联 // @Description 为指定菜单批量创建路由关联 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param menuID path int true "菜单ID" // @Param routeMappingIDs body []uint true "路由映射ID列表" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Router /api/menus/{menuID}/routes [post] func (c *MenuRouteController) CreateMenuRoutes(ctx *gin.Context) { menuIDStr := ctx.Param("menuID") menuID, err := strconv.ParseUint(menuIDStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "菜单ID格式错误", err.Error()) return } var routeMappingIDs []uint if err := ctx.ShouldBindJSON(&routeMappingIDs); err != nil { response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error()) return } if err := c.menuRouteService.CreateMenuRoutes(uint(menuID), routeMappingIDs); err != nil { response.Error(ctx, http.StatusInternalServerError, "批量创建菜单路由关联失败", err.Error()) return } response.Success(ctx, "批量创建菜单路由关联成功", nil) } // GetMenuRoutes 获取菜单的路由关联 // @Summary 获取菜单的路由关联 // @Description 获取指定菜单的所有路由关联 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param menuID path int true "菜单ID" // @Success 200 {object} response.Response{data=[]model.MenuRoute} // @Failure 400 {object} response.Response // @Router /api/menus/{menuID}/routes [get] func (c *MenuRouteController) GetMenuRoutes(ctx *gin.Context) { menuIDStr := ctx.Param("menuID") menuID, err := strconv.ParseUint(menuIDStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "菜单ID格式错误", err.Error()) return } menuRoutes, err := c.menuRouteService.GetMenuRoutes(uint(menuID)) if err != nil { response.Error(ctx, http.StatusInternalServerError, "获取菜单路由关联失败", err.Error()) return } response.Success(ctx, "获取菜单路由关联成功", menuRoutes) } // GetRouteMenus 获取路由的菜单关联 // @Summary 获取路由的菜单关联 // @Description 获取指定路由的所有菜单关联 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param routeMappingID path int true "路由映射ID" // @Success 200 {object} response.Response{data=[]model.MenuRoute} // @Failure 400 {object} response.Response // @Router /api/route-mappings/{routeMappingID}/menus [get] func (c *MenuRouteController) GetRouteMenus(ctx *gin.Context) { routeMappingIDStr := ctx.Param("routeMappingID") routeMappingID, err := strconv.ParseUint(routeMappingIDStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "路由映射ID格式错误", err.Error()) return } menuRoutes, err := c.menuRouteService.GetRouteMenus(uint(routeMappingID)) if err != nil { response.Error(ctx, http.StatusInternalServerError, "获取路由菜单关联失败", err.Error()) return } response.Success(ctx, "获取路由菜单关联成功", menuRoutes) } // GetMenuWithRoutes 获取菜单及其关联的路由信息 // @Summary 获取菜单及其关联的路由信息 // @Description 获取菜单详细信息及其关联的所有路由 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param menuID path int true "菜单ID" // @Success 200 {object} response.Response{data=map[string]interface{}} // @Failure 400 {object} response.Response // @Router /api/menus/{menuID}/routes/detail [get] func (c *MenuRouteController) GetMenuWithRoutes(ctx *gin.Context) { menuIDStr := ctx.Param("menuID") menuID, err := strconv.ParseUint(menuIDStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "菜单ID格式错误", err.Error()) return } menu, routes, err := c.menuRouteService.GetMenuWithRoutes(uint(menuID)) if err != nil { response.Error(ctx, http.StatusInternalServerError, "获取菜单及路由信息失败", err.Error()) return } result := map[string]interface{}{ "menu": menu, "routes": routes, } response.Success(ctx, "获取菜单及路由信息成功", result) } // GetRouteWithMenus 获取路由及其关联的菜单信息 // @Summary 获取路由及其关联的菜单信息 // @Description 获取路由详细信息及其关联的所有菜单 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param routeMappingID path int true "路由映射ID" // @Success 200 {object} response.Response{data=map[string]interface{}} // @Failure 400 {object} response.Response // @Router /api/route-mappings/{routeMappingID}/menus/detail [get] func (c *MenuRouteController) GetRouteWithMenus(ctx *gin.Context) { routeMappingIDStr := ctx.Param("routeMappingID") routeMappingID, err := strconv.ParseUint(routeMappingIDStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "路由映射ID格式错误", err.Error()) return } route, menus, err := c.menuRouteService.GetRouteWithMenus(uint(routeMappingID)) if err != nil { response.Error(ctx, http.StatusInternalServerError, "获取路由及菜单信息失败", err.Error()) return } result := map[string]interface{}{ "route": route, "menus": menus, } response.Success(ctx, "获取路由及菜单信息成功", result) } // UpdateMenuRoute 更新菜单路由关联 // @Summary 更新菜单路由关联 // @Description 更新菜单路由关联信息 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param id path int true "关联ID" // @Param menuRoute body model.MenuRoute true "菜单路由关联信息" // @Success 200 {object} response.Response{data=model.MenuRoute} // @Failure 400 {object} response.Response // @Router /api/menu-routes/{id} [put] func (c *MenuRouteController) UpdateMenuRoute(ctx *gin.Context) { idStr := ctx.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "ID格式错误", err.Error()) return } var menuRoute model.MenuRoute if err := ctx.ShouldBindJSON(&menuRoute); err != nil { response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error()) return } menuRoute.ID = uint(id) if err := c.menuRouteService.UpdateMenuRoute(&menuRoute); err != nil { response.Error(ctx, http.StatusInternalServerError, "更新菜单路由关联失败", err.Error()) return } response.Success(ctx, "更新菜单路由关联成功", menuRoute) } // DeleteMenuRoute 删除菜单路由关联 // @Summary 删除菜单路由关联 // @Description 删除指定的菜单路由关联 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param id path int true "关联ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Router /api/menu-routes/{id} [delete] func (c *MenuRouteController) DeleteMenuRoute(ctx *gin.Context) { idStr := ctx.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "ID格式错误", err.Error()) return } if err := c.menuRouteService.DeleteMenuRoute(uint(id)); err != nil { response.Error(ctx, http.StatusInternalServerError, "删除菜单路由关联失败", err.Error()) return } response.Success(ctx, "删除菜单路由关联成功", nil) } // DeleteMenuRoutes 删除菜单的所有路由关联 // @Summary 删除菜单的所有路由关联 // @Description 删除指定菜单的所有路由关联 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param menuID path int true "菜单ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Router /api/menus/{menuID}/routes [delete] func (c *MenuRouteController) DeleteMenuRoutes(ctx *gin.Context) { menuIDStr := ctx.Param("menuID") menuID, err := strconv.ParseUint(menuIDStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "菜单ID格式错误", err.Error()) return } if err := c.menuRouteService.DeleteMenuRoutes(uint(menuID)); err != nil { response.Error(ctx, http.StatusInternalServerError, "删除菜单路由关联失败", err.Error()) return } response.Success(ctx, "删除菜单路由关联成功", nil) } // SyncMenuRoutes 同步菜单路由关联 // @Summary 同步菜单路由关联 // @Description 同步菜单的路由关联(删除现有关联并创建新关联) // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param menuID path int true "菜单ID" // @Param routeMappingIDs body []uint true "路由映射ID列表" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Router /api/menus/{menuID}/routes/sync [post] func (c *MenuRouteController) SyncMenuRoutes(ctx *gin.Context) { menuIDStr := ctx.Param("menuID") menuID, err := strconv.ParseUint(menuIDStr, 10, 32) if err != nil { response.Error(ctx, http.StatusBadRequest, "菜单ID格式错误", err.Error()) return } var routeMappingIDs []uint if err := ctx.ShouldBindJSON(&routeMappingIDs); err != nil { response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error()) return } if err := c.menuRouteService.SyncMenuRoutes(uint(menuID), routeMappingIDs); err != nil { response.Error(ctx, http.StatusInternalServerError, "同步菜单路由关联失败", err.Error()) return } response.Success(ctx, "同步菜单路由关联成功", nil) } // ListMenuRoutes 获取菜单路由关联列表 // @Summary 获取菜单路由关联列表 // @Description 分页获取菜单路由关联列表 // @Tags 菜单路由关联 // @Accept json // @Produce json // @Param page query int false "页码" default(1) // @Param pageSize query int false "每页数量" default(10) // @Success 200 {object} response.Response{data=map[string]interface{}} // @Failure 400 {object} response.Response // @Router /api/menu-routes [get] func (c *MenuRouteController) ListMenuRoutes(ctx *gin.Context) { pageStr := ctx.DefaultQuery("page", "1") pageSizeStr := ctx.DefaultQuery("pageSize", "10") page, err := strconv.Atoi(pageStr) if err != nil { response.Error(ctx, http.StatusBadRequest, "页码格式错误", err.Error()) return } pageSize, err := strconv.Atoi(pageSizeStr) if err != nil { response.Error(ctx, http.StatusBadRequest, "每页数量格式错误", err.Error()) return } menuRoutes, total, err := c.menuRouteService.ListMenuRoutes(page, pageSize) if err != nil { response.Error(ctx, http.StatusInternalServerError, "获取菜单路由关联列表失败", err.Error()) return } result := map[string]interface{}{ "list": menuRoutes, "total": total, "page": page, "pageSize": pageSize, "pageCount": (total + int64(pageSize) - 1) / int64(pageSize), } response.Success(ctx, "获取菜单路由关联列表成功", result) }