Skip to content

Commit 78bdf27

Browse files
authored
Merge branch 'develop' into minorchange/about
2 parents 727c5ef + 7cd7399 commit 78bdf27

File tree

8 files changed

+155
-20
lines changed

8 files changed

+155
-20
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright 2025 BitCodersNN
3+
4+
import 'package:unn_mobile/core/misc/json/json_utils.dart';
5+
6+
T? findFirstNonNullNotesDeep<T>(dynamic data, String key) {
7+
if (data is! JsonMap && data is! List) {
8+
return null;
9+
}
10+
11+
if (data is JsonMap && data.containsKey(key) && data[key] is T) {
12+
return data[key]! as T;
13+
}
14+
15+
Iterable<dynamic> items;
16+
if (data is JsonMap) {
17+
items = data.values;
18+
} else {
19+
items = data;
20+
}
21+
22+
for (final item in items) {
23+
final result = findFirstNonNullNotesDeep<T>(item, key);
24+
if (result != null) {
25+
return result;
26+
}
27+
}
28+
29+
return null;
30+
}
31+
32+
void collectFirstValues(
33+
dynamic data,
34+
Set<String> keys,
35+
JsonMap results,
36+
) {
37+
if (data is! JsonMap && data is! List) {
38+
return;
39+
}
40+
41+
if (results.length == keys.length) {
42+
return;
43+
}
44+
45+
Iterable<dynamic> items;
46+
if (data is JsonMap) {
47+
for (final key in keys) {
48+
if (results.containsKey(key)) {
49+
continue;
50+
}
51+
final value = data[key];
52+
if (value != null) {
53+
results[key] = value;
54+
}
55+
}
56+
items = data.values;
57+
} else {
58+
items = data;
59+
}
60+
61+
for (final item in items) {
62+
collectFirstValues(item, keys, results);
63+
if (results.length == keys.length) {
64+
return;
65+
}
66+
}
67+
}

lib/core/models/profile/employee/employee_data.dart

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ import 'package:unn_mobile/core/models/profile/user_data.dart';
77

88
class _EmployeeDataJsonKeys {
99
static const String profiles = 'profiles';
10-
static const String user = 'user';
1110
static const String syncId = 'sync_id';
1211
}
1312

1413
class EmployeeData extends UserData {
14+
static Set<String> get jsonKeys => {
15+
_EmployeeDataJsonKeys.syncId,
16+
_EmployeeDataJsonKeys.profiles,
17+
...UserData.jsonKeys,
18+
};
19+
1520
final String syncId;
1621
final List<EmployeeProfile> profiles;
1722

@@ -25,6 +30,8 @@ class EmployeeData extends UserData {
2530
required super.phone,
2631
required super.sex,
2732
required super.notes,
33+
required super.web,
34+
required super.birthdate,
2835
required this.syncId,
2936
required this.profiles,
3037
});
@@ -43,6 +50,8 @@ class EmployeeData extends UserData {
4350
sex: userData.sex,
4451
photoSrc: userData.photoSrc,
4552
notes: userData.notes,
53+
web: userData.web,
54+
birthdate: userData.birthdate,
4655
);
4756

4857
@override
@@ -55,13 +64,7 @@ class EmployeeData extends UserData {
5564
};
5665

