接入生活缴费支付功能

hmxc
张萌 3 years ago
parent 9f25d105c6
commit fd66b06c7e

@ -21,6 +21,7 @@ class API {
static _Market market = _Market();
static _News news = _News();
static _Search search = _Search();
static _Pay pay = _Pay();
}
class _Login {
@ -419,3 +420,11 @@ class _Facility {
String get detailType =>
'/user/facilitiesAppointment/findFacilitiesByCategoryId';
}
class _Pay {
///
String get dailyPayMentAliPay => '/user/alipay/dailyPaymentAlipay';
///
String get dailPayMentCheck => '/user/alipay/dailyPaymentCheckAlipay';
}

@ -0,0 +1,69 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'pay_model.g.dart';
@JsonSerializable()
class PayModel extends Equatable {
@JsonKey(name: 'alipay_trade_app_pay_response')
final AliPayTradeAppPayResponse aliPayTradeAppPayResponse;
final String sign;
@JsonKey(name: 'sign_type')
final String signType;
PayModel({
required this.aliPayTradeAppPayResponse,
required this.sign,
required this.signType,
});
factory PayModel.fromJson(Map<String, dynamic> json) =>
_$PayModelFromJson(json);
@override
List<Object> get props => [aliPayTradeAppPayResponse, sign, signType];
}
@JsonSerializable()
class AliPayTradeAppPayResponse extends Equatable {
final String code;
final String msg;
@JsonKey(name: 'app_id')
final String appId;
@JsonKey(name: 'out_trade_no')
final String outTradeNo;
@JsonKey(name: 'trade_no')
final String tradeNo;
@JsonKey(name: 'total_amount')
final String totalAmount;
@JsonKey(name: 'seller_id')
final String sellerId;
final String charset;
final String timestamp;
AliPayTradeAppPayResponse({
required this.code,
required this.msg,
required this.appId,
required this.outTradeNo,
required this.tradeNo,
required this.totalAmount,
required this.sellerId,
required this.charset,
required this.timestamp,
});
factory AliPayTradeAppPayResponse.fromJson(Map<String, dynamic> json) =>
_$AliPayTradeAppPayResponseFromJson(json);
@override
List<Object> get props {
return [
code,
msg,
appId,
outTradeNo,
tradeNo,
totalAmount,
sellerId,
charset,
timestamp,
];
}
}

@ -0,0 +1,31 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'pay_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
PayModel _$PayModelFromJson(Map<String, dynamic> json) {
return PayModel(
aliPayTradeAppPayResponse: AliPayTradeAppPayResponse.fromJson(
json['alipay_trade_app_pay_response'] as Map<String, dynamic>),
sign: json['sign'] as String,
signType: json['sign_type'] as String,
);
}
AliPayTradeAppPayResponse _$AliPayTradeAppPayResponseFromJson(
Map<String, dynamic> json) {
return AliPayTradeAppPayResponse(
code: json['code'] as String,
msg: json['msg'] as String,
appId: json['app_id'] as String,
outTradeNo: json['out_trade_no'] as String,
tradeNo: json['trade_no'] as String,
totalAmount: json['total_amount'] as String,
sellerId: json['seller_id'] as String,
charset: json['charset'] as String,
timestamp: json['timestamp'] as String,
);
}

@ -1,3 +1,6 @@
import 'package:aku_community/pages/life_pay/pay_util.dart';
import 'package:aku_community/utils/network/base_model.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -17,7 +20,6 @@ import 'package:aku_community/provider/app_provider.dart';
import 'package:aku_community/ui/profile/house/pick_my_house_page.dart';
import 'package:aku_community/utils/bee_parse.dart';
import 'package:aku_community/utils/headers.dart';
import 'package:aku_community/utils/network/base_model.dart';
import 'package:aku_community/utils/network/net_util.dart';
import 'package:aku_community/widget/bee_divider.dart';
import 'package:aku_community/widget/bee_scaffold.dart';
@ -49,6 +51,7 @@ class _LifePayPageState extends State<LifePayPage> {
bool get allSelect =>
((_models.length == _selectYears.length) && (_models.length != 0));
@override
void initState() {
super.initState();
@ -58,6 +61,7 @@ class _LifePayPageState extends State<LifePayPage> {
@override
void dispose() {
_controller?.dispose();
BotToast.closeAllLoading();
super.dispose();
}
@ -140,12 +144,6 @@ class _LifePayPageState extends State<LifePayPage> {
_selectPay[index].ids.forEach((element) {
_ids.remove(element);
});
if (_count < 0) {
_count = 0;
}
if (_totalCost < 0) {
_totalCost = 0;
}
} else {
_selectYears.add(index);
_totalCost += (_selectPay[index].payTotal);
@ -187,7 +185,8 @@ class _LifePayPageState extends State<LifePayPage> {
fontWeight: FontWeight.bold),
children: [
TextSpan(
text: '¥ ${_selectPay[index].payTotal}',
text:
'¥ ${_selectPay[index].payTotal.toStringAsFixed(2)}',
style: TextStyle(
color: kDangerColor,
fontSize: 28.sp,
@ -201,11 +200,23 @@ class _LifePayPageState extends State<LifePayPage> {
children: [
GestureDetector(
onTap: () async {
if (_selectYears.contains(index)) {
_totalCost -= _selectPay[index].payTotal;
_count -= _selectPay[index].payCount;
_selectPay[index].ids.forEach((element) {
_ids.remove(element);
});
}
List payMent = await (Get.to(
() => LifePayDetailPage(model: _models[index])));
_selectPay[index].payCount = payMent[0];
_selectPay[index].payTotal = payMent[1];
_selectPay[index].ids = payMent[2];
if (_selectYears.contains(index)) {
_totalCost += _selectPay[index].payTotal;
_count += _selectPay[index].payCount;
}
setState(() {});
},
child: Container(
@ -257,6 +268,58 @@ class _LifePayPageState extends State<LifePayPage> {
return _list;
}
_allSelectOption() {
//
if (_models.length == _selectYears.length) {
_selectYears.clear();
_ids.clear();
_totalCost = 0;
_count = 0;
} else {
for (var i = 0; i < _models.length; i++) {
if (!_selectYears.contains(i)) {
_selectYears.add(i);
}
}
_totalCost = 0;
_count = 0;
_ids.clear();
for (var item in _selectPay) {
_totalCost += item.payTotal;
_count += item.payCount;
_ids.addAll(item.ids);
}
}
setState(() {});
}
Widget _payButton() {
return MaterialButton(
elevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(37.w)),
color: kPrimaryColor,
padding: EdgeInsets.symmetric(horizontal: 50.w, vertical: 15.w),
onPressed: () async {
Function cancel = BotToast.showLoading();
BaseModel baseModel =
await NetUtil().post('/user/alipay/dailyPaymentAlipay', params: {
"ids": _ids,
"payType": 1, //
"payPrice": _totalCost.toStringAsFixed(2)
});
if (baseModel.status ?? false) {
bool result = await PayUtil()
.callAliPay(baseModel.message!, API.pay.dailPayMentCheck);
if (result) {
Get.off(PayFinishPage());
}
}
cancel();
},
child: '去缴费'.text.black.size(32.sp).bold.make(),
);
}
@override
Widget build(BuildContext context) {
final appProvider = Provider.of<AppProvider>(context);
@ -322,28 +385,7 @@ class _LifePayPageState extends State<LifePayPage> {
children: [
GestureDetector(
onTap: () {
//
if (_models.length == _selectYears.length) {
_selectYears.clear();
_ids.clear();
_totalCost = 0;
_count = 0;
} else {
for (var i = 0; i < _models.length; i++) {
if (!_selectYears.contains(i)) {
_selectYears.add(i);
}
}
_totalCost = 0;
_count = 0;
_ids.clear();
for (var item in _selectPay) {
_totalCost += item.payTotal;
_count += item.payCount;
_ids.addAll(item.ids);
}
}
setState(() {});
_allSelectOption();
},
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
@ -379,7 +421,7 @@ class _LifePayPageState extends State<LifePayPage> {
fontWeight: FontWeight.bold),
children: [
TextSpan(
text: '$_totalCost',
text: _totalCost.toStringAsFixed(2),
style: TextStyle(
color: kDangerColor,
fontSize: 32.sp,
@ -389,25 +431,7 @@ class _LifePayPageState extends State<LifePayPage> {
],
),
24.w.widthBox,
MaterialButton(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(37.w)),
color: kPrimaryColor,
padding: EdgeInsets.symmetric(horizontal: 50.w, vertical: 15.w),
onPressed: () async {
BaseModel baseModel =
await NetUtil().post('/user/dailyPayment/pay', params: {
"ids": _ids,
"payType": 1, //
"payPrice": _totalCost
});
if (baseModel.status ?? false) {
Get.off(() => PayFinishPage());
}
},
child: '去缴费'.text.black.size(32.sp).bold.make(),
),
_payButton(),
],
),
),

@ -0,0 +1,96 @@
import 'dart:convert';
import 'package:aku_community/models/pay/pay_model.dart';
import 'package:aku_community/utils/network/net_util.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:dio/dio.dart';
import 'package:power_logger/power_logger.dart';
import 'package:tobias/tobias.dart';
enum PAYTYPE {
///
ALI,
///
WX,
///
CASH,
///pos
POS
}
class PayUtil {
void resultSatus(String status) {
switch (status) {
case '8000':
BotToast.showText(text: '正在处理中');
break;
case '4000':
BotToast.showText(text: '订单支付失败');
break;
case '5000':
BotToast.showText(text: '重复请求');
break;
case '6001':
BotToast.showText(text: ' 用户中途取消');
break;
case '6002':
BotToast.showText(text: '网络连接出错');
break;
case '6004':
BotToast.showText(text: '支付结果未知,请查询商户订单列表中订单的支付状态');
break;
default:
BotToast.showText(text: '其他支付错误');
break;
}
}
String _resultStatus = '';
///
Future<bool> callAliPay(String order, String path) async {
Map<dynamic, dynamic> result = await aliPay(order);
_resultStatus = result['resultStatus'];
if (_resultStatus == '9000') {
String _res = result['result'];
PayModel _model = PayModel.fromJson(jsonDecode(_res));
bool _confirmResult = await _confirmPayResult(
path, _model.aliPayTradeAppPayResponse.outTradeNo);
return _confirmResult;
} else {
resultSatus(_resultStatus);
return false;
}
}
Future<bool> _confirmPayResult(String path, String code) async {
try {
int status = 0;
for (var i = 0; i < 3; i++) {
await Future.delayed(Duration(milliseconds: 1000), () async {
Response response = await NetUtil().dio!.get(path, queryParameters: {
"code": code,
});
status = response.data['status'] as int;
});
if (status == 2) {
break;
}
}
if (status == 2) {
BotToast.showText(text: '交易成功');
return true;
} else {
BotToast.showText(text: '交易失败 错误码${status}');
return false;
}
} catch (e) {
BotToast.showText(text: '网络请求错误');
LoggerData.addData(e);
return false;
}
}
}

@ -236,7 +236,7 @@ class _LifePayDetailPageState extends State<LifePayDetailPage> {
fontWeight: FontWeight.bold),
children: [
TextSpan(
text: '$_payTotal',
text: '${_payTotal.toStringAsFixed(2)}',
style: TextStyle(
color: kDangerColor,
fontSize: 32.sp,

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flustars/flustars.dart';
import 'package:get/get.dart';
import 'package:jpush_flutter/jpush_flutter.dart';
import 'package:power_logger/power_logger.dart';
import 'package:provider/provider.dart';
import 'package:aku_community/constants/api.dart';
@ -52,7 +53,11 @@ class UserProvider extends ChangeNotifier {
Future updateProfile() async {
_userInfoModel = await SignFunc.getUserInfo();
if (_userInfoModel != null && !kIsWeb && !Platform.isMacOS) {
await JPush().setAlias(_userInfoModel?.id.toString() ?? '');
try {
await JPush().setAlias(_userInfoModel!.id.toString());
} catch (e) {
LoggerData.addData(e);
}
}
notifyListeners();
}

@ -46,8 +46,7 @@ class _HomeNotificationState extends State<HomeNotification> {
.toList(),
repeatForever: true,
),
),
Spacer(),
).expand(),
MaterialButton(
shape: StadiumBorder(),
padding: EdgeInsets.symmetric(horizontal: 12.w),

@ -81,7 +81,6 @@ class _GoodsOrderDetailPageState extends State<GoodsOrderDetailPage> {
),
bottomNavi: BottomButton(
onPressed: () async {
final cancel = BotToast.showLoading();
BaseModel baseModel = await NetUtil().post(
API.market.appointment,

@ -13,7 +13,7 @@ class HouseFunc {
}
///
static Future get passedHouses async{
static Future<List<PassedHouseListModel>> get passedHouses async{
BaseModel model = await NetUtil().get(API.user.passedHouseList);
if (!model.status!) return [];
return (model.data as List).map((e) => PassedHouseListModel.fromJson(e)).toList();

@ -1061,6 +1061,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.0"
tobias:
dependency: "direct main"
description:
name: tobias
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
typed_data:
dependency: transitive
description:

@ -37,6 +37,9 @@ dependencies:
#用户存储路径
path_provider: ^2.0.1
#支付宝支付功能
tobias: ^2.1.0
#微信支付
fluwx: ^3.4.2
get: ^4.1.4
velocity_x: ^3.0.0

@ -41,3 +41,9 @@ void gen() async {
arguments: ['build'],
);
}
@Task('build runner clean')
void genClean() async {
await Pub.runAsync('build_runner',
arguments: ['build', '--delete-conflicting-outputs']);
}

Loading…
Cancel
Save