feat: 尚未购买的弹窗

This commit is contained in:
2025-11-27 22:58:42 -08:00
parent adcde623c7
commit 55d7508807
7 changed files with 403 additions and 451 deletions
@@ -86,8 +86,17 @@ class HIAnimatedConnectButton extends GetView<KRHomeController> {
print('🔵 Switch UI 正在更新,切换中点击了按钮: status=${status.runtimeType}, isConnected=$isConnected, isSwitching=$isSwitching');
return;
}
final hasValidSubscription =
controller.kr_subscribeService.kr_availableSubscribes.isNotEmpty;
final current = controller.kr_subscribeService.kr_currentSubscribe.value;
bool hasValidSubscription = false;
if (current != null) {
DateTime? expire;
try {
expire = DateTime.parse(current.expireTime);
} catch (_) {
expire = null;
}
hasValidSubscription = expire != null && expire.isAfter(DateTime.now());
}
if (hasValidSubscription) {
controller.kr_toggleSwitch(!controller.kr_isConnected.value);
} else {
@@ -291,4 +300,3 @@ class _ContinuousRippleEffectState extends State<ContinuousRippleEffect>
);
}
}
+176 -167
View File
@@ -18,7 +18,6 @@ import 'kr_home_subscription_view.dart';
import './hi_animated_connect_button.dart';
import 'package:kaer_with_panels/app/services/global_overlay_service.dart';
class KRHomeView extends StatefulWidget {
const KRHomeView({super.key});
@@ -35,8 +34,6 @@ class _KRHomeViewState extends State<KRHomeView> {
controller = Get.find<KRHomeController>();
}
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -50,174 +47,186 @@ class _KRHomeViewState extends State<KRHomeView> {
children: [
HIBaseScaffold(
showMenuButton: true,
topContentAreaHeight: 80,
child: Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment.topLeft,
child:
SafeArea(
child: Padding(
padding: EdgeInsets.fromLTRB(40.w, 8.w, 0, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Hi快VPN-网在我在,网快我快',
style: TextStyle(
color: Colors.white,
fontSize: 14.sp,
fontWeight: FontWeight.w600,
),
),
// 订阅信息
Obx(() {
// 1. 先获取订阅信息
final currentSubscribe =
controller.kr_subscribeService.kr_currentSubscribe.value;
// 2. 准备一个 Widget 变量,用于存放最终要显示的内容
Widget content;
// --- 定义统一的文本样式,并设置行高 ---
final textStyle = TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: FontWeight.w600,
height: 1.2, // 您可以微调这个值来达到想要的视觉效果
);
// 3. 开始条件判断
if (currentSubscribe == null) {
// --- 情况1: 没有任何订阅信息 ---
content = Text(
'尚未购买套餐',
style: textStyle,
);
} else {
// --- 情况2: 有订阅信息,需要判断是否过期 ---
final now = DateTime.now();
DateTime? expireDateTime;
try {
expireDateTime = DateTime.parse(currentSubscribe.expireTime);
} catch (e) {
// 日期格式解析失败
}
if (expireDateTime != null && expireDateTime.isBefore(now)) {
// --- 情况2.1: 订阅已过期 ---
final formattedExpireDate =
'${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')}';
// 使用换行符 \n 合并为单个 Text 组件
content = Text(
'您的套餐已于 $formattedExpireDate 到期\n请前往购买新套餐',
style: textStyle,
);
} else {
// --- 情况2.2: 订阅有效 ---
final difference = expireDateTime?.difference(now);
final remainingDaysText = (difference?.inDays ?? 0) > 0
? '${difference!.inDays}'
: '不足一天';
// 使用换行符 \n 合并为单个 Text 组件
content = Text(
'套餐剩余:$remainingDaysText\n${controller.kr_isConnected.value ? '当前线路:${controller.kr_getRealConnectedNodeCountry()}' : '未连接'}',
style: textStyle,
);
}
}
// 4. 返回包裹在公共 Container 中的最终内容
return Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(top: 8.h),
child: content,
);
}),
SizedBox(height: 8.h), // 添加一些垂直间距
// --- 自定义“闪连”Checkbox ---
Obx(() {
return Row(
mainAxisSize: MainAxisSize.min, // 让 Row 的宽度包裹其内容
children: [
// --- 可点击的 Checkbox 区域 ---
GestureDetector(
// 点击方框和文字都可以切换状态
onTap: () => controller.toggleQuickConnect(!controller.isQuickConnectEnabled.value),
child: AbsorbPointer(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// 1. 自定义 Checkbox 的方框外观
Container(
width: 20.w,
height: 20.w,
decoration: BoxDecoration(
color: controller.isQuickConnectEnabled.value
? Theme.of(context).primaryColor
: Colors.transparent,
border: Border.all(
color: Theme.of(context).primaryColor,
width: 1.5,
),
borderRadius: BorderRadius.circular(4.r),
),
child: controller.isQuickConnectEnabled.value
? Icon(
Icons.check,
size: 14.w,
color: Colors.black,
)
: null,
),
SizedBox(width: 8.w),
// 2. “闪连”标签
Text(
'闪连',
style: TextStyle(
color: Colors.white,
fontSize: 20.sp,
fontWeight: FontWeight.w600,
),
),
],
),
),
topContentAreaHeight: 80,
child: Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment.topLeft,
child: SafeArea(
child: Padding(
padding: EdgeInsets.fromLTRB(40.w, 8.w, 0, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Hi快VPN-网在我在,网快我快',
style: TextStyle(
color: Colors.white,
fontSize: 14.sp,
fontWeight: FontWeight.w600,
),
// --- 问号图标和点击弹窗区域 ---
SizedBox(width: 6.w), // 文字和问号图标之间的间距
GestureDetector(
onTap: () {
HIDialog.show(
title: '*闪连功能',
message: '开启后,每次打开软件默认自动连接,无需点击连接按钮\n在后台关闭软件后,软件将自动断开',
),
// 订阅信息
Obx(() {
// 1. 先获取订阅信息
final currentSubscribe = controller
.kr_subscribeService.kr_currentSubscribe.value;
// 2. 准备一个 Widget 变量,用于存放最终要显示的内容
Widget content;
// --- 定义统一的文本样式,并设置行高 ---
final normalStyle = TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: FontWeight.w600,
height: 1.2,
);
final highlightStyle = normalStyle.copyWith(
color: const Color(0xFFFF00B7),
);
// 3. 开始条件判断
if (currentSubscribe == null) {
// --- 情况1: 没有任何订阅信息 ---
content = Text(
'尚未购买套餐',
style: highlightStyle,
);
} else {
// --- 情况2: 有订阅信息,需要判断是否过期 ---
final now = DateTime.now();
DateTime? expireDateTime;
try {
expireDateTime =
DateTime.parse(currentSubscribe.expireTime);
} catch (e) {
// 日期格式解析失败
}
if (expireDateTime != null &&
expireDateTime.isBefore(now)) {
// --- 情况2.1: 订阅已过期 ---
final formattedExpireDate =
'${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')}';
// 使用换行符 \n 合并为单个 Text 组件
content = Text(
'您的套餐已于 $formattedExpireDate 到期\n请前往购买新套餐',
style: highlightStyle,
);
},
child: KrLocalImage(
imageName: 'question-icon', // 图片名称
imageType: ImageType.svg, // 图片类型
width: 24.w,
height: 24.w,
color: Colors.white, // 让图标颜色与边框协调
),
),
],
);
}),
],
} else {
// --- 情况2.2: 订阅有效 ---
final difference =
expireDateTime?.difference(now);
final remainingDaysText =
(difference?.inDays ?? 0) > 0
? '${difference!.inDays}'
: '不足一天';
// 使用换行符 \n 合并为单个 Text 组件
content = Text(
'套餐剩余:$remainingDaysText\n${controller.kr_isConnected.value ? '当前线路:${controller.kr_getRealConnectedNodeCountry()}' : '未连接'}',
style: normalStyle,
);
}
}
// 4. 返回包裹在公共 Container 中的最终内容
return Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(top: 8.h),
child: content,
);
}),
SizedBox(height: 8.h), // 添加一些垂直间距
// --- 自定义“闪连”Checkbox ---
Obx(() {
return Row(
mainAxisSize: MainAxisSize.min, // 让 Row 的宽度包裹其内容
children: [
// --- 可点击的 Checkbox 区域 ---
GestureDetector(
// 点击方框和文字都可以切换状态
onTap: () => controller.toggleQuickConnect(
!controller.isQuickConnectEnabled.value),
child: AbsorbPointer(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// 1. 自定义 Checkbox 的方框外观
Container(
width: 20.w,
height: 20.w,
decoration: BoxDecoration(
color: controller
.isQuickConnectEnabled.value
? Theme.of(context).primaryColor
: Colors.transparent,
border: Border.all(
color:
Theme.of(context).primaryColor,
width: 1.5,
),
borderRadius:
BorderRadius.circular(4.r),
),
child: controller
.isQuickConnectEnabled.value
? Icon(
Icons.check,
size: 14.w,
color: Colors.black,
)
: null,
),
SizedBox(width: 8.w),
// 2. “闪连”标签
Text(
'闪连',
style: TextStyle(
color: Colors.white,
fontSize: 20.sp,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
// --- 问号图标和点击弹窗区域 ---
SizedBox(width: 6.w), // 文字和问号图标之间的间距
GestureDetector(
onTap: () {
HIDialog.show(
title: '*闪连功能',
message:
'开启后,每次打开软件默认自动连接,无需点击连接按钮\n在后台关闭软件后,软件将自动断开',
);
},
child: KrLocalImage(
imageName: 'question-icon', // 图片名称
imageType: ImageType.svg, // 图片类型
width: 24.w,
height: 24.w,
color: Colors.white, // 让图标颜色与边框协调
),
),
],
);
}),
],
),
),
),
),
),
],
),
],
),
),
// 将 HIAnimatedConnectButton 移到 HIBaseScaffold 外部,避免 SafeArea 约束
HIAnimatedConnectButton(),
],
);
),
// 将 HIAnimatedConnectButton 移到 HIBaseScaffold 外部,避免 SafeArea 约束
HIAnimatedConnectButton(),
],
);
}
}