223 lines
6.3 KiB
Dart
223 lines
6.3 KiB
Dart
// 烹饪笔记控制器
|
||
// 创建时间: 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');
|
||
}
|
||
}
|
||
}
|