更新
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
/// ============================================================
|
||||
/// 【课堂习题 · 会话状态与 UI 桥接】
|
||||
///
|
||||
/// Vue 端各 createXxxHandlers 通过一堆 ref 共享状态;Flutter 端按
|
||||
/// 用户拍板用“普通 Dart 控制器(无 Riverpod)”,因此把跨控制器共享
|
||||
/// 的可变状态收敛到 [ExerciseSession],把与 Widget/导航/弹窗相关的
|
||||
/// 副作用收敛到 [ExerciseUiBridge],由页面 State 实现并注入。
|
||||
/// ============================================================
|
||||
library;
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:new_learn/features/conquerPackage/classExercises/exercise_question_view.dart';
|
||||
import 'package:new_learn/features/conquerPackage/classExercises/models/question_model.dart';
|
||||
import 'package:new_learn/features/conquerPackage/classExercises/widgets/compound_question_panel.dart';
|
||||
import 'package:new_learn/features/conquerPackage/classExercises/widgets/question_plan_countdown.dart';
|
||||
|
||||
/// 当前本地 ISO 时间(对标 getCurrentISO)
|
||||
String getCurrentISO() => DateTime.now().toIso8601String();
|
||||
|
||||
/// 攻克流程弹窗配置(对标 Vue conquerPopupCon)
|
||||
class ConquerPopupConfig {
|
||||
ConquerPopupConfig({
|
||||
this.show = false,
|
||||
this.type = 'note',
|
||||
this.title = '',
|
||||
this.subtitle = '',
|
||||
this.confirmText = '确定',
|
||||
this.cancelText = '取消',
|
||||
this.isConfirm = false,
|
||||
this.confirmAction = '',
|
||||
});
|
||||
|
||||
bool show;
|
||||
String type; // note / time / submit / grading
|
||||
String title;
|
||||
String subtitle;
|
||||
String confirmText;
|
||||
String cancelText;
|
||||
bool isConfirm;
|
||||
String confirmAction;
|
||||
}
|
||||
|
||||
/// 跨控制器共享的会话状态(字段名与 Vue 保持一致)
|
||||
class ExerciseSession {
|
||||
/// 题目列表(解析后的 QuestionModel,与 Map 同引用语义)
|
||||
List<QuestionModel> questions = [];
|
||||
|
||||
/// 当前大题索引(swiper index)
|
||||
int currentIndex = 0;
|
||||
|
||||
/// edit / view
|
||||
String mode = 'edit';
|
||||
|
||||
String courseId = '';
|
||||
String packId = '';
|
||||
String totalPackId = '';
|
||||
String recordId = '';
|
||||
|
||||
bool isWrong = false;
|
||||
|
||||
/// view 全量题号(originalMaxSort)
|
||||
int originalMaxSort = 0;
|
||||
|
||||
/// 导航栏标题
|
||||
String navBarTitle = '';
|
||||
|
||||
/// 大题索引 -> 激活子题索引
|
||||
final Map<int, int> activeSubIndexMap = {};
|
||||
|
||||
/// 大题索引 -> 等待页面挂载后定位的子题索引
|
||||
final Map<int, int> pendingSubIndexMap = {};
|
||||
|
||||
/// 已处理过的题目 id(避免重复提交,对应 processedQuestionIds)
|
||||
final Set<String> processedQuestionIds = <String>{};
|
||||
|
||||
/// 单题页 ref(itemRefs)
|
||||
final Map<int, GlobalKey<ExerciseQuestionViewState>> itemRefs = {};
|
||||
|
||||
/// 复合题面板 ref(compoundQuestionFn)
|
||||
GlobalKey<CompoundQuestionPanelState>? panelKey;
|
||||
|
||||
/// 倒计时组件 ref(countDownRef)
|
||||
GlobalKey<QuestionPlanCountDownState>? countDownKey;
|
||||
|
||||
bool get isView => mode == 'view';
|
||||
|
||||
/// 当前题(questionsInfo)。Flutter 与列表元素保持同一引用,
|
||||
/// 不再做 Vue 的浅拷贝。
|
||||
QuestionModel? get currentQuestion {
|
||||
if (currentIndex < 0 || currentIndex >= questions.length) return null;
|
||||
return questions[currentIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/// 控制器 -> 页面的副作用桥接(页面 State implements 本接口)
|
||||
abstract class ExerciseUiBridge {
|
||||
/// 全局 loading(对标 uni.showLoading({mask:true}))
|
||||
void showLoading([String message]);
|
||||
void hideLoading();
|
||||
|
||||
/// 轻提示(对标 uni.showToast icon:none)
|
||||
void toast(String message);
|
||||
|
||||
/// 通知页面刷新(对标 Vue ref 赋值触发渲染)
|
||||
void notifyListeners();
|
||||
|
||||
/// PageController 切页(对标 swiper.slideTo)
|
||||
void jumpToPage(int index);
|
||||
|
||||
/// 打开“退出攻克”确认框(openExitPopup)
|
||||
void openExitPopup();
|
||||
|
||||
/// 展示攻克流程弹窗(getConquerPopupCon)
|
||||
void showConquerPopup(ConquerPopupConfig config);
|
||||
|
||||
/// 关闭攻克流程弹窗
|
||||
void hideConquerPopup();
|
||||
|
||||
/// 答题卡显隐(showAnswerSheet)
|
||||
void setAnswerSheetVisible(bool visible);
|
||||
|
||||
/// 暂停弹窗显隐(showPausePopup)
|
||||
void setPausePopupVisible(bool visible);
|
||||
|
||||
/// 交卷成功跳报告页(redirectTo report)
|
||||
void redirectToReport(String recordId, String packId);
|
||||
|
||||
/// 返回上 N 页(navigateBack delta)
|
||||
void navigateBack({int delta});
|
||||
|
||||
/// 重启到攻克列表(reLaunch captureList)
|
||||
void relaunchCaptureList(String courseId);
|
||||
|
||||
/// 是否平板(对标 isPadDevice(),time 弹窗字号用)
|
||||
bool get isPad;
|
||||
}
|
||||
Reference in New Issue
Block a user