You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter登录后存储Token、Go Router跳转及JSON数据处理求助

解决方案

一、修复JSON解析错误

你的Loginuser.fromJson直接将json['userinfo']赋值给userinfo是错误的,必须通过Userinfo.fromJson解析嵌套对象;另外Userinfo的字段类型明显不符合实际数据(name应为字符串,branchcode/role大概率是整数),先修正数据模型:

class Userinfo {
  final int branchcode;
  final int role;
  final String name;

  Userinfo({required this.branchcode, required this.role, required this.name});

  factory Userinfo.fromJson(Map<String, dynamic> json) {
    return Userinfo(
      branchcode: json['branchcode'] as int,
      role: json['role'] as int,
      name: json['name'] as String,
    );
  }

  // 用于后续存本地的序列化方法
  Map<String, dynamic> toJson() {
    return {
      'branchcode': branchcode,
      'role': role,
      'name': name,
    };
  }
}

class Loginuser {
  final String message;
  final String messagecode;
  final String token;
  final Userinfo userinfo;

  const Loginuser({
    required this.message,
    required this.messagecode,
    required this.token,
    required this.userinfo,
  });

  factory Loginuser.fromJson(Map<String, dynamic> json) {
    return Loginuser(
      message: json['message'] as String,
      messagecode: json['messagecode'] as String,
      token: json['token'] as String,
      // 解析嵌套的userinfo对象
      userinfo: Userinfo.fromJson(json['userinfo'] as Map<String, dynamic>),
    );
  }
}

二、Token存储(用shared_preferences,新手友好)

  1. 在pubspec.yaml添加依赖:
dependencies:
  shared_preferences: ^2.2.2
  1. 封装Token存取方法:
// 保存Token到本地
Future<void> saveToken(String token) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('auth_token', token);
}

// 从本地获取Token
Future<String?> getToken() async {
  final prefs = await SharedPreferences.getInstance();
  return prefs.getString('auth_token');
}

三、登录成功后用Go Router跳转

在登录按钮的点击事件中,完成登录请求后先存Token,再跳转首页:

void handleLogin(String mobile, String password) async {
  try {
    final loginResult = await fetchLoginuser(mobile, password);
    // 保存Token
    await saveToken(loginResult.token);
    // 跳转到首页(假设首页路由为'/home')
    if (context.mounted) {
      context.go('/home');
    }
  } catch (e) {
    // 处理登录失败,比如弹窗提示
    print('登录失败: $e');
  }
}

四、展示用户信息

方法1:全局变量存储(最简单)

定义全局类保存当前用户信息:

class GlobalUser {
  static Userinfo? currentUser;
}

登录成功时赋值:

final loginResult = await fetchLoginuser(mobile, password);
GlobalUser.currentUser = loginResult.userinfo;

首页直接调用:

Column(
  children: [
    Text('用户名: ${GlobalUser.currentUser?.name ?? ''}'),
    Text('角色ID: ${GlobalUser.currentUser?.role ?? 0}'),
    Text('分支代码: ${GlobalUser.currentUser?.branchcode ?? 0}'),
  ],
)

方法2:FutureBuilder(适合需要重新加载的场景)

如果需要从本地重新读取用户信息,先封装读取方法:

Future<Userinfo?> getUserInfo() async {
  final prefs = await SharedPreferences.getInstance();
  final userInfoStr = prefs.getString('user_info');
  if (userInfoStr != null) {
    return Userinfo.fromJson(jsonDecode(userInfoStr));
  }
  return null;
}

登录成功时同时存用户信息到本地:

await prefs.setString('user_info', jsonEncode(loginResult.userinfo.toJson()));

首页用FutureBuilder展示:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: FutureBuilder<Userinfo?>(
      future: getUserInfo(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return Center(child: Text('加载失败: ${snapshot.error}'));
        } else if (snapshot.hasData && snapshot.data != null) {
          final user = snapshot.data!;
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('欢迎你, ${user.name}'),
              Text('角色ID: ${user.role}'),
              Text('分支代码: ${user.branchcode}'),
            ],
          );
        } else {
          return const Center(child: Text('未登录'));
        }
      },
    ),
  );
}

内容的提问来源于stack exchange,提问作者Hari .S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 08:45:16