提交 7547ba58 authored 作者: yueweilu's avatar yueweilu

网络请求缓存

上级 c46ea472
...@@ -38,10 +38,10 @@ class BuildBanner extends StatelessWidget { ...@@ -38,10 +38,10 @@ class BuildBanner extends StatelessWidget {
// ), // ),
), ),
//CustomImage.network(item.pic??'',)
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(8.w), borderRadius: BorderRadius.circular(8.w),
child: Image.network(item.pic??'',) child: CustomImage.network(url: item.pic??'')
), ),
// child: CustomImage.asset( // child: CustomImage.asset(
// url: 'assets/images/banner.png', // url: 'assets/images/banner.png',
......
...@@ -19,6 +19,7 @@ class HttpService extends GetxService { ...@@ -19,6 +19,7 @@ class HttpService extends GetxService {
_dio = Dio(options); _dio = Dio(options);
_dio.interceptors.add(_RequestInterceptor()); _dio.interceptors.add(_RequestInterceptor());
_dio.interceptors.add(_CacheInterceptor());
} }
/// 组织 headers 参数 /// 组织 headers 参数
...@@ -56,11 +57,18 @@ class HttpService extends GetxService { ...@@ -56,11 +57,18 @@ class HttpService extends GetxService {
CancelToken? cancelToken, CancelToken? cancelToken,
bool excludeToken = false, bool excludeToken = false,
bool showLoading = false, bool showLoading = false,
bool cacheEnabled = false,
}) async { }) async {
if (showLoading) CustomToast.loading(); if (showLoading) CustomToast.loading();
try { try {
final requestOptions = options ?? Options(); final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,params: params,url: url); requestOptions.headers = _getHeaders(excludeToken: excludeToken,params: params,url: url);
// 如果启用缓存,将cacheEnabled参数添加到请求选项中
if(cacheEnabled){
requestOptions.extra ??= {};
requestOptions.extra!['cacheEnabled'] = true;
}
final response = await _dio.get( final response = await _dio.get(
url, url,
queryParameters: params, queryParameters: params,
...@@ -83,6 +91,7 @@ class HttpService extends GetxService { ...@@ -83,6 +91,7 @@ class HttpService extends GetxService {
CancelToken? cancelToken, CancelToken? cancelToken,
bool excludeToken = false, bool excludeToken = false,
bool showLoading = false, bool showLoading = false,
bool cacheEnabled = true,
}) async{ }) async{
if (showLoading) CustomToast.loading(); if (showLoading) CustomToast.loading();
try { try {
...@@ -90,6 +99,12 @@ class HttpService extends GetxService { ...@@ -90,6 +99,12 @@ class HttpService extends GetxService {
requestOptions.headers = _getHeaders(excludeToken: excludeToken,params: params,url: url); requestOptions.headers = _getHeaders(excludeToken: excludeToken,params: params,url: url);
Console.log('----headers------${requestOptions.headers}'); Console.log('----headers------${requestOptions.headers}');
Console.log('----params------$params'); Console.log('----params------$params');
// 如果启用缓存,将cacheEnabled参数添加到请求选项中
if(cacheEnabled){
requestOptions.extra ??= {};
requestOptions.extra!['cacheEnabled'] = true;
}
final response = await _dio.post( final response = await _dio.post(
url, url,
data: params, data: params,
...@@ -313,4 +328,61 @@ class _RequestInterceptor extends Interceptor { ...@@ -313,4 +328,61 @@ class _RequestInterceptor extends Interceptor {
} }
// 缓存拦截器
class _CacheInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
final cacheEnabled = options.extra?['cacheEnabled'] ?? false;
if (cacheEnabled) {
// 在发起请求之前,检查缓存是否存在有效数据
final cachedFile = await DefaultCacheManager().getFileFromCache(options.uri.toString());
if (cachedFile != null && cachedFile.validTill.isAfter(DateTime.now())) {
// 如果缓存有效,直接返回缓存数据
final cachedData = await cachedFile.file.readAsBytes();
final decodedData = utf8.decode(cachedData); // 将字节列表解码为字符串
final jsonData = jsonDecode(decodedData);
handler.resolve(Response(
requestOptions: options,
statusCode: 200,
data: jsonData,
));
return;
}
}
// 如果缓存不存在或已过期,或未启用缓存,继续发起网络请求
handler.next(options);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) async {
// 只缓存状态码为200的响应
if (response.statusCode == 200) {
try {
// 获取请求的 URL
final url = response.requestOptions.uri.toString();
// 获取请求体参数(如果是 POST 请求)
final requestBody = response.requestOptions.data.toString();
// 将 GET 请求的参数和请求体参数拼接成缓存的键
final cacheKey = requestBody.isEmpty ? url : '$url?$requestBody';
Console.log('----------cacheKey-----------------------$cacheKey');
// 将响应数据转换为字符串,并将其编码为字节列表
List<int> bytes = utf8.encode(jsonEncode(response.data));
Uint8List uint8List = Uint8List.fromList(bytes);
// 创建一个缓存文件并将数据写入其中
DefaultCacheManager().putFile(
cacheKey,
uint8List,
fileExtension: '.json', // 可以根据需求修改文件扩展名
maxAge: const Duration(hours: 1)
);
} catch (e) {
Console.log('Error caching response: $e');
}
}
super.onResponse(response, handler);
}
}
...@@ -2,11 +2,13 @@ library services; ...@@ -2,11 +2,13 @@ library services;
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter_book/store/index.dart'; import 'package:flutter_book/store/index.dart';
import 'package:flutter_book/utils/index.dart'; import 'package:flutter_book/utils/index.dart';
import 'package:flutter_book/widgets/index.dart'; import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:get/get.dart' hide Response, FormData, MultipartFile; import 'package:get/get.dart' hide Response, FormData, MultipartFile;
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
......
...@@ -206,6 +206,14 @@ packages: ...@@ -206,6 +206,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.0.4" version: "3.0.4"
flutter_cache_manager:
dependency: "direct main"
description:
name: flutter_cache_manager
sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.3.1"
flutter_easyloading: flutter_easyloading:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -810,6 +818,22 @@ packages: ...@@ -810,6 +818,22 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.9.1" version: "1.9.1"
sqflite:
dependency: transitive
description:
name: sqflite
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.2"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.5.3"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
......
...@@ -104,8 +104,11 @@ dependencies: ...@@ -104,8 +104,11 @@ dependencies:
# 内购 # 内购
flutter_inapp_purchase: ^5.6.1 flutter_inapp_purchase: ^5.6.1
encrypt: ^5.0.3 encrypt: ^5.0.3
# 阿里oss直传
flutter_oss_aliyun: ^6.4.1 flutter_oss_aliyun: ^6.4.1
just_audio: ^0.9.36 just_audio: ^0.9.36
# 缓存
flutter_cache_manager: ^3.3.1
dev_dependencies: dev_dependencies:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论