feat: 进行功能分区方便后期维护

- 添加导航条目和分类数据模型
- 实现导航卡片网格展示
- 支持点击卡片打开链接
- 添加主题样式(渐变色、卡片阴影)
- 区分系统默认和自定义条目
- 添加分类统计信息"
This commit is contained in:
2026-09-13 22:49:02 +08:00
parent 4075519075
commit e2cc3ac30f
40 changed files with 3379 additions and 515 deletions
@@ -0,0 +1,13 @@
import '../domain/models/home_data.dart';
/// 首页数据仓库契约。
///
/// 界面层只认这个接口,不关心数据来自本地 mock 还是 Rust 后端。
///
/// 目前是同步返回:mock 数据是恒定常量,加一层 Future 只会凭空多出
/// loading / error 分支。等真正走网络请求时,把返回值改成
/// `Future<HomeData>`,改动范围仅限实现类与页面的一次数据加载。
abstract interface class HomeRepository {
/// 读取首页需要的全部数据。
HomeData fetchHomeData();
}
@@ -0,0 +1,83 @@
import '../domain/models/home_data.dart';
import '../domain/models/link_item.dart';
import '../domain/models/link_section.dart';
import '../domain/models/nav_node.dart';
/// 侧栏导航树,与 `index3.html` 的 `<ul class="nav-group">` 一一对应。
const List<NavNode> mockNavNodes = <NavNode>[
NavNode(id: 'common', title: '常用推荐'),
NavNode(
id: 'materials',
title: '素材资源',
children: <NavNode>[
NavNode(id: 'design', title: 'UI 设计'),
NavNode(id: 'icon', title: '图标库'),
NavNode(id: 'stock', title: '高清壁纸'),
],
),
NavNode(
id: 'dev-tools',
title: '开发工具',
children: <NavNode>[
NavNode(id: 'dev', title: '前端框架'),
NavNode(id: 'api', title: '在线 API'),
],
),
];
/// 内容区分组,与 `index3.html` 的两段内容一一对应。
///
/// 原型只写了 `#common` 与 `#design` 两段;导航里的 `#icon`、`#stock`、
/// `#dev`、`#api` 在原型中没有对应元素,点击不会发生任何事——这里保持一致。
const List<LinkSection> mockLinkSections = <LinkSection>[
LinkSection(
id: 'common',
title: '常用推荐',
items: <LinkItem>[
LinkItem(
id: 'github',
title: 'GitHub',
url: 'https://github.com',
description: '代码托管与开源社区',
),
LinkItem(
id: 'zhihu',
title: '知乎',
url: 'https://www.zhihu.com',
description: '深度内容问答社区',
),
LinkItem(
id: 'bilibili',
title: '哔哩哔哩',
url: 'https://www.bilibili.com',
description: '弹幕视频分享网站',
),
],
),
LinkSection(
id: 'design',
title: '素材资源 - UI 设计',
items: <LinkItem>[
LinkItem(
id: 'figma',
title: 'Figma',
url: 'https://www.figma.com',
description: '协同界面设计工具',
),
LinkItem(
id: 'dribbble',
title: 'Dribbble',
url: 'https://dribbble.com',
description: '全球设计作品分享社区',
),
],
),
];
/// 首页聚合数据。
const HomeData mockHomeData = HomeData(
siteName: 'Suxing Nav',
searchHint: '输入关键字搜索全网资源...',
navNodes: mockNavNodes,
sections: mockLinkSections,
);
@@ -0,0 +1,14 @@
import '../domain/models/home_data.dart';
import 'home_repository.dart';
import 'mock_home_data.dart';
/// [HomeRepository] 的本地实现,返回 [mockHomeData]。
///
/// 单独建一个类而不是让页面直接读常量:页面因此只依赖接口,
/// 换成后端实现时不用碰界面代码,测试里也能注入任意数据集。
class MockHomeRepository implements HomeRepository {
const MockHomeRepository();
@override
HomeData fetchHomeData() => mockHomeData;
}