// Logan.Li // 导航链接相关处理器方法 // 从 navigation.go 拆分而来,包含导航链接的 CRUD 及收藏功能 package controller import ( "encoding/json" "net/http" "strconv" "ezops/model" "github.com/gin-gonic/gin" ) // ListLinks 获取导航链接列表 // @Summary 获取导航链接列表 // @Description 获取所有导航链接列表 // @Tags 站内导航 // @Produce json // @Security Bearer // @Param group_id query int false "分组ID" // @Param keyword query string false "搜索关键词" // @Success 200 {object} model.Response{data=[]model.NavigationLink} // @Router /navigations/links [get] func (h *NavigationHandler) ListLinks(c *gin.Context) { db := h.db.Model(&model.NavigationLink{}).Preload("Group") // 分组过滤 if groupID := c.Query("group_id"); groupID != "" { db = db.Where("group_id = ?", groupID) } // 关键词搜索 if keyword := c.Query("keyword"); keyword != "" { db = db.Where("name LIKE ? OR description LIKE ?", "%"+keyword+"%", "%"+keyword+"%") } var links []model.NavigationLink db.Order("sort ASC, created_at ASC").Find(&links) c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "success", Data: links, }) } // CreateLink 创建导航链接 // @Summary 创建导航链接 // @Description 创建新导航链接 // @Tags 站内导航 // @Accept json // @Produce json // @Security Bearer // @Param request body model.CreateNavigationLinkRequest true "创建请求" // @Success 200 {object} model.Response{data=model.NavigationLink} // @Router /navigations/links [post] func (h *NavigationHandler) CreateLink(c *gin.Context) { var req model.CreateNavigationLinkRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, model.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } tags, _ := json.Marshal(req.Tags) link := model.NavigationLink{ GroupID: req.GroupID, Name: req.Name, URL: req.URL, Description: req.Description, Icon: req.Icon, Tags: string(tags), Sort: req.Sort, Enabled: true, } if err := h.db.Create(&link).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "创建失败", }) return } // 更新分组链接数 h.db.Model(&model.NavigationGroup{}).Where("id = ?", req.GroupID). UpdateColumn("link_count", h.db.Model(&model.NavigationLink{}).Where("group_id = ?", req.GroupID).Select("COUNT(*)")) h.db.Preload("Group").First(&link, link.ID) c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "创建成功", Data: link, }) } // UpdateLink 更新导航链接 // @Summary 更新导航链接 // @Description 更新指定导航链接 // @Tags 站内导航 // @Accept json // @Produce json // @Security Bearer // @Param id path int true "链接ID" // @Param request body model.UpdateNavigationLinkRequest true "更新请求" // @Success 200 {object} model.Response{data=model.NavigationLink} // @Router /navigations/links/{id} [put] func (h *NavigationHandler) UpdateLink(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req model.UpdateNavigationLinkRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, model.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } var link model.NavigationLink if err := h.db.First(&link, id).Error; err != nil { c.JSON(http.StatusNotFound, model.Response{ Code: 404, Message: "链接不存在", }) return } updates := map[string]interface{}{} if req.GroupID > 0 { updates["group_id"] = req.GroupID } if req.Name != "" { updates["name"] = req.Name } if req.URL != "" { updates["url"] = req.URL } if req.Description != "" { updates["description"] = req.Description } if req.Icon != "" { updates["icon"] = req.Icon } if len(req.Tags) > 0 { tags, _ := json.Marshal(req.Tags) updates["tags"] = string(tags) } updates["sort"] = req.Sort if req.Enabled != nil { updates["enabled"] = *req.Enabled } if err := h.db.Model(&link).Updates(updates).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "更新失败", }) return } h.db.Preload("Group").First(&link, id) c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "更新成功", Data: link, }) } // DeleteLink 删除导航链接 // @Summary 删除导航链接 // @Description 删除指定导航链接 // @Tags 站内导航 // @Produce json // @Security Bearer // @Param id path int true "链接ID" // @Success 200 {object} model.Response // @Router /navigations/links/{id} [delete] func (h *NavigationHandler) DeleteLink(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var link model.NavigationLink h.db.First(&link, id) if err := h.db.Delete(&model.NavigationLink{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "删除失败", }) return } // 更新分组链接数 if link.GroupID > 0 { h.db.Model(&model.NavigationGroup{}).Where("id = ?", link.GroupID). UpdateColumn("link_count", h.db.Model(&model.NavigationLink{}).Where("group_id = ?", link.GroupID).Select("COUNT(*)")) } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "删除成功", }) } // ToggleFavorite 切换收藏状态 // @Summary 切换收藏状态 // @Description 切换导航链接的收藏状态 // @Tags 站内导航 // @Accept json // @Produce json // @Security Bearer // @Param id path int true "链接ID" // @Param request body model.ToggleFavoriteRequest true "收藏请求" // @Success 200 {object} model.Response{data=model.NavigationLink} // @Router /navigations/links/{id}/favorite [post] func (h *NavigationHandler) ToggleFavorite(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req model.ToggleFavoriteRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, model.Response{ Code: 400, Message: "请求参数错误", }) return } var link model.NavigationLink if err := h.db.First(&link, id).Error; err != nil { c.JSON(http.StatusNotFound, model.Response{ Code: 404, Message: "链接不存在", }) return } link.IsFavorite = req.IsFavorite if err := h.db.Save(&link).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "操作失败", }) return } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "操作成功", Data: link, }) }