login_page.dart 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. import 'package:cs_resources/constants/color_constants.dart';
  2. import 'package:cs_resources/generated/assets.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/gestures.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter/widgets.dart';
  7. import 'package:get/get.dart';
  8. import 'package:plugin_basic/base/base_stateful_page.dart';
  9. import 'package:plugin_basic/base/base_state.dart';
  10. import 'package:plugin_basic/base/mixin_state_lifecycle.dart';
  11. import 'package:plugin_basic/service/app_config_service.dart';
  12. import 'package:plugin_basic/utils/ext_get_nav.dart';
  13. import 'package:router/path/router_path.dart';
  14. import 'package:shared/utils/device_utils.dart';
  15. import 'package:shared/utils/log_utils.dart';
  16. import 'package:shared/utils/screen_util.dart';
  17. import 'package:widgets/ext/ex_widget.dart';
  18. import 'package:widgets/my_button.dart';
  19. import 'package:widgets/my_load_image.dart';
  20. import 'package:widgets/my_text_field.dart';
  21. import 'package:widgets/my_text_view.dart';
  22. import 'package:widgets/shatter/custom_radio_check.dart';
  23. import 'package:widgets/widget_export.dart';
  24. import 'login_controller.dart';
  25. import 'login_state.dart';
  26. /*
  27. App 登录页面
  28. */
  29. class LoginPage extends BaseStatefulPage<LoginController> {
  30. LoginPage({super.key});
  31. //启动当前页面
  32. static void startInstance() {
  33. return Get.start(RouterPath.AUTH_LOGIN, launchModel: LaunchModel.standard);
  34. }
  35. static void startWithPopAll() {
  36. Get.offAllNamed(RouterPath.AUTH_LOGIN);
  37. }
  38. @override
  39. State<LoginPage> createState() => _MainPageState();
  40. @override
  41. LoginController createRawController() {
  42. return LoginController();
  43. }
  44. }
  45. /**
  46. * 页面
  47. */
  48. class _MainPageState extends BaseState<LoginPage, LoginController> with StateLifecycle {
  49. late LoginState state;
  50. @override
  51. void initState() {
  52. super.initState();
  53. state = controller.state;
  54. }
  55. @override
  56. void dispose() {
  57. Get.delete<LoginController>();
  58. super.dispose();
  59. }
  60. @override
  61. Widget build(BuildContext context) {
  62. Log.d("LoginPage Lifecycle - build走了一遍");
  63. return autoCtlGetBuilder(
  64. builder: (controller) {
  65. return Scaffold(
  66. body: Container(
  67. width: double.infinity,
  68. height: double.infinity,
  69. decoration: const BoxDecoration(
  70. gradient: LinearGradient(
  71. colors: [
  72. Color(0xFF091D44),
  73. Color(0xFF245A8A),
  74. Color(0xFF7F7CEC),
  75. ],
  76. begin: Alignment.topCenter,
  77. end: Alignment.bottomCenter,
  78. ),
  79. ),
  80. child: Column(
  81. mainAxisSize: MainAxisSize.max,
  82. crossAxisAlignment: CrossAxisAlignment.center,
  83. children: [
  84. //当前选择的国家,这个不跟随滚动
  85. Align(
  86. alignment: Alignment.topRight,
  87. child: Row(
  88. mainAxisSize: MainAxisSize.min,
  89. crossAxisAlignment: CrossAxisAlignment.center,
  90. children: [
  91. Obx(() {
  92. return MyTextView(
  93. ConfigService.to.curSelectCountry == 0 ? "Vietnam".tr : "Singapore".tr,
  94. textColor: ColorConstants.white,
  95. isFontMedium: true,
  96. marginRight: 5,
  97. fontSize: 15,
  98. );
  99. }),
  100. MyAssetImage(
  101. Assets.baseServiceTriangleDropDown,
  102. width: 8,
  103. height: 5,
  104. ),
  105. ],
  106. ).onTap(() => controller.gotoSelectCountryPage()).marginOnly(right: 20, top: ScreenUtil.getStatusBarH(context) + 20),
  107. ),
  108. // 底部滚动的布局
  109. SingleChildScrollView(
  110. scrollDirection: Axis.vertical,
  111. physics: const BouncingScrollPhysics(),
  112. child: Column(
  113. mainAxisSize: MainAxisSize.max,
  114. crossAxisAlignment: CrossAxisAlignment.center,
  115. children: [
  116. MyTextView(
  117. "Casual Labour System",
  118. textColor: ColorConstants.white,
  119. isFontBold: true,
  120. fontSize: 35,
  121. marginTop: 20,
  122. fontStyle: FontStyle.italic,
  123. textAlign: TextAlign.center,
  124. marginLeft: 50,
  125. marginRight: 50,
  126. ),
  127. //中间的输入框布局
  128. Container(
  129. width: double.infinity,
  130. margin: EdgeInsets.symmetric(vertical: 45, horizontal: 15),
  131. padding: EdgeInsets.symmetric(vertical: 33, horizontal: 20),
  132. decoration: BoxDecoration(
  133. color: Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
  134. borderRadius: BorderRadius.circular(5.0), // 设置圆角
  135. ),
  136. child: Center(
  137. child: Column(
  138. crossAxisAlignment: CrossAxisAlignment.start,
  139. children: [
  140. //登录文本
  141. MyTextView(
  142. "Email".tr,
  143. isFontMedium: true,
  144. fontSize: 17,
  145. textColor: ColorConstants.white,
  146. ),
  147. // 登录表单 - 账号
  148. _buildInputLayout(
  149. "code",
  150. textInputAction: TextInputAction.next,
  151. errorText: state.codeErrorText,
  152. onSubmit: (formKey, value) {
  153. state.formData[formKey]!['focusNode'].unfocus();
  154. FocusScope.of(context).requestFocus(state.formData['password']!['focusNode']);
  155. },
  156. ),
  157. //密码文本
  158. MyTextView(
  159. "Password".tr,
  160. isFontMedium: true,
  161. fontSize: 17,
  162. textColor: ColorConstants.white,
  163. marginTop: 18,
  164. ),
  165. // 登录表单 - 密码
  166. _buildInputLayout(
  167. "password",
  168. obscureText: !state.pwdVisibility,
  169. errorText: state.passwordErrorText,
  170. showRightIcon: true,
  171. rightWidget: IconButton(
  172. highlightColor: Colors.transparent,
  173. splashColor: Colors.transparent,
  174. icon: state.pwdVisibility
  175. ? const MyAssetImage(
  176. Assets.cptAuthPasswordShowIcon,
  177. width: 21,
  178. height: 21,
  179. color: ColorConstants.white,
  180. )
  181. : const MyAssetImage(
  182. Assets.cptAuthPasswordHideIcon,
  183. width: 21,
  184. height: 21,
  185. color: ColorConstants.white,
  186. ),
  187. onPressed: () {
  188. controller.switchPwdVisibility();
  189. },
  190. ),
  191. onSubmit: (formKey, value) {
  192. state.formData[formKey]!['focusNode'].unfocus();
  193. controller.doInputLogin();
  194. },
  195. ),
  196. //选择签到功能还是全功能
  197. Obx(() {
  198. return Visibility(
  199. visible: ConfigService.to.curSelectCountry == 0,
  200. child: CustomRadioCheck(
  201. options: state.loginOption,
  202. onOptionSelected: (index, text) {
  203. state.loginOptionPosition = index;
  204. },
  205. ).marginOnly(top: 20),
  206. );
  207. }),
  208. //登录按钮
  209. MyButton(
  210. type: ClickType.throttle,
  211. milliseconds: 500,
  212. onPressed: () {
  213. FocusScope.of(context).unfocus();
  214. controller.doInputLogin();
  215. },
  216. text: "Log in".tr,
  217. textColor: ColorConstants.white,
  218. fontSize: 16,
  219. radius: 22.5,
  220. backgroundColor: hexToColor("#FFBB1B"),
  221. fontWeight: FontWeight.w500,
  222. ).marginOnly(top: 20),
  223. //注册入口
  224. Visibility(
  225. visible: !DeviceUtils.isAndroid,
  226. child: _buildRichText(),
  227. ),
  228. ],
  229. ),
  230. ), // 传递子部件
  231. ),
  232. ],
  233. )).expanded(),
  234. ],
  235. ),
  236. ),
  237. );
  238. },
  239. );
  240. }
  241. //底部的注册文本
  242. Widget _buildRichText() {
  243. return Align(
  244. alignment: Alignment.center,
  245. child: RichText(
  246. text: TextSpan(
  247. style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: ColorConstants.textGrayAECAE5),
  248. children: <TextSpan>[
  249. TextSpan(
  250. text: "Don’t have an account?".tr,
  251. style: TextStyle(color: ColorConstants.textGrayAECAE5),
  252. ),
  253. TextSpan(
  254. text: "Sign up".tr,
  255. style: TextStyle(color: ColorConstants.textYellowFFBB1B),
  256. recognizer: TapGestureRecognizer()
  257. ..onTap = () {
  258. //去登录页面
  259. controller.gotoSignUpPage();
  260. },
  261. ),
  262. ],
  263. ),
  264. ),
  265. ).marginOnly(top: 23);
  266. }
  267. /// 输入框 账号与密码
  268. Widget _buildInputLayout(
  269. String key, {
  270. double marginTop = 0,
  271. bool? showRightIcon = false, //是否展示右侧的布局
  272. Widget? rightWidget, //右侧的布局
  273. TextInputType textInputType = TextInputType.text,
  274. String? errorText,
  275. bool obscureText = false,
  276. TextInputAction textInputAction = TextInputAction.done,
  277. Function? onSubmit,
  278. }) {
  279. return IgnoreKeyboardDismiss(
  280. child: MyTextField(
  281. key,
  282. state.formData[key]!['value'],
  283. hintText: state.formData[key]!['hintText'],
  284. hintStyle: TextStyle(
  285. color: hexToColor("#AECAE5"),
  286. fontSize: 15.0,
  287. fontWeight: FontWeight.w500,
  288. ),
  289. controller: state.formData[key]!['controller'],
  290. focusNode: state.formData[key]!['focusNode'],
  291. margin: EdgeInsets.only(top: marginTop),
  292. showDivider: true,
  293. dividerColor: hexToColor("#7BABC8"),
  294. style: TextStyle(
  295. color: ColorConstants.white,
  296. fontSize: 15.0,
  297. fontWeight: FontWeight.w500,
  298. ),
  299. inputType: textInputType,
  300. height: 35,
  301. textInputAction: textInputAction,
  302. onSubmit: onSubmit,
  303. cursorColor: ColorConstants.white,
  304. obscureText: obscureText,
  305. errorText: errorText,
  306. showLeftIcon: true,
  307. showRightIcon: showRightIcon,
  308. rightWidget: rightWidget,
  309. ),
  310. );
  311. }
  312. }