/** /** * OmniCard AI (CRMmp) - 商务日程预约与日历服务 (UTS 强类型版本) * 严格对齐 backend/src/modules/card/service/calendar.ts 规范 */ import { MeetingInviteOptions, CalendarInviteBundle } from './types.uts'; import { getBaseUrl } from './request.uts'; /** * 格式化 UTC 时间为 RFC 5545 日期时间戳 (YYYYMMDDTHHmmssZ) */ export function formatIcsDate(date: Date | string | number): string { const d = date instanceof Date ? date : new Date(date); if (isNaN(d.getTime())) { return ''; } const pad = (n: number): string => (n < 10 ? '0' + n : String(n)); const year = d.getUTCFullYear(); const month = pad(d.getUTCMonth() + 1); const day = pad(d.getUTCDate()); const hours = pad(d.getUTCHours()); const minutes = pad(d.getUTCMinutes()); const seconds = pad(d.getUTCSeconds()); return `${year}${month}${day}T${hours}${minutes}${seconds}Z`; } /** * 格式化为 ISO 8601 字符串 (用于 Outlook) */ export function toIsoDate(date: Date | string | number): string { const d = date instanceof Date ? date : new Date(date); if (isNaN(d.getTime())) { return ''; } return d.toISOString(); } /** * 生成 Google Calendar Web 一键预约 URL */ export function generateGoogleCalendarUrl(meeting: MeetingInviteOptions): string { const summary = meeting.summary || meeting.title || '商务洽谈'; const dtStart = formatIcsDate(meeting.startTime); const dtEnd = formatIcsDate(meeting.endTime); let details = meeting.description || ''; if (meeting.organizerEmail) { details += `\nOrganizer: ${meeting.organizerEmail}`; } const queryParts: string[] = [ 'action=TEMPLATE', `text=${encodeURIComponent(summary)}`, `dates=${encodeURIComponent(`${dtStart}/${dtEnd}`)}`, `details=${encodeURIComponent(details.trim())}`, `location=${encodeURIComponent(meeting.location || '')}`, ]; return `https://calendar.google.com/calendar/render?${queryParts.join('&')}`; } /** * 生成 Outlook Live 一键预约 URL */ export function generateOutlookCalendarUrl(meeting: MeetingInviteOptions): string { const summary = meeting.summary || meeting.title || '商务洽谈'; const startDt = toIsoDate(meeting.startTime); const endDt = toIsoDate(meeting.endTime); const queryParts: string[] = [ 'path=%2Fcalendar%2Faction%2Fcompose', 'rru=addevent', `subject=${encodeURIComponent(summary)}`, `startdt=${encodeURIComponent(startDt)}`, `enddt=${encodeURIComponent(endDt)}`, `body=${encodeURIComponent(meeting.description || '')}`, `location=${encodeURIComponent(meeting.location || '')}`, ]; return `https://outlook.live.com/calendar/0/deeplink/compose?${queryParts.join('&')}`; } /** * 获取后端 RFC 5545 ICS 订阅文件下载 URL */ export function getMeetingIcsDownloadUrl(meeting: MeetingInviteOptions): string { const baseUrl = getBaseUrl(); const summary = meeting.summary || meeting.title || '商务洽谈'; const dtStart = formatIcsDate(meeting.startTime); const dtEnd = formatIcsDate(meeting.endTime); const queryParts: string[] = [ `summary=${encodeURIComponent(summary)}`, `startTime=${encodeURIComponent(dtStart)}`, `endTime=${encodeURIComponent(dtEnd)}`, `description=${encodeURIComponent(meeting.description || '')}`, `location=${encodeURIComponent(meeting.location || '')}`, ]; if (meeting.organizerName) { queryParts.push(`organizerName=${encodeURIComponent(meeting.organizerName)}`); } if (meeting.organizerEmail) { queryParts.push(`organizerEmail=${encodeURIComponent(meeting.organizerEmail)}`); } return `${baseUrl}/open/card/portal/meeting-ics?${queryParts.join('&')}`; } /** * 综合生成全平台日历预约包 */ export function buildCalendarInviteBundle(meeting: MeetingInviteOptions): CalendarInviteBundle { return { googleUrl: generateGoogleCalendarUrl(meeting), outlookUrl: generateOutlookCalendarUrl(meeting), icsUrl: getMeetingIcsDownloadUrl(meeting), }; }