.
This commit is contained in:
87
internal/api/auth_api.go
Normal file
87
internal/api/auth_api.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ssq-desk/internal/service"
|
||||
"ssq-desk/internal/storage/repository"
|
||||
)
|
||||
|
||||
// AuthAPI 授权码 API
|
||||
type AuthAPI struct {
|
||||
authService *service.AuthService
|
||||
}
|
||||
|
||||
// NewAuthAPI 创建授权码 API
|
||||
func NewAuthAPI() (*AuthAPI, error) {
|
||||
repo, err := repository.NewSQLiteAuthRepository()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
authService := service.NewAuthService(repo)
|
||||
|
||||
return &AuthAPI{
|
||||
authService: authService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ActivateLicense 激活授权码
|
||||
func (api *AuthAPI) ActivateLicense(licenseCode string) (map[string]interface{}, error) {
|
||||
if api.authService == nil {
|
||||
newAPI, err := NewAuthAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.authService = newAPI.authService
|
||||
}
|
||||
|
||||
err := api.authService.ValidateLicense(licenseCode)
|
||||
if err != nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
status, err := api.authService.CheckAuthStatus()
|
||||
if err != nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"message": "激活成功",
|
||||
"data": status,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetAuthStatus 获取授权状态
|
||||
func (api *AuthAPI) GetAuthStatus() (map[string]interface{}, error) {
|
||||
if api.authService == nil {
|
||||
newAPI, err := NewAuthAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.authService = newAPI.authService
|
||||
}
|
||||
|
||||
status, err := api.authService.CheckAuthStatus()
|
||||
if err != nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"data": status,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetDeviceID 获取设备ID
|
||||
func (api *AuthAPI) GetDeviceID() (string, error) {
|
||||
return service.GetDeviceID()
|
||||
}
|
||||
67
internal/api/backup_api.go
Normal file
67
internal/api/backup_api.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ssq-desk/internal/service"
|
||||
)
|
||||
|
||||
// BackupAPI 数据备份 API
|
||||
type BackupAPI struct {
|
||||
backupService *service.BackupService
|
||||
}
|
||||
|
||||
// NewBackupAPI 创建数据备份 API
|
||||
func NewBackupAPI() *BackupAPI {
|
||||
return &BackupAPI{
|
||||
backupService: service.NewBackupService(),
|
||||
}
|
||||
}
|
||||
|
||||
// Backup 备份数据
|
||||
func (api *BackupAPI) Backup() (map[string]interface{}, error) {
|
||||
result, err := api.backupService.Backup()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"backup_path": result.BackupPath,
|
||||
"file_name": result.FileName,
|
||||
"file_size": result.FileSize,
|
||||
"created_at": result.CreatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Restore 恢复数据
|
||||
func (api *BackupAPI) Restore(backupPath string) (map[string]interface{}, error) {
|
||||
if err := api.backupService.Restore(backupPath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"message": "数据恢复成功",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListBackups 列出所有备份
|
||||
func (api *BackupAPI) ListBackups() (map[string]interface{}, error) {
|
||||
backups, err := api.backupService.ListBackups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
backupList := make([]map[string]interface{}, len(backups))
|
||||
for i, backup := range backups {
|
||||
backupList[i] = map[string]interface{}{
|
||||
"backup_path": backup.BackupPath,
|
||||
"file_name": backup.FileName,
|
||||
"file_size": backup.FileSize,
|
||||
"created_at": backup.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"backups": backupList,
|
||||
"count": len(backupList),
|
||||
}, nil
|
||||
}
|
||||
121
internal/api/package_api.go
Normal file
121
internal/api/package_api.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ssq-desk/internal/service"
|
||||
)
|
||||
|
||||
// PackageAPI 离线数据包 API
|
||||
type PackageAPI struct {
|
||||
packageService *service.PackageService
|
||||
}
|
||||
|
||||
// NewPackageAPI 创建数据包 API
|
||||
func NewPackageAPI() (*PackageAPI, error) {
|
||||
packageService, err := service.NewPackageService()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PackageAPI{
|
||||
packageService: packageService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DownloadPackage 下载数据包
|
||||
func (api *PackageAPI) DownloadPackage(downloadURL string) (map[string]interface{}, error) {
|
||||
if api.packageService == nil {
|
||||
newAPI, err := NewPackageAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.packageService = newAPI.packageService
|
||||
}
|
||||
|
||||
result, err := api.packageService.DownloadPackage(downloadURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"file_path": result.FilePath,
|
||||
"file_size": result.FileSize,
|
||||
"duration": result.Duration,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ImportPackage 导入数据包
|
||||
func (api *PackageAPI) ImportPackage(packagePath string) (map[string]interface{}, error) {
|
||||
if api.packageService == nil {
|
||||
newAPI, err := NewPackageAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.packageService = newAPI.packageService
|
||||
}
|
||||
|
||||
result, err := api.packageService.ImportPackage(packagePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"imported_count": result.ImportedCount,
|
||||
"updated_count": result.UpdatedCount,
|
||||
"error_count": result.ErrorCount,
|
||||
"duration": result.Duration,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CheckPackageUpdate 检查数据包更新
|
||||
func (api *PackageAPI) CheckPackageUpdate(remoteURL string) (map[string]interface{}, error) {
|
||||
if api.packageService == nil {
|
||||
newAPI, err := NewPackageAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.packageService = newAPI.packageService
|
||||
}
|
||||
|
||||
info, err := api.packageService.CheckPackageUpdate(remoteURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if info == nil {
|
||||
return map[string]interface{}{
|
||||
"need_update": false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"need_update": true,
|
||||
"version": info.Version,
|
||||
"total_count": info.TotalCount,
|
||||
"latest_issue": info.LatestIssue,
|
||||
"package_size": info.PackageSize,
|
||||
"download_url": info.DownloadURL,
|
||||
"release_date": info.ReleaseDate,
|
||||
"checksum": info.CheckSum,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListLocalPackages 列出本地数据包
|
||||
func (api *PackageAPI) ListLocalPackages() (map[string]interface{}, error) {
|
||||
if api.packageService == nil {
|
||||
newAPI, err := NewPackageAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.packageService = newAPI.packageService
|
||||
}
|
||||
|
||||
packages, err := api.packageService.ListLocalPackages()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"packages": packages,
|
||||
"count": len(packages),
|
||||
}, nil
|
||||
}
|
||||
55
internal/api/ssq_api.go
Normal file
55
internal/api/ssq_api.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ssq-desk/internal/service"
|
||||
"ssq-desk/internal/storage/repository"
|
||||
)
|
||||
|
||||
// SsqAPI 双色球查询 API
|
||||
type SsqAPI struct {
|
||||
queryService *service.QueryService
|
||||
}
|
||||
|
||||
// NewSsqAPI 创建双色球查询 API
|
||||
func NewSsqAPI() (*SsqAPI, error) {
|
||||
// 优先使用 MySQL(数据源)
|
||||
repo, err := repository.NewMySQLSsqRepository()
|
||||
if err != nil {
|
||||
// MySQL 连接失败,降级使用本地 SQLite
|
||||
repo, err = repository.NewSQLiteSsqRepository()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
queryService := service.NewQueryService(repo)
|
||||
|
||||
return &SsqAPI{
|
||||
queryService: queryService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// QueryRequest 查询请求参数
|
||||
type QueryRequest struct {
|
||||
RedBalls []int `json:"red_balls"` // 红球列表
|
||||
BlueBall int `json:"blue_ball"` // 蓝球(0表示不限制)
|
||||
BlueBallRange []int `json:"blue_ball_range"` // 蓝球筛选范围
|
||||
}
|
||||
|
||||
// QueryHistory 查询历史数据
|
||||
func (api *SsqAPI) QueryHistory(req QueryRequest) (*service.QueryResult, error) {
|
||||
if api.queryService == nil {
|
||||
// 重新初始化
|
||||
newAPI, err := NewSsqAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.queryService = newAPI.queryService
|
||||
}
|
||||
|
||||
return api.queryService.Query(service.QueryRequest{
|
||||
RedBalls: req.RedBalls,
|
||||
BlueBall: req.BlueBall,
|
||||
BlueBallRange: req.BlueBallRange,
|
||||
})
|
||||
}
|
||||
69
internal/api/sync_api.go
Normal file
69
internal/api/sync_api.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ssq-desk/internal/service"
|
||||
"ssq-desk/internal/storage/repository"
|
||||
)
|
||||
|
||||
// SyncAPI 数据同步 API
|
||||
type SyncAPI struct {
|
||||
syncService *service.SyncService
|
||||
}
|
||||
|
||||
// NewSyncAPI 创建数据同步 API
|
||||
func NewSyncAPI() (*SyncAPI, error) {
|
||||
// 获取 MySQL 和 SQLite Repository
|
||||
mysqlRepo, err := repository.NewMySQLSsqRepository()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqliteRepo, err := repository.NewSQLiteSsqRepository()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
syncService := service.NewSyncService(mysqlRepo, sqliteRepo)
|
||||
|
||||
return &SyncAPI{
|
||||
syncService: syncService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Sync 执行数据同步
|
||||
func (api *SyncAPI) Sync() (map[string]interface{}, error) {
|
||||
if api.syncService == nil {
|
||||
newAPI, err := NewSyncAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.syncService = newAPI.syncService
|
||||
}
|
||||
|
||||
result, err := api.syncService.Sync()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"total_count": result.TotalCount,
|
||||
"synced_count": result.SyncedCount,
|
||||
"new_count": result.NewCount,
|
||||
"updated_count": result.UpdatedCount,
|
||||
"error_count": result.ErrorCount,
|
||||
"latest_issue": result.LatestIssue,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetSyncStatus 获取同步状态
|
||||
func (api *SyncAPI) GetSyncStatus() (map[string]interface{}, error) {
|
||||
if api.syncService == nil {
|
||||
newAPI, err := NewSyncAPI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api.syncService = newAPI.syncService
|
||||
}
|
||||
|
||||
return api.syncService.GetSyncStatus()
|
||||
}
|
||||
254
internal/api/update_api.go
Normal file
254
internal/api/update_api.go
Normal file
@@ -0,0 +1,254 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"ssq-desk/internal/service"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
// UpdateAPI 版本更新 API
|
||||
type UpdateAPI struct {
|
||||
updateService *service.UpdateService
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// NewUpdateAPI 创建版本更新 API
|
||||
func NewUpdateAPI(checkURL string) (*UpdateAPI, error) {
|
||||
updateService := service.NewUpdateService(checkURL)
|
||||
|
||||
return &UpdateAPI{
|
||||
updateService: updateService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetContext 设置上下文(用于事件推送)
|
||||
func (api *UpdateAPI) SetContext(ctx context.Context) {
|
||||
api.ctx = ctx
|
||||
}
|
||||
|
||||
// CheckUpdate 检查更新
|
||||
func (api *UpdateAPI) CheckUpdate() (map[string]interface{}, error) {
|
||||
if api.updateService == nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": "更新服务未初始化",
|
||||
}, nil
|
||||
}
|
||||
|
||||
result, err := api.updateService.CheckUpdate()
|
||||
if err != nil {
|
||||
errorMsg := err.Error()
|
||||
if errorMsg == "" {
|
||||
errorMsg = "未知错误"
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": errorMsg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": "检查更新返回结果为空",
|
||||
}, nil
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"data": result,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetCurrentVersion 获取当前版本号
|
||||
func (api *UpdateAPI) GetCurrentVersion() (map[string]interface{}, error) {
|
||||
version := service.GetCurrentVersion()
|
||||
|
||||
// 更新配置中的版本号
|
||||
if config, err := service.LoadUpdateConfig(); err == nil && config.CurrentVersion != version {
|
||||
config.CurrentVersion = version
|
||||
service.SaveUpdateConfig(config)
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"data": map[string]interface{}{
|
||||
"version": version,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetUpdateConfig 获取更新配置
|
||||
func (api *UpdateAPI) GetUpdateConfig() (map[string]interface{}, error) {
|
||||
config, err := service.LoadUpdateConfig()
|
||||
if err != nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 确保版本号是最新的
|
||||
latestVersion := service.GetCurrentVersion()
|
||||
if config.CurrentVersion != latestVersion {
|
||||
config.CurrentVersion = latestVersion
|
||||
service.SaveUpdateConfig(config)
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"data": map[string]interface{}{
|
||||
"current_version": config.CurrentVersion,
|
||||
"last_check_time": config.LastCheckTime.Format("2006-01-02 15:04:05"),
|
||||
"auto_check_enabled": config.AutoCheckEnabled,
|
||||
"check_interval_minutes": config.CheckIntervalMinutes,
|
||||
"check_url": config.CheckURL,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetUpdateConfig 设置更新配置
|
||||
func (api *UpdateAPI) SetUpdateConfig(autoCheckEnabled bool, checkIntervalMinutes int, checkURL string) (map[string]interface{}, error) {
|
||||
config, err := service.LoadUpdateConfig()
|
||||
if err != nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
config.AutoCheckEnabled = autoCheckEnabled
|
||||
config.CheckIntervalMinutes = checkIntervalMinutes
|
||||
if checkURL != "" {
|
||||
config.CheckURL = checkURL
|
||||
// 如果 URL 改变,需要重新创建服务
|
||||
api.updateService = service.NewUpdateService(checkURL)
|
||||
}
|
||||
|
||||
if err := service.SaveUpdateConfig(config); err != nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"message": "配置保存成功",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DownloadUpdate 下载更新包(异步,通过事件推送进度)
|
||||
func (api *UpdateAPI) DownloadUpdate(downloadURL string) (map[string]interface{}, error) {
|
||||
if downloadURL == "" {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": "下载地址不能为空",
|
||||
}, nil
|
||||
}
|
||||
|
||||
go func() {
|
||||
progressCallback := func(progress float64, speed float64, downloaded int64, total int64) {
|
||||
if api.ctx == nil {
|
||||
return
|
||||
}
|
||||
// 确保进度值在 0-100 之间
|
||||
if progress < 0 {
|
||||
progress = 0
|
||||
} else if progress > 100 {
|
||||
progress = 100
|
||||
}
|
||||
|
||||
progressInfo := map[string]interface{}{
|
||||
"progress": progress,
|
||||
"speed": speed,
|
||||
"downloaded": downloaded,
|
||||
"total": total,
|
||||
}
|
||||
progressJSON, _ := json.Marshal(progressInfo)
|
||||
runtime.EventsEmit(api.ctx, "download-progress", string(progressJSON))
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
result, err := service.DownloadUpdate(downloadURL, progressCallback)
|
||||
|
||||
if api.ctx != nil {
|
||||
if err != nil {
|
||||
errorInfo := map[string]interface{}{"error": err.Error()}
|
||||
errorJSON, _ := json.Marshal(errorInfo)
|
||||
runtime.EventsEmit(api.ctx, "download-complete", string(errorJSON))
|
||||
} else {
|
||||
resultInfo := map[string]interface{}{
|
||||
"success": true,
|
||||
"file_path": result.FilePath,
|
||||
"file_size": result.FileSize,
|
||||
}
|
||||
resultJSON, _ := json.Marshal(resultInfo)
|
||||
runtime.EventsEmit(api.ctx, "download-complete", string(resultJSON))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"message": "下载已开始",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InstallUpdate 安装更新包
|
||||
func (api *UpdateAPI) InstallUpdate(installerPath string, autoRestart bool) (map[string]interface{}, error) {
|
||||
return api.InstallUpdateWithHash(installerPath, autoRestart, "", "")
|
||||
}
|
||||
|
||||
// InstallUpdateWithHash 安装更新包(带哈希验证)
|
||||
func (api *UpdateAPI) InstallUpdateWithHash(installerPath string, autoRestart bool, expectedHash string, hashType string) (map[string]interface{}, error) {
|
||||
if installerPath == "" {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": "安装文件路径不能为空",
|
||||
}, nil
|
||||
}
|
||||
|
||||
result, err := service.InstallUpdateWithHash(installerPath, autoRestart, expectedHash, hashType)
|
||||
if err != nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": result.Success,
|
||||
"message": result.Message,
|
||||
"data": result,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// VerifyUpdateFile 验证更新文件哈希值
|
||||
func (api *UpdateAPI) VerifyUpdateFile(filePath string, expectedHash string, hashType string) (map[string]interface{}, error) {
|
||||
if filePath == "" {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": "文件路径不能为空",
|
||||
}, nil
|
||||
}
|
||||
|
||||
valid, err := service.VerifyFileHash(filePath, expectedHash, hashType)
|
||||
if err != nil {
|
||||
return map[string]interface{}{
|
||||
"success": false,
|
||||
"message": err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"data": map[string]interface{}{
|
||||
"valid": valid,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user