import { utils, CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService'; import { _ } from '@joplin/lib/locale'; import Note from '@joplin/lib/models/Note'; import Folder from '@joplin/lib/models/Folder'; import time from '@joplin/lib/time'; import CommandService from '@joplin/lib/services/CommandService'; import { createNoteInActiveFolder, newNoteEnabledConditions } from './newNote'; import { formatChineseDateTitle } from '../../NoteEditor/utils/searchNotesForMention'; /** * 英文星期映射至中文星期 */ const ENGLISH_TO_CHINESE_WEEKDAY: Record = { Monday: '星期一', Tuesday: '星期二', Wednesday: '星期三', Thursday: '星期四', Friday: '星期五', Saturday: '星期六', Sunday: '星期日', }; /** * 将文本中携带英文星期的日期(如 2026-11-02 Monday)转换为中文星期(如 2026-11-02 星期一) */ export const normalizeDateWeekdayToChinese = (str: string): string => { if (!str) return str; let result = str; for (const [en, zh] of Object.entries(ENGLISH_TO_CHINESE_WEEKDAY)) { result = result.replace(new RegExp(`(\\b\\d{4}-\\d{2}-\\d{2}\\s+)` + en + `\\b`, 'g'), `$1${zh}`); } return result; }; /** * 获取今日日志的匹配前缀(格式:YYYY-MM-DD) */ export const getTodayDatePrefix = (nowMs = Date.now()): string => { return time.formatMsToLocal(nowMs, 'YYYY-MM-DD'); }; /** * 获取今日日志默认标题(格式:YYYY-MM-DD 星期X) */ export const getTodayNoteTitle = (nowMs = Date.now()): string => { return formatChineseDateTitle(nowMs); }; export const declaration: CommandDeclaration = { name: 'openTodayNote', label: () => _('Today\'s note'), iconName: 'far fa-calendar-alt', }; export const runtime = (): CommandRuntime => { return { execute: async (_context: CommandContext) => { const prefix = getTodayDatePrefix(); const folder = await Folder.getValidActiveFolder(); let existingNoteId: string | null = null; if (folder) { const row = await Note.db().selectOne( 'SELECT id FROM notes WHERE is_conflict = 0 AND parent_id = ? AND title LIKE ? AND (deleted_time = 0 OR deleted_time IS NULL) ORDER BY updated_time DESC LIMIT 1', [folder.id, `${prefix}%`], ); if (row && typeof row.id === 'string') { existingNoteId = row.id; } } if (!existingNoteId) { const row = await Note.db().selectOne( 'SELECT id FROM notes WHERE is_conflict = 0 AND title LIKE ? AND (deleted_time = 0 OR deleted_time IS NULL) ORDER BY updated_time DESC LIMIT 1', [`${prefix}%`], ); if (row && typeof row.id === 'string') { existingNoteId = row.id; } } if (existingNoteId) { // 自动将旧格式(如 2026-11-02 Monday)平滑迁移为标准中文星期(2026-11-02 星期一) const note = await Note.load(existingNoteId); if (note) { const newTitle = normalizeDateWeekdayToChinese(note.title); const newBody = normalizeDateWeekdayToChinese(note.body); if (newTitle !== note.title || newBody !== note.body) { await Note.save({ id: note.id, title: newTitle, body: newBody, }); } } utils.store.dispatch({ type: 'NOTE_SELECT', id: existingNoteId }); } else { const title = getTodayNoteTitle(); const body = `# ${title}\n\n- [ ] `; const created = await createNoteInActiveFolder({ title, body }); if (!created) return; } if (CommandService.instance().exists('focusElement')) { setTimeout(() => { void CommandService.instance().execute('focusElement', 'noteBody'); }, 100); } }, enabledCondition: newNoteEnabledConditions, }; };