flutter/lib/pages/order/seller.dart

523 lines
16 KiB
Dart
Raw Normal View History

2025-09-06 14:57:47 +08:00
/// 商家的订单
library;
import 'package:flutter/material.dart';
import 'package:get/get.dart';
2025-09-11 16:42:35 +08:00
import 'package:loopin/api/shop_api.dart';
import 'package:loopin/service/http.dart';
2025-09-06 14:57:47 +08:00
import '../../behavior/custom_scroll_behavior.dart';
class Seller extends StatefulWidget {
const Seller({super.key});
@override
State<Seller> createState() => _SellerState();
}
class _SellerState extends State<Seller> with SingleTickerProviderStateMixin {
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
2025-09-11 16:42:35 +08:00
// 分页内容
int pageNum = 1;
final int pageSize = 10;
bool isLoadingMore = false;
bool isRefreshing = false;
List<Map<String, dynamic>> pageOrderList = [];
2025-09-06 14:57:47 +08:00
List tabList = [
2025-09-11 16:42:35 +08:00
{'id': 0, 'name': "全部"}, // 0表示全部
{'id': 4, 'name': "已退款", 'badge': 1}, // 4对应已退款
{'id': 2, 'name': "待核销", 'badge': 1}, // 2对待核销
{'id': 3, 'name': "已完成"}, // 3对已完成
{'id': 5, 'name': "取消"} // 5对取消
2025-09-06 14:57:47 +08:00
];
late ScrollController scrollController = ScrollController();
late TabController tabController = TabController(initialIndex: 0, length: tabList.length, vsync: this);
@override
void initState() {
super.initState();
2025-09-11 16:42:35 +08:00
// 监听滚动事件
scrollController.addListener(_scrollListener);
// 监听tab切换事件
tabController.addListener(_tabChanged);
// 获取初始订单列表
getOrderList(false);
2025-09-06 14:57:47 +08:00
}
@override
void dispose() {
2025-09-11 16:42:35 +08:00
scrollController.removeListener(_scrollListener);
2025-09-06 14:57:47 +08:00
scrollController.dispose();
2025-09-11 16:42:35 +08:00
tabController.removeListener(_tabChanged);
2025-09-06 14:57:47 +08:00
tabController.dispose();
super.dispose();
}
2025-09-11 16:42:35 +08:00
// 滚动监听
void _scrollListener() {
if (scrollController.position.pixels == scrollController.position.maxScrollExtent && !isLoadingMore) {
getOrderList(true);
}
}
// Tab切换监听
void _tabChanged() {
if (tabController.indexIsChanging) {
// 切换tab时重新加载数据
getOrderList(false);
}
}
// 获取订单列表
void getOrderList(bool loadMore) async {
if (isLoadingMore || isRefreshing) return;
setState(() {
if (!loadMore) {
pageNum = 1; // 重置为第一页
isRefreshing = true;
pageOrderList = [];
} else {
isLoadingMore = true;
}
});
try {
final currentTab = tabList[tabController.index];
final status = currentTab['id'];
final res = await Http.post(ShopApi.myOrderList, data: {
'current': pageNum, // 当前页码
'size': pageSize,
// 'orderStatus': status == 0 ? '' : status.toString(), // 0表示全部传空字符串
});
if (res['code'] == 200 && res['data'] != null) {
final data = res['data'];
final List<Map<String, dynamic>> newOrders = List<Map<String, dynamic>>.from(data['records'] ?? []);
final int total = data['total'] ?? 0;
final int currentPage = data['current'] ?? 1;
final int pages = data['pages'] ?? 1;
setState(() {
if (loadMore) {
pageOrderList.addAll(newOrders);
} else {
pageOrderList = newOrders;
}
// 分页逻辑
if (newOrders.isNotEmpty && currentPage < pages) {
pageNum = currentPage + 1; // 下一页
isLoadingMore = true;
} else {
isLoadingMore = false; // 没有更多数据
}
});
}
} catch (e) {
print('获取订单列表失败: $e');
setState(() {
isLoadingMore = false;
});
} finally {
setState(() {
isRefreshing = false;
});
}
}
// 刷新数据时重置分页状态
void _refreshData() {
setState(() {
pageNum = 1;
isLoadingMore = false;
});
getOrderList(false);
}
// 构建订单项Widget
Widget _buildOrderItem(Map<String, dynamic> order) {
return GestureDetector(
child: Container(
margin: EdgeInsets.only(bottom: 10.0),
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15.0),
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(10),
offset: Offset(0.0, 1.0),
blurRadius: 1.0,
spreadRadius: 0.0,
),
],
),
child: Column(
children: [
Row(
children: [
Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 5.0,
children: [
ClipOval(
child: Image.asset(
'assets/images/avatar/img11.jpg',
width: 25.0,
),
),
Text(order['shopName'] ?? '商家名称'),
Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.grey,
size: 12.0,
),
],
),
Spacer(),
Text(
_getStatusText(order['status']),
style: TextStyle(color: _getStatusColor(order['status'])),
)
],
),
SizedBox(height: 10),
// 商品信息
if (order['items'] != null && order['items'].isNotEmpty)
...order['items'].map<Widget>((item) => Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(4.0),
),
child: item['image'] != null && item['image'].isNotEmpty
? Image.network(
item['image'],
width: 80.0,
height: 80.0,
fit: BoxFit.cover,
)
: Icon(
Icons.shopping_bag_outlined,
size: 40.0,
color: Colors.grey[400],
),
),
SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item['productName'] ?? '商品名称',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14),
),
SizedBox(height: 5),
Row(
children: [
Text(
'¥${item['price'] ?? '0'}',
style: TextStyle(color: Colors.red, fontSize: 16),
),
Spacer(),
Text(
'x${item['quantity'] ?? '1'}',
style: TextStyle(color: Colors.grey),
),
],
),
],
),
)
],
)).toList(),
SizedBox(height: 10),
// 金额信息
Container(
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(5.0),
),
child: Row(
children: [
Spacer(),
Text.rich(
TextSpan(children: [
TextSpan(text: '实付款: '),
TextSpan(
text: '¥${order['totalAmount'] ?? '0'}',
style: TextStyle(color: Colors.red, fontSize: 16),
),
]),
),
],
),
),
SizedBox(height: 10),
// 根据状态显示不同的按钮
_buildActionButtons(order['status']),
],
),
),
onTap: () {
Get.toNamed('/order/detail', arguments: {'orderId': order['id']});
},
);
}
// 获取状态文本
String _getStatusText(dynamic status) {
// 处理字符串或数字类型的状态
int statusCode = status is String ? int.tryParse(status) ?? 0 : (status is int ? status : 0);
switch (statusCode) {
case 1:
return '待付款';
case 2:
return '待核销';
case 3:
return '已完成';
case 4:
return '已退款';
case 5:
return '已取消';
default:
return '未知状态';
}
}
// 获取状态颜色
Color _getStatusColor(dynamic status) {
int statusCode = status is String ? int.tryParse(status) ?? 0 : (status is int ? status : 0);
switch (statusCode) {
case 1:
return Colors.orange;
case 2:
return Colors.blue;
case 3:
return Colors.green;
case 4:
return Colors.red;
case 5:
return Colors.grey;
default:
return Colors.black;
}
}
// 构建操作按钮
Widget _buildActionButtons(dynamic status) {
// 处理字符串或数字类型的状态
int statusCode = status is String ? int.tryParse(status) ?? 0 : (status is int ? status : 0);
switch (statusCode) {
case 1: // 待付款
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () => _cancelOrder(),
style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.white)),
child: Text('取消订单'),
),
SizedBox(width: 10),
ElevatedButton(
onPressed: () => _payOrder(),
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Color(0xff07c160)),
foregroundColor: WidgetStateProperty.all(Colors.white),
),
child: Text('去支付'),
),
],
);
case 2: // 待核销
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () => _contactCustomerService(),
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Color(0xFFFCBE13)),
foregroundColor: WidgetStateProperty.all(Colors.white),
),
child: Text('联系客服'),
),
],
);
case 3: // 已完成
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () => _deleteOrder(),
style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.white)),
child: Text('删除订单'),
),
],
);
default:
return SizedBox.shrink();
}
}
// 订单操作的方法
void _cancelOrder() {
// 取消订单逻辑
}
void _payOrder() {
// 支付订单逻辑
}
void _contactCustomerService() {
// 联系客服逻辑
}
void _deleteOrder() {
// 删除订单逻辑
}
2025-09-06 14:57:47 +08:00
@override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
backgroundColor: Colors.white,
appBar: AppBar(
titleSpacing: 1.0,
title: Text(
'商家订单',
style: TextStyle(fontSize: 18),
),
bottom: PreferredSize(
preferredSize: Size.fromHeight(45.0),
child: Row(children: [
Expanded(
child: TabBar(
controller: tabController,
tabs: tabList
.map((item) => Container(
alignment: Alignment.center,
height: 45.0,
child: Badge.count(
backgroundColor: Colors.red,
offset: Offset(14, -4),
count: item['badge'] ?? 0,
isLabelVisible: item['badge'] != null ? true : false,
child: Text(
item['name'],
style: TextStyle(fontSize: 16),
overflow: TextOverflow.ellipsis,
softWrap: false,
),
),
))
.toList(),
isScrollable: false,
overlayColor: WidgetStateProperty.all(Colors.transparent),
unselectedLabelColor: Colors.black87,
labelColor: Color(0xFFFF5000),
indicator: UnderlineTabIndicator(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide(color: Color(0xFFFF5000), width: 2.0),
),
indicatorSize: TabBarIndicatorSize.tab,
unselectedLabelStyle: TextStyle(fontSize: 16.0, fontFamily: 'Microsoft YaHei'),
labelStyle: TextStyle(fontSize: 18.0, fontFamily: 'Microsoft YaHei', fontWeight: FontWeight.w700),
dividerHeight: 0,
padding: EdgeInsets.symmetric(horizontal: 10.0),
labelPadding: EdgeInsets.symmetric(horizontal: 10.0),
indicatorPadding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 5.0),
),
),
]),
),
),
2025-09-11 16:42:35 +08:00
body: TabBarView(
controller: tabController,
children: List.generate(tabList.length, (index) {
return RefreshIndicator(
onRefresh: () async {
_refreshData();
},
child: ScrollConfiguration(
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
child: Container(
color: Colors.grey[50],
child: pageOrderList.isEmpty && !isRefreshing
? emptyTip()
: ListView.builder(
controller: scrollController,
physics: AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.all(10.0),
itemCount: pageOrderList.length + (isLoadingMore ? 1 : 0),
itemBuilder: (context, index) {
if (index == pageOrderList.length) {
return _buildLoadMoreIndicator();
}
return _buildOrderItem(pageOrderList[index]);
},
2025-09-06 14:57:47 +08:00
),
),
2025-09-11 16:42:35 +08:00
),
);
}),
2025-09-06 14:57:47 +08:00
),
);
}
2025-09-11 16:42:35 +08:00
// 加载更多指示器
Widget _buildLoadMoreIndicator() {
return Padding(
padding: EdgeInsets.symmetric(vertical: 15.0),
child: Center(
child: isLoadingMore
? Row(
mainAxisAlignment: MainAxisAlignment.center,
2025-09-06 14:57:47 +08:00
children: [
2025-09-11 16:42:35 +08:00
SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
2025-09-06 14:57:47 +08:00
),
2025-09-11 16:42:35 +08:00
SizedBox(width: 10),
Text('加载中...', style: TextStyle(color: Colors.grey)),
2025-09-06 14:57:47 +08:00
],
2025-09-11 16:42:35 +08:00
)
: Text('没有更多数据了', style: TextStyle(color: Colors.grey)),
2025-09-06 14:57:47 +08:00
),
2025-09-11 16:42:35 +08:00
);
}
2025-09-06 14:57:47 +08:00
2025-09-11 16:42:35 +08:00
Widget emptyTip() {
return Container(
width: double.infinity, // 覆盖整个页面宽度
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/empty.png',
width: 100.0,
2025-09-06 14:57:47 +08:00
),
2025-09-11 16:42:35 +08:00
SizedBox(height: 10),
Text(
'还没有相关订单~',
style: TextStyle(color: Colors.grey, fontSize: 12.0),
)
],
2025-09-06 14:57:47 +08:00
),
2025-09-11 16:42:35 +08:00
);
}
}