import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/pages/user/login_page.dart'; import 'package:qhd_prevention/services/SessionService.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../http/ApiService.dart'; class MineSetPwdPage extends StatefulWidget { const MineSetPwdPage(this.type, {super.key}); final String type; @override State createState() => _MineSetPwdPageState(); } class _MineSetPwdPageState extends State { final _formKey = GlobalKey(); final _oldPwdController = TextEditingController(); final _newPwdController = TextEditingController(); final _confirmPwdController = TextEditingController(); bool _obscureOld = true; bool _obscureNew = true; bool _obscureConfirm = true; String textString = "为了您的账户安全,请确保密码长度为 8-18 位,必须包含大小写字母+数字+特殊字符,例如:Aa@123456"; Map passData = { "id": '', "password": "", "newPassword": "", }; @override void initState() { super.initState(); switch (widget.type) { case "0": textString = "密码长度8-18位,需包含数字、字母、英文符号至少2种或以上元素"; break; case "1": textString = "检测到您的密码为弱密码,请修改密码后重新登录。为了您的账户安全,请确保密码长度为 8-18 位,必须包含大小写字母+数字+特殊字符,例如:Aa@123456"; break; case "2": textString = "检测到您30天内未修改密码,请修改密码后重新登录。为了您的账户安全,请确保密码长度为 8-18 位,必须包含大小写字母+数字+特殊字符,例如:Aa@123456"; break; case "3": textString = "检测到您的密码为弱密码,请修改密码后重新登录。为了您的账户安全,请确保密码长度为 8-18 位,必须包含大小写字母+数字+特殊字符,例如:Aa@123456"; break; case "4": textString = "检测到您30天内未修改密码,请修改密码后重新登录。为了您的账户安全,请确保密码长度为 8-18 位,必须包含大小写字母+数字+特殊字符,例如:Aa@123456"; break; } } @override void dispose() { _oldPwdController.dispose(); _newPwdController.dispose(); _confirmPwdController.dispose(); super.dispose(); } // 与登录页一致的输入框样式 Widget _buildRoundedInput({ required TextEditingController controller, required String hint, bool obscure = false, VoidCallback? toggleObscure, FormFieldValidator? validator, }) { return TextFormField( controller: controller, obscureText: obscure, validator: validator, decoration: InputDecoration( hintText: hint, hintStyle: const TextStyle(color: Colors.grey), filled: true, fillColor: const Color(0xFFE2EBF4), contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14), suffixIcon: toggleObscure == null ? null : IconButton( icon: Icon( obscure ? Icons.visibility_off : Icons.visibility, color: Colors.grey, ), onPressed: toggleObscure, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30), borderSide: BorderSide.none, ), ), style: const TextStyle(color: Colors.black), ); } // 密码复杂度校验 bool isPasswordValid(String password) { final hasUpperCase = RegExp(r'[A-Z]'); final hasLowerCase = RegExp(r'[a-z]'); final hasNumber = RegExp(r'[0-9]'); final hasSpecialChar = RegExp(r'[!@#\$%\^&\*\(\)_\+\-=\[\]\{\};:"\\|,.<>\/\?~`]'); return hasUpperCase.hasMatch(password) && hasLowerCase.hasMatch(password) && hasNumber.hasMatch(password) && hasSpecialChar.hasMatch(password); } void _handleSubmit() async { // 使用 Form 验证必填 if (!(_formKey.currentState?.validate() ?? false)) return; final oldPwd = _oldPwdController.text.trim(); final newPwd = _newPwdController.text.trim(); final confirmPwd = _confirmPwdController.text.trim(); if (newPwd != confirmPwd) { ToastUtil.showNormal(context, '新密码和确认密码两次输入的密码不一致'); return; } if (newPwd.length < 8) { ToastUtil.showNormal(context, '新密码需要大于8位'); return; } if (newPwd.length > 32) { ToastUtil.showNormal(context, '新密码需要小于32位'); return; } if (!isPasswordValid(newPwd)) { ToastUtil.showNormal(context, '新密码必须包含大小写字母、数字和特殊符号。'); return; } await _changePass(oldPwd, newPwd, confirmPwd); } Future _changePass(String oldPwd, String newPwd, String confirmPwd) async { try { passData['id'] = SessionService.instance.accountId ?? ""; passData['password'] = oldPwd; passData['newPassword'] = newPwd; passData['confirmPassword'] = confirmPwd; final raw = await AuthApi.changePassWord(passData); if (raw['success'] == true) { ToastUtil.showNormal(context, '新密码修改成功!'); Navigator.pop(context, true); // 清除用户登录状态 await _clearUserSession(); // 跳转到登录页并清除所有历史路由 Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => const LoginPage()), (Route route) => false, ); } else if (raw['success'] == false) { ToastUtil.showNormal(context, '当前密码密码有误'); } else { ToastUtil.showNormal(context, '登录错误!请联系管理员'); } } catch (e) { print('修改密码出错:$e'); ToastUtil.showNormal(context, '登录错误!请联系管理员'); } } Future _clearUserSession() async { final prefs = await SharedPreferences.getInstance(); await prefs.remove('isLoggedIn'); // 清除登录状态 // 根据你项目的实际 key 再删除 token 等(如果有) // await prefs.remove('user_token'); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: const MyAppbar(title: '修改密码'), body: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '修改密码', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const SizedBox(height: 30), // 当前密码 _buildRoundedInput( controller: _oldPwdController, hint: '当前密码', obscure: _obscureOld, toggleObscure: () => setState(() => _obscureOld = !_obscureOld), validator: (v) { if (v == null || v.isEmpty) return '请输入当前密码'; return null; }, ), const SizedBox(height: 20), // 新密码 _buildRoundedInput( controller: _newPwdController, hint: '新密码', obscure: _obscureNew, toggleObscure: () => setState(() => _obscureNew = !_obscureNew), validator: (v) { if (v == null || v.isEmpty) return '请输入新密码'; return null; }, ), const SizedBox(height: 20), // 确认新密码 _buildRoundedInput( controller: _confirmPwdController, hint: '确认新密码', obscure: _obscureConfirm, toggleObscure: () => setState(() => _obscureConfirm = !_obscureConfirm), validator: (v) { if (v == null || v.isEmpty) return '请输入确认密码'; return null; }, ), const SizedBox(height: 15), Text( textString, style: const TextStyle(color: Colors.red, fontSize: 13), ), const SizedBox(height: 30), SizedBox( width: double.infinity, height: 45, child: CustomButton( onPressed: _handleSubmit, text: "提交", backgroundColor: Colors.blue, ), ), ], ), ), ), ), ); } }