feat:增加对话框工具类

This commit is contained in:
2025-11-23 23:07:36 +08:00
parent 98b389a6ff
commit 1953e43ca4
11 changed files with 669 additions and 93 deletions

View File

@@ -12,6 +12,15 @@ List<T> convertList<T>(
); );
} }
List<String> convertStringList(dynamic data) {
if (data is List) {
return data.map((item) => item.toString()).toList();
}
throw FormatException(
'Expected a list of items for conversion, but got ${data.runtimeType}',
);
}
PageResult<T> convertPage<T>( PageResult<T> convertPage<T>(
dynamic data, dynamic data,
T Function(Map<String, dynamic>) fromJson, T Function(Map<String, dynamic>) fromJson,

50
lib/utils/file_utils.dart Normal file
View File

@@ -0,0 +1,50 @@
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'log_utils.dart';
String getFileExtension(String fileName) {
if (fileName.contains('.')) {
return '.${fileName.split('.').last.toLowerCase()}';
}
return '';
}
Future<String> generateMD5HashName(String filePath) async {
final file = File(filePath);
final bytes = await file.readAsBytes();
final hash = md5.convert(bytes);
return hash.toString();
}
// 图片压缩方法
Future<File> compressImage(File file) async {
try {
// 获取压缩后的文件路径
final result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path,
'${file.parent.path}/compressed_${DateTime.now().millisecondsSinceEpoch}.jpg',
minWidth: 800,
minHeight: 600,
quality: 70,
format: CompressFormat.jpeg,
);
if (result == null) {
throw Exception('图片压缩失败');
}
return File(result.path);
} catch (e) {
logger.e('图片压缩失败,使用原文件: $e');
return file;
}
}
// 检查是否为图片文件
bool isImageFile(String fileName) {
final imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'];
final extension = fileName.toLowerCase().substring(fileName.lastIndexOf('.'));
return imageExtensions.contains(extension);
}

View File

@@ -0,0 +1,58 @@
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:minio/io.dart';
import 'package:minio/minio.dart';
import 'file_utils.dart';
class MinIOHelper {
static final MinIOHelper _instance = MinIOHelper._internal();
factory MinIOHelper() => _instance;
final String ip = '14.103.235.151';
final String fileUrl = 'http://14.103.235.151:9100';
MinIOHelper._internal() {
_minio = Minio(
endPoint: ip,
port: 9100,
accessKey: "tHSFfcDW8qpCzKa2Xg6Y",
secretKey: "oq79EeYJ4jdczRp2IHUMCnbKtSw58NgDlG3sOkvX",
useSSL: false,
);
}
late Minio _minio;
Future<String> uploadFile({
required PlatformFile file,
required String bucketName,
Function(double)? onProgress,
}) async {
try {
if (isImageFile(file.name)) {
// 压缩图片
final compressedFile = await compressImage(File(file.path!));
String hashName = await generateMD5HashName(compressedFile.path);
String fileName = '$hashName${getFileExtension(file.name)}';
await _minio.fPutObject(bucketName, fileName, compressedFile.path);
await compressedFile.delete();
return fileName;
} else {
String hashName = await generateMD5HashName(file.path!);
String fileName = '$hashName${getFileExtension(file.name)}';
await _minio.fPutObject(bucketName, fileName, file.path!);
return fileName;
}
} catch (e) {
throw Exception('文件上传失败: $e');
}
}
}

48
lib/utils/toast_util.dart Normal file
View File

@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class ToastUtil {
static void success(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
backgroundColor: Colors.green,
textColor: Colors.white,
fontSize: 16.0,
);
}
static void error(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0,
);
}
static void warning(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
backgroundColor: Colors.orange,
textColor: Colors.white,
fontSize: 16.0,
);
}
static void info(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
backgroundColor: Colors.blue,
textColor: Colors.white,
fontSize: 16.0,
);
}
}

View File

