165 lines
5.3 KiB
Go
165 lines
5.3 KiB
Go
|
|
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
|
||
|
|
}
|