From 414f0f28ab77777d64770679461ffaabae7d27f1 Mon Sep 17 00:00:00 2001
From: Lazy <2211717435@qq.com>
Date: Sun, 12 Nov 2023 21:23:11 +0800
Subject: [PATCH 01/11] Feat: get schedules
---
frontend/src/config/index.ts | 4 +-
frontend/src/config/router.ts | 18 ++
frontend/src/services/apis/instance.ts | 16 +-
frontend/src/types/index.ts | 10 +
frontend/src/widgets/instance/ManagerBtns.vue | 14 +-
frontend/src/widgets/instance/schedule.vue | 223 ++++++++++++++++++
panel/src/app/service/frontend_layout.ts | 22 ++
7 files changed, 302 insertions(+), 5 deletions(-)
create mode 100644 frontend/src/widgets/instance/schedule.vue
diff --git a/frontend/src/config/index.ts b/frontend/src/config/index.ts
index b990ceec..56e47161 100644
--- a/frontend/src/config/index.ts
+++ b/frontend/src/config/index.ts
@@ -32,6 +32,7 @@ import UserStatusBlock from "@/widgets/UserStatusBlock.vue";
import UserInstanceList from "@/widgets/UserInstanceList.vue";
import ImageManager from "@/widgets/imageManager/index.vue";
import NewImage from "@/widgets/imageManager/NewImage.vue";
+import Schedule from "@/widgets/instance/schedule.vue";
import { NEW_CARD_TYPE } from "../types/index";
import { ROLE } from "./router";
@@ -67,7 +68,8 @@ export const LAYOUT_CARD_TYPES: { [key: string]: any } = {
UserStatusBlock,
UserInstanceList,
ImageManager,
- NewImage
+ NewImage,
+ Schedule
};
export interface NewCardItem extends LayoutCard {
diff --git a/frontend/src/config/router.ts b/frontend/src/config/router.ts
index bd908fe4..b1005067 100644
--- a/frontend/src/config/router.ts
+++ b/frontend/src/config/router.ts
@@ -103,6 +103,24 @@ let originRouterConfig: RouterConfig[] = [
]
}
]
+ },
+ {
+ path: "/instances/schedule",
+ name: t("计划任务"),
+ component: LayoutContainer,
+ meta: {
+ permission: ROLE.USER
+ }
+ // children: [
+ // {
+ // path: "/instances/schedule/new",
+ // name: t("新增计划任务"),
+ // component: LayoutContainer,
+ // meta: {
+ // permission: ROLE.USER
+ // }
+ // }
+ // ]
}
]
},
diff --git a/frontend/src/services/apis/instance.ts b/frontend/src/services/apis/instance.ts
index 8282aa52..92fb1236 100644
--- a/frontend/src/services/apis/instance.ts
+++ b/frontend/src/services/apis/instance.ts
@@ -1,5 +1,5 @@
import { useDefineApi } from "@/stores/useDefineApi";
-import type { InstanceDetail, NewInstanceForm, QuickStartTemplate } from "@/types";
+import type { InstanceDetail, NewInstanceForm, QuickStartTemplate, Schedule } from "@/types";
import type { IGlobalInstanceConfig } from "../../../../common/global";
import type { InstanceMoreDetail } from "@/hooks/useInstance";
@@ -343,3 +343,17 @@ export const batchDelete = useDefineApi<
method: "DELETE",
url: "/api/instance"
});
+
+// 获取计划任务
+export const scheduleList = useDefineApi<
+ {
+ params: {
+ remote_uuid: string;
+ uuid: string;
+ };
+ },
+ Schedule[]
+>({
+ method: "GET",
+ url: "/api/protected_schedule"
+});
diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts
index 2746ab48..9526c755 100644
--- a/frontend/src/types/index.ts
+++ b/frontend/src/types/index.ts
@@ -218,3 +218,13 @@ export interface MountComponent {
destroyComponent: Function;
emitResult: Function;
}
+
+export interface Schedule {
+ instanceUuid: string;
+ name: string;
+ count: number;
+ time: string;
+ action: string;
+ payload: string;
+ type: number;
+}
diff --git a/frontend/src/widgets/instance/ManagerBtns.vue b/frontend/src/widgets/instance/ManagerBtns.vue
index 7cb5a24f..3b86abd6 100644
--- a/frontend/src/widgets/instance/ManagerBtns.vue
+++ b/frontend/src/widgets/instance/ManagerBtns.vue
@@ -3,7 +3,7 @@ import { ref, computed } from "vue";
import type { LayoutCard } from "@/types";
import { arrayFilter } from "../../tools/array";
import { t } from "@/lang/i18n";
-import { ArrowRightOutlined, CloudServerOutlined } from "@ant-design/icons-vue";
+import { ArrowRightOutlined, CloudServerOutlined, FieldTimeOutlined } from "@ant-design/icons-vue";
import InnerCard from "@/components/InnerCard.vue";
import { LayoutCardHeight } from "../../config/originLayoutConfig";
import { useAppRouters } from "@/hooks/useAppRouters";
@@ -80,9 +80,17 @@ const btns = computed(() =>
},
{
title: t("TXT_CODE_b7d026f8"),
- icon: CloudServerOutlined,
+ icon: FieldTimeOutlined,
condition: () => !isGlobalTerminal.value,
- click: () => {}
+ click: () => {
+ toPage({
+ path: "/instances/schedule",
+ query: {
+ instanceId,
+ daemonId
+ }
+ });
+ }
},
// 暂时删除
// {
diff --git a/frontend/src/widgets/instance/schedule.vue b/frontend/src/widgets/instance/schedule.vue
new file mode 100644
index 00000000..5b88845d
--- /dev/null
+++ b/frontend/src/widgets/instance/schedule.vue
@@ -0,0 +1,223 @@
+
+
+
+
+
+
+
+
+
+
+ {{ card.title }}
+
+
+
+
+ {{ t("返回控制台") }}
+
+
+ {{ t("刷新") }}
+
+
+ {{ t("新增计划任务") }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t("删除") }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/panel/src/app/service/frontend_layout.ts b/panel/src/app/service/frontend_layout.ts
index 68a87486..4f4f78e9 100644
--- a/panel/src/app/service/frontend_layout.ts
+++ b/panel/src/app/service/frontend_layout.ts
@@ -254,6 +254,28 @@ function getDefaultFrontendLayoutConfig(): IPageLayoutConfig[] {
}
]
},
+ {
+ page: "/instances/schedule",
+ items: [
+ {
+ id: getRandomId(),
+ meta: {},
+ type: "Schedule",
+ title: t("计划任务"),
+ width: 12,
+ height: LayoutCardHeight.AUTO,
+ disableDelete: true
+ },
+ {
+ id: getRandomId(),
+ meta: {},
+ type: "EmptyCard",
+ title: "",
+ width: 12,
+ height: LayoutCardHeight.MINI
+ }
+ ]
+ },
{
page: "/users",
items: [
From 649d0147d054f3003b22e88907ba458f5c777cbb Mon Sep 17 00:00:00 2001
From: Lazy <2211717435@qq.com>
Date: Sun, 12 Nov 2023 21:29:26 +0800
Subject: [PATCH 02/11] Fix: Capitalize
---
frontend/src/config/index.ts | 2 +-
frontend/src/widgets/instance/{schedule.vue => Schedule.vue} | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
rename frontend/src/widgets/instance/{schedule.vue => Schedule.vue} (98%)
diff --git a/frontend/src/config/index.ts b/frontend/src/config/index.ts
index 56e47161..a2ea3c9f 100644
--- a/frontend/src/config/index.ts
+++ b/frontend/src/config/index.ts
@@ -32,7 +32,7 @@ import UserStatusBlock from "@/widgets/UserStatusBlock.vue";
import UserInstanceList from "@/widgets/UserInstanceList.vue";
import ImageManager from "@/widgets/imageManager/index.vue";
import NewImage from "@/widgets/imageManager/NewImage.vue";
-import Schedule from "@/widgets/instance/schedule.vue";
+import Schedule from "@/widgets/instance/Schedule.vue";
import { NEW_CARD_TYPE } from "../types/index";
import { ROLE } from "./router";
diff --git a/frontend/src/widgets/instance/schedule.vue b/frontend/src/widgets/instance/Schedule.vue
similarity index 98%
rename from frontend/src/widgets/instance/schedule.vue
rename to frontend/src/widgets/instance/Schedule.vue
index 5b88845d..282e051c 100644
--- a/frontend/src/widgets/instance/schedule.vue
+++ b/frontend/src/widgets/instance/Schedule.vue
@@ -51,8 +51,8 @@ const type = {
3: t("指定时间性任务")
};
-const rendTime = (text: string, e: Schedule) => {
- switch (e.type) {
+const rendTime = (text: string, schedule: Schedule) => {
+ switch (schedule.type) {
case 1: {
const time = Number(text);
let s = time;
From f42ba4a819849617e4812cabeb75fe496a47c7b4 Mon Sep 17 00:00:00 2001
From: Lazy <2211717435@qq.com>
Date: Sun, 12 Nov 2023 21:51:46 +0800
Subject: [PATCH 03/11] Feat: del schedule
---
frontend/src/services/apis/instance.ts | 15 ++++++++++
frontend/src/widgets/instance/Schedule.vue | 35 ++++++++++++++++++----
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/frontend/src/services/apis/instance.ts b/frontend/src/services/apis/instance.ts
index 92fb1236..089bbf21 100644
--- a/frontend/src/services/apis/instance.ts
+++ b/frontend/src/services/apis/instance.ts
@@ -357,3 +357,18 @@ export const scheduleList = useDefineApi<
method: "GET",
url: "/api/protected_schedule"
});
+
+// 删除计划任务
+export const scheduleDelete = useDefineApi<
+ {
+ params: {
+ remote_uuid: string;
+ uuid: string;
+ task_name: string;
+ };
+ },
+ boolean
+>({
+ method: "DELETE",
+ url: "/api/protected_schedule"
+});
diff --git a/frontend/src/widgets/instance/Schedule.vue b/frontend/src/widgets/instance/Schedule.vue
index 282e051c..effeb9d7 100644
--- a/frontend/src/widgets/instance/Schedule.vue
+++ b/frontend/src/widgets/instance/Schedule.vue
@@ -9,7 +9,7 @@ import BetweenMenus from "@/components/BetweenMenus.vue";
import { useLayoutCardTools } from "@/hooks/useCardTools";
import { useScreen } from "@/hooks/useScreen";
import { useAppRouters } from "@/hooks/useAppRouters";
-import { scheduleList } from "@/services/apis/instance";
+import { scheduleList, scheduleDelete } from "@/services/apis/instance";
import type { LayoutCard, Schedule } from "@/types/index";
const props = defineProps<{
@@ -37,6 +37,26 @@ const getScheduleList = async () => {
}
};
+const deleteSchedule = async (name: string) => {
+ const { execute, state } = scheduleDelete();
+ try {
+ await execute({
+ params: {
+ remote_uuid: daemonId ?? "",
+ uuid: instanceId ?? "",
+ task_name: name
+ }
+ });
+ if (state.value) {
+ message.success(t("删除成功"));
+ refresh();
+ }
+ } catch (err: any) {
+ console.error(err);
+ message.error(err.message);
+ }
+};
+
const action = {
command: t("发送命令"),
stop: t("停止实例"),
@@ -191,10 +211,15 @@ onMounted(async () => {
-
- {{ t("删除") }}
-
-
+
+
+ {{ t("删除") }}
+
+
+
From d250c298bb27b7bbeb1ef187a1bd9b7512298263 Mon Sep 17 00:00:00 2001
From: Lazy <2211717435@qq.com>
Date: Mon, 13 Nov 2023 14:01:48 +0800
Subject: [PATCH 04/11] Feat: create schedule
---
frontend/components.d.ts | 1 +
frontend/src/services/apis/instance.ts | 23 +-
frontend/src/types/const.ts | 14 +
frontend/src/types/index.ts | 8 +
frontend/src/widgets/instance/Schedule.vue | 46 ++--
.../widgets/instance/dialogs/NewSchedule.vue | 252 ++++++++++++++++++
6 files changed, 323 insertions(+), 21 deletions(-)
create mode 100644 frontend/src/widgets/instance/dialogs/NewSchedule.vue
diff --git a/frontend/components.d.ts b/frontend/components.d.ts
index 77c21ffc..66ed7237 100644
--- a/frontend/components.d.ts
+++ b/frontend/components.d.ts
@@ -51,6 +51,7 @@ declare module 'vue' {
ATabs: typeof import('ant-design-vue/es')['Tabs']
ATag: typeof import('ant-design-vue/es')['Tag']
ATextarea: typeof import('ant-design-vue/es')['Textarea']
+ ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATypography: typeof import('ant-design-vue/es')['Typography']
ATypographyParagraph: typeof import('ant-design-vue/es')['TypographyParagraph']
diff --git a/frontend/src/services/apis/instance.ts b/frontend/src/services/apis/instance.ts
index 089bbf21..57734a9f 100644
--- a/frontend/src/services/apis/instance.ts
+++ b/frontend/src/services/apis/instance.ts
@@ -1,5 +1,11 @@
import { useDefineApi } from "@/stores/useDefineApi";
-import type { InstanceDetail, NewInstanceForm, QuickStartTemplate, Schedule } from "@/types";
+import type {
+ InstanceDetail,
+ NewInstanceForm,
+ QuickStartTemplate,
+ Schedule,
+ NewScheduleTask
+} from "@/types";
import type { IGlobalInstanceConfig } from "../../../../common/global";
import type { InstanceMoreDetail } from "@/hooks/useInstance";
@@ -372,3 +378,18 @@ export const scheduleDelete = useDefineApi<
method: "DELETE",
url: "/api/protected_schedule"
});
+
+// 创建计划任务
+export const scheduleCreate = useDefineApi<
+ {
+ params: {
+ remote_uuid: string;
+ uuid: string;
+ };
+ data: NewScheduleTask;
+ },
+ boolean
+>({
+ url: "/api/protected_schedule",
+ method: "POST"
+});
diff --git a/frontend/src/types/const.ts b/frontend/src/types/const.ts
index 0c83ff5a..e7a770e1 100644
--- a/frontend/src/types/const.ts
+++ b/frontend/src/types/const.ts
@@ -80,3 +80,17 @@ ENV LC_ALL=zh_CN.UTF-8
ENV TZ=Asia/Shanghai
WORKDIR /workspace
`;
+
+export const ScheduleAction = {
+ command: t("发送命令"),
+ stop: t("停止实例"),
+ start: t("开启实例"),
+ restart: t("重启实例"),
+ kill: t("终止实例")
+};
+
+export const ScheduleType = {
+ 1: t("间隔时间性任务"),
+ 2: t("周期时间性任务"),
+ 3: t("指定时间性任务")
+};
diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts
index 9526c755..460d0c66 100644
--- a/frontend/src/types/index.ts
+++ b/frontend/src/types/index.ts
@@ -228,3 +228,11 @@ export interface Schedule {
payload: string;
type: number;
}
+
+export interface NewScheduleTask {
+ name: String;
+ count: String;
+ time: String;
+ action: String;
+ type: String;
+}
diff --git a/frontend/src/widgets/instance/Schedule.vue b/frontend/src/widgets/instance/Schedule.vue
index effeb9d7..7f4211e7 100644
--- a/frontend/src/widgets/instance/Schedule.vue
+++ b/frontend/src/widgets/instance/Schedule.vue
@@ -11,6 +11,8 @@ import { useScreen } from "@/hooks/useScreen";
import { useAppRouters } from "@/hooks/useAppRouters";
import { scheduleList, scheduleDelete } from "@/services/apis/instance";
import type { LayoutCard, Schedule } from "@/types/index";
+import { ScheduleAction, ScheduleType } from "@/types/const";
+import NewSchedule from "@/widgets/instance/dialogs/NewSchedule.vue";
const props = defineProps<{
card: LayoutCard;
@@ -21,6 +23,7 @@ const instanceId = getMetaOrRouteValue("instanceId");
const daemonId = getMetaOrRouteValue("daemonId");
const { toPage } = useAppRouters();
const screen = useScreen();
+const newScheduleDialog = ref>();
const { state, execute, isLoading } = scheduleList();
const getScheduleList = async () => {
@@ -57,20 +60,6 @@ const deleteSchedule = async (name: string) => {
}
};
-const action = {
- command: t("发送命令"),
- stop: t("停止实例"),
- start: t("开启实例"),
- restart: t("重启实例"),
- kill: t("终止实例")
-};
-
-const type = {
- 1: t("间隔时间性任务"),
- 2: t("周期时间性任务"),
- 3: t("指定时间性任务")
-};
-
const rendTime = (text: string, schedule: Schedule) => {
switch (schedule.type) {
case 1: {
@@ -105,7 +94,7 @@ const rendTime = (text: string, schedule: Schedule) => {
const s = timeArr[0];
const dd = timeArr[3];
const mm = timeArr[4];
- return `${mm} ${t("每隔")} ${dd} ${t("每隔")} ${h}:${m}:${s}`;
+ return `${mm} ${t("月")} ${dd} ${t("日")} ${h}:${m}:${s}`;
}
default:
return "Unknown Time";
@@ -142,7 +131,7 @@ const columns = [
key: "action",
minWidth: "180px",
customRender: (e: { text: "command" | "stop" | "start" | "restart" | "kill" }) => {
- return action[e.text];
+ return ScheduleAction[e.text];
}
},
{
@@ -152,7 +141,7 @@ const columns = [
key: "type",
minWidth: "180px",
customRender: (e: { text: 1 | 2 | 3 }) => {
- return type[e.text];
+ return ScheduleType[e.text];
}
},
{
@@ -173,7 +162,17 @@ const columns = [
const refresh = throttle(() => {
getScheduleList();
-}, 600);
+}, 100);
+
+const toConsole = () => {
+ toPage({
+ path: "/instances/terminal",
+ query: {
+ daemonId,
+ instanceId
+ }
+ });
+};
onMounted(async () => {
getScheduleList();
@@ -192,13 +191,13 @@ onMounted(async () => {
-
+
{{ t("返回控制台") }}
{{ t("刷新") }}
-
+
{{ t("新增计划任务") }}
@@ -229,6 +228,13 @@ onMounted(async () => {
+
+