package service import ( "context" "github.com/gogf/gf/v2/errors/gerror" "golang.org/x/crypto/bcrypt" "service.xpcool.com/internal/consts" "service.xpcool.com/internal/dao" "service.xpcool.com/internal/library/jwt" "service.xpcool.com/internal/library/response" "service.xpcool.com/internal/model/do" "service.xpcool.com/internal/model/dto" "service.xpcool.com/internal/model/entity" ) type adminAuth struct{ tokens *jwt.Service } func NewAdminAuth(tokens *jwt.Service) IAdminAuth { return &adminAuth{tokens} } func (s *adminAuth) Login(ctx context.Context, in dto.AdminLoginInput) (*dto.TokenPair, uint64, error) { // 管理端只允许账号密码登录,状态异常或密码错误均返回统一错误,避免枚举账号。 var a entity.AdminUser if err := dao.AdminUser.Ctx(ctx).Where(do.AdminUser{Username: in.Username}).Scan(&a); err != nil { return nil, 0, gerror.Wrap(err, "query administrator") } if a.Id == 0 { return nil, 0, response.Error(consts.CodeAdminNotFound, "administrator not found") } if a.Status != 1 || bcrypt.CompareHashAndPassword([]byte(a.PasswordHash), []byte(in.Password)) != nil { return nil, 0, response.Error(consts.CodeAdminPasswordWrong, "username or password incorrect") } access, refresh, exp, err := s.tokens.Issue(a.Id, "admin", "") if err != nil { return nil, 0, gerror.Wrap(err, "issue token") } return &dto.TokenPair{AccessToken: access, RefreshToken: refresh, ExpiresIn: exp}, a.Id, nil } func (s *adminAuth) HasPermission(ctx context.Context, adminID uint64, permission string) (bool, error) { // 多角色权限通过管理员-角色-菜单三表关联查询,菜单中的 permission 即接口权限标识。 count, err := dao.AdminUserRole.Ctx(ctx).As("ur").LeftJoin("admin_role_menu rm", "ur.role_id=rm.role_id").LeftJoin("admin_menu m", "rm.menu_id=m.id").Where("ur.admin_user_id", adminID).Where("m.permission", permission).Where("m.status", 1).Count() if err != nil { return false, gerror.Wrap(err, "check permission") } return count > 0, nil }