feat: 实现导航页基础功能

- 添加导航条目和分类数据模型
- 实现导航卡片网格展示
- 支持点击卡片打开链接
- 添加主题样式(渐变色、卡片阴影)
- 区分系统默认和自定义条目
- 添加分类统计信息"
This commit is contained in:
2026-09-19 21:53:15 +08:00
parent e2cc3ac30f
commit 1c98340fc5
42 changed files with 6054 additions and 140 deletions
@@ -1,13 +1,36 @@
import '../domain/models/home_data.dart';
import '../domain/models/submit_site_draft.dart';
/// 首页数据仓库契约。
///
/// 界面层只认这个接口,不关心数据来自本地 mock 还是 Rust 后端。
///
/// 目前是同步返回:mock 数据是恒定常量,加一层 Future 只会凭空多出
/// loading / error 分支。等真正走网络请求时,把返回值改成
/// `Future<HomeData>`,改动范围仅限实现类与页面的一次数据加载。
/// 两个方法都是异步的:接上后端之后「加载中 / 提交中」和「失败」都是必须
/// 表达的状态,所以契约从一开始就按异步来——mock 实现直接返回已经就绪的值。
abstract interface class HomeRepository {
/// 读取首页需要的全部数据。
HomeData fetchHomeData();
Future<HomeData> fetchHomeData();
/// 提交一个网站。
///
/// 成功不返回内容:后端会回创建出来的条目,但页面用不到(提交完重新拉一次
/// `/api/nav` 就有了)。失败时抛 [HomeFailure],`message` 可以直接展示。
Future<void> submitSite(SubmitSiteDraft draft);
/// 修改一个已有的网站(只能改用户提交 / 接口推送进来的,系统内置的会返回 403)。
Future<void> updateSite(String id, SubmitSiteDraft draft);
/// 删除一个已有的网站(同样只对可修改的条目有效)。
Future<void> deleteSite(String id);
}
/// 取数或提交失败。[message] 是可以直接显示给用户的说明。
class HomeFailure implements Exception {
const HomeFailure(this.message);
/// 面向用户的说明。
final String message;
@override
String toString() => message;
}