From cd56a9d8febad09f219f6b5543a0dc86cc4cffce Mon Sep 17 00:00:00 2001 From: laoyang Date: Wed, 28 Oct 2026 21:34:43 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=94=E8=AE=B0=E5=9B=BE=E7=89=87=E5=9D=97?= =?UTF-8?q?=EF=BC=9A=E8=A1=A5=20API=20=E4=B8=8A=E4=BC=A0=E5=AD=90=E7=AB=AF?= =?UTF-8?q?=E7=82=B9=EF=BC=88=E5=9B=BE=E6=96=87=E6=B7=B7=E6=8E=92=E7=9A=84?= =?UTF-8?q?=E5=89=8D=E5=8D=8A=E7=A8=8B=EF=BC=89#23?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户原话(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) --- app/ApiHandler.php | 49 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/app/ApiHandler.php b/app/ApiHandler.php index 89353d9..21ee04d 100644 --- a/app/ApiHandler.php +++ b/app/ApiHandler.php @@ -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('这条笔记'); }