fix: correct ticket charge API body, logout type, and login/logout flow

- Fix upsertUserChargeLog: use separate userCharge + userChargelog objects
  matching Lionheart reference, validDate 90 days at 4AM
- Fix userLogout: use LogoutType.Logout = 1 (was incorrectly changed to 0)
- Fix loginDateTime tracking: userLoginFull now returns the exact timestamp
  sent to server, ensuring logout uses matching value
- Fix home page logout: call UserLogoutApi before navigating back
- Add force-logout for stale sessions before ticket flow login
- Add comprehensive debug logging across entire ticket flow

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 13:10:10 +08:00
parent fee7291ab9
commit 4ad57dc1cf
4 changed files with 467 additions and 153 deletions

View File

@@ -28,6 +28,7 @@ class _HomePageState extends State<HomePage> {
UserPreviewDataBean? _data;
String? _error;
bool _loading = true;
bool _loggingOut = false;
static const _tabTitles = [AppStrings.tabHome, AppStrings.tabTickets, AppStrings.tabSettings, AppStrings.tabAbout];
@@ -89,6 +90,22 @@ class _HomePageState extends State<HomePage> {
}
}
Future<void> _performLogout() async {
setState(() => _loggingOut = true);
try {
if (TitleServerConfigHolder().isConfigured && _data != null && _data!.isLogin) {
final service = TitleApiService(TitleServerConfigHolder().config!);
final loginDateTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
await service.userLogout(userId: widget.userId, loginDateTime: loginDateTime);
}
} catch (_) {
// Proceed with navigation even if logout fails
}
if (mounted) {
Navigator.of(context).pop();
}
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
@@ -98,9 +115,15 @@ class _HomePageState extends State<HomePage> {
title: Text(_tabTitles[_currentTab]),
actions: [
IconButton(
icon: const Icon(Icons.logout),
icon: _loggingOut
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.logout),
tooltip: AppStrings.logoutTooltip,
onPressed: () => Navigator.of(context).pop(),
onPressed: _loggingOut ? null : _performLogout,
),
],
),