网络请求打通,ws 打通
This commit is contained in:
@@ -11,21 +11,23 @@ class ApiPaths {
|
||||
ApiPaths._();
|
||||
|
||||
// ── Auth ──
|
||||
static const authLogin = '/auth/login';
|
||||
static const authRefreshToken = '/auth/refresh-token';
|
||||
static const authLogout = '/auth/logout';
|
||||
static const authSendOtp = '/app/api/auth/vcode/get';
|
||||
static const authVerifyOtp = '/app/api/auth/vcode/check';
|
||||
static const authLogin = '/app/api/auth/login-user';
|
||||
static const authRefreshToken = '/app/api/auth/refresh-token';
|
||||
static const authLogout = '/app/api/auth/logout';
|
||||
|
||||
// ── User ──
|
||||
static const userProfile = '/user/profile';
|
||||
static const userUpdateProfile = '/user/update-profile';
|
||||
static const userProfile = '/app/api/user/profile';
|
||||
static const userUpdateProfile = '/app/api/user/update-profile';
|
||||
|
||||
// ── Chat ──
|
||||
static const chatSendMessage = '/chat/send-message';
|
||||
static const chatHistory = '/chat/history';
|
||||
static const chatSendMessage = '/app/api/chat/send-message';
|
||||
static const chatHistory = '/app/api/chat/history';
|
||||
|
||||
// ── Upload ──
|
||||
static const uploadFile = '/upload/file';
|
||||
static const uploadFile = '/app/api/upload/file';
|
||||
|
||||
// ── WebSocket ──
|
||||
static const wsConnect = '/ws';
|
||||
static const wsConnect = '/websock/open';
|
||||
}
|
||||
|
||||
@@ -7,7 +7,14 @@ class AppConfig {
|
||||
static const isDev = bool.fromEnvironment('IS_DEV', defaultValue: true);
|
||||
static const apiBaseUrl = String.fromEnvironment(
|
||||
'API_BASE_URL',
|
||||
defaultValue: 'https://dev-api.example.com',
|
||||
defaultValue: 'http://gateway.winwayinfo.com',
|
||||
);
|
||||
|
||||
static const channel = String.fromEnvironment('CHANNEL', defaultValue: '10');
|
||||
|
||||
static const appVersion = String.fromEnvironment(
|
||||
'APP_VERSION',
|
||||
defaultValue: '1.0.0',
|
||||
);
|
||||
|
||||
static bool get isProd => !isDev;
|
||||
|
||||
108
apps/im_app/lib/core/foundation/device_info.dart
Normal file
108
apps/im_app/lib/core/foundation/device_info.dart
Normal file
@@ -0,0 +1,108 @@
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
|
||||
/// 设备 / 运行时信息 — 用于构建 HTTP 请求头中的平台字段
|
||||
///
|
||||
/// 同步 getter(platform / lang / osType)可直接使用。
|
||||
/// deviceId / deviceName 需调用 [init()] 预取后才能通过同步 getter 访问。
|
||||
///
|
||||
/// 在 `AppInitializer.critical` 中调用 [init()],之后 `platformHeaders` 可同步读取所有字段:
|
||||
/// ```dart
|
||||
/// platformHeaders: {
|
||||
/// 'platform': DeviceInfo.platform,
|
||||
/// 'lang': DeviceInfo.lang,
|
||||
/// 'client-version': AppConfig.appVersion,
|
||||
/// 'channel': AppConfig.channel,
|
||||
/// 'device-id': DeviceInfo.deviceId,
|
||||
/// 'device-name': DeviceInfo.deviceName,
|
||||
/// }
|
||||
/// ```
|
||||
// ignore: avoid_classes_with_only_static_members
|
||||
class DeviceInfo {
|
||||
DeviceInfo._();
|
||||
|
||||
static String _deviceId = '';
|
||||
static String _deviceName = '';
|
||||
|
||||
/// 预取设备 ID / 设备名,缓存后可通过同步 getter 访问。
|
||||
/// 在 AppInitializer.critical 中调用一次即可。
|
||||
static Future<void> init() async {
|
||||
_deviceId = await fetchDeviceId();
|
||||
_deviceName = await fetchDeviceName();
|
||||
}
|
||||
|
||||
/// 缓存的设备唯一标识(需先调用 [init()])
|
||||
static String get deviceId => _deviceId;
|
||||
|
||||
/// 缓存的设备名称(需先调用 [init()])
|
||||
static String get deviceName => _deviceName;
|
||||
|
||||
/// HTTP `Platform` 请求头(服务端用于区分来源平台)
|
||||
///
|
||||
/// 返回值:iOS / Android / macOS / Windows / Linux
|
||||
static String get platform {
|
||||
if (Platform.isIOS) return 'iOS';
|
||||
if (Platform.isAndroid) return 'Android';
|
||||
if (Platform.isMacOS) return 'macOS';
|
||||
if (Platform.isWindows) return 'Windows';
|
||||
if (Platform.isLinux) return 'Linux';
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
/// HTTP `lang` 请求头(取系统首选语言,如 "zh-CN"、"en-US")
|
||||
///
|
||||
/// 使用 `dart:ui` 的 `PlatformDispatcher`,不依赖 Flutter widget tree。
|
||||
static String get lang => PlatformDispatcher.instance.locale.toLanguageTag();
|
||||
|
||||
/// 操作系统类型编号(与服务端约定一致):
|
||||
/// 1=Android 2=iOS 3=Windows 4=macOS 5=Linux 6=其他
|
||||
static int get osType {
|
||||
if (Platform.isAndroid) return 1;
|
||||
if (Platform.isIOS) return 2;
|
||||
if (Platform.isWindows) return 3;
|
||||
if (Platform.isMacOS) return 4;
|
||||
if (Platform.isLinux) return 5;
|
||||
return 6;
|
||||
}
|
||||
|
||||
/// 设备唯一标识
|
||||
///
|
||||
/// Android:Build.ID(非持久化硬件 ID,可作为临时标识;如需稳定 ID 后续接入 android_id)
|
||||
/// iOS:identifierForVendor
|
||||
/// macOS:systemGUID
|
||||
/// Windows:deviceId
|
||||
static Future<String> fetchDeviceId() async {
|
||||
final plugin = DeviceInfoPlugin();
|
||||
if (Platform.isAndroid) {
|
||||
return (await plugin.androidInfo).id;
|
||||
} else if (Platform.isIOS) {
|
||||
return (await plugin.iosInfo).identifierForVendor ?? '';
|
||||
} else if (Platform.isMacOS) {
|
||||
return (await plugin.macOsInfo).systemGUID ?? '';
|
||||
} else if (Platform.isWindows) {
|
||||
return (await plugin.windowsInfo).deviceId;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/// 设备名称(品牌 + 型号)
|
||||
static Future<String> fetchDeviceName() async {
|
||||
final plugin = DeviceInfoPlugin();
|
||||
if (Platform.isAndroid) {
|
||||
final info = await plugin.androidInfo;
|
||||
return '${info.brand} ${info.model}';
|
||||
} else if (Platform.isIOS) {
|
||||
final info = await plugin.iosInfo;
|
||||
return info.utsname.machine;
|
||||
} else if (Platform.isMacOS) {
|
||||
return (await plugin.macOsInfo).model;
|
||||
} else if (Platform.isWindows) {
|
||||
return (await plugin.windowsInfo).computerName;
|
||||
} else if (Platform.isLinux) {
|
||||
return (await plugin.linuxInfo).name;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -36,22 +36,9 @@ class ApiErrorCodes {
|
||||
/// 账号在其他设备登录
|
||||
static const int loggedInAnotherDevice = 30006;
|
||||
|
||||
// ── 错误码集合 ──
|
||||
// ── 验证码(30170-30179)──
|
||||
|
||||
/// Token 过期错误码集合 — 触发自动刷新 Token
|
||||
static const Set<int> tokenExpiredCodes = {
|
||||
tokenInvalid,
|
||||
jwtInvalid,
|
||||
sessionInvalid,
|
||||
};
|
||||
/// 触发图片验证:data 含各平台 CAPTCHA token(android / ios / web)
|
||||
static const int captchaRequired = 30174;
|
||||
|
||||
/// 强制登出错误码集合 — 触发退出登录流程
|
||||
static const Set<int> forceLogoutCodes = {refreshTokenFailed};
|
||||
|
||||
/// 踢下线错误码集合 — 触发踢下线 UI 提示
|
||||
static const Set<int> kickOffCodes = {
|
||||
loggedInAnotherDevice,
|
||||
signingMethodError,
|
||||
parsingKeyError,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user