136 lines
4.1 KiB
Go
136 lines
4.1 KiB
Go
|
|
package service
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
"with_you/internal/grpc/runner"
|
||
|
|
"with_you/internal/model"
|
||
|
|
"with_you/internal/repository"
|
||
|
|
pb "with_you/proto/runner"
|
||
|
|
|
||
|
|
"github.com/google/uuid"
|
||
|
|
"go.uber.org/zap"
|
||
|
|
)
|
||
|
|
|
||
|
|
type SyncEmptyClassroomsRequest struct {
|
||
|
|
Username string `json:"username" binding:"required"`
|
||
|
|
Password string `json:"password" binding:"required"`
|
||
|
|
Semester string `json:"semester"`
|
||
|
|
WeekStart string `json:"week_start"`
|
||
|
|
WeekEnd string `json:"week_end"`
|
||
|
|
CampusCode string `json:"campus_code"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type SyncEmptyClassroomsResult struct {
|
||
|
|
Success bool `json:"success"`
|
||
|
|
Message string `json:"message"`
|
||
|
|
SyncedCount int `json:"synced_count"`
|
||
|
|
ErrorMessage string `json:"error_message,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type EmptyClassroomSyncService interface {
|
||
|
|
SyncUserEmptyClassrooms(ctx context.Context, userID string, req *SyncEmptyClassroomsRequest) (*SyncEmptyClassroomsResult, error)
|
||
|
|
}
|
||
|
|
|
||
|
|
type emptyClassroomSyncService struct {
|
||
|
|
taskManager *runner.TaskManager
|
||
|
|
classroomRepo repository.EmptyClassroomRepository
|
||
|
|
logger *zap.Logger
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewEmptyClassroomSyncService(
|
||
|
|
taskManager *runner.TaskManager,
|
||
|
|
classroomRepo repository.EmptyClassroomRepository,
|
||
|
|
logger *zap.Logger,
|
||
|
|
) EmptyClassroomSyncService {
|
||
|
|
return &emptyClassroomSyncService{
|
||
|
|
taskManager: taskManager,
|
||
|
|
classroomRepo: classroomRepo,
|
||
|
|
logger: logger,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *emptyClassroomSyncService) SyncUserEmptyClassrooms(ctx context.Context, userID string, req *SyncEmptyClassroomsRequest) (*SyncEmptyClassroomsResult, error) {
|
||
|
|
payload := &pb.GetEmptyClassroomPayload{
|
||
|
|
Username: req.Username,
|
||
|
|
Password: req.Password,
|
||
|
|
Semester: req.Semester,
|
||
|
|
WeekStart: req.WeekStart,
|
||
|
|
WeekEnd: req.WeekEnd,
|
||
|
|
CampusCode: req.CampusCode,
|
||
|
|
}
|
||
|
|
|
||
|
|
taskResult, err := s.taskManager.SubmitTaskSync(ctx, pb.TaskType_TASK_TYPE_GET_EMPTY_CLASSROOM, payload)
|
||
|
|
if err != nil {
|
||
|
|
s.logger.Error("failed to submit empty classroom sync task",
|
||
|
|
zap.String("user_id", userID),
|
||
|
|
zap.Error(err))
|
||
|
|
return nil, fmt.Errorf("failed to submit task: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if taskResult.Status != pb.TaskStatus_TASK_STATUS_SUCCESS {
|
||
|
|
return &SyncEmptyClassroomsResult{
|
||
|
|
Success: false,
|
||
|
|
Message: "空教室查询失败",
|
||
|
|
ErrorMessage: taskResult.ErrorMessage,
|
||
|
|
}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
var resultData pb.EmptyClassroomResultData
|
||
|
|
if err := json.Unmarshal(taskResult.Data, &resultData); err != nil {
|
||
|
|
s.logger.Error("failed to parse empty classroom result",
|
||
|
|
zap.String("user_id", userID),
|
||
|
|
zap.Error(err))
|
||
|
|
return nil, fmt.Errorf("failed to parse result: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
classrooms := s.convertClassrooms(userID, &resultData)
|
||
|
|
if err := s.saveClassrooms(ctx, userID, resultData.Semester, classrooms); err != nil {
|
||
|
|
s.logger.Error("failed to save empty classrooms",
|
||
|
|
zap.String("user_id", userID),
|
||
|
|
zap.Error(err))
|
||
|
|
return nil, fmt.Errorf("failed to save classrooms: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
s.logger.Info("empty classrooms sync completed",
|
||
|
|
zap.String("user_id", userID),
|
||
|
|
zap.Int("classroom_count", len(classrooms)))
|
||
|
|
|
||
|
|
return &SyncEmptyClassroomsResult{
|
||
|
|
Success: true,
|
||
|
|
Message: "空教室查询成功",
|
||
|
|
SyncedCount: len(classrooms),
|
||
|
|
}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *emptyClassroomSyncService) convertClassrooms(userID string, data *pb.EmptyClassroomResultData) []*model.EmptyClassroom {
|
||
|
|
classrooms := make([]*model.EmptyClassroom, 0, len(data.Classrooms))
|
||
|
|
for _, c := range data.Classrooms {
|
||
|
|
classrooms = append(classrooms, &model.EmptyClassroom{
|
||
|
|
ID: uuid.New().String(),
|
||
|
|
UserID: userID,
|
||
|
|
Semester: data.Semester,
|
||
|
|
Classroom: c.Classroom,
|
||
|
|
Weekday: c.Weekday,
|
||
|
|
Periods: c.Periods,
|
||
|
|
Weeks: c.Weeks,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
return classrooms
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *emptyClassroomSyncService) saveClassrooms(ctx context.Context, userID, semester string, classrooms []*model.EmptyClassroom) error {
|
||
|
|
if err := s.classroomRepo.DeleteByUserAndSemester(ctx, userID, semester); err != nil {
|
||
|
|
return fmt.Errorf("failed to delete old classrooms: %w", err)
|
||
|
|
}
|
||
|
|
if len(classrooms) == 0 {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
if err := s.classroomRepo.BatchCreate(ctx, classrooms); err != nil {
|
||
|
|
return fmt.Errorf("failed to create classrooms: %w", err)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|