ChadCSong

苹果订阅相关维护修改

......@@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) {
}
android {
compileSdkVersion 32
compileSdkVersion 33
buildToolsVersion "32"
compileOptions {
......
......@@ -27,7 +27,7 @@ PODS:
- Flutter
- flutter_native_splash (0.0.1):
- Flutter
- flutter_secure_storage (3.3.1):
- flutter_secure_storage (6.0.0):
- Flutter
- flutter_sound (9.2.13):
- Flutter
......@@ -53,6 +53,7 @@ PODS:
- Flutter
- in_app_purchase_storekit (0.0.1):
- Flutter
- FlutterMacOS
- integration_test (0.0.1):
- Flutter
- JCore (3.2.5)
......@@ -220,7 +221,7 @@ SPEC CHECKSUMS:
flutter_facebook_auth: c69f4e643b1d9cc9063ec87c9411bd9ec268108f
flutter_inapp_purchase: 5c6a1ac3f11b11d0c8c0321c0c41c1f05805e4c8
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
flutter_sound: c60effa2a350fb977885f0db2fbc4c1ad5160900
flutter_sound_core: 26c10e5832e76aaacfae252d8925232281c486ae
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
......@@ -229,7 +230,7 @@ SPEC CHECKSUMS:
image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98
image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
in_app_purchase_storekit: d7fcf4646136ec258e237872755da8ea6c1b6096
in_app_purchase_storekit: 6b297e2b5eab9fa3251a492d57301722e4132a71
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5
JCore: 4c9febdfdb1a5675ab361bc1f06c0905391d7b23
JPush: 2caabdb6d62d009bc07a9bd115d03c7c42512b5e
......@@ -252,4 +253,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 7d714a5ac7fda1315bc261738086cf00fa98c7e3
COCOAPODS: 1.11.3
COCOAPODS: 1.11.2
......
......@@ -380,14 +380,14 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = FLS6Y2LS7Z;
DEVELOPMENT_TEAM = 5PX6JTCZ6G;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = pub.yiyan.parlando.Parlando;
PRODUCT_BUNDLE_IDENTIFIER = ink.parlando.parlando;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
......@@ -509,14 +509,14 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = FLS6Y2LS7Z;
DEVELOPMENT_TEAM = 5PX6JTCZ6G;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = pub.yiyan.parlando.Parlando;
PRODUCT_BUNDLE_IDENTIFIER = ink.parlando.parlando;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
......@@ -533,14 +533,14 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = FLS6Y2LS7Z;
DEVELOPMENT_TEAM = 5PX6JTCZ6G;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = pub.yiyan.parlando.Parlando;
PRODUCT_BUNDLE_IDENTIFIER = ink.parlando.parlando;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
......
......@@ -2,12 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocalNetworkUsageDescription</key>
<string>Allow flutter app</string>
<key>NSBonjourServices</key>
<array>
<string>_dartobservatory._tcp</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
......@@ -35,6 +29,12 @@
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSBonjourServices</key>
<array>
<string>_dartobservatory._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>Allow flutter app</string>
<key>NSMicrophoneUsageDescription</key>
<string>打开话筒</string>
<key>UILaunchStoryboardName</key>
......
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
abstract class BaseState<T extends StatefulWidget> extends State<T> {
bool _isFirstBuild = true;
List<Timer> delayTimers = [];
@override
Widget build(BuildContext context) {
......@@ -13,6 +16,11 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
return buildBody(context);
}
postDelay(VoidCallback fn, int delayTime) {
var delayTimer = Timer(Duration(milliseconds: delayTime), fn);
delayTimers.add(delayTimer);
}
Widget buildBody(BuildContext context);
void onFirstBuildBody(BuildContext context) {}
......@@ -32,4 +40,12 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
Widget buildLoading() {
return const Center(child: CircularProgressIndicator());
}
@override
void dispose() {
super.dispose();
for (var element in delayTimers) {
element.cancel();
}
}
}
......
......@@ -68,6 +68,10 @@ MembershipData $MembershipDataFromJson(Map<String, dynamic> json) {
if (videoCover != null) {
membershipData.videoCover = videoCover;
}
final String? expireVipAt = jsonConvert.convert<String>(json['expire_vip_time']);
if (videoCover != null) {
membershipData.expireVipAt = expireVipAt;
}
final String? terminal = jsonConvert.convert<String>(json['terminal']);
if (terminal != null) {
membershipData.terminal = terminal;
......@@ -105,6 +109,7 @@ Map<String, dynamic> $MembershipDataToJson(MembershipData entity) {
data['bg_images'] = entity.bgImages;
data['video_url'] = entity.videoUrl;
data['video_cover'] = entity.videoCover;
data['expire_vip_time'] = entity.expireVipAt;
data['terminal'] = entity.terminal;
data['state'] = entity.state;
data['created_at'] = entity.createdAt;
......
......@@ -42,6 +42,8 @@ class MembershipData {
String? createdAt;
@JSONField(name: "updated_at")
String? updatedAt;
@JSONField(name: "expire_vip_time")
String? expireVipAt;
@JSONField(name: "is_vip")
int? isVip;
@JSONField(name: "goods_list")
......
......@@ -41,12 +41,20 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
super.initState();
PaymentSdk.instance.initState(onPaySuccess: () {
hideLoading();
toast("购买成功, 请等待订阅生效");
postDelay(() {
refreshData();
}, 1000);
print("onPaySuccess");
}, onCancel: () {
hideLoading();
print("onCancel");
}, onFailed: () {
hideLoading();
print("onFailed");
}, onPending: () {
toast("订单Pending");
showLoading();
print("onPending");
});
PaymentSdk.instance.queryProducts().then((value) {
_products.clear();
......@@ -54,14 +62,18 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
setState(() {});
});
if (SpUtil.containsKey(Constant.userToken)!) {
showLoading();
Provider.of<MembershipViewProvider>(context, listen: false).setSelectedMembership(null);
Provider.of<MembershipViewProvider>(context, listen: false).fetchMembershipData('0');
refreshData();
} else {
NavigatorUtils.push(context, LoginRouter.loginPage, replace: true);
}
}
void refreshData() {
showLoading();
Provider.of<MembershipViewProvider>(context, listen: false).setSelectedMembership(null);
Provider.of<MembershipViewProvider>(context, listen: false).fetchMembershipData('0');
}
@override
Widget buildBody(BuildContext context) {
///响应数据
......@@ -120,7 +132,7 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
children: [
Text(mb?.title ?? "一言会员", style: TextStyle(fontSize: 18.px, color: Colors.white)),
Gaps.vGap24,
mb?.goodsList?.isNotEmpty == true ? buildProductWidget(mb) : const GFLoader(),
mb?.goodsList?.isNotEmpty == true ? buildProductWidget(mb) : buildLoadingOrSuccess(mb),
Gaps.vGap24,
Text(mb?.intro ?? "一言介绍", style: TextStyle(fontSize: 14.px, color: Colors.white)),
Gaps.vGap10,
......@@ -208,7 +220,10 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
),
Container(width: 0.6, height: 15.0, color: Colours.line),
TextButton(
onPressed: () {},
onPressed: () {
PaymentSdk.instance.restore();
showLoading();
},
child: Text(
"恢复购买",
style: TextStyle(fontSize: 14.px, color: Colors.white),
......@@ -223,4 +238,22 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
PaymentSdk.instance.dispose();
super.dispose();
}
buildLoadingOrSuccess(MembershipData? mb) {
if (mb?.isVip == 1) {
return Column(
children: [
Text(
"过期时间:",
style: TextStyle(fontSize: 14.px, color: Colors.white),
),
Text(
mb?.expireVipAt ?? "",
style: TextStyle(fontSize: 14.px, color: Colors.white),
)
],
);
}
return const GFLoader();
}
}
......
......@@ -109,7 +109,7 @@ class PaymentSdk {
}
bool _isConsumable(ProductDetails details) {
return true;
return false;
}
void restore() {
......
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
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+13
version: 1.0.0+15
environment:
sdk: ">=2.16.2 <3.0.0"
......