笔记图片块:展示真图 + 插图 + blocks 保存(图文混排后半程)laoyang/FamilyBook#23
用户原话(2026-10-28):「鸿蒙端对齐网页端」,笔记端上只支持纯文本。 这半程改鸿蒙端,配合服务端 cd56a9d 补的 /notes/upload: 1) 展示:FbNoteItem 新增 blocks(FbNoteBlock[]),parseNotes 把原始块 带进来;FbNoteSheet 里 image 块真画图(fbImageSrc),不再显示「[图片]」。 2) 插图:正文区下加「+ 插图」,选图 → fbUploadKey 上传拿 key → 加入 待保存列表;每张图带「×」可删。 3) 保存(P0 修复):带图时改走 saveNoteWithBlocks —— 正文 text 块 + 图片 image 块整组提交。原来只传 body,服务端折成单个 text 块整组替换, **编辑带图笔记会把图片块静默删光**。 4) fbUploadKey 是 fbUpload 抽出的第二出口:复用同一 multipart 核心拿 key, 不复制第二份实现(本项目"两份实现漂移"栽过多次)。 编译 BUILD SUCCESSFUL;守卫 _fb_arkts_guard.js 1324/0;服务端冒烟 _i23_note_image_api.py 11/0(含 PATCH 后图片块不被删)+ 反证命中 2/2。
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
import {
|
||||
FbAccount, FbAnniversaryItem, FbBookItem, FbBookNoteItem, FbCalEvent, FbHomeData, FbKinChip,
|
||||
FbMark,
|
||||
FbLedgerBook, FbLedgerDetail, FbLedgerEntry, FbNoteItem, FbNotificationItem, FbResourceItem,
|
||||
FbLedgerBook, FbLedgerDetail, FbLedgerEntry, FbNoteItem, FbNoteBlock, FbNotificationItem, FbResourceItem,
|
||||
FbTaskItem, FbTripItem, FbWeather, FbStat, FbMemoryItem, FbRecentDay,
|
||||
FbTaskAttach, FbTaskComment, FbTaskDetail, FbTaskKid, FbTaskMeta, FbCatOpt, FbBoardOpt,
|
||||
} from '../model/Types';
|
||||
@@ -614,6 +614,7 @@ export function parseNotes(json: string): FbNoteItem[] {
|
||||
/* ⚠️ 服务端列表已带 `blocks` / `tags` / `excerpt`(`Note::attachChildren`),
|
||||
这里把它们都取出来 —— 原来只拿 blocks 算了个摘要,正文和标签全丢了。 */
|
||||
const body: string = noteBodyOf(r.blocks);
|
||||
const blocks: FbNoteBlock[] = noteBlocksOf(r.blocks);
|
||||
const tags: string[] = [];
|
||||
for (const t of arr<string>(r.tags)) {
|
||||
tags.push(s(t));
|
||||
@@ -628,6 +629,7 @@ export function parseNotes(json: string): FbNoteItem[] {
|
||||
shared: n(r.is_shared) !== 0,
|
||||
attachCount: 0,
|
||||
body: body,
|
||||
blocks: blocks,
|
||||
mine: n(r.is_mine) !== 0,
|
||||
});
|
||||
}
|
||||
@@ -635,10 +637,34 @@ export function parseNotes(json: string): FbNoteItem[] {
|
||||
}
|
||||
|
||||
/**
|
||||
* `note_blocks` → 一段纯文本。
|
||||
* `note_blocks` → 端上块数组(工单 #23:图文混排要原始块,别只留一张拼好的文本)。
|
||||
*
|
||||
* ⚠️ 图片块的内容是**附件 key**(不是正文),拼进来会变成一串乱码 key
|
||||
* ⇒ 记成「[图片]」,用户一眼知道那里有张图。
|
||||
* ⚠️ 只保留白名单里的 `text` / `image`(服务端 `Note::BLOCK_KINDS`),
|
||||
* 其它一律归一成 text 并交给 noteBodyOf 语义处理;这里只吐给展示/编辑用。
|
||||
*/
|
||||
function noteBlocksOf(blocks: RawNoteBlock[] | undefined): FbNoteBlock[] {
|
||||
const rows: RawNoteBlock[] = arr<RawNoteBlock>(blocks);
|
||||
const out: FbNoteBlock[] = [];
|
||||
for (const bk of rows) {
|
||||
const kind: string = s(bk.kind);
|
||||
if (kind !== 'text' && kind !== 'image') {
|
||||
continue;
|
||||
}
|
||||
out.push({
|
||||
kind: kind,
|
||||
content: s(bk.content),
|
||||
position: n(bk.position),
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* `note_blocks` → 一段纯文本(**只拼 text 块**,图片块跳过)。
|
||||
*
|
||||
* 🔴 工单 #23:原来图片块被记成「[图片]」占位字,正文框显示它、保存还会把
|
||||
* 它当正文写回去。现在图片块由 `FbNoteItem.blocks` 单独承载,正文只留纯文本。
|
||||
* 这样:① 显示真图不靠占位字;② 保存时用 `blocks` 传法,图片不会被覆盖丢。
|
||||
*/
|
||||
function noteBodyOf(blocks: RawNoteBlock[] | undefined): string {
|
||||
const rows: RawNoteBlock[] = arr<RawNoteBlock>(blocks);
|
||||
@@ -646,7 +672,6 @@ function noteBodyOf(blocks: RawNoteBlock[] | undefined): string {
|
||||
for (const b of rows) {
|
||||
const kind: string = s(b.kind);
|
||||
if (kind === 'image') {
|
||||
parts.push('[图片]');
|
||||
continue;
|
||||
}
|
||||
const txt: string = s(b.content).trim();
|
||||
@@ -657,6 +682,18 @@ function noteBodyOf(blocks: RawNoteBlock[] | undefined): string {
|
||||
return parts.join('\n\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片块 content → 纯净附件 key(剥掉「`|宽度`」后缀)。
|
||||
*
|
||||
* 与 Web 端 `Note::imageKey` 同语义:图片块 content 可能是 `key` 或 `key|50`,
|
||||
* 拼图片 URL 时必须取 `|` 之前的 key,否则带后缀的那张图永远加载不出来。
|
||||
*/
|
||||
export function noteImageKey(content: string): string {
|
||||
const c: string = content.trim();
|
||||
const i: number = c.indexOf('|');
|
||||
return i >= 0 ? c.substring(0, i).trim() : c;
|
||||
}
|
||||
|
||||
/** 通知 → FbNotificationItem[] */
|
||||
export function parseNotifications(json: string): FbNotificationItem[] {
|
||||
const root: Record<string, Object> | null = asObject(json);
|
||||
|
||||
Reference in New Issue
Block a user