import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appFontsize.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/component/img/img_default_widget.dart'; import 'package:vbvs_app/component/img/img_preview_widget.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/mh_controller/apply_repair_controller.dart'; import 'package:vbvs_app/controller/mh_controller/repair_list_controller.dart'; import 'package:vbvs_app/controller/repair/repair_controller.dart'; import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/pages/mh_page/applyRepair/apply_repair_success.dart'; class ApplyRepairPage extends GetView { final scaffoldKey = GlobalKey(); BoxConstraints? bodysize; RepairListController repairListController = Get.find(); ApplyRepairController applyRepairController = Get.find(); ApplyRepairPage() { controller.attr.value.listenlists.clear(); controller.getDeviceList(); controller.model.device_type = null; controller.model.select_device = ""; controller.model.device_category = ""; controller.model.device_name = ""; controller.model.device_id = ""; } final List repairItemKeys = []; final GlobalKey contactKey = GlobalKey(); final GlobalKey phoneKey = GlobalKey(); @override Widget build(BuildContext context) { var tmpcontroller = FormFieldController(controller.model.select_device); // List deviceTypeNames = ['床', '床垫']; // List deviceTypeIds = ['床', '床垫']; return LayoutBuilder(builder: (context, cc) { bodysize = cc; return GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/new_background.png'), // 本地图片 fit: BoxFit.fill, // 填满整个 Container ), ), child: Scaffold( resizeToAvoidBottomInset: true, // 自动调整页面避免被键盘遮挡 backgroundColor: Colors.transparent, appBar: AppBar( backgroundColor: Colors.transparent, iconTheme: const IconThemeData(color: Colors.white), automaticallyImplyLeading: false, titleSpacing: 0, title: SizedBox( width: double.infinity, height: 180.rpx, child: Stack( alignment: Alignment.center, children: [ // 中间居中的标题 Text( '申请报修', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 30.rpx, ), ), // 左侧图标 Positioned( left: 0.rpx, child: returnIconButtomNew, ), ], ), ), centerTitle: false, ), body: Container( width: bodysize!.maxWidth, height: bodysize!.maxHeight * 1, child: Column( mainAxisSize: MainAxisSize.max, children: [ // TitleComponentWidget( // titleName: '申请保修', // ), Flexible( child: Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 0, 30.rpx, 30.rpx), child: Container( width: bodysize!.maxWidth, height: 1000, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.max, children: [ Padding( padding: EdgeInsetsDirectional.fromSTEB( 0, 27.rpx, 0, 0), child: Container( width: MediaQuery.sizeOf(context).width, height: MediaQuery.sizeOf(context).height * 0.247, constraints: BoxConstraints( minHeight: 500.rpx, maxHeight: 500.rpx, ), decoration: BoxDecoration( color: const Color(0XFF003058), borderRadius: BorderRadius.circular(16.rpx), ), child: Padding( padding: EdgeInsetsDirectional.fromSTEB( 25.rpx, 27.rpx, 34.rpx, 0), child: Container( width: 100, height: 100, child: Container( width: 100, height: 100, child: Column( mainAxisSize: MainAxisSize.max, children: [ Align( alignment: const AlignmentDirectional( 0, 0), child: Container( width: MediaQuery.sizeOf(context) .width, height: 44, child: Align( alignment: const AlignmentDirectional( 0, -1), child: Text( '选择需要报修的设备', style: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, fontSize: AppFontsize .title_size, color: Colors .white // 加粗文字 ), ), ), ), ), Expanded( child: Column( mainAxisSize: MainAxisSize.max, children: [ Flexible( child: Container( width: MediaQuery.sizeOf( context) .width, height: 10, constraints: BoxConstraints( minHeight: 60.rpx, ), child: Row( mainAxisSize: MainAxisSize.max, children: [ Container( width: 105.rpx, height: MediaQuery .sizeOf( context) .height * 0.038, constraints: const BoxConstraints( minWidth: 60, ), child: Align( alignment: const AlignmentDirectional( -1, 0), child: Text( '已绑设备', style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26 .rpx, letterSpacing: 0, color: Colors .white), ), ), ), Expanded( child: Container( width: 300, // 可以根据需要调整宽度 height: 56, // 可以根据需要调整高度 decoration: BoxDecoration( borderRadius: BorderRadius.circular( 8), color: Colors .white, ), // child: Obx( // () { // List> deviceOptions = controller // .model // .device_list! // .map((device) => { // 'mac': device['mac'].toString(), // 提取设备 Mac // 'name': device['name'].toString(), // 提取设备名称 // 'type': device['device_type'].toString() // }) // .toList(); // // 提取 optionsLabel 和 optionsValue // // List deviceNames = deviceOptions // // .map((device) => device['name']!) // 用于显示的名称列表 // // .toList(); // List // deviceNames = // controller.model.device_list!.map((device) { // final mac = // device['mac']?.toString() ?? ''; // final name = // device['name']?.toString() ?? ''; // final type = // getDeviceTypeName(int.tryParse('${device['device_type']}')); // return name.isNotEmpty // ? '$name-MAC$mac' // : '$type-MAC$mac'; // }).toList(); // List deviceMacs = deviceOptions // .map((device) => device['mac']!) // 用于匹配的 ID 列表 // .toList(); // return FlutterFlowDropDown< // String>( // controller: // tmpcontroller, // fillColor: // Colors.white, // 控件区域背景色 // options: // deviceMacs, // 下拉菜单选项为设备的 ID // optionLabels: // deviceNames, // 下拉菜单显示的内容为设备名称 // onChanged: // (val) { // // var selectedDevice = controller.model.device_list!.firstWhere((device) => device['mac'].toString() == val); // // controller.model.select_device = val; // // controller.model.device_type = selectedDevice['device_type']; // // // controller.model.device_category = selectedDevice['deviceSeries']['name'] ?? '未知型号'; // 获取设备型号 // // controller.model.device_category = '未知型号'; // // controller.model.device_id = selectedDevice['mac'] ?? '未知设备mac'; // 获取设备ID // // controller.model.device_name = selectedDevice['name'] ?? '未知设备'; // 获取设备名称 // // controller.updateAll(); // var selectedDevice = controller.model.device_list!.firstWhere((device) => device['mac'].toString() == val); // final mac = selectedDevice['mac']?.toString() ?? '未知MAC'; // final name = selectedDevice['name']?.toString(); // final type = int.tryParse('${selectedDevice['device_type']}'); // final typeName = getDeviceTypeName(type); // controller.model.select_device = mac; // controller.model.device_type = selectedDevice['device_type']; // controller.model.device_category = '未知型号'; // 后续可替换成设备系列 // // 如果 name 不为空则用 name,否则用 typeName-mac // controller.model.device_name = (name != null && name.isNotEmpty) ? name : '$typeName-MAC$mac'; // controller.model.device_id = mac; // controller.updateAll(); // }, // width: // 300, // height: // 56, // searchHintTextStyle: // const TextStyle( // fontFamily: 'Readex Pro', // letterSpacing: 0, // ), // searchTextStyle: // const TextStyle( // fontFamily: 'Readex Pro', // letterSpacing: 0, // ), // textStyle: // TextStyle( // fontFamily: 'Readex Pro', // color: Colors.black, // fontSize: 26.rpx, // letterSpacing: 0, // ), // hintText: // '请选择绑定设备', // searchHintText: // '查找', // icon: // const Icon( // Icons.keyboard_arrow_down_rounded, // color: Colors.black, // size: 24, // ), // // fillColor: // // FlutterFlowTheme.of(context).secondaryBackground, // elevation: // 2, // borderColor: // Colors.white, // borderWidth: // 0, // borderRadius: // 8, // margin: const EdgeInsetsDirectional.fromSTEB( // 10, // 4, // 10, // 4), // hidesUnderline: // true, // isOverButton: // false, // isSearchable: // false, // isMultiSelect: // false, // ); // }) child: Obx(() { final isDeviceListEmpty = controller .model .device_list ?.isEmpty ?? true; List< Map> deviceOptions = controller .model .device_list! .map((device) => { 'mac': device['mac'].toString(), 'name': device['name'].toString(), 'type': device['device_type'].toString() }) .toList(); List deviceNames = controller .model .device_list! .map((device) { final mac = device['mac']?.toString() ?? ''; final name = device['name']?.toString() ?? ''; final type = getDeviceTypeName(int.tryParse('${device['device_type']}')); return name.isNotEmpty ? '$name-MAC$mac' : '$type-MAC$mac'; }).toList(); List deviceMacs = deviceOptions .map((device) => device['mac']!) .toList(); return AbsorbPointer( absorbing: isDeviceListEmpty, // 禁止点击 child: FlutterFlowDropDown< String>( controller: tmpcontroller, fillColor: isDeviceListEmpty ? Colors.grey[300]! : Colors.white, options: isDeviceListEmpty ? [] : deviceMacs, optionLabels: isDeviceListEmpty ? [] : deviceNames, onChanged: (val) { var selectedDevice = controller.model.device_list!.firstWhere((device) => device['mac'].toString() == val); final mac = selectedDevice['mac']?.toString() ?? '未知MAC'; final name = selectedDevice['name']?.toString(); final type = int.tryParse('${selectedDevice['device_type']}'); final typeName = getDeviceTypeName(type); controller.model.select_device = mac; controller.model.device_type = selectedDevice['device_type']; controller.model.device_category = '未知型号'; controller.model.device_name = (name != null && name.isNotEmpty) ? name : '$typeName-MAC$mac'; controller.model.device_id = mac; controller.updateAll(); }, width: 300, height: 56, textStyle: TextStyle( fontFamily: 'Readex Pro', color: isDeviceListEmpty ? Colors.grey : Colors.black, fontSize: 26.rpx, letterSpacing: 0, ), hintText: isDeviceListEmpty ? '暂无可选设备' : '请选择绑定设备', searchHintText: '查找', icon: Icon( Icons.keyboard_arrow_down_rounded, color: isDeviceListEmpty ? Colors.grey : Colors.black, size: 24, ), elevation: 2, borderColor: Colors.white, borderWidth: 0, borderRadius: 8, margin: const EdgeInsetsDirectional .fromSTEB( 10, 4, 10, 4), hidesUnderline: true, isOverButton: false, isSearchable: false, isMultiSelect: false, ), ); }))), ].divide(SizedBox( width: 26.rpx)), ), ), ), Flexible( child: Container( width: MediaQuery.sizeOf( context) .width, height: 10, constraints: BoxConstraints( minHeight: 60.rpx, ), child: Row( mainAxisSize: MainAxisSize.max, children: [ Container( width: 105.rpx, height: MediaQuery .sizeOf( context) .height * 0.038, constraints: const BoxConstraints( minWidth: 60, ), child: Align( alignment: const AlignmentDirectional( -1, 0), child: Text( '设备系列', style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26 .rpx, letterSpacing: 0, color: Colors .white), ), ), ), Expanded( child: Container( decoration: BoxDecoration( color: Colors .white, borderRadius: BorderRadius .circular( 8), ), width: double .infinity, child: Padding( padding: EdgeInsetsDirectional .fromSTEB( 35.rpx, 0, 35.rpx, 0), child: Row( mainAxisSize: MainAxisSize .max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Expanded( child: Container( child: Align( alignment: AlignmentDirectional(-1, 0), child: TextFormField( onChanged: (value) { controller.model.device_series = value; }, autofocus: false, obscureText: false, decoration: InputDecoration( contentPadding: EdgeInsets.all(0), isDense: true, labelStyle: TextStyle( fontFamily: 'Inter', fontSize: 26.rpx, letterSpacing: 0.0, ), hintStyle: TextStyle( fontFamily: 'Inter', fontSize: 26.rpx, letterSpacing: 0.0, color: themeController.currentColor.sc4, ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0x00000000), width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0x00000000), width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), errorBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), filled: false, fillColor: Colors.white, ), style: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, color: Colors.black, fontSize: 26.rpx, ), // cursorColor: // Colors.black, // validator: _model // .textControllerValidator // .asValidator(context), ), ), ), ), ], ), ), ), ), ].divide(SizedBox( width: 26.rpx)), ), ), ), // Flexible( // child: Container( // width: // MediaQuery.sizeOf( // context) // .width, // height: 10, // constraints: // BoxConstraints( // minHeight: 60.rpx, // ), // child: Row( // mainAxisSize: // MainAxisSize.max, // children: [ // Container( // width: 105.rpx, // height: MediaQuery // .sizeOf( // context) // .height * // 0.038, // constraints: // const BoxConstraints( // minWidth: 60, // ), // child: Align( // alignment: // const AlignmentDirectional( // -1, 0), // child: Text( // '产品型号', // style: TextStyle( // fontFamily: // 'Readex Pro', // fontSize: 26 // .rpx, // letterSpacing: // 0, // color: Colors // .white), // ), // ), // ), // // Expanded( // // child: Container( // // width: 100, // // height: 100, // // decoration: // // BoxDecoration( // // color: Colors // // .white, // // borderRadius: // // BorderRadius // // .circular(8), // // ), // // child: Padding( // // padding: EdgeInsets.only(left: 26.rpx), // // child: Align( // // alignment: Alignment.centerLeft, // // child: Obx(() => Text( // // controller.model.device_category ?? '', // // style: TextStyle(fontSize: 26.rpx, color: Colors.black), // // ))))), // // ), // Expanded( // child: Container( // child: Align( // alignment: // AlignmentDirectional( // -1, // 0), // child: // TextFormField( // onChanged: // (value) { // controller // .model // .device_category = value; // }, // autofocus: // false, // obscureText: // false, // decoration: // InputDecoration( // contentPadding: // EdgeInsets.all( // 0), // isDense: // true, // labelStyle: // TextStyle( // fontFamily: // 'Inter', // fontSize: // 26.rpx, // letterSpacing: // 0.0, // ), // hintStyle: // TextStyle( // fontFamily: // 'Inter', // fontSize: // 26.rpx, // letterSpacing: // 0.0, // color: themeController // .currentColor // .sc4, // ), // enabledBorder: // OutlineInputBorder( // borderSide: // BorderSide( // color: // Color(0x00000000), // width: // 1.rpx, // ), // borderRadius: // BorderRadius.circular(8.rpx), // ), // focusedBorder: // OutlineInputBorder( // borderSide: // BorderSide( // color: // Color(0x00000000), // width: // 1.rpx, // ), // borderRadius: // BorderRadius.circular(8.rpx), // ), // errorBorder: // OutlineInputBorder( // borderSide: // BorderSide( // color: // Colors.red, // width: // 1.rpx, // ), // borderRadius: // BorderRadius.circular(8.rpx), // ), // focusedErrorBorder: // OutlineInputBorder( // borderSide: // BorderSide( // color: // Colors.red, // width: // 1.rpx, // ), // borderRadius: // BorderRadius.circular(8.rpx), // ), // filled: // false, // fillColor: // Colors // .white, // ), // style: // TextStyle( // fontFamily: // 'Readex Pro', // letterSpacing: // 0, // color: Colors // .black, // fontSize: // 26.rpx, // ), // // cursorColor: // // Colors.black, // // validator: _model // // .textControllerValidator // // .asValidator(context), // ), // ), // ), // ), // ].divide(SizedBox( // width: 26.rpx)), // ), // ), // ), // Flexible( // child: Container( // width: // MediaQuery.sizeOf( // context) // .width, // height: 10, // constraints: // BoxConstraints( // minHeight: 60.rpx, // ), // child: Row( // mainAxisSize: // MainAxisSize.max, // children: [ // Container( // width: 105.rpx, // height: MediaQuery // .sizeOf( // context) // .height * // 0.038, // constraints: // const BoxConstraints( // minWidth: 60, // ), // child: Align( // alignment: // const AlignmentDirectional( // -1, 0), // child: Text( // '序列号', // style: TextStyle( // fontFamily: // 'Readex Pro', // fontSize: 26 // .rpx, // letterSpacing: // 0, // color: Colors // .white), // ), // ), // ), // // Expanded( // // child: Container( // // width: 100, // // height: 100, // // decoration: // // BoxDecoration( // // color: Colors // // .white, // // borderRadius: // // BorderRadius // // .circular(8), // // ), // // child: Padding( // // padding: EdgeInsets.only(left: 26.rpx), // // child: Align( // // alignment: Alignment.centerLeft, // // child: Obx(() => Text( // // controller.model.device_id ?? '', // // style: TextStyle(fontSize: 26.rpx, color: Colors.black), // // ))))), // // ), // Expanded( // child: Container( // child: Align( // alignment: // AlignmentDirectional( // -1, // 0), // child: // TextFormField( // onChanged: // (value) { // controller // .model // .device_id = value; // }, // autofocus: // false, // obscureText: // false, // decoration: // InputDecoration( // contentPadding: // EdgeInsets.all( // 0), // isDense: // true, // labelStyle: // TextStyle( // fontFamily: // 'Inter', // fontSize: // 26.rpx, // letterSpacing: // 0.0, // ), // hintStyle: // TextStyle( // fontFamily: // 'Inter', // fontSize: // 26.rpx, // letterSpacing: // 0.0, // color: themeController // .currentColor // .sc4, // ), // enabledBorder: // OutlineInputBorder( // borderSide: // BorderSide( // color: // Color(0x00000000), // width: // 1.rpx, // ), // borderRadius: // BorderRadius.circular(8.rpx), // ), // focusedBorder: // OutlineInputBorder( // borderSide: // BorderSide( // color: // Color(0x00000000), // width: // 1.rpx, // ), // borderRadius: // BorderRadius.circular(8.rpx), // ), // errorBorder: // OutlineInputBorder( // borderSide: // BorderSide( // color: // Colors.red, // width: // 1.rpx, // ), // borderRadius: // BorderRadius.circular(8.rpx), // ), // focusedErrorBorder: // OutlineInputBorder( // borderSide: // BorderSide( // color: // Colors.red, // width: // 1.rpx, // ), // borderRadius: // BorderRadius.circular(8.rpx), // ), // filled: // false, // fillColor: // Colors // .white, // ), // style: // TextStyle( // fontFamily: // 'Readex Pro', // letterSpacing: // 0, // color: Colors // .black, // fontSize: // 26.rpx, // ), // // cursorColor: // // Colors.black, // // validator: _model // // .textControllerValidator // // .asValidator(context), // ), // ), // ), // ), // ].divide(SizedBox( // width: 26.rpx)), // ), // ), // ), Flexible( child: Container( width: MediaQuery.sizeOf( context) .width, height: 10, constraints: BoxConstraints( minHeight: 60.rpx, ), child: Row( mainAxisSize: MainAxisSize.max, children: [ Container( width: 105.rpx, height: MediaQuery .sizeOf( context) .height * 0.038, constraints: const BoxConstraints( minWidth: 60, ), child: Align( alignment: const AlignmentDirectional( -1, 0), child: Text( '产品型号', style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26 .rpx, letterSpacing: 0, color: Colors .white), ), ), ), Expanded( child: Container( decoration: BoxDecoration( color: Colors .white, borderRadius: BorderRadius .circular( 8), ), width: double .infinity, child: Padding( padding: EdgeInsetsDirectional .fromSTEB( 35.rpx, 0, 35.rpx, 0), child: Row( mainAxisSize: MainAxisSize .max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Expanded( child: Container( child: Align( alignment: AlignmentDirectional(-1, 0), child: TextFormField( onChanged: (value) { controller.model.device_category = value; }, autofocus: false, obscureText: false, decoration: InputDecoration( contentPadding: EdgeInsets.all(0), isDense: true, labelStyle: TextStyle( fontFamily: 'Inter', fontSize: 26.rpx, letterSpacing: 0.0, ), hintStyle: TextStyle( fontFamily: 'Inter', fontSize: 26.rpx, letterSpacing: 0.0, color: themeController.currentColor.sc4, ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0x00000000), width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0x00000000), width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), errorBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), filled: false, fillColor: Colors.white, ), style: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, color: Colors.black, fontSize: 26.rpx, ), // cursorColor: // Colors.black, // validator: _model // .textControllerValidator // .asValidator(context), ), ), ), ), ], ), ), ), ), ].divide(SizedBox( width: 26.rpx)), ), ), ), Flexible( child: Container( width: MediaQuery.sizeOf( context) .width, height: 10, constraints: BoxConstraints( minHeight: 60.rpx, ), child: Row( mainAxisSize: MainAxisSize.max, children: [ Container( width: 105.rpx, height: MediaQuery .sizeOf( context) .height * 0.038, constraints: const BoxConstraints( minWidth: 60, ), child: Align( alignment: const AlignmentDirectional( -1, 0), child: Text( '序列号', style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26 .rpx, letterSpacing: 0, color: Colors .white), ), ), ), Expanded( child: Container( decoration: BoxDecoration( color: Colors .white, borderRadius: BorderRadius .circular( 8), ), width: double .infinity, child: Padding( padding: EdgeInsetsDirectional .fromSTEB( 35.rpx, 0, 35.rpx, 0), child: Row( mainAxisSize: MainAxisSize .max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Expanded( child: Container( child: Align( alignment: AlignmentDirectional(-1, 0), child: TextFormField( onChanged: (value) { controller.model.device_id = value; }, autofocus: false, obscureText: false, decoration: InputDecoration( contentPadding: EdgeInsets.all(0), isDense: true, labelStyle: TextStyle( fontFamily: 'Inter', fontSize: 26.rpx, letterSpacing: 0.0, ), hintStyle: TextStyle( fontFamily: 'Inter', fontSize: 26.rpx, letterSpacing: 0.0, color: themeController.currentColor.sc4, ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0x00000000), width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0x00000000), width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), errorBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 1.rpx, ), borderRadius: BorderRadius.circular(8.rpx), ), filled: false, fillColor: Colors.white, ), style: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, color: Colors.black, fontSize: 26.rpx, ), // cursorColor: // Colors.black, // validator: _model // .textControllerValidator // .asValidator(context), ), ), ), ), ], ), ), ), ), ].divide(SizedBox( width: 26.rpx)), ), ), ), ].divide( SizedBox(height: 30.rpx)), ), ) ], ), ), ), ), ), ), Padding( padding: EdgeInsetsDirectional.fromSTEB( 0, 26.rpx, 0, 0), child: Container( width: bodysize!.maxWidth, height: bodysize!.maxHeight * 0.17, constraints: BoxConstraints( minHeight: 345.rpx, ), decoration: BoxDecoration( color: const Color(0XFF003058), borderRadius: BorderRadius.circular(16.rpx), ), child: Obx(() { return Container( width: bodysize!.maxWidth, height: bodysize!.maxHeight * 0.17, decoration: BoxDecoration( color: const Color(0XFF003058), borderRadius: BorderRadius.circular(16.rpx), ), child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ if (controller.model.issue_img == null || controller .model.issue_img!.isEmpty) Flexible( child: InkWell( onTap: () async { ApiResponse apiResponse = await applyRepairController .uploadImg(); if (apiResponse.code == HttpStatusCodes.ok) { } else { if (controller.model .issue_img == null || controller .model .issue_img! .isEmpty) { TopSlideNotification.show( context, text: apiResponse.msg!, textColor: apiResponse .code == HttpStatusCodes .ok ? themeController .currentColor .sc2 : themeController .currentColor .sc9, ); } } }, child: Container( width: MediaQuery.sizeOf(context) .width, height: MediaQuery.sizeOf(context) .height * 0.186, child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .center, crossAxisAlignment: CrossAxisAlignment .center, children: [ Flexible( child: Align( alignment: const AlignmentDirectional( 0, 0), // child: Icon( // Icons // .linked_camera_outlined, // color: // Color(0xFF9EA4B7), // size: 40, // ), child: Container( width: 50, height: 50, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit .cover, image: Image.asset( 'assets/images/camera.png', ).image, ), ), ), ), ), Flexible( child: Container( width: 138, height: 31, decoration: BoxDecoration( borderRadius: BorderRadius .circular( 50), border: Border.all( color: const Color( 0xFF9EA4B7), ), ), child: Align( alignment: const AlignmentDirectional( 0, 0), child: Text( '上传设备故障照片', style: TextStyle( fontFamily: 'Readex Pro', color: const Color( 0xFF9EA4B7), fontSize: AppFontsize .normal_text_size, letterSpacing: 0, ), ), ), ), ), ], ), ), )), if (controller.model.issue_img != null && controller.model.issue_img! .isNotEmpty) Flexible( child: Container( width: MediaQuery.sizeOf(context) .width, height: MediaQuery.sizeOf(context) .height * 0.186, constraints: const BoxConstraints( minHeight: 250, ), decoration: const BoxDecoration( color: Colors.white, ), child: Column( mainAxisSize: MainAxisSize.max, children: [ Align( alignment: const AlignmentDirectional( 1, 0), child: Padding( padding: const EdgeInsetsDirectional .fromSTEB( 0, 7, 21, 7), child: Container( width: MediaQuery .sizeOf( context) .width * 0.2, height: 21, decoration: const BoxDecoration( color: Colors.white, ), child: Container( width: MediaQuery .sizeOf( context) .width * 0.2, height: 21, decoration: const BoxDecoration( color: Colors .white, ), child: Row( mainAxisSize: MainAxisSize .max, mainAxisAlignment: MainAxisAlignment .end, children: [ Text( // '2', controller .model .issue_img! .length .toString(), style: TextStyle( fontFamily: 'Readex Pro', fontSize: AppFontsize .normal_text_size, letterSpacing: 0, ), ), Text( '/', style: TextStyle( fontFamily: 'Readex Pro', fontSize: AppFontsize .normal_text_size, letterSpacing: 0, ), ), Text( '3', style: TextStyle( fontFamily: 'Readex Pro', fontSize: AppFontsize .normal_text_size, letterSpacing: 0, ), ), ], ), ), ), ), ), Flexible( child: Padding( padding: const EdgeInsetsDirectional .fromSTEB( 0, 0, 21, 0), child: Container( width: MediaQuery .sizeOf( context) .width, height: MediaQuery .sizeOf( context) .height * 0.15, constraints: const BoxConstraints( minHeight: 152, ), decoration: const BoxDecoration( color: Colors.white, ), child: Container( width: 100, height: 100, decoration: const BoxDecoration( color: Colors .white, ), child: Obx(() => ListView( shrinkWrap: true, scrollDirection: Axis.horizontal, children: getImage() .divide(const SizedBox( width: 12, )) .addToStart(const SizedBox( width: 21, ))))), ), ), ), ], ), ), ), ], ), ); }), ), ), Padding( padding: EdgeInsetsDirectional.fromSTEB( 0, 25.rpx, 0, 0), child: Container( width: bodysize!.maxWidth, height: bodysize!.maxHeight * 0.17, constraints: BoxConstraints( minHeight: 345.rpx, ), decoration: BoxDecoration( color: const Color(0xFF003058), borderRadius: BorderRadius.circular(16.rpx), ), child: Container( width: bodysize!.maxWidth, height: bodysize!.maxHeight * 0.19, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.rpx), ), child: Column( mainAxisSize: MainAxisSize.max, children: [ Align( alignment: const AlignmentDirectional( 0, 0), child: Padding( padding: const EdgeInsetsDirectional .fromSTEB(0, 15, 0, 16), child: Text( '请描述一下您的问题', style: TextStyle( fontFamily: 'Readex Pro', color: Colors.white, fontSize: 30.rpx, letterSpacing: 0, fontWeight: FontWeight.w600, ), ), ), ), Expanded( child: Padding( padding: EdgeInsetsDirectional .fromSTEB(34.rpx, 0, 34.rpx, 34.rpx), child: Container( width: MediaQuery.sizeOf(context) .width, height: MediaQuery.sizeOf(context) .height * 1, constraints: BoxConstraints( minHeight: 181.rpx, ), decoration: BoxDecoration( color: const Color(0xFFF3F5F6), borderRadius: BorderRadius.circular(8), ), child: TextFormField( // autofocus: true, onChanged: (value) { controller.model.desc = value; }, initialValue: controller.model.desc, obscureText: false, decoration: InputDecoration( hintText: '问题描述(100个字以内)', labelStyle: TextStyle( fontFamily: 'Readex Pro', fontSize: AppFontsize .normal_text_size, letterSpacing: 0, color: const Color( 0XFF929699)), hintStyle: TextStyle( fontFamily: 'Readex Pro', fontSize: AppFontsize .normal_text_size, letterSpacing: 0, color: const Color( 0XFF929699)), enabledBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color(0x00000000), width: 2, ), borderRadius: BorderRadius.circular( 8), ), focusedBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color(0x00000000), width: 2, ), borderRadius: BorderRadius.circular( 8), ), errorBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color(0x00000000), width: 2, ), borderRadius: BorderRadius.circular( 8), ), focusedErrorBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color(0x00000000), width: 2, ), borderRadius: BorderRadius.circular( 8), ), // contentPadding: // EdgeInsetsDirectional // .fromSTEB(0, 0, 0, 12), contentPadding: const EdgeInsetsDirectional .fromSTEB( 10, 5, 10, 5), ), maxLines: 4, maxLength: 100, // ✅ 限制最多输入 100 字符 style: TextStyle( fontFamily: 'Readex Pro', fontSize: AppFontsize .normal_text_size, letterSpacing: 0, ), ), ), ), ), ], ), ), ), ), Padding( padding: EdgeInsetsDirectional.fromSTEB( 0, 48.rpx, 0, 0), child: Container( width: bodysize!.maxWidth, height: bodysize!.maxHeight * 0.17, constraints: BoxConstraints( minHeight: 345.rpx, ), decoration: BoxDecoration( color: const Color(0XFF003058), borderRadius: BorderRadius.circular(16), ), child: Column( mainAxisSize: MainAxisSize.max, children: [ Align( alignment: const AlignmentDirectional(0, 0), child: Padding( padding: EdgeInsetsDirectional.fromSTEB( 0, 48.rpx, 0, 48.rpx), child: Text( '联系方式', style: TextStyle( fontFamily: 'Readex Pro', color: Colors.white, fontSize: 30.rpx, letterSpacing: 0, fontWeight: FontWeight.w600, ), ), ), ), Expanded( child: Padding( padding: EdgeInsetsDirectional.fromSTEB( 25.rpx, 0, 34.rpx, 70.rpx), child: Container( width: MediaQuery.sizeOf(context) .width, height: MediaQuery.sizeOf(context) .height * 1, child: Column( mainAxisSize: MainAxisSize.max, children: [ Flexible( child: Container( width: MediaQuery.sizeOf( context) .width, height: MediaQuery.sizeOf( context) .height * 0.038, constraints: BoxConstraints( minHeight: 61.rpx, ), child: Row( mainAxisSize: MainAxisSize.max, children: [ Container( width: 105.rpx, height: MediaQuery .sizeOf( context) .height * 0.038, constraints: BoxConstraints( minWidth: 60.rpx, ), // decoration: // BoxDecoration( // color: FlutterFlowTheme.of( // context) // .secondaryBackground, // ), child: Row( mainAxisSize: MainAxisSize .max, children: [ Text( '联系人', style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26 .rpx, letterSpacing: 0, color: Colors .white), ), ], ), ), Expanded( child: Container( width: MediaQuery .sizeOf( context) .width, height: 100, decoration: BoxDecoration( color: Colors .white, borderRadius: BorderRadius .circular( 8), ), child: TextFormField( // autofocus: true, obscureText: false, onChanged: (val) { controller .model .apply_name = val; }, decoration: InputDecoration( contentPadding: EdgeInsets .symmetric( vertical: 25.rpx, horizontal: 26.rpx, ), labelStyle: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, ), hintStyle: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, ), enabledBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color( 0x00000000), width: 2, ), borderRadius: BorderRadius .circular(8), ), focusedBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color( 0x00000000), width: 2, ), borderRadius: BorderRadius .circular(8), ), errorBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color( 0x00000000), width: 2, ), borderRadius: BorderRadius .circular(8), ), focusedErrorBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color( 0x00000000), width: 2, ), borderRadius: BorderRadius .circular(8), ), ), style: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, color: Colors .black, fontSize: 26.rpx, ), ), ), ), ].divide(const SizedBox( width: 13)), ), ), ), Flexible( child: Container( width: MediaQuery.sizeOf( context) .width, height: MediaQuery.sizeOf( context) .height * 0.038, constraints: const BoxConstraints( minHeight: 31, ), child: Row( mainAxisSize: MainAxisSize.max, children: [ Container( width: 105.rpx, height: MediaQuery .sizeOf( context) .height * 0.038, constraints: BoxConstraints( minWidth: 60.rpx, ), child: Row( mainAxisSize: MainAxisSize .max, children: [ Text( '手机号码', style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26 .rpx, letterSpacing: 0, color: Colors .white), ), ], ), ), Expanded( child: Container( width: 100, height: 100, decoration: BoxDecoration( color: Colors .white, borderRadius: BorderRadius .circular( 8), ), child: TextFormField( // autofocus: true, obscureText: false, onChanged: (val) { controller .model .tel = val; }, decoration: InputDecoration( contentPadding: EdgeInsets .symmetric( vertical: 25.rpx, horizontal: 26.rpx, ), labelStyle: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, ), hintStyle: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, ), enabledBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color( 0x00000000), width: 2, ), borderRadius: BorderRadius .circular(8), ), focusedBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color( 0x00000000), width: 2, ), borderRadius: BorderRadius .circular(8), ), errorBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color( 0x00000000), width: 2, ), borderRadius: BorderRadius .circular(8), ), focusedErrorBorder: UnderlineInputBorder( borderSide: const BorderSide( color: Color( 0x00000000), width: 2, ), borderRadius: BorderRadius .circular(8), ), ), style: TextStyle( fontFamily: 'Readex Pro', letterSpacing: 0, color: Colors .black, fontSize: 26.rpx, ), ), ), ), ].divide(const SizedBox( width: 13)), ), ), ), ].divide( const SizedBox(height: 15)), ), ), ), ), ], ), ), ), ], ), ), ), ), ), Padding( padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 30.rpx, 30.rpx, AppConstants.page_button_bottom_padding), child: Container( width: bodysize!.maxWidth, height: bodysize!.maxHeight * 0.056, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.rpx), ), child: CustomCard( borderRadius: 16.rpx, gradientDirection: GradientDirection.vertical, onTap: () async { String msg = checkRepairParam(); if (msg.isNotEmpty) { TopSlideNotification.show(context, text: msg, textColor: themeController.currentColor.sc9); } else { String serviceAddress = ServiceConstant.service_address; String serviceName = ServiceConstant.server_service; String serviceApi = ServiceConstant.submit_repair; String queryUrl = "$serviceAddress$serviceName$serviceApi"; var data = { "type": controller.model.device_type, "contacts": { "name": controller.model.apply_name, "phone": controller.model.tel, }, "device": [ { "mac": controller.model.device_id, "desc": controller.model.desc, "img": controller.model.issue_img, "category": controller.model.device_category, "series": controller.model.device_series, "name": controller.model.device_name } ], }; ApiResponse apiResponse = await requestWithLog( logTitle: "提交报修信息", method: MyHttpMethod.post, queryUrl: queryUrl, data: data, onSuccess: (res) { TopSlideNotification.show(context, text: res.msg!); repairListController.getRepairList(); Get.toNamed("/applyRepairSuccess"); }, onFailure: (res) { TopSlideNotification.show(context, text: res.msg!, textColor: themeController.currentColor.sc9); }, ); controller.model = ApplyRepairModel(); // 在 submitRepair 完成后执行 controller.updateAll(); } }, colors: const [ Color(0xFFFCFCFC), Color(0xFFF8FAF9), Color(0XFFECF6F3), Color(0XFFD9F0E9), Color(0xFFCEECE3) ], child: Container( width: double.infinity, height: 90.rpx, alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(6), ), child: Text( "提交申请", style: TextStyle( fontFamily: 'Readex Pro', color: stringToColor("#011D33"), letterSpacing: 0, fontSize: 30.rpx, ), ), ), )), ), ], ), ), ), )); }); } List getImage() { List images = []; controller.model.issue_img!.forEach((element) async { images.add(ImgPreviewWidget( imgUrl: element, index: controller.model.issue_img!.indexOf(element), applyRepairController: controller, isDel: true, )); }); if (images.length < controller.model.imagesLImit!) { images.add(ImgPreviewDefaultWidget( applyRepairController: controller, )); } return images; } List> _getDropdownItems() { List options = [ '智能床垫AH-2型', '智能床垫BY-H型', '智能床垫BY-C型', // 可以在这里添加更多选项 ]; return options.map((String value) { return DropdownMenuItem( value: value, child: Text(value), ); }).toList(); } String checkRepairParam() { String message = ""; if (controller.model.device_type == null || controller.model.device_series!.isEmpty) { message = '请输入设备系列!'; return message; } if (controller.model.device_category == null || controller.model.device_category!.isEmpty) { message = '请输入设备型号!'; return message; } if (controller.model.device_id == null || controller.model.device_id!.isEmpty) { message = '请输入设备序列号id!'; return message; } if (controller.model.apply_name == null || controller.model.apply_name!.isEmpty) { message = '请输入姓名!'; return message; } RegExp nameRegExp = RegExp(r'^[\u4e00-\u9fa5]{2,4}$'); if (!nameRegExp.hasMatch(controller.model.apply_name!)) { message = '姓名必须为2到4个汉字!'; return message; } if (controller.model.tel == null || controller.model.tel!.isEmpty) { message = '请输入手机号!'; return message; } if (!MyUtils.isValidPhoneNumber(controller.model.tel!)) { message = '无效的手机号!'; return message; } if (controller.model.desc == null || controller.model.desc!.isEmpty) { message = '请输入问题描述!'; return message; } if (controller.model.issue_img == null || controller.model.issue_img!.isEmpty) { message = '请至少上传一张问题图片!'; return message; } return message; } // 新增滚动方法 void _scrollToKey(GlobalKey key) { WidgetsBinding.instance.addPostFrameCallback((_) { Scrollable.ensureVisible( key.currentContext!, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); }); } String getDeviceTypeName(int? type) { if (type == null) return ''; switch (type) { case 1: return '体征检测设备'; case 2: return '智能床'; case 3: return '智能床垫'; default: return '未知设备'; } } }