Files
tuiche/lib/pages/login/th_bind_tel_page.dart
2026-04-07 14:49:31 +08:00

742 lines
43 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:get_storage/get_storage.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/CheckNetwork.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/login/login_controller.dart';
import 'package:vbvs_app/controller/time/countdown_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/mh_page/user/controller/bind_tel_controller.dart';
import 'package:vbvs_app/pages/person/select_time.dart';
import 'package:flutter/services.dart';
class THBindTelWidget extends GetView<AuthBindTelController> {
BoxConstraints? bodysize;
Map img;
final scaffoldKey = GlobalKey<ScaffoldState>();
UserInfoController userInfoController = Get.find();
THBindTelWidget({super.key, required this.img});
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return Container(
// onTap: () => FocusScope.of(context).unfocus(),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage((img!['img'] == null || "" == img!['img'])
? 'assets/images/new_background.png'
: img!['img']!),
fit: BoxFit.fill,
),
),
child: Scaffold(
resizeToAvoidBottomInset: false,
key: scaffoldKey,
backgroundColor: Colors.transparent,
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent, // 状态栏背景色
statusBarIconBrightness: Brightness.light, // 图标颜色Android
statusBarBrightness: Brightness.light, // 图标颜色iOS
),
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
Text(
'绑定手机号码'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
Positioned(
left: 0.rpx,
// child: returnIconButtomNew(onBack: () {
// UserInfoController userInfoController = Get.find();
// ApiResponse apiResponse = userInfoController.logOut();
// TopSlideNotification.show(
// context,
// text: apiResponse.msg!,
// textColor: apiResponse.code == HttpStatusCodes.ok
// ? themeController.currentColor.sc2
// : themeController.currentColor.sc9,
// );
// if (apiResponse.code == HttpStatusCodes.ok) {
// Get.offAllNamed("/mianPageBottomChange");
// }
// }),
child: returnIconButtomNew(),
),
],
),
),
actions: [],
centerTitle: false,
),
body: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(49.rpx, 0, 49.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.886,
decoration: BoxDecoration(),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 92, 0, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.05,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
'绑定手机号码'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 24,
letterSpacing: 0.0,
),
),
),
),
),
Flexible(
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.06,
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'为了您的账号安全,验证手机号码后,可直接使用此手机号登录。'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0.0,
),
),
],
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 95.rpx, 0, 0), // 对齐第一个 UI 的上边距
child: Container(
width: double.infinity,
height: bodysize!.maxHeight * 0.056,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(
AppConstants().button_container_radius),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
constraints: BoxConstraints(
minHeight: 90.rpx,
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
60.rpx, 0, 35.rpx, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0, 0, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
InkWell(
onTap: () async {
await showCountryCodePickerDialog(
context,
initialCode: userInfoController
.select_country_code
.value, // ✅ 来自 controller
onConfirm: (String code) {
print("选中的区号:$code");
userInfoController
.select_country_code
.value = code;
userInfoController
.updateAll();
// setState / controller.update
},
title: "选择区号".tr,
);
},
child: Obx(() {
return Container(
width: 80.rpx,
alignment: Alignment.center,
child: Text(
"${userInfoController.select_country_code.value}",
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController
.currentColor.sc2,
fontSize: AppConstants()
.middler_text_fontSize,
),
),
);
}),
),
SizedBox(
height: 30.rpx,
child: VerticalDivider(
thickness: 2.rpx,
color: themeController
.currentColor.sc4,
),
),
].divide(SizedBox(width: 10.rpx)),
),
),
Expanded(
child: Align(
alignment:
AlignmentDirectional(-1, 0),
child: TextFormField(
onChanged: (value) {
controller.model.phone = value;
},
autofocus: false,
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelStyle: TextStyle(
fontFamily: 'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0.0,
),
hintText: '请输入手机号'.tr,
hintStyle: TextStyle(
fontFamily: 'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedErrorBorder:
OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
filled: false,
fillColor: Colors.white,
contentPadding: EdgeInsets.zero,
),
style: TextStyle(
fontFamily: 'Readex Pro',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
cursorColor: themeController
.currentColor.sc3,
),
),
),
],
),
),
),
),
Obx(() {
controller.model.code;
final CountdownController countdownController =
Get.find<CountdownController>();
return Visibility(
visible: true,
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 26.rpx, 0, 0),
child: Container(
height: bodysize!.maxHeight * 0.056,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(
AppConstants()
.button_container_radius),
border: Border.all(
color: themeController
.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
constraints: BoxConstraints(
minHeight: 90.rpx,
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
35.rpx, 0, 35.rpx, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Align(
alignment:
AlignmentDirectional(-1, 0),
child: TextFormField(
onChanged: (value) {
controller.model.code =
value;
},
autofocus: false,
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelStyle: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
),
hintText: '请输入验证码',
hintStyle: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
enabledBorder:
OutlineInputBorder(
borderSide: BorderSide(
color:
Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedBorder:
OutlineInputBorder(
borderSide: BorderSide(
color:
Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
errorBorder:
OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedErrorBorder:
OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
filled: true,
fillColor:
Colors.transparent,
),
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
cursorColor: themeController
.currentColor.sc3,
),
),
),
Padding(
padding: EdgeInsetsDirectional
.fromSTEB(26.rpx, 0, 0, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(
height: 30.rpx,
child: VerticalDivider(
thickness: 2.rpx,
color: themeController
.currentColor.sc7,
),
),
InkWell(
onTap: () async {
if (countdownController
.countdown
.value !=
0) {
return;
}
String msg =
await controller
.getCode(
context, img);
if (msg.isNotEmpty) {
return;
}
countdownController
.countdown
.value ==
0
? countdownController
.startCountdown(
AppConstants
.code_time)
: null;
},
child: Container(
alignment:
Alignment.center,
constraints:
BoxConstraints(
minWidth: 150.rpx,
),
child: Text(
countdownController
.countdown
.value ==
0
? '获取验证码'
: '${countdownController.countdown.value}',
style: TextStyle(
fontFamily:
'Readex Pro',
color: themeController
.currentColor.sc2,
fontSize: AppConstants()
.middler_text_fontSize,
letterSpacing: 0,
),
),
),
),
].divide(
SizedBox(width: 26.rpx)),
),
),
],
),
),
),
),
),
);
}),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 19, 0, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.022,
constraints: BoxConstraints(
minWidth: 466,
minHeight: 30,
),
decoration: BoxDecoration(),
),
),
// Padding(
// padding:
// EdgeInsetsDirectional.fromSTEB(0, 29, 0, 0),
// child: Container(
// width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 0.056,
// decoration: BoxDecoration(),
// child: Container(
// width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 0.056,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(0),
// ),
// child: CustomCard(
// borderRadius: 16.rpx,
// gradientDirection:
// GradientDirection.vertical,
// onTap: () async {
// ApiResponse apiResponse =
// await controller.updateUserPhone();
// if (apiResponse.code ==
// HttpStatusCodes.ok) {
// UserInfoController userInfoController =
// Get.find();
// await userInfoController.getUserInfo();
// MHTLoginController loginController =
// Get.find();
// //TODO 微信回调监听操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听
// loginController.fluwxCancelable
// ?.cancel();
// // 登录成功移出网络检查监听
// Checknetwork.subscription?.cancel();
// final box = GetStorage();
// box.remove('countdown');
// CountdownController
// countdownController = Get.find();
// countdownController.countdown = 0.obs;
// Get.offAndToNamed(
// "/mianPageBottomChange");
// } else {
// TopSlideNotification.show(context,
// textColor: themeController
// .currentColor.sc9,
// text: apiResponse.msg ?? '失败'.tr);
// }
// },
// colors: const [
// Color(0xFFFCFCFC),
// Color(0xFFF8FAF9),
// Color(0XFFECF6F3),
// Color(0XFFD9F0E9),
// Color(0xFFCEECE3)
// ],
// child: Container(
// width: double.infinity,
// height: 90.rpx,
// alignment: Alignment.center,
// decoration: BoxDecoration(
// borderRadius:
// BorderRadius.circular(16.rpx),
// ),
// child: Text(
// "提交".tr,
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: Color(0XFF003058),
// letterSpacing: 0,
// fontSize: 26.rpx,
// ),
// ),
// ),
// ),
// ),
// ),
// ),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 26.rpx, 0, 0), // 与登录按钮一致
child: CustomCard(
borderRadius: AppConstants()
.button_container_radius, // 统一圆角
// 保留你原有的业务逻辑不变
onTap: () async {
// String msg = await controller.bindTel(context);
// if (msg == null || msg.isEmpty) {
// MHTLoginController loginController =
// Get.find();
// //TODO 微信回调监听操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听
// loginController.fluwxCancelable?.cancel();
// // 登录成功移出网络检查监听
// Checknetwork.subscription?.cancel();
// final box = GetStorage();
// box.remove('countdown');
// CountdownController countdownController =
// Get.find();
// countdownController.countdown = 0.obs;
// Get.offAndToNamed("/mianPageBottomChange");
// } else {
// TopSlideNotification.show(context,text: msg!,textColor: themeController.currentColor.sc9);
// }
AuthBindTelController authBindTelController =
Get.find();
String message = "";
if (authBindTelController.model.phone ==
null ||
authBindTelController
.model.phone!.isEmpty) {
message = "请输入手机号".tr;
TopSlideNotification.show(context,
text: message);
return;
}
if (!MyUtils.isValidPhoneNumber(
authBindTelController.model.phone!)) {
message = '请输入正确的手机号'.tr;
TopSlideNotification.show(context,
text: message);
return;
}
if (authBindTelController.model.code ==
null ||
authBindTelController
.model.code!.isEmpty) {
message = "请输入验证码".tr;
TopSlideNotification.show(context,
text: message);
return;
}
ApiResponse apiResponse =
await controller.updateUserPhone();
if (apiResponse.code == HttpStatusCodes.ok) {
UserInfoController userInfoController =
Get.find();
await userInfoController.getUserInfo();
LoginController loginController =
Get.find();
//TODO 微信回调监听操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听
loginController.fluwxCancelable?.cancel();
// 登录成功移出网络检查监听
Checknetwork.subscription?.cancel();
final box = GetStorage();
box.remove('countdown');
CountdownController countdownController =
Get.find();
countdownController.countdown = 0.obs;
Get.offAndToNamed("/mianPageBottomChange");
} else {
TopSlideNotification.show(
context,
textColor:
themeController.currentColor.sc9,
text: apiResponse.msg ?? '失败'.tr,
);
}
},
// 与“登录按钮”一致的主题渐变
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: bodysize!.maxWidth,
height: MediaQuery.sizeOf(context).height *
0.055, // 与登录按钮一致
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"提交".tr,
style: TextStyle(
color: themeController
.currentColor.sc3, // 与登录按钮一致
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
)
],
),
),
),
),
),
],
),
),
),
);
});
}
}