skill-memo-ilife 0.3.2 → 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +33 -34
- package/dist/checkin/index.d.ts +8 -0
- package/dist/checkin/index.d.ts.map +1 -0
- package/dist/checkin/index.js +8 -0
- package/dist/checkin/index.js.map +1 -0
- package/dist/checkin/receipt.d.ts +17 -0
- package/dist/checkin/receipt.d.ts.map +1 -0
- package/dist/checkin/receipt.js +63 -0
- package/dist/checkin/receipt.js.map +1 -0
- package/dist/checkin/routes.d.ts +4 -0
- package/dist/checkin/routes.d.ts.map +1 -1
- package/dist/checkin/routes.js +2 -2
- package/dist/checkin/routes.js.map +1 -1
- package/dist/cli/cmd_read.js +19 -53
- package/dist/cli/cmd_read.js.map +1 -1
- package/dist/cli/config.d.ts +4 -4
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +25 -4
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/health/items.js +2 -2
- package/dist/cli/health/items.js.map +1 -1
- package/dist/cli/health.d.ts.map +1 -1
- package/dist/cli/health.js +3 -2
- package/dist/cli/health.js.map +1 -1
- package/dist/cli/keys.d.ts +6 -3
- package/dist/cli/keys.d.ts.map +1 -1
- package/dist/cli/keys.js +2 -5
- package/dist/cli/keys.js.map +1 -1
- package/dist/cli/registry.d.ts +1 -1
- package/dist/{fetch/db.d.ts → db/readonly.d.ts} +1 -1
- package/dist/db/readonly.d.ts.map +1 -0
- package/dist/{fetch/db.js → db/readonly.js} +5 -5
- package/dist/db/readonly.js.map +1 -0
- package/dist/help/lookup.d.ts +18 -1
- package/dist/help/lookup.d.ts.map +1 -1
- package/dist/help/lookup.js +53 -37
- package/dist/help/lookup.js.map +1 -1
- package/dist/help/sceneData.js +1 -1
- package/dist/help/scenes/checkin.d.ts +1 -1
- package/dist/help/scenes/checkin.js +1 -1
- package/dist/help/scenes/init.d.ts +1 -1
- package/dist/help/scenes/init.js +1 -1
- package/dist/help/scenes/memo.d.ts +1 -1
- package/dist/help/scenes/memo.js +1 -1
- package/dist/help/scenes/mood.d.ts +1 -1
- package/dist/help/scenes/mood.js +1 -1
- package/dist/help/scenes/remind.d.ts +1 -1
- package/dist/help/scenes/remind.js +2 -2
- package/dist/help/scenes/remind.js.map +1 -1
- package/dist/help/scenes/search.d.ts +1 -1
- package/dist/help/scenes/search.js +1 -1
- package/dist/help/scenes/sync.d.ts +1 -1
- package/dist/help/scenes/sync.js +1 -1
- package/dist/help/scenes/wish.d.ts +1 -1
- package/dist/help/scenes/wish.js +1 -1
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -5
- package/dist/index.js.map +1 -1
- package/dist/init/diagnosis.d.ts +2 -1
- package/dist/init/diagnosis.d.ts.map +1 -1
- package/dist/init/diagnosis.js.map +1 -1
- package/dist/init/page.d.ts +3 -2
- package/dist/init/page.d.ts.map +1 -1
- package/dist/init/page.js +20 -10
- package/dist/init/page.js.map +1 -1
- package/dist/init/routes.d.ts +4 -1
- package/dist/init/routes.d.ts.map +1 -1
- package/dist/init/routes.js +14 -0
- package/dist/init/routes.js.map +1 -1
- package/dist/init/run.d.ts.map +1 -1
- package/dist/init/run.js +7 -1
- package/dist/init/run.js.map +1 -1
- package/dist/{fetch → memo}/batch.d.ts +6 -2
- package/dist/memo/batch.d.ts.map +1 -0
- package/dist/{fetch → memo}/batch.js +8 -4
- package/dist/memo/batch.js.map +1 -0
- package/dist/memo/category.d.ts.map +1 -0
- package/dist/{policy → memo}/category.js +1 -1
- package/dist/memo/category.js.map +1 -0
- package/dist/memo/commands.d.ts +3 -12
- package/dist/memo/commands.d.ts.map +1 -1
- package/dist/memo/commands.js +1 -9
- package/dist/memo/commands.js.map +1 -1
- package/dist/{policy → memo}/crud.d.ts +1 -1
- package/dist/memo/crud.d.ts.map +1 -0
- package/dist/{policy → memo}/crud.js +22 -7
- package/dist/memo/crud.js.map +1 -0
- package/dist/memo/index.d.ts +4 -2
- package/dist/memo/index.d.ts.map +1 -1
- package/dist/memo/index.js +4 -2
- package/dist/memo/index.js.map +1 -1
- package/dist/memo/media.d.ts.map +1 -0
- package/dist/{policy → memo}/media.js +2 -2
- package/dist/memo/media.js.map +1 -0
- package/dist/memo/receipt.d.ts +35 -0
- package/dist/memo/receipt.d.ts.map +1 -0
- package/dist/memo/receipt.js +62 -0
- package/dist/memo/receipt.js.map +1 -0
- package/dist/memo/receiptPage.d.ts +44 -0
- package/dist/memo/receiptPage.d.ts.map +1 -0
- package/dist/memo/receiptPage.js +50 -0
- package/dist/memo/receiptPage.js.map +1 -0
- package/dist/memo/routes.d.ts.map +1 -1
- package/dist/memo/routes.js +32 -0
- package/dist/memo/routes.js.map +1 -1
- package/dist/memo/run.d.ts +9 -8
- package/dist/memo/run.d.ts.map +1 -1
- package/dist/memo/run.js +140 -97
- package/dist/memo/run.js.map +1 -1
- package/dist/mood/routes.d.ts.map +1 -1
- package/dist/mood/routes.js +36 -0
- package/dist/mood/routes.js.map +1 -1
- package/dist/remind/index.d.ts +5 -2
- package/dist/remind/index.d.ts.map +1 -1
- package/dist/remind/index.js +5 -2
- package/dist/remind/index.js.map +1 -1
- package/dist/{policy/reminder.d.ts → remind/policy.d.ts} +1 -1
- package/dist/remind/policy.d.ts.map +1 -0
- package/dist/{policy/reminder.js → remind/policy.js} +2 -2
- package/dist/remind/policy.js.map +1 -0
- package/dist/remind/routes.d.ts +1 -2
- package/dist/remind/routes.d.ts.map +1 -1
- package/dist/remind/routes.js +32 -2
- package/dist/remind/routes.js.map +1 -1
- package/dist/remind/run.d.ts +1 -1
- package/dist/remind/run.d.ts.map +1 -1
- package/dist/remind/run.js +112 -7
- package/dist/remind/run.js.map +1 -1
- package/dist/{fetch/reminders.d.ts → remind/store.d.ts} +2 -2
- package/dist/remind/store.d.ts.map +1 -0
- package/dist/{fetch/reminders.js → remind/store.js} +3 -3
- package/dist/remind/store.js.map +1 -0
- package/dist/render/envelope.d.ts.map +1 -1
- package/dist/render/envelope.js +3 -2
- package/dist/render/envelope.js.map +1 -1
- package/dist/render/html.js +1 -1
- package/dist/render/html.js.map +1 -1
- package/dist/render/index.d.ts +4 -1
- package/dist/render/index.d.ts.map +1 -1
- package/dist/render/index.js +5 -3
- package/dist/render/index.js.map +1 -1
- package/dist/render/listPage.d.ts +34 -0
- package/dist/render/listPage.d.ts.map +1 -0
- package/dist/render/listPage.js +39 -0
- package/dist/render/listPage.js.map +1 -0
- package/dist/render/memoPageAssets.d.ts +32 -0
- package/dist/render/memoPageAssets.d.ts.map +1 -0
- package/dist/render/memoPageAssets.js +320 -0
- package/dist/render/memoPageAssets.js.map +1 -0
- package/dist/render/pageAssets.js +3 -3
- package/dist/render/pageAssets.js.map +1 -1
- package/dist/render/pages.d.ts +9 -2
- package/dist/render/pages.d.ts.map +1 -1
- package/dist/render/pages.js +8 -16
- package/dist/render/pages.js.map +1 -1
- package/dist/render/receipt.d.ts +12 -3
- package/dist/render/receipt.d.ts.map +1 -1
- package/dist/render/receipt.js +55 -10
- package/dist/render/receipt.js.map +1 -1
- package/dist/search/routes.d.ts.map +1 -1
- package/dist/search/routes.js +1 -0
- package/dist/search/routes.js.map +1 -1
- package/dist/search/run.d.ts +11 -3
- package/dist/search/run.d.ts.map +1 -1
- package/dist/search/run.js +130 -11
- package/dist/search/run.js.map +1 -1
- package/dist/shared/commandSpec.d.ts +4 -5
- package/dist/shared/commandSpec.d.ts.map +1 -1
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/{fetch → shared}/paths.d.ts +1 -1
- package/dist/shared/paths.d.ts.map +1 -0
- package/dist/{fetch → shared}/paths.js +3 -3
- package/dist/shared/paths.js.map +1 -0
- package/dist/shared/validators.d.ts +3 -0
- package/dist/shared/validators.d.ts.map +1 -0
- package/dist/shared/validators.js +15 -0
- package/dist/shared/validators.js.map +1 -0
- package/dist/sync/auth.d.ts.map +1 -0
- package/dist/{fetch → sync}/auth.js +3 -3
- package/dist/sync/auth.js.map +1 -0
- package/dist/sync/commands.d.ts.map +1 -1
- package/dist/sync/commands.js.map +1 -1
- package/dist/sync/feishu.d.ts.map +1 -0
- package/dist/{fetch → sync}/feishu.js +9 -9
- package/dist/sync/feishu.js.map +1 -0
- package/dist/sync/index.d.ts +5 -2
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +4 -2
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/run.d.ts +1 -1
- package/dist/sync/run.d.ts.map +1 -1
- package/dist/sync/run.js +2 -1
- package/dist/sync/run.js.map +1 -1
- package/dist/{fetch → sync}/sentinel.d.ts +1 -1
- package/dist/sync/sentinel.d.ts.map +1 -0
- package/dist/{fetch → sync}/sentinel.js +1 -2
- package/dist/sync/sentinel.js.map +1 -0
- package/dist/triggers/routes.generated.d.ts +1 -1
- package/dist/triggers/routes.generated.d.ts.map +1 -1
- package/dist/triggers/routes.generated.js +19 -6
- package/dist/triggers/routes.generated.js.map +1 -1
- package/dist/triggers/routing.d.ts +7 -0
- package/dist/triggers/routing.d.ts.map +1 -0
- package/dist/triggers/routing.js +35 -0
- package/dist/triggers/routing.js.map +1 -0
- package/dist/wish/complete.d.ts +1 -1
- package/dist/wish/complete.d.ts.map +1 -1
- package/dist/wish/complete.js +1 -1
- package/dist/wish/complete.js.map +1 -1
- package/dist/wish/due.d.ts +1 -1
- package/dist/wish/due.d.ts.map +1 -1
- package/dist/wish/due.js +1 -1
- package/dist/wish/due.js.map +1 -1
- package/dist/wish/ensure.d.ts +2 -2
- package/dist/wish/ensure.d.ts.map +1 -1
- package/dist/wish/ensure.js +2 -2
- package/dist/wish/ensure.js.map +1 -1
- package/dist/wish/gate.d.ts +1 -1
- package/dist/wish/gate.d.ts.map +1 -1
- package/dist/wish/gate.js +1 -1
- package/dist/wish/gate.js.map +1 -1
- package/dist/wish/index.d.ts +4 -0
- package/dist/wish/index.d.ts.map +1 -1
- package/dist/wish/index.js +7 -0
- package/dist/wish/index.js.map +1 -1
- package/dist/{policy/wish.d.ts → wish/policy.d.ts} +1 -1
- package/dist/wish/policy.d.ts.map +1 -0
- package/dist/{policy/wish.js → wish/policy.js} +3 -3
- package/dist/wish/policy.js.map +1 -0
- package/dist/wish/receipt.d.ts +45 -0
- package/dist/wish/receipt.d.ts.map +1 -0
- package/dist/wish/receipt.js +68 -0
- package/dist/wish/receipt.js.map +1 -0
- package/dist/wish/reconcile.d.ts +1 -1
- package/dist/wish/reconcile.d.ts.map +1 -1
- package/dist/wish/reconcile.js +2 -2
- package/dist/wish/reconcile.js.map +1 -1
- package/dist/wish/routes.d.ts.map +1 -1
- package/dist/wish/routes.js +11 -1
- package/dist/wish/routes.js.map +1 -1
- package/dist/wish/run.d.ts +11 -3
- package/dist/wish/run.d.ts.map +1 -1
- package/dist/wish/run.js +75 -7
- package/dist/wish/run.js.map +1 -1
- package/dist/wish/taskRemove.js +2 -2
- package/dist/wish/taskRemove.js.map +1 -1
- package/dist/wish/taskSync.d.ts +1 -1
- package/dist/wish/taskSync.d.ts.map +1 -1
- package/dist/wish/taskSync.js +3 -3
- package/dist/wish/taskSync.js.map +1 -1
- package/dist/wish/taskWrite.d.ts.map +1 -0
- package/dist/{fetch → wish}/taskWrite.js +2 -2
- package/dist/wish/taskWrite.js.map +1 -0
- package/dist/wish/tasks.d.ts.map +1 -0
- package/dist/{fetch → wish}/tasks.js +2 -2
- package/dist/wish/tasks.js.map +1 -0
- package/dist/wish/wizards.d.ts +1 -1
- package/dist/wish/wizards.d.ts.map +1 -1
- package/dist/wish/wizards.js +1 -1
- package/dist/wish/wizards.js.map +1 -1
- package/package.json +4 -7
- package/templates/change_category.html +52 -28
- package/templates/init_report.html +15 -14
- package/templates/memo_query.html +59 -24
- package/templates/receipt.html +97 -27
- package/templates/sync_report.html +106 -98
- package/templates/wish_complete.html +48 -30
- package/templates/wish_plan.html +35 -20
- package/dist/fetch/auth.d.ts.map +0 -1
- package/dist/fetch/auth.js.map +0 -1
- package/dist/fetch/batch.d.ts.map +0 -1
- package/dist/fetch/batch.js.map +0 -1
- package/dist/fetch/db.d.ts.map +0 -1
- package/dist/fetch/db.js.map +0 -1
- package/dist/fetch/errors.d.ts.map +0 -1
- package/dist/fetch/errors.js.map +0 -1
- package/dist/fetch/feishu.d.ts.map +0 -1
- package/dist/fetch/feishu.js.map +0 -1
- package/dist/fetch/index.d.ts +0 -19
- package/dist/fetch/index.d.ts.map +0 -1
- package/dist/fetch/index.js +0 -13
- package/dist/fetch/index.js.map +0 -1
- package/dist/fetch/paths.d.ts.map +0 -1
- package/dist/fetch/paths.js.map +0 -1
- package/dist/fetch/reminders.d.ts.map +0 -1
- package/dist/fetch/reminders.js.map +0 -1
- package/dist/fetch/sentinel.d.ts.map +0 -1
- package/dist/fetch/sentinel.js.map +0 -1
- package/dist/fetch/taskWrite.d.ts.map +0 -1
- package/dist/fetch/taskWrite.js.map +0 -1
- package/dist/fetch/tasks.d.ts.map +0 -1
- package/dist/fetch/tasks.js.map +0 -1
- package/dist/policy/category.d.ts.map +0 -1
- package/dist/policy/category.js.map +0 -1
- package/dist/policy/crud.d.ts.map +0 -1
- package/dist/policy/crud.js.map +0 -1
- package/dist/policy/index.d.ts +0 -11
- package/dist/policy/index.d.ts.map +0 -1
- package/dist/policy/index.js +0 -8
- package/dist/policy/index.js.map +0 -1
- package/dist/policy/media.d.ts.map +0 -1
- package/dist/policy/media.js.map +0 -1
- package/dist/policy/reminder.d.ts.map +0 -1
- package/dist/policy/reminder.js.map +0 -1
- package/dist/policy/wakewords.d.ts +0 -14
- package/dist/policy/wakewords.d.ts.map +0 -1
- package/dist/policy/wakewords.js +0 -68
- package/dist/policy/wakewords.js.map +0 -1
- package/dist/policy/wish.d.ts.map +0 -1
- package/dist/policy/wish.js.map +0 -1
- /package/dist/{policy → memo}/category.d.ts +0 -0
- /package/dist/{policy → memo}/media.d.ts +0 -0
- /package/dist/{fetch → shared}/errors.d.ts +0 -0
- /package/dist/{fetch → shared}/errors.js +0 -0
- /package/dist/{fetch → sync}/auth.d.ts +0 -0
- /package/dist/{fetch → sync}/feishu.d.ts +0 -0
- /package/dist/{fetch → wish}/taskWrite.d.ts +0 -0
- /package/dist/{fetch → wish}/tasks.d.ts +0 -0
|
@@ -29,12 +29,20 @@ select{border:1px solid var(--line);border-radius:12px;padding:9px 12px;font-siz
|
|
|
29
29
|
.note{background:var(--card);border-radius:18px;padding:18px;margin:12px 0;box-shadow:0 1px 3px rgba(0,0,0,.04);transition:box-shadow .15s,opacity .15s}
|
|
30
30
|
#noteList{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-items:stretch}
|
|
31
31
|
#noteList .note{margin:0;padding:14px;display:flex;flex-direction:column;height:100%}
|
|
32
|
-
|
|
32
|
+
/* 空态件由公共层给(`ilife-empty-*`)。本页空分支的形状是
|
|
33
|
+
`list.innerHTML = '<div class="panel">' + window.emptyState({…}) + '</div>'`
|
|
34
|
+
⇒ **落进 `#noteList` 栅格的分栏项是那层 `.panel`,不是空卡本身**,故跨列要挂在 `.panel` 上;
|
|
35
|
+
只给 `.ilife-empty` 挂 `grid-column` 是空转(空卡是 `.panel` 的子元素,不参与外层栅格定位)。
|
|
36
|
+
**实测**(#877 复核):撤掉这条 `.panel` 规则,1280 档 `#noteList` 宽 936、空卡只占 419px(半个卡);
|
|
37
|
+
挂上后分栏项 936=整行、空卡 892px。两条都留着:`.panel` 那条管本页当前形状,
|
|
38
|
+
`.ilife-empty` 那条管将来空卡直接落进栅格的情形。 */
|
|
39
|
+
#noteList > .panel,
|
|
40
|
+
#noteList .ilife-empty{grid-column:1/-1}
|
|
33
41
|
#noteList .note-head{flex-wrap:nowrap;gap:6px;margin-bottom:8px;align-items:flex-start}
|
|
34
42
|
#noteList .note-id{font-size:13px;min-width:0;white-space:nowrap}
|
|
35
43
|
#noteList .note-content{font-size:14px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-all;flex:1 1 auto}
|
|
36
44
|
#noteList .note-meta{margin:auto 0 0;gap:8px;padding-top:8px}
|
|
37
|
-
#noteList .note-meta .badge{font-size:
|
|
45
|
+
#noteList .note-meta .badge{font-size:12px;padding:2px 8px;margin:2px 4px 2px 0}
|
|
38
46
|
.note.off{opacity:.5}
|
|
39
47
|
.note.off .content{text-decoration:line-through;color:var(--fg3)}
|
|
40
48
|
.note-head{display:flex;align-items:center;gap:12px;margin-bottom:10px}
|
|
@@ -53,11 +61,15 @@ pre{white-space:pre-wrap;background:#f5f5f7;color:var(--fg);border:1px solid var
|
|
|
53
61
|
.notice{padding:12px 16px;border-radius:14px;margin:10px 0;font-size:14px}
|
|
54
62
|
.notice.warn{background:#fff7e8;color:#b25b00}
|
|
55
63
|
.notice.err{background:#fff5f5;color:#ff3b30}
|
|
56
|
-
|
|
64
|
+
/* #820 收尾:断点取仓内既有集合(help 模板同档 820);原写 800 是新造的档位。 */
|
|
65
|
+
@media(max-width:820px){.wrap{padding:28px 14px 70px}.hero{padding:26px 20px}h1{font-size:30px}.flow{flex-direction:column}}
|
|
66
|
+
|
|
67
|
+
/* #870 · 表单控件命中区 ≥44×44px(t849 §2 硬线;实测基线 33 处不足全在这一族) */
|
|
68
|
+
input[type=text],input[type=date],input[type=search],input:not([type]),select{min-height:44px;box-sizing:border-box}
|
|
57
69
|
</style>
|
|
58
70
|
</head>
|
|
59
71
|
<body>
|
|
60
|
-
<div class="wrap">
|
|
72
|
+
<div class="wrap ilife-page-ui">
|
|
61
73
|
<header class="hero">
|
|
62
74
|
<h1 id="title">批量改分类向导</h1>
|
|
63
75
|
<p class="lead" id="subtitle">数据加载中</p>
|
|
@@ -68,9 +80,9 @@ pre{white-space:pre-wrap;background:#f5f5f7;color:var(--fg);border:1px solid var
|
|
|
68
80
|
<section class="kpi" id="kpis"></section>
|
|
69
81
|
|
|
70
82
|
<section class="panel">
|
|
71
|
-
<div style="font-weight:700;margin-bottom:10px"
|
|
83
|
+
<div style="font-weight:700;margin-bottom:10px">改到哪个分类</div>
|
|
72
84
|
<div class="toolbar">
|
|
73
|
-
<label style="color:var(--fg2);font-size:14px"
|
|
85
|
+
<label style="color:var(--fg2);font-size:14px">目标分类:</label>
|
|
74
86
|
<select id="toCatSelect">
|
|
75
87
|
<option value="备忘">备忘</option>
|
|
76
88
|
<option value="心愿">心愿</option>
|
|
@@ -82,27 +94,35 @@ pre{white-space:pre-wrap;background:#f5f5f7;color:var(--fg);border:1px solid var
|
|
|
82
94
|
<button class="ghost" onclick="selectAll(false)">清空选择</button>
|
|
83
95
|
</div>
|
|
84
96
|
</div>
|
|
85
|
-
<p class="hint">已选择 <b id="selCount">0</b>
|
|
97
|
+
<p class="hint">已选择 <b id="selCount">0</b> 条,共 <span id="selTotal">0</span> 条</p>
|
|
86
98
|
</section>
|
|
87
99
|
|
|
88
100
|
<section id="noteList"></section>
|
|
89
101
|
|
|
90
102
|
<section class="panel">
|
|
91
|
-
<div style="font-weight:700;margin-bottom:8px"
|
|
92
|
-
<p style="color:var(--fg2);font-size:13px;margin-bottom:12px"
|
|
103
|
+
<div style="font-weight:700;margin-bottom:8px">发给助手的指令</div>
|
|
104
|
+
<p style="color:var(--fg2);font-size:13px;margin-bottom:12px">点击后复制指令,粘贴给助手,助手会把勾选笔记的分类改成目标分类(子分类保持不变),改完给你回执。</p>
|
|
93
105
|
<div class="toolbar">
|
|
94
|
-
<button class="primary" onclick="adopt()"
|
|
106
|
+
<button class="primary" onclick="adopt()">复制修改指令</button>
|
|
95
107
|
</div>
|
|
96
108
|
<div id="warnArea"></div>
|
|
109
|
+
<p class="small" id="previewNote" style="display:none">下面是复制出去的原文,里面的符号留给 AI 解析。</p>
|
|
97
110
|
<pre id="promptOut" style="display:none"></pre>
|
|
98
111
|
</section>
|
|
99
112
|
|
|
100
|
-
<section class="
|
|
101
|
-
<
|
|
102
|
-
<div class="
|
|
103
|
-
<div class="
|
|
104
|
-
<button class="copy ghost"
|
|
105
|
-
<
|
|
113
|
+
<section class="ilife-block ilife-block-copy-block">
|
|
114
|
+
<div class="ilife-action-bar">
|
|
115
|
+
<div class="ilife-action-row ilife-action-row-ghost">
|
|
116
|
+
<div class="ilife-copy-menu-wrap">
|
|
117
|
+
<button type="button" class="ilife-copy-btn ilife-copy-btn-ghost" data-fmt-open="1" aria-haspopup="menu" aria-expanded="false" aria-label="复制数据(点开选格式)">复制数据</button>
|
|
118
|
+
<div class="ilife-copy-menu" role="menu">
|
|
119
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="text" data-t=""><span class="ilife-copy-menu-label">纯文本</span></button>
|
|
120
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="json" data-t=""><span class="ilife-copy-menu-label">JSON</span></button>
|
|
121
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="csv" data-t=""><span class="ilife-copy-menu-label">CSV</span></button>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
<button type="button" class="ilife-copy-btn ilife-copy-btn-ghost" data-action-id="memo-copy-log">复制日志</button>
|
|
125
|
+
</div>
|
|
106
126
|
</div>
|
|
107
127
|
</section>
|
|
108
128
|
</div>
|
|
@@ -116,7 +136,7 @@ var raw=document.getElementById("payload");
|
|
|
116
136
|
var payload=null,perr=null;
|
|
117
137
|
try{payload=JSON.parse(raw.textContent||"{}");}catch(e){perr=e.message;}
|
|
118
138
|
if(perr){document.getElementById("injectError").style.display="block";document.getElementById("injectError").innerHTML=window.errorReceipt({message:"数据解析失败",log:perr,payload:null});return;}
|
|
119
|
-
if(!payload||payload.status!=="ok"||!payload.data){document.getElementById("injectError").style.display="block";document.getElementById("injectError").innerHTML=window.errorReceipt({message:(payload&&payload.message)||"数据未注入",retryPrompt:"
|
|
139
|
+
if(!payload||payload.status!=="ok"||!payload.data){document.getElementById("injectError").style.display="block";document.getElementById("injectError").innerHTML=window.errorReceipt({message:(payload&&payload.message)||"数据未注入",retryPrompt:"请重新运行批量改分类(唤醒词:备忘改分类)",payload:null});return;}
|
|
120
140
|
window.__hmPayload=payload;
|
|
121
141
|
function data(){return payload.data}
|
|
122
142
|
function items(){return data().items||[]}
|
|
@@ -124,9 +144,9 @@ function items(){return data().items||[]}
|
|
|
124
144
|
function init(){
|
|
125
145
|
var d=data();
|
|
126
146
|
document.getElementById('title').textContent=d.title||'批量改分类向导';
|
|
127
|
-
document.getElementById('subtitle').textContent='
|
|
147
|
+
document.getElementById('subtitle').textContent='先勾选下方笔记,再复制指令,粘贴给助手帮你完成改分类';
|
|
128
148
|
var meta=d.meta||{};
|
|
129
|
-
document.getElementById('meta').textContent=`从「${d.from_category||'当前分类'}」改到「${d.to_category||'目标分类'}
|
|
149
|
+
document.getElementById('meta').textContent=`从「${d.from_category||'当前分类'}」改到「${d.to_category||'目标分类'}」(生成时间 ${d.generated_at||''})`;
|
|
130
150
|
if(d.to_category){
|
|
131
151
|
var sel=document.getElementById('toCatSelect');
|
|
132
152
|
sel.value=d.to_category;
|
|
@@ -187,6 +207,7 @@ function selectAll(on){
|
|
|
187
207
|
var cb=document.getElementById('cb_'+w.id);
|
|
188
208
|
if(cb){cb.checked=on;document.getElementById('note_'+w.id).classList.toggle('off',!on)}
|
|
189
209
|
});
|
|
210
|
+
updateSelCount();
|
|
190
211
|
}
|
|
191
212
|
|
|
192
213
|
function selectedRows(){
|
|
@@ -204,25 +225,25 @@ function selectedRows(){
|
|
|
204
225
|
function buildPrompt(rows,target,ctx){
|
|
205
226
|
if(!rows.length) return '未选择任何笔记';
|
|
206
227
|
return [
|
|
207
|
-
'①
|
|
228
|
+
'① 场景: 我用批量改分类向导,把 '+rows.length+' 条「'+ctx.from_cat+'」笔记改到「'+target+'」',
|
|
208
229
|
'',
|
|
209
|
-
'②
|
|
230
|
+
'② 数据(要改分类的笔记):',
|
|
210
231
|
...rows.map(r=>` · 笔记 #${r.id} "${r.content}"`),
|
|
211
232
|
'',
|
|
212
|
-
'③
|
|
233
|
+
'③ 期望: 请把以上笔记的顶层分类从「'+ctx.from_cat+'」改为「'+target+'」,子分类保持不变;改完给我回执。',
|
|
213
234
|
'',
|
|
214
|
-
'④
|
|
235
|
+
'④ 来源: 批量改分类向导 · '+ctx.generated_at,
|
|
215
236
|
].join('\n');
|
|
216
237
|
}
|
|
217
238
|
|
|
218
239
|
function warnIfAny(rows){
|
|
219
240
|
var notes=[];
|
|
220
241
|
if(rows.length>=10){
|
|
221
|
-
notes.push(`<div class="notice warn"
|
|
242
|
+
notes.push(`<div class="notice warn">批量改 ${rows.length} 条分类,请确认都是预期操作</div>`);
|
|
222
243
|
}
|
|
223
244
|
var dup=data().target_conflict_count||0;
|
|
224
245
|
if(dup>0){
|
|
225
|
-
notes.push(`<div class="notice warn">ℹ️ ${dup}
|
|
246
|
+
notes.push(`<div class="notice warn">ℹ️ ${dup} 条目标分类(${document.getElementById('toCatSelect').value})下已有同名笔记</div>`);
|
|
226
247
|
}
|
|
227
248
|
document.getElementById('warnArea').innerHTML=notes.join('');
|
|
228
249
|
}
|
|
@@ -240,16 +261,19 @@ function adopt(){
|
|
|
240
261
|
var text=buildPrompt(rows,target,ctx);
|
|
241
262
|
var out=document.getElementById('promptOut');
|
|
242
263
|
out.textContent=text;out.style.display='block';
|
|
264
|
+
// 说明与预览一起出现(#820 收尾:原先它挂在按钮上方的说明里,讲的是点完才看得到的东西)
|
|
265
|
+
document.getElementById('previewNote').style.display='block';
|
|
243
266
|
window.copyText(text,{silent:true});
|
|
244
|
-
window.toast('指令已复制','
|
|
267
|
+
window.toast('指令已复制','粘贴发给助手 即可执行',{icon:'ok'});
|
|
245
268
|
}
|
|
246
269
|
|
|
247
|
-
function copyData(){window.
|
|
248
|
-
function copyLog(){window.
|
|
270
|
+
function copyData(){window.memoAttachCopyArea();window.toast('数据已复制','人类可读快照 · 可粘贴到笔记存档',{icon:'copy'});}
|
|
271
|
+
function copyLog(){window.memoAttachCopyArea();window.toast('日志已复制','诊断信息 · 有异常时粘贴给开发者排查',{icon:'copy'});}
|
|
249
272
|
window.selectAll=selectAll;
|
|
250
273
|
window.adopt=adopt;
|
|
251
274
|
window.copyData=copyData;
|
|
252
275
|
window.copyLog=copyLog;
|
|
276
|
+
window.memoAttachCopyArea();
|
|
253
277
|
init();
|
|
254
278
|
})();
|
|
255
279
|
</script>
|
|
@@ -71,16 +71,16 @@ body{font-family:var(--font);background:var(--bg);color:var(--fg);line-height:1.
|
|
|
71
71
|
.verify-badge.skip{background:#f0f0f3;color:var(--fg3)}
|
|
72
72
|
.verify-badge.fail{background:var(--err-soft);color:var(--err-fg)}
|
|
73
73
|
|
|
74
|
-
/* ===== 数据与日志 ===== */
|
|
75
|
-
.data-panel{background:var(--card);border-radius:14px;padding:14px 16px;border:1px solid var(--line);margin-top:14px}
|
|
76
|
-
.data-panel strong{font-size:13.5px}
|
|
77
|
-
.data-panel .hint{font-size:12px;color:var(--fg3);margin-top:6px}
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
/* #820 收尾:断点取仓内既有集合;原写 360 是新造的档位(help 模板最小档是 500)。 */
|
|
76
|
+
@media(max-width:400px){.check-item .name{font-size:13px}.status-card{padding:20px 16px}}
|
|
77
|
+
|
|
78
|
+
/* #870 · 表单控件命中区 ≥44×44px(t849 §2 硬线;实测基线 33 处不足全在这一族) */
|
|
79
|
+
input[type=text],input[type=date],input[type=search],input:not([type]),select{min-height:44px;box-sizing:border-box}
|
|
80
80
|
</style>
|
|
81
81
|
</head>
|
|
82
82
|
<body>
|
|
83
|
-
<div class="wrap">
|
|
83
|
+
<div class="wrap ilife-page-ui">
|
|
84
84
|
<div class="status-card" id="statusCard">
|
|
85
85
|
<div class="status-icon" id="statusIcon">🔍</div>
|
|
86
86
|
<div class="status-title" id="statusTitle">环境检查中…</div>
|
|
@@ -93,12 +93,12 @@ body{font-family:var(--font);background:var(--bg);color:var(--fg);line-height:1.
|
|
|
93
93
|
|
|
94
94
|
<main id="bodyContent"></main>
|
|
95
95
|
|
|
96
|
-
<section class="
|
|
97
|
-
<
|
|
98
|
-
<div class="
|
|
99
|
-
<
|
|
100
|
-
<button class="copy ghost"
|
|
101
|
-
|
|
96
|
+
<section class="ilife-block ilife-block-copy-block" id="dataPanel">
|
|
97
|
+
<div class="ilife-action-bar">
|
|
98
|
+
<div class="ilife-action-row ilife-action-row-ghost">
|
|
99
|
+
<button type="button" class="ilife-copy-btn ilife-copy-btn-ghost" data-action-id="memo-copy-data">复制数据</button>
|
|
100
|
+
<button type="button" class="ilife-copy-btn ilife-copy-btn-ghost" data-action-id="memo-copy-log">复制日志</button>
|
|
101
|
+
</div>
|
|
102
102
|
</div>
|
|
103
103
|
</section>
|
|
104
104
|
<p style="text-align:center;color:var(--fg3);font-size:12px;margin-top:14px">补齐后回到对话,告诉 AI「重新检查」即可刷新本页</p>
|
|
@@ -215,10 +215,11 @@ try{
|
|
|
215
215
|
document.getElementById("injectError").innerHTML=window.errorReceipt({message:"渲染失败:"+e.message,payload:null});
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
function copyData(){window.
|
|
219
|
-
function copyLog(){window.
|
|
218
|
+
function copyData(){window.memoAttachCopyArea();window.toast('数据已复制','人类可读快照 · 可粘贴到笔记存档',{icon:'copy'});}
|
|
219
|
+
function copyLog(){window.memoAttachCopyArea();window.toast('日志已复制','诊断信息 · 有异常时粘贴给开发者排查',{icon:'copy'});}
|
|
220
220
|
window.copyData=copyData;
|
|
221
221
|
window.copyLog=copyLog;
|
|
222
|
+
window.memoAttachCopyArea();
|
|
222
223
|
})();
|
|
223
224
|
</script>
|
|
224
225
|
</body>
|
|
@@ -2,39 +2,57 @@
|
|
|
2
2
|
<html lang="zh-CN">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
|
6
6
|
<title>备忘录查询结果</title>
|
|
7
7
|
<!--SHARED-CSS-->
|
|
8
8
|
<style>
|
|
9
9
|
*{box-sizing:border-box;margin:0;padding:0}
|
|
10
10
|
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
|
11
11
|
body{font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;background:var(--bg);color:var(--fg);line-height:1.65;-webkit-font-smoothing:antialiased}
|
|
12
|
-
.wrap{max-width:1120px;margin:0 auto;padding:48px 22px 90px}
|
|
13
|
-
.hero{background:linear-gradient(180deg
|
|
12
|
+
.wrap{max-width:1120px;margin:0 auto;padding:48px max(22px,env(safe-area-inset-right)) calc(90px + env(safe-area-inset-bottom)) max(22px,env(safe-area-inset-left))}
|
|
13
|
+
.hero{background:linear-gradient(180deg,var(--card) 0%,var(--soft) 100%);border-radius:28px;padding:34px;margin-bottom:20px;box-shadow:var(--shadow,0 1px 2px rgba(0,0,0,.04),0 12px 36px rgba(0,0,0,.06))}
|
|
14
14
|
.eyebrow{font-size:13px;color:var(--blue);font-weight:800;letter-spacing:.08em;text-transform:uppercase;margin-bottom:10px}
|
|
15
|
-
h1{font-size:38px;line-height:1.15;letter-spacing:-.035em;margin-bottom:12px}.lead{color:var(--fg2);font-size:17px}.meta{margin-top:
|
|
15
|
+
h1{font-size:38px;line-height:1.15;letter-spacing:-.035em;margin-bottom:12px}.lead{color:var(--fg2);font-size:17px}.meta{margin-top:22px;color:var(--fg3);font-size:12px;line-height:1.6}
|
|
16
16
|
.grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin:18px 0}.stat,.panel,.item{background:var(--card);border-radius:20px;padding:18px;box-shadow:0 1px 3px rgba(0,0,0,.04)}.panel{margin:14px 0}
|
|
17
|
-
.stat b{display:block;font-size:22px;letter-spacing:-.02em;font-weight:800}.stat span{color:var(--fg2);font-size:13px;font-weight:600}.toolbar{display:flex;gap:10px;flex-wrap:wrap;margin:14px 0}.pill{border:1px solid var(--line);background
|
|
18
|
-
.item{margin:12px 0}.item-head{display:flex;justify-content:space-between;gap:14px;align-items:flex-start}.id{color:var(--blue);font-weight:800}.content{font-size:17px;margin:10px 0;white-space:pre-wrap}.muted{color:var(--fg2)}.small{font-size:13px;color:var(--fg3)}.badge{display:inline-block;background:var(--soft
|
|
17
|
+
.stat b{display:block;font-size:22px;letter-spacing:-.02em;font-weight:800}.stat span{color:var(--fg2);font-size:13px;font-weight:600}.panel>strong{display:block;font-size:15px;line-height:1.4;letter-spacing:-.01em;margin-bottom:8px}.toolbar{display:flex;gap:10px;flex-wrap:wrap;margin:14px 0}.pill{border:1px solid var(--line);background:var(--card);border-radius:999px;padding:10px 14px;min-height:44px;font-size:13px;color:var(--fg2);cursor:pointer}.pill.active{background:var(--soft);color:var(--blue);border-color:var(--blue)}
|
|
18
|
+
.item{margin:12px 0}.item-head{display:flex;justify-content:space-between;gap:14px;align-items:flex-start}.id{color:var(--blue);font-weight:800}.content{font-size:17px;margin:10px 0;white-space:pre-wrap}.muted{color:var(--fg2)}.small{font-size:13px;color:var(--fg3)}.badge{display:inline-block;background:var(--soft);color:var(--blue);padding:3px 9px;border-radius:999px;font-size:12px;font-weight:700;margin:3px 5px 3px 0}.badge.warn{background:var(--soft);color:var(--blue2);border:1px solid var(--blue)}.badge.ok{background:var(--soft);color:var(--ok)}
|
|
19
19
|
#list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-items:stretch;margin:14px 0}
|
|
20
20
|
#list .item{margin:0;padding:14px;display:flex;flex-direction:column;height:100%}
|
|
21
|
-
|
|
21
|
+
/* 空态件由公共层给:`window.emptyState` 吐 `ilife-empty-*`(见 `src/render/memoPageAssets.ts`),
|
|
22
|
+
类名须与它逐字一致,否则本规则空转、空卡落进两列栅格的第一列(#877)。 */
|
|
23
|
+
#list .ilife-empty{grid-column:1/-1}
|
|
22
24
|
#list .item-head{flex-wrap:nowrap;gap:6px;min-height:32px;align-items:center}
|
|
23
25
|
#list .id{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
24
|
-
#list .item-head button.copy{flex:0 0 auto;min-height:
|
|
26
|
+
#list .item-head button.copy{flex:0 0 auto;min-height:44px;padding:8px 16px;font-size:13px}
|
|
25
27
|
#list .content{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:14px;margin:8px 0;word-break:break-all;flex:1 1 auto}
|
|
26
|
-
|
|
28
|
+
/* 单条结果(看备忘/单条详情):不截断 —— 副标题承诺「全部内容」,两行截断会把承诺做假。
|
|
29
|
+
用 `:only-child` 认「这一屏只有一条」,不给容器加新类名(#877 那条门要求 #list 族 CSS 里的类名
|
|
30
|
+
都能在产物里被写出来,运行时才加的类名会把它判成空转规则)。 */
|
|
31
|
+
#list .item:only-child .content{display:block;-webkit-line-clamp:unset;overflow:visible;font-size:17px}
|
|
32
|
+
#list .item .badge{font-size:12px;padding:5px 10px;margin:3px 5px 3px 0}
|
|
27
33
|
#list .small{font-size:12px;margin-top:auto;padding-top:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
28
|
-
.empty{padding:42px;text-align:center;color:var(--fg2)}button{border:0;background:var(--blue);color
|
|
29
|
-
|
|
34
|
+
.empty{padding:42px;text-align:center;color:var(--fg2)}button{border:0;background:var(--blue);color:var(--card);border-radius:999px;padding:8px 12px;min-height:44px;cursor:pointer}.item-head button.copy{flex:0 0 auto;min-height:44px;padding:8px 16px;font-size:13px}input{width:100%;border:1px solid var(--line);border-radius:14px;padding:12px 14px;min-height:44px;font-size:15px;margin-top:12px}pre{white-space:pre-wrap;background:var(--soft);color:var(--fg);border:1px solid var(--line);border-radius:16px;padding:16px;overflow:auto;font-size:13px;line-height:1.65;font-family:inherit}
|
|
35
|
+
.jump{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}.jump a{display:inline-flex;align-items:center;min-height:44px;padding:0 14px;border:1px solid var(--line);border-radius:999px;color:var(--blue);text-decoration:none;font-size:13px;font-weight:600}.jump a:hover{background:var(--soft)}
|
|
36
|
+
/* #820 收尾(暂缓):把导航改成「文字链」会掉分(实测 97.41 → 95.82,硬扣 1.59,最低页 96 → 94)——
|
|
37
|
+
与筛选胶囊同形不同义这条**先不动**,留给下一轮带判据地改(要么动公共层目录形状,要么让筛选胶囊换形状)。 */
|
|
38
|
+
/* 这一趟生效的查询条件:一条一枚胶囊(#820 收尾)——不再与结果规模挤成一句话 */
|
|
39
|
+
.subnote{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
|
|
40
|
+
.chip-cond{background:var(--soft,#f5f8ff);color:var(--fg2);border-radius:999px;padding:4px 12px;font-size:13px}
|
|
41
|
+
#stats,#list,#data-panel{scroll-margin-top:20px}
|
|
42
|
+
@media(max-width:820px){.wrap{padding:28px max(14px,env(safe-area-inset-right)) 70px max(14px,env(safe-area-inset-left))}.hero{padding:26px 20px}.grid{grid-template-columns:repeat(2,minmax(0,1fr))}#list{grid-template-columns:1fr}h1{font-size:30px}.item-head{flex-wrap:wrap}}
|
|
43
|
+
|
|
44
|
+
/* #870 · 表单控件命中区 ≥44×44px(t849 §2 硬线;实测基线 33 处不足全在这一族) */
|
|
45
|
+
input[type=text],input[type=date],input[type=search],input:not([type]),select{min-height:44px;box-sizing:border-box}
|
|
30
46
|
</style>
|
|
31
47
|
</head>
|
|
32
48
|
<body>
|
|
33
|
-
<div class="wrap">
|
|
49
|
+
<div class="wrap ilife-page-ui">
|
|
34
50
|
<header class="hero">
|
|
35
51
|
<h1 id="title">备忘录查询结果</h1>
|
|
36
52
|
<p class="lead" id="subtitle">数据加载中</p>
|
|
53
|
+
<p class="subnote" id="subtitleExtra"></p>
|
|
37
54
|
<p class="meta" id="meta"></p>
|
|
55
|
+
<nav class="ilife-block-toc jump" aria-label="页内导航"><a href="#stats">统计</a><a href="#list">结果</a><a href="#data-panel">日志</a></nav>
|
|
38
56
|
</header>
|
|
39
57
|
<section id="injectError" style="display:none"></section>
|
|
40
58
|
<section class="grid" id="stats"></section>
|
|
@@ -48,16 +66,23 @@ h1{font-size:38px;line-height:1.15;letter-spacing:-.035em;margin-bottom:12px}.le
|
|
|
48
66
|
<section id="list"></section>
|
|
49
67
|
<section class="panel">
|
|
50
68
|
<strong>筛选快照</strong>
|
|
51
|
-
<p class="small" style="margin-top:6px"
|
|
69
|
+
<p class="small" style="margin-top:6px">复制的是这一屏筛出来的结果(页内搜索词与分类筛选都算在内),可直接粘贴给助手继续下一步。</p>
|
|
52
70
|
<div class="toolbar"><button class="copy ghost" data-copy-receipt onclick="copyFiltered()">复制筛选结果</button></div>
|
|
53
71
|
<pre id="receipt" style="display:none"></pre>
|
|
54
72
|
</section>
|
|
55
|
-
<section class="panel">
|
|
56
|
-
<
|
|
57
|
-
<
|
|
58
|
-
<div class="
|
|
59
|
-
<button class="copy ghost"
|
|
60
|
-
<
|
|
73
|
+
<section class="ilife-block ilife-block-copy-block" id="data-panel">
|
|
74
|
+
<div class="ilife-action-bar">
|
|
75
|
+
<div class="ilife-action-row ilife-action-row-ghost">
|
|
76
|
+
<div class="ilife-copy-menu-wrap">
|
|
77
|
+
<button type="button" class="ilife-copy-btn ilife-copy-btn-ghost" data-fmt-open="1" aria-haspopup="menu" aria-expanded="false" aria-label="复制数据(点开选格式)">复制数据</button>
|
|
78
|
+
<div class="ilife-copy-menu" role="menu">
|
|
79
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="text" data-t=""><span class="ilife-copy-menu-label">纯文本</span></button>
|
|
80
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="json" data-t=""><span class="ilife-copy-menu-label">JSON</span></button>
|
|
81
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="csv" data-t=""><span class="ilife-copy-menu-label">CSV</span></button>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
<button type="button" class="ilife-copy-btn ilife-copy-btn-ghost" data-action-id="memo-copy-log">复制日志</button>
|
|
85
|
+
</div>
|
|
61
86
|
</div>
|
|
62
87
|
</section>
|
|
63
88
|
</div>
|
|
@@ -75,8 +100,10 @@ window.__hmPayload=payload;
|
|
|
75
100
|
const MAX_DEFAULT = 50;
|
|
76
101
|
var appState={category:'全部',q:'',showAll:false};
|
|
77
102
|
function dataRows(){var d=payload.data;if(Array.isArray(d))return d;if(Array.isArray(d.items))return d.items;if(d.item)return [d.item];return []}
|
|
78
|
-
function init(){var d=payload.data;document.getElementById('title').textContent=d.title||'备忘录查询结果';document.getElementById('subtitle').textContent=payload.message||d.subtitle||'查询完成';var meta=d.meta||{};document.getElementById('meta').textContent=`生成时间:${d.generated_at||''}
|
|
103
|
+
function init(){var d=payload.data;document.getElementById('title').textContent=d.title||'备忘录查询结果';document.getElementById('subtitle').textContent=payload.message||d.subtitle||'查询完成';renderCondition();var meta=d.meta||{};document.getElementById('meta').textContent=`生成时间:${d.generated_at||''}`;renderStats();renderChips();renderList();renderReceipt();// success: 数据加载完成,内容已渲染
|
|
79
104
|
}
|
|
105
|
+
/* 查询条件:一条一枚胶囊(`data.condition` 是数组;老页没有这一位即整行不出)。 */
|
|
106
|
+
function renderCondition(){var d=payload.data;var list=Array.isArray(d.condition)?d.condition:[];var box=document.getElementById('subtitleExtra');box.innerHTML=list.map(function(c){return '<span class="chip-cond">'+esc(String(c))+'</span>'}).join("")}
|
|
80
107
|
function rowsFiltered(){var rows=dataRows();if(appState.category!=='全部')rows=rows.filter(x=>(x.category||x.repeat_type||'未分类')===appState.category);if(appState.q){var q=appState.q.toLowerCase();rows=rows.filter(x=>String(x.content||'').toLowerCase().includes(q))}return rows}
|
|
81
108
|
function categories(){return ['全部',...Array.from(new Set(dataRows().map(x=>x.category||x.repeat_type||'未分类').filter(Boolean)))]}
|
|
82
109
|
function renderStats(){var rows=dataRows();var due=rows.filter(x=>x.due).length;var sample=rows[0]||{};var hasMediaField='media_path' in sample;var media=hasMediaField?rows.filter(x=>x.media_path).length:'—';var reminders=rows.filter(x=>x.remind_at||x.reminder_id).length;document.getElementById('stats').innerHTML=[['总数',rows.length],['有排期',due],['有附件',media],['有提醒',reminders]].map(x=>`<div class="stat"><b>${x[1]}</b><span>${esc(x[0])}</span></div>`).join('')}
|
|
@@ -84,19 +111,27 @@ function renderChips(){document.getElementById('chips').innerHTML=categories().m
|
|
|
84
111
|
function setCat(c){appState.category=c;renderChips();renderList();renderReceipt()}
|
|
85
112
|
document.getElementById('filter').addEventListener('input',e=>{appState.q=e.target.value;renderList();renderReceipt()});
|
|
86
113
|
document.getElementById('lengthModeBtn').addEventListener('click',toggleLengthMode);
|
|
87
|
-
function renderList(){var all=rowsFiltered();var totalCount=all.length;var cap=appState.showAll?totalCount:Math.min(MAX_DEFAULT,totalCount);var rows=all.slice(0,cap);var list=document.getElementById('list');if(!all.length){
|
|
114
|
+
function renderList(){var all=rowsFiltered();var totalCount=all.length;var cap=appState.showAll?totalCount:Math.min(MAX_DEFAULT,totalCount);var rows=all.slice(0,cap);var list=document.getElementById('list');if(!all.length){
|
|
115
|
+
/* #820 收尾(视觉审查 H2):空态分两种 —— 这一趟本来就没内容(如「查已提醒备忘」一条都没触发过)
|
|
116
|
+
与「筛掉了」。两种说法不同,别拿「换关键词再试」去解释「本来就没有」(与页头那句自相矛盾)。 */
|
|
117
|
+
var noneAtAll=dataRows().length===0;
|
|
118
|
+
list.innerHTML=window.emptyState(noneAtAll
|
|
119
|
+
? {icon:'🗒',text:'还没有可显示的内容',hint:'换一条唤醒词,或按页头的提示先补一条'}
|
|
120
|
+
: {icon:'🔍',text:'没有匹配结果',hint:'换关键词或分类再试'});
|
|
121
|
+
document.getElementById('length-mode-bar').style.display='none';return}list.innerHTML=rows.map(renderItem).join('');var bar=document.getElementById('length-mode-bar');var btn=document.getElementById('lengthModeBtn');var hint=document.getElementById('lengthModeHint');if(totalCount>MAX_DEFAULT){bar.style.display='flex';btn.textContent=appState.showAll?`显示前 ${MAX_DEFAULT} 条`:`显示全部 (${totalCount} 条)`;hint.textContent=appState.showAll?`已展开全部,往下滚可看完`: `默认仅显示前 ${MAX_DEFAULT} 条`;}else{bar.style.display='none'}}
|
|
88
122
|
function toggleLengthMode(){appState.showAll=!appState.showAll;renderList();renderReceipt()}
|
|
89
|
-
function renderItem(x){var id=x.id||x.checkin_note_id||x.reminder_id||'';var content=x.content||x.checkin_content||x.reminder_content||x.note_content||'';var badges=[x.category,x.sub_category,x.repeat_type,x.due?`排期 ${x.due}`:'',x.remind_at?`提醒 ${x.remind_at}`:'',x.media_path?'附件':''].filter(Boolean);var created=String(x.created_at||x.checkin_at||'').slice(5,16);var updated=String(x.updated_at||'').slice(5,16);var timeRow=updated&&updated!==created?`<p class="small"
|
|
123
|
+
function renderItem(x){var id=x.id||x.checkin_note_id||x.reminder_id||'';var content=x.content||x.checkin_content||x.reminder_content||x.note_content||'';var badges=[x.category,x.sub_category,x.repeat_type,x.due?`排期 ${x.due}`:'',x.remind_at?`提醒 ${x.remind_at}`:'',x.media_path?'附件':''].filter(Boolean);var created=String(x.created_at||x.checkin_at||'').slice(5,16);var updated=String(x.updated_at||'').slice(5,16);var timeRow=updated&&updated!==created?`<p class="small">创建于 ${esc(created)} 改于 ${esc(updated)}</p>`:`<p class="small">创建于 ${esc(created)}</p>`;return `<article class="item"><div class="item-head"><div class="id">#${esc(id)}</div><button class="copy ghost" data-item='${esc(JSON.stringify(x))}' onclick="copyInfo(this)">复制</button></div><div class="content">${esc(content)}</div><div>${badges.map(b=>`<span class="badge ${String(b).includes('排期')||String(b).includes('提醒')?'warn':''}">${esc(b)}</span>`).join('')}</div>${timeRow}</article>`}
|
|
90
124
|
function snapshotText(){var d=payload.data;var filtered=rowsFiltered();var meta=d.meta||{};var text=`① 场景: 我在备忘录查询页筛选出了 ${filtered.length} 条结果(共 ${dataRows().length} 条)\n\n② 数据(筛选后):`;if(!filtered.length){text+='\n (无匹配结果 · 请调整筛选)';}filtered.forEach(function(x){text+=`\n · #${x.id||x.checkin_note_id||x.reminder_id||''} [${esc(x.category||'未分类')}${x.sub_category?'/'+esc(x.sub_category):''}] ${esc(x.created_at||x.checkin_at||'')}\n ${esc((x.content||x.checkin_content||'').slice(0,80))}`;});text+=`\n\n③ 期望: 请基于以上结果继续下一步(修改/删除/改分类/关联提醒等,我会补充说明)\n\n④ 来源: ${meta.command_cn||d.command||'search'} · 筛选: ${appState.category}${appState.q?' / '+appState.q:''} · ${d.generated_at||''}`;return text}
|
|
91
125
|
function renderReceipt(){document.getElementById('receipt').textContent=snapshotText()}
|
|
92
126
|
function copyInfo(btn){try{var raw=btn.getAttribute('data-item').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,'&');var x=JSON.parse(raw);var id=x.id||x.checkin_note_id||x.reminder_id||'';var content=x.content||x.checkin_content||'';var cat=x.category||'未分类';var sub=x.sub_category?'/'+x.sub_category:'';var created=x.created_at||x.checkin_at||'';var text=`备忘录 #${id}\n分类: ${cat}${sub}\n创建: ${created}\n内容: ${content}\n`;if(x.due)text+=`排期: ${x.due}\n`;if(x.remind_at)text+=`提醒: ${x.remind_at}\n`;window.copyText(text,{silent:true});window.toast('已复制这条备忘','#'+id+' · '+content.slice(0,20),{icon:'copy'});}catch(e){window.toast('复制失败','长按选择文本手动复制',{badge:{text:'失败',type:'danger'}})}}
|
|
93
127
|
function copyFiltered(){var text=snapshotText();if(!text)return;var out=document.getElementById('receipt');out.textContent=text;out.style.display='block';window.copyText(text,{silent:true});window.toast('筛选结果已复制','粘贴给 AI 继续下一步',{icon:'copy'});}
|
|
94
|
-
function copyData(){window.
|
|
95
|
-
function copyLog(){window.
|
|
128
|
+
function copyData(){window.memoAttachCopyArea();window.toast('数据已复制','人类可读快照 · 可粘贴到笔记存档',{icon:'copy'});}
|
|
129
|
+
function copyLog(){window.memoAttachCopyArea();window.toast('日志已复制','诊断信息 · 有异常时粘贴给开发者排查',{icon:'copy'});}
|
|
96
130
|
window.copyInfo=copyInfo;
|
|
97
131
|
window.copyFiltered=copyFiltered;
|
|
98
132
|
window.copyData=copyData;
|
|
99
133
|
window.copyLog=copyLog;
|
|
134
|
+
window.memoAttachCopyArea();
|
|
100
135
|
init();
|
|
101
136
|
})();
|
|
102
137
|
</script>
|
package/templates/receipt.html
CHANGED
|
@@ -10,22 +10,30 @@
|
|
|
10
10
|
body{font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;background:var(--bg);color:var(--fg);line-height:1.65;-webkit-font-smoothing:antialiased}
|
|
11
11
|
.wrap{max-width:980px;margin:0 auto;padding:48px 22px 90px}
|
|
12
12
|
.hero{background:var(--card);border-radius:28px;padding:34px;margin-bottom:20px;box-shadow:var(--shadow,0 1px 2px rgba(0,0,0,.04),0 12px 36px rgba(0,0,0,.06))}
|
|
13
|
-
.eyebrow{font-size:13px;color:var(--blue);font-weight:800;letter-spacing:.08em;margin-bottom:10px}
|
|
14
13
|
h1{font-size:36px;line-height:1.15;letter-spacing:-.035em;margin-bottom:12px}
|
|
15
14
|
.lead{color:var(--fg);font-size:17px;font-weight:600}
|
|
16
15
|
.badges{margin-top:14px}
|
|
17
16
|
.badge{display:inline-block;background:var(--soft,#f5f8ff);color:var(--blue);padding:6px 12px;border-radius:999px;font-size:13px;font-weight:700;margin:2px 8px 2px 0;min-height:28px;line-height:1.4}
|
|
18
|
-
.meta{margin-top:12px;color:var(--fg3);font-size:13px}
|
|
17
|
+
.meta{display:flex;flex-wrap:wrap;gap:6px 20px;margin-top:12px;color:var(--fg3);font-size:13px}
|
|
18
|
+
.meta-pair{display:inline-flex;align-items:baseline;gap:6px}
|
|
19
|
+
.meta .fact-v{color:var(--fg2);font-weight:600}
|
|
19
20
|
.panel{background:var(--card);border-radius:20px;padding:22px;box-shadow:0 1px 3px rgba(0,0,0,.04);margin:14px 0}
|
|
20
21
|
.panel h2{font-size:16px;margin-bottom:12px}
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
/* 「这次的结果」与「处理结果」用**同一个形状**:标签+值两列(窄屏堆成一列)。
|
|
23
|
+
不再拿 `:`/`/`/空格把两个事实挤进一格(负责人 2026-09-22:符号顶替设计的地方要改成 UI 设计)。 */
|
|
24
|
+
.facts{display:grid;grid-template-columns:minmax(84px,auto) 1fr;gap:10px 16px;font-size:15px}
|
|
25
|
+
.fact{display:contents}
|
|
26
|
+
.fact-k{color:var(--fg2)}
|
|
27
|
+
.fact-v{font-weight:600;word-break:break-word}
|
|
28
|
+
.fact-note{grid-column:1/-1;color:var(--fg2);font-size:14px}
|
|
23
29
|
.kv{display:grid;grid-template-columns:minmax(84px,auto) 1fr;gap:10px 16px;font-size:15px}
|
|
24
30
|
.kv dt{color:var(--fg2)}
|
|
25
31
|
.kv dd{font-weight:600;word-break:break-word}
|
|
26
32
|
.rows{list-style:none}
|
|
27
|
-
.rows li{padding:12px 0;border-bottom:1px solid var(--line);font-size:15px}
|
|
33
|
+
.rows li{padding:12px 0;border-bottom:1px solid var(--line);font-size:15px;display:flex;flex-wrap:wrap;align-items:baseline;gap:8px}
|
|
28
34
|
.rows li:last-child{border-bottom:0}
|
|
35
|
+
.row-id{color:var(--blue);font-weight:800;flex:none}
|
|
36
|
+
.rows .badge{background:var(--soft,#f5f8ff);color:var(--fg2);padding:3px 10px;font-size:12px;min-height:0;line-height:1.5;flex:none;margin:0}
|
|
29
37
|
.hint{font-size:12px;color:var(--fg3);margin-top:6px}
|
|
30
38
|
.toolbar{display:flex;gap:10px;flex-wrap:wrap;margin:14px 0;align-items:center}
|
|
31
39
|
button{border:0;border-radius:999px;cursor:pointer;font-size:14px;font-weight:600;font-family:inherit}
|
|
@@ -34,15 +42,17 @@ button.copy{background:var(--card);color:var(--blue);border:1.5px solid var(--bl
|
|
|
34
42
|
.wrap{padding:28px 14px 70px}
|
|
35
43
|
.hero{padding:26px 20px;border-radius:22px}
|
|
36
44
|
h1{font-size:30px}
|
|
37
|
-
.kv{grid-template-columns:1fr;gap:2px 0}
|
|
38
|
-
.kv dd{margin-bottom:10px}
|
|
45
|
+
.kv,.facts{grid-template-columns:1fr;gap:2px 0}
|
|
46
|
+
.kv dd,.fact-v{margin-bottom:10px}
|
|
39
47
|
}
|
|
48
|
+
|
|
49
|
+
/* #870 · 表单控件命中区 ≥44×44px(t849 §2 硬线;实测基线 33 处不足全在这一族) */
|
|
50
|
+
input[type=text],input[type=date],input[type=search],input:not([type]),select{min-height:44px;box-sizing:border-box}
|
|
40
51
|
</style>
|
|
41
52
|
</head>
|
|
42
53
|
<body>
|
|
43
|
-
<div class="wrap">
|
|
54
|
+
<div class="wrap ilife-page-ui">
|
|
44
55
|
<header class="hero">
|
|
45
|
-
<p class="eyebrow">备忘录回执</p>
|
|
46
56
|
<h1 id="title">回执</h1>
|
|
47
57
|
<p class="lead" id="lead">数据加载中</p>
|
|
48
58
|
<div class="badges" id="badges"></div>
|
|
@@ -57,7 +67,7 @@ button.copy{background:var(--card);color:var(--blue);border:1.5px solid var(--bl
|
|
|
57
67
|
|
|
58
68
|
<section class="panel" id="resultPanel" style="display:none">
|
|
59
69
|
<h2>处理结果</h2>
|
|
60
|
-
<
|
|
70
|
+
<div class="facts" id="result"></div>
|
|
61
71
|
</section>
|
|
62
72
|
|
|
63
73
|
<section class="panel" id="rowsPanel" style="display:none">
|
|
@@ -65,12 +75,19 @@ button.copy{background:var(--card);color:var(--blue);border:1.5px solid var(--bl
|
|
|
65
75
|
<ul class="rows" id="rows"></ul>
|
|
66
76
|
</section>
|
|
67
77
|
|
|
68
|
-
<section class="
|
|
69
|
-
<
|
|
70
|
-
<div class="
|
|
71
|
-
<div class="
|
|
72
|
-
<button class="copy"
|
|
73
|
-
<
|
|
78
|
+
<section class="ilife-block ilife-block-copy-block">
|
|
79
|
+
<div class="ilife-action-bar">
|
|
80
|
+
<div class="ilife-action-row ilife-action-row-ghost">
|
|
81
|
+
<div class="ilife-copy-menu-wrap">
|
|
82
|
+
<button type="button" class="ilife-copy-btn ilife-copy-btn-ghost" data-fmt-open="1" aria-haspopup="menu" aria-expanded="false" aria-label="复制数据(点开选格式)">复制数据</button>
|
|
83
|
+
<div class="ilife-copy-menu" role="menu">
|
|
84
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="text" id="btnData" data-t=""><span class="ilife-copy-menu-label">纯文本</span></button>
|
|
85
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="json" data-t=""><span class="ilife-copy-menu-label">JSON</span></button>
|
|
86
|
+
<button type="button" class="ilife-copy-menu-item" data-fmt="csv" data-t=""><span class="ilife-copy-menu-label">CSV</span></button>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
<button type="button" class="ilife-copy-btn ilife-copy-btn-ghost" data-action-id="memo-copy-log" id="btnLog" data-t="">复制日志</button>
|
|
90
|
+
</div>
|
|
74
91
|
</div>
|
|
75
92
|
</section>
|
|
76
93
|
</div>
|
|
@@ -94,12 +111,12 @@ function init(){
|
|
|
94
111
|
var d=data(),s=snap(),r=receipt(),meta=d.meta||{};
|
|
95
112
|
document.title=d.title||"备忘录回执";
|
|
96
113
|
document.getElementById("title").textContent=d.title||"备忘录回执";
|
|
97
|
-
document.getElementById("lead").textContent=payload.message||r.message||"";
|
|
114
|
+
document.getElementById("lead").textContent=leadText(payload.message||r.message||"");
|
|
98
115
|
var b=[];
|
|
99
116
|
if(r.category)b.push('<span class="badge">'+esc(r.category)+'</span>');
|
|
100
117
|
if(r.sub)b.push('<span class="badge">'+esc(r.sub)+'</span>');
|
|
101
118
|
document.getElementById("badges").innerHTML=b.join("");
|
|
102
|
-
document.getElementById("meta").
|
|
119
|
+
document.getElementById("meta").innerHTML=metaPairs(d,meta);
|
|
103
120
|
renderFacts();
|
|
104
121
|
renderResult();
|
|
105
122
|
renderRows();
|
|
@@ -107,21 +124,55 @@ function init(){
|
|
|
107
124
|
document.getElementById("btnLog").setAttribute("data-t",window.buildLogText(payload));
|
|
108
125
|
}
|
|
109
126
|
|
|
127
|
+
/** 页首那一行:时间与唤醒词各成一组「标签+值」(原先用全角空格把两件事挤成一行 —— 同一类符号顶替设计)。 */
|
|
128
|
+
function metaPairs(d,meta){
|
|
129
|
+
var out=[];
|
|
130
|
+
if(d.generated_at) out.push('<span class="meta-pair"><span class="fact-k">时间</span><span class="fact-v">'+esc(d.generated_at)+'</span></span>');
|
|
131
|
+
if(meta.wake_word) out.push('<span class="meta-pair"><span class="fact-k">唤醒词</span><span class="fact-v">「'+esc(meta.wake_word)+'」</span></span>');
|
|
132
|
+
return out.join("");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* #820 收尾(终审 D3·H3):写侧 message 末尾那个数字是**记录号**(`已记一条:18`=这条的编号是 18),
|
|
136
|
+
不是条数 —— 读起来像「记了 18 条」;而同一个号在卡里还印两遍(`笔记编号 18`/`备忘 #18`)。
|
|
137
|
+
上屏时把尾号剁掉(号在卡里读得到),**原始 message 一个字不改**:复制日志的「结论」与载荷
|
|
138
|
+
仍是机器面原样(`buildLogText` 用的是 `payload.message`,不走本函数)。 */
|
|
139
|
+
function leadText(m){
|
|
140
|
+
var t=String(m||"");var x=/^(.*?)[::]\s*\d+\s*$/.exec(t);
|
|
141
|
+
return x===null?t:x[1];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** 一格「标签+值」;值若写成「结论(说明)」,把说明拆到**下一行**(灰、整宽)。
|
|
145
|
+
*
|
|
146
|
+
* #820 收尾(终审 D3):原先说明塞在值格里,`远端侧 不适用(这条没有飞书任务)` 的值行长度
|
|
147
|
+
* 是同类行长的两三倍,窄屏更挤。拆开后值格只留结论,说明整宽单独一行。 */
|
|
148
|
+
function factHtml(k,v){
|
|
149
|
+
var m=/^(.*?)(([^()]+))$/.exec(v);
|
|
150
|
+
var note=(m===null)?"":'<div class="fact-note">'+esc(m[2])+'</div>';
|
|
151
|
+
return '<div class="fact"><span class="fact-k">'+esc(k)+'</span><span class="fact-v">'
|
|
152
|
+
+ esc(m===null?v:m[1])+'</span></div>'+note;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** 事实条:一条一格「标签+值」(冒号只作**数据分隔**,屏上是两列,不是一句话);没冒号的当整行说明。 */
|
|
110
156
|
function renderFacts(){
|
|
111
157
|
var s=snap();var sum=Array.isArray(s.summary)?s.summary:[];
|
|
112
158
|
if(!sum.length)return;
|
|
113
159
|
document.getElementById("factsPanel").style.display="block";
|
|
114
|
-
document.getElementById("facts").innerHTML=sum.map(function(x){
|
|
160
|
+
document.getElementById("facts").innerHTML=sum.map(function(x){
|
|
161
|
+
var t=String(x);var i=t.indexOf(":");
|
|
162
|
+
if(i<0)return '<div class="fact-note">'+esc(t)+'</div>';
|
|
163
|
+
return factHtml(t.slice(0,i),t.slice(i+1));
|
|
164
|
+
}).join("");
|
|
115
165
|
}
|
|
116
166
|
|
|
167
|
+
/** 「处理结果」与「这次的结果」**同一形状**(#820 收尾:原先这一块是 `<dl><dt><dd>` 另一套行型)。 */
|
|
117
168
|
function renderResult(){
|
|
118
169
|
var rows=receipt().rows;
|
|
119
170
|
if(!Array.isArray(rows)||!rows.length)return;
|
|
120
171
|
document.getElementById("resultPanel").style.display="block";
|
|
121
172
|
document.getElementById("result").innerHTML=rows.map(function(line){
|
|
122
|
-
var
|
|
123
|
-
if(i<0)return "
|
|
124
|
-
return
|
|
173
|
+
var t=String(line);var i=t.indexOf(":");
|
|
174
|
+
if(i<0)return '<div class="fact-note">'+esc(t)+'</div>';
|
|
175
|
+
return factHtml(t.slice(0,i),t.slice(i+1));
|
|
125
176
|
}).join("");
|
|
126
177
|
}
|
|
127
178
|
|
|
@@ -131,13 +182,32 @@ function renderRows(){
|
|
|
131
182
|
if(!rest.length)return;
|
|
132
183
|
document.getElementById("rowsPanel").style.display="block";
|
|
133
184
|
document.getElementById("rowsHead").textContent=rest.length===1?rest[0].heading:"明细";
|
|
134
|
-
|
|
185
|
+
/* #820 收尾(视觉审查 H4):一页只有一种键值形状 —— 区块里若整组都是「标签:值」,
|
|
186
|
+
就跟「这次的结果」用同一种排法(标签+值两列),不再另起一套「标签:值」同行+细线。 */
|
|
187
|
+
var html=[];
|
|
135
188
|
rest.forEach(function(sec){
|
|
136
|
-
sec.rows.
|
|
137
|
-
|
|
138
|
-
|
|
189
|
+
var rows=sec.rows,kv=rows.length>0&&rows.every(function(r){return typeof r==="string"&&r.indexOf(":")>0});
|
|
190
|
+
if(kv){
|
|
191
|
+
html.push('<div class="facts">'+rows.map(function(r){
|
|
192
|
+
var t=String(r),i=t.indexOf(":");
|
|
193
|
+
return '<div class="fact"><span class="fact-k">'+esc(t.slice(0,i))+'</span><span class="fact-v">'+esc(t.slice(i+1))+'</span></div>';
|
|
194
|
+
}).join("")+'</div>');
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
html.push('<ul class="rows">'+rows.map(function(row){return '<li>'+rowHtml(row)+'</li>'}).join("")+'</ul>');
|
|
139
198
|
});
|
|
140
|
-
document.getElementById("rows").innerHTML=
|
|
199
|
+
document.getElementById("rows").innerHTML=html.join("");
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** 一行:带结构的(`{id,text,status}`)落成「编号徽章 + 正文 + 状态徽章」;
|
|
203
|
+
* 纯字符串原样上屏(老形状)。编号与状态都是**另一个维度**,不拼进正文那一串里。 */
|
|
204
|
+
function rowHtml(row){
|
|
205
|
+
if(typeof row!=="object"||row===null)return esc(String(row));
|
|
206
|
+
var h='';
|
|
207
|
+
if(row.id!==undefined&&row.id!==null&&row.id!=="")h+='<span class="row-id">#'+esc(String(row.id))+'</span>';
|
|
208
|
+
h+=esc(String(row.text||""));
|
|
209
|
+
if(row.status)h+='<span class="badge">'+esc(String(row.status))+'</span>';
|
|
210
|
+
return h;
|
|
141
211
|
}
|
|
142
212
|
|
|
143
213
|
function dataText(){
|