login_page.dart 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. import 'package:dio/dio.dart';
  2. import 'package:flutter/foundation.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
  5. import 'package:lszlgl/base/base_lifecycle_state.dart';
  6. import 'package:lszlgl/main.dart';
  7. import 'package:lszlgl/model/req/login_req.dart';
  8. import 'package:lszlgl/network/my_api.dart';
  9. import 'package:lszlgl/service/dict_service.dart';
  10. import 'package:lszlgl/service/upgrade_service.dart';
  11. import 'package:lszlgl/service/user_service.dart';
  12. import 'package:lszlgl/widget/button.dart';
  13. import '../../config/reresh_config.dart';
  14. import '../../drfit/database.dart';
  15. import '../../network/base_dio.dart';
  16. import '../../utils/location_utils.dart';
  17. import '../../utils/sp_utils.dart';
  18. import 'package:lszlgl/service/print_service.dart';
  19. import 'package:path_provider/path_provider.dart';
  20. import 'package:path/path.dart' as p;
  21. /// 登录页面
  22. class LoginPage extends StatefulWidget {
  23. const LoginPage({Key? key}) : super(key: key);
  24. @override
  25. State<LoginPage> createState() => _LoginPageState();
  26. }
  27. class _LoginPageState extends BaseLifecycleState<LoginPage> {
  28. late TextEditingController accountCtrl;
  29. late TextEditingController pwdCtrl;
  30. void onLogin() async {
  31. var account = accountCtrl.text;
  32. var pwd = pwdCtrl.text;
  33. if (account.isEmpty || pwd.isEmpty) {
  34. MyNavigator.showToast('请输入账号和密码');
  35. return;
  36. }
  37. MyNavigator.showLoading();
  38. try {
  39. // 登录
  40. var login = await MyApi.get().login(LoginReq(username: account, password: pwd));
  41. await UserService.get().saveLogin(login.data);
  42. getSystemData();
  43. } on DioException catch (_) {
  44. } catch (_) {
  45. MyNavigator.showToast('获取数据失败');
  46. }
  47. MyNavigator.dismissLoading();
  48. }
  49. /// 获取基础数据
  50. void getSystemData() async {
  51. MyNavigator.showLoading(clickDismiss: false);
  52. try {
  53. // 获取用户数据
  54. var user = await MyApi.get().userProfile();
  55. await UserService.get().saveUser(user.data);
  56. // 获取字典
  57. var dictData = await MyApi.get().getAllDict();
  58. DictService.saveDictList(dictData.data);
  59. UpgradeService.checkUpgrade(false);
  60. // 进入主页
  61. MyNavigator.dismissLoading();
  62. startHome();
  63. } on DioException catch (_) {
  64. } on Exception catch (a, _) {
  65. logger.e('$a');
  66. MyNavigator.showToast('获取数据失败');
  67. }
  68. MyNavigator.dismissLoading();
  69. }
  70. /// 进入主页
  71. void startHome() {
  72. MyRouter.startMain(popAll: true);
  73. }
  74. @override
  75. void onInit() {
  76. accountCtrl = TextEditingController();
  77. pwdCtrl = TextEditingController();
  78. }
  79. @override
  80. void onFirstShow(Duration timeStamp) async {
  81. // MyNavigator.showLoading();
  82. /// 初始化基础库 start
  83. BaseDio.get().init();
  84. await SPUtils.getInstance().init();
  85. RefreshConfig.get().initDefault();
  86. LocationUtils.updatePrivacyShow(true, true);
  87. LocationUtils.updatePrivacyAgree(true);
  88. LocationUtils.setApiKey(kReleaseMode ? '2c783509376e267b24d63b21681686fa' : '7d0c033909f84adc14a0e60a835f044f', '');
  89. /// 获取手机设备信息
  90. PrintService.getDeviceInfo();
  91. /// 同步数据库里的蓝牙设备信息到服务器
  92. database.savaBleDataToServer();
  93. /// 初始化基础库 end
  94. MyNavigator.dismissLoading();
  95. // 已登录
  96. if (UserService.get().getLogin() != null) {
  97. getSystemData();
  98. }
  99. }
  100. @override
  101. void onDestroy() {
  102. accountCtrl.dispose();
  103. pwdCtrl.dispose();
  104. }
  105. @override
  106. Widget build(BuildContext context) {
  107. return Scaffold(
  108. backgroundColor: const Color(0xFF49AAF2),
  109. body: KeyboardDismissOnTap(
  110. child: SingleChildScrollView(
  111. physics: const BouncingScrollPhysics(),
  112. child: Stack(
  113. children: [
  114. Positioned.fill(child: Image.asset(imgLoginBg, fit: BoxFit.fill)),
  115. SizedBox(
  116. height: MediaQuery.of(context).size.height,
  117. child: buildBody(),
  118. ),
  119. ],
  120. ),
  121. ),
  122. ),
  123. );
  124. }
  125. Widget buildBody() {
  126. return Column(
  127. children: [
  128. const Spacer(flex: 3),
  129. Container(
  130. width: double.infinity,
  131. padding: const EdgeInsets.symmetric(horizontal: 48),
  132. child: Image.asset(imgLoginTitle, fit: BoxFit.fill),
  133. ),
  134. const Spacer(),
  135. loginContainer(),
  136. const Spacer(flex: 7),
  137. ],
  138. );
  139. }
  140. Widget loginContainer() {
  141. return SizedBox(
  142. width: double.infinity,
  143. child: Stack(
  144. alignment: Alignment.topCenter,
  145. children: [
  146. buildInputContent(),
  147. userTitle(),
  148. ],
  149. ),
  150. );
  151. }
  152. Widget userTitle() {
  153. return Row(
  154. children: [
  155. const Spacer(),
  156. Expanded(
  157. child: Container(
  158. padding: const EdgeInsets.symmetric(vertical: 12),
  159. alignment: Alignment.center,
  160. decoration: const BoxDecoration(
  161. color: Colors.white,
  162. borderRadius: BorderRadius.all(Radius.circular(100)),
  163. border: Border.fromBorderSide(BorderSide(color: Color(0xFF49AAF2), width: 1)),
  164. boxShadow: [BoxShadow(color: Color(0x941C90FF), offset: Offset(0, 2))],
  165. ),
  166. child: const Text(
  167. '用户登录',
  168. style: TextStyle(color: Color(0xFF1187DE), fontSize: 14),
  169. ),
  170. ),
  171. ),
  172. const Spacer(),
  173. ],
  174. );
  175. }
  176. Widget buildInputContent() {
  177. return Container(
  178. margin: const EdgeInsets.only(top: 18, left: 16, right: 16),
  179. padding: const EdgeInsets.all(6),
  180. decoration: BoxDecoration(
  181. color: Colors.white.withOpacity(0.2),
  182. borderRadius: const BorderRadius.all(Radius.circular(36)),
  183. ),
  184. child: Container(
  185. padding: const EdgeInsets.symmetric(horizontal: 24),
  186. alignment: Alignment.center,
  187. decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(32))),
  188. child: Column(
  189. children: [
  190. const SizedBox(height: 56),
  191. buildEdit(
  192. ctrl: accountCtrl,
  193. hint: '请输入登录账号',
  194. icon: imgLoginAccount,
  195. action: TextInputAction.next,
  196. ),
  197. const SizedBox(height: 32),
  198. buildEdit(
  199. ctrl: pwdCtrl,
  200. hint: '请输入登录密码',
  201. icon: imgLoginPwd,
  202. obscure: true,
  203. onSubmit: (value) => onLogin(),
  204. ),
  205. const SizedBox(height: 64),
  206. buildLoginBtn(),
  207. const SizedBox(height: 48),
  208. ],
  209. ),
  210. ),
  211. );
  212. }
  213. Widget buildEdit({
  214. required TextEditingController ctrl,
  215. required String hint,
  216. String? icon,
  217. TextInputAction action = TextInputAction.done,
  218. bool obscure = false,
  219. ValueChanged? onSubmit,
  220. }) {
  221. return TextField(
  222. controller: ctrl,
  223. decoration: InputDecoration(
  224. prefixIcon: icon == null
  225. ? null
  226. : Padding(
  227. padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
  228. child: Image.asset(icon, height: 18),
  229. ),
  230. prefixIconConstraints: const BoxConstraints(),
  231. border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(100))),
  232. enabledBorder: const OutlineInputBorder(
  233. borderSide: BorderSide(color: Color(0xFFE6E6E6), width: 1),
  234. borderRadius: BorderRadius.all(Radius.circular(100)),
  235. ),
  236. hintText: hint,
  237. hintStyle: const TextStyle(color: Color(0xFFBBBBBB)),
  238. isDense: true,
  239. contentPadding: EdgeInsets.zero,
  240. ),
  241. style: const TextStyle(fontSize: 14),
  242. textInputAction: action,
  243. obscureText: obscure,
  244. onSubmitted: onSubmit,
  245. );
  246. }
  247. Widget buildLoginBtn() {
  248. return MyButton(
  249. '登录',
  250. onTap: onLogin,
  251. gradient: const LinearGradient(colors: [Color(0xFF60B5F4), Color(0xFF62A4D6)]),
  252. );
  253. }
  254. }