Files
cpdaily_xiaozhushou/backed/internal/handler/admin_auth.go
T
becomer 2e2c161770 feat: init cpdaily-xiaozhushou with blue-green deploy
- backed/: Go Fiber backend with cpdaily integration
- frondend/: Vue 3 + Vite frontend
- Dockerfile: multi-stage build (Node → Go → Alpine)
- deploy/docker-compose.yml: production compose file
- .woodpecker/build.yml: CI/CD with blue-green zero-downtime deploy
- /health endpoint for deployment health checks
- Port 8884/8885 blue-green swap via 1Panel OpenResty
2026-07-03 15:37:55 +08:00

184 lines
4.9 KiB
Go

package handler
import (
"cpdaily-new/internal/database"
"cpdaily-new/internal/model"
"cpdaily-new/internal/service"
"cpdaily-new/internal/utils"
"log/slog"
"github.com/gofiber/fiber/v2"
"golang.org/x/crypto/bcrypt"
)
// AdminSetupStatus 检查是否已安装(是否有admin账号)
func AdminSetupStatus(c *fiber.Ctx) error {
var count int64
database.DB.Model(&model.AgentUser{}).Where("role = ?", "admin").Count(&count)
return utils.Success(c, fiber.Map{
"installed": count > 0,
})
}
// AdminSetupInitRequest 初始化安装请求
type AdminSetupInitRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
// AdminSetupInit 初始化创建管理员账号
func AdminSetupInit(c *fiber.Ctx) error {
var req AdminSetupInitRequest
if err := c.BodyParser(&req); err != nil {
return utils.FailParam(c, "请求参数错误")
}
if req.Username == "" || req.Password == "" {
return utils.FailParam(c, "用户名和密码不能为空")
}
if len(req.Password) < 6 {
return utils.FailParam(c, "密码长度不能少于6位")
}
// 检查是否已存在admin
var count int64
database.DB.Model(&model.AgentUser{}).Where("role = ?", "admin").Count(&count)
if count > 0 {
return utils.Fail(c, 400, "管理员账号已存在,不能重复初始化")
}
// 加密密码
hashedPwd, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
if err != nil {
slog.Error("密码加密失败", "error", err)
return utils.FailServer(c, "初始化失败")
}
// 创建管理员
admin := model.AgentUser{
Username: req.Username,
Password: string(hashedPwd),
Role: "admin",
Rate: 1.00,
Balance: 0,
Status: "active",
}
if err := database.DB.Create(&admin).Error; err != nil {
slog.Error("创建管理员失败", "error", err)
return utils.FailServer(c, "初始化失败")
}
// 生成 token 直接登录
token, expiresIn, err := service.GenerateAdminToken(admin.ID, admin.Username, admin.Role)
if err != nil {
slog.Error("生成token失败", "error", err)
return utils.FailServer(c, "初始化成功但生成token失败,请前往登录")
}
slog.Info("管理员初始化成功", "username", req.Username)
return utils.Success(c, fiber.Map{
"token": fiber.Map{
"accessToken": token,
"expiresIn": expiresIn,
"tokenType": "Bearer",
},
"agent": fiber.Map{
"id": admin.ID,
"username": admin.Username,
"role": admin.Role,
"rate": admin.Rate,
"balance": admin.Balance,
"status": admin.Status,
},
})
}
// AdminLoginRequest 管理员登录请求
type AdminLoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
// AdminLogin 管理员/代理登录
func AdminLogin(c *fiber.Ctx) error {
var req AdminLoginRequest
if err := c.BodyParser(&req); err != nil {
return utils.FailParam(c, "请求参数错误")
}
if req.Username == "" || req.Password == "" {
return utils.FailParam(c, "用户名或密码不能为空")
}
// 查找管理员/代理
var agent model.AgentUser
if err := database.DB.Where("username = ?", req.Username).First(&agent).Error; err != nil {
return utils.Fail(c, 401, "用户名或密码错误")
}
// 验证密码
if err := bcrypt.CompareHashAndPassword([]byte(agent.Password), []byte(req.Password)); err != nil {
return utils.Fail(c, 401, "用户名或密码错误")
}
// 检查状态
if agent.Status == "disabled" {
return utils.Fail(c, 403, "账号已被禁用")
}
// 生成 token
token, expiresIn, err := service.GenerateAdminToken(agent.ID, agent.Username, agent.Role)
if err != nil {
slog.Error("生成管理员token失败", "error", err)
return utils.FailServer(c, "登录失败")
}
slog.Info("管理员登录成功", "agentId", agent.ID, "username", agent.Username, "role", agent.Role)
return utils.Success(c, fiber.Map{
"token": fiber.Map{
"accessToken": token,
"expiresIn": expiresIn,
"tokenType": "Bearer",
},
"agent": fiber.Map{
"id": agent.ID,
"username": agent.Username,
"role": agent.Role,
"rate": agent.Rate,
"balance": agent.Balance,
"status": agent.Status,
},
})
}
// AdminMe 获取当前管理员/代理信息
func AdminMe(c *fiber.Ctx) error {
agentID := c.Locals("adminId").(uint)
var agent model.AgentUser
if err := database.DB.First(&agent, agentID).Error; err != nil {
return utils.FailAuth(c, "账号不存在")
}
// 查询下级代理数量
var subCount int64
database.DB.Model(&model.AgentUser{}).Where("parent_id = ?", agentID).Count(&subCount)
// 查询CDK数量
var cdkCount int64
database.DB.Model(&model.CDKCode{}).Where("agent_id = ?", agentID).Count(&cdkCount)
return utils.Success(c, fiber.Map{
"id": agent.ID,
"username": agent.Username,
"role": agent.Role,
"rate": agent.Rate,
"balance": agent.Balance,
"status": agent.Status,
"parentId": agent.ParentID,
"subCount": subCount,
"cdkCount": cdkCount,
"createdAt": agent.CreatedAt,
})
}