v63:卡片配色 / 日历本靠右 / 地图题图 / 设置页清理 / 公共标签颜色 / 令牌下线

- 卡片右上角按钮改用「来自哪个模块」的主题色:HomeCards 登记表新增 mod 字段
  与 module(),首页从登记表取色(原来是模板里硬编码 in_array(['agenda','tasks'])
  白名单,新加带按钮的卡片会默默变灰)
- 首页日程把日历本放到色块右侧:.ag-ev 改弹性行,「时间+标题」包进
  .ag-ev-main(flex:1 1 auto; min-width:0),日历本作右侧兄弟。
  原来 display:block 会把日历本顶到第二行,色块一矮就完全看不见
- 旅程地图显示题图:服务端把 media_url(cover_key) 塞进地图数据,
  地图卡片左侧 40x40 题图(object-fit:cover),没有题图不留灰框
- 系统设置第一块改叫「系统标语」;删掉「首页上那一行小字」提示、
  「不是全家的统一口号」说明、「上次结构升级有步骤失败了」整框;
  运行环境删「排错时看这一块」与「亲属连线」那一行(功能与数据未动)
- 公共标签:说明文字全删;列表与编辑合并成一行(色块+名字+N人+箭头+编辑);
  person_groups 加 color 列(Schema addColumn,老库可升);点「编辑」弹框
  改名字与颜色、点「完成」提交;下面那个独立编辑列表撤掉。删除挪进弹框
- 个人设置删掉「手动签发接口令牌」整块;settings/api_token 路由保留但挡下提交
  (只删界面会留下知道地址就能用的后门);令牌只由登录后自动签发,
  设备管理卡保留。apiTokens/apiPlain/apiLabel/apiBase 四个变量一并撤掉
This commit is contained in:
2026-10-19 17:27:37 +08:00
parent 2e40133d8f
commit 2f7dc6ca23
11 changed files with 450 additions and 189 deletions
+15 -80
View File
@@ -246,87 +246,22 @@ $rosterCount = $rosterCount ?? 0;
<?php endif; ?>
</div>
<div class="card card-pad" id="api" style="margin-top:20px">
<h2 class="section-title">
手动签发接口令牌
<span class="hint">第三方脚本 / 调试用;App 正常登录**不需要**这里</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 &lt;令牌&gt;</span>。
先调 <span class="mono">GET <?= e((string)$apiBase) ?>/api/v1/ping</span> 探连通(免令牌)。
<br>完整接口清单见仓库里的 <span class="mono">docs/API.md</span>。
</p>
<?php /* ==================== 手动签发接口令牌:v63 已整块删除 ====================
🔴 v63(用户 2026-10-19 第 7 条)用户原话:
「个人设置中:手动签发接口令牌,这一部分删除,不允许用户修改,
不允许用户手动签发令牌,只能通过登录后,系统自动签发令牌。」
<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">还没有手动签发的令牌。App 登录走上面的「设备管理」,不用在这里生成。</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>
⇒ 这一整块(接口根地址说明 + 用户名对账行 + 明文令牌回显 + 已签发列表 +
「生成新令牌」/「吊销全部」两个按钮)**全部撤掉**。
⚠️ 令牌机制本身一点没动:`api_tokens` 表、`Authorization: Bearer` 校验、
`settings/device_remove`(按设备踢)全都还在 —— 撤掉的只是"人手签发"这条入口。
令牌从此只有一个来源:**App 登录成功后由服务端自动签发**(见 ApiTokens::issue
在登录流程里的调用点),登记成一台设备,在上一张「设备管理」卡里可见可踢。
⚠️ 路由 `settings/api_token`(生成)也必须一起下线,否则它就是一个
"界面上找不到、但知道地址就能用"的后门 —— 那种入口比显式按钮危险得多。
保留 `settings/api_revoke`:**踢设备**是用户该有的能力(同上卡在用)。
⚠️ 别把这张卡改成"只读展示已签发令牌":那等于把"哪些设备在用我的账号"
又摆第二遍 —— 上面「设备管理」已经是那个清单了(按设备聚合,比按令牌行更准)。 */ ?>
<!-- ==================== 天气地点(用户 2026-10-03 第 1 条)==================== -->
<?php /* 原话:「天气这个这样吧,让用户在个人设置中填写自己的城市。」