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( '申请报修'.tr, 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( '选择需要报修的设备'.tr, 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( '已绑设备'.tr, style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26.rpx, letterSpacing: 0, height: 1, color: Colors .white), ), ), ), Expanded( child: Container( width: 300, // 可以根据需要调整宽度 height: 56, // 可以根据需要调整高度 decoration: BoxDecoration( borderRadius: BorderRadius .circular( 8), color: Colors .white, ), child: Obx(() { final isDeviceListEmpty = controller .model .device_list ?.isEmpty ?? true; List> deviceOptions = controller .model .device_list! .map((device) => { 'mac'.tr: device['mac'.tr].toString(), 'name': device['name'].toString(), 'type': device['device_type'].toString() }) .toList(); List deviceNames = controller .model .device_list! .map( (device) { final mac = device['mac'.tr]?.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'.tr]!) .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'.tr].toString() == val); final mac = selectedDevice['mac'.tr]?.toString() ?? '未知MAC'.tr; 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 = '未知型号'.tr; 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 ? '暂无可选设备' .tr : '请选择绑定设备' .tr, searchHintText: '查找'.tr, 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: BoxConstraints( minWidth: 62, ), child: Align( alignment: const AlignmentDirectional( -1, 0), child: Text( '设备系列'.tr, maxLines: 2, style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26.rpx, letterSpacing: 0, height: 1, 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( '产品型号'.tr, style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26.rpx, letterSpacing: 0, height: 1, 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: BoxConstraints( minWidth: 60, minHeight: 60.rpx), child: Align( alignment: const AlignmentDirectional( -1, 0), child: Text( '序列号'.tr, style: TextStyle( fontFamily: 'Readex Pro', fontSize: 26.rpx, letterSpacing: 0, height: 1, 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( '上传设备故障照片'.tr, 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( '请描述一下您的问题'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Colors.white, fontSize: 30.rpx, letterSpacing: 0, ), ), ), ), 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个字以内)'.tr, 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( '联系方式'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Colors.white, fontSize: 30.rpx, letterSpacing: 0, ), ), ), ), 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( '联系人'.tr, 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( '手机号码'.tr, 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, ), // hintText: // "请输入手机号".tr, 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".tr: 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: "提交报修信息".tr, 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( "提交申请".tr, 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; } String checkRepairParam() { String message = ""; if (controller.model.device_type == null || controller.model.device_series!.isEmpty) { message = '请输入设备系列!'.tr; return message; } if (controller.model.device_category == null || controller.model.device_category!.isEmpty) { message = '请输入设备型号!'.tr; return message; } if (controller.model.device_id == null || controller.model.device_id!.isEmpty) { message = '请输入设备序列号id!'.tr; return message; } if (controller.model.apply_name == null || controller.model.apply_name!.isEmpty) { message = '请输入姓名!'.tr; return message; } RegExp nameRegExp = RegExp(r'^[\u4e00-\u9fa5]{2,4}$'); if (!nameRegExp.hasMatch(controller.model.apply_name!)) { message = '姓名必须为2到4个汉字!'.tr; return message; } if (controller.model.tel == null || controller.model.tel!.isEmpty) { message = '请输入手机号!'.tr; return message; } if (!MyUtils.isValidPhoneNumber(controller.model.tel!)) { message = '无效的手机号!'.tr; return message; } if (controller.model.desc == null || controller.model.desc!.isEmpty) { message = '请输入问题描述!'.tr; return message; } if (controller.model.issue_img == null || controller.model.issue_img!.isEmpty) { message = '请至少上传一张问题图片!'.tr; 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 '体征检测设备'.tr; case 2: return '智能床'.tr; case 3: return '智能床垫'.tr; default: return '未知设备'.tr; } } }