- 新增访问统计:visitstats 服务与查询、visit_capture 中间件、爬虫/来源识别、管理端 analytics 页面 - 新增侧边栏:sidebar 服务与 handler、管理端 sidebar 配置页、前端侧边栏组件 - 新增 widget 嵌入代码生成(widgetCode)与 widgetApi - 遥测逻辑迁移至 handler 层,删除 service/telemetry - env 示例补充 Docker 部署可信代理 IP 说明
124 lines
3.9 KiB
Go
124 lines
3.9 KiB
Go
package handler
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/freefire/jiang13-bbs/model"
|
|
"github.com/freefire/jiang13-bbs/service"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// GET /api/sidebar 公开侧栏载荷(布局 + 启用中的自定义工具)
|
|
func (h *Handlers) GetSidebar(c *gin.Context) {
|
|
payload, err := h.Sidebar.PublicPayload()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取侧栏配置失败"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, payload)
|
|
}
|
|
|
|
// GET /api/admin/sidebar 管理端全量(生效配置 + 全部工具)
|
|
func (h *Handlers) AdminGetSidebar(c *gin.Context) {
|
|
cfg, err := h.Sidebar.GetConfig()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取侧栏配置失败"})
|
|
return
|
|
}
|
|
widgets, err := h.Sidebar.ListWidgets()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取侧栏工具失败"})
|
|
return
|
|
}
|
|
if widgets == nil {
|
|
widgets = []model.SidebarWidget{}
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"config": cfg, "widgets": widgets})
|
|
}
|
|
|
|
// PUT /api/admin/sidebar/config 保存布局配置
|
|
func (h *Handlers) AdminSaveSidebarConfig(c *gin.Context) {
|
|
var req struct {
|
|
Config *service.SidebarConfig `json:"config"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil || req.Config == nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
|
return
|
|
}
|
|
saved, err := h.Sidebar.SaveConfig(*req.Config)
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrSidebarInvalid) {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "侧栏布局配置无效"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存侧栏配置失败"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"config": saved})
|
|
}
|
|
|
|
// POST /api/admin/sidebar/widgets 新建自定义工具
|
|
func (h *Handlers) AdminCreateSidebarWidget(c *gin.Context) {
|
|
var w model.SidebarWidget
|
|
if err := c.ShouldBindJSON(&w); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
|
return
|
|
}
|
|
if err := h.Sidebar.CreateWidget(&w); err != nil {
|
|
if errors.Is(err, service.ErrSidebarInvalid) {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "工具名称或代码长度无效"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "创建侧栏工具失败"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"widget": w})
|
|
}
|
|
|
|
// PUT /api/admin/sidebar/widgets/:id 更新工具(内容 + 启用态)
|
|
func (h *Handlers) AdminUpdateSidebarWidget(c *gin.Context) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil || id == 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
|
return
|
|
}
|
|
var body model.SidebarWidget
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
|
return
|
|
}
|
|
if err := h.Sidebar.UpdateWidget(uint(id), &body); err != nil {
|
|
if errors.Is(err, service.ErrSidebarWidgetNotFound) {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "侧栏工具不存在"})
|
|
return
|
|
}
|
|
if errors.Is(err, service.ErrSidebarInvalid) {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "工具名称或代码长度无效"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "更新侧栏工具失败"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
}
|
|
|
|
// DELETE /api/admin/sidebar/widgets/:id 删除工具并清理布局引用
|
|
func (h *Handlers) AdminDeleteSidebarWidget(c *gin.Context) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil || id == 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
|
return
|
|
}
|
|
if err := h.Sidebar.DeleteWidget(uint(id)); err != nil {
|
|
if errors.Is(err, service.ErrSidebarWidgetNotFound) {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "侧栏工具不存在"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "删除侧栏工具失败"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
}
|