feat: 增加flutter_keychain来缓存订单号
This commit is contained in:
@@ -17,6 +17,9 @@ import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart';
|
||||
import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:kaer_with_panels/app/widgets/dialogs/hi_dialog.dart';
|
||||
import '../../../routes/app_pages.dart';
|
||||
|
||||
|
||||
/// 购买会员页面视图
|
||||
class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController>
|
||||
@@ -29,135 +32,219 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return HIBaseScaffold(
|
||||
showBackgroundImage: false,
|
||||
title: '套餐选择',
|
||||
subtitle: '*所有套餐均不限流量不限速度',
|
||||
topContentAreaHeight: 110,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
width: 20,
|
||||
child: const _LeftEdgeSwipeBack(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Stack(
|
||||
children: [
|
||||
Obx(() {
|
||||
return Positioned.fill(
|
||||
bottom: 90.0,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
/*_kr_buildAccountSection(context),*/
|
||||
if (controller.kr_isLoading.value)
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height * 0.5,
|
||||
child: Center(
|
||||
child: KRSimpleLoading(
|
||||
color: Colors.white,
|
||||
size: 50.0,
|
||||
),
|
||||
),
|
||||
)
|
||||
else if (controller.kr_plans.isEmpty)
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height * 0.5,
|
||||
child: Center(
|
||||
child: Text(
|
||||
AppTranslations.kr_purchaseMembership.noData,
|
||||
style: KrAppTextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.color,
|
||||
// 获取屏幕顶部的安全区域高度(状态栏高度)
|
||||
final double topSafeArea = MediaQuery.of(context).padding.top;
|
||||
final double buttonTopPosition = 80 + topSafeArea;
|
||||
|
||||
// 在最外层包裹一个 Stack
|
||||
return Stack(
|
||||
children: [
|
||||
// 第一层:整个页面原来的内容
|
||||
HIBaseScaffold(
|
||||
showBackgroundImage: false,
|
||||
title: '套餐选择',
|
||||
subtitle: '*所有套餐均不限流量不限速度',
|
||||
topContentAreaHeight: 110,
|
||||
child: Stack(
|
||||
// 允许内部的 slogan 等元素超出边界
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Positioned(
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
width: 20,
|
||||
child: const _LeftEdgeSwipeBack(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Stack(
|
||||
children: [
|
||||
Obx(() {
|
||||
return Positioned.fill(
|
||||
bottom: 90.0,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
/*_kr_buildAccountSection(context),*/
|
||||
if (controller.kr_isLoading.value)
|
||||
Container(
|
||||
height:
|
||||
MediaQuery.of(context).size.height * 0.5,
|
||||
child: Center(
|
||||
child: KRSimpleLoading(
|
||||
color: Colors.white,
|
||||
size: 50.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
Container(
|
||||
margin:
|
||||
EdgeInsets.only(left: 40.0 - 20, right: 40.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// 套餐选择部分
|
||||
Container(
|
||||
padding: EdgeInsets.all(0.0),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
)
|
||||
else if (controller.kr_plans.isEmpty)
|
||||
Container(
|
||||
height:
|
||||
MediaQuery.of(context).size.height * 0.5,
|
||||
child: Center(
|
||||
child: Text(
|
||||
AppTranslations
|
||||
.kr_purchaseMembership.noData,
|
||||
style: KrAppTextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.color,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: 40.0 - 20, right: 40.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// 套餐选择部分
|
||||
Container(
|
||||
padding: EdgeInsets.all(0.0),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
// 使用 List.generate 动态创建卡片列表
|
||||
children: List.generate(
|
||||
controller.kr_getTotalOptionsCount(
|
||||
controller.kr_plans[controller
|
||||
.kr_selectedPlanIndex
|
||||
.value]),
|
||||
(index) {
|
||||
final plan = controller.kr_plans[
|
||||
children: [
|
||||
Column(
|
||||
// 使用 List.generate 动态创建卡片列表
|
||||
children: List.generate(
|
||||
controller
|
||||
.kr_getTotalOptionsCount(
|
||||
controller.kr_plans[
|
||||
controller
|
||||
.kr_selectedPlanIndex
|
||||
.value]),
|
||||
(index) {
|
||||
final plan = controller.kr_plans[
|
||||
controller
|
||||
.kr_selectedPlanIndex
|
||||
.value];
|
||||
final discountIndex =
|
||||
final discountIndex =
|
||||
plan.kr_discount.isEmpty
|
||||
? null
|
||||
: index;
|
||||
// 使用 Padding 来为每个卡片添加底部的间距,模拟 mainAxisSpacing
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: 8.0),
|
||||
child: SizedBox(
|
||||
height: 130.0,
|
||||
child:
|
||||
// 使用 Padding 来为每个卡片添加底部的间距,模拟 mainAxisSpacing
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: 8.0),
|
||||
child: SizedBox(
|
||||
height: 130.0,
|
||||
child:
|
||||
_kr_buildPlanOptionCard(
|
||||
plan,
|
||||
controller
|
||||
.kr_selectedPlanIndex
|
||||
.value,
|
||||
discountIndex,
|
||||
context,
|
||||
index,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
plan,
|
||||
controller
|
||||
.kr_selectedPlanIndex
|
||||
.value,
|
||||
discountIndex,
|
||||
context,
|
||||
index,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
Positioned(
|
||||
top: 160.0,
|
||||
right: 10.0,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.clearPendingOrderNo();
|
||||
},
|
||||
child: KrLocalImage(
|
||||
imageName: 'purchase_slogan',
|
||||
imageType: ImageType.svg,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
Positioned(
|
||||
top: 160.0, // 距离顶部的距离
|
||||
right: 10.0, // 固定在右侧 20.w 的位置
|
||||
child: KrLocalImage(
|
||||
imageName: 'purchase_slogan',
|
||||
imageType: ImageType.svg,
|
||||
),
|
||||
const HIHelpEntrance(isLight: false)
|
||||
],
|
||||
),
|
||||
const HIHelpEntrance(isLight: false)
|
||||
],
|
||||
),
|
||||
// --- 从这里移除按钮的 Positioned ---
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// 第二层:恢复按钮,放在 HIBaseScaffold 的上层
|
||||
Positioned(
|
||||
// top 值需要根据 HIBaseScaffold 的标题栏高度来精确调整
|
||||
// topContentAreaHeight 是 110,按钮高度是 20,让按钮下半部分贴着内容区顶部
|
||||
top: buttonTopPosition, // 110是标题区域高度, 10是按钮高度的一半
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: _buildRestoreButton(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建“恢复已购项目”按钮
|
||||
Widget _buildRestoreButton() {
|
||||
if (!Platform.isIOS ) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Center(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// 异步处理补单
|
||||
controller.kr_restorePurchases(isShowLoading: false); // 恢复未完成订单
|
||||
HIDialog.show(
|
||||
title: '温馨提示',
|
||||
message: '购买订单已确认,请耐心等待。若时长未到账,请联系在线客服处理。',
|
||||
confirmText: '联系客服',
|
||||
cancelText: '关闭',
|
||||
autoClose: false,
|
||||
showLoading: true,
|
||||
barrierDismissible: false,
|
||||
preventBackDismiss: true,
|
||||
onConfirm: () async {
|
||||
Get.toNamed(Routes.KR_CRISP);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
height: 20,
|
||||
width: 94, // 保持固定宽度 94
|
||||
// 移除 padding 属性
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
// 这个 Center 组件会使其子组件 Text 在 94x20 的空间内水平和垂直居中
|
||||
child: Center(
|
||||
child: Text(
|
||||
'恢复已购项目',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 12,
|
||||
height: 1.1,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 账号部分
|
||||
Widget _kr_buildAccountSection(BuildContext context) {
|
||||
return Container(
|
||||
|
||||
Reference in New Issue
Block a user