Files
UnionApp/lib/service/song_service.dart
spasolreisa 9ce601aa8d initial
2026-04-16 14:26:52 +08:00

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 "请求失败";
}
}
}