This commit is contained in:
Developer
2026-06-06 06:12:30 +08:00
parent 214a0684d0
commit bc7cb075c5
9 changed files with 8 additions and 712 deletions

View File

@@ -1,16 +1,8 @@
PODS:
- app_links (7.0.0):
- Flutter
- AppAuth (1.7.6):
- AppAuth/Core (= 1.7.6)
- AppAuth/ExternalUserAgent (= 1.7.6)
- AppAuth/Core (1.7.6)
- AppAuth/ExternalUserAgent (1.7.6):
- AppAuth/Core
- AppCheckCore (11.2.0):
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- PromisesObjC (~> 2.4)
- app_tracking_transparency (0.0.1):
- Flutter
- audioplayers_darwin (0.0.1):
- Flutter
- FlutterMacOS
@@ -58,8 +50,6 @@ PODS:
- Flutter
- flutter_vibrate (0.0.1):
- Flutter
- flutter_web_auth (0.6.0):
- Flutter
- flutter_webrtc (1.4.0):
- Flutter
- WebRTC-SDK (= 144.7559.01)
@@ -68,34 +58,6 @@ PODS:
- gal (1.0.0):
- Flutter
- FlutterMacOS
- google_sign_in_ios (0.0.1):
- AppAuth (>= 1.7.4)
- Flutter
- FlutterMacOS
- GoogleSignIn (~> 8.0)
- GTMSessionFetcher (>= 3.4.0)
- GoogleSignIn (8.0.0):
- AppAuth (< 2.0, >= 1.7.3)
- AppCheckCore (~> 11.0)
- GTMAppAuth (< 5.0, >= 4.1.1)
- GTMSessionFetcher/Core (~> 3.3)
- GoogleUtilities/Environment (8.1.0):
- GoogleUtilities/Privacy
- GoogleUtilities/Logger (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (8.1.0)
- GoogleUtilities/UserDefaults (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GTMAppAuth (4.1.1):
- AppAuth/Core (~> 1.7)
- GTMSessionFetcher/Core (< 4.0, >= 3.3)
- GTMSessionFetcher (3.5.0):
- GTMSessionFetcher/Full (= 3.5.0)
- GTMSessionFetcher/Core (3.5.0)
- GTMSessionFetcher/Full (3.5.0):
- GTMSessionFetcher/Core
- home_widget (0.0.1):
- Flutter
- image_picker_ios (0.0.1):
@@ -135,7 +97,6 @@ PODS:
- Flutter
- pro_image_editor (12.0.8):
- Flutter
- PromisesObjC (2.4.0)
- quick_actions_ios (0.0.1):
- Flutter
- quill_native_bridge_ios (0.0.1):
@@ -159,8 +120,6 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sign_in_with_apple (0.0.1):
- Flutter
- speech_to_text (7.2.0):
- CwlCatchException
- Flutter
@@ -210,6 +169,7 @@ PODS:
DEPENDENCIES:
- app_links (from `.symlinks/plugins/app_links/ios`)
- app_tracking_transparency (from `.symlinks/plugins/app_tracking_transparency/ios`)
- audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/darwin`)
- battery_plus (from `.symlinks/plugins/battery_plus/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
@@ -227,11 +187,9 @@ DEPENDENCIES:
- flutter_secure_storage_darwin (from `.symlinks/plugins/flutter_secure_storage_darwin/darwin`)
- flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
- flutter_vibrate (from `.symlinks/plugins/flutter_vibrate/ios`)
- flutter_web_auth (from `.symlinks/plugins/flutter_web_auth/ios`)
- flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- gal (from `.symlinks/plugins/gal/darwin`)
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`)
- home_widget (from `.symlinks/plugins/home_widget/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- live_activities (from `.symlinks/plugins/live_activities/ios`)
@@ -250,7 +208,6 @@ DEPENDENCIES:
- sensors_plus (from `.symlinks/plugins/sensors_plus/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
- speech_to_text (from `.symlinks/plugins/speech_to_text/darwin`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
@@ -263,18 +220,11 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- AppAuth
- AppCheckCore
- CwlCatchException
- CwlCatchExceptionSupport
- GoogleSignIn
- GoogleUtilities
- GTMAppAuth
- GTMSessionFetcher
- libwebp
- Mantle
- OrderedSet
- PromisesObjC
- SDWebImage
- SDWebImageWebPCoder
- sqlite3
@@ -283,6 +233,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
app_links:
:path: ".symlinks/plugins/app_links/ios"
app_tracking_transparency:
:path: ".symlinks/plugins/app_tracking_transparency/ios"
audioplayers_darwin:
:path: ".symlinks/plugins/audioplayers_darwin/darwin"
battery_plus:
@@ -317,16 +269,12 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_tts/ios"
flutter_vibrate:
:path: ".symlinks/plugins/flutter_vibrate/ios"
flutter_web_auth:
:path: ".symlinks/plugins/flutter_web_auth/ios"
flutter_webrtc:
:path: ".symlinks/plugins/flutter_webrtc/ios"
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
gal:
:path: ".symlinks/plugins/gal/darwin"
google_sign_in_ios:
:path: ".symlinks/plugins/google_sign_in_ios/darwin"
home_widget:
:path: ".symlinks/plugins/home_widget/ios"
image_picker_ios:
@@ -363,8 +311,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
sign_in_with_apple:
:path: ".symlinks/plugins/sign_in_with_apple/ios"
speech_to_text:
:path: ".symlinks/plugins/speech_to_text/darwin"
sqflite_darwin:
@@ -386,8 +332,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
app_links: a754cbec3c255bd4bbb4d236ecc06f28cd9a7ce8
AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73
AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f
app_tracking_transparency: 3d84f147f67ca82d3c15355c36b1fa6b66ca7c92
audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5
battery_plus: b42253f6d2dde71712f8c36fef456d99121c5977
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
@@ -407,15 +352,9 @@ SPEC CHECKSUMS:
flutter_secure_storage_darwin: acdb3f316ed05a3e68f856e0353b133eec373a23
flutter_tts: 35ac3c7d42412733e795ea96ad2d7e05d0a75113
flutter_vibrate: 207bbbeb62dd5638b479846c8e46168d7229f14a
flutter_web_auth: e5618c2e8a6822d86a0dc49f08d00a7ba25cfafd
flutter_webrtc: ec91d94b484ad49cf191ef93413f64a40ffd3b4c
fluttertoast: fe6790210fdba20801685be946e3a2124b72eef5
gal: baecd024ebfd13c441269ca7404792a7152fde89
google_sign_in_ios: b48bb9af78576358a168361173155596c845f0b9
GoogleSignIn: ce8c89bb9b37fb624b92e7514cc67335d1e277e4
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
home_widget: 54b4f6b36ed8d64cfee594a476225c35c3e45091
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
@@ -429,7 +368,6 @@ SPEC CHECKSUMS:
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
permission_handler_apple: 92d754bbaa7361d436db2d6c3c1c2a0fdcec462e
pro_image_editor: 3dedac450f82a389877286fa9eb08852cefb04ea
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
quick_actions_ios: 500fcc11711d9f646739093395c4ae8eec25f779
quill_native_bridge_ios: f47af4b14e7757968486641656c5d23250cee521
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
@@ -440,7 +378,6 @@ SPEC CHECKSUMS:
sensors_plus: 6a11ed0c2e1d0bd0b20b4029d3bad27d96e0c65b
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
speech_to_text: 3b313d98516d3d0406cea424782ec25470c59d19
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sqlite3: a51c07cf16e023d6c48abd5e5791a61a47354921

View File

@@ -22,19 +22,6 @@
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLName</key>
<string>apps.xy.xianyan</string>
<key>CFBundleURLSchemes</key>
<array>
<string>xianyan</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>

View File

@@ -2,12 +2,10 @@
/// 闲言APP — 登录页面
/// 创建时间: 2026-04-28
/// 更新时间: 2026-06-05
/// 作用: 用户登录界面,支持密码/验证码/Token/老用户/二维码/OAuth社交登录
/// 上次更新: 新增Apple/Google/GitHub OAuth社交登录入口
/// 作用: 用户登录界面,支持密码/验证码/Token/老用户/二维码登录
/// 上次更新: 移除OAuth社交登录(未正式使用)
/// ============================================================
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
@@ -17,7 +15,6 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../../../core/router/app_routes.dart';
import '../../../core/network/api_exception.dart';
import '../../../core/services/device/device_info_service.dart';
import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_typography.dart';
@@ -31,7 +28,6 @@ import '../config/register_config.dart';
import '../providers/auth_provider.dart';
import '../services/auth_service.dart';
import '../services/email_service.dart';
import '../services/oauth_service.dart';
import 'login_form_sections.dart';
import 'register_section.dart';
@@ -527,60 +523,6 @@ class _LoginPageState extends ConsumerState<LoginPage>
],
),
const SizedBox(height: AppSpacing.md),
// TODO: [OAuth社交登录] 待各平台OAuth配置完成后启用详见 docs/OAUTH_INTEGRATION_GUIDE.md
// 第二行分隔线:社交登录
// Row(
// children: [
// Expanded(
// child: Divider(color: ext.textHint.withValues(alpha: 0.15)),
// ),
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm),
// child: Text(
// auth.otherLoginMethods,
// style: AppTypography.caption2.copyWith(
// color: ext.textHint,
// fontSize: 10,
// ),
// ),
// ),
// Expanded(
// child: Divider(color: ext.textHint.withValues(alpha: 0.15)),
// ),
// ],
// ),
// const SizedBox(height: AppSpacing.md),
// // 第三行Apple/Google/GitHub
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// // Apple登录仅iOS/macOS
// if (Platform.isIOS || Platform.isMacOS) ...[
// _buildOAuthButton(
// ext,
// icon: '',
// label: 'Apple',
// onTap: () => _handleOAuthLogin(OAuthPlatform.apple),
// ),
// const SizedBox(width: AppSpacing.lg),
// ],
// // Google登录
// _buildOAuthButton(
// ext,
// icon: '',
// label: 'Google',
// onTap: () => _handleOAuthLogin(OAuthPlatform.google),
// ),
// const SizedBox(width: AppSpacing.lg),
// // GitHub登录
// _buildOAuthButton(
// ext,
// icon: '',
// label: 'GitHub',
// onTap: () => _handleOAuthLogin(OAuthPlatform.github),
// ),
// ],
// ),
],
);
}
@@ -654,96 +596,6 @@ class _LoginPageState extends ConsumerState<LoginPage>
);
}
/// OAuth社交登录按钮
Widget _buildOAuthButton(
AppThemeExtension ext, {
required String icon,
required String label,
required VoidCallback onTap,
}) {
return GestureDetector(
onTap: onTap,
child: Column(
children: [
Container(
width: 52,
height: 52,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: ext.bgCard,
border: Border.all(
color: ext.textHint.withValues(alpha: 0.2),
),
),
child: Center(
child: Text(icon, style: const TextStyle(fontSize: 22)),
),
),
const SizedBox(height: 4),
Text(
label,
style: AppTypography.caption2.copyWith(
color: ext.textSecondary,
fontSize: 10,
),
),
],
),
);
}
/// 处理OAuth社交登录
Future<void> _handleOAuthLogin(OAuthPlatform platform) async {
final deviceModel = DeviceInfoService.cachedDeviceModel;
final deviceName = DeviceInfoService.cachedDeviceName;
OAuthLoginResult result;
switch (platform) {
case OAuthPlatform.apple:
result = await OAuthService.loginWithApple(
deviceName: deviceName,
deviceModel: deviceModel,
platformType: Platform.isIOS ? 'ios' : 'mac',
);
case OAuthPlatform.google:
result = await OAuthService.loginWithGoogle(
deviceName: deviceName,
deviceModel: deviceModel,
platformType: Platform.isIOS ? 'ios' : 'android',
);
case OAuthPlatform.github:
result = await OAuthService.loginWithGithub(
deviceName: deviceName,
deviceModel: deviceModel,
platformType: Platform.isIOS ? 'ios' : 'android',
);
}
if (!mounted) return;
if (result.success && result.token != null) {
// 登录成功通过token登录到本地
try {
await AuthService.tokenLogin(result.token!);
ref.invalidate(authProvider);
if (mounted) {
final t = ref.read(translationsProvider);
AppToast.showSuccess(t.auth.loginSuccess);
_navigateAfterLogin();
}
} on ApiException catch (e) {
if (mounted) AppToast.showError(e.message);
} catch (e) {
if (mounted) AppToast.showError('登录失败: $e');
}
} else if (result.error != null) {
if (result.error != '用户取消') {
AppToast.showError(result.error!);
}
}
}
Widget _buildAgreement(AppThemeExtension ext, TAuth auth) {
return Padding(
padding: const EdgeInsets.only(top: AppSpacing.md),

View File

@@ -1,377 +0,0 @@
/// ============================================================
/// 文件: oauth_service.dart
/// 创建时间: 2026-06-05
/// 更新时间: 2026-06-05
/// 名称: OAuth社交登录服务
/// 作用: 处理Apple/Google/GitHub第三方登录
/// 上次更新: 新增OAuth社交登录服务
/// ============================================================
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_web_auth/flutter_web_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import '../../../core/network/api_client.dart';
import '../../../core/utils/logger.dart';
import '../../../core/utils/platform/platform_utils.dart' as pu;
/// OAuth平台枚举
enum OAuthPlatform {
apple,
google,
github;
/// 平台标识值
String get value => switch (this) {
OAuthPlatform.apple => 'apple',
OAuthPlatform.google => 'google',
OAuthPlatform.github => 'github',
};
/// 显示名称
String get displayName => switch (this) {
OAuthPlatform.apple => 'Apple',
OAuthPlatform.google => 'Google',
OAuthPlatform.github => 'GitHub',
};
/// 图标emoji
String get icon => switch (this) {
OAuthPlatform.apple => '',
OAuthPlatform.google => '',
OAuthPlatform.github => '',
};
}
/// OAuth登录结果
class OAuthLoginResult {
const OAuthLoginResult({
required this.success,
this.token,
this.userinfo,
this.isNewUser = false,
this.bindPlatform,
this.error,
});
final bool success;
final String? token;
final Map<String, dynamic>? userinfo;
final bool isNewUser;
final String? bindPlatform;
final String? error;
/// 从服务端响应JSON构造
factory OAuthLoginResult.fromJson(Map<String, dynamic> json) {
final data = json['data'];
final Map<String, dynamic>? dataMap =
data is Map<String, dynamic> ? data : null;
return OAuthLoginResult(
success: json['code'] == 1,
token: dataMap?['token'] as String?,
userinfo: dataMap?['userinfo'] != null
? Map<String, dynamic>.from(dataMap!['userinfo'] as Map)
: null,
isNewUser: dataMap?['is_new_user'] as bool? ?? false,
bindPlatform: dataMap?['bind_platform'] as String?,
error: json['code'] != 1 ? json['msg'] as String? : null,
);
}
}
/// OAuth社交登录服务
class OAuthService {
OAuthService._();
static const String _tag = 'OAuthService';
/// ApiClient单例的Dio实例
static final Dio _dio = ApiClient.instance.dio;
// ============================================================
// Apple登录
// ============================================================
/// Apple登录
///
/// 仅支持iOS和macOS平台通过Sign in with Apple获取id_token后发送到服务端验证。
static Future<OAuthLoginResult> loginWithApple({
String? deviceName,
String? deviceModel,
String? platformType,
String? deviceId,
}) async {
try {
if (!pu.isIOS && !pu.isMacOS) {
return const OAuthLoginResult(
success: false,
error: 'Apple登录仅支持iOS和macOS',
);
}
final credential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: pu.isIOS
? null
: WebAuthenticationOptions(
clientId: 'apps.xy.xianyan.service',
redirectUri:
Uri.parse('https://tools.wktyl.com/oauth/callback'),
),
);
Log.i('$_tag: Apple登录获取id_token成功');
return _loginToServer(
platform: OAuthPlatform.apple,
idToken: credential.identityToken,
authorizationCode: credential.authorizationCode,
deviceName: deviceName,
deviceModel: deviceModel,
platformType: platformType,
deviceId: deviceId,
);
} on SignInWithAppleAuthorizationException catch (e) {
if (e.code == AuthorizationErrorCode.canceled) {
return const OAuthLoginResult(success: false, error: '用户取消');
}
Log.e('$_tag: Apple登录失败: $e');
return OAuthLoginResult(
success: false,
error: 'Apple登录失败: ${e.message}',
);
} on PlatformException catch (e) {
Log.e('$_tag: Apple登录平台异常: $e');
return const OAuthLoginResult(success: false, error: 'Apple登录失败');
} catch (e) {
Log.e('$_tag: Apple登录异常: $e');
return const OAuthLoginResult(success: false, error: 'Apple登录失败');
}
}
// ============================================================
// Google登录
// ============================================================
/// Google登录
///
/// 通过Google Sign In获取serverAuthCode后发送到服务端验证。
static Future<OAuthLoginResult> loginWithGoogle({
String? deviceName,
String? deviceModel,
String? platformType,
String? deviceId,
}) async {
try {
final googleSignIn = GoogleSignIn(scopes: ['email', 'profile']);
final account = await googleSignIn.signIn();
if (account == null) {
return const OAuthLoginResult(success: false, error: '用户取消');
}
final auth = await account.authentication;
final serverAuthCode = auth.serverAuthCode;
if (serverAuthCode == null) {
Log.w('$_tag: Google serverAuthCode为空尝试使用idToken');
return const OAuthLoginResult(
success: false,
error: 'Google授权码获取失败请重试',
);
}
Log.i('$_tag: Google登录获取serverAuthCode成功');
return _loginToServer(
platform: OAuthPlatform.google,
code: serverAuthCode,
deviceName: deviceName,
deviceModel: deviceModel,
platformType: platformType,
deviceId: deviceId,
);
} on PlatformException catch (e) {
if (e.code == 'sign_in_canceled') {
return const OAuthLoginResult(success: false, error: '用户取消');
}
Log.e('$_tag: Google登录平台异常: $e');
return const OAuthLoginResult(success: false, error: 'Google登录失败');
} catch (e) {
Log.e('$_tag: Google登录异常: $e');
return const OAuthLoginResult(success: false, error: 'Google登录失败');
}
}
// ============================================================
// GitHub登录
// ============================================================
/// GitHub登录通过浏览器OAuth
///
/// 先从服务端获取OAuth配置再通过浏览器完成授权流程最后将授权码发送到服务端。
static Future<OAuthLoginResult> loginWithGithub({
String? deviceName,
String? deviceModel,
String? platformType,
String? deviceId,
}) async {
try {
// 从服务端获取GitHub OAuth配置
final configResp = await _dio.get<Map<String, dynamic>>(
'/api/oauth/config',
queryParameters: {'platform': 'github'},
);
final configData = configResp.data;
if (configData == null ||
configData['code'] != 1 ||
(configData['data'] as Map<String, dynamic>?)?['configured'] !=
true) {
return const OAuthLoginResult(
success: false,
error: 'GitHub登录暂未配置',
);
}
final dataMap = configData['data'] as Map<String, dynamic>;
final authorizeUrl = dataMap['authorize_url'] as String;
// 通过浏览器完成OAuth
final result = await FlutterWebAuth.authenticate(
url: authorizeUrl,
callbackUrlScheme: 'xianyan',
);
// 从回调URL中提取code
final callbackUri = Uri.parse(result);
final code = callbackUri.queryParameters['code'];
if (code == null || code.isEmpty) {
return const OAuthLoginResult(
success: false,
error: 'GitHub授权码获取失败',
);
}
Log.i('$_tag: GitHub登录获取授权码成功');
return _loginToServer(
platform: OAuthPlatform.github,
code: code,
deviceName: deviceName,
deviceModel: deviceModel,
platformType: platformType,
deviceId: deviceId,
);
} on PlatformException catch (e) {
if (e.code == 'CANCELED') {
return const OAuthLoginResult(success: false, error: '用户取消');
}
Log.e('$_tag: GitHub登录平台异常: $e');
return const OAuthLoginResult(success: false, error: 'GitHub登录失败');
} catch (e) {
Log.e('$_tag: GitHub登录异常: $e');
return const OAuthLoginResult(success: false, error: 'GitHub登录失败');
}
}
// ============================================================
// 绑定/解绑社交账号
// ============================================================
/// 绑定社交账号
static Future<Map<String, dynamic>> bind({
required OAuthPlatform platform,
String? code,
String? idToken,
}) async {
final resp = await _dio.post<Map<String, dynamic>>(
'/api/oauth/bind',
data: {
'platform': platform.value,
if (code != null) 'code': code,
if (idToken != null) 'id_token': idToken,
},
);
return resp.data ?? {};
}
/// 解绑社交账号
static Future<Map<String, dynamic>> unbind({
required OAuthPlatform platform,
}) async {
final resp = await _dio.post<Map<String, dynamic>>(
'/api/oauth/unbind',
data: {'platform': platform.value},
);
return resp.data ?? {};
}
/// 获取已绑定列表
static Future<List<Map<String, dynamic>>> getBoundList() async {
final resp = await _dio.get<Map<String, dynamic>>('/api/oauth/bound');
final data = resp.data;
if (data != null && data['code'] == 1) {
final innerData = data['data'];
if (innerData is Map<String, dynamic> &&
innerData['bindings'] != null) {
return List<Map<String, dynamic>>.from(
innerData['bindings'] as List,
);
}
}
return [];
}
// ============================================================
// 内部方法
// ============================================================
/// 向服务端发送登录请求
static Future<OAuthLoginResult> _loginToServer({
required OAuthPlatform platform,
String? code,
String? idToken,
String? authorizationCode,
String? deviceName,
String? deviceModel,
String? platformType,
String? deviceId,
}) async {
try {
final resp = await _dio.post<Map<String, dynamic>>(
'/api/oauth/login',
data: {
'platform': platform.value,
if (code != null) 'code': code,
if (idToken != null) 'id_token': idToken,
if (authorizationCode != null) 'code': authorizationCode,
if (deviceName != null) 'device_name': deviceName,
if (deviceModel != null) 'device_model': deviceModel,
if (platformType != null) 'platform_type': platformType,
if (deviceId != null) 'device_id': deviceId,
},
);
final result = OAuthLoginResult.fromJson(resp.data ?? {});
Log.i(
'$_tag: ${platform.displayName}登录${result.success ? "成功" : "失败"}',
);
return result;
} on DioException catch (e) {
Log.e('$_tag: 服务端登录请求失败: $e');
return const OAuthLoginResult(
success: false,
error: '网络请求失败,请检查网络连接',
);
} catch (e) {
Log.e('$_tag: 服务端登录异常: $e');
return const OAuthLoginResult(success: false, error: '登录失败');
}
}
}

View File

@@ -19,10 +19,8 @@ import flutter_inappwebview_macos
import flutter_local_notifications
import flutter_secure_storage_darwin
import flutter_tts
import flutter_web_auth
import flutter_webrtc
import gal
import google_sign_in_ios
import local_auth_darwin
import mobile_scanner
import nearby_service
@@ -35,7 +33,6 @@ import rive_native
import screen_retriever_macos
import share_plus
import shared_preferences_foundation
import sign_in_with_apple
import speech_to_text
import sqflite_darwin
import sqlite3_flutter_libs
@@ -60,10 +57,8 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
FlutterSecureStorageDarwinPlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStorageDarwinPlugin"))
FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin"))
FlutterWebAuthPlugin.register(with: registry.registrar(forPlugin: "FlutterWebAuthPlugin"))
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin"))
FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin"))
LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin"))
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
NearbyServicePlugin.register(with: registry.registrar(forPlugin: "NearbyServicePlugin"))
@@ -76,7 +71,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin"))
SpeechToTextPlugin.register(with: registry.registrar(forPlugin: "SpeechToTextPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))

View File

@@ -1,16 +1,6 @@
PODS:
- app_links (6.4.1):
- FlutterMacOS
- AppAuth (1.7.6):
- AppAuth/Core (= 1.7.6)
- AppAuth/ExternalUserAgent (= 1.7.6)
- AppAuth/Core (1.7.6)
- AppAuth/ExternalUserAgent (1.7.6):
- AppAuth/Core
- AppCheckCore (11.2.0):
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- PromisesObjC (~> 2.4)
- audioplayers_darwin (0.0.1):
- Flutter
- FlutterMacOS
@@ -44,8 +34,6 @@ PODS:
- FlutterMacOS
- flutter_tts (0.0.1):
- FlutterMacOS
- flutter_web_auth (0.6.0):
- FlutterMacOS
- flutter_webrtc (1.4.0):
- FlutterMacOS
- WebRTC-SDK (= 144.7559.01)
@@ -53,34 +41,6 @@ PODS:
- gal (1.0.0):
- Flutter
- FlutterMacOS
- google_sign_in_ios (0.0.1):
- AppAuth (>= 1.7.4)
- Flutter
- FlutterMacOS
- GoogleSignIn (~> 8.0)
- GTMSessionFetcher (>= 3.4.0)
- GoogleSignIn (8.0.0):
- AppAuth (< 2.0, >= 1.7.3)
- AppCheckCore (~> 11.0)
- GTMAppAuth (< 5.0, >= 4.1.1)
- GTMSessionFetcher/Core (~> 3.3)
- GoogleUtilities/Environment (8.1.0):
- GoogleUtilities/Privacy
- GoogleUtilities/Logger (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (8.1.0)
- GoogleUtilities/UserDefaults (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GTMAppAuth (4.1.1):
- AppAuth/Core (~> 1.7)
- GTMSessionFetcher/Core (< 4.0, >= 3.3)
- GTMSessionFetcher (3.5.0):
- GTMSessionFetcher/Full (= 3.5.0)
- GTMSessionFetcher/Core (3.5.0)
- GTMSessionFetcher/Full (3.5.0):
- GTMSessionFetcher/Core
- local_auth_darwin (0.0.1):
- Flutter
- FlutterMacOS
@@ -97,7 +57,6 @@ PODS:
- FlutterMacOS
- pro_image_editor (12.0.8):
- FlutterMacOS
- PromisesObjC (2.4.0)
- quill_native_bridge_macos (0.0.1):
- FlutterMacOS
- record_macos (1.2.1):
@@ -111,8 +70,6 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sign_in_with_apple (0.0.1):
- FlutterMacOS
- speech_to_text (7.2.0):
- CwlCatchException
- Flutter
@@ -173,11 +130,9 @@ DEPENDENCIES:
- flutter_local_notifications (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos`)
- flutter_secure_storage_darwin (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_darwin/darwin`)
- flutter_tts (from `Flutter/ephemeral/.symlinks/plugins/flutter_tts/macos`)
- flutter_web_auth (from `Flutter/ephemeral/.symlinks/plugins/flutter_web_auth/macos`)
- flutter_webrtc (from `Flutter/ephemeral/.symlinks/plugins/flutter_webrtc/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- gal (from `Flutter/ephemeral/.symlinks/plugins/gal/darwin`)
- google_sign_in_ios (from `Flutter/ephemeral/.symlinks/plugins/google_sign_in_ios/darwin`)
- local_auth_darwin (from `Flutter/ephemeral/.symlinks/plugins/local_auth_darwin/darwin`)
- mobile_scanner (from `Flutter/ephemeral/.symlinks/plugins/mobile_scanner/darwin`)
- nearby_service (from `Flutter/ephemeral/.symlinks/plugins/nearby_service/darwin`)
@@ -190,7 +145,6 @@ DEPENDENCIES:
- screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`)
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sign_in_with_apple (from `Flutter/ephemeral/.symlinks/plugins/sign_in_with_apple/macos`)
- speech_to_text (from `Flutter/ephemeral/.symlinks/plugins/speech_to_text/darwin`)
- sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin`)
@@ -202,16 +156,9 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- AppAuth
- AppCheckCore
- CwlCatchException
- CwlCatchExceptionSupport
- GoogleSignIn
- GoogleUtilities
- GTMAppAuth
- GTMSessionFetcher
- OrderedSet
- PromisesObjC
- sqlite3
- WebRTC-SDK
@@ -244,16 +191,12 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_darwin/darwin
flutter_tts:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_tts/macos
flutter_web_auth:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_web_auth/macos
flutter_webrtc:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_webrtc/macos
FlutterMacOS:
:path: Flutter/ephemeral
gal:
:path: Flutter/ephemeral/.symlinks/plugins/gal/darwin
google_sign_in_ios:
:path: Flutter/ephemeral/.symlinks/plugins/google_sign_in_ios/darwin
local_auth_darwin:
:path: Flutter/ephemeral/.symlinks/plugins/local_auth_darwin/darwin
mobile_scanner:
@@ -278,8 +221,6 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sign_in_with_apple:
:path: Flutter/ephemeral/.symlinks/plugins/sign_in_with_apple/macos
speech_to_text:
:path: Flutter/ephemeral/.symlinks/plugins/speech_to_text/darwin
sqflite_darwin:
@@ -299,8 +240,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
app_links: 05a6ec2341985eb05e9f97dc63f5837c39895c3f
AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73
AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f
audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5
battery_plus: f51ad29136e025b714b96f7d096f44f604615da7
connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e
@@ -316,15 +255,9 @@ SPEC CHECKSUMS:
flutter_local_notifications: 1fc7ffb10a83d6a2eeeeddb152d43f1944b0aad0
flutter_secure_storage_darwin: acdb3f316ed05a3e68f856e0353b133eec373a23
flutter_tts: ae915565cc6948444b513acc8ee021993281e027
flutter_web_auth: af71951c1cfef0e74932304283d99e419fc3d754
flutter_webrtc: f1fb1a00c6080461bb2bc6caa5b93d07ddb68466
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
gal: baecd024ebfd13c441269ca7404792a7152fde89
google_sign_in_ios: b48bb9af78576358a168361173155596c845f0b9
GoogleSignIn: ce8c89bb9b37fb624b92e7514cc67335d1e277e4
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb
mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93
nearby_service: 608702f35ef2b2f4d10b29b49c9a1bd24ae2ff03
@@ -332,14 +265,12 @@ SPEC CHECKSUMS:
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
pro_image_editor: e4f2ca0bcf5d755d81620d531b00e0906ccaa0ae
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
quill_native_bridge_macos: 2b005cb56902bb740e0cd9620aa399dfac6b4882
record_macos: 5d55909f9650314be6424ffd6b123ac75a08c3c1
rive_native: 7c43020540833c8258564b726317daf39d2c3bda
screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f
share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
sign_in_with_apple: 6673c03c9e3643f6c8d33601943fbfa9ae99f94e
speech_to_text: 3b313d98516d3d0406cea424782ec25470c59d19
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sqlite3: a51c07cf16e023d6c48abd5e5791a61a47354921

View File

@@ -241,7 +241,6 @@
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
D06B9597A43A5822D591EB0B /* [CP] Embed Pods Frameworks */,
77629487F17C9402822B9BEB /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -362,23 +361,6 @@
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
};
77629487F17C9402822B9BEB /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
A56E9379F374F7CCC33D60A7 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;

View File

@@ -242,11 +242,6 @@ dependencies:
nearby_service: ^0.2.1 # 近场设备发现+通信
nearby_connections: ^4.1.1 # Google Nearby Connections(蓝牙发现+Wi-Fi Direct传输,仅Android/iOS)
# --- OAuth社交登录 ---
flutter_web_auth: ^0.6.0 # 浏览器OAuth认证(GitHub登录)
google_sign_in: ^6.2.1 # Google登录
sign_in_with_apple: ^6.1.4 # Apple登录
flutter_localizations:
sdk: flutter # Flutter国际化支持
timezone: ^0.11.0 # 时区数据库

View File

@@ -283,11 +283,6 @@ dependencies:
path: packages/nearby_service
nearby_connections: ^4.1.1 # Google Nearby Connections(蓝牙发现+Wi-Fi Direct传输,仅Android/iOS)
# --- OAuth社交登录 ---
flutter_web_auth: ^0.6.0 # 浏览器OAuth认证(GitHub登录)
google_sign_in: ^6.2.1 # Google登录
sign_in_with_apple: ^6.1.4 # Apple登录
flutter_localizations:
sdk: flutter # Flutter国际化支持
timezone: ^0.11.0 # 时区数据库