package service import ( "fmt" "ssq-desk/internal/storage/models" "ssq-desk/internal/storage/repository" ) // SyncService 数据同步服务 type SyncService struct { mysqlRepo repository.SsqRepository sqliteRepo repository.SsqRepository } // NewSyncService 创建同步服务 func NewSyncService(mysqlRepo, sqliteRepo repository.SsqRepository) *SyncService { return &SyncService{ mysqlRepo: mysqlRepo, sqliteRepo: sqliteRepo, } } // SyncResult 同步结果 type SyncResult struct { TotalCount int `json:"total_count"` // 远程数据总数 SyncedCount int `json:"synced_count"` // 已同步数量 NewCount int `json:"new_count"` // 新增数量 UpdatedCount int `json:"updated_count"` // 更新数量 ErrorCount int `json:"error_count"` // 错误数量 LatestIssue string `json:"latest_issue"` // 最新期号 } // Sync 执行数据同步(增量同步) func (s *SyncService) Sync() (*SyncResult, error) { result := &SyncResult{} // 获取本地最新期号 localLatestIssue, err := s.sqliteRepo.GetLatestIssue() if err != nil { return nil, fmt.Errorf("获取本地最新期号失败: %v", err) } // 获取远程所有数据 remoteHistories, err := s.mysqlRepo.FindAll() if err != nil { return nil, fmt.Errorf("获取远程数据失败: %v", err) } result.TotalCount = len(remoteHistories) if len(remoteHistories) == 0 { return result, nil } // 确定最新期号 if len(remoteHistories) > 0 { result.LatestIssue = remoteHistories[0].IssueNumber } // 增量同步:只同步本地没有的数据 if localLatestIssue == "" { // 首次同步,全量同步 for _, history := range remoteHistories { if err := s.sqliteRepo.Create(&history); err != nil { result.ErrorCount++ continue } result.NewCount++ result.SyncedCount++ } } else { // 增量同步:同步期号大于本地最新期号的数据 for _, history := range remoteHistories { // 如果期号小于等于本地最新期号,跳过 if history.IssueNumber <= localLatestIssue { continue } // 检查本地是否已存在(基于期号) localHistory, err := s.sqliteRepo.FindByIssue(history.IssueNumber) if err == nil && localHistory != nil { // 已存在,检查是否需要更新 if s.needUpdate(localHistory, &history) { // 更新逻辑(目前使用创建,如需更新可扩展) result.UpdatedCount++ } continue } // 新数据,插入 if err := s.sqliteRepo.Create(&history); err != nil { result.ErrorCount++ continue } result.NewCount++ result.SyncedCount++ } } return result, nil } // needUpdate 判断是否需要更新 func (s *SyncService) needUpdate(local, remote *models.SsqHistory) bool { // 简单比较:如果任何字段不同,则认为需要更新 return local.RedBall1 != remote.RedBall1 || local.RedBall2 != remote.RedBall2 || local.RedBall3 != remote.RedBall3 || local.RedBall4 != remote.RedBall4 || local.RedBall5 != remote.RedBall5 || local.RedBall6 != remote.RedBall6 || local.BlueBall != remote.BlueBall } // GetSyncStatus 获取同步状态 func (s *SyncService) GetSyncStatus() (map[string]interface{}, error) { // 获取本地统计 localCount, err := s.sqliteRepo.Count() if err != nil { return nil, err } localLatestIssue, err := s.sqliteRepo.GetLatestIssue() if err != nil { return nil, err } // 获取远程统计 remoteCount, err := s.mysqlRepo.Count() if err != nil { // 远程连接失败不影响本地状态 remoteCount = 0 } remoteLatestIssue := "" remoteHistories, err := s.mysqlRepo.FindAll() if err == nil && len(remoteHistories) > 0 { remoteLatestIssue = remoteHistories[0].IssueNumber } return map[string]interface{}{ "local_count": localCount, "local_latest_issue": localLatestIssue, "remote_count": remoteCount, "remote_latest_issue": remoteLatestIssue, "need_sync": remoteLatestIssue > localLatestIssue, }, nil }