feat: 更新代码仓库全部修改
Build Android APK / 编译 libcore.aar (push) Has been cancelled
Build Android APK / 编译 Android APK (release) (push) Has been cancelled
Build Android APK / 创建 GitHub Release (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Android) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Windows) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (macOS) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Linux) (push) Has been cancelled
Build Multi-Platform / 构建 Android APK (push) Has been cancelled
Build Multi-Platform / 构建 Windows (push) Has been cancelled
Build Multi-Platform / 构建 macOS (push) Has been cancelled
Build Multi-Platform / 构建 Linux (push) Has been cancelled
Build Multi-Platform / 创建 Release (push) Has been cancelled
Build Windows / build (push) Has been cancelled
Build Android APK / 编译 libcore.aar (push) Has been cancelled
Build Android APK / 编译 Android APK (release) (push) Has been cancelled
Build Android APK / 创建 GitHub Release (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Android) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Windows) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (macOS) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Linux) (push) Has been cancelled
Build Multi-Platform / 构建 Android APK (push) Has been cancelled
Build Multi-Platform / 构建 Windows (push) Has been cancelled
Build Multi-Platform / 构建 macOS (push) Has been cancelled
Build Multi-Platform / 构建 Linux (push) Has been cancelled
Build Multi-Platform / 创建 Release (push) Has been cancelled
Build Windows / build (push) Has been cancelled
This commit is contained in:
@@ -16,7 +16,7 @@ import 'package:flutter/foundation.dart';
|
||||
class KRProtocol {
|
||||
static const String kr_https = "https";
|
||||
static const String kr_http = "http";
|
||||
static const String kr_ws = "ws";
|
||||
static const String kr_ws = "wss";
|
||||
}
|
||||
|
||||
/// 域名配置
|
||||
@@ -26,25 +26,27 @@ class KRDomain {
|
||||
static const String kr_domainKey = "kr_base_domain";
|
||||
static const String kr_domainsKey = "kr_domains_list";
|
||||
|
||||
static List<String> kr_baseDomains = ["api.maodag.top","api.maodag.top"];
|
||||
static String kr_currentDomain = "api.maodag.top";
|
||||
// static List<String> kr_baseDomains = ["apicn.bearvpn.top","apibear.nsdsox.com"];
|
||||
// static String kr_currentDomain = "apicn.bearvpn.top";
|
||||
|
||||
// static List<String> kr_baseDomains = ["api.kkmen.cc"];
|
||||
// static String kr_currentDomain = "api.kkmen.cc";
|
||||
static List<String> kr_baseDomains = ["api.hifast.biz",];
|
||||
static String kr_currentDomain = "api.hifast.biz";
|
||||
|
||||
// 备用域名获取地址列表
|
||||
static List<String> kr_backupDomainUrls = [
|
||||
"https://ppp2.oss-cn-hongkong.aliyuncs.com/bear1.txt",
|
||||
"https://xgp3.oss-ap-northeast-1.aliyuncs.com/bear1.txt",
|
||||
"https://xpp4.oss-ap-northeast-2.aliyuncs.com/bear1.txt",
|
||||
"https://xpp5.oss-ap-southeast-1.aliyuncs.com/bear1.txt",
|
||||
// "https://bear-1347601445.cos.ap-guangzhou.myqcloud.com/bear.txt",
|
||||
// "https://getbr.oss-cn-shanghai.aliyuncs.com/bear.txt",
|
||||
// "https://gitee.com/karelink/getbr/raw/master/README.en.md",
|
||||
// "https://configfortrans.oss-cn-guangzhou.aliyuncs.com/bear/bear.txt",
|
||||
];
|
||||
|
||||
// 本地备用域名列表(当服务器获取的域名都不可用时使用)
|
||||
static List<String> kr_localBackupDomains = [
|
||||
"p1.maoayi.top",
|
||||
"p2.maoayi.top",
|
||||
"p3.maoayi.top",
|
||||
// "api.omntech.com",
|
||||
// "api6.omntech.com",
|
||||
// "api7.omntech.com",
|
||||
// "apicn.bearvpn.top",
|
||||
// "apibear.nsdsox.com",
|
||||
];
|
||||
|
||||
static final _storage = KRSecureStorage();
|
||||
@@ -365,10 +367,10 @@ class KRDomain {
|
||||
/// 预检测域名可用性(在应用启动时调用)
|
||||
static Future<void> kr_preCheckDomains() async {
|
||||
// Debug 模式下跳过域名预检测
|
||||
if (kDebugMode) {
|
||||
KRLogUtil.kr_i('🐛 Debug 模式,跳过域名预检测', tag: 'KRDomain');
|
||||
return;
|
||||
}
|
||||
// if (kDebugMode) {
|
||||
// KRLogUtil.kr_i('🐛 Debug 模式,跳过域名预检测', tag: 'KRDomain');
|
||||
// return;
|
||||
// }
|
||||
|
||||
KRLogUtil.kr_i('🚀 开始预检测域名可用性', tag: 'KRDomain');
|
||||
|
||||
@@ -1055,23 +1057,22 @@ class AppConfig {
|
||||
|
||||
/// 请求域名地址
|
||||
/// 基础url
|
||||
///
|
||||
// static String baseUrl = "http://103.112.98.72:8088";
|
||||
|
||||
/// 请求域名地址调试模式
|
||||
/// 请求域名地址
|
||||
String get baseUrl {
|
||||
if (kDebugMode) {
|
||||
return "http://154.12.35.103:8080";
|
||||
}
|
||||
// if (kDebugMode) {
|
||||
// return "http://192.168.0.113:8082";
|
||||
// }
|
||||
return "${KRProtocol.kr_https}://${KRDomain.kr_api}";
|
||||
}
|
||||
|
||||
/// ⚠️ 已遗弃:WebSocket 连接不再使用
|
||||
@Deprecated('wsBaseUrl has been deprecated')
|
||||
String get wsBaseUrl {
|
||||
if (kDebugMode) {
|
||||
return "ws://192.168.0.113";
|
||||
}
|
||||
// if (kDebugMode) {
|
||||
// return "ws://192.168.0.113";
|
||||
// }
|
||||
return "${KRProtocol.kr_ws}://${KRDomain.kr_ws}";
|
||||
}
|
||||
|
||||
@@ -1095,22 +1096,6 @@ 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;
|
||||
|
||||
@@ -1151,15 +1136,17 @@ class AppConfig {
|
||||
_isInitializing = true;
|
||||
try {
|
||||
// Debug 模式下直接使用固定地址,跳过所有配置请求和域名切换逻辑
|
||||
if (kDebugMode) {
|
||||
KRLogUtil.kr_i('🐛 Debug 模式,使用固定 API 地址,跳过配置请求', tag: 'AppConfig');
|
||||
if (onSuccess != null) {
|
||||
await onSuccess();
|
||||
}
|
||||
return;
|
||||
// if (kDebugMode) {
|
||||
// KRLogUtil.kr_i('🐛 Debug 模式,使用固定 API 地址,跳过配置请求', tag: 'AppConfig');
|
||||
// if (onSuccess != null) {
|
||||
// await onSuccess();
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
if (onSuccess != null) {
|
||||
await onSuccess();
|
||||
}
|
||||
|
||||
await _startAutoRetry(onSuccess);
|
||||
// await _startAutoRetry(onSuccess);
|
||||
} finally {
|
||||
_isInitializing = false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:kaer_with_panels/app/common/app_config.dart';
|
||||
|
||||
@@ -9,12 +10,19 @@ import 'package:kaer_with_panels/app/modules/kr_main/controllers/kr_main_control
|
||||
import 'package:kaer_with_panels/app/services/kr_socket_service.dart';
|
||||
import 'package:kaer_with_panels/app/utils/kr_secure_storage.dart';
|
||||
import 'package:kaer_with_panels/app/services/kr_device_info_service.dart';
|
||||
import 'package:kaer_with_panels/app/routes/app_pages.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 '../services/singbox_imp/kr_sing_box_imp.dart';
|
||||
import '../utils/kr_event_bus.dart';
|
||||
import '../../singbox/model/singbox_status.dart';
|
||||
|
||||
import 'package:kaer_with_panels/app/widgets/dialogs/hi_dialog.dart';
|
||||
import 'package:kaer_with_panels/app/services/api_service/kr_auth_api.dart';
|
||||
import 'package:kaer_with_panels/app/services/kr_subscribe_service.dart';
|
||||
|
||||
class KRAppRunData {
|
||||
static final KRAppRunData _instance = KRAppRunData._internal();
|
||||
@@ -42,6 +50,9 @@ class KRAppRunData {
|
||||
/// 登录类型
|
||||
KRLoginType? kr_loginType;
|
||||
|
||||
/// 设备ID
|
||||
String? deviceId;
|
||||
|
||||
/// 区号
|
||||
String? kr_areaCode;
|
||||
|
||||
@@ -56,10 +67,11 @@ class KRAppRunData {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
|
||||
/// 判断是否是设备登录(游客模式)
|
||||
bool isDeviceLogin() {
|
||||
// 设备登录的账号格式为 "device_设备ID"
|
||||
return kr_account.value != null && kr_account.value!.startsWith('device_');
|
||||
return kr_account.value != null && kr_account.value!.startsWith('9000');
|
||||
}
|
||||
|
||||
/// 从JWT token中解析userId
|
||||
@@ -118,23 +130,24 @@ class KRAppRunData {
|
||||
KRLogUtil.kr_i('开始保存用户信息', tag: 'AppRunData');
|
||||
|
||||
try {
|
||||
// 更新内存中的数据
|
||||
kr_token = token;
|
||||
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 accountText = account.startsWith('device_') ? '9000${kr_userId}' : account;
|
||||
// 更新内存中的数据
|
||||
kr_token = token;
|
||||
kr_account.value = accountText;
|
||||
kr_loginType = loginType;
|
||||
kr_areaCode = areaCode;
|
||||
|
||||
|
||||
final Map<String, dynamic> userInfo = {
|
||||
'token': token,
|
||||
'account': account,
|
||||
'account': accountText,
|
||||
'loginType': loginType.value,
|
||||
'areaCode': areaCode ?? "",
|
||||
};
|
||||
|
||||
// _kr_connectSocket(kr_userId.value.toString());
|
||||
KRLogUtil.kr_i('准备保存用户信息到存储', tag: 'AppRunData');
|
||||
|
||||
await KRSecureStorage().kr_saveData(
|
||||
@@ -144,6 +157,7 @@ class KRAppRunData {
|
||||
|
||||
// 验证保存是否成功
|
||||
final savedData = await KRSecureStorage().kr_readData(key: _keyUserInfo);
|
||||
KRLogUtil.kr_i('用户信息-kr_readData$savedData', tag: 'AppRunData');
|
||||
if (savedData == null || savedData.isEmpty) {
|
||||
KRLogUtil.kr_e('数据保存后无法读取,保存失败', tag: 'AppRunData');
|
||||
kr_isLogin.value = false;
|
||||
@@ -154,18 +168,12 @@ class KRAppRunData {
|
||||
|
||||
// 只有在保存成功后才设置登录状态
|
||||
kr_isLogin.value = true;
|
||||
KRLogUtil.kr_i('用户信息-kr_isLogin$kr_isLogin', tag: 'AppRunData');
|
||||
|
||||
// 🔧 非游客模式下,调用用户信息接口获取 refer_code 等信息
|
||||
KRLogUtil.kr_i('🔍 [AppRunData] 检查登录模式: account=$account', tag: 'AppRunData');
|
||||
final isDevice = isDeviceLogin();
|
||||
KRLogUtil.kr_i('🔍 [AppRunData] isDeviceLogin: $isDevice', tag: 'AppRunData');
|
||||
|
||||
if (!isDevice) {
|
||||
KRLogUtil.kr_i('✅ [AppRunData] 正常登录模式,开始获取用户详细信息', tag: 'AppRunData');
|
||||
await _fetchUserInfo();
|
||||
} else {
|
||||
KRLogUtil.kr_i('⏭️ [AppRunData] 设备登录模式,跳过用户信息接口调用', tag: 'AppRunData');
|
||||
}
|
||||
await _fetchUserInfo();
|
||||
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('保存用户信息失败: $e', tag: 'AppRunData');
|
||||
@@ -175,29 +183,122 @@ class KRAppRunData {
|
||||
}
|
||||
}
|
||||
|
||||
/// 退出登录
|
||||
/// 退出登录(其实是设备重新登录)
|
||||
Future<void> kr_loginOut() async {
|
||||
// 先将登录状态设置为 false,防止重连
|
||||
kr_isLogin.value = false;
|
||||
HIDialog.show(
|
||||
message: '当前登录已过期,请重新登录',
|
||||
preventBackDismiss: true,
|
||||
confirmText: '确定',
|
||||
autoClose: false,
|
||||
onConfirm: () async{
|
||||
// 先将登录状态设置为 false,防止重连
|
||||
kr_isLogin.value = false;
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('开始重新进行设备登录', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'AppRunData');
|
||||
// === 停止 VPN 服务 ===
|
||||
try {
|
||||
// 检查 SingBox 服务状态并停止
|
||||
if (KRSingBoxImp.instance.kr_status.value is SingboxStarted) {
|
||||
await KRSingBoxImp.instance.kr_stop();
|
||||
KRLogUtil.kr_i('VPN 服务已停止', tag: 'Logout');
|
||||
}
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('停止 VPN 服务失败: $e', tag: 'Logout');
|
||||
}
|
||||
|
||||
// 断开 Socket 连接
|
||||
await _kr_disconnectSocket();
|
||||
// 断开 Socket 连接
|
||||
await _kr_disconnectSocket();
|
||||
|
||||
// 清理用户信息
|
||||
kr_token = null;
|
||||
kr_account.value = null;
|
||||
kr_userId.value = null;
|
||||
kr_loginType = null;
|
||||
kr_areaCode = null;
|
||||
// 清理用户信息
|
||||
kr_token = null;
|
||||
kr_account.value = null;
|
||||
kr_userId.value = null;
|
||||
kr_loginType = null;
|
||||
kr_areaCode = null;
|
||||
|
||||
// 删除存储的用户信息
|
||||
await KRSecureStorage().kr_deleteData(key: _keyUserInfo);
|
||||
// 删除存储的用户信息
|
||||
await KRSecureStorage().kr_deleteData(key: _keyUserInfo);
|
||||
|
||||
// 重置公告显示状态
|
||||
KRAnnouncementService().kr_reset();
|
||||
// 重置公告显示状态
|
||||
KRAnnouncementService().kr_reset();
|
||||
// 5️⃣ 执行设备登录
|
||||
final success = await kr_checkAndPerformDeviceLogin();
|
||||
|
||||
// 重置主页面
|
||||
Get.find<KRMainController>().kr_setPage(0);
|
||||
if (!success) {
|
||||
// 设备登录失败 → 提示用户重试
|
||||
HIDialog.show(
|
||||
message: '设备登录失败,请检查网络或重试',
|
||||
confirmText: '重试',
|
||||
preventBackDismiss: true,
|
||||
onConfirm: () async {
|
||||
await kr_loginOut(); // 递归重试
|
||||
},
|
||||
);
|
||||
return; // 阻止跳首页
|
||||
}
|
||||
|
||||
// 等待一小段时间,确保登录状态已经更新
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
|
||||
// 刷新订阅信息
|
||||
KRLogUtil.kr_i('🔄 开始刷新订阅信息...', tag: 'DeviceManagement');
|
||||
try {
|
||||
await KRSubscribeService().kr_refreshAll();
|
||||
KRLogUtil.kr_i('✅ 订阅信息刷新成功', tag: 'DeviceManagement');
|
||||
} catch (e) {
|
||||
KRLogUtil.kr_e('订阅信息刷新失败: $e', tag: 'DeviceManagement');
|
||||
}
|
||||
|
||||
Get.offAllNamed(Routes.KR_HOME);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// 检查并执行设备登录
|
||||
Future<bool> kr_checkAndPerformDeviceLogin() async {
|
||||
try {
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
print('🔍 开始执行设备登录...');
|
||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
// 初始化设备信息服务
|
||||
await KRDeviceInfoService().initialize();
|
||||
|
||||
KRLogUtil.kr_i('🔐 开始执行设备登录', tag: 'SplashController');
|
||||
|
||||
// 执行设备登录
|
||||
final authApi = KRAuthApi();
|
||||
final result = await authApi.kr_deviceLogin();
|
||||
|
||||
return await result.fold(
|
||||
(error) {
|
||||
print('❌ 设备登录失败: ${error.msg}');
|
||||
KRLogUtil.kr_e('❌ 设备登录失败: ${error.msg}', tag: 'SplashController');
|
||||
return false;
|
||||
},
|
||||
(token) async {
|
||||
print('✅ 设备登录成功!Token: $token');
|
||||
KRLogUtil.kr_i('✅ 设备登录成功', tag: 'SplashController');
|
||||
|
||||
final deviceId = KRDeviceInfoService().deviceId ?? 'unknown';
|
||||
await kr_saveUserInfo(
|
||||
token,
|
||||
'device_$deviceId', // 临时账号
|
||||
KRLoginType.kr_email,
|
||||
null, // 设备登录无需区号
|
||||
);
|
||||
|
||||
kr_isLogin.value = true;
|
||||
print('✅ 已标记为登录状态');
|
||||
return true;
|
||||
},
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
print('❌ 设备登录检查异常: $e');
|
||||
print('📚 堆栈跟踪: $stackTrace');
|
||||
KRLogUtil.kr_e('❌ 设备登录检查异常: $e', tag: 'SplashController');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化用户信息
|
||||
@@ -205,6 +306,8 @@ class KRAppRunData {
|
||||
KRLogUtil.kr_i('开始初始化用户信息', tag: 'AppRunData');
|
||||
|
||||
try {
|
||||
|
||||
deviceId = KRDeviceInfoService().deviceId ?? 'unknown';
|
||||
final String? userInfoString =
|
||||
await KRSecureStorage().kr_readData(key: _keyUserInfo);
|
||||
|
||||
@@ -258,7 +361,7 @@ class KRAppRunData {
|
||||
}
|
||||
|
||||
/// 建立 Socket 连接
|
||||
/// ⚠️ 已遗弃:wsBaseUrl 不再使用
|
||||
/// /// ⚠️ 已遗弃:wsBaseUrl 不再使用
|
||||
Future<void> _kr_connectSocket(String userId) async {
|
||||
// 已遗弃,不再建立 Socket 连接
|
||||
KRLogUtil.kr_i('Socket 连接已遗弃', tag: 'AppRunData');
|
||||
@@ -310,19 +413,27 @@ class KRAppRunData {
|
||||
final result = await KRUserApi.kr_getUserInfo();
|
||||
|
||||
result.fold(
|
||||
(error) {
|
||||
(error) {
|
||||
KRLogUtil.kr_e('❌ [AppRunData] 获取用户信息失败: ${error.msg} (code: ${error.code})', tag: 'AppRunData');
|
||||
},
|
||||
(userInfo) {
|
||||
(userInfo) {
|
||||
final authType = userInfo.authMethods.isNotEmpty
|
||||
? userInfo.authMethods[0].authType
|
||||
: null;
|
||||
final authIdentifier = userInfo.authMethods.isNotEmpty
|
||||
? userInfo.authMethods[0].authIdentifier
|
||||
: null;
|
||||
KRLogUtil.kr_i('✅ [AppRunData] 获取用户信息成功', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('📋 [AppRunData] refer_code: "${userInfo.referCode}"', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('💰 [AppRunData] balance: ${userInfo.balance}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('💵 [AppRunData] commission: ${userInfo.commission}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('📧 [AppRunData] email: ${userInfo.email}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('📧 [AppRunData] 登录类型: ${authType}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('📧 [AppRunData] email: ${authIdentifier}', tag: 'AppRunData');
|
||||
KRLogUtil.kr_i('🆔 [AppRunData] id: ${userInfo.id}', tag: 'AppRunData');
|
||||
|
||||
// 保存到全局状态
|
||||
kr_referCode.value = userInfo.referCode;
|
||||
kr_account.value = authType == 'device' ? '9000${userInfo.id}' : authIdentifier;
|
||||
kr_balance.value = userInfo.balance;
|
||||
kr_commission.value = userInfo.commission;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user