所有数据库表,提供相应的provider、桥接等方法
This commit is contained in:
159
apps/im_app/lib/data/repositories/api_retry_repository_impl.dart
Normal file
159
apps/im_app/lib/data/repositories/api_retry_repository_impl.dart
Normal 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>();
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
272
apps/im_app/lib/data/repositories/chat_repository_impl.dart
Normal file
272
apps/im_app/lib/data/repositories/chat_repository_impl.dart
Normal 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>();
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
151
apps/im_app/lib/data/repositories/favorite_repository_impl.dart
Normal file
151
apps/im_app/lib/data/repositories/favorite_repository_impl.dart
Normal 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>();
|
||||
}
|
||||
}
|
||||
163
apps/im_app/lib/data/repositories/group_repository_impl.dart
Normal file
163
apps/im_app/lib/data/repositories/group_repository_impl.dart
Normal 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>();
|
||||
}
|
||||
}
|
||||
203
apps/im_app/lib/data/repositories/message_repository_impl.dart
Normal file
203
apps/im_app/lib/data/repositories/message_repository_impl.dart
Normal 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>();
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
138
apps/im_app/lib/data/repositories/sound_repository_impl.dart
Normal file
138
apps/im_app/lib/data/repositories/sound_repository_impl.dart
Normal 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>();
|
||||
}
|
||||
}
|
||||
142
apps/im_app/lib/data/repositories/tag_repository_impl.dart
Normal file
142
apps/im_app/lib/data/repositories/tag_repository_impl.dart
Normal 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>();
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
123
apps/im_app/lib/data/repositories/workspace_repository_impl.dart
Normal file
123
apps/im_app/lib/data/repositories/workspace_repository_impl.dart
Normal 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>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user