fix(app): 对齐 release 修复(播放明文HTTP、shared_preferences 降级防崩溃、双网络访问)
This commit is contained in:
1 parent
190e4f9c67
commit
de941c841c
7 files changed
+67
-84
No files matched your search
@@ -15,6 +15,9 @@ class AppConfig {
|
||||
/// `ipconfig getifaddr en0` 重新确认。默认值只改这一行。
|
||||
static const String devHostBaseUrl = 'http://192.168.31.187:8081';
|
||||
|
||||
/// 办公室内网(Wi-Fi)直连地址,双网络自动切换时的首选。
|
||||
static const String lanBaseUrl = 'http://192.168.31.250:8081';
|
||||
|
||||
static const String _loopbackBaseUrl = 'http://127.0.0.1:8081';
|
||||
|
||||
static const String _overrideBaseUrl = String.fromEnvironment('API_BASE_URL');
|
||||
@@ -59,6 +62,31 @@ class AppConfig {
|
||||
|
||||
static const Duration requestTimeout = Duration(seconds: 8);
|
||||
|
||||
/// 探测内网地址是否可达,可达则切换为内网直连,否则回落到公网地址。
|
||||
///
|
||||
/// Wi-Fi 下内网直连更快;移动数据下内网不可达,自动回落到公网端口映射。
|
||||
static Future<void> probeAndApplyBaseUrl() async {
|
||||
try {
|
||||
final client = HttpClient()
|
||||
..connectionTimeout = const Duration(seconds: 2);
|
||||
final request = await client.getUrl(
|
||||
Uri.parse('$lanBaseUrl/app/categories'),
|
||||
);
|
||||
final response = await request.close().timeout(const Duration(seconds: 2));
|
||||
await response.drain<void>();
|
||||
client.close(force: true);
|
||||
if (response.statusCode == 200) {
|
||||
applyRuntimeBaseUrl(lanBaseUrl);
|
||||
return;
|
||||
}
|
||||
} catch (_) {
|
||||
// 内网不可达,回落到公网。
|
||||
}
|
||||
applyRuntimeBaseUrl(
|
||||
compiledBaseUrl.isNotEmpty ? compiledBaseUrl : defaultBaseUrl,
|
||||
);
|
||||
}
|
||||
|
||||
/// 后端返回的是相对路径(/files/...),这里补上服务地址。
|
||||
static String mediaUrl(String path) {
|
||||
if (path.isEmpty) return '';
|
||||
|
||||
@@ -39,11 +39,11 @@ abstract final class ServerEndpoint {
|
||||
/// In release builds this returns immediately without reading preferences.
|
||||
static Future<void> load({
|
||||
bool debug = kDebugMode,
|
||||
SharedPreferencesAsync? preferences,
|
||||
SharedPreferences? preferences,
|
||||
}) async {
|
||||
if (!debug) return;
|
||||
try {
|
||||
final prefs = preferences ?? SharedPreferencesAsync();
|
||||
final prefs = preferences ?? await SharedPreferences.getInstance();
|
||||
final stored = await prefs.getString(preferenceKey);
|
||||
AppConfig.applyRuntimeBaseUrl(
|
||||
resolve(
|
||||
@@ -60,12 +60,12 @@ abstract final class ServerEndpoint {
|
||||
/// Persists a normalized runtime endpoint.
|
||||
static Future<bool> save(
|
||||
String raw, {
|
||||
SharedPreferencesAsync? preferences,
|
||||
SharedPreferences? preferences,
|
||||
}) async {
|
||||
final normalized = normalize(raw);
|
||||
if (normalized == null) return false;
|
||||
try {
|
||||
await (preferences ?? SharedPreferencesAsync()).setString(
|
||||
await (preferences ?? await SharedPreferences.getInstance()).setString(
|
||||
preferenceKey,
|
||||
normalized,
|
||||
);
|
||||
@@ -76,9 +76,9 @@ abstract final class ServerEndpoint {
|
||||
}
|
||||
|
||||
/// Removes the persisted runtime endpoint.
|
||||
static Future<void> clear({SharedPreferencesAsync? preferences}) async {
|
||||
static Future<void> clear({SharedPreferences? preferences}) async {
|
||||
try {
|
||||
await (preferences ?? SharedPreferencesAsync()).remove(preferenceKey);
|
||||
await (preferences ?? await SharedPreferences.getInstance()).remove(preferenceKey);
|
||||
} catch (_) {
|
||||
// Clearing an optional developer override is best effort.
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class AuthSessionStore {
|
||||
|
||||
Future<String> deviceId() async {
|
||||
if (_cachedDeviceId != null) return _cachedDeviceId!;
|
||||
final prefs = SharedPreferencesAsync();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
var value = await prefs.getString(_kDeviceId) ?? '';
|
||||
if (value.isEmpty) {
|
||||
final random = Random();
|
||||
@@ -37,7 +37,7 @@ class AuthSessionStore {
|
||||
}
|
||||
|
||||
Future<AuthSession?> read() async {
|
||||
final prefs = SharedPreferencesAsync();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final accessToken = await prefs.getString(_kAccessToken) ?? '';
|
||||
final refreshToken = await prefs.getString(_kRefreshToken) ?? '';
|
||||
if (accessToken.isEmpty || refreshToken.isEmpty) return null;
|
||||
@@ -58,14 +58,14 @@ class AuthSessionStore {
|
||||
}
|
||||
|
||||
Future<void> save(AuthSession session) async {
|
||||
final prefs = SharedPreferencesAsync();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_kAccessToken, session.accessToken);
|
||||
await prefs.setString(_kRefreshToken, session.refreshToken);
|
||||
await prefs.setString(_kUser, jsonEncode(session.user.toJson()));
|
||||
}
|
||||
|
||||
Future<void> clear() async {
|
||||
final prefs = SharedPreferencesAsync();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(_kAccessToken);
|
||||
await prefs.remove(_kRefreshToken);
|
||||
await prefs.remove(_kUser);
|
||||
|
||||
Reference in new issue
Block a user