初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
import 'package:collection/collection.dart';
import 'package:hgdj/hj_utils/const.dart';
//亚模块模型
class ModuleData {
String? id;
String? moduleName;
//1首页(原首页视频) 2社区 3暗网 4动漫 5漫画 6小说 7黄油 8图集 9短视频 10私密圈 11AI广场 12短剧
int? type;
//1 模块普通海角系样式(HJShowType) 2 全专题组合样式(AllSectionShowType)
int? showType;
bool? pureVersion; //true:广告纯净模式
String? defaultTagId; //社区默认选中
HaiJiaoStyle? haiJiaoStyle;
ModuleData({this.moduleName, this.type, this.id, this.showType});
ModuleData.fromJson(Map<String, dynamic>? json) {
json ??= {};
id = json['id'];
moduleName = json['moduleName'];
type = json['type'];
showType = json['showType'];
pureVersion = json['pureVersion'];
defaultTagId = json['defaultTagId'];
haiJiaoStyle = HaiJiaoStyle.fromJson(json['haiJiaoStyle']);
}
//只给 ModuleSortManager 存本地排序用,读回来只按 id 跟后端最新数据配对,故不存 haiJiaoStyle 等内容字段
Map<String, dynamic> toJson() {
return {
"id": id,
"moduleName": moduleName,
"type": type,
"showType": showType,
'defaultTagId': defaultTagId,
};
}
//动漫/漫画/小说
bool get isACG => type == 4 || type == 5 || type == 6;
/// 展示用的排序项:top=true 的置顶,最多 4 个。
/// 标题、sort 值、随机刷新配置一律从这份派生——分头各排一次,遇到同名/同值 remove 会删错元素,两边就对不上了。
/// haiJiaoStyle 解析完就不再变,算一次存起来,别每个 getter 各构造一遍
late final List<SortRuleModel> _sortedRules = () {
final rules = [...?haiJiaoStyle?.sortRules];
final topIndex = rules.indexWhere((e) => e.top == true);
if (topIndex > 0) rules.insert(0, rules.removeAt(topIndex));
return rules.length > 4 ? rules.sublist(0, 4) : rules;
}();
/// 排序 tab(标题 + sort 值),为空返回 null 让调用方退回默认值。
/// 标题和 sort 值必须一起产出:拆成两个并行数组时,后端只下发其中一个就会静默错位
List<SortTab<int>>? get sortTabs => _sortedRules.isEmpty
? null
: _sortedRules.map((e) => SortTab(e.name ?? '', e.val ?? -1)).toList();
/// 按 sort 值取对应的排序规则(用于判断该排序项是否走随机刷新接口)
SortRuleModel? sortRuleOf(int? val) =>
_sortedRules.firstWhereOrNull((e) => e.val == val);
}
class HaiJiaoStyle {
int? defaultShow; //默认展示 0-一排两个 1-一排一个
int? sectionStyle; //专题展示样式 0-不展示 1-十六岁专题 2-女优专题 3-网黄专题 4-普通专题
int? showChosenVideo; //0-不展示精选视频 1-展示精选视频
int? sortShow; //排序规则展示样式 0-不展示 1-展示
List<SortRuleModel>? sortRules; //排序规则
HaiJiaoStyle.fromJson(Map<String, dynamic>? json) {
json ??= {};
defaultShow = json['defaultShow'];
sectionStyle = json['sectionStyle'];
showChosenVideo = json['showChosenVideo'];
sortShow = json['sortShow'];
final rules = json['sortRules'];
if (rules is List)
sortRules = rules.map((e) => SortRuleModel.fromJson(e)).toList();
}
}
class SortRuleModel {
int? val;
bool? top; //是否置顶
String? name;
//刷新模式 DEFAULT / RANDOM_TOP_N,判断随机刷新只认这个字段,不许匹配 name 或硬编码 val
String? refreshMode;
SortRuleModel.fromJson(Map<String, dynamic>? json) {
json ??= {};
val = json['val'];
top = json['top'];
name = json['name'];
refreshMode = json['refreshMode'];
}
bool get isRandomRefresh => refreshMode == 'RANDOM_TOP_N';
}
class HomePlateModel {
//解析一律走 _modules,字段缺失也退化成空列表,所以都是非空的,调用方不用判空
List<ModuleData> homePage = []; //首页-视频
List<ModuleData> deepWeb = []; //暗网
List<ModuleData> community = []; //社区
List<ModuleData> novel = []; //小说
List<ModuleData> pics = []; //图集:后端原始模块,展示要用 picsUi
List<ModuleData> game = []; //黄游:后端原始模块,展示要用 gameUi
List<ModuleData> dramaPage = []; //短剧专题(与 update-markers.modules 按 id 对齐)
//图集:固定注入「热门推荐」(type -100 对应 PIC 数据源) 再接后端模块
List<ModuleData> get picsUi => [
ModuleData(moduleName: '热门推荐', type: -100, showType: 1),
...pics,
];
//黄游:固定注入「热门推荐」(type -101 对应 SEED_LINK 数据源) 再接后端模块,showType 2 走列表样式
List<ModuleData> get gameUi => [
ModuleData(moduleName: '热门推荐', type: -101, showType: 2),
...game,
];
HomePlateModel.fromJson(Map<String, dynamic>? json) {
json ??= {};
homePage = _modules(json['homePage']);
deepWeb = _modules(json['deepWeb']);
community = _modules(json['community']);
novel = _modules(json['novel']);
pics = _modules(json['pics']);
game = _modules(json['game']);
dramaPage = _modules(json['dramaPage']);
}
//字段缺失或类型不对(后端偶发下发非数组)都退化成空列表,别让首页解析整个抛掉
static List<ModuleData> _modules(dynamic list) =>
(list is List ? list : const [])
.map((e) => ModuleData.fromJson(e))
.toList();
}