Browse Source

[new]新增确认弹窗

Destiny 1 year ago
parent
commit
60e2b51bc0
3 changed files with 482 additions and 226 deletions
  1. 80 1
      lib/module/login/controller.dart
  2. 173 225
      lib/module/login/view.dart
  3. 229 0
      lib/widget/alert_dialog.dart

+ 80 - 1
lib/module/login/controller.dart

@@ -1,7 +1,12 @@
 import 'package:electronic_assistant/base/base_controller.dart';
 import 'package:electronic_assistant/data/repositories/account_repository.dart';
+import 'package:electronic_assistant/popup/talk_popup.dart';
 import 'package:electronic_assistant/utils/error_handler.dart';
+import 'package:electronic_assistant/utils/expand.dart';
 import 'package:electronic_assistant/utils/toast_util.dart';
+import 'package:electronic_assistant/widget/alert_dialog.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
 
 class LoginController extends BaseController {
@@ -28,13 +33,87 @@ class LoginController extends BaseController {
   }
 
   void login() {
+    FocusScope.of(Get.context!).requestFocus(FocusNode());
+
+    if (phone.value.isEmpty) {
+      ToastUtil.showToast("请输入手机号");
+      return;
+    }
+
     if (code.value.isEmpty) {
       ToastUtil.showToast("请输入验证码");
       return;
     }
 
     if (!isAgree.value) {
-      ToastUtil.showToast("请先阅读并同意《隐私政策》和《用户使用协议》");
+      EAAlertDialog.show(
+        title: "隐私政策及权限说明",
+        contentWidget: Wrap(
+          children: [
+            Text(
+              "进入下一步前,请先阅读并同意小听的",
+              textAlign: TextAlign.center,
+              style: TextStyle(
+                color: "#5F5F61".toColor(),
+                fontSize: 14,
+                decoration: TextDecoration.none,
+              ),
+            ),
+            GestureDetector(
+              onTap: () {},
+              child: Text(
+                "《隐私政策》",
+                textAlign: TextAlign.center,
+                style: TextStyle(
+                  color: "#5E8BFF".toColor(),
+                  fontSize: 14,
+                  decoration: TextDecoration.none,
+                ),
+              ),
+            ),
+            Text(
+              "和",
+              textAlign: TextAlign.center,
+              style: TextStyle(
+                color: "#5F5F61".toColor(),
+                fontSize: 14,
+                decoration: TextDecoration.none,
+              ),
+            ),
+            GestureDetector(
+              onTap: () {},
+              child: Text(
+                "《用户试用协议》",
+                textAlign: TextAlign.center,
+                style: TextStyle(
+                  color: "#5E8BFF".toColor(),
+                  fontSize: 14,
+                  decoration: TextDecoration.none,
+                ),
+              ),
+            ),
+            Text(
+              "。",
+              textAlign: TextAlign.center,
+              style: TextStyle(
+                color: "#5F5F61".toColor(),
+                fontSize: 14,
+                decoration: TextDecoration.none,
+              ),
+            ),
+          ],
+        ),
+        cancelText: "不同意",
+        confirmText: "同意并继续",
+        cancelOnTap: () {
+          EAAlertDialog.dismiss();
+        },
+        confirmOnTap: () {
+          EAAlertDialog.dismiss();
+          isAgree.value = true;
+          login();
+        },
+      );
       return;
     }
 

+ 173 - 225
lib/module/login/view.dart

@@ -29,7 +29,7 @@ class LoginPage extends BasePage<LoginController> {
   Widget buildBody(BuildContext context) {
     return Stack(
       children: [
-        buildBackgroundImage(),
+        _buildBackgroundImage(),
         Scaffold(
           resizeToAvoidBottomInset: false,
           backgroundColor: Colors.transparent,
@@ -52,174 +52,10 @@ class LoginPage extends BasePage<LoginController> {
                 height: 71.h,
                 child: Image(image: Assets.images.iconLoginLogo.provider()),
               ),
-              Container(
-                margin: EdgeInsets.only(top: 44.h, left: 28.w, right: 28.w),
-                alignment: Alignment.center,
-                height: 44.h,
-                decoration: BoxDecoration(
-                  border: Border(
-                    bottom: BorderSide(
-                      width: 1.0,
-                      color: "#F0F0F0".toColor(),
-                    ),
-                  ),
-                ),
-                child: TextField(
-                  maxLines: 1,
-                  textAlignVertical: TextAlignVertical.center,
-                  textInputAction: TextInputAction.search,
-                  decoration: InputDecoration(
-                    hintText: '输入手机号码',
-                    hintStyle:
-                        TextStyle(fontSize: 16, color: "#AFAFAF".toColor()),
-                    labelStyle: const TextStyle(
-                      fontSize: 16,
-                      color: ColorName.primaryTextColor,
-                    ),
-                    contentPadding: const EdgeInsets.all(0),
-                    border:
-                        const OutlineInputBorder(borderSide: BorderSide.none),
-                    enabled: true,
-                  ),
-                  style: TextStyle(fontSize: 14.sp),
-                  onChanged: (value) {
-                    controller.setPhone(value);
-                  },
-                ),
-              ),
-              Container(
-                margin: EdgeInsets.only(top: 36.h, left: 28.w, right: 28.w),
-                alignment: Alignment.center,
-                height: 44.h,
-                decoration: BoxDecoration(
-                  border: Border(
-                    bottom: BorderSide(
-                      width: 1.0,
-                      color: "#F0F0F0".toColor(),
-                    ),
-                  ),
-                ),
-                child: Row(
-                  children: [
-                    Expanded(
-                      child: TextField(
-                        maxLines: 1,
-                        textAlignVertical: TextAlignVertical.center,
-                        textInputAction: TextInputAction.search,
-                        decoration: InputDecoration(
-                          hintText: '输入验证码',
-                          hintStyle: TextStyle(
-                              fontSize: 16, color: "#AFAFAF".toColor()),
-                          labelStyle: const TextStyle(
-                            fontSize: 16,
-                            color: ColorName.primaryTextColor,
-                          ),
-                          contentPadding: const EdgeInsets.all(0),
-                          border: const OutlineInputBorder(
-                              borderSide: BorderSide.none),
-                          enabled: true,
-                        ),
-                        style: TextStyle(fontSize: 14.sp),
-                        onChanged: (value) {
-                          controller.setCode(value);
-                        },
-                      ),
-                    ),
-                    LoginCodeBtn(
-                      onTapCallback: () {
-                        controller.getUserCode();
-                      },
-                      available: true,
-                    ),
-                  ],
-                ),
-              ),
-              GestureDetector(
-                onTap: () {
-                  controller.login();
-                },
-                child: Container(
-                  margin: EdgeInsets.only(
-                    top: 54.h,
-                    left: 28.w,
-                    right: 28.w,
-                  ),
-                  height: 48.h,
-                  alignment: Alignment.center,
-                  decoration: BoxDecoration(
-                    gradient: LinearGradient(
-                      colors: ['#6177F2'.toColor(), '#8B9DFF'.toColor()],
-                      stops: const [0, 1.0],
-                    ),
-                    borderRadius: BorderRadius.circular(8),
-                  ),
-                  child: const Text(
-                    "登录",
-                    style: TextStyle(
-                      color: ColorName.white,
-                      fontSize: 16,
-                      fontWeight: FontWeight.w500,
-                    ),
-                  ),
-                ),
-              ),
-              Container(
-                margin: EdgeInsets.only(left: 28.w, top: 16.h),
-                child: Row(
-                  children: [
-                    Obx(
-                      () {
-                        return GestureDetector(
-                          onTap: () {
-                            controller.isAgree.value =
-                                !controller.isAgree.value;
-                          },
-                          child: SizedBox(
-                              width: 20.w,
-                              height: 20.w,
-                              child: controller.isAgree.value
-                                  ? Assets.images.iconSelectTrue.image()
-                                  : Assets.images.iconSelectFalse.image()),
-                        );
-                      },
-                    ),
-                    Text(
-                      "我已阅读并同意",
-                      style: TextStyle(
-                        color: "#AFAFAF".toColor(),
-                        fontSize: 12,
-                      ),
-                    ),
-                    GestureDetector(
-                      onTap: () {},
-                      child: Text(
-                        "《隐私政策》",
-                        style: TextStyle(
-                          color: "#5E8BFF".toColor(),
-                          fontSize: 12,
-                        ),
-                      ),
-                    ),
-                    Text(
-                      "和",
-                      style: TextStyle(
-                        color: "#AFAFAF".toColor(),
-                        fontSize: 12,
-                      ),
-                    ),
-                    GestureDetector(
-                      onTap: () {},
-                      child: Text(
-                        "《用户使用协议》",
-                        style: TextStyle(
-                          color: "#5E8BFF".toColor(),
-                          fontSize: 12,
-                        ),
-                      ),
-                    ),
-                  ],
-                ),
-              ),
+              _buildPhoneTextField(),
+              _buildCodeTextField(),
+              _buildLoginBtn(),
+              _buildAgreeText(),
             ],
           ),
         ),
@@ -263,74 +99,186 @@ class LoginPage extends BasePage<LoginController> {
     // );
   }
 
-  Widget buildBackgroundImage() {
+  // 背景图片
+  Widget _buildBackgroundImage() {
     return Image(image: Assets.images.bgLogin.provider());
   }
 
-  Widget buildBackgroundGradient() {
-    return Stack(
-      children: [
-        Container(
-          width: 1.sw,
-          height: 1.sh,
-          decoration: BoxDecoration(
-            gradient: LinearGradient(
-              colors: [
-                '#FFC0CF'.toColor().withOpacity(0.62),
-                '#F6F6F6'.toColor().withOpacity(0)
-              ],
-              begin: Alignment.topCenter,
-              end: Alignment.bottomCenter,
-              stops: const [0, 1.0],
-            ),
+  // 电话号码输入框
+  Widget _buildPhoneTextField() {
+    return Container(
+      margin: EdgeInsets.only(top: 44.h, left: 28.w, right: 28.w),
+      alignment: Alignment.center,
+      height: 44.h,
+      decoration: BoxDecoration(
+        border: Border(
+          bottom: BorderSide(
+            width: 1.0,
+            color: "#F0F0F0".toColor(),
           ),
         ),
-        Container(
-          width: 1.sw,
-          height: 1.sh,
-          decoration: BoxDecoration(
-            gradient: LinearGradient(
-              colors: [
-                '#CADCFD'.toColor().withOpacity(0.72),
-                '#F6F5F8'.toColor().withOpacity(0.72)
-              ],
-              begin: Alignment.topCenter,
-              end: Alignment.bottomCenter,
-              stops: const [0, 1.0],
-            ),
+      ),
+      child: TextField(
+        maxLines: 1,
+        textAlignVertical: TextAlignVertical.center,
+        textInputAction: TextInputAction.search,
+        decoration: InputDecoration(
+          hintText: '输入手机号码',
+          hintStyle: TextStyle(fontSize: 16, color: "#AFAFAF".toColor()),
+          labelStyle: const TextStyle(
+            fontSize: 16,
+            color: ColorName.primaryTextColor,
           ),
+          contentPadding: const EdgeInsets.all(0),
+          border: const OutlineInputBorder(borderSide: BorderSide.none),
+          enabled: true,
         ),
-        Container(
-          width: 1.sw,
-          height: 1.sh,
-          decoration: BoxDecoration(
-            gradient: LinearGradient(
-              colors: [
-                '#B0BCFF'.toColor(),
-                '#FFFFFF'.toColor(),
-              ],
-              begin: Alignment.topCenter,
-              end: Alignment.bottomCenter,
-              stops: const [0, 1.0],
-            ),
+        style: TextStyle(fontSize: 14.sp),
+        onChanged: (value) {
+          controller.setPhone(value);
+        },
+      ),
+    );
+  }
+
+  // 验证码输入框
+  Widget _buildCodeTextField() {
+    return Container(
+      margin: EdgeInsets.only(top: 36.h, left: 28.w, right: 28.w),
+      alignment: Alignment.center,
+      height: 44.h,
+      decoration: BoxDecoration(
+        border: Border(
+          bottom: BorderSide(
+            width: 1.0,
+            color: "#F0F0F0".toColor(),
           ),
         ),
-        Container(
-          width: 1.sw,
-          height: 1.sh,
-          decoration: BoxDecoration(
-            gradient: LinearGradient(
-              colors: [
-                '#7E92FF'.toColor(),
-                '#B0BCFF'.toColor(),
-              ],
-              begin: Alignment.topCenter,
-              end: Alignment.bottomCenter,
-              stops: const [0, 1.0],
+      ),
+      child: Row(
+        children: [
+          Expanded(
+            child: TextField(
+              maxLines: 1,
+              textAlignVertical: TextAlignVertical.center,
+              textInputAction: TextInputAction.search,
+              decoration: InputDecoration(
+                hintText: '输入验证码',
+                hintStyle: TextStyle(fontSize: 16, color: "#AFAFAF".toColor()),
+                labelStyle: const TextStyle(
+                  fontSize: 16,
+                  color: ColorName.primaryTextColor,
+                ),
+                contentPadding: const EdgeInsets.all(0),
+                border: const OutlineInputBorder(borderSide: BorderSide.none),
+                enabled: true,
+              ),
+              style: TextStyle(fontSize: 14.sp),
+              onChanged: (value) {
+                controller.setCode(value);
+              },
             ),
           ),
+          LoginCodeBtn(
+            onTapCallback: () {
+              controller.getUserCode();
+            },
+            available: true,
+          ),
+        ],
+      ),
+    );
+  }
+
+  // 登录按钮
+  Widget _buildLoginBtn() {
+    return GestureDetector(
+      onTap: () {
+        controller.login();
+      },
+      child: Container(
+        margin: EdgeInsets.only(
+          top: 54.h,
+          left: 28.w,
+          right: 28.w,
         ),
-      ],
+        height: 48.h,
+        alignment: Alignment.center,
+        decoration: BoxDecoration(
+          gradient: LinearGradient(
+            colors: ['#6177F2'.toColor(), '#8B9DFF'.toColor()],
+            stops: const [0, 1.0],
+          ),
+          borderRadius: BorderRadius.circular(8),
+        ),
+        child: const Text(
+          "登录",
+          style: TextStyle(
+            color: ColorName.white,
+            fontSize: 16,
+            fontWeight: FontWeight.w500,
+          ),
+        ),
+      ),
+    );
+  }
+
+  Widget _buildAgreeText() {
+    return Container(
+      margin: EdgeInsets.only(left: 28.w, top: 16.h),
+      child: Row(
+        children: [
+          Obx(
+            () {
+              return GestureDetector(
+                onTap: () {
+                  controller.isAgree.value = !controller.isAgree.value;
+                },
+                child: SizedBox(
+                    width: 20.w,
+                    height: 20.w,
+                    child: controller.isAgree.value
+                        ? Assets.images.iconSelectTrue.image()
+                        : Assets.images.iconSelectFalse.image()),
+              );
+            },
+          ),
+          Text(
+            "我已阅读并同意",
+            style: TextStyle(
+              color: "#AFAFAF".toColor(),
+              fontSize: 12,
+            ),
+          ),
+          GestureDetector(
+            onTap: () {},
+            child: Text(
+              "《隐私政策》",
+              style: TextStyle(
+                color: "#5E8BFF".toColor(),
+                fontSize: 12,
+              ),
+            ),
+          ),
+          Text(
+            "和",
+            style: TextStyle(
+              color: "#AFAFAF".toColor(),
+              fontSize: 12,
+            ),
+          ),
+          GestureDetector(
+            onTap: () {},
+            child: Text(
+              "《用户使用协议》",
+              style: TextStyle(
+                color: "#5E8BFF".toColor(),
+                fontSize: 12,
+              ),
+            ),
+          ),
+        ],
+      ),
     );
   }
 }

+ 229 - 0
lib/widget/alert_dialog.dart

@@ -0,0 +1,229 @@
+import 'package:electronic_assistant/popup/talk_popup.dart';
+import 'package:electronic_assistant/utils/expand.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+
+class EAAlertDialog {
+  static void show({
+    String? title,
+    String? contentText,
+    Widget? contentWidget,
+    String? confirmText,
+    String? cancelText,
+    VoidCallback? cancelOnTap,
+    VoidCallback? confirmOnTap,
+    VoidCallback? onDismiss,
+  }) {
+    SmartDialog.show(
+      builder: (_) {
+        return _EAAlertDialog(
+            title: title,
+            content: contentText,
+            contentWidget: contentWidget,
+            confirmText: confirmText,
+            cancelText: cancelText,
+            confirmOnTap: confirmOnTap,
+            cancelOnTap: cancelOnTap);
+      },
+      tag: "EAAlertDialog",
+      onDismiss: onDismiss,
+      clickMaskDismiss: false,
+    );
+  }
+
+  static void dismiss() {
+    SmartDialog.dismiss(tag: "EAAlertDialog");
+  }
+}
+
+class _EAAlertDialog extends Dialog {
+  // 标题
+  final String? title;
+
+  final Widget? contentWidget;
+
+  // 内容
+  final String? content;
+
+  // 取消按钮文字
+  final String? cancelText;
+
+  // 取消按钮回调
+  final VoidCallback? cancelOnTap;
+
+  // 确认按钮文字
+  final String? confirmText;
+
+  // 确认按钮文字回调
+  final VoidCallback? confirmOnTap;
+
+  const _EAAlertDialog({
+    this.title,
+    this.content,
+    this.contentWidget,
+    required this.cancelText,
+    required this.confirmText,
+    this.cancelOnTap,
+    this.confirmOnTap,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: Column(
+        children: [
+          const Spacer(),
+
+          Container(
+            alignment: Alignment.center,
+            padding: EdgeInsets.symmetric(vertical: 24.h, horizontal: 16.w),
+            width: ScreenUtil().screenWidth - 80.w,
+            decoration: BoxDecoration(
+              borderRadius: BorderRadius.all(Radius.circular(12.w)),
+              color: "#FFFFFF".toColor(),
+            ),
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                /// 标题
+                if (title != null)
+                  Text(
+                    title!,
+                    style: TextStyle(
+                      color: "#25262A".toColor(),
+                      fontSize: 15.sp,
+                      fontWeight: FontWeight.w500,
+                      decoration: TextDecoration.none,
+                    ),
+                  ),
+
+                if (title != null) SizedBox(height: 12.h),
+
+                if (content != null)
+
+                  /// 内容
+                  Text(
+                    content ?? "",
+                    textAlign: TextAlign.center,
+                    style: TextStyle(
+                      color: "#5F5F61".toColor(),
+                      fontWeight: FontWeight.w500,
+                      fontSize: 14.sp,
+                      decoration: TextDecoration.none,
+                    ),
+                  ),
+
+                if (contentWidget != null) contentWidget!,
+
+                SizedBox(height: 34.h),
+
+                ///
+                _buttonWidget(context),
+              ],
+            ),
+          ),
+
+          //
+          const Spacer(),
+        ],
+      ),
+    );
+  }
+
+  Widget _buttonWidget(BuildContext context) {
+    if (cancelText == null) {
+      return Row(
+        children: [
+          const Spacer(),
+
+          ///确认按钮
+          GestureDetector(
+            onTap: () {
+              _clickConfirm();
+            },
+            child: _button(text: confirmText ?? "", color: "#6177F2".toColor()),
+          ),
+
+          //
+          const Spacer(),
+        ],
+      );
+    } else {
+      return Row(
+        children: [
+          ///  取消按钮
+          Expanded(
+            child: InkWell(
+              onTap: () {
+                _clickCancel();
+              },
+              child: _button(
+                text: cancelText ?? "",
+                color: "#F0F0F0".toColor(),
+                textColor: "#5F5F61".toColor(),
+              ),
+            ),
+          ),
+
+          ///
+          const SizedBox(width: 8),
+
+          /// 确认按钮
+          Expanded(
+            child: InkWell(
+              onTap: () {
+                _clickConfirm();
+              },
+              child:
+                  _button(text: confirmText ?? "", color: "#6177F2".toColor()),
+            ),
+          ),
+        ],
+      );
+    }
+  }
+
+  Widget _button({
+    required String text,
+    Color? color,
+    BoxBorder? border,
+    Color? textColor = Colors.white,
+  }) {
+    return Container(
+      height: 36.w,
+      decoration: BoxDecoration(
+        borderRadius: BorderRadius.all(Radius.circular(8.w)),
+        color: color,
+        border: border,
+      ),
+      alignment: Alignment.center,
+      child: Text(
+        text,
+        style: TextStyle(
+          color: textColor,
+          fontSize: 14.sp,
+          fontWeight: FontWeight.w500,
+        ),
+      ),
+    );
+  }
+
+  void _clickConfirm() {
+    EAAlertDialog.dismiss();
+
+    if (confirmOnTap != null) {
+      confirmOnTap!();
+    }
+  }
+
+  void _clickCancel() {
+    EAAlertDialog.dismiss();
+
+    if (cancelOnTap != null) {
+      cancelOnTap!();
+    }
+  }
+}