@@ -2,6 +2,83 @@ import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart'; import 'package:syncfusion_flutter_charts/charts.dart';
import '../models/common_model.dart'; import '../models/common_model.dart';
import 'common_widget.dart';
class StatsCard extends StatelessWidget {
final String title;
final String value;
final String unit;
final IconData icon;
const StatsCard(
{super.key,
required this.title,
required this.value,
required this.unit,
required this.icon});
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
return CommonCard(
child: Row(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: colors.primary.withAlpha(50),
shape: BoxShape.circle,
),
child: Icon(icon, size: 26, color: colors.primary),
),
SizedBox(width: 6),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
title,
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade600,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 6),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
value,
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: colors.primary,
height: 1.0,
),
),
const SizedBox(width: 4),
Text(
unit,
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
fontWeight: FontWeight.w500,
),
),
],
),
],
),
),
],
),
);
}
}
class LineChart extends StatelessWidget { class LineChart extends StatelessWidget {
final String title; final String title;
@@ -168,6 +245,7 @@ class BarChart extends StatelessWidget {
} }
class DoubleBarChart extends StatelessWidget { class DoubleBarChart extends StatelessWidget {
final String title;
final String xAxisName; final String xAxisName;
final String yAxisName; final String yAxisName;
final String unit; final String unit;
@@ -178,6 +256,7 @@ class DoubleBarChart extends StatelessWidget {
const DoubleBarChart( const DoubleBarChart(
{super.key, {super.key,
required this.title,
required this.xAxisName, required this.xAxisName,
required this.yAxisName, required this.yAxisName,
required this.unit, required this.unit,
@@ -190,81 +269,88 @@ class DoubleBarChart extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme; final colors = Theme.of(context).colorScheme;
return SfCartesianChart( return Column(children: [
// X轴配置类别轴 _buildChartTitle(context, title, Icons.bar_chart),
primaryXAxis: const SizedBox(height: 3),
CategoryAxis(majorGridLines: const MajorGridLines(width: 0)), _buildChartDivider(context),
const SizedBox(height: 3),
Expanded(
child: SfCartesianChart(
// X轴配置类别轴
primaryXAxis:
CategoryAxis(majorGridLines: const MajorGridLines(width: 0)),
// Y轴配置数值轴 // Y轴配置数值轴
// primaryYAxis: NumericAxis(title: AxisTitle(text: '$yAxisName$unit')), // primaryYAxis: NumericAxis(title: AxisTitle(text: '$yAxisName$unit')),
// 图例配置 // 图例配置
legend: Legend( legend: Legend(
isVisible: true, isVisible: true,
position: LegendPosition.top, position: LegendPosition.top,
overflowMode: LegendItemOverflowMode.wrap, overflowMode: LegendItemOverflowMode.wrap,
),
// 启用交互提示
tooltipBehavior: TooltipBehavior(
enable: true,
format: 'series.name: point.y $unit',
),
// 双柱状图数据系列
series: <ColumnSeries<ChartData, String>>[
ColumnSeries<ChartData, String>(
dataSource: data1,
// X轴数据映射
xValueMapper: (ChartData chart, _) => chart.name,
// Y轴数据映射
yValueMapper: (ChartData chart, _) => chart.value,
// 系列名称
name: series1Name,
// 柱子颜色
color: colors.primary,
// 柱子宽度
width: 0.3,
// 柱子边框
borderWidth: 1,
borderColor: Colors.black12,
// 数据标签
dataLabelSettings: const DataLabelSettings(
isVisible: true,
color: Colors.white,
opacity: 0,
alignment: ChartAlignment.center,
),
// 动画效果
animationDuration: 2000,
), ),
ColumnSeries<ChartData, String>(
dataSource: data2, // 启用交互提示
// X轴数据映射 tooltipBehavior: TooltipBehavior(
xValueMapper: (ChartData chart, _) => chart.name, enable: true,
// Y轴数据映射 format: 'series.name: point.y $unit',
yValueMapper: (ChartData chart, _) => chart.value,
// 系列名称
name: series2Name,
// 柱子颜色
color: colors.inversePrimary,
// 柱子宽度
width: 0.3,
// 柱子边框
borderWidth: 1,
borderColor: Colors.black12,
// 数据标签
dataLabelSettings: const DataLabelSettings(
isVisible: true,
color: Colors.white,
opacity: 0,
alignment: ChartAlignment.center,
),
// 动画效果
animationDuration: 2000,
), ),
],
); // 双柱状图数据系列
series: <ColumnSeries<ChartData, String>>[
ColumnSeries<ChartData, String>(
dataSource: data1,
// X轴数据映射
xValueMapper: (ChartData chart, _) => chart.name,
// Y轴数据映射
yValueMapper: (ChartData chart, _) => chart.value,
// 系列名称
name: series1Name,
// 柱子颜色
color: colors.primary,
// 柱子宽度
width: 0.3,
// 柱子边框
borderWidth: 1,
borderColor: Colors.black12,
// 数据标签
dataLabelSettings: const DataLabelSettings(
isVisible: true,
color: Colors.white,
opacity: 0,
alignment: ChartAlignment.center,
),
// 动画效果
animationDuration: 2000,
),
ColumnSeries<ChartData, String>(
dataSource: data2,
// X轴数据映射
xValueMapper: (ChartData chart, _) => chart.name,
// Y轴数据映射
yValueMapper: (ChartData chart, _) => chart.value,
// 系列名称
name: series2Name,
// 柱子颜色
color: colors.inversePrimary,
// 柱子宽度
width: 0.3,
// 柱子边框
borderWidth: 1,
borderColor: Colors.black12,
// 数据标签
dataLabelSettings: const DataLabelSettings(
isVisible: true,
color: Colors.white,
opacity: 0,
alignment: ChartAlignment.center,
),
// 动画效果
animationDuration: 2000,
),
],
))
]);
} }
} }

View File

@@ -64,3 +64,9 @@ Widget buildErrorInfo({
Widget buildLoadingIndicator() { Widget buildLoadingIndicator() {
return Center(child: CircularProgressIndicator()); return Center(child: CircularProgressIndicator());
} }
Widget buildEmptyData() {
return Center(
child: Text('暂无数据', style: TextStyle(fontSize: 16, color: Colors.grey)),
);
}

View File

@@ -0,0 +1,100 @@
import 'package:awesome_dialog/awesome_dialog.dart';
import 'package:flutter/material.dart';
void showAwesomeDialog({
required BuildContext context,
required Widget body,
required VoidCallback onOk,
required VoidCallback onCancel,
}) {
AwesomeDialog(
context: context,
dialogType: DialogType.noHeader,
animType: AnimType.scale,
body: body,
dialogBackgroundColor: Theme.of(context).colorScheme.surfaceContainer,
btnOkText: "确认",
btnCancelText: "取消",
btnOkColor: Colors.orange,
btnCancelColor: Colors.grey,
buttonsBorderRadius: BorderRadius.circular(10),
headerAnimationLoop: false,
dismissOnTouchOutside: false,
dismissOnBackKeyPress: true,
btnOk: ElevatedButton(
onPressed: onOk,
style: ElevatedButton.styleFrom(
elevation: 0,
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 6),
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
fontFamily: 'CustomFont'),
),
child: Text("确认"),
),
btnCancelOnPress: onCancel,
).show();
}
// 显示成功提示
void showSuccessTip(BuildContext context, String message) {
AwesomeDialog(
context: context,
dialogType: DialogType.success,
animType: AnimType.scale,
title: message,
btnOkText: "好的",
btnOkColor: Colors.green,
btnOkOnPress: () {},
autoHide: Duration(seconds: 2),
).show();
}
// 显示失败提示
void showErrorTip(BuildContext context, String message) {
AwesomeDialog(
context: context,
dialogType: DialogType.error,
animType: AnimType.scale,
title: message,
btnOkText: "好的",
btnOkColor: Colors.red,
btnOkOnPress: () {},
autoHide: Duration(seconds: 2),
).show();
}
// 确认对话框
Future<bool?> showConfirmDialog(BuildContext context, String text) async {
final colors = Theme.of(context).colorScheme;
return showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('确认'),
backgroundColor: colors.surfaceContainer,
content: Text(text),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(
'取消',
style: TextStyle(color: colors.secondary.withAlpha(150)),
),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: Text('确认', style: TextStyle(color: colors.primary)),
),
],
);
},
);
}

