This commit is contained in:
@@ -104,6 +104,46 @@ export function moveItemWithinScope<T extends { id: string; parent_id?: string |
|
||||
return items.map((item) => (item.parent_id ?? null) === (source.parent_id ?? null) ? reorderedIterator.next().value! : item)
|
||||
}
|
||||
|
||||
export type TaskRepeatConfig = {
|
||||
frequency: 'daily' | 'weekly' | 'monthly' | 'yearly'
|
||||
interval: number
|
||||
weekdays?: string[]
|
||||
monthDays?: number[]
|
||||
endMode: 'never' | 'date' | 'count'
|
||||
count?: number
|
||||
until?: string
|
||||
}
|
||||
|
||||
export function buildTaskRrule(config: TaskRepeatConfig) {
|
||||
const interval = Math.floor(Number(config.interval))
|
||||
if (!Number.isFinite(interval) || interval < 1) throw new Error('重复间隔至少为 1')
|
||||
if (config.frequency === 'weekly' && !config.weekdays?.length) throw new Error('至少选择一个重复日期')
|
||||
if (config.frequency === 'monthly' && (!config.monthDays?.length || config.monthDays.some((day) => day < 1 || day > 31))) throw new Error('请输入 1 到 31 的每月日期')
|
||||
if (config.endMode === 'count' && (!config.count || config.count < 1)) throw new Error('重复次数至少为 1')
|
||||
if (config.endMode === 'date' && !config.until) throw new Error('请选择结束日期')
|
||||
const parts = [`FREQ=${config.frequency.toUpperCase()}`]
|
||||
if (interval > 1) parts.push(`INTERVAL=${interval}`)
|
||||
if (config.frequency === 'weekly' && config.weekdays?.length) parts.push(`BYDAY=${config.weekdays.join(',')}`)
|
||||
if (config.frequency === 'monthly' && config.monthDays?.length) parts.push(`BYMONTHDAY=${config.monthDays.join(',')}`)
|
||||
if (config.endMode === 'count') parts.push(`COUNT=${Math.max(1, Math.floor(config.count ?? 1))}`)
|
||||
if (config.endMode === 'date' && config.until) parts.push(`UNTIL=${config.until}T23:59:59`)
|
||||
return parts.join(';')
|
||||
}
|
||||
|
||||
export function parseTaskRrule(rrule = ''): TaskRepeatConfig {
|
||||
const parts = Object.fromEntries(rrule.split(';').filter(Boolean).map((part) => part.split('=', 2)))
|
||||
const frequency = (parts.FREQ?.toLowerCase() || 'daily') as TaskRepeatConfig['frequency']
|
||||
return {
|
||||
frequency,
|
||||
interval: Math.max(1, Number(parts.INTERVAL ?? 1)),
|
||||
weekdays: parts.BYDAY?.split(',').filter(Boolean) ?? [],
|
||||
monthDays: parts.BYMONTHDAY?.split(',').map(Number).filter(Number.isFinite) ?? [],
|
||||
endMode: parts.COUNT ? 'count' : parts.UNTIL ? 'date' : 'never',
|
||||
count: parts.COUNT ? Number(parts.COUNT) : 1,
|
||||
until: parts.UNTIL?.slice(0, 10) ?? '',
|
||||
}
|
||||
}
|
||||
|
||||
export function toDateTimeLocal(value: string | null | undefined) {
|
||||
if (!value) return ''
|
||||
const date = new Date(value)
|
||||
|
||||
Reference in New Issue
Block a user