Browse Source

上传会员服务协议

newdev_shunjiawei
liwei1dao 6 months ago
parent
commit
11a73d19ae
  1. 6
      lib/core/translations/language/en_us.dart
  2. 6
      lib/core/translations/language/zh_cn.dart
  3. 6
      lib/core/translations/language/zh_hk.dart
  4. 6
      lib/core/translations/language/zh_tw.dart
  5. 22
      lib/core/utils/doc_url_helper.dart
  6. 155
      lib/modules/common/widgets/member_service_agreement_dialog.dart
  7. 10
      lib/modules/goods/controllers/goods_base_controller.dart

6
lib/core/translations/language/en_us.dart

@ -114,6 +114,12 @@ const Map<String, String> enUS = {
". By clicking \"Agree and Enter\", you indicate that you have fully read and agree to the above agreements. Clicking \"Disagree\" will exit the application.", // ,点击"同意并进入"表示您已充分阅读并同意上述协议。点击"不同意"将退出应用。
"disagree": "Disagree", // 不同意
"agreeAndEnter": "Agree and Enter", // 同意并进入
"agreeAndContinue": "Agree and Continue",
"memberServiceAgreement": "Membership Service Agreement",
"memberServiceAgreementTitle": "Membership Service Agreement",
"memberServiceAgreementIntro": "To provide you with better membership services, please read carefully before subscribing: ",
"memberServiceAgreementOutro": ". By clicking \"Agree and Continue\", you confirm that you have fully read and accept the above agreement.",
"memberAgreementRejectedTip": "You must agree to the Membership Service Agreement to continue.",
// 首页
"deviceStatus": "Device Status",

6
lib/core/translations/language/zh_cn.dart

@ -110,6 +110,12 @@ const Map<String, String> zhCN = {
",点击'同意并进入'表示您已充分阅读并同意上述协议。点击'不同意'将退出应用。", // ,点击"同意并进入"表示您已充分阅读并同意上述协议。点击"不同意"将退出应用。
"disagree": "不同意", // 不同意
"agreeAndEnter": "同意并进入", // 同意并进入
"agreeAndContinue": "同意并继续",
"memberServiceAgreement": "《会员服务协议》",
"memberServiceAgreementTitle": "会员服务协议",
"memberServiceAgreementIntro": "为给您提供更优质的会员服务,请您在订阅会员前仔细阅读",
"memberServiceAgreementOutro": "。点击\"同意并继续\"表示您已充分阅读并同意上述协议。",
"memberAgreementRejectedTip": "需同意《会员服务协议》后才能继续支付",
// 首页
"deviceStatus": "设备状态",

6
lib/core/translations/language/zh_hk.dart

@ -110,6 +110,12 @@ const Map<String, String> zhHK = {
"點擊'同意並進入'表示您已充分閱讀並同意上述協議。點擊'不同意'將退出應用。", // ,点击"同意并进入"表示您已充分阅读并同意上述协议。点击"不同意"将退出应用。
"disagree": "不同意", // 不同意
"agreeAndEnter": "同意並進入", // 同意并进入
"agreeAndContinue": "同意並繼續",
"memberServiceAgreement": "《會員服務協議》",
"memberServiceAgreementTitle": "會員服務協議",
"memberServiceAgreementIntro": "為向您提供更優質的會員服務,請您在訂閱會員前仔細閱讀",
"memberServiceAgreementOutro": "。點擊\"同意並繼續\"表示您已充分閱讀並同意上述協議。",
"memberAgreementRejectedTip": "需同意《會員服務協議》後才能繼續支付",
// 首页
"deviceStatus": "設備狀態",

6
lib/core/translations/language/zh_tw.dart

@ -110,6 +110,12 @@ const Map<String, String> zhTW = {
"點擊'同意並進入'表示您已充分閱讀並同意上述協議。點擊'不同意'將退出應用。", // ,点击"同意并进入"表示您已充分阅读并同意上述协议。点击"不同意"将退出应用。
"disagree": "不同意", // 不同意
"agreeAndEnter": "同意並進入", // 同意并进入
"agreeAndContinue": "同意並繼續",
"memberServiceAgreement": "《會員服務協議》",
"memberServiceAgreementTitle": "會員服務協議",
"memberServiceAgreementIntro": "為向您提供更優質的會員服務,請您在訂閱會員前仔細閱讀",
"memberServiceAgreementOutro": "。點擊\"同意並繼續\"表示您已充分閱讀並同意上述協議。",
"memberAgreementRejectedTip": "需同意《會員服務協議》後才能繼續支付",
// 首页
"deviceStatus": "設備狀態",

22
lib/core/utils/doc_url_helper.dart

@ -1,4 +1,5 @@
import 'package:get/get.dart';
import '../../data/services/network/dio_manager.dart';
/// 根据当前语言返回 doc 目录名,如 "zh_cn"、"en"、"fr"
String docLangPath() {
@ -18,10 +19,23 @@ String docLangPath() {
return supported.contains(lang) ? lang : 'en';
}
/// 构建隐私政策 URL
/// 业务服务器上的法律文档目录前缀
String _legalDocBase() => '${DioManager().baseUrl}/docs/legal';
/// 当前语言对应的协议文件后缀(zh / en)
String _legalDocLang() {
final lang = Get.locale?.languageCode ?? 'en';
return lang == 'zh' ? 'zh' : 'en';
}
/// 构建隐私政策 URL(托管在业务服务器上)
String privacyPolicyUrl() =>
'https://www.voitrans.net/doc/${docLangPath()}/privacy_policy.html';
'${_legalDocBase()}/privacy_policy_${_legalDocLang()}.html';
/// 构建用户协议 URL
/// 构建用户协议 URL(托管在业务服务器上)
String userAgreementUrl() =>
'https://www.voitrans.net/doc/${docLangPath()}/user_agreement.html';
'${_legalDocBase()}/user_agreement_${_legalDocLang()}.html';
/// 构建会员服务协议 URL(托管在业务服务器上)
String memberServiceAgreementUrl() =>
'${_legalDocBase()}/member_service_agreement_${_legalDocLang()}.html';

155
lib/modules/common/widgets/member_service_agreement_dialog.dart

@ -0,0 +1,155 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../webview_page.dart';
import '../../../core/utils/doc_url_helper.dart';
/// 会员服务协议确认弹窗
/// 在用户进入支付(充值/购买会员)前必须显式同意
class MemberServiceAgreementDialog extends StatelessWidget {
final VoidCallback? onAccept; // 同意回调
final VoidCallback? onReject; // 拒绝回调
final bool canDismiss; // 是否可通过返回键关闭
const MemberServiceAgreementDialog({
super.key,
this.onAccept,
this.onReject,
this.canDismiss = true,
});
/// 显示会员服务协议弹窗,返回值为 true 表示同意,false / null 表示拒绝或取消
static Future<bool> show({bool canDismiss = true}) async {
final result = await Get.dialog<bool>(
MemberServiceAgreementDialog(
canDismiss: canDismiss,
onAccept: () => Get.back(result: true),
onReject: () => Get.back(result: false),
),
barrierDismissible: canDismiss,
);
return result == true;
}
@override
Widget build(BuildContext context) {
final bool isDarkMode = Get.theme.brightness == Brightness.dark;
return PopScope(
canPop: canDismiss,
child: Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
backgroundColor: isDarkMode ? Colors.grey[800] : Colors.white,
child: Container(
padding: EdgeInsets.all(20.w),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'memberServiceAgreementTitle'.tr, // 会员服务协议
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
color: isDarkMode ? Colors.white : Colors.black,
),
),
SizedBox(height: 16.h),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: 'memberServiceAgreementIntro'.tr,
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode
? Colors.white70
: Colors.black87,
),
),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: GestureDetector(
onTap: () {
Get.to(() => WebViewPage(
url: memberServiceAgreementUrl(),
title: 'memberServiceAgreement'.tr,
));
},
child: Text(
'memberServiceAgreement'.tr, // 《会员服务协议》
style: TextStyle(
fontSize: 14.sp,
color: const Color(0xFF3B82F6),
),
),
),
),
TextSpan(
text: 'memberServiceAgreementOutro'.tr,
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode ? Colors.white70 : Colors.black87,
),
),
],
),
textAlign: TextAlign.center,
),
),
SizedBox(height: 20.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(
onPressed: () {
if (onReject != null) {
onReject!();
} else {
Get.back(result: false);
}
},
style: TextButton.styleFrom(
foregroundColor: isDarkMode
? Colors.grey[400]
: Colors.black54,
),
child: Text(
'disagree'.tr, // 不同意
style: TextStyle(
color: isDarkMode ? Colors.grey[400] : Colors.black54,
),
),
),
ElevatedButton(
onPressed: () {
if (onAccept != null) {
onAccept!();
} else {
Get.back(result: true);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF0066CC),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.r),
),
elevation: isDarkMode ? 4 : 2,
padding: EdgeInsets.symmetric(
horizontal: 16.w, vertical: 10.h),
),
child: Text('agreeAndContinue'.tr), // 同意并继续
),
],
),
],
),
),
),
);
}
}

10
lib/modules/goods/controllers/goods_base_controller.dart

@ -10,6 +10,7 @@ import '../../../data/services/network/api.dart';
import 'package:flutter/foundation.dart';
import 'dart:async';
import 'package:app_links/app_links.dart';
import '../../common/widgets/member_service_agreement_dialog.dart';
/// goods 模块基础控制器,封装通用的商品加载与支付流程
abstract class GoodsBaseController extends GetxController {
@ -97,6 +98,15 @@ abstract class GoodsBaseController extends GetxController {
method = enabled.first;
}
// 3.5 充值前必须显式同意《会员服务协议》(合规要求)
final agreed = await MemberServiceAgreementDialog.show();
if (!agreed) {
Get.snackbar('tip'.tr, 'memberAgreementRejectedTip'.tr,
snackPosition: SnackPosition.BOTTOM,
margin: const EdgeInsets.all(12));
return;
}
// 4. 根据选择的支付方式执行支付
bool ok = false;
String failMsg = 'paymentFailedTryAgain'.tr; // 支付失败,请重试

Loading…
Cancel
Save