From 9c97579843971b01b87ae4db8a2f590dd86e06ac Mon Sep 17 00:00:00 2001 From: xiaoz Date: Mon, 27 Apr 2026 13:03:31 +0800 Subject: [PATCH] 1.2.3 --- .gitignore | 3 ++ AGENTS.md | 44 +++++++++++++++++++++++++++ class/Api.php | 26 ++++++++++++++-- controller/api.php | 6 ++-- data/update.log | 4 +++ templates/admin/index.php | 5 +++ templates/admin/setting/subscribe.php | 7 ++++- templates/admin/static/embed.js | 2 +- version.txt | 2 +- 9 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 .gitignore create mode 100644 AGENTS.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4484209 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +class/cache +data/config.php +data/onenav.db3 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..5456f77 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,44 @@ +# AGENTS + +- 全程使用中文输出,包括分析、进度说明、变更说明、提交信息建议;不要默认切回英文。 + +## 入口与分发 + +- 真实入口是根目录 `index.php`,不要从 README 猜流程。 +- `index.php` 启动顺序固定:先检查 `data/config.php`,不存在就进入 `controller/init.php`;再检查 `data/onenav.db3`,不存在时从 `db/onenav.simple.db3` 复制;然后 `require ./data/config.php`;最后按 `?c=` 分发到 `controller/*.php`。 +- 未传 `c` 时进入 `controller/index.php`;`?c=api`、`?c=admin`、`?c=login`、`?c=mobile` 等都直接映射到 `controller/.php`。 +- `index.php` 会拒绝包含 `./` 的控制器参数;改路由时不要破坏这层基于文件名的动态分发。 +- `.htaccess` 只做两条重要伪静态:`/click/` -> `index.php?c=click&id=`,`/api/` -> `index.php?c=api&method=`。 + +## 关键目录 + +- `controller/` 放页面/入口控制器,真正的 API 业务主要在 `class/Api.php`,不要只改 `controller/api.php` 的参数转发层。 +- `functions/helper.php` 放登录态、主题枚举、移动端跳转等共享函数;前台首页和后台都依赖它。 +- 后台管理的大部分前端交互、表格渲染和 API 调用集中在 `templates/admin/static/embed.js`;改后台管理行为时要同时检查这个文件。 +- 内置主题在 `templates/`,用户自定义主题走 `data/templates/`;代码里默认先找内置目录,再回退到 `data/templates/`。 +- `db/onenav.simple.db3` 是初始化种子库,`data/onenav.db3` 是运行中的真实数据。 + +## 运行与状态文件 + +- `data/config.php` 和 `data/onenav.db3` 是本地实例状态文件,且被 `.gitignore` 忽略;除非用户明确要求,不要覆盖、删除、重建这两个文件。 +- 安装流程依赖 `config.simple.php` 模板生成 `data/config.php`;涉及初始化逻辑时,同时检查 `controller/init.php` 和 `config.simple.php`。 +- `controller/init.php` 的可执行约束比 README 更可信:初始化会检查 `pdo_sqlite`、`openssl`、`zlib`、`curl`,并拒绝二级目录安装。 + +## 前台与主题流程 + +- `controller/index.php` 会先查 `on_options.s_site` 和分类/链接,再决定主题;不要只看模板目录名判断首页行为。 +- 未配置主题时默认 `default2`;已配置时按 UA 在 `s_themes` 中区分 `pc_theme` 和 `mobile_theme`。 +- `?theme=` 只允许切到 `get_all_themes()` 返回的主题;这个函数会排除 `admin`、`mobile`、`universal`。 +- 主题配置文件兼容两套命名:优先 `config.json`,其次 `info.json`;内置主题和 `data/templates/` 都要一起兼容。 + +## 认证与 API 约束 + +- 登录态不是 PHP session,而是 `key` cookie;`functions/helper.php::is_login()` 会把它和 `USER + ENCRYPTED_PASSWORD + onenav + User-Agent` 的 MD5 比较。 +- `class/Api.php::auth()` 允许两种 API 鉴权:`token=md5(USER + SecretKey)` 或请求头 `X-Token`;没传 token 时会退回 cookie 登录态。 +- 后台和移动后台都依赖同一套 cookie 登录判断;改鉴权时要一起看 `controller/admin.php`、`controller/mobile.php`、`controller/login.php`。 + +## 验证方式 + +- 仓库里没有可验证的 `composer.json`、`package.json`、CI workflow、lint/test 配置;不要臆造 `composer test`、`npm run build` 之类命令。 +- 对 PHP 改动,最小可执行验证是对改过的文件运行 `php -l `。 +- 对路由或接口改动,优先按真实入口验证:`/index.php?c=...` 或重写后的 `/api/...`、`/click/...`。 diff --git a/class/Api.php b/class/Api.php index 4ae9f25..0b6ddf7 100755 --- a/class/Api.php +++ b/class/Api.php @@ -753,10 +753,12 @@ class Api { */ public function export_link(){ //鉴权 - $this->auth($token); + $this->auth(''); // 一次性获取所有分类与链接,减少查询次数 $categories = $this->db->select("on_categorys", [ "id","name","fid","weight","add_time" + ],[ + "ORDER" => ["fid" => "ASC", "weight" => "DESC", "id" => "DESC"] ]); $links = $this->db->select("on_links", [ "id","fid","title","url","add_time","weight" @@ -777,6 +779,8 @@ class Api { 'id' => $c['id'], 'name' => $c['name'], 'fid' => $c['fid'], + 'weight' => isset($c['weight']) ? intval($c['weight']) : 0, + 'add_time' => isset($c['add_time']) ? $c['add_time'] : '', 'links' => isset($linksByCat[$c['id']]) ? $linksByCat[$c['id']] : [], 'children' => [] ]; @@ -797,6 +801,25 @@ class Api { } } unset($node); + + $sortCategoryTree = function (&$nodes) use (&$sortCategoryTree) { + usort($nodes, function ($a, $b) { + $weightDiff = intval($b['weight']) - intval($a['weight']); + if ($weightDiff !== 0) { + return $weightDiff; + } + return intval($b['id']) - intval($a['id']); + }); + + foreach ($nodes as &$item) { + if (!empty($item['children'])) { + $sortCategoryTree($item['children']); + } + } + unset($item); + }; + + $sortCategoryTree($tree); return $tree; } /** @@ -3367,4 +3390,3 @@ class Api { } - diff --git a/controller/api.php b/controller/api.php index 53a3d91..a6601c6 100755 --- a/controller/api.php +++ b/controller/api.php @@ -584,10 +584,10 @@ function export_link($api) { HTML; - // 构造根目录“书签栏”包裹所有顶级分类 + // 构造浏览器兼容的根目录,名称使用 Bookmarks 以兼容导入器忽略系统根目录的逻辑 $rootAdd = $now; $rootMod = $now; - echo "

