package admin import ( "context" "encoding/json" "fmt" "time" "go.uber.org/zap" "golang.org/x/crypto/bcrypt" "tyapi-server/internal/application/admin/dto/commands" "tyapi-server/internal/application/admin/dto/queries" "tyapi-server/internal/application/admin/dto/responses" "tyapi-server/internal/domains/admin/entities" "tyapi-server/internal/domains/admin/repositories" ) // AdminApplicationServiceImpl 管理员应用服务实现 type AdminApplicationServiceImpl struct { adminRepo repositories.AdminRepository loginLogRepo repositories.AdminLoginLogRepository operationLogRepo repositories.AdminOperationLogRepository permissionRepo repositories.AdminPermissionRepository logger *zap.Logger } // NewAdminApplicationService 创建管理员应用服务 func NewAdminApplicationService( adminRepo repositories.AdminRepository, loginLogRepo repositories.AdminLoginLogRepository, operationLogRepo repositories.AdminOperationLogRepository, permissionRepo repositories.AdminPermissionRepository, logger *zap.Logger, ) AdminApplicationService { return &AdminApplicationServiceImpl{ adminRepo: adminRepo, loginLogRepo: loginLogRepo, operationLogRepo: operationLogRepo, permissionRepo: permissionRepo, logger: logger, } } func (s *AdminApplicationServiceImpl) Login(ctx context.Context, cmd *commands.AdminLoginCommand) (*responses.AdminLoginResponse, error) { s.logger.Info("管理员登录", zap.String("username", cmd.Username)) admin, err := s.adminRepo.FindByUsername(ctx, cmd.Username) if err != nil { s.logger.Warn("管理员登录失败:用户不存在", zap.String("username", cmd.Username)) return nil, fmt.Errorf("用户名或密码错误") } if !admin.IsActive { s.logger.Warn("管理员登录失败:账户已禁用", zap.String("username", cmd.Username)) return nil, fmt.Errorf("账户已被禁用,请联系管理员") } if err := bcrypt.CompareHashAndPassword([]byte(admin.Password), []byte(cmd.Password)); err != nil { s.logger.Warn("管理员登录失败:密码错误", zap.String("username", cmd.Username)) return nil, fmt.Errorf("用户名或密码错误") } if err := s.adminRepo.UpdateLoginStats(ctx, admin.ID); err != nil { s.logger.Error("更新登录统计失败", zap.Error(err)) } // This part would ideally be in a separate auth service or helper token, expiresAt, err := s.generateJWTToken(admin) if err != nil { return nil, fmt.Errorf("生成令牌失败: %w", err) } permissions, err := s.getAdminPermissions(ctx, admin) if err != nil { s.logger.Error("获取管理员权限失败", zap.Error(err)) permissions = []string{} } adminInfo := responses.AdminInfoResponse{ ID: admin.ID, Username: admin.Username, Email: admin.Email, Phone: admin.Phone, RealName: admin.RealName, Role: admin.Role, IsActive: admin.IsActive, LastLoginAt: admin.LastLoginAt, LoginCount: admin.LoginCount, Permissions: permissions, CreatedAt: admin.CreatedAt, } s.logger.Info("管理员登录成功", zap.String("username", cmd.Username)) return &responses.AdminLoginResponse{ Token: token, ExpiresAt: expiresAt, Admin: adminInfo, }, nil } func (s *AdminApplicationServiceImpl) CreateAdmin(ctx context.Context, cmd *commands.CreateAdminCommand) error { // ... implementation ... return nil } func (s *AdminApplicationServiceImpl) UpdateAdmin(ctx context.Context, cmd *commands.UpdateAdminCommand) error { // ... implementation ... return nil } func (s *AdminApplicationServiceImpl) ChangePassword(ctx context.Context, cmd *commands.ChangeAdminPasswordCommand) error { // ... implementation ... return nil } func (s *AdminApplicationServiceImpl) ListAdmins(ctx context.Context, query *queries.ListAdminsQuery) (*responses.AdminListResponse, error) { // ... implementation ... return nil, nil } func (s *AdminApplicationServiceImpl) GetAdminByID(ctx context.Context, query *queries.GetAdminInfoQuery) (*responses.AdminInfoResponse, error) { // ... implementation ... return nil, nil } func (s *AdminApplicationServiceImpl) DeleteAdmin(ctx context.Context, cmd *commands.DeleteAdminCommand) error { // ... implementation ... return nil } func (s *AdminApplicationServiceImpl) GetAdminStats(ctx context.Context) (*responses.AdminStatsResponse, error) { // ... implementation ... return nil, nil } // Private helper methods from old service func (s *AdminApplicationServiceImpl) getAdminPermissions(ctx context.Context, admin *entities.Admin) ([]string, error) { rolePermissions, err := s.adminRepo.GetPermissionsByRole(ctx, admin.Role) if err != nil { return nil, err } permissions := make([]string, 0, len(rolePermissions)) for _, perm := range rolePermissions { permissions = append(permissions, perm.Code) } if admin.Permissions != "" { var customPermissions []string if err := json.Unmarshal([]byte(admin.Permissions), &customPermissions); err == nil { permissions = append(permissions, customPermissions...) } } return permissions, nil } func (s *AdminApplicationServiceImpl) generateJWTToken(admin *entities.Admin) (string, time.Time, error) { // This should be handled by a dedicated auth service token := fmt.Sprintf("admin_token_%s_%d", admin.ID, time.Now().Unix()) expiresAt := time.Now().Add(24 * time.Hour) return token, expiresAt, nil }