Создание карточки в коллекции + экран поиска коллекции

This commit is contained in:
2025-04-02 21:40:31 +03:00
parent fb7ff84087
commit 17dff72655
36 changed files with 2495 additions and 277 deletions

View File

@@ -3,7 +3,7 @@ import 'package:drift/drift.dart';
import 'package:remever/common/functions.dart';
import 'package:remever/database/database.dart';
import 'package:remever/database/tables.dart';
import 'package:remever/models/collection_dto.dart';
import 'package:remever/models/crud_collection_dto.dart';
part 'collections_dao.g.dart';
@@ -16,9 +16,11 @@ class CollectionsDao extends DatabaseAccessor<AppDatabase>
CollectionsDao(super.attachedDatabase);
/// Получение коллекций из базы данных
Stream<List<Collection>> getCollections() {
Stream<List<Collection>> getCollections(String? search) {
try {
return db.managers.collections.watch();
return db.managers.collections
.filter((f) => f.title.contains(search ?? ''))
.watch();
} catch (e, st) {
logger.logError('Ошибка в методе getCollections', e, st);
@@ -27,7 +29,7 @@ class CollectionsDao extends DatabaseAccessor<AppDatabase>
}
/// Создание коллекции
Future<void> createCollection(CollectionDto dto) async {
Future<void> createCollection(CrudCollectionDto dto) async {
try {
await db.managers.collections.create(
(o) => o(
@@ -43,7 +45,7 @@ class CollectionsDao extends DatabaseAccessor<AppDatabase>
}
/// Обновление коллекции
Future<void> updateCollection(CollectionDto dto, String id) async {
Future<void> updateCollection(CrudCollectionDto dto, String id) async {
try {
await db.managers.collections
.filter((f) => f.id(id))

View File

@@ -0,0 +1,70 @@
// Package imports:
import 'package:drift/drift.dart';
import 'package:remever/common/functions.dart';
import 'package:remever/database/database.dart';
import 'package:remever/database/tables.dart';
import 'package:remever/models/create_ticket_dto.dart';
import 'package:remever/models/crud_collection_dto.dart';
part 'tickets_dao.g.dart';
@DriftAccessor(tables: <Type>[Tickets])
class TicketsDao extends DatabaseAccessor<AppDatabase> with _$TicketsDaoMixin {
///
/// Репозиторий для работы с билетами
///
TicketsDao(super.attachedDatabase);
/// Получение билетов из базы данных
Stream<List<Ticket>> getTickets(String collectionId) {
try {
return db.managers.tickets
.filter((f) => f.collectionId.id(collectionId))
.watch();
} catch (e, st) {
logger.logError('Ошибка в методе getTickets', e, st);
throw ('EXEPTION');
}
}
/// Удаление билета
Future<void> deleteTicket(String id) async {
try {
await db.managers.tickets.filter((f) => f.id(id)).delete();
} catch (e, st) {
logger.logError('Ошибка в методе deleteTicket', e, st);
}
}
/// Создание билета
Future<void> createTicket(CreateTicketDto dto) async {
try {
final TicketsCompanion companion = TicketsCompanion.insert(
question: dto.question!,
answer: dto.answer!,
collectionId: dto.collection!.id,
questionImage: Value<Uint8List?>(dto.questionImage),
answerImage: Value<Uint8List?>(dto.answerImage),
);
await db.managers.tickets.create((o) => companion);
if (dto.needRevert != null && dto.needRevert!) {
/// Создаем обратную карточку где ответ == вопрос и вопрос == ответ
final TicketsCompanion revertCompanion = TicketsCompanion.insert(
answer: dto.question!,
question: dto.answer!,
collectionId: dto.collection!.id,
answerImage: Value<Uint8List?>(dto.questionImage),
questionImage: Value<Uint8List?>(dto.answerImage),
);
await db.managers.tickets.create((o) => revertCompanion);
}
} catch (e, st) {
logger.logError('Ошибка в методе createTicket', e, st);
}
}
}

View File

@@ -0,0 +1,9 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'tickets_dao.dart';
// ignore_for_file: type=lint
mixin _$TicketsDaoMixin on DatabaseAccessor<AppDatabase> {
$CollectionsTable get collections => attachedDatabase.collections;
$TicketsTable get tickets => attachedDatabase.tickets;
}

View File

@@ -2,6 +2,7 @@ import 'package:drift/drift.dart';
import 'package:flutter/foundation.dart';
import 'package:injectable/injectable.dart';
import 'package:remever/database/dao/collections_dao.dart';
import 'package:remever/database/dao/tickets_dao.dart';
import 'package:remever/database/tables.dart';
import 'connection/connection.dart' as impl;
import 'package:uuid/uuid.dart';
@@ -10,8 +11,8 @@ part 'database.g.dart';
@DriftDatabase(
include: <String>{'sql.drift'},
daos: <Type>[CollectionsDao],
tables: <Type>[Collections],
daos: <Type>[CollectionsDao, TicketsDao],
tables: <Type>[Collections, Tickets],
)
@Singleton()
final class AppDatabase extends _$AppDatabase {

View File

@@ -745,6 +745,18 @@ class $TicketsTable extends Tickets with TableInfo<$TicketsTable, Ticket> {
type: DriftSqlType.string,
requiredDuringInsert: true,
);
static const VerificationMeta _questionImageMeta = const VerificationMeta(
'questionImage',
);
@override
late final GeneratedColumn<Uint8List> questionImage =
GeneratedColumn<Uint8List>(
'question_image',
aliasedName,
true,
type: DriftSqlType.blob,
requiredDuringInsert: false,
);
static const VerificationMeta _answerMeta = const VerificationMeta('answer');
@override
late final GeneratedColumn<String> answer = GeneratedColumn<String>(
@@ -754,15 +766,18 @@ class $TicketsTable extends Tickets with TableInfo<$TicketsTable, Ticket> {
type: DriftSqlType.string,
requiredDuringInsert: true,
);
static const VerificationMeta _imageMeta = const VerificationMeta('image');
@override
late final GeneratedColumn<Uint8List> image = GeneratedColumn<Uint8List>(
'image',
aliasedName,
true,
type: DriftSqlType.blob,
requiredDuringInsert: false,
static const VerificationMeta _answerImageMeta = const VerificationMeta(
'answerImage',
);
@override
late final GeneratedColumn<Uint8List> answerImage =
GeneratedColumn<Uint8List>(
'answer_image',
aliasedName,
true,
type: DriftSqlType.blob,
requiredDuringInsert: false,
);
static const VerificationMeta _collectionIdMeta = const VerificationMeta(
'collectionId',
);
@@ -795,8 +810,9 @@ class $TicketsTable extends Tickets with TableInfo<$TicketsTable, Ticket> {
createdAt,
updatedAt,
question,
questionImage,
answer,
image,
answerImage,
collectionId,
progress,
];
@@ -835,6 +851,15 @@ class $TicketsTable extends Tickets with TableInfo<$TicketsTable, Ticket> {
} else if (isInserting) {
context.missing(_questionMeta);
}
if (data.containsKey('question_image')) {
context.handle(
_questionImageMeta,
questionImage.isAcceptableOrUnknown(
data['question_image']!,
_questionImageMeta,
),
);
}
if (data.containsKey('answer')) {
context.handle(
_answerMeta,
@@ -843,10 +868,13 @@ class $TicketsTable extends Tickets with TableInfo<$TicketsTable, Ticket> {
} else if (isInserting) {
context.missing(_answerMeta);
}
if (data.containsKey('image')) {
if (data.containsKey('answer_image')) {
context.handle(
_imageMeta,
image.isAcceptableOrUnknown(data['image']!, _imageMeta),
_answerImageMeta,
answerImage.isAcceptableOrUnknown(
data['answer_image']!,
_answerImageMeta,
),
);
}
if (data.containsKey('collection_id')) {
@@ -895,14 +923,18 @@ class $TicketsTable extends Tickets with TableInfo<$TicketsTable, Ticket> {
DriftSqlType.string,
data['${effectivePrefix}question'],
)!,
questionImage: attachedDatabase.typeMapping.read(
DriftSqlType.blob,
data['${effectivePrefix}question_image'],
),
answer:
attachedDatabase.typeMapping.read(
DriftSqlType.string,
data['${effectivePrefix}answer'],
)!,
image: attachedDatabase.typeMapping.read(
answerImage: attachedDatabase.typeMapping.read(
DriftSqlType.blob,
data['${effectivePrefix}image'],
data['${effectivePrefix}answer_image'],
),
collectionId:
attachedDatabase.typeMapping.read(
@@ -933,8 +965,9 @@ class Ticket extends DataClass implements Insertable<Ticket> {
/// Дата последней модификации
final DateTime updatedAt;
final String question;
final Uint8List? questionImage;
final String answer;
final Uint8List? image;
final Uint8List? answerImage;
final String collectionId;
final double progress;
const Ticket({
@@ -942,8 +975,9 @@ class Ticket extends DataClass implements Insertable<Ticket> {
required this.createdAt,
required this.updatedAt,
required this.question,
this.questionImage,
required this.answer,
this.image,
this.answerImage,
required this.collectionId,
required this.progress,
});
@@ -954,9 +988,12 @@ class Ticket extends DataClass implements Insertable<Ticket> {
map['created_at'] = Variable<DateTime>(createdAt);
map['updated_at'] = Variable<DateTime>(updatedAt);
map['question'] = Variable<String>(question);
if (!nullToAbsent || questionImage != null) {
map['question_image'] = Variable<Uint8List>(questionImage);
}
map['answer'] = Variable<String>(answer);
if (!nullToAbsent || image != null) {
map['image'] = Variable<Uint8List>(image);
if (!nullToAbsent || answerImage != null) {
map['answer_image'] = Variable<Uint8List>(answerImage);
}
map['collection_id'] = Variable<String>(collectionId);
map['progress'] = Variable<double>(progress);
@@ -969,9 +1006,15 @@ class Ticket extends DataClass implements Insertable<Ticket> {
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
question: Value(question),
questionImage:
questionImage == null && nullToAbsent
? const Value.absent()
: Value(questionImage),
answer: Value(answer),
image:
image == null && nullToAbsent ? const Value.absent() : Value(image),
answerImage:
answerImage == null && nullToAbsent
? const Value.absent()
: Value(answerImage),
collectionId: Value(collectionId),
progress: Value(progress),
);
@@ -987,8 +1030,9 @@ class Ticket extends DataClass implements Insertable<Ticket> {
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
question: serializer.fromJson<String>(json['question']),
questionImage: serializer.fromJson<Uint8List?>(json['questionImage']),
answer: serializer.fromJson<String>(json['answer']),
image: serializer.fromJson<Uint8List?>(json['image']),
answerImage: serializer.fromJson<Uint8List?>(json['answerImage']),
collectionId: serializer.fromJson<String>(json['collectionId']),
progress: serializer.fromJson<double>(json['progress']),
);
@@ -1001,8 +1045,9 @@ class Ticket extends DataClass implements Insertable<Ticket> {
'createdAt': serializer.toJson<DateTime>(createdAt),
'updatedAt': serializer.toJson<DateTime>(updatedAt),
'question': serializer.toJson<String>(question),
'questionImage': serializer.toJson<Uint8List?>(questionImage),
'answer': serializer.toJson<String>(answer),
'image': serializer.toJson<Uint8List?>(image),
'answerImage': serializer.toJson<Uint8List?>(answerImage),
'collectionId': serializer.toJson<String>(collectionId),
'progress': serializer.toJson<double>(progress),
};
@@ -1013,8 +1058,9 @@ class Ticket extends DataClass implements Insertable<Ticket> {
DateTime? createdAt,
DateTime? updatedAt,
String? question,
Value<Uint8List?> questionImage = const Value.absent(),
String? answer,
Value<Uint8List?> image = const Value.absent(),
Value<Uint8List?> answerImage = const Value.absent(),
String? collectionId,
double? progress,
}) => Ticket(
@@ -1022,8 +1068,10 @@ class Ticket extends DataClass implements Insertable<Ticket> {
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
question: question ?? this.question,
questionImage:
questionImage.present ? questionImage.value : this.questionImage,
answer: answer ?? this.answer,
image: image.present ? image.value : this.image,
answerImage: answerImage.present ? answerImage.value : this.answerImage,
collectionId: collectionId ?? this.collectionId,
progress: progress ?? this.progress,
);
@@ -1033,8 +1081,13 @@ class Ticket extends DataClass implements Insertable<Ticket> {
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
question: data.question.present ? data.question.value : this.question,
questionImage:
data.questionImage.present
? data.questionImage.value
: this.questionImage,
answer: data.answer.present ? data.answer.value : this.answer,
image: data.image.present ? data.image.value : this.image,
answerImage:
data.answerImage.present ? data.answerImage.value : this.answerImage,
collectionId:
data.collectionId.present
? data.collectionId.value
@@ -1050,8 +1103,9 @@ class Ticket extends DataClass implements Insertable<Ticket> {
..write('createdAt: $createdAt, ')
..write('updatedAt: $updatedAt, ')
..write('question: $question, ')
..write('questionImage: $questionImage, ')
..write('answer: $answer, ')
..write('image: $image, ')
..write('answerImage: $answerImage, ')
..write('collectionId: $collectionId, ')
..write('progress: $progress')
..write(')'))
@@ -1064,8 +1118,9 @@ class Ticket extends DataClass implements Insertable<Ticket> {
createdAt,
updatedAt,
question,
$driftBlobEquality.hash(questionImage),
answer,
$driftBlobEquality.hash(image),
$driftBlobEquality.hash(answerImage),
collectionId,
progress,
);
@@ -1077,8 +1132,9 @@ class Ticket extends DataClass implements Insertable<Ticket> {
other.createdAt == this.createdAt &&
other.updatedAt == this.updatedAt &&
other.question == this.question &&
$driftBlobEquality.equals(other.questionImage, this.questionImage) &&
other.answer == this.answer &&
$driftBlobEquality.equals(other.image, this.image) &&
$driftBlobEquality.equals(other.answerImage, this.answerImage) &&
other.collectionId == this.collectionId &&
other.progress == this.progress);
}
@@ -1088,8 +1144,9 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
final Value<DateTime> createdAt;
final Value<DateTime> updatedAt;
final Value<String> question;
final Value<Uint8List?> questionImage;
final Value<String> answer;
final Value<Uint8List?> image;
final Value<Uint8List?> answerImage;
final Value<String> collectionId;
final Value<double> progress;
final Value<int> rowid;
@@ -1098,8 +1155,9 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
this.createdAt = const Value.absent(),
this.updatedAt = const Value.absent(),
this.question = const Value.absent(),
this.questionImage = const Value.absent(),
this.answer = const Value.absent(),
this.image = const Value.absent(),
this.answerImage = const Value.absent(),
this.collectionId = const Value.absent(),
this.progress = const Value.absent(),
this.rowid = const Value.absent(),
@@ -1109,8 +1167,9 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
this.createdAt = const Value.absent(),
this.updatedAt = const Value.absent(),
required String question,
this.questionImage = const Value.absent(),
required String answer,
this.image = const Value.absent(),
this.answerImage = const Value.absent(),
required String collectionId,
this.progress = const Value.absent(),
this.rowid = const Value.absent(),
@@ -1122,8 +1181,9 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
Expression<DateTime>? createdAt,
Expression<DateTime>? updatedAt,
Expression<String>? question,
Expression<Uint8List>? questionImage,
Expression<String>? answer,
Expression<Uint8List>? image,
Expression<Uint8List>? answerImage,
Expression<String>? collectionId,
Expression<double>? progress,
Expression<int>? rowid,
@@ -1133,8 +1193,9 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
if (createdAt != null) 'created_at': createdAt,
if (updatedAt != null) 'updated_at': updatedAt,
if (question != null) 'question': question,
if (questionImage != null) 'question_image': questionImage,
if (answer != null) 'answer': answer,
if (image != null) 'image': image,
if (answerImage != null) 'answer_image': answerImage,
if (collectionId != null) 'collection_id': collectionId,
if (progress != null) 'progress': progress,
if (rowid != null) 'rowid': rowid,
@@ -1146,8 +1207,9 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
Value<DateTime>? createdAt,
Value<DateTime>? updatedAt,
Value<String>? question,
Value<Uint8List?>? questionImage,
Value<String>? answer,
Value<Uint8List?>? image,
Value<Uint8List?>? answerImage,
Value<String>? collectionId,
Value<double>? progress,
Value<int>? rowid,
@@ -1157,8 +1219,9 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
question: question ?? this.question,
questionImage: questionImage ?? this.questionImage,
answer: answer ?? this.answer,
image: image ?? this.image,
answerImage: answerImage ?? this.answerImage,
collectionId: collectionId ?? this.collectionId,
progress: progress ?? this.progress,
rowid: rowid ?? this.rowid,
@@ -1180,11 +1243,14 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
if (question.present) {
map['question'] = Variable<String>(question.value);
}
if (questionImage.present) {
map['question_image'] = Variable<Uint8List>(questionImage.value);
}
if (answer.present) {
map['answer'] = Variable<String>(answer.value);
}
if (image.present) {
map['image'] = Variable<Uint8List>(image.value);
if (answerImage.present) {
map['answer_image'] = Variable<Uint8List>(answerImage.value);
}
if (collectionId.present) {
map['collection_id'] = Variable<String>(collectionId.value);
@@ -1205,8 +1271,9 @@ class TicketsCompanion extends UpdateCompanion<Ticket> {
..write('createdAt: $createdAt, ')
..write('updatedAt: $updatedAt, ')
..write('question: $question, ')
..write('questionImage: $questionImage, ')
..write('answer: $answer, ')
..write('image: $image, ')
..write('answerImage: $answerImage, ')
..write('collectionId: $collectionId, ')
..write('progress: $progress, ')
..write('rowid: $rowid')
@@ -1223,6 +1290,7 @@ abstract class _$AppDatabase extends GeneratedDatabase {
late final CollectionsDao collectionsDao = CollectionsDao(
this as AppDatabase,
);
late final TicketsDao ticketsDao = TicketsDao(this as AppDatabase);
@override
Iterable<TableInfo<Table, Object?>> get allTables =>
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
@@ -1675,8 +1743,9 @@ typedef $$TicketsTableCreateCompanionBuilder =
Value<DateTime> createdAt,
Value<DateTime> updatedAt,
required String question,
Value<Uint8List?> questionImage,
required String answer,
Value<Uint8List?> image,
Value<Uint8List?> answerImage,
required String collectionId,
Value<double> progress,
Value<int> rowid,
@@ -1687,8 +1756,9 @@ typedef $$TicketsTableUpdateCompanionBuilder =
Value<DateTime> createdAt,
Value<DateTime> updatedAt,
Value<String> question,
Value<Uint8List?> questionImage,
Value<String> answer,
Value<Uint8List?> image,
Value<Uint8List?> answerImage,
Value<String> collectionId,
Value<double> progress,
Value<int> rowid,
@@ -1747,13 +1817,18 @@ class $$TicketsTableFilterComposer
builder: (column) => ColumnFilters(column),
);
ColumnFilters<Uint8List> get questionImage => $composableBuilder(
column: $table.questionImage,
builder: (column) => ColumnFilters(column),
);
ColumnFilters<String> get answer => $composableBuilder(
column: $table.answer,
builder: (column) => ColumnFilters(column),
);
ColumnFilters<Uint8List> get image => $composableBuilder(
column: $table.image,
ColumnFilters<Uint8List> get answerImage => $composableBuilder(
column: $table.answerImage,
builder: (column) => ColumnFilters(column),
);
@@ -1815,13 +1890,18 @@ class $$TicketsTableOrderingComposer
builder: (column) => ColumnOrderings(column),
);
ColumnOrderings<Uint8List> get questionImage => $composableBuilder(
column: $table.questionImage,
builder: (column) => ColumnOrderings(column),
);
ColumnOrderings<String> get answer => $composableBuilder(
column: $table.answer,
builder: (column) => ColumnOrderings(column),
);
ColumnOrderings<Uint8List> get image => $composableBuilder(
column: $table.image,
ColumnOrderings<Uint8List> get answerImage => $composableBuilder(
column: $table.answerImage,
builder: (column) => ColumnOrderings(column),
);
@@ -1875,11 +1955,18 @@ class $$TicketsTableAnnotationComposer
GeneratedColumn<String> get question =>
$composableBuilder(column: $table.question, builder: (column) => column);
GeneratedColumn<Uint8List> get questionImage => $composableBuilder(
column: $table.questionImage,
builder: (column) => column,
);
GeneratedColumn<String> get answer =>
$composableBuilder(column: $table.answer, builder: (column) => column);
GeneratedColumn<Uint8List> get image =>
$composableBuilder(column: $table.image, builder: (column) => column);
GeneratedColumn<Uint8List> get answerImage => $composableBuilder(
column: $table.answerImage,
builder: (column) => column,
);
GeneratedColumn<double> get progress =>
$composableBuilder(column: $table.progress, builder: (column) => column);
@@ -1940,8 +2027,9 @@ class $$TicketsTableTableManager
Value<DateTime> createdAt = const Value.absent(),
Value<DateTime> updatedAt = const Value.absent(),
Value<String> question = const Value.absent(),
Value<Uint8List?> questionImage = const Value.absent(),
Value<String> answer = const Value.absent(),
Value<Uint8List?> image = const Value.absent(),
Value<Uint8List?> answerImage = const Value.absent(),
Value<String> collectionId = const Value.absent(),
Value<double> progress = const Value.absent(),
Value<int> rowid = const Value.absent(),
@@ -1950,8 +2038,9 @@ class $$TicketsTableTableManager
createdAt: createdAt,
updatedAt: updatedAt,
question: question,
questionImage: questionImage,
answer: answer,
image: image,
answerImage: answerImage,
collectionId: collectionId,
progress: progress,
rowid: rowid,
@@ -1962,8 +2051,9 @@ class $$TicketsTableTableManager
Value<DateTime> createdAt = const Value.absent(),
Value<DateTime> updatedAt = const Value.absent(),
required String question,
Value<Uint8List?> questionImage = const Value.absent(),
required String answer,
Value<Uint8List?> image = const Value.absent(),
Value<Uint8List?> answerImage = const Value.absent(),
required String collectionId,
Value<double> progress = const Value.absent(),
Value<int> rowid = const Value.absent(),
@@ -1972,8 +2062,9 @@ class $$TicketsTableTableManager
createdAt: createdAt,
updatedAt: updatedAt,
question: question,
questionImage: questionImage,
answer: answer,
image: image,
answerImage: answerImage,
collectionId: collectionId,
progress: progress,
rowid: rowid,

View File

@@ -78,8 +78,9 @@ class Collections extends Table with _UuidPrimaryKey, _Timestampable {
@DataClassName('Ticket')
class Tickets extends Table with _UuidPrimaryKey, _Timestampable {
TextColumn get question => text()();
BlobColumn get questionImage => blob().named('question_image').nullable()();
TextColumn get answer => text()();
BlobColumn get image => blob().nullable()();
BlobColumn get answerImage => blob().named('answer_image').nullable()();
TextColumn get collectionId =>
text().references(Collections, #id, onDelete: KeyAction.cascade)();
RealColumn get progress => real().withDefault(Constant(0))();