diff --git a/atune/web/package.json b/atune/web/package.json
index ef5a01fdf2ad2b07b2b174610c8216ac2bab3b34..23d6b779b016c41dca06f8e1fb2ee1cbbb6238b2 100644
--- a/atune/web/package.json
+++ b/atune/web/package.json
@@ -11,8 +11,11 @@
"dependencies": {
"axios": "^1.6.0",
"element-plus": "^2.4.1",
+ "esbuild": "^0.19.10",
+ "konva": "^9.3.0",
"pinia": "^2.1.7",
"vue": "^3.3.4",
+ "vue-konva": "^3.0.2",
"vue-router": "^4.2.5"
},
"devDependencies": {
diff --git a/atune/web/src/api/atune.ts b/atune/web/src/api/atune.ts
index fa0cba1bdfe373c8ae9d7559e9429f3bc9a02868..0ea89bfb0517f4c1dc2590253c2b6c4f7b45d1fa 100644
--- a/atune/web/src/api/atune.ts
+++ b/atune/web/src/api/atune.ts
@@ -9,6 +9,24 @@ export function getTaskLists(data: Object) {
});
}
+// 新增任务
+export function addTask(data: object) {
+ return request({
+ url: "/plugin/atune/run",
+ method: "post",
+ data,
+ });
+}
+
+// 删除任务
+export function deleteTask(data: object) {
+ return request({
+ url: "/plugin/atune/delete",
+ method: "delete",
+ data,
+ });
+}
+
// 获取所有的调优列表
export function getAtuneAllName() {
return request({
@@ -38,7 +56,7 @@ export function getTuneLists(data: object) {
// 保存调优模板
export function saveTune(data: object) {
return request({
- url: "/plugin/atune/save",
+ url: "/plugin/atune/save_tune",
method: "post",
data,
});
@@ -47,7 +65,7 @@ export function saveTune(data: object) {
// 删除调优模板
export function deleteTune(data: object) {
return request({
- url: "/plugin/atune/delete",
+ url: "/plugin/atune/delete_tune",
method: "delete",
data,
});
@@ -56,7 +74,7 @@ export function deleteTune(data: object) {
// 高级搜索模板列表分页
export function searchTune(data: object) {
return request({
- url: "/plugin/atune/search",
+ url: "/plugin/atune/search_tune",
method: "get",
params: data,
});
@@ -65,7 +83,7 @@ export function searchTune(data: object) {
// 编辑模板更新
export function updateTune(data: object) {
return request({
- url: "/plugin/atune/update",
+ url: "/plugin/atune/update_tune",
method: "post",
data,
});
diff --git a/atune/web/src/components/atuneList.vue b/atune/web/src/components/atuneList.vue
deleted file mode 100644
index be5dd06d277e89d7cbe25ef792367bc845cc4b4c..0000000000000000000000000000000000000000
--- a/atune/web/src/components/atuneList.vue
+++ /dev/null
@@ -1,155 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- 成功
- 失败
- 执行中
-
-
-
-
-
-
- 详情
-
-
-
-
-
-
-
-
-
-
diff --git a/atune/web/src/components/atuneTemplete.vue b/atune/web/src/components/atuneTemplete.vue
index 602011ec591eac892713600ba1d14bd96fe25bef..f1937d043fab95c4e788374db5dc066bcc0b3514 100644
--- a/atune/web/src/components/atuneTemplete.vue
+++ b/atune/web/src/components/atuneTemplete.vue
@@ -1,164 +1,163 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 保存
- 取消
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 取消
+
+
-
-
diff --git a/atune/web/src/components/flowChart.ts b/atune/web/src/components/flowChart.ts
new file mode 100644
index 0000000000000000000000000000000000000000..88503722d870fa20d0287e3c9073d4ae9939846e
--- /dev/null
+++ b/atune/web/src/components/flowChart.ts
@@ -0,0 +1,46 @@
+import { useCanvasStore } from "@/store/canvas";
+const fromX = useCanvasStore().width || 0;
+console.log("起始位置X:", fromX);
+export const rectStart = {
+ x: fromX / 2,
+ y: 50,
+ width: 100,
+ height: 40,
+ fill: "#fff",
+ stroke: "#fff",
+ shadowBlur: 2,
+ cornerRadius: 10,
+};
+
+export const rectPrepare = {
+ x: 20,
+ y: 50,
+ width: 100,
+ height: 40,
+ fill: "#fff",
+ stroke: "#fff",
+ shadowBlur: 2,
+ cornerRadius: 10,
+};
+
+export const rectTune = {
+ x: 20,
+ y: 50,
+ width: 100,
+ height: 40,
+ fill: "#fff",
+ stroke: "#fff",
+ shadowBlur: 2,
+ cornerRadius: 10,
+};
+
+export const rectRestore = {
+ x: 20,
+ y: 50,
+ width: 100,
+ height: 40,
+ fill: "#fff",
+ stroke: "#fff",
+ shadowBlur: 2,
+ cornerRadius: 10,
+};
diff --git a/atune/web/src/components/flowChart.vue b/atune/web/src/components/flowChart.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6f76c79bed8f5ece954ab2335ed58f1d35420ce8
--- /dev/null
+++ b/atune/web/src/components/flowChart.vue
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/atune/web/src/components/table.vue b/atune/web/src/components/table.vue
index 8d19c5f66626bfcd059c44c66606c3b7e6b97adc..629cd42e1c30d859b3fb4f28aad55422a09842d3 100644
--- a/atune/web/src/components/table.vue
+++ b/atune/web/src/components/table.vue
@@ -24,7 +24,7 @@
>();
+const myTableRef = ref>();
const currentNum = ref(0); //复选框当前页数量
const keyWord = ref("");
const selectedRows = ref([] as any[]);
@@ -97,19 +98,66 @@ const page = reactive({
});
onMounted(async () => {
await getTableData();
- getAllData();
+ // getAllData();
});
// 获取表格数据
const getTableData = () => {
- loading.value = true;
+ // loading.value = true;
+ tableData.value = [
+ {
+ id: 2,
+ task_name: "准备调优环境",
+ command: "ls",
+ task_status: "已完成",
+ create_time: "2023-12-25 11:23:18",
+ update_time: "2023-12-25 11:23:18",
+ results: [
+ {
+ id: 2,
+ task_id: 2,
+ machine_uuid: "13ff60a7-0f7d-49d6-b7fc-b766cc347ba8",
+ machine_ip: "192.168.160.20",
+ command: "ls",
+ retcode: 0,
+ stdout:
+ "app\nconfig_agent.yaml\nconfig_agent.yaml.templete\nconfig_server.yaml\nconfig_server.yaml.templete\ndbmanager\nglobal\ngo.mod\ngo.sum\nuser.xlsx.templete\nutils\nvendor",
+ stderr: "",
+ is_update: true,
+ },
+ ],
+ },
+ {
+ id: 1,
+ task_name: "执行中",
+ command: "ls",
+ task_status: "执行中",
+ create_time: "2023-12-25 10:08:15",
+ update_time: "",
+ results: [
+ {
+ id: 1,
+ task_id: 1,
+ machine_uuid: "13ff60a7-0f7d-49d6-b7fc-b766cc347ba8",
+ machine_ip: "192.168.160.20",
+ command: "ls",
+ retcode: 0,
+ stdout:
+ "app\nconfig_agent.yaml\nconfig_agent.yaml.templete\nconfig_server.yaml\nconfig_server.yaml.templete\ndbmanager\nglobal\ngo.mod\ngo.sum\nuser.xlsx.templete\nutils\nvendor",
+ stderr: "",
+ is_update: false,
+ },
+ ],
+ },
+ ];
props.getData!({ page: page.currentPage, size: page.pageSize }).then(
- (res: any) => {
- if (res.data && res.data.code === 200) {
+ (res: { data: ReaultData }) => {
+ let result: ReaultData = res.data;
+ if (result && result.code === 200) {
loading.value = false;
- tableData.value = res.data.data;
- currentNum.value = res.data.data.length;
- page.total = res.data.total;
+ tableData.value = result.data;
+ currentNum.value = result.data.length;
+ page.total = result.total;
} else {
loading.value = false;
tableData.value = [];
@@ -155,10 +203,19 @@ const handleSelectinChange = (rows: any) => {
};
// 用户点击某一行的复选框
-const handleRowSelectionChange = (val: any, _row: any) => {
+const handleRowSelectionChange = (val: [], _row: any) => {
+ // 输出当前选中的所有行数组
console.log(val);
};
+// 刷新表格
+const handleRefresh = () => {
+ // 清空选项
+ myTableRef.value?.clearSelection();
+ // 重新获取数据
+ getTableData();
+};
+
// 删除
const handleDelete = () => {
ElMessageBox.confirm("确定要删除吗?", "提示", {
@@ -174,6 +231,7 @@ const handleDelete = () => {
.then((res: any) => {
if (res.data.code === 200) {
ElMessage.success(res.data.msg);
+ handleRefresh();
} else {
ElMessage.error(res.data.msg);
}
@@ -186,6 +244,8 @@ const handleDelete = () => {
defineExpose({
getTableData,
+ handleDelete,
+ handleRefresh,
});
diff --git a/atune/web/src/components/taskDetail.vue b/atune/web/src/components/taskDetail.vue
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/atune/web/src/main.ts b/atune/web/src/main.ts
index b59e91f1ad4fbc5adc9ae8e302be84bf8545cf0b..0165c2a0f2b31482f0e42510bf7996d220f2b52a 100644
--- a/atune/web/src/main.ts
+++ b/atune/web/src/main.ts
@@ -1,16 +1,24 @@
-import './assets/main.css'
+import "./assets/main.css";
-import { createApp } from 'vue';
-import App from './App.vue';
-import ElementPlus from 'element-plus';
-import 'element-plus/dist/index.css';
-import router from './router';
-import { createPinia } from 'pinia';
+import { createApp } from "vue";
+import App from "./App.vue";
+import ElementPlus from "element-plus";
+import MyTable from "@/components/table.vue";
+import MyButton from "@/components/myButton.vue";
+import "element-plus/dist/index.css";
+import router from "./router";
+import { createPinia } from "pinia";
+import VueKonva from "vue-konva";
const app = createApp(App);
+// 设置全局变量
+// app.config.globalProperties.$router = router;
+app.component("my-table", MyTable);
+app.component("my-button", MyButton);
app.use(createPinia());
app.use(router);
app.use(ElementPlus);
+app.use(VueKonva);
-app.mount('#app');
+app.mount("#app");
diff --git a/atune/web/src/router/index.ts b/atune/web/src/router/index.ts
index e40df3f34505869e8e01b3542083f83d05c5f81b..ba402a4e150ead7a8f715120bc153d3a96c2ff3b 100644
--- a/atune/web/src/router/index.ts
+++ b/atune/web/src/router/index.ts
@@ -1,7 +1,7 @@
import { createRouter, createWebHistory } from "vue-router";
import type { RouteRecordRaw } from "vue-router";
import Home from "@/views/Home.vue";
-import Atune from "@/components/atuneList.vue";
+import Atune from "@/views/atuneList.vue";
import Result from "@/views/ResultInfo.vue";
const routes: Array = [
@@ -16,6 +16,7 @@ const routes: Array = [
children: [
{
path: "detail",
+ name: "taskDetail",
component: () => import("../views/taskDetail.vue"),
},
],
@@ -24,6 +25,13 @@ const routes: Array = [
path: "/atune",
component: Atune,
meta: { title: "模板列表" },
+ children: [
+ {
+ path: "detail",
+ name: "atuneDetail",
+ component: () => import("../views/atuneDetail.vue"),
+ },
+ ],
},
{
path: "/result",
diff --git a/atune/web/src/store/atune.ts b/atune/web/src/store/atune.ts
index 7ad8093288c287bae45c7d680e06073ac2ea2423..65767fd26d756441985bbc338e0f33a3b302006e 100644
--- a/atune/web/src/store/atune.ts
+++ b/atune/web/src/store/atune.ts
@@ -1,7 +1,11 @@
-import { defineStore } from 'pinia';
+import { defineStore } from "pinia";
+import { Task, Atune } from "@/types/atune";
-export const useAtuneStore = defineStore('atune', {
- state: () => ({ count: 0 }),
+export const useAtuneStore = defineStore("atune", {
+ state: () => ({
+ count: 0,
+ taskRow: {} as Task,
+ }),
getters: {
double: (state) => state.count * 2,
},
@@ -9,6 +13,10 @@ export const useAtuneStore = defineStore('atune', {
increment() {
this.count++;
},
+ // 设置taskRow数据
+ setTaskRow(row: Task) {
+ this.taskRow = row;
+ },
},
// persist: {
// enabled: true, // 开启存储
diff --git a/atune/web/src/store/canvas.ts b/atune/web/src/store/canvas.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0e5dfbb50662c045522c5690133c66a2cf900686
--- /dev/null
+++ b/atune/web/src/store/canvas.ts
@@ -0,0 +1,112 @@
+import { defineStore } from "pinia";
+import { RectConfig } from "@/types/atune";
+export const useCanvasStore = defineStore("canvas", {
+ state: () => ({
+ ctx: {},
+ width: 0,
+ fromX: 0,
+ fromY: 50,
+ rectWidth: 100,
+ rectHeight: 50,
+ rectConfig: {
+ x: 0,
+ y: 0,
+ width: 100,
+ height: 50,
+ fill: "#fff",
+ stroke: "#fff",
+ shadowBlur: 2,
+ cornerRadius: 10,
+ },
+ }),
+ getters: {
+ /**
+ * 箭头函数的写法,直接把 state 中的值传进来使用
+ * 如果要在 Getter 中调用其他的计算属性方法,不能使用箭头函数
+ * 注意:需要自己定义当前方法的返回值类型
+ * @param state
+ * @returns
+ */
+ // 计算各个图形的起始位置
+ rectStart: (state) => {
+ let rectConfig: RectConfig = JSON.parse(JSON.stringify(state.rectConfig));
+ rectConfig.x = state.width / 2 - state.rectWidth;
+ rectConfig.y = state.fromY;
+ return rectConfig;
+ },
+ rectPrepare: (state) => {
+ let rectConfig: RectConfig = JSON.parse(JSON.stringify(state.rectConfig));
+ rectConfig.x = state.width / 2 - state.rectWidth;
+ rectConfig.y = state.fromY + state.fromY * 2;
+ return rectConfig;
+ },
+ rectTune: (state) => {
+ let rectConfig: RectConfig = JSON.parse(JSON.stringify(state.rectConfig));
+ rectConfig.x = state.width / 2 - state.rectWidth;
+ rectConfig.y = state.fromY + state.fromY * 4;
+ return rectConfig;
+ },
+ rectRestore: (state) => {
+ let rectConfig: RectConfig = JSON.parse(JSON.stringify(state.rectConfig));
+ rectConfig.x = state.width / 2 - state.rectWidth;
+ rectConfig.y = state.fromY + state.fromY * 6;
+ return rectConfig;
+ },
+ arrowStartX: (state) => {
+ return state.fromX - state.rectWidth / 2;
+ },
+ arrowStartY: (state) => {
+ return state.fromY + state.rectHeight;
+ },
+ },
+ actions: {
+ setCtx(ctx: any) {
+ this.ctx = ctx;
+ },
+ setWidth(width: number) {
+ this.width = width;
+ this.fromX = width / 2;
+ },
+ drawArrow(
+ context: any,
+ shape: any,
+ fX: number,
+ tX: number,
+ fY: number,
+ tY: number
+ ) {
+ const headlen = 10; //箭头线的长度
+ const theta = 30; //箭头线与直线的夹角
+ const fromX = fX;
+ const fromY = fY;
+ const toX = tX;
+ const toY = tY;
+ let arrowX, arrowY; //箭头线终点坐标
+ // 计算各角度和对应的箭头终点坐标
+ let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI;
+ let angle1 = ((angle + theta) * Math.PI) / 180;
+ let angle2 = ((angle - theta) * Math.PI) / 180;
+ let topX = headlen * Math.cos(angle1);
+ let topY = headlen * Math.sin(angle1);
+ let botX = headlen * Math.cos(angle2);
+ let botY = headlen * Math.sin(angle2);
+ context.beginPath();
+ // draw a line
+ context.moveTo(fromX, fromY);
+ context.lineTo(toX, toY);
+ // draw top arrow
+ arrowX = toX + topX;
+ arrowY = toY + topY;
+ context.moveTo(arrowX, arrowY);
+ context.lineTo(toX, toY);
+ // draw bottom arrow
+ arrowX = toX + botX;
+ arrowY = toY + botY;
+ context.lineTo(arrowX, arrowY);
+ context.closePath();
+
+ // special Konva.js method
+ context.fillStrokeShape(shape);
+ },
+ },
+});
diff --git a/atune/web/src/types/atune.d.ts b/atune/web/src/types/atune.d.ts
index 18ea8b2cedb779f1bbae28881d8b1b4c30cec218..349d456a099428c9fc4ddb2d0ecfa5ceeb3a263a 100644
--- a/atune/web/src/types/atune.d.ts
+++ b/atune/web/src/types/atune.d.ts
@@ -5,7 +5,7 @@ export interface Task {
task_status: string;
create_time: string;
update_time: string;
- results: [{}];
+ results: Array;
}
export interface Atune {
@@ -17,3 +17,34 @@ export interface Atune {
restore: string;
note: string;
}
+
+// 画布矩形的参数配置
+export interface RectConfig {
+ x: number;
+ y: number;
+ width: number;
+ height: number;
+ fill: string;
+ stroke: string;
+ shadowBlur: number;
+ cornerRadius: number;
+}
+
+// 导出接口字面量
+export type TaskArray = Task[];
+export type AtuneArray = Atune[];
+
+// *接口api返回结果约束不含data
+export interface Result {
+ code: number;
+ msg: string;
+}
+
+// *接口api返回结果含有page信息
+export interface ReaultData extends Result {
+ data: Task[] | Atune[];
+ ok?: string;
+ page: number;
+ size: number;
+ total: number;
+}
diff --git a/atune/web/src/views/Home.vue b/atune/web/src/views/Home.vue
index d2d5845219c5b4e68af4942b5cc3e7cf00026349..6f51d4c717c5df4047aa686eaef8faf1842465a9 100644
--- a/atune/web/src/views/Home.vue
+++ b/atune/web/src/views/Home.vue
@@ -40,7 +40,8 @@ import { ref } from "vue";
import { ElDialog } from "element-plus";
import taskList from "./taskList.vue";
import atuneTemplete from "@/components/atuneTemplete.vue";
-import router from "../router/index.ts";
+import { useRouter } from "vue-router";
+import { Task, Atune } from "@/types/atune";
const selectedNodeData = ref("");
const searchTuneName = ref("");
@@ -50,6 +51,9 @@ const selectedEditRow = ref();
const refreshData = ref(false);
const showDetail = ref(false);
+// 路由管理器
+const router = useRouter();
+
// 关闭dialog弹框
const closeDialog = () => {
showDialog.value = false;
@@ -64,19 +68,14 @@ const returnHome = () => {
const handleCreat = () => {};
// 查看模板详情
-const handleAtuneDetail = (editRow: any) => {
- selectedEditRow.value = editRow;
+const handleAtuneDetail = (taskRow: Task | Atune) => {
+ selectedEditRow.value = taskRow;
showDialog.value = true;
};
// 查看任务详情
-const handleTaskDetail = (editRow: any) => {
- router.push({
- path: "/task/detail",
- params: {
- row: editRow,
- },
- });
+const handleTaskDetail = () => {
+ router.push("/task/detail");
showDetail.value = true;
};
diff --git a/atune/web/src/views/ResultInfo.vue b/atune/web/src/views/ResultInfo.vue
index 8814d52552f202acf7aebb213c899f0664eb8233..cc340bc4c9b9e6521aed291b67c90b6b45870aad 100644
--- a/atune/web/src/views/ResultInfo.vue
+++ b/atune/web/src/views/ResultInfo.vue
@@ -1,162 +1 @@
-
-
-
- A-Tune调优结果展示
-
-
-
-
-
- 搜索
- 删除
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/atune/web/src/views/atuneDetail.vue b/atune/web/src/views/atuneDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..e9e1d82f9c39ab5bab8b6cde3d07f5a522f7bbad
--- /dev/null
+++ b/atune/web/src/views/atuneDetail.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+ kooriookami
+ 18100000000
+ Suzhou
+
+ School
+
+ No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu
+ Province
+
+
+
+
+
+ {{ "qweqweqeqr/qweqeqwew" }}
+
+
+
+
+
+
+
diff --git a/atune/web/src/views/atuneList.vue b/atune/web/src/views/atuneList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..29227d05e9ac2845af12836f61aa61ce057e1d49
--- /dev/null
+++ b/atune/web/src/views/atuneList.vue
@@ -0,0 +1,67 @@
+
+
+
+ 模板列表
+
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+ 详情
+ 编辑
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/atune/web/src/views/taskDetail.vue b/atune/web/src/views/taskDetail.vue
index 5b52e6eefded3627a6099a5f8bd82d8160a4058c..d0fda5ff5fe3d458adbaed3a5ce83e4ecb07b3ca 100644
--- a/atune/web/src/views/taskDetail.vue
+++ b/atune/web/src/views/taskDetail.vue
@@ -1,10 +1,16 @@
- 任务详情页面
+
-
+