初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
+125
View File
@@ -0,0 +1,125 @@
import 'dart:convert';
import 'package:hgdj/hj_model/home/collection_model.dart';
import 'package:hgdj/hj_model/video_model.dart';
import 'package:hgdj/hj_utils/const.dart';
import 'package:hgdj/tools_base/cache/history/base_history_record_store.dart';
import 'package:hgdj/tools_base/cache/history/cartoon_history_store.dart';
import 'package:hgdj/tools_base/cache/history/comics_history_store.dart';
import 'package:hgdj/tools_base/cache/history/community_history_store.dart';
import 'package:hgdj/tools_base/cache/history/game_history_store.dart';
import 'package:hgdj/tools_base/cache/history/novel_history_store.dart';
import 'package:hgdj/tools_base/cache/history/pic_history_store.dart';
import 'package:hgdj/tools_base/cache/history/search_history_store.dart';
import 'package:hgdj/tools_base/cache/history/short_video_history_store.dart';
import 'package:hgdj/tools_base/cache/history/video_history_store.dart';
import 'package:hgdj/tools_base/debug_log.dart';
import '../hj_model/cartoon_media_info.dart';
/// 浏览历史 + 搜索历史的统一入口。按 [MediaStyle] 派发到各自的 store,业务层不直接碰 store
class HistoryUtil {
/// 每种类型独占一个 db 文件,store 自身是单例。返回 null = 该类型不记历史
static BaseHistoryRecordStore? _storeOf(MediaStyle type) => switch (type) {
MediaStyle.Video => VideoHistoryStore(),
MediaStyle.ShortVideo => ShortVideoHistoryStore(),
MediaStyle.Comics => ComicsHistoryStore(),
MediaStyle.Cartoon => CartoonHistoryStore(),
MediaStyle.Novel => NovelHistoryStore(),
MediaStyle.Community => CommunityHistoryStore(),
MediaStyle.Pic => PicHistoryStore(),
MediaStyle.Game => GameHistoryStore(),
// 短剧的观看历史和续播位置是同一张表,走 DramaResumeStore;其余是当前业务无浏览历史需求的类型
MediaStyle.Drama ||
MediaStyle.Area ||
MediaStyle.Seed ||
MediaStyle.Actress ||
MediaStyle.NakedChat ||
MediaStyle.GroupChat =>
null,
};
/// 插入浏览历史(已存在则刷新到最前;超上限自动删最旧,上限见 BaseHistoryRecordStore.maxRows
static Future<void> insert(Object? model, MediaStyle type) async {
try {
final json = _toJson(model);
if (json == null) {
//类型没在 _toJson/_idOf 里登记 → 静默不记历史。入参是 Object? 编译期拦不住,只能靠日志暴露
debugLog('HistoryUtil.insert 未登记的类型', model?.runtimeType);
return;
}
final id = _idOf(model);
final store = _storeOf(type);
if (id == null || id.isEmpty || store == null) return;
await store.save(modelId: id, modelDataJson: jsonEncode(json));
} catch (e) {
debugLog('HistoryUtil.insert', e);
}
}
/// 删除单条浏览历史
static Future<void> delete(Object? model, MediaStyle type) async {
try {
final id = _idOf(model);
if (id == null) {
debugLog('HistoryUtil.delete 未登记的类型', model?.runtimeType);
return;
}
final store = _storeOf(type);
if (id.isEmpty || store == null) return;
await store.remove(id);
} catch (e) {
debugLog('HistoryUtil.delete', e);
}
}
/// 指定类型的浏览历史(按时间倒序,分页)。解析不出的条目直接丢弃,不让一条脏数据废掉整页
static Future<List<T>> fetch<T>(MediaStyle type,
{int page = 1, int pageSize = 20}) async {
try {
final store = _storeOf(type);
if (store == null) return <T>[];
final jsonList = await store.fetch(page: page, pageSize: pageSize);
return jsonList.map((e) => _fromJson<T>(e)).whereType<T>().toList();
} catch (e) {
debugLog('HistoryUtil.fetch', e);
return <T>[];
}
}
/// 三个 _xxx 按实例匹配,新增可记历史的 model 时这里和 [_fromJson] 一起加一行
static String? _idOf(Object? model) => switch (model) {
VideoModel m => m.id,
CartoonMediaInfo m => m.id,
CollectionModel m => m.id,
_ => null,
};
static Map<String, dynamic>? _toJson(Object? model) => switch (model) {
VideoModel m => m.toJson(),
CartoonMediaInfo m => m.toJson(),
CollectionModel m => m.toJson(),
_ => null,
};
/// 反序列化只能按 [T] 分派(拿不到实例)。**必须用 T == 类型比较**:
/// 靠 T.toString() 对类名在 release 混淆后必然失配,表现是列表静默空白
static T? _fromJson<T>(String raw) {
final json = Map<String, dynamic>.from(jsonDecode(raw));
if (T == VideoModel) return VideoModel.fromJson(json) as T;
if (T == CartoonMediaInfo) return CartoonMediaInfo.fromJson(json) as T;
if (T == CollectionModel) return CollectionModel.fromJson(json) as T;
return null;
}
//搜索历史(按时间倒序)
static Future<List<String>> searchHistories() =>
SearchHistoryStore().fetchAll();
//新增一条搜索历史(已存在则去重提到最前,超上限自动删最旧)
static Future<void> addSearch(String keyword) =>
SearchHistoryStore().save(keyword);
//清空搜索历史
static Future<void> clearSearch() => SearchHistoryStore().clean();
}