import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_cupertino_datetime_picker/flutter_cupertino_datetime_picker.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:odf/bean/odf_details_bean.dart'; import 'package:odf/network/NetworkConfig.dart'; import 'package:odf/tools/machine/machine_model.dart'; import '../bean/history_fault_bean.dart'; import '../common/func.dart'; import 'add_note_dialog.dart'; class ModifyInfoDialog extends StatefulWidget { final Function onTap; final String id; const ModifyInfoDialog({super.key, required this.onTap, required this.id}); @override State createState() => _ModifyInfoDialogState(); } class DataItem { String time; String content; DataItem({required this.time, required this.content}); } class _ModifyInfoDialogState extends State { late StreamSubscription subscription; final MachineModel _viewmodel = MachineModel(); late OdfDetailsBean odfDetailsBean; final TextEditingController _remarksController = TextEditingController(); final TextEditingController _opticalAttenuationController = TextEditingController(); final TextEditingController _historyRemarksController = TextEditingController(); final TextEditingController _opticalCableOffRemarksController = TextEditingController(); bool isConnect = false; bool isLoad = false; // 用列表存储所有输入框的值,通过索引区分不同输入框 late List _controllers; final List _items = []; /// 添加新视图 void _addItem() { setState(() { _items.add(HistoryFaultBean("", "")); _controllers.add(TextEditingController(text: "")); }); } /// 移除指定视图 void _removeItem(int index) { setState(() { _items.removeAt(index); _controllers.removeAt(index); }); } ///输入框拼接内容 void appendTextWithNewline(String newContent) { // 获取当前文本,拼接新内容和换行符 String currentText = _remarksController.text; // 如果当前文本不为空,先加一个换行,再添加新内容 String updatedText = currentText.isEmpty ? newContent : '$currentText\n$newContent'; _remarksController.text = updatedText; // 让光标移动到末尾 _remarksController.selection = TextSelection.fromPosition(TextPosition(offset: _remarksController.text.length)); } @override void initState() { // TODO: implement initState super.initState(); subscription = _viewmodel.streamController.stream.listen((event) { String code = event['code']; if (code.isNotEmpty) { switch (code) { case "odfDetails": isLoad = true; odfDetailsBean = event['data']; _remarksController.text = '${odfDetailsBean.remarks}'; _opticalAttenuationController.text = '${odfDetailsBean.opticalAttenuation}'; _historyRemarksController.text = '${odfDetailsBean.historyRemarks}'; _opticalCableOffRemarksController.text = '${odfDetailsBean.opticalCableOffRemarks}'; if (odfDetailsBean.status == 0) { isConnect = false; } else { isConnect = true; } if (odfDetailsBean.historyFault!.isNotEmpty) { for (var data in odfDetailsBean.historyFault!) { _items.add(data); } } _controllers = List.generate( _items.length, // 可以根据数据项的初始值设置控制器的默认文本 (index) => TextEditingController(text: odfDetailsBean.historyFault![index].faultReason), ); break; case "save": //保存信息 EasyLoading.dismiss(); widget.onTap(); Navigator.pop(context); break; } } EasyLoading.dismiss(); setState(() {}); }); EasyLoading.show(status: "loading..."); _viewmodel.odfDetails(widget.id); } @override void dispose() { // TODO: implement dispose subscription.cancel(); _remarksController.dispose(); _opticalAttenuationController.dispose(); _historyRemarksController.dispose(); _opticalCableOffRemarksController.dispose(); for (var controller in _controllers) { controller.dispose(); } super.dispose(); } ///提交保存 Future saveData() async { ///获取历史故障原因所有值. for (int i = 0; i < _controllers.length; i++) { // print('输入框的值: ${_controllers[i].text}'); _items[i].faultReason = _controllers[i].text; } if (_items.isNotEmpty) { bool allFaultTimeEmpty = _items.every((bean) { // 检查faultTime是否不为null且不是空字符串(去除空格后) return bean.faultTime != null && bean.faultTime!.trim().isNotEmpty; }); if (!allFaultTimeEmpty) { EasyLoading.showToast("请选择障碍发生时间!"); return; } } EasyLoading.show(status: "loading..."); _viewmodel.save(widget.id, isConnect ? 1 : 0, _remarksController.text, _opticalAttenuationController.text, _historyRemarksController.text, _items, _opticalCableOffRemarksController.text); } @override Widget build(BuildContext context) { final bottomInset = MediaQuery.of(context).viewInsets.bottom; return Material( type: MaterialType.transparency, //透明类型 color: const Color(0x1A000000), child: Center( child: ClipRRect( borderRadius: BorderRadius.circular(10), child: SingleChildScrollView( scrollDirection: Axis.vertical, child: Container( width: 307, color: Colors.white, padding: EdgeInsets.only(left: 5, right: 5, top: 5, bottom: bottomInset), child: isLoad ? Column( mainAxisSize: MainAxisSize.min, children: [ Container( margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), child: Row( // crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Text( "位置:${odfDetailsBean.frameName}${odfDetailsBean.name}", style: const TextStyle(fontSize: 12), ), GestureDetector( onTap: () { if (NetworkConfig.isPermission) { FunctionUtil.popDialog2( context, AddNoteDialog( onTap: (value1, value2, value3, value4) { // print("$value1-$value2-$value3-$value4"); // appendTextWithNewline("$value1 $value2 $value3 $value4"); _remarksController.text = "$value1 $value2 $value3 $value4"; setState(() {}); }, ), ); } }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.only(left: 10), width: 60, height: 20, decoration: const BoxDecoration( color: Colors.lightBlue, borderRadius: BorderRadius.all(Radius.circular(5)), ), child: const Text( "添加备注", style: TextStyle(fontSize: 11, color: Colors.white), ), ), ), ], ), Row( children: [ const Text( "当前状态:", style: TextStyle(fontSize: 12), ), Container( width: 12, height: 12, margin: const EdgeInsets.only(left: 10, right: 5), decoration: BoxDecoration( color: odfDetailsBean.status == 0 ? Colors.red : Colors.green, shape: BoxShape.circle, ), ), Text( odfDetailsBean.status == 0 ? "已断开" : "已连接", style: const TextStyle(fontSize: 12), ) ], ), ], ), ), Container( width: double.infinity, margin: const EdgeInsets.only(left: 10, right: 10), padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), decoration: const BoxDecoration(color: Color(0xFFEBEBEB), borderRadius: BorderRadius.all(Radius.circular(7))), child: TextField( maxLines: 5, cursorColor: const Color(0xFF1A73EC), controller: _remarksController, enabled: NetworkConfig.isPermission, decoration: const InputDecoration( contentPadding: EdgeInsets.zero, hintText: '请输入备注说明', border: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, hintStyle: TextStyle(color: Color(0xFF999999), fontSize: 12), ), style: const TextStyle(fontSize: 12), ), ), Container( alignment: Alignment.centerLeft, margin: const EdgeInsets.all(10), child: const Text( "光衰信息", style: TextStyle(fontSize: 12), ), ), Container( margin: const EdgeInsets.only(left: 10, right: 10), padding: const EdgeInsets.symmetric(horizontal: 5), alignment: Alignment.center, height: 35, decoration: const BoxDecoration(color: Color(0xFFEBEBEB), borderRadius: BorderRadius.all(Radius.circular(7))), child: TextField( cursorColor: const Color(0xFF1A73EC), controller: _opticalAttenuationController, enabled: NetworkConfig.isPermission, decoration: const InputDecoration( isDense: true, contentPadding: EdgeInsets.zero, hintText: '请输入光衰信息', border: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, hintStyle: TextStyle(color: Color(0xFF999999), fontSize: 12), ), style: const TextStyle(fontSize: 12), ), ), Container( alignment: Alignment.centerLeft, margin: const EdgeInsets.all(10), child: const Text( "历史障碍发生原因及时间", style: TextStyle(fontSize: 12), ), ), ListView.builder( shrinkWrap: true, itemCount: _items.length, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return _item(index, context, _items[index]); }), GestureDetector( onTap: () { if (NetworkConfig.isPermission) { _addItem(); } }, child: const Text( "添加新记录", style: TextStyle(fontSize: 12, color: Colors.lightBlue), ), ), // Container( // margin: EdgeInsets.only(left: 10, right: 10), // padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5), // decoration: BoxDecoration(color: Color(0xFFEBEBEB), borderRadius: BorderRadius.all(Radius.circular(10))), // child: TextField( // maxLines: 3, // cursorColor: Color(0xFF1A73EC), // controller: _historyRemarksController, // enabled: NetworkConfig.isPermission, // decoration: InputDecoration( // contentPadding: EdgeInsets.zero, // hintText: '请输入历史障碍发生原因及时间', // border: InputBorder.none, // enabledBorder: InputBorder.none, // focusedBorder: InputBorder.none, // hintStyle: TextStyle(color: Color(0xFF999999), fontSize: 12), // ), // style: TextStyle(fontSize: 12), // ), // ), Container( alignment: Alignment.centerLeft, margin: const EdgeInsets.all(10), child: const Text( "光缆段信息", style: TextStyle(fontSize: 12), ), ), Container( margin: const EdgeInsets.only(left: 10, right: 10), padding: const EdgeInsets.symmetric(horizontal: 5), height: 35, alignment: Alignment.center, decoration: const BoxDecoration(color: Color(0xFFEBEBEB), borderRadius: BorderRadius.all(Radius.circular(10))), child: TextField( maxLines: 1, cursorColor: const Color(0xFF1A73EC), controller: _opticalCableOffRemarksController, enabled: NetworkConfig.isPermission, decoration: const InputDecoration( isDense: true, contentPadding: EdgeInsets.zero, hintText: '请输入光缆段信息', border: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, hintStyle: TextStyle(color: Color(0xFF999999), fontSize: 12), ), style: const TextStyle(fontSize: 12), ), ), NetworkConfig.isPermission ? Container( alignment: Alignment.centerLeft, margin: const EdgeInsets.all(10), child: const Text( "改变状态", style: TextStyle(fontSize: 12), ), ) : Container(), NetworkConfig.isPermission ? Container( margin: const EdgeInsets.symmetric(horizontal: 10), child: Row( children: [ Expanded( child: GestureDetector( onTap: () { isConnect = true; setState(() {}); }, child: Container( height: 40, margin: const EdgeInsets.only(right: 5), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(7)), color: isConnect ? const Color(0xFF13ED13) : const Color(0xFFEBEBEB), ), child: Text( "连接", style: TextStyle(fontSize: 12, color: isConnect ? Colors.white : Colors.black), ), ), )), Expanded( child: GestureDetector( onTap: () { isConnect = false; setState(() {}); }, child: Container( height: 40, margin: const EdgeInsets.only(left: 5), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(7)), color: !isConnect ? const Color(0xFFFF0000) : const Color(0xFFEBEBEB), ), child: Text( "断开", style: TextStyle(fontSize: 12, color: !isConnect ? Colors.white : Colors.black), ), ), )) ], ), ) : Container(), NetworkConfig.isPermission ? Container( margin: const EdgeInsets.symmetric(vertical: 5), child: const Text( "断开后只清空备注说明,其他内容不影响", style: TextStyle(fontSize: 10, color: Color(0xFF999999)), ), ) : Container(), NetworkConfig.isPermission ? Row( children: [ Expanded( flex: 1, child: GestureDetector( onTap: () { Navigator.pop(context); }, child: Container( height: 32, alignment: Alignment.center, margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), decoration: const BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.all(Radius.circular(6)), ), child: const Text( "取消", style: TextStyle(fontSize: 14, color: Colors.white), ), ), ), ), Expanded( flex: 2, child: GestureDetector( onTap: () { saveData(); }, child: Container( height: 32, alignment: Alignment.center, margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), decoration: const BoxDecoration( color: Color(0xFF1A73EC), borderRadius: BorderRadius.all(Radius.circular(6)), ), child: const Text( "提交", style: TextStyle(fontSize: 14, color: Colors.white), ), ), ), ), ], ) : Container(), !NetworkConfig.isPermission ? GestureDetector( onTap: () { Navigator.pop(context); }, child: Container( height: 32, alignment: Alignment.center, margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), decoration: const BoxDecoration( color: Color(0xFF1A73EC), borderRadius: BorderRadius.all(Radius.circular(6)), ), child: const Text( "关闭", style: TextStyle(fontSize: 14, color: Colors.white), ), ), ) : Container(), ], ) : GestureDetector( onTap: () { Navigator.pop(context); }, child: Container( height: 32, alignment: Alignment.center, margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), decoration: const BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.all(Radius.circular(6)), ), child: const Text( "取消", style: TextStyle(fontSize: 14, color: Colors.white), ), ), ), ), ), ), ), ); } _item(index, context, dataItem) { return Container( margin: const EdgeInsets.only(left: 10, right: 10, bottom: 10), child: Column( children: [ SizedBox( height: 35, child: Row( children: [ Expanded( flex: 5, child: GestureDetector( onTap: () { if (!NetworkConfig.isPermission) { return; } DatePicker.showDatePicker( context, minDateTime: DateTime(1980), maxDateTime: DateTime(2080), initialDateTime: DateTime.now(), dateFormat: "yyyy-MM-dd HH:mm:ss", pickerTheme: const DateTimePickerTheme( backgroundColor: Colors.white, cancelTextStyle: TextStyle( color: Colors.grey, fontSize: 16, ), confirmTextStyle: TextStyle( color: Colors.lightBlueAccent, fontSize: 16, ), pickerHeight: 220, ), // timeFormat: "HH:mm", locale: DateTimePickerLocale.zh_cn, onConfirm: (dateTime, List data) { setState(() { _items[index].faultTime = "${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')} " "${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}"; }); }, ); }, child: Container( height: 35, padding: const EdgeInsets.symmetric(horizontal: 10), decoration: const BoxDecoration(color: Color(0xFFEBEBEB), borderRadius: BorderRadius.all(Radius.circular(5))), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "时间:${dataItem.faultTime}", style: const TextStyle(fontSize: 12), ), const Icon( Icons.arrow_drop_down, color: Colors.blue, size: 20, ), ], ), ), ), ), Expanded( flex: 1, child: GestureDetector( onTap: () { if (NetworkConfig.isPermission) { _removeItem(index); } }, child: Container( height: 30, decoration: BoxDecoration( border: Border.all(color: Colors.red, width: 1, style: BorderStyle.solid), borderRadius: const BorderRadius.all(Radius.circular(5))), margin: const EdgeInsets.only(left: 10), alignment: Alignment.center, child: const Text( "-", style: TextStyle( fontSize: 25, color: Colors.red, ), ), ), )) ], ), ), Container( margin: const EdgeInsets.only(top: 10), padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), decoration: const BoxDecoration(color: Color(0xFFEBEBEB), borderRadius: BorderRadius.all(Radius.circular(10))), child: TextField( maxLines: 3, cursorColor: const Color(0xFF1A73EC), controller: _controllers[index], enabled: NetworkConfig.isPermission, decoration: const InputDecoration( contentPadding: EdgeInsets.zero, hintText: '请输入历史障碍发生原因及时间', border: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, hintStyle: TextStyle(color: Color(0xFF999999), fontSize: 12), ), style: const TextStyle(fontSize: 12), ), ), ], ), ); } }