所有数据库表,提供相应的provider、桥接等方法

This commit is contained in:
Happi (哈比)
2026-03-10 12:09:45 +08:00
parent 084b7bbd23
commit 8130bf63fa
79 changed files with 3465 additions and 2730 deletions

View File

@@ -0,0 +1,28 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/api_retry_repository_impl.dart';
import 'package:im_app/domain/entities/api_retry.dart';
import 'package:im_app/domain/repositories/api_retry_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'api_retry_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
final apiRetryRepositoryProvider = Provider<ApiRetryRepository>((ref) {
return ApiRetryRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有重试任务
@riverpod
Stream<List<ApiRetry>> allApiRetries(Ref ref) {
return ref.watch(apiRetryRepositoryProvider).watchAll();
}
/// 监听未同步的重试任务
@riverpod
Stream<List<ApiRetry>> pendingApiRetries(Ref ref) {
return ref.watch(apiRetryRepositoryProvider).watchPending();
}

View File

@@ -0,0 +1,34 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/sound_repository_impl.dart';
import 'package:im_app/domain/entities/sound.dart';
import 'package:im_app/domain/repositories/sound_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'sound_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
final soundRepositoryProvider = Provider<SoundRepository>((ref) {
return SoundRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有音效
@riverpod
Stream<List<Sound>> allSounds(Ref ref) {
return ref.watch(soundRepositoryProvider).watchAll();
}
/// 监听指定类型音效
@riverpod
Stream<List<Sound>> soundsByType(Ref ref, int typ) {
return ref.watch(soundRepositoryProvider).watchByType(typ);
}
/// 监听指定音效
@riverpod
Stream<Sound?> soundById(Ref ref, int id) {
return ref.watch(soundRepositoryProvider).watchById(id);
}

View File

@@ -0,0 +1,40 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/tag_repository_impl.dart';
import 'package:im_app/domain/entities/tag.dart';
import 'package:im_app/domain/repositories/tag_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'tag_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
final tagRepositoryProvider = Provider<TagRepository>((ref) {
return TagRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有标签
@riverpod
Stream<List<Tag>> allTags(Ref ref) {
return ref.watch(tagRepositoryProvider).watchAll();
}
/// 监听指定 uid 的标签
@riverpod
Stream<List<Tag>> tagsByUid(Ref ref, int uid) {
return ref.watch(tagRepositoryProvider).watchByUid(uid);
}
/// 监听指定类型的标签
@riverpod
Stream<List<Tag>> tagsByType(Ref ref, int type) {
return ref.watch(tagRepositoryProvider).watchByType(type);
}
/// 监听指定标签
@riverpod
Stream<Tag?> tagById(Ref ref, int id) {
return ref.watch(tagRepositoryProvider).watchById(id);
}

View File

@@ -1,17 +1,17 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/tables/favourites.dart';
import 'package:im_app/data/local/drift/tables/sounds.dart'; import 'package:im_app/data/local/drift/tables/sounds.dart';
import 'package:im_app/data/local/drift/tables/tags.dart'; import 'package:im_app/data/local/drift/tables/tags.dart';
import 'package:im_app/data/local/drift/tables/favorite_details.dart';
import 'package:im_app/data/local/drift/tables/pending_friend_request_histories.dart'; import 'package:im_app/data/local/drift/tables/pending_friend_request_histories.dart';
import 'package:im_app/data/local/drift/tables/favorites.dart';
import 'package:im_app/data/local/drift/tables/message.dart'; import 'package:im_app/data/local/drift/tables/message.dart';
import 'package:im_app/data/local/drift/tables/recent_mini_apps.dart'; import 'package:im_app/data/local/drift/tables/recent_mini_apps.dart';
import 'package:im_app/data/local/drift/tables/retries.dart';
import 'package:im_app/data/local/drift/tables/groups.dart'; import 'package:im_app/data/local/drift/tables/groups.dart';
import 'package:im_app/data/local/drift/tables/favorite_mini_apps.dart'; import 'package:im_app/data/local/drift/tables/favorite_mini_apps.dart';
import 'package:im_app/data/local/drift/tables/discover_mini_apps.dart'; import 'package:im_app/data/local/drift/tables/discover_mini_apps.dart';
import 'package:im_app/data/local/drift/tables/chat_categories.dart'; import 'package:im_app/data/local/drift/tables/chat_categories.dart';
import 'package:im_app/data/local/drift/tables/api_retries.dart';
import 'package:im_app/data/local/drift/tables/chat_bots.dart'; import 'package:im_app/data/local/drift/tables/chat_bots.dart';
import 'package:im_app/data/local/drift/tables/favourite_details.dart';
import 'package:im_app/data/local/drift/tables/user_request_histories.dart'; import 'package:im_app/data/local/drift/tables/user_request_histories.dart';
import 'package:im_app/data/local/drift/tables/workspaces.dart'; import 'package:im_app/data/local/drift/tables/workspaces.dart';
import 'package:im_app/data/local/drift/tables/users.dart'; import 'package:im_app/data/local/drift/tables/users.dart';
@@ -23,19 +23,19 @@ part 'app_database.g.dart';
@DriftDatabase( @DriftDatabase(
tables: [ tables: [
Favourites, Favorites,
Sounds, Sounds,
Tags, Tags,
PendingFriendRequestHistories, PendingFriendRequestHistories,
Messages, Messages,
RecentMiniApps, RecentMiniApps,
Retries, ApiRetries,
Groups, Groups,
FavoriteMiniApps, FavoriteMiniApps,
DiscoverMiniApps, DiscoverMiniApps,
ChatCategories, ChatCategories,
ChatBots, ChatBots,
FavouriteDetails, FavoriteDetails,
UserRequestHistories, UserRequestHistories,
Workspaces, Workspaces,
Users, Users,
@@ -50,19 +50,19 @@ class AppDatabase extends _$AppDatabase {
return {}; return {};
} }
return { return {
DriftFavourite: database.favourites,
DriftSound: database.sounds, DriftSound: database.sounds,
DriftTag: database.tags, DriftTag: database.tags,
DriftFavoriteDetail: database.favoriteDetails,
DriftPendingFriendRequestHistory: database.pendingFriendRequestHistories, DriftPendingFriendRequestHistory: database.pendingFriendRequestHistories,
DriftFavorite: database.favorites,
DriftMessage: database.messages, DriftMessage: database.messages,
DriftRecentMiniApp: database.recentMiniApps, DriftRecentMiniApp: database.recentMiniApps,
DriftRetry: database.retries,
DriftGroup: database.groups, DriftGroup: database.groups,
DriftFavoriteMiniApp: database.favoriteMiniApps, DriftFavoriteMiniApp: database.favoriteMiniApps,
DriftDiscoverMiniApp: database.discoverMiniApps, DriftDiscoverMiniApp: database.discoverMiniApps,
DriftChatCategory: database.chatCategories, DriftChatCategory: database.chatCategories,
DriftApiRetry: database.apiRetries,
DriftChatBot: database.chatBots, DriftChatBot: database.chatBots,
DriftFavouriteDetail: database.favouriteDetails,
DriftUserRequestHistory: database.userRequestHistories, DriftUserRequestHistory: database.userRequestHistories,
DriftWorkspace: database.workspaces, DriftWorkspace: database.workspaces,
DriftUser: database.users, DriftUser: database.users,

View File

@@ -1,20 +1,31 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
@DataClassName('DriftRetry') @DataClassName('DriftApiRetry')
class Retries extends Table { class ApiRetries extends Table {
IntColumn get id => integer().autoIncrement()(); IntColumn get id => integer().autoIncrement()();
IntColumn get uid => integer().nullable()(); IntColumn get uid => integer().nullable()();
TextColumn get apiType => text().withDefault(const Constant(''))(); TextColumn get apiType => text().withDefault(const Constant(''))();
TextColumn get endPoint => text().withDefault(const Constant(''))(); TextColumn get endPoint => text().withDefault(const Constant(''))();
TextColumn get requestData => text().withDefault(const Constant(''))(); TextColumn get requestData => text().withDefault(const Constant(''))();
IntColumn get synced => integer().nullable()(); IntColumn get synced => integer().nullable()();
TextColumn get callbackFun => text().withDefault(const Constant(''))(); TextColumn get callbackFun => text().withDefault(const Constant(''))();
IntColumn get expired => integer().nullable()(); IntColumn get expired => integer().nullable()();
IntColumn get replace => integer().nullable()(); IntColumn get replace => integer().nullable()();
IntColumn get expireTime => integer().nullable()(); IntColumn get expireTime => integer().nullable()();
IntColumn get createTime => integer().nullable()(); IntColumn get createTime => integer().nullable()();
IntColumn get addIndex => integer().nullable()(); IntColumn get addIndex => integer().nullable()();
@override @override
String get tableName => 'retry'; String get tableName => 'api_retry';
} }

View File

@@ -1,36 +1,8 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/tables/mixin/mini_app_table_mixin.dart';
@DataClassName('DriftDiscoverMiniApp') @DataClassName('DriftDiscoverMiniApp')
class DiscoverMiniApps extends Table { class DiscoverMiniApps extends Table with MiniAppTableMixin {
TextColumn get id => text()();
TextColumn get name => text().nullable()();
TextColumn get openuid => text().nullable()();
TextColumn get devId => text().nullable()();
TextColumn get icon => text().nullable()();
TextColumn get iconGaussian => text().nullable()();
TextColumn get downloadUrl => text().nullable()();
TextColumn get description => text().nullable()();
IntColumn get version => integer().nullable()();
IntColumn get typ => integer().nullable()();
IntColumn get flag => integer().nullable()();
IntColumn get reviewStatus => integer().nullable()();
IntColumn get favoriteAt => integer().nullable()();
IntColumn get isActive => integer().nullable()();
IntColumn get createdAt => integer().nullable()();
IntColumn get updatedAt => integer().nullable()();
IntColumn get deletedAt => integer().nullable()();
RealColumn get score => real().nullable()();
TextColumn get channels => text().nullable()();
TextColumn get devName => text().nullable()();
TextColumn get pictureGaussian => text().nullable()();
TextColumn get picture => text().nullable()();
IntColumn get commentNum => integer().nullable()();
TextColumn get lastLoginAt => text().nullable()();
TextColumn get screen => text().nullable()();
@override
Set<Column> get primaryKey => {id};
@override @override
String get tableName => 'discover_mini_app'; String get tableName => 'discover_mini_app';
} }

View File

@@ -1,36 +1,8 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/tables/mixin/mini_app_table_mixin.dart';
@DataClassName('DriftExploreMiniApp') @DataClassName('DriftExploreMiniApp')
class ExploreMiniApps extends Table { class ExploreMiniApps extends Table with MiniAppTableMixin {
TextColumn get id => text()();
TextColumn get name => text().nullable()();
TextColumn get openuid => text().nullable()();
TextColumn get devId => text().nullable()();
TextColumn get icon => text().nullable()();
TextColumn get iconGaussian => text().nullable()();
TextColumn get downloadUrl => text().nullable()();
TextColumn get description => text().nullable()();
IntColumn get version => integer().nullable()();
IntColumn get typ => integer().nullable()();
IntColumn get flag => integer().nullable()();
IntColumn get reviewStatus => integer().nullable()();
IntColumn get favoriteAt => integer().nullable()();
IntColumn get isActive => integer().nullable()();
IntColumn get createdAt => integer().nullable()();
IntColumn get updatedAt => integer().nullable()();
IntColumn get deletedAt => integer().nullable()();
RealColumn get score => real().nullable()();
TextColumn get channels => text().nullable()();
TextColumn get devName => text().nullable()();
TextColumn get pictureGaussian => text().nullable()();
TextColumn get picture => text().nullable()();
IntColumn get commentNum => integer().nullable()();
IntColumn get lastLoginAt => integer().nullable()();
TextColumn get screen => text().nullable()();
@override
Set<Column> get primaryKey => {id};
@override @override
String get tableName => 'explore_mini_app'; String get tableName => 'explore_mini_app';
} }

View File

@@ -1,16 +1,23 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
@DataClassName('DriftFavouriteDetail') @DataClassName('DriftFavoriteDetail')
class FavouriteDetails extends Table { class FavoriteDetails extends Table {
IntColumn get id => integer().autoIncrement()(); IntColumn get id => integer().autoIncrement()();
TextColumn get relatedId => text().withDefault(const Constant(''))(); TextColumn get relatedId => text().withDefault(const Constant(''))();
TextColumn get content => text().withDefault(const Constant(''))(); TextColumn get content => text().withDefault(const Constant(''))();
IntColumn get typ => integer().nullable()(); IntColumn get typ => integer().nullable()();
IntColumn get messageId => integer().nullable()(); IntColumn get messageId => integer().nullable()();
IntColumn get sendId => integer().nullable()(); IntColumn get sendId => integer().nullable()();
IntColumn get chatId => integer().nullable()(); IntColumn get chatId => integer().nullable()();
IntColumn get sendTime => integer().nullable()(); IntColumn get sendTime => integer().nullable()();
@override @override
String get tableName => 'favourite_detail'; String get tableName => 'favorite_detail';
} }

View File

@@ -1,36 +1,8 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/tables/mixin/mini_app_table_mixin.dart';
@DataClassName('DriftFavoriteMiniApp') @DataClassName('DriftFavoriteMiniApp')
class FavoriteMiniApps extends Table { class FavoriteMiniApps extends Table with MiniAppTableMixin {
TextColumn get id => text()();
TextColumn get name => text().nullable()();
TextColumn get openuid => text().nullable()();
TextColumn get devId => text().nullable()();
TextColumn get icon => text().nullable()();
TextColumn get iconGaussian => text().nullable()();
TextColumn get downloadUrl => text().nullable()();
TextColumn get description => text().nullable()();
IntColumn get version => integer().nullable()();
IntColumn get typ => integer().nullable()();
IntColumn get flag => integer().nullable()();
IntColumn get reviewStatus => integer().nullable()();
IntColumn get favoriteAt => integer().nullable()();
IntColumn get isActive => integer().nullable()();
IntColumn get createdAt => integer().nullable()();
IntColumn get updatedAt => integer().nullable()();
IntColumn get deletedAt => integer().nullable()();
RealColumn get score => real().nullable()();
TextColumn get channels => text().nullable()();
TextColumn get devName => text().nullable()();
TextColumn get pictureGaussian => text().nullable()();
TextColumn get picture => text().nullable()();
IntColumn get commentNum => integer().nullable()();
IntColumn get lastLoginAt => integer().nullable()();
TextColumn get screen => text().nullable()();
@override
Set<Column> get primaryKey => {id};
@override @override
String get tableName => 'favorite_mini_app'; String get tableName => 'favorite_mini_app';
} }

View File

@@ -1,26 +1,40 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
@DataClassName('DriftFavourite') @DataClassName('DriftFavorite')
class Favourites extends Table { class Favorites extends Table {
IntColumn get id => integer()(); IntColumn get id => integer()();
TextColumn get parentId => text().withDefault(const Constant(''))(); TextColumn get parentId => text().withDefault(const Constant(''))();
TextColumn get data => text().withDefault(const Constant(''))(); TextColumn get data => text().withDefault(const Constant(''))();
IntColumn get createdAt => integer().withDefault(const Constant(0))(); IntColumn get createdAt => integer().withDefault(const Constant(0))();
IntColumn get updatedAt => integer().withDefault(const Constant(0))(); IntColumn get updatedAt => integer().withDefault(const Constant(0))();
IntColumn get deletedAt => integer().withDefault(const Constant(0))(); IntColumn get deletedAt => integer().withDefault(const Constant(0))();
IntColumn get source => integer().nullable()(); IntColumn get source => integer().nullable()();
IntColumn get userId => integer().nullable()(); IntColumn get userId => integer().nullable()();
IntColumn get authorId => integer().nullable()(); IntColumn get authorId => integer().nullable()();
TextColumn get typ => text().withDefault(const Constant('[]'))(); TextColumn get typ => text().withDefault(const Constant('[]'))();
TextColumn get tag => text().withDefault(const Constant('[]'))(); TextColumn get tag => text().withDefault(const Constant('[]'))();
IntColumn get isPin => integer().withDefault(const Constant(0))(); IntColumn get isPin => integer().withDefault(const Constant(0))();
IntColumn get chatTyp => integer().withDefault(const Constant(0))(); IntColumn get chatTyp => integer().withDefault(const Constant(0))();
IntColumn get isUploaded => integer().withDefault(const Constant(1))(); IntColumn get isUploaded => integer().withDefault(const Constant(1))();
TextColumn get urls => text().withDefault(const Constant('[]'))(); TextColumn get urls => text().withDefault(const Constant('[]'))();
@override @override
Set<Column> get primaryKey => {id}; Set<Column> get primaryKey => {id};
@override @override
String get tableName => 'favourite'; String get tableName => 'favorite';
} }

View File

@@ -0,0 +1,58 @@
import 'package:drift/drift.dart';
/// 小程序表共用列 mixin
/// discover / explore / favorite / recent 四张表共用
mixin MiniAppTableMixin on Table {
TextColumn get id => text()();
TextColumn get name => text().nullable()();
TextColumn get openuid => text().nullable()();
TextColumn get devId => text().nullable()();
TextColumn get icon => text().nullable()();
TextColumn get iconGaussian => text().nullable()();
TextColumn get downloadUrl => text().nullable()();
TextColumn get description => text().nullable()();
IntColumn get version => integer().nullable()();
IntColumn get typ => integer().nullable()();
IntColumn get flag => integer().nullable()();
IntColumn get reviewStatus => integer().nullable()();
IntColumn get favoriteAt => integer().nullable()();
IntColumn get isActive => integer().nullable()();
IntColumn get createdAt => integer().nullable()();
IntColumn get updatedAt => integer().nullable()();
IntColumn get deletedAt => integer().nullable()();
RealColumn get score => real().nullable()();
TextColumn get channels => text().nullable()();
TextColumn get devName => text().nullable()();
TextColumn get pictureGaussian => text().nullable()();
TextColumn get picture => text().nullable()();
IntColumn get commentNum => integer().nullable()();
TextColumn get lastLoginAt => text().nullable()();
TextColumn get screen => text().nullable()();
@override
Set<Column> get primaryKey => {id};
}

View File

@@ -1,36 +1,8 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/tables/mixin/mini_app_table_mixin.dart';
@DataClassName('DriftRecentMiniApp') @DataClassName('DriftRecentMiniApp')
class RecentMiniApps extends Table { class RecentMiniApps extends Table with MiniAppTableMixin {
TextColumn get id => text()();
TextColumn get name => text().nullable()();
TextColumn get openuid => text().nullable()();
TextColumn get devId => text().nullable()();
TextColumn get icon => text().nullable()();
TextColumn get iconGaussian => text().nullable()();
TextColumn get downloadUrl => text().nullable()();
TextColumn get description => text().nullable()();
IntColumn get version => integer().nullable()();
IntColumn get typ => integer().nullable()();
IntColumn get flag => integer().nullable()();
IntColumn get reviewStatus => integer().nullable()();
IntColumn get favoriteAt => integer().nullable()();
IntColumn get isActive => integer().nullable()();
IntColumn get createdAt => integer().nullable()();
IntColumn get updatedAt => integer().nullable()();
IntColumn get deletedAt => integer().nullable()();
RealColumn get score => real().nullable()();
TextColumn get channels => text().nullable()();
TextColumn get devName => text().nullable()();
TextColumn get pictureGaussian => text().nullable()();
TextColumn get picture => text().nullable()();
IntColumn get commentNum => integer().nullable()();
IntColumn get lastLoginAt => integer().nullable()();
TextColumn get screen => text().nullable()();
@override
Set<Column> get primaryKey => {id};
@override @override
String get tableName => 'recent_mini_app'; String get tableName => 'recent_mini_app';
} }

View File

@@ -1,179 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/chat_bot.dart';
/// 聊天机器人 DTO
class ChatBotDto {
final int id;
final String? name;
final String? username;
final int? botUserId;
final String? icon;
final String? iconGaussian;
final String? description;
final String? token;
final int? flag;
final int? status;
final String? webhook;
final String? commands;
final String? banner;
final int? channelId;
final int? channelGroupId;
final int? deletedAt;
final String? internalWebhook;
final int? mode;
final String? redirectUrl;
final int? isInvitable;
final int? isAllowForward;
final String? tips;
const ChatBotDto({
required this.id,
this.name,
this.username,
this.botUserId,
this.icon,
this.iconGaussian,
this.description,
this.token,
this.flag,
this.status,
this.webhook,
this.commands,
this.banner,
this.channelId,
this.channelGroupId,
this.deletedAt,
this.internalWebhook,
this.mode,
this.redirectUrl,
this.isInvitable,
this.isAllowForward,
this.tips,
});
factory ChatBotDto.fromJson(Map<String, dynamic> json) => ChatBotDto(
id: json['id'] as int,
name: json['name'],
username: json['username'],
botUserId: json['bot_user_id'],
icon: json['icon'],
iconGaussian: json['icon_gaussian'],
description: json['description'],
token: json['token'],
flag: json['flag'],
status: json['status'],
webhook: json['webhook'],
commands: json['commands'],
banner: json['banner'],
channelId: json['channel_id'],
channelGroupId: json['channel_group_id'],
deletedAt: json['deleted_at'],
internalWebhook: json['internal_webhook'],
mode: json['mode'],
redirectUrl: json['redirect_url'],
isInvitable: json['is_invitable'],
isAllowForward: json['is_allow_forward'],
tips: json['tips'],
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'username': username,
'bot_user_id': botUserId,
'icon': icon,
'icon_gaussian': iconGaussian,
'description': description,
'token': token,
'flag': flag,
'status': status,
'webhook': webhook,
'commands': commands,
'banner': banner,
'channel_id': channelId,
'channel_group_id': channelGroupId,
'deleted_at': deletedAt,
'internal_webhook': internalWebhook,
'mode': mode,
'redirect_url': redirectUrl,
'is_invitable': isInvitable,
'is_allow_forward': isAllowForward,
'tips': tips,
};
ChatBot toEntity() => ChatBot(
id: id,
name: name,
username: username,
botUserId: botUserId,
icon: icon,
iconGaussian: iconGaussian,
description: description,
token: token,
flag: flag,
status: status,
webhook: webhook,
commands: commands,
banner: banner,
channelId: channelId,
channelGroupId: channelGroupId,
deletedAt: deletedAt,
internalWebhook: internalWebhook,
mode: mode,
redirectUrl: redirectUrl,
isInvitable: isInvitable,
isAllowForward: isAllowForward,
tips: tips,
);
factory ChatBotDto.fromEntity(ChatBot chatBot) => ChatBotDto(
id: chatBot.id,
name: chatBot.name,
username: chatBot.username,
botUserId: chatBot.botUserId,
icon: chatBot.icon,
iconGaussian: chatBot.iconGaussian,
description: chatBot.description,
token: chatBot.token,
flag: chatBot.flag,
status: chatBot.status,
webhook: chatBot.webhook,
commands: chatBot.commands,
banner: chatBot.banner,
channelId: chatBot.channelId,
channelGroupId: chatBot.channelGroupId,
deletedAt: chatBot.deletedAt,
internalWebhook: chatBot.internalWebhook,
mode: chatBot.mode,
redirectUrl: chatBot.redirectUrl,
isInvitable: chatBot.isInvitable,
isAllowForward: chatBot.isAllowForward,
tips: chatBot.tips,
);
ChatBotsCompanion toCompanion() => ChatBotsCompanion(
id: Value(id),
name: Value(name),
username: Value(username),
botUserId: Value(botUserId),
icon: Value(icon),
iconGaussian: Value(iconGaussian),
description: Value(description),
token: Value(token),
flag: Value(flag),
status: Value(status),
webhook: Value(webhook ?? ''),
commands: Value(commands ?? '[]'),
banner: Value(banner),
channelId: Value(channelId),
channelGroupId: Value(channelGroupId),
deletedAt: Value(deletedAt),
internalWebhook: Value(internalWebhook),
mode: Value(mode),
redirectUrl: Value(redirectUrl),
isInvitable: Value(isInvitable),
isAllowForward: Value(isAllowForward),
tips: Value(tips),
);
}

View File

@@ -1,90 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/chat_category.dart';
/// 聊天分类 DTO
class ChatCategoryDto {
final int id;
final String? name;
final String? includedChatIds;
final String? excludedChatIds;
final int? seq;
final int isHide;
final int createdAt;
final int updatedAt;
final int deletedAt;
const ChatCategoryDto({
required this.id,
this.name,
this.includedChatIds,
this.excludedChatIds,
this.seq,
this.isHide = 0,
this.createdAt = 0,
this.updatedAt = 0,
this.deletedAt = 0,
});
factory ChatCategoryDto.fromJson(Map<String, dynamic> json) =>
ChatCategoryDto(
id: json['id'] as int,
name: json['name'],
includedChatIds: json['included_chat_ids'],
excludedChatIds: json['excluded_chat_ids'],
seq: json['seq'],
isHide: json['is_hide'] ?? 0,
createdAt: json['created_at'] ?? 0,
updatedAt: json['updated_at'] ?? 0,
deletedAt: json['deleted_at'] ?? 0,
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'included_chat_ids': includedChatIds,
'excluded_chat_ids': excludedChatIds,
'seq': seq,
'is_hide': isHide,
'created_at': createdAt,
'updated_at': updatedAt,
'deleted_at': deletedAt,
};
ChatCategory toEntity() => ChatCategory(
id: id,
name: name,
includedChatIds: includedChatIds,
excludedChatIds: excludedChatIds,
seq: seq,
isHide: isHide,
createdAt: createdAt,
updatedAt: updatedAt,
deletedAt: deletedAt,
);
factory ChatCategoryDto.fromEntity(ChatCategory chatCategory) =>
ChatCategoryDto(
id: chatCategory.id,
name: chatCategory.name,
includedChatIds: chatCategory.includedChatIds,
excludedChatIds: chatCategory.excludedChatIds,
seq: chatCategory.seq,
isHide: chatCategory.isHide,
createdAt: chatCategory.createdAt,
updatedAt: chatCategory.updatedAt,
deletedAt: chatCategory.deletedAt,
);
ChatCategoriesCompanion toCompanion() => ChatCategoriesCompanion(
id: Value(id),
name: Value(name),
includedChatIds: Value(includedChatIds),
excludedChatIds: Value(excludedChatIds),
seq: Value(seq),
isHide: Value(isHide),
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
deletedAt: Value(deletedAt),
);
}

View File

@@ -1,200 +0,0 @@
/// 聊天 Domain 实体
class Chat {
final int id;
final int? typ;
final int? lastId;
final int? lastTyp;
final String? lastMsg;
final int? lastTime;
final int lastPos;
final int firstPos;
final int? msgIdx;
final String? profile;
final String? pin;
final String? icon;
final String iconGaussian;
final String? name;
final int? userId;
final int? chatId;
final int? friendId;
final int? sort;
final int? unreadNum;
final int? unreadCount;
final int? hideChatMsgIdx;
final int? readChatMsgIdx;
final int? otherReadIdx;
final String? unreadAtMsgIdx;
final int? deleteTime;
final int? addIndex;
final int flag;
final int? flagMy;
final int? autoDeleteInterval;
final int? mute;
final int? verified;
final int? createTime;
final int? startIdx;
final int? isReadMsg;
final String translateOutgoing;
final String translateIncoming;
final int incomingIdx;
final int outgoingIdx;
final int incomingSoundId;
final int outgoingSoundId;
final int notificationSoundId;
final String chatKey;
final String activeChatKey;
final int coverIdx;
final int round;
final int workspaceId;
final int localPermission;
const Chat({
required this.id,
this.typ,
this.lastId,
this.lastTyp,
this.lastMsg,
this.lastTime,
this.lastPos = 0,
this.firstPos = -1,
this.msgIdx,
this.profile,
this.pin,
this.icon,
this.iconGaussian = '',
this.name,
this.userId,
this.chatId,
this.friendId,
this.sort,
this.unreadNum,
this.unreadCount,
this.hideChatMsgIdx,
this.readChatMsgIdx,
this.otherReadIdx,
this.unreadAtMsgIdx,
this.deleteTime,
this.addIndex,
this.flag = 0,
this.flagMy,
this.autoDeleteInterval,
this.mute,
this.verified,
this.createTime,
this.startIdx,
this.isReadMsg,
this.translateOutgoing = '',
this.translateIncoming = '',
this.incomingIdx = 0,
this.outgoingIdx = 0,
this.incomingSoundId = 0,
this.outgoingSoundId = 0,
this.notificationSoundId = 0,
this.chatKey = '',
this.activeChatKey = '',
this.coverIdx = 0,
this.round = 0,
this.workspaceId = 0,
this.localPermission = 0,
});
Chat copyWith({
int? id,
int? typ,
int? lastId,
int? lastTyp,
String? lastMsg,
int? lastTime,
int? lastPos,
int? firstPos,
int? msgIdx,
String? profile,
String? pin,
String? icon,
String? iconGaussian,
String? name,
int? userId,
int? chatId,
int? friendId,
int? sort,
int? unreadNum,
int? unreadCount,
int? hideChatMsgIdx,
int? readChatMsgIdx,
int? otherReadIdx,
String? unreadAtMsgIdx,
int? deleteTime,
int? addIndex,
int? flag,
int? flagMy,
int? autoDeleteInterval,
int? mute,
int? verified,
int? createTime,
int? startIdx,
int? isReadMsg,
String? translateOutgoing,
String? translateIncoming,
int? incomingIdx,
int? outgoingIdx,
int? incomingSoundId,
int? outgoingSoundId,
int? notificationSoundId,
String? chatKey,
String? activeChatKey,
int? coverIdx,
int? round,
int? workspaceId,
int? localPermission,
}) {
return Chat(
id: id ?? this.id,
typ: typ ?? this.typ,
lastId: lastId ?? this.lastId,
lastTyp: lastTyp ?? this.lastTyp,
lastMsg: lastMsg ?? this.lastMsg,
lastTime: lastTime ?? this.lastTime,
lastPos: lastPos ?? this.lastPos,
firstPos: firstPos ?? this.firstPos,
msgIdx: msgIdx ?? this.msgIdx,
profile: profile ?? this.profile,
pin: pin ?? this.pin,
icon: icon ?? this.icon,
iconGaussian: iconGaussian ?? this.iconGaussian,
name: name ?? this.name,
userId: userId ?? this.userId,
chatId: chatId ?? this.chatId,
friendId: friendId ?? this.friendId,
sort: sort ?? this.sort,
unreadNum: unreadNum ?? this.unreadNum,
unreadCount: unreadCount ?? this.unreadCount,
hideChatMsgIdx: hideChatMsgIdx ?? this.hideChatMsgIdx,
readChatMsgIdx: readChatMsgIdx ?? this.readChatMsgIdx,
otherReadIdx: otherReadIdx ?? this.otherReadIdx,
unreadAtMsgIdx: unreadAtMsgIdx ?? this.unreadAtMsgIdx,
deleteTime: deleteTime ?? this.deleteTime,
addIndex: addIndex ?? this.addIndex,
flag: flag ?? this.flag,
flagMy: flagMy ?? this.flagMy,
autoDeleteInterval: autoDeleteInterval ?? this.autoDeleteInterval,
mute: mute ?? this.mute,
verified: verified ?? this.verified,
createTime: createTime ?? this.createTime,
startIdx: startIdx ?? this.startIdx,
isReadMsg: isReadMsg ?? this.isReadMsg,
translateOutgoing: translateOutgoing ?? this.translateOutgoing,
translateIncoming: translateIncoming ?? this.translateIncoming,
incomingIdx: incomingIdx ?? this.incomingIdx,
outgoingIdx: outgoingIdx ?? this.outgoingIdx,
incomingSoundId: incomingSoundId ?? this.incomingSoundId,
outgoingSoundId: outgoingSoundId ?? this.outgoingSoundId,
notificationSoundId: notificationSoundId ?? this.notificationSoundId,
chatKey: chatKey ?? this.chatKey,
activeChatKey: activeChatKey ?? this.activeChatKey,
coverIdx: coverIdx ?? this.coverIdx,
round: round ?? this.round,
workspaceId: workspaceId ?? this.workspaceId,
localPermission: localPermission ?? this.localPermission,
);
}
}

View File

@@ -1,201 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/explore_mini_app.dart';
/// 探索小程序 DTO
class ExploreMiniAppDto {
final String id;
final String? name;
final String? openuid;
final String? devId;
final String? icon;
final String? iconGaussian;
final String? downloadUrl;
final String? description;
final int? version;
final int? typ;
final int? flag;
final int? reviewStatus;
final int? favoriteAt;
final int? isActive;
final int? createdAt;
final int? updatedAt;
final int? deletedAt;
final double? score;
final String? channels;
final String? devName;
final String? pictureGaussian;
final String? picture;
final int? commentNum;
final int? lastLoginAt;
final String? screen;
const ExploreMiniAppDto({
required this.id,
this.name,
this.openuid,
this.devId,
this.icon,
this.iconGaussian,
this.downloadUrl,
this.description,
this.version,
this.typ,
this.flag,
this.reviewStatus,
this.favoriteAt,
this.isActive,
this.createdAt,
this.updatedAt,
this.deletedAt,
this.score,
this.channels,
this.devName,
this.pictureGaussian,
this.picture,
this.commentNum,
this.lastLoginAt,
this.screen,
});
factory ExploreMiniAppDto.fromJson(Map<String, dynamic> json) =>
ExploreMiniAppDto(
id: json['id'] as String,
name: json['name'],
openuid: json['openuid'],
devId: json['dev_id'],
icon: json['icon'],
iconGaussian: json['icon_gaussian'],
downloadUrl: json['download_url'],
description: json['description'],
version: json['version'],
typ: json['typ'],
flag: json['flag'],
reviewStatus: json['review_status'],
favoriteAt: json['favorite_at'],
isActive: json['is_active'],
createdAt: json['created_at'],
updatedAt: json['updated_at'],
deletedAt: json['deleted_at'],
score: json['score']?.toDouble(),
channels: json['channels'],
devName: json['dev_name'],
pictureGaussian: json['picture_gaussian'],
picture: json['picture'],
commentNum: json['comment_num'],
lastLoginAt: json['last_login_at'],
screen: json['screen'],
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'openuid': openuid,
'dev_id': devId,
'icon': icon,
'icon_gaussian': iconGaussian,
'download_url': downloadUrl,
'description': description,
'version': version,
'typ': typ,
'flag': flag,
'review_status': reviewStatus,
'favorite_at': favoriteAt,
'is_active': isActive,
'created_at': createdAt,
'updated_at': updatedAt,
'deleted_at': deletedAt,
'score': score,
'channels': channels,
'dev_name': devName,
'picture_gaussian': pictureGaussian,
'picture': picture,
'comment_num': commentNum,
'last_login_at': lastLoginAt,
'screen': screen,
};
ExploreMiniApp toEntity() => ExploreMiniApp(
id: id,
name: name,
openuid: openuid,
devId: devId,
icon: icon,
iconGaussian: iconGaussian,
downloadUrl: downloadUrl,
description: description,
version: version,
typ: typ,
flag: flag,
reviewStatus: reviewStatus,
favoriteAt: favoriteAt,
isActive: isActive,
createdAt: createdAt,
updatedAt: updatedAt,
deletedAt: deletedAt,
score: score,
channels: channels,
devName: devName,
pictureGaussian: pictureGaussian,
picture: picture,
commentNum: commentNum,
lastLoginAt: lastLoginAt,
screen: screen,
);
factory ExploreMiniAppDto.fromEntity(ExploreMiniApp app) => ExploreMiniAppDto(
id: app.id,
name: app.name,
openuid: app.openuid,
devId: app.devId,
icon: app.icon,
iconGaussian: app.iconGaussian,
downloadUrl: app.downloadUrl,
description: app.description,
version: app.version,
typ: app.typ,
flag: app.flag,
reviewStatus: app.reviewStatus,
favoriteAt: app.favoriteAt,
isActive: app.isActive,
createdAt: app.createdAt,
updatedAt: app.updatedAt,
deletedAt: app.deletedAt,
score: app.score,
channels: app.channels,
devName: app.devName,
pictureGaussian: app.pictureGaussian,
picture: app.picture,
commentNum: app.commentNum,
lastLoginAt: app.lastLoginAt,
screen: app.screen,
);
ExploreMiniAppsCompanion toCompanion() => ExploreMiniAppsCompanion(
id: Value(id),
name: Value(name),
openuid: Value(openuid),
devId: Value(devId),
icon: Value(icon),
iconGaussian: Value(iconGaussian),
downloadUrl: Value(downloadUrl),
description: Value(description),
version: Value(version),
typ: Value(typ),
flag: Value(flag),
reviewStatus: Value(reviewStatus),
favoriteAt: Value(favoriteAt),
isActive: Value(isActive),
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
deletedAt: Value(deletedAt),
score: Value(score),
channels: Value(channels),
devName: Value(devName),
pictureGaussian: Value(pictureGaussian),
picture: Value(picture),
commentNum: Value(commentNum),
lastLoginAt: Value(lastLoginAt),
screen: Value(screen),
);
}

View File

@@ -1,202 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/favorite_mini_app.dart';
/// 收藏小程序 DTO
class FavoriteMiniAppDto {
final String id;
final String? name;
final String? openuid;
final String? devId;
final String? icon;
final String? iconGaussian;
final String? downloadUrl;
final String? description;
final int? version;
final int? typ;
final int? flag;
final int? reviewStatus;
final int? favoriteAt;
final int? isActive;
final int? createdAt;
final int? updatedAt;
final int? deletedAt;
final double? score;
final String? channels;
final String? devName;
final String? pictureGaussian;
final String? picture;
final int? commentNum;
final int? lastLoginAt;
final String? screen;
const FavoriteMiniAppDto({
required this.id,
this.name,
this.openuid,
this.devId,
this.icon,
this.iconGaussian,
this.downloadUrl,
this.description,
this.version,
this.typ,
this.flag,
this.reviewStatus,
this.favoriteAt,
this.isActive,
this.createdAt,
this.updatedAt,
this.deletedAt,
this.score,
this.channels,
this.devName,
this.pictureGaussian,
this.picture,
this.commentNum,
this.lastLoginAt,
this.screen,
});
factory FavoriteMiniAppDto.fromJson(Map<String, dynamic> json) =>
FavoriteMiniAppDto(
id: json['id'] as String,
name: json['name'],
openuid: json['openuid'],
devId: json['dev_id'],
icon: json['icon'],
iconGaussian: json['icon_gaussian'],
downloadUrl: json['download_url'],
description: json['description'],
version: json['version'],
typ: json['typ'],
flag: json['flag'],
reviewStatus: json['review_status'],
favoriteAt: json['favorite_at'],
isActive: json['is_active'],
createdAt: json['created_at'],
updatedAt: json['updated_at'],
deletedAt: json['deleted_at'],
score: json['score']?.toDouble(),
channels: json['channels'],
devName: json['dev_name'],
pictureGaussian: json['picture_gaussian'],
picture: json['picture'],
commentNum: json['comment_num'],
lastLoginAt: json['last_login_at'],
screen: json['screen'],
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'openuid': openuid,
'dev_id': devId,
'icon': icon,
'icon_gaussian': iconGaussian,
'download_url': downloadUrl,
'description': description,
'version': version,
'typ': typ,
'flag': flag,
'review_status': reviewStatus,
'favorite_at': favoriteAt,
'is_active': isActive,
'created_at': createdAt,
'updated_at': updatedAt,
'deleted_at': deletedAt,
'score': score,
'channels': channels,
'dev_name': devName,
'picture_gaussian': pictureGaussian,
'picture': picture,
'comment_num': commentNum,
'last_login_at': lastLoginAt,
'screen': screen,
};
FavoriteMiniApp toEntity() => FavoriteMiniApp(
id: id,
name: name,
openuid: openuid,
devId: devId,
icon: icon,
iconGaussian: iconGaussian,
downloadUrl: downloadUrl,
description: description,
version: version,
typ: typ,
flag: flag,
reviewStatus: reviewStatus,
favoriteAt: favoriteAt,
isActive: isActive,
createdAt: createdAt,
updatedAt: updatedAt,
deletedAt: deletedAt,
score: score,
channels: channels,
devName: devName,
pictureGaussian: pictureGaussian,
picture: picture,
commentNum: commentNum,
lastLoginAt: lastLoginAt,
screen: screen,
);
factory FavoriteMiniAppDto.fromEntity(FavoriteMiniApp app) =>
FavoriteMiniAppDto(
id: app.id,
name: app.name,
openuid: app.openuid,
devId: app.devId,
icon: app.icon,
iconGaussian: app.iconGaussian,
downloadUrl: app.downloadUrl,
description: app.description,
version: app.version,
typ: app.typ,
flag: app.flag,
reviewStatus: app.reviewStatus,
favoriteAt: app.favoriteAt,
isActive: app.isActive,
createdAt: app.createdAt,
updatedAt: app.updatedAt,
deletedAt: app.deletedAt,
score: app.score,
channels: app.channels,
devName: app.devName,
pictureGaussian: app.pictureGaussian,
picture: app.picture,
commentNum: app.commentNum,
lastLoginAt: app.lastLoginAt,
screen: app.screen,
);
FavoriteMiniAppsCompanion toCompanion() => FavoriteMiniAppsCompanion(
id: Value(id),
name: Value(name),
openuid: Value(openuid),
devId: Value(devId),
icon: Value(icon),
iconGaussian: Value(iconGaussian),
downloadUrl: Value(downloadUrl),
description: Value(description),
version: Value(version),
typ: Value(typ),
flag: Value(flag),
reviewStatus: Value(reviewStatus),
favoriteAt: Value(favoriteAt),
isActive: Value(isActive),
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
deletedAt: Value(deletedAt),
score: Value(score),
channels: Value(channels),
devName: Value(devName),
pictureGaussian: Value(pictureGaussian),
picture: Value(picture),
commentNum: Value(commentNum),
lastLoginAt: Value(lastLoginAt),
screen: Value(screen),
);
}

View File

@@ -1,83 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/favourite_detail.dart';
/// 收藏详情 DTO
class FavouriteDetailDto {
final int? id;
final String relatedId;
final String content;
final int? typ;
final int? messageId;
final int? sendId;
final int? chatId;
final int? sendTime;
const FavouriteDetailDto({
this.id,
this.relatedId = '',
this.content = '',
this.typ,
this.messageId,
this.sendId,
this.chatId,
this.sendTime,
});
factory FavouriteDetailDto.fromJson(Map<String, dynamic> json) =>
FavouriteDetailDto(
id: json['id'],
relatedId: json['related_id'] ?? '',
content: json['content'] ?? '',
typ: json['typ'],
messageId: json['messageId'],
sendId: json['sendId'],
chatId: json['chatId'],
sendTime: json['sendTime'],
);
Map<String, dynamic> toJson() => {
'id': id,
'related_id': relatedId,
'content': content,
'typ': typ,
'messageId': messageId,
'sendId': sendId,
'chatId': chatId,
'sendTime': sendTime,
};
FavouriteDetail toEntity() => FavouriteDetail(
id: id,
relatedId: relatedId,
content: content,
typ: typ,
messageId: messageId,
sendId: sendId,
chatId: chatId,
sendTime: sendTime,
);
factory FavouriteDetailDto.fromEntity(FavouriteDetail detail) =>
FavouriteDetailDto(
id: detail.id,
relatedId: detail.relatedId,
content: detail.content,
typ: detail.typ,
messageId: detail.messageId,
sendId: detail.sendId,
chatId: detail.chatId,
sendTime: detail.sendTime,
);
FavouriteDetailsCompanion toCompanion() => FavouriteDetailsCompanion(
id: id != null ? Value(id!) : const Value.absent(),
relatedId: Value(relatedId),
content: Value(content),
typ: Value(typ),
messageId: Value(messageId),
sendId: Value(sendId),
chatId: Value(chatId),
sendTime: Value(sendTime),
);
}

View File

@@ -1,130 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/favourite.dart';
/// 收藏 DTO
class FavouriteDto {
final int id;
final String parentId;
final String data;
final int createdAt;
final int updatedAt;
final int deletedAt;
final int? source;
final int? userId;
final int? authorId;
final String typ;
final String tag;
final int isPin;
final int chatTyp;
final int isUploaded;
final String urls;
const FavouriteDto({
required this.id,
this.parentId = '',
this.data = '',
this.createdAt = 0,
this.updatedAt = 0,
this.deletedAt = 0,
this.source,
this.userId,
this.authorId,
this.typ = '[]',
this.tag = '[]',
this.isPin = 0,
this.chatTyp = 0,
this.isUploaded = 1,
this.urls = '[]',
});
factory FavouriteDto.fromJson(Map<String, dynamic> json) => FavouriteDto(
id: json['id'] as int,
parentId: json['parent_id'] ?? '',
data: json['data'] ?? '',
createdAt: json['created_at'] ?? 0,
updatedAt: json['updated_at'] ?? 0,
deletedAt: json['deleted_at'] ?? 0,
source: json['source'],
userId: json['user_id'],
authorId: json['author_id'],
typ: json['typ'] ?? '[]',
tag: json['tag'] ?? '[]',
isPin: json['is_pin'] ?? 0,
chatTyp: json['chat_typ'] ?? 0,
isUploaded: json['is_uploaded'] ?? 1,
urls: json['urls'] ?? '[]',
);
Map<String, dynamic> toJson() => {
'id': id,
'parent_id': parentId,
'data': data,
'created_at': createdAt,
'updated_at': updatedAt,
'deleted_at': deletedAt,
'source': source,
'user_id': userId,
'author_id': authorId,
'typ': typ,
'tag': tag,
'is_pin': isPin,
'chat_typ': chatTyp,
'is_uploaded': isUploaded,
'urls': urls,
};
Favourite toEntity() => Favourite(
id: id,
parentId: parentId,
data: data,
createdAt: createdAt,
updatedAt: updatedAt,
deletedAt: deletedAt,
source: source,
userId: userId,
authorId: authorId,
typ: typ,
tag: tag,
isPin: isPin,
chatTyp: chatTyp,
isUploaded: isUploaded,
urls: urls,
);
factory FavouriteDto.fromEntity(Favourite favourite) => FavouriteDto(
id: favourite.id,
parentId: favourite.parentId,
data: favourite.data,
createdAt: favourite.createdAt,
updatedAt: favourite.updatedAt,
deletedAt: favourite.deletedAt,
source: favourite.source,
userId: favourite.userId,
authorId: favourite.authorId,
typ: favourite.typ,
tag: favourite.tag,
isPin: favourite.isPin,
chatTyp: favourite.chatTyp,
isUploaded: favourite.isUploaded,
urls: favourite.urls,
);
FavouritesCompanion toCompanion() => FavouritesCompanion(
id: Value(id),
parentId: Value(parentId),
data: Value(data),
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
deletedAt: Value(deletedAt),
source: Value(source),
userId: Value(userId),
authorId: Value(authorId),
typ: Value(typ),
tag: Value(tag),
isPin: Value(isPin),
chatTyp: Value(chatTyp),
isUploaded: Value(isUploaded),
urls: Value(urls),
);
}

View File

@@ -1,221 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/group.dart';
/// 群组 DTO
class GroupDto {
final int id;
final int? userJoinDate;
final String? name;
final String? profile;
final String? icon;
final String iconGaussian;
final int? permission;
final int? admin;
final String? members;
final int? owner;
final String? admins;
final int? visible;
final int? speakInterval;
final int? groupType;
final int? roomType;
final int? maxNumber;
final int? channelId;
final int? channelGroupId;
final int? createTime;
final int? updateTime;
final int? addIndex;
final int? maxMember;
final int? expireTime;
final int workspaceId;
final int mode;
final int redpacketPlay;
final String? topic;
final String? rp;
const GroupDto({
required this.id,
this.userJoinDate,
this.name,
this.profile,
this.icon,
this.iconGaussian = '',
this.permission,
this.admin,
this.members,
this.owner,
this.admins,
this.visible,
this.speakInterval,
this.groupType,
this.roomType,
this.maxNumber,
this.channelId,
this.channelGroupId,
this.createTime,
this.updateTime,
this.addIndex,
this.maxMember,
this.expireTime,
this.workspaceId = 0,
this.mode = 0,
this.redpacketPlay = 0,
this.topic,
this.rp,
});
factory GroupDto.fromJson(Map<String, dynamic> json) => GroupDto(
id: json['id'] as int,
userJoinDate: json['user_join_date'],
name: json['name'],
profile: json['profile'],
icon: json['icon'],
iconGaussian: json['icon_gaussian'] ?? '',
permission: json['permission'],
admin: json['admin'],
members: json['members'],
owner: json['owner'],
admins: json['admins'],
visible: json['visible'],
speakInterval: json['speak_interval'],
groupType: json['group_type'],
roomType: json['room_type'],
maxNumber: json['max_number'],
channelId: json['channel_id'],
channelGroupId: json['channel_group_id'],
createTime: json['create_time'],
updateTime: json['update_time'],
addIndex: json['__add_index'],
maxMember: json['max_member'],
expireTime: json['expire_time'],
workspaceId: json['workspace_id'] ?? 0,
mode: json['mode'] ?? 0,
redpacketPlay: json['redpacket_play'] ?? 0,
topic: json['topic'],
rp: json['rp'],
);
Map<String, dynamic> toJson() => {
'id': id,
'user_join_date': userJoinDate,
'name': name,
'profile': profile,
'icon': icon,
'icon_gaussian': iconGaussian,
'permission': permission,
'admin': admin,
'members': members,
'owner': owner,
'admins': admins,
'visible': visible,
'speak_interval': speakInterval,
'group_type': groupType,
'room_type': roomType,
'max_number': maxNumber,
'channel_id': channelId,
'channel_group_id': channelGroupId,
'create_time': createTime,
'update_time': updateTime,
'__add_index': addIndex,
'max_member': maxMember,
'expire_time': expireTime,
'workspace_id': workspaceId,
'mode': mode,
'redpacket_play': redpacketPlay,
'topic': topic,
'rp': rp,
};
Group toEntity() => Group(
id: id,
userJoinDate: userJoinDate,
name: name,
profile: profile,
icon: icon,
iconGaussian: iconGaussian,
permission: permission,
admin: admin,
members: members,
owner: owner,
admins: admins,
visible: visible,
speakInterval: speakInterval,
groupType: groupType,
roomType: roomType,
maxNumber: maxNumber,
channelId: channelId,
channelGroupId: channelGroupId,
createTime: createTime,
updateTime: updateTime,
addIndex: addIndex,
maxMember: maxMember,
expireTime: expireTime,
workspaceId: workspaceId,
mode: mode,
redpacketPlay: redpacketPlay,
topic: topic,
rp: rp,
);
factory GroupDto.fromEntity(Group group) => GroupDto(
id: group.id,
userJoinDate: group.userJoinDate,
name: group.name,
profile: group.profile,
icon: group.icon,
iconGaussian: group.iconGaussian,
permission: group.permission,
admin: group.admin,
members: group.members,
owner: group.owner,
admins: group.admins,
visible: group.visible,
speakInterval: group.speakInterval,
groupType: group.groupType,
roomType: group.roomType,
maxNumber: group.maxNumber,
channelId: group.channelId,
channelGroupId: group.channelGroupId,
createTime: group.createTime,
updateTime: group.updateTime,
addIndex: group.addIndex,
maxMember: group.maxMember,
expireTime: group.expireTime,
workspaceId: group.workspaceId,
mode: group.mode,
redpacketPlay: group.redpacketPlay,
topic: group.topic,
rp: group.rp,
);
GroupsCompanion toCompanion() => GroupsCompanion(
id: Value(id),
userJoinDate: Value(userJoinDate),
name: Value(name),
profile: Value(profile),
icon: Value(icon),
iconGaussian: Value(iconGaussian),
permission: Value(permission),
admin: Value(admin),
members: Value(members),
owner: Value(owner),
admins: Value(admins),
visible: Value(visible),
speakInterval: Value(speakInterval),
groupType: Value(groupType),
roomType: Value(roomType),
maxNumber: Value(maxNumber),
channelId: Value(channelId),
channelGroupId: Value(channelGroupId),
createTime: Value(createTime),
updateTime: Value(updateTime),
addIndex: Value(addIndex),
maxMember: Value(maxMember),
expireTime: Value(expireTime),
workspaceId: Value(workspaceId),
mode: Value(mode),
redpacketPlay: Value(redpacketPlay),
topic: Value(topic),
rp: Value(rp),
);
}

View File

@@ -1,137 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/message.dart';
/// 消息 DTO
class MessageDto {
final int id;
final int? messageId;
final int? chatId;
final int? chatIdx;
final int? sendId;
final String? content;
final int? typ;
final int? sendTime;
final int? expireTime;
final int? createTime;
final String? atUsers;
final String emojis;
final int editTime;
final int refTyp;
final int flag;
final String cmid;
const MessageDto({
required this.id,
this.messageId,
this.chatId,
this.chatIdx,
this.sendId,
this.content,
this.typ,
this.sendTime,
this.expireTime,
this.createTime,
this.atUsers,
this.emojis = '[]',
this.editTime = 0,
this.refTyp = 0,
this.flag = 0,
this.cmid = '',
});
factory MessageDto.fromJson(Map<String, dynamic> json) => MessageDto(
id: json['id'] as int,
messageId: json['message_id'],
chatId: json['chat_id'],
chatIdx: json['chat_idx'],
sendId: json['send_id'],
content: json['content'],
typ: json['typ'],
sendTime: json['send_time'],
expireTime: json['expire_time'],
createTime: json['create_time'],
atUsers: json['at_users'],
emojis: json['emojis'] ?? '[]',
editTime: json['edit_time'] ?? 0,
refTyp: json['ref_typ'] ?? 0,
flag: json['flag'] ?? 0,
cmid: json['cmid'] ?? '',
);
Map<String, dynamic> toJson() => {
'id': id,
'message_id': messageId,
'chat_id': chatId,
'chat_idx': chatIdx,
'send_id': sendId,
'content': content,
'typ': typ,
'send_time': sendTime,
'expire_time': expireTime,
'create_time': createTime,
'at_users': atUsers,
'emojis': emojis,
'edit_time': editTime,
'ref_typ': refTyp,
'flag': flag,
'cmid': cmid,
};
Message toEntity() => Message(
id: id,
messageId: messageId,
chatId: chatId,
chatIdx: chatIdx,
sendId: sendId,
content: content,
typ: typ,
sendTime: sendTime,
expireTime: expireTime,
createTime: createTime,
atUsers: atUsers,
emojis: emojis,
editTime: editTime,
refTyp: refTyp,
flag: flag,
cmid: cmid,
);
factory MessageDto.fromEntity(Message message) => MessageDto(
id: message.id,
messageId: message.messageId,
chatId: message.chatId,
chatIdx: message.chatIdx,
sendId: message.sendId,
content: message.content,
typ: message.typ,
sendTime: message.sendTime,
expireTime: message.expireTime,
createTime: message.createTime,
atUsers: message.atUsers,
emojis: message.emojis,
editTime: message.editTime,
refTyp: message.refTyp,
flag: message.flag,
cmid: message.cmid,
);
MessagesCompanion toCompanion() => MessagesCompanion(
id: Value(id),
messageId: Value(messageId),
chatId: Value(chatId),
chatIdx: Value(chatIdx),
sendId: Value(sendId),
content: Value(content),
typ: Value(typ),
sendTime: Value(sendTime),
expireTime: Value(expireTime),
createTime: Value(createTime),
atUsers: Value(atUsers),
emojis: Value(emojis),
editTime: Value(editTime),
refTyp: Value(refTyp),
flag: Value(flag),
cmid: Value(cmid),
);
}

View File

@@ -1,71 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/pending_friend_request_history.dart';
/// 待处理好友请求历史 DTO
class PendingFriendRequestHistoryDto {
final int id;
final int uid;
final int requestTime;
final String? remarks;
final String? source;
final int? rs;
const PendingFriendRequestHistoryDto({
required this.id,
required this.uid,
required this.requestTime,
this.remarks,
this.source,
this.rs,
});
factory PendingFriendRequestHistoryDto.fromJson(Map<String, dynamic> json) =>
PendingFriendRequestHistoryDto(
id: json['id'] as int,
uid: json['uid'] as int,
requestTime: json['request_time'] as int,
remarks: json['remarks'],
source: json['source'],
rs: json['rs'],
);
Map<String, dynamic> toJson() => {
'id': id,
'uid': uid,
'request_time': requestTime,
'remarks': remarks,
'source': source,
'rs': rs,
};
PendingFriendRequestHistory toEntity() => PendingFriendRequestHistory(
id: id,
uid: uid,
requestTime: requestTime,
remarks: remarks,
source: source,
rs: rs,
);
factory PendingFriendRequestHistoryDto.fromEntity(
PendingFriendRequestHistory history,
) => PendingFriendRequestHistoryDto(
id: history.id,
uid: history.uid,
requestTime: history.requestTime,
remarks: history.remarks,
source: history.source,
rs: history.rs,
);
PendingFriendRequestHistoriesCompanion toCompanion() =>
PendingFriendRequestHistoriesCompanion(
id: Value(id),
uid: Value(uid),
requestTime: Value(requestTime),
remarks: Value(remarks),
source: Value(source),
rs: Value(rs),
);
}

View File

@@ -1,201 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/recent_mini_app.dart';
/// 最近小程序 DTO
class RecentMiniAppDto {
final String id;
final String? name;
final String? openuid;
final String? devId;
final String? icon;
final String? iconGaussian;
final String? downloadUrl;
final String? description;
final int? version;
final int? typ;
final int? flag;
final int? reviewStatus;
final int? favoriteAt;
final int? isActive;
final int? createdAt;
final int? updatedAt;
final int? deletedAt;
final double? score;
final String? channels;
final String? devName;
final String? pictureGaussian;
final String? picture;
final int? commentNum;
final int? lastLoginAt;
final String? screen;
const RecentMiniAppDto({
required this.id,
this.name,
this.openuid,
this.devId,
this.icon,
this.iconGaussian,
this.downloadUrl,
this.description,
this.version,
this.typ,
this.flag,
this.reviewStatus,
this.favoriteAt,
this.isActive,
this.createdAt,
this.updatedAt,
this.deletedAt,
this.score,
this.channels,
this.devName,
this.pictureGaussian,
this.picture,
this.commentNum,
this.lastLoginAt,
this.screen,
});
factory RecentMiniAppDto.fromJson(Map<String, dynamic> json) =>
RecentMiniAppDto(
id: json['id'] as String,
name: json['name'],
openuid: json['openuid'],
devId: json['dev_id'],
icon: json['icon'],
iconGaussian: json['icon_gaussian'],
downloadUrl: json['download_url'],
description: json['description'],
version: json['version'],
typ: json['typ'],
flag: json['flag'],
reviewStatus: json['review_status'],
favoriteAt: json['favorite_at'],
isActive: json['is_active'],
createdAt: json['created_at'],
updatedAt: json['updated_at'],
deletedAt: json['deleted_at'],
score: json['score']?.toDouble(),
channels: json['channels'],
devName: json['dev_name'],
pictureGaussian: json['picture_gaussian'],
picture: json['picture'],
commentNum: json['comment_num'],
lastLoginAt: json['last_login_at'],
screen: json['screen'],
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'openuid': openuid,
'dev_id': devId,
'icon': icon,
'icon_gaussian': iconGaussian,
'download_url': downloadUrl,
'description': description,
'version': version,
'typ': typ,
'flag': flag,
'review_status': reviewStatus,
'favorite_at': favoriteAt,
'is_active': isActive,
'created_at': createdAt,
'updated_at': updatedAt,
'deleted_at': deletedAt,
'score': score,
'channels': channels,
'dev_name': devName,
'picture_gaussian': pictureGaussian,
'picture': picture,
'comment_num': commentNum,
'last_login_at': lastLoginAt,
'screen': screen,
};
RecentMiniApp toEntity() => RecentMiniApp(
id: id,
name: name,
openuid: openuid,
devId: devId,
icon: icon,
iconGaussian: iconGaussian,
downloadUrl: downloadUrl,
description: description,
version: version,
typ: typ,
flag: flag,
reviewStatus: reviewStatus,
favoriteAt: favoriteAt,
isActive: isActive,
createdAt: createdAt,
updatedAt: updatedAt,
deletedAt: deletedAt,
score: score,
channels: channels,
devName: devName,
pictureGaussian: pictureGaussian,
picture: picture,
commentNum: commentNum,
lastLoginAt: lastLoginAt,
screen: screen,
);
factory RecentMiniAppDto.fromEntity(RecentMiniApp app) => RecentMiniAppDto(
id: app.id,
name: app.name,
openuid: app.openuid,
devId: app.devId,
icon: app.icon,
iconGaussian: app.iconGaussian,
downloadUrl: app.downloadUrl,
description: app.description,
version: app.version,
typ: app.typ,
flag: app.flag,
reviewStatus: app.reviewStatus,
favoriteAt: app.favoriteAt,
isActive: app.isActive,
createdAt: app.createdAt,
updatedAt: app.updatedAt,
deletedAt: app.deletedAt,
score: app.score,
channels: app.channels,
devName: app.devName,
pictureGaussian: app.pictureGaussian,
picture: app.picture,
commentNum: app.commentNum,
lastLoginAt: app.lastLoginAt,
screen: app.screen,
);
RecentMiniAppsCompanion toCompanion() => RecentMiniAppsCompanion(
id: Value(id),
name: Value(name),
openuid: Value(openuid),
devId: Value(devId),
icon: Value(icon),
iconGaussian: Value(iconGaussian),
downloadUrl: Value(downloadUrl),
description: Value(description),
version: Value(version),
typ: Value(typ),
flag: Value(flag),
reviewStatus: Value(reviewStatus),
favoriteAt: Value(favoriteAt),
isActive: Value(isActive),
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
deletedAt: Value(deletedAt),
score: Value(score),
channels: Value(channels),
devName: Value(devName),
pictureGaussian: Value(pictureGaussian),
picture: Value(picture),
commentNum: Value(commentNum),
lastLoginAt: Value(lastLoginAt),
screen: Value(screen),
);
}

View File

@@ -1,109 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/retry.dart';
/// 重试 DTO
class RetryDto {
final int? id;
final int? uid;
final String apiType;
final String endPoint;
final String requestData;
final int? synced;
final String callbackFun;
final int? expired;
final int? replace;
final int? expireTime;
final int? createTime;
final int? addIndex;
const RetryDto({
this.id,
this.uid,
this.apiType = '',
this.endPoint = '',
this.requestData = '',
this.synced,
this.callbackFun = '',
this.expired,
this.replace,
this.expireTime,
this.createTime,
this.addIndex,
});
factory RetryDto.fromJson(Map<String, dynamic> json) => RetryDto(
id: json['id'],
uid: json['uid'],
apiType: json['api_type'] ?? '',
endPoint: json['end_point'] ?? '',
requestData: json['request_data'] ?? '',
synced: json['synced'],
callbackFun: json['callback_fun'] ?? '',
expired: json['expired'],
replace: json['replace'],
expireTime: json['expire_time'],
createTime: json['create_time'],
addIndex: json['__add_index'],
);
Map<String, dynamic> toJson() => {
'id': id,
'uid': uid,
'api_type': apiType,
'end_point': endPoint,
'request_data': requestData,
'synced': synced,
'callback_fun': callbackFun,
'expired': expired,
'replace': replace,
'expire_time': expireTime,
'create_time': createTime,
'__add_index': addIndex,
};
Retry toEntity() => Retry(
id: id,
uid: uid,
apiType: apiType,
endPoint: endPoint,
requestData: requestData,
synced: synced,
callbackFun: callbackFun,
expired: expired,
replace: replace,
expireTime: expireTime,
createTime: createTime,
addIndex: addIndex,
);
factory RetryDto.fromEntity(Retry retry) => RetryDto(
id: retry.id,
uid: retry.uid,
apiType: retry.apiType,
endPoint: retry.endPoint,
requestData: retry.requestData,
synced: retry.synced,
callbackFun: retry.callbackFun,
expired: retry.expired,
replace: retry.replace,
expireTime: retry.expireTime,
createTime: retry.createTime,
addIndex: retry.addIndex,
);
RetriesCompanion toCompanion() => RetriesCompanion(
id: id != null ? Value(id!) : const Value.absent(),
uid: Value(uid),
apiType: Value(apiType),
endPoint: Value(endPoint),
requestData: Value(requestData),
synced: Value(synced),
callbackFun: Value(callbackFun),
expired: Value(expired),
replace: Value(replace),
expireTime: Value(expireTime),
createTime: Value(createTime),
addIndex: Value(addIndex),
);
}

View File

@@ -1,88 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/sound.dart';
/// 音效 DTO
class SoundDto {
final int id;
final String filePath;
final int typ;
final String name;
final int createdAt;
final int updatedAt;
final int deletedAt;
final int channelGroupId;
final int isDefault;
const SoundDto({
required this.id,
this.filePath = '',
required this.typ,
this.name = '',
required this.createdAt,
required this.updatedAt,
this.deletedAt = 0,
required this.channelGroupId,
required this.isDefault,
});
factory SoundDto.fromJson(Map<String, dynamic> json) => SoundDto(
id: json['id'] as int,
filePath: json['file_path'] ?? '',
typ: json['typ'] as int,
name: json['name'] ?? '',
createdAt: json['created_at'] as int,
updatedAt: json['updated_at'] as int,
deletedAt: json['deleted_at'] ?? 0,
channelGroupId: json['channel_group_id'] as int,
isDefault: json['is_default'] as int,
);
Map<String, dynamic> toJson() => {
'id': id,
'file_path': filePath,
'typ': typ,
'name': name,
'created_at': createdAt,
'updated_at': updatedAt,
'deleted_at': deletedAt,
'channel_group_id': channelGroupId,
'is_default': isDefault,
};
Sound toEntity() => Sound(
id: id,
filePath: filePath,
typ: typ,
name: name,
createdAt: createdAt,
updatedAt: updatedAt,
deletedAt: deletedAt,
channelGroupId: channelGroupId,
isDefault: isDefault,
);
factory SoundDto.fromEntity(Sound sound) => SoundDto(
id: sound.id,
filePath: sound.filePath,
typ: sound.typ,
name: sound.name,
createdAt: sound.createdAt,
updatedAt: sound.updatedAt,
deletedAt: sound.deletedAt,
channelGroupId: sound.channelGroupId,
isDefault: sound.isDefault,
);
SoundsCompanion toCompanion() => SoundsCompanion(
id: Value(id),
filePath: Value(filePath),
typ: Value(typ),
name: Value(name),
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
deletedAt: Value(deletedAt),
channelGroupId: Value(channelGroupId),
isDefault: Value(isDefault),
);
}

View File

@@ -1,74 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/tag.dart';
/// 标签 DTO
class TagDto {
final int? id;
final int? uid;
final String name;
final int? type;
final int? createdAt;
final int? updatedAt;
final int? addIndex;
const TagDto({
this.id,
this.uid,
this.name = '',
this.type,
this.createdAt,
this.updatedAt,
this.addIndex,
});
factory TagDto.fromJson(Map<String, dynamic> json) => TagDto(
id: json['id'],
uid: json['uid'],
name: json['name'] ?? '',
type: json['type'],
createdAt: json['created_at'],
updatedAt: json['updated_at'],
addIndex: json['__add_index'],
);
Map<String, dynamic> toJson() => {
'id': id,
'uid': uid,
'name': name,
'type': type,
'created_at': createdAt,
'updated_at': updatedAt,
'__add_index': addIndex,
};
Tag toEntity() => Tag(
id: id,
uid: uid,
name: name,
type: type,
createdAt: createdAt,
updatedAt: updatedAt,
addIndex: addIndex,
);
factory TagDto.fromEntity(Tag tag) => TagDto(
id: tag.id,
uid: tag.uid,
name: tag.name,
type: tag.type,
createdAt: tag.createdAt,
updatedAt: tag.updatedAt,
addIndex: tag.addIndex,
);
TagsCompanion toCompanion() => TagsCompanion(
id: id != null ? Value(id!) : const Value.absent(),
uid: Value(uid),
name: Value(name),
type: Value(type),
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
addIndex: Value(addIndex),
);
}

View File

@@ -1,41 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/user_request_history.dart';
/// 用户请求历史 DTO
class UserRequestHistoryDto {
final int id;
final int? status;
final int? createdAt;
const UserRequestHistoryDto({required this.id, this.status, this.createdAt});
factory UserRequestHistoryDto.fromJson(Map<String, dynamic> json) =>
UserRequestHistoryDto(
id: json['id'] as int,
status: json['status'],
createdAt: json['created_at'],
);
Map<String, dynamic> toJson() => {
'id': id,
'status': status,
'created_at': createdAt,
};
UserRequestHistory toEntity() =>
UserRequestHistory(id: id, status: status, createdAt: createdAt);
factory UserRequestHistoryDto.fromEntity(UserRequestHistory history) =>
UserRequestHistoryDto(
id: history.id,
status: history.status,
createdAt: history.createdAt,
);
UserRequestHistoriesCompanion toCompanion() => UserRequestHistoriesCompanion(
id: Value(id),
status: Value(status),
createdAt: Value(createdAt),
);
}

View File

@@ -1,116 +0,0 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/workspace.dart';
/// 工作空间 DTO
class WorkspaceDto {
final int id;
final String? name;
final int? ownerId;
final String? description;
final String? logo;
final int? grade;
final int? cap;
final String? currency;
final int? status;
final int? createdAt;
final int? updatedAt;
final int? deletedAt;
final int? channelGroupId;
const WorkspaceDto({
required this.id,
this.name,
this.ownerId,
this.description,
this.logo,
this.grade,
this.cap,
this.currency,
this.status,
this.createdAt,
this.updatedAt,
this.deletedAt,
this.channelGroupId,
});
factory WorkspaceDto.fromJson(Map<String, dynamic> json) => WorkspaceDto(
id: json['id'] as int,
name: json['name'],
ownerId: json['owner_id'],
description: json['description'],
logo: json['logo'],
grade: json['grade'],
cap: json['cap'],
currency: json['currency'],
status: json['status'],
createdAt: json['created_at'],
updatedAt: json['updated_at'],
deletedAt: json['deleted_at'],
channelGroupId: json['channel_group_id'],
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'owner_id': ownerId,
'description': description,
'logo': logo,
'grade': grade,
'cap': cap,
'currency': currency,
'status': status,
'created_at': createdAt,
'updated_at': updatedAt,
'deleted_at': deletedAt,
'channel_group_id': channelGroupId,
};
Workspace toEntity() => Workspace(
id: id,
name: name,
ownerId: ownerId,
description: description,
logo: logo,
grade: grade,
cap: cap,
currency: currency,
status: status,
createdAt: createdAt,
updatedAt: updatedAt,
deletedAt: deletedAt,
channelGroupId: channelGroupId,
);
factory WorkspaceDto.fromEntity(Workspace workspace) => WorkspaceDto(
id: workspace.id,
name: workspace.name,
ownerId: workspace.ownerId,
description: workspace.description,
logo: workspace.logo,
grade: workspace.grade,
cap: workspace.cap,
currency: workspace.currency,
status: workspace.status,
createdAt: workspace.createdAt,
updatedAt: workspace.updatedAt,
deletedAt: workspace.deletedAt,
channelGroupId: workspace.channelGroupId,
);
WorkspacesCompanion toCompanion() => WorkspacesCompanion(
id: Value(id),
name: Value(name),
ownerId: Value(ownerId),
description: Value(description),
logo: Value(logo),
grade: Value(grade),
cap: Value(cap),
currency: Value(currency),
status: Value(status),
createdAt: Value(createdAt),
updatedAt: Value(updatedAt),
deletedAt: Value(deletedAt),
channelGroupId: Value(channelGroupId),
);
}

View File

@@ -0,0 +1,159 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/api_retry.dart';
import 'package:im_app/domain/repositories/api_retry_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class ApiRetryRepositoryImpl implements ApiRetryRepository {
final StorageSdkApi _storage;
ApiRetryRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
ApiRetry _toEntity(DriftApiRetry row) => ApiRetry(
id: row.id,
uid: row.uid,
apiType: row.apiType,
endPoint: row.endPoint,
requestData: row.requestData,
synced: row.synced,
callbackFun: row.callbackFun,
expired: row.expired,
replace: row.replace,
expireTime: row.expireTime,
createTime: row.createTime,
addIndex: row.addIndex,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
ApiRetriesCompanion _toCompanion(ApiRetry apiRetry) => ApiRetriesCompanion(
// id is autoIncrement — omit if null so DB generates it
id: apiRetry.id != null ? Value(apiRetry.id!) : const Value.absent(),
uid: Value(apiRetry.uid),
apiType: Value(apiRetry.apiType),
endPoint: Value(apiRetry.endPoint),
requestData: Value(apiRetry.requestData),
synced: Value(apiRetry.synced),
callbackFun: Value(apiRetry.callbackFun),
expired: Value(apiRetry.expired),
replace: Value(apiRetry.replace),
expireTime: Value(apiRetry.expireTime),
createTime: Value(apiRetry.createTime),
addIndex: Value(apiRetry.addIndex),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<ApiRetry>> watchAll() {
return _storage.watchAll<DriftApiRetry>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<List<ApiRetry>> watchPending() {
return _storage
.watchWhere<DriftApiRetry, $ApiRetriesTable>((t) => t.synced.equals(0))
.map((rows) => rows.map(_toEntity).toList());
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<ApiRetry>> getAll() async {
final rows = await _storage.selectAll<DriftApiRetry>();
return rows.map(_toEntity).toList();
}
@override
Future<ApiRetry?> getById(int id) async {
final row = await _storage.selectFirst<DriftApiRetry, $ApiRetriesTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<ApiRetry>> getPending() async {
final rows = await _storage.selectWhere<DriftApiRetry, $ApiRetriesTable>(
(t) => t.synced.equals(0),
);
return rows.map(_toEntity).toList();
}
@override
Future<List<ApiRetry>> getActive() async {
final rows = await _storage.selectWhere<DriftApiRetry, $ApiRetriesTable>(
(t) => t.expired.equals(0),
);
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insert(ApiRetry apiRetry) async {
await _storage.insert<DriftApiRetry>(_toCompanion(apiRetry));
}
@override
Future<void> insertOrReplace(ApiRetry apiRetry) async {
await _storage.insertOrReplace<DriftApiRetry>(_toCompanion(apiRetry));
}
@override
Future<void> update(ApiRetry apiRetry) async {
if (apiRetry.id == null) return;
await _storage.updateWhere<DriftApiRetry, $ApiRetriesTable>(
_toCompanion(apiRetry),
(t) => t.id.equals(apiRetry.id!),
);
}
@override
Future<void> markSynced(int id) async {
await _storage.updateWhere<DriftApiRetry, $ApiRetriesTable>(
const ApiRetriesCompanion(synced: Value(1)),
(t) => t.id.equals(id),
);
}
@override
Future<void> markExpired(int id) async {
await _storage.updateWhere<DriftApiRetry, $ApiRetriesTable>(
const ApiRetriesCompanion(expired: Value(1)),
(t) => t.id.equals(id),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<DriftApiRetry, $ApiRetriesTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> deleteByUid(int uid) async {
await _storage.deleteWhere<DriftApiRetry, $ApiRetriesTable>(
(t) => t.uid.equals(uid),
);
}
@override
Future<void> deleteSynced() async {
await _storage.deleteWhere<DriftApiRetry, $ApiRetriesTable>(
(t) => t.synced.equals(1),
);
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftApiRetry>();
}
}

View File

@@ -0,0 +1,118 @@
import 'package:drift/drift.dart';
import 'package:im_app/domain/entities/mini_app.dart';
import 'package:im_app/domain/repositories/mini_app_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
/// 小程序仓储基类
///
/// discover / explore / favorite / recent 四张表共用同一套映射逻辑。
/// 子类只需提供泛型类型参数 + 实现 [toCompanion]。
abstract class BaseMiniAppRepositoryImpl<D, T extends Table>
implements MiniAppRepository {
final StorageSdkApi _storage;
BaseMiniAppRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
MiniApp _toEntity(dynamic row) => MiniApp(
id: row.id as String,
name: row.name as String?,
openuid: row.openuid as String?,
devId: row.devId as String?,
icon: row.icon as String?,
iconGaussian: row.iconGaussian as String?,
downloadUrl: row.downloadUrl as String?,
description: row.description as String?,
version: row.version as int?,
typ: row.typ as int?,
flag: row.flag as int?,
reviewStatus: row.reviewStatus as int?,
favoriteAt: row.favoriteAt as int?,
isActive: row.isActive as int?,
createdAt: row.createdAt as int?,
updatedAt: row.updatedAt as int?,
deletedAt: row.deletedAt as int?,
score: row.score as double?,
channels: row.channels as String?,
devName: row.devName as String?,
pictureGaussian: row.pictureGaussian as String?,
picture: row.picture as String?,
commentNum: row.commentNum as int?,
lastLoginAt: row.lastLoginAt as String?,
screen: row.screen as String?,
);
/// 子类提供对应表的 Companion
Insertable<D> toCompanion(MiniApp miniApp);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<MiniApp>> watchAll() {
return _storage.watchAll<D>().map((rows) => rows.map(_toEntity).toList());
}
@override
Stream<MiniApp?> watch(String id) {
return _storage
.watchFirst<D, T>((t) => (t as dynamic).id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<MiniApp>> getAll() async {
final rows = await _storage.selectAll<D>();
return rows.map(_toEntity).toList();
}
@override
Future<MiniApp?> get(String id) async {
final row = await _storage.selectFirst<D, T>(
(t) => (t as dynamic).id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<bool> isExist(String id) async {
final row = await _storage.selectFirst<D, T>(
(t) => (t as dynamic).id.equals(id),
);
return row != null;
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplace(MiniApp miniApp) async {
await _storage.insertOrReplace<D>(toCompanion(miniApp));
}
@override
Future<void> insertOrReplaceAll(List<MiniApp> miniApps) async {
await _storage.batchInsertOrReplace<D>(miniApps.map(toCompanion).toList());
}
@override
Future<void> update(MiniApp miniApp) async {
await _storage.updateWhere<D, T>(
toCompanion(miniApp),
(t) => (t as dynamic).id.equals(miniApp.id),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(String id) async {
await _storage.deleteWhere<D, T>((t) => (t as dynamic).id.equals(id));
}
@override
Future<void> clear() async {
await _storage.deleteAll<D>();
}
}

View File

@@ -0,0 +1,127 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/chat_category.dart';
import 'package:im_app/domain/repositories/chat_category_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
/// 聊天分类仓储实现
///
/// ## 职责
/// - 所有 DB 操作通过 [StorageSdkApi],不直接接触 AppDatabase
/// - DriftChatCategory ↔ Domain ChatCategory 映射
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在此类
///
/// ## 数据流
/// ```
/// 网络ChatCategory.fromJson(json) → insertOrReplaceChatCategory(chatCategory) → StorageSdkApi → DB
/// 监听StorageSdkApi.watchAll → DriftChatCategory → _toEntity() → UI
/// ```
class ChatCategoryRepositoryImpl implements ChatCategoryRepository {
final StorageSdkApi _storage;
ChatCategoryRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
ChatCategory _toEntity(DriftChatCategory row) => ChatCategory(
id: row.id,
name: row.name,
includedChatIds: row.includedChatIds,
excludedChatIds: row.excludedChatIds,
seq: row.seq,
isHide: row.isHide,
createdAt: row.createdAt,
updatedAt: row.updatedAt,
deletedAt: row.deletedAt,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
ChatCategoriesCompanion _toCompanion(ChatCategory chatCategory) =>
ChatCategoriesCompanion(
id: Value(chatCategory.id),
name: Value(chatCategory.name),
includedChatIds: Value(chatCategory.includedChatIds),
excludedChatIds: Value(chatCategory.excludedChatIds),
seq: Value(chatCategory.seq),
isHide: Value(chatCategory.isHide),
createdAt: Value(chatCategory.createdAt),
updatedAt: Value(chatCategory.updatedAt),
deletedAt: Value(chatCategory.deletedAt),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<ChatCategory>> watchAllChatCategories() {
return _storage.watchAll<DriftChatCategory>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<ChatCategory?> watchChatCategory(int id) {
return _storage
.watchFirst<DriftChatCategory, $ChatCategoriesTable>(
(t) => t.id.equals(id),
)
.map((row) => row != null ? _toEntity(row) : null);
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<ChatCategory>> getChatCategories() async {
final rows = await _storage.selectAll<DriftChatCategory>();
return rows.map(_toEntity).toList();
}
@override
Future<ChatCategory?> getChatCategory(int id) async {
final row = await _storage
.selectFirst<DriftChatCategory, $ChatCategoriesTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplaceChatCategory(ChatCategory chatCategory) async {
await _storage.insertOrReplace<DriftChatCategory>(
_toCompanion(chatCategory),
);
}
@override
Future<void> insertOrReplaceChatCategories(
List<ChatCategory> chatCategories,
) async {
await _storage.batchInsertOrReplace<DriftChatCategory>(
chatCategories.map(_toCompanion).toList(),
);
}
@override
Future<void> updateChatCategory(ChatCategory chatCategory) async {
await _storage.updateWhere<DriftChatCategory, $ChatCategoriesTable>(
_toCompanion(chatCategory),
(t) => t.id.equals(chatCategory.id),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> deleteChatCategory(int id) async {
await _storage.deleteWhere<DriftChatCategory, $ChatCategoriesTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> clearChatCategories() async {
await _storage.deleteAll<DriftChatCategory>();
}
}

View File

@@ -0,0 +1,272 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/chat.dart';
import 'package:im_app/domain/repositories/chat_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
/// 聊天仓储实现
///
/// ## 职责
/// - 所有 DB 操作通过 [StorageSdkApi],不直接接触 AppDatabase
/// - DriftChat ↔ Domain Chat 映射
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在此类
///
/// ## 数据流
/// ```
/// 网络Chat.fromJson(json) → insertOrReplaceChat(chat) → StorageSdkApi → DB
/// 监听StorageSdkApi.watchAll → DriftChat → _toEntity() → UI
/// ```
class ChatRepositoryImpl implements ChatRepository {
final StorageSdkApi _storage;
ChatRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
Chat _toEntity(DriftChat row) => Chat(
id: row.id,
typ: row.typ,
lastId: row.lastId,
lastTyp: row.lastTyp,
lastMsg: row.lastMsg,
lastTime: row.lastTime,
lastPos: row.lastPos,
firstPos: row.firstPos,
msgIdx: row.msgIdx,
profile: row.profile,
pin: row.pin,
icon: row.icon,
iconGaussian: row.iconGaussian,
name: row.name,
userId: row.userId,
chatId: row.chatId,
friendId: row.friendId,
sort: row.sort,
unreadNum: row.unreadNum,
unreadCount: row.unreadCount,
hideChatMsgIdx: row.hideChatMsgIdx,
readChatMsgIdx: row.readChatMsgIdx,
otherReadIdx: row.otherReadIdx,
unreadAtMsgIdx: row.unreadAtMsgIdx,
deleteTime: row.deleteTime,
addIndex: row.addIndex,
flag: row.flag,
flagMy: row.flagMy,
autoDeleteInterval: row.autoDeleteInterval,
mute: row.mute,
verified: row.verified,
createTime: row.createTime,
startIdx: row.startIdx,
isReadMsg: row.isReadMsg,
translateOutgoing: row.translateOutgoing,
translateIncoming: row.translateIncoming,
incomingIdx: row.incomingIdx,
outgoingIdx: row.outgoingIdx,
incomingSoundId: row.incomingSoundId,
outgoingSoundId: row.outgoingSoundId,
notificationSoundId: row.notificationSoundId,
chatKey: row.chatKey,
activeChatKey: row.activeChatKey,
coverIdx: row.coverIdx,
round: row.round,
workspaceId: row.workspaceId,
localPermission: row.localPermission,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
ChatsCompanion _toCompanion(Chat chat) => ChatsCompanion(
id: Value(chat.id),
typ: Value(chat.typ),
lastId: Value(chat.lastId),
lastTyp: Value(chat.lastTyp),
lastMsg: Value(chat.lastMsg),
lastTime: Value(chat.lastTime),
lastPos: Value(chat.lastPos),
firstPos: Value(chat.firstPos),
msgIdx: Value(chat.msgIdx),
profile: Value(chat.profile),
pin: Value(chat.pin),
icon: Value(chat.icon),
iconGaussian: Value(chat.iconGaussian),
name: Value(chat.name),
userId: Value(chat.userId),
chatId: Value(chat.chatId),
friendId: Value(chat.friendId),
sort: Value(chat.sort),
unreadNum: Value(chat.unreadNum),
unreadCount: Value(chat.unreadCount),
hideChatMsgIdx: Value(chat.hideChatMsgIdx),
readChatMsgIdx: Value(chat.readChatMsgIdx),
otherReadIdx: Value(chat.otherReadIdx),
unreadAtMsgIdx: Value(chat.unreadAtMsgIdx),
deleteTime: Value(chat.deleteTime),
addIndex: Value(chat.addIndex),
flag: Value(chat.flag),
flagMy: Value(chat.flagMy),
autoDeleteInterval: Value(chat.autoDeleteInterval),
mute: Value(chat.mute),
verified: Value(chat.verified),
createTime: Value(chat.createTime),
startIdx: Value(chat.startIdx),
isReadMsg: Value(chat.isReadMsg),
translateOutgoing: Value(chat.translateOutgoing),
translateIncoming: Value(chat.translateIncoming),
incomingIdx: Value(chat.incomingIdx),
outgoingIdx: Value(chat.outgoingIdx),
incomingSoundId: Value(chat.incomingSoundId),
outgoingSoundId: Value(chat.outgoingSoundId),
notificationSoundId: Value(chat.notificationSoundId),
chatKey: Value(chat.chatKey),
activeChatKey: Value(chat.activeChatKey),
coverIdx: Value(chat.coverIdx),
round: Value(chat.round),
workspaceId: Value(chat.workspaceId),
localPermission: Value(chat.localPermission),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<Chat>> watchAllChats() {
return _storage.watchAll<DriftChat>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<Chat?> watchChat(int id) {
return _storage
.watchFirst<DriftChat, $ChatsTable>((t) => t.id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<Chat>> getChats() async {
final rows = await _storage.selectAll<DriftChat>();
return rows.map(_toEntity).toList();
}
@override
Future<Chat?> getChat(int id) async {
final row = await _storage.selectFirst<DriftChat, $ChatsTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<Chat>> getChatsPage({
required int offset,
required int limit,
}) async {
final rows = await _storage.rawQuery(
'SELECT * FROM chat ORDER BY id LIMIT ? OFFSET ?',
[limit, offset],
);
return rows
.map(
(row) => Chat(
id: row.read<int>('id'),
typ: row.readNullable<int>('typ'),
lastId: row.readNullable<int>('last_id'),
lastTyp: row.readNullable<int>('last_typ'),
lastMsg: row.readNullable<String>('last_msg'),
lastTime: row.readNullable<int>('last_time'),
lastPos: row.read<int>('last_pos'),
firstPos: row.read<int>('first_pos'),
msgIdx: row.readNullable<int>('msg_idx'),
profile: row.readNullable<String>('profile'),
pin: row.readNullable<String>('pin'),
icon: row.readNullable<String>('icon'),
iconGaussian: row.read<String>('icon_gaussian'),
name: row.readNullable<String>('name'),
userId: row.readNullable<int>('user_id'),
chatId: row.readNullable<int>('chat_id'),
friendId: row.readNullable<int>('friend_id'),
sort: row.readNullable<int>('sort'),
unreadNum: row.readNullable<int>('unread_num'),
unreadCount: row.readNullable<int>('unread_count'),
hideChatMsgIdx: row.readNullable<int>('hide_chat_msg_idx'),
readChatMsgIdx: row.readNullable<int>('read_chat_msg_idx'),
otherReadIdx: row.readNullable<int>('other_read_idx'),
unreadAtMsgIdx: row.readNullable<String>('unread_at_msg_idx'),
deleteTime: row.readNullable<int>('delete_time'),
addIndex: row.readNullable<int>('add_index'),
flag: row.read<int>('flag'),
flagMy: row.readNullable<int>('flag_my'),
autoDeleteInterval: row.readNullable<int>('auto_delete_interval'),
mute: row.readNullable<int>('mute'),
verified: row.readNullable<int>('verified'),
createTime: row.readNullable<int>('create_time'),
startIdx: row.readNullable<int>('start_idx'),
isReadMsg: row.readNullable<int>('is_read_msg'),
translateOutgoing: row.read<String>('translate_outgoing'),
translateIncoming: row.read<String>('translate_incoming'),
incomingIdx: row.read<int>('incoming_idx'),
outgoingIdx: row.read<int>('outgoing_idx'),
incomingSoundId: row.read<int>('incoming_sound_id'),
outgoingSoundId: row.read<int>('outgoing_sound_id'),
notificationSoundId: row.read<int>('notification_sound_id'),
chatKey: row.read<String>('chat_key'),
activeChatKey: row.read<String>('active_chat_key'),
coverIdx: row.read<int>('cover_idx'),
round: row.read<int>('round'),
workspaceId: row.read<int>('workspace_id'),
localPermission: row.read<int>('local_permission'),
),
)
.toList();
}
@override
Future<int> countChats() async {
return _storage.count<DriftChat, $ChatsTable>();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplaceChat(Chat chat) async {
await _storage.insertOrReplace<DriftChat>(_toCompanion(chat));
}
@override
Future<void> insertOrReplaceChats(List<Chat> chats) async {
await _storage.batchInsertOrReplace<DriftChat>(
chats.map(_toCompanion).toList(),
);
}
@override
Future<void> updateChat(Chat chat) async {
await _storage.updateWhere<DriftChat, $ChatsTable>(
_toCompanion(chat),
(t) => t.id.equals(chat.id),
);
}
@override
Future<void> updateChatsBatch(List<Chat> chats) async {
for (final chat in chats) {
await _storage.updateWhere<DriftChat, $ChatsTable>(
_toCompanion(chat),
(t) => t.id.equals(chat.id),
);
}
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> deleteChat(int id) async {
await _storage.deleteWhere<DriftChat, $ChatsTable>((t) => t.id.equals(id));
}
@override
Future<void> clearChats() async {
await _storage.deleteAll<DriftChat>();
}
}

View File

@@ -0,0 +1,43 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/data/repositories/base/base_mini_app_repository_impl.dart';
import 'package:im_app/domain/entities/mini_app.dart';
class DiscoverMiniAppRepositoryImpl
extends
BaseMiniAppRepositoryImpl<
DriftDiscoverMiniApp,
$DiscoverMiniAppsTable
> {
DiscoverMiniAppRepositoryImpl(super.storage);
@override
Insertable<DriftDiscoverMiniApp> toCompanion(MiniApp miniApp) =>
DiscoverMiniAppsCompanion(
id: Value(miniApp.id),
name: Value(miniApp.name),
openuid: Value(miniApp.openuid),
devId: Value(miniApp.devId),
icon: Value(miniApp.icon),
iconGaussian: Value(miniApp.iconGaussian),
downloadUrl: Value(miniApp.downloadUrl),
description: Value(miniApp.description),
version: Value(miniApp.version),
typ: Value(miniApp.typ),
flag: Value(miniApp.flag),
reviewStatus: Value(miniApp.reviewStatus),
favoriteAt: Value(miniApp.favoriteAt),
isActive: Value(miniApp.isActive),
createdAt: Value(miniApp.createdAt),
updatedAt: Value(miniApp.updatedAt),
deletedAt: Value(miniApp.deletedAt),
score: Value(miniApp.score),
channels: Value(miniApp.channels),
devName: Value(miniApp.devName),
pictureGaussian: Value(miniApp.pictureGaussian),
picture: Value(miniApp.picture),
commentNum: Value(miniApp.commentNum),
lastLoginAt: Value(miniApp.lastLoginAt),
screen: Value(miniApp.screen),
);
}

View File

@@ -0,0 +1,40 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/data/repositories/base/base_mini_app_repository_impl.dart';
import 'package:im_app/domain/entities/mini_app.dart';
class ExploreMiniAppRepositoryImpl
extends
BaseMiniAppRepositoryImpl<DriftExploreMiniApp, $ExploreMiniAppsTable> {
ExploreMiniAppRepositoryImpl(super.storage);
@override
Insertable<DriftExploreMiniApp> toCompanion(MiniApp miniApp) =>
ExploreMiniAppsCompanion(
id: Value(miniApp.id),
name: Value(miniApp.name),
openuid: Value(miniApp.openuid),
devId: Value(miniApp.devId),
icon: Value(miniApp.icon),
iconGaussian: Value(miniApp.iconGaussian),
downloadUrl: Value(miniApp.downloadUrl),
description: Value(miniApp.description),
version: Value(miniApp.version),
typ: Value(miniApp.typ),
flag: Value(miniApp.flag),
reviewStatus: Value(miniApp.reviewStatus),
favoriteAt: Value(miniApp.favoriteAt),
isActive: Value(miniApp.isActive),
createdAt: Value(miniApp.createdAt),
updatedAt: Value(miniApp.updatedAt),
deletedAt: Value(miniApp.deletedAt),
score: Value(miniApp.score),
channels: Value(miniApp.channels),
devName: Value(miniApp.devName),
pictureGaussian: Value(miniApp.pictureGaussian),
picture: Value(miniApp.picture),
commentNum: Value(miniApp.commentNum),
lastLoginAt: Value(miniApp.lastLoginAt),
screen: Value(miniApp.screen),
);
}

View File

@@ -0,0 +1,139 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/favorite_detail.dart';
import 'package:im_app/domain/repositories/favorite_detail_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
/// 收藏详情仓储实现
///
/// ## 注意
/// - id 为 autoIncrement — insert 时不传 id由 DB 自动生成
/// - insertOrReplace 时若 id 为 null 则作为新增处理
class FavoriteDetailRepositoryImpl implements FavoriteDetailRepository {
final StorageSdkApi _storage;
FavoriteDetailRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
FavoriteDetail _toEntity(DriftFavoriteDetail row) => FavoriteDetail(
id: row.id,
relatedId: row.relatedId,
content: row.content,
typ: row.typ,
messageId: row.messageId,
sendId: row.sendId,
chatId: row.chatId,
sendTime: row.sendTime,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
FavoriteDetailsCompanion _toCompanion(FavoriteDetail detail) =>
FavoriteDetailsCompanion(
// id is autoIncrement — omit if null so DB generates it
id: detail.id != null ? Value(detail.id!) : const Value.absent(),
relatedId: Value(detail.relatedId),
content: Value(detail.content),
typ: Value(detail.typ),
messageId: Value(detail.messageId),
sendId: Value(detail.sendId),
chatId: Value(detail.chatId),
sendTime: Value(detail.sendTime),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<FavoriteDetail>> watchAll() {
return _storage.watchAll<DriftFavoriteDetail>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<List<FavoriteDetail>> watchByRelatedId(String relatedId) {
return _storage
.watchWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
(t) => t.relatedId.equals(relatedId),
)
.map((rows) => rows.map(_toEntity).toList());
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<FavoriteDetail>> getAll() async {
final rows = await _storage.selectAll<DriftFavoriteDetail>();
return rows.map(_toEntity).toList();
}
@override
Future<FavoriteDetail?> getById(int id) async {
final row = await _storage
.selectFirst<DriftFavoriteDetail, $FavoriteDetailsTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<FavoriteDetail>> getByRelatedId(String relatedId) async {
final rows = await _storage
.selectWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
(t) => t.relatedId.equals(relatedId),
);
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insert(FavoriteDetail favoriteDetail) async {
await _storage.insert<DriftFavoriteDetail>(_toCompanion(favoriteDetail));
}
@override
Future<void> insertAll(List<FavoriteDetail> favoriteDetails) async {
for (final detail in favoriteDetails) {
await _storage.insert<DriftFavoriteDetail>(_toCompanion(detail));
}
}
@override
Future<void> insertOrReplace(FavoriteDetail favoriteDetail) async {
await _storage.insertOrReplace<DriftFavoriteDetail>(
_toCompanion(favoriteDetail),
);
}
@override
Future<void> update(FavoriteDetail favoriteDetail) async {
if (favoriteDetail.id == null) return;
await _storage.updateWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
_toCompanion(favoriteDetail),
(t) => t.id.equals(favoriteDetail.id!),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> deleteByRelatedId(String relatedId) async {
await _storage.deleteWhere<DriftFavoriteDetail, $FavoriteDetailsTable>(
(t) => t.relatedId.equals(relatedId),
);
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftFavoriteDetail>();
}
}

View File

@@ -0,0 +1,43 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/data/repositories/base/base_mini_app_repository_impl.dart';
import 'package:im_app/domain/entities/mini_app.dart';
class FavoriteMiniAppRepositoryImpl
extends
BaseMiniAppRepositoryImpl<
DriftFavoriteMiniApp,
$FavoriteMiniAppsTable
> {
FavoriteMiniAppRepositoryImpl(super.storage);
@override
Insertable<DriftFavoriteMiniApp> toCompanion(MiniApp miniApp) =>
FavoriteMiniAppsCompanion(
id: Value(miniApp.id),
name: Value(miniApp.name),
openuid: Value(miniApp.openuid),
devId: Value(miniApp.devId),
icon: Value(miniApp.icon),
iconGaussian: Value(miniApp.iconGaussian),
downloadUrl: Value(miniApp.downloadUrl),
description: Value(miniApp.description),
version: Value(miniApp.version),
typ: Value(miniApp.typ),
flag: Value(miniApp.flag),
reviewStatus: Value(miniApp.reviewStatus),
favoriteAt: Value(miniApp.favoriteAt),
isActive: Value(miniApp.isActive),
createdAt: Value(miniApp.createdAt),
updatedAt: Value(miniApp.updatedAt),
deletedAt: Value(miniApp.deletedAt),
score: Value(miniApp.score),
channels: Value(miniApp.channels),
devName: Value(miniApp.devName),
pictureGaussian: Value(miniApp.pictureGaussian),
picture: Value(miniApp.picture),
commentNum: Value(miniApp.commentNum),
lastLoginAt: Value(miniApp.lastLoginAt),
screen: Value(miniApp.screen),
);
}

View File

@@ -0,0 +1,151 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/favorite.dart';
import 'package:im_app/domain/repositories/favorite_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class FavoriteRepositoryImpl implements FavoriteRepository {
final StorageSdkApi _storage;
FavoriteRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
Favorite _toEntity(DriftFavorite row) => Favorite(
id: row.id,
parentId: row.parentId,
data: row.data,
createdAt: row.createdAt,
updatedAt: row.updatedAt,
deletedAt: row.deletedAt,
source: row.source,
userId: row.userId,
authorId: row.authorId,
typ: row.typ,
tag: row.tag,
isPin: row.isPin,
chatTyp: row.chatTyp,
isUploaded: row.isUploaded,
urls: row.urls,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
FavoritesCompanion _toCompanion(Favorite favorite) => FavoritesCompanion(
id: Value(favorite.id),
parentId: Value(favorite.parentId),
data: Value(favorite.data),
createdAt: Value(favorite.createdAt),
updatedAt: Value(favorite.updatedAt),
deletedAt: Value(favorite.deletedAt),
source: Value(favorite.source),
userId: Value(favorite.userId),
authorId: Value(favorite.authorId),
typ: Value(favorite.typ),
tag: Value(favorite.tag),
isPin: Value(favorite.isPin),
chatTyp: Value(favorite.chatTyp),
isUploaded: Value(favorite.isUploaded),
urls: Value(favorite.urls),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<Favorite>> watchAll() {
return _storage.watchAll<DriftFavorite>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<Favorite?> watchById(int id) {
return _storage
.watchFirst<DriftFavorite, $FavoritesTable>((t) => t.id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
@override
Stream<List<Favorite>> watchByParentId(String parentId) {
return _storage
.watchWhere<DriftFavorite, $FavoritesTable>(
(t) => t.parentId.equals(parentId),
)
.map((rows) => rows.map(_toEntity).toList());
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<Favorite>> getAll() async {
final rows = await _storage.selectAll<DriftFavorite>();
return rows.map(_toEntity).toList();
}
@override
Future<Favorite?> getById(int id) async {
final row = await _storage.selectFirst<DriftFavorite, $FavoritesTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<Favorite>> getByParentId(String parentId) async {
final rows = await _storage.selectWhere<DriftFavorite, $FavoritesTable>(
(t) => t.parentId.equals(parentId),
);
return rows.map(_toEntity).toList();
}
@override
Future<List<Favorite>> getUnuploaded() async {
final rows = await _storage.selectWhere<DriftFavorite, $FavoritesTable>(
(t) => t.isUploaded.equals(0),
);
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplace(Favorite favorite) async {
await _storage.insertOrReplace<DriftFavorite>(_toCompanion(favorite));
}
@override
Future<void> insertOrReplaceAll(List<Favorite> favorites) async {
await _storage.batchInsertOrReplace<DriftFavorite>(
favorites.map(_toCompanion).toList(),
);
}
@override
Future<void> update(Favorite favorite) async {
await _storage.updateWhere<DriftFavorite, $FavoritesTable>(
_toCompanion(favorite),
(t) => t.id.equals(favorite.id),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<DriftFavorite, $FavoritesTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> deleteByParentId(String parentId) async {
await _storage.deleteWhere<DriftFavorite, $FavoritesTable>(
(t) => t.parentId.equals(parentId),
);
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftFavorite>();
}
}

View File

@@ -0,0 +1,163 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/group.dart';
import 'package:im_app/domain/repositories/group_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class GroupRepositoryImpl implements GroupRepository {
final StorageSdkApi _storage;
GroupRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
Group _toEntity(DriftGroup row) => Group(
id: row.id,
userJoinDate: row.userJoinDate,
name: row.name,
profile: row.profile,
icon: row.icon,
iconGaussian: row.iconGaussian,
permission: row.permission,
admin: row.admin,
members: row.members,
owner: row.owner,
admins: row.admins,
visible: row.visible,
speakInterval: row.speakInterval,
groupType: row.groupType,
roomType: row.roomType,
maxNumber: row.maxNumber,
channelId: row.channelId,
channelGroupId: row.channelGroupId,
createTime: row.createTime,
updateTime: row.updateTime,
addIndex: row.addIndex,
maxMember: row.maxMember,
expireTime: row.expireTime,
workspaceId: row.workspaceId,
mode: row.mode,
redpacketPlay: row.redpacketPlay,
topic: row.topic,
rp: row.rp,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
GroupsCompanion _toCompanion(Group group) => GroupsCompanion(
id: Value(group.id),
userJoinDate: Value(group.userJoinDate),
name: Value(group.name),
profile: Value(group.profile),
icon: Value(group.icon),
iconGaussian: Value(group.iconGaussian),
permission: Value(group.permission),
admin: Value(group.admin),
members: Value(group.members),
owner: Value(group.owner),
admins: Value(group.admins),
visible: Value(group.visible),
speakInterval: Value(group.speakInterval),
groupType: Value(group.groupType),
roomType: Value(group.roomType),
maxNumber: Value(group.maxNumber),
channelId: Value(group.channelId),
channelGroupId: Value(group.channelGroupId),
createTime: Value(group.createTime),
updateTime: Value(group.updateTime),
addIndex: Value(group.addIndex),
maxMember: Value(group.maxMember),
expireTime: Value(group.expireTime),
workspaceId: Value(group.workspaceId),
mode: Value(group.mode),
redpacketPlay: Value(group.redpacketPlay),
topic: Value(group.topic),
rp: Value(group.rp),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<Group>> watchAll() {
return _storage.watchAll<DriftGroup>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<Group?> watchById(int id) {
return _storage
.watchFirst<DriftGroup, $GroupsTable>((t) => t.id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<Group>> getAll() async {
final rows = await _storage.selectAll<DriftGroup>();
return rows.map(_toEntity).toList();
}
@override
Future<Group?> getById(int id) async {
final row = await _storage.selectFirst<DriftGroup, $GroupsTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<Group>> getByWorkspace(int workspaceId) async {
final rows = await _storage.selectWhere<DriftGroup, $GroupsTable>(
(t) => t.workspaceId.equals(workspaceId),
);
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplace(Group group) async {
await _storage.insertOrReplace<DriftGroup>(_toCompanion(group));
}
@override
Future<void> insertOrReplaceAll(List<Group> groups) async {
await _storage.batchInsertOrReplace<DriftGroup>(
groups.map(_toCompanion).toList(),
);
}
@override
Future<void> update(Group group) async {
await _storage.updateWhere<DriftGroup, $GroupsTable>(
_toCompanion(group),
(t) => t.id.equals(group.id),
);
}
@override
Future<void> updateBatch(List<Group> groups) async {
for (final group in groups) {
await _storage.updateWhere<DriftGroup, $GroupsTable>(
_toCompanion(group),
(t) => t.id.equals(group.id),
);
}
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<DriftGroup, $GroupsTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftGroup>();
}
}

View File

@@ -0,0 +1,203 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/message.dart';
import 'package:im_app/domain/repositories/message_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class MessageRepositoryImpl implements MessageRepository {
final StorageSdkApi _storage;
MessageRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
Message _toEntity(DriftMessage row) => Message(
id: row.id,
messageId: row.messageId,
chatId: row.chatId,
chatIdx: row.chatIdx,
sendId: row.sendId,
content: row.content,
typ: row.typ,
sendTime: row.sendTime,
expireTime: row.expireTime,
createTime: row.createTime,
atUsers: row.atUsers,
emojis: row.emojis,
editTime: row.editTime,
refTyp: row.refTyp,
flag: row.flag,
cmid: row.cmid,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
MessagesCompanion _toCompanion(Message message) => MessagesCompanion(
id: Value(message.id),
messageId: Value(message.messageId),
chatId: Value(message.chatId),
chatIdx: Value(message.chatIdx),
sendId: Value(message.sendId),
content: Value(message.content),
typ: Value(message.typ),
sendTime: Value(message.sendTime),
expireTime: Value(message.expireTime),
createTime: Value(message.createTime),
atUsers: Value(message.atUsers),
emojis: Value(message.emojis),
editTime: Value(message.editTime),
refTyp: Value(message.refTyp),
flag: Value(message.flag),
cmid: Value(message.cmid),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<Message>> watchByChatId(int chatId) {
return _storage
.watchWhere<DriftMessage, $MessagesTable>(
(t) => t.chatId.equals(chatId),
)
.map((rows) => rows.map(_toEntity).toList());
}
@override
Stream<Message?> watchById(int id) {
return _storage
.watchFirst<DriftMessage, $MessagesTable>((t) => t.id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<Message>> getByChatId(int chatId) async {
final rows = await _storage.rawQuery(
'SELECT * FROM message WHERE chat_id = ? ORDER BY chat_idx ASC',
[chatId],
);
return rows
.map(
(row) => Message(
id: row.read<int>('id'),
messageId: row.readNullable<int>('message_id'),
chatId: row.readNullable<int>('chat_id'),
chatIdx: row.readNullable<int>('chat_idx'),
sendId: row.readNullable<int>('send_id'),
content: row.readNullable<String>('content'),
typ: row.readNullable<int>('typ'),
sendTime: row.readNullable<int>('send_time'),
expireTime: row.readNullable<int>('expire_time'),
createTime: row.readNullable<int>('create_time'),
atUsers: row.readNullable<String>('at_users'),
emojis: row.read<String>('emojis'),
editTime: row.read<int>('edit_time'),
refTyp: row.read<int>('ref_typ'),
flag: row.read<int>('flag'),
cmid: row.read<String>('cmid'),
),
)
.toList();
}
@override
Future<List<Message>> getByChatIdPage({
required int chatId,
required int offset,
required int limit,
}) async {
final rows = await _storage.rawQuery(
'SELECT * FROM message WHERE chat_id = ? ORDER BY chat_idx ASC LIMIT ? OFFSET ?',
[chatId, limit, offset],
);
return rows
.map(
(row) => Message(
id: row.read<int>('id'),
messageId: row.readNullable<int>('message_id'),
chatId: row.readNullable<int>('chat_id'),
chatIdx: row.readNullable<int>('chat_idx'),
sendId: row.readNullable<int>('send_id'),
content: row.readNullable<String>('content'),
typ: row.readNullable<int>('typ'),
sendTime: row.readNullable<int>('send_time'),
expireTime: row.readNullable<int>('expire_time'),
createTime: row.readNullable<int>('create_time'),
atUsers: row.readNullable<String>('at_users'),
emojis: row.read<String>('emojis'),
editTime: row.read<int>('edit_time'),
refTyp: row.read<int>('ref_typ'),
flag: row.read<int>('flag'),
cmid: row.read<String>('cmid'),
),
)
.toList();
}
@override
Future<Message?> getById(int id) async {
final row = await _storage.selectFirst<DriftMessage, $MessagesTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<Message?> getByMessageId(int messageId) async {
final row = await _storage.selectFirst<DriftMessage, $MessagesTable>(
(t) => t.messageId.equals(messageId),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<int> countByChatId(int chatId) async {
return _storage.count<DriftMessage, $MessagesTable>(
filter: (t) => t.chatId.equals(chatId),
);
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplace(Message message) async {
await _storage.insertOrReplace<DriftMessage>(_toCompanion(message));
}
@override
Future<void> insertOrReplaceAll(List<Message> messages) async {
await _storage.batchInsertOrReplace<DriftMessage>(
messages.map(_toCompanion).toList(),
);
}
@override
Future<void> update(Message message) async {
await _storage.updateWhere<DriftMessage, $MessagesTable>(
_toCompanion(message),
(t) => t.id.equals(message.id),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<DriftMessage, $MessagesTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> deleteByChatId(int chatId) async {
await _storage.deleteWhere<DriftMessage, $MessagesTable>(
(t) => t.chatId.equals(chatId),
);
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftMessage>();
}
}

View File

@@ -0,0 +1,143 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/pending_friend_request_history.dart';
import 'package:im_app/domain/repositories/pending_friend_request_history_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class PendingFriendRequestHistoryRepositoryImpl
implements PendingFriendRequestHistoryRepository {
final StorageSdkApi _storage;
PendingFriendRequestHistoryRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
PendingFriendRequestHistory _toEntity(DriftPendingFriendRequestHistory row) =>
PendingFriendRequestHistory(
id: row.id,
uid: row.uid,
requestTime: row.requestTime,
remarks: row.remarks,
source: row.source,
rs: row.rs,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
PendingFriendRequestHistoriesCompanion _toCompanion(
PendingFriendRequestHistory history,
) => PendingFriendRequestHistoriesCompanion(
id: Value(history.id),
uid: Value(history.uid),
requestTime: Value(history.requestTime),
remarks: Value(history.remarks),
source: Value(history.source),
rs: Value(history.rs),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<PendingFriendRequestHistory>> watchAll() {
return _storage.watchAll<DriftPendingFriendRequestHistory>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<PendingFriendRequestHistory?> watchById(int id) {
return _storage
.watchFirst<
DriftPendingFriendRequestHistory,
$PendingFriendRequestHistoriesTable
>((t) => t.id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
@override
Stream<List<PendingFriendRequestHistory>> watchByUid(int uid) {
return _storage
.watchWhere<
DriftPendingFriendRequestHistory,
$PendingFriendRequestHistoriesTable
>((t) => t.uid.equals(uid))
.map((rows) => rows.map(_toEntity).toList());
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<PendingFriendRequestHistory>> getAll() async {
final rows = await _storage.selectAll<DriftPendingFriendRequestHistory>();
return rows.map(_toEntity).toList();
}
@override
Future<PendingFriendRequestHistory?> getById(int id) async {
final row = await _storage
.selectFirst<
DriftPendingFriendRequestHistory,
$PendingFriendRequestHistoriesTable
>((t) => t.id.equals(id));
return row != null ? _toEntity(row) : null;
}
@override
Future<List<PendingFriendRequestHistory>> getByUid(int uid) async {
final rows = await _storage
.selectWhere<
DriftPendingFriendRequestHistory,
$PendingFriendRequestHistoriesTable
>((t) => t.uid.equals(uid));
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplace(PendingFriendRequestHistory history) async {
await _storage.insertOrReplace<DriftPendingFriendRequestHistory>(
_toCompanion(history),
);
}
@override
Future<void> insertOrReplaceAll(
List<PendingFriendRequestHistory> histories,
) async {
await _storage.batchInsertOrReplace<DriftPendingFriendRequestHistory>(
histories.map(_toCompanion).toList(),
);
}
@override
Future<void> update(PendingFriendRequestHistory history) async {
await _storage.updateWhere<
DriftPendingFriendRequestHistory,
$PendingFriendRequestHistoriesTable
>(_toCompanion(history), (t) => t.id.equals(history.id));
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<
DriftPendingFriendRequestHistory,
$PendingFriendRequestHistoriesTable
>((t) => t.id.equals(id));
}
@override
Future<void> deleteByUid(int uid) async {
await _storage.deleteWhere<
DriftPendingFriendRequestHistory,
$PendingFriendRequestHistoriesTable
>((t) => t.uid.equals(uid));
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftPendingFriendRequestHistory>();
}
}

View File

@@ -0,0 +1,40 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/data/repositories/base/base_mini_app_repository_impl.dart';
import 'package:im_app/domain/entities/mini_app.dart';
class RecentMiniAppRepositoryImpl
extends
BaseMiniAppRepositoryImpl<DriftRecentMiniApp, $RecentMiniAppsTable> {
RecentMiniAppRepositoryImpl(super.storage);
@override
Insertable<DriftRecentMiniApp> toCompanion(MiniApp miniApp) =>
RecentMiniAppsCompanion(
id: Value(miniApp.id),
name: Value(miniApp.name),
openuid: Value(miniApp.openuid),
devId: Value(miniApp.devId),
icon: Value(miniApp.icon),
iconGaussian: Value(miniApp.iconGaussian),
downloadUrl: Value(miniApp.downloadUrl),
description: Value(miniApp.description),
version: Value(miniApp.version),
typ: Value(miniApp.typ),
flag: Value(miniApp.flag),
reviewStatus: Value(miniApp.reviewStatus),
favoriteAt: Value(miniApp.favoriteAt),
isActive: Value(miniApp.isActive),
createdAt: Value(miniApp.createdAt),
updatedAt: Value(miniApp.updatedAt),
deletedAt: Value(miniApp.deletedAt),
score: Value(miniApp.score),
channels: Value(miniApp.channels),
devName: Value(miniApp.devName),
pictureGaussian: Value(miniApp.pictureGaussian),
picture: Value(miniApp.picture),
commentNum: Value(miniApp.commentNum),
lastLoginAt: Value(miniApp.lastLoginAt),
screen: Value(miniApp.screen),
);
}

View File

@@ -0,0 +1,138 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/sound.dart';
import 'package:im_app/domain/repositories/sound_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class SoundRepositoryImpl implements SoundRepository {
final StorageSdkApi _storage;
SoundRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
Sound _toEntity(DriftSound row) => Sound(
id: row.id,
filePath: row.filePath,
typ: row.typ,
name: row.name,
createdAt: row.createdAt,
updatedAt: row.updatedAt,
deletedAt: row.deletedAt,
channelGroupId: row.channelGroupId,
isDefault: row.isDefault,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
SoundsCompanion _toCompanion(Sound sound) => SoundsCompanion(
id: Value(sound.id),
filePath: Value(sound.filePath),
typ: Value(sound.typ),
name: Value(sound.name),
createdAt: Value(sound.createdAt),
updatedAt: Value(sound.updatedAt),
deletedAt: Value(sound.deletedAt),
channelGroupId: Value(sound.channelGroupId),
isDefault: Value(sound.isDefault),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<Sound>> watchAll() {
return _storage.watchAll<DriftSound>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<Sound?> watchById(int id) {
return _storage
.watchFirst<DriftSound, $SoundsTable>((t) => t.id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
@override
Stream<List<Sound>> watchByType(int typ) {
return _storage
.watchWhere<DriftSound, $SoundsTable>((t) => t.typ.equals(typ))
.map((rows) => rows.map(_toEntity).toList());
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<Sound>> getAll() async {
final rows = await _storage.selectAll<DriftSound>();
return rows.map(_toEntity).toList();
}
@override
Future<Sound?> getById(int id) async {
final row = await _storage.selectFirst<DriftSound, $SoundsTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<Sound>> getByType(int typ) async {
final rows = await _storage.selectWhere<DriftSound, $SoundsTable>(
(t) => t.typ.equals(typ),
);
return rows.map(_toEntity).toList();
}
@override
Future<List<Sound>> getByChannelGroup(int channelGroupId) async {
final rows = await _storage.selectWhere<DriftSound, $SoundsTable>(
(t) => t.channelGroupId.equals(channelGroupId),
);
return rows.map(_toEntity).toList();
}
@override
Future<List<Sound>> getDefaults() async {
final rows = await _storage.selectWhere<DriftSound, $SoundsTable>(
(t) => t.isDefault.equals(1),
);
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplace(Sound sound) async {
await _storage.insertOrReplace<DriftSound>(_toCompanion(sound));
}
@override
Future<void> insertOrReplaceAll(List<Sound> sounds) async {
await _storage.batchInsertOrReplace<DriftSound>(
sounds.map(_toCompanion).toList(),
);
}
@override
Future<void> update(Sound sound) async {
await _storage.updateWhere<DriftSound, $SoundsTable>(
_toCompanion(sound),
(t) => t.id.equals(sound.id),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<DriftSound, $SoundsTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftSound>();
}
}

View File

@@ -0,0 +1,142 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/tag.dart';
import 'package:im_app/domain/repositories/tag_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class TagRepositoryImpl implements TagRepository {
final StorageSdkApi _storage;
TagRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
Tag _toEntity(DriftTag row) => Tag(
id: row.id,
uid: row.uid,
name: row.name,
type: row.type,
createdAt: row.createdAt,
updatedAt: row.updatedAt,
addIndex: row.addIndex,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
TagsCompanion _toCompanion(Tag tag) => TagsCompanion(
id: tag.id != null ? Value(tag.id!) : const Value.absent(),
uid: Value(tag.uid),
name: Value(tag.name),
type: Value(tag.type),
createdAt: Value(tag.createdAt),
updatedAt: Value(tag.updatedAt),
addIndex: Value(tag.addIndex),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<Tag>> watchAll() {
return _storage.watchAll<DriftTag>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<Tag?> watchById(int id) {
return _storage
.watchFirst<DriftTag, $TagsTable>((t) => t.id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
@override
Stream<List<Tag>> watchByUid(int uid) {
return _storage
.watchWhere<DriftTag, $TagsTable>((t) => t.uid.equals(uid))
.map((rows) => rows.map(_toEntity).toList());
}
@override
Stream<List<Tag>> watchByType(int type) {
return _storage
.watchWhere<DriftTag, $TagsTable>((t) => t.type.equals(type))
.map((rows) => rows.map(_toEntity).toList());
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<Tag>> getAll() async {
final rows = await _storage.selectAll<DriftTag>();
return rows.map(_toEntity).toList();
}
@override
Future<Tag?> getById(int id) async {
final row = await _storage.selectFirst<DriftTag, $TagsTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<Tag>> getByUid(int uid) async {
final rows = await _storage.selectWhere<DriftTag, $TagsTable>(
(t) => t.uid.equals(uid),
);
return rows.map(_toEntity).toList();
}
@override
Future<List<Tag>> getByType(int type) async {
final rows = await _storage.selectWhere<DriftTag, $TagsTable>(
(t) => t.type.equals(type),
);
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insert(Tag tag) async {
await _storage.insert<DriftTag>(_toCompanion(tag));
}
@override
Future<void> insertOrReplace(Tag tag) async {
await _storage.insertOrReplace<DriftTag>(_toCompanion(tag));
}
@override
Future<void> insertOrReplaceAll(List<Tag> tags) async {
await _storage.batchInsertOrReplace<DriftTag>(
tags.map(_toCompanion).toList(),
);
}
@override
Future<void> update(Tag tag) async {
if (tag.id == null) return;
await _storage.updateWhere<DriftTag, $TagsTable>(
_toCompanion(tag),
(t) => t.id.equals(tag.id!),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<DriftTag, $TagsTable>((t) => t.id.equals(id));
}
@override
Future<void> deleteByUid(int uid) async {
await _storage.deleteWhere<DriftTag, $TagsTable>((t) => t.uid.equals(uid));
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftTag>();
}
}

View File

@@ -0,0 +1,122 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/user_request_history.dart';
import 'package:im_app/domain/repositories/user_request_history_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class UserRequestHistoryRepositoryImpl implements UserRequestHistoryRepository {
final StorageSdkApi _storage;
UserRequestHistoryRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
UserRequestHistory _toEntity(DriftUserRequestHistory row) =>
UserRequestHistory(
id: row.id,
status: row.status,
createdAt: row.createdAt,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
UserRequestHistoriesCompanion _toCompanion(UserRequestHistory history) =>
UserRequestHistoriesCompanion(
id: Value(history.id),
status: Value(history.status),
createdAt: Value(history.createdAt),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<UserRequestHistory>> watchAll() {
return _storage.watchAll<DriftUserRequestHistory>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<UserRequestHistory?> watchById(int id) {
return _storage
.watchFirst<DriftUserRequestHistory, $UserRequestHistoriesTable>(
(t) => t.id.equals(id),
)
.map((row) => row != null ? _toEntity(row) : null);
}
@override
Stream<List<UserRequestHistory>> watchByStatus(int status) {
return _storage
.watchWhere<DriftUserRequestHistory, $UserRequestHistoriesTable>(
(t) => t.status.equals(status),
)
.map((rows) => rows.map(_toEntity).toList());
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<UserRequestHistory>> getAll() async {
final rows = await _storage.selectAll<DriftUserRequestHistory>();
return rows.map(_toEntity).toList();
}
@override
Future<UserRequestHistory?> getById(int id) async {
final row = await _storage
.selectFirst<DriftUserRequestHistory, $UserRequestHistoriesTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<UserRequestHistory>> getByStatus(int status) async {
final rows = await _storage
.selectWhere<DriftUserRequestHistory, $UserRequestHistoriesTable>(
(t) => t.status.equals(status),
);
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplace(UserRequestHistory history) async {
await _storage.insertOrReplace<DriftUserRequestHistory>(
_toCompanion(history),
);
}
@override
Future<void> insertOrReplaceAll(List<UserRequestHistory> histories) async {
await _storage.batchInsertOrReplace<DriftUserRequestHistory>(
histories.map(_toCompanion).toList(),
);
}
@override
Future<void> update(UserRequestHistory history) async {
await _storage
.updateWhere<DriftUserRequestHistory, $UserRequestHistoriesTable>(
_toCompanion(history),
(t) => t.id.equals(history.id),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage
.deleteWhere<DriftUserRequestHistory, $UserRequestHistoriesTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftUserRequestHistory>();
}
}

View File

@@ -0,0 +1,123 @@
import 'package:drift/drift.dart';
import 'package:im_app/data/local/drift/app_database.dart';
import 'package:im_app/domain/entities/workspace.dart';
import 'package:im_app/domain/repositories/workspace_repository.dart';
import 'package:storage_sdk/storage_sdk.dart';
class WorkspaceRepositoryImpl implements WorkspaceRepository {
final StorageSdkApi _storage;
WorkspaceRepositoryImpl(this._storage);
// ── DB row → Domain ──────────────────────────────────────────────────────
Workspace _toEntity(DriftWorkspace row) => Workspace(
id: row.id,
name: row.name,
ownerId: row.ownerId,
description: row.description,
logo: row.logo,
grade: row.grade,
cap: row.cap,
currency: row.currency,
status: row.status,
createdAt: row.createdAt,
updatedAt: row.updatedAt,
deletedAt: row.deletedAt,
channelGroupId: row.channelGroupId,
);
// ── Domain → DB companion (internal only) ────────────────────────────────
WorkspacesCompanion _toCompanion(Workspace workspace) => WorkspacesCompanion(
id: Value(workspace.id),
name: Value(workspace.name),
ownerId: Value(workspace.ownerId),
description: Value(workspace.description),
logo: Value(workspace.logo),
grade: Value(workspace.grade),
cap: Value(workspace.cap),
currency: Value(workspace.currency),
status: Value(workspace.status),
createdAt: Value(workspace.createdAt),
updatedAt: Value(workspace.updatedAt),
deletedAt: Value(workspace.deletedAt),
channelGroupId: Value(workspace.channelGroupId),
);
// ── 监听 ─────────────────────────────────────────────────────────────────
@override
Stream<List<Workspace>> watchAll() {
return _storage.watchAll<DriftWorkspace>().map(
(rows) => rows.map(_toEntity).toList(),
);
}
@override
Stream<Workspace?> watchById(int id) {
return _storage
.watchFirst<DriftWorkspace, $WorkspacesTable>((t) => t.id.equals(id))
.map((row) => row != null ? _toEntity(row) : null);
}
// ── 读取 ─────────────────────────────────────────────────────────────────
@override
Future<List<Workspace>> getAll() async {
final rows = await _storage.selectAll<DriftWorkspace>();
return rows.map(_toEntity).toList();
}
@override
Future<Workspace?> getById(int id) async {
final row = await _storage.selectFirst<DriftWorkspace, $WorkspacesTable>(
(t) => t.id.equals(id),
);
return row != null ? _toEntity(row) : null;
}
@override
Future<List<Workspace>> getByOwner(int ownerId) async {
final rows = await _storage.selectWhere<DriftWorkspace, $WorkspacesTable>(
(t) => t.ownerId.equals(ownerId),
);
return rows.map(_toEntity).toList();
}
// ── 写入 ─────────────────────────────────────────────────────────────────
@override
Future<void> insertOrReplace(Workspace workspace) async {
await _storage.insertOrReplace<DriftWorkspace>(_toCompanion(workspace));
}
@override
Future<void> insertOrReplaceAll(List<Workspace> workspaces) async {
await _storage.batchInsertOrReplace<DriftWorkspace>(
workspaces.map(_toCompanion).toList(),
);
}
@override
Future<void> update(Workspace workspace) async {
await _storage.updateWhere<DriftWorkspace, $WorkspacesTable>(
_toCompanion(workspace),
(t) => t.id.equals(workspace.id),
);
}
// ── 删除 ─────────────────────────────────────────────────────────────────
@override
Future<void> delete(int id) async {
await _storage.deleteWhere<DriftWorkspace, $WorkspacesTable>(
(t) => t.id.equals(id),
);
}
@override
Future<void> clear() async {
await _storage.deleteAll<DriftWorkspace>();
}
}

View File

@@ -1,5 +1,5 @@
/// Domain /// Domain
class Retry { class ApiRetry {
final int? id; final int? id;
final int? uid; final int? uid;
final String apiType; final String apiType;
@@ -13,7 +13,7 @@ class Retry {
final int? createTime; final int? createTime;
final int? addIndex; final int? addIndex;
const Retry({ const ApiRetry({
this.id, this.id,
this.uid, this.uid,
this.apiType = '', this.apiType = '',
@@ -28,7 +28,7 @@ class Retry {
this.addIndex, this.addIndex,
}); });
Retry copyWith({ ApiRetry copyWith({
int? id, int? id,
int? uid, int? uid,
String? apiType, String? apiType,
@@ -42,7 +42,7 @@ class Retry {
int? createTime, int? createTime,
int? addIndex, int? addIndex,
}) { }) {
return Retry( return ApiRetry(
id: id ?? this.id, id: id ?? this.id,
uid: uid ?? this.uid, uid: uid ?? this.uid,
apiType: apiType ?? this.apiType, apiType: apiType ?? this.apiType,

View File

@@ -1,112 +1,31 @@
/// 发现小程序 Domain 实体 import 'package:im_app/domain/entities/mini_app.dart';
class DiscoverMiniApp {
final String id;
final String? name;
final String? openuid;
final String? devId;
final String? icon;
final String? iconGaussian;
final String? downloadUrl;
final String? description;
final int? version;
final int? typ;
final int? flag;
final int? reviewStatus;
final int? favoriteAt;
final int? isActive;
final int? createdAt;
final int? updatedAt;
final int? deletedAt;
final double? score;
final String? channels;
final String? devName;
final String? pictureGaussian;
final String? picture;
final int? commentNum;
final String? lastLoginAt;
final String? screen;
class DiscoverMiniApp extends MiniApp {
const DiscoverMiniApp({ const DiscoverMiniApp({
required this.id, required super.id,
this.name, super.name,
this.openuid, super.openuid,
this.devId, super.devId,
this.icon, super.icon,
this.iconGaussian, super.iconGaussian,
this.downloadUrl, super.downloadUrl,
this.description, super.description,
this.version, super.version,
this.typ, super.typ,
this.flag, super.flag,
this.reviewStatus, super.reviewStatus,
this.favoriteAt, super.favoriteAt,
this.isActive, super.isActive,
this.createdAt, super.createdAt,
this.updatedAt, super.updatedAt,
this.deletedAt, super.deletedAt,
this.score, super.score,
this.channels, super.channels,
this.devName, super.devName,
this.pictureGaussian, super.pictureGaussian,
this.picture, super.picture,
this.commentNum, super.commentNum,
this.lastLoginAt, super.lastLoginAt,
this.screen, super.screen,
}); });
DiscoverMiniApp copyWith({
String? id,
String? name,
String? openuid,
String? devId,
String? icon,
String? iconGaussian,
String? downloadUrl,
String? description,
int? version,
int? typ,
int? flag,
int? reviewStatus,
int? favoriteAt,
int? isActive,
int? createdAt,
int? updatedAt,
int? deletedAt,
double? score,
String? channels,
String? devName,
String? pictureGaussian,
String? picture,
int? commentNum,
String? lastLoginAt,
String? screen,
}) {
return DiscoverMiniApp(
id: id ?? this.id,
name: name ?? this.name,
openuid: openuid ?? this.openuid,
devId: devId ?? this.devId,
icon: icon ?? this.icon,
iconGaussian: iconGaussian ?? this.iconGaussian,
downloadUrl: downloadUrl ?? this.downloadUrl,
description: description ?? this.description,
version: version ?? this.version,
typ: typ ?? this.typ,
flag: flag ?? this.flag,
reviewStatus: reviewStatus ?? this.reviewStatus,
favoriteAt: favoriteAt ?? this.favoriteAt,
isActive: isActive ?? this.isActive,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
deletedAt: deletedAt ?? this.deletedAt,
score: score ?? this.score,
channels: channels ?? this.channels,
devName: devName ?? this.devName,
pictureGaussian: pictureGaussian ?? this.pictureGaussian,
picture: picture ?? this.picture,
commentNum: commentNum ?? this.commentNum,
lastLoginAt: lastLoginAt ?? this.lastLoginAt,
screen: screen ?? this.screen,
);
}
} }

View File

@@ -1,112 +1,31 @@
/// 探索小程序 Domain 实体 import 'package:im_app/domain/entities/mini_app.dart';
class ExploreMiniApp {
final String id;
final String? name;
final String? openuid;
final String? devId;
final String? icon;
final String? iconGaussian;
final String? downloadUrl;
final String? description;
final int? version;
final int? typ;
final int? flag;
final int? reviewStatus;
final int? favoriteAt;
final int? isActive;
final int? createdAt;
final int? updatedAt;
final int? deletedAt;
final double? score;
final String? channels;
final String? devName;
final String? pictureGaussian;
final String? picture;
final int? commentNum;
final int? lastLoginAt;
final String? screen;
class ExploreMiniApp extends MiniApp {
const ExploreMiniApp({ const ExploreMiniApp({
required this.id, required super.id,
this.name, super.name,
this.openuid, super.openuid,
this.devId, super.devId,
this.icon, super.icon,
this.iconGaussian, super.iconGaussian,
this.downloadUrl, super.downloadUrl,
this.description, super.description,
this.version, super.version,
this.typ, super.typ,
this.flag, super.flag,
this.reviewStatus, super.reviewStatus,
this.favoriteAt, super.favoriteAt,
this.isActive, super.isActive,
this.createdAt, super.createdAt,
this.updatedAt, super.updatedAt,
this.deletedAt, super.deletedAt,
this.score, super.score,
this.channels, super.channels,
this.devName, super.devName,
this.pictureGaussian, super.pictureGaussian,
this.picture, super.picture,
this.commentNum, super.commentNum,
this.lastLoginAt, super.lastLoginAt,
this.screen, super.screen,
}); });
ExploreMiniApp copyWith({
String? id,
String? name,
String? openuid,
String? devId,
String? icon,
String? iconGaussian,
String? downloadUrl,
String? description,
int? version,
int? typ,
int? flag,
int? reviewStatus,
int? favoriteAt,
int? isActive,
int? createdAt,
int? updatedAt,
int? deletedAt,
double? score,
String? channels,
String? devName,
String? pictureGaussian,
String? picture,
int? commentNum,
int? lastLoginAt,
String? screen,
}) {
return ExploreMiniApp(
id: id ?? this.id,
name: name ?? this.name,
openuid: openuid ?? this.openuid,
devId: devId ?? this.devId,
icon: icon ?? this.icon,
iconGaussian: iconGaussian ?? this.iconGaussian,
downloadUrl: downloadUrl ?? this.downloadUrl,
description: description ?? this.description,
version: version ?? this.version,
typ: typ ?? this.typ,
flag: flag ?? this.flag,
reviewStatus: reviewStatus ?? this.reviewStatus,
favoriteAt: favoriteAt ?? this.favoriteAt,
isActive: isActive ?? this.isActive,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
deletedAt: deletedAt ?? this.deletedAt,
score: score ?? this.score,
channels: channels ?? this.channels,
devName: devName ?? this.devName,
pictureGaussian: pictureGaussian ?? this.pictureGaussian,
picture: picture ?? this.picture,
commentNum: commentNum ?? this.commentNum,
lastLoginAt: lastLoginAt ?? this.lastLoginAt,
screen: screen ?? this.screen,
);
}
} }

View File

@@ -1,5 +1,5 @@
/// Domain /// Domain
class Favourite { class Favorite {
final int id; final int id;
final String parentId; final String parentId;
final String data; final String data;
@@ -16,7 +16,7 @@ class Favourite {
final int isUploaded; final int isUploaded;
final String urls; final String urls;
const Favourite({ const Favorite({
required this.id, required this.id,
this.parentId = '', this.parentId = '',
this.data = '', this.data = '',
@@ -34,7 +34,7 @@ class Favourite {
this.urls = '[]', this.urls = '[]',
}); });
Favourite copyWith({ Favorite copyWith({
int? id, int? id,
String? parentId, String? parentId,
String? data, String? data,
@@ -51,7 +51,7 @@ class Favourite {
int? isUploaded, int? isUploaded,
String? urls, String? urls,
}) { }) {
return Favourite( return Favorite(
id: id ?? this.id, id: id ?? this.id,
parentId: parentId ?? this.parentId, parentId: parentId ?? this.parentId,
data: data ?? this.data, data: data ?? this.data,

View File

@@ -1,5 +1,5 @@
/// Domain /// Domain
class FavouriteDetail { class FavoriteDetail {
final int? id; final int? id;
final String relatedId; final String relatedId;
final String content; final String content;
@@ -9,7 +9,7 @@ class FavouriteDetail {
final int? chatId; final int? chatId;
final int? sendTime; final int? sendTime;
const FavouriteDetail({ const FavoriteDetail({
this.id, this.id,
this.relatedId = '', this.relatedId = '',
this.content = '', this.content = '',
@@ -20,7 +20,7 @@ class FavouriteDetail {
this.sendTime, this.sendTime,
}); });
FavouriteDetail copyWith({ FavoriteDetail copyWith({
int? id, int? id,
String? relatedId, String? relatedId,
String? content, String? content,
@@ -30,7 +30,7 @@ class FavouriteDetail {
int? chatId, int? chatId,
int? sendTime, int? sendTime,
}) { }) {
return FavouriteDetail( return FavoriteDetail(
id: id ?? this.id, id: id ?? this.id,
relatedId: relatedId ?? this.relatedId, relatedId: relatedId ?? this.relatedId,
content: content ?? this.content, content: content ?? this.content,

View File

@@ -1,112 +1,32 @@
import 'package:im_app/domain/entities/mini_app.dart';
/// 收藏小程序 Domain 实体 /// 收藏小程序 Domain 实体
class FavoriteMiniApp { class FavoriteMiniApp extends MiniApp {
final String id;
final String? name;
final String? openuid;
final String? devId;
final String? icon;
final String? iconGaussian;
final String? downloadUrl;
final String? description;
final int? version;
final int? typ;
final int? flag;
final int? reviewStatus;
final int? favoriteAt;
final int? isActive;
final int? createdAt;
final int? updatedAt;
final int? deletedAt;
final double? score;
final String? channels;
final String? devName;
final String? pictureGaussian;
final String? picture;
final int? commentNum;
final int? lastLoginAt;
final String? screen;
const FavoriteMiniApp({ const FavoriteMiniApp({
required this.id, required super.id,
this.name, super.name,
this.openuid, super.openuid,
this.devId, super.devId,
this.icon, super.icon,
this.iconGaussian, super.iconGaussian,
this.downloadUrl, super.downloadUrl,
this.description, super.description,
this.version, super.version,
this.typ, super.typ,
this.flag, super.flag,
this.reviewStatus, super.reviewStatus,
this.favoriteAt, super.favoriteAt,
this.isActive, super.isActive,
this.createdAt, super.createdAt,
this.updatedAt, super.updatedAt,
this.deletedAt, super.deletedAt,
this.score, super.score,
this.channels, super.channels,
this.devName, super.devName,
this.pictureGaussian, super.pictureGaussian,
this.picture, super.picture,
this.commentNum, super.commentNum,
this.lastLoginAt, super.lastLoginAt,
this.screen, super.screen,
}); });
FavoriteMiniApp copyWith({
String? id,
String? name,
String? openuid,
String? devId,
String? icon,
String? iconGaussian,
String? downloadUrl,
String? description,
int? version,
int? typ,
int? flag,
int? reviewStatus,
int? favoriteAt,
int? isActive,
int? createdAt,
int? updatedAt,
int? deletedAt,
double? score,
String? channels,
String? devName,
String? pictureGaussian,
String? picture,
int? commentNum,
int? lastLoginAt,
String? screen,
}) {
return FavoriteMiniApp(
id: id ?? this.id,
name: name ?? this.name,
openuid: openuid ?? this.openuid,
devId: devId ?? this.devId,
icon: icon ?? this.icon,
iconGaussian: iconGaussian ?? this.iconGaussian,
downloadUrl: downloadUrl ?? this.downloadUrl,
description: description ?? this.description,
version: version ?? this.version,
typ: typ ?? this.typ,
flag: flag ?? this.flag,
reviewStatus: reviewStatus ?? this.reviewStatus,
favoriteAt: favoriteAt ?? this.favoriteAt,
isActive: isActive ?? this.isActive,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
deletedAt: deletedAt ?? this.deletedAt,
score: score ?? this.score,
channels: channels ?? this.channels,
devName: devName ?? this.devName,
pictureGaussian: pictureGaussian ?? this.pictureGaussian,
picture: picture ?? this.picture,
commentNum: commentNum ?? this.commentNum,
lastLoginAt: lastLoginAt ?? this.lastLoginAt,
screen: screen ?? this.screen,
);
}
} }

View File

@@ -1,5 +1,7 @@
/// Domain /// Domain
class DiscoverMiniApp { ///
/// discover / explore / favorite / recent
class MiniApp {
final String id; final String id;
final String? name; final String? name;
final String? openuid; final String? openuid;
@@ -26,7 +28,7 @@ class DiscoverMiniApp {
final String? lastLoginAt; final String? lastLoginAt;
final String? screen; final String? screen;
const DiscoverMiniApp({ const MiniApp({
required this.id, required this.id,
this.name, this.name,
this.openuid, this.openuid,
@@ -54,7 +56,7 @@ class DiscoverMiniApp {
this.screen, this.screen,
}); });
DiscoverMiniApp copyWith({ MiniApp copyWith({
String? id, String? id,
String? name, String? name,
String? openuid, String? openuid,
@@ -81,7 +83,7 @@ class DiscoverMiniApp {
String? lastLoginAt, String? lastLoginAt,
String? screen, String? screen,
}) { }) {
return DiscoverMiniApp( return MiniApp(
id: id ?? this.id, id: id ?? this.id,
name: name ?? this.name, name: name ?? this.name,
openuid: openuid ?? this.openuid, openuid: openuid ?? this.openuid,

View File

@@ -1,112 +1,32 @@
import 'package:im_app/domain/entities/mini_app.dart';
/// 最近小程序 Domain 实体 /// 最近小程序 Domain 实体
class RecentMiniApp { class RecentMiniApp extends MiniApp {
final String id;
final String? name;
final String? openuid;
final String? devId;
final String? icon;
final String? iconGaussian;
final String? downloadUrl;
final String? description;
final int? version;
final int? typ;
final int? flag;
final int? reviewStatus;
final int? favoriteAt;
final int? isActive;
final int? createdAt;
final int? updatedAt;
final int? deletedAt;
final double? score;
final String? channels;
final String? devName;
final String? pictureGaussian;
final String? picture;
final int? commentNum;
final int? lastLoginAt;
final String? screen;
const RecentMiniApp({ const RecentMiniApp({
required this.id, required super.id,
this.name, super.name,
this.openuid, super.openuid,
this.devId, super.devId,
this.icon, super.icon,
this.iconGaussian, super.iconGaussian,
this.downloadUrl, super.downloadUrl,
this.description, super.description,
this.version, super.version,
this.typ, super.typ,
this.flag, super.flag,
this.reviewStatus, super.reviewStatus,
this.favoriteAt, super.favoriteAt,
this.isActive, super.isActive,
this.createdAt, super.createdAt,
this.updatedAt, super.updatedAt,
this.deletedAt, super.deletedAt,
this.score, super.score,
this.channels, super.channels,
this.devName, super.devName,
this.pictureGaussian, super.pictureGaussian,
this.picture, super.picture,
this.commentNum, super.commentNum,
this.lastLoginAt, super.lastLoginAt,
this.screen, super.screen,
}); });
RecentMiniApp copyWith({
String? id,
String? name,
String? openuid,
String? devId,
String? icon,
String? iconGaussian,
String? downloadUrl,
String? description,
int? version,
int? typ,
int? flag,
int? reviewStatus,
int? favoriteAt,
int? isActive,
int? createdAt,
int? updatedAt,
int? deletedAt,
double? score,
String? channels,
String? devName,
String? pictureGaussian,
String? picture,
int? commentNum,
int? lastLoginAt,
String? screen,
}) {
return RecentMiniApp(
id: id ?? this.id,
name: name ?? this.name,
openuid: openuid ?? this.openuid,
devId: devId ?? this.devId,
icon: icon ?? this.icon,
iconGaussian: iconGaussian ?? this.iconGaussian,
downloadUrl: downloadUrl ?? this.downloadUrl,
description: description ?? this.description,
version: version ?? this.version,
typ: typ ?? this.typ,
flag: flag ?? this.flag,
reviewStatus: reviewStatus ?? this.reviewStatus,
favoriteAt: favoriteAt ?? this.favoriteAt,
isActive: isActive ?? this.isActive,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
deletedAt: deletedAt ?? this.deletedAt,
score: score ?? this.score,
channels: channels ?? this.channels,
devName: devName ?? this.devName,
pictureGaussian: pictureGaussian ?? this.pictureGaussian,
picture: picture ?? this.picture,
commentNum: commentNum ?? this.commentNum,
lastLoginAt: lastLoginAt ?? this.lastLoginAt,
screen: screen ?? this.screen,
);
}
} }

View File

@@ -0,0 +1,48 @@
import 'package:im_app/domain/entities/api_retry.dart';
/// API 重试仓储接口
abstract class ApiRetryRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
Stream<List<ApiRetry>> watchAll();
Stream<List<ApiRetry>> watchPending();
// ── 读取 ─────────────────────────────────────────────────────────────────
Future<List<ApiRetry>> getAll();
Future<ApiRetry?> getById(int id);
/// 读取未同步的重试任务
Future<List<ApiRetry>> getPending();
/// 读取未过期的重试任务
Future<List<ApiRetry>> getActive();
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入重试任务autoIncrement id无需提供
Future<void> insert(ApiRetry apiRetry);
Future<void> insertOrReplace(ApiRetry apiRetry);
Future<void> update(ApiRetry apiRetry);
/// 标记为已同步
Future<void> markSynced(int id);
/// 标记为已过期
Future<void> markExpired(int id);
// ── 删除 ─────────────────────────────────────────────────────────────────
Future<void> delete(int id);
Future<void> deleteByUid(int uid);
/// 清除已同步的重试任务
Future<void> deleteSynced();
Future<void> clear();
}

View File

@@ -0,0 +1,51 @@
import 'package:im_app/domain/entities/chat_category.dart';
/// 聊天分类仓储接口
///
/// ## 职责
/// - StorageSdkApi ↔ Domain ChatCategory 映射
/// - CRUD 操作(通过 StorageSdkApi不直接接触 DB
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在 Impl
///
/// ## 数据流
/// ```
/// 写入Domain ChatCategory → _toCompanion() → StorageSdkApi → DB
/// 读取DB row (DriftChatCategory) → _toEntity() → Domain ChatCategory
/// 监听DB 变化 → stream → Domain ChatCategory → UI
/// ```
abstract class ChatCategoryRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
/// 监听所有聊天分类DB 变化自动反映
Stream<List<ChatCategory>> watchAllChatCategories();
/// 监听指定聊天分类
Stream<ChatCategory?> watchChatCategory(int id);
// ── 读取 ─────────────────────────────────────────────────────────────────
/// 读取所有聊天分类
Future<List<ChatCategory>> getChatCategories();
/// 读取指定聊天分类,不存在返回 null
Future<ChatCategory?> getChatCategory(int id);
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入或替换聊天分类
Future<void> insertOrReplaceChatCategory(ChatCategory chatCategory);
/// 批量插入或替换聊天分类
Future<void> insertOrReplaceChatCategories(List<ChatCategory> chatCategories);
/// 更新聊天分类
Future<void> updateChatCategory(ChatCategory chatCategory);
// ── 删除 ─────────────────────────────────────────────────────────────────
/// 删除指定聊天分类
Future<void> deleteChatCategory(int id);
/// 清空所有聊天分类
Future<void> clearChatCategories();
}

View File

@@ -0,0 +1,60 @@
import 'package:im_app/domain/entities/chat.dart';
/// 聊天仓储接口
///
/// ## 职责
/// - StorageSdkApi ↔ Domain Chat 映射
/// - CRUD 操作(通过 StorageSdkApi不直接接触 DB
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在 Impl
///
/// ## 数据流
/// ```
/// 写入Domain Chat → _toCompanion() → StorageSdkApi → DB
/// 读取DB row (DriftChat) → _toEntity() → Domain Chat
/// 监听DB 变化 → stream → Domain Chat → UI
/// ```
abstract class ChatRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
/// 监听所有聊天DB 变化自动反映
Stream<List<Chat>> watchAllChats();
/// 监听指定聊天
Stream<Chat?> watchChat(int id);
// ── 读取 ─────────────────────────────────────────────────────────────────
/// 读取所有聊天
Future<List<Chat>> getChats();
/// 读取指定聊天,不存在返回 null
Future<Chat?> getChat(int id);
/// 分页读取聊天
Future<List<Chat>> getChatsPage({required int offset, required int limit});
/// 统计聊天总数
Future<int> countChats();
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入或替换聊天
Future<void> insertOrReplaceChat(Chat chat);
/// 批量插入或替换聊天
Future<void> insertOrReplaceChats(List<Chat> chats);
/// 更新聊天
Future<void> updateChat(Chat chat);
/// 批量更新聊天
Future<void> updateChatsBatch(List<Chat> chats);
// ── 删除 ─────────────────────────────────────────────────────────────────
/// 删除指定聊天
Future<void> deleteChat(int id);
/// 清空所有聊天
Future<void> clearChats();
}

View File

@@ -0,0 +1,60 @@
import 'package:im_app/domain/entities/favorite_detail.dart';
/// 收藏详情仓储接口
///
/// ## 职责
/// - StorageSdkApi ↔ Domain FavoriteDetail 映射
/// - CRUD 操作(通过 StorageSdkApi不直接接触 DB
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在 Impl
///
/// ## 数据流
/// ```
/// 写入Domain FavoriteDetail → _toCompanion() → StorageSdkApi → DB
/// 读取DB row (DriftFavoriteDetail) → _toEntity() → Domain FavoriteDetail
/// 监听DB 变化 → stream → Domain FavoriteDetail → UI
/// ```
abstract class FavoriteDetailRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
/// 监听所有收藏详情DB 变化自动反映
Stream<List<FavoriteDetail>> watchAll();
/// 监听指定 relatedId 的收藏详情
Stream<List<FavoriteDetail>> watchByRelatedId(String relatedId);
// ── 读取 ─────────────────────────────────────────────────────────────────
/// 读取所有收藏详情
Future<List<FavoriteDetail>> getAll();
/// 读取指定 id不存在返回 null
Future<FavoriteDetail?> getById(int id);
/// 读取指定 relatedId 的所有收藏详情
Future<List<FavoriteDetail>> getByRelatedId(String relatedId);
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入收藏详情autoIncrement id无需提供
Future<void> insert(FavoriteDetail favoriteDetail);
/// 批量插入收藏详情
Future<void> insertAll(List<FavoriteDetail> favoriteDetails);
/// 插入或替换收藏详情
Future<void> insertOrReplace(FavoriteDetail favoriteDetail);
/// 更新收藏详情
Future<void> update(FavoriteDetail favoriteDetail);
// ── 删除 ─────────────────────────────────────────────────────────────────
/// 删除指定 id
Future<void> delete(int id);
/// 删除指定 relatedId 的所有收藏详情
Future<void> deleteByRelatedId(String relatedId);
/// 清空所有收藏详情
Future<void> clear();
}

View File

@@ -0,0 +1,63 @@
import 'package:im_app/domain/entities/favorite.dart';
/// 收藏仓储接口
///
/// ## 职责
/// - StorageSdkApi ↔ Domain Favorite 映射
/// - CRUD 操作(通过 StorageSdkApi不直接接触 DB
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在 Impl
///
/// ## 数据流
/// ```
/// 写入Domain Favorite → _toCompanion() → StorageSdkApi → DB
/// 读取DB row (DriftFavorite) → _toEntity() → Domain Favorite
/// 监听DB 变化 → stream → Domain Favorite → UI
/// ```
abstract class FavoriteRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
/// 监听所有收藏DB 变化自动反映
Stream<List<Favorite>> watchAll();
/// 监听指定收藏
Stream<Favorite?> watchById(int id);
/// 监听指定 parentId 的收藏
Stream<List<Favorite>> watchByParentId(String parentId);
// ── 读取 ─────────────────────────────────────────────────────────────────
/// 读取所有收藏
Future<List<Favorite>> getAll();
/// 读取指定收藏,不存在返回 null
Future<Favorite?> getById(int id);
/// 读取指定 parentId 的所有收藏
Future<List<Favorite>> getByParentId(String parentId);
/// 读取未上传的收藏
Future<List<Favorite>> getUnuploaded();
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入或替换收藏
Future<void> insertOrReplace(Favorite favorite);
/// 批量插入或替换收藏
Future<void> insertOrReplaceAll(List<Favorite> favorites);
/// 更新收藏
Future<void> update(Favorite favorite);
// ── 删除 ─────────────────────────────────────────────────────────────────
/// 删除指定收藏
Future<void> delete(int id);
/// 删除指定 parentId 的所有收藏
Future<void> deleteByParentId(String parentId);
/// 清空所有收藏
Future<void> clear();
}

View File

@@ -0,0 +1,57 @@
import 'package:im_app/domain/entities/group.dart';
/// 群组仓储接口
///
/// ## 职责
/// - StorageSdkApi ↔ Domain Group 映射
/// - CRUD 操作(通过 StorageSdkApi不直接接触 DB
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在 Impl
///
/// ## 数据流
/// ```
/// 写入Domain Group → _toCompanion() → StorageSdkApi → DB
/// 读取DB row (DriftGroup) → _toEntity() → Domain Group
/// 监听DB 变化 → stream → Domain Group → UI
/// ```
abstract class GroupRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
/// 监听所有群组DB 变化自动反映
Stream<List<Group>> watchAll();
/// 监听指定群组
Stream<Group?> watchById(int id);
// ── 读取 ─────────────────────────────────────────────────────────────────
/// 读取所有群组
Future<List<Group>> getAll();
/// 读取指定群组,不存在返回 null
Future<Group?> getById(int id);
/// 读取指定 workspaceId 的所有群组
Future<List<Group>> getByWorkspace(int workspaceId);
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入或替换群组
Future<void> insertOrReplace(Group group);
/// 批量插入或替换群组
Future<void> insertOrReplaceAll(List<Group> groups);
/// 更新群组
Future<void> update(Group group);
/// 批量更新群组
Future<void> updateBatch(List<Group> groups);
// ── 删除 ─────────────────────────────────────────────────────────────────
/// 删除指定群组
Future<void> delete(int id);
/// 清空所有群组
Future<void> clear();
}

View File

@@ -0,0 +1,67 @@
import 'package:im_app/domain/entities/message.dart';
/// 消息仓储接口
///
/// ## 职责
/// - StorageSdkApi ↔ Domain Message 映射
/// - CRUD 操作(通过 StorageSdkApi不直接接触 DB
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在 Impl
///
/// ## 数据流
/// ```
/// 写入Domain Message → _toCompanion() → StorageSdkApi → DB
/// 读取DB row (DriftMessage) → _toEntity() → Domain Message
/// 监听DB 变化 → stream → Domain Message → UI
/// ```
abstract class MessageRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
/// 监听指定 chatId 的所有消息,按 chatIdx 升序
Stream<List<Message>> watchByChatId(int chatId);
/// 监听指定消息
Stream<Message?> watchById(int id);
// ── 读取 ─────────────────────────────────────────────────────────────────
/// 读取指定 chatId 的所有消息,按 chatIdx 升序
Future<List<Message>> getByChatId(int chatId);
/// 分页读取指定 chatId 的消息
Future<List<Message>> getByChatIdPage({
required int chatId,
required int offset,
required int limit,
});
/// 读取指定消息,不存在返回 null
Future<Message?> getById(int id);
/// 读取指定 messageId不存在返回 null
Future<Message?> getByMessageId(int messageId);
/// 统计指定 chatId 的消息数量
Future<int> countByChatId(int chatId);
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入或替换消息
Future<void> insertOrReplace(Message message);
/// 批量插入或替换消息
Future<void> insertOrReplaceAll(List<Message> messages);
/// 更新消息
Future<void> update(Message message);
// ── 删除 ─────────────────────────────────────────────────────────────────
/// 删除指定消息
Future<void> delete(int id);
/// 删除指定 chatId 的所有消息
Future<void> deleteByChatId(int chatId);
/// 清空所有消息
Future<void> clear();
}

View File

@@ -0,0 +1,47 @@
import 'package:im_app/domain/entities/mini_app.dart';
/// 小程序仓储接口discover / explore / favorite / recent 共用)
///
/// ## 职责
/// - StorageSdkApi ↔ Domain MiniApp 映射
/// - CRUD 操作(通过 StorageSdkApi不直接接触 DB
/// - 所有公开接口只接受 Domain 实体Companion 转换完全内聚在 Impl
abstract class MiniAppRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
/// 监听所有小程序DB 变化自动反映
Stream<List<MiniApp>> watchAll();
/// 监听指定小程序
Stream<MiniApp?> watch(String id);
// ── 读取 ─────────────────────────────────────────────────────────────────
/// 读取所有小程序
Future<List<MiniApp>> getAll();
/// 读取指定小程序,不存在返回 null
Future<MiniApp?> get(String id);
/// 检查是否存在
Future<bool> isExist(String id);
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入或替换小程序
Future<void> insertOrReplace(MiniApp miniApp);
/// 批量插入或替换小程序
Future<void> insertOrReplaceAll(List<MiniApp> miniApps);
/// 更新小程序
Future<void> update(MiniApp miniApp);
// ── 删除 ─────────────────────────────────────────────────────────────────
/// 删除指定小程序
Future<void> delete(String id);
/// 清空所有小程序
Future<void> clear();
}

View File

@@ -0,0 +1,36 @@
import 'package:im_app/domain/entities/pending_friend_request_history.dart';
/// 待处理好友请求历史仓储接口
abstract class PendingFriendRequestHistoryRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
Stream<List<PendingFriendRequestHistory>> watchAll();
Stream<PendingFriendRequestHistory?> watchById(int id);
Stream<List<PendingFriendRequestHistory>> watchByUid(int uid);
// ── 读取 ─────────────────────────────────────────────────────────────────
Future<List<PendingFriendRequestHistory>> getAll();
Future<PendingFriendRequestHistory?> getById(int id);
Future<List<PendingFriendRequestHistory>> getByUid(int uid);
// ── 写入 ─────────────────────────────────────────────────────────────────
Future<void> insertOrReplace(PendingFriendRequestHistory history);
Future<void> insertOrReplaceAll(List<PendingFriendRequestHistory> histories);
Future<void> update(PendingFriendRequestHistory history);
// ── 删除 ─────────────────────────────────────────────────────────────────
Future<void> delete(int id);
Future<void> deleteByUid(int uid);
Future<void> clear();
}

View File

@@ -0,0 +1,38 @@
import 'package:im_app/domain/entities/sound.dart';
/// 音效仓储接口
abstract class SoundRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
Stream<List<Sound>> watchAll();
Stream<Sound?> watchById(int id);
Stream<List<Sound>> watchByType(int typ);
// ── 读取 ─────────────────────────────────────────────────────────────────
Future<List<Sound>> getAll();
Future<Sound?> getById(int id);
Future<List<Sound>> getByType(int typ);
Future<List<Sound>> getByChannelGroup(int channelGroupId);
Future<List<Sound>> getDefaults();
// ── 写入 ─────────────────────────────────────────────────────────────────
Future<void> insertOrReplace(Sound sound);
Future<void> insertOrReplaceAll(List<Sound> sounds);
Future<void> update(Sound sound);
// ── 删除 ─────────────────────────────────────────────────────────────────
Future<void> delete(int id);
Future<void> clear();
}

View File

@@ -0,0 +1,43 @@
import 'package:im_app/domain/entities/tag.dart';
/// 标签仓储接口
abstract class TagRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
Stream<List<Tag>> watchAll();
Stream<Tag?> watchById(int id);
Stream<List<Tag>> watchByUid(int uid);
Stream<List<Tag>> watchByType(int type);
// ── 读取 ─────────────────────────────────────────────────────────────────
Future<List<Tag>> getAll();
Future<Tag?> getById(int id);
Future<List<Tag>> getByUid(int uid);
Future<List<Tag>> getByType(int type);
// ── 写入 ─────────────────────────────────────────────────────────────────
/// 插入标签autoIncrement id无需提供
Future<void> insert(Tag tag);
Future<void> insertOrReplace(Tag tag);
Future<void> insertOrReplaceAll(List<Tag> tags);
Future<void> update(Tag tag);
// ── 删除 ─────────────────────────────────────────────────────────────────
Future<void> delete(int id);
Future<void> deleteByUid(int uid);
Future<void> clear();
}

View File

@@ -0,0 +1,34 @@
import 'package:im_app/domain/entities/user_request_history.dart';
/// 用户请求历史仓储接口
abstract class UserRequestHistoryRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
Stream<List<UserRequestHistory>> watchAll();
Stream<UserRequestHistory?> watchById(int id);
Stream<List<UserRequestHistory>> watchByStatus(int status);
// ── 读取 ─────────────────────────────────────────────────────────────────
Future<List<UserRequestHistory>> getAll();
Future<UserRequestHistory?> getById(int id);
Future<List<UserRequestHistory>> getByStatus(int status);
// ── 写入 ─────────────────────────────────────────────────────────────────
Future<void> insertOrReplace(UserRequestHistory history);
Future<void> insertOrReplaceAll(List<UserRequestHistory> histories);
Future<void> update(UserRequestHistory history);
// ── 删除 ─────────────────────────────────────────────────────────────────
Future<void> delete(int id);
Future<void> clear();
}

View File

@@ -0,0 +1,32 @@
import 'package:im_app/domain/entities/workspace.dart';
/// 工作空间仓储接口
abstract class WorkspaceRepository {
// ── 监听 ─────────────────────────────────────────────────────────────────
Stream<List<Workspace>> watchAll();
Stream<Workspace?> watchById(int id);
// ── 读取 ─────────────────────────────────────────────────────────────────
Future<List<Workspace>> getAll();
Future<Workspace?> getById(int id);
Future<List<Workspace>> getByOwner(int ownerId);
// ── 写入 ─────────────────────────────────────────────────────────────────
Future<void> insertOrReplace(Workspace workspace);
Future<void> insertOrReplaceAll(List<Workspace> workspaces);
Future<void> update(Workspace workspace);
// ── 删除 ─────────────────────────────────────────────────────────────────
Future<void> delete(int id);
Future<void> clear();
}

View File

@@ -0,0 +1,36 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/favorite_detail_repository_impl.dart';
import 'package:im_app/domain/repositories/favorite_detail_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:im_app/domain/entities/favorite_detail.dart';
part 'favorite_detail_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
/// 收藏详情仓储 Provider
final favoriteDetailRepositoryProvider = Provider<FavoriteDetailRepository>((
ref,
) {
return FavoriteDetailRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有收藏详情
@riverpod
Stream<List<FavoriteDetail>> allFavoriteDetails(Ref ref) {
return ref.watch(favoriteDetailRepositoryProvider).watchAll();
}
/// 监听指定 relatedId 的收藏详情
@riverpod
Stream<List<FavoriteDetail>> favoriteDetailsByRelatedId(
Ref ref,
String relatedId,
) {
return ref
.watch(favoriteDetailRepositoryProvider)
.watchByRelatedId(relatedId);
}

View File

@@ -0,0 +1,35 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/favorite_repository_impl.dart';
import 'package:im_app/domain/entities/favorite.dart';
import 'package:im_app/domain/repositories/favorite_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'favorite_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
/// 收藏仓储 Provider
final favoriteRepositoryProvider = Provider<FavoriteRepository>((ref) {
return FavoriteRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有收藏
@riverpod
Stream<List<Favorite>> allFavorites(Ref ref) {
return ref.watch(favoriteRepositoryProvider).watchAll();
}
/// 监听指定收藏
@riverpod
Stream<Favorite?> favoriteById(Ref ref, int id) {
return ref.watch(favoriteRepositoryProvider).watchById(id);
}
/// 监听指定 parentId 的收藏
@riverpod
Stream<List<Favorite>> favoritesByParentId(Ref ref, String parentId) {
return ref.watch(favoriteRepositoryProvider).watchByParentId(parentId);
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/chat_category_repository_impl.dart';
import 'package:im_app/domain/entities/chat_category.dart';
import 'package:im_app/domain/repositories/chat_category_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'chat_category_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
/// 聊天分类仓储 Provider
final chatCategoryRepositoryProvider = Provider<ChatCategoryRepository>((ref) {
return ChatCategoryRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有聊天分类
@riverpod
Stream<List<ChatCategory>> allChatCategories(Ref ref) {
return ref.watch(chatCategoryRepositoryProvider).watchAllChatCategories();
}
/// 监听指定聊天分类
@riverpod
Stream<ChatCategory?> chatCategory(Ref ref, int id) {
return ref.watch(chatCategoryRepositoryProvider).watchChatCategory(id);
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/chat_repository_impl.dart';
import 'package:im_app/domain/entities/chat.dart';
import 'package:im_app/domain/repositories/chat_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'chat_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
/// 聊天仓储 Provider
final chatRepositoryProvider = Provider<ChatRepository>((ref) {
return ChatRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有聊天
@riverpod
Stream<List<Chat>> allChats(Ref ref) {
return ref.watch(chatRepositoryProvider).watchAllChats();
}
/// 监听指定聊天
@riverpod
Stream<Chat?> chat(Ref ref, int id) {
return ref.watch(chatRepositoryProvider).watchChat(id);
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/group_repository_impl.dart';
import 'package:im_app/domain/entities/group.dart';
import 'package:im_app/domain/repositories/group_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'group_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
/// 群组仓储 Provider
final groupRepositoryProvider = Provider<GroupRepository>((ref) {
return GroupRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有群组
@riverpod
Stream<List<Group>> allGroups(Ref ref) {
return ref.watch(groupRepositoryProvider).watchAll();
}
/// 监听指定群组
@riverpod
Stream<Group?> groupById(Ref ref, int id) {
return ref.watch(groupRepositoryProvider).watchById(id);
}

View File

@@ -0,0 +1,29 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/message_repository_impl.dart';
import 'package:im_app/domain/entities/message.dart';
import 'package:im_app/domain/repositories/message_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'message_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
/// 消息仓储 Provider
final messageRepositoryProvider = Provider<MessageRepository>((ref) {
return MessageRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听指定 chatId 的消息列表
@riverpod
Stream<List<Message>> messagesByChatId(Ref ref, int chatId) {
return ref.watch(messageRepositoryProvider).watchByChatId(chatId);
}
/// 监听指定消息
@riverpod
Stream<Message?> messageById(Ref ref, int id) {
return ref.watch(messageRepositoryProvider).watchById(id);
}

View File

@@ -0,0 +1,38 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/pending_friend_request_history_repository_impl.dart';
import 'package:im_app/domain/entities/pending_friend_request_history.dart';
import 'package:im_app/domain/repositories/pending_friend_request_history_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'pending_friend_request_history_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
final pendingFriendRequestHistoryRepositoryProvider =
Provider<PendingFriendRequestHistoryRepository>((ref) {
return PendingFriendRequestHistoryRepositoryImpl(
ref.watch(storageSdkProvider),
);
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有好友请求历史
@riverpod
Stream<List<PendingFriendRequestHistory>> allPendingFriendRequestHistories(
Ref ref,
) {
return ref.watch(pendingFriendRequestHistoryRepositoryProvider).watchAll();
}
/// 监听指定 uid 的好友请求历史
@riverpod
Stream<List<PendingFriendRequestHistory>> pendingFriendRequestHistoriesByUid(
Ref ref,
int uid,
) {
return ref
.watch(pendingFriendRequestHistoryRepositoryProvider)
.watchByUid(uid);
}

View File

@@ -0,0 +1,38 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/user_request_history_repository_impl.dart';
import 'package:im_app/domain/entities/user_request_history.dart';
import 'package:im_app/domain/repositories/user_request_history_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'user_request_history_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
final userRequestHistoryRepositoryProvider =
Provider<UserRequestHistoryRepository>((ref) {
return UserRequestHistoryRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有用户请求历史
@riverpod
Stream<List<UserRequestHistory>> allUserRequestHistories(Ref ref) {
return ref.watch(userRequestHistoryRepositoryProvider).watchAll();
}
/// 监听指定状态的用户请求历史
@riverpod
Stream<List<UserRequestHistory>> userRequestHistoriesByStatus(
Ref ref,
int status,
) {
return ref.watch(userRequestHistoryRepositoryProvider).watchByStatus(status);
}
/// 监听指定用户请求历史
@riverpod
Stream<UserRequestHistory?> userRequestHistoryById(Ref ref, int id) {
return ref.watch(userRequestHistoryRepositoryProvider).watchById(id);
}

View File

@@ -0,0 +1,25 @@
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/discover_mini_app_repository_impl.dart';
import 'package:im_app/data/repositories/explore_mini_app_repository_impl.dart';
import 'package:im_app/data/repositories/favorite_mini_app_repository_impl.dart';
import 'package:im_app/data/repositories/recent_mini_app_repository_impl.dart';
import 'package:im_app/domain/repositories/mini_app_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'mini_app_provider.g.dart';
@riverpod
MiniAppRepository discoverMiniAppRepository(Ref ref) =>
DiscoverMiniAppRepositoryImpl(ref.watch(storageSdkProvider));
@riverpod
MiniAppRepository exploreMiniAppRepository(Ref ref) =>
ExploreMiniAppRepositoryImpl(ref.watch(storageSdkProvider));
@riverpod
MiniAppRepository favoriteMiniAppRepository(Ref ref) =>
FavoriteMiniAppRepositoryImpl(ref.watch(storageSdkProvider));
@riverpod
MiniAppRepository recentMiniAppRepository(Ref ref) =>
RecentMiniAppRepositoryImpl(ref.watch(storageSdkProvider));

View File

@@ -0,0 +1,28 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:im_app/app/di/db_provider.dart';
import 'package:im_app/data/repositories/workspace_repository_impl.dart';
import 'package:im_app/domain/entities/workspace.dart';
import 'package:im_app/domain/repositories/workspace_repository.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'workspace_provider.g.dart';
// ── Repository ────────────────────────────────────────────────────────────────
final workspaceRepositoryProvider = Provider<WorkspaceRepository>((ref) {
return WorkspaceRepositoryImpl(ref.watch(storageSdkProvider));
});
// ── Streams ───────────────────────────────────────────────────────────────────
/// 监听所有工作空间
@riverpod
Stream<List<Workspace>> allWorkspaces(Ref ref) {
return ref.watch(workspaceRepositoryProvider).watchAll();
}
/// 监听指定工作空间
@riverpod
Stream<Workspace?> workspaceById(Ref ref, int id) {
return ref.watch(workspaceRepositoryProvider).watchById(id);
}