12 changed files with 848 additions and 26 deletions
Unified View
Diff Options
-
2android/app/src/main/res/xml/network_security_config.xml
-
BINassets/images/matcher_apply.png
-
BINassets/images/matcher_task.png
-
BINassets/images/timer.png
-
148lib/controller/setting/task_controller.dart
-
3lib/generated/assets.dart
-
24lib/main.dart
-
31lib/model/mine/matchmaker_requirement_data.dart
-
48lib/pages/main/main_controller.dart
-
4lib/pages/main/main_page.dart
-
228lib/pages/main/update_dialog.dart
-
386lib/pages/setting/match_task_page.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 = <MatchmakerRequirement>[].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<UserApi>(); |
||||
|
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('申请失败'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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<String, dynamic> json) { |
||||
|
return MatchmakerRequirement( |
||||
|
id: json['id'] as String?, |
||||
|
type: json['type'] as int?, |
||||
|
liveDurationHours: json['liveDurationHours'] as int?, |
||||
|
liveConsumptionAmount: json['liveConsumptionAmount'] as int?, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
Map<String, dynamic> toJson() { |
||||
|
return { |
||||
|
'id': id, |
||||
|
'type': type, |
||||
|
'liveDurationHours': liveDurationHours, |
||||
|
'liveConsumptionAmount': liveConsumptionAmount, |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
@ -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<UserApi>(); |
||||
|
await getAppInfo(); |
||||
|
await checkForUpdates(); |
||||
|
} |
||||
|
|
||||
|
Future<void> getAppInfo() async { |
||||
|
try { |
||||
|
PackageInfo packageInfo = await PackageInfo.fromPlatform(); |
||||
|
buildNumber.value = packageInfo.buildNumber; |
||||
|
} catch (e) { |
||||
|
print('获取应用信息失败: $e'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 获取环信用户token |
||||
|
Future<void> 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'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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<UpdateDialog> createState() => _UpdateDialogState(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
class _UpdateDialogState extends State<UpdateDialog> { |
||||
|
|
||||
|
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'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
@ -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<TaskController>( |
||||
|
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<PayItem> createState() => _PayItemState(); |
||||
|
} |
||||
|
|
||||
|
class _PayItemState extends State<PayItem> { |
||||
|
@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<RevenueItem> createState() => _RevenueItemState(); |
||||
|
} |
||||
|
|
||||
|
class _RevenueItemState extends State<RevenueItem> { |
||||
|
|
||||
|
@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位置) |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save