OneNav

\n"; + echo "

Bookmarks

\n"; echo "

\n"; foreach ($tree as $topCat) { @@ -771,4 +771,4 @@ function get_subscribe(){ function get_subscribe_status(){ global $api; $api->get_subscribe_status(); -} \ No newline at end of file +} diff --git a/data/update.log b/data/update.log index e91d010..96f0c8f 100755 --- a/data/update.log +++ b/data/update.log @@ -1,3 +1,7 @@ +2026.04.27 +1. 【后台 - 链接管理 - 我的链接】,导出所有链接支持保留二级分类。 +2. 后台首页和订阅页面,新增ZMark发布提示。 + 2025.09.01 1. 导出所有链接支持二级分类 2. 删除空白的default3主题 diff --git a/templates/admin/index.php b/templates/admin/index.php index adec37d..d7ec8a7 100755 --- a/templates/admin/index.php +++ b/templates/admin/index.php @@ -5,6 +5,11 @@

+
+
+ OneNav重构版ZMark现已发布,点此了解如何升级。 +
+
diff --git a/templates/admin/setting/subscribe.php b/templates/admin/setting/subscribe.php index 4f6512e..1a8c07d 100755 --- a/templates/admin/setting/subscribe.php +++ b/templates/admin/setting/subscribe.php @@ -5,6 +5,11 @@
+
+
+ OneNav重构版ZMark现已发布,点此了解如何升级。 +
+
@@ -270,4 +275,4 @@ $("#btn_update").show(); $("#btn_updating").hide(); } - \ No newline at end of file + diff --git a/templates/admin/static/embed.js b/templates/admin/static/embed.js index c4ca947..acea03c 100755 --- a/templates/admin/static/embed.js +++ b/templates/admin/static/embed.js @@ -1166,7 +1166,7 @@ function set_link_attribute(ids,property) { //导出所有链接 function export_link(url, fileName) { - layer.confirm('导出的链接可以导入到浏览器也可以再次导入到OneNav!', {icon: 3, title:'确定导出所有链接?'}, function(index){ + layer.confirm('导出的链接可以导入到浏览器也可以再次导入到OneNav/ZMark!', {icon: 3, title:'确定导出所有链接?'}, function(index){ var date = new Date(); var current_time = date.toLocaleDateString(); current_time = current_time.replaceAll("/","."); diff --git a/version.txt b/version.txt index c82b86c..15842ff 100755 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v1.2.2-20250901 \ No newline at end of file +v1.2.3-20260427 \ No newline at end of file