import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:get/get_core/src/get_main.dart'; import 'package:location/base/base_page.dart'; import 'package:location/data/bean/track_daily_bean.dart'; import 'package:location/data/bean/user_info.dart'; import 'package:location/resource/colors.gen.dart'; import 'package:location/resource/string.gen.dart'; import 'package:location/router/app_pages.dart'; import 'package:location/utils/common_expand.dart'; import 'package:lottie/lottie.dart'; import 'package:video_player/video_player.dart'; import '../../resource/assets.gen.dart'; import '../../utils/common_style.dart'; import '../../widget/animated_visibility.dart'; import '../../widget/common_view.dart'; import '../../widget/gradually_print_text.dart'; import '../../widget/typewriter_text.dart'; import 'location_analyse_controller.dart'; class LocationAnalysePage extends BasePage { const LocationAnalysePage({super.key}); static void start( {required TrackDailyBean errorData, required UserInfo userInfo}) { Get.toNamed(RoutePath.locationAnalyse, arguments: { 'errorData': errorData, 'userInfo': userInfo, }); } @override bool immersive() { return true; } @override Widget buildBody(BuildContext context) { return Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( gradient: LinearGradient(colors: [ ColorName.white, '#D8D8FE'.color, ], begin: Alignment.topCenter, end: Alignment.bottomCenter)), child: Stack( children: [buildAnalyseView(), buildBackBtnView()], ), ); } Widget buildAnalyseView() { return SizedBox( width: double.infinity, height: double.infinity, child: SingleChildScrollView( child: Column( children: [ buildAIAnalyseView(), SizedBox(height: 10.w), buildTrackAnalyseHeaderView(), SizedBox(height: 8.w), buildAnalyseResultView(), SizedBox(height: 30.w), ], )), ); } Widget buildAnalyseResultView() { return Obx(() { return AnimatedOpacity( duration: const Duration(milliseconds: 500), opacity: controller.isShowAnalyseResult ? 1.0 : 0.0, child: Container( padding: EdgeInsets.only(left: 11.w, right: 11.w, top: 20.w, bottom: 20.w), margin: EdgeInsets.symmetric(horizontal: 10.w), decoration: BoxDecoration( color: ColorName.white, borderRadius: BorderRadius.circular(12.w), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Assets.images.iconTrackDailySummary.image(width: 20.w), SizedBox(width: 4.w), Text(StringName.trackAnalyseResultTitle, style: TextStyle( fontSize: 13.sp, color: '#333333'.color, fontWeight: FontWeight.bold)) ], ), SizedBox(height: 10.w), Obx(() { if (controller.summaryError?.isNotEmpty == true) { return Text(controller.summaryError!, style: TextStyle(fontSize: 12.sp, color: '#FF0000'.color)); } else { return GraduallyPrintText( graduallyController: controller.graduallyController, textStyle: TextStyle(fontSize: 12.sp, color: '#333333'.color), ); } }), ], ), ), ); }); } Widget buildTrackAnalyseHeaderView() { return SizedBox( width: double.infinity, child: Stack( children: [ buildHeaderContentView(), Positioned( top: 8.w, left: 20.w, child: Container( width: 64.w, height: 64.w, padding: EdgeInsets.all(2.w), decoration: BoxDecoration( shape: BoxShape.circle, color: ColorName.white, ), child: buildCustomAvatarOrDefaultAvatarView( size: double.infinity, avatar: controller.userInfo?.avatar, isMine: controller.userInfo?.isMine == true, ), ), ), buildAnalyseBtn(), ], ), ); } Widget buildHeaderContentView() { return Container( width: double.infinity, margin: EdgeInsets.only(left: 10.w, right: 10.w, top: 25.w), decoration: BoxDecoration( color: ColorName.white, borderRadius: BorderRadius.circular(12.w)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.only(left: 85.w, top: 8.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( controller.userInfo?.getUserNickName() ?? '', style: TextStyle( fontSize: 14.sp, color: '#333333'.color, fontWeight: FontWeight.bold), ), SizedBox(height: 3.w), Text( controller.errorInfo?.addr == null ? StringName.trackAnalyseNoNewPosition : '异常地点:${controller.errorInfo?.addr}', style: TextStyle(fontSize: 12.sp, color: '#F24D4D'.color), ) ], ), ), SizedBox(height: 20.w), Container( margin: EdgeInsets.only(left: 14.w), child: Row( children: [ Assets.images.iconTrackAiInterpretation .image(width: 16.w, height: 16.w), SizedBox(width: 6.w), Text( StringName.trackAnalyseAiInterpretation, style: TextStyle( fontSize: 14.sp, color: '#333333'.color, fontWeight: FontWeight.bold), ) ], ), ), SizedBox(height: 10.w), Padding( padding: EdgeInsets.symmetric(horizontal: 12.w), child: TypewriterText( text: StringName.trackAnalyseAiInterpretationDetails, style: TextStyle(fontSize: 11.sp, color: '#666666'.color), onComplete: controller.onAnalyseTextComplete, ), ), SizedBox(height: 4.w), buildAnalyseErrorAddressView(), SizedBox(height: 4.w), Obx(() { return Visibility( visible: controller.showAnalyseRemainContent, child: Padding( padding: EdgeInsets.symmetric(horizontal: 12.w), child: TypewriterText( text: StringName.trackAnalyseAiInterpretationDetailsFinally, style: TextStyle(fontSize: 11.sp, color: '#666666'.color), onComplete: controller.onAnalyseFinishComplete, ), ), ); }), SizedBox(height: 12.w), ], ), ); } Widget buildAnalyseErrorAddressView() { return Obx(() { return AnimatedVisibility( duration: const Duration(milliseconds: 600), visible: controller.isShowAnalyseAddr, child: Column( children: [ for (int i = 0; i < controller.errorAddr.length; i++) ...[ Container( padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.w), child: Row( children: [ Expanded( child: Text( controller.errorAddr[i].addr ?? '', style: TextStyle(fontSize: 11.sp, color: '#666666'.color), ), ), SizedBox(width: 16.w), Text(controller.getErrorDistance(controller.errorAddr[i]), style: TextStyle(fontSize: 11.sp, color: '#666666'.color)) ], ), ), if (i < controller.errorAddr.length - 1) Container(width: 316.w, height: 1.w, color: '#EEEEEE'.color), ] ], ), ); }); } Widget buildAnalyseBtn() { return Positioned( top: 0, right: 10.w, child: GestureDetector( onTap: controller.onTrackRefreshClick, child: Container( padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 4.w), child: IntrinsicWidth( child: Row( children: [ Assets.images.iconTrackAnalyseRefresh.image(width: 12.w), SizedBox(width: 3.w), Text( StringName.trackAnalyseRefresh, style: TextStyle( fontSize: 12.sp, color: '#333333'.color, ), ), ], ), ), ), ), ); } Widget buildAIAnalyseView() { return Stack( children: [ Container( margin: EdgeInsets.only(bottom: 40.w), child: Assets.images.bgLocationAnalyse.image(width: double.infinity)), SafeArea( child: SizedBox( width: double.infinity, height: 317.w, child: Stack( alignment: Alignment.center, children: [ buildRobotView(), Obx(() { return Visibility( visible: controller.keywordDelegates != null, child: Lottie.asset( controller: controller.keywordLottieController, Assets.anim.locationLabel, onLoaded: controller.locationKeywordLottieLoad, delegates: controller.keywordDelegates), ); }), ], ), )), Positioned( bottom: 10.w, left: 0, right: 0, child: Column( children: [ Obx(() { return Text( controller.isRequestedAnalyse ? StringName.trackAnalyseDone : (controller.errorInfo?.addr == null ? StringName.trackAnalysing : StringName.trackErrorAddrAnalysing), style: TextStyle( fontSize: 16.sp, color: '#333333'.color, fontWeight: FontWeight.bold), ); }), SizedBox(height: 10.w), Obx(() { return Text( controller.isRequestedAnalyse ? StringName.trackAnalyseDoneDetail : StringName.trackAnalysingTips, style: TextStyle( fontSize: 13.sp, color: '#9D96AD'.color, fontWeight: FontWeight.bold), ); }) ], ), ) ], ); } Widget buildRobotView() { return SizedBox( width: 248.w, height: 248.w, child: Stack( children: [ Assets.images.bgLocationAnalyseAi .image(width: double.infinity, height: double.infinity), Center( child: ClipOval( child: SizedBox( width: 144.w, height: 144.w, child: Obx(() { if (!controller.videoReady) { return SizedBox.shrink(); } return Transform.scale( scale: 1.012, // 放大 3%,可以试试 1.01 ~ 1.05 child: VideoPlayer(controller.locaController), ); }), ), ), ) ], ), ); } Widget buildBackBtnView() { return SafeArea( child: GestureDetector( onTap: controller.back, child: Container( margin: EdgeInsets.only(top: 14.w, left: 12.w), decoration: BoxDecoration(boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10.w, offset: Offset(0, 2.w), ), ]), child: CommonView.getBackBtnView(), ), ), ); } }