Browse Source

完善功能

dev-2.0
王子贤 2 days ago
parent
commit
7a237fe804
16 changed files with 716 additions and 146 deletions
  1. 309
      lib/controller/home/home_controller.dart
  2. 6
      lib/controller/setting/blacklist_controller.dart
  3. 18
      lib/model/home/check_black_data.dart
  4. 15
      lib/model/home/friend_footprint_info_data.dart
  5. 92
      lib/model/home/friend_footprint_list_data.dart
  6. 4
      lib/network/api_urls.dart
  7. 4
      lib/network/home_api.dart
  8. 36
      lib/network/home_api.g.dart
  9. 6
      lib/network/user_api.dart
  10. 33
      lib/network/user_api.g.dart
  11. 34
      lib/pages/home/content_card.dart
  12. 153
      lib/pages/home/friend_footprint_page.dart
  13. 120
      lib/pages/home/recommend_tab.dart
  14. 26
      lib/pages/mine/mine_page.dart
  15. 2
      lib/pages/mine/real_feedback_page.dart
  16. 4
      lib/pages/setting/blacklist_page.dart

309
lib/controller/home/home_controller.dart

@ -16,12 +16,16 @@ class HomeController extends GetxController {
//
final nearbyFeed = <MarriageData>[].obs;
final nearbyDisFeed = <MarriageData>[].obs;
final friendFootFeed = <MarriageData>[].obs;
//
final recommendIsLoading = false.obs;
final recommendPage = 1.obs;
final recommendHasMore = true.obs;
final friendHasMore = true.obs;
final friendIsLoading = false.obs;
final friendPage = 1.obs;
//
final nearbyIsLoading = false.obs;
final nearbyPage = 1.obs;
@ -48,6 +52,8 @@ class HomeController extends GetxController {
Map<String, double>? _location;
CityInfo? _cityInfo;
final friendFootprintInfo = <String>[].obs;
Timer? _timer;
@override
void onInit() {
super.onInit();
@ -55,19 +61,49 @@ class HomeController extends GetxController {
_homeApi = Get.find<HomeApi>();
//
loadInitialData();
getFriendFootprintInfo();
_timer = Timer.periodic(const Duration(minutes: 1), (timer) {
getFriendFootprintInfo();
});
}
@override
void onClose() {
super.onClose();
_timer?.cancel();
}
getFriendFootprintInfo() async {
try {
final response = await _homeApi.userGetFriendFootprintInfo();
if (response.data.isSuccess && response.data.data != null) {
friendFootprintInfo.value = response.data.data?.profilePhotoList ?? [];
update();
} else {
//
throw Exception(response.data.message ?? '获取数据失败');
}
} catch(e){
print('钱包数据获取失败: $e');
SmartDialog.showToast('钱包数据获取失败');
rethrow;
}
}
Future<void> _fetchLocation() async {
_status = 'Fetching location...';
try {
print(1);
final location = await _locationPlugin.getCurrentLocation();
print(2);
print(location);
if (location == null) {
_status = 'Location unavailable';
@ -94,6 +130,9 @@ class HomeController extends GetxController {
_cityStatus = 'Skip city lookup';
_cityInfo = null;
print(_status);
print(_cityStatus);
}
}
@ -112,6 +151,8 @@ class HomeController extends GetxController {
print(_cityInfo!.code);
print("_cityInfo.code");
loadNearbyInitialData();
loadNearbyDisInitialData();
} on CityInfoLookupException catch (e) {
@ -211,34 +252,68 @@ class HomeController extends GetxController {
if(cityCode.value == null || cityCode.value == 0){
await _fetchLocation();
} else {
if (nearbyIsLoading.value) return;
try {
nearbyIsLoading.value = true;
nearbyPage.value = 1;
nearbyHasMore.value = true;
// (type=1)
final result = await _fetchMarriageData(
pageNum: 1,
type: 2,
code: districtCode.value
);
//
nearbyDisFeed.clear();
nearbyDisFeed.addAll(result['records']);
//
final int currentPage = result['current'] ?? 1;
// final int totalPages = result['pages'] ?? 1;
final int totalPages = 100;
nearbyHasMore.value = currentPage < totalPages;
} catch (e) {
_handleError('获取同城列表异常', e, '同城列表加载失败,请稍后重试');
} finally {
nearbyIsLoading.value = false;
}
}
if (nearbyIsLoading.value) return;
}
///
Future<void> loadFriendFootInitialData() async {
if (friendIsLoading.value) return;
try {
nearbyIsLoading.value = true;
nearbyPage.value = 1;
nearbyHasMore.value = true;
friendIsLoading.value = true;
friendPage.value = 1;
friendHasMore.value = true;
// (type=1)
// (type=0)
final result = await _fetchMarriageData(
pageNum: 1,
type: 2,
code: districtCode.value
pageNum: 1,
type: 5,
);
//
nearbyDisFeed.clear();
nearbyDisFeed.addAll(result['records']);
//
friendFootFeed.clear();
friendFootFeed.addAll(result['records']);
//
final int currentPage = result['current'] ?? 1;
// final int totalPages = result['pages'] ?? 1;
final int totalPages = 100;
nearbyHasMore.value = currentPage < totalPages;
friendHasMore.value = currentPage < totalPages;
print(friendHasMore.value);
} catch (e) {
_handleError('获取同城列表异常', e, '同城列表加载失败,请稍后重试');
_handleError('获取推荐列表异常', e, '推荐列表加载失败,请稍后重试');
} finally {
nearbyIsLoading.value = false;
friendIsLoading.value = false;
}
}
@ -360,6 +435,41 @@ class HomeController extends GetxController {
}
}
///
Future<void> loadFriendFootMoreData() async {
if (friendIsLoading.value || !friendHasMore.value) return;
try {
friendIsLoading.value = true;
// final nextPage = recommendPage.value + 1;
final nextPage = friendPage.value;
print('推荐列表加载更多 - 当前页: ${friendPage.value}, 下一页: $nextPage');
// (type=0)
final result = await _fetchMarriageData(
pageNum: nextPage,
type: 5,
);
//
friendPage.value = nextPage;
//
friendFootFeed.addAll(result['records']);
//
final int currentPage = result['current'] as int;
// final int totalPages = result['pages'] as int;
final int totalPages = 100;
friendHasMore.value = currentPage < totalPages;
print('推荐列表加载更多完成 - 当前页: $currentPage, 总页数: $totalPages, 还有更多: ${friendHasMore.value}');
} catch (e) {
_handleError('加载推荐更多异常', e, '加载更多失败');
} finally {
friendIsLoading.value = false;
}
}
///
Future<void> refreshData([int? tabIndex]) async {
final targetTab = tabIndex ?? selectedTabIndex.value;
@ -468,6 +578,37 @@ class HomeController extends GetxController {
}
}
///
Future<void> refreshFriendData() async {
if (friendIsLoading.value) return;
try {
friendIsLoading.value = true;
friendPage.value = 1;
friendHasMore.value = true;
// (type=0)
final result = await _fetchMarriageData(
pageNum: 1,
type: 5,
);
//
friendFootFeed.clear();
friendFootFeed.addAll(result['records']);
//
final int currentPage = result['current'] ?? 1;
// final int totalPages = result['pages'] ?? 1;
final int totalPages = 100;
friendHasMore.value = currentPage < totalPages;
} catch (e) {
_handleError('刷新推荐数据异常', e, '刷新失败,请稍后重试');
} finally {
friendIsLoading.value = false;
}
}
///
void setSelectedTabIndex(int index) async {
print('Setting selected tab index to: $index');
@ -475,10 +616,14 @@ class HomeController extends GetxController {
// UI能够更新
update();
if(index == 2 && nearbyFeed.isEmpty){
print(cityCode.value == null || cityCode.value == 0);
print("cityCode.value == null || cityCode.value == 0");
if(cityCode.value == null || cityCode.value == 0){
await _fetchLocation();
_fetchLocation();
} else {
loadNearbyInitialData();
}
loadNearbyInitialData();
}
}
@ -495,51 +640,101 @@ class HomeController extends GetxController {
int? code
}) async {
try {
print('_fetchMarriageData - pageNum: $pageNum, pageSize: $pageSize, type: $type');
// API获取数据
var response = await _homeApi.getMarriageList(
pageNum: pageNum,
pageSize: pageSize,
type: type,
cityCode: type == 1 ? code : null,
districtCode: type == 2 ? code : null,
);
if(type != 5){
print('_fetchMarriageData - pageNum: $pageNum, pageSize: $pageSize, type: $type');
// API获取数据
var response = await _homeApi.getMarriageList(
pageNum: pageNum,
pageSize: pageSize,
type: type,
cityCode: type == 1 ? code : null,
districtCode: type == 2 ? code : null,
);
if (response.data.isSuccess) {
final paginatedData = response.data.data;
// data是否为空
if (paginatedData == null) {
return {
'records': <MarriageData>[],
'current': pageNum,
'pages': 1,
'total': 0,
'size': pageSize,
};
}
// data PaginatedResponse<dynamic>使
// records dynamic MarriageData
final allRecords = paginatedData.records
.map((item) => MarriageData.fromJson(item as Map<String, dynamic>))
.toList();
//
final records = allRecords.where((item) => !item.isLive).toList();
print('_fetchMarriageData 返回 - 请求页码: $pageNum, 返回当前页: ${paginatedData.current}, 总页数: ${paginatedData.pages}, 原始记录数: ${allRecords.length}, 过滤后记录数: ${records.length}');
if (response.data.isSuccess) {
final paginatedData = response.data.data;
// data是否为空
if (paginatedData == null) {
return {
'records': <MarriageData>[],
'current': pageNum,
'pages': 1,
'total': 0,
'size': pageSize,
'records': records,
'current': paginatedData.current,
'pages': paginatedData.pages,
'total': paginatedData.total,
'size': paginatedData.size,
};
} else {
//
throw Exception(response.data.message);
}
// data PaginatedResponse<dynamic>使
// records dynamic MarriageData
final allRecords = paginatedData.records
.map((item) => MarriageData.fromJson(item as Map<String, dynamic>))
.toList();
//
final records = allRecords.where((item) => !item.isLive).toList();
print('_fetchMarriageData 返回 - 请求页码: $pageNum, 返回当前页: ${paginatedData.current}, 总页数: ${paginatedData.pages}, 原始记录数: ${allRecords.length}, 过滤后记录数: ${records.length}');
return {
'records': records,
'current': paginatedData.current,
'pages': paginatedData.pages,
'total': paginatedData.total,
'size': paginatedData.size,
};
} else {
//
throw Exception(response.data.message);
print('_fetchMarriageData - pageNum: $pageNum, pageSize: $pageSize, type: $type');
// API获取数据
var response = await _homeApi.userPageFriendFootprint(
pageNum: pageNum,
pageSize: pageSize,
);
if (response.data.isSuccess) {
final paginatedData = response.data.data;
// data是否为空
if (paginatedData == null) {
return {
'records': <MarriageData>[],
'current': pageNum,
'pages': 1,
'total': 0,
'size': pageSize,
};
}
paginatedData.records.forEach((e){
e["liveStreaming"] = true;
e["isLiveChannelId"] = e["channelId"];
});
// data PaginatedResponse<dynamic>使
// records dynamic MarriageData
final allRecords = paginatedData.records
.map((item) => MarriageData.fromJson(item as Map<String, dynamic>))
.toList();
//
final records = allRecords.where((item) => !item.isLive).toList();
print('_fetchMarriageData 返回 - 请求页码: $pageNum, 返回当前页: ${paginatedData.current}, 总页数: ${paginatedData.pages}, 原始记录数: ${allRecords.length}, 过滤后记录数: ${records.length}');
return {
'records': records,
'current': paginatedData.current,
'pages': paginatedData.pages,
'total': paginatedData.total,
'size': paginatedData.size,
};
} else {
//
throw Exception(response.data.message);
}
}
} catch (e) {
//

6
lib/controller/setting/blacklist_controller.dart

@ -58,15 +58,15 @@ class BlacklistController extends GetxController {
}
}
unBlack(String blackUserId) async {
unBlack(String id) async {
try {
final response = await _userApi.userDeleteUserBlacklist({
"blackUserId": blackUserId,
"id": id,
});
if (response.data.isSuccess) {
SmartDialog.showToast('已解除拉黑');
blackList.value = blackList.where((e) => e.blackUserId != blackUserId).toList();
blackList.value = blackList.where((e) => e.id != id).toList();
} else {
//

18
lib/model/home/check_black_data.dart

@ -0,0 +1,18 @@
class CheckBlackData {
bool? activeBlack;
bool? passiveBlack;
CheckBlackData({this.activeBlack, this.passiveBlack});
CheckBlackData.fromJson(Map<String, dynamic> json) {
activeBlack = json['activeBlack'];
passiveBlack = json['passiveBlack'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['activeBlack'] = this.activeBlack;
data['passiveBlack'] = this.passiveBlack;
return data;
}
}

15
lib/model/home/friend_footprint_info_data.dart

@ -0,0 +1,15 @@
class FriendFootprintInfoData {
List<String>? profilePhotoList;
FriendFootprintInfoData({this.profilePhotoList});
FriendFootprintInfoData.fromJson(Map<String, dynamic> json) {
profilePhotoList = json['profilePhotoList'].cast<String>();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['profilePhotoList'] = this.profilePhotoList;
return data;
}
}

92
lib/model/home/friend_footprint_list_data.dart

@ -0,0 +1,92 @@
class FriendFootprintListData {
List<Records>? records;
int? total;
int? size;
int? current;
int? pages;
FriendFootprintListData(
{this.records, this.total, this.size, this.current, this.pages});
FriendFootprintListData.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? channelId;
String? nickName;
String? profilePhoto;
int? genderCode;
String? birthYear;
String? birthDate;
int? age;
int? provinceCode;
String? provinceName;
int? cityCode;
String? cityName;
Records(
{this.channelId,
this.nickName,
this.profilePhoto,
this.genderCode,
this.birthYear,
this.birthDate,
this.age,
this.provinceCode,
this.provinceName,
this.cityCode,
this.cityName});
Records.fromJson(Map<String, dynamic> json) {
channelId = json['channelId'];
nickName = json['nickName'];
profilePhoto = json['profilePhoto'];
genderCode = json['genderCode'];
birthYear = json['birthYear'];
birthDate = json['birthDate'];
age = json['age'];
provinceCode = json['provinceCode'];
provinceName = json['provinceName'];
cityCode = json['cityCode'];
cityName = json['cityName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['channelId'] = this.channelId;
data['nickName'] = this.nickName;
data['profilePhoto'] = this.profilePhoto;
data['genderCode'] = this.genderCode;
data['birthYear'] = this.birthYear;
data['birthDate'] = this.birthDate;
data['age'] = this.age;
data['provinceCode'] = this.provinceCode;
data['provinceName'] = this.provinceName;
data['cityCode'] = this.cityCode;
data['cityName'] = this.cityName;
return data;
}
}

4
lib/network/api_urls.dart

@ -109,7 +109,9 @@ class ApiUrls {
static const String userGetFriendFootprintInfo =
'dating-agency-chat-audio/user/get/friend-footprint-info';
static const String userPageFriendFootprint =
'/dating-agency-chat-audio/user/page/friend-footprint';
'dating-agency-chat-audio/user/page/friend-footprint';
static const String userCheckUserBlacklist =
'dating-agency-chat-audio/user/check/user-blacklist';
//
static const String getMarriageList =

4
lib/network/home_api.dart

@ -1,3 +1,5 @@
import 'package:dating_touchme_app/model/home/friend_footprint_info_data.dart';
import 'package:dating_touchme_app/model/home/friend_footprint_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/model/home/trend_data.dart' hide Records;
@ -91,7 +93,7 @@ abstract class HomeApi {
@GET(ApiUrls.userGetFriendFootprintInfo)
Future<HttpResponse<BaseResponse<List<String>>>> userGetFriendFootprintInfo();
Future<HttpResponse<BaseResponse<FriendFootprintInfoData>>> userGetFriendFootprintInfo();
@GET(ApiUrls.userPageFriendFootprint)
Future<HttpResponse<BaseResponse<PaginatedResponse<dynamic>>>> userPageFriendFootprint({

36
lib/network/home_api.g.dart

@ -457,30 +457,32 @@ class _HomeApi implements HomeApi {
}
@override
Future<HttpResponse<BaseResponse<List<String>>>>
Future<HttpResponse<BaseResponse<FriendFootprintInfoData>>>
userGetFriendFootprintInfo() async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<HttpResponse<BaseResponse<List<String>>>>(
Options(method: 'GET', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/get/friend-footprint-info',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _options =
_setStreamType<HttpResponse<BaseResponse<FriendFootprintInfoData>>>(
Options(method: 'GET', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/get/friend-footprint-info',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl),
),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<List<String>> _value;
late BaseResponse<FriendFootprintInfoData> _value;
try {
_value = BaseResponse<List<String>>.fromJson(
_value = BaseResponse<FriendFootprintInfoData>.fromJson(
_result.data!,
(json) => json is List<dynamic>
? json.map<String>((i) => i as String).toList()
: List.empty(),
(json) =>
FriendFootprintInfoData.fromJson(json as Map<String, dynamic>),
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
@ -505,7 +507,7 @@ class _HomeApi implements HomeApi {
Options(method: 'GET', headers: _headers, extra: _extra)
.compose(
_dio.options,
'/dating-agency-chat-audio/user/page/friend-footprint',
'dating-agency-chat-audio/user/page/friend-footprint',
queryParameters: queryParameters,
data: _data,
)

6
lib/network/user_api.dart

@ -1,5 +1,6 @@
import 'package:dating_touchme_app/model/common/oss_data.dart';
import 'package:dating_touchme_app/model/discover/task_data.dart';
import 'package:dating_touchme_app/model/home/check_black_data.dart';
import 'package:dating_touchme_app/model/home/post_data.dart';
import 'package:dating_touchme_app/model/home/user_info_data.dart';
import 'package:dating_touchme_app/model/mine/bank_card_data.dart';
@ -335,4 +336,9 @@ abstract class UserApi {
Future<HttpResponse<BaseResponse<dynamic>>> userCreateUserFeedback(
@Body() Map<String, dynamic> data,
);
@GET(ApiUrls.userCheckUserBlacklist)
Future<HttpResponse<BaseResponse<CheckBlackData>>> userCheckUserBlacklist({
@Query('targetUserId') required String targetUserId,
});
}

33
lib/network/user_api.g.dart

@ -2035,6 +2035,39 @@ class _UserApi implements UserApi {
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<CheckBlackData>>> userCheckUserBlacklist({
required String targetUserId,
}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{r'targetUserId': targetUserId};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<HttpResponse<BaseResponse<CheckBlackData>>>(
Options(method: 'GET', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/check/user-blacklist',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<CheckBlackData> _value;
try {
_value = BaseResponse<CheckBlackData>.fromJson(
_result.data!,
(json) => CheckBlackData.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 ||

34
lib/pages/home/content_card.dart

@ -15,7 +15,8 @@ import 'package:get/get.dart';
// //线//Hi/
class _CardHeader extends StatelessWidget {
final MarriageData item;
const _CardHeader({required this.item});
final bool isFoot;
_CardHeader({required this.item, this.isFoot = false});
@override
Widget build(BuildContext context) {
@ -123,6 +124,32 @@ class _CardHeader extends StatelessWidget {
],
),
),
if (isFoot)
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 2,
),
decoration: BoxDecoration(
color: Color.fromRGBO(237, 237, 237, 1),
borderRadius: BorderRadius.circular(12),
),
constraints: BoxConstraints(
minWidth: 40, //
),
child: Row(
mainAxisSize: MainAxisSize.min, // Row只占用必要的宽度
children: [
const Text(
'相遇过',
style: TextStyle(
fontSize: 9,
color: Color.fromRGBO(166, 166, 166, 1),
),
),
],
),
),
//
if (false)
Container(
@ -237,7 +264,8 @@ class _CardHeader extends StatelessWidget {
//
class ContentCard extends StatelessWidget {
final MarriageData item;
ContentCard({required this.item});
final bool isFoot;
ContentCard({required this.item, this.isFoot = false});
@override
Widget build(BuildContext context) {
@ -270,7 +298,7 @@ class ContentCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 线 - HI位置
_CardHeader(item: item),
_CardHeader(item: item, isFoot: isFoot,),
// -
_buildContent(),

153
lib/pages/home/friend_footprint_page.dart

@ -0,0 +1,153 @@
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/content_card.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class FriendFootprintPage extends StatefulWidget {
const FriendFootprintPage({super.key});
@override
State<FriendFootprintPage> createState() => _FriendFootprintPageState();
}
class _FriendFootprintPageState extends State<FriendFootprintPage> {
final HomeController controller = Get.find<HomeController>();
late final EasyRefreshController _refreshController;
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
_refreshController = EasyRefreshController(controlFinishRefresh: true, controlFinishLoad: true);
controller.loadFriendFootInitialData();
}
@override
void dispose() {
_refreshController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PageAppbar(title: "好友足迹"),
body: Obx(() {
if (controller.recommendIsLoading.value && controller.recommendFeed.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('加载数据中...'),
],
),
);
}
return EasyRefresh(
controller: _refreshController,
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('推荐列表下拉刷新被触发');
try {
await controller.refreshFriendData();
print( '推荐列表刷新完成, hasMore: $controller.recommendHasMore.value');
_refreshController.finishRefresh();
_refreshController.resetFooter();
} catch (e) {
print('推荐列表刷新失败: $e');
_refreshController.finishRefresh(IndicatorResult.fail);
}
},
//
onLoad: () async {
print('推荐列表上拉加载被触发, hasMore: $controller.recommendHasMore.value');
try {
await controller.loadFriendFootMoreData();
//
if (controller.friendHasMore.value) {
_refreshController.finishLoad(IndicatorResult.success);
print('推荐列表加载更多成功');
} else {
_refreshController.finishLoad(IndicatorResult.noMore);
print('推荐列表没有更多数据了');
}
} catch (e) {
print('推荐列表加载更多失败: $e');
_refreshController.finishLoad(IndicatorResult.fail);
}
},
child: ListView.separated(
controller: _scrollController,
// 使
// padding AppBar
padding: EdgeInsets.only(left: 12, right: 12),
itemBuilder: (context, index) {
//
if (controller.friendFootFeed.isEmpty && index == 0) {
// 使
if (controller.friendIsLoading.value) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('加载数据中...'),
],
),
);
} else {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('暂无数据'),
],
),
);
}
}
//
final item = controller.friendFootFeed[index];
return ContentCard(item: item, isFoot: true,);
},
separatorBuilder: (context, index) {
//
if (controller.friendFootFeed.isEmpty) {
return const SizedBox.shrink();
}
return const SizedBox(height: 12);
},
// item
itemCount: controller.friendFootFeed.isEmpty ? 1 : controller.friendFootFeed.length,
)
);
}),
);
}
}

120
lib/pages/home/recommend_tab.dart

@ -1,10 +1,15 @@
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/friend_footprint_page.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';
import 'package:dating_touchme_app/controller/home/home_controller.dart';
import 'package:dating_touchme_app/pages/home/content_card.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:flutter_swiper_null_safety/flutter_swiper_null_safety.dart';
/// Tab
class RecommendTab extends StatefulWidget {
@ -173,60 +178,79 @@ class _RecommendTabState extends State<RecommendTab>
)
);
}),
Positioned(
right: 0,
bottom: 42,
child: Obx(() {
return AnimatedContainer(
duration: const Duration(milliseconds: 250),
width: _shrink ? 50 : 142,
height: 50,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50)),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color(0xFF8359FF),
Color(0xFF3D8AE0),
],
Obx(() {
if(controller.friendFootprintInfo.isNotEmpty) {
return Positioned(
right: 0,
bottom: 42,
child: AnimatedContainer(
duration: const Duration(milliseconds: 250),
width: _shrink ? 50 : 142,
height: 50,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50)),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color(0xFF8359FF),
Color(0xFF3D8AE0),
],
),
),
),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(40)),
child: Image.asset(
Assets.imagesUserAvatar,
child: Row(
children: [
SizedBox(
width: 40,
height: 40,
),
),
if(!_shrink) SizedBox(width: 4,),
if(!_shrink) Column(
children: [
Text(
"与你匹配的",
style: TextStyle(
fontSize: 15,
color: Colors.white
),
child: Swiper(
autoplay: true,
itemCount: controller.friendFootprintInfo.length,
loop: true,
itemBuilder: (BuildContext context, int index) {
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(40)),
child: CachedNetworkImage(
imageUrl: controller.friendFootprintInfo[index],
width: 40,
height: 40,
fit: BoxFit.cover,
),
);
},
),
Text(
"${controller.cityCode.value ?? 0}人正在连麦...",
style: TextStyle(
fontSize: 11,
color: Colors.white
),
if(!_shrink) SizedBox(width: 4,),
if(!_shrink) Column(
children: [
Text(
"与你匹配的",
style: TextStyle(
fontSize: 15,
color: Colors.white
),
),
)
],
)
],
),
Text(
"${controller.friendFootprintInfo.length}人正在连麦...",
style: TextStyle(
fontSize: 11,
color: Colors.white
),
)
],
)
],
),
).onTap((){
Get.to(() => FriendFootprintPage());
}),
);
}),
)
} else {
return SizedBox();
}
})
],
);
}

26
lib/pages/mine/mine_page.dart

@ -394,18 +394,6 @@ class MinePageState extends State<MinePage> with AutomaticKeepAliveClientMixin{
Get.to(() => SettingPage());
}
),
TDCell(arrow: true,
leftIconWidget: Image.asset(
gaplessPlayback: true,Assets.imagesCustomer, height: 22.w, width: 22.w),
titleWidget: Text(
"联系客服",
style: TextStyle(
fontSize: 14.w
),
), onClick: (cell) {
Get.to(() => FeedbackPage());
}
),
TDCell(arrow: true,
leftIconWidget: Image.asset(
gaplessPlayback: true,Assets.imagesMail, height: 22.w, width: 22.w),
@ -415,9 +403,21 @@ class MinePageState extends State<MinePage> with AutomaticKeepAliveClientMixin{
fontSize: 14.w
),
), onClick: (cell) {
Get.to(() => UserHelpCenterPage());
Get.to(() => FeedbackPage());
}
),
// TDCell(arrow: true,
// leftIconWidget: Image.asset(
// gaplessPlayback: true,Assets.imagesCustomer, height: 22.w, width: 22.w),
// titleWidget: Text(
// "意见反馈",
// style: TextStyle(
// fontSize: 14.w
// ),
// ), onClick: (cell) {
// Get.to(() => UserHelpCenterPage());
// }
// ),
],
),
],

2
lib/pages/mine/real_feedback_page.dart

@ -264,7 +264,7 @@ class RealFeedbackPage extends StatelessWidget {
vertical: 0,
horizontal: 0
),
hintText: "请输入交友心声",
hintText: "请输入您的宝贵的建议",
border: const OutlineInputBorder(
borderSide: BorderSide.none, // //

4
lib/pages/setting/blacklist_page.dart

@ -137,7 +137,7 @@ class _BlackItemState extends State<BlackItem> {
),
),
Text(
"30岁·广州",
"拉黑时间:${widget.item.createTime}",
style: TextStyle(
fontSize: 11.w,
color: const Color.fromRGBO(144, 144, 144, 1)
@ -199,7 +199,7 @@ class _BlackItemState extends State<BlackItem> {
),
),
).onTap((){
widget.controller.unBlack(widget.item.blackUserId ?? "");
widget.controller.unBlack(widget.item.id ?? "");
}),
Container(
height: 65.w,

Loading…
Cancel
Save