flutter/lib/pages/order/seller_detail.dart
2025-09-13 16:14:27 +08:00

572 lines
18 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

library;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:loopin/service/http.dart';
import 'package:loopin/api/shop_api.dart';
import 'package:shirne_dialog/shirne_dialog.dart';
import 'package:loopin/components/my_toast.dart';
import '../../behavior/custom_scroll_behavior.dart';
class SellerOrderDetail extends StatefulWidget {
const SellerOrderDetail({super.key});
@override
State<SellerOrderDetail> createState() => _SellerOrderDetailState();
}
class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTickerProviderStateMixin {
late String ? _orderId;
late String ?_writeOffCodeId;
dynamic orderGoodsInfo;
bool _isLoading = true; // 添加加载状态
@override
void initState() {
super.initState();
_orderId = Get.arguments['orderId'] ?? ''; // 从商家订单列表进入此页面此时带着订单id
_writeOffCodeId = Get.arguments['writeOffCodeId'] ?? ''; // 从扫码核销进入此页面,此时带着核销码
if(_orderId != null){
getOrderDetailByOrderId(_orderId);
}else if(_writeOffCodeId != null){
getOrderDetailByWriteOffId(_writeOffCodeId);
}
}
@override
void dispose() {
super.dispose();
}
// 获取订单详情信息根据订单id
void getOrderDetailByOrderId(orderId) async {
try {
setState(() {
_isLoading = true;
});
final res = await Http.get('${ShopApi.goodsOrderDetail}/$orderId');
debugPrint(res['data'].toString(), wrapWidth: 600);
setState(() {
orderGoodsInfo = res['data'];
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
MyDialog.toast('获取订单详情失败');
}
}
// 获取订单详情信息,根据核销码
void getOrderDetailByWriteOffId(code) async {
try {
setState(() {
_isLoading = true;
});
final res = await Http.get('${ShopApi.getWriteOffDetail}?code=$code');
print('订单详情-------------->${res['data']}');
setState(() {
orderGoodsInfo = res['data'];
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
MyDialog.toast('获取订单详情失败');
}
}
// 确认核销订单
void _confirmVerifyCode () async {
late String writeOffCode;
if(_orderId != null){ // 商家可以直接从订单详情获取核销码,并过滤后进行核销
var verificationCodesList = orderGoodsInfo['verificationCodes'];
if (verificationCodesList != null && verificationCodesList.isNotEmpty) {
// 过滤可用的核销码status为0
List<dynamic> newVerifyList = verificationCodesList.where((item) => item['status'] == 0).toList();
if (newVerifyList.isNotEmpty) {
writeOffCode = newVerifyList[0]['code'] ?? '';
} else {
return MyToast().tip(
title: '暂无可用的核销码',
position: 'center',
type: 'error',
);
}
} else {
return MyToast().tip(
title: '暂无可用的核销码',
position: 'center',
type: 'error',
);
}
}else if(_writeOffCodeId != null){
writeOffCode = _writeOffCodeId?? '';
}
try {
final res = await Http.get('${ShopApi.confirmWriteOff}?code=$writeOffCode');
debugPrint(res['data'].toString(), wrapWidth: 600);
MyToast().tip(
title: '核销成功',
position: 'center',
type: 'error',
);
} catch (e) {
}
}
// 获取订单状态文本
String getOrderStatusText(int status) {
switch (status) {
case 0:
return '待付款';
case 1:
return '待核销';
case 2:
return '已完成';
case 3:
return '已关闭';
case 4:
return '退款中';
case 5:
return '已退款';
case 6:
return '已取消';
default:
return '未知状态';
}
}
// 获取订单状态颜色
Color getOrderStatusColor(int status) {
switch (status) {
case 0:
return Colors.grey;
case 1:
return Colors.blue;
case 2:
return Colors.green;
case 3:
return Colors.red;
case 4:
return Colors.orange;
case 5:
return Colors.grey;
case 6:
return Colors.grey;
default:
return Colors.black;
}
}
// 获取商品信息列表
List<dynamic> getProductInfoList() {
// 优先使用 items 字段
if (orderGoodsInfo?['items'] != null && orderGoodsInfo!['items'] is List) {
return orderGoodsInfo!['items'];
}
// 如果 items 为空,使用 productInfo 字段
if (orderGoodsInfo?['productInfo'] != null && orderGoodsInfo!['productInfo'] is List) {
return orderGoodsInfo!['productInfo'];
}
// 如果都为空,返回空列表
return [];
}
// 获取第一个商品信息
dynamic getFirstProductInfo() {
final productList = getProductInfoList();
return productList.isNotEmpty ? productList[0] : null;
}
// 构建商品图片
Widget _buildProductImage(dynamic productInfo) {
final picUrl = productInfo?['pic'];
if (picUrl == null || picUrl.isEmpty) {
return Container(
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8.0),
),
child: Icon(
Icons.shopping_bag_outlined,
size: 40.0,
color: Colors.grey[400],
),
);
}
return Image.network(
picUrl,
width: 80.0,
height: 80.0,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Container(
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8.0),
),
child: Icon(
Icons.shopping_bag_outlined,
size: 40.0,
color: Colors.grey[400],
),
);
},
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return Container(
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8.0),
),
child: Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
: null,
),
),
);
},
);
}
// 构建商品列表
Widget _buildProductList() {
final productList = getProductInfoList();
if (productList.isEmpty) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Text(
'暂无商品信息',
style: TextStyle(color: Colors.grey, fontSize: 14),
),
);
}
return Column(
children: productList.map((product) {
return Padding(
padding: const EdgeInsets.only(bottom: 12.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildProductImage(product),
SizedBox(width: 10.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product?['productName']?.toString() ?? '未知商品',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14),
),
SizedBox(height: 8),
Row(
children: [
Text(
'¥${product?['salePrice']?.toString() ?? '0.00'}',
style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),
),
Spacer(),
Text(
'x${product?['buyNum']?.toString() ?? '1'}',
style: TextStyle(color: Colors.grey),
),
],
),
],
),
)
],
),
);
}).toList(),
);
}
// 构建底部按钮
Widget buildBottomButtons() {
if (orderGoodsInfo == null) return SizedBox.shrink();
int orderStatus = orderGoodsInfo?['status'] ?? 0;
switch (orderStatus) {
case 0: // 待付款
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [],
);
case 1: // 待核销
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const SizedBox(width: 10.0),
ElevatedButton(
onPressed: () {
_confirmVerifyCode();
},
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Color(0xFFFF5000)),
foregroundColor: WidgetStateProperty.all(Colors.white),
),
child: const Text('确认核销'),
),
],
);
case 2: // 已完成
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [],
);
case 3: // 已关闭
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [],
);
case 4: // 退款中
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [],
);
case 5: // 已退款
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [],
);
case 6: // 已取消
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [],
);
default:
return SizedBox.shrink();
}
}
Widget emptyTip() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/empty.png',
width: 100.0,
),
SizedBox(height: 16),
Text(
'还没有订单信息~',
style: TextStyle(color: Colors.grey, fontSize: 12.0),
)
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
backgroundColor: Color(0xFFFF5000),
foregroundColor: Colors.white,
title: Text('订单详情'),
titleSpacing: 1.0,
),
body: _isLoading
? Center(child: CircularProgressIndicator())
: orderGoodsInfo == null
? emptyTip()
: ScrollConfiguration(
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
child: ListView(
physics: BouncingScrollPhysics(),
padding: EdgeInsets.all(10.0),
children: [
if (orderGoodsInfo?['status'] == 0)
Container(
padding: EdgeInsets.all(12.0),
margin: EdgeInsets.only(bottom: 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(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.info,
size: 16.0,
color: Colors.orange,
),
SizedBox(width: 4),
Text(
getOrderStatusText(orderGoodsInfo?['status'] ?? 0),
style: TextStyle(color: Colors.orange),
),
SizedBox(width: 4),
],
),
SizedBox(height: 4),
],
),
),
// 商品信息
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: [
Spacer(),
Text(
getOrderStatusText(orderGoodsInfo?['status'] ?? 0),
style: TextStyle(
color: getOrderStatusColor(orderGoodsInfo?['status'] ?? 0),
fontWeight: FontWeight.bold,
),
)
],
),
SizedBox(height: 10),
_buildProductList(),
],
),
),
// 订单信息
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: [
Text(
'订单信息',
style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold),
),
Spacer(),
InkWell(
child: Icon(
Icons.copy,
color: Colors.grey,
size: 18.0,
),
onTap: () async {
await Clipboard.setData(ClipboardData(text: _orderId??''));
MyDialog.toast('订单已复制到剪切板', icon: Icon(Icons.check_circle));
},
)
],
),
SizedBox(height: 10),
Column(
children: [
_buildOrderInfoRow('订单号', orderGoodsInfo?['orderId']?.toString() ?? ''),
_buildOrderInfoRow('下单时间', orderGoodsInfo?['createTime']?.toString() ?? ''),
_buildOrderInfoRow('购买数量', _calculateTotalQuantity().toString()),
_buildOrderInfoRow('订单金额', '¥${orderGoodsInfo?['totalAmount']?.toString() ?? '0.00'}'),
_buildOrderInfoRow('实付金额', '¥${orderGoodsInfo?['payAmount']?.toString() ?? '0.00'}'),
],
)
],
),
),
],
),
),
// 底部固定按钮
bottomNavigationBar: orderGoodsInfo == null
? null
: SafeArea(
minimum: const EdgeInsets.all(10),
child: Container(
height: 60.0,
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
// child: buildBottomButtons(),
),
),
);
}
// 计算总购买数量
int _calculateTotalQuantity() {
final productList = getProductInfoList();
int total = 0;
for (var product in productList) {
total += (product?['buyNum'] as int? ?? 0);
}
return total;
}
Widget _buildOrderInfoRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 6.0),
child: Row(
children: [
Text(
label,
style: TextStyle(color: Colors.grey, fontSize: 13),
),
Spacer(),
Text(value, style: TextStyle(fontSize: 13)),
],
),
);
}
}