Commit ad37b6538c6ae4c2ea19c971845f4baa4cebd8d9
1 parent
e62c1a97
feat:1、完成微信支付;2、商品详情页ui优化
Showing
6 changed files
with
196 additions
and
95 deletions
lib/common/request/apis.dart
@@ -92,4 +92,7 @@ class Apis { | @@ -92,4 +92,7 @@ class Apis { | ||
92 | /// 获取阿里支付token | 92 | /// 获取阿里支付token |
93 | static const String getAliPayToken = 'pay/alipay/token'; | 93 | static const String getAliPayToken = 'pay/alipay/token'; |
94 | 94 | ||
95 | + /// 获取微信支付token | ||
96 | + static const String getWxPayToken = 'pay/wxPay/token'; | ||
97 | + | ||
95 | } | 98 | } |
lib/common/request/dao/shop_dao.dart
@@ -13,9 +13,15 @@ class ShopDao { | @@ -13,9 +13,15 @@ class ShopDao { | ||
13 | .post<Map<String, dynamic>>(Apis.createOrder, data: {'courseComboId': productEntity.id}); | 13 | .post<Map<String, dynamic>>(Apis.createOrder, data: {'courseComboId': productEntity.id}); |
14 | } | 14 | } |
15 | 15 | ||
16 | - ///获取ali支付订单信息 | 16 | + ///获取alipay支付订单信息 |
17 | static Future getAliPayToken(String orderNo) async { | 17 | static Future getAliPayToken(String orderNo) async { |
18 | return await requestClient | 18 | return await requestClient |
19 | .post<Map<String, dynamic>>(Apis.getAliPayToken, data: {'orderNo': orderNo}); | 19 | .post<Map<String, dynamic>>(Apis.getAliPayToken, data: {'orderNo': orderNo}); |
20 | } | 20 | } |
21 | + | ||
22 | + ///获取weixin支付订单信息 | ||
23 | + static Future getWxPayToken(String orderNo) async { | ||
24 | + return await requestClient | ||
25 | + .post<Map<String, dynamic>>(Apis.getWxPayToken, data: {'orderNo': orderNo}); | ||
26 | + } | ||
21 | } | 27 | } |
lib/pages/reading/bloc/reading_bloc.dart
@@ -247,7 +247,7 @@ class ReadingPageBloc extends Bloc<ReadingPageEvent, ReadingPageState> { | @@ -247,7 +247,7 @@ class ReadingPageBloc extends Bloc<ReadingPageEvent, ReadingPageState> { | ||
247 | final recordAudioUrl = currentPageData()?.recordUrl; | 247 | final recordAudioUrl = currentPageData()?.recordUrl; |
248 | _playAudio(recordAudioUrl); | 248 | _playAudio(recordAudioUrl); |
249 | } | 249 | } |
250 | - // emit(VoicePlayStateChange()); | 250 | + // emitter(VoicePlayStateChange()); |
251 | } | 251 | } |
252 | 252 | ||
253 | void _playAudio(String? audioUrl) async { | 253 | void _playAudio(String? audioUrl) async { |
@@ -358,7 +358,7 @@ class ReadingPageBloc extends Bloc<ReadingPageEvent, ReadingPageState> { | @@ -358,7 +358,7 @@ class ReadingPageBloc extends Bloc<ReadingPageEvent, ReadingPageState> { | ||
358 | OnXSVoiceStateChangeEvent event, | 358 | OnXSVoiceStateChangeEvent event, |
359 | Emitter<ReadingPageState> emitter | 359 | Emitter<ReadingPageState> emitter |
360 | ) async { | 360 | ) async { |
361 | - emit(XSVoiceTestState()); | 361 | + emitter(XSVoiceTestState()); |
362 | } | 362 | } |
363 | } | 363 | } |
364 | 364 |
lib/pages/shopping/bloc.dart
1 | +import 'dart:io'; | ||
2 | + | ||
1 | import 'package:bloc/bloc.dart'; | 3 | import 'package:bloc/bloc.dart'; |
4 | +import 'package:flutter/cupertino.dart'; | ||
2 | import 'package:fluwx/fluwx.dart'; | 5 | import 'package:fluwx/fluwx.dart'; |
3 | import 'package:tobias/tobias.dart'; | 6 | import 'package:tobias/tobias.dart'; |
4 | import 'package:wow_english/generated/json/base/json_convert_content.dart'; | 7 | import 'package:wow_english/generated/json/base/json_convert_content.dart'; |
@@ -22,6 +25,11 @@ class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> { | @@ -22,6 +25,11 @@ class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> { | ||
22 | 25 | ||
23 | PaymentChannel get curPaymentChannel => _curPaymentChannel; | 26 | PaymentChannel get curPaymentChannel => _curPaymentChannel; |
24 | 27 | ||
28 | + Fluwx? fluwx; | ||
29 | + Function(WeChatResponse)? wxPayResponseListener; | ||
30 | + bool _isWxPayListenerInitialized = false; | ||
31 | + | ||
32 | + | ||
25 | 33 | ||
26 | ShoppingBloc(this._productData) : super(ShoppingState().init()) { | 34 | ShoppingBloc(this._productData) : super(ShoppingState().init()) { |
27 | //页面初始化时刻 | 35 | //页面初始化时刻 |
@@ -66,19 +74,53 @@ class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> { | @@ -66,19 +74,53 @@ class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> { | ||
66 | Log.d("orderNo $orderNo"); | 74 | Log.d("orderNo $orderNo"); |
67 | 75 | ||
68 | if (event.paymentChannel == PaymentChannel.wechatPay) { | 76 | if (event.paymentChannel == PaymentChannel.wechatPay) { |
69 | - Fluwx fluwx = Fluwx(); | ||
70 | - fluwx.registerApi(appId: "wxd930ea5d5a228f5f", | ||
71 | - universalLink: "https://app-api.wowenglish.com.cn/.well-known/apple-app-site-association"); | ||
72 | - // fluwx.pay( | ||
73 | - // which: Payment( | ||
74 | - // appId: _orderInfo['appid'].toString(), | ||
75 | - // partnerId: _orderInfo['partnerid'].toString(), | ||
76 | - // prepayId: _orderInfo['prepayid'].toString(), | ||
77 | - // packageValue: _orderInfo['package'].toString(), | ||
78 | - // nonceStr: _orderInfo['noncestr'].toString(), | ||
79 | - // timestamp: _orderInfo['timestamp'], | ||
80 | - // sign: _orderInfo['sign'].toString(), | ||
81 | - // )); | 77 | + if (_isWxPayListenerInitialized == false) { |
78 | + _isWxPayListenerInitialized = true; | ||
79 | + fluwx = Fluwx(); | ||
80 | + fluwx?.registerApi(appId: "wx365e5a79956a450a", | ||
81 | + universalLink: "https://app-api.wowenglish.com.cn/app/"); | ||
82 | + wxPayResponseListener = (WeChatResponse response) { | ||
83 | + Log.d("wxPayResponseListener $response"); | ||
84 | + if (response is WeChatPaymentResponse) { | ||
85 | + if (response.errCode == 0) { | ||
86 | + Log.d("wxPayResponseListener response=${response.errCode}"); | ||
87 | + showToast("支付成功"); | ||
88 | + // Log.d("emitter isDone=${emitter.isDone}"); | ||
89 | + // emitter(PaySuccessState()); | ||
90 | + } else { | ||
91 | + showToast("支付失败"); | ||
92 | + } | ||
93 | + } | ||
94 | + }; | ||
95 | + fluwx?.addSubscriber(wxPayResponseListener!); | ||
96 | + } | ||
97 | + | ||
98 | + bool installed = await fluwx?.isWeChatInstalled == true; | ||
99 | + if (!installed) { | ||
100 | + // 未安装微信,请前去下载 | ||
101 | + String name = Platform.isIOS ? "AppStore" : "应用商店"; | ||
102 | + showToast("您未安装微信,请前往$name下载~"); | ||
103 | + return; | ||
104 | + } | ||
105 | + | ||
106 | + final Map<String, dynamic> wxPayOrderInfo = await ShopDao.getWxPayToken(orderNo); | ||
107 | + Log.d("wxPayOrderInfo=$wxPayOrderInfo type=${wxPayOrderInfo.runtimeType}"); | ||
108 | + final String? wxPayInfo = wxPayOrderInfo.getOrNull("appId"); | ||
109 | + if (wxPayInfo == null) { | ||
110 | + showToast("微信订单创建失败"); | ||
111 | + return; | ||
112 | + } | ||
113 | + | ||
114 | + await fluwx?.pay( | ||
115 | + which: Payment( | ||
116 | + appId: wxPayOrderInfo['appId'].toString(), | ||
117 | + partnerId: wxPayOrderInfo['partnerId'].toString(), | ||
118 | + prepayId: wxPayOrderInfo['prepayId'].toString(), | ||
119 | + packageValue: wxPayOrderInfo['packageValue'].toString(), | ||
120 | + nonceStr: wxPayOrderInfo['nonceStr'].toString(), | ||
121 | + timestamp: int.parse(wxPayOrderInfo['timeStamp']), | ||
122 | + sign: wxPayOrderInfo['sign'].toString(), | ||
123 | + )); | ||
82 | } else { | 124 | } else { |
83 | final Map<String, dynamic> aliPayOrderInfo = await ShopDao.getAliPayToken(orderNo); | 125 | final Map<String, dynamic> aliPayOrderInfo = await ShopDao.getAliPayToken(orderNo); |
84 | Log.d("aliPayOrderInfo=$aliPayOrderInfo type=${aliPayOrderInfo.runtimeType}"); | 126 | Log.d("aliPayOrderInfo=$aliPayOrderInfo type=${aliPayOrderInfo.runtimeType}"); |
@@ -95,7 +137,7 @@ class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> { | @@ -95,7 +137,7 @@ class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> { | ||
95 | // 判断resultStatus 为9000则代表支付成功 | 137 | // 判断resultStatus 为9000则代表支付成功 |
96 | if (aliPayResult.getOrNull("resultStatus") == "9000") { | 138 | if (aliPayResult.getOrNull("resultStatus") == "9000") { |
97 | showToast("支付成功"); | 139 | showToast("支付成功"); |
98 | - emit(PaySuccessState()); | 140 | + emitter(PaySuccessState()); |
99 | } else { | 141 | } else { |
100 | showToast("支付失败"); | 142 | showToast("支付失败"); |
101 | } | 143 | } |
@@ -107,6 +149,12 @@ class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> { | @@ -107,6 +149,12 @@ class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> { | ||
107 | } | 149 | } |
108 | } | 150 | } |
109 | } | 151 | } |
152 | + | ||
153 | + void dispose() { | ||
154 | + fluwx?.clearSubscribers(); | ||
155 | + // 释放资源的逻辑 | ||
156 | + debugPrint('BLoC disposed'); | ||
157 | + } | ||
110 | } | 158 | } |
111 | 159 | ||
112 | enum PaymentChannel { | 160 | enum PaymentChannel { |
lib/pages/shopping/view.dart
@@ -8,7 +8,6 @@ import 'package:wow_english/models/product_entity.dart'; | @@ -8,7 +8,6 @@ import 'package:wow_english/models/product_entity.dart'; | ||
8 | import '../../common/core/assets_const.dart'; | 8 | import '../../common/core/assets_const.dart'; |
9 | import '../../common/widgets/we_app_bar.dart'; | 9 | import '../../common/widgets/we_app_bar.dart'; |
10 | import '../../utils/image_util.dart'; | 10 | import '../../utils/image_util.dart'; |
11 | -import '../../utils/log_util.dart'; | ||
12 | import 'bloc.dart'; | 11 | import 'bloc.dart'; |
13 | import 'event.dart'; | 12 | import 'event.dart'; |
14 | import 'state.dart'; | 13 | import 'state.dart'; |
@@ -17,33 +16,36 @@ Widget buildRadioOption({ | @@ -17,33 +16,36 @@ Widget buildRadioOption({ | ||
17 | required int value, | 16 | required int value, |
18 | required ImageProvider icon, | 17 | required ImageProvider icon, |
19 | required String text, | 18 | required String text, |
20 | - required int groupValue, | ||
21 | - required ValueChanged onChanged, | 19 | + required bool isSelected, |
20 | + required ValueChanged onSelect, | ||
22 | }) { | 21 | }) { |
23 | - return Row( | ||
24 | - children: [ | ||
25 | - Image(image: icon, | ||
26 | - width: 20.0.w, | ||
27 | - height: 20.0.h, | ||
28 | - fit: BoxFit.contain), | ||
29 | - const SizedBox(width: 10.0), | ||
30 | - // Expanded( | ||
31 | - // child: Text( | ||
32 | - // text, | ||
33 | - // style: TextStyle(color: Color(0xFF333333), fontSize: 12.5.sp), | ||
34 | - // ), | ||
35 | - // ), | ||
36 | - Text( | ||
37 | - text, | ||
38 | - style: TextStyle(color: Color(0xFF333333), fontSize: 12.5.sp), | ||
39 | - ), | ||
40 | - Radio( | ||
41 | - value: value, | ||
42 | - groupValue: groupValue, | ||
43 | - onChanged: onChanged | 22 | + return |
23 | + GestureDetector( | ||
24 | + onTap: () { | ||
25 | + onSelect(value); | ||
26 | + }, | ||
27 | + child: Row( | ||
28 | + crossAxisAlignment: CrossAxisAlignment.center, | ||
29 | + children: [ | ||
30 | + Image(image: icon, width: 25.0.w, height: 25.0.h, fit: BoxFit.contain), | ||
31 | + const SizedBox(width: 10.0), | ||
32 | + Expanded( | ||
33 | + child: Text( | ||
34 | + text, | ||
35 | + style: TextStyle(color: const Color(0xFF333333), fontSize: 12.5.sp), | ||
36 | + ), | ||
37 | + ), | ||
38 | + Image( | ||
39 | + image: isSelected | ||
40 | + ? AssetImage('checked'.assetPng) | ||
41 | + : AssetImage('unchecked'.assetPng), | ||
42 | + width: 22.0.w, | ||
43 | + height: 22.0.h, | ||
44 | + ), | ||
45 | + ], | ||
44 | ), | 46 | ), |
45 | - ], | ||
46 | - ); | 47 | + ); |
48 | + | ||
47 | } | 49 | } |
48 | 50 | ||
49 | class ShoppingPage extends StatelessWidget { | 51 | class ShoppingPage extends StatelessWidget { |
@@ -55,30 +57,26 @@ class ShoppingPage extends StatelessWidget { | @@ -55,30 +57,26 @@ class ShoppingPage extends StatelessWidget { | ||
55 | Widget build(BuildContext context) { | 57 | Widget build(BuildContext context) { |
56 | return BlocProvider( | 58 | return BlocProvider( |
57 | create: (BuildContext context) => | 59 | create: (BuildContext context) => |
58 | - ShoppingBloc(productEntity) | ||
59 | - ..add(InitEvent()), | 60 | + ShoppingBloc(productEntity)..add(InitEvent()), |
60 | child: _ShoppingView(), | 61 | child: _ShoppingView(), |
61 | ); | 62 | ); |
62 | } | 63 | } |
63 | } | 64 | } |
64 | 65 | ||
65 | class _ShoppingView extends StatelessWidget { | 66 | class _ShoppingView extends StatelessWidget { |
66 | - | ||
67 | @override | 67 | @override |
68 | Widget build(BuildContext context) { | 68 | Widget build(BuildContext context) { |
69 | final bloc = BlocProvider.of<ShoppingBloc>(context); | 69 | final bloc = BlocProvider.of<ShoppingBloc>(context); |
70 | - // var title1 = bloc.productData?.name ?? ''; | ||
71 | return BlocListener<ShoppingBloc, ShoppingState>( | 70 | return BlocListener<ShoppingBloc, ShoppingState>( |
72 | listener: (context, state) { | 71 | listener: (context, state) { |
73 | - Log.d("wqf state=$state"); | ||
74 | if (state is PaySuccessState) { | 72 | if (state is PaySuccessState) { |
75 | Navigator.pop(context); | 73 | Navigator.pop(context); |
76 | } | 74 | } |
77 | }, | 75 | }, |
78 | child: Scaffold( | 76 | child: Scaffold( |
79 | - appBar: const WEAppBar( | 77 | + appBar: WEAppBar( |
80 | //标题传进来的 | 78 | //标题传进来的 |
81 | - titleText: "商品详情", | 79 | + titleText: bloc.productData?.name ?? '', |
82 | ), | 80 | ), |
83 | body: Container( | 81 | body: Container( |
84 | margin: const EdgeInsets.only(left: 80.0, top: 28.0, right: 56.0), | 82 | margin: const EdgeInsets.only(left: 80.0, top: 28.0, right: 56.0), |
@@ -87,49 +85,63 @@ class _ShoppingView extends StatelessWidget { | @@ -87,49 +85,63 @@ class _ShoppingView extends StatelessWidget { | ||
87 | children: [ | 85 | children: [ |
88 | CachedNetworkImage( | 86 | CachedNetworkImage( |
89 | imageUrl: bloc.productData?.detailPicUrl ?? '', | 87 | imageUrl: bloc.productData?.detailPicUrl ?? '', |
90 | - imageBuilder: (context, imageProvider) => | ||
91 | - Container( | ||
92 | - decoration: BoxDecoration( | ||
93 | - image: DecorationImage( | ||
94 | - image: imageProvider, | ||
95 | - fit: BoxFit.cover, | ||
96 | - ), | ||
97 | - borderRadius: BorderRadius.circular(5.0), | ||
98 | - ), | 88 | + imageBuilder: (context, imageProvider) => Container( |
89 | + decoration: BoxDecoration( | ||
90 | + image: DecorationImage( | ||
91 | + image: imageProvider, | ||
92 | + fit: BoxFit.cover, | ||
99 | ), | 93 | ), |
100 | - placeholder: (context, url) => const CircularProgressIndicator(), | 94 | + borderRadius: BorderRadius.circular(5.0), |
95 | + ), | ||
96 | + ), | ||
97 | + placeholder: (context, url) => | ||
98 | + const CircularProgressIndicator(), | ||
101 | // errorWidget: (context, url, error) => const Icon(Icons.error), | 99 | // errorWidget: (context, url, error) => const Icon(Icons.error), |
102 | height: 210.0.h, | 100 | height: 210.0.h, |
103 | width: 210.0.w, | 101 | width: 210.0.w, |
104 | ), | 102 | ), |
105 | const SizedBox(width: 35.5), | 103 | const SizedBox(width: 35.5), |
106 | - _paymentWidget(), | 104 | + Expanded(child: _paymentWidget()) |
107 | ], | 105 | ], |
108 | ), | 106 | ), |
109 | ), | 107 | ), |
110 | - ),); | 108 | + ), |
109 | + ); | ||
111 | } | 110 | } |
112 | } | 111 | } |
113 | 112 | ||
114 | -Widget _paymentWidget() => | ||
115 | - BlocBuilder<ShoppingBloc, ShoppingState> | ||
116 | - ( | 113 | +Widget _paymentWidget() => BlocBuilder<ShoppingBloc, ShoppingState>( |
117 | builder: (context, state) { | 114 | builder: (context, state) { |
118 | final bloc = BlocProvider.of<ShoppingBloc>(context); | 115 | final bloc = BlocProvider.of<ShoppingBloc>(context); |
119 | return Column( | 116 | return Column( |
120 | crossAxisAlignment: CrossAxisAlignment.start, | 117 | crossAxisAlignment: CrossAxisAlignment.start, |
121 | children: [ | 118 | children: [ |
122 | - Text('套餐价格:${bloc.productData?.price ?? ''}', | ||
123 | - style: TextStyle( | ||
124 | - color: const Color(0xFF333333), fontSize: 16.sp)), | ||
125 | - const SizedBox(height: 15.0), | ||
126 | - Text('套餐名称:${bloc.productData?.name ?? ''}', | ||
127 | - style: TextStyle( | ||
128 | - color: const Color(0xFF333333), fontSize: 16.sp)), | ||
129 | - const SizedBox(height: 15.0), | 119 | + RichText( |
120 | + text: TextSpan( | ||
121 | + children: [ | ||
122 | + TextSpan( | ||
123 | + text: '套餐价格:', | ||
124 | + style: | ||
125 | + TextStyle(color: const Color(0xFF333333), fontSize: 16.5.sp) | ||
126 | + ), | ||
127 | + TextSpan( | ||
128 | + text: '¥${bloc.productData?.price ?? ''}', | ||
129 | + style: | ||
130 | + TextStyle(color: const Color(0xFFE5262A), fontSize: 16.5.sp) | ||
131 | + ), | ||
132 | + ] | ||
133 | + ), | ||
134 | + ), | ||
135 | + const SizedBox(height: 14.5), | ||
136 | + Text( | ||
137 | + '套餐名称:${bloc.productData?.name}', | ||
138 | + style: | ||
139 | + TextStyle(color: const Color(0xFF333333), fontSize: 16.sp), | ||
140 | + maxLines: 2, | ||
141 | + ), | ||
142 | + const SizedBox(height: 14.5), | ||
130 | Container( | 143 | Container( |
131 | - padding: | ||
132 | - EdgeInsets.symmetric(horizontal: 6.w, vertical: 10.h), | 144 | + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h), |
133 | decoration: BoxDecoration( | 145 | decoration: BoxDecoration( |
134 | image: DecorationImage( | 146 | image: DecorationImage( |
135 | image: ImageUtil.getImageProviderOnDefault( | 147 | image: ImageUtil.getImageProviderOnDefault( |
@@ -138,41 +150,61 @@ Widget _paymentWidget() => | @@ -138,41 +150,61 @@ Widget _paymentWidget() => | ||
138 | child: const Text('支付方式选择', | 150 | child: const Text('支付方式选择', |
139 | style: TextStyle( | 151 | style: TextStyle( |
140 | color: Color(0xFF333333), | 152 | color: Color(0xFF333333), |
141 | - fontSize: 12, | 153 | + fontSize: 12.5, |
142 | fontFamily: 'PingFangSC-Regular')), | 154 | fontFamily: 'PingFangSC-Regular')), |
143 | ), | 155 | ), |
144 | - const SizedBox(height: 15.0), | 156 | + const SizedBox(height: 18.0), |
145 | buildRadioOption( | 157 | buildRadioOption( |
146 | value: PaymentChannel.wechatPay.payChannelType, | 158 | value: PaymentChannel.wechatPay.payChannelType, |
147 | icon: AssetImage('weixin'.assetPng), | 159 | icon: AssetImage('weixin'.assetPng), |
148 | text: PaymentChannel.wechatPay.payChannelName, | 160 | text: PaymentChannel.wechatPay.payChannelName, |
149 | - groupValue: bloc.curPaymentChannel.payChannelType, | ||
150 | - onChanged: (newValue) { | ||
151 | - bloc.add( | ||
152 | - ChangePaymentChannelEvent(PaymentChannel.wechatPay)); | 161 | + isSelected: bloc.curPaymentChannel.payChannelType == PaymentChannel.wechatPay.payChannelType, |
162 | + onSelect: (newValue) { | ||
163 | + bloc.add(ChangePaymentChannelEvent(PaymentChannel.wechatPay)); | ||
153 | }, | 164 | }, |
154 | ), | 165 | ), |
166 | + const SizedBox(height: 15.0), | ||
155 | buildRadioOption( | 167 | buildRadioOption( |
156 | value: PaymentChannel.aliPay.payChannelType, | 168 | value: PaymentChannel.aliPay.payChannelType, |
157 | icon: AssetImage('zhifubao'.assetPng), | 169 | icon: AssetImage('zhifubao'.assetPng), |
158 | text: PaymentChannel.aliPay.payChannelName, | 170 | text: PaymentChannel.aliPay.payChannelName, |
159 | - groupValue: bloc.curPaymentChannel.payChannelType, | ||
160 | - onChanged: (newValue) { | 171 | + isSelected: bloc.curPaymentChannel.payChannelType == PaymentChannel.aliPay.payChannelType, |
172 | + onSelect: (newValue) { | ||
161 | bloc.add(ChangePaymentChannelEvent(PaymentChannel.aliPay)); | 173 | bloc.add(ChangePaymentChannelEvent(PaymentChannel.aliPay)); |
162 | }, | 174 | }, |
163 | ), | 175 | ), |
164 | - const SizedBox(height: 15.0), | ||
165 | - // 确认支付按钮 | ||
166 | - InkWell( | ||
167 | - onTap: () { | ||
168 | - Log.d('点击支付按钮 ${bloc.productData}'); | ||
169 | - bloc.add(DoPayEvent(bloc.productData, bloc.curPaymentChannel)); | ||
170 | - }, | ||
171 | - child: Image( | ||
172 | - width: 125.w, | ||
173 | - height: 45.h, | ||
174 | - image: AssetImage('btn_pay'.assetPng), | ||
175 | - ), | 176 | + const SizedBox(height: 20.0), |
177 | + Row( | ||
178 | + mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
179 | + children: [ | ||
180 | + RichText( | ||
181 | + text: TextSpan( | ||
182 | + children: [ | ||
183 | + const TextSpan( | ||
184 | + text: '需支付:', | ||
185 | + style: | ||
186 | + TextStyle(color: Color(0xFF333333), fontSize: 12.5, fontFamily: 'PingFangSC-Regular') | ||
187 | + ), | ||
188 | + TextSpan( | ||
189 | + text: '¥${bloc.productData?.price ?? ''}', | ||
190 | + style: | ||
191 | + TextStyle(color: const Color(0xFFE7383B), fontSize: 41.sp, fontFamily: 'PingFangSC-Regular') | ||
192 | + ), | ||
193 | + ] | ||
194 | + ), | ||
195 | + ), | ||
196 | + // 确认支付按钮 | ||
197 | + GestureDetector( | ||
198 | + onTap: () { | ||
199 | + bloc.add(DoPayEvent(bloc.productData, bloc.curPaymentChannel)); | ||
200 | + }, | ||
201 | + child: Image( | ||
202 | + width: 105.w, | ||
203 | + height: 45.h, | ||
204 | + image: AssetImage('btn_pay'.assetPng), | ||
205 | + ), | ||
206 | + ) | ||
207 | + ], | ||
176 | ), | 208 | ), |
177 | ], | 209 | ], |
178 | ); | 210 | ); |
pubspec.yaml
@@ -142,3 +142,15 @@ tobias: | @@ -142,3 +142,15 @@ tobias: | ||
142 | url_scheme: ishowwoweng | 142 | url_scheme: ishowwoweng |
143 | ios: | 143 | ios: |
144 | ignore_security: true | 144 | ignore_security: true |
145 | + | ||
146 | +fluwx: | ||
147 | + app_id: 'wx365e5a79956a450a' | ||
148 | + debug_logging: true # Logging in debug mode. | ||
149 | + android: | ||
150 | + # interrupt_wx_request: true # Defaults to true. | ||
151 | + # flutter_activity: 'MainActivity' # Defaults to app's launcher | ||
152 | + ios: | ||
153 | + universal_link: https://app-api.wowenglish.com.cn/app/ | ||
154 | + # scene_delegate: true # Defaults to false. | ||
155 | + # no_pay: false # Set to false to disable payment. | ||
156 | + # ignore_security: true # Set to true to disable security seetings. |