lumin_ui 1.0.17
lumin_ui: ^1.0.17 copied to clipboard
A modern Flutter UI component library with GetX integration, providing rich customizable components and smart text overflow handling.
Lumin UI 🌟 #
A comprehensive Flutter UI library providing beautiful, customizable, and high-performance components for modern mobile and web applications.
一个基于 Flutter 的现代化 UI 组件库,集成了 GetX 状态管理,提供丰富的可定制组件。
特性 #
- 🎨 现代化设计 - 遵循 Material Design 3 设计规范
- 🚀 高性能 - 基于 Flutter 原生组件构建
- 🔧 高度可定制 - 支持主题定制和样式覆盖
- 📱 响应式 - 适配不同屏幕尺寸
- 🎯 GetX 集成 - 内置状态管理和路由管理
- 📦 开箱即用 - 提供常用业务组件
安装 #
在 pubspec.yaml 中添加依赖:
dependencies:
lumin: ^1.0.0
get: ^4.6.6
intl: ^0.19.0
快速开始 #
1. 初始化应用 #
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:lumin/ui/core.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Lumin UI Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: HomePage(),
);
}
}
2. 使用组件 #
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Lumin UI Demo')),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
// 文本组件
luminText('Hello Lumin UI!'),
// 按钮组件
LuminButtons.primary(
text: '主要按钮',
onPressed: () => print('按钮被点击'),
),
// 输入框组件
LuminTextField(
label: '用户名',
placeholder: '请输入用户名',
prefixIcon: Icons.person,
),
],
),
),
);
}
}
组件文档 #
文本组件 (LuminText) #
用于显示文本内容,支持占位符、前缀、后缀等功能。
luminText(
'显示文本',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
placeholder: '暂无数据',
prefix: '前缀',
suffix: '后缀',
)
按钮组件 (LuminButton) #
提供多种样式的按钮组件。
// 基础按钮
LuminButton(
text: '按钮文本',
onPressed: () {},
style: LuminButtonStyle.filled, // filled, outlined, text
)
// 预设样式按钮
LuminButtons.primary(text: '主要按钮', onPressed: () {})
LuminButtons.secondary(text: '次要按钮', onPressed: () {})
LuminButtons.danger(text: '危险按钮', onPressed: () {})
LuminButtons.success(text: '成功按钮', onPressed: () {})
输入框组件 (LuminTextField) #
增强的文本输入框,支持多种输入类型和验证。
LuminTextField(
controller: controller,
label: '标签',
placeholder: '占位符',
inputType: LuminInputType.email, // text, password, email, phone, number 等
prefixIcon: Icons.email,
suffixIcon: Icons.visibility,
clearable: true,
validator: (value) => value?.isEmpty == true ? '不能为空' : null,
)
下拉框组件 (LuminDropdown) #
支持单选和多选的下拉框组件。
// 单选下拉框
LuminDropdown<String>(
value: selectedValue,
items: [
LuminDropdownItem(value: 'option1', label: '选项1'),
LuminDropdownItem(value: 'option2', label: '选项2'),
],
onChanged: (value) => setState(() => selectedValue = value),
placeholder: '请选择',
)
// 多选下拉框
LuminMultiSelectDropdown<String>(
values: selectedValues,
items: [
LuminDropdownItem(value: 'option1', label: '选项1'),
LuminDropdownItem(value: 'option2', label: '选项2'),
],
onChanged: (values) => setState(() => selectedValues = values),
)
对话框组件 (LuminDialog) #
提供多种类型的对话框。
// 基础对话框
LuminDialog.show(
title: '标题',
content: '内容',
actions: [
TextButton(onPressed: () => Get.back(), child: Text('取消')),
ElevatedButton(onPressed: () => Get.back(), child: Text('确认')),
],
);
// 确认对话框
final result = await LuminDialog.confirm(
title: '确认删除',
content: '确定要删除这个项目吗?',
);
// 输入对话框
final input = await LuminDialog.input(
title: '输入名称',
placeholder: '请输入名称',
);
// 选择对话框
final selected = await LuminDialog.select<String>(
title: '选择选项',
options: [
LuminSelectOption(value: 'option1', label: '选项1'),
LuminSelectOption(value: 'option2', label: '选项2'),
],
);
日期时间选择器 (LuminDatePicker) #
提供日期、时间、日期时间和日期范围选择功能。
// 日期选择器
final date = await LuminDatePicker.show(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime(2030),
);
// 时间选择器
final time = await LuminTimePicker.show(
context: context,
initialTime: TimeOfDay.now(),
);
// 日期时间选择器
final dateTime = await LuminDateTimePicker.show(
context: context,
initialDateTime: DateTime.now(),
);
// 日期范围选择器
final dateRange = await LuminDateRangePicker.show(
context: context,
initialDateRange: DateTimeRange(
start: DateTime.now(),
end: DateTime.now().add(Duration(days: 7)),
),
);
// 时间范围选择器
LuminTimeRangePicker(
label: '时间范围',
selectedRange: timeRange,
onRangeChanged: (range) => setState(() => timeRange = range),
hintText: '请选择时间范围',
)
// 日期时间范围选择器
LuminDateTimeRangePicker(
label: '日期时间范围',
selectedRange: dateTimeRange,
onRangeChanged: (range) => setState(() => dateTimeRange = range),
hintText: '请选择日期时间范围',
)
分页组件 (LuminPagination) #
提供完整的分页功能。
// 基础分页
LuminPagination(
currentPage: currentPage,
totalPages: totalPages,
onPageChanged: (page) => setState(() => currentPage = page),
)
// 完整分页(包含页面大小选择器和信息显示)
LuminFullPagination(
currentPage: currentPage,
totalPages: totalPages,
totalItems: totalItems,
pageSize: pageSize,
onPageChanged: (page) => setState(() => currentPage = page),
onPageSizeChanged: (size) => setState(() => pageSize = size),
)
容器组件 (LuminContainer) #
增强的容器组件,支持渐变、边框、阴影等效果。
luminContainer(
child: Text('容器内容'),
backgroundColor: Colors.blue.shade50,
borderRadius: 12,
border: Border.all(color: Colors.blue),
gradient: LinearGradient(
colors: [Colors.blue.shade100, Colors.blue.shade200],
),
elevation: 4,
padding: EdgeInsets.all(16),
margin: EdgeInsets.all(8),
)
Flex 布局扩展 (LuminFlex) #
为 Widget 列表提供便捷的布局方法。
// 水平布局
[widget1, widget2, widget3].toRow(spacing: 8)
// 垂直布局
[widget1, widget2, widget3].toColumn(spacing: 8)
// 包装布局
[widget1, widget2, widget3].toWrap(spacing: 8, runSpacing: 8)
表单字段组件 (LuminFormField) #
统一的表单字段组件,支持多种输入类型和自定义样式。
// 普通文本输入
LuminFormFields.text(
label: '姓名',
placeholder: '请输入姓名',
isRequired: true,
rightWidget: Icon(Icons.person),
)
// 数字输入(带单位)
LuminFormFields.number(
label: '重量',
placeholder: '请输入重量',
unit: 'KG',
isRequired: true,
)
// 下拉选择
LuminFormFields.dropdown(
label: '城市',
options: ['北京', '上海', '广州', '深圳'],
placeholder: '请选择城市',
rightWidget: Icon(Icons.arrow_forward_ios, size: 16),
)
// 多行文本
LuminFormFields.multiline(
label: '备注',
placeholder: '请输入备注信息',
maxLines: 3,
)
// 开关
LuminFormFields.switch_(
label: '启用通知',
initialValue: true,
)
// 步进器
LuminFormFields.stepper(
label: '数量',
min: 0,
max: 100,
step: 1,
initialValue: 1,
)
// 自定义组件
LuminFormFields.custom(
label: '自定义',
customWidget: YourCustomWidget(),
rightWidget: Icon(Icons.settings),
)
表单字段特性
- 统一样式: 所有字段保持一致的视觉风格
- 必填标识: 支持红色星号标记必填字段
- 右侧扩展: 可添加自定义右侧组件(图标、按钮等)
- 单位支持: 数字输入框支持单位显示
- 验证集成: 内置表单验证支持
- 响应式: 集成GetX响应式状态管理
- 多种类型: 支持文本、数字、下拉、开关、步进器等
- 样式自定义: 支持边框、标题、输入框、箭头等样式配置
样式配置选项
// 自定义样式示例
LuminFormFields.text(
label: '自定义样式',
placeholder: '请输入内容',
// 边框配置
borderColor: Colors.blue,
showBorder: true,
// 标题配置
labelColor: Colors.blue.shade700,
labelFontSize: 18,
// 输入框配置
inputBackgroundColor: Colors.blue.shade50,
)
// 下拉选择框箭头配置
LuminFormFields.dropdown(
label: '选择项',
options: ['选项1', '选项2'],
// 箭头配置
showArrow: true,
arrowColor: Colors.grey.shade600,
// 无边框样式
showBorder: false,
)
表格组件 (LuminTable) #
功能强大的表格组件,支持自定义表头、表头合并、固定列、左右滑动、分页等功能。
// 基础表格
LuminTables.basic(
columns: [
LuminTableColumn(key: 'name', title: '姓名', width: 100),
LuminTableColumn(key: 'age', title: '年龄', width: 80, textAlign: TextAlign.center),
LuminTableColumn(key: 'city', title: '城市', width: 100),
],
data: data.map((item) => LuminTableRow(
data: item,
onTap: () => print('点击了${item['name']}'),
)).toList(),
config: LuminTableConfig(
showBorder: true,
showRowDivider: true,
hoverColor: Colors.grey.shade100,
),
)
// 分页表格
LuminTables.paginated(
columns: [
LuminTableColumn(
key: 'id',
title: 'ID',
width: 60,
fixed: true, // 固定列
textAlign: TextAlign.center,
),
LuminTableColumn(
key: 'name',
title: '姓名',
width: 120,
sortable: true, // 可排序
),
LuminTableColumn(
key: 'status',
title: '状态',
width: 100,
cellBuilder: (context, data, column) {
// 自定义单元格内容
final status = data['status'] as String;
Color color = status == '活跃' ? Colors.green : Colors.red;
return Container(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color.withOpacity(0.3)),
),
child: Text(
status,
style: TextStyle(color: color, fontSize: 12),
),
);
},
),
LuminTableColumn(
key: 'actions',
title: '操作',
width: 120,
cellBuilder: (context, data, column) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () => print('编辑${data['name']}'),
child: Text('编辑', style: TextStyle(fontSize: 12)),
),
TextButton(
onPressed: () => print('删除${data['name']}'),
child: Text('删除', style: TextStyle(fontSize: 12, color: Colors.red)),
),
],
);
},
),
],
data: currentData.map((item) => LuminTableRow(
data: item,
onTap: () => print('点击了${item['name']}'),
)).toList(),
config: LuminTableConfig(
showBorder: true,
showRowDivider: true,
showColumnDivider: true,
hoverColor: Colors.blue.shade50,
headerBackgroundColor: Colors.grey.shade100,
height: 300, // 固定高度,支持滚动
),
paginationConfig: LuminTablePaginationConfig(
currentPage: currentPage,
totalPages: totalPages,
pageSize: pageSize,
pageSizeOptions: [5, 10, 20, 50],
onPageChanged: (page) => setState(() => currentPage = page),
onPageSizeChanged: (size) => setState(() => pageSize = size),
showPageSizeSelector: true,
showPageInfo: true,
),
sortConfig: LuminTableSort(
column: sortColumn,
ascending: sortAscending,
onSort: (column, ascending) {
setState(() {
sortColumn = column;
sortAscending = ascending;
});
},
),
)
// 表头合并示例
LuminTable(
columns: [
LuminTableColumn(
key: 'name',
title: '基本信息',
width: 100,
colspan: 2, // 合并2列
headerBuilder: (context, column) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.blue.shade100,
border: Border.all(color: Colors.grey.shade300),
),
child: Text(
column.title,
style: TextStyle(fontWeight: FontWeight.bold),
),
);
},
),
LuminTableColumn(key: 'age', title: '', width: 80, isSubHeader: true),
LuminTableColumn(
key: 'score',
title: '成绩信息',
width: 100,
colspan: 2,
headerBuilder: (context, column) {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.green.shade100,
border: Border.all(color: Colors.grey.shade300),
),
child: Text(
column.title,
style: TextStyle(fontWeight: FontWeight.bold),
),
);
},
),
LuminTableColumn(key: 'status', title: '', width: 80, isSubHeader: true),
],
data: data.map((item) => LuminTableRow(data: item)).toList(),
config: LuminTableConfig(
showBorder: true,
showRowDivider: true,
showColumnDivider: true,
height: 200,
),
)
表格组件特性
- 自定义表头: 支持自定义表头样式和内容
- 表头合并: 支持跨列合并表头单元格
- 固定列: 支持左侧固定列,右侧可滚动
- 左右滑动: 当内容超出屏幕宽度时支持水平滚动
- 分页功能: 集成现有分页组件,支持页面大小选择
- 排序功能: 支持列排序,可自定义排序逻辑
- 行选择: 支持单选和多选行
- 自定义单元格: 支持自定义单元格内容和样式
- 悬停效果: 支持行悬停高亮效果
- 边框控制: 支持表格边框、行分割线、列分割线的显示控制
- 响应式: 支持不同屏幕尺寸的适配
表格配置选项
// 列配置
LuminTableColumn(
key: 'column_key', // 列标识
title: '列标题', // 列标题
width: 100, // 列宽度
minWidth: 80, // 最小宽度
maxWidth: 200, // 最大宽度
fixed: false, // 是否固定列
sortable: false, // 是否可排序
textAlign: TextAlign.left, // 文本对齐方式
colspan: 1, // 表头合并列数
rowspan: 1, // 表头合并行数
isSubHeader: false, // 是否为子表头
cellBuilder: (context, data, column) => Widget, // 自定义单元格
headerBuilder: (context, column) => Widget, // 自定义表头
)
// 表格配置
LuminTableConfig(
showBorder: true, // 显示外边框
showRowDivider: true, // 显示行分割线
showColumnDivider: false, // 显示列分割线
hoverColor: Colors.grey.shade100, // 悬停颜色
selectedColor: Colors.blue.shade100, // 选中颜色
headerBackgroundColor: Colors.grey.shade50, // 表头背景色
borderColor: Colors.grey.shade300, // 边框颜色
dividerColor: Colors.grey.shade200, // 分割线颜色
height: 400, // 表格高度
headerHeight: 48, // 表头高度
rowHeight: 48, // 行高度
)
// 分页配置
LuminTablePaginationConfig(
currentPage: 1, // 当前页码
totalPages: 10, // 总页数
pageSize: 10, // 每页大小
pageSizeOptions: [10, 20, 50], // 页面大小选项
showPageSizeSelector: true, // 显示页面大小选择器
showPageInfo: true, // 显示页面信息
onPageChanged: (page) {}, // 页码变化回调
onPageSizeChanged: (size) {}, // 页面大小变化回调
)
GetX 集成 #
控制器基类 #
Lumin UI 提供了几个控制器基类来简化状态管理:
// 基础控制器
class MyController extends LuminController {
void doSomething() async {
await executeAsync(
operation: () => apiCall(),
loadingMessage: '加载中...',
successMessage: '操作成功',
showLoadingDialog: true,
showSuccessSnackbar: true,
);
}
}
// 列表控制器
class MyListController extends LuminListController<MyModel> {
@override
Future<void> loadData({bool showLoading = true}) async {
final data = await apiService.getList(
page: currentPage,
pageSize: pageSize,
keyword: searchKeyword,
);
if (currentPage == 1) {
items = data.items;
} else {
items.addAll(data.items);
}
totalPages = data.totalPages;
totalItems = data.totalItems;
hasMore = currentPage < totalPages;
}
}
// 表单控制器
class MyFormController extends LuminFormController {
@override
Future<void> submitForm() async {
if (!validateForm()) return;
await executeAsync(
operation: () => apiService.submit({
'name': getFieldValue('name'),
'email': getFieldValue('email'),
}),
loadingMessage: '提交中...',
successMessage: '提交成功',
showLoadingDialog: true,
showSuccessSnackbar: true,
);
}
}
GetX 工具类 #
// 显示确认对话框
final confirmed = await LuminGetX.showConfirmDialog(
title: '确认操作',
message: '确定要执行此操作吗?',
);
// 显示输入对话框
final input = await LuminGetX.showInputDialog(
title: '输入信息',
hintText: '请输入内容',
);
// 显示选择对话框
final selected = await LuminGetX.showSelectDialog<String>(
title: '选择选项',
options: [
LuminSelectOption(value: 'option1', label: '选项1'),
LuminSelectOption(value: 'option2', label: '选项2'),
],
);
// 显示底部选择器
final selected = await LuminGetX.showBottomPicker<String>(
title: '选择选项',
options: [
LuminSelectOption(value: 'option1', label: '选项1'),
LuminSelectOption(value: 'option2', label: '选项2'),
],
);
// 显示自定义 Snackbar
LuminGetX.showSnackbar(
title: '提示',
message: '这是一个提示消息',
backgroundColor: Colors.blue,
icon: Icon(Icons.info),
);
主题定制 #
你可以通过 Flutter 的主题系统来定制 Lumin UI 组件的外观:
GetMaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
// 自定义按钮主题
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
borderRadius: BorderRadius.circular(8),
),
),
// 自定义输入框主题
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
home: HomePage(),
)
示例项目 #
查看 lib/main.dart 文件获取完整的使用示例。
网络请求 #
网络管理器 (LuminNetworkManager) #
Lumin UI 提供了强大的网络请求管理功能,基于 Dio 封装,支持请求拦截、响应处理、错误处理等。
// 初始化网络管理器
final networkManager = LuminNetworkManager(
config: LuminNetworkConfig(
baseUrl: 'https://api.example.com',
connectTimeout: const Duration(seconds: 30),
receiveTimeout: const Duration(seconds: 30),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
),
);
// 添加请求拦截器
networkManager.addRequestInterceptor(
onRequest: (options, handler) {
// 添加认证token
final token = AuthService.getToken();
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
handler.next(options);
},
);
// 添加响应拦截器
networkManager.addResponseInterceptor(
onResponse: (response, handler) {
// 处理响应数据
print('响应状态: ${response.statusCode}');
handler.next(response);
},
onError: (error, handler) {
// 处理错误
if (error.response?.statusCode == 401) {
// token过期,跳转到登录页
Get.offAllNamed('/login');
}
handler.next(error);
},
);
基础请求方法
// GET 请求
LuminResponse<Map<String, dynamic>> response = await networkManager.get(
'/api/users',
queryParameters: {'page': 1, 'limit': 10},
);
if (response.isSuccess) {
print('用户列表: ${response.data}');
} else {
print('请求失败: ${response.message}');
}
// POST 请求
LuminResponse<Map<String, dynamic>> response = await networkManager.post(
'/api/users',
data: {
'name': 'John Doe',
'email': 'john@example.com',
},
);
// PUT 请求
LuminResponse<Map<String, dynamic>> response = await networkManager.put(
'/api/users/123',
data: {'name': 'Jane Doe'},
);
// DELETE 请求
LuminResponse<bool> response = await networkManager.delete('/api/users/123');
文件上传下载
// 图片选择和上传
class ImageUploadController extends GetxController with LuminNetworkMixin {
final ImagePicker _imagePicker = ImagePicker();
final uploadProgress = 0.0.obs;
final uploadedImageUrl = ''.obs;
final selectedImage = Rxn<File>();
@override
void onInit() {
super.onInit();
// 初始化网络管理器
initNetworkManager(LuminNetworkConfig(
baseUrl: 'https://api.example.com',
connectTimeout: const Duration(seconds: 30),
receiveTimeout: const Duration(seconds: 30),
));
}
// 选择图片
Future<void> pickImage() async {
try {
final XFile? image = await _imagePicker.pickImage(
source: ImageSource.gallery,
maxWidth: 1920,
maxHeight: 1080,
imageQuality: 85,
);
if (image != null) {
selectedImage.value = File(image.path);
uploadProgress.value = 0.0;
uploadedImageUrl.value = '';
}
} catch (e) {
Get.snackbar('错误', '选择图片失败: $e');
}
}
// 上传图片
Future<void> uploadImage() async {
if (selectedImage.value == null) {
Get.snackbar('提示', '请先选择图片');
return;
}
try {
// 创建FormData
FormData formData = FormData.fromMap({
'file': await MultipartFile.fromFile(
selectedImage.value!.path,
filename: 'image_${DateTime.now().millisecondsSinceEpoch}.jpg',
),
'type': 'image',
'description': '用户上传的图片',
});
// 执行上传请求
await executeRequest<Map<String, dynamic>>(
() => networkManager.upload(
'/api/upload/image',
formData,
onSendProgress: (sent, total) {
uploadProgress.value = sent / total;
},
),
onSuccess: (response) {
if (response.data != null && response.data!['url'] != null) {
uploadedImageUrl.value = response.data!['url'];
Get.snackbar('成功', '图片上传成功');
}
},
onError: (error) {
uploadProgress.value = 0.0;
Get.snackbar('错误', '上传失败: ${error.message}');
},
showLoading: true,
loadingText: '正在上传图片...',
);
} catch (e) {
uploadProgress.value = 0.0;
Get.snackbar('错误', '上传异常: $e');
}
}
// 多张图片上传
Future<void> uploadMultipleImages() async {
try {
final List<XFile> images = await _imagePicker.pickMultiImage(
maxWidth: 1920,
maxHeight: 1080,
imageQuality: 85,
);
if (images.isEmpty) return;
List<Future<LuminResponse<Map<String, dynamic>>>> uploadTasks = [];
for (int i = 0; i < images.length; i++) {
FormData formData = FormData.fromMap({
'file': await MultipartFile.fromFile(
images[i].path,
filename: 'image_${i}_${DateTime.now().millisecondsSinceEpoch}.jpg',
),
'type': 'image',
'batch_id': DateTime.now().millisecondsSinceEpoch.toString(),
});
uploadTasks.add(networkManager.upload('/api/upload/batch', formData));
}
// 并发上传多张图片
await executeMultipleRequests(
uploadTasks,
onSuccess: (responses) {
int successCount = responses.where((r) => r.isSuccess).length;
Get.snackbar('完成', '成功上传 $successCount/${images.length} 张图片');
},
onError: (error) {
Get.snackbar('错误', '批量上传失败: ${error.message}');
},
showLoading: true,
loadingText: '正在批量上传图片...',
);
} catch (e) {
Get.snackbar('错误', '批量上传异常: $e');
}
}
}
// 文件下载
LuminResponse<ResponseBody> response = await networkManager.download(
'/api/download/file.pdf',
savePath: '/path/to/save/file.pdf',
onReceiveProgress: (received, total) {
print('下载进度: ${(received / total * 100).toStringAsFixed(1)}%');
},
);
网络混入 (LuminNetworkMixin)
为了简化网络请求的使用,Lumin UI 提供了网络混入类:
class ApiController extends GetxController with LuminNetworkMixin {
@override
void onInit() {
super.onInit();
// 初始化网络管理器
initNetworkManager(LuminNetworkConfig(
baseUrl: 'https://api.example.com',
));
}
// 获取用户列表
Future<void> getUserList() async {
await executeRequest<List<Map<String, dynamic>>>(
() => networkManager.get('/api/users'),
onSuccess: (response) {
// 处理成功响应
print('用户列表: ${response.data}');
},
onError: (error) {
// 处理错误
Get.snackbar('错误', error.message);
},
showLoading: true,
loadingText: '正在加载用户列表...',
);
}
// 创建用户
Future<void> createUser(Map<String, dynamic> userData) async {
await executeRequest<Map<String, dynamic>>(
() => networkManager.post('/api/users', data: userData),
onSuccess: (response) {
Get.snackbar('成功', '用户创建成功');
getUserList(); // 刷新列表
},
onError: (error) {
Get.snackbar('错误', '创建失败: ${error.message}');
},
showLoading: true,
loadingText: '正在创建用户...',
);
}
// 批量请求
Future<void> loadDashboardData() async {
await executeMultipleRequests([
networkManager.get('/api/users/count'),
networkManager.get('/api/orders/count'),
networkManager.get('/api/revenue/today'),
],
onSuccess: (responses) {
// 处理所有响应
final userCount = responses[0].data;
final orderCount = responses[1].data;
final todayRevenue = responses[2].data;
print('仪表板数据加载完成');
},
onError: (error) {
Get.snackbar('错误', '数据加载失败: ${error.message}');
},
showLoading: true,
loadingText: '正在加载仪表板数据...',
);
}
}
响应模型
// 统一响应模型
class LuminResponse<T> {
final bool isSuccess;
final int statusCode;
final String message;
final T? data;
final Map<String, dynamic>? headers;
final dynamic originalResponse;
LuminResponse({
required this.isSuccess,
required this.statusCode,
required this.message,
this.data,
this.headers,
this.originalResponse,
});
// 成功响应
factory LuminResponse.success({
required T data,
int statusCode = 200,
String message = 'Success',
Map<String, dynamic>? headers,
dynamic originalResponse,
}) {
return LuminResponse<T>(
isSuccess: true,
statusCode: statusCode,
message: message,
data: data,
headers: headers,
originalResponse: originalResponse,
);
}
// 错误响应
factory LuminResponse.error({
required String message,
int statusCode = 500,
Map<String, dynamic>? headers,
dynamic originalResponse,
}) {
return LuminResponse<T>(
isSuccess: false,
statusCode: statusCode,
message: message,
headers: headers,
originalResponse: originalResponse,
);
}
}
贡献 #
欢迎提交 Issue 和 Pull Request 来帮助改进这个项目。
许可证 #
MIT License