149 lines
3.9 KiB
Go
149 lines
3.9 KiB
Go
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
|
|
}
|