From ca17df419806441f087d57d5549a982b073bdf7b Mon Sep 17 00:00:00 2001 From: roo Date: Fri, 5 Dec 2025 20:28:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AF=B9=E4=BB=BB=E5=8A=A1=E9=A1=B9?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BD=AE=E9=A1=B6=20=E7=BD=AE=E5=BA=95?= =?UTF-8?q?=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/config/translation/i18n_cn.dart | 6 + lib/config/translation/i18n_content.dart | 6 + lib/config/translation/i18n_us.dart | 6 + lib/views/overview/overview_view.dart | 1 + lib/views/overview/taskitem_view.dart | 163 +++++++++++++++++++++-- 5 files changed, 172 insertions(+), 10 deletions(-) diff --git a/lib/config/translation/i18n_cn.dart b/lib/config/translation/i18n_cn.dart index 306085c..185036f 100644 --- a/lib/config/translation/i18n_cn.dart +++ b/lib/config/translation/i18n_cn.dart @@ -28,6 +28,12 @@ final Map _cn_ui = { I18n.pending: '队列中', I18n.waiting: '等待中', I18n.task_setting: '设置', + I18n.task_pin_top: '置顶', + I18n.task_pin_bottom: '置底', + I18n.operation_failed: '操作失败', + I18n.task_next_run_updated_to: '的下一次运行时间已更新为', + I18n.update_task_next_run_failed: '更新任务的下一次运行时间失败', + I18n.update_task_run_time_error: '更新任务运行时间时出错', I18n.log: '日志', I18n.clear_log: '清空日志', I18n.login: '登录', diff --git a/lib/config/translation/i18n_content.dart b/lib/config/translation/i18n_content.dart index 1560fd4..4db5a20 100644 --- a/lib/config/translation/i18n_content.dart +++ b/lib/config/translation/i18n_content.dart @@ -28,6 +28,12 @@ class I18n { static const String pending = 'Pendings'; static const String waiting = 'Waitings'; static const String task_setting = 'Task Setting'; + static const String task_pin_top = 'Pin Top'; + static const String task_pin_bottom = 'Pin Bottom'; + static const String operation_failed = 'Operation Failed'; + static const String task_next_run_updated_to = 'Task next run time updated to'; + static const String update_task_next_run_failed = 'Failed to update task next run time'; + static const String update_task_run_time_error = 'Error updating task run time'; static const String log = 'Log'; static const String clear_log = 'Clear Log'; static const String login = 'Login'; diff --git a/lib/config/translation/i18n_us.dart b/lib/config/translation/i18n_us.dart index d629f88..dbb8a0e 100644 --- a/lib/config/translation/i18n_us.dart +++ b/lib/config/translation/i18n_us.dart @@ -18,6 +18,12 @@ final Map _us_ui = { I18n.en_us: 'English', I18n.project_statement: 'Open Source Software', I18n.task_setting: 'Settings', + I18n.task_pin_top: 'Pin Top', + I18n.task_pin_bottom: 'Pin Bottom', + I18n.operation_failed: 'Operation Failed', + I18n.task_next_run_updated_to: 'next run time updated to', + I18n.update_task_next_run_failed: 'Failed to update task next run time', + I18n.update_task_run_time_error: 'Error updating task run time', I18n.notify_test_help: 'Please refer to the documentation [Message Push] to fill in the relevant configuration', I18n.root_path_server_help: diff --git a/lib/views/overview/overview_view.dart b/lib/views/overview/overview_view.dart index a555050..a9d3e0b 100644 --- a/lib/views/overview/overview_view.dart +++ b/lib/views/overview/overview_view.dart @@ -13,6 +13,7 @@ import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:oasx/views/nav/view_nav.dart'; import 'package:oasx/config/translation/i18n_content.dart'; +import 'package:oasx/api/api_client.dart'; part '../../controller/overview/overview_controller.dart'; part '../../controller/overview/taskitem_model.dart'; diff --git a/lib/views/overview/taskitem_view.dart b/lib/views/overview/taskitem_view.dart index 7c0a6c5..fcb099e 100644 --- a/lib/views/overview/taskitem_view.dart +++ b/lib/views/overview/taskitem_view.dart @@ -9,11 +9,11 @@ class TaskItemView extends StatelessWidget { return model.isAllEmpty() ? const SizedBox(height: 30) : [ - _name(context), - _action(context), - ] - .toRow(mainAxisAlignment: MainAxisAlignment.spaceBetween) - .padding(bottom: 10); + _name(context), + _actionButtons(context), // 改为渲染多个按钮的容器 + ] + .toRow(mainAxisAlignment: MainAxisAlignment.spaceBetween) + .padding(bottom: 10); } Widget _name(BuildContext context) { @@ -23,8 +23,148 @@ class TaskItemView extends StatelessWidget { ].toColumn(crossAxisAlignment: CrossAxisAlignment.start); } - Widget _action(BuildContext context) { - return OutlinedButton( + // 新增:封装两个按钮(立即运行 + 任务设置) + Widget _actionButtons(BuildContext context) { + return [ + // 1. 立即运行按钮 + Tooltip( + message: I18n.task_pin_top.tr, + child: OutlinedButton( + style: OutlinedButton.styleFrom( + padding: const EdgeInsets.all(0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + // 可自定义按钮颜色(如需匹配主题,用 Theme.of(context).primaryColor) + ), + // 立即运行按钮点击事件:将此任务的下一次运行时间设置为当前时间 + onPressed: () async { + try { + // 获取当前脚本名称 + final scriptName = Get.find().selectedScript.value; + print("scriptName: $scriptName"); + // 格式化当前时间为 "YYYY-MM-DD HH:mm:ss" 格式 + final now = DateTime.now(); + final year = now.year.toString(); + final month = now.month.toString().padLeft(2, '0'); + final day = now.day.toString().padLeft(2, '0'); + final hour = now.hour.toString().padLeft(2, '0'); + final minute = now.minute.toString().padLeft(2, '0'); + final second = now.second.toString().padLeft(2, '0'); + final currentTime = '$year-$month-$day $hour:$minute:$second'; + + // 更新任务的 next_run 时间为当前时间 + final success = await ApiClient().putScriptArg( + scriptName, + model.taskName, + 'scheduler', + 'next_run', + 'string', + currentTime, + ); + + if (success) { + print("${model.taskName} 的下一次运行时间已更新为: $currentTime"); + // 显示成功通知 + Get.snackbar(I18n.task_pin_top.tr, '${model.taskName} ${I18n.task_next_run_updated_to.tr}: $currentTime', + duration: const Duration(seconds: 1)); + // 刷新任务状态 + Get.find().wsService.send(scriptName, 'get_state'); + } else { + print("更新 ${model.taskName} 的下一次运行时间失败"); + // 显示失败通知 + Get.snackbar(I18n.operation_failed.tr, I18n.update_task_next_run_failed.tr, + duration: const Duration(seconds: 1)); + } + } catch (e) { + print("更新任务运行时间时出错: $e"); + // 显示错误通知 + Get.snackbar(I18n.operation_failed.tr, '${I18n.update_task_run_time_error.tr}: $e', + duration: const Duration(seconds: 2)); + } + }, + child: Text( + '▲', // 'I18n.run_now.tr', // 新增国际化key:"立即运行"(需在I18n文件中添加) + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Colors.black, + ), + ), + ), + ).constrained(maxWidth: 30, maxHeight: 30), + + const SizedBox(width: 5), // 按钮之间的间距 + + // 2. 延迟运行按钮:将下次运行时间设置为1年后的今天 + Tooltip( + message: I18n.task_pin_bottom.tr, + child: OutlinedButton( + style: OutlinedButton.styleFrom( + padding: const EdgeInsets.all(0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + ), + onPressed: () async { + try { + // 获取当前脚本名称 + final scriptName = Get.find().selectedScript.value; + + // 计算1年后的今天 + final now = DateTime.now(); + final oneYearLater = DateTime(now.year + 1, now.month, now.day, now.hour, now.minute, now.second); + + // 格式化为 "YYYY-MM-DD HH:mm:ss" 格式 + final year = oneYearLater.year.toString(); + final month = oneYearLater.month.toString().padLeft(2, '0'); + final day = oneYearLater.day.toString().padLeft(2, '0'); + final hour = oneYearLater.hour.toString().padLeft(2, '0'); + final minute = oneYearLater.minute.toString().padLeft(2, '0'); + final second = oneYearLater.second.toString().padLeft(2, '0'); + final oneYearLaterTime = '$year-$month-$day $hour:$minute:$second'; + + // 更新任务的 next_run 时间为1年后的今天 + final success = await ApiClient().putScriptArg( + scriptName, + model.taskName, + 'scheduler', + 'next_run', + 'string', + oneYearLaterTime, + ); + + if (success) { + print("${model.taskName} 的下一次运行时间已更新为: $oneYearLaterTime"); + // 显示成功通知 + Get.snackbar(I18n.task_pin_bottom.tr, '${model.taskName} ${I18n.task_next_run_updated_to.tr}: $oneYearLaterTime', + duration: const Duration(seconds: 1)); + // 刷新任务状态 + Get.find().wsService.send(scriptName, 'get_state'); + } else { + print("更新 ${model.taskName} 的下一次运行时间失败"); + // 显示失败通知 + Get.snackbar(I18n.operation_failed.tr, I18n.update_task_next_run_failed.tr, + duration: const Duration(seconds: 1)); + } + } catch (e) { + print("更新任务运行时间时出错: $e"); + // 显示错误通知 + Get.snackbar(I18n.operation_failed.tr, '${I18n.update_task_run_time_error.tr}: $e', + duration: const Duration(seconds: 2)); + } + }, + child: Text( + '▼', + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Colors.black, + ), + ), + ), + ).constrained(maxWidth: 30, maxHeight: 30), + + const SizedBox(width: 5), // 按钮之间的间距 + + // 3. 原有的任务设置按钮(保持不变) + OutlinedButton( style: OutlinedButton.styleFrom( padding: const EdgeInsets.all(0), shape: RoundedRectangleBorder( @@ -32,8 +172,11 @@ class TaskItemView extends StatelessWidget { ), ), onPressed: () => Get.find().switchContent(model.taskName), - child: Text(I18n.task_setting.tr, - style: Theme.of(context).textTheme.bodySmall)) - .constrained(maxWidth: 100, maxHeight: 30); + child: Text( + I18n.task_setting.tr, + style: Theme.of(context).textTheme.bodySmall, + ), + ).constrained(maxWidth: 100, maxHeight: 30), + ].toRow(mainAxisAlignment: MainAxisAlignment.end); // 按钮右对齐 } }