新增游客模式

This commit is contained in:
2025-10-17 15:28:40 +08:00
parent f5bc239b6a
commit 2333ad52a9
15 changed files with 1434 additions and 53 deletions
+4
View File
@@ -19,6 +19,10 @@ abstract class Api {
/// 登录接口
static const String kr_login = "/v1/app/auth/login";
/// 设备登录(游客登录)
/// 参考 OmnOem 项目 ppanel.json 配置
static const String kr_deviceLogin = "/v1/auth/login/device";
/// 删除账号
static const String kr_deleteAccount = "/v1/app/user/account";
@@ -1,5 +1,6 @@
import 'dart:io';
import 'dart:math';
import 'dart:convert';
import 'package:fpdart/fpdart.dart';
import 'package:get/get.dart';
@@ -15,6 +16,11 @@ import 'package:kaer_with_panels/app/utils/kr_device_util.dart';
import '../../utils/kr_common_util.dart';
import '../../utils/kr_log_util.dart';
import '../../utils/kr_aes_util.dart';
import '../kr_device_info_service.dart';
import '../kr_site_config_service.dart';
import '../../common/app_config.dart';
import 'package:dio/dio.dart' as dio;
class KRAuthApi {
/// 是否开启了审核开关
@@ -221,6 +227,145 @@ class KRAuthApi {
return right(baseResponse.model.kr_token.toString());
}
/// 设备登录(游客登录)
Future<Either<HttpError, String>> kr_deviceLogin() async {
try {
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('🔐 开始设备登录(游客模式)');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('🔐 开始设备登录(游客模式)', tag: 'KRAuthApi');
// 获取设备信息
final deviceInfoService = KRDeviceInfoService();
final deviceId = deviceInfoService.deviceId;
final userAgent = deviceInfoService.getUserAgent();
if (deviceId == null) {
print('❌ 设备ID为空,无法登录');
return left(HttpError(msg: '设备ID获取失败', code: -1));
}
print('📱 设备ID: $deviceId');
print('📱 User-Agent: $userAgent');
KRLogUtil.kr_i('📱 设备ID: $deviceId', tag: 'KRAuthApi');
KRLogUtil.kr_i('📱 User-Agent: $userAgent', tag: 'KRAuthApi');
// 构建请求数据
Map<String, dynamic> data = {
'identifier': deviceId,
'user_agent': userAgent,
};
print('📤 原始请求数据: $data');
// 检查是否需要加密
final siteConfigService = KRSiteConfigService();
final needEncryption = siteConfigService.isDeviceSecurityEnabled();
print('🔒 是否需要加密: $needEncryption');
KRLogUtil.kr_i('🔒 是否需要加密: $needEncryption', tag: 'KRAuthApi');
String? requestBody;
if (needEncryption) {
// 加密请求数据
print('🔐 加密请求数据...');
final encrypted = KRAesUtil.encryptJson(data, AppConfig.kr_encryptionKey);
requestBody = '{"data":"${encrypted['data']}","time":"${encrypted['time']}"}';
print('🔐 加密后请求体: $requestBody');
KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi');
} else {
// 使用明文
requestBody = jsonEncode(data);
print('📝 明文请求体: $requestBody');
}
// 使用 Dio 直接发送请求(因为需要特殊的加密处理)
final dioInstance = dio.Dio();
final baseUrl = AppConfig.getInstance().baseUrl;
final url = '$baseUrl${Api.kr_deviceLogin}';
print('📤 请求URL: $url');
KRLogUtil.kr_i('📤 请求URL: $url', tag: 'KRAuthApi');
// 设置请求头
final headers = <String, String>{
'Content-Type': 'application/json',
};
if (needEncryption) {
headers['Login-Type'] = 'device';
}
print('📤 请求头: $headers');
// 配置Dio实例的超时设置
dioInstance.options.connectTimeout = const Duration(seconds: 10);
dioInstance.options.sendTimeout = const Duration(seconds: 10);
dioInstance.options.receiveTimeout = const Duration(seconds: 10);
final response = await dioInstance.post(
url,
data: requestBody,
options: dio.Options(
headers: headers,
),
);
print('📥 响应状态码: ${response.statusCode}');
print('📥 响应数据: ${response.data}');
KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi');
KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi');
if (response.statusCode == 200) {
Map<String, dynamic> responseData = response.data as Map<String, dynamic>;
// 检查是否需要解密响应
if (needEncryption && responseData.containsKey('data')) {
final dataField = responseData['data'];
if (dataField is Map<String, dynamic> &&
dataField.containsKey('data') &&
dataField.containsKey('time')) {
print('🔓 解密响应数据...');
final decrypted = KRAesUtil.decryptJson(
dataField['data'] as String,
dataField['time'] as String,
AppConfig.kr_encryptionKey,
);
responseData['data'] = decrypted;
print('🔓 解密后数据: ${responseData['data']}');
KRLogUtil.kr_i('🔓 解密成功', tag: 'KRAuthApi');
}
}
if (responseData['code'] == 200) {
final token = responseData['data']['token'] as String;
print('✅ 设备登录成功');
print('🎫 Token: ${token.substring(0, min(20, token.length))}...');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('✅ 设备登录成功', tag: 'KRAuthApi');
return right(token);
} else {
final msg = responseData['msg'] ?? '登录失败';
print('❌ 登录失败: $msg');
return left(HttpError(msg: msg, code: responseData['code']));
}
} else {
print('❌ HTTP错误: ${response.statusCode}');
return left(HttpError(msg: 'HTTP错误', code: response.statusCode ?? -1));
}
} on dio.DioException catch (e) {
print('❌ Dio异常: ${e.type}');
print('❌ 错误信息: ${e.message}');
KRLogUtil.kr_e('❌ 设备登录Dio异常: ${e.message}', tag: 'KRAuthApi');
return left(HttpError(msg: '网络请求失败: ${e.message}', code: -1));
} catch (e, stackTrace) {
print('❌ 设备登录异常: $e');
print('📚 堆栈跟踪: $stackTrace');
KRLogUtil.kr_e('❌ 设备登录异常: $e', tag: 'KRAuthApi');
return left(HttpError(msg: '设备登录失败: $e', code: -1));
}
}
String _kr_getUserAgent() {
if (Platform.isAndroid) {
return 'android';