package service import ( "context" "fmt" "time" apperrors "with_you/internal/errors" "with_you/internal/model" "with_you/internal/repository" ) type VerificationService interface { SubmitVerification(ctx context.Context, userID string, identity model.UserIdentity, realName, studentID, employeeID, department, proofMaterials string) (*model.VerificationRecord, error) GetVerificationStatus(ctx context.Context, userID string) (*VerificationStatusResponse, error) GetVerificationRecords(ctx context.Context, userID string, page, pageSize int) ([]*model.VerificationRecord, int64, error) } type VerificationStatusResponse struct { UserID string `json:"user_id"` Identity string `json:"identity"` VerificationStatus string `json:"verification_status"` HasPendingRequest bool `json:"has_pending_request"` LatestRecord *model.VerificationRecord `json:"latest_record,omitempty"` } type verificationServiceImpl struct { verificationRepo repository.VerificationRepository userRepo repository.UserRepository } func NewVerificationService( verificationRepo repository.VerificationRepository, userRepo repository.UserRepository, ) VerificationService { return &verificationServiceImpl{ verificationRepo: verificationRepo, userRepo: userRepo, } } func (s *verificationServiceImpl) SubmitVerification(ctx context.Context, userID string, identity model.UserIdentity, realName, studentID, employeeID, department, proofMaterials string) (*model.VerificationRecord, error) { user, err := s.userRepo.GetByID(userID) if err != nil { return nil, apperrors.ErrUserNotFound } if user.VerificationStatus == model.VerificationStatusApproved { return nil, apperrors.ErrAlreadyVerified } existing, err := s.verificationRepo.GetPendingByUserID(userID) if err == nil && existing != nil { return nil, apperrors.ErrVerificationPending } record := &model.VerificationRecord{ UserID: userID, Identity: identity, Status: model.VerificationStatusPending, RealName: realName, StudentID: studentID, EmployeeID: employeeID, Department: department, ProofMaterials: proofMaterials, } if err := s.verificationRepo.Create(record); err != nil { return nil, fmt.Errorf("创建认证记录失败: %w", err) } user.VerificationStatus = model.VerificationStatusPending user.Identity = identity if err := s.userRepo.Update(user); err != nil { return nil, fmt.Errorf("更新用户状态失败: %w", err) } return record, nil } func (s *verificationServiceImpl) GetVerificationStatus(ctx context.Context, userID string) (*VerificationStatusResponse, error) { user, err := s.userRepo.GetByID(userID) if err != nil { return nil, apperrors.ErrUserNotFound } response := &VerificationStatusResponse{ UserID: userID, Identity: string(user.Identity), VerificationStatus: string(user.VerificationStatus), HasPendingRequest: false, } latestRecord, err := s.verificationRepo.GetLatestByUserID(userID) if err == nil && latestRecord != nil { response.LatestRecord = latestRecord response.HasPendingRequest = latestRecord.Status == model.VerificationStatusPending } return response, nil } func (s *verificationServiceImpl) GetVerificationRecords(ctx context.Context, userID string, page, pageSize int) ([]*model.VerificationRecord, int64, error) { return s.verificationRepo.GetRecordsByUserID(userID, page, pageSize) } type AdminVerificationService interface { ListVerifications(ctx context.Context, page, pageSize int, status, keyword string) ([]*model.VerificationRecord, int64, error) GetVerificationDetail(ctx context.Context, id string) (*model.VerificationRecord, error) ReviewVerification(ctx context.Context, reviewerID string, recordID string, approve bool, rejectReason string) (*model.VerificationRecord, error) } type adminVerificationServiceImpl struct { verificationRepo repository.VerificationRepository userRepo repository.UserRepository } func NewAdminVerificationService( verificationRepo repository.VerificationRepository, userRepo repository.UserRepository, ) AdminVerificationService { return &adminVerificationServiceImpl{ verificationRepo: verificationRepo, userRepo: userRepo, } } func (s *adminVerificationServiceImpl) ListVerifications(ctx context.Context, page, pageSize int, status, keyword string) ([]*model.VerificationRecord, int64, error) { return s.verificationRepo.List(page, pageSize, status, keyword) } func (s *adminVerificationServiceImpl) GetVerificationDetail(ctx context.Context, id string) (*model.VerificationRecord, error) { return s.verificationRepo.GetByID(id) } func (s *adminVerificationServiceImpl) ReviewVerification(ctx context.Context, reviewerID string, recordID string, approve bool, rejectReason string) (*model.VerificationRecord, error) { record, err := s.verificationRepo.GetByID(recordID) if err != nil { return nil, apperrors.ErrVerificationNotFound } if record.Status != model.VerificationStatusPending { return nil, apperrors.ErrVerificationAlreadyHandled } if approve { record.Status = model.VerificationStatusApproved } else { record.Status = model.VerificationStatusRejected record.RejectReason = rejectReason } now := time.Now() record.ReviewedBy = &reviewerID record.ReviewedAt = &now if err := s.verificationRepo.Update(record); err != nil { return nil, fmt.Errorf("更新认证记录失败: %w", err) } user, err := s.userRepo.GetByID(record.UserID) if err != nil { return record, nil } if approve { user.VerificationStatus = model.VerificationStatusApproved user.Identity = record.Identity } else { user.VerificationStatus = model.VerificationStatusRejected } _ = s.userRepo.Update(user) return record, nil }