最近闲来无事又重拾起了flutter之旅(ps: 码农就是这么的贱,没事喜欢找事),哈哈,上述只针对我自己,向广大码农道歉,别给我发律师函哦。
背景:n年前,初学node的时候搭建了一个漏洞百出的后台接口系统,又不想去重写,只能能用就用,写到一半发现,算了,倔强个什么劲呢,直接用别人现成的接口算了,不是有个大大大佬,把微博用flutter重构了,真的是牛逼至极(ps: 奈何本人没文化,一句牛逼走天下),我也去翻翻我手头的接口,发现还真有。
首先:七牛云的地址是和普通的接口请求是不一样的,所以需要重新new一个新的dio实例,如:
// 上传七牛云服务
class UploadAxios {
Dio uploadDio;
UploadAxios() {
uploadDio = Dio(BaseOptions(
baseUrl: 'https://up-z2.qiniup.com', // 这里的地址得看你们的七牛云服务器在哪里,一一对应就好了
connectTimeout: 5000000,
receiveTimeout: 10000000,
));
}
// post
dynamic post(String url, [dynamic params]) async {
try {
Response response = await uploadDio.post(url, data: params);
return response.data;
} catch (e) {
return;
}
}
// 并发
Future<List<dynamic>> all(Iterable<Future> list) async {
return await Future.wait(list);
}
}
final UploadAxios uploadAxios = UploadAxios();
所谓遇事不决写dynamic,没有什么是一个dynamic解决不了的问题,如果有那就写一个屏幕。哈哈,这是个坏习惯,如果时间不是很紧急的话,还是要把这些类型都推导表明一下,养成一个良好的习惯,毕竟dart是强类型语言,可不是写js了,anyscript表示,我也可以遇事不决写any。
其次:就开始封装我们的上传资源通用方法了,上传七牛云之前要先通关后台向七牛云获取token,单次token只对单次上传任务有效。
dio单文件上传
单文件上传的话就需要用到Future.wait了,由于我这边接口的特定性,所以采用了单文件上传方式,一般可以用dio文档的多文件上传就可以了。
Future<List<dynamic>> Function(List<String>) uploadQiNiu =
(List<String> paths) async {
// 获取上传七牛云token
final publicsModal.QiNiuTokenResponse tokenR =
await publics.api.getQiNiuToken();
if (tokenR.code != 1) return [];
final List<dynamic> response = await uploadQiNiuFiles(paths, tokenR);
if (response == null) return [];
// 构造成可储存的数据结构
return formatSource(tokenR.data.domain, response);
};
// 并发上传七牛云
Future<List<dynamic>> Function(List<String>, publicsModal.QiNiuTokenResponse)
uploadQiNiuFiles =
(List<String> paths, publicsModal.QiNiuTokenResponse tokenR) async {
return uploadAxios
.all(paths.map((e) async => uploadQiNiuFile(e, tokenR)).toList());
};
// 单个上传七牛云
Future<dynamic> Function(String, publicsModal.QiNiuTokenResponse)
uploadQiNiuFile =
(String path, publicsModal.QiNiuTokenResponse tokenR) async {
final String token = tokenR.data.token;
final String basePath = tokenR.data.basePath;
// 生成随机数文件名
String name = Random().nextInt(10000).toString() +
DateTime.now().millisecondsSinceEpoch.toString() +
path.substring(path.lastIndexOf("."));
// 构造FormData
FormData formData = FormData.fromMap({
"file": await MultipartFile.fromFile(path, filename: name),
'token': token, // 上传前,向七牛云获取到的token
'key': '$basePath$name'
});
// 开始上传
return uploadAxios.post('', formData);
};
上传多个文件
只需要把上面的并发去掉,把file字段改成files就可以了,如:
FormData.fromMap({
"name": "wendux",
"age": 25,
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt"),
"files": [
await MultipartFile.fromFile("./text1.txt", filename: "text1.txt"),
await MultipartFile.fromFile("./text2.txt", filename: "text2.txt"),
]
});
response = await dio.post("/info", data: formData);
具体请参考dio文档
好了就是这么的简单,到这里差不多就大功告成了,给自己鼓个掌。
项目地址:传送门
目前实现了一套完整的社交平台的逻辑,项目介绍先写到这里,有其他问题的小伙伴,欢迎评论区留言,知无不言。
撒花
完结