QinGang_interested/lib/pages/mine/mine_set_pwd_page.dart

279 lines
9.3 KiB
Dart
Raw Normal View History

2025-12-12 09:11:30 +08:00
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<MineSetPwdPage> createState() => _MineSetPwdPageState();
}
class _MineSetPwdPageState extends State<MineSetPwdPage> {
final _formKey = GlobalKey<FormState>();
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<String, dynamic> 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<String>? 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<void> _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<dynamic> route) => false,
);
} else if (raw['success'] == false) {
ToastUtil.showNormal(context, '当前密码密码有误');
} else {
ToastUtil.showNormal(context, '登录错误!请联系管理员');
}
} catch (e) {
print('修改密码出错:$e');
ToastUtil.showNormal(context, '登录错误!请联系管理员');
}
}
Future<void> _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,
),
),
],
),
),
),
),
);
}
}