- Remove BOM from all Go source files - Standardize import ordering and whitespace across handlers and services - Replace PostgreSQL full-text search with ILIKE pattern matching in post and user repositories - Enhance JPush client with TLS transport, rate limit monitoring, and simplified API - Refactor PushService to include userID in device management methods - Add MaxDevicesPerUser limit and extract helper functions for push payload construction
177 lines
5.8 KiB
Go
177 lines
5.8 KiB
Go
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
|
|
}
|