6dd3bd8e9d
- Translate all login error messages to Chinese (network errors, HTTP status codes, URL validation errors) - Add password visibility toggle (eye icon) to login form - Add live countdown timer when login is locked, disable login button during cooldown, auto-clear error when countdown ends - Add X button red hover feedback in server settings dialog - Add LoginGuard.Unlock() method to clear Redis lock/failure keys - Expose POST /admin-users/:id/reset-login-lock endpoint in ops API - Add "重置登录保护" button in ops-web user management table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
101 lines
4.1 KiB
Go
101 lines
4.1 KiB
Go
package transport
|
|
|
|
import (
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/geo-platform/tenant-api/internal/ops/app"
|
|
"github.com/geo-platform/tenant-api/internal/shared/middleware"
|
|
"github.com/geo-platform/tenant-api/internal/shared/response"
|
|
)
|
|
|
|
type Deps struct {
|
|
Engine *gin.Engine
|
|
Logger *zap.Logger
|
|
DB *pgxpool.Pool
|
|
MonitoringDB *pgxpool.Pool
|
|
Issuer *app.TokenIssuer
|
|
Auth *app.AuthService
|
|
Accounts *app.AccountService
|
|
AdminUsers *app.AdminUserService
|
|
KolSubs *app.KolSubscriptionService
|
|
Audits *app.AuditService
|
|
SiteDomains *app.SiteDomainMappingService
|
|
}
|
|
|
|
func RegisterRoutes(d Deps) {
|
|
d.Engine.Use(
|
|
middleware.Recovery(d.Logger),
|
|
middleware.RequestID(),
|
|
middleware.Logger(d.Logger),
|
|
middleware.CORS(),
|
|
)
|
|
|
|
d.Engine.GET("/api/health/live", func(c *gin.Context) {
|
|
response.Success(c, gin.H{"status": "alive"})
|
|
})
|
|
d.Engine.GET("/api/health/ready", func(c *gin.Context) {
|
|
if err := d.DB.Ping(c.Request.Context()); err != nil {
|
|
response.Error(c, response.ErrServiceUnavailable(50301, "postgres_unavailable", "数据库不可达"))
|
|
return
|
|
}
|
|
if d.MonitoringDB != nil {
|
|
if err := d.MonitoringDB.Ping(c.Request.Context()); err != nil {
|
|
response.Error(c, response.ErrServiceUnavailable(50303, "monitoring_postgres_unavailable", "监控数据库不可达"))
|
|
return
|
|
}
|
|
}
|
|
response.Success(c, gin.H{"status": "ready"})
|
|
})
|
|
|
|
api := d.Engine.Group("/api/ops")
|
|
{
|
|
api.POST("/auth/login", loginHandler(d.Auth))
|
|
}
|
|
|
|
authed := api.Group("")
|
|
authed.Use(authMiddleware(d.Issuer))
|
|
{
|
|
authed.GET("/auth/me", meHandler(d.Accounts))
|
|
authed.POST("/auth/password", changeOwnPasswordHandler(d.Accounts))
|
|
|
|
authed.GET("/accounts", listAccountsHandler(d.Accounts))
|
|
authed.POST("/accounts", createAccountHandler(d.Accounts))
|
|
authed.GET("/accounts/:id", getAccountHandler(d.Accounts))
|
|
authed.PATCH("/accounts/:id", updateAccountProfileHandler(d.Accounts))
|
|
authed.POST("/accounts/:id/status", setAccountStatusHandler(d.Accounts))
|
|
authed.POST("/accounts/:id/password", resetAccountPasswordHandler(d.Accounts))
|
|
|
|
authed.GET("/plans", listPlansHandler(d.AdminUsers))
|
|
authed.GET("/roles", listRolesHandler(d.AdminUsers))
|
|
|
|
authed.GET("/admin-users", listAdminUsersHandler(d.AdminUsers))
|
|
authed.POST("/admin-users", createAdminUserHandler(d.AdminUsers))
|
|
authed.GET("/admin-users/:id", getAdminUserHandler(d.AdminUsers))
|
|
authed.PATCH("/admin-users/:id", updateAdminUserHandler(d.AdminUsers))
|
|
authed.POST("/admin-users/:id/plan", changeAdminUserPlanHandler(d.AdminUsers))
|
|
authed.POST("/admin-users/:id/subscription-expiry", updateAdminUserSubscriptionExpiryHandler(d.AdminUsers))
|
|
authed.POST("/admin-users/:id/reset-plan-usage", resetAdminUserPlanUsageHandler(d.AdminUsers))
|
|
authed.POST("/admin-users/:id/role", changeAdminUserRoleHandler(d.AdminUsers))
|
|
authed.POST("/admin-users/:id/kol", setAdminUserKOLHandler(d.AdminUsers))
|
|
authed.POST("/admin-users/:id/status", setAdminUserStatusHandler(d.AdminUsers))
|
|
authed.POST("/admin-users/:id/password", resetAdminUserPasswordHandler(d.AdminUsers))
|
|
authed.POST("/admin-users/:id/reset-login-lock", resetAdminUserLoginLockHandler(d.AdminUsers))
|
|
|
|
authed.GET("/kol/packages", listKolSubscriptionPackagesHandler(d.KolSubs))
|
|
authed.GET("/kol/subscriptions", listKolSubscriptionsHandler(d.KolSubs))
|
|
authed.POST("/kol/subscriptions/manual-bind", manualBindKolSubscriptionHandler(d.KolSubs))
|
|
authed.POST("/kol/subscriptions/:id/approve", approveKolSubscriptionHandler(d.KolSubs))
|
|
authed.POST("/kol/subscriptions/:id/revoke", revokeKolSubscriptionHandler(d.KolSubs))
|
|
|
|
authed.GET("/audits", listAuditsHandler(d.Audits))
|
|
|
|
authed.GET("/site-domain-mappings", listSiteDomainMappingsHandler(d.SiteDomains))
|
|
authed.POST("/site-domain-mappings", createSiteDomainMappingHandler(d.SiteDomains))
|
|
authed.PATCH("/site-domain-mappings/:id", updateSiteDomainMappingHandler(d.SiteDomains))
|
|
authed.POST("/site-domain-mappings/:id/active", setSiteDomainMappingActiveHandler(d.SiteDomains))
|
|
authed.DELETE("/site-domain-mappings/:id", deleteSiteDomainMappingHandler(d.SiteDomains))
|
|
}
|
|
}
|