flutter架 构项目基础
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:new_learn/core/storage/stores/answer_record_store.dart';
|
||||
|
||||
/// ============================================================
|
||||
/// 【answerProvider】答题状态 —— Riverpod 内存主状态
|
||||
///
|
||||
/// 一、架构定位(对应方案分析结论):
|
||||
/// 答案主状态必须住内存(每题作答高频读写、交卷即弃),
|
||||
/// Isar 只是"备份恢复层":每次作答同步写一条 AnswerRecord,
|
||||
/// 进程杀掉后下次进卷按 paperId 读回 restore() 续答。
|
||||
///
|
||||
/// 二、数据结构:`Map<questionId, String>`
|
||||
/// key 用服务器题号(Question.questionId),不依赖本地自增 id,
|
||||
/// 这样续答恢复时即使题目重新拉取也能对上。
|
||||
///
|
||||
/// 三、持久化为什么 fire-and-forget:
|
||||
/// put 走 Isar 毫秒级完成,没必要阻塞 UI 作答回调;
|
||||
/// web 端 store 是空实现(打印跳过),行为自动降级为纯内存。
|
||||
/// ============================================================
|
||||
|
||||
/// Demo 试卷 id(真实项目由试卷对象传入,如 paper.paperId)
|
||||
const int demoPaperId = 1001;
|
||||
|
||||
final answerProvider =
|
||||
NotifierProvider<AnswerNotifier, Map<int, String>>(AnswerNotifier.new);
|
||||
|
||||
class AnswerNotifier extends Notifier<Map<int, String>> {
|
||||
@override
|
||||
Map<int, String> build() => {};
|
||||
|
||||
/// 【作答】更新内存 + 同步落盘(续答持久化)
|
||||
void answer(int questionId, String value) {
|
||||
state = {...state, questionId: value};
|
||||
// fire-and-forget:写库毫秒级,不阻塞作答回调
|
||||
unawaited(
|
||||
AnswerRecordStore.instance.put(
|
||||
paperId: demoPaperId,
|
||||
questionId: questionId,
|
||||
answer: value,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 【续答恢复】进卷时从 Isar 读回,整体注入(只恢复本卷存在的题)
|
||||
void restore(Map<int, String> saved) {
|
||||
if (saved.isEmpty) return;
|
||||
state = {...state, ...saved};
|
||||
}
|
||||
|
||||
/// 【交卷清理】清空内存状态(Isar 记录由页面调 deleteByPaper)
|
||||
void clear() => state = {};
|
||||
}
|
||||
Reference in New Issue
Block a user