Flutter登录应用求助:公司代码/账号/密码错误时拦截登录
Flutter登录应用的空值校验问题及修复方案
一、空值校验代码的问题
你这段空值校验逻辑完全写反了:
// 错误代码 if (DBname.isNotEmpty || empl_no.isNotEmpty || passwd.isNotEmpty) { print('Please fill in all fields.'); return; }
当前逻辑是只要任意一个字段不为空,就提示用户填完所有字段,这和你要的「检查所有字段是否填写」完全相反。正确逻辑应该是只要任意一个字段为空,就拦截并提示:
// 修正后的空值校验 if (DBname.isEmpty || empl_no.isEmpty || passwd.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('请填写所有字段')), ); return; }
二、代码里的其他关键问题
除了空值校验,你的代码还有几个会导致登录逻辑失效的问题:
- 用户编号和密码字段未绑定控制器:你声明了
_empl_noController和_passwdController,但对应的TextField没设置controller属性,导致拿不到用户输入的账号和密码,数据库查询永远查不到数据。 - 登录失败后仍会跳转页面:代码最后不管数据库查询结果如何,都会执行
Navigator.push跳转到Menu页面,这会导致即使账号密码错误,用户也能进入首页,必须把跳转逻辑只放在登录成功的分支里。 - TextFormField的validator未生效:你给公司代码的TextFormField加了validator,但没有用
Form组件包裹,validator不会自动触发,建议用Form组件统一管理表单验证。
三、修正后的核心代码片段
下面是修复后的登录按钮点击逻辑,包含正确的空值校验、控制器绑定、数据库验证和页面跳转:
// 先给用户编号和密码的TextField绑定控制器 TextField( maxLength: 6, controller: _empl_noController, // 绑定控制器 decoration: InputDecoration( labelText: '用户编号', ), ), TextField( obscureText: true, controller: _passwdController, // 绑定控制器 decoration: InputDecoration( labelText: '密码', ), ), // 登录按钮的onPressed逻辑 onPressed: () async { final String DBname = DBnameController.text; final String empl_no = _empl_noController.text; final String passwd = _passwdController.text; // 正确的空值校验 if (DBname.isEmpty || empl_no.isEmpty || passwd.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('请填写所有字段')), ); return; } PostgreSQLConnection connection = PostgreSQLConnection( 'ip', 5432, DBname, username: 'username', password: 'password', ); try { await connection.open(); // 修正SQL语句的重复别名问题 final List<List<dynamic>> results = await connection.query( 'SELECT empl_no, passwd FROM spaprsn0 WHERE empl_no = @empl_no AND passwd = @passwd', substitutionValues: { 'empl_no': empl_no, 'passwd': passwd, }, ); if (results.isNotEmpty) { // 登录成功,跳转页面 print('登录成功'); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('登录成功')), ); Navigator.push( context, MaterialPageRoute(builder: (_) => Menu()), ); } else { // 账号或密码错误 print('用户编号或密码错误'); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('用户编号或密码错误')), ); } } catch (e) { // 捕获数据库连接或查询异常 print('登录出错:$e'); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('登录失败,请稍后重试')), ); } finally { await connection.close(); } },
四、额外建议
- 不要明文存储和传输密码,建议在后端对密码进行哈希处理,前端只传明文密码,后端比对哈希值。
- 可以给输入框添加实时验证,比如用户输入时就提示格式错误(比如公司代码必须是4位)。
内容的提问来源于stack exchange,提问作者김민규
相关产品推荐
相关产品推荐

