v27 个人笔记模块:分块(段落/图片/清单)+ 单层多标签 + 默认私有可共享
参考 flomo(时间流卡片 + 标签即筛)、Obsidian(图文混排的直觉)、
思源(「块」的粒度),但刻意只取轻的那一层:
- 分块只做 text / image / list 三种,可增删、可上下移;不做块引用 / 块 ID 双链
- 标签单层、多对多,只存字符串(**不建标签表**)——改名/合并这类重型能力一律不做
- 不做富文本工具栏、不做 Markdown 预览、不做拖拽排序(只有 ↑↓ 按钮)
- 可见性默认**私有**,单条可勾「共享给全家」;共享出去只给别人看,不给别人改
落地:
- 新增 app/Note.php(块清洗、标签归一、可见性、认领草稿附件)
- 新增 3 张表 notes / note_blocks / note_tags;Schema VERSION 26→27
- 🔴 attachments.target_type 是 ENUM:加 'note' 必须同时改建表串 +
新增 widenAttachTargetEnum()(老库不做这一步,传笔记图片会被严格模式拒掉)
- 路由 5 条:notes / notes/form / notes/save / notes/destroy / notes/upload
- 模板 templates/notes/index.php(列表)+ form.php(分块编辑)
- JS assets/js/note_editor.js(按需加载,同 person_picker 那套)
- 编辑器状态放 DOM 而非 JS 数组:移动块时用户已输入的内容一字不丢
This commit is contained in:
@@ -4465,3 +4465,109 @@ button.btn, a.btn, summary.btn, .seg-btn, .icon-btn, .rv-act-btn, .cs-btn, .bf-b
|
||||
.nav-reuse-f { font-size: 12px; color: var(--muted); margin-top: 8px; }
|
||||
/* 空 img(没有图标可复用)别占位成一个破图框 */
|
||||
.nav-reuse-item img:not([src]) { visibility: hidden; }
|
||||
|
||||
/* ============================================================
|
||||
v27 个人笔记(用户 2026-10-07)
|
||||
参考 flomo(时间流卡片 + 标签)/ Obsidian(图文混排的直觉)/ 思源(分块),
|
||||
但一律取**轻**的那一层:块只有 段落/图片/清单,不做块引用、不做富文本。
|
||||
配色沿用宣纸米 + 砖红,不引入第三套色。
|
||||
============================================================ */
|
||||
|
||||
/* ---- 列表页:左标签云 + 右卡片流 ---- */
|
||||
.note-layout { display: grid; grid-template-columns: 220px 1fr; gap: 16px; align-items: start; }
|
||||
.note-side { position: sticky; top: 16px; }
|
||||
.note-main { min-width: 0; }
|
||||
.note-search-card { margin-bottom: 12px; }
|
||||
.note-search-card .search { margin: 0; }
|
||||
|
||||
.note-tags { display: flex; flex-wrap: wrap; gap: 6px; }
|
||||
.note-tag {
|
||||
display: inline-flex; align-items: center; gap: 5px;
|
||||
padding: 4px 9px; border-radius: 999px; cursor: pointer;
|
||||
border: 1px solid var(--line); background: #fff;
|
||||
font-size: 12.5px; color: var(--muted); text-decoration: none;
|
||||
}
|
||||
.note-tag:hover { border-color: var(--brand-2); color: var(--brand-ink); text-decoration: none; }
|
||||
.note-tag.is-on { border-color: var(--brand); color: var(--brand-ink); background: var(--brand-soft, #FDF3EC); }
|
||||
.note-tag b { font-weight: 600; color: var(--faint); font-variant-numeric: tabular-nums; }
|
||||
.note-tag.is-on b { color: var(--brand-ink); }
|
||||
.note-tags-inline { margin-top: 10px; }
|
||||
.note-tags-suggest { margin-top: 8px; align-items: center; }
|
||||
|
||||
/* ---- 卡片 ---- */
|
||||
.note-card { margin-bottom: 12px; }
|
||||
.note-head { display: flex; align-items: center; gap: 8px; }
|
||||
.note-meta { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; }
|
||||
.note-ava { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
|
||||
.note-who { font-size: 13px; color: var(--ink); font-weight: 500; }
|
||||
.note-time { font-size: 12px; color: var(--faint); margin-left: auto; padding-right: 4px; }
|
||||
/* 共享/私有标记:一眼分清"这是我写给自己看的"还是"全家都能看的" */
|
||||
.note-share, .note-private {
|
||||
font-size: 11px; padding: 1px 7px; border-radius: 999px; flex: 0 0 auto;
|
||||
}
|
||||
.note-share { color: #2F6B4F; background: #E7F2EC; }
|
||||
.note-private { color: var(--faint); background: var(--line-2); }
|
||||
.note-ops { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
|
||||
.note-ops .inline-form { display: inline; }
|
||||
|
||||
.note-title { margin: 10px 0 6px; font-size: 16px; font-weight: 600; color: var(--ink); }
|
||||
.note-body { display: flex; flex-direction: column; gap: 8px; }
|
||||
.note-text { margin: 0; font-size: 14.5px; line-height: 1.7; color: var(--ink); white-space: pre-wrap; }
|
||||
.note-list { margin: 0; padding-left: 20px; font-size: 14.5px; line-height: 1.7; color: var(--ink); }
|
||||
.note-list li { margin: 2px 0; }
|
||||
/* 图片:等比缩到卡片宽,圆角与卡片一致;点开走全站预览层(data-prev) */
|
||||
.note-img { display: block; }
|
||||
.note-img img {
|
||||
max-width: 100%; max-height: 420px; border-radius: var(--radius-s);
|
||||
border: 1px solid var(--line); display: block;
|
||||
}
|
||||
.note-more { text-align: center; margin: 16px 0 8px; }
|
||||
|
||||
/* ---- 编辑页:分块 ---- */
|
||||
.note-form .card { margin-bottom: 12px; }
|
||||
.note-block-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
|
||||
.note-block-head .cinema-h2 { margin: 0; flex: 1 1 auto; }
|
||||
.note-add { display: flex; gap: 6px; flex: 0 0 auto; }
|
||||
.note-blocks { display: flex; flex-direction: column; gap: 8px; }
|
||||
.note-block {
|
||||
display: flex; gap: 8px; align-items: flex-start;
|
||||
border: 1px dashed var(--line); border-radius: var(--radius-s);
|
||||
padding: 8px; background: #FDFCFA;
|
||||
}
|
||||
.note-block:focus-within { border-color: var(--brand-2); border-style: solid; }
|
||||
.note-block-ops { display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }
|
||||
.nb-btn {
|
||||
width: 24px; height: 22px; line-height: 1; padding: 0;
|
||||
border: 1px solid var(--line); border-radius: 5px; background: #fff;
|
||||
color: var(--muted); cursor: pointer; font-size: 12px;
|
||||
}
|
||||
.nb-btn:hover { border-color: var(--brand-2); color: var(--brand-ink); }
|
||||
.nb-del:hover { border-color: var(--red); color: var(--red); }
|
||||
.note-block-body { flex: 1 1 auto; min-width: 0; }
|
||||
.note-block-ta { width: 100%; resize: vertical; font-size: 14.5px; line-height: 1.7; }
|
||||
.note-block-img {
|
||||
max-width: 100%; max-height: 320px; border-radius: var(--radius-s);
|
||||
border: 1px solid var(--line); display: block; margin-bottom: 6px;
|
||||
}
|
||||
/* 还没选图时:不要显示破图框(那是 <img src=""> 的默认表现,很难看) */
|
||||
.note-block-img.is-empty { display: none; }
|
||||
.note-img-pick {
|
||||
padding: 4px 10px; border: 1px solid var(--line); border-radius: var(--radius-s);
|
||||
background: #fff; color: var(--muted); cursor: pointer; font-size: 12.5px;
|
||||
}
|
||||
.note-img-pick:hover { border-color: var(--brand-2); color: var(--brand-ink); }
|
||||
.note-share-toggle {
|
||||
display: flex; align-items: center; gap: 8px; margin-top: 12px;
|
||||
font-size: 13.5px; color: var(--muted); cursor: pointer;
|
||||
}
|
||||
.note-share-toggle input { width: 16px; height: 16px; accent-color: var(--brand); }
|
||||
.note-actions { display: flex; gap: 8px; margin: 4px 0 20px; }
|
||||
|
||||
/* ---- 窄屏:标签云折到上面,卡片满宽 ---- */
|
||||
@media (max-width: 760px) {
|
||||
.note-layout { grid-template-columns: 1fr; }
|
||||
.note-side { position: static; }
|
||||
.note-side .card { margin-bottom: 12px; }
|
||||
/* 长英文/URL 不要把卡片撑出横向滚动(全站反复栽在这条上) */
|
||||
.note-text, .note-list, .note-title { overflow-wrap: anywhere; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user