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` /// key 用服务器题号(Question.questionId),不依赖本地自增 id, /// 这样续答恢复时即使题目重新拉取也能对上。 /// /// 三、持久化为什么 fire-and-forget: /// put 走 Isar 毫秒级完成,没必要阻塞 UI 作答回调; /// web 端 store 是空实现(打印跳过),行为自动降级为纯内存。 /// ============================================================ /// Demo 试卷 id(真实项目由试卷对象传入,如 paper.paperId) const int demoPaperId = 1001; final answerProvider = NotifierProvider>(AnswerNotifier.new); class AnswerNotifier extends Notifier> { @override Map 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 saved) { if (saved.isEmpty) return; state = {...state, ...saved}; } /// 【交卷清理】清空内存状态(Isar 记录由页面调 deleteByPaper) void clear() => state = {}; }