Files
rosercode b1fb2c68a9 docs: 新增日历页文档并补充记账直接新建分类/标签/渠道说明
补上此前已完成但未提交的文档更新:新增「日历」页面使用文档,并把登录后默认落地页由统计面板调整为日历,同步页面流程与偏好说明;同时补充记账弹窗内可直接新建分类/标签/渠道的说明,并登记相应截图场景。

变更内容:
- 新增 guide/calendar.md,并在 .vitepress/config.mts 侧边栏与 guide/pages.md、guide/index.md 登记日历页
- index.md、guide/getting-started.md、guide/dashboard.md、guide/pages.md 同步日历为登录后默认落地页与页面流程
- dev/preferences.md 新增日历偏好 ledgerly.calendar.view/year/month/statsScope 说明
- guide/transactions.md 补充记账弹窗内直接新建分类/标签/渠道的说明,guide/ai.md、guide/categories-tags.md、guide/channels.md 同步相关描述
- scripts/ts/capture-all.ts、capture-pages.ts、capture-elements.ts 增加日历与新建分类等截图场景,captureModals 支持按场景过滤
2026-10-13 12:52:08 +08:00

72 lines
2.9 KiB
TypeScript

// 整页截图:遍历页面清单,截取完整页面并写入 public/screenshots/。
import { resolve } from 'node:path'
import { pathToFileURL } from 'node:url'
import type { Page } from 'playwright-core'
import { injectSession, launchBrowser, login, newContext, waitPage } from './browser.js'
import { BASE_URL, OUT_DIR } from './config.js'
/** 整页截图清单:文件名、路由、视口宽度、视口高度、关键元素选择器 */
const PAGES: Array<[string, string, number, number, string]> = [
['login', '/login', 1440, 900, '.n-card'],
['register', '/register', 1440, 900, '.n-card'],
['calendar', '/calendar', 1440, 1280, '.n-calendar'],
['dashboard', '/dashboard', 1440, 1280, 'canvas'],
['sql-query', '/smart-query', 1440, 1180, '.n-card'],
['transactions', '/transactions', 1720, 1200, '.n-data-table-tbody tr'],
['categories', '/categories', 1440, 1100, '.n-data-table-tbody tr'],
['tags', '/tags', 1440, 1100, '.n-data-table-tbody tr'],
['rules', '/rules', 1440, 1100, '.n-data-table-tbody tr'],
['channels', '/channels', 1440, 1000, '.n-data-table-tbody tr'],
['email-bills-configs', '/email-bills/configs', 1440, 1000, '.n-data-table-tbody tr'],
['email-bills-sender-rules', '/email-bills/senderRules', 1440, 1000, '.n-data-table-tbody tr'],
['email-bills-messages', '/email-bills/messages', 1440, 1000, '.n-data-table-tbody tr'],
['bill-import', '/bill-import', 1440, 1000, '.n-card'],
['settings', '/settings', 1440, 1900, '.config-card'],
['ai-usage', '/ai-usage', 1440, 1000, '.n-card'],
['logs-http', '/logs/http', 1440, 1000, '.n-data-table-tbody tr'],
['logs-login', '/logs/login', 1440, 1000, '.n-data-table-tbody tr'],
['logs-app', '/logs/app', 1440, 1000, '.n-log'],
]
/**
* 截取整页。
*
* @param page Page 实例
* @param only 仅截取指定页面名(可选,缺省截取全部)
*/
export async function capturePages(page: Page, only?: string[]): Promise<void> {
const pages = only ? PAGES.filter(([name]) => only.includes(name)) : PAGES
for (const [name, path, width, height, selector] of pages) {
try {
await page.setViewportSize({ width, height })
await page.goto(BASE_URL + path)
await waitPage(page, { selector })
await page.screenshot({ path: resolve(OUT_DIR, `${name}.png`) })
console.log(`[OK] page/${name}`)
} catch (err) {
console.log(`[FAIL] page/${name}: ${err}`)
}
}
}
async function main(): Promise<void> {
const browser = await launchBrowser()
try {
const token = await login()
const context = await newContext(browser)
await injectSession(context, token)
const page = await context.newPage()
await capturePages(page)
await context.close()
} finally {
await browser.close()
}
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
main().catch((err) => {
console.error('FAIL', err)
process.exit(1)
})
}