diff --git a/astrbot/core/cron/manager.py b/astrbot/core/cron/manager.py index 9f3116f65..fde2ad5cd 100644 --- a/astrbot/core/cron/manager.py +++ b/astrbot/core/cron/manager.py @@ -15,6 +15,7 @@ from astrbot.core.cron.events import CronMessageEvent from astrbot.core.db import BaseDatabase from astrbot.core.db.po import CronJob from astrbot.core.platform.message_session import MessageSession +from astrbot.core.platform.message_type import MessageType from astrbot.core.provider.entites import ProviderRequest from astrbot.core.utils.history_saver import persist_agent_history @@ -200,9 +201,18 @@ class CronJobManager: return None return aps_job.next_run_time.astimezone(timezone.utc) - async def _run_job(self, job_id: str) -> None: + async def run_job_now(self, job_id: str) -> None: + await self._run_job(job_id, ignore_enabled=True, delete_run_once=False) + + async def _run_job( + self, + job_id: str, + *, + ignore_enabled: bool = False, + delete_run_once: bool = True, + ) -> None: job = await self.db.get_cron_job(job_id) - if not job or not job.enabled: + if not job or (not job.enabled and not ignore_enabled): return start_time = datetime.now(timezone.utc) await self.db.update_cron_job( @@ -230,7 +240,7 @@ class CronJobManager: last_error=last_error, next_run_time=next_run, ) - if job.run_once: + if job.run_once and delete_run_once: # one-shot: remove after execution regardless of success await self.delete_job(job_id) @@ -245,9 +255,14 @@ class CronJobManager: async def _run_active_agent_job(self, job: CronJob, start_time: datetime) -> None: payload = job.payload or {} - session_str = payload.get("session") - if not session_str: - raise ValueError("ActiveAgentCronJob missing session.") + delivery_session_str = str(payload.get("session") or "").strip() + session_str = delivery_session_str or str( + MessageSession( + platform_name="cron", + message_type=MessageType.OTHER_MESSAGE, + session_id=job.job_id, + ) + ) note = payload.get("note") or job.description or job.name extras = { @@ -262,7 +277,7 @@ class CronJobManager: "run_at": ( job.payload.get("run_at") if isinstance(job.payload, dict) else None ), - "session": session_str, + "session": delivery_session_str, }, "cron_payload": payload, } @@ -271,6 +286,7 @@ class CronJobManager: message=note, session_str=session_str, extras=extras, + delivery_session_str=delivery_session_str, ) async def _woke_main_agent( @@ -279,6 +295,7 @@ class CronJobManager: message: str, session_str: str, extras: dict, + delivery_session_str: str = "", ) -> None: """Woke the main agent to handle the cron job message.""" from astrbot.core.astr_main_agent import ( @@ -353,11 +370,12 @@ class CronJobManager: "Output using same language as previous conversation. " "After completing your task, summarize and output your actions and results." ) - if not req.func_tool: - req.func_tool = ToolSet() - req.func_tool.add_tool( - self.ctx.get_llm_tool_manager().get_builtin_tool(SendMessageToUserTool) - ) + if delivery_session_str: + if not req.func_tool: + req.func_tool = ToolSet() + req.func_tool.add_tool( + self.ctx.get_llm_tool_manager().get_builtin_tool(SendMessageToUserTool) + ) result = await build_main_agent( event=cron_event, plugin_context=self.ctx, config=config, req=req diff --git a/astrbot/dashboard/routes/cron.py b/astrbot/dashboard/routes/cron.py index 8417c970c..85dbc2509 100644 --- a/astrbot/dashboard/routes/cron.py +++ b/astrbot/dashboard/routes/cron.py @@ -1,3 +1,4 @@ +import asyncio import traceback from datetime import datetime, timezone @@ -15,11 +16,13 @@ class CronRoute(Route): ) -> None: super().__init__(context) self.core_lifecycle = core_lifecycle + self._background_tasks: set[asyncio.Task] = set() self.routes = [ ("/cron/jobs", ("GET", self.list_jobs)), ("/cron/jobs", ("POST", self.create_job)), ("/cron/jobs/", ("PATCH", self.update_job)), ("/cron/jobs/", ("DELETE", self.delete_job)), + ("/cron/jobs//run", ("POST", self.run_job_now)), ] self.register_routes() @@ -71,7 +74,7 @@ class CronRoute(Route): name = payload.get("name") or "active_agent_task" cron_expression = payload.get("cron_expression") note = payload.get("note") or payload.get("description") or name - session = payload.get("session") + session = str(payload.get("session") or "").strip() persona_id = payload.get("persona_id") provider_id = payload.get("provider_id") timezone = payload.get("timezone") @@ -79,8 +82,6 @@ class CronRoute(Route): run_once = bool(payload.get("run_once", False)) run_at = payload.get("run_at") - if not session: - return jsonify(Response().error("session is required").__dict__) if run_once and not run_at: return jsonify( Response().error("run_at is required when run_once=true").__dict__ @@ -172,11 +173,10 @@ class CronRoute(Route): if "session" in payload: session = str(payload.get("session") or "").strip() - if not session: - return jsonify( - Response().error("session cannot be empty").__dict__ - ) - merged_payload["session"] = session + if session: + merged_payload["session"] = session + else: + merged_payload.pop("session", None) note_updated = False if "note" in payload: @@ -281,3 +281,21 @@ class CronRoute(Route): except Exception as e: # noqa: BLE001 logger.error(traceback.format_exc()) return jsonify(Response().error(f"Failed to delete job: {e!s}").__dict__) + + async def run_job_now(self, job_id: str): + try: + cron_mgr = self.core_lifecycle.cron_manager + if cron_mgr is None: + return jsonify( + Response().error("Cron manager not initialized").__dict__ + ) + job = await cron_mgr.db.get_cron_job(job_id) + if not job: + return jsonify(Response().error("Job not found").__dict__) + task = asyncio.create_task(cron_mgr.run_job_now(job_id)) + self._background_tasks.add(task) + task.add_done_callback(self._background_tasks.discard) + return jsonify(Response().ok(message="started").__dict__) + except Exception as e: # noqa: BLE001 + logger.error(traceback.format_exc()) + return jsonify(Response().error(f"Failed to run job: {e!s}").__dict__) diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css b/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css index 73e5e1b92..8e5fd76cd 100644 --- a/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css +++ b/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css @@ -1,4 +1,4 @@ -/* Auto-generated MDI subset – 268 icons */ +/* Auto-generated MDI subset – 271 icons */ /* Do not edit manually. Run: pnpm run subset-icons */ @font-face { @@ -228,6 +228,10 @@ content: "\F0150"; } +.mdi-clock-time-four-outline::before { + content: "\F144E"; +} + .mdi-close::before { content: "\F0156"; } @@ -820,6 +824,10 @@ content: "\F040A"; } +.mdi-play-circle-outline::before { + content: "\F040D"; +} + .mdi-plus::before { content: "\F0415"; } @@ -892,6 +900,10 @@ content: "\F167A"; } +.mdi-send-outline::before { + content: "\F1165"; +} + .mdi-server::before { content: "\F048B"; } diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff index 79ae57535..181ce7f86 100644 Binary files a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff and b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff differ diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 index 13a0380b9..931625c6d 100644 Binary files a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 and b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 differ diff --git a/dashboard/src/i18n/locales/en-US/features/cron.json b/dashboard/src/i18n/locales/en-US/features/cron.json index a3bafd4d6..5b081d69e 100644 --- a/dashboard/src/i18n/locales/en-US/features/cron.json +++ b/dashboard/src/i18n/locales/en-US/features/cron.json @@ -6,8 +6,9 @@ "page": { "title": "Future Task Management", "beta": "Experimental", - "subtitle": "See scheduled tasks for AstrBot. AstrBot will wake up, run them, and deliver the results.", + "subtitle": "AstrBot wakes up at the scheduled time, completes the task, and sends the result back to the target conversation.", "proactive": { + "link": "Supported platforms", "supported": "Proactive delivery is available only on the configured platforms below", "unsupported": "No proactive messaging platforms enabled. Turn them on in Platform settings." } @@ -18,9 +19,36 @@ "refresh": "Refresh", "delete": "Delete", "cancel": "Cancel", + "close": "Close", + "more": "More actions", + "runNow": "Run now", "save": "Save", "submit": "Create" }, + "platformDialog": { + "title": "Supported Platforms", + "description": "Only the following platforms support proactive message delivery. AstrBot can send future task results back only to target conversations on these platforms." + }, + "card": { + "onceAt": "One-off · {time}", + "runAt": "Run at: {time}", + "nextRun": "Next run: {time}", + "dailyAt": "Daily at {time}", + "weeklyAt": "Every {day} at {time}", + "monthlyAt": "Monthly on day {day} at {time}", + "everyMinutes": "Every {count} minutes", + "everyHours": "Every {count} hours", + "everyDays": "Every {count} days", + "customCron": "Custom · {cron}", + "noDeliveryTarget": "No delivery target" + }, + "filters": { + "search": "Search title and content", + "umo": "Filter by delivery target", + "noUmos": "No UMOs", + "noDeliveryTarget": "No delivery target", + "noMatches": "No matching future tasks." + }, "overview": { "totalTasks": "Total Tasks", "totalTasksNote": "Registered future tasks", @@ -82,12 +110,43 @@ "editTitle": "Edit Task", "chatHint": "You can ask AstrBot in chat to create future tasks instead of adding them here.", "runOnce": "One-off task", - "name": "Task name", - "note": "Task description", - "cron": "Cron expression", + "name": "Task name *", + "note": "Task requirements *", + "scheduleMode": "Execution time *", + "scheduleModes": { + "once": "One-off", + "interval": "Interval", + "daily": "Daily", + "weekly": "Weekly", + "monthly": "Monthly", + "cron": "Custom Cron" + }, + "intervalEvery": "Every *", + "intervalUnit": "Unit *", + "intervalUnits": { + "minutes": "Minutes", + "hours": "Hours", + "days": "Days" + }, + "dailyTime": "Time *", + "weeklyDay": "Weekday *", + "weeklyTime": "Time *", + "monthlyDay": "Day *", + "monthlyTime": "Time *", + "weekdays": { + "sunday": "Sunday", + "monday": "Monday", + "tuesday": "Tuesday", + "wednesday": "Wednesday", + "thursday": "Thursday", + "friday": "Friday", + "saturday": "Saturday" + }, + "cron": "Cron expression *", "cronPlaceholder": "0 9 * * *", - "runAt": "Run at", - "session": "Target session (platform_id:message_type:session_id)", + "runAt": "Run at *", + "session": "Deliver to", + "noUmos": "No sessions available", "timezone": "Timezone (optional, e.g. Asia/Shanghai)", "enabled": "Enabled" }, @@ -97,11 +156,18 @@ "updateFailed": "Failed to update", "deleteSuccess": "Deleted", "deleteFailed": "Failed to delete", - "sessionRequired": "Session is required", - "noteRequired": "Description is required", + "nameRequired": "Task name is required", + "sessionRequired": "Delivery target is required", + "noteRequired": "Task requirements are required", "cronRequired": "Cron expression is required", "runAtRequired": "Please select run time", + "intervalRequired": "Please enter a valid interval", + "dailyTimeRequired": "Please select the daily run time", + "weeklyTimeRequired": "Please select the weekly day and time", + "monthlyTimeRequired": "Please select the monthly day and time", "createSuccess": "Created successfully", - "createFailed": "Failed to create" + "createFailed": "Failed to create", + "runStarted": "Started", + "runFailed": "Failed to run" } } diff --git a/dashboard/src/i18n/locales/ru-RU/features/cron.json b/dashboard/src/i18n/locales/ru-RU/features/cron.json index 76b875ad1..104228950 100644 --- a/dashboard/src/i18n/locales/ru-RU/features/cron.json +++ b/dashboard/src/i18n/locales/ru-RU/features/cron.json @@ -1,107 +1,173 @@ { - "header": { - "eyebrow": "Automation", - "live": "Живая синхронизация" - }, - "page": { - "title": "Запланированные задачи", - "beta": "Экспериментальные функции", - "subtitle": "Управление будущими задачами AstrBot. Бот автоматически проснется, выполнит задачу и отправит результат. Требуется включить «Проактивные способности» в конфигурации.", - "proactive": { - "supported": "Отправка результатов поддерживается только на указанных ниже настроенных платформах", - "unsupported": "Нет платформ, поддерживающих проактивные сообщения. Включите их в настройках платформ." - } - }, - "actions": { - "create": "Новая задача", - "edit": "Изменить", - "refresh": "Обновить", - "delete": "Удалить", - "cancel": "Отмена", - "save": "Сохранить", - "submit": "Создать" - }, - "overview": { - "totalTasks": "Всего задач", - "totalTasksNote": "Все зарегистрированные будущие задачи", - "enabledTasks": "Активные задачи", - "enabledTasksNote": "Задачи, которые будут автоматически выполнены", - "oneOffTasks": "Разовые задачи", - "recurringTasksNote": "Повторяющихся задач: {count}", - "proactivePlatforms": "Проактивные платформы", - "proactivePlatformsNote": "Платформы, способные отправлять результат сами" - }, - "section": { - "registered": { - "title": "Список задач", - "subtitle": "Просматривайте зарегистрированные задачи, время запуска и состояние" - }, - "delivery": { - "title": "Статус доставки", - "subtitle": "После выполнения задачи результат будет отправлен обратно через поддерживаемые платформы", - "support": "Проактивная доставка", - "available": "Доступна", - "unavailable": "Недоступна", - "enabledPlatforms": "Включенные платформы" - }, - "quickCreate": { - "title": "Быстрое создание", - "runMode": "Режим задачи", - "target": "Целевой контекст" - }, - "platforms": { - "title": "Поддерживаемые платформы" - } - }, - "table": { - "title": "Список задач", - "subtitle": "Отслеживайте cron, целевую сессию, историю запусков и состояние", - "empty": "Задач пока нет.", - "headers": { - "name": "Имя", - "type": "Тип", - "cron": "Cron", - "session": "ID сессии", - "nextRun": "Следующий запуск", - "lastRun": "Последний запуск", - "note": "Описание", - "actions": "Действия" - }, - "type": { - "once": "Разовая", - "recurring": "Повторяющаяся", - "activeAgent": "Активный агент", - "workflow": "Рабочий процесс", - "unknown": "{type}" - }, - "timezoneLocal": "Местное время", - "notAvailable": "—" - }, - "form": { - "title": "Создать задачу", - "editTitle": "Редактировать задачу", - "chatHint": "Вы можете ставить задачи прямо в чате, AstrBot создаст их автоматически без заполнения этой формы.", - "runOnce": "Разовая задача", - "name": "Имя задачи", - "note": "Описание", - "cron": "Cron-выражения", - "cronPlaceholder": "0 9 * * *", - "runAt": "Время запуска", - "session": "Целевая сессия (platform_id:message_type:session_id)", - "timezone": "Часовой пояс (опционально, напр. Europe/Moscow)", - "enabled": "Включено" - }, - "messages": { - "loadFailed": "Ошибка загрузки задач", - "updateSuccess": "Задача обновлена", - "updateFailed": "Ошибка обновления", - "deleteSuccess": "Удалено", - "deleteFailed": "Ошибка удаления", - "sessionRequired": "Укажите сессию", - "noteRequired": "Заполните описание", - "cronRequired": "Укажите Cron-выражение", - "runAtRequired": "Выберите время запуска", - "createSuccess": "Задача создана", - "createFailed": "Ошибка создания" + "header": { + "eyebrow": "Automation", + "live": "Живая синхронизация" + }, + "page": { + "title": "Запланированные задачи", + "beta": "Экспериментальные функции", + "subtitle": "AstrBot проснется в заданное время, выполнит задачу и отправит результат в целевую беседу.", + "proactive": { + "link": "Поддерживаемые платформы", + "supported": "Отправка результатов поддерживается только на указанных ниже настроенных платформах", + "unsupported": "Нет платформ, поддерживающих проактивные сообщения. Включите их в настройках платформ." } + }, + "actions": { + "create": "Новая задача", + "edit": "Изменить", + "refresh": "Обновить", + "delete": "Удалить", + "cancel": "Отмена", + "close": "Закрыть", + "more": "Другие действия", + "runNow": "Запустить сейчас", + "save": "Сохранить", + "submit": "Создать" + }, + "platformDialog": { + "title": "Поддерживаемые платформы", + "description": "Только следующие платформы поддерживают проактивную отправку сообщений. AstrBot сможет отправить результат будущей задачи только в целевые беседы на этих платформах." + }, + "card": { + "onceAt": "Один раз · {time}", + "runAt": "Время запуска: {time}", + "nextRun": "Следующий запуск: {time}", + "dailyAt": "Каждый день в {time}", + "weeklyAt": "Каждый {day} в {time}", + "monthlyAt": "Каждый месяц, день {day}, {time}", + "everyMinutes": "Каждые {count} мин.", + "everyHours": "Каждые {count} ч.", + "everyDays": "Каждые {count} дн.", + "customCron": "Вручную · {cron}", + "noDeliveryTarget": "Цель доставки не задана" + }, + "filters": { + "search": "Поиск по названию и содержанию", + "umo": "Фильтр по цели доставки", + "noUmos": "Нет UMO", + "noDeliveryTarget": "Цель доставки не задана", + "noMatches": "Нет подходящих будущих задач." + }, + "overview": { + "totalTasks": "Всего задач", + "totalTasksNote": "Все зарегистрированные будущие задачи", + "enabledTasks": "Активные задачи", + "enabledTasksNote": "Задачи, которые будут автоматически выполнены", + "oneOffTasks": "Разовые задачи", + "recurringTasksNote": "Повторяющихся задач: {count}", + "proactivePlatforms": "Проактивные платформы", + "proactivePlatformsNote": "Платформы, способные отправлять результат сами" + }, + "section": { + "registered": { + "title": "Список задач", + "subtitle": "Просматривайте зарегистрированные задачи, время запуска и состояние" + }, + "delivery": { + "title": "Статус доставки", + "subtitle": "После выполнения задачи результат будет отправлен обратно через поддерживаемые платформы", + "support": "Проактивная доставка", + "available": "Доступна", + "unavailable": "Недоступна", + "enabledPlatforms": "Включенные платформы" + }, + "quickCreate": { + "title": "Быстрое создание", + "runMode": "Режим задачи", + "target": "Целевой контекст" + }, + "platforms": { + "title": "Поддерживаемые платформы" + } + }, + "table": { + "title": "Список задач", + "subtitle": "Отслеживайте cron, целевую сессию, историю запусков и состояние", + "empty": "Задач пока нет.", + "headers": { + "name": "Имя", + "type": "Тип", + "cron": "Cron", + "session": "ID сессии", + "nextRun": "Следующий запуск", + "lastRun": "Последний запуск", + "note": "Описание", + "actions": "Действия" + }, + "type": { + "once": "Разовая", + "recurring": "Повторяющаяся", + "activeAgent": "Активный агент", + "workflow": "Рабочий процесс", + "unknown": "{type}" + }, + "timezoneLocal": "Местное время", + "notAvailable": "—" + }, + "form": { + "title": "Создать задачу", + "editTitle": "Редактировать задачу", + "chatHint": "Вы можете ставить задачи прямо в чате, AstrBot создаст их автоматически без заполнения этой формы.", + "runOnce": "Разовая задача", + "name": "Имя задачи *", + "note": "Требования задачи *", + "scheduleMode": "Время выполнения *", + "scheduleModes": { + "once": "Один раз", + "interval": "Интервал", + "daily": "Каждый день", + "weekly": "Каждую неделю", + "monthly": "Каждый месяц", + "cron": "Cron вручную" + }, + "intervalEvery": "Каждые *", + "intervalUnit": "Единица *", + "intervalUnits": { + "minutes": "Минуты", + "hours": "Часы", + "days": "Дни" + }, + "dailyTime": "Время *", + "weeklyDay": "День недели *", + "weeklyTime": "Время *", + "monthlyDay": "День *", + "monthlyTime": "Время *", + "weekdays": { + "sunday": "Воскресенье", + "monday": "Понедельник", + "tuesday": "Вторник", + "wednesday": "Среда", + "thursday": "Четверг", + "friday": "Пятница", + "saturday": "Суббота" + }, + "cron": "Cron-выражения *", + "cronPlaceholder": "0 9 * * *", + "runAt": "Время запуска *", + "session": "Доставить в", + "noUmos": "Нет доступных сессий", + "timezone": "Часовой пояс (опционально, напр. Europe/Moscow)", + "enabled": "Включено" + }, + "messages": { + "loadFailed": "Ошибка загрузки задач", + "updateSuccess": "Задача обновлена", + "updateFailed": "Ошибка обновления", + "deleteSuccess": "Удалено", + "deleteFailed": "Ошибка удаления", + "nameRequired": "Укажите имя задачи", + "sessionRequired": "Укажите цель доставки", + "noteRequired": "Заполните требования задачи", + "cronRequired": "Укажите Cron-выражение", + "runAtRequired": "Выберите время запуска", + "intervalRequired": "Укажите корректный интервал", + "dailyTimeRequired": "Выберите ежедневное время запуска", + "weeklyTimeRequired": "Выберите день недели и время запуска", + "monthlyTimeRequired": "Выберите день месяца и время запуска", + "createSuccess": "Задача создана", + "createFailed": "Ошибка создания", + "runStarted": "Запущено", + "runFailed": "Ошибка запуска" + } } diff --git a/dashboard/src/i18n/locales/zh-CN/features/cron.json b/dashboard/src/i18n/locales/zh-CN/features/cron.json index 2345efe98..750af66bb 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/cron.json +++ b/dashboard/src/i18n/locales/zh-CN/features/cron.json @@ -4,10 +4,11 @@ "live": "实时同步" }, "page": { - "title": "未来任务管理", + "title": "未来任务", "beta": "实验性", - "subtitle": "AstrBot 可以被自动唤醒然后执行任务,并将结果告知任务布置方。需要先在配置文件中启用“主动型能力”。", + "subtitle": "AstrBot 会在设定时间自动唤醒,完成任务后把结果投递回目标会话。", "proactive": { + "link": "支持的消息平台", "supported": "主动发送结果仅支持以下您已配置的平台", "unsupported": "暂无支持主动消息的平台,请在平台设置中开启。" } @@ -18,9 +19,36 @@ "refresh": "刷新", "delete": "删除", "cancel": "取消", + "close": "关闭", + "more": "更多操作", + "runNow": "立即执行", "save": "保存", "submit": "创建" }, + "platformDialog": { + "title": "支持的消息平台", + "description": "只有以下平台支持主动推送消息。未来任务完成后,AstrBot 才能把结果投递回这些平台的目标会话。" + }, + "card": { + "onceAt": "一次性 · {time}", + "runAt": "执行时间:{time}", + "nextRun": "下次执行:{time}", + "dailyAt": "每天 {time}", + "weeklyAt": "每周{day} {time}", + "monthlyAt": "每月 {day} 日 {time}", + "everyMinutes": "每隔 {count} 分钟", + "everyHours": "每隔 {count} 小时", + "everyDays": "每隔 {count} 天", + "customCron": "自定义 · {cron}", + "noDeliveryTarget": "未设置投递地" + }, + "filters": { + "search": "搜索任务名称和内容", + "umo": "按投递地筛选", + "noUmos": "暂无 UMO", + "noDeliveryTarget": "未设置投递地", + "noMatches": "没有匹配的未来任务。" + }, "overview": { "totalTasks": "任务总数", "totalTasksNote": "当前已注册的未来任务", @@ -82,12 +110,43 @@ "editTitle": "编辑任务", "chatHint": "你可以直接通过聊天的方式来让 AstrBot 创建未来任务,而不必在此添加。", "runOnce": "一次性任务", - "name": "任务名称", - "note": "任务说明", - "cron": "Cron 表达式", + "name": "任务名称 *", + "note": "任务需求 *", + "scheduleMode": "执行时间 *", + "scheduleModes": { + "once": "一次性", + "interval": "间隔", + "daily": "每天", + "weekly": "每周", + "monthly": "每个月", + "cron": "自定义" + }, + "intervalEvery": "每隔 *", + "intervalUnit": "单位 *", + "intervalUnits": { + "minutes": "分钟", + "hours": "小时", + "days": "天" + }, + "dailyTime": "时间 *", + "weeklyDay": "星期 *", + "weeklyTime": "时间 *", + "monthlyDay": "日期 *", + "monthlyTime": "时间 *", + "weekdays": { + "sunday": "周日", + "monday": "周一", + "tuesday": "周二", + "wednesday": "周三", + "thursday": "周四", + "friday": "周五", + "saturday": "周六" + }, + "cron": "Cron 表达式 *", "cronPlaceholder": "0 9 * * *", - "runAt": "执行时间", - "session": "目标 session (platform_id:message_type:session_id)", + "runAt": "执行时间 *", + "session": "投递到(可选)", + "noUmos": "暂无可用会话", "timezone": "时区(可选,如 Asia/Shanghai)", "enabled": "启用" }, @@ -97,11 +156,18 @@ "updateFailed": "更新失败", "deleteSuccess": "已删除", "deleteFailed": "删除失败", - "sessionRequired": "请填写 session", - "noteRequired": "请填写说明", + "nameRequired": "请填写任务名称", + "sessionRequired": "请选择投递目标", + "noteRequired": "请填写任务需求", "cronRequired": "请填写 Cron 表达式", "runAtRequired": "请选择执行时间", + "intervalRequired": "请填写有效的间隔时间", + "dailyTimeRequired": "请选择每天执行的时间", + "weeklyTimeRequired": "请选择每周执行的星期和时间", + "monthlyTimeRequired": "请选择每月执行的日期和时间", "createSuccess": "创建成功", - "createFailed": "创建失败" + "createFailed": "创建失败", + "runStarted": "已开始执行", + "runFailed": "执行失败" } } diff --git a/dashboard/src/theme/LightTheme.ts b/dashboard/src/theme/LightTheme.ts index b88f05c28..a91e212ae 100644 --- a/dashboard/src/theme/LightTheme.ts +++ b/dashboard/src/theme/LightTheme.ts @@ -27,7 +27,7 @@ const PurpleTheme: ThemeTypes = { borderLight: '#d0d0d0', border: '#d0d0d0', inputBorder: '#787878', - containerBg: '#f9fafcf4', + containerBg: '#fffffff4', surface: '#fff', 'on-surface-variant': '#fff', facebook: '#4267b2', diff --git a/dashboard/src/views/CronJobPage.vue b/dashboard/src/views/CronJobPage.vue index b59d3b0be..c1d6e2737 100644 --- a/dashboard/src/views/CronJobPage.vue +++ b/dashboard/src/views/CronJobPage.vue @@ -1,348 +1,744 @@ + + + + + + {{ tm("platformDialog.title") }} + + +

+ {{ tm("platformDialog.description") }} +

+
+
+
+ {{ platform.display_name || platform.name }} +
+
{{ platform.id }}
+
+
+
+ {{ tm("page.proactive.unsupported") }} +
+
+ + + {{ tm("actions.close") }} + + +
+
+ + + {{ snackbar.message }} + + + + + {{ + dialogTitle + }} + +
+ + + +
+ + + + +
+ + +
+ + + +
+ + +
+ +
+ + +
+ + +
+ + +
+
+ + {{ + tm("actions.cancel") + }} + + {{ dialogSubmitText }} + + +
+
+