feature(core):save

This commit is contained in:
2025-10-29 10:13:34 +03:00
parent e791f08eef
commit 6d04c0ada0
12 changed files with 351 additions and 20 deletions

View File

@@ -5,7 +5,7 @@ part of '../env.dart';
///
class DevEnv extends Env {
@override
Uri get url => Uri.parse('https://api.remever.dizoft-studio.ru');
Uri get url => Uri.parse('https://remever.neojik.tech');
@override
String get mode => 'dev';

View File

@@ -1,6 +1,9 @@
// Package imports:
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:remever/common/functions.dart';
import 'package:remever/common/typedef.dart';
import 'package:remever/database/database.dart';
import 'package:remever/database/tables.dart';
import 'package:remever/models/crud_collection_dto.dart';
@@ -56,6 +59,33 @@ class CollectionsDao extends DatabaseAccessor<AppDatabase>
}
}
/// Синхронизация коллекций
Future<void> syncCollectionFromApi(List<Json> data) async {
for (final item in data) {
try {
await db.managers.collections.create(
(o) => o(
// id: Value<String>(item['id'].toString()),
title: item['title'],
desc: item['description'],
isPublic: Value<bool>(item['is_public']),
image: Value<String?>(null),
createdAt: Value<DateTime>(DateTime.parse(item['created_at'])),
updatedAt: Value<DateTime>(DateTime.parse(item['updated_at'])),
),
);
} catch (e, st) {
logger.logError(
'Не смог добавить колекцию в методе syncCollectionFromApi',
e,
st,
);
continue;
}
}
}
/// Обновление коллекции
Future<void> updateCollection(CrudCollectionDto dto, String id) async {
try {

View File

@@ -158,7 +158,9 @@ class CollectionDetailScreen extends StatelessWidget {
fallback:
(context) => Center(
child: AppTypography(
collection.title.substring(0, 1),
collection.title.isNotEmpty
? collection.title.substring(0, 1)
: '',
type: Bold34px(),
),
),

View File

@@ -69,7 +69,7 @@ class _CollectionScreenState extends State<CollectionScreen> {
child: FloatingActionButton(
backgroundColor: AppColors.primary,
// onPressed: () {
// getIt<CollectionsInterface>().createCollectionApi();
// getIt<CollectionsInterface>().getCollectionsFromApi();
// },
onPressed: () => context.pushRoute(CrudCollectionRoute()),
child: const Icon(Icons.add),

View File

@@ -185,7 +185,7 @@ class CollectionCard extends StatelessWidget {
decoration: BoxDecoration(shape: BoxShape.circle, color: AppColors.bg),
child: Wif(
condition: collection.image != null,
condition: collection.image != null && collection.image != '',
builder:
(context) => ClipOval(
child: Image.file(File(collection.image!), fit: BoxFit.cover),
@@ -193,7 +193,9 @@ class CollectionCard extends StatelessWidget {
fallback:
(context) => Center(
child: AppTypography(
collection.title.substring(0, 1),
collection.title.isNotEmpty
? collection.title.substring(0, 1)
: '',
type: Bold34px(),
),
),

View File

@@ -100,7 +100,9 @@ class InfoDialog extends StatelessWidget {
fallback:
(context) => Center(
child: AppTypography(
collection.title.substring(0, 1),
collection.title.isNotEmpty
? collection.title.substring(0, 1)
: '',
type: Bold34px(),
),
),

View File

@@ -7,7 +7,6 @@ import 'package:remever/models/crud_collection_dto.dart';
abstract interface class CollectionsInterface {
/// работа с api
Future<void> getCollectionsFromApi();
Future<void> createCollectionApi();
/// Получение списка коллекций
Stream<List<Collection>> watchCollectionsList({String? search});

View File

@@ -1,6 +1,8 @@
import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';
import 'package:remever/common/functions.dart';
import 'package:remever/common/services/api_client.dart';
import 'package:remever/common/typedef.dart';
import 'package:remever/database/database.dart';
import 'package:remever/inject.dart';
import 'package:remever/models/crud_collection_dto.dart';
@@ -19,6 +21,10 @@ final class CollectionsService implements CollectionsInterface {
@override
Future<void> createCollection(CrudCollectionDto dto) async {
try {
createCollectionApi(dto);
} catch (_) {}
return await getIt<AppDatabase>().collectionsDao.createCollection(dto);
}
@@ -41,33 +47,70 @@ final class CollectionsService implements CollectionsInterface {
@override
Future<void> getCollectionsFromApi() async {
try {
final List<Json> items = [];
final perPage = 20;
final Response<dynamic> response = await apiClient.get(
'/collections',
queryParameters: <String, dynamic>{'perPage': 20, 'page': 1},
queryParameters: <String, dynamic>{'perPage': perPage, 'page': 9999},
);
print('data');
} catch (e) {
if (response.data['success'] != true) {
logger.logInfo('В методе getCollectionsFromApi success false');
throw Exception('Не удалось получить коллекции');
}
int totalCount = response.data['result']['totalCount'];
if (totalCount == 0) {
return;
}
int pagesCount = (totalCount / perPage).ceil();
int currentPage = 0;
while (pagesCount != currentPage) {
final Response<dynamic> response = await apiClient.get(
'/collections',
queryParameters: <String, dynamic>{
'perPage': perPage,
'page': currentPage + 1,
},
);
if (response.data['success'] != true) {
throw Exception('Не удалось получить $currentPage страницу журнала');
}
items.addAll(
(response.data['result']['items'] as List)
.cast<Map<String, dynamic>>(),
);
currentPage = currentPage + 1;
}
await getIt<AppDatabase>().collectionsDao.syncCollectionFromApi(items);
} catch (e, st) {
print('Response error $e');
logger.logError('Ошибка в методе getCollectionsFromApi', e, st);
}
}
@override
Future<void> createCollectionApi() async {
Future<void> createCollectionApi(CrudCollectionDto dto) async {
try {
final Response<dynamic> response = await apiClient.post(
'/collections',
data: {
"title": "Основы программирования для утюгов",
"description":
"Коллекция карточек по основам программирования для начинающих",
"is_public": true,
"title": dto.title,
"description": dto.desc,
"is_public": dto.isPublic,
},
);
print('data');
} catch (e) {
} catch (e, st) {
print('Response error $e');
logger.logError('Ошибка в методе createCollectionApi', e, st);
}
}
}