Files
laoyang 075ac6bbeb v44 第 44 批:界面 5 条 + 移动端 API v1 全量
界面(用户 2026-10-12 第 1~5 条)
1. 新建日程「日历本」并入 .cs 自绘下拉,颜色画进候选项,三字与下拉同行。
2. 新建日程「开始/结束」改「日期范围:」,删旧日期控件;
   重复相关三行仅选重复时出现;删「(含第一次)」与「这段时间算忙碌」。
3. 条目浮层加「地点」、去掉「状态」行;首页红线按分钟定位(原只取整小时);
   去掉左侧红点只留红线。
4. 任务页删掉状态说明提示(STATUS_HINT 三值清空)。
5. 新建任务:标题在前树框在后;截止时间改最新日历控件;负责人默认自己;
   删冗余提示;「上面要做什么」→「任务名称」;清理括号说明。

移动端 API(用户第 6 条:导航模块除外,其余全量)
- 新增 Bearer 令牌鉴权(api_tokens 表,Schema v32),与登录口令 / DAV 口令三套分立。
- Api.php 内核(鉴权/取参/信封/分页/分发 + _method 覆写)+
  ApiHandler.php 17 条资源 + ApiToken.php + api.php 入口。
- 路由:router.php / .htaccess / index.php 三处 /api/ 兜底(部署脚本自动追加线上规则)。
- 个人设置新增「App 接口令牌」卡;docs/API.md 接口文档;
  docs/API-QUESTION-LIST.md 自主决策与待确认缺口清单。

验证:本地 e2e 1510/0、v43 真机 33/0、v43 反向 9/0、
v44 真机 41/0、v44 API 63/0、v44 反向 19/0;全流水线 PUSH_RC=0。
2026-10-12 15:31:03 +08:00

93 lines
4.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 前端控制器(路由表)—— 只给 **PHP 内置服务器** 用(php -S ... router.php)。
*
* 为什么要它:
* · 线上是 Apache,`/dav/3.ics/` 这种没有对应文件的 URL 靠 .htaccess 重写到 dav.php;
* · 本地 `php -S` **不读 .htaccess**,所以同一个地址会被当成"文件不存在"直接 404,
* 于是「CalDAV 在本地测不了、只能上线验证」——这正是最容易上线才发现问题的写法。
* 这个文件把那几条重写规则用 PHP 重述一遍,本地与线上一模一样的路径行为。
* (v24 第 22 批加了 CardDAV,同样两条:/dav/ 与 /carddav/。)
*
* ⚠️ 里面**不写任何业务**:只决定"交给哪个脚本",所有业务仍在 index.php / dav.php / media.php。
* 线上部署不该带它(Apache 走 .htaccess),但带着也无害 —— 它不会被执行。
*/
$path = (string)parse_url((string)($_SERVER['REQUEST_URI'] ?? '/'), PHP_URL_PATH);
// 🔴 v33:站点根的 DAV 请求(PROPFIND / REPORT / OPTIONS)→ dav.php。
// 为什么需要:RFC 6764 允许客户端从**域名根**开始发现 DAV 服务
// (`PROPFIND /` 问 current-user-principal),Thunderbird 就会走这条。
// Apache 把 `/` 交给 index.php(→ 302 登录页),客户端判定"这里没有日历"。
// ⇒ 只对 **DAV 方法**转发,`GET /` 仍是站点首页(绝不能把首页吞掉)。
// ⚠️ 线上等价物在 `.htaccess` 里(RewriteCond 判 REQUEST_METHOD)。
$method = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
if (($path === '/' || $path === '') && in_array($method, ['PROPFIND', 'REPORT', 'OPTIONS'], true)) {
require __DIR__ . '/dav.php';
return true;
}
// 🔴 v31:`/.well-known/caldav` 与 `/.well-known/carddav`(RFC 6764)。
// 标准客户端(DAVx⁵ / iOS / Evolution)添加账号时**第一句**就试这里 ——
// 原来没有这条路由,于是落到 index.php、被 302 去登录页,
// 客户端判定"域名下没有 DAV 服务",连口令框都不弹。
// 症状正是用户报的「同步不出任何数据」(账号根本建不起来)。
// ⚠️ 必须排在下面 dav/carddav 通配两条**之前**?不需要(前缀互不包含),
// 但**必须**排在后面"真实文件"判断之前 —— 这个目录线上并不存在。
if ($path === '/.well-known/caldav') {
require __DIR__ . '/dav.php';
return true;
}
if ($path === '/.well-known/carddav') {
require __DIR__ . '/carddav.php';
return true;
}
// CalDAV:/dav/ 及其子路径(/dav/、/dav/3.ics/、/dav/3.ics/12.ics)
if (preg_match('#^/dav(/.*)?$#', $path)) {
require __DIR__ . '/dav.php';
return true;
}
// CardDAV:/carddav/ 及其子路径(v24 第 22 批)
// ⚠️ 这条必须在下面那条"真实文件"判断**之前**:carddav.php 本身是个真文件,
// 但我们要的是把 /carddav/1.vcf/ 这种**不存在的路径**交给它处理;
// 顺序反了的话 /carddav/ 会去要一个不存在的目录 → 404。
if (preg_match('#^/carddav(/.*)?$#', $path)) {
require __DIR__ . '/carddav.php';
return true;
}
// 🔴 v44(用户 2026-10-12 第 6 条):移动端 API —— `/api/v1/...` 交给 api.php。
// ⚠️ 必须排在下面"真实文件"判断**之前**:`/api/v1/tasks` 不是真文件,
// 落到 index.php 会被当成未知路由(302 到登录页),App 端只会看到一坨 HTML。
// 线上等价物在 `.htaccess` 里(同样一条 RewriteRule)。
if (preg_match('#^/api(/|$)#', $path)) {
require __DIR__ . '/api.php';
return true;
}
// 导航**展示页**(v24 第 24 批 用户第 4 条):`/nav/?<短语>` —— 全站唯一免登录页面。
// ⚠️ 三条顺序**不能换**:
// ① `/nav/suggest.php` 是联想接口(免登录,但凭短语门禁放行);
// ② `/nav/` 恰好是展示页;
// ③ 两者都必须排在下面"真实文件"判断**之前** —— 否则 `/nav/` 会去找一个
// 不存在的目录 → 404(与上面 carddav 那条同一个坑)。
if ($path === '/nav/suggest.php') {
require __DIR__ . '/nav_suggest.php';
return true;
}
if (preg_match('#^/nav/?$#', $path)) {
require __DIR__ . '/nav_show.php';
return true;
}
// 真实存在的文件(静态资源、media.php 等)→ 交给内置服务器自己处理
$file = __DIR__ . $path;
if ($path !== '/' && is_file($file)) {
return false;
}
// 其余交给主路由
require __DIR__ . '/index.php';
return true;