diff --git a/lib/features/my/presentation/pages/my_page.dart b/lib/features/my/presentation/pages/my_page.dart index d05eb0af..8f83ed7e 100644 --- a/lib/features/my/presentation/pages/my_page.dart +++ b/lib/features/my/presentation/pages/my_page.dart @@ -1,10 +1,194 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../../../web_view/web_view_page.dart'; +import '../web_view/web_view_page.dart'; // 相对路径 + + class MyPage extends StatelessWidget { const MyPage({super.key}); @override Widget build(BuildContext context) { - return Scaffold(body: Center(child: Text('Welcome My page'))); + return Scaffold( + body: SafeArea( + child: SingleChildScrollView( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 顶部用户信息 + _buildUserInfo(), + + SizedBox(height: 16), + + // 中间横幅 + _buildBanner(context), + + SizedBox(height: 16), + + // 功能列表 + _buildFunctionList(context), + + SizedBox(height: 16), + + // 退出登录按钮 + _buildLogoutButton(), + ], + ), + ), + ), + ); + } + + Widget _buildUserInfo() { + return Row( + children: [ + Container( + width: 48, + height: 48, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + image: NetworkImage('https://pic4.zhimg.com/v2-c34c61a90095abb8713de9d1dca7ec7b_r.jpg'), + fit: BoxFit.cover, + ), + ), + ), + SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('宋', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + Text('用户id:songchunyi', style: TextStyle(fontSize: 12, color: Colors.grey)), + ], + ), + ), + IconButton( + icon: Icon(Icons.edit), + onPressed: () {}, + ), + Spacer(), + IconButton( + icon: Icon(Icons.add), + onPressed: () {}, + ), + ], + ); + } + + Widget _buildBanner(BuildContext context) { // 添加 context 参数 + return GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => WebViewPage(url: 'https://www.satabot.com/'), + ), + ); + }, + child: Container( + width: double.infinity, + height: 160, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + image: DecorationImage( + image: NetworkImage('https://c.53326.com/d/file/lan20221010/fyhj0ibovbp.jpg'), + fit: BoxFit.cover, + ), + ), + child: Stack( + children: [ + Positioned( + top: 12, + right: 12, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.5), + borderRadius: BorderRadius.circular(4), + ), + child: Text( + '了解我们', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + Positioned( + left: 12, + bottom: 12, + child: Text( + 'AI赋能农业', + style: TextStyle(color: Colors.white, fontSize: 16), + ), + ), + ], + ), + ), + ); + } + + + Widget _buildFunctionList(BuildContext context) { // 添加 context 参数 + //https://www.satabot.com/ + final items = [ + {'icon': Icons.play_arrow, 'title': '操作视频', 'url': 'https://www.satabot.com/Support/index.html'}, + {'icon': Icons.car_rental, 'title': '租赁服务', 'url': 'https://www.satabot.com/Leasing.html'}, + {'icon': Icons.help_outline, 'title': '帮助与支持', 'url': 'https://www.satabot.com/support/index.html'}, + {'icon': Icons.policy, 'title': '售后政策', 'url': 'https://www.satabot.com/Aftersales-Service.html'}, + ]; + + + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow(color: Colors.grey.withOpacity(0.1), blurRadius: 4), + ], + ), + child: ListView.builder( + shrinkWrap: true, + itemCount: items.length, + itemBuilder: (context, index) { + final item = items[index]; + return ListTile( + leading: Icon(item['icon'] as IconData), + title: Text(item['title'] as String), + trailing: Icon(Icons.arrow_forward), + onTap: () { + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => WebViewPage(url: item['url'] as String), + ), + ); + }, + ); + }, + ), + ); + } + + Widget _buildLogoutButton() { + return ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + foregroundColor: Colors.red, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.exit_to_app, size: 16, color: Colors.red), + SizedBox(width: 8), + Text('退出登录'), + ], + ), + ); } } diff --git a/lib/features/my/presentation/web_view/web_view_page.dart b/lib/features/my/presentation/web_view/web_view_page.dart new file mode 100644 index 00000000..b9f78bb0 --- /dev/null +++ b/lib/features/my/presentation/web_view/web_view_page.dart @@ -0,0 +1 @@ +// TODO Implement this library. \ No newline at end of file diff --git a/lib/features/remote_control/presentation/widgets/top_status_bar.dart b/lib/features/remote_control/presentation/widgets/top_status_bar.dart index b23881a2..e74d1db4 100644 --- a/lib/features/remote_control/presentation/widgets/top_status_bar.dart +++ b/lib/features/remote_control/presentation/widgets/top_status_bar.dart @@ -16,6 +16,22 @@ class TopStatusBar extends StatelessWidget { // 监听全局设备状态 final deviceState = context.watch().state; final device = deviceState.selectedDevice; + ControlMode _parseControlMode(String modeString) { + switch (modeString.toUpperCase()) { + case 'BLE': + return ControlMode.BLE; + case 'LOCAL': + return ControlMode.LOCAL; + case 'TCP': + return ControlMode.TCP; + case 'NONE': + return ControlMode.NONE; + case 'OTHER': + return ControlMode.OTHER; + default: + return ControlMode.NONE; + } + } // 监听局部遥控状态 final remoteState = context.watch().state; @@ -61,7 +77,7 @@ class TopStatusBar extends StatelessWidget { const Spacer(), // TODO - _buildControlModeChip(,remoteState.runningStatusModel.controlMode), + _buildControlModeChip( _parseControlMode(remoteState.runningStatusModel.controlMode)), const SizedBox(width: 8), diff --git a/lib/features/web_view/web_view_page.dart b/lib/features/web_view/web_view_page.dart new file mode 100644 index 00000000..be15b448 --- /dev/null +++ b/lib/features/web_view/web_view_page.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class WebViewPage extends StatefulWidget { + final String url; + final String title; + + const WebViewPage({ + Key? key, + required this.url, + this.title = '' + }) : super(key: key); + + @override + State createState() => _WebViewPageState(); +} + +class _WebViewPageState extends State { + late final WebViewController _controller; + + @override + void initState() { + super.initState(); + _controller = WebViewController() + ..loadRequest(Uri.parse(widget.url)) + ..setJavaScriptMode(JavaScriptMode.unrestricted); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title.isNotEmpty ? widget.title : '网页浏览'), + leading: IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () => Navigator.of(context).pop(), + ), + ), + body: WebViewWidget(controller: _controller), + ); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 6ff70be1..201371fe 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -12,6 +12,7 @@ import package_info_plus import path_provider_foundation import sentry_flutter import shared_preferences_foundation +import webview_flutter_wkwebview func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) @@ -21,4 +22,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index aec7f63a..0d16fe0b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -395,10 +395,10 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: ba03d03bcaa2f6cb7bd920e3b5027181db75ab524f8891c8bc3aa603885b8055 + sha256: e20ff62b158b96f392bfc8afe29dee1503c94fbea2cbe8186fd59b756b8ae982 url: "https://pub.flutter-io.cn" source: hosted - version: "6.3.3" + version: "5.1.0" google_nav_bar: dependency: "direct main" description: @@ -1028,6 +1028,38 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.3.0" + webview_flutter: + dependency: "direct main" + description: + name: webview_flutter + sha256: a3da219916aba44947d3a5478b1927876a09781174b5a2b67fa5be0555154bf9 + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.13.1" + webview_flutter_android: + dependency: transitive + description: + name: webview_flutter_android + sha256: eeeb3fcd5f0ff9f8446c9f4bbc18a99b809e40297528a3395597d03aafb9f510 + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.10.11" + webview_flutter_platform_interface: + dependency: transitive + description: + name: webview_flutter_platform_interface + sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.14.0" + webview_flutter_wkwebview: + dependency: transitive + description: + name: webview_flutter_wkwebview + sha256: e49f378ed066efb13fc36186bbe0bd2425630d4ea0dbc71a18fdd0e4d8ed8ebc + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.23.5" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 9129b9ef..2b9161c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -75,7 +75,7 @@ dependencies: google_nav_bar: ^5.0.7 # ===== 字体 ===== - google_fonts: ^6.2.1 + google_fonts: ^5.1.0 # 或其他稳定版本 # ===== WebView ===== # flutter_inappwebview: ^6.1.5 @@ -99,6 +99,9 @@ dependencies: path_provider: ^2.1.5 intl: ^0.20.2 + webview_flutter: ^4.4.2 # 将此行移到这里 + + dev_dependencies: flutter_test: