flutter file_picker dio web端上传记录

发布时间:2024年01月12日

app端的上传 获取到FilePickerResult 对象 里面包含 选择上传的文件信息

?FilePickerResult? result = await FilePicker.platform.pickFiles(

? ? ? allowMultiple: true,

? ? );

app端上传逻辑

final allLength = file?.count ?? 0;
int curUploadLength = 0;
// 文件为空
for (var path in file!.paths) {
  final res =
      await Api.uploadFile(path as String);
  final String httpPath = res["data"] ?? "";
  imgList.add(httpPath);
  curUploadLength++;
  widget.onChange?.call(imgList);
}
setState(() {
  cruProgress = curUploadLength / allLength;
});

setState(() {
  isUploading = false;
});

api上传

  static uploadFile(
    String path, {
    ProgressCallback? onSendProgress,
  }) async {
    FormData formData =
        FormData.fromMap({'file': await MultipartFile.fromFile(path)});
    final res = await dio.post(
      Url.uploadFile,
      data: formData,
      options: Options(
        method: "post",
        contentType: "multipart/form-data",
      ),
      onSendProgress: onSendProgress,
    );
    return res.data;
  }

?

其中file.count 表示上传的文件数量

file.paths 表示 选择文件的路径数组

通过dio 上传? 使用FormData 进行转载

?Global.isWeb? == kIsWeb

web端上传报错: 不能使用file.paths 来上传文件

修改如下

web 使用 dio 和?file_picker 上传需要处理

获取?file_picker 的?PlatformFile 对象是一致的 ,在点击文件上传的时候进行逻辑处理

if (kIsWeb) {
final allLength = file?.count ?? 0;
int curUploadLength = 0;
print(file);
// 文件为空
for (PlatformFile curFile in file!.files) {
  final res =
      await Api.uploadFilePlatformFile(curFile);
  final String httpPath = res["data"] ?? "";
  imgList.add(httpPath);
  curUploadLength++;
  widget.onChange?.call(imgList);
}

Console.d("上传 click $allLength");
setState(() {
  cruProgress = curUploadLength / allLength;
});

setState(() {
  isUploading = false;
});

web端的api


  static uploadFilePlatformFile(
    PlatformFile file, {
    ProgressCallback? onSendProgress,
  }) async {
    List<int> fileBytes = file.bytes!;
    MultipartFile multipartFile =
        MultipartFile.fromBytes(fileBytes, filename: file.name);
    FormData formData = FormData.fromMap({'file': multipartFile});
    final res = await dio.post(
      Url.uploadFile,
      data: formData,
      options: Options(
        method: "post",
        contentType: "multipart/form-data",
      ),
      onSendProgress: onSendProgress,
    );
    return res.data;
  }

最关键的问题?

?List<int> fileBytes = file.bytes!;

file.bytes 返回的是?Uint8List? 需要转成??List<int> 才行? 不然 虽然文件通过FormData 发送给后端了 但是后端一直拿不到数据。

完整组件代码

// 文件上传

import 'package:LS/common/index.dart';
import 'package:LS/gen/assets.gen.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';

class MoreFileUploadWidget extends StatefulWidget {
  final Function(List<String?>)? onChange;
  const MoreFileUploadWidget({
    super.key,
    this.onChange,
  });

  @override
  State<MoreFileUploadWidget> createState() => _MoreFileUploadWidgetState();
}

class _MoreFileUploadWidgetState extends State<MoreFileUploadWidget> {
  FilePickerResult? file;

  double cruProgress = 0;

  bool isUploading = false;

  List<String> imgList = [];

  Future getFile() async {
    setState(() {
      imgList.clear();
      cruProgress = 0;
      isUploading = false;
    });

    FilePickerResult? result = await FilePicker.platform.pickFiles(
      allowMultiple: true,
    );

    file = result;
    setState(() {});
  }

  Widget addContainer() {
    return InkWell(
      child: Container(
        width: 108.w,
        height: 108.w,
        alignment: Alignment.center,
        decoration: BoxDecoration(
          color: const Color(0xffF4F6F8),
          borderRadius: BorderRadius.circular(5.r),
        ),
        child: Assets.icon.addImage.image(width: 34.w),
      ),
      onTap: () async {
        await getFile();
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return file == null
        ? addContainer()
        : LayoutBuilder(
            builder: (BuildContext context, BoxConstraints constraints) {
              final width = (constraints.maxWidth - 30) / 2;

              return Wrap(
                spacing: 30,
                runSpacing: 30,
                children: [
                  for (final name in file!.names)
                    Container(
                      width: width,
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(8.r),
                      ),
                      child: Text(
                        (name as String).tr,
                        style: TextStyle(
                          fontSize: 12.sp,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                  addContainer(),
                  if (isUploading)
                    Text(
                      "上传中...".tr,
                      style: TextStyle(
                        fontSize: 12.sp,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  if (file?.names != null && file!.names.isNotEmpty)
                    LineProgressWidget(
                      cruProgress: cruProgress,
                    ),
                  if (file?.names != null &&
                      file!.names.isNotEmpty &&
                      cruProgress != 1)
                    Center(
                      child: PrimaryBtn(
                        text: "上传",
                        onTap: () async {
                          if (isUploading) {
                            return;
                          }
                          Console.d("上传 click");
                          setState(() {
                            isUploading = true;
                          });

                          if (Global.isWeb) {
                            final allLength = file?.count ?? 0;
                            int curUploadLength = 0;
                            print(file);
                            // 文件为空
                            for (PlatformFile curFile in file!.files) {
                              final res =
                                  await Api.uploadFilePlatformFile(curFile);
                              final String httpPath = res["data"] ?? "";
                              imgList.add(httpPath);
                              curUploadLength++;
                              widget.onChange?.call(imgList);
                            }

                            Console.d("上传 click $allLength");
                            setState(() {
                              cruProgress = curUploadLength / allLength;
                            });

                            setState(() {
                              isUploading = false;
                            });
                          } else {
                            try {
                              final allLength = file?.count ?? 0;
                              int curUploadLength = 0;
                              // 文件为空
                              for (var path in file!.paths) {
                                final res =
                                    await Api.uploadFile(path as String);
                                final String httpPath = res["data"] ?? "";
                                imgList.add(httpPath);
                                curUploadLength++;
                                widget.onChange?.call(imgList);
                              }
                              setState(() {
                                cruProgress = curUploadLength / allLength;
                              });

                              setState(() {
                                isUploading = false;
                              });
                            } catch (e) {
                              Console.d("错误 $e");
                              setState(() {
                                isUploading = false;
                              });
                            }
                          }
                        },
                      ),
                    ),
                ],
              );
            },
          );
  }
}

文章来源:https://blog.csdn.net/weixin_43575775/article/details/135553998
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。