107 lines
3.8 KiB
Dart
107 lines
3.8 KiB
Dart
import 'dart:convert';
|
|
import 'dart:math';
|
|
import 'package:dio/dio.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import '../model/song_model.dart';
|
|
import 'user_service.dart'; // 引用 baseUrl
|
|
|
|
class SongService {
|
|
static final Dio _dio = new Dio();
|
|
static const String _cacheKeySongs = 'cached_songs_json';
|
|
static const String _cacheKeyInfo = 'cached_song_info';
|
|
|
|
/// 获取所有歌曲数据(带缓存逻辑)
|
|
static Future<List<SongModel>> getAllSongs() async {
|
|
try {
|
|
// 1. 获取远程元数据 (判断是否需要更新)
|
|
final metaRes = await _dio.get('${UserService.baseUrl}/api/union/');
|
|
final remoteSize = metaRes.data['songSize'] as int? ?? 0;
|
|
final remoteVersion = metaRes.data['version'] as String? ?? '';
|
|
|
|
// 2. 获取本地缓存信息
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final cachedInfoJson = prefs.getString(_cacheKeyInfo);
|
|
|
|
bool needFetch = true;
|
|
|
|
if (cachedInfoJson != null) {
|
|
final cachedInfo = SongCacheInfo.fromJson(jsonDecode(cachedInfoJson));
|
|
// 如果本地歌曲数量与远程一致,且版本号一致,则使用缓存
|
|
// 注意:这里简单判断 size 相同即认为无需更新,实际业务中可能需要更严格的版本对比
|
|
if (cachedInfo.songSize == remoteSize && cachedInfo.version == remoteVersion) {
|
|
needFetch = false;
|
|
}
|
|
}
|
|
|
|
if (needFetch) {
|
|
print("SongService: Cache miss or outdated. Fetching full song list...");
|
|
// 3. 拉取最新全量数据
|
|
final songsRes = await _dio.get('${UserService.baseUrl}/api/union/uni');
|
|
final List<dynamic> songsJson = songsRes.data as List;
|
|
|
|
// 4. 保存新数据和元数据到本地
|
|
final songsList = songsJson.map((e) => SongModel.fromJson(e)).toList();
|
|
final newInfo = SongCacheInfo(
|
|
songSize: remoteSize,
|
|
version: remoteVersion,
|
|
lastUpdate: DateTime.now()
|
|
);
|
|
|
|
await prefs.setString(_cacheKeySongs, jsonEncode(songsJson));
|
|
await prefs.setString(_cacheKeyInfo, jsonEncode(newInfo.toJson()));
|
|
|
|
return songsList;
|
|
} else {
|
|
print("SongService: Using cached song list.");
|
|
// 5. 使用缓存
|
|
final cachedSongsJson = prefs.getString(_cacheKeySongs);
|
|
if (cachedSongsJson != null) {
|
|
final List<dynamic> songsJson = jsonDecode(cachedSongsJson);
|
|
return songsJson.map((e) => SongModel.fromJson(e)).toList();
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print("SongService Error: $e");
|
|
// 如果出错,尝试返回旧缓存以防万一
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final cachedSongsJson = prefs.getString(_cacheKeySongs);
|
|
if (cachedSongsJson != null) {
|
|
final List<dynamic> songsJson = jsonDecode(cachedSongsJson);
|
|
return songsJson.map((e) => SongModel.fromJson(e)).toList();
|
|
}
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
static Future<Map<String, dynamic>> getUserAllScores(String token, {String? name}) async {
|
|
try {
|
|
if(name!=null) {
|
|
return await UserService.getUserAllScores(token,name: name);
|
|
}else{
|
|
return await UserService.getUserAllScores(token);
|
|
}
|
|
} on DioException catch (e) {
|
|
throw _getErrorMessage(e);
|
|
}
|
|
}
|
|
|
|
static String _getErrorMessage(DioException e) {
|
|
if (e.response?.data != null) {
|
|
final data = e.response!.data;
|
|
if (data is Map && data["msg"] != null) {
|
|
return data["msg"].toString();
|
|
}
|
|
}
|
|
switch (e.type) {
|
|
case DioExceptionType.connectionTimeout:
|
|
case DioExceptionType.receiveTimeout:
|
|
case DioExceptionType.sendTimeout:
|
|
return "网络超时";
|
|
case DioExceptionType.connectionError:
|
|
return "网络异常";
|
|
default:
|
|
return "请求失败";
|
|
}
|
|
}
|
|
} |