123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- import 'package:auto_route/auto_route.dart';
- import 'package:eitc_erm_dental_flutter/app_router.gr.dart';
- import 'package:eitc_erm_dental_flutter/funcs.dart';
- import 'package:eitc_erm_dental_flutter/pages/login/vm/login_view_model.dart';
- import 'package:eitc_erm_dental_flutter/pages/patient/vm/patient_view_model.dart';
- import 'package:eitc_erm_dental_flutter/vm/global_view_model.dart';
- import 'package:eitc_erm_dental_flutter/widget/counting_button.dart';
- import 'package:eitc_erm_dental_flutter/widget/main_button.dart';
- import 'package:flutter/foundation.dart';
- import 'package:flutter/gestures.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import '../../global.dart';
- @RoutePage(name: "loginRoute")
- class LoginPage extends ConsumerStatefulWidget {
- final bool cancelable;
- const LoginPage({super.key, required this.cancelable});
- @override
- ConsumerState createState() => _LoginPageState();
- }
- class _LoginPageState extends ConsumerState<LoginPage> {
- final TextEditingController _mobileTextController = TextEditingController();
- final TextEditingController _captchaTextController = TextEditingController();
- final CountingButtonController _countingButtonController =
- CountingButtonController();
- bool _isAgreementChecked = false;
- @override
- void initState() {
- super.initState();
- WidgetsBinding.instance.addPostFrameCallback((_) {
- //刷新本地就诊人列表数据
- ref.invalidate(localPatientListProvider);
- if (!widget.cancelable) {
- //停止检查连接
- ref
- .read(deviceConnectStatusProvider(videoChannel).notifier)
- .stopCheck();
- }
- });
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- automaticallyImplyLeading: widget.cancelable,
- forceMaterialTransparency: true,
- ),
- body: SafeArea(
- child: SingleChildScrollView(
- child: Padding(
- padding: EdgeInsets.fromLTRB(15.w, 50.h, 15.w, 0.0),
- child: Column(children: [
- Text(
- getS().registerHint,
- textAlign: TextAlign.center,
- style: Theme.of(context).textTheme.titleMedium,
- ),
- SizedBox(
- height: 80.h,
- ),
- _getInputs(),
- SizedBox(
- height: 10.h,
- ),
- _getAgreements(),
- SizedBox(
- height: 80.h,
- ),
- SizedBox(
- width: double.infinity,
- child: MainButton(text: getS().login, onPressed: _onLogin),
- ),
- ]),
- ),
- )),
- );
- }
- ///输入框
- Widget _getInputs() {
- //保证内部元素高度一致
- return IntrinsicHeight(
- child: Row(
- children: [
- Column(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- Text(getS().mobileColon),
- SizedBox(
- height: 30.h,
- ),
- Text(getS().captchaColon)
- ],
- ),
- SizedBox(
- width: 10.w,
- ),
- Expanded(
- child: Column(
- children: [
- _getMobileInput(),
- SizedBox(
- height: 30.h,
- ),
- Row(
- children: [
- Expanded(child: _getCaptchInput()),
- SizedBox(
- width: 10.w,
- ),
- CountingButton(
- controller: _countingButtonController,
- onGetChild: (t, isCounting) {
- String str = getS().send;
- if (isCounting) {
- str = "$str(${60 - t})";
- }
- return Text(
- str,
- style: TextStyle(
- color: Theme.of(context).colorScheme.onPrimary,
- fontWeight: FontWeight.bold),
- );
- },
- onPressed: _onSendCaptcha,
- )
- ],
- ),
- ],
- ))
- ],
- ),
- );
- }
- ///手机号输入框
- Widget _getMobileInput() {
- return _getTextInput(_mobileTextController, 11, TextInputType.phone,
- getS().mobileInputHint, [FilteringTextInputFormatter.digitsOnly]);
- }
- ///验证码输入框
- Widget _getCaptchInput() {
- return _getTextInput(_captchaTextController, 6, TextInputType.number,
- getS().captchaInputHint, [FilteringTextInputFormatter.digitsOnly]);
- }
- ///文本输入框
- Widget _getTextInput(
- TextEditingController controller,
- int? maxLength,
- TextInputType? keyboardType,
- String hint,
- List<TextInputFormatter>? inputFormatters) {
- return Container(
- padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
- decoration: BoxDecoration(
- color: Theme.of(context).colorScheme.surfaceContainerHigh,
- borderRadius: BorderRadius.circular(8.r)),
- child: TextField(
- controller: controller,
- maxLines: 1,
- maxLength: maxLength,
- keyboardType: keyboardType,
- decoration: InputDecoration(
- isDense: true,
- contentPadding: EdgeInsets.zero,
- border: const OutlineInputBorder(borderSide: BorderSide.none),
- counterText: "",
- hintText: hint,
- hintStyle: const TextStyle(color: Color(0xFF999999)),
- ),
- inputFormatters: inputFormatters,
- ),
- );
- }
- ///用户协议及隐私协议
- Widget _getAgreements() {
- return Row(
- children: [
- Checkbox(
- value: _isAgreementChecked,
- onChanged: (bo) {
- setState(() {
- _isAgreementChecked = bo ?? false;
- });
- }),
- Expanded(
- child: Text.rich(
- softWrap: true,
- TextSpan(text: getS().readAndAgree, children: [
- getClickTextSpan(getS().userAgreementBookTitle,
- () => gotoUserAgreement(context, checkWifi: false)),
- TextSpan(text: "、"),
- getClickTextSpan(getS().privacyPolicyBookTitle,
- () => gotoPrivacyPolicy(context, checkWifi: false)),
- ]),
- )),
- ],
- );
- }
- TextSpan getClickTextSpan(String text, GestureTapCallback onTap) {
- return TextSpan(
- text: text,
- style: TextStyle(color: Theme.of(context).colorScheme.primary),
- recognizer: TapGestureRecognizer()..onTap = onTap);
- }
- ///发送验证码
- void _onSendCaptcha() async {
- if (!validMobile(_mobileTextController.text)) {
- showToast(text: getS().mobileFormatError);
- return;
- }
- _countingButtonController.start(60);
- bool bo = await ref
- .read(captchaProvider.notifier)
- .sendCaptcha(_mobileTextController.text);
- showToast(text: bo ? getS().captchaHasSend : getS().captchaSendError);
- }
- ///验证输入
- Future<bool> _validInput() async {
- ///手机号
- if (_mobileTextController.text.isEmpty) {
- showToast(text: getS().mobileInputHint);
- return SynchronousFuture(false);
- }
- ///手机号格式
- if (!validMobile(_mobileTextController.text)) {
- showToast(text: getS().mobileFormatError);
- return SynchronousFuture(false);
- }
- ///验证码
- if (_captchaTextController.text.isEmpty) {
- showToast(text: getS().captchaInputHint);
- return SynchronousFuture(false);
- }
- ///用户协议及隐私协议
- if (!_isAgreementChecked) {
- showToast(text: getS().needReadAndAgree);
- return SynchronousFuture(false);
- }
- //调用接口验证验证码
- logd("验证验证码");
- if (!await ref.read(captchaProvider.notifier).checkCaptcha(
- _captchaTextController.text, _mobileTextController.text)) {
- showToast(text: getS().captchaError);
- return SynchronousFuture(false);
- }
- return SynchronousFuture(true);
- }
- void _onLogin() async {
- if (!await _validInput()) {
- return;
- }
- logd("登录");
- bool bo = await ref
- .read(loginProvider.notifier)
- .login(_mobileTextController.text);
- if (bo) {
- showToast(text: getS().loginSuccess);
- if (mounted) {
- popAllRoutes(context);
- context.pushRoute(const MainRoute());
- //刷新本地就诊人列表数据
- ref.invalidate(localPatientListProvider);
- }
- } else {
- showToast(text: getS().loginFailed);
- }
- }
- }
|