From eb41ecaec40596e6e231e06280f8faeb1891a6a1 Mon Sep 17 00:00:00 2001 From: userGyl Date: Mon, 16 Mar 2026 16:00:38 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/app/src/main/AndroidManifest.xml | 42 ------------------- ln_jq_app/pubspec.lock | 10 ++--- ln_jq_app/pubspec.yaml | 1 + 3 files changed, 6 insertions(+), 47 deletions(-) diff --git a/ln_jq_app/android/app/src/main/AndroidManifest.xml b/ln_jq_app/android/app/src/main/AndroidManifest.xml index c23b807..5d75ff4 100644 --- a/ln_jq_app/android/app/src/main/AndroidManifest.xml +++ b/ln_jq_app/android/app/src/main/AndroidManifest.xml @@ -61,48 +61,6 @@ - - - - - - - - - - - - - - - - - - - - - - Date: Tue, 17 Mar 2026 13:31:58 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E9=9A=90=E7=A7=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ln_jq_app/assets/html/map.html | 4 +- .../lib/pages/b_page/reservation/view.dart | 36 ++++++++++++++++++ ln_jq_app/lib/pages/c_page/mine/view.dart | 38 +++++++++++++++++++ ln_jq_app/lib/pages/login/view.dart | 4 +- 4 files changed, 77 insertions(+), 5 deletions(-) diff --git a/ln_jq_app/assets/html/map.html b/ln_jq_app/assets/html/map.html index a4d16d3..dfb6c22 100644 --- a/ln_jq_app/assets/html/map.html +++ b/ln_jq_app/assets/html/map.html @@ -21,9 +21,7 @@ .amap-callamap, .amap-lib-driving-callBtn, .amap-copyright, - .amap-logo { - display: none !important; - } + .amap-logo{bottom: 60px} /* 去除高德默认的 label 边框 and 背景 */ .amap-marker-label { diff --git a/ln_jq_app/lib/pages/b_page/reservation/view.dart b/ln_jq_app/lib/pages/b_page/reservation/view.dart index ed89f3b..1d53aed 100644 --- a/ln_jq_app/lib/pages/b_page/reservation/view.dart +++ b/ln_jq_app/lib/pages/b_page/reservation/view.dart @@ -1,9 +1,13 @@ +import 'dart:io'; + +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:ln_jq_app/common/login_util.dart'; import 'package:ln_jq_app/pages/b_page/reservation/controller.dart'; import 'package:ln_jq_app/pages/c_page/message/view.dart'; +import 'package:ln_jq_app/pages/common/webview/view.dart'; class ReservationPage extends GetView { const ReservationPage({super.key}); @@ -36,6 +40,30 @@ class ReservationPage extends GetView { _buildSystemTips(), SizedBox(height: 24), _buildLogoutButton(), + SizedBox(height: 15.h), + Text.rich( + TextSpan( + style: const TextStyle(color: Colors.grey, fontSize: 13), + children: [ + TextSpan( + text: '《用户协议》', + style: TextStyle(color: Colors.blue, fontSize: 13), + recognizer: TapGestureRecognizer() + ..onTap = () { + openPage("用户协议", "https://lnh2e.com/user_agreement.html"); + }, + ), + TextSpan( + text: '《隐私政策》', + style: TextStyle(color: Colors.blue, fontSize: 13), + recognizer: TapGestureRecognizer() + ..onTap = () { + openPage("隐私政策", "https://lnh2e.com/privacy_agreement.html"); + }, + ), + ], + ), + ), SizedBox(height: 95.h), ], ), @@ -48,6 +76,14 @@ class ReservationPage extends GetView { ); } + void openPage(String title, String url) { + if (Platform.isIOS) { + openWebPage(url); + return; + } + Get.to(() => const WebViewPage(), arguments: {'title': title, 'url': url}); + } + /// 1. 顶部个人信息及统计栏 Widget _buildTopSection(BuildContext context) { return Container( diff --git a/ln_jq_app/lib/pages/c_page/mine/view.dart b/ln_jq_app/lib/pages/c_page/mine/view.dart index b816ca5..2543f33 100644 --- a/ln_jq_app/lib/pages/c_page/mine/view.dart +++ b/ln_jq_app/lib/pages/c_page/mine/view.dart @@ -1,10 +1,15 @@ +import 'dart:io'; + +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:getx_scaffold/common/index.dart'; import 'package:getx_scaffold/common/widgets/index.dart'; import 'package:ln_jq_app/common/login_util.dart'; +import 'package:ln_jq_app/common/styles/theme.dart'; import 'package:ln_jq_app/pages/c_page/message/view.dart'; +import 'package:ln_jq_app/pages/common/webview/view.dart'; import 'package:ln_jq_app/storage_service.dart'; import 'controller.dart'; @@ -38,6 +43,30 @@ class MinePage extends GetView { _buildSafetyReminderCard(), SizedBox(height: 24.h), _buildLogoutButton(), + SizedBox(height: 15.h), + Text.rich( + TextSpan( + style: const TextStyle(color: Colors.grey, fontSize: 13), + children: [ + TextSpan( + text: '《用户协议》', + style: TextStyle(color: Colors.blue, fontSize: 13), + recognizer: TapGestureRecognizer() + ..onTap = () { + openPage("用户协议", "https://lnh2e.com/user_agreement.html"); + }, + ), + TextSpan( + text: '《隐私政策》', + style: TextStyle(color: Colors.blue, fontSize: 13), + recognizer: TapGestureRecognizer() + ..onTap = () { + openPage("隐私政策", "https://lnh2e.com/privacy_agreement.html"); + }, + ), + ], + ), + ), SizedBox(height: 95.h), ], ), @@ -51,6 +80,15 @@ class MinePage extends GetView { ); } + void openPage(String title, String url) { + if (Platform.isIOS) { + openWebPage(url); + return; + } + Get.to(() => const WebViewPage(), arguments: {'title': title, 'url': url}); + } + + /// 构建顶部用户信息卡片 Widget _buildUserInfoCard() { return Card( diff --git a/ln_jq_app/lib/pages/login/view.dart b/ln_jq_app/lib/pages/login/view.dart index d23150c..ee15b18 100644 --- a/ln_jq_app/lib/pages/login/view.dart +++ b/ln_jq_app/lib/pages/login/view.dart @@ -150,7 +150,8 @@ class _LoginPageState extends State with SingleTickerProviderStateMix const SizedBox(height: 10), buildAgreement(), - const SizedBox(height: 40), + const SizedBox(height: 80), + _buildFooterSlogan() ], ), ), @@ -159,7 +160,6 @@ class _LoginPageState extends State with SingleTickerProviderStateMix ), ), ), - Positioned(left: 0, right: 0, bottom: 33.h, child: _buildFooterSlogan()), if (AppTheme.is_show_host) Positioned( top: 40.h, From 03b35f660c4172e6b6ced9e6cbface5aabe597c1 Mon Sep 17 00:00:00 2001 From: userGyl Date: Thu, 19 Mar 2026 14:41:32 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=8D=8F=E8=AE=AE=E5=89=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ln_jq_app/ios/Podfile.lock | 6 +- ln_jq_app/lib/pages/welcome/controller.dart | 89 ++++++++++++++++++++- 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/ln_jq_app/ios/Podfile.lock b/ln_jq_app/ios/Podfile.lock index a09f840..3b0366f 100644 --- a/ln_jq_app/ios/Podfile.lock +++ b/ln_jq_app/ios/Podfile.lock @@ -1,7 +1,7 @@ PODS: - AlicloudELS (1.0.3) - AlicloudPush (3.2.3): - - AlicloudELS (= 1.0.3) + - AlicloudELS (~> 1.0.3) - AlicloudUTDID (~> 1.0) - AlicloudUTDID (1.6.1) - aliyun_push_flutter (0.0.1): @@ -115,11 +115,11 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: AlicloudELS: fbf821383330465a5af84a033f36f263ae46ca41 - AlicloudPush: 95150880af380f64cf1741f5586047c17d36c1d9 + AlicloudPush: 52cbf38ffc20c07f039cbc72d5738745fd986215 AlicloudUTDID: 5d2f22d50e11eecd38f30bc7a48c71925ea90976 aliyun_push_flutter: 0fc2f048a08687ef256c0cfdd72dd7a550ef3347 connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd - device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896 + device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9 flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99 diff --git a/ln_jq_app/lib/pages/welcome/controller.dart b/ln_jq_app/lib/pages/welcome/controller.dart index 151e33a..0a381bc 100644 --- a/ln_jq_app/lib/pages/welcome/controller.dart +++ b/ln_jq_app/lib/pages/welcome/controller.dart @@ -1,16 +1,103 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:get/get.dart'; +import 'package:getx_scaffold/common/components/index.dart'; +import 'package:getx_scaffold/common/widgets/rich_text_x.dart'; import 'package:ln_jq_app/pages/home/view.dart'; import 'package:ln_jq_app/pages/login/view.dart'; import 'package:ln_jq_app/storage_service.dart'; +import '../common/webview/view.dart'; + class WelcomeController extends GetxController { @override void onReady() { super.onReady(); // 移除原生闪屏页(如果有的话) FlutterNativeSplash.remove(); - _startTimer(); + + if (Platform.isAndroid) { + if (StorageService.to.isPrivacyAgreed) { + _startTimer(); + } else { + showPrivacyDialog(); + } + } else if (Platform.isIOS) { + _startTimer(); + } + } + + void showPrivacyDialog() { + DialogX.to.showConfirmDialog( + title: "个人信息保护提示", + content: _buildDialogContent(), + confirmText: '同意', + cancelText: '不同意', + onConfirm: () async { + await StorageService.to.savePrivacyAgreed(true); + Get.offAll(() => const HomePage()); + }, + onCancel: () { + DialogX.to.showConfirmDialog( + title: "温馨提示", + content: RichTextX( + children: [ + TextSpanItem('如果您不同意'), + TextSpanItem( + '《隐私协议》', + onTap: () => openPage("隐私政策", "https://lnh2e.com/privacy_agreement.html"), + ), + TextSpanItem('和'), + TextSpanItem( + '《用户政策》', + onTap: () => openPage("用户协议", "https://lnh2e.com/user_agreement.html"), + ), + TextSpanItem( + ',很遗憾我们将无法为您提供服务。您需要同意以上协议后,才能使用本应用。\n\n我们将严格按照相关法律法规要求,坚决保护您的个人隐私和信息安全。', + ), + TextSpanItem('\n点击“同意”按钮,表示您已知情并同意以上协议。'), + ], + ), + confirmText: '同意并继续', + cancelText: '不同意', + onConfirm: () async { + await StorageService.to.savePrivacyAgreed(true); + Get.offAll(() => const HomePage()); + }, + onCancel: () { + SystemNavigator.pop(); + }, + ); + }, + ); + } + + Widget _buildDialogContent() { + return RichTextX( + children: [ + TextSpanItem('欢迎使用小羚羚!\n我们将通过'), + TextSpanItem( + '《隐私协议》', + onTap: () => openPage("隐私政策", "https://lnh2e.com/privacy_agreement.html"), + ), + TextSpanItem('和'), + TextSpanItem( + '《用户政策》', + onTap: () => openPage("用户协议", "https://lnh2e.com/user_agreement.html"), + ), + TextSpanItem( + ',帮助您了解我们为您提供的服务、我们如何处理个人信息以及您享有的权利。我们会严格按照相关法律法规要求,采取各种安全措施来保护您的个人信息。', + ), + TextSpanItem('\n点击“同意”按钮,表示您已知情并同意以上协议。'), + ], + ); + } + + void openPage(String title, String url) { + Get.to(() => const WebViewPage(), arguments: {'title': title, 'url': url}); } void _startTimer() { From 3f282d15c1477f46f62aa8bfdfa14574c0b6961c Mon Sep 17 00:00:00 2001 From: userGyl Date: Thu, 19 Mar 2026 16:37:57 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=8D=8F=E8=AE=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ln_jq_app/lib/pages/home/controller.dart | 15 ++++++----- ln_jq_app/lib/pages/login/view.dart | 32 ++++++++++++++++++------ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/ln_jq_app/lib/pages/home/controller.dart b/ln_jq_app/lib/pages/home/controller.dart index 998664f..ac8b213 100644 --- a/ln_jq_app/lib/pages/home/controller.dart +++ b/ln_jq_app/lib/pages/home/controller.dart @@ -29,14 +29,6 @@ class HomeController extends GetxController with BaseControllerMixin { @override void onInit() { super.onInit(); - - // 检查是否同意过隐私政策,只有同意后才初始化推送 - if (StorageService.to.isPrivacyAgreed) { - requestPermission(); - initAliyunPush(); - addPushCallback(); - } - FlutterNativeSplash.remove(); log('page-init'); @@ -159,6 +151,13 @@ class HomeController extends GetxController with BaseControllerMixin { // 根据登录状态和登录渠道返回不同的首页 Widget getHomePage() { if (StorageService.to.isLoggedIn) { + // 检查是否同意过隐私政策,只有同意后才初始化推送 + if (StorageService.to.isPrivacyAgreed) { + requestPermission(); + initAliyunPush(); + addPushCallback(); + } + if (StorageService.to.loginChannel == LoginChannel.station) { return B_BaseWidgetsPage(); } else if (StorageService.to.loginChannel == LoginChannel.driver) { diff --git a/ln_jq_app/lib/pages/login/view.dart b/ln_jq_app/lib/pages/login/view.dart index ee15b18..e6b00fa 100644 --- a/ln_jq_app/lib/pages/login/view.dart +++ b/ln_jq_app/lib/pages/login/view.dart @@ -140,9 +140,29 @@ class _LoginPageState extends State with SingleTickerProviderStateMix children: [ const SizedBox(height: 30), // 根据 Tab 显示不同的输入框 - _tabController.index == 0 + !_isAgreed + ? GestureDetector( + onTap: () => _handleLogin(controller), + behavior: HitTestBehavior.opaque, + child: Container( + width: double.infinity, + height: 55.h, + padding: const EdgeInsets.symmetric( + horizontal: 24, + ), + alignment: Alignment.centerLeft, + child: Text( + "请先阅读并同意用户协议和隐私政策", + style: TextStyle( + color: Colors.grey, + fontSize: 16, + ), + ), + ), + ) + : (_tabController.index == 0 ? _buildDriverInputFields(controller) - : _buildStationInputFields(controller), + : _buildStationInputFields(controller)), const SizedBox(height: 30), // 统一登录按钮 @@ -151,7 +171,7 @@ class _LoginPageState extends State with SingleTickerProviderStateMix const SizedBox(height: 10), buildAgreement(), const SizedBox(height: 80), - _buildFooterSlogan() + _buildFooterSlogan(), ], ), ), @@ -475,7 +495,6 @@ class _LoginPageState extends State with SingleTickerProviderStateMix } } - _processLoginResponse(responseData, "station", account); } catch (e) { dismissLoading(); @@ -539,7 +558,6 @@ class _LoginPageState extends State with SingleTickerProviderStateMix Logger.d("暂时不处理 查询车辆信息失败的情况"); } - dismissLoading(); Get.offAll(() => BaseWidgetsPage()); } else { @@ -596,9 +614,7 @@ class _LoginPageState extends State with SingleTickerProviderStateMix } // 添加推送回调 - _aliyunPush.addMessageReceiver( - onNotificationOpened: _onNotificationOpened, - ); + _aliyunPush.addMessageReceiver(onNotificationOpened: _onNotificationOpened); isPushInitialized = true; Logger.d('推送服务初始化成功'); From a497bc64696011a9c49c5f1557537ea51c911c50 Mon Sep 17 00:00:00 2001 From: userGyl Date: Thu, 19 Mar 2026 17:41:28 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=B8=85=E7=90=86=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ln_jq_app/pubspec.lock | 8 -------- ln_jq_app/pubspec.yaml | 1 - 2 files changed, 9 deletions(-) diff --git a/ln_jq_app/pubspec.lock b/ln_jq_app/pubspec.lock index 06da830..e2516a6 100644 --- a/ln_jq_app/pubspec.lock +++ b/ln_jq_app/pubspec.lock @@ -741,14 +741,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" - mobile_scanner: - dependency: "direct main" - description: - name: mobile_scanner - sha256: c6184bf2913dd66be244108c9c27ca04b01caf726321c44b0e7a7a1e32d41044 - url: "https://pub.flutter-io.cn" - source: hosted - version: "7.1.4" modal_bottom_sheet: dependency: transitive description: diff --git a/ln_jq_app/pubspec.yaml b/ln_jq_app/pubspec.yaml index 3700dca..cdd5ccc 100644 --- a/ln_jq_app/pubspec.yaml +++ b/ln_jq_app/pubspec.yaml @@ -45,7 +45,6 @@ dependencies: dropdown_button2: ^2.3.8 image_picker: ^1.2.1 # 用于从相册选择图片 image: ^4.5.4 - mobile_scanner: ^7.1.4 flutter_pdfview: 1.4.3 #显示pdf photo_view: ^0.15.0 #操作图片 flutter_inappwebview: ^6.1.5 # WebView插件