generated from dellevin/template
优化主界面显示
This commit is contained in:
@@ -26,14 +26,12 @@ void main() async {
|
|||||||
|
|
||||||
// 初始化用户偏好设置
|
// 初始化用户偏好设置
|
||||||
await UserPrefs.init();
|
await UserPrefs.init();
|
||||||
// 初始化数据库
|
|
||||||
final appProvider = AppProvider();
|
final appProvider = AppProvider();
|
||||||
await appProvider.initDatabase();
|
// 先显示界面,后台加载数据
|
||||||
appProvider.initMainTabIndex();
|
runApp(MyApp(appProvider: appProvider));
|
||||||
// 以下初始化不阻塞界面显示
|
unawaited(appProvider.initDatabase().then((_) => appProvider.initMainTabIndex()));
|
||||||
unawaited(_initAutoBackup());
|
unawaited(_initAutoBackup());
|
||||||
unawaited(_initUsageStats());
|
unawaited(_initUsageStats());
|
||||||
runApp(MyApp(appProvider: appProvider));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 初始化自动备份
|
/// 初始化自动备份
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class _ServerSyncPageState extends State<ServerSyncPage> {
|
|||||||
final exp = _prefs.syncExpiresAt;
|
final exp = _prefs.syncExpiresAt;
|
||||||
if (exp.isNotEmpty) {
|
if (exp.isNotEmpty) {
|
||||||
try {
|
try {
|
||||||
final dt = DateTime.parse(exp);
|
final dt = DateTime.parse(exp).add(const Duration(hours: 8));
|
||||||
_expiresText = '有效期至 ${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')} '
|
_expiresText = '有效期至 ${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')} '
|
||||||
'${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}';
|
'${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}';
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class UsageStatsService with WidgetsBindingObserver {
|
|||||||
final UserPrefs _prefs = UserPrefs();
|
final UserPrefs _prefs = UserPrefs();
|
||||||
|
|
||||||
/// 统计服务器地址,发布前替换为实际地址,置空则禁用
|
/// 统计服务器地址,发布前替换为实际地址,置空则禁用
|
||||||
static String serverUrl = 'http://192.168.31.48:5000';
|
static String serverUrl = 'http://api.mooknote.iletter.top/';
|
||||||
|
|
||||||
Timer? _heartbeatTimer;
|
Timer? _heartbeatTimer;
|
||||||
bool _started = false;
|
bool _started = false;
|
||||||
@@ -54,23 +54,6 @@ class UsageStatsService with WidgetsBindingObserver {
|
|||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取统计信息(总用户数 / 在线数)
|
|
||||||
static Future<Map<String, dynamic>?> fetchStats() async {
|
|
||||||
if (serverUrl.isEmpty) return null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
final response = await http
|
|
||||||
.get(Uri.parse('$serverUrl/api/stats'))
|
|
||||||
.timeout(const Duration(seconds: 5));
|
|
||||||
if (response.statusCode == 200) {
|
|
||||||
return jsonDecode(response.body) as Map<String, dynamic>;
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
// 静默失败
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── 内部方法 ──────────────────────────────────────────────────────────
|
// ─── 内部方法 ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/// 确保设备有匿名ID
|
/// 确保设备有匿名ID
|
||||||
@@ -106,8 +89,10 @@ class UsageStatsService with WidgetsBindingObserver {
|
|||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
'device_hash': deviceId,
|
'device_hash': deviceId,
|
||||||
'device_type': Platform.operatingSystem, // android/ios/windows/macos/linux
|
'device_type':
|
||||||
'device_name': '${Platform.operatingSystem} ${Platform.operatingSystemVersion}',
|
Platform.operatingSystem, // android/ios/windows/macos/linux
|
||||||
|
'device_name':
|
||||||
|
'${Platform.operatingSystem} ${Platform.operatingSystemVersion}',
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.timeout(const Duration(seconds: 5));
|
.timeout(const Duration(seconds: 5));
|
||||||
|
|||||||
Reference in New Issue
Block a user