Initial commit: Flutter 无书应用项目

This commit is contained in:
Developer
2026-03-30 02:35:31 +08:00
commit 9175ff9905
566 changed files with 103261 additions and 0 deletions

View File

@@ -0,0 +1,218 @@
/// 时间: 2025-03-21
/// 功能: HTTP客户端工具类使用纯Dart dio库
/// 介绍: 提供统一的HTTP请求方法支持GET、POST等请求用于项目中的网络请求
/// 最新变化: 移除CORS代理需后台服务器配置CORS响应头
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
class HttpClient {
static const String _baseUrl = 'https://yy.vogov.cn/api/';
static const Duration _timeout = Duration(seconds: 30);
static final BaseOptions _options = BaseOptions(
baseUrl: _baseUrl,
connectTimeout: _timeout,
receiveTimeout: _timeout,
sendTimeout: _timeout,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Accept': 'application/json',
'User-Agent': 'Poes-Flutter/1.0.0',
},
);
static final Dio _dio = Dio(_options);
/// 添加调试日志
static void _debugLog(String message) {
if (kDebugMode) {
print('HttpClient: $message');
}
}
/// GET请求
static Future<HttpResponse> get(
String path, {
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
Duration? timeout,
}) async {
return _request(
'GET',
path,
queryParameters: queryParameters,
headers: headers,
timeout: timeout,
);
}
/// POST请求
static Future<HttpResponse> post(
String path, {
Map<String, dynamic>? data,
Map<String, String>? headers,
Duration? timeout,
}) async {
return _request(
'POST',
path,
data: data,
headers: headers,
timeout: timeout,
);
}
/// 通用请求方法
static Future<HttpResponse> _request(
String method,
String path, {
Map<String, dynamic>? queryParameters,
Map<String, dynamic>? data,
Map<String, String>? headers,
Duration? timeout,
}) async {
try {
final url = '$_baseUrl$path';
_debugLog('请求 $method $url');
if (queryParameters != null) {
_debugLog('查询参数: $queryParameters');
}
final options = Options(
method: method,
headers: headers != null
? {..._options.headers!, ...headers}
: _options.headers,
);
if (timeout != null) {
options.connectTimeout = timeout;
options.receiveTimeout = timeout;
options.sendTimeout = timeout;
}
Response response;
if (method.toUpperCase() == 'GET') {
response = await _dio.get(
url,
queryParameters: queryParameters,
options: options,
);
} else if (method.toUpperCase() == 'POST') {
response = await _dio.post(
url,
data: data,
queryParameters: queryParameters,
options: options,
);
} else {
throw UnsupportedError('HTTP method $method is not supported');
}
_debugLog('响应状态: ${response.statusCode}');
_debugLog('响应数据: ${response.data}');
return HttpResponse(
statusCode: response.statusCode ?? 0,
body: response.data is String
? response.data
: json.encode(response.data),
headers: response.headers.map.cast<String, String>(),
);
} on DioException catch (e) {
_debugLog('Dio异常: ${e.type} - ${e.message}');
String message;
switch (e.type) {
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
message = '请求超时,请检查网络连接';
break;
case DioExceptionType.connectionError:
message = '网络连接失败,请检查网络设置';
break;
case DioExceptionType.badResponse:
message = '服务器错误: ${e.response?.statusCode} - ${e.response?.data}';
break;
default:
message = '请求失败: ${e.message}';
}
throw HttpException(message);
} catch (e) {
_debugLog('未知异常: $e');
throw HttpException('请求失败:$e');
}
}
}
/// HTTP响应类
class HttpResponse {
final int statusCode;
final String body;
final Map<String, String> headers;
HttpResponse({
required this.statusCode,
required this.body,
required this.headers,
});
/// 是否成功 (2xx状态码)
bool get isSuccess => statusCode >= 200 && statusCode < 300;
/// 解析JSON响应
Map<String, dynamic> get jsonData {
try {
return json.decode(body) as Map<String, dynamic>;
} catch (e) {
throw FormatException('Invalid JSON response: $body');
}
}
/// 获取响应消息
String get message {
if (isSuccess) {
try {
return jsonData['msg'] ?? 'Success';
} catch (e) {
return 'Success';
}
} else {
return body;
}
}
/// 获取响应数据
dynamic get data {
if (isSuccess) {
return jsonData['data'];
}
return null;
}
/// 获取响应代码
int get code {
if (isSuccess) {
try {
return jsonData['code'] ?? 0;
} catch (e) {
return 0;
}
}
return statusCode;
}
}
/// HTTP异常类
class HttpException implements Exception {
final String message;
const HttpException(this.message);
@override
String toString() => 'HttpException: $message';
}