change_password.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'package:eitc_erm_app/bean/normal_response.dart';
  4. import 'package:eitc_erm_app/utils/Component.dart';
  5. import 'package:eitc_erm_app/utils/Constants.dart';
  6. import 'package:eitc_erm_app/utils/logger.dart';
  7. import 'package:flutter/material.dart';
  8. import 'package:flutter/services.dart';
  9. import 'package:http/http.dart' as http;
  10. import 'package:http/http.dart';
  11. import 'login.dart';
  12. class ChangePasswordPage extends StatefulWidget {
  13. @override
  14. _ChangePasswordPageState createState() => _ChangePasswordPageState();
  15. }
  16. class _ChangePasswordPageState extends State<ChangePasswordPage> {
  17. final _formKey = GlobalKey<FormState>();
  18. String phoneNo = '';
  19. String _newPassword = '';
  20. String _confirmPassword = '';
  21. bool _isLoading = false;
  22. bool isButtonEnable = true;
  23. int count = 60;
  24. Timer? timer;
  25. String buttonText = '发送验证码';
  26. TextEditingController mController = TextEditingController();
  27. void _buttonClickListen() {
  28. setState(() {
  29. sendCaptchaCode();
  30. if (isButtonEnable) {
  31. //当按钮可点击时
  32. isButtonEnable = false; //按钮状态标记
  33. _initTimer();
  34. return null; //返回null按钮禁止点击
  35. } else {
  36. //当按钮不可点击时
  37. // logd('false');
  38. return null; //返回null按钮禁止点击
  39. }
  40. });
  41. }
  42. void _initTimer() {
  43. timer = Timer.periodic(const Duration(seconds: 1), (Timer timer) {
  44. count--;
  45. setState(() {
  46. if (count == 0) {
  47. timer.cancel(); //倒计时结束取消定时器
  48. isButtonEnable = true; //按钮可点击
  49. count = 60; //重置时间
  50. buttonText = '发送验证码'; //重置按钮文本
  51. } else {
  52. buttonText = '重新发送($count)'; //更新文本内容
  53. }
  54. });
  55. });
  56. }
  57. @override
  58. void dispose() {
  59. timer?.cancel();
  60. super.dispose();
  61. }
  62. ///检查验证码
  63. Future<bool> _checkCaptchaCode() async {
  64. Map<String, dynamic> params = {
  65. "phoneNumber": Global.loginPhoneNo,
  66. "captchaCode": mController.text
  67. };
  68. Uri uri = Uri.parse("${Global.BaseUrl}api/checkCaptchaCode");
  69. logd("检查验证码,uri=$uri");
  70. Response response =
  71. await http.post(uri, body: encodeBody(params), headers: jsonHeaders());
  72. if (response.statusCode == 200) {
  73. final json = decodeBodyToJson(response.bodyBytes);
  74. logd("检查验证码结果$json");
  75. NormalResponse mNormalResponse = NormalResponse.fromJson(json);
  76. return mNormalResponse.code == 200;
  77. } else {
  78. logd("检查验证码异常${response.body}");
  79. }
  80. return false;
  81. }
  82. Future<void> _changePassword(
  83. {required String newPassword, required String phoneNo}) async {
  84. bool bo = await _checkCaptchaCode();
  85. if (!bo) {
  86. Component.toast("验证码错误!", 0);
  87. return;
  88. }
  89. var params = {
  90. 'phoneNumber': phoneNo,
  91. 'password': newPassword,
  92. 'confirmPassword': newPassword,
  93. 'captchaCode': mController.text,
  94. };
  95. final response =
  96. await http.post(Uri.parse('${Global.BaseUrl}user/setPassword'),
  97. headers: jsonHeaders(withToken: true),
  98. body: encodeBody(params));
  99. setState(() {
  100. _isLoading = true;
  101. });
  102. try {
  103. final json = decodeBodyToJson(response.bodyBytes);
  104. logd("修改密码结果=$json");
  105. NormalResponse mNormalResponse = new NormalResponse.fromJson(json);
  106. if (mNormalResponse.code == Global.responseSuccessCode) {
  107. Component.toast("密码修改成功!", 2);
  108. Navigator.of(context).pop();
  109. Navigator.pushReplacement(
  110. context,
  111. MaterialPageRoute(builder: (context) => Login()),
  112. );
  113. } else {
  114. Component.toast(mNormalResponse.msg.toString(), 0);
  115. }
  116. } catch (e) {
  117. Component.toast("异常: $e", 0);
  118. } finally {
  119. setState(() {
  120. _isLoading = false;
  121. });
  122. }
  123. }
  124. @override
  125. Widget build(BuildContext context) {
  126. return Scaffold(
  127. appBar: AppBar(
  128. title: const Text('修改密码',
  129. style: TextStyle(
  130. color: Colors.white,
  131. )),
  132. centerTitle: true,
  133. elevation: 0.5,
  134. backgroundColor: Global.StatusBarColor,
  135. leading: IconButton(
  136. tooltip: '返回上一页',
  137. icon: const Icon(
  138. Icons.arrow_back_ios,
  139. color: Colors.white,
  140. ),
  141. onPressed: () {
  142. Navigator.of(context).pop();
  143. //_nextPage(-1);
  144. },
  145. ),
  146. ),
  147. body: SingleChildScrollView(
  148. child: Form(
  149. key: _formKey,
  150. child: Padding(
  151. padding: const EdgeInsets.all(20.0),
  152. child: Column(
  153. children: <Widget>[
  154. const SizedBox(height: 30.0),
  155. TextFormField(
  156. enabled: false,
  157. decoration: const InputDecoration(
  158. labelText: '手机号',
  159. ),
  160. initialValue: Global.loginPhoneNo,
  161. onSaved: (value) => phoneNo = value!,
  162. ),
  163. TextFormField(
  164. decoration: const InputDecoration(labelText: '新密码'),
  165. obscureText: true,
  166. onSaved: (value) => _newPassword = value!,
  167. ),
  168. TextFormField(
  169. decoration: const InputDecoration(labelText: '确认新密码'),
  170. obscureText: true,
  171. onSaved: (value) => _confirmPassword = value!,
  172. ),
  173. Row(
  174. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  175. crossAxisAlignment: CrossAxisAlignment.baseline,
  176. textBaseline: TextBaseline.alphabetic,
  177. children: <Widget>[
  178. Expanded(
  179. child: Padding(
  180. padding:
  181. const EdgeInsets.only(left: 0, right: 15, top: 15),
  182. child: TextFormField(
  183. maxLines: 1,
  184. onSaved: (value) {},
  185. controller: mController,
  186. textAlign: TextAlign.left,
  187. inputFormatters: [
  188. FilteringTextInputFormatter.digitsOnly,
  189. LengthLimitingTextInputFormatter(6)
  190. ],
  191. decoration: const InputDecoration(
  192. hintText: ('请输入验证码'),
  193. contentPadding: EdgeInsets.only(top: -5, bottom: 0),
  194. alignLabelWithHint: true,
  195. // border:
  196. // OutlineInputBorder(borderSide: BorderSide.none),
  197. ),
  198. ),
  199. ),
  200. ),
  201. Container(
  202. padding: const EdgeInsets.all(0),
  203. width: 120,
  204. child: ElevatedButton(
  205. style: ButtonStyle(
  206. backgroundColor:
  207. WidgetStateProperty.resolveWith<Color>((states) {
  208. return Colors.blue; // Regular color
  209. }),
  210. foregroundColor:
  211. WidgetStateProperty.all(Colors.white),
  212. ),
  213. // backgroundColor : isButtonEnable
  214. // ? Color(0xff44c5fe)
  215. // : Colors.grey.withOpacity(0.1), //按钮的颜色
  216. // splashColor: isButtonEnable
  217. // ? Colors.white.withOpacity(0.1)
  218. // : Colors.transparent,
  219. // shape: StadiumBorder(side: BorderSide.none),
  220. onPressed: () {
  221. setState(() {
  222. _buttonClickListen();
  223. });
  224. },
  225. child: Text(
  226. buttonText,
  227. style: TextStyle(
  228. fontSize: 12,
  229. ),
  230. ),
  231. ),
  232. ),
  233. ],
  234. ),
  235. Container(
  236. width: double.infinity,
  237. height: 45,
  238. margin: EdgeInsets.only(top: 40, left: 10, right: 10),
  239. child: ElevatedButton(
  240. style: ButtonStyle(
  241. backgroundColor:
  242. MaterialStateProperty.resolveWith<Color>((states) {
  243. return Colors.blue; // Regular color
  244. }),
  245. ),
  246. child: _isLoading
  247. ? CircularProgressIndicator(
  248. valueColor:
  249. AlwaysStoppedAnimation<Color>(Colors.white),
  250. )
  251. : Text(
  252. '修改密码',
  253. style: TextStyle(color: Colors.white, fontSize: 15),
  254. ),
  255. onPressed: _isLoading
  256. ? null
  257. : () {
  258. if (_formKey.currentState!.validate()) {
  259. _formKey.currentState?.save();
  260. if (_newPassword != _confirmPassword) {
  261. Component.toast("两次密码输入不一致", 0);
  262. return;
  263. }
  264. _changePassword(
  265. phoneNo: phoneNo,
  266. newPassword: _newPassword,
  267. );
  268. }
  269. },
  270. ),
  271. ),
  272. ],
  273. ),
  274. ),
  275. ),
  276. ),
  277. );
  278. }
  279. Future<String?> sendCaptchaCode() async {
  280. var params = {
  281. 'phoneNumber': Global.loginPhoneNo,
  282. };
  283. var response = await http.post(
  284. Uri.parse('${Global.BaseUrl}sendCaptchaCode'),
  285. body: encodeBody(params),
  286. headers: jsonHeaders());
  287. if (response.statusCode == 200) {
  288. final json = decodeBodyToJson(response.bodyBytes);
  289. logd("发送验证码结果=$json");
  290. NormalResponse mNormalResponse = new NormalResponse.fromJson(json);
  291. if (mNormalResponse.code == Global.responseSuccessCode) {
  292. Component.toast("短信发送成功,请查收!", 2);
  293. } else {
  294. Component.toast(mNormalResponse.msg.toString(), 0);
  295. }
  296. return response.toString();
  297. } else {
  298. Component.toast("出错了,请稍后再试!", 0);
  299. return null;
  300. }
  301. }
  302. }