chore(project): 初始化项目基础配置文件
- 添加 CodeGraph、Android 和通用 gitignore 配置 - 创建项目元数据文件跟踪 Flutter 项目属性 - 添加 Codex AI 指导文档 AGENTS.md 说明项目架构 - 配置代码分析选项 analysis_options.yaml - 设置 Android 应用清单权限和 Kiosk 模式配置 - 实现中英文国际化支持 AppLocalizations - 配置 GoRouter 应用路由导航 - 创建明亮工业控制风格的主题配置 AppTheme
This commit is contained in:
188
lib/features/device/providers/run_state_provider.dart
Normal file
188
lib/features/device/providers/run_state_provider.dart
Normal file
@@ -0,0 +1,188 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../programs/models/program.dart';
|
||||
import '../../programs/models/step.dart';
|
||||
import '../../programs/services/program_service.dart';
|
||||
import '../services/mock_runner.dart';
|
||||
|
||||
/// 运行状态枚举
|
||||
enum RunStatus {
|
||||
idle, // 待机
|
||||
running, // 运行中
|
||||
paused, // 已暂停
|
||||
completed,// 已完成
|
||||
error, // 错误
|
||||
}
|
||||
|
||||
/// 运行状态
|
||||
class RunState {
|
||||
final RunStatus status;
|
||||
final Program? currentProgram;
|
||||
final List<Step> steps;
|
||||
final int currentStepIndex;
|
||||
final int remainingSeconds;
|
||||
final double progress;
|
||||
final String? currentWell;
|
||||
|
||||
const RunState({
|
||||
this.status = RunStatus.idle,
|
||||
this.currentProgram,
|
||||
this.steps = const [],
|
||||
this.currentStepIndex = 0,
|
||||
this.remainingSeconds = 0,
|
||||
this.progress = 0,
|
||||
this.currentWell,
|
||||
});
|
||||
|
||||
RunState copyWith({
|
||||
RunStatus? status,
|
||||
Program? currentProgram,
|
||||
List<Step>? steps,
|
||||
int? currentStepIndex,
|
||||
int? remainingSeconds,
|
||||
double? progress,
|
||||
String? currentWell,
|
||||
bool clearProgram = false,
|
||||
bool clearWell = false,
|
||||
}) {
|
||||
return RunState(
|
||||
status: status ?? this.status,
|
||||
currentProgram: clearProgram ? null : (currentProgram ?? this.currentProgram),
|
||||
steps: steps ?? this.steps,
|
||||
currentStepIndex: currentStepIndex ?? this.currentStepIndex,
|
||||
remainingSeconds: remainingSeconds ?? this.remainingSeconds,
|
||||
progress: progress ?? this.progress,
|
||||
currentWell: clearWell ? null : (currentWell ?? this.currentWell),
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取当前步骤
|
||||
Step? get currentStep {
|
||||
if (steps.isEmpty || currentStepIndex >= steps.length) return null;
|
||||
return steps[currentStepIndex];
|
||||
}
|
||||
|
||||
/// 格式化剩余时间 (HH:MM:SS)
|
||||
String get formattedRemainingTime {
|
||||
final hours = remainingSeconds ~/ 3600;
|
||||
final minutes = (remainingSeconds % 3600) ~/ 60;
|
||||
final seconds = remainingSeconds % 60;
|
||||
return '${hours.toString().padLeft(2, '0')}:'
|
||||
'${minutes.toString().padLeft(2, '0')}:'
|
||||
'${seconds.toString().padLeft(2, '0')}';
|
||||
}
|
||||
|
||||
/// 格式化进度百分比
|
||||
String get formattedProgress {
|
||||
return '${(progress * 100).toStringAsFixed(0)}%';
|
||||
}
|
||||
}
|
||||
|
||||
/// 运行状态 Notifier
|
||||
class RunStateNotifier extends StateNotifier<RunState> {
|
||||
final MockRunner _runner;
|
||||
final ProgramService _programService;
|
||||
|
||||
RunStateNotifier(this._runner, this._programService) : super(const RunState());
|
||||
|
||||
/// 开始运行程序
|
||||
Future<void> start(Program program) async {
|
||||
// 获取程序步骤(这里使用模拟数据,实际应从数据库读取)
|
||||
final steps = await _loadSteps(program.id!);
|
||||
|
||||
if (steps.isEmpty) {
|
||||
state = state.copyWith(status: RunStatus.error);
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
status: RunStatus.running,
|
||||
currentProgram: program,
|
||||
steps: steps,
|
||||
currentStepIndex: 0,
|
||||
progress: 0,
|
||||
);
|
||||
|
||||
_runner.start(
|
||||
program,
|
||||
steps,
|
||||
(stepIndex, remaining, progress, well) {
|
||||
state = state.copyWith(
|
||||
currentStepIndex: stepIndex,
|
||||
remainingSeconds: remaining,
|
||||
progress: progress,
|
||||
currentWell: well,
|
||||
);
|
||||
},
|
||||
() {
|
||||
state = state.copyWith(
|
||||
status: RunStatus.completed,
|
||||
progress: 1,
|
||||
clearWell: true,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 暂停运行
|
||||
void pause() {
|
||||
if (state.status == RunStatus.running) {
|
||||
_runner.pause();
|
||||
state = state.copyWith(status: RunStatus.paused);
|
||||
}
|
||||
}
|
||||
|
||||
/// 继续运行
|
||||
void resume() {
|
||||
if (state.status == RunStatus.paused) {
|
||||
_runner.resume();
|
||||
state = state.copyWith(status: RunStatus.running);
|
||||
}
|
||||
}
|
||||
|
||||
/// 停止运行
|
||||
void stop() {
|
||||
_runner.stop();
|
||||
state = const RunState(status: RunStatus.idle);
|
||||
}
|
||||
|
||||
/// 重置状态
|
||||
void reset() {
|
||||
stop();
|
||||
}
|
||||
|
||||
/// 加载程序步骤(从数据库读取)
|
||||
Future<List<Step>> _loadSteps(int programId) async {
|
||||
return await _programService.getStepsByProgramId(programId);
|
||||
}
|
||||
}
|
||||
|
||||
/// MockRunner Provider
|
||||
final mockRunnerProvider = Provider<MockRunner>((ref) {
|
||||
return MockRunner();
|
||||
});
|
||||
|
||||
/// ProgramService Provider
|
||||
final programServiceProvider = Provider<ProgramService>((ref) {
|
||||
return ProgramService.instance;
|
||||
});
|
||||
|
||||
/// 运行状态 Provider
|
||||
final runStateProvider =
|
||||
StateNotifierProvider<RunStateNotifier, RunState>((ref) {
|
||||
final runner = ref.watch(mockRunnerProvider);
|
||||
final programService = ref.watch(programServiceProvider);
|
||||
return RunStateNotifier(runner, programService);
|
||||
});
|
||||
|
||||
/// 是否正在运行 Provider
|
||||
final isRunningProvider = Provider<bool>((ref) {
|
||||
final status = ref.watch(runStateProvider).status;
|
||||
return status == RunStatus.running;
|
||||
});
|
||||
|
||||
/// 是否已暂停 Provider
|
||||
final isPausedProvider = Provider<bool>((ref) {
|
||||
final status = ref.watch(runStateProvider).status;
|
||||
return status == RunStatus.paused;
|
||||
});
|
||||
Reference in New Issue
Block a user