login_phone_page.dart 14.2 KB
import 'package:appframe/bloc/login_phone_cubit.dart';
import 'package:appframe/config/routes.dart';
import 'package:appframe/ui/widgets/login/login_page_agreed_widget.dart';
import 'package:appframe/ui/widgets/tip_overlay_widget.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class LoginPhonePage extends StatelessWidget {
  const LoginPhonePage({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => LoginPhoneCubit(LoginPhoneState()),
      child: BlocConsumer<LoginPhoneCubit, LoginPhoneState>(
        builder: (ctx, state) {
          var loginPhoneCubit = ctx.read<LoginPhoneCubit>();
          return Scaffold(
            backgroundColor: Colors.white,
            body: SafeArea(
              top: false,
              child: SingleChildScrollView(
                child: Column(
                  children: [
                    Image.asset(
                      'assets/images/login_v2/banner_2.png',
                      width: MediaQuery.of(context).size.width,
                      fit: BoxFit.fitWidth,
                    ),
                    SizedBox(height: 15.5),
                    Padding(
                      padding: EdgeInsets.symmetric(horizontal: 30),
                      child: Column(children: [
                        _buildInputFields(loginPhoneCubit, state),
                        SizedBox(height: 15),
                        _buildLoginButton(ctx),
                      ]),
                    ),
                    SizedBox(height: 15),
                    _buildAgreement(ctx, loginPhoneCubit, state.agreed),
                    SizedBox(height: 140),
                    Text(
                      '其他方式登录',
                      style: TextStyle(
                        fontSize: 14,
                        color: Color(0xFF999999),
                      ),
                      strutStyle: StrutStyle(height: 16 / 14),
                    ),
                    SizedBox(height: 15),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        InkWell(
                          onTap: () {
                            loginPhoneCubit.goLoginMain();
                          },
                          child: Image.asset(
                            'assets/images/login_v2/wechat_green_icon.png',
                          ),
                        ),
                        SizedBox(width: 25),
                        InkWell(
                          onTap: () {
                            loginPhoneCubit.goLoginQr();
                          },
                          child: Image.asset(
                            'assets/images/login_v2/qr_green_icon.png',
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          );
        },
        listener: (context, state) {
          if (state.showAgreed) {
            _showAgreementDialog(context, context.read<LoginPhoneCubit>());
          } else if (state.showSnackBar) {
            TipOverlayUtil.showTip(context, state.snackBarMsg);
          }
        },
      ),
    );
  }

  Widget _buildInputFields(LoginPhoneCubit loginPhoneCubit, LoginPhoneState state) {
    return Column(
      children: [
        // 手机号输入框
        Container(
          height: 60,
          decoration: BoxDecoration(
            color: Color(0xFFF7F9FF),
            borderRadius: BorderRadius.circular(10),
          ),
          child: TextField(
            controller: loginPhoneCubit.phoneController,
            keyboardType: TextInputType.phone,
            inputFormatters: [
              FilteringTextInputFormatter.digitsOnly,
              LengthLimitingTextInputFormatter(11), // 使用这个来限制长度
              FilteringTextInputFormatter.allow(RegExp(r'^1[0-9]{0,10}$')),
            ],
            decoration: InputDecoration(
              hintText: '请输入手机号',
              hintStyle: TextStyle(
                fontSize: 18,
                color: Color(0xFFCCCCCC),
              ),
              border: InputBorder.none,
              contentPadding: EdgeInsets.fromLTRB(0, 22, 0, 19),
              // 左右内边距,垂直居中
              prefixIcon: Container(
                // width: 25.5,
                // height: 25.5,
                margin: EdgeInsets.only(left: 15), // 控制左边距
                child: Image.asset(
                  'assets/images/login_v2/phone_small.png',
                  width: 25.5,
                  height: 25.5,
                  fit: BoxFit.contain,
                ),
              ),
            ),
            style: TextStyle(
              fontSize: 18,
              color: Color(0xFF000000),
            ),
          ),
        ),
        // 手机号输入框和发送按钮之间的间隔
        SizedBox(height: 15),
        // 验证码输入框和发送按钮
        Container(
          height: 60,
          decoration: BoxDecoration(
            color: Color(0xFFF7F9FF),
            borderRadius: BorderRadius.circular(10),
          ),
          child: Stack(
            children: [
              TextField(
                controller: loginPhoneCubit.codeController,
                keyboardType: TextInputType.number,
                inputFormatters: [
                  FilteringTextInputFormatter.digitsOnly,
                  LengthLimitingTextInputFormatter(4), // 使用这个来限制长度
                ],
                decoration: InputDecoration(
                  hintText: '请输入验证码',
                  hintStyle: TextStyle(
                    fontSize: 18,
                    color: Color(0xFFCCCCCC),
                  ),
                  border: InputBorder.none,
                  contentPadding: EdgeInsets.fromLTRB(0, 22, 0, 19),
                  // 左右内边距,垂直居中
                  prefixIcon: Container(
                    margin: EdgeInsets.only(left: 15), // 控制左边距
                    child: Image.asset(
                      'assets/images/login_v2/secure_small.png',
                      width: 25.5,
                      height: 25.5,
                      fit: BoxFit.contain,
                    ),
                  ),
                ),
                style: TextStyle(
                  fontSize: 18,
                  color: Color(0xFF000000),
                ),
              ),
              Positioned(
                right: 0,
                top: 0,
                bottom: 0,
                child: Container(
                  width: 100,
                  decoration: BoxDecoration(
                    color: Colors.transparent,
                  ),
                  child: TextButton(
                    onPressed: () {
                      if (state.allowSend) {
                        loginPhoneCubit.sendVerificationCode();
                      }
                    },
                    style: TextButton.styleFrom(
                      backgroundColor: Colors.transparent,
                      // foregroundColor: Colors.blue,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(8),
                      ),
                      padding: EdgeInsets.zero,
                    ),
                    child: Text(
                      state.allowSend ? '发送验证码' : '${state.seconds}s后可重发',
                      style: TextStyle(
                        fontSize: 16,
                        color: Color(0xFF7691FA),
                        fontWeight: FontWeight.normal,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  Widget _buildLoginButton(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: 47,
      child: ElevatedButton(
        onPressed: () {
          context.read<LoginPhoneCubit>().phoneAuth();
        },
        style: ElevatedButton.styleFrom(
          backgroundColor: Color(0xFF7691FA),
          foregroundColor: Colors.white,
          textStyle: TextStyle(fontSize: 19),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(23.5),
          ),
        ),
        child: Text(
          '手机号登录',
          style: TextStyle(
            fontSize: 19,
            fontWeight: FontWeight.w400,
            color: Color(0xFFFFFFFF),
          ),
          strutStyle: StrutStyle(height: 22 / 19),
        ),
      ),
    );
  }

  Widget _buildAgreement(BuildContext context, LoginPhoneCubit loginPhoneCubit, bool agreed) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Theme(
          data: Theme.of(context).copyWith(
            checkboxTheme: CheckboxThemeData(
              shape: CircleBorder(
                side: BorderSide(width: 0.5, color: Color(0xFF999999)),
              ),
              fillColor: WidgetStateProperty.resolveWith<Color>(
                (Set<WidgetState> states) {
                  if (states.contains(WidgetState.selected)) {
                    return Color(0xFF7691FA); // 选中时的颜色
                  }
                  return Colors.white; // 未选中时的颜色
                },
              ),
              checkColor: WidgetStateProperty.all<Color>(Colors.white),
              side: BorderSide(width: 0.5, color: Color(0xFF999999)),
            ),
            cardColor: Colors.white,
            unselectedWidgetColor: Color(0xFF999999),
          ),
          child: SizedBox(
            height: 19,
            child: Checkbox(
              value: agreed,
              onChanged: (bool? value) {
                loginPhoneCubit.toggleAgreed(value!);
              },
              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, // 缩小点击区域,减小间隔
            ),
          ),
        ),
        LoginPageAgreedWidget(),
      ],
    );
  }

  Future<void> _showAgreementDialog(BuildContext context, LoginPhoneCubit loginPhoneCubit) async {
    final result = await showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(
              Radius.circular(5),
            ),
          ),
          title: Text(
            '个人信息保护指引',
            style: TextStyle(
              fontSize: 17,
              color: Color(0xFF000000),
              // fontWeight: FontWeight.bold,
            ),
            textAlign: TextAlign.center,
          ),
          content: Text.rich(
            TextSpan(
              children: [
                TextSpan(
                  text: '感谢使用班小二APP,为保护您的个人权益,请仔细阅读并充分理解',
                  style: TextStyle(color: Color(0xFF666666), fontSize: 14),
                ),
                TextSpan(
                  text: '《班小二数据据安全和隐私政策》',
                  style: TextStyle(color: Color(0xFF7691FA), fontSize: 14),
                  recognizer: TapGestureRecognizer()
                    ..onTap = () {
                      router.push(
                        '/link',
                        extra: {'url': 'https://bxr.banxiaoer.net/apps/privacysettings.html', 'title': '隐私保障'},
                      );
                    },
                ),
                TextSpan(
                  text: '与',
                  style: TextStyle(color: Color(0xFF666666), fontSize: 14),
                ),
                TextSpan(
                  text: '《用户协议》',
                  style: TextStyle(color: Color(0xFF7691FA), fontSize: 14),
                  recognizer: TapGestureRecognizer()
                    ..onTap = () {
                      router.push(
                        '/link',
                        extra: {'url': 'https://bxr.banxiaoer.net/apps/useragreement.html', 'title': '用户协议'},
                      );
                    },
                ),
                TextSpan(
                  text: '。如您同意上述文件的全部内容,请点击“同意”以继续。',
                  style: TextStyle(color: Color(0xFF666666), fontSize: 14),
                ),
              ],
            ),
          ),
          actions: [
            Table(
              children: [
                TableRow(
                  children: [
                    TableCell(
                      child: TextButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                        style: TextButton.styleFrom(
                          foregroundColor: Color(0xFF666666),
                          textStyle: TextStyle(fontSize: 17),
                          padding: EdgeInsets.zero,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.zero,
                          ),
                        ),
                        child: Text('放弃登录'),
                      ),
                    ),
                    TableCell(
                      child: TextButton(
                        onPressed: () {
                          Navigator.of(context).pop('OK');
                        },
                        style: TextButton.styleFrom(
                          foregroundColor: Color(0xFF7691FA),
                          textStyle: TextStyle(fontSize: 17),
                          minimumSize: Size.fromHeight(40),
                          padding: EdgeInsets.zero,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.zero,
                          ),
                        ),
                        child: Text('同意'),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ],
        );
      },
    );
    if (result != null) {
      loginPhoneCubit.confirmAgreed();
    } else {
      loginPhoneCubit.cancelAgreed();
    }
  }
}