zk 10 месяцев назад
Родитель
Сommit
cda787ca54

+ 6 - 0
assets/string/base/string.xml

@@ -189,5 +189,11 @@
     <string name="message_accepted">已同意您的好友申请</string>
     <string name="message_rejected">已拒绝您的好友申请</string>
     <string name="message_delete_your">您的好友删除了你</string>
+    <string name="message_no_data">暂无消息</string>
+    <string name="message_new_friend_title">新的好友</string>
+    <string name="message_friend_refuse">拒绝</string>
+    <string name="message_friend_agree">同意</string>
+    <string name="message_friend_request_rejected">好友请求已拒绝</string>
+    <string name="message_friend_request_agreed">好友请求已同意</string>
 
 </resources>

+ 10 - 1
lib/data/api/atmob_api.dart

@@ -7,6 +7,7 @@ import 'package:location/data/api/request/friends_list_request.dart';
 import 'package:location/data/api/request/friends_operation_request.dart';
 import 'package:location/data/api/request/login_request.dart';
 import 'package:location/data/api/request/message_request.dart';
+import 'package:location/data/api/request/operation_friend_request.dart';
 import 'package:location/data/api/request/query_track_request.dart';
 import 'package:location/data/api/request/request_friendlist_request.dart';
 import 'package:location/data/api/request/send_code_request.dart';
@@ -91,6 +92,14 @@ abstract class AtmobApi {
       @Body() RequestFriendListRequest request);
 
   @POST("/s/v1/friend/request/list/waiting")
-  Future<BaseResponse<RequestFriendListResponse>> getFriendRequestCount(
+  Future<BaseResponse<RequestFriendListResponse>> getRequestWaitingList(
       @Body() RequestFriendListRequest request);
+
+  @POST("/s/v1/friend/request/accept")
+  Future<BaseResponse> acceptFriendAccept(
+      @Body() OperationFriendRequest request);
+
+  @POST("/s/v1/friend/request/refuse")
+  Future<BaseResponse> refuseFriendAccept(
+      @Body() OperationFriendRequest request);
 }

+ 77 - 1
lib/data/api/atmob_api.g.dart

@@ -638,7 +638,7 @@ class _AtmobApi implements AtmobApi {
   }
 
   @override
