忘记密码

This commit is contained in:
2025-11-18 17:08:46 +08:00
parent 959fe89bed
commit 6a78d186d0
2 changed files with 84 additions and 82 deletions

View File

@@ -18,25 +18,26 @@ class LoginPage extends StatefulWidget {
class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMixin {
late TabController tabController;
//默认司机端
bool cLogin = true;
bool _obscureText = true; // 默认密码为隐藏状态
bool _obscureText = true;
// 用于管理“记住密码”的复选框状态
bool _rememberPassword = true;
// 用于确保凭证只在首次加载时回填一次
bool _credentialsLoaded = false;
@override
void initState() {
super.initState();
// 初始化 TabController传入 vsync 参数
tabController = TabController(length: 2, vsync: this);
tabController.addListener(_tabChangeListener);
}
void _tabChangeListener() {
// 如果 TabController 不是正在被用户手动滑动(即是初始化或其他操作)
if (!tabController.indexIsChanging) {
switchTab(tabController.index);
}
}
// 切换Tab
void switchTab(int index) {
setState(() {
cLogin = (index == 0);
@@ -45,14 +46,22 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
@override
void dispose() {
tabController.dispose(); // 销毁 TabController
tabController.dispose();
super.dispose();
}
// 主视图
Widget _buildView() {
// 使用 Get.find 获取控制器
final controller = Get.find<LoginController>();
Widget _buildView(LoginController controller) {
// 在视图构建时,检查并回填已保存的凭证
if (!_credentialsLoaded) {
final savedAccount = StorageService.to.stationAccount;
final savedPassword = StorageService.to.stationPassword;
if (savedAccount != null && savedPassword != null) {
controller.stationIdController.text = savedAccount;
controller.passwordController.text = savedPassword;
_rememberPassword = true; // 如果有保存的密码,则默认勾选
}
_credentialsLoaded = true; // 标记为已加载,防止重复执行
}
return Container(
color: Color(0xFFEFF4F7),
@@ -69,10 +78,9 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
margin: EdgeInsets.all(15),
elevation: 4,
child: Container(
height: cLogin ? 285.h : 350.h,
height: cLogin ? 285.h : 360.h,
padding: EdgeInsets.all(15),
child: // TabBar切换
Column(
child: Column(
children: [
Card(
elevation: 2,
@@ -82,19 +90,15 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
child: TabBar(
controller: tabController,
onTap: (index) {
//保证尺寸变化
delayed(300, () {
switchTab(index);
});
},
// 修改TabBar的选中状态和未选中状态样式
labelColor: Colors.white,
// 选中时的文字颜色
unselectedLabelColor: Colors.black,
// 未选中时的文字颜色
indicator: BoxDecoration(
color: AppTheme.themeColor, // 选中的Tab背景色模拟卡片式效果
borderRadius: BorderRadius.circular(12), // 卡片的圆角效果
color: AppTheme.themeColor,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.blue.withOpacity(0.2),
@@ -111,14 +115,11 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
),
),
),
// 根据选择的Tab展示不同的输入框
Flexible(
child: TabBarView(
controller: tabController,
children: [
// 司机端登录
_driverLoginView(controller),
// 加氢站登录
_stationLoginView(controller),
],
),
@@ -131,7 +132,6 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
);
}
// 司机端登录界面
Widget _driverLoginView(LoginController controller) {
return !cLogin
? SizedBox()
@@ -158,44 +158,28 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
SizedBox(height: 20.h),
ElevatedButton(
onPressed: () async {
// 司机端登录
String password = controller.driverIdentityController.text;
if (password.isEmpty) {
showToast("请输入密码");
return;
}
showLoading('登录中...');
try {
// 调用登录接口
var responseData = await HttpService.to.post(
'appointment/login/loginForDriver',
data: {'idNo': password},
);
if (responseData == null && responseData!.data == null) {
dismissLoading();
showToast('登录失败:无法获取凭证');
return;
}
try {
var result = BaseModel.fromJson(responseData.data);
//保存用户信息
String token = result.data['token'] ?? '';
String idCard = result.data['idCard'] ?? '';
String name = result.data['name'] ?? '';
String phone = result.data['phone'] ?? '';
/*{
"token": "a615cf38a066473ebf8e9a956fc51928",
"idCard": "330324200010241024",
"name": "王小龙",
"phone": "15888331828"
}*/
await StorageService.to.saveLoginInfo(
token: token,
userId: "",
@@ -204,14 +188,10 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
name: name,
phone: phone,
);
dismissLoading();
showToast('登录成功,欢迎您');
// 跳转到主页,并清除所有历史页面
Get.offAll(() => BaseWidgetsPage());
} catch (e) {
// 如果解析 JSON 失败
dismissLoading();
showToast('登录失败:数据异常');
}
@@ -221,7 +201,7 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
},
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.themeColor,
minimumSize: Size(double.infinity, 50), // 设置按钮宽度占满,指定最小高度
minimumSize: Size(double.infinity, 50),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
),
child: Text('登录'),
@@ -230,7 +210,6 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
);
}
// 加氢站登录界面
Widget _stationLoginView(LoginController controller) {
return cLogin
? SizedBox()
@@ -253,7 +232,7 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
),
),
),
SizedBox(height: 20),
SizedBox(height: 10),
TextFormField(
controller: controller.passwordController,
obscureText: _obscureText,
@@ -266,7 +245,7 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
border: OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(
_obscureText ? Icons.visibility_off : Icons.visibility, // 切换图标
_obscureText ? Icons.visibility_off : Icons.visibility,
),
onPressed: () {
setState(() {
@@ -280,22 +259,40 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
),
),
),
SizedBox(height: 20),
SizedBox(height: 10),
//记住密码复选框 ---
Row(
children: <Widget>[
SizedBox(
height: 24,
width: 24,
child: Checkbox(
value: _rememberPassword,
activeColor: AppTheme.themeColor,
onChanged: (bool? value) {
setState(() {
_rememberPassword = value ?? true;
});
},
),
),
GestureDetector(
onTap: () => setState(() => _rememberPassword = !_rememberPassword),
child: const Text('记住密码', style: TextStyle(color: Colors.grey)),
)
],
),
SizedBox(height: 20), // 调整间距
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.themeColor,
minimumSize: Size(double.infinity, 50), // 设置按钮宽度占满,指定最小高度
minimumSize: Size(double.infinity, 50),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
),
onPressed: () async {
// 加氢站登录逻辑
String account = controller.stationIdController.text;
String password = controller.passwordController.text;
//todo 删除
account = "000017";
password = "LnQn.314000";
if (account.isEmpty || password.isEmpty) {
showToast("请输入账号和密码");
return;
@@ -304,10 +301,7 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
showLoading('登录中...');
try {
// 对密码进行AES加密
String encryptedPassword = LoginUtil.encrypt(password);
// 调用登录接口
var responseData = await HttpService.to.post(
'/login/password',
data: {
@@ -325,10 +319,7 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
try {
var result = BaseModel.fromJson(responseData.data);
//保存用户信息
String token = result.data['token'] ?? '';
//hydrogenId
String userId = result.data['userId'] ?? '';
await StorageService.to.saveLoginInfo(
@@ -337,13 +328,17 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
channel: "station",
);
// 根据复选框状态保存或清除密码 ---
if (_rememberPassword) {
await StorageService.to.saveStationCredentials(account, password);
} else {
await StorageService.to.clearStationCredentials();
}
dismissLoading();
showToast('登录成功,欢迎您');
// 跳转到主页,并清除所有历史页面
Get.offAll(() => B_BaseWidgetsPage());
} catch (e) {
// 如果解析 JSON 失败
dismissLoading();
showToast('登录失败:数据异常');
}
@@ -362,8 +357,8 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
return GetBuilder<LoginController>(
init: LoginController(),
id: 'login',
builder: (_) {
return Scaffold(body: _buildView());
builder: (controller) {
return Scaffold(body: _buildView(controller));
},
);
}