Files
kitchen/lib/src/controllers/data/cooking_note_controller.dart
Developer 5667435b56 重构5
2026-04-19 04:27:16 +08:00

223 lines
6.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 烹饪笔记控制器
// 创建时间: 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<CookingNoteModel> _notes = <CookingNoteModel>[].obs;
static const String _sharedPrefsKey = 'cooking_notes';
SharedPreferences? _prefs;
List<CookingNoteModel> get notes => _notes;
@override
void onInit() {
super.onInit();
_initPrefs();
}
Future<void> _initPrefs() async {
try {
_prefs = await SharedPreferences.getInstance();
await loadNotes();
} catch (e) {
debugPrint('初始化SharedPreferences失败: $e');
}
}
/// 加载所有烹饪笔记优先Hive失败则从SharedPreferences加载
Future<void> 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<dynamic> jsonList = json.decode(data);
_notes.assignAll(
jsonList.map((json) => CookingNoteModel.fromJson(json)).toList(),
);
debugPrint('从SharedPreferences加载笔记: ${_notes.length}');
}
} catch (e) {
debugPrint('加载烹饪笔记失败: $e');
}
}
/// 添加烹饪笔记
Future<void> 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<void> 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<void> 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<CookingNoteModel> getNotesByRecipeId(String recipeId) {
return _notes.where((note) => note.recipeId == recipeId).toList();
}
/// 清空所有笔记
Future<void> clearAllNotes() async {
try {
// 清空Hive
if (_hiveService.isInitialized) {
await _hiveService.clearCookingNotes();
}
// 清空SharedPreferences
_notes.clear();
await _saveToSharedPreferences();
} catch (e) {
debugPrint('清空烹饪笔记失败: $e');
}
}
/// 保存到SharedPreferences
Future<void> _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<String> getAllTags() {
final tags = <String>{};
for (final note in _notes) {
tags.addAll(note.tags);
}
return tags.toList()..sort();
}
/// 根据标签筛选笔记
List<CookingNoteModel> 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<String, dynamic> json) {
try {
final note = CookingNoteModel.fromJson(json);
if (!_notes.any((n) => n.id == note.id)) {
addNote(note);
}
} catch (e) {
debugPrint('CookingNoteController: importFromJson failed: $e');
}
}
}