diff --git a/assets/images/income_bg.png b/assets/images/income_bg.png new file mode 100644 index 0000000..a8616e4 Binary files /dev/null and b/assets/images/income_bg.png differ diff --git a/assets/images/merchant/income_bg.png b/assets/images/merchant/income_bg.png new file mode 100644 index 0000000..6f89da2 Binary files /dev/null and b/assets/images/merchant/income_bg.png differ diff --git a/lib/api/shop_api.dart b/lib/api/shop_api.dart index 7a6c987..36f8845 100644 --- a/lib/api/shop_api.dart +++ b/lib/api/shop_api.dart @@ -27,4 +27,13 @@ class ShopApi { // 取消订单 static const String cancelGoodsOrder= '/app/order/cancel'; + // app端我的订单 + static const String myOrderList= '/oms/order/list'; + + // 商家营收摘要 + static const String revenueInfo= '/app/merchant/account/statistic'; + + // 商家营收分页 + static const String revenueList= '/app/merchant/account/bill/page'; + } diff --git a/lib/pages/my/all_function.dart b/lib/pages/my/all_function.dart new file mode 100644 index 0000000..210a2fa --- /dev/null +++ b/lib/pages/my/all_function.dart @@ -0,0 +1,219 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +class AllFunctionsPage extends StatefulWidget { + const AllFunctionsPage({super.key}); + + @override + State createState() => _AllFunctionsPageState(); +} + +class _AllFunctionsPageState extends State { + // 功能数据列表 - 添加唯一ID + final List> functionList = [ + { + 'title': '主页展示', + 'items': [ + {'id': 'home_order', 'icon': 'assets/images/ico_order.png', 'label': '订单'}, + {'id': 'home_balance', 'icon': 'assets/images/ico_dhx.png', 'label': '余额logout'}, + {'id': 'home_withdraw', 'icon': 'assets/images/ico_sh.png', 'label': '提现vloger'}, + {'id': 'home_promo', 'icon': 'assets/images/ico_tgm.png', 'label': '推广码'}, + ] + }, + { + 'title': '更多功能', + 'items': [ + {'id': 'more_seller_order', 'icon': 'assets/images/ico_order.png', 'label': '商家订单'}, + {'id': 'more_seller_income', 'icon': 'assets/images/ico_sh.png', 'label': '商家营收'}, + ] + }, + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF0F0F0F), + appBar: AppBar( + backgroundColor: const Color(0xFF1A1A1A), + elevation: 0, + centerTitle: true, + title: const Text( + '全部功能', + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w600, + ), + ), + leading: IconButton( + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () => Navigator.pop(context), + ), + ), + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color(0xFF1A1A1A), + Color(0xFF0F0F0F), + ], + ), + ), + child: ListView.builder( + padding: const EdgeInsets.symmetric(vertical: 12), + itemCount: functionList.length, + itemBuilder: (context, sectionIndex) { + final section = functionList[sectionIndex]; + return _buildSection(section); + }, + ), + ), + ); + } + + Widget _buildSection(Map section) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + // 分区标题 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), + child: Text( + section['title'], + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Colors.white70, + ), + ), + ), + + // 功能项网格 + GridView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: const EdgeInsets.symmetric(horizontal: 16), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + crossAxisSpacing: 12, + mainAxisSpacing: 16, + childAspectRatio: 0.85, + ), + itemCount: (section['items'] as List).length, + itemBuilder: (context, index) { + final item = (section['items'] as List)[index]; + return _buildFunctionItem(item); + }, + ), + + // 分隔线 - 只在不是最后一个section时显示 + if (functionList.indexOf(section) != functionList.length - 1) + Container( + height: 2, + margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 20), + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + Color.fromRGBO(128, 128, 128, 0.3), + Color.fromRGBO(158, 158, 158, 0.1), + Color.fromRGBO(128, 128, 128, 0.3), + ], + ), + ), + ), + ], + ); + } + + Widget _buildFunctionItem(Map item) { + return GestureDetector( + onTap: () { + _handleFunctionTap(item['id']); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 36, + height: 36, + child: Center( + child: Image.asset( + item['icon'], + width: 26, + height: 26, + color: Colors.white, + ), + ), + ), + const SizedBox(height: 4), + // 标签 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 1), + child: Text( + item['label'], + style: const TextStyle( + fontSize: 11, + color: Colors.white70, + fontWeight: FontWeight.w500, + ), + textAlign: TextAlign.center, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ); + } + + void _handleFunctionTap(String functionId) { + switch (functionId) { + case 'home_order': + Get.toNamed('/sellerOrder'); + break; + case 'home_balance': + showLogoutDialog(context); + break; + case 'home_withdraw': + Get.toNamed('/vloger'); + break; + case 'home_promo': + break; + case 'more_seller_order': + break; + case 'more_seller_income': + Get.toNamed('/merchant/income'); + break; + } + } + + // 退出登录弹窗 + void showLogoutDialog(BuildContext context) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: const Text('确认退出当前账号吗?', style: TextStyle(fontSize: 16.0)), + backgroundColor: Colors.white, + surfaceTintColor: Colors.white, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)), + elevation: 2.0, + actionsPadding: const EdgeInsets.all(15.0), + actions: [ + TextButton( + onPressed: () { + Get.back(); + }, + child: const Text('取消', style: TextStyle(color: Colors.black54)), + ), + TextButton(onPressed: ()=>{}, child: const Text('退出登录', style: TextStyle(color: Colors.red))), + ], + ); + }, + ); + } +} \ No newline at end of file diff --git a/lib/pages/my/index.dart b/lib/pages/my/index.dart index 825db97..34ccc2e 100644 --- a/lib/pages/my/index.dart +++ b/lib/pages/my/index.dart @@ -846,7 +846,9 @@ class MyPageState extends State with SingleTickerProviderStateMixin { ], ), ), - onTap: () {}, + onTap: () { + Get.toNamed('/functions'); + }, ), Padding( padding: const EdgeInsets.all(10.0), diff --git a/lib/pages/my/merchant/income.dart b/lib/pages/my/merchant/income.dart new file mode 100644 index 0000000..6fc1fb9 --- /dev/null +++ b/lib/pages/my/merchant/income.dart @@ -0,0 +1,465 @@ +import 'package:flutter/material.dart'; +import 'package:loopin/api/shop_api.dart'; +import 'package:loopin/service/http.dart'; +import '../../../behavior/custom_scroll_behavior.dart'; + +class SellerRevenue extends StatefulWidget { + const SellerRevenue({super.key}); + + @override + State createState() => _SellerRevenueState(); +} + +class _SellerRevenueState extends State { + // 分页内容 + int pageNum = 1; + final int pageSize = 10; + bool isLoadingMore = false; + bool isRefreshing = false; + List> revenueList = []; + int totalRecords = 0; // 添加总记录数 + + // 营收统计数据 + double totalRevenue = 1000.00; + double pendingCount = 17; + double settledCount = 30; + + late ScrollController scrollController = ScrollController(); + + @override + void initState() { + super.initState(); + // 监听滚动事件 + scrollController.addListener(_scrollListener); + // 获取营收摘要 + getRevenueInfo(); + // 获取初始流水列表 + getRevenueList(false); + } + + @override + void dispose() { + scrollController.removeListener(_scrollListener); + scrollController.dispose(); + super.dispose(); + } + + // 滚动监听 + void _scrollListener() { + if (scrollController.position.pixels >= + scrollController.position.maxScrollExtent - 50 && // 添加一个阈值,提前加载 + !isLoadingMore && + !isRefreshing && + revenueList.isNotEmpty && + revenueList.length < totalRecords) { // 确保有数据且未加载完所有数据时才加载更多 + + getRevenueList(true); + } + } + + // 获取营收摘要 + void getRevenueInfo() async { + try { + final res = await Http.post(ShopApi.revenueList, data: {}); + + if (res['code'] == 200 && res['data'] != null) { + final data = res['data']; + totalRevenue = data['moneyIn'] ?? 0.00; + pendingCount = data['credited']?? 0.00; + settledCount = data['pending'] ?? 0.00; + } + } catch (e) { + print('获取营收摘要: $e'); + } + } + + // 获取流水列表 + void getRevenueList(bool loadMore) async { + if (isLoadingMore || isRefreshing) return; + + setState(() { + if (!loadMore) { + pageNum = 1; // 重置为第一页 + isRefreshing = true; + revenueList = []; + totalRecords = 0; // 重置总记录数 + } else { + isLoadingMore = true; + } + }); + + try { + final res = await Http.post(ShopApi.revenueList, data: { + 'current': pageNum, // 当前页码 + 'size': pageSize, + }); + + if (res['code'] == 200 && res['data'] != null) { + final data = res['data']; + final List> newRevenues = List>.from(data['records'] ?? []); + final int total = data['total']; + debugPrint(data.toString(), wrapWidth: 1024); + setState(() { + if (loadMore) { + revenueList.addAll(newRevenues); + } else { + revenueList = newRevenues; + } + + totalRecords = total; + if (newRevenues.isNotEmpty && revenueList.length < total) { + pageNum++; // 增加页码 + isLoadingMore = false; // 重置加载状态,允许再次加载 + } else { + isLoadingMore = false; // 没有更多数据 + } + + isRefreshing = false; + }); + } + } catch (e) { + print('获取营收列表失败: $e'); + setState(() { + isLoadingMore = false; + isRefreshing = false; + }); + } + } + + // 刷新数据时重置分页状态 + void _refreshData() { + setState(() { + pageNum = 1; + isLoadingMore = false; + totalRecords = 0; + }); + getRevenueList(false); + } + + // 构建营收项 + Widget _buildRevenueItem(Map revenue) { + return Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // 第一列:用户 + Expanded( + flex: 1, + child: Text( + revenue['changeDesc']??'未知', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.black, + ), + overflow: TextOverflow.ellipsis, + ), + ), + // 第二列:流水明细 + Expanded( + flex: 1, + child: Text( + '${revenue['changeType'] == '1' ? '+' : '-'}${revenue['changeAmount']}', + style: TextStyle( + fontSize: 14, + color: revenue['changeType'] == '1' ? Colors.red : Colors.green, + ), + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + ), + ), + // 第三列:流水日期 + Expanded( + flex: 1, + child: Text( + revenue['createTime'] ?? '日期', + style: TextStyle( + fontSize: 12, + color: Colors.black, + ), + textAlign: TextAlign.right, + ), + ), + ], + ), + ); + } + + // 构建顶部营收面板 + Widget _buildRevenuePanel() { + return Container( + margin: EdgeInsets.symmetric(horizontal: 12.0), + padding: EdgeInsets.all(20), + decoration: BoxDecoration( + color: Color(0xFF4477FC), + borderRadius: BorderRadius.circular(6), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(15), + blurRadius: 10, + offset: Offset(0, 2), + ), + ], + ), + child: Column( + children: [ + // 总入账 + Text( + '总入账', + style: TextStyle( + fontSize: 14, + color: Colors.white, + ), + ), + SizedBox(height: 8), + Text( + '¥$totalRevenue', + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + SizedBox(height: 20), + // 待入账和已入账 + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Column( + children: [ + Text( + '待入账', + style: TextStyle( + fontSize: 14, + color: Colors.white, + ), + ), + SizedBox(height: 4), + Text( + '$pendingCount', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ], + ), + Container( + width: 1, + height: 30, + color: Colors.white, + ), + Column( + children: [ + Text( + '已入账', + style: TextStyle( + fontSize: 14, + color: Colors.white, + ), + ), + SizedBox(height: 4), + Text( + '$settledCount', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ], + ), + ], + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor:Color(0xFFF8F8F8), + body: Stack( + children: [ + // 背景图片 - 从顶部开始 + Positioned.fill( + child: Image.asset( + 'assets/images/income_bg.png', + fit: BoxFit.contain, + alignment: Alignment.topCenter, + ), + ), + // 主要内容区域 + Column( + children: [ + // AppBar区域 + Container( + height: kToolbarHeight + MediaQuery.of(context).padding.top, + child: AppBar( + title: Text( + '商家营收', + style: TextStyle( + fontSize: 18, + color: Colors.white, + ), + ), + centerTitle: true, + backgroundColor: Colors.transparent, + elevation: 0, + iconTheme: IconThemeData(color: Colors.white), + ), + ), + // 营收面板 + SizedBox(height: 10), + _buildRevenuePanel(), + SizedBox(height: 10), + // 流水明细 + Expanded( + child: Container( + color: Colors.white, + margin: EdgeInsets.symmetric(horizontal: 12.0), + child: Column( + children: [ + // 流水明细标题 + Container( + padding: EdgeInsets.only( + left: 12.0, + right: 12.0, + top: 10.0, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 1, + child: Text( + '来源', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + ), + Expanded( + flex: 1, + child: Text( + '流水明细', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + textAlign: TextAlign.center, + ), + ), + Expanded( + flex: 1, + child: Text( + '流水日期', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + textAlign: TextAlign.right, + ), + ), + ], + ), + ), + SizedBox(height: 10), + // 流水列表区域 + Expanded( + child: Container( + margin: EdgeInsets.symmetric(horizontal: 12.0), + child: RefreshIndicator( + onRefresh: () async { + _refreshData(); + }, + child: ScrollConfiguration( + behavior: CustomScrollBehavior().copyWith(scrollbars: false), + child: revenueList.isEmpty && !isRefreshing + ? emptyTip() + : Container( + child: ListView.builder( + padding: EdgeInsets.zero, + controller: scrollController, + physics: AlwaysScrollableScrollPhysics(), + itemCount: revenueList.length + (isLoadingMore ? 1 : 0), + itemBuilder: (context, index) { + if (index == revenueList.length) { + return _buildLoadMoreIndicator(); + } + return _buildRevenueItem(revenueList[index]); + }, + ), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ], + ), + ], + ), + ); + } + + // 加载更多指示器 + Widget _buildLoadMoreIndicator() { + return Padding( + padding: EdgeInsets.symmetric(vertical: 15.0), + child: Center( + child: isLoadingMore + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ), + SizedBox(width: 10), + Text('加载中...', style: TextStyle(color: Colors.grey)), + ], + ) + : revenueList.length >= totalRecords + ? Text('没有更多数据了', style: TextStyle(color: Colors.grey)) + : SizedBox(), // 如果还有数据但不在加载中,不显示任何内容 + ), + ); + } + + Widget emptyTip() { + return Container( + width: double.infinity, + padding: EdgeInsets.all(12.0), + color: Colors.white, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/empty.png', + width: 100.0, + errorBuilder: (context, error, stackTrace) { + return Icon(Icons.receipt_long, size: 60, color: Colors.grey); + }, + ), + SizedBox(height: 10), + Text( + '还没有营收记录~', + style: TextStyle(color: Colors.grey, fontSize: 12.0), + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/my/merchant/order.dart b/lib/pages/my/merchant/order.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/pages/order/seller.dart b/lib/pages/order/seller.dart index c3e764c..1b7c183 100644 --- a/lib/pages/order/seller.dart +++ b/lib/pages/order/seller.dart @@ -3,6 +3,8 @@ library; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:loopin/api/shop_api.dart'; +import 'package:loopin/service/http.dart'; import '../../behavior/custom_scroll_behavior.dart'; @@ -15,47 +17,379 @@ class Seller extends StatefulWidget { class _SellerState extends State with SingleTickerProviderStateMixin { GlobalKey scaffoldKey = GlobalKey(); + // 分页内容 + int pageNum = 1; + final int pageSize = 10; + bool isLoadingMore = false; + bool isRefreshing = false; + List> pageOrderList = []; List tabList = [ - {'name': "全部"}, - {'name': "已退款", 'badge': 1}, - {'name': "待核销", 'badge': 1}, - {'name': "已完成"}, - {'name': "取消"} + {'id': 0, 'name': "全部"}, // 0表示全部 + {'id': 4, 'name': "已退款", 'badge': 1}, // 4对应已退款 + {'id': 2, 'name': "待核销", 'badge': 1}, // 2对待核销 + {'id': 3, 'name': "已完成"}, // 3对已完成 + {'id': 5, 'name': "取消"} // 5对取消 ]; late ScrollController scrollController = ScrollController(); late TabController tabController = TabController(initialIndex: 0, length: tabList.length, vsync: this); - Widget emptyTip() { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - spacing: 5.0, - children: [ - Image.asset( - 'assets/images/empty.png', - width: 100.0, - ), - Text( - '还没有相关订单~', - style: TextStyle(color: Colors.grey, fontSize: 12.0), - ) - ], - ); - } - @override void initState() { super.initState(); + // 监听滚动事件 + scrollController.addListener(_scrollListener); + // 监听tab切换事件 + tabController.addListener(_tabChanged); + // 获取初始订单列表 + getOrderList(false); } @override void dispose() { + scrollController.removeListener(_scrollListener); scrollController.dispose(); + tabController.removeListener(_tabChanged); tabController.dispose(); super.dispose(); } + // 滚动监听 + 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> newOrders = List>.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 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((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() { + // 删除订单逻辑 + } + @override Widget build(BuildContext context) { return Scaffold( @@ -111,478 +445,79 @@ class _SellerState extends State with SingleTickerProviderStateMixin { ]), ), ), - body: ScrollConfiguration( - behavior: CustomScrollBehavior().copyWith(scrollbars: false), - child: Container( - color: Colors.grey[50], - child: TabBarView( - controller: tabController, - children: [ - ListView( - controller: scrollController, - physics: BouncingScrollPhysics(), - padding: EdgeInsets.all(10.0), - children: [ - 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( - spacing: 10.0, - children: [ - Row( - children: [ - Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - spacing: 5.0, - children: [ - ClipOval( - child: Image.asset( - 'assets/images/avatar/img11.jpg', - width: 25.0, - ), - ), - Text('人人乐超市'), - Icon( - Icons.arrow_forward_ios_rounded, - color: Colors.grey, - size: 12.0, - ), - ], - ), - Spacer(), - Text( - '待付款', - style: TextStyle(color: Colors.red), - ) - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 10.0, - children: [ - Image.network( - 'https://img13.360buyimg.com/n1/jfs/t1/263909/5/4187/123220/676eb220F3e481086/0cee829b1894fc4c.jpg', - width: 80.0, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 5.0, - children: [ - Text( - '茅台(MOUTAI)飞天 53度 酱香型白酒 500ml*2 海外版送礼袋年货送礼', - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - Row( - children: [ - Text( - '¥3800', - style: TextStyle(color: Colors.red), - ), - Spacer(), - Text( - 'x10', - style: TextStyle(color: Colors.grey), - ), - ], - ), - ], - ), - ) - ], - ), - // 提示信息 - 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: '¥38000', - style: TextStyle(color: Colors.red), - ), - ]), - ), - ], - ), - ), - // 按钮组 - Row( - spacing: 10.0, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('取消订单'), - ), - ElevatedButton( - onPressed: () {}, - style: ButtonStyle( - backgroundColor: WidgetStateProperty.all(Color(0xff07c160)), foregroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('去支付'), - ), - ], - ), - Row( - spacing: 10.0, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - ElevatedButton( - onPressed: () {}, - style: ButtonStyle( - backgroundColor: WidgetStateProperty.all(Color(0xFF10B9FC)), foregroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('评价'), - ), - ], - ), - Row( - spacing: 10.0, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('申请退款'), - ), - ElevatedButton( - onPressed: () {}, - style: ButtonStyle( - backgroundColor: WidgetStateProperty.all(Color(0xFFFCBE13)), foregroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('联系客服'), - ), - ], - ), - - Row( - spacing: 10.0, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('删除'), - ), - ], - ), - ], + 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]); + }, ), - ), - onTap: () { - Get.toNamed('/order/detail'); - }, - ), - ], ), - emptyTip(), - hexiao(), - finish(), - emptyTip(), - emptyTip(), - ], - ), - ), + ), + ); + }), ), ); } -} -Widget finish() { - return ListView( - physics: BouncingScrollPhysics(), - padding: EdgeInsets.all(10.0), - children: [ - 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( - spacing: 10.0, - children: [ - Row( + // 加载更多指示器 + Widget _buildLoadMoreIndicator() { + return Padding( + padding: EdgeInsets.symmetric(vertical: 15.0), + child: Center( + child: isLoadingMore + ? Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ - Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - spacing: 5.0, - children: [ - ClipOval( - child: Image.asset( - 'assets/images/avatar/img12.jpg', - width: 25.0, - ), - ), - Text('人人乐超市'), - Icon( - Icons.arrow_forward_ios_rounded, - color: Colors.grey, - size: 12.0, - ), - ], + SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(strokeWidth: 2), ), - Spacer(), - Text( - '已完成', - style: TextStyle(color: Colors.red), - ) + SizedBox(width: 10), + Text('加载中...', style: TextStyle(color: Colors.grey)), ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 10.0, - children: [ - Image.network( - 'https://img13.360buyimg.com/n1/jfs/t1/263909/5/4187/123220/676eb220F3e481086/0cee829b1894fc4c.jpg', - width: 80.0, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 5.0, - children: [ - Text( - '茅台(MOUTAI)飞天 53度 酱香型白酒 500ml 海外版送礼袋年货送礼', - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - Row( - children: [ - Text( - '¥1900', - style: TextStyle(color: Colors.red), - ), - ], - ), - ], - ), - ) - ], - ), - // 提示信息 - Container( - padding: EdgeInsets.all(5.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5.0), - ), - child: Row( - children: [ - Spacer(), - Text.rich( - TextSpan(children: [ - TextSpan(text: '实付款: '), - TextSpan( - text: '¥1880', - style: TextStyle(color: Colors.red), - ), - ]), - ), - ], - ), - ), - ], - ), - ), - onTap: () { - Get.toNamed('/order/detail'); - }, + ) + : Text('没有更多数据了', style: TextStyle(color: Colors.grey)), ), - ], - ); -} + ); + } -Widget hexiao() { - return ListView( - physics: BouncingScrollPhysics(), - padding: EdgeInsets.all(10.0), - children: [ - 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( - spacing: 10.0, - children: [ - Row( - children: [ - Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - spacing: 5.0, - children: [ - ClipOval( - child: Image.asset( - 'assets/images/avatar/img11.jpg', - width: 25.0, - ), - ), - Text('老白干自营旗舰店'), - Icon( - Icons.arrow_forward_ios_rounded, - color: Colors.grey, - size: 12.0, - ), - ], - ), - Spacer(), - Text( - '待付款', - style: TextStyle(color: Colors.red), - ) - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 10.0, - children: [ - Image.network( - 'https://img13.360buyimg.com/n1/jfs/t1/263909/5/4187/123220/676eb220F3e481086/0cee829b1894fc4c.jpg', - width: 80.0, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 5.0, - children: [ - Text( - '茅台(MOUTAI)飞天 53度 酱香型白酒 500ml*2 海外版送礼袋年货送礼', - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - Row( - children: [ - Text( - '¥3800', - style: TextStyle(color: Colors.red), - ), - Spacer(), - Text( - 'x10', - style: TextStyle(color: Colors.grey), - ), - ], - ), - ], - ), - ) - ], - ), - // 提示信息 - 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: '¥38000', - style: TextStyle(color: Colors.red), - ), - ]), - ), - ], - ), - ), - // 按钮组 - Row( - spacing: 10.0, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('取消订单'), - ), - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Color(0xff07c160)), foregroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('去支付'), - ), - ], - ), - Row( - spacing: 10.0, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Color(0xFF10B9FC)), foregroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('评价'), - ), - ], - ), - Row( - spacing: 10.0, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('申请退款'), - ), - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Color(0xFFFCBE13)), foregroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('联系客服'), - ), - ], - ), - - Row( - spacing: 10.0, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - ElevatedButton( - onPressed: () {}, - style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.white)), - child: Text('删除'), - ), - ], - ), - ], + Widget emptyTip() { + return Container( + width: double.infinity, // 覆盖整个页面宽度 + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/empty.png', + width: 100.0, ), - ), - onTap: () { - Get.toNamed('/order/detail'); - }, + SizedBox(height: 10), + Text( + '还没有相关订单~', + style: TextStyle(color: Colors.grey, fontSize: 12.0), + ) + ], ), - ], - ); -} + ); + } +} \ No newline at end of file diff --git a/lib/router/index.dart b/lib/router/index.dart index 920cfb2..dae93df 100644 --- a/lib/router/index.dart +++ b/lib/router/index.dart @@ -20,6 +20,9 @@ import 'package:loopin/pages/my/nick_name.dart'; import 'package:loopin/pages/my/setting.dart'; import 'package:loopin/pages/my/user_info.dart'; import 'package:loopin/pages/my/vloger.dart'; +import 'package:loopin/pages/my/all_function.dart'; +import 'package:loopin/pages/my/merchant/income.dart'; +import 'package:loopin/pages/my/merchant/order.dart'; import 'package:loopin/pages/order/seller.dart'; import 'package:loopin/pages/search/index.dart'; import 'package:loopin/pages/search/search-result.dart'; @@ -53,6 +56,9 @@ final Map routes = { '/search-result': const SearchResultPage(), //settins '/setting': const Setting(), + '/functions': const AllFunctionsPage(), + '/merchant/income': const SellerRevenue(), + //'/merchant/order': const SellerRevenue(), '/userInfo': const UserInfo(), '/notifications': const Setting(), '/privacy': const Setting(),