You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

545 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* ====================================================
* package :
* author : Created by nansi.
* time : 2019-07-19 14:17
* remark :
* ====================================================
*/
import 'package:common_utils/common_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_union_pay/flutter_union_pay.dart';
import 'package:recook/base/base_store_state.dart';
import 'package:recook/manager/http_manager.dart';
import 'package:recook/manager/user_manager.dart';
import 'package:recook/models/PayInfoModel.dart';
import 'package:recook/models/alipay_order_model.dart';
import 'package:recook/models/base_model.dart';
import 'package:recook/models/order_prepay_model.dart';
import 'package:recook/models/pay_result_model.dart';
import 'package:recook/models/recook_fund_model.dart';
import 'package:recook/pages/home/classify/mvp/order_mvp/order_presenter_impl.dart';
import 'package:recook/pages/user/order/order_center_page.dart';
import 'package:recook/pages/user/order/order_detail_page.dart';
import 'package:recook/third_party/alipay/alipay_utils.dart';
import 'package:recook/third_party/wechat/wechat_utils.dart';
import 'package:recook/widgets/alert.dart';
import 'package:recook/widgets/custom_app_bar.dart';
import 'package:recook/constants/header.dart';
import 'package:recook/widgets/custom_image_button.dart';
import 'package:recook/widgets/keyboard/bottom_keyboard_widget.dart';
import 'package:recook/widgets/toast.dart';
class OrderPrepayPage extends StatefulWidget {
final Map arguments;
const OrderPrepayPage({Key key, this.arguments}) : super(key: key);
static setArguments(OrderPrepayModel model, {bool goToOrder = false}) {
return {"model": model, "goToOrder": goToOrder};
}
@override
State<StatefulWidget> createState() {
return _OrderPrepayPageState();
}
}
class _OrderPrepayPageState extends BaseStoreState<OrderPrepayPage>
with WidgetsBindingObserver {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
OrderPresenterImpl _presenter;
OrderPrepayModel _model;
int _defaultPayIndex = 1;
RecookFundModel _recookFundModel;
/// 取消支付后是否跳转到订单界面从预览订单进来的会调到订单订单列表继续支付进来的只会pop
bool _goToOrder;
/// 用于辅助判断 app 从后台进入前台时,是否需要向后台验证订单状态
bool _clickPay = false;
BottomKeyBoardController _bottomKeyBoardController =
BottomKeyBoardController();
// @override
// bool needStore() {
// return true;
// }
@override
void initState() {
super.initState();
FlutterUnionPay.listen((result) {
switch (result.status) {
case PaymentStatus.CANCEL:
Toast.showError('银联取消支付');
break;
case PaymentStatus.SUCCESS:
Toast.showSuccess('支付成功');
break;
case PaymentStatus.FAIL:
Toast.showError('银联支付失败');
break;
}
});
UserManager.instance.setPassword.addListener(_setPassword);
WidgetsBinding.instance.addObserver(this);
_presenter = OrderPresenterImpl();
_model = widget.arguments["model"];
_goToOrder = widget.arguments["goToOrder"];
_presenter
.queryRecookPayFund(UserManager.instance.user.info.id)
.then((HttpResultModel<RecookFundModel> model) {
if (!model.result) {
showError(model.msg);
return;
}
setState(() {
if (model.data.data.amount > _model.data.actualTotalAmount) {
_defaultPayIndex = 0;
}
_recookFundModel = model.data;
});
});
}
_setPassword() {
if (_recookFundModel != null) {
_recookFundModel.data.havePassword = true;
}
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
UserManager.instance.setPassword.removeListener(_setPassword);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
DPrint.printf(state);
if (state == AppLifecycleState.resumed) {
DPrint.printf("app 进入前台了");
_verifyPayStatus();
_clickPay = false;
}
}
@override
Widget buildContext(BuildContext context, {store}) {
return WillPopScope(
child: Scaffold(
key: _scaffoldKey,
appBar: CustomAppBar(
themeData: AppThemes.themeDataGrey.appBarTheme,
title: "订单支付",
),
backgroundColor: AppColor.frenchColor,
body: _buildBody(context),
),
onWillPop: () {
Alert.show(
context,
NormalTextDialog(
type: NormalTextDialogType.delete,
title: "确认要离开收银台?",
content: "您的订单在生成后20分钟内未支付将被取消请尽快完成支付。",
items: ["继续支付"],
listener: (index) {
Alert.dismiss(context);
},
deleteItem: "确认离开",
deleteListener: () {
_updateUserBrief();
Alert.dismiss(context);
if (_goToOrder) {
AppRouter.pushAndReplaced(
globalContext, RouteName.ORDER_DETAIL,
arguments: OrderDetailPage.setArguments(_model.data.id));
return;
}
Navigator.pop(context);
},
));
return Future.value(false);
},
);
}
ListView _buildBody(BuildContext context) {
return ListView(
children: <Widget>[
_priceView(),
Text(
"创建时间: ${_model.data.createdAt}",
textAlign: TextAlign.center,
style: AppTextStyle.generate(ScreenAdapterUtils.setSp(15),
color: Colors.grey),
),
Container(
height: rSize(50),
),
_payTile(
"",
SvgPicture.asset(
AppSvg.svg_balance_pay,
width: rSize(30),
height: rSize(30),
),
0,
widgetTitle: RichText(
text: TextSpan(
text: "余额支付 ",
style: AppTextStyle.generate(ScreenAdapterUtils.setSp(17)),
children: [
TextSpan(
style: AppTextStyle.generate(
ScreenAdapterUtils.setSp(14),
color: Colors.grey),
text:
"(可用余额: ¥${_recookFundModel == null ? "--" : _recookFundModel.data.amount})")
]),
),
enable: _recookFundModel != null &&
(_recookFundModel.data.amount >=
_model.data.actualTotalAmount)),
_payTile(
"微信支付",
Icon(
AppIcons.icon_pay_wechat,
color: Color.fromARGB(255, 67, 170, 97),
),
1),
_payTile(
"支付宝支付",
Icon(
AppIcons.icon_pay_alipay,
color: Color.fromARGB(255, 17, 142, 228),
),
2),
_payTile(
"云闪付支付",
Image.asset(
R.ASSETS_UNION_PAY_PNG,
height: rSize(30),
),
3),
Container(
margin:
EdgeInsets.symmetric(horizontal: rSize(40), vertical: rSize(150)),
child: CustomImageButton(
title: "确认支付",
fontSize: ScreenAdapterUtils.setSp(16),
padding: EdgeInsets.symmetric(vertical: rSize(8)),
borderRadius: BorderRadius.all(Radius.circular(10)),
backgroundColor: AppColor.themeColor,
color: Colors.white,
onPressed: () {
_submit();
},
),
)
],
);
}
Container _priceView() {
return Container(
margin: EdgeInsets.symmetric(vertical: 20),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: AppTextStyle.generate(ScreenAdapterUtils.setSp(22),
fontWeight: FontWeight.w500),
text: "",
children: [
TextSpan(
style: AppTextStyle.generate(ScreenAdapterUtils.setSp(33),
fontWeight: FontWeight.w500),
text: _model.data.actualTotalAmount.toString())
])),
);
}
_payTile(String title, Widget icon, int index,
{Widget widgetTitle, bool enable = true}) {
return CustomImageButton(
padding: EdgeInsets.zero,
child: Padding(
padding: EdgeInsets.only(left: rSize(15)),
child: Row(
children: <Widget>[
icon,
Expanded(
child: Container(
padding: EdgeInsets.only(
top: rSize(17), bottom: rSize(17), right: rSize(15)),
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: Colors.grey[400], width: 0.5))),
margin: EdgeInsets.only(left: rSize(15)),
child: Row(
children: <Widget>[
widgetTitle ??
Text(
title,
style: AppTextStyle.generate(
ScreenAdapterUtils.setSp(17)),
),
Spacer(),
Icon(
_defaultPayIndex == index
? AppIcons.icon_check_circle
: AppIcons.icon_circle,
color: _defaultPayIndex == index
? AppColor.themeColor
: Colors.grey[300],
size: rSize(20),
)
],
),
),
),
],
),
),
onPressed: !enable
? null
: () {
setState(() {
_defaultPayIndex = index;
});
},
);
}
_submit() {
showLoading("");
if (_model.data.actualTotalAmount == 0) {
// _zeroPay();
// _recookPay();
_submitPassword();
return;
}
_clickPay = true;
switch (_defaultPayIndex) {
case 0:
// _recookPay();
_submitPassword();
break;
case 1:
_weChatPay(context);
break;
case 2:
_aliPay(context);
break;
case 3:
_unionPay(context);
break;
}
}
_zeroPay() async {
HttpResultModel<BaseModel> resultModel = await _presenter
.createZeroPayOrder(UserManager.instance.user.info.id, _model.data.id);
if (!resultModel.result) {
showError(resultModel.msg);
return;
}
_updateUserBrief();
showSuccess("订单支付成功").then((value) {
AppRouter.pushAndReplaced(globalContext, RouteName.ORDER_LIST_PAGE,
arguments: OrderCenterPage.setArguments(2));
});
}
_aliPay(BuildContext context) async {
HttpResultModel<AlipayOrderModel> resultModel = await _presenter
.createAliPayOrder(UserManager.instance.user.info.id, _model.data.id);
dismissLoading();
if (!resultModel.result) {
GSDialog.of(context).showError(context, resultModel.msg);
return;
}
AliPayUtils.callAliPay(resultModel.data.data.orderString);
}
_weChatPay(BuildContext context) async {
HttpResultModel<PayInfoModel> resultModel = await _presenter
.createWeChatOrder(UserManager.instance.user.info.id, _model.data.id);
GSDialog.of(context).dismiss(context);
if (!resultModel.result) {
GSDialog.of(context).showError(context, resultModel.msg);
return;
}
PayInfoModel wxPayModel = resultModel.data;
WeChatUtils.pay(
appId: wxPayModel.payInfo.appid,
partnerId: wxPayModel.payInfo.partnerid,
prepayId: wxPayModel.payInfo.prepayid,
packageValue: wxPayModel.payInfo.package,
nonceStr: wxPayModel.payInfo.noncestr,
timeStamp: int.parse(wxPayModel.payInfo.timestamp),
sign: wxPayModel.payInfo.sign,
listener: (WXPayResult result) {});
}
_unionPay(BuildContext context) async {
ResultData resultData =
await HttpManager.post("/v1/pay/unionpay/order/create", {
"orderId": _model.data.id,
"userId": UserManager.instance.user.info.id,
});
dismissLoading();
if (!TextUtil.isEmpty(resultData?.data['data']['tn'] ?? null)) {
FlutterUnionPay.pay(
tn: resultData?.data['data']['tn'],
mode: AppConfig.debug ? PaymentEnv.DEVELOPMENT : PaymentEnv.PRODUCT,
scheme: "RecookUnionPay",
);
}
}
// 密码支付
_submitPassword() {
dismissLoading();
if (!_recookFundModel.data.havePassword) {
// if (true) {
//未设置密码 先设置密码
// 创建密码
Alert.show(
context,
NormalTextDialog(
type: NormalTextDialogType.delete,
// title: "支付密码",
content: "您当前未设置支付密码,请先设置 支付密码,或更换支付方式。",
items: ["更换支付方式"],
listener: (index) {
Alert.dismiss(context);
},
deleteItem: "设置密码",
deleteListener: () {
Alert.dismiss(context);
AppRouter.push(context, RouteName.USER_SET_PASSWORD_VARCODE);
},
));
// AppRouter.push(context, RouteName.USER_SET_PASSWORD);
} else {
//输入密码
_showPasswordBottomSheet();
}
}
_showPasswordBottomSheet() {
bool forgetPassword = false;
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return SizedBox(
height: 220.0 + 190.0,
child: BottomKeyBoardWidget(
controller: _bottomKeyBoardController,
close: () {
Navigator.pop(context);
},
passwordReturn: (password) {
_recookPay(password);
},
forgetPassword: () {
Navigator.pop(context);
forgetPassword = true;
},
),
);
// return BottomKeyBoardWidget(
// close: (){
// Navigator.pop(context);
// },
// passwordReturn: (password){
// // Navigator.pop(context);
// // DPrint.printf(password);
// // showError(password);
// _recookPay(password);
// },
// forgetPassword: (){
// Navigator.pop(context);
// forgetPassword = true;
// },
// );
},
).then((val) {
if (mounted) {
if (forgetPassword) {
AppRouter.push(context, RouteName.USER_SET_PASSWORD_VARCODE);
// AppRouter.push(context, RouteName.USER_SET_PASSWORD);
}
}
});
}
_recookPay(password) async {
showLoading("");
HttpResultModel<BaseModel> resultModel =
await _presenter.createRecookPayOrder(
UserManager.instance.user.info.id, _model.data.id, password);
dismissLoading();
if (!resultModel.result) {
_bottomKeyBoardController.clearPassWord();
showError(resultModel.msg, duration: Duration(milliseconds: 2000));
return;
}
UserManager.instance.refreshShoppingCart.value = true;
Navigator.pop(context);
_updateUserBrief();
showSuccess("订单支付成功").then((value) {
AppRouter.pushAndReplaced(globalContext, RouteName.ORDER_LIST_PAGE,
arguments: OrderCenterPage.setArguments(2));
});
}
_verifyPayStatus() async {
GSDialog.of(_scaffoldKey.currentContext)
.showLoadingDialog(_scaffoldKey.currentContext, "正在验证订单...");
await Future.delayed(Duration(seconds: 1));
HttpResultModel<PayResult> resultModel =
await _presenter.verifyOrderPayStatus(_model.data.id);
GSDialog.of(_scaffoldKey.currentContext)
.dismiss(_scaffoldKey.currentContext);
if (!resultModel.result) {
GSDialog.of(_scaffoldKey.currentContext)
.showError(_scaffoldKey.currentContext, resultModel.msg);
return;
}
if (resultModel.data.status == 0) {
// Navigator.popUntil(context, ModalRoute.withName(RouteName.ORDER_LIST_PAGE));
if (_goToOrder) {
AppRouter.pushAndReplaced(globalContext, RouteName.ORDER_DETAIL,
arguments: OrderDetailPage.setArguments(_model.data.id));
} else {
Navigator.pop(context);
}
return;
}
UserManager.instance.refreshShoppingCart.value = true;
_updateUserBrief();
AppRouter.pushAndReplaced(globalContext, RouteName.ORDER_LIST_PAGE,
arguments: OrderCenterPage.setArguments(2));
}
_updateUserBrief() {
UserManager.instance.updateUserBriefInfo(getStore());
}
}