refactor: 拆分主页与公共组件,扫码登录改走 WinHTTP
- 抽出 lib/core 的日期/JSON 工具,收敛各页重复解析 - 主页与音乐风险页拆成组件,风险功能共用一套运行框架 - 修复设置页作为主页页签保存时弹掉根路由导致的黑屏 - 登录对齐 Astral aimedb 协议:84 位二维码校验、签名与请求头修正, 补 GlobalSign 中间证书;Windows 改用 WinHTTP 绕过服务端对 BoringSSL 的 TLS 指纹拦截(证书校验保持开启) - 补开发预览数据与测试
This commit is contained in:
1 parent
0cb5320290
commit
e9357f5969
55 files changed
+4387
-3392
No files matched your search
+20
-25
@@ -6,6 +6,7 @@ import '../models/session_model.dart';
|
||||
import '../models/session_share.dart';
|
||||
import '../services/file_picker_service.dart';
|
||||
import '../services/qr_service.dart';
|
||||
import '../services/title_api_service.dart';
|
||||
import '../widgets/app_notice.dart';
|
||||
import 'home_page.dart';
|
||||
import 'settings_page.dart';
|
||||
@@ -22,7 +23,6 @@ class LoginPage extends StatefulWidget {
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
final _qrController = TextEditingController();
|
||||
String _qrCode = '';
|
||||
String _rawInput = '';
|
||||
SessionShare? _share;
|
||||
bool _loading = false;
|
||||
@@ -38,7 +38,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
final text = value.trim();
|
||||
setState(() {
|
||||
_rawInput = text;
|
||||
_qrCode = SessionModel.extractQRCode(text);
|
||||
_share = SessionShare.tryDecode(text);
|
||||
});
|
||||
}
|
||||
@@ -51,12 +50,9 @@ class _LoginPageState extends State<LoginPage> {
|
||||
final result = await decodeQRFromBytes(bytes);
|
||||
|
||||
if (result != null && result.isNotEmpty) {
|
||||
if (!mounted) return;
|
||||
_qrController.text = result;
|
||||
setState(() {
|
||||
_rawInput = result.trim();
|
||||
_qrCode = SessionModel.extractQRCode(result);
|
||||
_share = SessionShare.tryDecode(result);
|
||||
});
|
||||
_onQRContentChanged(result);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text(AppStrings.qrScanSuccess)),
|
||||
@@ -79,18 +75,11 @@ class _LoginPageState extends State<LoginPage> {
|
||||
}
|
||||
|
||||
Future<void> _onLogin() async {
|
||||
if (_qrCode.isEmpty) return;
|
||||
|
||||
// 令牌是粘贴内容的后 64 位,前缀可能在截取之后就没了,所以要拿原文判断;
|
||||
// 认不出来时必须给提示,否则点了按钮一声不响,像是坏了。
|
||||
if (!_rawInput.contains('SGWCMAID')) {
|
||||
context.showSnack(AppStrings.qrTokenUnrecognized);
|
||||
return;
|
||||
}
|
||||
if (_rawInput.isEmpty) return;
|
||||
setState(() => _loading = true);
|
||||
|
||||
try {
|
||||
final result = await SessionModel.instance.loginWithQr(_qrCode);
|
||||
final result = await SessionModel.instance.loginWithQr(_rawInput);
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
@@ -105,18 +94,22 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'${AppStrings.loginFailed} (errorID: ${result.errorId})',
|
||||
),
|
||||
),
|
||||
context.showSnack(
|
||||
'${AppStrings.loginFailed}:'
|
||||
'${result.message ?? 'errorID=${result.errorId}'}',
|
||||
);
|
||||
}
|
||||
} on FormatException catch (e) {
|
||||
// 令牌格式不对 / 没配 Keychip:登录请求根本没发出去,要说清楚是哪一种。
|
||||
if (mounted) {
|
||||
context.showSnack('${AppStrings.qrTokenUnrecognized}:${e.message}');
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('${AppStrings.requestFailed}: $e')),
|
||||
SnackBar(
|
||||
content: Text('${AppStrings.requestFailed}: ${describeApiError(e)}'),
|
||||
),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
@@ -155,7 +148,9 @@ class _LoginPageState extends State<LoginPage> {
|
||||
);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
context.showSnack('${AppStrings.sessionRestoreFailed}: $e');
|
||||
context.showSnack(
|
||||
'${AppStrings.sessionRestoreFailed}: ${describeApiError(e)}',
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (mounted) setState(() => _loading = false);
|
||||
@@ -285,7 +280,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
child: FilledButton.icon(
|
||||
onPressed: isRestore
|
||||
? (_loading ? null : _onRestoreSession)
|
||||
: (_qrCode.isNotEmpty && !_loading)
|
||||
: (_rawInput.isNotEmpty && !_loading)
|
||||
? _onLogin
|
||||
: null,
|
||||
icon: _loading
|
||||
|
||||
Reference in new issue
Block a user