-  Future<BaseResponse<RequestFriendListResponse>> getFriendRequestCount(
+  Future<BaseResponse<RequestFriendListResponse>> getRequestWaitingList(
       RequestFriendListRequest request) async {
     final _extra = <String, dynamic>{};
     final queryParameters = <String, dynamic>{};
@@ -677,6 +677,82 @@ class _AtmobApi implements AtmobApi {
     return _value;
   }
 
+  @override
+  Future<BaseResponse<dynamic>> acceptFriendAccept(
+      OperationFriendRequest request) async {
+    final _extra = <String, dynamic>{};
+    final queryParameters = <String, dynamic>{};
+    final _headers = <String, dynamic>{};
+    final _data = <String, dynamic>{};
+    _data.addAll(request.toJson());
+    final _options = _setStreamType<BaseResponse<dynamic>>(Options(
+      method: 'POST',
+      headers: _headers,
+      extra: _extra,
+    )
+        .compose(
+      _dio.options,
+      '/s/v1/friend/request/accept',
+      queryParameters: queryParameters,
+      data: _data,
+    )
+        .copyWith(
+        baseUrl: _combineBaseUrls(
+          _dio.options.baseUrl,
+          baseUrl,
+        )));
+    final _result = await _dio.fetch<Map<String, dynamic>>(_options);
+    late BaseResponse<dynamic> _value;
+    try {
+      _value = BaseResponse<dynamic>.fromJson(
+        _result.data!,
+            (json) => json as dynamic,
+      );
+    } on Object catch (e, s) {
+      errorLogger?.logError(e, s, _options);
+      rethrow;
+    }
+    return _value;
+  }
+
+  @override
+  Future<BaseResponse<dynamic>> refuseFriendAccept(
+      OperationFriendRequest request) async {
+    final _extra = <String, dynamic>{};
+    final queryParameters = <String, dynamic>{};
+    final _headers = <String, dynamic>{};
+    final _data = <String, dynamic>{};
+    _data.addAll(request.toJson());
+    final _options = _setStreamType<BaseResponse<dynamic>>(Options(
+      method: 'POST',
+      headers: _headers,
+      extra: _extra,
+    )
+        .compose(
+      _dio.options,
+      '/s/v1/friend/request/refuse',
+      queryParameters: queryParameters,
+      data: _data,
+    )
+        .copyWith(
+        baseUrl: _combineBaseUrls(
+          _dio.options.baseUrl,
+          baseUrl,
+        )));
+    final _result = await _dio.fetch<Map<String, dynamic>>(_options);
+    late BaseResponse<dynamic> _value;
+    try {
+      _value = BaseResponse<dynamic>.fromJson(
+        _result.data!,
+            (json) => json as dynamic,
+      );
+    } on Object catch (e, s) {
+      errorLogger?.logError(e, s, _options);
+      rethrow;
+    }
+    return _value;
+  }
+
   RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
     if (T != dynamic &&
         !(requestOptions.responseType == ResponseType.bytes ||

+ 71 - 0
lib/data/api/request/message_request.g.dart

@@ -0,0 +1,71 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'message_request.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+MessageRequest _$MessageRequestFromJson(Map<String, dynamic> json) =>
+    MessageRequest(
+      offset: (json['offset'] as num?)?.toInt(),
+      limit: (json['limit'] as num?)?.toInt(),
+    )
+      ..appPlatform = (json['appPlatform'] as num).toInt()
+      ..os = json['os'] as String
+      ..osVersion = json['osVersion'] as String
+      ..packageName = json['packageName'] as String?
+      ..appVersionName = json['appVersionName'] as String?
+      ..appVersionCode = (json['appVersionCode'] as num?)?.toInt()
+      ..channelName = json['channelName'] as String?
+      ..appId = (json['appId'] as num?)?.toInt()
+      ..tgPlatform = (json['tgPlatform'] as num?)?.toInt()
+      ..oaid = json['oaid'] as String?
+      ..aaid = json['aaid'] as String?
+      ..androidId = json['androidId'] as String?
+      ..imei = json['imei'] as String?
+      ..simImei0 = json['simImei0'] as String?
+      ..simImei1 = json['simImei1'] as String?
+      ..mac = json['mac'] as String?
+      ..idfa = json['idfa'] as String?
+      ..idfv = json['idfv'] as String?
+      ..machineId = json['machineId'] as String?
+      ..brand = json['brand'] as String?
+      ..model = json['model'] as String?
+      ..wifiName = json['wifiName'] as String?
+      ..region = json['region'] as String?
+      ..locLng = (json['locLng'] as num?)?.toDouble()
+      ..locLat = (json['locLat'] as num?)?.toDouble()
+      ..authToken = json['authToken'] as String?;
+
+Map<String, dynamic> _$MessageRequestToJson(MessageRequest instance) =>
+    <String, dynamic>{
+      'appPlatform': instance.appPlatform,
+      'os': instance.os,
+      'osVersion': instance.osVersion,
+      'packageName': instance.packageName,
+      'appVersionName': instance.appVersionName,
+      'appVersionCode': instance.appVersionCode,
+      'channelName': instance.channelName,
+      'appId': instance.appId,
+      'tgPlatform': instance.tgPlatform,
+      'oaid': instance.oaid,
+      'aaid': instance.aaid,
+      'androidId': instance.androidId,
+      'imei': instance.imei,
+      'simImei0': instance.simImei0,
+      'simImei1': instance.simImei1,
+      'mac': instance.mac,
+      'idfa': instance.idfa,
+      'idfv': instance.idfv,
+      'machineId': instance.machineId,
+      'brand': instance.brand,
+      'model': instance.model,
+      'wifiName': instance.wifiName,
+      'region': instance.region,
+      'locLng': instance.locLng,
+      'locLat': instance.locLat,
+      'authToken': instance.authToken,
+      'offset': instance.offset,
+      'limit': instance.limit,
+    };

+ 18 - 0
lib/data/api/request/operation_friend_request.dart

@@ -0,0 +1,18 @@
+import 'package:json_annotation/json_annotation.dart';
+import 'package:location/base/app_base_request.dart';
+
+part 'operation_friend_request.g.dart';
+
+@JsonSerializable()
+class OperationFriendRequest extends AppBaseRequest {
+  @JsonKey(name: 'id')
+  int friendId;
+
+  OperationFriendRequest(this.friendId);
+
+  factory OperationFriendRequest.fromJson(Map<String, dynamic> json) =>
+      _$OperationFriendRequestFromJson(json);
+
+  @override
+  Map<String, dynamic> toJson() => _$OperationFriendRequestToJson(this);
+}

+ 71 - 0
lib/data/api/request/operation_friend_request.g.dart

@@ -0,0 +1,71 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'operation_friend_request.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+OperationFriendRequest _$OperationFriendRequestFromJson(
+    Map<String, dynamic> json) =>
+    OperationFriendRequest(
+      (json['id'] as num).toInt(),
+    )
+      ..appPlatform = (json['appPlatform'] as num).toInt()
+      ..os = json['os'] as String
+      ..osVersion = json['osVersion'] as String
+      ..packageName = json['packageName'] as String?
+      ..appVersionName = json['appVersionName'] as String?
+      ..appVersionCode = (json['appVersionCode'] as num?)?.toInt()
+      ..channelName = json['channelName'] as String?
+      ..appId = (json['appId'] as num?)?.toInt()
+      ..tgPlatform = (json['tgPlatform'] as num?)?.toInt()
+      ..oaid = json['oaid'] as String?
+      ..aaid = json['aaid'] as String?
+      ..androidId = json['androidId'] as String?
+      ..imei = json['imei'] as String?
+      ..simImei0 = json['simImei0'] as String?
+      ..simImei1 = json['simImei1'] as String?
+      ..mac = json['mac'] as String?
+      ..idfa = json['idfa'] as String?
+      ..idfv = json['idfv'] as String?
+      ..machineId = json['machineId'] as String?
+      ..brand = json['brand'] as String?
+      ..model = json['model'] as String?
+      ..wifiName = json['wifiName'] as String?
+      ..region = json['region'] as String?
+      ..locLng = (json['locLng'] as num?)?.toDouble()
+      ..locLat = (json['locLat'] as num?)?.toDouble()
+      ..authToken = json['authToken'] as String?;
+
+Map<String, dynamic> _$OperationFriendRequestToJson(
+    OperationFriendRequest instance) =>
+    <String, dynamic>{
+      'appPlatform': instance.appPlatform,
+      'os': instance.os,
+      'osVersion': instance.osVersion,
+      'packageName': instance.packageName,
+      'appVersionName': instance.appVersionName,
+      'appVersionCode': instance.appVersionCode,
+      'channelName': instance.channelName,
+      'appId': instance.appId,
+      'tgPlatform': instance.tgPlatform,
+      'oaid': instance.oaid,
+      'aaid': instance.aaid,
+      'androidId': instance.androidId,
+      'imei': instance.imei,
+      'simImei0': instance.simImei0,
+      'simImei1': instance.simImei1,
+      'mac': instance.mac,
+      'idfa': instance.idfa,
+      'idfv': instance.idfv,
+      'machineId': instance.machineId,
+      'brand': instance.brand,
+      'model': instance.model,
+      'wifiName': instance.wifiName,
+      'region': instance.region,
+      'locLng': instance.locLng,
+      'locLat': instance.locLat,
+      'authToken': instance.authToken,
+      'id': instance.friendId,
+    };

+ 77 - 0
lib/data/api/request/request_friendlist_request.g.dart

@@ -0,0 +1,77 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'request_friendlist_request.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+RequestFriendListRequest _$RequestFriendListRequestFromJson(
+    Map<String, dynamic> json) =>
+    RequestFriendListRequest(
+      offset: (json['offset'] as num?)?.toInt(),
+      limit: (json['limit'] as num?)?.toInt(),
+      after: (json['after'] as num?)?.toInt(),
+      before: (json['before'] as num?)?.toInt(),
+    )
+      ..appPlatform = (json['appPlatform'] as num).toInt()
+      ..os = json['os'] as String
+      ..osVersion = json['osVersion'] as String
+      ..packageName = json['packageName'] as String?
+      ..appVersionName = json['appVersionName'] as String?
+      ..appVersionCode = (json['appVersionCode'] as num?)?.toInt()
+      ..channelName = json['channelName'] as String?
+      ..appId = (json['appId'] as num?)?.toInt()
+      ..tgPlatform = (json['tgPlatform'] as num?)?.toInt()
+      ..oaid = json['oaid'] as String?
+      ..aaid = json['aaid'] as String?
+      ..androidId = json['androidId'] as String?
+      ..imei = json['imei'] as String?
+      ..simImei0 = json['simImei0'] as String?
+      ..simImei1 = json['simImei1'] as String?
+      ..mac = json['mac'] as String?
+      ..idfa = json['idfa'] as String?
+      ..idfv = json['idfv'] as String?
+      ..machineId = json['machineId'] as String?
+      ..brand = json['brand'] as String?
+      ..model = json['model'] as String?
+      ..wifiName = json['wifiName'] as String?
+      ..region = json['region'] as String?
+      ..locLng = (json['locLng'] as num?)?.toDouble()
+      ..locLat = (json['locLat'] as num?)?.toDouble()
+      ..authToken = json['authToken'] as String?;
+
+Map<String, dynamic> _$RequestFriendListRequestToJson(
+    RequestFriendListRequest instance) =>
+    <String, dynamic>{
+      'appPlatform': instance.appPlatform,
+      'os': instance.os,
+      'osVersion': instance.osVersion,
+      'packageName': instance.packageName,
+      'appVersionName': instance.appVersionName,
+      'appVersionCode': instance.appVersionCode,
+      'channelName': instance.channelName,
+      'appId': instance.appId,
+      'tgPlatform': instance.tgPlatform,
+      'oaid': instance.oaid,
+      'aaid': instance.aaid,
+      'androidId': instance.androidId,
+      'imei': instance.imei,
+      'simImei0': instance.simImei0,
+      'simImei1': instance.simImei1,
+      'mac': instance.mac,
+      'idfa': instance.idfa,
+      'idfv': instance.idfv,
+      'machineId': instance.machineId,
+      'brand': instance.brand,
+      'model': instance.model,
+      'wifiName': instance.wifiName,
+      'region': instance.region,
+      'locLng': instance.locLng,
+      'locLat': instance.locLat,
+      'authToken': instance.authToken,
+      'offset': instance.offset,
+      'limit': instance.limit,
+      'after': instance.after,
+      'before': instance.before,
+    };

+ 21 - 0
lib/data/api/response/message_response.g.dart

@@ -0,0 +1,21 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'message_response.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+MessageResponse _$MessageResponseFromJson(Map<String, dynamic> json) =>
+    MessageResponse(
+      (json['count'] as num).toInt(),
+      (json['list'] as List<dynamic>?)
+          ?.map((e) => MessageInfo.fromJson(e as Map<String, dynamic>))
+          .toList(),
+    );
+
+Map<String, dynamic> _$MessageResponseToJson(MessageResponse instance) =>
+    <String, dynamic>{
+      'count': instance.count,
+      'list': instance.list,
+    };

+ 23 - 0
lib/data/api/response/request_friend_list_response.g.dart

@@ -0,0 +1,23 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'request_friend_list_response.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+RequestFriendListResponse _$RequestFriendListResponseFromJson(
+    Map<String, dynamic> json) =>
+    RequestFriendListResponse(
+      (json['count'] as num).toInt(),
+      (json['list'] as List<dynamic>?)
+          ?.map((e) => RequestFriendInfo.fromJson(e as Map<String, dynamic>))
+          .toList(),
+    );
+
+Map<String, dynamic> _$RequestFriendListResponseToJson(
+    RequestFriendListResponse instance) =>
+    <String, dynamic>{
+      'count': instance.count,
+      'list': instance.list,
+    };

+ 27 - 0
lib/data/bean/message_info.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'message_info.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+MessageInfo _$MessageInfoFromJson(Map<String, dynamic> json) =>
+    MessageInfo(
+      id: (json['id'] as num).toInt(),
+      type: (json['type'] as num).toInt(),
+      senderId: json['senderId'] as String,
+      senderPhone: json['senderPhone'] as String,
+      content: json['content'] as String?,
+      createTime: (json['createTime'] as num).toInt(),
+    );
+
+Map<String, dynamic> _$MessageInfoToJson(MessageInfo instance) =>
+    <String, dynamic>{
+      'id': instance.id,
+      'type': instance.type,
+      'senderId': instance.senderId,
+      'senderPhone': instance.senderPhone,
+      'content': instance.content,
+      'createTime': instance.createTime,
+    };

+ 29 - 0
lib/data/bean/request_friend_info.g.dart

@@ -0,0 +1,29 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'request_friend_info.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+RequestFriendInfo _$RequestFriendInfoFromJson(Map<String, dynamic> json) =>
+    RequestFriendInfo(
+      id: (json['id'] as num).toInt(),
+      userId: json['userId'] as String,
+      userPhone: json['userPhone'] as String,
+      friendId: json['friendId'] as String,
+      friendPhone: json['friendPhone'] as String,
+      createTime: (json['createTime'] as num).toInt(),
+      status: (json['status'] as num).toInt(),
+    );
+
+Map<String, dynamic> _$RequestFriendInfoToJson(RequestFriendInfo instance) =>
+    <String, dynamic>{
+      'id': instance.id,
+      'userId': instance.userId,
+      'userPhone': instance.userPhone,
+      'friendId': instance.friendId,
+      'friendPhone': instance.friendPhone,
+      'createTime': instance.createTime,
+      'status': instance.status,
+    };

+ 1 - 1
lib/data/repositories/account_repository.dart

@@ -119,7 +119,7 @@ class AccountRepository {
 
     refreshMemberStatus();
     friendsRepository.refreshFriends();
-    messageRepository.refreshFriendRequest();
+    messageRepository.refreshFriendWaitingCount();
   }
 
   void logout() {

+ 27 - 5
lib/data/repositories/message_repository.dart

@@ -5,6 +5,7 @@ import 'package:location/di/get_it.dart';
 import 'package:location/utils/http_handler.dart';
 
 import '../api/request/message_request.dart';
+import '../api/request/operation_friend_request.dart';
 import '../api/request/request_friendlist_request.dart';
 import '../api/response/message_response.dart';
 import '../api/response/request_friend_list_response.dart';
@@ -19,26 +20,26 @@ class MessageRepository {
   RxInt waitingCount = RxInt(0);
 
   MessageRepository(this.atmobApi) {
-    refreshFriendRequest();
+    refreshFriendWaitingCount();
   }
 
   static MessageRepository getInstance() {
     return getIt.get<MessageRepository>();
   }
 
-  void refreshFriendRequest() {
+  void refreshFriendWaitingCount() {
     if (isRefreshing) {
       return;
     }
     isRefreshing = true;
-    _getFriendRequestCount().whenComplete(() {
+    getRequestWaitingList().whenComplete(() {
       isRefreshing = false;
     });
   }
 
-  Future<RequestFriendListResponse> _getFriendRequestCount() {
+  Future<RequestFriendListResponse> getRequestWaitingList() {
     return atmobApi
-        .getFriendRequestCount(RequestFriendListRequest())
+        .getRequestWaitingList(RequestFriendListRequest())
         .then(HttpHandler.handle(true))
         .then((data) {
       if (data.list == null || data.list!.isEmpty) {
@@ -51,8 +52,15 @@ class MessageRepository {
     });
   }
 
+  Future<RequestFriendListResponse> getRequestFriendList() {
+    return atmobApi
+        .getRequestFriendList(RequestFriendListRequest())
+        .then(HttpHandler.handle(true));
+  }
+
   void clearMessage() {
     latestFriendRequest.value = null;
+    waitingCount.value = 0;
   }
 
   Future<MessageResponse> getMessageList() {
@@ -60,4 +68,18 @@ class MessageRepository {
         .getMessageList(MessageRequest())
         .then(HttpHandler.handle(true));
   }
+
+  Future<void> acceptFriendAccept(int friendId) {
+    return atmobApi
+        .acceptFriendAccept(OperationFriendRequest(friendId))
+        .then(HttpHandler.handle(true))
+        .then((_) => refreshFriendWaitingCount());
+  }
+
+  Future<void> refuseFriendAccept(int friendId) {
+    return atmobApi
+        .refuseFriendAccept(OperationFriendRequest(friendId))
+        .then(HttpHandler.handle(true))
+        .then((_) => refreshFriendWaitingCount());
+  }
 }

+ 6 - 0
lib/di/get_it.config.dart

@@ -28,6 +28,7 @@ import '../module/main/main_controller.dart' as _i731;
 import '../module/member/member_controller.dart' as _i269;
 import '../module/mine/mine_controller.dart' as _i732;
 import '../module/news/news_controller.dart' as _i489;
+import '../module/news/pending_list/news_pending_list_controller.dart' as _i433;
 import '../module/splash/splash_controller.dart' as _i973;
 import '../module/track/track_controller.dart' as _i518;
 import '../socket/atmob_location_client.dart' as _i220;
@@ -82,6 +83,11 @@ extension GetItInjectableX on _i174.GetIt {
           gh<_i1053.FriendsRepository>(),
           gh<_i20.AccountRepository>(),
         ));
+    gh.factory<_i433.NewsPendingListController>(
+        () => _i433.NewsPendingListController(
+              gh<_i791.MessageRepository>(),
+              gh<_i1053.FriendsRepository>(),
+            ));
     gh.factory<_i897.AddFriendDialogController>(
         () => _i897.AddFriendDialogController(gh<_i1053.FriendsRepository>()));
     gh.factory<_i492.FriendSettingController>(

+ 4 - 0
lib/module/main/main_controller.dart

@@ -268,6 +268,10 @@ class MainController extends BaseController {
   }
 
   void onNewsClick() {
+    if (!accountRepository.isLogin.value) {
+      LoginPage.start();
+      return;
+    }
     NewsPage.start();
   }
 }

+ 8 - 1
lib/module/news/news_controller.dart

@@ -6,6 +6,7 @@ import 'package:injectable/injectable.dart';
 import 'package:location/base/base_controller.dart';
 import 'package:location/data/repositories/message_repository.dart';
 import 'package:location/handler/error_handler.dart';
+import 'package:location/module/news/pending_list/news_pending_list_page.dart';
 import 'package:url_launcher/url_launcher.dart';
 import '../../data/bean/message_info.dart';
 import '../../data/bean/request_friend_info.dart';
@@ -52,7 +53,9 @@ class NewsController extends BaseController {
     Get.back();
   }
 
-  void newsClick() {}
+  void newsClick() {
+    NewsPendingListPage.start();
+  }
 
   void requestMessageList() {
     messageRepository.getMessageList().then((response) {
@@ -91,4 +94,8 @@ class NewsController extends BaseController {
       throw '无法跳转拨号界面';
     }
   }
+
+  void onMessageWaitingClick() {
+    NewsPendingListPage.start();
+  }
 }

+ 2 - 3
lib/module/news/news_list_item.dart

@@ -13,7 +13,7 @@ typedef MessageFunCallback = void Function(MessageInfo info);
 Widget buildMessageInfoItem(MessageInfo item, MessageFunCallback callback) {
   return buildMessageItem(Assets.images.iconDefaultFriendAvatar.provider(),
       title: item.senderPhone ?? '',
-      content: getMessageContentTxt(item),
+      content: getMessageContentTxt(item.type),
       contentTextStyle: getMessageContentTextStyle(item.type),
       createTime: item.createTime,
       bgGradient: getMessageBgGradient(item.type),
@@ -73,8 +73,7 @@ Widget getMessageStatusWidget(int type, {VoidCallback? funClick}) {
 // 3:你的好友请求已经被拒绝
 // 4:好友发来的求救
 // 5:你的好友删除了你
-String getMessageContentTxt(MessageInfo info) {
-  int type = info.type;
+String getMessageContentTxt(int type) {
   if (type == 2) {
     return StringName.messageAccepted;
   } else if (type == 3) {

+ 72 - 40
lib/module/news/news_page.dart

@@ -1,12 +1,12 @@
 import 'dart:ui';
 
+import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
 import 'package:get/get_core/src/get_main.dart';
 import 'package:location/base/base_page.dart';
-import 'package:location/data/bean/message_info.dart';
 import 'package:location/utils/common_expand.dart';
 import '../../resource/assets.gen.dart';
 import '../../resource/colors.gen.dart';
@@ -37,27 +37,25 @@ class NewsPage extends BasePage<NewsController> {
             top: 24.w,
             right: 19.w,
             child: SafeArea(child: Obx(() {
-              return Opacity(
-                  opacity: 1 - controller.opacity,
-                  child: Assets.images.iconNews.image(width: 118.w));
+              return Visibility(
+                visible: controller.waitingNewsCount > 0 ||
+                    controller.messageList.isNotEmpty,
+                child: Opacity(
+                    opacity: 1 - controller.opacity,
+                    child: Assets.images.iconNews.image(width: 118.w)),
+              );
             }))),
         SafeArea(
           child: Column(
             children: [
               buildHeadView(),
-              Expanded(
-                  child: CustomScrollView(
-                controller: controller.scrollController,
-                slivers: [
-                  buildSliverTitle(),
-                  buildSliverWaiting(),
-                  Obx(() {
-                    return SliverList.builder(
-                        itemBuilder: buildNewsItem,
-                        itemCount: controller.messageList.length);
-                  })
-                ],
-              ))
+              Obx(() {
+                return Expanded(
+                    child: controller.waitingNewsCount == 0 &&
+                            controller.messageList.isEmpty
+                        ? buildNoMessageView()
+                        : buildHasMessageView());
+              })
             ],
           ),
         )
@@ -65,6 +63,21 @@ class NewsPage extends BasePage<NewsController> {
     );
   }
 
+  CustomScrollView buildHasMessageView() {
+    return CustomScrollView(
+      controller: controller.scrollController,
+      slivers: [
+        buildSliverTitle(),
+        buildSliverWaiting(),
+        Obx(() {
+          return SliverList.builder(
+              itemBuilder: buildNewsItem,
+              itemCount: controller.messageList.length);
+        })
+      ],
+    );
+  }
+
   SliverToBoxAdapter buildSliverTitle() {
     return SliverToBoxAdapter(
         child: Column(
@@ -117,29 +130,32 @@ class NewsPage extends BasePage<NewsController> {
       if (controller.waitingNewsCount == 0) {
         return SizedBox.shrink();
       }
-      return buildMessageItem(Assets.images.iconNewsItem.provider(),
-          title: StringName.newsRequestTitle,
-          content: StringName.newsRequestDesc,
-          contentTextStyle:
-              TextStyle(fontSize: 12.sp, color: ColorName.black60),
-          createTime: controller.latestFriendRequest?.createTime ?? 0,
-          statusWidget: Container(
-            height: 16.w,
-            constraints: BoxConstraints(
-              minWidth: 16.w,
-            ),
-            padding: EdgeInsets.symmetric(horizontal: 2.w),
-            decoration: BoxDecoration(
-              color: '#FF333D'.color,
-              borderRadius: BorderRadius.circular(100),
-            ),
-            child: Center(
-              child: Text('${controller.waitingNewsCount}',
-                  textAlign: TextAlign.center,
-                  style: TextStyle(
-                      fontSize: 10.sp, color: ColorName.white, height: 1)),
-            ),
-          ));
+      return GestureDetector(
+        onTap: () => controller.onMessageWaitingClick(),
+        child: buildMessageItem(Assets.images.iconNewsItem.provider(),
+            title: StringName.newsRequestTitle,
+            content: StringName.newsRequestDesc,
+            contentTextStyle:
+                TextStyle(fontSize: 12.sp, color: ColorName.black60),
+            createTime: controller.latestFriendRequest?.createTime ?? 0,
+            statusWidget: Container(
+              height: 16.w,
+              constraints: BoxConstraints(
+                minWidth: 16.w,
+              ),
+              padding: EdgeInsets.symmetric(horizontal: 2.w),
+              decoration: BoxDecoration(
+                color: '#FF333D'.color,
+                borderRadius: BorderRadius.circular(100),
+              ),
+              child: Center(
+                child: Text('${controller.waitingNewsCount}',
+                    textAlign: TextAlign.center,
+                    style: TextStyle(
+                        fontSize: 10.sp, color: ColorName.white, height: 1)),
+              ),
+            )),
+      );
     }));
   }
 
@@ -148,4 +164,20 @@ class NewsPage extends BasePage<NewsController> {
     return buildMessageInfoItem(
         item, (info) => controller.onMessageFunClick(info));
   }
+
+  Widget buildNoMessageView() {
+    return Align(
+      alignment: Alignment(0, -0.1),
+      child: IntrinsicHeight(
+        child: Column(
+          children: [
+            Assets.images.iconNews.image(width: 150.w),
+            SizedBox(height: 9.w),
+            Text(StringName.messageNoData,
+                style: TextStyle(fontSize: 16.sp, color: ColorName.black60))
+          ],
+        ),
+      ),
+    );
+  }
 }

+ 66 - 0
lib/module/news/pending_list/news_pending_list_controller.dart

@@ -0,0 +1,66 @@
+import 'package:get/get.dart';
+import 'package:get/get_core/src/get_main.dart';
+import 'package:injectable/injectable.dart';
+import 'package:location/base/base_controller.dart';
+import 'package:location/data/bean/request_friend_info.dart';
+import 'package:location/data/repositories/friends_repository.dart';
+import 'package:location/data/repositories/message_repository.dart';
+import 'package:location/handler/error_handler.dart';
+import 'package:location/resource/string.gen.dart';
+import 'package:location/utils/toast_util.dart';
+
+import '../../../utils/de_bounce.dart';
+
+@injectable
+class NewsPendingListController extends BaseController {
+  final RxList<RequestFriendInfo> pendingList = RxList();
+
+  final MessageRepository messageRepository;
+  final FriendsRepository friendsRepository;
+
+  final Debounce _saveDebounce = Debounce(debounceTime: 500);
+
+  NewsPendingListController(this.messageRepository, this.friendsRepository);
+
+  @override
+  void onReady() {
+    super.onReady();
+    refreshWaitingList();
+  }
+
+  void back() {
+    Get.back();
+  }
+
+  void refreshWaitingList() {
+    messageRepository.getRequestFriendList().then((response) {
+      final list = response.list;
+      pendingList.clear();
+      if (list != null) {
+        pendingList.addAll(list);
+      }
+    }).catchError((error) {
+      ErrorHandler.toastError(error);
+    });
+  }
+
+  void onRefuseFriend(RequestFriendInfo item) {
+    _saveDebounce
+        .onClick(() => messageRepository.refuseFriendAccept(item.id).then((_) {
+              ToastUtil.show(StringName.messageFriendRequestRejected);
+              refreshWaitingList();
+            }).catchError((error) {
+              ErrorHandler.toastError(error);
+            }));
+  }
+
+  onAgreeFriend(RequestFriendInfo item) {
+    _saveDebounce
+        .onClick(() => messageRepository.acceptFriendAccept(item.id).then((_) {
+              ToastUtil.show(StringName.messageFriendRequestAgreed);
+              refreshWaitingList();
+            }).catchError((error) {
+              ErrorHandler.toastError(error);
+            }));
+  }
+}

+ 171 - 0
lib/module/news/pending_list/news_pending_list_page.dart

@@ -0,0 +1,171 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:get/get_core/src/get_main.dart';
+import 'package:location/base/base_page.dart';
+import 'package:location/data/bean/request_friend_info.dart';
+import 'package:location/resource/assets.gen.dart';
+import 'package:location/resource/colors.gen.dart';
+import 'package:location/utils/common_expand.dart';
+import 'package:location/utils/date_util.dart';
+import '../../../resource/string.gen.dart';
+import '../../../router/app_pages.dart';
+import '../../../widget/common_view.dart';
+import '../news_list_item.dart';
+import 'news_pending_list_controller.dart';
+
+class NewsPendingListPage extends BasePage<NewsPendingListController> {
+  const NewsPendingListPage({super.key});
+
+  static void start() {
+    Get.toNamed(RoutePath.newsPendingList);
+  }
+
+  @override
+  Color backgroundColor() {
+    return '#F7F7F7'.color;
+  }
+
+  @override
+  Widget buildBody(BuildContext context) {
+    return Column(
+      children: [
+        buildHeadView(),
+        Expanded(child: Obx(() {
+          return ListView.builder(
+              itemBuilder: buildPendingItem,
+              itemCount: controller.pendingList.length);
+        }))
+      ],
+    );
+  }
+
+  Widget buildHeadView() {
+    return Container(
+      margin: EdgeInsets.symmetric(horizontal: 12.w, vertical: 14.w),
+      child: Row(
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: [
+          GestureDetector(
+              onTap: controller.back, child: CommonView.getBackBtnView()),
+          Text(StringName.messageNewFriendTitle,
+              style: TextStyle(
+                  fontSize: 18.sp,
+                  color: '#202020'.color,
+                  fontWeight: FontWeight.bold)),
+          SizedBox(width: 24.w, height: 24.w)
+        ],
+      ),
+    );
+  }
+
+  ///1:待处理
+  // 2:接受
+  // 3:拒绝
+  Widget buildPendingItem(BuildContext context, int index) {
+    final item = controller.pendingList[index];
+    if (item.status == 1) {
+      return buildTodoItem(item);
+    } else {
+      return buildMessageItem(Assets.images.iconDefaultFriendAvatar.provider(),
+          title: item.userPhone,
+          content: getMessageContentTxt(item.status),
+          contentTextStyle: getMessageContentTextStyle(item.status),
+          createTime: item.createTime,
+          statusWidget: getMessageStatusWidget(item.status));
+    }
+  }
+
+  Widget buildTodoItem(RequestFriendInfo item) {
+    return Container(
+      decoration: BoxDecoration(
+          color: Colors.white, borderRadius: BorderRadius.circular(14.w)),
+      padding:
+          EdgeInsets.only(top: 16.w, left: 10.w, right: 17.w, bottom: 20.w),
+      margin: EdgeInsets.only(left: 12.w, right: 12.w, bottom: 10.w),
+      child: Column(
+        children: [
+          Row(
+            children: [
+              Assets.images.iconDefaultFriendAvatar
+                  .image(width: 48.w, height: 48.w),
+              SizedBox(width: 9.w),
+              Expanded(
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    RichText(
+                        text: TextSpan(
+                            style: TextStyle(
+                                fontSize: 14.sp,
+                                color: '#404040'.color,
+                                fontWeight: FontWeight.bold),
+                            children: [
+                          TextSpan(text: '用户 '),
+                          TextSpan(
+                              text: item.userPhone,
+                              style: TextStyle(color: ColorName.colorPrimary)),
+                          TextSpan(text: ' 向您发出了好友申请')
+                        ])),
+                    SizedBox(height: 5.w),
+                    Text(
+                      DateUtil.fromMillisecondsSinceEpoch(
+                          'yyyy-MM-dd HH:mm', item.createTime),
+                      style: TextStyle(fontSize: 13.sp, color: '#A7A7A7'.color),
+                    ),
+                  ],
+                ),
+              )
+            ],
+          ),
+          SizedBox(height: 20.w),
+          Row(
+            children: [
+              SizedBox(width: 57.w),
+              Expanded(
+                  child: GestureDetector(
+                onTap: () => controller.onRefuseFriend(item),
+                child: Container(
+                  padding: EdgeInsets.symmetric(vertical: 8.w),
+                  decoration: BoxDecoration(
+                    border: Border.all(color: '#E2E2E2'.color, width: 1.w),
+                    borderRadius: BorderRadius.circular(100.w),
+                  ),
+                  child: Center(
+                    child: Text(StringName.messageFriendRefuse,
+                        style: TextStyle(
+                            fontSize: 15.sp,
+                            color: '#A7A7A7'.color,
+                            fontWeight: FontWeight.bold)),
+                  ),
+                ),
+              )),
+              SizedBox(width: 12.w),
+              Expanded(
+                  child: GestureDetector(
+                onTap: () => controller.onAgreeFriend(item),
+                child: Container(
+                  padding: EdgeInsets.symmetric(vertical: 8.w),
+                  decoration: BoxDecoration(
+                    color: ColorName.colorPrimary,
+                    borderRadius: BorderRadius.circular(100.w),
+                  ),
+                  child: Center(
+                    child: Text(StringName.messageFriendAgree,
+                        style: TextStyle(
+                            fontSize: 15.sp,
+                            color: ColorName.white,
+                            fontWeight: FontWeight.bold)),
+                  ),
+                ),
+              ))
+            ],
+          )
+        ],
+      ),
+    );
+  }
+}

+ 15 - 0
lib/resource/string.gen.dart

@@ -156,6 +156,15 @@ class StringName {
   static final String messageAccepted = 'message_accepted'.tr; // 已同意您的好友申请
   static final String messageRejected = 'message_rejected'.tr; // 已拒绝您的好友申请
   static final String messageDeleteYour = 'message_delete_your'.tr; // 您的好友删除了你
+  static final String messageNoData = 'message_no_data'.tr; // 暂无消息
+  static final String messageNewFriendTitle =
+      'message_new_friend_title'.tr; // 新的好友
+  static final String messageFriendRefuse = 'message_friend_refuse'.tr; // 拒绝
+  static final String messageFriendAgree = 'message_friend_agree'.tr; // 同意
+  static final String messageFriendRequestRejected =
+      'message_friend_request_rejected'.tr; // 好友请求已拒绝
+  static final String messageFriendRequestAgreed =
+      'message_friend_request_agreed'.tr; // 好友请求已同意
 }
 class StringMultiSource {
   StringMultiSource._();
@@ -313,6 +322,12 @@ class StringMultiSource {
       'message_accepted': '已同意您的好友申请',
       'message_rejected': '已拒绝您的好友申请',
       'message_delete_your': '您的好友删除了你',
+      'message_no_data': '暂无消息',
+      'message_new_friend_title': '新的好友',
+      'message_friend_refuse': '拒绝',
+      'message_friend_agree': '同意',
+      'message_friend_request_rejected': '好友请求已拒绝',
+      'message_friend_request_agreed': '好友请求已同意',
     },
   };
 }

+ 5 - 0
lib/router/app_pages.dart

@@ -11,6 +11,8 @@ import 'package:location/module/member/member_controller.dart';
 import 'package:location/module/member/member_page.dart';
 import 'package:location/module/mine/mine_page.dart';
 import 'package:location/module/news/news_page.dart';
+import 'package:location/module/news/pending_list/news_pending_list_controller.dart';
+import 'package:location/module/news/pending_list/news_pending_list_page.dart';
 import '../module/add_friend/add_friend_dialog_controller.dart';
 import '../module/login/login_page.dart';
 import '../module/main/main_controller.dart';
@@ -36,6 +38,7 @@ abstract class RoutePath {
   static const member = '/member';
   static const track = '/track';
   static const news = '/news';
+  static const newsPendingList = '/newsPendingList';
 }
 
 class AppBinding extends Bindings {
@@ -51,6 +54,7 @@ class AppBinding extends Bindings {
     lazyPut(() => getIt.get<MemberController>());
     lazyPut(() => getIt.get<TrackController>());
     lazyPut(() => getIt.get<NewsController>());
+    lazyPut(() => getIt.get<NewsPendingListController>());
   }
 
   void lazyPut<S>(InstanceBuilderCallback<S> builder) {
@@ -68,4 +72,5 @@ final generalPages = [
   GetPage(name: RoutePath.member, page: () => MemberPage()),
   GetPage(name: RoutePath.track, page: () => TrackPage()),
   GetPage(name: RoutePath.news, page: () => NewsPage()),
+  GetPage(name: RoutePath.newsPendingList, page: () => NewsPendingListPage()),
 ];

+ 1 - 1
lib/socket/atmob_location_client.dart

@@ -122,7 +122,7 @@ class AtmobLocationClient {
               FriendsRepository.getInstance().refreshFriends();
               break;
             case SocketConstants.refreshFriendRequest:
-              MessageRepository.getInstance().refreshFriendRequest();
+              MessageRepository.getInstance().refreshFriendWaitingCount();
               break;
             // case SocketConstants.refreshFriendMessage:
             //   MessageRepository.getInstance().requestMessageList();

+ 0 - 8
pubspec.lock

@@ -1022,14 +1022,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.1.5"
-  timelines_plus:
-    dependency: "direct main"
-    description:
-      name: timelines_plus
-      sha256: be31f493402dc24df7fe410dc5f82a605807bb4ca13183de6d4362886449b593
-      url: "https://pub.dev"
-    source: hosted
-    version: "1.0.6"
   timing:
     dependency: transitive
     description:

+ 2 - 2
pubspec.yaml

@@ -98,10 +98,10 @@ dependencies:
   sliding_sheet2: ^2.0.1
 
   #时间轴
-  timelines_plus: 1.0.6
+  #  timelines_plus: 1.0.6
 
   #时间滚轴选择器
-  #  flutter_cupertino_datetime_picker: ^3.0.0
+  flutter_cupertino_datetime_picker: ^3.0.0
 
   #拨号
   url_launcher: 6.3.1