核销联调
This commit is contained in:
parent
c6c6acf9dc
commit
09f0048b67
@ -39,4 +39,9 @@ class ShopApi {
|
||||
// 商家营收分页
|
||||
static const String revenueList= '/app/merchant/account/bill/page';
|
||||
|
||||
// 根据核销码查询详情
|
||||
static const String getWriteOffDetail= '/app/merchant/order/scan';
|
||||
|
||||
// 确认核销
|
||||
static const String confirmWriteOff= '/app/merchant/order/verify';
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import 'package:loopin/components/scan_util.dart';
|
||||
import 'package:loopin/models/conversation_type.dart';
|
||||
import 'package:loopin/models/conversation_view_model.dart';
|
||||
import 'package:loopin/utils/index.dart';
|
||||
import 'package:loopin/utils/scan_code_type.dart'; // 导入外部枚举
|
||||
import 'package:loopin/utils/parse_message_summary.dart';
|
||||
import 'package:shirne_dialog/shirne_dialog.dart';
|
||||
|
||||
@ -51,7 +52,55 @@ class ChatPageState extends State<ChatPage> {
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
setState(() {});
|
||||
}
|
||||
// 处理扫码结果
|
||||
void handleScanResult(String code) {
|
||||
print('扫码结果11111111111111111111111:$code');
|
||||
|
||||
// 使用外部枚举的方法检查扫码类型
|
||||
final scanType = ScanCodeType.fromCode(code);
|
||||
if (scanType != null) {
|
||||
final value = code.substring(scanType.prefix.length + 1); // 获取后缀值
|
||||
_processScanCode(scanType, value);
|
||||
} else {
|
||||
// 未知类型的码
|
||||
Get.snackbar('未知的二维码类型', '无法识别此二维码: $code');
|
||||
}
|
||||
}
|
||||
|
||||
// 处理不同类型的扫码结果
|
||||
void _processScanCode(ScanCodeType type, String value) {
|
||||
switch (type) {
|
||||
case ScanCodeType.verification:
|
||||
_handleVerificationCode(value);
|
||||
break;
|
||||
case ScanCodeType.friend:
|
||||
_handleFriendCode(value);
|
||||
break;
|
||||
case ScanCodeType.promotion:
|
||||
_handlePromotionCode(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理核销码
|
||||
void _handleVerificationCode (String value) async {
|
||||
print('处理核销码: $value');
|
||||
// 带着核销码,跳转到商家的商品详情页面,引导商家去手动点击核销按钮
|
||||
Get.toNamed('/sellerOrder/detail', arguments: {'writeOffCodeId':value});
|
||||
}
|
||||
|
||||
// 处理好友码
|
||||
void _handleFriendCode(String value) {
|
||||
print('处理好友码: $value');
|
||||
// 模仿抖音,去个人页面手动点击关注
|
||||
Get.toNamed('/vloger', arguments: {'memberId':value});
|
||||
}
|
||||
|
||||
// 处理推广码
|
||||
void _handlePromotionCode(String value) {
|
||||
print('处理推广码: $value');
|
||||
Get.toNamed('/vloger', arguments: {'memberId':value});
|
||||
}
|
||||
// 长按菜单
|
||||
void showContextMenu(BuildContext context, ConversationViewModel item) {
|
||||
bool isLeft = posDX > MediaQuery.of(context).size.width / 2 ? false : true;
|
||||
@ -240,11 +289,7 @@ class ChatPageState extends State<ChatPage> {
|
||||
break;
|
||||
case 'scan':
|
||||
logger.w('点击了扫一扫');
|
||||
ScanUtil.openScanner(onResult: (code) {
|
||||
logger.w('扫码结果:$code');
|
||||
Get.snackbar('扫码成功', code);
|
||||
// 执行业务逻辑
|
||||
});
|
||||
ScanUtil.openScanner(onResult: handleScanResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,19 @@ library;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:loopin/service/http.dart';
|
||||
import 'package:loopin/IM/controller/chat_controller.dart';
|
||||
import 'package:loopin/IM/global_badge.dart';
|
||||
import 'package:loopin/IM/im_service.dart';
|
||||
import 'package:loopin/behavior/custom_scroll_behavior.dart';
|
||||
import 'package:loopin/api/shop_api.dart';
|
||||
import 'package:loopin/components/network_or_asset_image.dart';
|
||||
import 'package:loopin/components/scan_util.dart';
|
||||
import 'package:loopin/models/conversation_type.dart';
|
||||
import 'package:loopin/models/conversation_view_model.dart';
|
||||
import 'package:loopin/styles/index.dart';
|
||||
import 'package:loopin/utils/parse_message_summary.dart';
|
||||
import 'package:loopin/utils/scan_code_type.dart'; // 导入外部枚举
|
||||
import 'package:shirne_dialog/shirne_dialog.dart';
|
||||
|
||||
// systemNotify, // 系统->通知
|
||||
@ -30,7 +33,7 @@ class System extends StatefulWidget {
|
||||
|
||||
class SystemState extends State<System> {
|
||||
late final ChatController controller;
|
||||
|
||||
dynamic writeOffInfo;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -121,6 +124,56 @@ class SystemState extends State<System> {
|
||||
);
|
||||
}
|
||||
|
||||
// 处理扫码结果
|
||||
void handleScanResult(String code) {
|
||||
print('扫码结果:$code');
|
||||
|
||||
// 使用外部枚举的方法检查扫码类型
|
||||
final scanType = ScanCodeType.fromCode(code);
|
||||
if (scanType != null) {
|
||||
final value = code.substring(scanType.prefix.length + 1); // 获取后缀值
|
||||
_processScanCode(scanType, value);
|
||||
} else {
|
||||
// 未知类型的码
|
||||
Get.snackbar('未知的二维码类型', '无法识别此二维码: $code');
|
||||
}
|
||||
}
|
||||
|
||||
// 处理不同类型的扫码结果
|
||||
void _processScanCode(ScanCodeType type, String value) {
|
||||
switch (type) {
|
||||
case ScanCodeType.verification:
|
||||
_handleVerificationCode(value);
|
||||
break;
|
||||
case ScanCodeType.friend:
|
||||
_handleFriendCode(value);
|
||||
break;
|
||||
case ScanCodeType.promotion:
|
||||
_handlePromotionCode(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理核销码
|
||||
void _handleVerificationCode (String value) async {
|
||||
print('处理核销码: $value');
|
||||
// 带着核销码,跳转到商家的商品详情页面,引导商家去手动点击核销按钮
|
||||
Get.toNamed('/sellerOrder/detail', arguments: {'writeOffCodeId':value});
|
||||
}
|
||||
|
||||
// 处理好友码
|
||||
void _handleFriendCode(String value) {
|
||||
print('处理好友码: $value');
|
||||
// 模仿抖音,去个人页面手动点击关注
|
||||
Get.toNamed('/vloger', arguments: {'memberId':value});
|
||||
}
|
||||
|
||||
// 处理推广码
|
||||
void _handlePromotionCode(String value) {
|
||||
print('处理推广码: $value');
|
||||
Get.toNamed('/vloger', arguments: {'memberId':value});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -242,11 +295,7 @@ class SystemState extends State<System> {
|
||||
break;
|
||||
case 'scan':
|
||||
print('点击了扫一扫');
|
||||
ScanUtil.openScanner(onResult: (code) {
|
||||
print('扫码结果:$code');
|
||||
Get.snackbar('扫码成功', code);
|
||||
// 在这里继续你的业务逻辑,比如跳转页面、请求接口等
|
||||
});
|
||||
ScanUtil.openScanner(onResult: handleScanResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
|
||||
void initState() {
|
||||
super.initState();
|
||||
args = Get.arguments ?? {};
|
||||
print('argsssssssssssssssssssssss${args}');
|
||||
itemsParams = PageParams();
|
||||
favoriteParams = PageParams();
|
||||
selfInfo();
|
||||
|
@ -4,9 +4,11 @@ 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:loopin/components/my_toast.dart';
|
||||
import 'package:shirne_dialog/shirne_dialog.dart';
|
||||
import 'package:timer_count_down/timer_count_down.dart';
|
||||
import 'package:loopin/utils/wxsdk.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import '../../behavior/custom_scroll_behavior.dart';
|
||||
import '../../utils/lifecycle_handler.dart';
|
||||
|
||||
@ -18,16 +20,17 @@ class OrderDetail extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStateMixin {
|
||||
late String _orderId;
|
||||
final String _orderId = Get.arguments['orderId'] ?? '';
|
||||
dynamic orderGoodsInfo;
|
||||
int _initialSeconds = 30 * 60; // 存储初始秒数
|
||||
bool _countdownFinished = false; // 新增标志位,用于跟踪倒计时是否结束
|
||||
bool _isLoading = true; // 添加加载状态
|
||||
bool _showQrCodeDialog = false;
|
||||
String _qrCodeUrl = '';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_orderId = Get.arguments['orderId'] ?? '';
|
||||
getOrderDetail(orderId: _orderId);
|
||||
LifecycleHandler.onAppResumed = _onAppResumed;
|
||||
}
|
||||
@ -61,7 +64,7 @@ class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStat
|
||||
_isLoading = true;
|
||||
});
|
||||
final res = await Http.get('${ShopApi.goodsOrderDetail}/$orderId');
|
||||
debugPrint('订单详情-------------->${res['data']}');
|
||||
debugPrint(res['data'].toString(), wrapWidth: 600);
|
||||
setState(() {
|
||||
orderGoodsInfo = res['data'];
|
||||
_isLoading = false;
|
||||
@ -84,6 +87,41 @@ class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStat
|
||||
}
|
||||
}
|
||||
|
||||
// 核销
|
||||
void _writeOffQrCode(verificationCodes) async {
|
||||
if (verificationCodes != null && verificationCodes.isNotEmpty) {
|
||||
// 过滤可用的核销码(status为0)
|
||||
List<dynamic> newVerifyList = verificationCodes.where((item) => item['status'] == 0).toList();
|
||||
|
||||
if (newVerifyList.isNotEmpty) {
|
||||
setState(() {
|
||||
_showQrCodeDialog = true;
|
||||
_qrCodeUrl = newVerifyList[0]['code'] ?? '';
|
||||
});
|
||||
} else {
|
||||
MyToast().tip(
|
||||
title: '暂无可用的核销码',
|
||||
position: 'center',
|
||||
type: 'error',
|
||||
);
|
||||
}
|
||||
} else {
|
||||
MyToast().tip(
|
||||
title: '暂无可用的核销码',
|
||||
position: 'center',
|
||||
type: 'error',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭二维码弹框
|
||||
void _closeQrCodeDialog() {
|
||||
setState(() {
|
||||
_showQrCodeDialog = false;
|
||||
_qrCodeUrl = '';
|
||||
});
|
||||
}
|
||||
|
||||
// 显示支付结果弹框
|
||||
void _showPaymentResultDialog() {
|
||||
showDialog(
|
||||
@ -314,7 +352,7 @@ class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStat
|
||||
if (orderGoodsInfo == null) return SizedBox.shrink();
|
||||
|
||||
int orderStatus = orderGoodsInfo?['status'] ?? 0;
|
||||
|
||||
List verificationCodes = orderGoodsInfo?['verificationCodes'] ?? [];
|
||||
switch (orderStatus) {
|
||||
case 0: // 待付款
|
||||
return Row(
|
||||
@ -353,12 +391,12 @@ class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStat
|
||||
children: [
|
||||
const SizedBox(width: 10.0),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
onPressed: () => _writeOffQrCode(verificationCodes),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Color(0xFFFF5000)),
|
||||
backgroundColor: WidgetStateProperty.all(Colors.green),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
),
|
||||
child: const Text('待核销'),
|
||||
child: const Text('核销码'),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -465,6 +503,137 @@ class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStat
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildQrCodeDialog() {
|
||||
return GestureDetector(
|
||||
onTap: _closeQrCodeDialog,
|
||||
child: Container(
|
||||
color: Colors.black54,
|
||||
child: Center(
|
||||
child: GestureDetector(
|
||||
onTap: () {}, // 阻止点击内容区域关闭
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black26,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'核销二维码',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
_qrCodeUrl.isNotEmpty
|
||||
? Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border.all(color: Colors.grey[300]!),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: QrImageView(
|
||||
data: _qrCodeUrl,
|
||||
version: QrVersions.auto,
|
||||
size: 180,
|
||||
foregroundColor: Colors.black,
|
||||
backgroundColor: Colors.white,
|
||||
errorStateBuilder: (cxt, err) {
|
||||
return Container(
|
||||
width: 180,
|
||||
height: 180,
|
||||
color: Colors.grey[200],
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.error_outline,
|
||||
color: Colors.grey[400],
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
width: 180,
|
||||
height: 180,
|
||||
color: Colors.grey[200],
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Color(0xff07c160),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Text(
|
||||
'订单号: $_orderId',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'核销码: $_qrCodeUrl',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey[500],
|
||||
fontFamily: 'monospace',
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: _closeQrCodeDialog,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xff07c160),
|
||||
foregroundColor: Colors.white,
|
||||
minimumSize: Size(120, 40),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
),
|
||||
child: Text('关闭'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final productInfo = _getFirstProductInfo();
|
||||
@ -477,7 +646,10 @@ class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStat
|
||||
title: Text('订单详情'),
|
||||
titleSpacing: 1.0,
|
||||
),
|
||||
body: _isLoading
|
||||
body: Stack(
|
||||
children: [
|
||||
// 主要内容
|
||||
_isLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
: orderGoodsInfo == null
|
||||
? emptyTip()
|
||||
@ -679,7 +851,11 @@ class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStat
|
||||
],
|
||||
),
|
||||
),
|
||||
// 底部固定按钮
|
||||
|
||||
// 二维码对话框(条件渲染)
|
||||
if (_showQrCodeDialog) _buildQrCodeDialog(),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: orderGoodsInfo == null
|
||||
? null
|
||||
: SafeArea(
|
||||
@ -693,20 +869,4 @@ class _OrderDetailState extends State<OrderDetail> with SingleTickerProviderStat
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -665,6 +665,7 @@ class _MyOrderState extends State<MyOrder> with SingleTickerProviderStateMixin {
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,8 @@ 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:timer_count_down/timer_count_down.dart';
|
||||
import 'package:loopin/utils/wxsdk.dart';
|
||||
import 'package:loopin/components/my_toast.dart';
|
||||
import '../../behavior/custom_scroll_behavior.dart';
|
||||
import '../../utils/lifecycle_handler.dart';
|
||||
|
||||
class SellerOrderDetail extends StatefulWidget {
|
||||
const SellerOrderDetail({super.key});
|
||||
@ -18,49 +16,54 @@ class SellerOrderDetail extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTickerProviderStateMixin {
|
||||
late String _orderId;
|
||||
late String ? _orderId;
|
||||
late String ?_writeOffCodeId;
|
||||
dynamic orderGoodsInfo;
|
||||
int _initialSeconds = 30 * 60; // 存储初始秒数
|
||||
bool _countdownFinished = false; // 新增标志位,用于跟踪倒计时是否结束
|
||||
bool _isLoading = true; // 添加加载状态
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_orderId = Get.arguments['orderId'] ?? '';
|
||||
getOrderDetail(orderId: _orderId);
|
||||
LifecycleHandler.onAppResumed = _onAppResumed;
|
||||
_orderId = Get.arguments['orderId'] ?? ''; // 从商家订单列表进入此页面,此时带着订单id
|
||||
_writeOffCodeId = Get.arguments['writeOffCodeId'] ?? ''; // 从扫码核销进入此页面,此时带着核销码
|
||||
if(_orderId != null){
|
||||
getOrderDetailByOrderId(_orderId);
|
||||
}else if(_writeOffCodeId != null){
|
||||
getOrderDetailByWriteOffId(_writeOffCodeId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
LifecycleHandler.onAppResumed = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onAppResumed() {
|
||||
print('App回到前台,刷新订单状态,订单Id${_orderId}');
|
||||
getOrderDetail(orderId: _orderId); // 刷新订单详情数据
|
||||
_showPaymentResultDialog(); // 展示支付结果弹框
|
||||
}
|
||||
|
||||
// 获取订单状态
|
||||
void getOrderRealStatus({required String orderId}) async {
|
||||
try {
|
||||
final res = await Http.get('${ShopApi.goodsOrderStatus}/$orderId');
|
||||
Get.toNamed('/myOrder');
|
||||
} catch (e) {
|
||||
print('报错-------------->${e}');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取订单详情信息,包含商品参数
|
||||
void getOrderDetail({required String orderId}) async {
|
||||
// 获取订单详情信息,根据订单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'];
|
||||
@ -74,123 +77,44 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
||||
}
|
||||
}
|
||||
|
||||
// 取消订单
|
||||
void _cancelOrder() async {
|
||||
// 确认核销订单
|
||||
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.post('${ShopApi.cancelGoodsOrder}/$_orderId');
|
||||
getOrderDetail(orderId: _orderId); // 刷新订单详情数据
|
||||
final res = await Http.get('${ShopApi.confirmWriteOff}?code=$writeOffCode');
|
||||
debugPrint(res['data'].toString(), wrapWidth: 600);
|
||||
MyToast().tip(
|
||||
title: '核销成功',
|
||||
position: 'center',
|
||||
type: 'error',
|
||||
);
|
||||
} catch (e) {
|
||||
MyDialog.toast('取消订单失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 显示支付结果弹框
|
||||
void _showPaymentResultDialog() {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
barrierColor: Colors.black54,
|
||||
builder: (BuildContext context) {
|
||||
return Dialog(
|
||||
backgroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// 图标
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFFF8E6),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.payment,
|
||||
size: 32,
|
||||
color: Color(0xFFFFA500),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
|
||||
// 标题
|
||||
Text(
|
||||
'支付确认',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
|
||||
// 描述
|
||||
Text(
|
||||
'请确认您的支付状态',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
|
||||
// 按钮区域
|
||||
Row(
|
||||
children: [
|
||||
// 支付遇到问题按钮
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
getOrderRealStatus(orderId: _orderId); // 主动再次拉取订单状态
|
||||
},
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.grey[700],
|
||||
side: BorderSide(color: Colors.grey[300]!),
|
||||
padding: EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Text('支付遇到问题'),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
|
||||
// 支付完成按钮
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
getOrderRealStatus(orderId: _orderId); // 同时主动拉取订单状态
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFFFF5000),
|
||||
foregroundColor: Colors.white,
|
||||
padding: EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Text('支付完成'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// 获取订单状态文本
|
||||
String getOrderStatusText(int status) {
|
||||
switch (status) {
|
||||
@ -383,32 +307,7 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
||||
case 0: // 待付款
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
// 取消订单逻辑
|
||||
_cancelOrder();
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.white),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.black87),
|
||||
side: WidgetStateProperty.all(BorderSide(color: Colors.grey[300]!)),
|
||||
),
|
||||
child: const Text('取消订单'),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
// 打开微信小程序的某个页面地址,如pages/index/index
|
||||
Wxsdk.openMiniApp(orderId: _orderId);
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Color(0xff07c160)),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
),
|
||||
child: const Text('去支付'),
|
||||
),
|
||||
],
|
||||
children: [],
|
||||
);
|
||||
|
||||
case 1: // 待核销
|
||||
@ -417,12 +316,14 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
||||
children: [
|
||||
const SizedBox(width: 10.0),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
_confirmVerifyCode();
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Color(0xFFFF5000)),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
),
|
||||
child: const Text('待核销'),
|
||||
child: const Text('确认核销'),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -430,81 +331,31 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
||||
case 2: // 已完成
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
const SizedBox(width: 10.0),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.green),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
),
|
||||
child: const Text('已完成'),
|
||||
),
|
||||
],
|
||||
children: [],
|
||||
);
|
||||
|
||||
case 3: // 已关闭
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
const SizedBox(width: 10.0),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.grey),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
),
|
||||
child: const Text('已关闭'),
|
||||
),
|
||||
],
|
||||
children: [],
|
||||
);
|
||||
|
||||
case 4: // 退款中
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
const SizedBox(width: 10.0),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.orange),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
),
|
||||
child: const Text('退款中'),
|
||||
),
|
||||
],
|
||||
children: [],
|
||||
);
|
||||
|
||||
case 5: // 已退款
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
const SizedBox(width: 10.0),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.grey),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
),
|
||||
child: const Text('已退款'),
|
||||
),
|
||||
],
|
||||
children: [],
|
||||
);
|
||||
|
||||
case 6: // 已取消
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
const SizedBox(width: 10.0),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.grey),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
),
|
||||
child: const Text('已取消'),
|
||||
),
|
||||
],
|
||||
children: [],
|
||||
);
|
||||
|
||||
default:
|
||||
@ -549,7 +400,7 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
||||
physics: BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.all(10.0),
|
||||
children: [
|
||||
if (orderGoodsInfo?['status'] == 0) // 修正:应该是 status 而不是 orderStatus
|
||||
if (orderGoodsInfo?['status'] == 0)
|
||||
Container(
|
||||
padding: EdgeInsets.all(12.0),
|
||||
margin: EdgeInsets.only(bottom: 10.0),
|
||||
@ -581,41 +432,11 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
||||
style: TextStyle(color: Colors.orange),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
_countdownFinished ? '倒计时已结束' : '剩余 ',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
if (!_countdownFinished)
|
||||
Countdown(
|
||||
seconds: _initialSeconds,
|
||||
build: (_, double time) {
|
||||
int m = ((time % 3600) ~/ 60).toInt();
|
||||
int s = (time % 60).toInt();
|
||||
String formatted = "${m.toString().padLeft(2, '0')}:${s.toString().padLeft(2, '0')}";
|
||||
|
||||
return Text(
|
||||
formatted,
|
||||
style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),
|
||||
);
|
||||
},
|
||||
interval: Duration(seconds: 1),
|
||||
onFinished: () {
|
||||
print("倒计时结束");
|
||||
_cancelOrder();
|
||||
setState(() {
|
||||
_countdownFinished = true;
|
||||
});
|
||||
},
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
_countdownFinished
|
||||
? '订单已自动取消'
|
||||
: '超过30分钟未支付,订单将自动取消',
|
||||
style: TextStyle(color: Colors.grey, fontSize: 12.0),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -686,7 +507,7 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
||||
size: 18.0,
|
||||
),
|
||||
onTap: () async {
|
||||
await Clipboard.setData(ClipboardData(text: _orderId));
|
||||
await Clipboard.setData(ClipboardData(text: _orderId??''));
|
||||
MyDialog.toast('订单已复制到剪切板', icon: Icon(Icons.check_circle));
|
||||
},
|
||||
)
|
||||
@ -717,7 +538,7 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
||||
height: 60.0,
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
|
||||
child: buildBottomButtons(),
|
||||
// child: buildBottomButtons(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -1136,7 +1136,8 @@ class _AttentionModuleState extends State<AttentionModule> {
|
||||
onTap: () async {
|
||||
player.pause();
|
||||
// 跳转到 Vloger 页面并等待返回结果
|
||||
final result = await Get.toNamed('/vloger', arguments: videoList[videoModuleController.videoPlayIndex.value]);
|
||||
final vloggerId = videoList[videoModuleController.videoPlayIndex.value]['memberId'];
|
||||
final result = await Get.toNamed('/vloger', arguments: {'memberId':vloggerId});
|
||||
if (result != null) {
|
||||
// 处理返回的参数
|
||||
print('返回的数据: ${result['followStatus']}');
|
||||
|
@ -1141,7 +1141,8 @@ class _FriendModuleState extends State<FriendModule> {
|
||||
onTap: () async {
|
||||
player.pause();
|
||||
// 跳转到 Vloger 页面并等待返回结果
|
||||
final result = await Get.toNamed('/vloger', arguments: videoList[videoModuleController.videoPlayIndex.value]);
|
||||
final vloggerId = videoList[videoModuleController.videoPlayIndex.value]['memberId'];
|
||||
final result = await Get.toNamed('/vloger', arguments: {'memberId':vloggerId});
|
||||
if (result != null) {
|
||||
// 处理返回的参数
|
||||
print('返回的数据: ${result['followStatus']}');
|
||||
|
@ -1125,7 +1125,8 @@ class _RecommendModuleState extends State<RecommendModule> {
|
||||
onTap: () async {
|
||||
player.pause();
|
||||
// 跳转到 Vloger 页面并等待返回结果
|
||||
final result = await Get.toNamed('/vloger', arguments: videoList[videoModuleController.videoPlayIndex.value]);
|
||||
final vloggerId = videoList[videoModuleController.videoPlayIndex.value]['memberId'];
|
||||
final result = await Get.toNamed('/vloger', arguments: {'memberId':vloggerId});
|
||||
if (result != null) {
|
||||
// 处理返回的参数
|
||||
print('返回的数据: ${result['followStatus']}');
|
||||
|
29
lib/utils/scan_code_type.dart
Normal file
29
lib/utils/scan_code_type.dart
Normal file
@ -0,0 +1,29 @@
|
||||
// 扫码 类型
|
||||
enum ScanCodeType {
|
||||
verification('hxm'), // 核销码
|
||||
friend('hym'), // 好友码
|
||||
promotion('tgm'); // 推广码
|
||||
|
||||
final String prefix;
|
||||
const ScanCodeType(this.prefix);
|
||||
|
||||
// 根据前缀获取对应的枚举值
|
||||
static ScanCodeType? fromPrefix(String prefix) {
|
||||
for (var type in ScanCodeType.values) {
|
||||
if (type.prefix == prefix) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 根据完整code获取对应的枚举值
|
||||
static ScanCodeType? fromCode(String code) {
|
||||
for (var type in ScanCodeType.values) {
|
||||
if (code.startsWith('${type.prefix}-')) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
16
pubspec.lock
16
pubspec.lock
@ -1093,6 +1093,22 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.1.5"
|
||||
qr:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: qr
|
||||
sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
qr_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: qr_flutter
|
||||
sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
record:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -42,6 +42,8 @@ dependencies:
|
||||
card_swiper: ^3.0.1
|
||||
flutter_svg: ^2.0.16
|
||||
easy_refresh: ^3.4.0
|
||||
# 二维码
|
||||
qr_flutter: ^4.1.0
|
||||
# 腾讯IM
|
||||
tencent_cloud_chat_sdk: ^8.6.7019+2
|
||||
# 离线推送
|
||||
|
Loading…
x
Reference in New Issue
Block a user