完善游客模式登录 并且新增设备管理
This commit is contained in:
@@ -1071,6 +1071,21 @@ class AppConfig {
|
||||
/// 网站ID
|
||||
String kr_website_id = "";
|
||||
|
||||
/// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
/// 用户信息固定值(临时)
|
||||
/// ⚠️ 注意:新版本后端已废弃 /v1/app/user/info 接口
|
||||
/// 等待新接口实现后,这些值应该从新接口动态获取
|
||||
/// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
/// 用户余额(单位:分)
|
||||
/// 临时固定值:0,表示0.00元
|
||||
static const int kr_userBalance = 0;
|
||||
|
||||
/// 用户邀请码
|
||||
/// 临时固定值:空字符串,待新接口实现
|
||||
static const String kr_userReferCode = "";
|
||||
|
||||
/// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
/// 是否为白天模式
|
||||
bool kr_is_daytime = true;
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'package:kaer_with_panels/app/utils/kr_device_util.dart';
|
||||
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
||||
|
||||
import '../services/api_service/kr_api.user.dart';
|
||||
import '../services/kr_announcement_service.dart';
|
||||
import '../utils/kr_event_bus.dart';
|
||||
|
||||
class KRAppRunData {
|
||||
@@ -23,11 +24,11 @@ class KRAppRunData {
|
||||
/// 登录token
|
||||
String? kr_token;
|
||||
|
||||
/// 用户账号
|
||||
String? kr_account;
|
||||
/// 用户账号(使用响应式变量以便 UI 能监听变化)
|
||||
final Rx<String?> kr_account = Rx<String?>(null);
|
||||
|
||||
/// 用户ID
|
||||
String? kr_userId;
|
||||
/// 用户ID(使用响应式变量以便 UI 能监听变化)
|
||||
final Rx<int?> kr_userId = Rx<int?>(null);
|
||||
|
||||
/// 登录类型
|
||||
KRLoginType? kr_loginType;
|
||||
@@ -46,17 +47,77 @@ class KRAppRunData {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
/// 判断是否是设备登录(游客模式)
|
||||
bool isDeviceLogin() {
|
||||
// 设备登录的账号格式为 "device_设备ID"
|
||||
return kr_account.value != null && kr_account.value!.startsWith('device_');
|
||||
}
|
||||
|
||||
/// 从JWT token中解析userId
|
||||
int? _kr_parseUserIdFromToken(String token) {
|
||||
try {
|
||||
// JWT格式: header.payload.signature
|
||||
final parts = token.split('.');
|
||||
if (parts.length != 3) {
|
||||
KRLogUtil.kr_e('JWT token格式错误', tag: 'AppRunData');
|
||||
return null;
|
||||
}
|
||||
|
||||
// 解码payload部分(base64)
|
||||
String payload = parts[1];
|
||||
// 手动添加必要的padding(base64要求长度是4的倍数)
|
||||
switch (payload.length % 4) {
|
||||
case 0:
|
||||
break; // 不需要padding
|
||||
case 2:
|
||||
payload += '==';
|
||||
break;
|
||||
case 3:
|
||||
payload += '=';
|
||||
break;
|
||||
default:
|
||||
KRLogUtil.kr_e('JWT payload长度无效', tag: 'AppRunData');
|
||||
return null;
|
||||
}
|
||||
|
||||
final decodedBytes = base64.decode(payload);
|
||||
final decodedString = utf8.decode(decodedBytes);
|
||||
|
||||
// 解析JSON
|
||||
final Map<String, dynamic> payloadMap = jsonDecode(decodedString);
|
||||
|
||||
// 获取UserId
|
||||
if (payloadMap.containsKey('UserId')) {
|
||||
final userId = payloadMap['UserId'];
|
||||
KRLogUtil.kr_i('从JWT解析出userId: $userId', tag: 'AppRunData');
|
||||
return userId is int ? userId : int.tryParse(userId.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('解析JWT token失败: $e', tag: 'AppRunData');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 保存用户信息
|
||||
Future<void> kr_saveUserInfo(
|
||||
String token, String account, KRLoginType loginType, String? areaCode) async {
|
||||
String token,
|
||||
String account,
|
||||
KRLoginType loginType,
|
||||
String? areaCode) async {
|
||||
KRLogUtil.kr_i('开始保存用户信息', tag: 'AppRunData');
|
||||
|
||||
|
||||
try {
|
||||
// 更新内存中的数据
|
||||
kr_token = token;
|
||||
kr_account = account;
|
||||
kr_account.value = account;
|
||||
kr_loginType = loginType;
|
||||
kr_areaCode = areaCode;
|
||||
|
||||
// 从JWT token中解析userId
|
||||
kr_userId.value = _kr_parseUserIdFromToken(token);
|
||||
KRLogUtil.kr_i('从JWT解析userId: ${kr_userId.value}', tag: 'AppRunData');
|
||||
|
||||
final Map<String, dynamic> userInfo = {
|
||||
'token': token,
|
||||
@@ -81,15 +142,13 @@ class KRAppRunData {
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('用户信息保存成功,设置登录状态为true', tag: 'AppRunData');
|
||||
|
||||
|
||||
// 只有在保存成功后才设置登录状态
|
||||
kr_isLogin.value = true;
|
||||
|
||||
// 异步获取用户信息并建立 Socket 连接,不等待结果
|
||||
_iniUserInfo().catchError((error) {
|
||||
KRLogUtil.kr_e('获取用户信息失败: $error', tag: 'AppRunData');
|
||||
// 即使获取用户信息失败,也保持登录状态
|
||||
});
|
||||
// 设备登录模式不再调用用户信息接口
|
||||
// Socket 连接将在需要时建立
|
||||
KRLogUtil.kr_i('用户信息已保存,跳过用户信息接口调用', tag: 'AppRunData');
|
||||
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('保存用户信息失败: $e', tag: 'AppRunData');
|
||||
@@ -103,20 +162,23 @@ class KRAppRunData {
|
||||
Future<void> kr_loginOut() async {
|
||||
// 先将登录状态设置为 false,防止重连
|
||||
kr_isLogin.value = false;
|
||||
|
||||
|
||||
// 断开 Socket 连接
|
||||
await _kr_disconnectSocket();
|
||||
|
||||
|
||||
// 清理用户信息
|
||||
kr_token = null;
|
||||
kr_account = null;
|
||||
kr_userId = null;
|
||||
kr_account.value = null;
|
||||
kr_userId.value = null;
|
||||
kr_loginType = null;
|
||||
kr_areaCode = null;
|
||||
|
||||
// 删除存储的用户信息
|
||||
await KRSecureStorage().kr_deleteData(key: _keyUserInfo);
|
||||
|
||||
// 重置公告显示状态
|
||||
KRAnnouncementService().kr_reset();
|
||||
|
||||
// 重置主页面
|
||||
Get.find<KRMainController>().kr_setPage(0);
|
||||
}
|
||||
@@ -135,7 +197,7 @@ class KRAppRunData {
|
||||
try {
|
||||
final Map<String, dynamic> userInfo = jsonDecode(userInfoString);
|
||||
kr_token = userInfo['token'];
|
||||
kr_account = userInfo['account'];
|
||||
kr_account.value = userInfo['account'];
|
||||
final loginTypeValue = userInfo['loginType'];
|
||||
kr_loginType = KRLoginType.values.firstWhere(
|
||||
(e) => e.value == loginTypeValue,
|
||||
@@ -143,18 +205,21 @@ class KRAppRunData {
|
||||
);
|
||||
kr_areaCode = userInfo['areaCode'] ?? "";
|
||||
|
||||
KRLogUtil.kr_i('解析用户信息成功: token=${kr_token != null}, account=$kr_account', tag: 'AppRunData');
|
||||
// 从token中解析userId
|
||||
if (kr_token != null && kr_token!.isNotEmpty) {
|
||||
kr_userId.value = _kr_parseUserIdFromToken(kr_token!);
|
||||
}
|
||||
|
||||
KRLogUtil.kr_i('解析用户信息成功: token=${kr_token != null}, account=${kr_account.value}', tag: 'AppRunData');
|
||||
|
||||
// 验证token有效性
|
||||
if (kr_token != null && kr_token!.isNotEmpty) {
|
||||
KRLogUtil.kr_i('设置登录状态为true', tag: 'AppRunData');
|
||||
kr_isLogin.value = true;
|
||||
|
||||
// 异步获取用户信息,但不等待结果
|
||||
_iniUserInfo().catchError((error) {
|
||||
KRLogUtil.kr_e('获取用户信息失败: $error', tag: 'AppRunData');
|
||||
// 如果获取用户信息失败,不重置登录状态,让用户重试
|
||||
});
|
||||
|
||||
// 设备登录模式不需要调用用户信息接口
|
||||
// 用户ID将从订阅信息或其他途径获取
|
||||
KRLogUtil.kr_i('已登录,跳过用户信息接口调用', tag: 'AppRunData');
|
||||
} else {
|
||||
KRLogUtil.kr_w('Token为空,设置为未登录状态', tag: 'AppRunData');
|
||||
kr_isLogin.value = false;
|
||||
@@ -175,20 +240,6 @@ class KRAppRunData {
|
||||
KRLogUtil.kr_i('用户信息初始化完成,登录状态: ${kr_isLogin.value}', tag: 'AppRunData');
|
||||
}
|
||||
|
||||
/// 初始化用户信息并建立 Socket 连接
|
||||
Future<void> _iniUserInfo() async {
|
||||
final either0 = await KRUserApi().kr_getUserInfo();
|
||||
either0.fold(
|
||||
(error) {
|
||||
KRLogUtil.kr_e(error.msg, tag: 'AppRunData');
|
||||
},
|
||||
(userInfo) async {
|
||||
kr_userId = userInfo.id.toString();
|
||||
_kr_connectSocket(kr_userId!);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 建立 Socket 连接
|
||||
Future<void> _kr_connectSocket(String userId) async {
|
||||
// 如果已存在连接,先断开
|
||||
|
||||
Reference in New Issue
Block a user