skill-bill 0.1.0
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/dist/cli/cmd_read.d.ts +3 -0
- package/dist/cli/cmd_read.d.ts.map +1 -0
- package/dist/cli/cmd_read.js +530 -0
- package/dist/cli/cmd_read.js.map +1 -0
- package/dist/fetch/db.d.ts +55 -0
- package/dist/fetch/db.d.ts.map +1 -0
- package/dist/fetch/db.js +255 -0
- package/dist/fetch/db.js.map +1 -0
- package/dist/fetch/errors.d.ts +13 -0
- package/dist/fetch/errors.d.ts.map +1 -0
- package/dist/fetch/errors.js +18 -0
- package/dist/fetch/errors.js.map +1 -0
- package/dist/fetch/index.d.ts +5 -0
- package/dist/fetch/index.d.ts.map +1 -0
- package/dist/fetch/index.js +4 -0
- package/dist/fetch/index.js.map +1 -0
- package/dist/fetch/paths.d.ts +8 -0
- package/dist/fetch/paths.d.ts.map +1 -0
- package/dist/fetch/paths.js +36 -0
- package/dist/fetch/paths.js.map +1 -0
- package/dist/help/index.d.ts +2 -0
- package/dist/help/index.d.ts.map +1 -0
- package/dist/help/index.js +2 -0
- package/dist/help/index.js.map +1 -0
- package/dist/help/lookup.d.ts +11 -0
- package/dist/help/lookup.d.ts.map +1 -0
- package/dist/help/lookup.js +53 -0
- package/dist/help/lookup.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/accounts.d.ts +13 -0
- package/dist/policy/accounts.d.ts.map +1 -0
- package/dist/policy/accounts.js +31 -0
- package/dist/policy/accounts.js.map +1 -0
- package/dist/policy/analysis.d.ts +12 -0
- package/dist/policy/analysis.d.ts.map +1 -0
- package/dist/policy/analysis.js +39 -0
- package/dist/policy/analysis.js.map +1 -0
- package/dist/policy/category.d.ts +31 -0
- package/dist/policy/category.d.ts.map +1 -0
- package/dist/policy/category.js +115 -0
- package/dist/policy/category.js.map +1 -0
- package/dist/policy/goals.d.ts +15 -0
- package/dist/policy/goals.d.ts.map +1 -0
- package/dist/policy/goals.js +33 -0
- package/dist/policy/goals.js.map +1 -0
- package/dist/policy/index.d.ts +13 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +7 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/record.d.ts +15 -0
- package/dist/policy/record.d.ts.map +1 -0
- package/dist/policy/record.js +62 -0
- package/dist/policy/record.js.map +1 -0
- package/dist/policy/wakewords.d.ts +14 -0
- package/dist/policy/wakewords.d.ts.map +1 -0
- package/dist/policy/wakewords.js +121 -0
- package/dist/policy/wakewords.js.map +1 -0
- package/dist/render/envelope.d.ts +6 -0
- package/dist/render/envelope.d.ts.map +1 -0
- package/dist/render/envelope.js +56 -0
- package/dist/render/envelope.js.map +1 -0
- package/dist/render/errors.d.ts +5 -0
- package/dist/render/errors.d.ts.map +1 -0
- package/dist/render/errors.js +9 -0
- package/dist/render/errors.js.map +1 -0
- package/dist/render/html.d.ts +13 -0
- package/dist/render/html.d.ts.map +1 -0
- package/dist/render/html.js +60 -0
- package/dist/render/html.js.map +1 -0
- package/dist/render/index.d.ts +8 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +6 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/templates.d.ts +5 -0
- package/dist/render/templates.d.ts.map +1 -0
- package/dist/render/templates.js +58 -0
- package/dist/render/templates.js.map +1 -0
- package/dist/render/views.d.ts +86 -0
- package/dist/render/views.d.ts.map +1 -0
- package/dist/render/views.js +127 -0
- package/dist/render/views.js.map +1 -0
- package/package.json +32 -0
- package/templates/account_query.html +16 -0
- package/templates/account_write.html +16 -0
- package/templates/analysis_compare.html +16 -0
- package/templates/analysis_overview.html +16 -0
- package/templates/analysis_trend.html +16 -0
- package/templates/goal_query.html +16 -0
- package/templates/goal_write.html +16 -0
- package/templates/help.html +16 -0
- package/templates/link_submit.html +16 -0
- package/templates/record_add.html +16 -0
- package/templates/record_detail.html +16 -0
- package/templates/record_range.html +16 -0
- package/templates/record_search.html +16 -0
- package/templates/record_today.html +16 -0
- package/templates/record_update.html +16 -0
- package/templates/setup_run.html +16 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// 渲染层·envelope:16 联动 key×shape 映射(拆分表);key 字符串后续票落表时冻结,此处只做形状分配与全字段校验。
|
|
2
|
+
import { createEnvelope, parseEnvelope, parseRegistryKey } from 'base-link-core';
|
|
3
|
+
import { BillRenderError } from './errors.js';
|
|
4
|
+
export const BILL_KEY_SHAPES = {
|
|
5
|
+
'bill.record.add': 'receipt',
|
|
6
|
+
'bill.record.update': 'receipt',
|
|
7
|
+
'bill.record.today': 'list',
|
|
8
|
+
'bill.record.range': 'list',
|
|
9
|
+
'bill.record.search': 'list',
|
|
10
|
+
'bill.record.detail': 'detail',
|
|
11
|
+
'bill.analysis.overview': 'stat',
|
|
12
|
+
'bill.analysis.compare': 'analysis',
|
|
13
|
+
'bill.analysis.trend': 'analysis',
|
|
14
|
+
'bill.goal.write': 'receipt',
|
|
15
|
+
'bill.goal.query': 'list',
|
|
16
|
+
'bill.account.write': 'receipt',
|
|
17
|
+
'bill.account.query': 'list',
|
|
18
|
+
'bill.link.submit': 'receipt',
|
|
19
|
+
'bill.setup.run': 'receipt',
|
|
20
|
+
'bill.help.lookup': 'list',
|
|
21
|
+
};
|
|
22
|
+
export function billShapeFor(key) {
|
|
23
|
+
const s = BILL_KEY_SHAPES[key];
|
|
24
|
+
if (!s)
|
|
25
|
+
throw new BillRenderError('BILL_UNKNOWN_KEY', '未知联动 key:' + key);
|
|
26
|
+
return s;
|
|
27
|
+
}
|
|
28
|
+
// 建 envelope:key 先过命名空间,再按分配形状做全字段校验;错形状载荷即 throw。
|
|
29
|
+
export function buildBillEnvelope(key, data) {
|
|
30
|
+
let parsedKey = '';
|
|
31
|
+
try {
|
|
32
|
+
parsedKey = parseRegistryKey(key).key;
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
throw new BillRenderError('BILL_UNKNOWN_KEY', '非法 key:' + e.message);
|
|
36
|
+
}
|
|
37
|
+
const shape = billShapeFor(parsedKey);
|
|
38
|
+
if (typeof data !== 'object' || data === null || Array.isArray(data)) {
|
|
39
|
+
throw new BillRenderError('BILL_BAD_PAYLOAD', '载荷须为对象:' + parsedKey);
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
return createEnvelope({ skill: 'bill', shape, key: parsedKey, data: data });
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
throw new BillRenderError('BILL_SHAPE_MISMATCH', shape + ' 全字段未过:' + e.message);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function parseBillEnvelope(input) {
|
|
49
|
+
try {
|
|
50
|
+
return parseEnvelope(input);
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
throw new BillRenderError('BILL_BAD_PAYLOAD', 'envelope 非法:' + e.message);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/render/envelope.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAqC,MAAM,gBAAgB,CAAC;AACpH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,eAAe,GAAkC;IAC5D,iBAAiB,EAAE,SAAS;IAC5B,oBAAoB,EAAE,SAAS;IAC/B,mBAAmB,EAAE,MAAM;IAC3B,mBAAmB,EAAE,MAAM;IAC3B,oBAAoB,EAAE,MAAM;IAC5B,oBAAoB,EAAE,QAAQ;IAC9B,wBAAwB,EAAE,MAAM;IAChC,uBAAuB,EAAE,UAAU;IACnC,qBAAqB,EAAE,UAAU;IACjC,iBAAiB,EAAE,SAAS;IAC5B,iBAAiB,EAAE,MAAM;IACzB,oBAAoB,EAAE,SAAS;IAC/B,oBAAoB,EAAE,MAAM;IAC5B,kBAAkB,EAAE,SAAS;IAC7B,gBAAgB,EAAE,SAAS;IAC3B,kBAAkB,EAAE,MAAM;CAC3B,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,WAAW,GAAG,GAAG,CAAC,CAAC;IACzE,OAAO,CAAC,CAAC;AACX,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,IAAa;IAC1D,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,CAAC;QAAC,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;IAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAC;QAAC,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,SAAS,GAAI,CAAW,CAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IAC9F,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACtC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,IAAa,EAAE,CAAC,CAAC;IACvF,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE,KAAK,GAAG,SAAS,GAAI,CAAW,CAAC,OAAO,CAAC,CAAC;IAC7F,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,CAAC;QAAC,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC;QAAC,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,cAAc,GAAI,CAAW,CAAC,OAAO,CAAC,CAAC;IAAC,CAAC;AACrG,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare class BillRenderError extends Error {
|
|
2
|
+
readonly code: 'BILL_UNKNOWN_KEY' | 'BILL_BAD_PAYLOAD' | 'BILL_SHAPE_MISMATCH' | 'BILL_TEMPLATE_MISSING' | 'BILL_MARKER_INVALID' | 'BILL_HTML_TOO_LARGE';
|
|
3
|
+
constructor(code: BillRenderError['code'], message: string);
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/render/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EACT,kBAAkB,GAAG,kBAAkB,GAAG,qBAAqB,GAC/D,uBAAuB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;gBAChE,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM;CAK3D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/render/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,IAAI,CAE+D;IAC5E,YAAY,IAA6B,EAAE,OAAe;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Envelope } from 'base-link-core';
|
|
2
|
+
export declare const BILL_HTML_MAX_BYTES: number;
|
|
3
|
+
export declare function escapeHtml(s: string): string;
|
|
4
|
+
export declare function renderEnvelopeHtml(env: Envelope): string;
|
|
5
|
+
export declare function estimateBytes(html: string): number;
|
|
6
|
+
export declare function assertHtmlSize(html: string, max?: number): void;
|
|
7
|
+
export declare const SHARED_CSS_MARKER = "<!--SHARED-CSS-->";
|
|
8
|
+
export declare const SHARED_HELPERS_MARKER = "<!--SHARED-HELPERS-->";
|
|
9
|
+
export declare const CONTENT_MARKER = "<!--CONTENT-->";
|
|
10
|
+
export declare const SHARED_CSS = ".page{font-family:system-ui,sans-serif;max-width:720px;margin:0 auto;padding:12px}.item{border:1px solid #ddd;border-radius:8px;padding:8px;margin:8px 0}.item-head{display:flex;gap:8px;align-items:center}.badge{background:#eee;border-radius:4px;padding:0 6px}.amt{font-weight:700}.receipt{background:#f0fff0;border:1px solid #090;border-radius:8px;padding:12px}.stat{display:flex;gap:8px}.analysis{white-space:pre-wrap}.hm-empty{color:#888}";
|
|
11
|
+
export declare const SHARED_HELPERS = "<script>function copyItem(id){var e=document.getElementById(id);if(e&&navigator.clipboard){navigator.clipboard.writeText(e.innerText);}}</script>";
|
|
12
|
+
export declare function fillTemplate(template: string, contentHtml: string): string;
|
|
13
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/render/html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,eAAO,MAAM,mBAAmB,QAAa,CAAC;AAE9C,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C;AAiBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAexD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAA4C;AAG/F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAsB,GAAG,IAAI,CAI5E;AAGD,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAC7D,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,eAAO,MAAM,UAAU,6bAA6b,CAAC;AACrd,eAAO,MAAM,cAAc,sJAAsJ,CAAC;AAElL,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAU1E"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { BillRenderError } from './errors.js';
|
|
2
|
+
export const BILL_HTML_MAX_BYTES = 256 * 1024;
|
|
3
|
+
export function escapeHtml(s) {
|
|
4
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
5
|
+
}
|
|
6
|
+
function billItemHtml(n) {
|
|
7
|
+
const time = escapeHtml(String(n.time ?? ''));
|
|
8
|
+
const cat = escapeHtml(String(n.category ?? ''));
|
|
9
|
+
const amt = escapeHtml(String(n.amount ?? ''));
|
|
10
|
+
const note = escapeHtml(String(n.note ?? ''));
|
|
11
|
+
const id = escapeHtml(String(n.id ?? ''));
|
|
12
|
+
return '<div class="item"><div class="item-head"><span class="id">' + id + '</span><span class="time">' + time + '</span><span class="badge">' + cat + '</span><span class="amt">' + amt + '</span></div><div class="content">' + note + '</div></div>';
|
|
13
|
+
}
|
|
14
|
+
function listHtml(items) {
|
|
15
|
+
if (!items.length)
|
|
16
|
+
return '<div class="hm-empty">暂无记录</div>';
|
|
17
|
+
return items.map((x) => billItemHtml(x)).join('');
|
|
18
|
+
}
|
|
19
|
+
// 按形状渲染 envelope 为 section 页;未知形状 throw 不返空页。
|
|
20
|
+
export function renderEnvelopeHtml(env) {
|
|
21
|
+
const head = '<section data-skill="bill" data-shape="' + env.shape + '" data-key="' + escapeHtml(env.key) + '">';
|
|
22
|
+
const d = env.data;
|
|
23
|
+
switch (env.shape) {
|
|
24
|
+
case 'list': return head + listHtml(d.items) + '</section>';
|
|
25
|
+
case 'detail': return head + billItemHtml(d.item) + '</section>';
|
|
26
|
+
case 'receipt': return head + '<div class="receipt">' + escapeHtml(String(d.message)) + '</div></section>';
|
|
27
|
+
case 'stat': {
|
|
28
|
+
const rows = Object.entries((d.metrics || {}));
|
|
29
|
+
return head + rows.map(([k, v]) => '<div class="stat"><b>' + v + '</b><span>' + escapeHtml(k) + '</span></div>').join('') + '</section>';
|
|
30
|
+
}
|
|
31
|
+
case 'analysis': return head + '<div class="analysis">' + escapeHtml(String(d.summary)).replace(/\n/g, '<br>') + '</div></section>';
|
|
32
|
+
case 'fallback': return head + '<div data-degraded="1">' + escapeHtml(String(d.reason)) + '</div></section>';
|
|
33
|
+
default: throw new BillRenderError('BILL_SHAPE_MISMATCH', '无法渲染形状:' + String(env.shape));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function estimateBytes(html) { return Buffer.byteLength(html, 'utf8'); }
|
|
37
|
+
// 体积门:超限 throw(调用方走 fallback 形状显式降级,不静默截断)。
|
|
38
|
+
export function assertHtmlSize(html, max = BILL_HTML_MAX_BYTES) {
|
|
39
|
+
if (estimateBytes(html) > max) {
|
|
40
|
+
throw new BillRenderError('BILL_HTML_TOO_LARGE', 'HTML 超体积:' + estimateBytes(html) + ' > ' + max);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// 共享标记填充(老家离线注入壳对应):CSS/HELPERS/CONTENT 三标记各恰出现 1 次,否则 throw。
|
|
44
|
+
export const SHARED_CSS_MARKER = '<!--SHARED-CSS-->';
|
|
45
|
+
export const SHARED_HELPERS_MARKER = '<!--SHARED-HELPERS-->';
|
|
46
|
+
export const CONTENT_MARKER = '<!--CONTENT-->';
|
|
47
|
+
export const SHARED_CSS = '.page{font-family:system-ui,sans-serif;max-width:720px;margin:0 auto;padding:12px}.item{border:1px solid #ddd;border-radius:8px;padding:8px;margin:8px 0}.item-head{display:flex;gap:8px;align-items:center}.badge{background:#eee;border-radius:4px;padding:0 6px}.amt{font-weight:700}.receipt{background:#f0fff0;border:1px solid #090;border-radius:8px;padding:12px}.stat{display:flex;gap:8px}.analysis{white-space:pre-wrap}.hm-empty{color:#888}';
|
|
48
|
+
export const SHARED_HELPERS = '<script>function copyItem(id){var e=document.getElementById(id);if(e&&navigator.clipboard){navigator.clipboard.writeText(e.innerText);}}</script>';
|
|
49
|
+
export function fillTemplate(template, contentHtml) {
|
|
50
|
+
for (const m of [SHARED_CSS_MARKER, SHARED_HELPERS_MARKER, CONTENT_MARKER]) {
|
|
51
|
+
if (template.split(m).length - 1 !== 1) {
|
|
52
|
+
throw new BillRenderError('BILL_MARKER_INVALID', '标记须恰出现 1 次:' + m);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return template
|
|
56
|
+
.split(SHARED_CSS_MARKER).join('<style>' + SHARED_CSS + '</style>')
|
|
57
|
+
.split(SHARED_HELPERS_MARKER).join(SHARED_HELPERS)
|
|
58
|
+
.split(CONTENT_MARKER).join(contentHtml);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/render/html.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { BillRenderError } from './errors.js';
|
|
2
|
+
export { BILL_KEY_SHAPES, billShapeFor, buildBillEnvelope, parseBillEnvelope } from './envelope.js';
|
|
3
|
+
export { BILL_HTML_MAX_BYTES, escapeHtml, renderEnvelopeHtml, estimateBytes, assertHtmlSize, SHARED_CSS_MARKER, SHARED_HELPERS_MARKER, CONTENT_MARKER, SHARED_CSS, SHARED_HELPERS, fillTemplate } from './html.js';
|
|
4
|
+
export { BILL_TEMPLATES, templateFor, loadTemplate } from './templates.js';
|
|
5
|
+
export type { BillTemplate } from './templates.js';
|
|
6
|
+
export { toBillItem, calcKpi, calcCategories, buildRecordToday, buildRecordRange, buildRecordSearch, buildRecordDetail, buildRecordReceipt, buildOverview, buildCompare, buildTrend, buildGoalQuery, buildAccountQuery, buildHelpItems } from './views.js';
|
|
7
|
+
export type { BillItem, HelpItem } from './views.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,kBAAkB,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACnN,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC3E,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3P,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { BillRenderError } from './errors.js';
|
|
2
|
+
export { BILL_KEY_SHAPES, billShapeFor, buildBillEnvelope, parseBillEnvelope } from './envelope.js';
|
|
3
|
+
export { BILL_HTML_MAX_BYTES, escapeHtml, renderEnvelopeHtml, estimateBytes, assertHtmlSize, SHARED_CSS_MARKER, SHARED_HELPERS_MARKER, CONTENT_MARKER, SHARED_CSS, SHARED_HELPERS, fillTemplate } from './html.js';
|
|
4
|
+
export { BILL_TEMPLATES, templateFor, loadTemplate } from './templates.js';
|
|
5
|
+
export { toBillItem, calcKpi, calcCategories, buildRecordToday, buildRecordRange, buildRecordSearch, buildRecordDetail, buildRecordReceipt, buildOverview, buildCompare, buildTrend, buildGoalQuery, buildAccountQuery, buildHelpItems } from './views.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,kBAAkB,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACnN,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const BILL_TEMPLATES: readonly ["record_add", "record_update", "record_today", "record_range", "record_search", "record_detail", "analysis_overview", "analysis_compare", "analysis_trend", "goal_write", "goal_query", "account_write", "account_query", "link_submit", "setup_run", "help"];
|
|
2
|
+
export type BillTemplate = (typeof BILL_TEMPLATES)[number];
|
|
3
|
+
export declare function templateFor(key: string): BillTemplate;
|
|
4
|
+
export declare function loadTemplate(name: string): string;
|
|
5
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/render/templates.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,yQAiBjB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAG3D,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAoBrD;AAID,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// 渲染层·模板装载:16 模板随包发布;未知/缺失大声失败。
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { BillRenderError } from './errors.js';
|
|
6
|
+
export const BILL_TEMPLATES = [
|
|
7
|
+
'record_add',
|
|
8
|
+
'record_update',
|
|
9
|
+
'record_today',
|
|
10
|
+
'record_range',
|
|
11
|
+
'record_search',
|
|
12
|
+
'record_detail',
|
|
13
|
+
'analysis_overview',
|
|
14
|
+
'analysis_compare',
|
|
15
|
+
'analysis_trend',
|
|
16
|
+
'goal_write',
|
|
17
|
+
'goal_query',
|
|
18
|
+
'account_write',
|
|
19
|
+
'account_query',
|
|
20
|
+
'link_submit',
|
|
21
|
+
'setup_run',
|
|
22
|
+
'help',
|
|
23
|
+
];
|
|
24
|
+
// key → 模板(1 键 1 模板)。
|
|
25
|
+
export function templateFor(key) {
|
|
26
|
+
switch (key) {
|
|
27
|
+
case 'bill.record.add': return 'record_add';
|
|
28
|
+
case 'bill.record.update': return 'record_update';
|
|
29
|
+
case 'bill.record.today': return 'record_today';
|
|
30
|
+
case 'bill.record.range': return 'record_range';
|
|
31
|
+
case 'bill.record.search': return 'record_search';
|
|
32
|
+
case 'bill.record.detail': return 'record_detail';
|
|
33
|
+
case 'bill.analysis.overview': return 'analysis_overview';
|
|
34
|
+
case 'bill.analysis.compare': return 'analysis_compare';
|
|
35
|
+
case 'bill.analysis.trend': return 'analysis_trend';
|
|
36
|
+
case 'bill.goal.write': return 'goal_write';
|
|
37
|
+
case 'bill.goal.query': return 'goal_query';
|
|
38
|
+
case 'bill.account.write': return 'account_write';
|
|
39
|
+
case 'bill.account.query': return 'account_query';
|
|
40
|
+
case 'bill.link.submit': return 'link_submit';
|
|
41
|
+
case 'bill.setup.run': return 'setup_run';
|
|
42
|
+
case 'bill.help.lookup': return 'help';
|
|
43
|
+
default: throw new BillRenderError('BILL_UNKNOWN_KEY', '无模板映射:' + key);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const templatesDir = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'templates');
|
|
47
|
+
export function loadTemplate(name) {
|
|
48
|
+
if (!BILL_TEMPLATES.includes(name)) {
|
|
49
|
+
throw new BillRenderError('BILL_TEMPLATE_MISSING', '未知模板:' + name);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return readFileSync(join(templatesDir, name + '.html'), 'utf8');
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
throw new BillRenderError('BILL_TEMPLATE_MISSING', '模板缺失:' + name);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/render/templates.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,YAAY;IACZ,eAAe;IACf,cAAc;IACd,cAAc;IACd,eAAe;IACf,eAAe;IACf,mBAAmB;IACnB,kBAAkB;IAClB,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,eAAe;IACf,aAAa;IACb,WAAW;IACX,MAAM;CACE,CAAC;AAGX,sBAAsB;AACtB,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,iBAAiB,CAAC,CAAC,OAAO,YAAY,CAAC;QAC5C,KAAK,oBAAoB,CAAC,CAAC,OAAO,eAAe,CAAC;QAClD,KAAK,mBAAmB,CAAC,CAAC,OAAO,cAAc,CAAC;QAChD,KAAK,mBAAmB,CAAC,CAAC,OAAO,cAAc,CAAC;QAChD,KAAK,oBAAoB,CAAC,CAAC,OAAO,eAAe,CAAC;QAClD,KAAK,oBAAoB,CAAC,CAAC,OAAO,eAAe,CAAC;QAClD,KAAK,wBAAwB,CAAC,CAAC,OAAO,mBAAmB,CAAC;QAC1D,KAAK,uBAAuB,CAAC,CAAC,OAAO,kBAAkB,CAAC;QACxD,KAAK,qBAAqB,CAAC,CAAC,OAAO,gBAAgB,CAAC;QACpD,KAAK,iBAAiB,CAAC,CAAC,OAAO,YAAY,CAAC;QAC5C,KAAK,iBAAiB,CAAC,CAAC,OAAO,YAAY,CAAC;QAC5C,KAAK,oBAAoB,CAAC,CAAC,OAAO,eAAe,CAAC;QAClD,KAAK,oBAAoB,CAAC,CAAC,OAAO,eAAe,CAAC;QAClD,KAAK,kBAAkB,CAAC,CAAC,OAAO,aAAa,CAAC;QAC9C,KAAK,gBAAgB,CAAC,CAAC,OAAO,WAAW,CAAC;QAC1C,KAAK,kBAAkB,CAAC,CAAC,OAAO,MAAM,CAAC;QACvC,OAAO,CAAC,CAAC,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,QAAQ,GAAG,GAAG,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AAE5F,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAoB,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,eAAe,CAAC,uBAAuB,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,CAAC;QAAC,OAAO,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC;IACxE,OAAO,CAAC,EAAE,CAAC;QAAC,MAAM,IAAI,eAAe,CAAC,uBAAuB,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;IAAC,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { BillRow } from '../fetch/db.js';
|
|
2
|
+
export interface BillItem {
|
|
3
|
+
id: number;
|
|
4
|
+
category: string;
|
|
5
|
+
time: string;
|
|
6
|
+
amount: number;
|
|
7
|
+
account: string;
|
|
8
|
+
ledger: string;
|
|
9
|
+
currency: string;
|
|
10
|
+
note: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function toBillItem(r: BillRow): BillItem;
|
|
13
|
+
export declare function calcKpi(records: BillRow[]): {
|
|
14
|
+
count: number;
|
|
15
|
+
expense: number;
|
|
16
|
+
income: number;
|
|
17
|
+
net: number;
|
|
18
|
+
};
|
|
19
|
+
export declare function calcCategories(records: BillRow[]): {
|
|
20
|
+
category: string;
|
|
21
|
+
total: number;
|
|
22
|
+
count: number;
|
|
23
|
+
}[];
|
|
24
|
+
export declare function buildRecordToday(date: string, records: BillRow[]): {
|
|
25
|
+
items: BillItem[];
|
|
26
|
+
total: number;
|
|
27
|
+
date: string;
|
|
28
|
+
kpi: ReturnType<typeof calcKpi>;
|
|
29
|
+
};
|
|
30
|
+
export declare function buildRecordRange(start: string, end: string, records: BillRow[]): {
|
|
31
|
+
items: BillItem[];
|
|
32
|
+
total: number;
|
|
33
|
+
start: string;
|
|
34
|
+
end: string;
|
|
35
|
+
kpi: ReturnType<typeof calcKpi>;
|
|
36
|
+
};
|
|
37
|
+
export declare function buildRecordSearch(kind: string, records: BillRow[]): {
|
|
38
|
+
items: BillItem[];
|
|
39
|
+
total: number;
|
|
40
|
+
kind: string;
|
|
41
|
+
kpi: ReturnType<typeof calcKpi>;
|
|
42
|
+
};
|
|
43
|
+
export declare function buildRecordDetail(record: BillRow): {
|
|
44
|
+
item: Record<string, unknown>;
|
|
45
|
+
};
|
|
46
|
+
export declare function buildRecordReceipt(message: string): {
|
|
47
|
+
ok: boolean;
|
|
48
|
+
message: string;
|
|
49
|
+
};
|
|
50
|
+
export declare function buildOverview(label: string, records: BillRow[]): {
|
|
51
|
+
metrics: Record<string, number>;
|
|
52
|
+
};
|
|
53
|
+
export declare function buildCompare(args: {
|
|
54
|
+
labelA: string;
|
|
55
|
+
labelB: string;
|
|
56
|
+
a: BillRow[];
|
|
57
|
+
b: BillRow[];
|
|
58
|
+
}): {
|
|
59
|
+
summary: string;
|
|
60
|
+
};
|
|
61
|
+
export declare function buildTrend(kind: string, records: BillRow[], opts?: {
|
|
62
|
+
limit?: number;
|
|
63
|
+
}): {
|
|
64
|
+
summary: string;
|
|
65
|
+
};
|
|
66
|
+
export declare function buildGoalQuery(op: string, items: Record<string, unknown>[]): {
|
|
67
|
+
items: Record<string, unknown>[];
|
|
68
|
+
total: number;
|
|
69
|
+
op: string;
|
|
70
|
+
};
|
|
71
|
+
export declare function buildAccountQuery(items: Record<string, unknown>[]): {
|
|
72
|
+
items: Record<string, unknown>[];
|
|
73
|
+
total: number;
|
|
74
|
+
};
|
|
75
|
+
export interface HelpItem {
|
|
76
|
+
phrase: string;
|
|
77
|
+
key: string;
|
|
78
|
+
shape: string;
|
|
79
|
+
cli: string;
|
|
80
|
+
desc: string;
|
|
81
|
+
}
|
|
82
|
+
export declare function buildHelpItems(all: HelpItem[], q?: string): {
|
|
83
|
+
items: HelpItem[];
|
|
84
|
+
total: number;
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=views.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../src/render/views.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { l1Of } from '../policy/category.js';
|
|
2
|
+
export function toBillItem(r) {
|
|
3
|
+
return {
|
|
4
|
+
id: r.id, category: r.category, time: r.time, amount: r.amount,
|
|
5
|
+
account: r.account, ledger: r.ledger, currency: r.currency, note: r.note,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function isTransfer(r) {
|
|
9
|
+
return r.ledger === '转账' || r.category.startsWith('转账/');
|
|
10
|
+
}
|
|
11
|
+
// KPI(转账除外):count/expense/income/net 全 number。
|
|
12
|
+
export function calcKpi(records) {
|
|
13
|
+
const real = records.filter((r) => !isTransfer(r));
|
|
14
|
+
let expense = 0;
|
|
15
|
+
let income = 0;
|
|
16
|
+
for (const r of real) {
|
|
17
|
+
if (r.amount < 0)
|
|
18
|
+
expense += Math.abs(r.amount);
|
|
19
|
+
else
|
|
20
|
+
income += r.amount;
|
|
21
|
+
}
|
|
22
|
+
expense = Math.round(expense * 100) / 100;
|
|
23
|
+
income = Math.round(income * 100) / 100;
|
|
24
|
+
return { count: real.length, expense, income, net: Math.round((income - expense) * 100) / 100 };
|
|
25
|
+
}
|
|
26
|
+
// 分类聚合(支出侧绝对值降序,转账除外)。
|
|
27
|
+
export function calcCategories(records) {
|
|
28
|
+
const agg = new Map();
|
|
29
|
+
for (const r of records) {
|
|
30
|
+
if (r.amount >= 0 || isTransfer(r))
|
|
31
|
+
continue;
|
|
32
|
+
const cat = r.category || '其他';
|
|
33
|
+
const it = agg.get(cat) ?? { category: cat, total: 0, count: 0 };
|
|
34
|
+
it.total += Math.abs(r.amount);
|
|
35
|
+
it.count += 1;
|
|
36
|
+
agg.set(cat, it);
|
|
37
|
+
}
|
|
38
|
+
const out = [...agg.values()].sort((a, b) => b.total - a.total);
|
|
39
|
+
for (const it of out)
|
|
40
|
+
it.total = Math.round(it.total * 100) / 100;
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
// 单日/区间/搜索:items + total + kpi(供模板主卡)。
|
|
44
|
+
export function buildRecordToday(date, records) {
|
|
45
|
+
const items = records.map(toBillItem);
|
|
46
|
+
return { items, total: items.length, date, kpi: calcKpi(records) };
|
|
47
|
+
}
|
|
48
|
+
export function buildRecordRange(start, end, records) {
|
|
49
|
+
const items = records.map(toBillItem);
|
|
50
|
+
return { items, total: items.length, start, end, kpi: calcKpi(records) };
|
|
51
|
+
}
|
|
52
|
+
export function buildRecordSearch(kind, records) {
|
|
53
|
+
const items = records.map(toBillItem);
|
|
54
|
+
return { items, total: items.length, kind, kpi: calcKpi(records) };
|
|
55
|
+
}
|
|
56
|
+
export function buildRecordDetail(record) {
|
|
57
|
+
return { item: { ...toBillItem(record) } };
|
|
58
|
+
}
|
|
59
|
+
export function buildRecordReceipt(message) {
|
|
60
|
+
return { ok: true, message };
|
|
61
|
+
}
|
|
62
|
+
// 总览:stat metrics(count/expense/income/net + l1.* + days 全 number)。
|
|
63
|
+
export function buildOverview(label, records) {
|
|
64
|
+
const kpi = calcKpi(records);
|
|
65
|
+
const metrics = { count: kpi.count, expense: kpi.expense, income: kpi.income, net: kpi.net };
|
|
66
|
+
const days = new Set();
|
|
67
|
+
for (const r of records) {
|
|
68
|
+
days.add(r.time.slice(0, 10));
|
|
69
|
+
if (r.amount < 0 && !isTransfer(r)) {
|
|
70
|
+
const k = 'l1.' + l1Of(r.category);
|
|
71
|
+
metrics[k] = Math.round(((metrics[k] || 0) + Math.abs(r.amount)) * 100) / 100;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
metrics.days = days.size;
|
|
75
|
+
void label;
|
|
76
|
+
return { metrics };
|
|
77
|
+
}
|
|
78
|
+
// 对比:analysis summary(两聚合 + 差异句;数字全来自实算)。
|
|
79
|
+
export function buildCompare(args) {
|
|
80
|
+
const ka = calcKpi(args.a);
|
|
81
|
+
const kb = calcKpi(args.b);
|
|
82
|
+
const fmt = (n) => String(n);
|
|
83
|
+
const lines = [
|
|
84
|
+
`${args.labelA} vs ${args.labelB}:笔数 ${ka.count}→${kb.count},支出 ${fmt(ka.expense)}→${fmt(kb.expense)},收入 ${fmt(ka.income)}→${fmt(kb.income)},净额 ${fmt(ka.net)}→${fmt(kb.net)}。`,
|
|
85
|
+
];
|
|
86
|
+
const d = Math.round((kb.expense - ka.expense) * 100) / 100;
|
|
87
|
+
lines.push('支出变化:' + (d >= 0 ? '+' : '') + d + '。');
|
|
88
|
+
return { summary: lines.join('\n') };
|
|
89
|
+
}
|
|
90
|
+
// 趋势/排行/洞察:analysis summary(按月聚合 + Top/高频/分布/异常句;数字全来自实算)。
|
|
91
|
+
export function buildTrend(kind, records, opts = {}) {
|
|
92
|
+
const limit = opts.limit ?? 5;
|
|
93
|
+
const byMonth = new Map();
|
|
94
|
+
for (const r of records) {
|
|
95
|
+
if (isTransfer(r))
|
|
96
|
+
continue;
|
|
97
|
+
const m = r.time.slice(0, 7);
|
|
98
|
+
byMonth.set(m, Math.round(((byMonth.get(m) || 0) + Math.abs(r.amount)) * 100) / 100);
|
|
99
|
+
}
|
|
100
|
+
const months = [...byMonth.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
101
|
+
const lines = [`${kind}:共 ${records.length} 笔,` + months.map(([m, v]) => `${m} ${v}`).join('、') + '。'];
|
|
102
|
+
if (kind === 'top' || kind === 'trend') {
|
|
103
|
+
const top = [...records].filter((r) => r.amount < 0 && !isTransfer(r)).sort((a, b) => a.amount - b.amount).slice(0, limit);
|
|
104
|
+
for (const r of top)
|
|
105
|
+
lines.push(`${r.time.slice(0, 10)} ${r.category} ${r.amount} ${r.note}`.trim());
|
|
106
|
+
}
|
|
107
|
+
if (kind === 'insight' || kind === 'anomaly') {
|
|
108
|
+
const cats = calcCategories(records).slice(0, 3);
|
|
109
|
+
if (cats.length)
|
|
110
|
+
lines.push('主要支出:' + cats.map((c) => `${c.category} ${c.total}`).join('、') + '。');
|
|
111
|
+
else
|
|
112
|
+
lines.push('样本不足,无显著异常。');
|
|
113
|
+
}
|
|
114
|
+
return { summary: lines.join('\n') };
|
|
115
|
+
}
|
|
116
|
+
// 目标/账户查询:list(items + total;预算执行/余额由调用方实算装配)。
|
|
117
|
+
export function buildGoalQuery(op, items) {
|
|
118
|
+
return { items, total: items.length, op };
|
|
119
|
+
}
|
|
120
|
+
export function buildAccountQuery(items) {
|
|
121
|
+
return { items, total: items.length };
|
|
122
|
+
}
|
|
123
|
+
export function buildHelpItems(all, q) {
|
|
124
|
+
const items = !q || !q.trim() ? all : all.filter((h) => q.includes(h.phrase) || h.phrase.includes(q.trim()));
|
|
125
|
+
return { items, total: items.length };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=views.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/render/views.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skill-bill",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "饼干记账SKILL一期:取数+口径+渲染+出口(16 联动 key+cmd_read+SKILL+HELP+parity),依 link-core",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./fetch": "./dist/fetch/index.js",
|
|
11
|
+
"./policy": "./dist/policy/index.js",
|
|
12
|
+
"./render": "./dist/render/index.js",
|
|
13
|
+
"./cli": "./dist/cli/cmd_read.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"templates/*.html"
|
|
18
|
+
],
|
|
19
|
+
"bin": {
|
|
20
|
+
"bill-cmd-read": "./dist/cli/cmd_read.js"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"base-link-core": "workspace:^0.1.0"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=22.13"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc -b && node scripts/build-help.mjs",
|
|
30
|
+
"test": "node --test test/*.test.mjs"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>看账户汇总</title>
|
|
6
|
+
<!--SHARED-CSS-->
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div class="page">
|
|
10
|
+
<h1>看账户汇总</h1>
|
|
11
|
+
<p class="cmd">bill-cmd-read bill.account.query</p>
|
|
12
|
+
<!--CONTENT-->
|
|
13
|
+
</div>
|
|
14
|
+
<!--SHARED-HELPERS-->
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>新增改转账</title>
|
|
6
|
+
<!--SHARED-CSS-->
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div class="page">
|
|
10
|
+
<h1>新增改转账</h1>
|
|
11
|
+
<p class="cmd">bill-cmd-read bill.account.write</p>
|
|
12
|
+
<!--CONTENT-->
|
|
13
|
+
</div>
|
|
14
|
+
<!--SHARED-HELPERS-->
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>看对比</title>
|
|
6
|
+
<!--SHARED-CSS-->
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div class="page">
|
|
10
|
+
<h1>看对比</h1>
|
|
11
|
+
<p class="cmd">bill-cmd-read bill.analysis.compare</p>
|
|
12
|
+
<!--CONTENT-->
|
|
13
|
+
</div>
|
|
14
|
+
<!--SHARED-HELPERS-->
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>看月度总览</title>
|
|
6
|
+
<!--SHARED-CSS-->
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div class="page">
|
|
10
|
+
<h1>看月度总览</h1>
|
|
11
|
+
<p class="cmd">bill-cmd-read bill.analysis.overview</p>
|
|
12
|
+
<!--CONTENT-->
|
|
13
|
+
</div>
|
|
14
|
+
<!--SHARED-HELPERS-->
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|