// 烹饪笔记控制器 // 创建时间: 2026-04-09 // 更新时间: 2026-04-12 // 名称: cooking_note_controller.dart // 作用: 管理烹饪笔记的增删改查,支持Hive和SharedPreferences双重存储 // 上次更新内容: 添加SharedPreferences备选存储,确保笔记正确保存 import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; import '../../models/data/record/cooking_note_model.dart'; import '../../services/data/storage/hive_service.dart'; class CookingNoteController extends GetxController { static CookingNoteController get to => Get.find(); final HiveService _hiveService = HiveService(); final RxList _notes = [].obs; static const String _sharedPrefsKey = 'cooking_notes'; SharedPreferences? _prefs; List get notes => _notes; @override void onInit() { super.onInit(); _initPrefs(); } Future _initPrefs() async { try { _prefs = await SharedPreferences.getInstance(); await loadNotes(); } catch (e) { debugPrint('初始化SharedPreferences失败: $e'); } } /// 加载所有烹饪笔记(优先Hive,失败则从SharedPreferences加载) Future loadNotes() async { try { // 先尝试从Hive加载 if (_hiveService.isInitialized) { final notes = _hiveService.getCookingNotes(); if (notes.isNotEmpty) { _notes.assignAll(notes); debugPrint('从Hive加载笔记: ${notes.length}条'); return; } } _prefs ??= await SharedPreferences.getInstance(); final String? data = _prefs!.getString(_sharedPrefsKey); if (data != null && data.isNotEmpty) { final List jsonList = json.decode(data); _notes.assignAll( jsonList.map((json) => CookingNoteModel.fromJson(json)).toList(), ); debugPrint('从SharedPreferences加载笔记: ${_notes.length}条'); } } catch (e) { debugPrint('加载烹饪笔记失败: $e'); } } /// 添加烹饪笔记 Future addNote(CookingNoteModel note) async { try { // 保存到Hive if (_hiveService.isInitialized) { await _hiveService.addCookingNote(note); debugPrint('笔记已保存到Hive: ${note.id}'); } // 同时保存到SharedPreferences作为备份 _notes.add(note); await _saveToSharedPreferences(); debugPrint('笔记已保存到SharedPreferences: ${note.id}'); } catch (e) { debugPrint('添加烹饪笔记失败: $e'); // 即使失败也尝试保存到内存 _notes.add(note); } } /// 更新烹饪笔记 Future updateNote(CookingNoteModel note) async { try { // 更新Hive if (_hiveService.isInitialized) { await _hiveService.updateCookingNote(note); } // 更新SharedPreferences final index = _notes.indexWhere((n) => n.id == note.id); if (index >= 0) { _notes[index] = note; await _saveToSharedPreferences(); } } catch (e) { debugPrint('更新烹饪笔记失败: $e'); } } /// 删除烹饪笔记 Future deleteNote(String id) async { try { // 从Hive删除 if (_hiveService.isInitialized) { await _hiveService.deleteCookingNote(id); } // 从SharedPreferences删除 _notes.removeWhere((n) => n.id == id); await _saveToSharedPreferences(); } catch (e) { debugPrint('删除烹饪笔记失败: $e'); } } /// 获取菜谱相关的笔记 List getNotesByRecipeId(String recipeId) { return _notes.where((note) => note.recipeId == recipeId).toList(); } /// 清空所有笔记 Future clearAllNotes() async { try { // 清空Hive if (_hiveService.isInitialized) { await _hiveService.clearCookingNotes(); } // 清空SharedPreferences _notes.clear(); await _saveToSharedPreferences(); } catch (e) { debugPrint('清空烹饪笔记失败: $e'); } } /// 保存到SharedPreferences Future _saveToSharedPreferences() async { try { _prefs ??= await SharedPreferences.getInstance(); final data = json.encode(_notes.map((n) => n.toJson()).toList()); await _prefs!.setString(_sharedPrefsKey, data); debugPrint('笔记已保存到SharedPreferences: ${_notes.length}条'); } catch (e) { debugPrint('保存笔记到SharedPreferences失败: $e'); } } /// 获取所有标签 List getAllTags() { final tags = {}; for (final note in _notes) { tags.addAll(note.tags); } return tags.toList()..sort(); } /// 根据标签筛选笔记 List getNotesByTag(String tag) { return _notes.where((note) => note.tags.contains(tag)).toList(); } String exportToJson() { final data = _notes.map((e) => e.toJson()).toList(); return const JsonEncoder.withIndent(' ').convert(data); } String exportToCsv() { final buffer = StringBuffer(); buffer.writeln('ID,菜谱ID,标题,内容,标签,创建时间'); for (final note in _notes) { buffer.writeln( [ note.id, note.recipeId, '"${(note.title ?? '').replaceAll('"', '""')}"', '"${note.content.replaceAll('"', '""').replaceAll('\n', ' ')}"', '"${note.tags.join('; ')}"', note.createdAt, ].join(','), ); } return buffer.toString(); } String exportToMarkdown() { final buffer = StringBuffer(); buffer.writeln('# 📝 烹饪笔记'); buffer.writeln(); for (final note in _notes) { buffer.writeln('## ${note.displayTitle}'); if (note.hasTags) { buffer.writeln('标签: ${note.tags.map((t) => '`$t`').join(' ')}'); } buffer.writeln(); buffer.writeln(note.content); buffer.writeln(); buffer.writeln('*${note.displayDate}*'); buffer.writeln('---'); buffer.writeln(); } return buffer.toString(); } void importFromJson(Map json) { try { final note = CookingNoteModel.fromJson(json); if (!_notes.any((n) => n.id == note.id)) { addNote(note); } } catch (e) { debugPrint('CookingNoteController: importFromJson failed: $e'); } } }