后端优化 agent 资产种子初始化和常量配置,前端新增数字员工 视图和调度对话框组件,重构个人工作台首页布局和洞察面板, 完善审计页面数字员工详情和运行时模型,优化侧边栏导航和图 标配置,新增工作台摘要和工作台数据模块,补充单元测试。
123 lines
3.7 KiB
JavaScript
123 lines
3.7 KiB
JavaScript
const DEFAULT_SCHEDULE_TIME = '00:00'
|
|
const CRON_TOKEN_PATTERN = /^[\d*/,?\-]+$/
|
|
|
|
export const DIGITAL_EMPLOYEE_SCHEDULE_MODES = [
|
|
{ value: 'manual', label: '手动触发' },
|
|
{ value: 'daily', label: '每天执行' },
|
|
{ value: 'weekly', label: '每周执行' },
|
|
{ value: 'custom', label: 'Cron 表达式' }
|
|
]
|
|
|
|
export const DIGITAL_EMPLOYEE_WEEKDAY_OPTIONS = [
|
|
{ value: '1', label: '周一' },
|
|
{ value: '2', label: '周二' },
|
|
{ value: '3', label: '周三' },
|
|
{ value: '4', label: '周四' },
|
|
{ value: '5', label: '周五' },
|
|
{ value: '6', label: '周六' },
|
|
{ value: '0', label: '周日' }
|
|
]
|
|
|
|
function normalizeText(value) {
|
|
return String(value ?? '').trim()
|
|
}
|
|
|
|
function normalizeTime(value) {
|
|
const raw = normalizeText(value)
|
|
return /^\d{2}:\d{2}$/.test(raw) ? raw : DEFAULT_SCHEDULE_TIME
|
|
}
|
|
|
|
function toTime(hour, minute) {
|
|
const hourNumber = Number(hour)
|
|
const minuteNumber = Number(minute)
|
|
if (!Number.isInteger(hourNumber) || hourNumber < 0 || hourNumber > 23) {
|
|
return DEFAULT_SCHEDULE_TIME
|
|
}
|
|
if (!Number.isInteger(minuteNumber) || minuteNumber < 0 || minuteNumber > 59) {
|
|
return DEFAULT_SCHEDULE_TIME
|
|
}
|
|
return `${String(hourNumber).padStart(2, '0')}:${String(minuteNumber).padStart(2, '0')}`
|
|
}
|
|
|
|
export function createDigitalEmployeeScheduleForm(cron = '') {
|
|
const normalizedCron = normalizeText(cron)
|
|
if (!normalizedCron) {
|
|
return { mode: 'manual', time: DEFAULT_SCHEDULE_TIME, weekday: '1', cron: '' }
|
|
}
|
|
|
|
const parts = normalizedCron.split(/\s+/)
|
|
if (parts.length !== 5) {
|
|
return { mode: 'custom', time: DEFAULT_SCHEDULE_TIME, weekday: '1', cron: normalizedCron }
|
|
}
|
|
|
|
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts
|
|
const time = toTime(hour, minute)
|
|
|
|
if (dayOfMonth === '*' && month === '*' && dayOfWeek === '*') {
|
|
return { mode: 'daily', time, weekday: '1', cron: normalizedCron }
|
|
}
|
|
|
|
if (dayOfMonth === '*' && month === '*' && dayOfWeek !== '*') {
|
|
return { mode: 'weekly', time, weekday: dayOfWeek || '1', cron: normalizedCron }
|
|
}
|
|
|
|
return { mode: 'custom', time, weekday: '1', cron: normalizedCron }
|
|
}
|
|
|
|
export function resolveDigitalEmployeeScheduleValue(employee = {}) {
|
|
const config = employee.configJson || {}
|
|
return (
|
|
normalizeText(employee.digitalEmployee?.scheduleValue) ||
|
|
normalizeText(config.cron) ||
|
|
normalizeText(config.schedule) ||
|
|
normalizeText(config.cron_expression)
|
|
)
|
|
}
|
|
|
|
export function buildDigitalEmployeeScheduleCron(form = {}) {
|
|
const mode = normalizeText(form.mode) || 'manual'
|
|
if (mode === 'manual') {
|
|
return ''
|
|
}
|
|
|
|
if (mode === 'custom') {
|
|
const cron = normalizeText(form.cron)
|
|
const parts = cron.split(/\s+/).filter(Boolean)
|
|
if (parts.length !== 5 || !parts.every((part) => CRON_TOKEN_PATTERN.test(part))) {
|
|
throw new Error('请输入 5 段 Cron 表达式。')
|
|
}
|
|
return parts.join(' ')
|
|
}
|
|
|
|
const [hour, minute] = normalizeTime(form.time).split(':')
|
|
if (mode === 'daily') {
|
|
return `${Number(minute)} ${Number(hour)} * * *`
|
|
}
|
|
|
|
if (mode === 'weekly') {
|
|
const weekday = normalizeText(form.weekday) || '1'
|
|
return `${Number(minute)} ${Number(hour)} * * ${weekday}`
|
|
}
|
|
|
|
throw new Error('请选择有效的执行方式。')
|
|
}
|
|
|
|
export function buildDigitalEmployeeScheduleConfig(config = {}, cron = '') {
|
|
const nextConfig = config && typeof config === 'object' && !Array.isArray(config)
|
|
? { ...config }
|
|
: {}
|
|
const normalizedCron = normalizeText(cron)
|
|
|
|
if (normalizedCron) {
|
|
nextConfig.cron = normalizedCron
|
|
nextConfig.schedule = normalizedCron
|
|
nextConfig.cron_expression = normalizedCron
|
|
return nextConfig
|
|
}
|
|
|
|
delete nextConfig.cron
|
|
delete nextConfig.schedule
|
|
delete nextConfig.cron_expression
|
|
return nextConfig
|
|
}
|