diff --git a/android/app/src/main/res/xml/network_security_config.xml b/android/app/src/main/res/xml/network_security_config.xml index 619cdda..61ebdf0 100644 --- a/android/app/src/main/res/xml/network_security_config.xml +++ b/android/app/src/main/res/xml/network_security_config.xml @@ -11,6 +11,6 @@ - pgyerapp.tracup.com + dating-agency-test.oss-accelerate.aliyuncs.com \ No newline at end of file diff --git a/assets/images/matcher_apply.png b/assets/images/matcher_apply.png new file mode 100644 index 0000000..f6e4e1b Binary files /dev/null and b/assets/images/matcher_apply.png differ diff --git a/assets/images/matcher_task.png b/assets/images/matcher_task.png new file mode 100644 index 0000000..432e343 Binary files /dev/null and b/assets/images/matcher_task.png differ diff --git a/assets/images/timer.png b/assets/images/timer.png new file mode 100644 index 0000000..fc396cd Binary files /dev/null and b/assets/images/timer.png differ diff --git a/lib/controller/setting/task_controller.dart b/lib/controller/setting/task_controller.dart new file mode 100644 index 0000000..b3b3711 --- /dev/null +++ b/lib/controller/setting/task_controller.dart @@ -0,0 +1,148 @@ +import 'package:dating_touchme_app/controller/global.dart'; +import 'package:dating_touchme_app/model/mine/chat_static_data.dart'; +import 'package:dating_touchme_app/model/mine/matchmaker_requirement_data.dart'; +import 'package:dating_touchme_app/network/user_api.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:fluwx/fluwx.dart'; +import 'package:get/get.dart'; + +class TaskController extends GetxController { + + // UserApi实例 + late UserApi _userApi; + final roseList = [].obs; + + final roseNum = 0.obs; + + final payChecked = true.obs; + + final activePay = 0.obs; + final enableIndex = (-1).obs; + final Fluwx fluwx = Fluwx(); + final matchmakerFlag = false.obs; + final button = '立即申请'.obs; + final canApply = false.obs; + String paymentOrderId = ''; + final revenue = [ + {'icon': '1', 'desc': '礼物收益范围15%-30%,嘉宾消费的分成3%;'}, + {'icon': '2', 'desc': '每天前5人连麦的礼物收益15%,第6-10人连麦的礼物收益20%,第11-15人连麦的礼物收益25%,第16人以上连麦的礼物收益30%;'}, + {'icon': '3', 'desc': '红娘推荐的嘉宾成为红娘,赚取入驻费的20%分成;'}, + {'icon': '4', 'desc': '新徒弟首月收益的10%(平台奖励)'}, + ].obs; + final userData = GlobalData().userData.obs; + final userId = GlobalData().userId.obs; + + final consumption = ChatStaticData().obs; + final countdownSeconds = 0.obs; + + @override + void onInit() { + super.onInit(); + _userApi = Get.find(); + if(GlobalData().userData!.matchmakerFlag != null && GlobalData().userData!.matchmakerFlag!){ + matchmakerFlag.value = true; + } + initDataList(); + } + + changePayActive(int index){ + if(index < enableIndex.value && enableIndex.value >= 0){ + return; + } + activePay.value = index; + canApply.value = false; + int hours = roseList[activePay.value].liveDurationHours!; + int rose = roseList[activePay.value].liveConsumptionAmount!; + if(hours > 0 && consumption.value.liveDurationMins! >= 60 * hours){ + if(rose <= 0){ + canApply.value = true; + } else if(consumption.value.liveConsumptionAmount! >= rose){ + canApply.value = true; + } + } + + button.value = canApply.value ? '立即申请' : '条件不满足'; + // 实习红娘 + if(roseList[activePay.value].type == 1){ + revenue.value = [ + {'icon': '1', 'desc': '礼物收益范围15%-30%,嘉宾消费的分成3%;'}, + {'icon': '2', 'desc': '每天前5人连麦的礼物收益15%,第6-10人连麦的礼物收益20%,第11-15人连麦的礼物收益25%,第16人以上连麦的礼物收益30%;'}, + {'icon': '3', 'desc': '红娘推荐的嘉宾成为红娘,赚取入驻费的20%分成;'}, + {'icon': '4', 'desc': '新徒弟首月收益的10%(平台奖励)'}, + ]; + } else if(roseList[activePay.value].type == 2){ + revenue.value = [ + {'icon': '1', 'desc': '礼物收益范围30%-40%,嘉宾消费的分成6%;'}, + {'icon': '2', 'desc': '每天前5人连麦的礼物收益30%,第6-10人连麦的礼物收益35%,第11人以上连麦的礼物收益40%;'}, + {'icon': '3', 'desc': '红娘推荐的嘉宾成为红娘,赚取入驻费的20%分成;'}, + {'icon': '4', 'desc': '新徒弟首月收益的10%(平台奖励)'}, + ]; + } else if(roseList[activePay.value].type == 3){ + revenue.value = [ + {'icon': '1', 'desc': '礼物收益范围40%,嘉宾消费的分成10%;'}, + // {'icon': '2', 'desc': '每天前5人连麦的礼物收益15%,第6-10人连麦的礼物收益20%,第11-15人连麦的礼物收益25%,第16人以上连麦的礼物收益30%;'}, + {'icon': '3', 'desc': '红娘推荐的嘉宾成为红娘,赚取入驻费的20%分成;'}, + {'icon': '4', 'desc': '新徒弟首月收益的10%(平台奖励)'}, + ]; + } + + } + + @override + void onClose() { + // WidgetsBinding.instance.removeObserver(this); + super.onClose(); + } + + initDataList() async { + try{ + final result = await _userApi.getMatchmakerRequirement(); + if (result.data.isSuccess && result.data.data != null) { + roseList.value = result.data.data!; + } + final response = await _userApi.getChatStaticsInfo(); + if (response.data.isSuccess && response.data.data != null) { + consumption.value = response.data.data!; + if(roseList[activePay.value].liveDurationHours != null){ + int hours = roseList[activePay.value].liveDurationHours!; + int rose = roseList[activePay.value].liveConsumptionAmount!; + if(hours > 0 && consumption.value.liveDurationMins! >= 60 * hours){ + if(rose <= 0){ + canApply.value = true; + } else if(consumption.value.liveConsumptionAmount! >= rose){ + canApply.value = true; + } + } + } + } + if(matchmakerFlag.value){ + final index = roseList.indexWhere((item) => item.type == GlobalData().userData!.matchmakerType!); + enableIndex.value = index >= 0 ? index : 0; + changePayActive(enableIndex.value); + } else { + changePayActive(0); + } + } catch (e) { + print('spread: $e'); + } + } + + submitOrder() async { + if(!canApply.value){ + return; + } + try { + final response = await _userApi.applyLiveMatchmaker({ + "behavior": GlobalData().userData!.matchmakerFlag! ? 2 : 1, + "type": roseList[activePay.value].type + }); + if (response.data.isSuccess) { + SmartDialog.showToast('申请成功,请等待审核'); + Get.back(); + } + } catch (e) { + SmartDialog.showToast('申请失败'); + } + } + +} \ No newline at end of file diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 0ff30ee..bf53b7f 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -141,6 +141,8 @@ class Assets { static const String imagesMale = 'assets/images/male.png'; static const String imagesMaleEmpty = 'assets/images/male_empty.png'; static const String imagesManIcon = 'assets/images/man_icon.png'; + static const String imagesMatcherApply = 'assets/images/matcher_apply.png'; + static const String imagesMatcherTask = 'assets/images/matcher_task.png'; static const String imagesMatchmaker = 'assets/images/matchmaker.png'; static const String imagesMatchmakerIcon1 = 'assets/images/matchmaker_icon1.png'; static const String imagesMatchmakerIcon2 = 'assets/images/matchmaker_icon2.png'; @@ -202,6 +204,7 @@ class Assets { static const String imagesTalkIcon = 'assets/images/talk_icon.png'; static const String imagesTeenagerBg = 'assets/images/teenager_bg.png'; static const String imagesTeenagerList = 'assets/images/teenager_list.png'; + static const String imagesTimer = 'assets/images/timer.png'; static const String imagesUnreadIcon = 'assets/images/unread_icon.png'; static const String imagesUpdataBg = 'assets/images/updata_bg.png'; static const String imagesUpdataFont = 'assets/images/updata_font.png'; diff --git a/lib/main.dart b/lib/main.dart index 7e1e0ad..bb55b90 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,7 +21,6 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:fluwx/fluwx.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; -import 'package:ota_update/ota_update.dart'; import 'extension/my_cupertino_localizations.dart'; @@ -183,29 +182,6 @@ class _MyAppState extends State { _initIMAsync(); // 检查是否已同意协议 _checkAgreement(); - updateTest(); - } - - updateTest() async { - // try { - // OtaUpdate() - // .execute( - // // 地址如果非https需要去 android\app\src\main\res\xml\network_security_config.xml 配置信任地址 - // 'https://pgyerapp.tracup.com/8bab5d3e8551e464d7d059160241ccc9.apk?sign=f2a40c8b607de18a7ab177c3b94f0bab&sign2=fd5574f9bf6d1c9328f1d95c40e87017&t=1767750116&response-content-disposition=attachment%3Bfilename%3D%22%E8%B6%A3%E6%81%8B%E6%81%8B_1.0.0.apk', - // - // destinationFilename: '趣恋恋_1.0.0.apk', - // - // ).listen( - // (OtaEvent event) { - // print(event.value); // 下载进度百分比 - // print("event.value"); - // print(event.status); // 下载状态 - // }, - // ); - // } catch (e) { - // print('Failed to make OTA update. Details: $e'); - // } - } /// 检查是否已同意用户协议(只在第一次安装时显示) diff --git a/lib/model/mine/matchmaker_requirement_data.dart b/lib/model/mine/matchmaker_requirement_data.dart new file mode 100644 index 0000000..cede100 --- /dev/null +++ b/lib/model/mine/matchmaker_requirement_data.dart @@ -0,0 +1,31 @@ +class MatchmakerRequirement { + final String? id; + final int? type; + final int? liveDurationHours; + final int? liveConsumptionAmount; + + MatchmakerRequirement({ + this.id, + this.type, + this.liveDurationHours, + this.liveConsumptionAmount, + }); + + factory MatchmakerRequirement.fromJson(Map json) { + return MatchmakerRequirement( + id: json['id'] as String?, + type: json['type'] as int?, + liveDurationHours: json['liveDurationHours'] as int?, + liveConsumptionAmount: json['liveConsumptionAmount'] as int?, + ); + } + + Map toJson() { + return { + 'id': id, + 'type': type, + 'liveDurationHours': liveDurationHours, + 'liveConsumptionAmount': liveConsumptionAmount, + }; + } +} \ No newline at end of file diff --git a/lib/pages/main/main_controller.dart b/lib/pages/main/main_controller.dart new file mode 100644 index 0000000..51c5af4 --- /dev/null +++ b/lib/pages/main/main_controller.dart @@ -0,0 +1,48 @@ +import 'package:dating_touchme_app/model/mine/app_version.dart'; +import 'package:dating_touchme_app/pages/main/update_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import '../../network/user_api.dart'; + +class MainController extends GetxController { + + // UserApi实例 + late UserApi _userApi; + final buildNumber = ''.obs; + + @override + void onInit() async { + super.onInit(); + // 从全局依赖中获取UserApi + _userApi = Get.find(); + await getAppInfo(); + await checkForUpdates(); + } + + Future getAppInfo() async { + try { + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + buildNumber.value = packageInfo.buildNumber; + } catch (e) { + print('获取应用信息失败: $e'); + } + } + + /// 获取环信用户token + Future checkForUpdates() async { + try { + final response = await _userApi.getAppVersionInfo(os: 1, code: int.parse(buildNumber.value)); + if (response.data.isSuccess && response.data.data != null) { + AppVersion version = response.data.data!; + showDialog( + context: Get.context!, + builder: (context) => UpdateDialog(version: version) + ); + } + } catch (e) { + print('检测版本跟新失败: $e'); + } + } + +} \ No newline at end of file diff --git a/lib/pages/main/main_page.dart b/lib/pages/main/main_page.dart index 193176e..6ffdd24 100644 --- a/lib/pages/main/main_page.dart +++ b/lib/pages/main/main_page.dart @@ -1,9 +1,9 @@ import 'package:dating_touchme_app/generated/assets.dart'; +import 'package:dating_touchme_app/pages/main/main_controller.dart'; import 'package:dating_touchme_app/pages/message/message_page.dart'; import 'package:dating_touchme_app/pages/mine/mine_page.dart'; import 'package:dating_touchme_app/rtc/rtm_manager.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; @@ -35,6 +35,8 @@ class _MainPageState extends State { late MessagePage messagePage; late MinePage minePage; + final MainController controller = Get.put(MainController()); + @override void initState() { super.initState(); diff --git a/lib/pages/main/update_dialog.dart b/lib/pages/main/update_dialog.dart new file mode 100644 index 0000000..29f7ced --- /dev/null +++ b/lib/pages/main/update_dialog.dart @@ -0,0 +1,228 @@ +import 'package:dating_touchme_app/extension/ex_widget.dart'; +import 'package:dating_touchme_app/generated/assets.dart'; +import 'package:dating_touchme_app/model/mine/app_version.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:ota_update/ota_update.dart'; +import 'package:tdesign_flutter/tdesign_flutter.dart'; + +class UpdateDialog extends StatefulWidget { + + final AppVersion version; + const UpdateDialog({super.key, required this.version}); + + @override + State createState() => _UpdateDialogState(); + +} + +class _UpdateDialogState extends State { + + bool updating = false; + TDLabelWidget buttonLabel = const TDTextLabel('0%'); + double progressValue = 0.0; + + @override + Widget build(BuildContext context) { + return PopScope( + canPop: !widget.version.isForcingUpdate!, + onPopInvokedWithResult: (bool didPop, Object? result) async { + if (didPop) { + Get.back(); + } + }, + child: Center( + child: Container( + color: Colors.transparent, + width: 299.w, + padding: EdgeInsets.only(top: 56.w), + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + width: 299.w, + padding: EdgeInsets.only( + top: 147.w, + left: 30.w, + right: 30.w, + bottom: 25.w + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18.w)), + color: Colors.white + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + widget.version.title!, + style: TextStyle( + fontSize: 16.w, + fontWeight: FontWeight.w500 + ), + ), + SizedBox(height: 14.w,), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 204.w, + child: Text( + widget.version.description!, + style: TextStyle( + fontSize: 12.w, + ), + ), + ) + ], + ), + SizedBox(height: 32.w,), + updating ? TDProgress( + type: TDProgressType.button, + strokeWidth: 40.w, + value: progressValue, + label: buttonLabel, + ) : + !widget.version.isForcingUpdate! ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: 113.w, + height: 40.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(9.w)), + color: const Color.fromRGBO(245, 245, 245, 1) + ), + child: Center( + child: Text( + "暂不更新", + style: TextStyle( + fontSize: 15.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ), + ), + ).onTap((){ + Navigator.of(context).pop(); + }), + Container( + width: 113.w, + height: 40.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(9.w)), + color: const Color.fromRGBO(245, 245, 245, 1), + gradient: const LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, // 对应 CSS 90deg + colors: [ + Color.fromRGBO(131, 89, 255, 1), // rgba(131, 89, 255, 1) + Color.fromRGBO(61, 138, 224, 1), // rgba(61, 138, 224, 1) + ], + ), + ), + child: Center( + child: Text( + "立即升级", + style: TextStyle( + fontSize: 15.w, + fontWeight: FontWeight.w500, + color: Colors.white + ), + ), + ), + ).onTap((){ + downloadAndInstall(widget.version); + }), + ], + ) : Container( + width: 240.w, + height: 40.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(9.w)), + color: const Color.fromRGBO(245, 245, 245, 1), + gradient: const LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, // 对应 CSS 90deg + colors: [ + Color.fromRGBO(131, 89, 255, 1), // rgba(131, 89, 255, 1) + Color.fromRGBO(61, 138, 224, 1), // rgba(61, 138, 224, 1) + ], + ), + ), + child: Center( + child: Text( + "立即升级", + style: TextStyle( + fontSize: 15.w, + fontWeight: FontWeight.w500, + color: Colors.white + ), + ), + ), + ).onTap((){ + downloadAndInstall(widget.version); + }) + ], + ), + ), + Positioned( + left: 0, + top: -56.w, + child: Image.asset( + Assets.imagesUpdataBg, + width: 299.w, + ), + ), + Positioned( + left: 11.w, + top: -14.w, + child: Image.asset( + Assets.imagesUpdataIcon, + width: 36.w, + ), + ), + Positioned( + left: 43.w, + top: 29.w, + child: Image.asset( + Assets.imagesUpdataFont, + width: 76.w, + ), + ) + ], + ), + ) + ), + ); + } + + downloadAndInstall(AppVersion version) async { + try { + if (mounted) { + setState(() { + updating = true; + }); + } + Get.log('url:${version.url!}'); + OtaUpdate().execute(version.url!, destinationFilename: '趣恋恋_${version.version}.apk').listen((OtaEvent event) { + print(event.value); // 下载进度百分比 + print("event.value"); + print(event.status); // 下载状态 + }, + ); + } catch (e) { + if (mounted) { + setState(() { + progressValue = 0.0; + buttonLabel = const TDTextLabel('开始'); + updating = false; + }); + } + print('Failed to make OTA update. Details: $e'); + } + } +} + + diff --git a/lib/pages/setting/match_task_page.dart b/lib/pages/setting/match_task_page.dart new file mode 100644 index 0000000..851ab2a --- /dev/null +++ b/lib/pages/setting/match_task_page.dart @@ -0,0 +1,386 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:dating_touchme_app/components/page_appbar.dart'; +import 'package:dating_touchme_app/controller/global.dart'; +import 'package:dating_touchme_app/controller/setting/task_controller.dart'; +import 'package:dating_touchme_app/extension/ex_widget.dart'; +import 'package:dating_touchme_app/generated/assets.dart'; +import 'package:dating_touchme_app/model/mine/matchmaker_requirement_data.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:tdesign_flutter/tdesign_flutter.dart'; + +class MatchTaskPage extends StatelessWidget { + const MatchTaskPage({super.key}); + + @override + Widget build(BuildContext context) { + return GetX( + init: TaskController(), + builder: (controller){ + controller.userData.value = GlobalData().userData; + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, // 0%:左边开始 + end: Alignment.bottomCenter, // 100%:右边结束 + colors: [ + Color.fromRGBO(172, 89, 255, 1), // 紫色 + Color.fromRGBO(117, 98, 249, 1), // 中间淡蓝 + Color.fromRGBO(255, 255, 255, 1), + Color.fromRGBO(255, 255, 255, 1),// 右侧深蓝 + ], + stops: [0.0, 0.32, 0.66, 1.0], // 对应 CSS 百分比:0%、77.53%、100% + ), + ), + child: controller.roseList.isNotEmpty ? Scaffold( + backgroundColor: Colors.transparent, + appBar: PageAppbar(title: "入驻加盟", backgroundColor: Colors.transparent, color: Colors.white, iconColor: Colors.white), + body: SingleChildScrollView( + child: Column( + children: [ + Container( + padding: EdgeInsets.symmetric(vertical: 10.w, horizontal: 12.w), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(80.w)), + child: (controller.userData.value?.profilePhoto?.isNotEmpty ?? false) ? CachedNetworkImage( + imageUrl: "${controller.userData.value?.profilePhoto ?? ""}?x-oss-process=image/format,webp/resize,w_120", + width: 80.w, + height: 80.w, + imageBuilder: (context, imageProvider) => Container( + decoration: BoxDecoration( + image: DecorationImage( + image: imageProvider, + fit: BoxFit.cover, + ), + ), + ), + ) : Image.asset( + Assets.imagesUserAvatar, + width: 80.w, + height: 80.w, + ) + ), + SizedBox(width: 16.w,), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ConstrainedBox( + constraints: BoxConstraints( maxWidth: 120.w), + child: Text( + "${controller.userData.value?.nickName ?? ""}", + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 24.w, + color: Colors.white, + fontWeight: FontWeight.w700 + ), + ), + ), + Text( + "ID:${controller.userId.value ?? ""}", + style: TextStyle( + fontSize: 16.w, + color: Colors.white, + fontWeight: FontWeight.w500 + ), + ) + ], + ) + ], + ), + ), + SizedBox(width: 12.w,), + Container( + padding: EdgeInsets.only(top: 8.w, bottom: 10.w, left: 24.w, right: 24.w), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Image.asset(Assets.imagesRoseWhite, width: 8.w, height: 15.w), + const SizedBox(width: 4), + Text('已消费玫瑰', style: TextStyle(fontSize: 14.w, color: Colors.white)), + ], + ), + SizedBox(height: 4,), + Row( + children: [ + SizedBox(width: 12,), + Text( + "${controller.consumption.value.liveConsumptionAmount}", + style: TextStyle( + fontSize: 30.w, + color: Colors.white, + fontWeight: FontWeight.bold + ), + ), + ], + ), + ], + ), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Image.asset('assets/images/timer.png', width: 15.w, height: 15.w), + const SizedBox(width: 4), + Text('已连麦时间(分钟)', style: TextStyle(fontSize: 14.w, color: Colors.white)), + ], + ), + SizedBox(height: 4,), + Row( + children: [ + SizedBox(width: 12,), + Text( + "${controller.consumption.value.liveDurationMins}", + style: TextStyle( + fontSize: 30.w, + color: Colors.white, + fontWeight: FontWeight.bold + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18.w)), + color: Colors.white + ), + padding: EdgeInsets.symmetric(vertical: 12.w, horizontal: 16.w), + margin: EdgeInsets.symmetric(vertical: 10.w, horizontal: 12.w), + child: Column( + children: [ + SizedBox(height: 12.w,), + ...controller.roseList.asMap().entries.map((entry){ + return PayItem(item: entry.value, active: controller.activePay.value, index: entry.key, changeActive: controller.changePayActive); + }), + Row( + children: [ + SizedBox(width: 4.w), + Container( + width: 6, + height: 6, + decoration: BoxDecoration( + color: Color(0xFF999999), // 圆点颜色 + shape: BoxShape.circle, // 圆形 + ), + ), + SizedBox(width: 4.w), + Text('仅限直播间相亲消费和连麦', style: TextStyle(fontSize: 12.w, color: Color(0xFF999999))), + ], + ), + SizedBox(height: 12.w), + ], + ), + ) + ], + ) + ), + bottomNavigationBar: SafeArea( + child: Container( + height: 60, + padding: EdgeInsets.symmetric(vertical: 5.w, horizontal: 20.w), + child: TDButton( + text: controller.button.value, + width: MediaQuery.of(context).size.width - 40, + size: TDButtonSize.large, + type: TDButtonType.fill, + shape: TDButtonShape.round, + disabled: !controller.canApply.value, + style: TDButtonStyle( + textColor: Colors.white, + backgroundColor: Color(0xFF7562F9), + ), + activeStyle: TDButtonStyle( + textColor: Colors.white, + backgroundColor: Color(0xC37562F9), + ), + disableStyle: TDButtonStyle( + textColor: Colors.white, + backgroundColor: Color(0xFFAAAAAA), + ), + onTap: (){ + controller.submitOrder(); + }, + ), + ) + ), + ) : null, + ); + }, + ); + } +} + + +class PayItem extends StatefulWidget { + final MatchmakerRequirement item; + final int active; + final int index; + final void Function(int) changeActive; + const PayItem({super.key, required this.item, required this.active, required this.index, required this.changeActive, }); + + @override + State createState() => _PayItemState(); +} + +class _PayItemState extends State { + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Container( + // width: 124.w, + height: 108.h, + margin: EdgeInsets.only(bottom: 12.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18.w)), + color: Colors.white, + border: widget.active == widget.index ? Border.all(width: 1, color: const Color(0xFF7562F9)) : Border.all(width: 1, color: const Color(0xFFEEEEEE)) + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(height: 20.h), + TDText(widget.item.liveConsumptionAmount! > 0 ? '累计消费' : '累计连麦相亲', style: TextStyle(color: Color(0xFF999999))), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + widget.item.liveConsumptionAmount! > 0 ? "${widget.item.liveConsumptionAmount}" : "${widget.item.liveDurationHours}", + style: TextStyle( + fontSize: 30.w, + color: Color.fromRGBO(251, 78, 35, 1), + fontWeight: FontWeight.bold + ), + ), + const SizedBox(width: 2), + Container( + padding: EdgeInsets.only(bottom: 8.h), + child: Text( + widget.item.liveConsumptionAmount! > 0 ? '朵玫瑰' : '小时', + style: TextStyle( + fontSize: 16.w, + color: Color.fromRGBO(251, 78, 35, 1), + fontWeight: FontWeight.bold + ), + ), + ), + ], + ), + // TDText("¥${widget.item.unitOriginalPrice}", isTextThrough: true, style: TextStyle(color: Color(0xFFCCCCCC)),), + Spacer() + ], + ), + ), + Positioned( + left: 0, + top: 0, + child: Container( + padding: EdgeInsets.symmetric(vertical: 4.w, horizontal: 12.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(18.w), + bottomRight: Radius.circular(18.w), + ), + color: widget.active == widget.index ? const Color(0xFF7562F9) : Color(0xFFCCCCCC) + ), + child: Center( + child: Text(_getNameByType(widget.item.type!), style: TextStyle(fontSize: 12, color: Colors.white)), + ), + ), + ) + ], + ).onTap((){ + widget.changeActive(widget.index); + }); + } + + String _getNameByType(int type) { + if(type == 1){ + return '实习红娘'; + } + if(type == 2){ + return '线上红娘'; + } + if(type == 3){ + return '签约红娘'; + } + return '实习红娘'; // 直播显示直播间按钮(放在HI位置) + } + +} + + +class RevenueItem extends StatefulWidget { + final dynamic item; + const RevenueItem({super.key, required this.item}); + + @override + State createState() => _RevenueItemState(); +} + +class _RevenueItemState extends State { + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(17.w), + margin: EdgeInsets.only(bottom: 8.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(16.w)), + color: const Color.fromRGBO(117, 98, 249, .1) + ), + child: Row( + children: [ + Image.asset( + _getButtonImage(widget.item['icon']), + width: 26.w, + height: 26.w, + ), + SizedBox(width: 14.w,), + Expanded( + child: Text( + widget.item['desc'], + style: TextStyle( + fontSize: 12.w, + color: Color(0xFF999999) + ), + ), + ) + ], + ), + ); + } + + String _getButtonImage(String icon) { + if(icon == '1'){ + return Assets.imagesMatchmakerIcon1; + } + if(icon == '2'){ + return Assets.imagesMatchmakerIcon2; + } + if(icon == '3'){ + return Assets.imagesMatchmakerIcon3; + } + return Assets.imagesMatchmakerIcon4; // 直播显示直播间按钮(放在HI位置) + } +} \ No newline at end of file