5766
factory EmployeeData.fromJson(JsonMap json) => EmployeeData.withUserData(
58-
userData: UserData.fromJson(
59-
// Если сделать каст, ужасно ломается форматирование
60-
// ignore: avoid_dynamic_calls
61-
(json[_EmployeeDataJsonKeys.profiles]! as List)[0]
62-
[_EmployeeDataJsonKeys.user] ??
63-
json,
64-
),
67+
userData: UserData.fromJson(json),
6568
syncId: json[_EmployeeDataJsonKeys.syncId]! as String,
6669
profiles: [
6770
for (final item in json[_EmployeeDataJsonKeys.profiles]! as List)

lib/core/models/profile/student/base_edu_info.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ class _BaseEduInfoJsonKeys {
2121
/// форму обучения, курс, уровень образования, факультет, направление подготовки,
2222
/// учебную группу и, при наличии, специализацию.
2323
class BaseEduInfo {
24+
static Set<String> get jsonKeys => {
25+
_BaseEduInfoJsonKeys.eduForm,
26+
_BaseEduInfoJsonKeys.eduCourse,
27+
_BaseEduInfoJsonKeys.eduLevel,
28+
_BaseEduInfoJsonKeys.eduDirection,
29+
_BaseEduInfoJsonKeys.eduGroup,
30+
_BaseEduInfoJsonKeys.eduSpecialization,
31+
_BaseEduInfoJsonKeys.faculty,
32+
};
2433
final String eduForm;
2534
final int eduCourse;
2635
final String eduLevel;

lib/core/models/profile/student/student_data.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ class _StudentDataJsonKeys {
1111
}
1212

1313
class StudentData extends UserData {
14+
static Set<String> get jsonKeys => {
15+
_StudentDataJsonKeys.eduStatus,
16+
_StudentDataJsonKeys.eduYear,
17+
...BaseEduInfo.jsonKeys,
18+
...UserData.jsonKeys,
19+
};
20+
1421
final BaseEduInfo baseEduInfo;
1522
final String eduStatus;
1623
final int eduYear;
@@ -25,6 +32,8 @@ class StudentData extends UserData {
2532
required super.phone,
2633
required super.sex,
2734
required super.notes,
35+
required super.web,
36+
required super.birthdate,
2837
required this.baseEduInfo,
2938
required this.eduStatus,
3039
required this.eduYear,
@@ -45,6 +54,8 @@ class StudentData extends UserData {
4554
sex: userData.sex,
4655
photoSrc: userData.photoSrc,
4756
notes: userData.notes,
57+
web: userData.web,
58+
birthdate: userData.birthdate,
4859
);
4960

5061
factory StudentData.fromJson(JsonMap json) => StudentData.withUserData(

lib/core/models/profile/user_data.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,30 @@ class _UserDataJsonKeys {
1212
static const String phone = 'phone';
1313
static const String sex = 'sex';
1414
static const String notes = 'notes';
15+
static const String web = 'web';
16+
static const String birthdate = 'birthdate';
1517
}
1618

1719
class UserData extends UserShortInfo {
20+
static Set<String> get jsonKeys => {
21+
_UserDataJsonKeys.id,
22+
_UserDataJsonKeys.login,
23+
_UserDataJsonKeys.email,
24+
_UserDataJsonKeys.phone,
25+
_UserDataJsonKeys.sex,
26+
_UserDataJsonKeys.notes,
27+
_UserDataJsonKeys.web,
28+
_UserDataJsonKeys.birthdate,
29+
...UserShortInfo.profileJsonKeys,
30+
};
1831
final int userId;
1932
final String? login;
2033
final String? email;
2134
final String? phone;
2235
final String sex;
2336
final String? notes;
37+
final String? web;
38+
final DateTime? birthdate;
2439

2540
UserData({
2641
required super.bitrixId,
@@ -32,16 +47,20 @@ class UserData extends UserShortInfo {
3247
required this.phone,
3348
required this.sex,
3449
required this.notes,
50+
required this.web,
51+
required this.birthdate,
3552
});
3653

3754
UserData.withUserShortInfo({
3855
required UserShortInfo userShortInfo,
3956
required this.userId,
4057
required this.sex,
58+
this.birthdate,
4159
this.login,
4260
this.email,
4361
this.phone,
4462
this.notes,
63+
this.web,
4564
}) : super(
4665
bitrixId: userShortInfo.bitrixId,
4766
fullname: userShortInfo.fullname,
@@ -58,6 +77,10 @@ class UserData extends UserShortInfo {
5877
phone: userJsonMap[_UserDataJsonKeys.phone] as String?,
5978
sex: userJsonMap[_UserDataJsonKeys.sex]! as String,
6079
notes: userJsonMap[_UserDataJsonKeys.notes] as String?,
80+
web: userJsonMap[_UserDataJsonKeys.web] as String?,
81+
birthdate: DateTime.tryParse(
82+
userJsonMap[_UserDataJsonKeys.birthdate] as String? ?? '',
83+
),
6184
);
6285
}
6386

lib/core/models/profile/user_short_info.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ class UserShortInfo
7373
BlogPostJsonSerializable,
7474
MessageJsonSerializable,
7575
ProfileJsonSerializable {
76+
static const _profileJsonKeys = _ProfileUserInfoKeys();
77+
static Set<String> get profileJsonKeys => {
78+
_profileJsonKeys.fullname,
79+
_profileJsonKeys.id,
80+
_profileJsonKeys.photoSrc,
81+
};
7682
final int? bitrixId;
7783
final String? fullname;
7884
final String? photoSrc;

lib/core/services/implementations/profile/profile_service_impl.dart

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:unn_mobile/core/constants/profiles_strings.dart';
88
import 'package:unn_mobile/core/misc/dio_interceptor/response_data_type.dart';
99
import 'package:unn_mobile/core/misc/dio_interceptor/response_type_interceptor.dart';
1010
import 'package:unn_mobile/core/misc/dio_options_factory/options_with_expected_type_factory.dart';
11+
import 'package:unn_mobile/core/misc/json/json_search.dart';
1112
import 'package:unn_mobile/core/misc/json/json_utils.dart';
1213
import 'package:unn_mobile/core/models/profile/employee/employee_data.dart';
1314
import 'package:unn_mobile/core/models/profile/student/student_data.dart';
@@ -40,31 +41,32 @@ class ProfileServiceImpl implements ProfileService {
4041
return null;
4142
}
4243

43-
final data = response.data as JsonMap;
44-
final userType = data[ProfilesStrings.type] ??
45-
((data[ProfilesStrings.profilesKey]! as List)[0]
44+
final responseData = response.data as JsonMap;
45+
final userType = responseData[ProfilesStrings.type] ??
46+
((responseData[ProfilesStrings.profilesKey]! as List)[0]
4647
as JsonMap)[ProfilesStrings.type];
4748

4849
UserData? userData;
4950
try {
5051
userData = switch (userType) {
51-
ProfilesStrings.student => StudentData.fromJson(response.data),
52-
ProfilesStrings.employee => EmployeeData.fromJson(response.data),
53-
_ => UserData.fromJson(response.data),
52+
ProfilesStrings.student =>
53+
StudentData.fromJson(_getStudentJson(responseData)),
54+
ProfilesStrings.employee =>
55+
EmployeeData.fromJson(_getEmployeeJson(responseData)),
56+
_ => UserData.fromJson(_getUserJson(responseData)),
5457
};
5558
} catch (error, stackTrace) {
5659
_loggerService.logError(
5760
error,
5861
stackTrace,
59-
information: [response.data.toString()],
62+
information: [responseData.toString()],
6063
);
6164
}
62-
6365
return userData;
6466
}
6567

6668
@override
67-
Future<UserData?> getProfileByBitrixId(int bitrixId) async {
69+
Future<UserData?> getProfileByBitrixId({required int bitrixId}) async {
6870
final userId = await _getUserIdByBitrixId(bitrixId: bitrixId);
6971
if (userId == null) {
7072
return null;
@@ -74,11 +76,11 @@ class ProfileServiceImpl implements ProfileService {
7476

7577
@override
7678
Future<UserData?> getProfileByAuthorId({required int authorId}) =>
77-
getProfileByBitrixId(authorId);
79+
getProfileByBitrixId(bitrixId: authorId);
7880

7981
@override
8082
Future<UserData?> getProfileByDialogId({required int dialogId}) =>
81-
getProfileByBitrixId(dialogId);
83+
getProfileByBitrixId(bitrixId: dialogId);
8284

8385
Future<int?> _getUserIdByBitrixId({required int bitrixId}) async {
8486
final path =
@@ -108,4 +110,18 @@ class ProfileServiceImpl implements ProfileService {
108110

109111
return id;
110112
}
113+
114+
JsonMap _extractJson(JsonMap json, Set<String> keys) {
115+
final JsonMap results = {};
116+
collectFirstValues(json, keys, results);
117+
return results;
118+
}
119+
120+
JsonMap _getStudentJson(JsonMap json) =>
121+
_extractJson(json, StudentData.jsonKeys);
122+
123+
JsonMap _getEmployeeJson(JsonMap json) =>
124+
_extractJson(json, EmployeeData.jsonKeys);
125+
126+
JsonMap _getUserJson(JsonMap json) => _extractJson(json, UserData.jsonKeys);
111127
}

lib/core/services/interfaces/profile/profile_service.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ abstract interface class ProfileService {
2323
/// Возвращает [StudentData] или [EmployeeData] — наследников [UserData], или null, если:
2424
/// 1. Не удалось получить userId по bitrixId (ошибка API, отсутствие id в ответе)
2525
/// 2. Не вышло получить профиль по найденному userId (ошибка API, некорректный ответ, ошибка декодирования)
26-
Future<UserData?> getProfileByBitrixId(int bitrixId);
26+
Future<UserData?> getProfileByBitrixId({required int bitrixId});
2727

2828
/// Получает профиль по id автора поста или комменатрия
2929
///

0 commit comments

Comments
 (0)