Update SproutGate

This commit is contained in:
2026-05-13 12:19:36 +08:00
parent f7db8aa053
commit a37b92e144
51 changed files with 12034 additions and 254 deletions

View File

@@ -1,3 +1,22 @@
//go:generate swag init -g main.go -o docs --parseInternal
// @title 萌芽账户认证中心 API
// @version 0.1.0
// @description 统一认证、用户资料、每日签到、公开用户主页与管理端等 JSON HTTP 接口。
// @host localhost:8080
// @BasePath /
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description JWTAuthorization 头填写「Bearer 」+ token示例Bearer eyJ...)。
// @securityDefinitions.apikey AdminToken
// @in header
// @name X-Admin-Token
// @description 管理端令牌;也可使用 Query `token` 或与部分客户端相同的 `Authorization` 头(见实现)。
// @schemes http https
package main
import (
@@ -8,12 +27,72 @@ import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
_ "sproutgate-backend/docs"
"sproutgate-backend/internal/database"
"sproutgate-backend/internal/handlers"
"sproutgate-backend/internal/storage"
)
func apiIntroPayload() gin.H {
return gin.H{
"name": "SproutGate API",
"title": "萌芽账户认证中心",
"description": "统一认证、用户资料、每日签到、公开用户主页与管理端等 JSON HTTP 接口。",
"version": "0.1.0",
"links": gin.H{
"health": "GET /api/health",
"docs": "GET /swagger/index.html",
},
"routePrefixes": []string{
"/api/auth — 登录、注册、邮箱验证、令牌校验、当前用户、资料、签到、辅助邮箱;可选 X-Auth-Client 记录应用接入",
"/api/public — 公开用户目录与资料、主页点赞、注册策略",
"/api/admin — 用户 CRUD、签到与注册/邀请码配置(请求头 X-Admin-Token 或 Query token",
},
}
}
// GetRoot
// @Summary API 简介 JSON
// @Description 与 GET /api 相同,返回名称、版本与路由前缀说明。
// @Tags meta
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router / [get]
func GetRoot(c *gin.Context) {
c.JSON(http.StatusOK, apiIntroPayload())
}
// GetAPI
// @Summary API 简介 JSON
// @Description 与 GET / 相同。
// @Tags meta
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router /api [get]
func GetAPI(c *gin.Context) {
c.JSON(http.StatusOK, apiIntroPayload())
}
// GetHealth
// @Summary 健康检查
// @Tags meta
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router /api/health [get]
func GetHealth(c *gin.Context) {
env := os.Getenv("APP_ENV")
if env == "" {
env = "development"
}
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"env": env,
})
}
func main() {
db, err := database.Open()
if err != nil {
@@ -35,37 +114,15 @@ func main() {
handler := handlers.NewHandler(store)
apiIntro := gin.H{
"name": "SproutGate API",
"title": "萌芽账户认证中心",
"description": "统一认证、用户资料、每日签到、公开用户主页与管理端等 JSON HTTP 接口。",
"version": "0.1.0",
"links": gin.H{
"health": "GET /api/health",
},
"routePrefixes": []string{
"/api/auth — 登录、注册、邮箱验证、令牌校验、当前用户、资料、签到、辅助邮箱;可选 X-Auth-Client 记录应用接入",
"/api/public — 公开用户目录与资料、主页点赞、注册策略",
"/api/admin — 用户 CRUD、签到与注册/邀请码配置(请求头 X-Admin-Token 或 Query token",
},
}
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, apiIntro)
})
router.GET("/api", func(c *gin.Context) {
c.JSON(http.StatusOK, apiIntro)
})
router.GET("/", GetRoot)
router.GET("/api", GetAPI)
router.GET("/api/health", func(c *gin.Context) {
env := os.Getenv("APP_ENV")
if env == "" {
env = "development"
}
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"env": env,
})
router.GET("/api/health", GetHealth)
router.GET("/api/docs", func(c *gin.Context) {
c.Redirect(http.StatusFound, "/swagger/index.html")
})
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
router.POST("/api/auth/login", handler.Login)
router.POST("/api/auth/register", handler.Register)
@@ -78,6 +135,10 @@ func main() {
router.GET("/api/auth/me", handler.Me)
router.POST("/api/auth/check-in", handler.CheckIn)
router.PUT("/api/auth/profile", handler.UpdateProfile)
router.GET("/api/auth/oauth/:provider/start", handler.OAuthStart)
router.GET("/api/auth/oauth/:provider/callback", handler.OAuthCallback)
router.POST("/api/auth/oauth/:provider/bind", handler.OAuthBindURL)
router.DELETE("/api/auth/oauth/:provider", handler.OAuthUnlink)
router.GET("/api/public/users", handler.ListPublicUsers)
router.GET("/api/public/users/:account", handler.GetPublicUser)
router.POST("/api/public/users/:account/like", handler.PostPublicProfileLike)
@@ -95,6 +156,10 @@ func main() {
admin.PUT("/registration", handler.PutAdminRegistrationPolicy)
admin.POST("/registration/invites", handler.PostAdminInvite)
admin.DELETE("/registration/invites/:code", handler.DeleteAdminInvite)
admin.GET("/oauth", handler.GetAdminOAuth)
admin.PUT("/oauth", handler.PutAdminOAuth)
admin.GET("/turnstile", handler.GetAdminTurnstile)
admin.PUT("/turnstile", handler.PutAdminTurnstile)
port := os.Getenv("PORT")
if port == "" {