import 'package:flutter/material.dart'; import '../../../core/localization/app_localizations.dart'; import '../../../core/theme/app_theme.dart'; import '../../../shared/utils/constants.dart'; import '../../../shared/widgets/common_button.dart'; import '../../programs/models/step.dart' as models; /// 步骤参数表单 class StepForm extends StatefulWidget { final int programId; final models.Step? step; final bool isNew; final void Function(models.Step) onSave; const StepForm({ super.key, required this.programId, this.step, this.isNew = false, required this.onSave, }); @override State createState() => _StepFormState(); } class _StepFormState extends State { final _formKey = GlobalKey(); late TextEditingController _nameController; late TextEditingController _mixTimeController; late TextEditingController _magnetTimeController; late TextEditingController _volumeController; late TextEditingController _blowTimeController; String _position = 'A1'; String _mixSpeed = '中速'; String _blowSpeed = '中速'; int _needleSpeed = 5; @override void initState() { super.initState(); _nameController = TextEditingController(text: widget.step?.name ?? ''); _mixTimeController = TextEditingController(text: '${widget.step?.mixTime ?? 0}'); _magnetTimeController = TextEditingController(text: '${widget.step?.magnetTime ?? 0}'); _volumeController = TextEditingController(text: '${widget.step?.volume ?? 0}'); _blowTimeController = TextEditingController(text: '${widget.step?.blowTime ?? 0}'); _position = widget.step?.position ?? 'A1'; _mixSpeed = widget.step?.mixSpeed ?? '中速'; _blowSpeed = widget.step?.blowSpeed ?? '中速'; _needleSpeed = widget.step?.needleSpeed ?? 5; } @override void dispose() { _nameController.dispose(); _mixTimeController.dispose(); _magnetTimeController.dispose(); _volumeController.dispose(); _blowTimeController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); return Padding( padding: const EdgeInsets.all(24), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 标题 Text( widget.isNew ? '添加步骤' : '编辑步骤', style: TextStyle( color: AppTheme.textPrimary, fontSize: 18, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 24), // 步骤名称 TextFormField( controller: _nameController, decoration: InputDecoration( labelText: l10n?.stepName ?? '步骤名称', hintText: '例如: 混合、吸磁、吹气', border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), validator: (value) { if (value == null || value.trim().isEmpty) { return '请输入步骤名称'; } return null; }, ), const SizedBox(height: 16), // 孔位选择 Row( children: [ Text(l10n?.position ?? '孔位', style: TextStyle(color: AppTheme.textPrimary)), const SizedBox(width: 16), Expanded( child: DropdownButtonFormField( value: _position, decoration: InputDecoration( border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), items: Constants.positions.map((p) => DropdownMenuItem(value: p, child: Text(p))).toList(), onChanged: (value) { if (value != null) setState(() => _position = value); }, ), ), ], ), const SizedBox(height: 16), // 时间参数行 Row( children: [ Expanded( child: TextFormField( controller: _mixTimeController, decoration: InputDecoration( labelText: '${l10n?.mixTime ?? '混合时间'} (${Constants.timeUnitSeconds})', border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), keyboardType: TextInputType.number, ), ), const SizedBox(width: 16), Expanded( child: TextFormField( controller: _magnetTimeController, decoration: InputDecoration( labelText: '${l10n?.magnetTime ?? '吸磁时间'} (${Constants.timeUnitSeconds})', border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), keyboardType: TextInputType.number, ), ), ], ), const SizedBox(height: 16), // 容积和吹气时间 Row( children: [ Expanded( child: TextFormField( controller: _volumeController, decoration: InputDecoration( labelText: '${l10n?.volume ?? '容积'} (${Constants.volumeUnit})', border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), keyboardType: TextInputType.number, ), ), const SizedBox(width: 16), Expanded( child: TextFormField( controller: _blowTimeController, decoration: InputDecoration( labelText: '${l10n?.blowTime ?? '吹气时间'} (${Constants.timeUnitMinutes})', border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), keyboardType: TextInputType.number, ), ), ], ), const SizedBox(height: 16), // 速度选择 Row( children: [ Expanded( child: DropdownButtonFormField( value: _mixSpeed, decoration: InputDecoration( labelText: l10n?.mixSpeed ?? '混合速度', border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), items: Constants.speedOptions.map((s) => DropdownMenuItem(value: s, child: Text(s))).toList(), onChanged: (value) { if (value != null) setState(() => _mixSpeed = value); }, ), ), const SizedBox(width: 16), Expanded( child: DropdownButtonFormField( value: _blowSpeed, decoration: InputDecoration( labelText: l10n?.blowSpeed ?? '吹气速度', border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), items: Constants.speedOptions.map((s) => DropdownMenuItem(value: s, child: Text(s))).toList(), onChanged: (value) { if (value != null) setState(() => _blowSpeed = value); }, ), ), ], ), const SizedBox(height: 16), // 下针速度滑块 Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('${l10n?.needleSpeed ?? '下针速度'}: $_needleSpeed 档', style: TextStyle(color: AppTheme.textPrimary)), Slider( value: _needleSpeed.toDouble(), min: 1, max: 10, divisions: 9, activeColor: AppTheme.primaryColor, onChanged: (value) { setState(() => _needleSpeed = value.round()); }, ), ], ), const SizedBox(height: 24), // 保存按钮 CommonButton( text: l10n?.save ?? '保存', icon: Icons.save, type: ButtonType.primary, onPressed: _saveStep, ), ], ), ), ); } /// 保存步骤 void _saveStep() { if (!_formKey.currentState!.validate()) return; final step = models.Step( id: widget.step?.id, programId: widget.programId, stepNo: widget.step?.stepNo ?? 1, position: _position, name: _nameController.text.trim(), mixTime: int.tryParse(_mixTimeController.text) ?? 0, magnetTime: int.tryParse(_magnetTimeController.text) ?? 0, volume: int.tryParse(_volumeController.text) ?? 0, mixSpeed: _mixSpeed, blowSpeed: _blowSpeed, blowTime: int.tryParse(_blowTimeController.text) ?? 0, needleSpeed: _needleSpeed, ); widget.onSave(step); } }