package service import ( "context" "encoding/json" "fmt" "time" "equipment-analyzer/internal/capture" "equipment-analyzer/internal/config" "equipment-analyzer/internal/model" "equipment-analyzer/internal/utils" ) type App struct { config *config.Config logger *utils.Logger captureService *CaptureService parserService *ParserService database *model.Database databaseService *DatabaseService } func NewApp(cfg *config.Config, logger *utils.Logger) *App { // 初始化数据库 database, err := model.NewDatabase() if err != nil { logger.Error("初始化数据库失败", "error", err) // 如果数据库初始化失败,仍然创建应用,但数据库功能不可用 return &App{ config: cfg, logger: logger, captureService: NewCaptureService(cfg, logger), parserService: NewParserService(cfg, logger), } } databaseService := NewDatabaseService(database, logger) return &App{ config: cfg, logger: logger, captureService: NewCaptureService(cfg, logger), parserService: NewParserService(cfg, logger), database: database, databaseService: databaseService, } } func (a *App) Startup(ctx context.Context) { a.logger.Info("应用启动") } func (a *App) DomReady(ctx context.Context) { a.logger.Info("DOM准备就绪") } func (a *App) BeforeClose(ctx context.Context) (prevent bool) { a.logger.Info("应用即将关闭") return false } func (a *App) Shutdown(ctx context.Context) { a.logger.Info("应用关闭") // 关闭数据库连接 if a.database != nil { if err := a.database.Close(); err != nil { a.logger.Error("关闭数据库连接失败", "error", err) } else { a.logger.Info("数据库连接已关闭") } } } // GetNetworkInterfaces 获取网络接口列表 func (a *App) GetNetworkInterfaces() ([]model.NetworkInterface, error) { interfaces, err := capture.GetNetworkInterfaces() if err != nil { a.logger.Error("获取网络接口失败", "error", err) return nil, err } return interfaces, nil } // StartCapture 开始抓包 func (a *App) StartCapture(interfaceName string) error { if a.captureService.IsCapturing() { return fmt.Errorf("抓包已在进行中") } config := capture.Config{ InterfaceName: interfaceName, Filter: a.config.Capture.DefaultFilter, Timeout: time.Duration(a.config.Capture.DefaultTimeout) * time.Millisecond, BufferSize: a.config.Capture.BufferSize, } err := a.captureService.StartCapture(context.Background(), config) if err != nil { a.logger.Error("开始抓包失败", "error", err) return err } a.logger.Info("抓包开始", "interface", interfaceName) return nil } // StopCapture 停止抓包 func (a *App) StopCapture() error { if !a.captureService.IsCapturing() { return fmt.Errorf("没有正在进行的抓包") } err := a.captureService.StopCapture() if err != nil { a.logger.Error("停止抓包失败", "error", err) return err } // 处理所有收集的数据 a.captureService.ProcessAllData() a.logger.Info("抓包停止") return nil } // GetCapturedData 获取抓包数据 func (a *App) GetCapturedData() ([]string, error) { return a.captureService.GetCapturedData(), nil } // ParseData 解析数据为JSON func (a *App) ParseData(hexDataList []string) (string, error) { _, rawJson, err := a.parserService.ParseHexData(hexDataList) if err != nil { a.logger.Error("解析数据失败", "error", err) return "", err } return rawJson, nil } // ExportData 导出数据到文件 func (a *App) ExportData(hexDataList []string, filename string) error { result, rawJson, err := a.parserService.ParseHexData(hexDataList) if err != nil { a.logger.Error("解析数据失败", "error", err) return err } // 这里可以添加文件写入逻辑 a.logger.Info("导出数据", "filename", filename, "count", len(result.Items)) // 简单示例:写入到当前目录 err = utils.WriteFile(filename, []byte(rawJson)) if err != nil { a.logger.Error("写入文件失败", "error", err) return err } return nil } // ExportCurrentData 导出当前数据库中的数据到文件 func (a *App) ExportCurrentData(filename string) error { if a.databaseService == nil { return fmt.Errorf("数据库服务未初始化") } // 从数据库获取最新数据 parsedResult, err := a.GetLatestParsedDataFromDatabase() if err != nil { a.logger.Error("获取数据库数据失败", "error", err) return err } if parsedResult == nil || (len(parsedResult.Items) == 0 && len(parsedResult.Heroes) == 0) { return fmt.Errorf("没有数据可导出") } // 创建导出数据格式 exportData := map[string]interface{}{ "items": parsedResult.Items, "heroes": parsedResult.Heroes, } // 序列化为JSON jsonData, err := json.MarshalIndent(exportData, "", " ") if err != nil { a.logger.Error("序列化数据失败", "error", err) return err } // 写入文件 err = utils.WriteFile(filename, jsonData) if err != nil { a.logger.Error("写入文件失败", "error", err) return err } a.logger.Info("数据导出成功", "filename", filename, "items_count", len(parsedResult.Items), "heroes_count", len(parsedResult.Heroes)) return nil } // GetCurrentDataForExport 获取当前数据库中的数据,供前端导出使用 func (a *App) GetCurrentDataForExport() (string, error) { if a.databaseService == nil { return "", fmt.Errorf("数据库服务未初始化") } // 从数据库获取最新数据 parsedResult, err := a.GetLatestParsedDataFromDatabase() if err != nil { a.logger.Error("获取数据库数据失败", "error", err) return "", err } if parsedResult == nil || (len(parsedResult.Items) == 0 && len(parsedResult.Heroes) == 0) { return "", fmt.Errorf("没有数据可导出") } // 创建导出数据格式 exportData := map[string]interface{}{ "items": parsedResult.Items, "heroes": parsedResult.Heroes, } // 序列化为JSON jsonData, err := json.MarshalIndent(exportData, "", " ") if err != nil { a.logger.Error("序列化数据失败", "error", err) return "", err } return string(jsonData), nil } // GetCaptureStatus 获取抓包状态 func (a *App) GetCaptureStatus() model.CaptureStatus { return model.CaptureStatus{ IsCapturing: a.captureService.IsCapturing(), Status: a.getStatusMessage(), } } func (a *App) getStatusMessage() string { if a.captureService.IsCapturing() { return "正在抓包..." } return "准备就绪" } // ReadRawJsonFile 已废弃,请使用GetLatestParsedDataFromDatabase从数据库获取数据 func (a *App) ReadRawJsonFile() (*model.ParsedResult, error) { return a.GetLatestParsedDataFromDatabase() } // StopAndParseCapture 停止抓包并解析数据,供前端调用 func (a *App) StopAndParseCapture() (*model.ParsedResult, error) { result, err := a.captureService.StopAndParseCapture(a.parserService) if err != nil { a.logger.Error("停止抓包并解析数据失败", "error", err) return nil, err } // 将解析结果保存到数据库 if a.databaseService != nil && result != nil { // 序列化装备数据 itemsJSON := "[]" if result.Items != nil { if jsonData, err := json.Marshal(result.Items); err == nil { itemsJSON = string(jsonData) } } // 序列化英雄数据 heroesJSON := "[]" if result.Heroes != nil { if jsonData, err := json.Marshal(result.Heroes); err == nil { heroesJSON = string(jsonData) } } // 保存到数据库 sessionName := fmt.Sprintf("capture_%d", time.Now().Unix()) if err := a.databaseService.SaveParsedDataToDatabase(sessionName, itemsJSON, heroesJSON); err != nil { a.logger.Error("保存解析数据到数据库失败", "error", err) // 不返回错误,因为解析成功了,只是保存失败 } else { a.logger.Info("解析数据已保存到数据库", "session_name", sessionName) } } return result, nil } // ========== 数据库相关API ========== // SaveParsedDataToDatabase 保存解析后的数据到数据库 func (a *App) SaveParsedDataToDatabase(sessionName string, itemsJSON, heroesJSON string) error { if a.databaseService == nil { return fmt.Errorf("数据库服务未初始化") } return a.databaseService.SaveParsedDataToDatabase(sessionName, itemsJSON, heroesJSON) } // GetLatestParsedDataFromDatabase 从数据库获取最新的解析数据 func (a *App) GetLatestParsedDataFromDatabase() (*model.ParsedResult, error) { if a.databaseService == nil { return nil, fmt.Errorf("数据库服务未初始化") } itemsJSON, heroesJSON, err := a.databaseService.GetLatestParsedDataFromDatabase() if err != nil { return nil, err } // 解析装备数据 var items []interface{} if itemsJSON != "" { if err := json.Unmarshal([]byte(itemsJSON), &items); err != nil { return nil, fmt.Errorf("解析装备数据失败: %w", err) } } // 解析英雄数据 var heroes []interface{} if heroesJSON != "" { if err := json.Unmarshal([]byte(heroesJSON), &heroes); err != nil { return nil, fmt.Errorf("解析英雄数据失败: %w", err) } } return &model.ParsedResult{ Items: items, Heroes: heroes, }, nil } // SaveAppSetting 保存应用设置 func (a *App) SaveAppSetting(key, value string) error { if a.databaseService == nil { return fmt.Errorf("数据库服务未初始化") } return a.databaseService.SaveAppSetting(key, value) } // GetAppSetting 获取应用设置 func (a *App) GetAppSetting(key string) (string, error) { if a.databaseService == nil { return "", fmt.Errorf("数据库服务未初始化") } return a.databaseService.GetAppSetting(key) } // GetAllAppSettings 获取所有应用设置 func (a *App) GetAllAppSettings() (map[string]string, error) { if a.databaseService == nil { return nil, fmt.Errorf("数据库服务未初始化") } return a.databaseService.GetAllAppSettings() }