笔记图片块:补 API 上传子端点(图文混排的前半程)#23
用户原话(2026-10-28):「鸿蒙端对齐网页端」,笔记端上只支持纯文本, 图片块显示成「[图片]」,且编辑带图笔记会静默删光图片块。 这半程只改服务端、补一个缺口: · POST /api/v1/notes/upload —— 笔记图片上传,返回附件 key。 放在 notes() 的 $id>0 分支之前(上传是草稿态,不依赖笔记 id, 新建笔记插图时还没有 id)。图片先挂 target_id=0,等 blocks 带 key 提交时由 Note::claimUploads 认领(与 Web 端 notes/upload 同一套)。 Attachment::save 只回 id 不回 key ⇒ 反查 Note::ATTACH=0 的 list 拿 key。 · dispatch 里 notes case 从 notes($id,$method) 改成 notes($id,$sub,$method), 否则 $sub='upload' 根本传不进去(405)。 判据: · _i23_note_image_api.py 11/0(上传返 key · 带 blocks 新建后 text+image 两块都在 · PATCH 后图片块不被删 —— 这是 P0 数据丢失修复的核心证据) · _i23_falsify.py 注掉 upload 分支 → ①② 变红(命中 2/2)
This commit is contained in:
+47
-2
@@ -111,7 +111,7 @@ final class ApiHandler
|
||||
case 'ledger': $this->ledger($id, $sub, $method); return;
|
||||
case 'resources': $this->resources($id, $method); return;
|
||||
case 'books': $this->books($id, $sub, $method); return;
|
||||
case 'notes': $this->notes($id, $method); return;
|
||||
case 'notes': $this->notes($id, $sub, $method); return;
|
||||
// 🔴 v45:登录(手机号 + 密码 → API 令牌)。
|
||||
// 为什么必须走 API 而不是网页登录后复制 Cookie:
|
||||
// App 是 Bearer 令牌那套,没有会话;而原先前端只能让人
|
||||
@@ -2878,9 +2878,54 @@ final class ApiHandler
|
||||
]));
|
||||
}
|
||||
|
||||
private function notes(int $id, string $method): void
|
||||
private function notes(int $id, string $sub, string $method): void
|
||||
{
|
||||
[$fam, $pid] = Api::me();
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════
|
||||
工单 #23(用户 2026-10-28「鸿蒙端对齐网页端」):笔记图片块。
|
||||
|
||||
端上要"图文混排"(往笔记里插图),缺两步:
|
||||
· 上传图片拿附件 key → 这里补 `POST /api/v1/notes/upload`
|
||||
· 拿到的 key 作为 `image` 块塞进 `blocks` 存 —— `noteBlocksIn()`
|
||||
本来就认 `blocks` 数组(见 `cleanBlocks` 的 image 分支),
|
||||
`Note::claimUploads` 也会按块里的 key 把"草稿附件"认领到笔记上。
|
||||
|
||||
🔴 上传是**草稿态**、**不依赖笔记 id**(新建笔记时还没有 id):
|
||||
图片先挂在 target_id=0,等 `blocks` 带 key 提交时再认领——
|
||||
与 Web 端 `notes/upload` 路由同一套语义。
|
||||
⚐ 注意:`Notes/upload` 的 `$sub='upload'`、`$id=0`,所以这里必须
|
||||
放在 `if ($id > 0)` **之前**(否则新建笔记插不了图)。
|
||||
═══════════════════════════════════════════════════════════ */
|
||||
if ($sub === 'upload') {
|
||||
Api::requireWrite();
|
||||
if ($method === 'POST') {
|
||||
$file = $_FILES['file'] ?? null;
|
||||
if (!is_array($file)) {
|
||||
Api::fail('没有收到文件。', 'unprocessable', 422);
|
||||
}
|
||||
$r = \App\Attachment::save($fam, Note::ATTACH, 0, $file, $pid);
|
||||
if (empty($r['ok'])) {
|
||||
$msg = (string)($r['error'] ?? '');
|
||||
Api::fail($msg !== '' ? $msg : '图片没存下来', 'unprocessable', 422);
|
||||
}
|
||||
// 🔴 `Attachment::save` 只回 id 不回 key ⇒ 反查一行拿 key
|
||||
// (与 Web 端 `notes/upload` 路由同一招,见 index.php 那段)。
|
||||
$key = '';
|
||||
foreach (\App\Attachment::list(Note::ATTACH, 0) as $a) {
|
||||
if ((int)$a['id'] === (int)($r['id'] ?? 0)) {
|
||||
$key = (string)$a['key'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
Api::ok([
|
||||
'key' => $key,
|
||||
'id' => (int)($r['id'] ?? 0),
|
||||
], 201);
|
||||
}
|
||||
Api::fail('不支持的方法。', 'method_not_allowed', 405);
|
||||
}
|
||||
|
||||
if ($id > 0) {
|
||||
$n = Note::find($fam, $id, $pid);
|
||||
if (!$n) { Api::notFound('这条笔记'); }
|
||||
|
||||
Reference in New Issue
Block a user