login_page.dart 11 KB

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