QinGang_interested/lib/pages/mine/mine_set_pwd_page.dart

279 lines
9.3 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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,
),
),
],
),
),
),
),
);
}
}