Merge branch 'dev_chad_v1.0' into 'dev_reason_v1.0'
Dev chad v1.0 See merge request !3
Showing
12 changed files
with
188 additions
and
20 deletions
| ... | @@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) { | ... | @@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) { |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | android { | 34 | android { |
| 35 | - compileSdkVersion 32 | 35 | + compileSdkVersion 33 |
| 36 | buildToolsVersion "32" | 36 | buildToolsVersion "32" |
| 37 | 37 | ||
| 38 | compileOptions { | 38 | compileOptions { | ... | ... |
| ... | @@ -27,7 +27,7 @@ PODS: | ... | @@ -27,7 +27,7 @@ PODS: |
| 27 | - Flutter | 27 | - Flutter |
| 28 | - flutter_native_splash (0.0.1): | 28 | - flutter_native_splash (0.0.1): |
| 29 | - Flutter | 29 | - Flutter |
| 30 | - - flutter_secure_storage (3.3.1): | 30 | + - flutter_secure_storage (6.0.0): |
| 31 | - Flutter | 31 | - Flutter |
| 32 | - flutter_sound (9.2.13): | 32 | - flutter_sound (9.2.13): |
| 33 | - Flutter | 33 | - Flutter |
| ... | @@ -53,6 +53,7 @@ PODS: | ... | @@ -53,6 +53,7 @@ PODS: |
| 53 | - Flutter | 53 | - Flutter |
| 54 | - in_app_purchase_storekit (0.0.1): | 54 | - in_app_purchase_storekit (0.0.1): |
| 55 | - Flutter | 55 | - Flutter |
| 56 | + - FlutterMacOS | ||
| 56 | - integration_test (0.0.1): | 57 | - integration_test (0.0.1): |
| 57 | - Flutter | 58 | - Flutter |
| 58 | - JCore (3.2.5) | 59 | - JCore (3.2.5) |
| ... | @@ -220,7 +221,7 @@ SPEC CHECKSUMS: | ... | @@ -220,7 +221,7 @@ SPEC CHECKSUMS: |
| 220 | flutter_facebook_auth: c69f4e643b1d9cc9063ec87c9411bd9ec268108f | 221 | flutter_facebook_auth: c69f4e643b1d9cc9063ec87c9411bd9ec268108f |
| 221 | flutter_inapp_purchase: 5c6a1ac3f11b11d0c8c0321c0c41c1f05805e4c8 | 222 | flutter_inapp_purchase: 5c6a1ac3f11b11d0c8c0321c0c41c1f05805e4c8 |
| 222 | flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef | 223 | flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef |
| 223 | - flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec | 224 | + flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be |
| 224 | flutter_sound: c60effa2a350fb977885f0db2fbc4c1ad5160900 | 225 | flutter_sound: c60effa2a350fb977885f0db2fbc4c1ad5160900 |
| 225 | flutter_sound_core: 26c10e5832e76aaacfae252d8925232281c486ae | 226 | flutter_sound_core: 26c10e5832e76aaacfae252d8925232281c486ae |
| 226 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a | 227 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a |
| ... | @@ -229,7 +230,7 @@ SPEC CHECKSUMS: | ... | @@ -229,7 +230,7 @@ SPEC CHECKSUMS: |
| 229 | image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98 | 230 | image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98 |
| 230 | image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 | 231 | image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 |
| 231 | image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb | 232 | image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb |
| 232 | - in_app_purchase_storekit: d7fcf4646136ec258e237872755da8ea6c1b6096 | 233 | + in_app_purchase_storekit: 6b297e2b5eab9fa3251a492d57301722e4132a71 |
| 233 | integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5 | 234 | integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5 |
| 234 | JCore: 4c9febdfdb1a5675ab361bc1f06c0905391d7b23 | 235 | JCore: 4c9febdfdb1a5675ab361bc1f06c0905391d7b23 |
| 235 | JPush: 2caabdb6d62d009bc07a9bd115d03c7c42512b5e | 236 | JPush: 2caabdb6d62d009bc07a9bd115d03c7c42512b5e |
| ... | @@ -252,4 +253,4 @@ SPEC CHECKSUMS: | ... | @@ -252,4 +253,4 @@ SPEC CHECKSUMS: |
| 252 | 253 | ||
| 253 | PODFILE CHECKSUM: 7d714a5ac7fda1315bc261738086cf00fa98c7e3 | 254 | PODFILE CHECKSUM: 7d714a5ac7fda1315bc261738086cf00fa98c7e3 |
| 254 | 255 | ||
| 255 | -COCOAPODS: 1.11.3 | 256 | +COCOAPODS: 1.11.2 | ... | ... |
ios/Runner/Info-Profile.plist
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | +<plist version="1.0"> | ||
| 4 | +<dict> | ||
| 5 | + <key>CFBundleDevelopmentRegion</key> | ||
| 6 | + <string>$(DEVELOPMENT_LANGUAGE)</string> | ||
| 7 | + <key>CFBundleDisplayName</key> | ||
| 8 | + <string>一言临境</string> | ||
| 9 | + <key>CFBundleExecutable</key> | ||
| 10 | + <string>$(EXECUTABLE_NAME)</string> | ||
| 11 | + <key>CFBundleIdentifier</key> | ||
| 12 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
| 13 | + <key>CFBundleInfoDictionaryVersion</key> | ||
| 14 | + <string>6.0</string> | ||
| 15 | + <key>CFBundleName</key> | ||
| 16 | + <string>Parlando</string> | ||
| 17 | + <key>CFBundlePackageType</key> | ||
| 18 | + <string>APPL</string> | ||
| 19 | + <key>CFBundleShortVersionString</key> | ||
| 20 | + <string>$(FLUTTER_BUILD_NAME)</string> | ||
| 21 | + <key>CFBundleSignature</key> | ||
| 22 | + <string>????</string> | ||
| 23 | + <key>CFBundleVersion</key> | ||
| 24 | + <string>$(FLUTTER_BUILD_NUMBER)</string> | ||
| 25 | + <key>LSRequiresIPhoneOS</key> | ||
| 26 | + <true/> | ||
| 27 | + <key>NSAppTransportSecurity</key> | ||
| 28 | + <dict> | ||
| 29 | + <key>NSAllowsArbitraryLoads</key> | ||
| 30 | + <true/> | ||
| 31 | + </dict> | ||
| 32 | + <key>NSMicrophoneUsageDescription</key> | ||
| 33 | + <string>打开话筒</string> | ||
| 34 | + <key>UILaunchStoryboardName</key> | ||
| 35 | + <string>LaunchScreen</string> | ||
| 36 | + <key>UIMainStoryboardFile</key> | ||
| 37 | + <string>Main</string> | ||
| 38 | + <key>UIStatusBarHidden</key> | ||
| 39 | + <false/> | ||
| 40 | + <key>UISupportedInterfaceOrientations</key> | ||
| 41 | + <array> | ||
| 42 | + <string>UIInterfaceOrientationPortrait</string> | ||
| 43 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
| 44 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
| 45 | + </array> | ||
| 46 | + <key>UISupportedInterfaceOrientations~ipad</key> | ||
| 47 | + <array> | ||
| 48 | + <string>UIInterfaceOrientationPortrait</string> | ||
| 49 | + <string>UIInterfaceOrientationPortraitUpsideDown</string> | ||
| 50 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
| 51 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
| 52 | + </array> | ||
| 53 | + <key>UIViewControllerBasedStatusBarAppearance</key> | ||
| 54 | + <false/> | ||
| 55 | +</dict> | ||
| 56 | +</plist> |
| ... | @@ -24,4 +24,19 @@ class OrderApi extends BaseApi { | ... | @@ -24,4 +24,19 @@ class OrderApi extends BaseApi { |
| 24 | return json.decode(value.data); | 24 | return json.decode(value.data); |
| 25 | }); | 25 | }); |
| 26 | } | 26 | } |
| 27 | + | ||
| 28 | + Future<dynamic> verifyOrder(String orderId, String type, String token, {Map<String, dynamic>? others}) { | ||
| 29 | + var data = { | ||
| 30 | + "order_sn": orderId, | ||
| 31 | + "pay_type": type, | ||
| 32 | + "token": token, | ||
| 33 | + "others": others ?? {}, | ||
| 34 | + }; | ||
| 35 | + return post("pay", data: data).then((value) { | ||
| 36 | + if (TextUtil.isEmpty(value.data)) { | ||
| 37 | + return {}; | ||
| 38 | + } | ||
| 39 | + return value.data; | ||
| 40 | + }); | ||
| 41 | + } | ||
| 27 | } | 42 | } | ... | ... |
| 1 | +import 'dart:async'; | ||
| 2 | + | ||
| 1 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
| 2 | import 'package:flutter_easyloading/flutter_easyloading.dart'; | 4 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
| 3 | 5 | ||
| 4 | abstract class BaseState<T extends StatefulWidget> extends State<T> { | 6 | abstract class BaseState<T extends StatefulWidget> extends State<T> { |
| 5 | bool _isFirstBuild = true; | 7 | bool _isFirstBuild = true; |
| 8 | + List<Timer> delayTimers = []; | ||
| 6 | 9 | ||
| 7 | @override | 10 | @override |
| 8 | Widget build(BuildContext context) { | 11 | Widget build(BuildContext context) { |
| ... | @@ -13,6 +16,11 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> { | ... | @@ -13,6 +16,11 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> { |
| 13 | return buildBody(context); | 16 | return buildBody(context); |
| 14 | } | 17 | } |
| 15 | 18 | ||
| 19 | + postDelay(VoidCallback fn, int delayTime) { | ||
| 20 | + var delayTimer = Timer(Duration(milliseconds: delayTime), fn); | ||
| 21 | + delayTimers.add(delayTimer); | ||
| 22 | + } | ||
| 23 | + | ||
| 16 | Widget buildBody(BuildContext context); | 24 | Widget buildBody(BuildContext context); |
| 17 | 25 | ||
| 18 | void onFirstBuildBody(BuildContext context) {} | 26 | void onFirstBuildBody(BuildContext context) {} |
| ... | @@ -32,4 +40,12 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> { | ... | @@ -32,4 +40,12 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> { |
| 32 | Widget buildLoading() { | 40 | Widget buildLoading() { |
| 33 | return const Center(child: CircularProgressIndicator()); | 41 | return const Center(child: CircularProgressIndicator()); |
| 34 | } | 42 | } |
| 43 | + | ||
| 44 | + @override | ||
| 45 | + void dispose() { | ||
| 46 | + super.dispose(); | ||
| 47 | + for (var element in delayTimers) { | ||
| 48 | + element.cancel(); | ||
| 49 | + } | ||
| 50 | + } | ||
| 35 | } | 51 | } | ... | ... |
| ... | @@ -68,6 +68,10 @@ MembershipData $MembershipDataFromJson(Map<String, dynamic> json) { | ... | @@ -68,6 +68,10 @@ MembershipData $MembershipDataFromJson(Map<String, dynamic> json) { |
| 68 | if (videoCover != null) { | 68 | if (videoCover != null) { |
| 69 | membershipData.videoCover = videoCover; | 69 | membershipData.videoCover = videoCover; |
| 70 | } | 70 | } |
| 71 | + final String? expireVipAt = jsonConvert.convert<String>(json['expire_vip_time']); | ||
| 72 | + if (videoCover != null) { | ||
| 73 | + membershipData.expireVipAt = expireVipAt; | ||
| 74 | + } | ||
| 71 | final String? terminal = jsonConvert.convert<String>(json['terminal']); | 75 | final String? terminal = jsonConvert.convert<String>(json['terminal']); |
| 72 | if (terminal != null) { | 76 | if (terminal != null) { |
| 73 | membershipData.terminal = terminal; | 77 | membershipData.terminal = terminal; |
| ... | @@ -105,6 +109,7 @@ Map<String, dynamic> $MembershipDataToJson(MembershipData entity) { | ... | @@ -105,6 +109,7 @@ Map<String, dynamic> $MembershipDataToJson(MembershipData entity) { |
| 105 | data['bg_images'] = entity.bgImages; | 109 | data['bg_images'] = entity.bgImages; |
| 106 | data['video_url'] = entity.videoUrl; | 110 | data['video_url'] = entity.videoUrl; |
| 107 | data['video_cover'] = entity.videoCover; | 111 | data['video_cover'] = entity.videoCover; |
| 112 | + data['expire_vip_time'] = entity.expireVipAt; | ||
| 108 | data['terminal'] = entity.terminal; | 113 | data['terminal'] = entity.terminal; |
| 109 | data['state'] = entity.state; | 114 | data['state'] = entity.state; |
| 110 | data['created_at'] = entity.createdAt; | 115 | data['created_at'] = entity.createdAt; | ... | ... |
| ... | @@ -42,6 +42,8 @@ class MembershipData { | ... | @@ -42,6 +42,8 @@ class MembershipData { |
| 42 | String? createdAt; | 42 | String? createdAt; |
| 43 | @JSONField(name: "updated_at") | 43 | @JSONField(name: "updated_at") |
| 44 | String? updatedAt; | 44 | String? updatedAt; |
| 45 | + @JSONField(name: "expire_vip_time") | ||
| 46 | + String? expireVipAt; | ||
| 45 | @JSONField(name: "is_vip") | 47 | @JSONField(name: "is_vip") |
| 46 | int? isVip; | 48 | int? isVip; |
| 47 | @JSONField(name: "goods_list") | 49 | @JSONField(name: "goods_list") | ... | ... |
| ... | @@ -41,12 +41,20 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO | ... | @@ -41,12 +41,20 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO |
| 41 | super.initState(); | 41 | super.initState(); |
| 42 | PaymentSdk.instance.initState(onPaySuccess: () { | 42 | PaymentSdk.instance.initState(onPaySuccess: () { |
| 43 | hideLoading(); | 43 | hideLoading(); |
| 44 | + toast("购买成功, 请等待订阅生效"); | ||
| 45 | + postDelay(() { | ||
| 46 | + refreshData(); | ||
| 47 | + }, 1000); | ||
| 48 | + print("onPaySuccess"); | ||
| 44 | }, onCancel: () { | 49 | }, onCancel: () { |
| 45 | hideLoading(); | 50 | hideLoading(); |
| 51 | + print("onCancel"); | ||
| 46 | }, onFailed: () { | 52 | }, onFailed: () { |
| 47 | hideLoading(); | 53 | hideLoading(); |
| 54 | + print("onFailed"); | ||
| 48 | }, onPending: () { | 55 | }, onPending: () { |
| 49 | - toast("订单Pending"); | 56 | + showLoading(); |
| 57 | + print("onPending"); | ||
| 50 | }); | 58 | }); |
| 51 | PaymentSdk.instance.queryProducts().then((value) { | 59 | PaymentSdk.instance.queryProducts().then((value) { |
| 52 | _products.clear(); | 60 | _products.clear(); |
| ... | @@ -54,14 +62,18 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO | ... | @@ -54,14 +62,18 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO |
| 54 | setState(() {}); | 62 | setState(() {}); |
| 55 | }); | 63 | }); |
| 56 | if (SpUtil.containsKey(Constant.userToken)!) { | 64 | if (SpUtil.containsKey(Constant.userToken)!) { |
| 57 | - showLoading(); | 65 | + refreshData(); |
| 58 | - Provider.of<MembershipViewProvider>(context, listen: false).setSelectedMembership(null); | ||
| 59 | - Provider.of<MembershipViewProvider>(context, listen: false).fetchMembershipData('0'); | ||
| 60 | } else { | 66 | } else { |
| 61 | NavigatorUtils.push(context, LoginRouter.loginPage, replace: true); | 67 | NavigatorUtils.push(context, LoginRouter.loginPage, replace: true); |
| 62 | } | 68 | } |
| 63 | } | 69 | } |
| 64 | 70 | ||
| 71 | + void refreshData() { | ||
| 72 | + showLoading(); | ||
| 73 | + Provider.of<MembershipViewProvider>(context, listen: false).setSelectedMembership(null); | ||
| 74 | + Provider.of<MembershipViewProvider>(context, listen: false).fetchMembershipData('0'); | ||
| 75 | + } | ||
| 76 | + | ||
| 65 | @override | 77 | @override |
| 66 | Widget buildBody(BuildContext context) { | 78 | Widget buildBody(BuildContext context) { |
| 67 | ///响应数据 | 79 | ///响应数据 |
| ... | @@ -120,7 +132,7 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO | ... | @@ -120,7 +132,7 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO |
| 120 | children: [ | 132 | children: [ |
| 121 | Text(mb?.title ?? "一言会员", style: TextStyle(fontSize: 18.px, color: Colors.white)), | 133 | Text(mb?.title ?? "一言会员", style: TextStyle(fontSize: 18.px, color: Colors.white)), |
| 122 | Gaps.vGap24, | 134 | Gaps.vGap24, |
| 123 | - mb?.goodsList?.isNotEmpty == true ? buildProductWidget(mb) : const GFLoader(), | 135 | + mb?.goodsList?.isNotEmpty == true ? buildProductWidget(mb) : buildLoadingOrSuccess(mb), |
| 124 | Gaps.vGap24, | 136 | Gaps.vGap24, |
| 125 | Text(mb?.intro ?? "一言介绍", style: TextStyle(fontSize: 14.px, color: Colors.white)), | 137 | Text(mb?.intro ?? "一言介绍", style: TextStyle(fontSize: 14.px, color: Colors.white)), |
| 126 | Gaps.vGap10, | 138 | Gaps.vGap10, |
| ... | @@ -208,7 +220,10 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO | ... | @@ -208,7 +220,10 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO |
| 208 | ), | 220 | ), |
| 209 | Container(width: 0.6, height: 15.0, color: Colours.line), | 221 | Container(width: 0.6, height: 15.0, color: Colours.line), |
| 210 | TextButton( | 222 | TextButton( |
| 211 | - onPressed: () {}, | 223 | + onPressed: () { |
| 224 | + PaymentSdk.instance.restore(); | ||
| 225 | + showLoading(); | ||
| 226 | + }, | ||
| 212 | child: Text( | 227 | child: Text( |
| 213 | "恢复购买", | 228 | "恢复购买", |
| 214 | style: TextStyle(fontSize: 14.px, color: Colors.white), | 229 | style: TextStyle(fontSize: 14.px, color: Colors.white), |
| ... | @@ -223,4 +238,22 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO | ... | @@ -223,4 +238,22 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO |
| 223 | PaymentSdk.instance.dispose(); | 238 | PaymentSdk.instance.dispose(); |
| 224 | super.dispose(); | 239 | super.dispose(); |
| 225 | } | 240 | } |
| 241 | + | ||
| 242 | + buildLoadingOrSuccess(MembershipData? mb) { | ||
| 243 | + if (mb?.isVip == 1) { | ||
| 244 | + return Column( | ||
| 245 | + children: [ | ||
| 246 | + Text( | ||
| 247 | + "过期时间:", | ||
| 248 | + style: TextStyle(fontSize: 14.px, color: Colors.white), | ||
| 249 | + ), | ||
| 250 | + Text( | ||
| 251 | + mb?.expireVipAt ?? "", | ||
| 252 | + style: TextStyle(fontSize: 14.px, color: Colors.white), | ||
| 253 | + ) | ||
| 254 | + ], | ||
| 255 | + ); | ||
| 256 | + } | ||
| 257 | + return const GFLoader(); | ||
| 258 | + } | ||
| 226 | } | 259 | } | ... | ... |
| ... | @@ -4,8 +4,12 @@ import 'package:Parlando/apis/api_order.dart'; | ... | @@ -4,8 +4,12 @@ import 'package:Parlando/apis/api_order.dart'; |
| 4 | import 'package:Parlando/membership/models/membership_entity.dart'; | 4 | import 'package:Parlando/membership/models/membership_entity.dart'; |
| 5 | import 'package:common_utils/common_utils.dart'; | 5 | import 'package:common_utils/common_utils.dart'; |
| 6 | import 'package:in_app_purchase/in_app_purchase.dart'; | 6 | import 'package:in_app_purchase/in_app_purchase.dart'; |
| 7 | +import 'package:in_app_purchase_android/in_app_purchase_android.dart'; | ||
| 8 | +import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart'; | ||
| 7 | 9 | ||
| 8 | class PaymentSdk { | 10 | class PaymentSdk { |
| 11 | + var currentOrder; | ||
| 12 | + | ||
| 9 | PaymentSdk._privateConstructor(); | 13 | PaymentSdk._privateConstructor(); |
| 10 | 14 | ||
| 11 | static final PaymentSdk _instance = PaymentSdk._privateConstructor(); | 15 | static final PaymentSdk _instance = PaymentSdk._privateConstructor(); |
| ... | @@ -59,6 +63,7 @@ class PaymentSdk { | ... | @@ -59,6 +63,7 @@ class PaymentSdk { |
| 59 | onFailed?.call(); | 63 | onFailed?.call(); |
| 60 | return; | 64 | return; |
| 61 | } | 65 | } |
| 66 | + currentOrder = orderId; | ||
| 62 | final PurchaseParam purchaseParam = PurchaseParam(productDetails: details, applicationUserName: orderId); | 67 | final PurchaseParam purchaseParam = PurchaseParam(productDetails: details, applicationUserName: orderId); |
| 63 | if (_isConsumable(details)) { | 68 | if (_isConsumable(details)) { |
| 64 | InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam); | 69 | InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam); |
| ... | @@ -97,7 +102,30 @@ class PaymentSdk { | ... | @@ -97,7 +102,30 @@ class PaymentSdk { |
| 97 | } | 102 | } |
| 98 | 103 | ||
| 99 | void _deliverProduct(PurchaseDetails purchaseDetails) { | 104 | void _deliverProduct(PurchaseDetails purchaseDetails) { |
| 100 | - onPaySuccess?.call(); | 105 | + String type = ""; |
| 106 | + Map<String, dynamic> otherField = {}; | ||
| 107 | + if (purchaseDetails is GooglePlayPurchaseDetails) { | ||
| 108 | + currentOrder = purchaseDetails.billingClientPurchase.obfuscatedAccountId; | ||
| 109 | + type = "google"; | ||
| 110 | + otherField["google"] = { | ||
| 111 | + "originalJson": purchaseDetails.billingClientPurchase.originalJson, | ||
| 112 | + }; | ||
| 113 | + } | ||
| 114 | + if (purchaseDetails is AppStorePurchaseDetails) { | ||
| 115 | + type = "apple"; | ||
| 116 | + otherField["apple"] = { | ||
| 117 | + "transactionIdentifier": purchaseDetails.skPaymentTransaction.transactionIdentifier, | ||
| 118 | + "originalTransactionIdentifier": | ||
| 119 | + purchaseDetails.skPaymentTransaction.originalTransaction?.transactionIdentifier ?? "", | ||
| 120 | + }; | ||
| 121 | + } | ||
| 122 | + var serverVerifyStr = purchaseDetails.verificationData.serverVerificationData; | ||
| 123 | + var verifySource = purchaseDetails.verificationData.source; | ||
| 124 | + otherField["source"] = verifySource; | ||
| 125 | + OrderApi.request.verifyOrder(currentOrder, type, serverVerifyStr, others: otherField).then((value) { | ||
| 126 | + if (value != null) {} | ||
| 127 | + onPaySuccess?.call(); | ||
| 128 | + }); | ||
| 101 | } | 129 | } |
| 102 | 130 | ||
| 103 | void _handleInvalidPurchase(PurchaseDetails purchaseDetails) { | 131 | void _handleInvalidPurchase(PurchaseDetails purchaseDetails) { |
| ... | @@ -109,7 +137,7 @@ class PaymentSdk { | ... | @@ -109,7 +137,7 @@ class PaymentSdk { |
| 109 | } | 137 | } |
| 110 | 138 | ||
| 111 | bool _isConsumable(ProductDetails details) { | 139 | bool _isConsumable(ProductDetails details) { |
| 112 | - return true; | 140 | + return false; |
| 113 | } | 141 | } |
| 114 | 142 | ||
| 115 | void restore() { | 143 | void restore() { | ... | ... |
| 1 | import 'dart:async'; | 1 | import 'dart:async'; |
| 2 | import 'dart:convert'; | 2 | import 'dart:convert'; |
| 3 | +import 'package:Parlando/base/base_state.dart'; | ||
| 3 | import 'package:Parlando/extension/widget_ext.dart'; | 4 | import 'package:Parlando/extension/widget_ext.dart'; |
| 4 | import 'package:Parlando/models/nearby_response.dart' as nearby; | 5 | import 'package:Parlando/models/nearby_response.dart' as nearby; |
| 5 | import 'package:Parlando/routers/fluro_navigator.dart'; | 6 | import 'package:Parlando/routers/fluro_navigator.dart'; |
| ... | @@ -20,7 +21,7 @@ class AddressSelectPage extends StatefulWidget { | ... | @@ -20,7 +21,7 @@ class AddressSelectPage extends StatefulWidget { |
| 20 | AddressSelectPageState createState() => AddressSelectPageState(); | 21 | AddressSelectPageState createState() => AddressSelectPageState(); |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 23 | -class AddressSelectPageState extends State<AddressSelectPage> { | 24 | +class AddressSelectPageState extends BaseState<AddressSelectPage> { |
| 24 | List<nearby.Results> _nearByList = []; | 25 | List<nearby.Results> _nearByList = []; |
| 25 | final ScrollController _controller = ScrollController(); | 26 | final ScrollController _controller = ScrollController(); |
| 26 | LatLng? _center; | 27 | LatLng? _center; |
| ... | @@ -32,10 +33,10 @@ class AddressSelectPageState extends State<AddressSelectPage> { | ... | @@ -32,10 +33,10 @@ class AddressSelectPageState extends State<AddressSelectPage> { |
| 32 | String apiKey = "AIzaSyDQZsMULyO-UtiSht4_MFi1uHT4BIqasjw"; | 33 | String apiKey = "AIzaSyDQZsMULyO-UtiSht4_MFi1uHT4BIqasjw"; |
| 33 | nearby.NearbyPlacesResponse nearbyPlacesResponse = nearby.NearbyPlacesResponse(); | 34 | nearby.NearbyPlacesResponse nearbyPlacesResponse = nearby.NearbyPlacesResponse(); |
| 34 | 35 | ||
| 35 | - | ||
| 36 | @override | 36 | @override |
| 37 | void initState() { | 37 | void initState() { |
| 38 | super.initState(); | 38 | super.initState(); |
| 39 | + showLoading(); | ||
| 39 | _getCurrentLocation(); | 40 | _getCurrentLocation(); |
| 40 | } | 41 | } |
| 41 | 42 | ||
| ... | @@ -81,11 +82,12 @@ class AddressSelectPageState extends State<AddressSelectPage> { | ... | @@ -81,11 +82,12 @@ class AddressSelectPageState extends State<AddressSelectPage> { |
| 81 | isLoading = false; | 82 | isLoading = false; |
| 82 | }); | 83 | }); |
| 83 | buildMarkers(); | 84 | buildMarkers(); |
| 85 | + hideLoading(); | ||
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | void _onMapCreated(GoogleMapController controller) { | 88 | void _onMapCreated(GoogleMapController controller) { |
| 87 | mapController = controller; | 89 | mapController = controller; |
| 88 | - getNearbyPlaces(""); | 90 | + buildMarkers(); |
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | void _goToCurrentCenter() { | 93 | void _goToCurrentCenter() { |
| ... | @@ -95,7 +97,7 @@ class AddressSelectPageState extends State<AddressSelectPage> { | ... | @@ -95,7 +97,7 @@ class AddressSelectPageState extends State<AddressSelectPage> { |
| 95 | } | 97 | } |
| 96 | 98 | ||
| 97 | @override | 99 | @override |
| 98 | - Widget build(BuildContext context) { | 100 | + Widget buildBody(BuildContext context) { |
| 99 | var loaderView = const GFLoader().expanded(flex: 11); | 101 | var loaderView = const GFLoader().expanded(flex: 11); |
| 100 | Widget realList = ListView.separated( | 102 | Widget realList = ListView.separated( |
| 101 | controller: _controller, | 103 | controller: _controller, |
| ... | @@ -113,6 +115,7 @@ class AddressSelectPageState extends State<AddressSelectPage> { | ... | @@ -113,6 +115,7 @@ class AddressSelectPageState extends State<AddressSelectPage> { |
| 113 | }, | 115 | }, |
| 114 | ).expanded(flex: 11); | 116 | ).expanded(flex: 11); |
| 115 | if (_nearByList.isEmpty) { | 117 | if (_nearByList.isEmpty) { |
| 118 | + print("isLoading $isLoading _nearByList ${_nearByList.length}"); | ||
| 116 | realList = const Center(child: Text("没有找到任何地点")).expanded(flex: 11); | 119 | realList = const Center(child: Text("没有找到任何地点")).expanded(flex: 11); |
| 117 | } | 120 | } |
| 118 | var listHolder = isLoading ? loaderView : realList; | 121 | var listHolder = isLoading ? loaderView : realList; |
| ... | @@ -224,15 +227,24 @@ class _AddressItem extends StatelessWidget { | ... | @@ -224,15 +227,24 @@ class _AddressItem extends StatelessWidget { |
| 224 | 227 | ||
| 225 | @override | 228 | @override |
| 226 | Widget build(BuildContext context) { | 229 | Widget build(BuildContext context) { |
| 230 | + var styleMain = TextStyle(color: Colors.black87); | ||
| 231 | + var styleSub = TextStyle(color: Colors.black45); | ||
| 227 | return InkWell( | 232 | return InkWell( |
| 228 | onTap: onTap, | 233 | onTap: onTap, |
| 229 | child: Container( | 234 | child: Container( |
| 230 | alignment: Alignment.centerLeft, | 235 | alignment: Alignment.centerLeft, |
| 231 | padding: const EdgeInsets.symmetric(horizontal: 16.0), | 236 | padding: const EdgeInsets.symmetric(horizontal: 16.0), |
| 232 | - height: 50.0, | ||
| 233 | child: Row( | 237 | child: Row( |
| 238 | + crossAxisAlignment: CrossAxisAlignment.center, | ||
| 234 | children: <Widget>[ | 239 | children: <Widget>[ |
| 235 | - Text('${data.name}').expanded(), | 240 | + Column( |
| 241 | + mainAxisAlignment: MainAxisAlignment.start, | ||
| 242 | + crossAxisAlignment: CrossAxisAlignment.start, | ||
| 243 | + children: [ | ||
| 244 | + Text('${data.name}', style: styleMain), | ||
| 245 | + Text('${data.vicinity}', style: styleSub), | ||
| 246 | + ], | ||
| 247 | + ).paddingTopBottom(10).expanded(), | ||
| 236 | Visibility(visible: isSelected, child: const Icon(Icons.done, color: Colors.blue)) | 248 | Visibility(visible: isSelected, child: const Icon(Icons.done, color: Colors.blue)) |
| 237 | ], | 249 | ], |
| 238 | ), | 250 | ), | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev | ... | @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev |
| 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. | 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. |
| 16 | # Read more about iOS versioning at | 16 | # Read more about iOS versioning at |
| 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html |
| 18 | -version: 1.0.0+13 | 18 | +version: 1.0.0+15 |
| 19 | 19 | ||
| 20 | environment: | 20 | environment: |
| 21 | sdk: ">=2.16.2 <3.0.0" | 21 | sdk: ">=2.16.2 <3.0.0" | ... | ... |
-
Please register or login to post a comment