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。
This commit is contained in:
@@ -149,6 +149,99 @@ $rosterCount = $rosterCount ?? 0;
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 移动端 API 令牌(v44 用户第 6 条)==================== -->
|
||||
<?php /* 用户原话:「我们现在马上要开始移动终端的开发,所以现在要开发所有接口。」
|
||||
这张卡是**发令牌**的地方 —— 没有它,App 连不上(接口做完了也没入口)。
|
||||
|
||||
为什么与 DAV 口令**分开**:
|
||||
· DAV 那把是给第三方同步客户端(DAVx⁵ / iOS 日历)的,走 Basic 鉴权、
|
||||
明文要手打进手机、一把管日历+通讯录;
|
||||
· API 令牌是给**自家 App** 的,走 `Authorization: Bearer`、可多枚
|
||||
(一台设备一枚)、可逐枚吊销、可设有效期、带设备名。
|
||||
两件事的生命周期完全不同(吊销 DAV 口令会连带断掉日历同步;
|
||||
吊销一枚 App 令牌不该影响别人的手机)。 */ ?>
|
||||
<div class="card card-pad" id="api" style="margin-top:20px">
|
||||
<h2 class="section-title">
|
||||
App 接口令牌
|
||||
<span class="hint">移动端 / 第三方程序调用用</span>
|
||||
</h2>
|
||||
<p class="small muted" style="margin:0 0 14px">
|
||||
接口地址前缀 <span class="mono"><b><?= e((string)$apiBase) ?>/api/v1/</b></span>,
|
||||
请求头带 <span class="mono">Authorization: Bearer <令牌></span>。
|
||||
先调 <span class="mono">GET <?= e((string)$apiBase) ?>/api/v1/ping</span> 探连通(免令牌)。
|
||||
<br>完整接口清单见仓库里的 <span class="mono">docs/API.md</span>。
|
||||
</p>
|
||||
|
||||
<div class="form-grid">
|
||||
<div class="field full">
|
||||
<label>接口根地址</label>
|
||||
<input class="input mono" readonly value="<?= e((string)$apiBase . '/api/v1') ?>">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>用户名 / 手机号</label>
|
||||
<input class="input mono" readonly value="<?= e((string)$person['name']) ?>">
|
||||
<span class="tip">令牌本身就是凭据,这一行只是给你对账用。</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($apiPlain)): ?>
|
||||
<p class="tip" style="background:#FFF6E5;border-color:#E8C98A;padding:10px 12px;border-radius:8px">
|
||||
<b>这是你的新令牌,只显示这一次,请立刻复制到 App 里:</b>
|
||||
<?php if ((string)$apiLabel !== ''): ?>
|
||||
(设备名:<?= e((string)$apiLabel) ?>)
|
||||
<?php endif; ?>
|
||||
<br><code class="mono" style="font-size:14px;word-break:break-all"><?= e((string)$apiPlain) ?></code>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($apiTokens)): ?>
|
||||
<table class="res-table" style="width:100%;margin:6px 0 10px">
|
||||
<thead>
|
||||
<tr><th>设备名</th><th>签发时间</th><th>最近使用</th><th></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($apiTokens as $tk): ?>
|
||||
<tr>
|
||||
<td><?= e((string)($tk['label'] ?: '(未命名)')) ?></td>
|
||||
<td class="small muted"><?= e((string)($tk['created_at'] ?? '')) ?></td>
|
||||
<td class="small muted"><?= e((string)($tk['last_used_at'] ?? '还没用过')) ?></td>
|
||||
<td>
|
||||
<form method="post" action="<?= e(url('settings/api_revoke')) ?>" class="res-inline"
|
||||
onsubmit="return confirm('吊销这枚令牌?这台设备会立刻掉线。')">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="id" value="<?= (int)$tk['id'] ?>">
|
||||
<button class="btn btn-ghost btn-sm" type="submit">吊销</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<p class="small muted">还没有令牌。给每台设备发一枚吧。</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (\App\Auth::canWrite()): ?>
|
||||
<div class="btn-row">
|
||||
<form method="post" action="<?= e(url('settings/api_token')) ?>" class="res-inline">
|
||||
<?= csrf_field() ?>
|
||||
<input class="input" name="label" placeholder="设备名(如:我的手机)" style="max-width:200px">
|
||||
<button class="btn btn-sm" type="submit">生成新令牌</button>
|
||||
</form>
|
||||
<?php if (!empty($apiTokens)): ?>
|
||||
<form method="post" action="<?= e(url('settings/api_revoke')) ?>" class="res-inline"
|
||||
onsubmit="return confirm('吊销全部令牌?所有 App 都要重新登录。')">
|
||||
<?= csrf_field() ?>
|
||||
<button class="btn btn-ghost btn-sm" type="submit">吊销全部</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<p class="small muted" style="margin:10px 0 0">
|
||||
令牌只在生成那一次显示明文(库里只存哈希)。手机丢了就吊销那一枚。
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 天气地点(用户 2026-10-03 第 1 条)==================== -->
|
||||
<?php /* 原话:「天气这个这样吧,让用户在个人设置中填写自己的城市。」
|
||||
所以地点从系统设置搬到了这里 —— 而且改成**城市名**,不是经纬度:
|
||||
|
||||
Reference in New Issue
Block a user