diff --git a/backend/services/identity-service/src/application/commands/recover-by-mnemonic/recover-by-mnemonic.handler.ts b/backend/services/identity-service/src/application/commands/recover-by-mnemonic/recover-by-mnemonic.handler.ts index ab7a6e84..ff6a1145 100644 --- a/backend/services/identity-service/src/application/commands/recover-by-mnemonic/recover-by-mnemonic.handler.ts +++ b/backend/services/identity-service/src/application/commands/recover-by-mnemonic/recover-by-mnemonic.handler.ts @@ -43,6 +43,10 @@ export class RecoverByMnemonicHandler { // 如果头像为空,重新生成一个 let avatarUrl = account.avatarUrl; + this.logger.log(`Account ${command.accountSequence} avatarUrl from DB: ${avatarUrl ? `长度=${avatarUrl.length}` : 'null'}`); + if (avatarUrl) { + this.logger.log(`Account ${command.accountSequence} avatarUrl前50字符: ${avatarUrl.substring(0, 50)}`); + } if (!avatarUrl) { this.logger.log(`Account ${command.accountSequence} has no avatar, generating new one`); avatarUrl = generateRandomAvatarSvg(); @@ -62,7 +66,7 @@ export class RecoverByMnemonicHandler { await this.eventPublisher.publishAll(account.domainEvents); account.clearDomainEvents(); - return { + const result = { userId: account.userId.toString(), accountSequence: account.accountSequence.value, nickname: account.nickname, @@ -71,5 +75,10 @@ export class RecoverByMnemonicHandler { accessToken: tokens.accessToken, refreshToken: tokens.refreshToken, }; + + this.logger.log(`RecoverByMnemonic result - accountSequence: ${result.accountSequence}, nickname: ${result.nickname}`); + this.logger.log(`RecoverByMnemonic result - avatarUrl: ${result.avatarUrl ? `长度=${result.avatarUrl.length}` : 'null'}`); + + return result; } } diff --git a/frontend/mobile-app/lib/core/services/account_service.dart b/frontend/mobile-app/lib/core/services/account_service.dart index 3c88f568..bd2cec48 100644 --- a/frontend/mobile-app/lib/core/services/account_service.dart +++ b/frontend/mobile-app/lib/core/services/account_service.dart @@ -199,11 +199,16 @@ class RecoverAccountResponse { factory RecoverAccountResponse.fromJson(Map json) { debugPrint('[AccountService] 解析 RecoverAccountResponse: ${json.keys.toList()}'); + final avatarUrl = json['avatarUrl'] as String?; + debugPrint('[AccountService] RecoverAccountResponse.avatarUrl: ${avatarUrl != null ? "长度=${avatarUrl.length}" : "null"}'); + if (avatarUrl != null && avatarUrl.isNotEmpty) { + debugPrint('[AccountService] RecoverAccountResponse.avatarUrl前50字符: ${avatarUrl.substring(0, avatarUrl.length > 50 ? 50 : avatarUrl.length)}'); + } return RecoverAccountResponse( userId: json['userId'] as String, userSerialNum: json['accountSequence'] as int, username: json['nickname'] as String, - avatarSvg: json['avatarUrl'] as String?, + avatarSvg: avatarUrl, referralCode: json['referralCode'] as String, accessToken: json['accessToken'] as String, refreshToken: json['refreshToken'] as String, @@ -884,12 +889,15 @@ class AccountService { value: response.username, ); - if (response.avatarSvg != null) { + if (response.avatarSvg != null && response.avatarSvg!.isNotEmpty) { debugPrint('$_tag _saveRecoverAccountData() - 保存 avatarSvg (长度: ${response.avatarSvg!.length})'); + debugPrint('$_tag _saveRecoverAccountData() - avatarSvg前50字符: ${response.avatarSvg!.substring(0, response.avatarSvg!.length > 50 ? 50 : response.avatarSvg!.length)}'); await _secureStorage.write( key: StorageKeys.avatarSvg, value: response.avatarSvg!, ); + } else { + debugPrint('$_tag _saveRecoverAccountData() - ⚠️ avatarSvg 为空! response.avatarSvg=${response.avatarSvg}'); } // 保存 Token diff --git a/frontend/mobile-app/lib/features/auth/presentation/pages/guide_page.dart b/frontend/mobile-app/lib/features/auth/presentation/pages/guide_page.dart index aae0b45d..845390a6 100644 --- a/frontend/mobile-app/lib/features/auth/presentation/pages/guide_page.dart +++ b/frontend/mobile-app/lib/features/auth/presentation/pages/guide_page.dart @@ -38,6 +38,31 @@ class _GuidePageState extends ConsumerState { final PageController _pageController = PageController(); int _currentPage = 0; + @override + void initState() { + super.initState(); + // 延迟到 build 后获取屏幕信息 + WidgetsBinding.instance.addPostFrameCallback((_) { + _logScreenInfo(); + }); + } + + /// 打印屏幕信息用于调试 + void _logScreenInfo() { + final mediaQuery = MediaQuery.of(context); + final screenSize = mediaQuery.size; + final devicePixelRatio = mediaQuery.devicePixelRatio; + final physicalSize = screenSize * devicePixelRatio; + + debugPrint('[GuidePage] ========== 屏幕信息 =========='); + debugPrint('[GuidePage] 逻辑分辨率: ${screenSize.width.toStringAsFixed(1)} x ${screenSize.height.toStringAsFixed(1)}'); + debugPrint('[GuidePage] 设备像素比: $devicePixelRatio'); + debugPrint('[GuidePage] 物理分辨率: ${physicalSize.width.toStringAsFixed(0)} x ${physicalSize.height.toStringAsFixed(0)}'); + debugPrint('[GuidePage] 屏幕宽高比: ${(screenSize.width / screenSize.height).toStringAsFixed(3)} (${screenSize.width.toStringAsFixed(0)}:${screenSize.height.toStringAsFixed(0)})'); + debugPrint('[GuidePage] 图片设计比例: 0.5625 (1080:1920 = 9:16)'); + debugPrint('[GuidePage] ================================'); + } + // 向导页1-5的数据 (第5页为欢迎加入页) // 支持 png、jpg、webp 等格式 final List _guidePages = const [ @@ -121,37 +146,50 @@ class _GuidePageState extends ConsumerState { } /// 构建向导页 (页面1-4) - 全屏背景图片,无文字 + /// 使用 BoxFit.fitWidth 保持图片原始比例,不拉伸文字 Widget _buildGuidePage(GuidePageData data, int index) { - return Stack( - fit: StackFit.expand, - children: [ - // 全屏背景图片 - if (data.imagePath != null) - Image.asset( - data.imagePath!, - fit: BoxFit.cover, - width: double.infinity, - height: double.infinity, - errorBuilder: (context, error, stackTrace) { - return Container( - color: const Color(0xFFFFF8E7), - child: _buildPlaceholderImage(index), - ); - }, - ) - else - Container( - color: const Color(0xFFFFF8E7), - child: _buildPlaceholderImage(index), + debugPrint('[GuidePage] _buildGuidePage() - 页面 ${index + 1}, 图片: ${data.imagePath}'); + return Container( + color: Colors.black, // 如果图片不够高,上下用黑色填充 + child: Stack( + fit: StackFit.expand, + children: [ + // 全屏背景图片 - 使用 fitWidth 保持宽高比 + if (data.imagePath != null) + LayoutBuilder( + builder: (context, constraints) { + debugPrint('[GuidePage] 页面 ${index + 1} 容器尺寸: ${constraints.maxWidth.toStringAsFixed(1)} x ${constraints.maxHeight.toStringAsFixed(1)}'); + debugPrint('[GuidePage] 页面 ${index + 1} 使用 BoxFit.fitWidth'); + return Center( + child: Image.asset( + data.imagePath!, + fit: BoxFit.fitWidth, + width: double.infinity, + errorBuilder: (context, error, stackTrace) { + debugPrint('[GuidePage] 页面 ${index + 1} 图片加载失败: $error'); + return Container( + color: const Color(0xFFFFF8E7), + child: _buildPlaceholderImage(index), + ); + }, + ), + ); + }, + ) + else + Container( + color: const Color(0xFFFFF8E7), + child: _buildPlaceholderImage(index), + ), + // 底部页面指示器 + Positioned( + left: 0, + right: 0, + bottom: 80.h, + child: _buildPageIndicator(), ), - // 底部页面指示器 - Positioned( - left: 0, - right: 0, - bottom: 80.h, - child: _buildPageIndicator(), - ), - ], + ], + ), ); } @@ -385,39 +423,42 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { Widget build(BuildContext context) { return GestureDetector( onTap: () => FocusScope.of(context).unfocus(), - child: Stack( - fit: StackFit.expand, - children: [ - // 全屏背景图片 - if (widget.backgroundImage != null) - Image.asset( - widget.backgroundImage!, - fit: BoxFit.cover, - width: double.infinity, - height: double.infinity, - errorBuilder: (context, error, stackTrace) { - return Container( - color: const Color(0xFFFFF8E7), - ); - }, - ) - else + child: Container( + color: Colors.black, // 如果图片不够高,上下用黑色填充 + child: Stack( + fit: StackFit.expand, + children: [ + // 全屏背景图片 - 使用 fitWidth 保持宽高比 + if (widget.backgroundImage != null) + Center( + child: Image.asset( + widget.backgroundImage!, + fit: BoxFit.fitWidth, + width: double.infinity, + errorBuilder: (context, error, stackTrace) { + return Container( + color: const Color(0xFFFFF8E7), + ); + }, + ), + ) + else + Container( + color: const Color(0xFFFFF8E7), + ), + // 半透明遮罩,让内容更清晰 Container( - color: const Color(0xFFFFF8E7), - ), - // 半透明遮罩,让内容更清晰 - Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Colors.black.withValues(alpha: 0.3), - Colors.black.withValues(alpha: 0.6), - ], + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.black.withValues(alpha: 0.3), + Colors.black.withValues(alpha: 0.6), + ], + ), ), ), - ), // 内容区域 SafeArea( child: LayoutBuilder( @@ -526,6 +567,7 @@ class _WelcomePageContentState extends ConsumerState<_WelcomePageContent> { ), ), ], + ), ), ); }