Browse Source

对接金牌红娘

ios
王子贤 2 months ago
parent
commit
0b17b3e1a3
11 changed files with 355 additions and 14 deletions
  1. 40
      lib/controller/home/home_controller.dart
  2. 84
      lib/model/home/matchmaker_data.dart
  3. 3
      lib/network/api_urls.dart
  4. 7
      lib/network/home_api.dart
  5. 38
      lib/network/home_api.g.dart
  6. 2
      lib/pages/discover/visitor_list_page.dart
  7. 109
      lib/pages/home/matchmaker_card.dart
  8. 11
      lib/pages/home/matchmaker_item.dart
  9. 71
      lib/pages/home/matchmaker_page.dart
  10. 2
      lib/pages/home/nearby_tab.dart
  11. 2
      lib/pages/home/recommend_tab.dart

40
lib/controller/home/home_controller.dart

@ -1,4 +1,6 @@
import 'package:dating_touchme_app/model/home/banner_data.dart';
import 'package:dating_touchme_app/model/home/matchmaker_data.dart' as md;
import 'package:easy_refresh/easy_refresh.dart';
import 'package:get/get.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import '../../network/home_api.dart';
@ -9,6 +11,8 @@ class HomeController extends GetxController {
final recommendFeed = <MarriageData>[].obs;
//
final bannerLint = <Records>[].obs;
final matchmakerList = <md.Records>[].obs;
//
final nearbyFeed = <MarriageData>[].obs;
@ -35,14 +39,22 @@ class HomeController extends GetxController {
// GetX依赖注入中获取HomeApi实例
late final HomeApi _homeApi;
late final EasyRefreshController listRefreshController;
@override
void onInit() {
super.onInit();
listRefreshController = EasyRefreshController(
controlFinishRefresh: true,
controlFinishLoad: true,
);
// HomeApi
_homeApi = Get.find<HomeApi>();
//
loadInitialData();
getBannerList();
getMatchmakerList();
}
@ -66,6 +78,34 @@ class HomeController extends GetxController {
}
}
getMatchmakerList() async {
try{
final response = await _homeApi.userPageDongwoMatchmakerMarriageInformation(
pageNum: 1,
pageSize: 10
);
if (response.data.isSuccess && response.data.data != null) {
final data = response.data.data?.records ?? [];
matchmakerList.addAll(data.toList());
if((data.length ?? 0) == 10){
listRefreshController.finishLoad(IndicatorResult.success);
} else {
listRefreshController.finishLoad(IndicatorResult.noMore);
}
} else {
//
throw Exception(response.data.message ?? '获取数据失败');
}
} catch(e) {
print('玫瑰记录获取失败: $e');
SmartDialog.showToast('玫瑰记录获取失败');
rethrow;
}
}
///
void loadInitialData() async {
//

84
lib/model/home/matchmaker_data.dart

@ -0,0 +1,84 @@
class MatchmakerData {
List<Records>? records;
int? total;
int? size;
int? current;
int? pages;
MatchmakerData(
{this.records, this.total, this.size, this.current, this.pages});
MatchmakerData.fromJson(Map<String, dynamic> json) {
if (json['records'] != null) {
records = <Records>[];
json['records'].forEach((v) {
records!.add(new Records.fromJson(v));
});
}
total = json['total'];
size = json['size'];
current = json['current'];
pages = json['pages'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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? miId;
String? userId;
String? matchmakerId;
String? profilePhoto;
String? nickName;
bool? isRealNameCertified;
String? birthYear;
String? birthDate;
int? age;
Records(
{this.miId,
this.userId,
this.matchmakerId,
this.profilePhoto,
this.nickName,
this.isRealNameCertified,
this.birthYear,
this.birthDate,
this.age});
Records.fromJson(Map<String, dynamic> json) {
miId = json['miId'];
userId = json['userId'];
matchmakerId = json['matchmakerId'];
profilePhoto = json['profilePhoto'];
nickName = json['nickName'];
isRealNameCertified = json['isRealNameCertified'];
birthYear = json['birthYear'];
birthDate = json['birthDate'];
age = json['age'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['miId'] = this.miId;
data['userId'] = this.userId;
data['matchmakerId'] = this.matchmakerId;
data['profilePhoto'] = this.profilePhoto;
data['nickName'] = this.nickName;
data['isRealNameCertified'] = this.isRealNameCertified;
data['birthYear'] = this.birthYear;
data['birthDate'] = this.birthDate;
data['age'] = this.age;
return data;
}
}

3
lib/network/api_urls.dart

@ -149,6 +149,9 @@ class ApiUrls {
static const String userPageBannerByCustomer =
'dating-agency-service/user/page/banner/by/customer';
static const String userPageDongwoMatchmakerMarriageInformation =
'dating-agency-service/user/page/dongwo/matchmaker-marriage-information';
// API端点
static const String listMatchmakerProduct =
'dating-agency-mall/user/page/product/by/matchmaker';

7
lib/network/home_api.dart

@ -1,6 +1,7 @@
import 'package:dating_touchme_app/model/home/banner_data.dart' hide Records;
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/matchmaker_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/model/home/trend_data.dart' hide Records;
@ -96,4 +97,10 @@ abstract class HomeApi {
@GET(ApiUrls.userPageBannerByCustomer)
Future<HttpResponse<BaseResponse<BannerData>>> userPageBannerByCustomer();
@GET(ApiUrls.userPageDongwoMatchmakerMarriageInformation)
Future<HttpResponse<BaseResponse<MatchmakerData>>> userPageDongwoMatchmakerMarriageInformation({
@Query('pageNum') required int pageNum,
@Query('pageSize') required int pageSize,
});
}

38
lib/network/home_api.g.dart

@ -522,6 +522,44 @@ class _HomeApi implements HomeApi {
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<MatchmakerData>>>
userPageDongwoMatchmakerMarriageInformation({
required int pageNum,
required int pageSize,
}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{
r'pageNum': pageNum,
r'pageSize': pageSize,
};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<HttpResponse<BaseResponse<MatchmakerData>>>(
Options(method: 'GET', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-service/user/page/dongwo/matchmaker-marriage-information',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<MatchmakerData> _value;
try {
_value = BaseResponse<MatchmakerData>.fromJson(
_result.data!,
(json) => MatchmakerData.fromJson(json as Map<String, dynamic>),
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
final httpResponse = HttpResponse(_value, _result);
return httpResponse;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||

2
lib/pages/discover/visitor_list_page.dart

@ -196,7 +196,7 @@ class VisitorItem extends StatelessWidget {
)
],
).onTap((){
Get.to(() => UserInformationPage(miId: visitor.miId, userId: GlobalData().userId!));
Get.to(() => UserInformationPage(miId: visitor.miId, userId: visitor.userId));
});
}

109
lib/pages/home/matchmaker_card.dart

@ -0,0 +1,109 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dating_touchme_app/controller/global.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/matchmaker_data.dart';
import 'package:dating_touchme_app/pages/home/user_information_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class MatchmakerCard extends StatelessWidget {
final Records visitor;
const MatchmakerCard({Key? key, required this.visitor}) : super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10.w)),
child: CachedNetworkImage(
imageUrl: "${visitor.profilePhoto}?x-oss-process=image/format,webp/resize,w_240",
width: 173.w,
height: 173.w,
fit: BoxFit.cover,
placeholder: (context, url) => Container(
color: Colors.white38,
child: Center(
child: CircularProgressIndicator(
strokeWidth: 1.w,
color: Colors.grey,
),
),
),
errorWidget: (context, url, error) =>
Image.asset(
Assets.imagesUserAvatar,
width: 173.w,
height: 173.w,
fit: BoxFit.cover,
),
),
),
Positioned(
left: 8.w,
bottom: 12.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if(visitor.nickName != "")SizedBox(
width: 156.w,
child: Text(visitor.nickName ?? "",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12.w,
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
),
SizedBox(height: 2.w),
SizedBox(
width: 156.w,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${visitor.age}",
style: TextStyle(
fontSize: 14.w,
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
],
),
)
],
),
)
],
).onTap((){
Get.to(() => UserInformationPage(miId: visitor.miId ?? "", userId: visitor.userId!));
});
}
// String _formatTime(String timestamp) {
// var time = DateTime.parse(timestamp);
// final now = DateTime.now();
// final difference = now.difference(time);
//
// if (difference.inMinutes < 1) {
// return '刚刚';
// } else if (difference.inHours < 1) {
// return '${difference.inMinutes}分钟前';
// } else if (difference.inDays < 1) {
// return '${difference.inHours}小时前';
// } else if (difference.inDays < 7) {
// return '${difference.inDays}天前';
// } else {
// return '${time.month}/${time.day}';
// }
// }
}

