init: 初始化项目
This commit is contained in:
77
internal/api/handler/app.go
Normal file
77
internal/api/handler/app.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"nebula/internal/api/response"
|
||||
"nebula/internal/app"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type AppHandler struct {
|
||||
service *app.AppService
|
||||
}
|
||||
|
||||
func NewAppHandler(service *app.AppService) *AppHandler {
|
||||
return &AppHandler{service: service}
|
||||
}
|
||||
|
||||
func (h *AppHandler) List(c *gin.Context) {
|
||||
apps, err := h.service.List()
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, apps)
|
||||
}
|
||||
|
||||
func (h *AppHandler) Get(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
app, err := h.service.Get(id)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, app)
|
||||
}
|
||||
|
||||
func (h *AppHandler) Create(c *gin.Context) {
|
||||
var app app.App
|
||||
if err := c.ShouldBindJSON(&app); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
err := h.service.Create(app)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "created")
|
||||
}
|
||||
|
||||
func (h *AppHandler) Update(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var app app.App
|
||||
if err := c.ShouldBindJSON(&app); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
err := h.service.Update(id, map[string]any{
|
||||
"name": app.Name,
|
||||
"description": app.Description,
|
||||
})
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "updated")
|
||||
}
|
||||
|
||||
func (h *AppHandler) Delete(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
err := h.service.Delete(id)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "deleted")
|
||||
}
|
||||
212
internal/api/handler/asset.go
Normal file
212
internal/api/handler/asset.go
Normal file
@@ -0,0 +1,212 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"nebula/internal/api/response"
|
||||
"nebula/internal/asset"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type AssetHandler struct {
|
||||
service *asset.AssetService
|
||||
}
|
||||
|
||||
func NewAssetHandler(service *asset.AssetService) *AssetHandler {
|
||||
return &AssetHandler{service: service}
|
||||
}
|
||||
|
||||
// List 获取所有资源列表
|
||||
// GET /api/assets
|
||||
func (h *AssetHandler) List(c *gin.Context) {
|
||||
assets, err := h.service.List()
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, assets)
|
||||
}
|
||||
|
||||
// ListByRelease 获取指定发布版本的所有资源
|
||||
// GET /api/releases/:id/assets
|
||||
func (h *AssetHandler) ListByRelease(c *gin.Context) {
|
||||
releaseID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid release id")
|
||||
return
|
||||
}
|
||||
|
||||
assets, err := h.service.ListByRelease(uint(releaseID))
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, assets)
|
||||
}
|
||||
|
||||
// Get 获取单个资源详情
|
||||
// GET /api/assets/:id
|
||||
func (h *AssetHandler) Get(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid asset id")
|
||||
return
|
||||
}
|
||||
|
||||
ast, err := h.service.Get(uint(id))
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, ast)
|
||||
}
|
||||
|
||||
// Upload 上传文件并创建资源
|
||||
// POST /api/releases/:id/assets/upload
|
||||
func (h *AssetHandler) Upload(c *gin.Context) {
|
||||
releaseID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid release id")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取表单参数
|
||||
platform := c.PostForm("platform")
|
||||
arch := c.PostForm("arch")
|
||||
|
||||
if platform == "" || arch == "" {
|
||||
response.FailBadRequest(c, "platform and arch are required")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取上传的文件
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "file is required")
|
||||
return
|
||||
}
|
||||
|
||||
// 验证文件扩展名(可选)
|
||||
ext := filepath.Ext(file.Filename)
|
||||
allowedExts := map[string]bool{
|
||||
".exe": true, ".dmg": true, ".pkg": true, ".deb": true,
|
||||
".rpm": true, ".appimage": true, ".zip": true, ".tar.gz": true,
|
||||
".msi": true, ".app": true,
|
||||
}
|
||||
if !allowedExts[ext] {
|
||||
response.FailBadRequest(c, "unsupported file type: "+ext)
|
||||
return
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
ast, err := h.service.Upload(uint(releaseID), platform, arch, file)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Ok(c, ast)
|
||||
}
|
||||
|
||||
// Create 创建资源记录(用于外部 URL)
|
||||
// POST /api/assets
|
||||
func (h *AssetHandler) Create(c *gin.Context) {
|
||||
var ast asset.Asset
|
||||
if err := c.ShouldBindJSON(&ast); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 基本验证
|
||||
if ast.ReleaseID == 0 {
|
||||
response.FailBadRequest(c, "releaseId is required")
|
||||
return
|
||||
}
|
||||
if ast.Platform == "" {
|
||||
response.FailBadRequest(c, "platform is required")
|
||||
return
|
||||
}
|
||||
if ast.Arch == "" {
|
||||
response.FailBadRequest(c, "arch is required")
|
||||
return
|
||||
}
|
||||
if ast.URL == "" {
|
||||
response.FailBadRequest(c, "url is required")
|
||||
return
|
||||
}
|
||||
|
||||
err := h.service.Create(ast)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "created")
|
||||
}
|
||||
|
||||
// Update 更新资源信息
|
||||
// PUT /api/assets/:id
|
||||
func (h *AssetHandler) Update(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid asset id")
|
||||
return
|
||||
}
|
||||
|
||||
var ast asset.Asset
|
||||
if err := c.ShouldBindJSON(&ast); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"platform": ast.Platform,
|
||||
"arch": ast.Arch,
|
||||
"signature": ast.Signature,
|
||||
"checksum": ast.Checksum,
|
||||
}
|
||||
|
||||
err = h.service.Update(uint(id), data)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "updated")
|
||||
}
|
||||
|
||||
// Delete 删除资源
|
||||
// DELETE /api/assets/:id
|
||||
func (h *AssetHandler) Delete(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid asset id")
|
||||
return
|
||||
}
|
||||
|
||||
err = h.service.Delete(uint(id))
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "deleted")
|
||||
}
|
||||
|
||||
// Download 下载资源文件
|
||||
// GET /api/assets/:id/download
|
||||
func (h *AssetHandler) Download(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid asset id")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取存储路径
|
||||
storagePath, err := h.service.GetStoragePath(uint(id))
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 返回文件(Gin 会自动处理文件下载)
|
||||
c.File(storagePath)
|
||||
}
|
||||
124
internal/api/handler/auth.go
Normal file
124
internal/api/handler/auth.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"nebula/internal/api/response"
|
||||
"nebula/internal/auth"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type AuthHandler struct {
|
||||
service *auth.AuthService
|
||||
}
|
||||
|
||||
func NewAuthHandler(service *auth.AuthService) *AuthHandler {
|
||||
return &AuthHandler{service: service}
|
||||
}
|
||||
|
||||
// Register 用户注册
|
||||
// POST /api/auth/register
|
||||
func (h *AuthHandler) Register(c *gin.Context) {
|
||||
var req auth.RegisterRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
user, tokens, err := h.service.Register(req)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Ok(c, gin.H{
|
||||
"user": user,
|
||||
"tokens": tokens,
|
||||
})
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
// POST /api/auth/login
|
||||
func (h *AuthHandler) Login(c *gin.Context) {
|
||||
var req auth.LoginRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
user, tokens, err := h.service.Login(req)
|
||||
if err != nil {
|
||||
response.Fail(c, 401, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Ok(c, gin.H{
|
||||
"user": user,
|
||||
"tokens": tokens,
|
||||
})
|
||||
}
|
||||
|
||||
// RefreshToken 刷新访问令牌
|
||||
// POST /api/auth/refresh
|
||||
func (h *AuthHandler) RefreshToken(c *gin.Context) {
|
||||
var req auth.RefreshTokenRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
tokens, err := h.service.RefreshToken(req)
|
||||
if err != nil {
|
||||
response.Fail(c, 401, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Ok(c, tokens)
|
||||
}
|
||||
|
||||
// GetProfile 获取当前用户信息
|
||||
// GET /api/auth/profile
|
||||
func (h *AuthHandler) GetProfile(c *gin.Context) {
|
||||
userID, exists := auth.GetCurrentUserID(c)
|
||||
if !exists {
|
||||
response.Fail(c, 401, "unauthorized")
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.service.GetUserByID(userID)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Ok(c, user)
|
||||
}
|
||||
|
||||
// ChangePasswordRequest 修改密码请求
|
||||
type ChangePasswordRequest struct {
|
||||
OldPassword string `json:"oldPassword" binding:"required"`
|
||||
NewPassword string `json:"newPassword" binding:"required,min=6"`
|
||||
}
|
||||
|
||||
// ChangePassword 修改密码
|
||||
// POST /api/auth/change-password
|
||||
func (h *AuthHandler) ChangePassword(c *gin.Context) {
|
||||
userID, exists := auth.GetCurrentUserID(c)
|
||||
if !exists {
|
||||
response.Fail(c, 401, "unauthorized")
|
||||
return
|
||||
}
|
||||
|
||||
var req ChangePasswordRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err := h.service.ChangePassword(userID, req.OldPassword, req.NewPassword)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.OkMsg(c, "password changed successfully")
|
||||
}
|
||||
11
internal/api/handler/handle.go
Normal file
11
internal/api/handler/handle.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package handler
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type Handler struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func New(db *gorm.DB) *Handler {
|
||||
return &Handler{db: db}
|
||||
}
|
||||
155
internal/api/handler/release.go
Normal file
155
internal/api/handler/release.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"nebula/internal/api/response"
|
||||
"nebula/internal/release"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ReleaseHandler struct {
|
||||
service *release.ReleaseService
|
||||
}
|
||||
|
||||
func NewReleaseHandler(service *release.ReleaseService) *ReleaseHandler {
|
||||
return &ReleaseHandler{service: service}
|
||||
}
|
||||
|
||||
// List 获取所有版本列表
|
||||
// GET /api/releases
|
||||
func (h *ReleaseHandler) List(c *gin.Context) {
|
||||
releases, err := h.service.List()
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, releases)
|
||||
}
|
||||
|
||||
// ListByApp 获取指定应用的所有版本
|
||||
// GET /api/apps/:id/releases
|
||||
func (h *ReleaseHandler) ListByApp(c *gin.Context) {
|
||||
appID := c.Param("id")
|
||||
channel := c.Query("channel") // 可选的渠道过滤
|
||||
|
||||
var releases []release.Release
|
||||
var err error
|
||||
|
||||
if channel != "" {
|
||||
releases, err = h.service.ListByAppAndChannel(appID, channel)
|
||||
} else {
|
||||
releases, err = h.service.ListByApp(appID)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, releases)
|
||||
}
|
||||
|
||||
// Get 获取单个版本详情
|
||||
// GET /api/releases/:id
|
||||
func (h *ReleaseHandler) Get(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid release id")
|
||||
return
|
||||
}
|
||||
|
||||
rel, err := h.service.Get(uint(id))
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, rel)
|
||||
}
|
||||
|
||||
// GetLatest 获取应用的最新版本
|
||||
// GET /api/apps/:id/releases/latest
|
||||
func (h *ReleaseHandler) GetLatest(c *gin.Context) {
|
||||
appID := c.Param("id")
|
||||
channel := c.Query("channel")
|
||||
|
||||
rel, err := h.service.GetLatest(appID, channel)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.Ok(c, rel)
|
||||
}
|
||||
|
||||
// Create 创建新版本
|
||||
// POST /api/releases
|
||||
func (h *ReleaseHandler) Create(c *gin.Context) {
|
||||
var rel release.Release
|
||||
if err := c.ShouldBindJSON(&rel); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 基本验证
|
||||
if rel.AppID == "" {
|
||||
response.FailBadRequest(c, "app_id is required")
|
||||
return
|
||||
}
|
||||
if rel.Version == "" {
|
||||
response.FailBadRequest(c, "version is required")
|
||||
return
|
||||
}
|
||||
|
||||
err := h.service.Create(rel)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "created")
|
||||
}
|
||||
|
||||
// Update 更新版本信息
|
||||
// PUT /api/releases/:id
|
||||
func (h *ReleaseHandler) Update(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid release id")
|
||||
return
|
||||
}
|
||||
|
||||
var rel release.Release
|
||||
if err := c.ShouldBindJSON(&rel); err != nil {
|
||||
response.FailBadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"version": rel.Version,
|
||||
"notes": rel.Notes,
|
||||
"channel": rel.Channel,
|
||||
"pub_date": rel.PubDate,
|
||||
}
|
||||
|
||||
err = h.service.Update(uint(id), data)
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "updated")
|
||||
}
|
||||
|
||||
// Delete 删除版本
|
||||
// DELETE /api/releases/:id
|
||||
func (h *ReleaseHandler) Delete(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
response.FailBadRequest(c, "invalid release id")
|
||||
return
|
||||
}
|
||||
|
||||
err = h.service.Delete(uint(id))
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
response.OkMsg(c, "deleted")
|
||||
}
|
||||
26
internal/api/handler/update.go
Normal file
26
internal/api/handler/update.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"nebula/internal/api/response"
|
||||
"nebula/internal/updater"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (h *Handler) CheckUpdate(c *gin.Context) {
|
||||
req := updater.CheckRequest{
|
||||
App: c.Query("app"),
|
||||
Version: c.Query("version"),
|
||||
Platform: c.Query("platform"),
|
||||
Arch: c.Query("arch"),
|
||||
}
|
||||
|
||||
resp, err := updater.CheckUpdate(h.db, req)
|
||||
|
||||
if err != nil {
|
||||
response.FailServer(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Ok(c, resp)
|
||||
}
|
||||
47
internal/api/response/response.go
Normal file
47
internal/api/response/response.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Result 通用 REST 返回结构
|
||||
type Result struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data any `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// 常用业务码
|
||||
const (
|
||||
CodeOk = 0
|
||||
CodeFail = 1
|
||||
CodeInvalid = 400
|
||||
CodeServer = 500
|
||||
)
|
||||
|
||||
// Ok 成功,带数据
|
||||
func Ok(c *gin.Context, data interface{}) {
|
||||
c.JSON(http.StatusOK, Result{Code: CodeOk, Message: "success", Data: data})
|
||||
}
|
||||
|
||||
// OkMsg 成功,自定义消息,无数据
|
||||
func OkMsg(c *gin.Context, message string) {
|
||||
c.JSON(http.StatusOK, Result{Code: CodeOk, Message: message})
|
||||
}
|
||||
|
||||
// Fail 失败,业务码 + 消息
|
||||
func Fail(c *gin.Context, code int, message string) {
|
||||
c.JSON(http.StatusOK, Result{Code: code, Message: message})
|
||||
}
|
||||
|
||||
// FailBadRequest 参数错误 (HTTP 400)
|
||||
func FailBadRequest(c *gin.Context, message string) {
|
||||
c.JSON(http.StatusBadRequest, Result{Code: CodeInvalid, Message: message})
|
||||
}
|
||||
|
||||
// FailServer 服务端错误 (HTTP 500)
|
||||
func FailServer(c *gin.Context, message string) {
|
||||
c.JSON(http.StatusInternalServerError, Result{Code: CodeServer, Message: message})
|
||||
}
|
||||
88
internal/api/router.go
Normal file
88
internal/api/router.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"nebula/internal/api/handler"
|
||||
"nebula/internal/app"
|
||||
"nebula/internal/asset"
|
||||
"nebula/internal/auth"
|
||||
"nebula/internal/release"
|
||||
"nebula/internal/storage"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func RegisterRoutes(r *gin.Engine, db *gorm.DB, stor storage.Storage, jwtService *auth.JWTService, authService *auth.AuthService) {
|
||||
h := handler.New(db)
|
||||
appHandler := handler.NewAppHandler(app.NewService(db))
|
||||
releaseHandler := handler.NewReleaseHandler(release.NewService(db))
|
||||
assetHandler := handler.NewAssetHandler(asset.NewService(db, stor))
|
||||
authHandler := handler.NewAuthHandler(authService)
|
||||
|
||||
api := r.Group("/api")
|
||||
|
||||
{
|
||||
// 认证相关路由(公开)
|
||||
authGroup := api.Group("/auth")
|
||||
{
|
||||
// 移除注册接口 - 只允许配置的管理员登录
|
||||
// authGroup.POST("/register", authHandler.Register)
|
||||
authGroup.POST("/login", authHandler.Login)
|
||||
authGroup.POST("/refresh", authHandler.RefreshToken)
|
||||
}
|
||||
|
||||
// 需要认证的路由
|
||||
authRequired := api.Group("")
|
||||
authRequired.Use(auth.JWTMiddleware(jwtService))
|
||||
{
|
||||
// 用户相关
|
||||
authRequired.GET("/auth/profile", authHandler.GetProfile)
|
||||
authRequired.POST("/auth/change-password", authHandler.ChangePassword)
|
||||
}
|
||||
|
||||
// 更新检查(公开)
|
||||
api.GET("/check-update", h.CheckUpdate)
|
||||
|
||||
// 应用管理(需要认证)
|
||||
appGroup := api.Group("/apps")
|
||||
appGroup.Use(auth.JWTMiddleware(jwtService))
|
||||
{
|
||||
appGroup.GET("", appHandler.List)
|
||||
appGroup.POST("", appHandler.Create)
|
||||
appGroup.GET("/:id", appHandler.Get)
|
||||
appGroup.PUT("/:id", appHandler.Update)
|
||||
appGroup.DELETE("/:id", appHandler.Delete)
|
||||
|
||||
// 应用相关的版本
|
||||
appGroup.GET("/:id/releases", releaseHandler.ListByApp)
|
||||
appGroup.GET("/:id/releases/latest", releaseHandler.GetLatest)
|
||||
}
|
||||
|
||||
// 版本管理(需要认证)
|
||||
releaseGroup := api.Group("/releases")
|
||||
releaseGroup.Use(auth.JWTMiddleware(jwtService))
|
||||
{
|
||||
releaseGroup.GET("", releaseHandler.List)
|
||||
releaseGroup.POST("", releaseHandler.Create)
|
||||
releaseGroup.GET("/:id", releaseHandler.Get)
|
||||
releaseGroup.PUT("/:id", releaseHandler.Update)
|
||||
releaseGroup.DELETE("/:id", releaseHandler.Delete)
|
||||
|
||||
// 版本相关的资源
|
||||
releaseGroup.GET("/:id/assets", assetHandler.ListByRelease)
|
||||
releaseGroup.POST("/:id/assets/upload", assetHandler.Upload)
|
||||
}
|
||||
|
||||
// 资源管理(需要认证)
|
||||
assetGroup := api.Group("/assets")
|
||||
assetGroup.Use(auth.JWTMiddleware(jwtService))
|
||||
{
|
||||
assetGroup.GET("", assetHandler.List)
|
||||
assetGroup.GET("/:id", assetHandler.Get)
|
||||
assetGroup.POST("", assetHandler.Create)
|
||||
assetGroup.PUT("/:id", assetHandler.Update)
|
||||
assetGroup.DELETE("/:id", assetHandler.Delete)
|
||||
assetGroup.GET("/:id/download", assetHandler.Download)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user