- 清理大量废弃的 barrel 导出文件,移除冗余的中间导出层 - 修复所有相对路径导入错误,统一调整为扁平化模块引用 - 更新多平台 pubspec 版本号与依赖库版本 - 补充后端功能问题管理后台与脚本工具 - 调整部分页面的快捷方式文案适配新功能 - 更新部分翻译覆盖率与API文档
208 lines
5.6 KiB
Dart
208 lines
5.6 KiB
Dart
/// ============================================================
|
|
/// 闲言APP — 笔记状态管理
|
|
/// 创建时间: 2026-04-28
|
|
/// 更新时间: 2026-05-24
|
|
/// 作用: 笔记CRUD功能状态管理
|
|
/// 上次更新: 修复deleteAllNotes未重置total字段的bug
|
|
/// ============================================================
|
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../core/utils/logger.dart';
|
|
import '../user_center/services/user_center_service.dart';
|
|
import 'note_model.dart';
|
|
|
|
class NoteListState {
|
|
const NoteListState({
|
|
this.notes = const [],
|
|
this.total = 0,
|
|
this.page = 1,
|
|
this.isLoading = false,
|
|
this.error,
|
|
});
|
|
|
|
final List<NoteModel> notes;
|
|
final int total;
|
|
final int page;
|
|
final bool isLoading;
|
|
final String? error;
|
|
|
|
bool get hasMore => notes.length < total;
|
|
|
|
NoteListState copyWith({
|
|
List<NoteModel>? notes,
|
|
int? total,
|
|
int? page,
|
|
bool? isLoading,
|
|
String? error,
|
|
bool clearError = false,
|
|
}) {
|
|
return NoteListState(
|
|
notes: notes ?? this.notes,
|
|
total: total ?? this.total,
|
|
page: page ?? this.page,
|
|
isLoading: isLoading ?? this.isLoading,
|
|
error: clearError ? null : (error ?? this.error),
|
|
);
|
|
}
|
|
}
|
|
|
|
class NoteListNotifier extends Notifier<NoteListState> {
|
|
@override
|
|
NoteListState build() => const NoteListState();
|
|
NoteListNotifier();
|
|
|
|
Future<void> loadNotes({
|
|
bool refresh = false,
|
|
String? noteType,
|
|
String? sourceType,
|
|
}) async {
|
|
if (state.isLoading) return;
|
|
final page = refresh ? 1 : state.page;
|
|
state = state.copyWith(isLoading: true, clearError: true);
|
|
if (refresh) {
|
|
state = state.copyWith(notes: [], total: 0);
|
|
}
|
|
|
|
try {
|
|
final result = await UserCenterService.note(
|
|
action: NoteAction.list,
|
|
page: page,
|
|
noteType: noteType,
|
|
sourceType: sourceType,
|
|
);
|
|
final total = result['total'] as int? ?? 0;
|
|
final list = (result['list'] as List<dynamic>? ?? [])
|
|
.map((e) => NoteModel.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
|
|
final newNotes = refresh ? list : [...state.notes, ...list];
|
|
state = state.copyWith(
|
|
notes: newNotes,
|
|
total: total,
|
|
page: page + 1,
|
|
isLoading: false,
|
|
);
|
|
} catch (e) {
|
|
Log.e('加载笔记失败', e);
|
|
state = state.copyWith(isLoading: false, error: '加载笔记失败: $e');
|
|
}
|
|
}
|
|
|
|
Future<bool> saveNote({
|
|
int? noteId,
|
|
required String title,
|
|
required String content,
|
|
String category = '',
|
|
String noteType = 'note',
|
|
String sourceType = '',
|
|
int sourceId = 0,
|
|
int isPublic = 0,
|
|
}) async {
|
|
try {
|
|
final action = (noteId != null && noteId > 0)
|
|
? NoteAction.edit
|
|
: NoteAction.add;
|
|
|
|
final result = await UserCenterService.note(
|
|
action: action,
|
|
id: noteId,
|
|
title: title,
|
|
content: content,
|
|
category: category.isNotEmpty ? category : null,
|
|
noteType: noteType != 'note' ? noteType : null,
|
|
sourceType: sourceType.isNotEmpty ? sourceType : null,
|
|
sourceId: sourceId > 0 ? sourceId : null,
|
|
isPublic: isPublic > 0 ? isPublic : null,
|
|
);
|
|
|
|
Log.i('笔记保存成功');
|
|
|
|
if (action == NoteAction.add) {
|
|
final rawId = result['id'];
|
|
final newId = rawId is int
|
|
? rawId
|
|
: int.tryParse(rawId?.toString() ?? '') ?? 0;
|
|
if (newId > 0) {
|
|
final now = (DateTime.now().millisecondsSinceEpoch ~/ 1000)
|
|
.toString();
|
|
final newNote = NoteModel(
|
|
id: newId,
|
|
userId: 0,
|
|
title: title,
|
|
content: content,
|
|
category: category,
|
|
noteType: noteType,
|
|
sourceType: sourceType,
|
|
sourceId: sourceId,
|
|
isPublic: isPublic,
|
|
createtime: now,
|
|
updatetime: now,
|
|
);
|
|
state = state.copyWith(
|
|
notes: [newNote, ...state.notes],
|
|
total: state.total + 1,
|
|
);
|
|
} else {
|
|
await loadNotes(refresh: true);
|
|
}
|
|
} else {
|
|
final updatedNotes = state.notes.map((n) {
|
|
if (n.id == noteId) {
|
|
return n.copyWith(
|
|
title: title,
|
|
content: content,
|
|
category: category,
|
|
noteType: noteType,
|
|
sourceType: sourceType,
|
|
sourceId: sourceId,
|
|
isPublic: isPublic,
|
|
updatetime: (DateTime.now().millisecondsSinceEpoch ~/ 1000)
|
|
.toString(),
|
|
);
|
|
}
|
|
return n;
|
|
}).toList();
|
|
state = state.copyWith(notes: updatedNotes);
|
|
}
|
|
|
|
return true;
|
|
} catch (e) {
|
|
Log.e('保存笔记异常', e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> deleteNote(int noteId) async {
|
|
try {
|
|
await UserCenterService.note(action: NoteAction.delete, id: noteId);
|
|
Log.i('笔记删除成功: $noteId');
|
|
state = state.copyWith(
|
|
notes: state.notes.where((n) => n.id != noteId).toList(),
|
|
total: state.total - 1,
|
|
);
|
|
return true;
|
|
} catch (e) {
|
|
Log.e('删除笔记异常', e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> deleteAllNotes() async {
|
|
try {
|
|
final notes = state.notes;
|
|
for (final note in notes) {
|
|
await UserCenterService.note(action: NoteAction.delete, id: note.id);
|
|
}
|
|
state = state.copyWith(notes: [], total: 0);
|
|
Log.i('全部笔记已清空');
|
|
return true;
|
|
} catch (e) {
|
|
Log.e('清空笔记异常', e);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
final noteListProvider = NotifierProvider<NoteListNotifier, NoteListState>(NoteListNotifier.new);
|