协议同意
This commit is contained in:
26
ln_jq_app/lib/pages/common/webview/controller.dart
Normal file
26
ln_jq_app/lib/pages/common/webview/controller.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class WebController extends GetxController {
|
||||
late String title;
|
||||
late String url;
|
||||
|
||||
final RxDouble progress = 0.0.obs;
|
||||
InAppWebViewController? webViewController;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
// 从参数中获取标题和URL
|
||||
title = Get.arguments['title'] ?? '详情';
|
||||
url = Get.arguments['url'] ?? '';
|
||||
}
|
||||
|
||||
void onWebViewCreated(InAppWebViewController controller) {
|
||||
webViewController = controller;
|
||||
}
|
||||
|
||||
void onProgressChanged(InAppWebViewController controller, int progressValue) {
|
||||
progress.value = progressValue / 100;
|
||||
}
|
||||
}
|
||||
50
ln_jq_app/lib/pages/common/webview/view.dart
Normal file
50
ln_jq_app/lib/pages/common/webview/view.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'controller.dart';
|
||||
|
||||
class WebViewPage extends GetView<WebController> {
|
||||
const WebViewPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Get.put(WebController());
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(controller.title),
|
||||
centerTitle: true,
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(2.0),
|
||||
child: Obx(
|
||||
() => controller.progress.value < 1.0
|
||||
? LinearProgressIndicator(
|
||||
value: controller.progress.value,
|
||||
backgroundColor: Colors.transparent,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Theme.of(context).primaryColor,
|
||||
),
|
||||
minHeight: 2.0,
|
||||
)
|
||||
: const SizedBox(height: 2.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: InAppWebView(
|
||||
initialUrlRequest: URLRequest(url: WebUri(controller.url)),
|
||||
initialSettings: InAppWebViewSettings(
|
||||
isInspectable: true,
|
||||
javaScriptEnabled: true,
|
||||
javaScriptCanOpenWindowsAutomatically: true,
|
||||
useShouldOverrideUrlLoading: true,
|
||||
mixedContentMode: MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW,
|
||||
mediaPlaybackRequiresUserGesture: false,
|
||||
allowsInlineMediaPlayback: true,
|
||||
),
|
||||
onWebViewCreated: controller.onWebViewCreated,
|
||||
onProgressChanged: controller.onProgressChanged,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:aliyun_push_flutter/aliyun_push_flutter.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -9,6 +12,7 @@ import 'package:ln_jq_app/common/model/vehicle_info.dart';
|
||||
import 'package:ln_jq_app/common/styles/theme.dart';
|
||||
import 'package:ln_jq_app/pages/b_page/base_widgets/view.dart';
|
||||
import 'package:ln_jq_app/pages/c_page/base_widgets/view.dart';
|
||||
import 'package:ln_jq_app/pages/common/webview/view.dart';
|
||||
import 'package:ln_jq_app/pages/login/controller.dart';
|
||||
import 'package:ln_jq_app/pages/url_host/view.dart';
|
||||
import 'package:ln_jq_app/storage_service.dart';
|
||||
@@ -85,7 +89,7 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
|
||||
margin: EdgeInsets.all(15),
|
||||
elevation: 4,
|
||||
child: Container(
|
||||
height: cLogin ? 285.h : 360.h,
|
||||
height: cLogin ? 290.h : 365.h,
|
||||
padding: EdgeInsets.all(15),
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -165,6 +169,20 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
|
||||
SizedBox(height: 20.h),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
if (!_isAgreed) {
|
||||
DialogX.to.showConfirmDialog(
|
||||
icon: DialogIcon.warn,
|
||||
content: _buildDialogContent(),
|
||||
confirmText: '同意',
|
||||
cancelText: '拒绝',
|
||||
onConfirm: () {
|
||||
_isAgreed = true;
|
||||
controller.updateUi();
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
String password = controller.driverIdentityController.text;
|
||||
if (password.isEmpty) {
|
||||
showToast("请输入密码");
|
||||
@@ -241,6 +259,7 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
|
||||
),
|
||||
child: Text('登录'),
|
||||
),
|
||||
buildAgreement(),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -323,6 +342,20 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
),
|
||||
onPressed: () async {
|
||||
if (!_isAgreed) {
|
||||
DialogX.to.showConfirmDialog(
|
||||
icon: DialogIcon.warn,
|
||||
content: _buildDialogContent(),
|
||||
confirmText: '同意',
|
||||
cancelText: '拒绝',
|
||||
onConfirm: () {
|
||||
_isAgreed = true;
|
||||
controller.updateUi();
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
String account = controller.stationIdController.text;
|
||||
String password = controller.passwordController.text;
|
||||
|
||||
@@ -393,10 +426,93 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
|
||||
},
|
||||
child: Text('登录'),
|
||||
),
|
||||
buildAgreement(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
bool _isAgreed = false;
|
||||
|
||||
Widget buildAgreement() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 13.h),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// 勾选框
|
||||
SizedBox(
|
||||
width: 22.w,
|
||||
height: 22.h,
|
||||
child: Checkbox(
|
||||
value: _isAgreed,
|
||||
activeColor: AppTheme.themeColor,
|
||||
// 简单的圆角样式
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
|
||||
onChanged: (bool? value) {
|
||||
setState(() {
|
||||
_isAgreed = value ?? false;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
// 富文本协议部分
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: '我已阅读并同意',
|
||||
style: const TextStyle(color: Colors.grey, fontSize: 13),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '《用户协议》',
|
||||
style: TextStyle(color: AppTheme.themeColor, fontSize: 13),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
openPage("用户协议", "https://lnh2e.com/user_agreement.html");
|
||||
},
|
||||
),
|
||||
const TextSpan(text: ' 和 '),
|
||||
TextSpan(
|
||||
text: '《隐私政策》',
|
||||
style: TextStyle(color: AppTheme.themeColor, fontSize: 13),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
openPage("隐私政策", "https://lnh2e.com/privacy_agreement.html");
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDialogContent() {
|
||||
return RichTextX(
|
||||
children: [
|
||||
TextSpanItem('请阅读并同意'),
|
||||
TextSpanItem(
|
||||
'《隐私协议》',
|
||||
onTap: () => openPage("隐私政策", "https://lnh2e.com/privacy_agreement.html"),
|
||||
),
|
||||
TextSpanItem('和'),
|
||||
TextSpanItem(
|
||||
'《用户政策》',
|
||||
onTap: () => openPage("用户协议", "https://lnh2e.com/user_agreement.html"),
|
||||
),
|
||||
TextSpanItem(',我们将在协议框架内为您提供更优质的服务。'),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void openPage(String title, String url) {
|
||||
if (Platform.isIOS) {
|
||||
openWebPage(url);
|
||||
return;
|
||||
}
|
||||
Get.to(() => const WebViewPage(), arguments: {'title': title, 'url': url});
|
||||
}
|
||||
|
||||
final _aliyunPush = AliyunPushFlutter();
|
||||
|
||||
void addAlias(String alias) async {
|
||||
|
||||
Reference in New Issue
Block a user