chore(project): 初始化项目基础配置文件
- 添加 CodeGraph、Android 和通用 gitignore 配置 - 创建项目元数据文件跟踪 Flutter 项目属性 - 添加 Codex AI 指导文档 AGENTS.md 说明项目架构 - 配置代码分析选项 analysis_options.yaml - 设置 Android 应用清单权限和 Kiosk 模式配置 - 实现中英文国际化支持 AppLocalizations - 配置 GoRouter 应用路由导航 - 创建明亮工业控制风格的主题配置 AppTheme
This commit is contained in:
242
lib/features/home/widgets/run_status_monitor.dart
Normal file
242
lib/features/home/widgets/run_status_monitor.dart
Normal file
@@ -0,0 +1,242 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../../core/localization/app_localizations.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../device/providers/run_state_provider.dart';
|
||||
|
||||
/// 运行状态监控面板 - 暗色工业风格
|
||||
/// 显示当前孔位、步骤、倒计时、进度条、参数详情
|
||||
class RunStatusMonitor extends ConsumerWidget {
|
||||
const RunStatusMonitor({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final runState = ref.watch(runStateProvider);
|
||||
|
||||
if (runState.status == RunStatus.idle) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.cardBg,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppTheme.borderSubtle, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 标题 + 程序名
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
l10n?.runningMonitor ?? '运行状态监控',
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textHeading,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
runState.currentProgram?.name ?? '',
|
||||
style: const TextStyle(
|
||||
color: AppTheme.accentPrimary,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 14),
|
||||
|
||||
// 进度信息横排 (孔位 / 步骤 / 剩余时间)
|
||||
Row(
|
||||
children: [
|
||||
// 当前孔位
|
||||
_buildInfoBlock(
|
||||
label: l10n?.currentHole ?? '当前孔位',
|
||||
value: runState.currentWell ?? '--',
|
||||
valueColor: AppTheme.textHeading,
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
// 当前步骤
|
||||
_buildInfoBlock(
|
||||
label: l10n?.currentStep ?? '当前步骤',
|
||||
value: '${l10n?.stepNo ?? '步骤'} ${runState.currentStepIndex + 1}',
|
||||
subValue: runState.currentStep?.name ?? '--',
|
||||
valueColor: AppTheme.accentInfo,
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
// 剩余时间
|
||||
_buildInfoBlock(
|
||||
label: l10n?.remainingTime ?? '剩余时间',
|
||||
value: runState.formattedRemainingTime,
|
||||
valueColor: AppTheme.textHeading,
|
||||
valueSize: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 14),
|
||||
|
||||
// 总进度条
|
||||
_buildProgressBar(l10n, runState),
|
||||
|
||||
const SizedBox(height: 14),
|
||||
|
||||
// 步骤参数
|
||||
if (runState.currentStep != null)
|
||||
_buildStepParams(l10n, runState.currentStep!),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 信息块
|
||||
Widget _buildInfoBlock({
|
||||
required String label,
|
||||
required String value,
|
||||
String? subValue,
|
||||
Color valueColor = AppTheme.textHeading,
|
||||
double valueSize = 16,
|
||||
}) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textTertiary,
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
color: valueColor,
|
||||
fontSize: valueSize,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'monospace',
|
||||
),
|
||||
),
|
||||
if (subValue != null) ...[
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
subValue,
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textSecondary,
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// 进度条
|
||||
Widget _buildProgressBar(AppLocalizations? l10n, RunState runState) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
l10n?.progress ?? '总进度',
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textTertiary,
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
runState.formattedProgress,
|
||||
style: const TextStyle(
|
||||
color: AppTheme.accentPrimary,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'monospace',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: LinearProgressIndicator(
|
||||
value: runState.progress,
|
||||
minHeight: 8,
|
||||
backgroundColor: const Color(0xFF1E293B),
|
||||
valueColor: AlwaysStoppedAnimation<Color>(AppTheme.accentPrimary),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// 步骤参数详情
|
||||
Widget _buildStepParams(AppLocalizations? l10n, dynamic step) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
l10n?.stepParams ?? '步骤参数',
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textTertiary,
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
if (step.mixTime > 0)
|
||||
_buildParamRow(
|
||||
l10n?.speed ?? '转速',
|
||||
'${step.mixSpeed}',
|
||||
),
|
||||
if (step.magnetTime > 0)
|
||||
_buildParamRow(
|
||||
l10n?.temperature ?? '温度',
|
||||
'65.0 °C',
|
||||
),
|
||||
_buildParamRow(
|
||||
l10n?.duration ?? '持续时间',
|
||||
step.mixTime > 0 ? '${step.mixTime} min' : '--',
|
||||
),
|
||||
_buildParamRow(
|
||||
l10n?.sampleVolume ?? '样品体积',
|
||||
'10.0 mL',
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// 参数行
|
||||
Widget _buildParamRow(String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textTertiary,
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textPrimary,
|
||||
fontSize: 11,
|
||||
fontFamily: 'monospace',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user