From 0af9f13c54ef88e3c84d3bf1c48191ce6754d142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=AD=90=E8=B4=A4?= Date: Wed, 31 Dec 2025 18:10:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=92=E7=89=88=E5=AF=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/event_info_controller.dart | 39 ++ .../home/event_list_controller.dart | 60 +++ lib/model/home/event_data.dart | 370 +++++++++++++++ lib/model/home/event_list_data.dart | 296 ++++++++++++ lib/network/api_urls.dart | 6 + lib/network/home_api.dart | 14 + lib/network/home_api.g.dart | 72 +++ lib/pages/home/event_info.dart | 439 +++++++++--------- lib/pages/home/event_list.dart | 203 ++++++++ lib/pages/home/recommend_tab.dart | 3 +- 10 files changed, 1290 insertions(+), 212 deletions(-) create mode 100644 lib/controller/home/event_info_controller.dart create mode 100644 lib/controller/home/event_list_controller.dart create mode 100644 lib/model/home/event_data.dart create mode 100644 lib/model/home/event_list_data.dart create mode 100644 lib/pages/home/event_list.dart diff --git a/lib/controller/home/event_info_controller.dart b/lib/controller/home/event_info_controller.dart new file mode 100644 index 0000000..54d875c --- /dev/null +++ b/lib/controller/home/event_info_controller.dart @@ -0,0 +1,39 @@ +import 'package:dating_touchme_app/model/home/event_data.dart'; +import 'package:dating_touchme_app/network/home_api.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; + +class EventInfoController extends GetxController { + final String id; + EventInfoController({required this.id}); + + final item = EventData().obs; + late final HomeApi _homeApi; + + @override + void onInit() { + super.onInit(); + _homeApi = Get.find(); + getEventData(); + } + + getEventData() async { + try { + final response = await _homeApi.userGetSiteActivityDetails(id: id); + if (response.data.isSuccess && response.data.data != null) { + item.value = response.data.data ?? EventData(); + + + } else { + + // 响应失败,抛出异常 + throw Exception(response.data.message ?? '获取数据失败'); + } + } catch(e){ + print('详情获取失败: $e'); + SmartDialog.showToast('详情获取失败'); + rethrow; + + } + } +} \ No newline at end of file diff --git a/lib/controller/home/event_list_controller.dart b/lib/controller/home/event_list_controller.dart new file mode 100644 index 0000000..47a83b7 --- /dev/null +++ b/lib/controller/home/event_list_controller.dart @@ -0,0 +1,60 @@ +import 'package:dating_touchme_app/network/home_api.dart'; +import 'package:easy_refresh/easy_refresh.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; + +import '../../model/home/event_list_data.dart'; + +class EventListController extends GetxController { + + late final HomeApi _homeApi; + + final page = 1.obs; + final size = 10.obs; + + final eventList = [].obs; + + late final EasyRefreshController listRefreshController; + + @override + void onInit() { + super.onInit(); + _homeApi = Get.find(); + + listRefreshController = EasyRefreshController( + controlFinishRefresh: true, + controlFinishLoad: true, + ); + + getEventList(); + } + + getEventList() async { + try{ + final response = await _homeApi.userGetSiteActivityPage( + pageNum: page.value, + pageSize: size.value, + queryType: 2 + ); + if (response.data.isSuccess && response.data.data != null) { + final data = response.data.data?.records ?? []; + + eventList.addAll(data.toList()); + if((data.length ?? 0) == size.value){ + + listRefreshController.finishLoad(IndicatorResult.success); + } else { + listRefreshController.finishLoad(IndicatorResult.noMore); + } + } else { + + // 响应失败,抛出异常 + throw Exception(response.data.message ?? '获取数据失败'); + } + } catch(e) { + print('活动列表获取失败: $e'); + SmartDialog.showToast('活动列表获取失败'); + rethrow; + } + } +} \ No newline at end of file diff --git a/lib/model/home/event_data.dart b/lib/model/home/event_data.dart new file mode 100644 index 0000000..5adfc1a --- /dev/null +++ b/lib/model/home/event_data.dart @@ -0,0 +1,370 @@ +class EventData { + String? id; + bool? isDelete; + String? createTime; + String? updateTime; + Null? event; + String? name; + String? vipActivityId; + String? goodsId; + String? applyStartTime; + String? applyEndTime; + String? beginTime; + String? endTime; + num? provinceCode; + String? provinceName; + num? cityCode; + String? cityName; + num? districtCode; + String? districtName; + String? detailedAddress; + num? numberParticipants; + num? numberMan; + num? numberWoman; + num? manEntryFee; + num? womanEntryFee; + num? manDiscount; + num? womanDiscount; + String? depict; + num? status; + num? activityType; + String? communityId; + String? communityName; + String? communityQrCodeUrl; + String? contactPictureUrl; + String? goodsName; + num? chargeType; + num? mutualAssistanceLimit; + bool? needRegInfo; + bool? realNameSwitch; + List? imgList; + num? topSerialNumber; + String? sharePhotosUrl; + String? contentPic; + num? contentPicHeight; + num? simulationNanNum; + num? simulationWonanNum; + String? participantId; + num? manNumber; + num? womanNumber; + num? participantStatus; + num? quitAuditStatus; + num? userOpenAssistanceStatus; + String? openedAssistanceId; + List? participationAllocationList; + String? thisDayTimes; + String? endTimes; + + EventData( + {this.id, + this.isDelete, + this.createTime, + this.updateTime, + this.event, + this.name, + this.vipActivityId, + this.goodsId, + this.applyStartTime, + this.applyEndTime, + this.beginTime, + this.endTime, + this.provinceCode, + this.provinceName, + this.cityCode, + this.cityName, + this.districtCode, + this.districtName, + this.detailedAddress, + this.numberParticipants, + this.numberMan, + this.numberWoman, + this.manEntryFee, + this.womanEntryFee, + this.manDiscount, + this.womanDiscount, + this.depict, + this.status, + this.activityType, + this.communityId, + this.communityName, + this.communityQrCodeUrl, + this.contactPictureUrl, + this.goodsName, + this.chargeType, + this.mutualAssistanceLimit, + this.needRegInfo, + this.realNameSwitch, + this.imgList, + this.topSerialNumber, + this.sharePhotosUrl, + this.contentPic, + this.contentPicHeight, + this.simulationNanNum, + this.simulationWonanNum, + this.participantId, + this.manNumber, + this.womanNumber, + this.participantStatus, + this.quitAuditStatus, + this.userOpenAssistanceStatus, + this.openedAssistanceId, + this.participationAllocationList, + this.thisDayTimes, + this.endTimes}); + + EventData.fromJson(Map json) { + id = json['id']; + isDelete = json['isDelete']; + createTime = json['createTime']; + updateTime = json['updateTime']; + event = json['event']; + name = json['name']; + vipActivityId = json['vipActivityId']; + goodsId = json['goodsId']; + applyStartTime = json['applyStartTime']; + applyEndTime = json['applyEndTime']; + beginTime = json['beginTime']; + endTime = json['endTime']; + provinceCode = json['provinceCode']; + provinceName = json['provinceName']; + cityCode = json['cityCode']; + cityName = json['cityName']; + districtCode = json['districtCode']; + districtName = json['districtName']; + detailedAddress = json['detailedAddress']; + numberParticipants = json['numberParticipants']; + numberMan = json['numberMan']; + numberWoman = json['numberWoman']; + manEntryFee = json['manEntryFee']; + womanEntryFee = json['womanEntryFee']; + manDiscount = json['manDiscount']; + womanDiscount = json['womanDiscount']; + depict = json['depict']; + status = json['status']; + activityType = json['activityType']; + communityId = json['communityId']; + communityName = json['communityName']; + communityQrCodeUrl = json['communityQrCodeUrl']; + contactPictureUrl = json['contactPictureUrl']; + goodsName = json['goodsName']; + chargeType = json['chargeType']; + mutualAssistanceLimit = json['mutualAssistanceLimit']; + needRegInfo = json['needRegInfo']; + realNameSwitch = json['realNameSwitch']; + if (json['imgList'] != null) { + imgList = []; + json['imgList'].forEach((v) { + imgList!.add(new ImgList.fromJson(v)); + }); + } + topSerialNumber = json['topSerialNumber']; + sharePhotosUrl = json['sharePhotosUrl']; + contentPic = json['contentPic']; + contentPicHeight = json['contentPicHeight']; + simulationNanNum = json['simulationNanNum']; + simulationWonanNum = json['simulationWonanNum']; + participantId = json['participantId']; + manNumber = json['manNumber']; + womanNumber = json['womanNumber']; + participantStatus = json['participantStatus']; + quitAuditStatus = json['quitAuditStatus']; + userOpenAssistanceStatus = json['userOpenAssistanceStatus']; + openedAssistanceId = json['openedAssistanceId']; + if (json['participationAllocationList'] != null) { + participationAllocationList = []; + json['participationAllocationList'].forEach((v) { + participationAllocationList! + .add(new ParticipationAllocationList.fromJson(v)); + }); + } + thisDayTimes = json['thisDayTimes']; + endTimes = json['endTimes']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['isDelete'] = this.isDelete; + data['createTime'] = this.createTime; + data['updateTime'] = this.updateTime; + data['event'] = this.event; + data['name'] = this.name; + data['vipActivityId'] = this.vipActivityId; + data['goodsId'] = this.goodsId; + data['applyStartTime'] = this.applyStartTime; + data['applyEndTime'] = this.applyEndTime; + data['beginTime'] = this.beginTime; + data['endTime'] = this.endTime; + data['provinceCode'] = this.provinceCode; + data['provinceName'] = this.provinceName; + data['cityCode'] = this.cityCode; + data['cityName'] = this.cityName; + data['districtCode'] = this.districtCode; + data['districtName'] = this.districtName; + data['detailedAddress'] = this.detailedAddress; + data['numberParticipants'] = this.numberParticipants; + data['numberMan'] = this.numberMan; + data['numberWoman'] = this.numberWoman; + data['manEntryFee'] = this.manEntryFee; + data['womanEntryFee'] = this.womanEntryFee; + data['manDiscount'] = this.manDiscount; + data['womanDiscount'] = this.womanDiscount; + data['depict'] = this.depict; + data['status'] = this.status; + data['activityType'] = this.activityType; + data['communityId'] = this.communityId; + data['communityName'] = this.communityName; + data['communityQrCodeUrl'] = this.communityQrCodeUrl; + data['contactPictureUrl'] = this.contactPictureUrl; + data['goodsName'] = this.goodsName; + data['chargeType'] = this.chargeType; + data['mutualAssistanceLimit'] = this.mutualAssistanceLimit; + data['needRegInfo'] = this.needRegInfo; + data['realNameSwitch'] = this.realNameSwitch; + if (this.imgList != null) { + data['imgList'] = this.imgList!.map((v) => v.toJson()).toList(); + } + data['topSerialNumber'] = this.topSerialNumber; + data['sharePhotosUrl'] = this.sharePhotosUrl; + data['contentPic'] = this.contentPic; + data['contentPicHeight'] = this.contentPicHeight; + data['simulationNanNum'] = this.simulationNanNum; + data['simulationWonanNum'] = this.simulationWonanNum; + data['participantId'] = this.participantId; + data['manNumber'] = this.manNumber; + data['womanNumber'] = this.womanNumber; + data['participantStatus'] = this.participantStatus; + data['quitAuditStatus'] = this.quitAuditStatus; + data['userOpenAssistanceStatus'] = this.userOpenAssistanceStatus; + data['openedAssistanceId'] = this.openedAssistanceId; + if (this.participationAllocationList != null) { + data['participationAllocationList'] = + this.participationAllocationList!.map((v) => v.toJson()).toList(); + } + data['thisDayTimes'] = this.thisDayTimes; + data['endTimes'] = this.endTimes; + return data; + } +} + +class ImgList { + String? id; + bool? isDelete; + List? createTime; + List? updateTime; + Null? event; + num? siteActivityId; + String? url; + num? serialNumber; + + ImgList( + {this.id, + this.isDelete, + this.createTime, + this.updateTime, + this.event, + this.siteActivityId, + this.url, + this.serialNumber}); + + ImgList.fromJson(Map json) { + id = json['id']; + isDelete = json['isDelete']; + createTime = json['createTime'].cast(); + updateTime = json['updateTime'].cast(); + event = json['event']; + siteActivityId = json['siteActivityId']; + url = json['url']; + serialNumber = json['serialNumber']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['isDelete'] = this.isDelete; + data['createTime'] = this.createTime; + data['updateTime'] = this.updateTime; + data['event'] = this.event; + data['siteActivityId'] = this.siteActivityId; + data['url'] = this.url; + data['serialNumber'] = this.serialNumber; + return data; + } +} + +class ParticipationAllocationList { + String? id; + bool? isDelete; + String? createTime; + String? updateTime; + Null? event; + num? siteActivityId; + num? transactionPrice; + num? originalPrice; + num? assistNumber; + num? assistRule; + num? discountAmount; + num? validTime; + num? userType; + num? genderCode; + String? genderValue; + bool? enable; + + ParticipationAllocationList( + {this.id, + this.isDelete, + this.createTime, + this.updateTime, + this.event, + this.siteActivityId, + this.transactionPrice, + this.originalPrice, + this.assistNumber, + this.assistRule, + this.discountAmount, + this.validTime, + this.userType, + this.genderCode, + this.genderValue, + this.enable}); + + ParticipationAllocationList.fromJson(Map json) { + id = json['id']; + isDelete = json['isDelete']; + createTime = json['createTime']; + updateTime = json['updateTime']; + event = json['event']; + siteActivityId = json['siteActivityId']; + transactionPrice = json['transactionPrice']; + originalPrice = json['originalPrice']; + assistNumber = json['assistNumber']; + assistRule = json['assistRule']; + discountAmount = json['discountAmount']; + validTime = json['validTime']; + userType = json['userType']; + genderCode = json['genderCode']; + genderValue = json['genderValue']; + enable = json['enable']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['isDelete'] = this.isDelete; + data['createTime'] = this.createTime; + data['updateTime'] = this.updateTime; + data['event'] = this.event; + data['siteActivityId'] = this.siteActivityId; + data['transactionPrice'] = this.transactionPrice; + data['originalPrice'] = this.originalPrice; + data['assistNumber'] = this.assistNumber; + data['assistRule'] = this.assistRule; + data['discountAmount'] = this.discountAmount; + data['validTime'] = this.validTime; + data['userType'] = this.userType; + data['genderCode'] = this.genderCode; + data['genderValue'] = this.genderValue; + data['enable'] = this.enable; + return data; + } +} diff --git a/lib/model/home/event_list_data.dart b/lib/model/home/event_list_data.dart new file mode 100644 index 0000000..eb81bb6 --- /dev/null +++ b/lib/model/home/event_list_data.dart @@ -0,0 +1,296 @@ +class EventListData { + List? records; + int? total; + int? size; + int? current; + int? pages; + + EventListData( + {this.records, this.total, this.size, this.current, this.pages}); + + EventListData.fromJson(Map json) { + if (json['records'] != null) { + records = []; + json['records'].forEach((v) { + records!.add(new Records.fromJson(v)); + }); + } + total = json['total']; + size = json['size']; + current = json['current']; + pages = json['pages']; + } + + Map toJson() { + final Map data = new Map(); + if (this.records != null) { + data['records'] = this.records!.map((v) => v.toJson()).toList(); + } + data['total'] = this.total; + data['size'] = this.size; + data['current'] = this.current; + data['pages'] = this.pages; + return data; + } +} + +class Records { + String? id; + bool? isDelete; + String? createTime; + String? updateTime; + Null? event; + String? name; + String? vipActivityId; + String? goodsId; + String? applyStartTime; + String? applyEndTime; + String? beginTime; + String? endTime; + int? provinceCode; + String? provinceName; + int? cityCode; + String? cityName; + int? districtCode; + String? districtName; + String? detailedAddress; + int? numberParticipants; + int? numberMan; + int? numberWoman; + double? manEntryFee; + double? womanEntryFee; + double? manDiscount; + double? womanDiscount; + String? depict; + int? status; + int? activityType; + String? communityId; + String? communityName; + String? communityQrCodeUrl; + String? contactPictureUrl; + String? goodsName; + int? chargeType; + int? mutualAssistanceLimit; + bool? needRegInfo; + bool? realNameSwitch; + List? imgList; + int? topSerialNumber; + String? sharePhotosUrl; + String? contentPic; + int? contentPicHeight; + int? simulationNanNum; + int? simulationWonanNum; + int? registrationPopulation; + int? participantStatus; + int? manNumber; + int? womanNumber; + + Records( + {this.id, + this.isDelete, + this.createTime, + this.updateTime, + this.event, + this.name, + this.vipActivityId, + this.goodsId, + this.applyStartTime, + this.applyEndTime, + this.beginTime, + this.endTime, + this.provinceCode, + this.provinceName, + this.cityCode, + this.cityName, + this.districtCode, + this.districtName, + this.detailedAddress, + this.numberParticipants, + this.numberMan, + this.numberWoman, + this.manEntryFee, + this.womanEntryFee, + this.manDiscount, + this.womanDiscount, + this.depict, + this.status, + this.activityType, + this.communityId, + this.communityName, + this.communityQrCodeUrl, + this.contactPictureUrl, + this.goodsName, + this.chargeType, + this.mutualAssistanceLimit, + this.needRegInfo, + this.realNameSwitch, + this.imgList, + this.topSerialNumber, + this.sharePhotosUrl, + this.contentPic, + this.contentPicHeight, + this.simulationNanNum, + this.simulationWonanNum, + this.registrationPopulation, + this.participantStatus, + this.manNumber, + this.womanNumber}); + + Records.fromJson(Map json) { + id = json['id']; + isDelete = json['isDelete']; + createTime = json['createTime']; + updateTime = json['updateTime']; + event = json['event']; + name = json['name']; + vipActivityId = json['vipActivityId']; + goodsId = json['goodsId']; + applyStartTime = json['applyStartTime']; + applyEndTime = json['applyEndTime']; + beginTime = json['beginTime']; + endTime = json['endTime']; + provinceCode = json['provinceCode']; + provinceName = json['provinceName']; + cityCode = json['cityCode']; + cityName = json['cityName']; + districtCode = json['districtCode']; + districtName = json['districtName']; + detailedAddress = json['detailedAddress']; + numberParticipants = json['numberParticipants']; + numberMan = json['numberMan']; + numberWoman = json['numberWoman']; + manEntryFee = json['manEntryFee']; + womanEntryFee = json['womanEntryFee']; + manDiscount = json['manDiscount']; + womanDiscount = json['womanDiscount']; + depict = json['depict']; + status = json['status']; + activityType = json['activityType']; + communityId = json['communityId']; + communityName = json['communityName']; + communityQrCodeUrl = json['communityQrCodeUrl']; + contactPictureUrl = json['contactPictureUrl']; + goodsName = json['goodsName']; + chargeType = json['chargeType']; + mutualAssistanceLimit = json['mutualAssistanceLimit']; + needRegInfo = json['needRegInfo']; + realNameSwitch = json['realNameSwitch']; + if (json['imgList'] != null) { + imgList = []; + json['imgList'].forEach((v) { + imgList!.add(new ImgList.fromJson(v)); + }); + } + topSerialNumber = json['topSerialNumber']; + sharePhotosUrl = json['sharePhotosUrl']; + contentPic = json['contentPic']; + contentPicHeight = json['contentPicHeight']; + simulationNanNum = json['simulationNanNum']; + simulationWonanNum = json['simulationWonanNum']; + registrationPopulation = json['registrationPopulation']; + participantStatus = json['participantStatus']; + manNumber = json['manNumber']; + womanNumber = json['womanNumber']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['isDelete'] = this.isDelete; + data['createTime'] = this.createTime; + data['updateTime'] = this.updateTime; + data['event'] = this.event; + data['name'] = this.name; + data['vipActivityId'] = this.vipActivityId; + data['goodsId'] = this.goodsId; + data['applyStartTime'] = this.applyStartTime; + data['applyEndTime'] = this.applyEndTime; + data['beginTime'] = this.beginTime; + data['endTime'] = this.endTime; + data['provinceCode'] = this.provinceCode; + data['provinceName'] = this.provinceName; + data['cityCode'] = this.cityCode; + data['cityName'] = this.cityName; + data['districtCode'] = this.districtCode; + data['districtName'] = this.districtName; + data['detailedAddress'] = this.detailedAddress; + data['numberParticipants'] = this.numberParticipants; + data['numberMan'] = this.numberMan; + data['numberWoman'] = this.numberWoman; + data['manEntryFee'] = this.manEntryFee; + data['womanEntryFee'] = this.womanEntryFee; + data['manDiscount'] = this.manDiscount; + data['womanDiscount'] = this.womanDiscount; + data['depict'] = this.depict; + data['status'] = this.status; + data['activityType'] = this.activityType; + data['communityId'] = this.communityId; + data['communityName'] = this.communityName; + data['communityQrCodeUrl'] = this.communityQrCodeUrl; + data['contactPictureUrl'] = this.contactPictureUrl; + data['goodsName'] = this.goodsName; + data['chargeType'] = this.chargeType; + data['mutualAssistanceLimit'] = this.mutualAssistanceLimit; + data['needRegInfo'] = this.needRegInfo; + data['realNameSwitch'] = this.realNameSwitch; + if (this.imgList != null) { + data['imgList'] = this.imgList!.map((v) => v.toJson()).toList(); + } + data['topSerialNumber'] = this.topSerialNumber; + data['sharePhotosUrl'] = this.sharePhotosUrl; + data['contentPic'] = this.contentPic; + data['contentPicHeight'] = this.contentPicHeight; + data['simulationNanNum'] = this.simulationNanNum; + data['simulationWonanNum'] = this.simulationWonanNum; + data['registrationPopulation'] = this.registrationPopulation; + data['participantStatus'] = this.participantStatus; + data['manNumber'] = this.manNumber; + data['womanNumber'] = this.womanNumber; + return data; + } +} + +class ImgList { + String? id; + bool? isDelete; + List? createTime; + List? updateTime; + Null? event; + int? siteActivityId; + String? url; + int? serialNumber; + + ImgList( + {this.id, + this.isDelete, + this.createTime, + this.updateTime, + this.event, + this.siteActivityId, + this.url, + this.serialNumber}); + + ImgList.fromJson(Map json) { + id = json['id']; + isDelete = json['isDelete']; + createTime = json['createTime'].cast(); + updateTime = json['updateTime'].cast(); + event = json['event']; + siteActivityId = json['siteActivityId']; + url = json['url']; + serialNumber = json['serialNumber']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['isDelete'] = this.isDelete; + data['createTime'] = this.createTime; + data['updateTime'] = this.updateTime; + data['event'] = this.event; + data['siteActivityId'] = this.siteActivityId; + data['url'] = this.url; + data['serialNumber'] = this.serialNumber; + return data; + } +} diff --git a/lib/network/api_urls.dart b/lib/network/api_urls.dart index 907fd74..28851f8 100644 --- a/lib/network/api_urls.dart +++ b/lib/network/api_urls.dart @@ -128,6 +128,12 @@ class ApiUrls { static const String userReportPost = 'dating-agency-service/user/report/post'; + static const String userGetSiteActivityPage = + 'dating-agency-service/user/get/site/activity/page'; + + static const String userGetSiteActivityDetails = + 'dating-agency-service/user/get/site/activity/details'; + // 后续可以在此添加更多API端点 static const String listMatchmakerProduct = 'dating-agency-mall/user/page/product/by/matchmaker'; diff --git a/lib/network/home_api.dart b/lib/network/home_api.dart index e0010f4..966fb98 100644 --- a/lib/network/home_api.dart +++ b/lib/network/home_api.dart @@ -1,3 +1,5 @@ +import 'package:dating_touchme_app/model/home/event_data.dart'; +import 'package:dating_touchme_app/model/home/event_list_data.dart' hide Records; import 'package:dating_touchme_app/model/home/post_comment_data.dart' hide Records; import 'package:dating_touchme_app/model/home/post_data.dart'; import 'package:dating_touchme_app/network/api_urls.dart'; @@ -60,4 +62,16 @@ abstract class HomeApi { Future>> userReportPost( @Body() Map data, ); + + @GET(ApiUrls.userGetSiteActivityPage) + Future>> userGetSiteActivityPage({ + @Query('pageNum') required int pageNum, + @Query('pageSize') required int pageSize, + @Query('queryType') required int queryType, + }); + + @GET(ApiUrls.userGetSiteActivityDetails) + Future>> userGetSiteActivityDetails({ + @Query('id') required String id, + }); } \ No newline at end of file diff --git a/lib/network/home_api.g.dart b/lib/network/home_api.g.dart index af5e46a..46a38f2 100644 --- a/lib/network/home_api.g.dart +++ b/lib/network/home_api.g.dart @@ -313,6 +313,78 @@ class _HomeApi implements HomeApi { return httpResponse; } + @override + Future>> userGetSiteActivityPage({ + required int pageNum, + required int pageSize, + required int queryType, + }) async { + final _extra = {}; + final queryParameters = { + r'pageNum': pageNum, + r'pageSize': pageSize, + r'queryType': queryType, + }; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType>>( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'dating-agency-service/user/get/site/activity/page', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch>(_options); + late BaseResponse _value; + try { + _value = BaseResponse.fromJson( + _result.data!, + (json) => EventListData.fromJson(json as Map), + ); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + final httpResponse = HttpResponse(_value, _result); + return httpResponse; + } + + @override + Future>> userGetSiteActivityDetails({ + required String id, + }) async { + final _extra = {}; + final queryParameters = {r'id': id}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType>>( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'dating-agency-service/user/get/site/activity/details', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch>(_options); + late BaseResponse _value; + try { + _value = BaseResponse.fromJson( + _result.data!, + (json) => EventData.fromJson(json as Map), + ); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + final httpResponse = HttpResponse(_value, _result); + return httpResponse; + } + RequestOptions _setStreamType(RequestOptions requestOptions) { if (T != dynamic && !(requestOptions.responseType == ResponseType.bytes || diff --git a/lib/pages/home/event_info.dart b/lib/pages/home/event_info.dart index 50e3d96..2f1cc09 100644 --- a/lib/pages/home/event_info.dart +++ b/lib/pages/home/event_info.dart @@ -1,271 +1,288 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:dating_touchme_app/components/page_appbar.dart'; +import 'package:dating_touchme_app/controller/home/event_info_controller.dart'; +import 'package:dating_touchme_app/generated/assets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; class EventInfo extends StatelessWidget { - const EventInfo({super.key}); + final String id; + const EventInfo({super.key, required this.id}); @override Widget build(BuildContext context) { - return Scaffold( - appBar: const PageAppbar(title: "活动详情"), - body: SingleChildScrollView( - child: Container( - padding: EdgeInsets.all(15.w), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(8.w)), + return GetX( + init: EventInfoController(id: id), + builder: (controller){ + return controller.item.value.id != null ? Scaffold( + appBar: const PageAppbar(title: "活动详情"), + body: SingleChildScrollView( child: Container( - width: 345.w, - color: Colors.white, - child: Column( - children: [ - CachedNetworkImage( - imageUrl: "https://dating-agency-test.oss-accelerate.aliyuncs.com/1.png", - width: 345.w, - fit: BoxFit.cover, - ), - Container( - padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 15.w), - margin: EdgeInsets.only(bottom: 15.w), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + padding: EdgeInsets.all(15.w), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(8.w)), + child: Container( + width: 345.w, + color: Colors.white, + child: Column( + children: [ + CachedNetworkImage( + imageUrl: controller.item.value.imgList?[0].url ?? "", + width: 345.w, + fit: BoxFit.cover, + errorWidget: (context, error, stackTrace) { + return Image.asset( + Assets.imagesBanner, + width: 345.w, + height: 150.w, + fit: BoxFit.cover, + ); + }, + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 15.w), + margin: EdgeInsets.only(bottom: 15.w), + child: Column( children: [ - Text( - "星河 DEEP--轻奢浪漫之旅", - style: TextStyle( - fontSize: 18.w, - color: const Color.fromRGBO(255, 66, 236, 1), - fontWeight: FontWeight.w500 - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + controller.item.value.name ?? "", + style: TextStyle( + fontSize: 18.w, + color: const Color.fromRGBO(255, 66, 236, 1), + fontWeight: FontWeight.w500 + ), + ), + Row( + children: [ + Icon( + Icons.group, + color: const Color.fromRGBO(255, 66, 236, 1), + size: 12.w, + ), + SizedBox(width: 5.w,), + Text( + "${(controller.item.value.manNumber ?? 0) + (controller.item.value.womanNumber ?? 0)}人已报名", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ) + ], + ) + ], ), + SizedBox(height: 5.w,), Row( children: [ Icon( - Icons.group, + Icons.access_time, color: const Color.fromRGBO(255, 66, 236, 1), size: 12.w, ), - SizedBox(width: 5.w,), Text( - "0人已报名", + "活动时间:", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ), + Text( + "${controller.item.value.beginTime!.substring(5, controller.item.value.beginTime!.length - 3)}至${controller.item.value.endTime!.substring(5, controller.item.value.endTime!.length - 3)}", style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) ), ) ], - ) - ], - ), - SizedBox(height: 5.w,), - Row( - children: [ - Icon( - Icons.access_time, - color: const Color.fromRGBO(255, 66, 236, 1), - size: 12.w, - ), - Text( - "活动时间:", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ), - Text( - "08-21 00:00至08-22 23:59", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ) - ], - ), - SizedBox(height: 5.w,), - Row( - children: [ - Icon( - Icons.location_on_outlined, - color: const Color.fromRGBO(255, 66, 236, 1), - size: 12.w, - ), - Text( - "地址:", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ), - Text( - "广州市天河区地址待定", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ) - ], - ), - SizedBox(height: 5.w,), - Row( - children: [ - Icon( - Icons.group_outlined, - color: const Color.fromRGBO(255, 66, 236, 1), - size: 12.w, - ), - Text( - "人数:", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ), - Text( - "男10人 女10人", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ) - ], - ), - SizedBox(height: 5.w,), - Row( - children: [ - Icon( - Icons.currency_yen, - color: const Color.fromRGBO(255, 66, 236, 1), - size: 12.w, - ), - Text( - "费用:", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), ), - Text( - "男:1520元/人", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ) - ], - ), - Row( - children: [ - Icon( - Icons.currency_yen, - color: const Color.fromRGBO(255, 66, 236, 0), - size: 12.w, - ), - Text( - "费用:", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 0) - ), - ), - Text( - "女:1520元/人", - style: TextStyle( - fontSize: 12.w, - color: const Color.fromRGBO(144, 144, 144, 1) - ), - ) - ], - ), - SizedBox(height: 15.w,), - Stack( - children: [ - ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(13.w)), - child: Row( - children: [ - Expanded( - child: Container( - height: 13.w, - color: const Color.fromRGBO(237, 245, 255, 1), - ), + SizedBox(height: 5.w,), + Row( + children: [ + Icon( + Icons.location_on_outlined, + color: const Color.fromRGBO(255, 66, 236, 1), + size: 12.w, + ), + Text( + "地址:", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) ), - Expanded( - child: Container( - height: 13.w, - color: const Color.fromRGBO(255, 237, 255, 1), - ), + ), + Text( + "${controller.item.value.cityName ?? ""}${controller.item.value.districtName ?? ""}${controller.item.value.detailedAddress ?? ""}", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) ), - ], - ), + ) + ], ), - Positioned( - child: Center( - child: Transform( - transform: Matrix4.skewX(0.6), - child: Container(width: 20.w, height: 13.w, color: Colors.white,), - ), - ), - ) - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ + SizedBox(height: 5.w,), Row( children: [ + Icon( + Icons.group_outlined, + color: const Color.fromRGBO(255, 66, 236, 1), + size: 12.w, + ), Text( - "男", + "人数:", style: TextStyle( - fontSize: 13.w, - color: const Color.fromRGBO(144, 144, 144, 1) + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) ), ), Text( - "0人", + "男${controller.item.value.numberMan}人 女${controller.item.value.womanNumber}人", style: TextStyle( - fontSize: 13.w, - color: const Color.fromRGBO(237, 245, 255, 1), + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) ), - ), + ) ], ), + SizedBox(height: 5.w,), Row( children: [ + Icon( + Icons.currency_yen, + color: const Color.fromRGBO(255, 66, 236, 1), + size: 12.w, + ), Text( - "女", + "费用:", style: TextStyle( - fontSize: 13.w, + fontSize: 12.w, color: const Color.fromRGBO(144, 144, 144, 1) ), ), Text( - "0人", + "男:${controller.item.value.participationAllocationList![0].originalPrice}元/人", style: TextStyle( - fontSize: 13.w, - color: const Color.fromRGBO(255, 237, 255, 1), + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) ), + ) + ], + ), + Row( + children: [ + Icon( + Icons.currency_yen, + color: const Color.fromRGBO(255, 66, 236, 0), + size: 12.w, + ), + Text( + "费用:", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 0) + ), + ), + Text( + "女:${controller.item.value.participationAllocationList![1].originalPrice}元/人", + style: TextStyle( + fontSize: 12.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ) + ], + ), + SizedBox(height: 15.w,), + Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(13.w)), + child: Row( + children: [ + Expanded( + child: Container( + height: 13.w, + color: const Color.fromRGBO(237, 245, 255, 1), + ), + ), + Expanded( + child: Container( + height: 13.w, + color: const Color.fromRGBO(255, 237, 255, 1), + ), + ), + ], + ), + ), + Positioned( + child: Center( + child: Transform( + transform: Matrix4.skewX(0.6), + child: Container(width: 20.w, height: 13.w, color: Colors.white,), + ), + ), + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Text( + "男", + style: TextStyle( + fontSize: 13.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ), + Text( + "${(controller.item.value.manNumber ?? 0)}人", + style: TextStyle( + fontSize: 13.w, + color: const Color.fromRGBO(237, 245, 255, 1), + ), + ), + ], + ), + Row( + children: [ + Text( + "女", + style: TextStyle( + fontSize: 13.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ), + Text( + "${(controller.item.value.womanNumber ?? 0)}人", + style: TextStyle( + fontSize: 13.w, + color: const Color.fromRGBO(255, 237, 255, 1), + ), + ), + ], ), ], ), ], ), - ], - ), + ), + CachedNetworkImage( + imageUrl: controller.item.value.contentPic ?? "", + width: 345.w, + fit: BoxFit.cover, + ) + ], ), - CachedNetworkImage( - imageUrl: "https://dating-agency-test.oss-accelerate.aliyuncs.com/09B987965731.jpg", - width: 345.w, - fit: BoxFit.cover, - ) - ], + ), ), ), ), - ), - ), + ) : Container(); + }, ); } } diff --git a/lib/pages/home/event_list.dart b/lib/pages/home/event_list.dart new file mode 100644 index 0000000..9c627dc --- /dev/null +++ b/lib/pages/home/event_list.dart @@ -0,0 +1,203 @@ +import 'package:dating_touchme_app/components/page_appbar.dart'; +import 'package:dating_touchme_app/controller/home/event_list_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/home/event_list_data.dart'; +import 'package:dating_touchme_app/pages/home/event_info.dart'; +import 'package:easy_refresh/easy_refresh.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +class EventList extends StatelessWidget { + const EventList({super.key}); + + @override + Widget build(BuildContext context) { + return GetX( + init: EventListController(), + builder: (controller){ + return Scaffold( + appBar: PageAppbar(title: "活动"), + backgroundColor: const Color.fromRGBO(242, 242, 242, 1), + body: EasyRefresh( + + controller: controller.listRefreshController, + header: const ClassicHeader( + dragText: '下拉刷新', + armedText: '释放刷新', + readyText: '刷新中...', + processingText: '刷新中...', + processedText: '刷新完成', + failedText: '刷新失败', + noMoreText: '没有更多数据', + showMessage: false + ), + footer: ClassicFooter( + dragText: '上拉加载', + armedText: '释放加载', + readyText: '加载中...', + processingText: '加载中...', + processedText: '加载完成', + failedText: '加载失败', + noMoreText: '没有更多数据', + showMessage: false + ), + // 下拉刷新 + onRefresh: () async { + print('推荐列表下拉刷新被触发'); + controller.page.value = 1; + controller.eventList.clear(); + await controller.getEventList(); + controller.listRefreshController.finishRefresh(IndicatorResult.success); + controller.listRefreshController.finishLoad(IndicatorResult.none); + }, + // 上拉加载更多 + onLoad: () async { + print('推荐列表上拉加载被触发, hasMore: '); + controller.page.value += 1; + await controller.getEventList(); + }, + child: Container( + padding: EdgeInsets.all(15.w), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Container( + height: 50.w, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(width: 1, color: Colors.black) + ) + ), + child: Center( + child: Text( + "我的活动" + ), + ), + ), + ), + Expanded( + child: Container( + height: 50.w, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(width: 1, color: Colors.black) + ) + ), + child: Center( + child: Text( + "我的活动" + ), + ), + ), + ), + ], + ), + SizedBox(height: 15.w,), + Expanded( + child: ListView.builder( + itemCount: controller.eventList.length, + itemBuilder: (_, index) { + return EventItem(item: controller.eventList[index],); + }, + ), + ) + ] + ) + ), + ), + ); + }, + ); + } +} + +class EventItem extends StatefulWidget { + final Records item; + const EventItem({super.key, required this.item}); + + @override + State createState() => _EventItemState(); +} + +class _EventItemState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.only(bottom: 10.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(8.w)), + color: Colors.white + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ClipRRect( + borderRadius: BorderRadius.vertical(top: Radius.circular(8.w)), + child: Image.network( + widget.item.imgList?[0].url ?? "", + width: 345.w, + height: 150.w, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) { + return Image.asset( + Assets.imagesBanner, + width: 345.w, + height: 150.w, + fit: BoxFit.cover, + ); + }, + ), + ), + Container( + padding: EdgeInsets.all(10.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "${widget.item.name}", + style: TextStyle( + fontSize: 15.w, + fontWeight: FontWeight.w700 + ), + ), + SizedBox(height: 5.w,), + Text( + "${widget.item.depict}", + style: TextStyle( + fontSize: 12.w + ), + ), + SizedBox(height: 5.w,), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "${widget.item.registrationPopulation}人已报名", + style: TextStyle( + fontSize: 12.w + ), + ), + Text( + "查看详情", + style: TextStyle( + fontSize: 12.w + ), + ) + ], + ) + ], + ), + ) + ], + ), + ).onTap((){ + Get.to(() => EventInfo(id: widget.item.id ?? "")); + }); + } +} + diff --git a/lib/pages/home/recommend_tab.dart b/lib/pages/home/recommend_tab.dart index 1099316..377b8d9 100644 --- a/lib/pages/home/recommend_tab.dart +++ b/lib/pages/home/recommend_tab.dart @@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:dating_touchme_app/extension/ex_widget.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/pages/home/event_info.dart'; +import 'package:dating_touchme_app/pages/home/event_list.dart'; import 'package:dating_touchme_app/pages/home/matchmaker_item.dart'; import 'package:dating_touchme_app/pages/home/matchmaker_page.dart'; import 'package:dating_touchme_app/pages/mine/open_webview.dart'; @@ -202,7 +203,7 @@ class _RecommendTabState extends State ], ), ).onTap((){ - Get.to(() => EventInfo()); + Get.to(() => EventList()); }), Container( width: 167.w,