View File

@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
class LoadingDialog {
static void show(BuildContext context, {String? message}) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return PopScope(
canPop: false,
child: AlertDialog(
backgroundColor: Colors.transparent,
elevation: 0,
content: _buildLoadingContent(context, message),
),
);
},
);
}
static void hide(BuildContext context) {
Navigator.of(context, rootNavigator: true).pop();
}
static Widget _buildLoadingContent(BuildContext context, String? message) {
final colors = Theme.of(context).colorScheme;
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(colors.primary),
strokeWidth: 3,
),
if (message != null) ...[
SizedBox(height: 16),
Text(
message,
style: TextStyle(fontSize: 14, color: Colors.grey[600]),
),
],
],
),
);
}
}

View File

@@ -3,26 +3,21 @@ import 'package:flutter/material.dart';
import 'common_widget.dart'; import 'common_widget.dart';
class YearSelector extends StatefulWidget { class YearSelector extends StatefulWidget {
final int initialYear; final int currentYear;
final int? minYear;
final int? maxYear;
final Function(int) onYearChanged; final Function(int) onYearChanged;
const YearSelector({ const YearSelector(
super.key, {super.key, required this.currentYear, required this.onYearChanged});
required this.initialYear,
required this.onYearChanged,
this.minYear,
this.maxYear,
});
@override @override
State<YearSelector> createState() => _YearSelectorState(); State<YearSelector> createState() => _YearSelectorState();
} }
// SingleTickerProviderStateMixin 动画控制器
class _YearSelectorState extends State<YearSelector> class _YearSelectorState extends State<YearSelector>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
final int minYear = 2000;
final int maxYear = 2100;
late int _currentYear; late int _currentYear;
// 用于动画效果 // 用于动画效果
@@ -32,7 +27,8 @@ class _YearSelectorState extends State<YearSelector>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_currentYear = widget.initialYear;
_currentYear = widget.currentYear;
// 初始化动画控制器 // 初始化动画控制器
_animationController = AnimationController( _animationController = AnimationController(
@@ -46,6 +42,17 @@ class _YearSelectorState extends State<YearSelector>
); );
} }
@override
void didUpdateWidget(YearSelector oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.currentYear != widget.currentYear) {
setState(() {
_currentYear = widget.currentYear;
});
}
}
@override @override
void dispose() { void dispose() {
_animationController.dispose(); _animationController.dispose();
@@ -54,24 +61,26 @@ class _YearSelectorState extends State<YearSelector>
/// 切换到上一年 /// 切换到上一年
void _previousYear() { void _previousYear() {
if (widget.minYear == null || _currentYear > widget.minYear!) { if (_currentYear > minYear) {
_animateYearChange(() { _animateYearChange(() {
final newYear = _currentYear - 1;
setState(() { setState(() {
_currentYear--; _currentYear = newYear;
}); });
widget.onYearChanged(_currentYear); widget.onYearChanged(newYear);
}); });
} }
} }
/// 切换到下一年 /// 切换到下一年
void _nextYear() { void _nextYear() {
if (widget.maxYear == null || _currentYear < widget.maxYear!) { if (_currentYear < maxYear) {
_animateYearChange(() { _animateYearChange(() {
final newYear = _currentYear + 1;
setState(() { setState(() {
_currentYear++; _currentYear = newYear;
}); });
widget.onYearChanged(_currentYear); widget.onYearChanged(newYear);
}); });
} }
} }
@@ -91,7 +100,7 @@ class _YearSelectorState extends State<YearSelector>
children: [ children: [
CircleIconButton( CircleIconButton(
icon: Icons.chevron_left, icon: Icons.chevron_left,
onPressed: () => _previousYear(), onPressed: _previousYear,
), ),
AnimatedBuilder( AnimatedBuilder(
animation: _scaleAnimation, animation: _scaleAnimation,
@@ -109,8 +118,8 @@ class _YearSelectorState extends State<YearSelector>
), ),
CircleIconButton( CircleIconButton(
icon: Icons.chevron_right, icon: Icons.chevron_right,
onPressed: () => _nextYear(), onPressed: _nextYear,
) ),
], ],
); );
} }

