自习室优化ok
This commit is contained in:
6
lib/utils/common.dart
Normal file
6
lib/utils/common.dart
Normal file
@@ -0,0 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
///判断是否是安卓
|
||||
bool isAndroid(){
|
||||
return Platform.isAndroid;
|
||||
}
|
||||
@@ -33,21 +33,41 @@ String formatDate(dynamic date, [String format = 'YYYY-MM-DD hh:mm:ss']) {
|
||||
|
||||
/// 将秒数格式化为 00:00 或 00:00:00
|
||||
/// - [seconds]: 秒数
|
||||
String formatSeconds(int seconds) {
|
||||
final h = seconds ~/ 3600;
|
||||
final m = (seconds % 3600) ~/ 60;
|
||||
final s = seconds % 60;
|
||||
/// - [format]: 格式化字符串,默认为 "hh:mm:ss"
|
||||
String formatSeconds(
|
||||
int seconds, [
|
||||
String format = 'hh:mm:ss',
|
||||
]) {
|
||||
if (seconds < 0) seconds = 0;
|
||||
|
||||
String twoDigits(int n) => n.toString().padLeft(2, '0');
|
||||
int h = seconds ~/ 3600;
|
||||
int m = (seconds % 3600) ~/ 60;
|
||||
int s = seconds % 60;
|
||||
|
||||
if (h > 0) {
|
||||
return '${twoDigits(h)}:${twoDigits(m)}:${twoDigits(s)}';
|
||||
} else {
|
||||
return '${twoDigits(m)}:${twoDigits(s)}';
|
||||
}
|
||||
String two(int n) => n.toString().padLeft(2, '0');
|
||||
|
||||
// 支持以下 token:
|
||||
// hh = 补零小时, h = 不补零小时
|
||||
// mm = 补零分钟, m = 不补零分钟
|
||||
// ss = 补零秒, s = 不补零秒
|
||||
final replacements = {
|
||||
'hh': two(h),
|
||||
'mm': two(m),
|
||||
'ss': two(s),
|
||||
'h': h.toString(),
|
||||
'm': m.toString(),
|
||||
's': s.toString(),
|
||||
};
|
||||
|
||||
String result = format;
|
||||
|
||||
replacements.forEach((key, value) {
|
||||
result = result.replaceAll(key, value);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// 将 "HH", "HH:mm" 或 "HH:mm:ss" 转为当天 DateTime
|
||||
DateTime parseTime(String timeStr) {
|
||||
final now = DateTime.now();
|
||||
|
||||
81
lib/utils/transfer/download.dart
Normal file
81
lib/utils/transfer/download.dart
Normal file
@@ -0,0 +1,81 @@
|
||||
//下载文件
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class LocalDownload {
|
||||
static Future<String> getLocalFilePath(String url, String path) async {
|
||||
Uri uri = Uri.parse(url);
|
||||
String fileName = uri.pathSegments.last;
|
||||
//获取下载目录
|
||||
Directory dir = await getApplicationCacheDirectory();
|
||||
Directory uploadPath = Directory("${dir.path}$path/");
|
||||
return uploadPath.path + fileName;
|
||||
}
|
||||
|
||||
/// 公用下载方法
|
||||
/// url 下载网络地址
|
||||
/// path 存储地址,如/test
|
||||
/// onProgress 下载回调函数
|
||||
/// onDone 下载完毕回调
|
||||
static downLoadFile({
|
||||
required url,
|
||||
required path,
|
||||
required Function(double) onProgress,
|
||||
required Function(String) onDone,
|
||||
}) async {
|
||||
HttpClient client = HttpClient();
|
||||
Uri uri = Uri.parse(url);
|
||||
//获取本地文件路径
|
||||
String filePath = await getLocalFilePath(url, path);
|
||||
// 发起 get 请求
|
||||
HttpClientRequest request = await client.getUrl(uri);
|
||||
// 响应
|
||||
HttpClientResponse response = await request.close();
|
||||
int contentLength = response.contentLength; // 获取文件总大小
|
||||
int bytesReceived = 0; // 已接收的字节数
|
||||
List<int> chunkList = [];
|
||||
if (response.statusCode == 200) {
|
||||
response.listen(
|
||||
(List<int> chunk) {
|
||||
chunkList.addAll(chunk);
|
||||
bytesReceived += chunk.length; //更新已接受的字节数
|
||||
//进度
|
||||
double progress = bytesReceived * 100 / contentLength * 100;
|
||||
progress = (progress / 100).truncateToDouble();
|
||||
onProgress(progress);
|
||||
},
|
||||
onDone: () async {
|
||||
//下载完毕
|
||||
client.close();
|
||||
File file = File(filePath);
|
||||
if (!file.existsSync()) {
|
||||
file.createSync(recursive: true);
|
||||
await file.writeAsBytes(chunkList);
|
||||
}
|
||||
onDone(file.path);
|
||||
},
|
||||
onError: () {
|
||||
client.close();
|
||||
},
|
||||
cancelOnError: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
///获取本地地址
|
||||
///
|
||||
static Future<String> getFilePath({
|
||||
required url,
|
||||
required path,
|
||||
}) async {
|
||||
//获取本地文件路径
|
||||
String filePath = await getLocalFilePath(url, path);
|
||||
File file = File(filePath);
|
||||
if (file.existsSync()) {
|
||||
return file.path;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
55
lib/utils/transfer/upload.dart
Normal file
55
lib/utils/transfer/upload.dart
Normal file
@@ -0,0 +1,55 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:app/config/config.dart';
|
||||
import 'package:app/request/api/common_api.dart';
|
||||
import 'package:app/request/dto/common/qiu_token_dto.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
|
||||
class QinUpload {
|
||||
///获取七牛token
|
||||
static Future<QiuTokenDto> _getQiuToken(File file, String path) async {
|
||||
// 读取文件的字节数据
|
||||
final fileBytes = await file.readAsBytes();
|
||||
String fileMd5 = md5.convert(fileBytes).toString();
|
||||
//前缀
|
||||
var prefix = Config.getEnv() == "dev" ? "test" : "release";
|
||||
var suffix = file.path.split(".").last;
|
||||
|
||||
var res = await getQiuTokenApi(
|
||||
"xueguang/$prefix/$path/$fileMd5.$suffix",
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
///上传文件
|
||||
/// - [file] 文件
|
||||
/// - [path] 目标目录
|
||||
static Future<String?> upload({
|
||||
required File file,
|
||||
required String path,
|
||||
}) async {
|
||||
var qiuToken = await _getQiuToken(file, path);
|
||||
//数据
|
||||
FormData formData = FormData.fromMap({
|
||||
"file": await MultipartFile.fromFile(file.path),
|
||||
"token": qiuToken.upToken,
|
||||
"fname": qiuToken.fileKey,
|
||||
"key": qiuToken.fileKey,
|
||||
});
|
||||
try {
|
||||
Dio dio = Dio();
|
||||
Response response = await dio.post(
|
||||
qiuToken.uploadUrl!,
|
||||
data: formData,
|
||||
onSendProgress: (int sent, int total) {},
|
||||
);
|
||||
String key = response.data['key'];
|
||||
return "https://${qiuToken.domain}/$key";
|
||||
} catch (e) {
|
||||
EasyLoading.showError("上传失败");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user