/* history.go - 历史记录管理 定义了历史记录的数据结构和相关功能 */ package calculator import ( "encoding/json" "fmt" "io/ioutil" "os" "strings" "time" ) // HistoryRecord 表示一条计算历史记录 type HistoryRecord struct { Expression string `json:"expression"` // 表达式 Result float64 `json:"result"` // 计算结果 Timestamp time.Time `json:"timestamp"` // 计算时间 } // NewHistoryRecord 创建新的历史记录 func NewHistoryRecord(expression string, result float64) HistoryRecord { return HistoryRecord{ Expression: expression, Result: result, Timestamp: time.Now(), } } // String 返回历史记录的字符串表示 func (h HistoryRecord) String() string { return fmt.Sprintf("%s = %g (计算时间: %s)", h.Expression, h.Result, h.Timestamp.Format("2006-01-02 15:04:05")) } // HistoryManager 历史记录管理器 type HistoryManager struct { records []HistoryRecord filePath string maxSize int } // NewHistoryManager 创建新的历史记录管理器 func NewHistoryManager(filePath string, maxSize int) *HistoryManager { return &HistoryManager{ records: make([]HistoryRecord, 0), filePath: filePath, maxSize: maxSize, } } // Add 添加历史记录 func (hm *HistoryManager) Add(expression string, result float64) { record := NewHistoryRecord(expression, result) hm.records = append(hm.records, record) // 限制历史记录数量 if len(hm.records) > hm.maxSize { hm.records = hm.records[len(hm.records)-hm.maxSize:] } } // GetAll 获取所有历史记录 func (hm *HistoryManager) GetAll() []HistoryRecord { // 返回副本以防止外部修改 records := make([]HistoryRecord, len(hm.records)) copy(records, hm.records) return records } // GetLast 获取最近的 n 条记录 func (hm *HistoryManager) GetLast(n int) []HistoryRecord { if n <= 0 { return []HistoryRecord{} } if n >= len(hm.records) { return hm.GetAll() } start := len(hm.records) - n records := make([]HistoryRecord, n) copy(records, hm.records[start:]) return records } // Clear 清空历史记录 func (hm *HistoryManager) Clear() { hm.records = make([]HistoryRecord, 0) } // Count 获取历史记录数量 func (hm *HistoryManager) Count() int { return len(hm.records) } // SaveToFile 保存历史记录到文件 func (hm *HistoryManager) SaveToFile() error { if hm.filePath == "" { return fmt.Errorf("文件路径未设置") } data, err := json.MarshalIndent(hm.records, "", " ") if err != nil { return fmt.Errorf("序列化历史记录失败: %v", err) } err = ioutil.WriteFile(hm.filePath, data, 0644) if err != nil { return fmt.Errorf("写入文件失败: %v", err) } return nil } // LoadFromFile 从文件加载历史记录 func (hm *HistoryManager) LoadFromFile() error { if hm.filePath == "" { return fmt.Errorf("文件路径未设置") } // 检查文件是否存在 if _, err := os.Stat(hm.filePath); os.IsNotExist(err) { // 文件不存在,创建空的历史记录 hm.records = make([]HistoryRecord, 0) return nil } data, err := ioutil.ReadFile(hm.filePath) if err != nil { return fmt.Errorf("读取文件失败: %v", err) } err = json.Unmarshal(data, &hm.records) if err != nil { return fmt.Errorf("反序列化历史记录失败: %v", err) } // 限制历史记录数量 if len(hm.records) > hm.maxSize { hm.records = hm.records[len(hm.records)-hm.maxSize:] } return nil } // Search 搜索包含指定关键词的历史记录 func (hm *HistoryManager) Search(keyword string) []HistoryRecord { var results []HistoryRecord for _, record := range hm.records { if contains(record.Expression, keyword) { results = append(results, record) } } return results } // GetStatistics 获取历史记录统计信息 func (hm *HistoryManager) GetStatistics() map[string]interface{} { stats := make(map[string]interface{}) stats["total_count"] = len(hm.records) if len(hm.records) == 0 { return stats } // 统计运算符使用频率 operatorCount := make(map[string]int) for _, record := range hm.records { for _, char := range record.Expression { switch char { case '+': operatorCount["addition"]++ case '-': operatorCount["subtraction"]++ case '*': operatorCount["multiplication"]++ case '/': operatorCount["division"]++ } } } stats["operator_usage"] = operatorCount // 最早和最晚的计算时间 if len(hm.records) > 0 { earliest := hm.records[0].Timestamp latest := hm.records[0].Timestamp for _, record := range hm.records { if record.Timestamp.Before(earliest) { earliest = record.Timestamp } if record.Timestamp.After(latest) { latest = record.Timestamp } } stats["earliest_calculation"] = earliest.Format("2006-01-02 15:04:05") stats["latest_calculation"] = latest.Format("2006-01-02 15:04:05") } return stats } // ExportToCSV 导出历史记录为 CSV 格式 func (hm *HistoryManager) ExportToCSV(filePath string) error { var csvContent strings.Builder // CSV 头部 csvContent.WriteString("Expression,Result,Timestamp\n") // 数据行 for _, record := range hm.records { csvContent.WriteString(fmt.Sprintf("\"%s\",%g,\"%s\"\n", record.Expression, record.Result, record.Timestamp.Format("2006-01-02 15:04:05"))) } err := ioutil.WriteFile(filePath, []byte(csvContent.String()), 0644) if err != nil { return fmt.Errorf("导出 CSV 文件失败: %v", err) } return nil } // contains 检查字符串是否包含子字符串(忽略大小写) func contains(s, substr string) bool { return len(s) >= len(substr) && (substr == "" || len(s) > 0 && (s == substr || strings.Contains(strings.ToLower(s), strings.ToLower(substr)))) }