View File

@@ -33,6 +33,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.12.0" version: "2.12.0"
awesome_dialog:
dependency: "direct main"
description:
name: awesome_dialog
sha256: "4c5821a0a637ceee022084e78c1b8237dd4b8bfca4dd24ac2484662a56707338"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.3.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@@ -41,6 +49,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.2" version: "2.1.2"
buffer:
dependency: transitive
description:
name: buffer
sha256: "389da2ec2c16283c8787e0adaede82b1842102f8c8aae2f49003a766c5c6b3d1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.3"
build: build:
dependency: transitive dependency: transitive
description: description:
@@ -153,8 +169,16 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.1.2" version: "3.1.2"
crypto: cross_file:
dependency: transitive dependency: transitive
description:
name: cross_file
sha256: "942a4791cd385a68ccb3b32c71c427aba508a1bb949b86dff2adbe4049f16239"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.3.5"
crypto:
dependency: "direct main"
description: description:
name: crypto name: crypto
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
@@ -177,6 +201,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
dbus:
dependency: transitive
description:
name: dbus
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.7.11"
dio: dio:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -217,6 +249,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "7.0.1" version: "7.0.1"
file_picker:
dependency: "direct main"
description:
name: file_picker
sha256: "7872545770c277236fd32b022767576c562ba28366204ff1a5628853cf8f2200"
url: "https://pub.flutter-io.cn"
source: hosted
version: "10.3.7"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
@@ -230,6 +270,54 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_image_compress:
dependency: "direct main"
description:
name: flutter_image_compress
sha256: "51d23be39efc2185e72e290042a0da41aed70b14ef97db362a6b5368d0523b27"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.0"
flutter_image_compress_common:
dependency: transitive
description:
name: flutter_image_compress_common
sha256: c5c5d50c15e97dd7dc72ff96bd7077b9f791932f2076c5c5b6c43f2c88607bfb
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.6"
flutter_image_compress_macos:
dependency: transitive
description:
name: flutter_image_compress_macos
sha256: "20019719b71b743aba0ef874ed29c50747461e5e8438980dfa5c2031898f7337"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.3"
flutter_image_compress_ohos:
dependency: transitive
description:
name: flutter_image_compress_ohos
sha256: e76b92bbc830ee08f5b05962fc78a532011fcd2041f620b5400a593e96da3f51
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.0.3"
flutter_image_compress_platform_interface:
dependency: transitive
description:
name: flutter_image_compress_platform_interface
sha256: "579cb3947fd4309103afe6442a01ca01e1e6f93dc53bb4cbd090e8ce34a41889"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.5"
flutter_image_compress_web:
dependency: transitive
description:
name: flutter_image_compress_web
sha256: b9b141ac7c686a2ce7bb9a98176321e1182c9074650e47bb140741a44b6f5a96
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.1.5"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@@ -238,6 +326,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "5.0.0" version: "5.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: c2fe1001710127dfa7da89977a08d591398370d099aacdaa6d44da7eb14b8476
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.31"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@@ -248,6 +344,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
fluttertoast:
dependency: "direct main"
description:
name: fluttertoast
sha256: "90778fe0497fe3a09166e8cf2e0867310ff434b794526589e77ec03cf08ba8e8"
url: "https://pub.flutter-io.cn"
source: hosted
version: "8.2.14"
frontend_server_client: frontend_server_client:
dependency: transitive dependency: transitive
description: description:
@@ -416,6 +520,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
minio:
dependency: "direct main"
description:
name: minio
sha256: ee2ce47766e46c7d164f960f2f5ed6a9a82844d877f6b82574f6876ec50c56d1
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.5.8"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@@ -464,6 +576,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.3.0" version: "2.3.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.1.0"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@@ -512,6 +632,22 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.5.0" version: "1.5.0"
rive:
dependency: transitive
description:
name: rive
sha256: fc0abf65d03d1c9afaeb35be9e71c7cf04d2d1f76e94e69d2af1b3ba413cddf9
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.14.0-dev.14"
rive_native:
dependency: transitive
description:
name: rive_native
sha256: e9c7d36f19eb6d32f563825d4e9d5032b19a36d3ca3341641431035bca022d19
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.0.17"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -741,6 +877,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.0.3" version: "3.0.3"
win32:
dependency: transitive
description:
name: win32
sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.13.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
@@ -749,6 +893,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.5.0"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:

View File

@@ -18,6 +18,12 @@ dependencies:
dio: ^5.7.0 dio: ^5.7.0
logger: ^2.6.0 logger: ^2.6.0
json_annotation: ^4.9.0 json_annotation: ^4.9.0
minio: ^3.5.8
crypto: ^3.0.7
file_picker: ^10.3.3
fluttertoast: ^8.2.2
flutter_image_compress: ^2.4.0
awesome_dialog: ^3.3.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: