Files
Navius/frontend/lib/features/home/domain/models/link_item.dart
CNWei 1c98340fc5 feat: 实现导航页基础功能
- 添加导航条目和分类数据模型
- 实现导航卡片网格展示
- 支持点击卡片打开链接
- 添加主题样式(渐变色、卡片阴影)
- 区分系统默认和自定义条目
- 添加分类统计信息"
2026-09-19 21:53:15 +08:00

82 lines
2.2 KiB
Dart

import '../../../../core/utils/text.dart';
/// 一张站点卡片,对应 `index.html` 里的 `.card`。
class LinkItem {
const LinkItem({
required this.id,
required this.title,
required this.url,
this.categoryId = '',
this.description = '',
this.editable = false,
});
/// 从 JSON 构造(将来接后端接口时使用)。
factory LinkItem.fromJson(Map<String, dynamic> json) {
return LinkItem(
id: json['id'] as String,
title: json['title'] as String,
url: json['url'] as String,
categoryId: json['categoryId'] as String? ?? '',
description: json['description'] as String? ?? '',
editable: json['editable'] as bool? ?? false,
);
}
/// 唯一标识。
final String id;
/// 站点名称,同时用于生成卡片左上角的首字母图标。
final String title;
/// 跳转地址。
final String url;
/// 所属分组 id。编辑时要靠它反查出分组名,才能把表单预填对。
final String categoryId;
/// 一句话描述。
final String description;
/// 这条能不能改。
///
/// 后端按 `source != "system"` 推导出 `editable`:系统内置的条目只读,
/// 卡片上不会出现编辑/删除;用户提交和接口推送进来的可以改、可以删。
final bool editable;
/// 卡片图标显示的首字符。
String get initial => firstChar(title).toUpperCase();
/// 展示用域名。
String get host => Uri.tryParse(url)?.host ?? url;
/// 序列化为 JSON。
Map<String, dynamic> toJson() => <String, dynamic>{
'id': id,
'title': title,
'url': url,
'categoryId': categoryId,
'description': description,
'editable': editable,
};
@override
bool operator ==(Object other) {
return identical(this, other) ||
other is LinkItem &&
other.id == id &&
other.title == title &&
other.url == url &&
other.categoryId == categoryId &&
other.description == description &&
other.editable == editable;
}
@override
int get hashCode =>
Object.hash(id, title, url, categoryId, description, editable);
@override
String toString() => 'LinkItem(id: $id, title: $title)';
}