import 'package:flutter/material.dart'; import '../../../core/localization/app_localizations.dart'; import '../../../core/theme/app_theme.dart'; import '../../../shared/widgets/common_button.dart'; import '../../programs/models/step.dart' as models; /// 步骤列表组件 class StepList extends StatefulWidget { final int programId; final List steps; final int? selectedStepId; final void Function(int?) onStepSelected; final void Function() onAddStep; final void Function(int oldIndex, int newIndex)? onReorder; final void Function(List stepIds)? onDeleteSteps; const StepList({ super.key, required this.programId, required this.steps, this.selectedStepId, required this.onStepSelected, required this.onAddStep, this.onReorder, this.onDeleteSteps, }); @override State createState() => _StepListState(); } class _StepListState extends State { final Set _selectedIds = {}; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); final allSelected = _selectedIds.length == widget.steps.length && widget.steps.isNotEmpty; return Container( color: Colors.white, child: Column( children: [ // 标题 Container( height: 50, padding: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: AppTheme.primaryColor.withValues(alpha: 0.1), ), child: Row( children: [ Icon(Icons.list, color: AppTheme.primaryColor, size: 20), const SizedBox(width: 12), Text( l10n?.stepList ?? '步骤列表', style: TextStyle( color: AppTheme.primaryColor, fontWeight: FontWeight.w600, ), ), const Spacer(), Text( l10n?.stepsCountLabel(widget.steps.length) ?? '${widget.steps.length} 步', style: TextStyle( color: AppTheme.textSecondary, fontSize: 12, ), ), ], ), ), // 表头 Container( height: 40, padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( border: Border( bottom: BorderSide(color: AppTheme.idleColor.withValues(alpha: 0.2)), ), ), child: Row( children: [ SizedBox( width: 40, child: Checkbox( value: allSelected, onChanged: (value) { setState(() { if (value == true) { _selectedIds.clear(); _selectedIds.addAll(widget.steps.map((s) => s.id!)); } else { _selectedIds.clear(); } }); }, ), ), SizedBox(width: 40, child: Text('#', style: TextStyle(fontSize: 12))), Expanded(child: Text(l10n?.stepName ?? '名称', style: TextStyle(fontSize: 12))), SizedBox(width: 60, child: Text(l10n?.position ?? '孔位', style: TextStyle(fontSize: 12))), ], ), ), // 步骤列表(可拖拽排序) Expanded( child: widget.steps.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.add_circle_outline, size: 48, color: AppTheme.idleColor), const SizedBox(height: 12), Text(l10n?.noSteps ?? '暂无步骤', style: TextStyle(color: AppTheme.textSecondary)), ], ), ) : ReorderableListView.builder( padding: const EdgeInsets.all(8), itemCount: widget.steps.length, onReorder: (oldIndex, newIndex) { if (widget.onReorder != null) { // 调整 newIndex(ReorderableListView 的特殊行为) if (newIndex > oldIndex) newIndex -= 1; widget.onReorder!(oldIndex, newIndex); } }, itemBuilder: (context, index) { final step = widget.steps[index]; final isSelected = widget.selectedStepId == step.id || _selectedIds.contains(step.id); return _buildStepItem(step, isSelected, index); }, ), ), // 底部操作栏 Container( height: 60, padding: const EdgeInsets.all(12), decoration: BoxDecoration( border: Border( top: BorderSide(color: AppTheme.idleColor.withValues(alpha: 0.2)), ), ), child: Row( children: [ // 添加按钮 CommonButton( text: l10n?.add ?? '添加', icon: Icons.add, type: ButtonType.primary, onPressed: widget.onAddStep, ), const SizedBox(width: 12), // 删除按钮 if (_selectedIds.isNotEmpty) CommonButton( text: l10n?.delete ?? '删除', icon: Icons.delete, type: ButtonType.danger, onPressed: () => _showDeleteConfirmDialog(context), ), ], ), ), ], ), ); } /// 步骤项 Widget _buildStepItem(models.Step step, bool isSelected, int index) { return Container( key: ValueKey(step.id), margin: const EdgeInsets.symmetric(vertical: 2), decoration: BoxDecoration( color: isSelected ? AppTheme.primaryLight.withValues(alpha: 0.3) : Colors.white, borderRadius: BorderRadius.circular(4), border: isSelected ? Border.all(color: AppTheme.primaryColor, width: 2) : null, ), child: ListTile( dense: true, leading: Checkbox( value: _selectedIds.contains(step.id), onChanged: (value) { setState(() { if (value == true) { _selectedIds.add(step.id!); } else { _selectedIds.remove(step.id!); } }); }, ), title: Row( children: [ Container( width: 30, alignment: Alignment.center, child: Text( '${step.stepNo}', style: TextStyle( color: AppTheme.primaryColor, fontWeight: FontWeight.bold, ), ), ), const SizedBox(width: 8), Expanded(child: Text(step.name)), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: AppTheme.primaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(4), ), child: Text( step.position, style: TextStyle( color: AppTheme.primaryColor, fontSize: 12, ), ), ), ], ), trailing: Icon(Icons.drag_handle, color: AppTheme.idleColor), onTap: () => widget.onStepSelected(step.id), ), ); } /// 显示删除确认对话框 void _showDeleteConfirmDialog(BuildContext context) { final l10n = AppLocalizations.of(context); showDialog( context: context, builder: (ctx) => AlertDialog( title: Text(l10n?.confirm ?? '确认'), content: Text( _selectedIds.length == 1 ? l10n?.deleteStepConfirmSingle ?? '确定要删除此步骤吗?' : l10n?.deleteStepConfirmMultiple(_selectedIds.length) ?? '确定要删除选中的 ${_selectedIds.length} 个步骤吗?', ), actions: [ TextButton( onPressed: () => Navigator.of(ctx).pop(), child: Text(l10n?.cancel ?? '取消'), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: AppTheme.errorColor, foregroundColor: Colors.white, ), onPressed: () { Navigator.of(ctx).pop(); if (widget.onDeleteSteps != null) { widget.onDeleteSteps!(_selectedIds.toList()); } setState(() { _selectedIds.clear(); }); }, child: Text(l10n?.confirm ?? '确认'), ), ], ), ); } }