skill-schedule 0.3.3 → 0.3.12
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 +12 -3
- package/dist/.gen-inputs.json +4 -4
- package/dist/admin/adminDocs.d.ts +57 -0
- package/dist/admin/adminDocs.d.ts.map +1 -0
- package/dist/admin/adminDocs.js +190 -0
- package/dist/admin/adminDocs.js.map +1 -0
- package/dist/admin/adminParts.d.ts +37 -0
- package/dist/admin/adminParts.d.ts.map +1 -0
- package/dist/admin/adminParts.js +83 -0
- package/dist/admin/adminParts.js.map +1 -0
- package/dist/admin/handlers.d.ts.map +1 -1
- package/dist/admin/handlers.js +196 -6
- package/dist/admin/handlers.js.map +1 -1
- package/dist/admin/routes.d.ts +10 -1
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +2 -0
- package/dist/admin/routes.js.map +1 -1
- package/dist/analyze/analyzeDocs.d.ts +51 -0
- package/dist/analyze/analyzeDocs.d.ts.map +1 -0
- package/dist/analyze/analyzeDocs.js +442 -0
- package/dist/analyze/analyzeDocs.js.map +1 -0
- package/dist/analyze/analyzeParts.d.ts +53 -0
- package/dist/analyze/analyzeParts.d.ts.map +1 -0
- package/dist/analyze/analyzeParts.js +229 -0
- package/dist/analyze/analyzeParts.js.map +1 -0
- package/dist/analyze/handlers.d.ts.map +1 -1
- package/dist/analyze/handlers.js +41 -4
- package/dist/analyze/handlers.js.map +1 -1
- package/dist/cli/cmd_read.js +8 -2
- package/dist/cli/cmd_read.js.map +1 -1
- package/dist/fetch/feishu.d.ts +6 -0
- package/dist/fetch/feishu.d.ts.map +1 -1
- package/dist/fetch/feishu.js +18 -7
- package/dist/fetch/feishu.js.map +1 -1
- package/dist/fetch/index.d.ts +1 -1
- package/dist/fetch/index.d.ts.map +1 -1
- package/dist/fetch/index.js +1 -1
- package/dist/fetch/index.js.map +1 -1
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +8 -5
- package/dist/health.js.map +1 -1
- package/dist/help/index.d.ts +1 -0
- package/dist/help/index.d.ts.map +1 -1
- package/dist/help/index.js +3 -0
- package/dist/help/index.js.map +1 -1
- package/dist/plan/discussDocs.d.ts +8 -0
- package/dist/plan/discussDocs.d.ts.map +1 -0
- package/dist/plan/discussDocs.js +321 -0
- package/dist/plan/discussDocs.js.map +1 -0
- package/dist/plan/feishuDocs.d.ts +19 -0
- package/dist/plan/feishuDocs.d.ts.map +1 -0
- package/dist/plan/feishuDocs.js +257 -0
- package/dist/plan/feishuDocs.js.map +1 -0
- package/dist/plan/handlers.d.ts.map +1 -1
- package/dist/plan/handlers.js +107 -3
- package/dist/plan/handlers.js.map +1 -1
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.d.ts.map +1 -1
- package/dist/plan/index.js +16 -9
- package/dist/plan/index.js.map +1 -1
- package/dist/plan/iso.d.ts +2 -0
- package/dist/plan/iso.d.ts.map +1 -1
- package/dist/plan/iso.js +6 -2
- package/dist/plan/iso.js.map +1 -1
- package/dist/plan/planDocs.d.ts +47 -0
- package/dist/plan/planDocs.d.ts.map +1 -0
- package/dist/plan/planDocs.js +159 -0
- package/dist/plan/planDocs.js.map +1 -0
- package/dist/plan/planParts.d.ts +38 -0
- package/dist/plan/planParts.d.ts.map +1 -0
- package/dist/plan/planParts.js +96 -0
- package/dist/plan/planParts.js.map +1 -0
- package/dist/plan/probe.d.ts +28 -0
- package/dist/plan/probe.d.ts.map +1 -0
- package/dist/plan/probe.js +114 -0
- package/dist/plan/probe.js.map +1 -0
- package/dist/plan/receipt.d.ts +12 -0
- package/dist/plan/receipt.d.ts.map +1 -1
- package/dist/plan/receipt.js +17 -0
- package/dist/plan/receipt.js.map +1 -1
- package/dist/plan/receiptDocs.d.ts +26 -0
- package/dist/plan/receiptDocs.d.ts.map +1 -0
- package/dist/plan/receiptDocs.js +341 -0
- package/dist/plan/receiptDocs.js.map +1 -0
- package/dist/plan/replayDocs.d.ts +165 -0
- package/dist/plan/replayDocs.d.ts.map +1 -0
- package/dist/plan/replayDocs.js +226 -0
- package/dist/plan/replayDocs.js.map +1 -0
- package/dist/plan/replaySections.d.ts +5 -0
- package/dist/plan/replaySections.d.ts.map +1 -0
- package/dist/plan/replaySections.js +471 -0
- package/dist/plan/replaySections.js.map +1 -0
- package/dist/plan/reviewDocs.d.ts +4 -0
- package/dist/plan/reviewDocs.d.ts.map +1 -0
- package/dist/plan/reviewDocs.js +130 -0
- package/dist/plan/reviewDocs.js.map +1 -0
- package/dist/plan/sync.d.ts.map +1 -1
- package/dist/plan/sync.js +5 -0
- package/dist/plan/sync.js.map +1 -1
- package/dist/policy/index.d.ts +1 -1
- package/dist/policy/index.d.ts.map +1 -1
- package/dist/policy/index.js +1 -1
- package/dist/policy/index.js.map +1 -1
- package/dist/policy/plan.d.ts +8 -0
- package/dist/policy/plan.d.ts.map +1 -1
- package/dist/policy/plan.js +20 -0
- package/dist/policy/plan.js.map +1 -1
- package/dist/query/handlers.d.ts +3 -0
- package/dist/query/handlers.d.ts.map +1 -1
- package/dist/query/handlers.js +86 -12
- package/dist/query/handlers.js.map +1 -1
- package/dist/query/queryDocs.d.ts +64 -0
- package/dist/query/queryDocs.d.ts.map +1 -0
- package/dist/query/queryDocs.js +554 -0
- package/dist/query/queryDocs.js.map +1 -0
- package/dist/query/routes.d.ts +11 -1
- package/dist/query/routes.d.ts.map +1 -1
- package/dist/query/routes.js +5 -1
- package/dist/query/routes.js.map +1 -1
- package/dist/render/copyArea.d.ts +61 -0
- package/dist/render/copyArea.d.ts.map +1 -0
- package/dist/render/copyArea.js +80 -0
- package/dist/render/copyArea.js.map +1 -0
- package/dist/render/html.d.ts.map +1 -1
- package/dist/render/html.js +3 -1
- package/dist/render/html.js.map +1 -1
- package/dist/render/index.d.ts +3 -0
- package/dist/render/index.d.ts.map +1 -1
- package/dist/render/index.js +2 -0
- package/dist/render/index.js.map +1 -1
- package/dist/shared/dayPage.d.ts +67 -0
- package/dist/shared/dayPage.d.ts.map +1 -0
- package/dist/shared/dayPage.js +92 -0
- package/dist/shared/dayPage.js.map +1 -0
- package/dist/shared/detailPage.d.ts +55 -0
- package/dist/shared/detailPage.d.ts.map +1 -0
- package/dist/shared/detailPage.js +65 -0
- package/dist/shared/detailPage.js.map +1 -0
- package/dist/shared/docPage.d.ts +22 -0
- package/dist/shared/docPage.d.ts.map +1 -0
- package/dist/shared/docPage.js +52 -0
- package/dist/shared/docPage.js.map +1 -0
- package/dist/shared/overviewPage.d.ts +52 -0
- package/dist/shared/overviewPage.d.ts.map +1 -0
- package/dist/shared/overviewPage.js +65 -0
- package/dist/shared/overviewPage.js.map +1 -0
- package/dist/shared/pageNav.d.ts +24 -0
- package/dist/shared/pageNav.d.ts.map +1 -0
- package/dist/shared/pageNav.js +70 -0
- package/dist/shared/pageNav.js.map +1 -0
- package/dist/shared/pageParts.d.ts +45 -0
- package/dist/shared/pageParts.d.ts.map +1 -0
- package/dist/shared/pageParts.js +154 -0
- package/dist/shared/pageParts.js.map +1 -0
- package/dist/shared/planPage.d.ts +49 -0
- package/dist/shared/planPage.d.ts.map +1 -0
- package/dist/shared/planPage.js +48 -0
- package/dist/shared/planPage.js.map +1 -0
- package/dist/shared/rangePage.d.ts +44 -0
- package/dist/shared/rangePage.d.ts.map +1 -0
- package/dist/shared/rangePage.js +50 -0
- package/dist/shared/rangePage.js.map +1 -0
- package/dist/shared/weekPage.d.ts +36 -0
- package/dist/shared/weekPage.d.ts.map +1 -0
- package/dist/shared/weekPage.js +42 -0
- package/dist/shared/weekPage.js.map +1 -0
- package/dist/triggers/routes.generated.d.ts +23 -1
- package/dist/triggers/routes.generated.d.ts.map +1 -1
- package/dist/triggers/routes.generated.js +4 -1
- package/dist/triggers/routes.generated.js.map +1 -1
- package/dist/write/handlers.d.ts.map +1 -1
- package/dist/write/handlers.js +101 -5
- package/dist/write/handlers.js.map +1 -1
- package/dist/write/writeDocs.d.ts +27 -0
- package/dist/write/writeDocs.d.ts.map +1 -0
- package/dist/write/writeDocs.js +423 -0
- package/dist/write/writeDocs.js.map +1 -0
- package/dist/write/writeParts.d.ts +54 -0
- package/dist/write/writeParts.d.ts.map +1 -0
- package/dist/write/writeParts.js +117 -0
- package/dist/write/writeParts.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/** #788 · 飞书两条唤醒词的**两张页**:能力探测(只读)与日程管家同步(回执)。
|
|
2
|
+
*
|
|
3
|
+
* 为什么两张分开(照老侧的分工,也与 #787 的接缝对上):
|
|
4
|
+
* · 「飞书探测」(`op=sync` + `dryRun`)——**先看**:三档能力门探一遍,一门写都不发;
|
|
5
|
+
* · 「日程管家同步」(`op=sync`)——**执行**:回填标识、补齐远端、清孤儿,然后把这一趟做了什么
|
|
6
|
+
* 分格报出来。老侧那种「写之前先问一句」的交互,落在这两张页的分工上:要问就先跑探测,
|
|
7
|
+
* 要写就说同步(#787 的证据件把这一问划给了本票)。
|
|
8
|
+
*
|
|
9
|
+
* **页上文案纪律**:不出现命令键、库列名、参数名、票号与远端对象标识(那一串是内部标识,只进回执,
|
|
10
|
+
* 不进页);并列关系用读数卡与表格表达,不拿 `·`/`;`/`|`/`、`/`~` 顶替。
|
|
11
|
+
*/
|
|
12
|
+
import { renderCaliberLine, renderConclusionBar, renderDataTable, renderFeedbackBlock, renderKpiGrid, renderListRows, renderPreBlock, } from 'base-paint/blocks';
|
|
13
|
+
import { renderFactStrip } from 'base-paint';
|
|
14
|
+
import { listPlanEvents, shortLarkVersion } from '../fetch/index.js';
|
|
15
|
+
import { fmtDurShort, l1Of } from '../policy/index.js';
|
|
16
|
+
import { scheduleCopyArea } from '../render/copyArea.js';
|
|
17
|
+
import { assembleDocPage } from '../shared/docPage.js';
|
|
18
|
+
import { pageSections } from '../shared/pageNav.js';
|
|
19
|
+
import { minutesOfDayEnd } from './planDocs.js';
|
|
20
|
+
import { planPartsCss, renderSectionTitle } from './planParts.js';
|
|
21
|
+
import { REMOTE_LABEL, planCopyArea } from './receipt.js';
|
|
22
|
+
import { TIER_CN, TIER_NEXT, TIER_VALUE } from './probe.js';
|
|
23
|
+
const EYEBROW = '作息管家 日程与计划';
|
|
24
|
+
/** 外部来的原话(命令行 stderr、回执 message、错误串)上屏前过分隔符门(#516):
|
|
25
|
+
* 页自己的文案本来就照纪律写,这几处是**别的进程吐出来的字**——真让它把 `/`/`、` 带上屏,
|
|
26
|
+
* 就是设计债进门。做法是把那几种并列符号换成行文逗号,只动上屏这一份,回执载荷一字不改。 */
|
|
27
|
+
function plain(text) {
|
|
28
|
+
return text
|
|
29
|
+
.replace(/[·;;||//、+~~]/g, ',')
|
|
30
|
+
.replace(/,{2,}/g, ',')
|
|
31
|
+
.replace(/,([))】」])/g, '$1');
|
|
32
|
+
}
|
|
33
|
+
/** 事实条「命令行版本」只印数字(口径唯一定义地是 `fetch` 门的 `shortLarkVersion`)。
|
|
34
|
+
* `null`(没装)印「没装」,`unknown`/无数字印「读不到」。 */
|
|
35
|
+
/** 同步回执的分格(`runSync` 的 `counts`)在页上的名字与读法,一处定义。 */
|
|
36
|
+
const COUNT_LABELS = [
|
|
37
|
+
{ key: 'backfilled', label: '回填标识', hint: '远端本来就有但本地缺标识的,这一趟认回来的' },
|
|
38
|
+
{ key: 'created', label: '远端新建', hint: '本地有但远端没有,这一趟补上去的' },
|
|
39
|
+
{ key: 'updated', label: '远端改动', hint: '两边标题或备注不一样,按本地那一条改过去的' },
|
|
40
|
+
{ key: 'timeSynced', label: '时段回写', hint: '你在飞书里改过时段,尊重你,把它写回本地的' },
|
|
41
|
+
{ key: 'deleted', label: '远端清理', hint: '孤儿与同槽冗余,这一趟清掉的' },
|
|
42
|
+
{ key: 'pastSkipped', label: '过去日期跳过', hint: '昨天以前的计划不补建,免得死灰复燃' },
|
|
43
|
+
{ key: 'duplicates', label: '同槽冗余', hint: '同一时段里历史留下的重复对象' },
|
|
44
|
+
{ key: 'failed', label: '失败', hint: '这一趟没成的那几件' },
|
|
45
|
+
];
|
|
46
|
+
function eventRows(events) {
|
|
47
|
+
return events.map((p) => ({
|
|
48
|
+
time: p.time_start + ' 至 ' + p.time_end,
|
|
49
|
+
title: p.title,
|
|
50
|
+
category: l1Of(p.category ?? ''),
|
|
51
|
+
remote: p.feishu_event_id === null ? '没同步过' : '已同步飞书',
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
function localCounts(handle, date) {
|
|
55
|
+
const events = listPlanEvents(handle, date);
|
|
56
|
+
return {
|
|
57
|
+
total: events.length,
|
|
58
|
+
synced: events.filter((p) => p.feishu_event_id !== null).length,
|
|
59
|
+
minutes: events.reduce((sum, p) => sum + Math.max(0, minutesOfDayEnd(p.time_end) - minutesOfDayEnd(p.time_start)), 0),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/* ─────────────────────── ① 飞书探测(只读,三档) ─────────────────────── */
|
|
63
|
+
/** 「飞书探测」整页:三档结论 + 下一步 + 本地这一天的账(**这一趟没写任何对象**)。
|
|
64
|
+
*
|
|
65
|
+
* #896 · 「授权登录过」与进度条读 `report.authenticated`(布尔位),不读 `report.openId` 原值:
|
|
66
|
+
* 回执不带 openId 原串(隐私),`handlers.ts` 重建时 `openId` 置 null 仅占形状,显示以布尔位为准。
|
|
67
|
+
*/
|
|
68
|
+
export function probePage(handle, date, report) {
|
|
69
|
+
const local = localCounts(handle, date);
|
|
70
|
+
const kpis = [
|
|
71
|
+
{ label: '能力档位', value: TIER_VALUE[report.tier], detail: plain(report.why) },
|
|
72
|
+
{ label: '这一天本地计划', value: String(local.total), unit: '条', detail: '共 ' + fmtDurShort(local.minutes) },
|
|
73
|
+
{ label: '带远端标识的', value: String(local.synced), unit: '条', detail: '同步过的那些' },
|
|
74
|
+
{
|
|
75
|
+
label: '这一趟写了几笔',
|
|
76
|
+
value: '0',
|
|
77
|
+
detail: '只读探测,远端一行没动',
|
|
78
|
+
// 三档全通时给满,其余档按三门过了几门给(读数同源:探测结果那一份)。
|
|
79
|
+
// #896 · 读 authenticated 布尔位,不读 openId 原值(回执不带原串,见 probe.ts 件头)。
|
|
80
|
+
bar: { pct: Math.round(([report.cliPath === null ? 0 : 1, report.authenticated ? 1 : 0, report.calendar ? 1 : 0]
|
|
81
|
+
.reduce((a, b) => a + b, 0) / 3) * 100) },
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
const head = {
|
|
85
|
+
docTitle: '作息管家 飞书探测',
|
|
86
|
+
eyebrow: EYEBROW,
|
|
87
|
+
title: '飞书探测',
|
|
88
|
+
subtitle: '看本机的飞书能力到哪一档,以及 ' + date + ' 这一天本地排了什么。这一步只读,不写任何对象。',
|
|
89
|
+
};
|
|
90
|
+
const steps = [
|
|
91
|
+
{ step: '装有命令行', state: report.cliPath === null ? '没找到' : '在场', why: report.cliPath === null ? '家目录与查找路径里都没有' : '找到了可执行文件' },
|
|
92
|
+
{ step: '授权登录过', state: report.authenticated ? '过了' : '没过', why: report.authenticated ? '查到了登录身份' : '终端里查不到登录身份' },
|
|
93
|
+
{ step: '日历拉得动', state: report.calendar ? '拉得动' : '拉不动', why: report.calendar ? '今日议程这一问有回应' : '今日议程那一问没成' },
|
|
94
|
+
];
|
|
95
|
+
const { toc, body } = pageSections([
|
|
96
|
+
{ navText: '这一趟探测的结论', html: renderKpiGrid(kpis, { title: '这一趟探测的结论' }) },
|
|
97
|
+
{ html: renderConclusionBar('飞书能力:' + TIER_CN[report.tier] + '。' + plain(report.why)
|
|
98
|
+
+ '。要动远端就说「日程管家同步」,要留个只读的快照就是这一页。') },
|
|
99
|
+
{ navText: '三道门逐道看', html: renderSectionTitle('三道门逐道看')
|
|
100
|
+
+ renderDataTable({
|
|
101
|
+
columns: [
|
|
102
|
+
{ key: 'step', label: '探什么' },
|
|
103
|
+
{ key: 'state', label: '结果' },
|
|
104
|
+
{ key: 'why', label: '怎么看出来的' },
|
|
105
|
+
],
|
|
106
|
+
rows: steps,
|
|
107
|
+
}) },
|
|
108
|
+
{ html: renderFactStrip({
|
|
109
|
+
items: [
|
|
110
|
+
{ label: '命令行版本', value: report.version === null ? '没装' : shortLarkVersion(report.version) },
|
|
111
|
+
{ label: '探测日期', value: date },
|
|
112
|
+
{ label: '本地这一天的计划', value: String(local.total) + ' 条' },
|
|
113
|
+
{ label: '远端这一趟', value: '没碰' },
|
|
114
|
+
],
|
|
115
|
+
}) },
|
|
116
|
+
{ navText: '下一步怎么走', html: renderSectionTitle('下一步怎么走')
|
|
117
|
+
+ renderListRows({
|
|
118
|
+
items: TIER_NEXT[report.tier].map((text) => ({ main: text })),
|
|
119
|
+
emptyText: '没有下一步',
|
|
120
|
+
}) },
|
|
121
|
+
{ navText: '本地这一天的账', html: renderSectionTitle('本地这一天的账')
|
|
122
|
+
+ '<p class="sch-pl-note">这一份读的是本地库:这一天排了几条计划,其中几条已经带上远端标识。远端那一边这一趟没拉,故不报对方的条数。</p>'
|
|
123
|
+
+ renderDataTable({
|
|
124
|
+
columns: [
|
|
125
|
+
{ key: 'time', label: '时段' },
|
|
126
|
+
{ key: 'title', label: '计划' },
|
|
127
|
+
{ key: 'category', label: '分类' },
|
|
128
|
+
{ key: 'remote', label: '远端标识' },
|
|
129
|
+
],
|
|
130
|
+
rows: eventRows(listPlanEvents(handle, date)),
|
|
131
|
+
emptyText: '这一天本地没有计划',
|
|
132
|
+
})
|
|
133
|
+
+ renderCaliberLine('探测只读,三道门都只问不写,本地库这一趟也没动过') },
|
|
134
|
+
{ html: renderPreBlock({
|
|
135
|
+
label: '要真同步就说这一句',
|
|
136
|
+
command: '同步 ' + date + ' 的日程到飞书',
|
|
137
|
+
actionId: 'ilife-sch-probe-copy-next',
|
|
138
|
+
copyLabel: '复制这句话',
|
|
139
|
+
}) },
|
|
140
|
+
{ navText: '复制与留档', html: scheduleCopyArea({
|
|
141
|
+
title: '复制与留档',
|
|
142
|
+
dataActionId: 'ilife-sch-probe-copy-data',
|
|
143
|
+
logActionId: 'ilife-sch-probe-copy-log',
|
|
144
|
+
...planCopyArea({
|
|
145
|
+
message: '飞书探测:日期 ' + date + ',档位 ' + TIER_CN[report.tier] + ',原因 ' + report.why
|
|
146
|
+
+ ',本地这一天计划 ' + String(local.total) + ' 条、带远端标识 ' + String(local.synced) + ' 条,这一趟写入 0 笔',
|
|
147
|
+
command: 'schedule-cmd-read schedule.plan.write --params {"op":"sync","dryRun":true,"date":"' + date + '"}',
|
|
148
|
+
source: '本机命令行探测与本地日程计划表',
|
|
149
|
+
}),
|
|
150
|
+
}) },
|
|
151
|
+
]);
|
|
152
|
+
return assembleDocPage({ head, content: toc + body, extraCss: planPartsCss() });
|
|
153
|
+
}
|
|
154
|
+
/** 这一趟的结论(页自己的句子,不照抄回执那一串以并列符号分隔的计数):
|
|
155
|
+
* 远端在场就报对齐结果,远端没成/跳过也照实说,失败数单独点名。 */
|
|
156
|
+
function syncConclusion(payload) {
|
|
157
|
+
const c = payload.counts;
|
|
158
|
+
const moved = (c.backfilled ?? 0) + (c.created ?? 0) + (c.updated ?? 0) + (c.timeSynced ?? 0) + (c.deleted ?? 0);
|
|
159
|
+
const head = payload.remote === 'unavailable'
|
|
160
|
+
? '这一趟远端没成,本地那边没有改动。'
|
|
161
|
+
: (moved === 0 ? '两边本来就是对得上,这一趟没有要动的东西。' : '这一趟一共动了 ' + String(moved) + ' 处。');
|
|
162
|
+
const parts = [
|
|
163
|
+
'回填标识 ' + String(c.backfilled ?? 0) + ' 笔',
|
|
164
|
+
'远端新建 ' + String(c.created ?? 0) + ' 笔',
|
|
165
|
+
'远端改动 ' + String(c.updated ?? 0) + ' 笔',
|
|
166
|
+
'时段回写 ' + String(c.timeSynced ?? 0) + ' 笔',
|
|
167
|
+
'远端清理 ' + String(c.deleted ?? 0) + ' 笔',
|
|
168
|
+
].join(',');
|
|
169
|
+
const tail = (c.failed ?? 0) === 0
|
|
170
|
+
? '失败 0 笔。'
|
|
171
|
+
: '失败 ' + String(c.failed ?? 0) + ' 笔,逐条在下面。';
|
|
172
|
+
return head + parts + '。' + tail;
|
|
173
|
+
}
|
|
174
|
+
/** 「日程管家同步」整页:这一趟做了什么分格报出来,没成的逐条点名。 */
|
|
175
|
+
export function syncPage(handle, date, payload) {
|
|
176
|
+
const events = listPlanEvents(handle, date);
|
|
177
|
+
const failed = payload.counts.failed ?? 0;
|
|
178
|
+
const kpis = COUNT_LABELS.map((c) => ({
|
|
179
|
+
label: c.label,
|
|
180
|
+
value: String(payload.counts[c.key] ?? 0),
|
|
181
|
+
unit: '笔',
|
|
182
|
+
detail: c.hint,
|
|
183
|
+
}));
|
|
184
|
+
const { toc, body } = pageSections([
|
|
185
|
+
{ navText: '这一趟的账', html: renderKpiGrid(kpis, { title: '这一趟的账' }) },
|
|
186
|
+
{ html: renderConclusionBar(syncConclusion(payload)) },
|
|
187
|
+
{ html: renderFactStrip({
|
|
188
|
+
items: [
|
|
189
|
+
{ label: '同步的日期', value: date },
|
|
190
|
+
{ label: '远端侧', value: REMOTE_LABEL[payload.remote] },
|
|
191
|
+
{ label: '本地这一天的计划', value: String(events.length) + ' 条' },
|
|
192
|
+
{ label: '没成的', value: String(failed) + ' 笔' },
|
|
193
|
+
],
|
|
194
|
+
}) },
|
|
195
|
+
{ navText: '这一趟的结果', html: renderFeedbackBlock({
|
|
196
|
+
title: '这一趟的结果',
|
|
197
|
+
toast: failed === 0
|
|
198
|
+
? { icon: payload.remote === 'unavailable' ? 'warn' : 'ok', msg: plain(payload.message) }
|
|
199
|
+
: { icon: 'danger', msg: plain(payload.message), lines: payload.errors.map(plain) },
|
|
200
|
+
staticNotice: true,
|
|
201
|
+
}) },
|
|
202
|
+
{ navText: payload.notes.length === 0 ? '' : '顺带记下的', html: payload.notes.length === 0 ? '' : renderSectionTitle('顺带记下的')
|
|
203
|
+
+ renderListRows({ items: payload.notes.map((text) => ({ main: plain(text) })), emptyText: '没有顺带记下的' }) },
|
|
204
|
+
{ navText: payload.errors.length === 0 ? '' : '没成的逐条名单', html: payload.errors.length === 0 ? '' : renderSectionTitle('没成的逐条名单')
|
|
205
|
+
+ renderListRows({ items: payload.errors.map((text) => ({ main: plain(text) })), emptyText: '没有没成的' }) },
|
|
206
|
+
{ navText: '本地这一天的排布', html: renderSectionTitle('本地这一天的排布')
|
|
207
|
+
+ renderCaliberLine('远端只动带归属标记的对象,你在飞书日历上自己加的那些一律不碰')
|
|
208
|
+
+ renderDataTable({
|
|
209
|
+
columns: [
|
|
210
|
+
{ key: 'time', label: '时段' },
|
|
211
|
+
{ key: 'title', label: '计划' },
|
|
212
|
+
{ key: 'category', label: '分类' },
|
|
213
|
+
{ key: 'remote', label: '远端标识' },
|
|
214
|
+
],
|
|
215
|
+
rows: eventRows(events),
|
|
216
|
+
emptyText: '这一天本地没有计划',
|
|
217
|
+
}) },
|
|
218
|
+
{ navText: '下一步', html: renderSectionTitle('下一步')
|
|
219
|
+
+ renderListRows({
|
|
220
|
+
items: [
|
|
221
|
+
{ main: '要看另一天的差异,把日期一并说清楚,比如「同步 2026-09-22 的日程」。' },
|
|
222
|
+
{ main: '只想先看一眼而不动远端,就说「飞书探测」,那一页只读。' },
|
|
223
|
+
],
|
|
224
|
+
emptyText: '没有下一步',
|
|
225
|
+
}) },
|
|
226
|
+
{ html: renderPreBlock({
|
|
227
|
+
label: '再同步一天就说这一句',
|
|
228
|
+
command: '同步 ' + date + ' 的日程到飞书',
|
|
229
|
+
actionId: 'ilife-sch-sync-copy-next',
|
|
230
|
+
copyLabel: '复制这句话',
|
|
231
|
+
}) },
|
|
232
|
+
{ navText: '复制与留档', html: scheduleCopyArea({
|
|
233
|
+
title: '复制与留档',
|
|
234
|
+
dataActionId: 'ilife-sch-sync-copy-data',
|
|
235
|
+
logActionId: 'ilife-sch-sync-copy-log',
|
|
236
|
+
...planCopyArea({
|
|
237
|
+
message: '日程管家同步:日期 ' + date + ',' + payload.message + ','
|
|
238
|
+
+ COUNT_LABELS.map((c) => c.label + ' ' + String(payload.counts[c.key] ?? 0) + ' 笔').join(',')
|
|
239
|
+
+ (payload.errors.length === 0 ? '' : ',没成的 ' + payload.errors.join(',')),
|
|
240
|
+
command: 'schedule-cmd-read schedule.plan.write --params {"op":"sync","date":"' + date + '"}',
|
|
241
|
+
source: '本地日程计划表与飞书日历',
|
|
242
|
+
ok: payload.errors.length === 0,
|
|
243
|
+
}),
|
|
244
|
+
}) },
|
|
245
|
+
]);
|
|
246
|
+
return assembleDocPage({
|
|
247
|
+
head: {
|
|
248
|
+
docTitle: '作息管家 日程管家同步',
|
|
249
|
+
eyebrow: EYEBROW,
|
|
250
|
+
title: '日程管家同步',
|
|
251
|
+
subtitle: date + ' 这一天本地与飞书对了一遍,这一页报的是这一趟真做了什么。',
|
|
252
|
+
},
|
|
253
|
+
content: toc + body,
|
|
254
|
+
extraCss: planPartsCss(),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=feishuDocs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishuDocs.js","sourceRoot":"","sources":["../../src/plan/feishuDocs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/plan/handlers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/plan/handlers.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AA6H7D,eAAO,MAAM,SAAS,EAAE,YAMvB,CAAC"}
|
package/dist/plan/handlers.js
CHANGED
|
@@ -2,10 +2,23 @@
|
|
|
2
2
|
*
|
|
3
3
|
* 逐字搬自 `src/cli/cmd_read.ts` 的 switch 一臂 + 远端门(行为零改动)。
|
|
4
4
|
* 写 op 全部统一成合成写(裁定 A6③):本地 +(可选)远端一条命令走完,回执分字段、退出码报达成与否。
|
|
5
|
+
*
|
|
6
|
+
* **#787 起这一臂多出「出页」那一半**(照 #783 写域的先例):写库之后各支出一张真页
|
|
7
|
+
* (`./receiptDocs.ts` 与 `./discussDocs.ts` 装配,件序列见那两件头)。回执载荷(`data`)与退出码口径
|
|
8
|
+
* 一行不改,追加的分字段只多不少。
|
|
9
|
+
*
|
|
10
|
+
* 页要的东西分两处拿:**写之前**的样貌(改前那一条、落盘前这一天的排布)在这一臂里先留一份
|
|
11
|
+
* (写完之后库里已经不是那个样子了);**写之后**的读数从回执载荷与库里现读。
|
|
5
12
|
*/
|
|
6
|
-
import { larkReady } from '../fetch/index.js';
|
|
7
|
-
import { parseFeishuMode, parsePlanOp } from '../policy/index.js';
|
|
13
|
+
import { getPlanEvent, larkReady, listPlanEvents } from '../fetch/index.js';
|
|
14
|
+
import { parseFeishuMode, parsePlanOp, resolveDateParam, validateUpdateInput, validateUpsertInput, } from '../policy/index.js';
|
|
8
15
|
import { runPlanOp } from './index.js';
|
|
16
|
+
import { deactivateReceiptPage, ensureBatchReceiptPage, ensureReceiptPage, updateReceiptPage, } from './receiptDocs.js';
|
|
17
|
+
import { previewPage, resultPage } from './discussDocs.js';
|
|
18
|
+
import { replayPage } from './replaySections.js';
|
|
19
|
+
import { replayWindowOf } from './replayDocs.js';
|
|
20
|
+
import { reviewPage } from './reviewDocs.js';
|
|
21
|
+
import { probePage, syncPage } from './feishuDocs.js';
|
|
9
22
|
/** 哪些 op 要碰远端(其余 op 连 lark-cli 都不探——探测本身是三次子进程)。 */
|
|
10
23
|
const REMOTE_OPS = ['ensure', 'upsert', 'update', 'deactivate', 'sync', 'check'];
|
|
11
24
|
/** 远端门:过了给 cliPath;没过给「为什么不在场」——**不拦本地写**,只如实进回执与退出码。 */
|
|
@@ -22,10 +35,101 @@ function remoteGate(op, params) {
|
|
|
22
35
|
return { cli: null, why: e.message };
|
|
23
36
|
}
|
|
24
37
|
}
|
|
38
|
+
function preStateOf(op, params, handle) {
|
|
39
|
+
const none = { candidates: null, locked: [], beforeEvent: null, patchKeys: [] };
|
|
40
|
+
try {
|
|
41
|
+
if (op === 'preview' || op === 'upsert') {
|
|
42
|
+
const v = validateUpsertInput(params);
|
|
43
|
+
return { ...none, candidates: v, locked: listPlanEvents(handle, v.date) };
|
|
44
|
+
}
|
|
45
|
+
if (op === 'update') {
|
|
46
|
+
const v = validateUpdateInput(params);
|
|
47
|
+
return { ...none, beforeEvent: getPlanEvent(handle, v.id), patchKeys: Object.keys(v.patch) };
|
|
48
|
+
}
|
|
49
|
+
if (op === 'deactivate') {
|
|
50
|
+
return { ...none, beforeEvent: getPlanEvent(handle, Number(params.id)) };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// 参数不对时由各 op 自己的校验报那一句原话(本件只少出一块,不抢着报错)。
|
|
55
|
+
return none;
|
|
56
|
+
}
|
|
57
|
+
return none;
|
|
58
|
+
}
|
|
59
|
+
const remoteOf = (data) => (data.remote ?? 'none');
|
|
60
|
+
/** 各 op 写完之后那张页(不落页的两支——复盘与飞书那两条——回空串,照旧走模板页)。
|
|
61
|
+
*
|
|
62
|
+
* #788 起「复盘」与「飞书」两条各接上自己的整页:复盘按粒度分两族(裸词那一档是单日逐条标记,
|
|
63
|
+
* 四档是跨域对照与趋势那一张一体页),飞书按 `probe` 那一格分探测(只读)与同步回执两张。 */
|
|
64
|
+
function pageOf(op, handle, data, pre, params) {
|
|
65
|
+
if (op === 'preview' && pre.candidates !== null) {
|
|
66
|
+
return previewPage(handle, pre.candidates.date, pre.candidates.events);
|
|
67
|
+
}
|
|
68
|
+
if (op === 'upsert' && pre.candidates !== null) {
|
|
69
|
+
return resultPage(handle, pre.candidates.date, pre.candidates.events, pre.locked, remoteOf(data));
|
|
70
|
+
}
|
|
71
|
+
if (op === 'ensure') {
|
|
72
|
+
if (Array.isArray(data.items)) {
|
|
73
|
+
const days = data.items.map((d) => ({
|
|
74
|
+
date: String(d.date),
|
|
75
|
+
id: Number(d.id),
|
|
76
|
+
created: d.local === 'created',
|
|
77
|
+
remote: remoteOf(d),
|
|
78
|
+
achieved: d.achieved !== false,
|
|
79
|
+
}));
|
|
80
|
+
return ensureBatchReceiptPage(handle, days);
|
|
81
|
+
}
|
|
82
|
+
return ensureReceiptPage(handle, {
|
|
83
|
+
id: Number(data.id),
|
|
84
|
+
date: String(data.date),
|
|
85
|
+
created: data.local === 'created',
|
|
86
|
+
remote: remoteOf(data),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (op === 'update' && pre.beforeEvent !== null) {
|
|
90
|
+
return updateReceiptPage(handle, pre.beforeEvent, getPlanEvent(handle, pre.beforeEvent.id), pre.patchKeys, remoteOf(data));
|
|
91
|
+
}
|
|
92
|
+
if (op === 'deactivate' && pre.beforeEvent !== null) {
|
|
93
|
+
return deactivateReceiptPage(handle, pre.beforeEvent, remoteOf(data));
|
|
94
|
+
}
|
|
95
|
+
if (op === 'review') {
|
|
96
|
+
// 裸词「复盘」=单日逐条标记那一张;四档(今日/本周/本月/区间)=一体页。
|
|
97
|
+
const granularity = params.granularity;
|
|
98
|
+
if (typeof granularity === 'string')
|
|
99
|
+
return replayPage(handle, replayWindowOf(granularity, params));
|
|
100
|
+
return reviewPage(handle, resolveDateParam(params));
|
|
101
|
+
}
|
|
102
|
+
if (op === 'sync') {
|
|
103
|
+
const date = resolveDateParam(params);
|
|
104
|
+
if (data.probe === true) {
|
|
105
|
+
return probePage(handle, date, {
|
|
106
|
+
tier: (data.tier ?? 'missing'),
|
|
107
|
+
cliPath: typeof data.cliPath === 'string' ? data.cliPath : null,
|
|
108
|
+
version: typeof data.cliVersion === 'string' ? data.cliVersion : null,
|
|
109
|
+
// #896 · openId 原串不进回执(隐私),重建置 null 仅占形状——页上「授权登录过」与进度条
|
|
110
|
+
// 读 `authenticated`(来自 `data.authReady`),不读它。写死 null 本身不是 bug,
|
|
111
|
+
// bug 是此前根本没传布尔位、页上又去读 openId 是否 null。
|
|
112
|
+
openId: null,
|
|
113
|
+
authenticated: data.authReady === true,
|
|
114
|
+
calendar: data.calendarReady === true,
|
|
115
|
+
why: String(data.tierWhy ?? ''),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return syncPage(handle, date, {
|
|
119
|
+
message: String(data.message ?? ''),
|
|
120
|
+
remote: remoteOf(data),
|
|
121
|
+
counts: (data.counts ?? {}),
|
|
122
|
+
notes: Array.isArray(data.notes) ? data.notes : [],
|
|
123
|
+
errors: Array.isArray(data.errors) ? data.errors : [],
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return '';
|
|
127
|
+
}
|
|
25
128
|
export const writePlan = (params, handle) => {
|
|
26
129
|
const op = parsePlanOp(params);
|
|
27
130
|
const gate = remoteGate(op, params);
|
|
131
|
+
const pre = preStateOf(op, params, handle);
|
|
28
132
|
const out = runPlanOp(op, { handle, params, cli: gate.cli, remoteWhy: gate.why });
|
|
29
|
-
return { data: out.data, html:
|
|
133
|
+
return { data: out.data, html: pageOf(op, handle, out.data, pre, params), exitCode: out.exitCode };
|
|
30
134
|
};
|
|
31
135
|
//# sourceMappingURL=handlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/plan/handlers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/plan/handlers.ts"],"names":[],"mappings":"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"}
|
package/dist/plan/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { type PlanOpCtx, type PlanOpResult } from './context.js';
|
|
|
5
5
|
export type { PlanOpCtx, PlanOpResult } from './context.js';
|
|
6
6
|
export { buildPlanOverview } from './overview.js';
|
|
7
7
|
export type { PlanOverviewPayload, PlanDayRow, PlanHourRow } from './overview.js';
|
|
8
|
+
export { eventsInWindow, renderPlanDayPage } from './planDocs.js';
|
|
9
|
+
export type { PlanDayPageOptions, PlanDaySearch } from './planDocs.js';
|
|
8
10
|
/** `schedule.plan.write` 的唯一入口:把 op 分给各件,回执与退出码由各件给。 */
|
|
9
11
|
export declare function runPlanOp(op: PlanWriteOp, ctx: PlanOpCtx): PlanOpResult;
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/plan/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plan/index.ts"],"names":[],"mappings":"AAQA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAE5B,OAAO,EAA0D,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plan/index.ts"],"names":[],"mappings":"AAQA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAE5B,OAAO,EAA0D,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAShF,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAuBvE,wDAAwD;AACxD,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,GAAG,YAAY,CAiBvE"}
|
package/dist/plan/index.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
export * from './commands.js';
|
|
10
10
|
export * from './routes.js';
|
|
11
11
|
import { getPlanEventsRange, SchedulePolicyError } from '../fetch/index.js';
|
|
12
|
-
import {
|
|
12
|
+
import { VALID_COMPLETIONS } from '../policy/index.js';
|
|
13
13
|
import { receiptResult } from './context.js';
|
|
14
14
|
import { buildReceipt } from './receipt.js';
|
|
15
15
|
import { runEnsure, runEnsureBatch } from './ensure.js';
|
|
@@ -17,23 +17,30 @@ import { runPreview, runUpsert } from './upsert.js';
|
|
|
17
17
|
import { runUpdate, runDeactivate } from './single.js';
|
|
18
18
|
import { runSync } from './sync.js';
|
|
19
19
|
import { runCheck } from './check.js';
|
|
20
|
+
import { dayWindow, replayWindowOf } from './replayDocs.js';
|
|
20
21
|
export { buildPlanOverview } from './overview.js';
|
|
21
|
-
|
|
22
|
+
// #786 · 「查日程」那一张页的口径(空档推算住本域:`plan` 侧与 `query` 侧都要用——f10 查日程页与
|
|
23
|
+
// f12 商量计划预览的空档提示是同一件事)经能力门出门,`query` 侧只走这个门、不深引用内部件。
|
|
24
|
+
export { eventsInWindow, renderPlanDayPage } from './planDocs.js';
|
|
25
|
+
/** #14 复盘:本地读,不碰远端(四粒度:day/week/month/range)。
|
|
26
|
+
*
|
|
27
|
+
* #788 起窗口口径**与页同源**:这一支的窗口与页装配件都走 `replayWindowOf`(页上画哪一段,
|
|
28
|
+
* 回执里就报哪一段)。此前这一支只按 `date` 参数算单日,于是「复盘本周」的页画了这一周、
|
|
29
|
+
* 回执却报当天——两处对不上。 */
|
|
22
30
|
function runReview(ctx) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const events = getPlanEventsRange(ctx.handle, start, end);
|
|
31
|
+
const g = ctx.params.granularity;
|
|
32
|
+
const win = typeof g === 'string' ? replayWindowOf(g, ctx.params) : dayWindow(ctx.params);
|
|
33
|
+
const events = getPlanEventsRange(ctx.handle, win.start, win.end);
|
|
27
34
|
const counts = {};
|
|
28
35
|
for (const e of events)
|
|
29
36
|
counts[e.completion || '未复盘'] = (counts[e.completion || '未复盘'] || 0) + 1;
|
|
30
37
|
const parts = VALID_COMPLETIONS.filter((k) => counts[k]).map((k) => k + counts[k]);
|
|
31
38
|
const message = events.length
|
|
32
|
-
? '已复盘 ' + start + '
|
|
33
|
-
: '复盘空:' + start + '
|
|
39
|
+
? '已复盘 ' + win.start + ' 至 ' + win.end + ':' + events.length + ' 个事件(' + parts.join(',') + ')'
|
|
40
|
+
: '复盘空:' + win.start + ' 至 ' + win.end + ' 没有日程事件(不是故障,是这一段没排)';
|
|
34
41
|
return receiptResult(buildReceipt({
|
|
35
42
|
op: 'review', message, local: 'reviewed', remote: 'none', remoteId: null,
|
|
36
|
-
errors: [], date: start, dates: [start, end], counts: { events: events.length },
|
|
43
|
+
errors: [], date: win.start, dates: [win.start, win.end], counts: { events: events.length },
|
|
37
44
|
}));
|
|
38
45
|
}
|
|
39
46
|
/** `schedule.plan.write` 的唯一入口:把 op 分给各件,回执与退出码由各件给。 */
|
package/dist/plan/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plan/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,oEAAoE;AACpE,iDAAiD;AACjD,kCAAkC;AAClC,EAAE;AACF,+CAA+C;AAC/C,4FAA4F;AAC5F,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plan/index.ts"],"names":[],"mappings":"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"}
|
package/dist/plan/iso.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const TZ_SUFFIX = "+08:00";
|
|
2
2
|
/** 分片拉取的窗口宽度(小时)。老家 `feishu_sync.py:522` 的 `timedelta(hours=6)`。 */
|
|
3
3
|
export declare const SHARD_HOURS = 6;
|
|
4
|
+
/** 日期挪一天(正负都走这一个公式;`nextDay` 与历史窗口都用它,别处不许再抄一遍)。 */
|
|
5
|
+
export declare function shiftDay(date: string, delta: number): string;
|
|
4
6
|
export declare function nextDay(date: string): string;
|
|
5
7
|
/** 本地 (日期, HH:MM) → 飞书 ISO。`24:00` 换到次日 `00:00`(飞书日历不接受 24:00)。 */
|
|
6
8
|
export declare function toFeishuISO(date: string, hhmm: string): string;
|
package/dist/plan/iso.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iso.d.ts","sourceRoot":"","sources":["../../src/plan/iso.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,oEAAoE;AACpE,eAAO,MAAM,WAAW,IAAI,CAAC;AAI7B,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"iso.d.ts","sourceRoot":"","sources":["../../src/plan/iso.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,oEAAoE;AACpE,eAAO,MAAM,WAAW,IAAI,CAAC;AAI7B,oDAAoD;AACpD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAA2C;AAC5F,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAA2C;AAE1F,iCAAiC;AACjC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI7C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAA6B;AAE3E;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAI7F;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAU3E;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAmD"}
|
package/dist/plan/iso.js
CHANGED
|
@@ -6,12 +6,16 @@ export const TZ_SUFFIX = '+08:00';
|
|
|
6
6
|
/** 分片拉取的窗口宽度(小时)。老家 `feishu_sync.py:522` 的 `timedelta(hours=6)`。 */
|
|
7
7
|
export const SHARD_HOURS = 6;
|
|
8
8
|
function pad(n) { return String(n).padStart(2, '0'); }
|
|
9
|
-
|
|
9
|
+
/** 日期挪一天(正负都走这一个公式;`nextDay` 与历史窗口都用它,别处不许再抄一遍)。 */
|
|
10
|
+
export function shiftDay(date, delta) {
|
|
10
11
|
const [y, m, d] = date.split('-').map(Number);
|
|
11
12
|
const t = new Date(y, m - 1, d);
|
|
12
|
-
t.setDate(t.getDate() +
|
|
13
|
+
t.setDate(t.getDate() + delta);
|
|
13
14
|
return t.getFullYear() + '-' + pad(t.getMonth() + 1) + '-' + pad(t.getDate());
|
|
14
15
|
}
|
|
16
|
+
export function nextDay(date) {
|
|
17
|
+
return shiftDay(date, 1);
|
|
18
|
+
}
|
|
15
19
|
/** 本地 (日期, HH:MM) → 飞书 ISO。`24:00` 换到次日 `00:00`(飞书日历不接受 24:00)。 */
|
|
16
20
|
export function toFeishuISO(date, hhmm) {
|
|
17
21
|
if (hhmm === '24:00')
|
package/dist/plan/iso.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iso.js","sourceRoot":"","sources":["../../src/plan/iso.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,uDAAuD;AACvD,iFAAiF;AACjF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,SAAS,GAAG,QAAQ,CAAC;AAClC,oEAAoE;AACpE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,SAAS,GAAG,CAAC,CAAS,IAAY,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAEtE,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"iso.js","sourceRoot":"","sources":["../../src/plan/iso.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { PlanEvent } from '../fetch/db.js';
|
|
2
|
+
/** 钟点 → 分钟,且**这一天末尾那一格**按 24:00 算:末段写 `23:59` 与写 `24:00` 是同一件事
|
|
3
|
+
* (校验口径 `assertCoverage24h` 的原话:「末事件 time_end 必须为 24:00,当前 23:59 视同」),
|
|
4
|
+
* 而落盘的候选是**归一过**的(`normalizeTime` 把 `24:00` 改写成 `23:59`)。整日覆盖、空隙、
|
|
5
|
+
* 时长三处都按这一条算,否则「整天接满」会被读成「还差一分钟」。定义只此一处。 */
|
|
6
|
+
export declare const minutesOfDayEnd: (hhmm: string) => number;
|
|
7
|
+
/** 空档:未排事件的连续时段(按时间先后扫一遍,游标只前进;相邻或重叠都不断档)。
|
|
8
|
+
* #787 起本件对外给这一条:f12「商量计划预览」的**空隙提示**与 f10「查日程」的空档是同一件事,
|
|
9
|
+
* 两个用法都在本能力目录里,故仍只此一处(收的只是「有起止的东西」,不要求是库行)。 */
|
|
10
|
+
export declare function gapsOf(events: readonly {
|
|
11
|
+
readonly time_start: string;
|
|
12
|
+
readonly time_end: string;
|
|
13
|
+
}[]): {
|
|
14
|
+
readonly start: number;
|
|
15
|
+
readonly end: number;
|
|
16
|
+
}[];
|
|
17
|
+
/** 分钟数 → `HH:MM` 钟点(`24:00` 收尾):页上空档与空隙两处共用的写法,只此一处。 */
|
|
18
|
+
export declare const clockOf: (minutes: number) => string;
|
|
19
|
+
/** 按标题搜或按时段查重(本票两支,老侧都只出 JSON)。
|
|
20
|
+
*
|
|
21
|
+
* 为什么同一张页:两个查法都落在 `schedule.plan.today` 这一枚 key 上,出口只按 key 分派
|
|
22
|
+
* (路由表没给它们各自的预设),下游分不出是哪种查法——故一张页把两支都答全,
|
|
23
|
+
* 页头与结论条如实写明这一趟的查法,不让人猜这一页为什么只有几件。 */
|
|
24
|
+
export interface PlanDaySearch {
|
|
25
|
+
/** 按标题搜索时命中的那个词(原样上屏)。 */
|
|
26
|
+
readonly title?: string;
|
|
27
|
+
/** 按时段查重时那一对钟点。 */
|
|
28
|
+
readonly window?: {
|
|
29
|
+
readonly start: string;
|
|
30
|
+
readonly end: string;
|
|
31
|
+
};
|
|
32
|
+
/** 命中集合(进列表的那几行);全天的色带/空档/读数仍按 `events` 算。 */
|
|
33
|
+
readonly list: readonly PlanEvent[];
|
|
34
|
+
}
|
|
35
|
+
/** `renderPlanDayPage` 的可选位(不给=#782 那张样张页的件序列与读数)。 */
|
|
36
|
+
export interface PlanDayPageOptions {
|
|
37
|
+
/** 这一天**已软删**的事件(`is_active = 0`):上同一张页、行尾标「已软删」,结论条报条数。 */
|
|
38
|
+
readonly inactive?: readonly PlanEvent[];
|
|
39
|
+
readonly search?: PlanDaySearch;
|
|
40
|
+
}
|
|
41
|
+
/** 这一时段里有哪几件:与窗口**重叠**即算(起在前、止在后都算)。查重用,故不要求整段包住。 */
|
|
42
|
+
export declare function eventsInWindow(events: readonly PlanEvent[], start: string, end: string): PlanEvent[];
|
|
43
|
+
/** 「查日程」整页(形状=A 覆盖条+事件卡;老侧 f10 的三个必现块都在)。
|
|
44
|
+
*
|
|
45
|
+
* `events` 是**这一天的活跃事件**(读数/色带/空档都按它算);`opts.search.list` 只换列表那一段。 */
|
|
46
|
+
export declare function renderPlanDayPage(events: readonly PlanEvent[], date: string, opts?: PlanDayPageOptions): string;
|
|
47
|
+
//# sourceMappingURL=planDocs.d.ts.map
|