import 'dart:async'; import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.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/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart'; import 'package:vbvs_app/controller/device/device_calibration_controller.dart'; import 'package:vbvs_app/pages/common/selectDialog.dart'; import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; class CalibrationPage extends StatefulWidget { int? type; //1.绑定时 2.绑定后 CalibrationPage({super.key, required this.type}); @override State createState() => _CalibrationPageState(); } class _CalibrationPageState extends State { DeviceCalibrationController deviceCalibrationController = Get.find(); BlueteethBindController blueteethBindController = Get.find(); @override void initState() { super.initState(); deviceCalibrationController.process.value = 0; deviceCalibrationController.bed_calibration.value = 0; deviceCalibrationController.position_calibration.value = 0; blueteethBindController.cid!.value = ""; deviceCalibrationController.complete = false; } @override void dispose() { blueteethBindController.cid!.value = ""; deviceCalibrationController.complete = false; super.dispose(); } @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, bodySize) => GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/img/bgNoImg.png'), fit: BoxFit.fill, ), ), child: Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( backgroundColor: themeController.currentColor.sc17, automaticallyImplyLeading: false, iconTheme: IconThemeData(color: themeController.currentColor.sc3), titleSpacing: 0, title: Container( width: double.infinity, height: 180.rpx, child: Stack( alignment: Alignment.center, children: [ Text( '设备校准'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: themeController.currentColor.sc3, letterSpacing: 0, fontSize: 30.rpx, ), ), Positioned( left: 0, child: returnIconButtom, ), if (widget.type == 1) Positioned( right: 20.rpx, child: CustomCard( borderRadius: 20.rpx, onTap: () async { // Get.toNamed("/personPage"); Get.toNamed("/bindDeviceSuccess"); }, colors: [ themeController.currentColor.sc1, themeController.currentColor.sc2, ], child: Container( width: 100.rpx, height: 60.rpx, alignment: Alignment.center, padding: EdgeInsetsDirectional.fromSTEB( 16.rpx, 0, 16.rpx, 0), child: Text( '跳过'.tr, style: TextStyle( fontFamily: 'Inter Tight', color: themeController.currentColor.sc3, letterSpacing: 0.0, ), ), ), ), ), ], ), ), actions: [], centerTitle: false, ), body: SafeArea( top: true, // child: Container(), child: Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 0.rpx, 30.rpx, 0.rpx), child: Column( mainAxisSize: MainAxisSize.max, children: [ Padding( padding: EdgeInsetsDirectional.fromSTEB(0.rpx, 30.rpx, 0, 0), child: Container( width: double.infinity, decoration: BoxDecoration( color: themeController.currentColor.sc5, borderRadius: BorderRadius.circular(16.rpx), ), child: Padding( padding: EdgeInsetsDirectional.fromSTEB( 10.rpx, 20.rpx, 34.rpx, 20.rpx), child: Column( mainAxisSize: MainAxisSize.max, children: [ ClickableContainer( backgroundColor: Colors.transparent, highlightColor: themeController.currentColor.sc21, borderRadius: 0, // 可按需设置圆角 padding: EdgeInsets.symmetric( vertical: 10.rpx), // 可自定义内边距 onTap: () { // deviceCalibrationController.process.value = 0; // deviceCalibrationController.updateAll(); }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Obx(() { return Visibility( maintainState: true, maintainAnimation: true, maintainSize: true, visible: deviceCalibrationController .process.value == 0, child: SvgPicture.asset( 'assets/img/icon/select_arrow.svg', width: 17.rpx, height: 17.rpx, color: themeController .currentColor.sc9, ), ); }), SizedBox(width: 8.rpx), Text( '离床校准'.tr, style: TextStyle( fontSize: 30.rpx, letterSpacing: 0.0, color: themeController .currentColor.sc3, ), ), ], ), Obx(() { return Text( deviceCalibrationController .bed_calibration.value == 0 ? '未完成'.tr : "已完成".tr, style: TextStyle( fontSize: 26.rpx, letterSpacing: 0.0, color: deviceCalibrationController .bed_calibration.value == 0 ? themeController.currentColor.sc3 : themeController .currentColor.sc1, ), ); }), ], ), ), SizedBox(height: 41.rpx), ClickableContainer( backgroundColor: Colors.transparent, highlightColor: themeController.currentColor.sc21, borderRadius: 0, // 可根据需要设为圆角 padding: EdgeInsets.symmetric( vertical: 10.rpx), // 可根据需要调整上下内边距 onTap: () { // deviceCalibrationController.process.value = 1; // deviceCalibrationController.updateAll(); }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Obx(() { return Visibility( maintainState: true, maintainAnimation: true, maintainSize: true, visible: deviceCalibrationController .process.value == 1, child: SvgPicture.asset( 'assets/img/icon/select_arrow.svg', width: 17.rpx, height: 17.rpx, color: themeController .currentColor.sc9, ), ); }), SizedBox(width: 8.rpx), Text( '位置校准'.tr, style: TextStyle( fontSize: 30.rpx, letterSpacing: 0.0, color: themeController .currentColor.sc3, ), ), ], ), Obx(() { return Text( deviceCalibrationController .position_calibration .value == 0 ? '未完成'.tr : "已完成".tr, style: TextStyle( fontSize: 26.rpx, letterSpacing: 0.0, color: deviceCalibrationController .position_calibration .value == 0 ? themeController.currentColor.sc3 : themeController .currentColor.sc1, ), ); }), ], ), ), ], ), ), ), ), Obx(() { return Expanded( child: SizedBox( width: double.infinity, child: Padding( padding: EdgeInsetsDirectional.fromSTEB( 100.rpx, 55.rpx, 100.rpx, 0), child: Stack( clipBehavior: Clip.none, children: [ Container( width: MediaQuery.sizeOf(context).width * 0.65, height: MediaQuery.sizeOf(context).height * 0.3, child: Stack( children: [ // Image.asset( // deviceCalibrationController // .bed_type.value == // 0 // ? "assets/img/single_pillow.png" // : "assets/img/double_pillow.png", // width: double.infinity, // height: double.infinity, // fit: BoxFit.contain, // ), Image.asset( deviceCalibrationController .process.value == 1 && deviceCalibrationController .position_calibration .value == 1 ? (deviceCalibrationController .bed_type.value == 0 ? "assets/img/single_person.png" : "assets/img/double_person.png") : (deviceCalibrationController .bed_type.value == 0 ? "assets/img/single_pillow.png" : "assets/img/double_pillow.png"), width: double.infinity, height: double.infinity, fit: BoxFit.contain, ), // 床头文字 Positioned( top: 23.rpx, left: (MediaQuery.sizeOf(context).width * 0.65) / 2 - 26.rpx, child: Text( '床头'.tr, style: TextStyle( fontSize: 26.rpx, color: themeController .currentColor.sc4, ), ), ), ], ), ), Obx(() { final double centerLeft = (bodySize.maxWidth * 0.56) / 2; if (deviceCalibrationController .bed_type.value == 0 && deviceCalibrationController .process.value == 1) { //单人床位置校准 return Positioned( top: -40.rpx, left: centerLeft - 0.rpx, child: Container( width: bodySize.maxWidth * 0.087, height: bodySize.maxHeight * 0.06, constraints: BoxConstraints( minWidth: 65.rpx, minHeight: 76.rpx, ), decoration: BoxDecoration( image: DecorationImage( image: AssetImage( 'assets/img/tip_arrow.gif'), fit: BoxFit.cover, ), ), ), ); } if (deviceCalibrationController .bed_type.value == 1 && deviceCalibrationController .process.value == 1) { //双人人床位置校准 return Positioned( top: -40.rpx, left: (MediaQuery.sizeOf(context).width * 0.65) * 0.22 - 0.rpx, child: Container( width: bodySize.maxWidth * 0.087, height: bodySize.maxHeight * 0.06, constraints: BoxConstraints( minWidth: 65.rpx, minHeight: 76.rpx, ), decoration: BoxDecoration( image: DecorationImage( image: AssetImage( 'assets/img/tip_arrow.gif'), fit: BoxFit.cover, ), ), ), ); } return Container(); }), Positioned( top: MediaQuery.sizeOf(context).height * 0.3 + 82.rpx, left: 0, right: 0, child: Obx(() { return Column( children: [ Text( (deviceCalibrationController .process.value == 0 && deviceCalibrationController .bed_calibration .value == 1) || (deviceCalibrationController .process.value == 1 && deviceCalibrationController .position_calibration .value == 1) ? '校准完成'.tr : deviceCalibrationController .process.value == 0 ? '离床校准提示'.tr : '位置校准提示'.tr, style: TextStyle( fontSize: 38.rpx, letterSpacing: 0.0, color: ((deviceCalibrationController .process .value == 0 && deviceCalibrationController .bed_calibration .value == 1) || (deviceCalibrationController .process .value == 1 && deviceCalibrationController .position_calibration .value == 1)) ? themeController .currentColor.sc1 : themeController .currentColor.sc9, ), ), ], ); }), ), ], ), ), ), ); }), Padding( padding: EdgeInsetsDirectional.fromSTEB( 100.rpx, 0.rpx, 100.rpx, 60.rpx), child: CustomCard( borderRadius: AppConstants().button_container_radius, // 圆角半径 // onTap: () async { // BlueteethBindController blueteethBindController = // Get.find(); // String serviceAddress = "http://192.168.1.80:8086"; // String serviceApi = ServiceConstant.start_calibration; // String queryUrl = "${serviceAddress}${serviceApi}"; // requestWithLog( // logTitle: "设备校准", // method: MyHttpMethod.post, // queryUrl: queryUrl, // data: { // "macA": blueteethBindController.currentDeviceMac, // if (blueteethBindController.cid!.value.isNotEmpty) // "id": blueteethBindController.cid!.value, // }, // onSuccess: (res) { // String cid = res.rawResponse.data['cid']; // blueteethBindController.cid!.value = cid; // final ValueNotifier progressNotifier = // ValueNotifier(0.0); // final ValueNotifier failureNotifier = // ValueNotifier(false); // Timer? pollingTimer; // // 定义请求函数 // void requestCalibrationProgress() { // String serviceAddress = // "http://192.168.1.80:8086"; // String serviceApi = // ServiceConstant.calibration_process; // String queryUrl = // "${serviceAddress}${serviceApi}?id=$cid"; // requestWithLog( // logTitle: "设备校准进度", // method: MyHttpMethod.get, // queryUrl: queryUrl, // onSuccess: (res) { // print(res); // deviceCalibrationController.tips.value = // res.data['statusText']; // if (res.data['per'] == 100) { // TopSlideNotification.show(context, // text: deviceCalibrationController // .tips.value); // } // double process = // (res.data['per'] ?? 0).toDouble(); // progressNotifier.value = process; // if (process >= 100) { // if (deviceCalibrationController // .process.value == // 0) { // deviceCalibrationController // .bed_calibration.value = 1; // deviceCalibrationController.updateAll(); // } // if (deviceCalibrationController // .process.value == // 1) { // deviceCalibrationController // .position_calibration.value = 1; // deviceCalibrationController.updateAll(); // } // deviceCalibrationController // .process.value = 1; // deviceCalibrationController.updateAll(); // pollingTimer?.cancel(); // } // }, // onFailure: (res) { // pollingTimer?.cancel(); // failureNotifier.value = true; // TopSlideNotification.show( // context, // text: res.msg ?? "服务器.失败".tr, // textColor: // themeController.currentColor.sc9, // ); // }, // ); // } // // 启动轮询 // pollingTimer = // Timer.periodic(Duration(seconds: 2), (timer) { // requestCalibrationProgress(); // }); // // 初始调用一次 // requestCalibrationProgress(); // // 显示进度弹窗 // showProgressDialog( // context, progressNotifier, failureNotifier); // }, // onFailure: (res) { // TopSlideNotification.show( // context, // text: res.msg ?? "服务器.失败".tr, // textColor: themeController.currentColor.sc9, // ); // }, // ); // }, onTap: () async { if (deviceCalibrationController.complete) { showConfirmDialog( context, Container(), "校准已经完成,是否重新开始校准?", onConfirm: () { BlueteethBindController blueteethBindController = Get.find(); deviceCalibrationController.process.value = 0; deviceCalibrationController .bed_calibration.value = 0; deviceCalibrationController .position_calibration.value = 0; blueteethBindController.cid!.value = ""; deviceCalibrationController.complete = false; }, onCancel: () {}); } BlueteethBindController blueteethBindController = Get.find(); String serviceAddress = "https://caibration.he-info.cn/"; String calibrationApi = ServiceConstant.start_calibration; String progressApi = ServiceConstant.calibration_process; String queryUrl = "$serviceAddress$calibrationApi"; final ValueNotifier progressNotifier = ValueNotifier(0.0); final ValueNotifier failureNotifier = ValueNotifier(false); Timer? pollingTimer; Map data = { "macA": blueteethBindController.currentDeviceMac, }; // 是否是二次点击(有cid表示进行第二阶段) bool isSecondStep = blueteethBindController.cid?.value.isNotEmpty ?? false; if (isSecondStep) { data["id"] = blueteethBindController.cid!.value; } // 发起校准请求 requestWithLog( logTitle: "设备校准", method: MyHttpMethod.post, queryUrl: queryUrl, data: data, onSuccess: (res) { if (!isSecondStep) { // 保存第一次获取的 cid String cid = res.rawResponse.data['cid']; blueteethBindController.cid!.value = cid; } void requestCalibrationProgress() { String cid = blueteethBindController.cid!.value; String progressUrl = "$serviceAddress$progressApi?id=$cid"; requestWithLog( logTitle: "设备校准进度", method: MyHttpMethod.get, queryUrl: progressUrl, onSuccess: (res) { final data = res.data; double per = (data['per'] ?? 0).toDouble(); int currStep = data['currStep'] ?? -1; bool status = data['status'] ?? false; String tips = data['statusText'] ?? ''; deviceCalibrationController.tips.value = tips; // progressNotifier.value = // (res.data['per'] ?? 0) / 100.0; progressNotifier.value = per; if (!isSecondStep && per >= 100) { // 第一步完成:仅 per >= 100 pollingTimer?.cancel(); TopSlideNotification.show(context, text: tips); deviceCalibrationController .process.value = 1; deviceCalibrationController .bed_calibration.value = 1; deviceCalibrationController.updateAll(); } if (isSecondStep && per >= 100 && currStep == 5 && status == true) { // 第二步完成:per >= 100 && currStep == 5 && status == true pollingTimer?.cancel(); TopSlideNotification.show(context, text: "设备校准完成".tr); // 可在这里执行校准完成后的业务逻辑更新 deviceCalibrationController .bed_calibration.value = 1; deviceCalibrationController .position_calibration.value = 1; deviceCalibrationController .process.value = 1; deviceCalibrationController.complete = true; deviceCalibrationController.updateAll(); } }, onFailure: (res) { pollingTimer?.cancel(); failureNotifier.value = true; TopSlideNotification.show( context, text: res.msg ?? "服务器.失败".tr, textColor: themeController.currentColor.sc9, ); }, ); } // 初始调用一次 requestCalibrationProgress(); // 开始轮询 pollingTimer = Timer.periodic(Duration(seconds: 2), (_) { requestCalibrationProgress(); }); // 显示进度弹窗 showProgressDialog( context, progressNotifier, failureNotifier); }, onFailure: (res) { TopSlideNotification.show( context, text: res.msg ?? "服务器.失败".tr, textColor: themeController.currentColor.sc9, ); }, ); }, colors: [ themeController.currentColor.sc1, themeController.currentColor.sc2, ], child: Container( width: bodySize.maxWidth, height: MediaQuery.sizeOf(context).height * 0.055, constraints: BoxConstraints( minWidth: 500.rpx, minHeight: 90.rpx, ), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '开始校准'.tr, style: FlutterFlowTheme.of(context) .bodyMedium .override( //todo 颜色 color: themeController.currentColor.sc3, fontFamily: 'Inter', fontSize: AppConstants().normal_text_fontSize, letterSpacing: 0.0, ), ), ].divide(SizedBox( width: 17.rpx, )), ), ), ), ), ], ), ), ), ), ), ), ); } }