Files
nl-video-api/internal/controller/admin/admin.go

371 lines
9.9 KiB
Go
Raw Normal View History

2025-08-03 00:11:15 +08:00
package admin
import (
"time"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/util/gconv"
"nl-video-api/internal/model/entity"
"nl-video-api/utility/crypto"
"nl-video-api/utility/jwt"
"nl-video-api/utility/response"
)
type AdminController struct{}
// AdminLoginReq 管理员登录请求
type AdminLoginReq struct {
Username string `json:"username" v:"required|length:3,20#用户名不能为空|用户名长度为3-20位"`
Password string `json:"password" v:"required|length:6,20#密码不能为空|密码长度为6-20位"`
}
// AdminLoginRes 管理员登录响应
type AdminLoginRes struct {
Token string `json:"token"`
AdminInfo *entity.NlAdmin `json:"admin_info"`
}
// AdminRegisterReq 管理员注册请求
type AdminRegisterReq struct {
Username string `json:"username" v:"required|length:3,20#用户名不能为空|用户名长度为3-20位"`
Password string `json:"password" v:"required|length:6,20#密码不能为空|密码长度为6-20位"`
Email string `json:"email" v:"required|email#邮箱不能为空|邮箱格式不正确"`
RealName string `json:"real_name" v:"required|length:2,10#真实姓名不能为空|真实姓名长度为2-10位"`
}
// AdminProfileRes 管理员信息响应
type AdminProfileRes struct {
AdminInfo *entity.NlAdmin `json:"admin_info"`
}
// AdminUpdateReq 更新管理员信息请求
type AdminUpdateReq struct {
Email string `json:"email" v:"email#邮箱格式不正确"`
RealName string `json:"real_name" v:"length:2,10#真实姓名长度为2-10位"`
Avatar string `json:"avatar" v:"url#头像必须是有效的URL"`
}
// Login 管理员登录
func (c *AdminController) Login(r *ghttp.Request) {
ctx := r.Context()
var req AdminLoginReq
if err := r.Parse(&req); err != nil {
response.Error(r, response.CodeInvalidParam, "参数错误: "+err.Error())
return
}
// 检查数据库连接
if err := g.DB().PingMaster(); err != nil {
g.Log().Error(ctx, "数据库连接失败:", err)
response.Error(r, response.CodeInternalError, "数据库连接失败,请稍后重试")
return
}
// 查询管理员信息
var admin *entity.NlAdmin
err := g.DB().Model("nl_admin").Where("username", req.Username).Scan(&admin)
if err != nil {
g.Log().Error(ctx, "查询管理员失败:", err)
response.Error(r, response.CodeInternalError, "数据库查询失败")
return
}
if admin == nil {
response.Error(r, response.CodeInvalidParam, "用户名或密码错误")
return
}
// 验证密码
if !crypto.CheckPassword(req.Password, admin.Password) {
response.Error(r, response.CodeInvalidParam, "用户名或密码错误")
return
}
// 检查管理员状态
if admin.Status != 1 {
response.Error(r, response.CodeForbidden, "账号已被禁用")
return
}
// 生成JWT Token
token, err := jwt.GenerateToken(admin.Id, admin.Username, "admin")
if err != nil {
g.Log().Error(ctx, "生成Token失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
// 更新最后登录时间
now := int(time.Now().Unix())
_, err = g.DB().Model("nl_admin").Where("id", admin.Id).Update(g.Map{
"last_login_time": now,
"last_login_ip": r.GetClientIp(),
"updated_at": now,
})
if err != nil {
g.Log().Error(ctx, "更新登录时间失败:", err)
}
// 格式化管理员信息返回
adminMap := g.Map{
"id": admin.Id,
"username": admin.Username,
"nick_name": admin.NickName,
"avatar": admin.Avatar,
"phone": admin.Phone,
"email": admin.Email,
"role_id": admin.RoleId,
"department": admin.Department,
"status": admin.Status,
"last_login_time": response.FormatTimestamp(now),
"created_at": response.FormatTimestamp(admin.CreatedAt),
"updated_at": response.FormatTimestamp(now),
}
response.Success(r, g.Map{
"token": token,
"admin_info": adminMap,
})
}
// Register 管理员注册
func (c *AdminController) Register(r *ghttp.Request) {
ctx := r.Context()
var req AdminRegisterReq
if err := r.Parse(&req); err != nil {
response.Error(r, response.CodeInvalidParam, "参数错误: "+err.Error())
return
}
// 检查用户名是否已存在
count, err := g.DB().Model("nl_admin").Where("username", req.Username).Count()
if err != nil {
g.Log().Error(ctx, "查询管理员失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
if count > 0 {
response.Error(r, response.CodeInvalidParam, "用户名已存在")
return
}
// 检查邮箱是否已存在
count, err = g.DB().Model("nl_admin").Where("email", req.Email).Count()
if err != nil {
g.Log().Error(ctx, "查询邮箱失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
if count > 0 {
response.Error(r, response.CodeInvalidParam, "邮箱已存在")
return
}
// 加密密码
hashedPassword, err := crypto.HashPassword(req.Password)
if err != nil {
g.Log().Error(ctx, "密码加密失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
// 创建管理员
now := int(time.Now().Unix())
adminData := g.Map{
"username": req.Username,
"password": hashedPassword,
"email": req.Email,
"nick_name": req.RealName,
"role_id": 1, // 默认角色ID
"status": 1, // 默认启用
"created_at": now,
"updated_at": now,
}
result, err := g.DB().Model("nl_admin").Insert(adminData)
if err != nil {
g.Log().Error(ctx, "创建管理员失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
// 获取新创建的管理员ID
adminId, err := result.LastInsertId()
if err != nil {
g.Log().Error(ctx, "获取管理员ID失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
// 生成JWT Token
token, err := jwt.GenerateToken(gconv.Uint(adminId), req.Username, "admin")
if err != nil {
g.Log().Error(ctx, "生成Token失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
// 查询新创建的管理员信息
var admin *entity.NlAdmin
err = g.DB().Model("nl_admin").Where("id", adminId).Scan(&admin)
if err != nil {
g.Log().Error(ctx, "查询管理员失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
// 清除密码字段
admin.Password = ""
response.Success(r, AdminLoginRes{
Token: token,
AdminInfo: admin,
})
}
// Profile 获取管理员信息
func (c *AdminController) Profile(r *ghttp.Request) {
ctx := r.Context()
// 从上下文获取管理员ID
adminId := r.GetCtxVar("admin_id")
if adminId == nil {
response.Error(r, response.CodeUnauthorized, "未授权访问")
return
}
// 查询管理员信息
var admin *entity.NlAdmin
err := g.DB().Model("nl_admin").Where("id", adminId).Scan(&admin)
if err != nil {
g.Log().Error(ctx, "查询管理员失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
if admin == nil {
response.Error(r, response.CodeNotFound, "管理员不存在")
return
}
// 清除密码字段
admin.Password = ""
response.Success(r, AdminProfileRes{
AdminInfo: admin,
})
}
// UpdateProfile 更新管理员信息
func (c *AdminController) UpdateProfile(r *ghttp.Request) {
ctx := r.Context()
var req AdminUpdateReq
if err := r.Parse(&req); err != nil {
response.Error(r, response.CodeInvalidParam, "参数错误: "+err.Error())
return
}
// 从上下文获取管理员ID
adminId := r.GetCtxVar("admin_id")
if adminId == nil {
response.Error(r, response.CodeUnauthorized, "未授权访问")
return
}
// 构建更新数据
updateData := g.Map{
"updated_at": int(time.Now().Unix()),
}
if req.Email != "" {
// 检查邮箱是否已被其他管理员使用
count, err := g.DB().Model("nl_admin").Where("email", req.Email).Where("id !=", adminId).Count()
if err != nil {
g.Log().Error(ctx, "查询邮箱失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
if count > 0 {
response.Error(r, response.CodeInvalidParam, "邮箱已被使用")
return
}
updateData["email"] = req.Email
}
if req.RealName != "" {
updateData["real_name"] = req.RealName
}
if req.Avatar != "" {
updateData["avatar"] = req.Avatar
}
// 更新管理员信息
_, err := g.DB().Model("nl_admin").Where("id", adminId).Update(updateData)
if err != nil {
g.Log().Error(ctx, "更新管理员信息失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
// 查询更新后的管理员信息
var admin *entity.NlAdmin
err = g.DB().Model("nl_admin").Where("id", adminId).Scan(&admin)
if err != nil {
g.Log().Error(ctx, "查询管理员失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
// 清除密码字段
admin.Password = ""
response.Success(r, AdminProfileRes{
AdminInfo: admin,
})
}
// Logout 管理员登出
func (c *AdminController) Logout(r *ghttp.Request) {
// 这里可以实现Token黑名单机制
// 目前简单返回成功
response.Success(r, nil)
}
// RefreshToken 刷新Token
func (c *AdminController) RefreshToken(r *ghttp.Request) {
// 从上下文获取管理员ID
adminId := r.GetCtxVar("admin_id")
if adminId == nil {
response.Error(r, response.CodeUnauthorized, "未授权访问")
return
}
// 查询管理员信息获取用户名
var admin *entity.NlAdmin
err := g.DB().Model("nl_admin").Where("id", adminId).Scan(&admin)
if err != nil {
g.Log().Error(r.Context(), "查询管理员失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
if admin == nil {
response.Error(r, response.CodeNotFound, "管理员不存在")
return
}
// 生成新的Token
token, err := jwt.GenerateToken(admin.Id, admin.Username, "admin")
if err != nil {
g.Log().Error(r.Context(), "生成Token失败:", err)
response.Error(r, response.CodeInternalError, "系统错误")
return
}
response.Success(r, g.Map{
"token": token,
})
}