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, }) }