11
lib/pages/home/matchmaker_item.dart

@ -2,13 +2,14 @@ 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/model/home/marriage_data.dart';
import 'package:dating_touchme_app/model/home/matchmaker_data.dart';
import 'package:dating_touchme_app/pages/home/user_information_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class MatchmakerItem extends StatefulWidget {
final MarriageData item;
final Records item;
const MatchmakerItem({super.key, required this.item});
@override
@ -24,7 +25,7 @@ class _MatchmakerItemState extends State<MatchmakerItem> {
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(40.w)),
child: widget.item.profilePhoto != "" ? CachedNetworkImage(
imageUrl: widget.item.profilePhoto,
imageUrl: widget.item.profilePhoto ?? "",
width: 40.w,
height: 40.w,
fit: BoxFit.cover,
@ -35,7 +36,7 @@ class _MatchmakerItemState extends State<MatchmakerItem> {
fit: BoxFit.cover,
),
),
Positioned(
if(false) Positioned(
left: -3.w,
bottom: -3.w,
child: Container(
@ -48,7 +49,7 @@ class _MatchmakerItemState extends State<MatchmakerItem> {
),
child: Center(
child: Text(
widget.item.nickName,
widget.item.nickName ?? "",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
@ -62,7 +63,7 @@ class _MatchmakerItemState extends State<MatchmakerItem> {
)
],
).onTap((){
Get.to(() => UserInformationPage(miId: widget.item.miId, userId: widget.item.userId,));
Get.to(() => UserInformationPage(miId: widget.item.miId ?? "", userId: widget.item.userId ?? "",));
});
}
}

71
lib/pages/home/matchmaker_page.dart

@ -1,7 +1,10 @@
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/controller/home/home_controller.dart';
import 'package:dating_touchme_app/pages/home/matchmaker_card.dart';
import 'package:dating_touchme_app/pages/home/nearby_tab.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 MatchmakerPage extends StatefulWidget {
@ -21,12 +24,68 @@ class _MatchmakerPageState extends State<MatchmakerPage> with AutomaticKeepAlive
super.build(context);
return Scaffold(
appBar: PageAppbar(title: "金牌红娘"),
body: Column(
children: [
Expanded(
child: NearbyTab(),
)
],
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.matchmakerList.clear();
await controller.getMatchmakerList();
controller.listRefreshController.finishRefresh(IndicatorResult.success);
controller.listRefreshController.finishLoad(IndicatorResult.none);
},
//
onLoad: () async {
print('推荐列表上拉加载被触发, hasMore: ');
await controller.getMatchmakerList();
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: 6.w,
horizontal: 15.w
),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height - MediaQuery.of(context).padding.top,
),
child: GridView.builder(
padding: EdgeInsets.only(top: 8.w, left: 10.w, right: 8.w, bottom: 0.w),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // 2
crossAxisSpacing: 4.w, //
mainAxisSpacing: 4.w, //
childAspectRatio: 1, //
),
itemCount: controller.matchmakerList.length,
itemBuilder: (context, index) {
final visitor = controller.matchmakerList[index];
return MatchmakerCard(visitor: visitor);
},
),
),
),
),
);
}

2
lib/pages/home/nearby_tab.dart

@ -38,7 +38,7 @@ class _NearbyTabState extends State<NearbyTab> with AutomaticKeepAliveClientMixi
return Obx(() {
return EasyRefresh(
controller: _refreshController,
controller: controller.listRefreshController,
header: const ClassicHeader(
dragText: '下拉刷新',
armedText: '释放刷新',

2
lib/pages/home/recommend_tab.dart

@ -244,7 +244,7 @@ class _RecommendTabState extends State<RecommendTab>
spacing: 14.w,
runSpacing: 8.w,
children: [
...controller.nearbyFeed.take(6).toList().map((e){
...controller.matchmakerList.take(6).toList().map((e){
return MatchmakerItem(item: e);
})
],

Loading…
Cancel
Save