面向高校学习与校园生活的原生 iOS 与 Android 应用,目前主要服务北京林业大学。
Android 正式版通过 官网与 GitHub Releases 下载。
MyLeafy 以课表和学业数据为核心,提供教务查询、个人记录、校园社区与共享课表。iOS 与 Android 均使用课表、校园、我的三个根 Tab,校园内包含社区、日迹和学校教学。两端独立发版,功能范围、验证证据和平台差异见跨端状态。
学校教务是课表、成绩等学校数据的权威来源;个人记录按校园身份本地保存。新版双端业务访问阿里云 ECS 上的 MyLeafy API,已安装旧版使用的 Supabase 服务继续保留。iOS 可主动开启限定范围的 iCloud 同步,实际生产与双设备验收单独记录;不代表 Android 已有同等云同步。
仓库名、Xcode target 与部分内部类型仍使用
leafy/Leafy。对外产品名称统一为 MyLeafy。
flowchart LR
Student["学生"]
Operator["运营人员"]
subgraph Product["MyLeafy 系统边界"]
direction TB
IOS["MyLeafy iOS<br/>课表 · 校园 · 我的"]
Local[("iOS 本地数据<br/>SwiftData · Keychain · 缓存")]
Android["MyLeafy Android<br/>课表 · 社区 · 日迹 · 校园 · 我的"]
AndroidLocal[("Android 本地数据<br/>Room · DataStore")]
Android --> AndroidLocal
Web["官网与运营后台<br/>公开页面 · 分享 · 内容治理"]
IOS -->|读写本地状态| Local
end
School["学校教务系统<br/>身份 · 课表 · 成绩 · 考试"]
Backend["阿里云 ECS 业务后端<br/>Node · SQLite · 文件 · Better Auth"]
Student -->|日常学习与校园任务| IOS
Student --> Android
Android -->|授权教务查询| School
Android -->|业务 API| Backend
Operator -->|受控运营| Web
IOS -->|授权访问教务数据| School
IOS -->|用户会话 + 业务 API| Backend
Web -->|管理代理 + 服务端授权| Backend
classDef actor fill:#F8FAFC,stroke:#64748B,color:#0F172A,stroke-width:1.5px;
classDef owned fill:#ECF7F0,stroke:#397A5A,color:#173C2B,stroke-width:2px;
classDef external fill:#FFF8E8,stroke:#B7791F,color:#5F3B0B,stroke-width:1.5px;
classDef data fill:#EDF4FF,stroke:#4776B5,color:#173B68,stroke-width:1.5px;
class Student,Operator actor;
class IOS,Android,Web owned;
class School,Backend external;
class Local,AndroidLocal data;
以下是产品能力概览,平台是否具备、验证与交付状态以跨端状态为准。
| 领域 | 当前能力 |
|---|---|
| 课表 | 课程网格、个人日程、备注与提醒、背景、导出及共享;iOS 使用固定 20 周容器和 1–24 节自定义作息,小组件和系统扩展按平台能力开放 |
| 校园 | 成绩、考试、教学计划、培养方案、校历、自习安排(空闲教室等内部工具、图书馆座位预约、校园热力图)、学习空间、体育与职业相关工具 |
| 社区 | 帖子、图片、评论、点赞、投票、通知、公告、个人内容与内容分享 |
| 日迹 | 随记、个人日程与推送;“记录”分组提供“记录日迹”和“每日回顾”;记录日迹按自然年查看月度随记数/记录天数、近 30 天热力、连续记录、星期/时段习惯、常用标签和里程碑,可点日期查看当天随记;统计图本机生成并通过系统分享,只含聚合统计,不上传;输入器支持聚焦展开,并在达到四个视觉行时提供放大/缩小编辑;加号菜单不再新建文章,历史文章仍可查看编辑;随记和日程按校园身份保存在本地 |
| 评价 | 教师、课程等结构化评分;详情页星级居中,数据能力按校园配置开放 |
| 个性化 | 浅色/深色外观、主题色、显示密度、多语言,以及照片和纯色课表背景 |
| 运营 | 独立 Web 管理后台、角色权限、内容管理、配置管理、审计与受控导出 |
功能是否显示由校园能力配置、用户身份与后端配置共同决定。各校园环境仅开放符合当前配置的入口。
MyLeafy 采用双端原生界面、边界清晰和本地可用的工程策略:
- SwiftUI 构建页面与导航,iOS 17 为部署基线;根导航使用系统
TabView,不叠加页面透明度伪造淡入;在 iOS 26 上使用受可用性检查保护的系统视觉能力。 - 教务数据通过
URLSession、显式 Cookie 管理和 SwiftSoup 解析;课表链路在必要时使用WKWebView复现浏览器路径。 - SwiftData 保存课表、成绩、按校园身份隔离的随记与个人日程等用户侧本地数据;页面通过预计算投影与展示数据降低复杂网格的渲染成本。
- Android 使用 Compose / Material 3、Room、DataStore、OkHttp 和 jsoup,保持平台交互及身份作用域。
- Node 24、Hono、SQLite、本地文件、WebSocket 与 Better Auth 在 ECS 承载非教务业务;服务端统一校验会话、校园范围和资源所有权,关联写入使用原子事务。
- Caddy 托管网站,Node 提供同域管理/分享/发行代理,内部管理处理器不暴露为公共路由;管理会话使用 HttpOnly Cookie。
详细边界、数据流和依赖方向见当前架构。
| 范围 | 技术 |
|---|---|
| iOS UI | SwiftUI |
| Android | Kotlin、Compose / Material 3、Room、DataStore、OkHttp、jsoup |
| 本地持久化 | SwiftData |
| 教务网络 | URLSession、HTTPCookieStorage、WKWebView |
| HTML 解析 | SwiftSoup |
| 系统服务 | WeatherKit、WidgetKit、Keychain |
| 业务后端 | ECS、Node 24、Hono、SQLite、文件与 WebSocket、Better Auth;Resend 验证邮件 |
| Web 后台 | React 18、Tailwind/Radix、TanStack Query/Table、React Hook Form、ECharts、Vite、TypeScript |
| 网关与代理 | Caddy HTTPS、Node 同域代理 |
| 自动化检查 | GitHub Actions、Vitest、Playwright、XCTest |
leafy/
├── leafy/ # iOS 主应用
│ ├── App/ # 应用启动、根导航、主题与生命周期
│ ├── Core/ # 依赖、持久化、校园能力、并发等基础设施
│ ├── Features/ # Auth、Timetable、Community、Schedule、Discover、Profile
│ ├── Services/ # 教务、MyLeafy API、同步与诊断服务
│ ├── Parsers/ # 教务 HTML 解析
│ └── Shared/ # 跨功能模型与共享组件
├── leafyTests/ # iOS 单元与契约测试
├── leafyWidget/ # Widget 扩展
├── LeafyShareExtension/ # 系统分享扩展
├── android/ # Kotlin / Compose 原生客户端
├── backend/ # Node API、SQLite migrations、业务测试与迁移工具
├── supabase/ # 旧版服务与迁移源,仍保留运行
├── site/ # 官网、运营后台与同域代理处理器
├── Config/ # 可提交的配置模板;本地密钥文件不入库
├── docs/ # 产品、设计、工程与运维文档(设计与规划)
├── state/ # 当前真实状态:进度与架构(CURRENT / ARCHITECTURE)
└── logs/ # 可复用的排查与根因知识
- macOS 与 Xcode 26 或更新版本(项目引用 iOS 26 SDK API,并为 iOS 17–25 提供运行时回退)
- iOS 17.0 或更新版本的模拟器/设备
- Node.js 与 npm:后端/ECS 使用 Node 24.22.1;网站静态 CI 版本以其工作流为准,依赖使用锁文件
- 可用的目标学校教务账号(验证真实教务链路时需要)
- 可用的 MyLeafy staging API(验证社区、共享与运营能力时需要)
git clone https://github.com/IsaacHuo/MyLeafy.git leafy
cd leafy
cp Config/Leafy.example.xcconfig Config/Leafy.local.xcconfig
open leafy.xcodeproj在 Config/Leafy.local.xcconfig 中设置 MYLEAFY_API_ORIGIN,然后选择 leafy scheme 运行。默认使用 https://api.myleafy.space;隔离调试使用 staging 域名。App 不携带数据库或服务端密钥,本地 xcconfig、证书和描述文件不得提交。
仅验证本地功能时可使用免登录入口;该身份不连接后台,课表、随记与个人日程保存在本机。
环境、构建与候选发布见 Android README。格式工具与本地/CI 命令见代码规范。
cd site
npm ci
npm run devnpm run dev 适合公开页面或 mock API 下的后台开发。实际同域代理由 Node 后端提供,私有/公开 staging 的配置见 ECS 交付;网站职责见 site/README.md。
backend/ 提供 /v1 业务 API、SQLite 迁移、文件校验、WebSocket 与持久化清理任务。Caddy 提供 HTTPS 和静态网站,管理处理器只经同域代理调用。
cd backend
npm ci
npm run typecheck
npm run check:contracts
npm test
npm run build运行需要隔离的数据库、对象目录及受保护环境文件;正式部署消费已验收的同一产物,并保留 production 所有者审批。见 ECS 交付与恢复。服务器配置及换机手册在 Configuration/myleafy-ecs,密钥和数据备份独立保存。
supabase/ 继续服务已安装旧客户端;其命令不适用于当前 ECS。部分客户端内部类型/路径保留 Cloudflare 名称,现网服务由 ECS 提供。旧 Cloudflare 源已冻结保留,不再执行原部署流程。
任务讨论见 Issues,进度与验收见 MyLeafy Development。贡献方式见 CONTRIBUTING。
| 文档 | 适用读者 | 内容 |
|---|---|---|
| 项目总览 | 所有人 | 产品定位、能力范围、数据边界与限制 |
| 跨端状态 | 所有人 | iOS / Android 实现、验证、交付与差异 |
| 当前架构 | 各端开发者 | 当前分层、依赖、教务链路、本地存储与系统边界 |
| App 产品设计 | 产品与客户端开发者 | 信息架构、核心流程、页面状态与产品原则 |
| UI 风格规范 | 设计与客户端开发者 | 设计令牌、组件、可访问性与页面模式 |
| ECS 后端 | 后端与客户端开发者 | API、认证、存储、迁移与验证边界 |
| 旧 Supabase 服务 | 旧服务维护者 | 旧版服务与迁移源说明 |
| 运营后台 | Web/后端开发者 | 管理架构、角色、安全、资源与开发验证 |
| 贡献规范 | 贡献者 | Issue、分支、PR、测试与安全要求 |
文档索引见 docs/README.md。当前开发状态见 state/CURRENT.md,可复用排查知识见 logs/。
- 教务系统不是稳定 API。页面结构、登录流程或网络策略变化可能使解析暂时失效。
- 当前教务身份绑定由 App 在登录成功后发起;它不等同于服务端对学校身份进行独立证明。
- 社区、评价和共享能力依赖正确部署的 ECS API、SQLite schema、对象目录与服务端权限检查。
- 教师与课程等目录型数据需要经过可信来源整理或后台审核,仓库不会自动保证数据完整性。
- 这是持续演进中的校园产品,内部数据模型与未稳定接口可能变化。
项目近期优先提高教务解析稳定性、完善错误与恢复流程、收紧后端安全边界,并支持不同校园通过能力配置复用基础架构。未来功能以实际使用反馈为依据,不承诺固定时间表。
提交代码前请阅读贡献规范。涉及新功能或行为变化的 PR 应同时更新对应文档;涉及用户数据、认证、校园身份或管理权限的改动必须说明安全边界与验证方式。
除另有说明外,本仓库中的原创源代码和项目文档使用 Apache License 2.0 许可。MyLeafy 名称、商标、Logo、校园照片、产品截图、第三方内容和用户数据不因该许可证获得额外授权;第三方材料继续遵循各自的许可与权利声明。
- 问题与建议:GitHub Issues
- 邮箱:
support@myleafy.space