import 'dart:io'; import 'package:app/config/theme/base/app_theme_ext.dart'; import 'package:app/utils/transfer/upload.dart'; import 'package:app/widgets/base/actionSheet/action_sheet.dart'; import 'package:app/widgets/base/actionSheet/type.dart'; import 'package:app/widgets/base/button/index.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:image_picker/image_picker.dart'; import '../common/preview/file_previewer.dart'; ///快捷打开文件弹窗 void showFileDialog( BuildContext context, { bool isUpload = true, String? name, List files = const [], ValueChanged>? onConfirm, }) { showGeneralDialog( context: context, barrierDismissible: true, // 点击外部关闭 barrierLabel: "RightSheet", pageBuilder: (context, animation, secondaryAnimation) { return FileDrawer( name: name, isUpload: isUpload, files: files, onConfirm: onConfirm, ); }, transitionBuilder: (context, animation, secondaryAnimation, child) { final tween = Tween(begin: Offset(1, 0), end: Offset(0, 0)); return SlideTransition( position: tween.animate(animation), child: child, ); }, ); } ///文件弹窗 class FileDrawer extends StatefulWidget { final String? name; final List files; final bool isUpload; final ValueChanged>? onConfirm; const FileDrawer({ super.key, this.name, this.isUpload = true, this.files = const [], this.onConfirm, }); @override State createState() => _FileDrawerState(); } class _FileDrawerState extends State { ///文件列表 List _fileList = []; @override void initState() { super.initState(); _fileList = List.from(widget.files); } ///打开选择面板 void _handOpenActionSheet() { showActionSheet( context, showCancel: true, actions: [ ActionSheetItem(title: "拍照", value: 1), ActionSheetItem(title: "选择图片", value: 2), ActionSheetItem(title: "选择PDF", value: 3), ], onConfirm: (res) async { List filesToUpload = []; try { if (res.value == 1) { final ImagePicker picker = ImagePicker(); final XFile? photo = await picker.pickImage(source: ImageSource.camera); if (photo == null) return; // 用户取消 filesToUpload.add(File(photo.path)); } else if (res.value == 2) { //选择图片 final result = await FilePicker.platform.pickFiles( allowMultiple: true, type: FileType.image, ); if (result == null) return; filesToUpload.addAll(result.paths.whereType().map((e) => File(e))); } else if (res.value == 3) { //选择pdf final result = await FilePicker.platform.pickFiles( allowMultiple: true, type: FileType.custom, allowedExtensions: ['pdf'], ); if (result == null) return; filesToUpload.addAll(result.paths.whereType().map((e) => File(e))); } if (filesToUpload.isEmpty) return; // 4) 上传文件 EasyLoading.show(status: "文件上传中"); final uploadTasks = filesToUpload.map((file) { return QinUpload.upload( file: file, path: "room/classroom", ); }); final List uploadedPaths = (await Future.wait( uploadTasks, )).whereType().toList(); EasyLoading.dismiss(); // 更新 UI setState(() => _fileList.addAll(uploadedPaths)); // 回调 widget.onConfirm?.call(uploadedPaths); } catch (e) { print(e); EasyLoading.showToast("文件上传失败"); } }, ); } @override Widget build(BuildContext context) { return Align( alignment: Alignment.centerRight, child: Container( width: 300, color: Colors.white, padding: EdgeInsets.all(context.pagePadding), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "${widget.name ?? ""}上传文件列表", style: Theme.of(context).textTheme.titleSmall, ), Expanded( child: Visibility( visible: _fileList.isNotEmpty, replacement: Align( child: Text("未上传文件"), ), child: ListView.separated( padding: EdgeInsets.symmetric(vertical: 15), itemBuilder: (_, index) { String item = _fileList[index]; String suffix = item.split(".").last; return InkWell( key: Key(item), onTap: () { showFilePreviewer(context, url: item); }, child: Container( padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceContainer, borderRadius: BorderRadius.circular(5), ), child: Text("文件${index + 1}.$suffix", style: TextStyle(fontSize: 14)), ), ); }, separatorBuilder: (_, __) => SizedBox(height: 15), itemCount: _fileList.length, ), ), ), Visibility( visible: widget.isUpload, child: Button( text: "上传", onPressed: _handOpenActionSheet, ), ), ], ), ), ); } } ///数据类 class UploadFileItem { String url; String name; bool loading; UploadFileItem({required this.url, this.loading = false, required this.name}); }