Commit 77b323c0 authored by 张俊's avatar 张俊

[feat](自动化运维): 列表页

parent 6621cf06
<template> <template>
<div>主机管理</div> <div class="detail_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入关键字">
<template v-slot:left_action>
<div class="apaas_button">
<el-button type="primary" @click="register">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon>
新增
</el-button>
<el-button type="default" @click="deleteAllTips"> 批量删除 </el-button>
<span class="header_info"
>已选择 <span style="color: #202531; font-weight: bold"> {{ state.selected.length }} </span>
</span>
<span class="header_info can_click_text" @click="clearSelected">清空</span>
</div>
</template>
<template v-slot:filter_group>
<div class="left-filter filter_list">
<div class="filter_item">
<span class="filter_title">创建时间</span>
<el-date-picker
v-model="filter.time"
type="daterange"
value-format="yyyy-MM-DD"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期" />
</div>
</div>
<div class="right-action apaas_button">
<el-button type="primary" @click="filterAction"> 查询 </el-button>
<el-button type="default" @click="filterClear"> 重置 </el-button>
</div>
</template>
</bg-filter-group>
<div class="table_container">
<div class="table bg-scroll">
<bg-table
ref="dataTable"
:headers="headers"
:rows="tableRows"
@selectAc="selectRows"
:isIndex="true"
:select="true"
:stripe="true">
<template v-slot:name="{ row }">
<span class="can_click_text" @click="getChildren(row)">
{{ row.name }}
</span>
</template>
<template v-slot:ipNumber="{ row }">
<span> {{ row.name }}/{{ row.name }} </span>
</template>
<template v-slot:updated_time="{ row }">
{{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
</template>
<template v-slot:action="{ row }">
<bg-table-btns2 :limit="3" :tableData="tableRows">
<bg-table-btn @click="editRow(row)">编辑</bg-table-btn>
<bg-table-btn @click="checkRow(row)">状态检测</bg-table-btn>
<bg-table-btn @click="exportRow(row, 1)">导出异常</bg-table-btn>
<bg-table-btn @click="deleteRow(row, 2)">删除</bg-table-btn>
</bg-table-btns2>
</template>
</bg-table>
</div>
<bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
<!-- 新增/编辑弹窗 -->
<!-- <el-dialog
class="dialog_box"
:title="addType == 1 ? '新增' : '编辑'"
v-model="addDialog"
width="758px">
<el-form ref="bgForm" :model="formData" :rules="rules" label-width="80px" class="bg_form">
<el-form-item label="名称" prop="name">
<el-input
v-model.trim="formData.name"
show-word-limit
:maxlength="
nodeClassifyId == 'eb9c7d70-c123-42b7-8e61-dde1b022b669'
? 6
: nodeClassifyId == 'efd9ec3b-7f18-49e2-9d88-bcca022243bb'
? 4
: nodeClassifyId == '949a1138-4995-464e-97a9-424d097eb271'
? 2
: 20
"
placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="描述" prop="describe">
<el-input
v-model="formData.describe"
type="textarea"
:autosize="{ minRows: 5 }"
show-word-limit
maxlength="200"
resize="vertical"
placeholder="请输入描述"></el-input>
</el-form-item>
<el-form-item label="是否启用" prop="state" style="margin-bottom: 0px">
<el-switch
class="bg-switch-ele"
v-model="formData.state"
:active-value="1"
:inactive-value="0"
inline-prompt
active-text="是"
inactive-text="否" />
</el-form-item>
</el-form>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="addDialog = false">取 消</el-button>
<el-button type="primary" @click="addConfirm">保 存</el-button>
</div>
</template>
</el-dialog> -->
<!-- 删除弹窗 -->
<!-- <el-dialog
class="dialog_box"
title="提示"
v-model="dialogDelete"
width="400px"
:before-close="
() => {
dialogDelete = false;
}
">
<div>确定要删除此字典值吗?</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="dialogDelete = false">取 消</el-button>
<el-button type="primary" @click="deleteData">确 定</el-button>
</div>
</template>
</el-dialog> -->
</div>
</template> </template>
<script setup></script> <script setup>
import { reactive, ref, onBeforeMount, toRefs, computed, watch, nextTick, watchEffect } from "vue";
import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
import { Search } from "@element-plus/icons-vue";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const bgForm = ref(null);
const dataTable = ref(null);
const headers = [
{
label: "主机分组名称",
prop: "name",
},
{
label: "IP数量(异常/全部)",
prop: "ipNumber",
},
{
label: "任务数量",
prop: "workTimes",
},
{
label: "创建人",
prop: "person",
},
{
label: "创建时间",
prop: "updated_time",
width: 220,
},
{
label: "操作",
prop: "action",
width: 200,
fixed: "right",
},
];
<style lang="scss" scoped></style> const state = reactive({
bgForm,
typeList: [], // 分类数据
typeKeyword: "", // 分类删选关键词
nodeClassifyId: null, // 当前选中分类的uuid 用于新增字典
nodeId: null, // 当前选中分类的id 用于请求列表
timer: null, // 定时器
tableRows: [], // 表格数据
selected: [], //选择数据
tableTotal: 0, // 表格数据条数
filter: {
time: "",
search: "",
page: 1,
limit: 10,
}, // 表格筛选项
stateOptions: [
{
name: "全部",
value: "",
},
{
name: "启用",
value: "1",
},
{
name: "禁用",
value: "0",
},
], // 启用禁用
actionRow: null, // 当前操作的数据
dialogDelete: false, // 删除弹窗
addType: 0, //
addDialog: false,
formData: {
name: "",
describe: "",
state: 1,
p_dict_id: "",
},
rules: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
describe: [
{ required: true, message: "请输入描述", trigger: "blur" },
{ max: 200, message: "描述最大为200字", trigger: "blur" },
],
state: [{ required: true, message: "请选择是否启用", trigger: "change" }],
},
fatherRow: null,
});
const selectRows = (data) => {
state.selected = data.selection;
};
const clearSelected = () => {
dataTable.value.clearTable();
};
const deleteAllTips = () => {};
const dictLevel = ref(1);
const getChildren = (row) => {
dictLevel.value = 2;
state.tableRows = row.children || [];
state.tableTotal = row.total_children;
state.fatherRow = row;
};
const getTypeList = () => {
let params = {
name: state.typeKeyword,
};
axios
.get(`/apaas/system/v5/dictionary/classify/list`, { params })
.then((res) => {
if (res.data.code == 200) {
state.typeList = res.data.data || [];
state.nodeClassifyId = state.typeList[0].classify_id || null;
state.nodeId = state.typeList[0].id || null;
if (state.nodeId) {
getTableRows();
}
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
console.log(err);
});
}; // 获取字典分类
const changeSearch = (val) => {
state.filter.search = val;
changePage(1);
}; // 表格关键字筛选
const filterAction = () => {
changePage(1);
}; // 查询按钮
const filterClear = () => {
state.filter = {
time: "",
search: "",
limit: 10,
page: 1,
};
changePage(1);
}; // 重置筛选项
const getTableRows = () => {
let params = { ...state.filter };
params.id = state.nodeId;
axios
.get(`/apaas/system/v5/dictionary/list`, {
params,
})
.then((res) => {
if (res.data.code == 200) {
let data = res.data.data || [];
if (dictLevel.value == 1) {
state.tableRows = data;
state.tableTotal = res.data.total;
} else {
let row = data.filter((e) => {
return e.dict_id == state.fatherRow.dict_id;
});
state.tableRows = row[0].children;
state.tableTotal = row[0].total_children;
}
if (state.tableRows.length > 0) {
state.tableRows.forEach((e) => {
e.canMoveUp = true;
e.canMoveDown = true;
});
state.tableRows[0].canMoveUp = false;
state.tableRows[state.tableRows.length - 1].canMoveDown = false;
}
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取表格数据
const changePage = (page) => {
state.filter.page = page;
getTableRows();
}; // 改变页码
const changeSize = (size) => {
state.filter.limit = size;
changePage(1);
}; // 改变每页条数
const register = () => {
state.formData = {
name: "",
describe: "",
state: 1,
p_dict_id: state.fatherRow ? state.fatherRow.dict_id : "",
};
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate((valid) => {
if (!valid) {
state.bgForm.clearValidate();
}
});
});
}
state.addType = 1;
state.addDialog = true;
}; // 新增字典按钮
onBeforeMount(() => {
getTypeList();
});
const { tableRows, tableTotal, filter } = toRefs(state);
</script>
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
.main_container {
height: 100%;
.filter-group {
.left-filter {
flex: 1;
display: flex;
justify-content: start;
flex-wrap: wrap;
}
.right-action {
width: 144px;
padding-bottom: 16px;
.el-button {
width: 64px;
}
}
}
.table_container {
height: calc(100% - 70px);
width: 100%;
padding: 0 16px;
.table {
max-height: calc(100% - 64px);
}
}
}
.bg_form {
width: 100%;
box-sizing: border-box;
.el-form-item {
margin-bottom: 24px;
:deep().el-form-item__label {
line-height: 36px;
height: 36px;
}
.el-form-item__content {
width: 100%;
.el-textarea {
:deep().el-input__count {
bottom: -16px;
right: 4px;
font-family: Roboto-Regular;
color: #a9b1c7;
}
}
.bg-switch-ele {
width: 52px;
height: 24px;
:deep().el-switch__core {
width: 100%;
height: 24px;
.el-switch__inner,
.el-switch__action {
top: 3px;
}
}
}
}
}
}
}
</style>
<template> <template>
<div>任务历史</div> <div class="detail_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入关键字"> </bg-filter-group>
<div class="table_container">
<div class="table bg-scroll">
<bg-table ref="dataTable" :headers="headers" :rows="tableRows" :stripe="true">
<template v-slot:name="{ row }">
<span class="can_click_text" @click="getChildren(row)">
{{ row.name }}
</span>
</template>
<template v-slot:state="{ row }">
<span> 执行中 </span>
</template>
</bg-table>
</div>
<bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
</div>
</template> </template>
<script setup></script> <script setup>
import { reactive, ref, onBeforeMount, toRefs, computed, watch, nextTick, watchEffect } from "vue";
import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
import { useRouter, useRoute } from "vue-router";
import { Search } from "@element-plus/icons-vue";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
<style lang="scss" scoped></style> const router = useRouter();
const route = useRoute();
const bgForm = ref(null);
const dataTable = ref(null);
const headers = [
{
label: "状态",
prop: "state",
},
{
label: "任务名称",
prop: "name",
},
{
label: "执行耗时",
prop: "workTime",
},
{
label: "操作人",
prop: "person",
},
];
const state = reactive({
bgForm,
typeList: [], // 分类数据
typeKeyword: "", // 分类删选关键词
nodeClassifyId: null, // 当前选中分类的uuid 用于新增字典
nodeId: null, // 当前选中分类的id 用于请求列表
timer: null, // 定时器
tableRows: [], // 表格数据
selected: [], //选择数据
tableTotal: 0, // 表格数据条数
filter: {
time: "",
search: "",
page: 1,
limit: 10,
}, // 表格筛选项
actionRow: null, // 当前操作的数据
dialogDelete: false, // 删除弹窗
addType: 0, //
addDialog: false,
formData: {
name: "",
describe: "",
state: 1,
p_dict_id: "",
},
rules: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
describe: [
{ required: true, message: "请输入描述", trigger: "blur" },
{ max: 200, message: "描述最大为200字", trigger: "blur" },
],
state: [{ required: true, message: "请选择是否启用", trigger: "change" }],
},
fatherRow: null,
});
const selectRows = (data) => {
state.selected = data.selection;
};
const clearSelected = () => {
dataTable.value.clearTable();
};
const deleteAllTips = () => {};
const getChildren = (row) => {
router.push(`/auto-maintenance/task-history/list`);
};
const getTypeList = () => {
let params = {
name: state.typeKeyword,
};
axios
.get(`/apaas/system/v5/dictionary/classify/list`, { params })
.then((res) => {
if (res.data.code == 200) {
state.typeList = res.data.data || [];
state.nodeClassifyId = state.typeList[0].classify_id || null;
state.nodeId = state.typeList[0].id || null;
if (state.nodeId) {
getTableRows();
}
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
console.log(err);
});
}; // 获取字典分类
const changeSearch = (val) => {
state.filter.search = val;
changePage(1);
}; // 表格关键字筛选
const filterAction = () => {
changePage(1);
}; // 查询按钮
const filterClear = () => {
state.filter = {
time: "",
search: "",
limit: 10,
page: 1,
};
changePage(1);
}; // 重置筛选项
const getTableRows = () => {
let params = { ...state.filter };
params.id = state.nodeId;
axios
.get(`/apaas/system/v5/dictionary/list`, {
params,
})
.then((res) => {
if (res.data.code == 200) {
let data = res.data.data || [];
state.tableRows = data;
state.tableTotal = res.data.total;
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取表格数据
const changePage = (page) => {
state.filter.page = page;
getTableRows();
}; // 改变页码
const changeSize = (size) => {
state.filter.limit = size;
changePage(1);
}; // 改变每页条数
const register = () => {
state.formData = {
name: "",
describe: "",
state: 1,
p_dict_id: state.fatherRow ? state.fatherRow.dict_id : "",
};
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate((valid) => {
if (!valid) {
state.bgForm.clearValidate();
}
});
});
}
state.addType = 1;
state.addDialog = true;
}; // 新增字典按钮
onBeforeMount(() => {
getTypeList();
});
const { tableRows, tableTotal, filter } = toRefs(state);
</script>
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
.main_container {
height: 100%;
.filter-group {
.left-filter {
flex: 1;
display: flex;
justify-content: start;
flex-wrap: wrap;
}
.right-action {
width: 144px;
padding-bottom: 16px;
.el-button {
width: 64px;
}
}
}
.table_container {
height: calc(100% - 70px);
width: 100%;
padding: 0 16px;
.table {
max-height: calc(100% - 64px);
}
}
}
.bg_form {
width: 100%;
box-sizing: border-box;
.el-form-item {
margin-bottom: 24px;
:deep().el-form-item__label {
line-height: 36px;
height: 36px;
}
.el-form-item__content {
width: 100%;
.el-textarea {
:deep().el-input__count {
bottom: -16px;
right: 4px;
font-family: Roboto-Regular;
color: #a9b1c7;
}
}
.bg-switch-ele {
width: 52px;
height: 24px;
:deep().el-switch__core {
width: 100%;
height: 24px;
.el-switch__inner,
.el-switch__action {
top: 3px;
}
}
}
}
}
}
}
</style>
<template>
<div class="detail_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<bg-filter-group
@search="changeSearch"
class="page-filter-group"
v-model="filter.search"
placeholder="请输入关键字">
<template v-slot:left_action>
<div class="apaas_button">
<el-button type="default" @click="deleteAllTips"> 返回 </el-button>
</div>
<span class="filter-group-item">执行ping命令</span>
</template>
</bg-filter-group>
<div class="table_container">
<div class="table bg-scroll">
<bg-table ref="dataTable" :headers="headers" :rows="tableRows" :stripe="true">
<template v-slot:desc="{ row }">
<span class="can_click_text" @click="getChildren(row)">
{{ row.name }}
</span>
</template>
<template v-slot:state="{ row }">
<span> 执行中 </span>
</template>
</bg-table>
</div>
<bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, onBeforeMount, toRefs, computed, watch, nextTick, watchEffect } from "vue";
import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
import { Search } from "@element-plus/icons-vue";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const bgForm = ref(null);
const dataTable = ref(null);
const headers = [
{
label: "状态",
prop: "state",
},
{
label: "执行说明",
prop: "desc",
},
{
label: "执行开始时间",
prop: "begin",
},
{
label: "执行耗时",
prop: "workTime",
},
{
label: "操作人",
prop: "person",
},
];
const state = reactive({
bgForm,
typeList: [], // 分类数据
typeKeyword: "", // 分类删选关键词
nodeClassifyId: null, // 当前选中分类的uuid 用于新增字典
nodeId: null, // 当前选中分类的id 用于请求列表
timer: null, // 定时器
tableRows: [], // 表格数据
selected: [], //选择数据
tableTotal: 0, // 表格数据条数
filter: {
time: "",
search: "",
page: 1,
limit: 10,
}, // 表格筛选项
actionRow: null, // 当前操作的数据
dialogDelete: false, // 删除弹窗
addType: 0, //
addDialog: false,
formData: {
name: "",
describe: "",
state: 1,
p_dict_id: "",
},
rules: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
describe: [
{ required: true, message: "请输入描述", trigger: "blur" },
{ max: 200, message: "描述最大为200字", trigger: "blur" },
],
state: [{ required: true, message: "请选择是否启用", trigger: "change" }],
},
fatherRow: null,
});
const selectRows = (data) => {
state.selected = data.selection;
};
const clearSelected = () => {
dataTable.value.clearTable();
};
const deleteAllTips = () => {};
const getChildren = (row) => {
state.tableRows = row.children || [];
state.tableTotal = row.total_children;
state.fatherRow = row;
};
const getTypeList = () => {
let params = {
name: state.typeKeyword,
};
axios
.get(`/apaas/system/v5/dictionary/classify/list`, { params })
.then((res) => {
if (res.data.code == 200) {
state.typeList = res.data.data || [];
state.nodeClassifyId = state.typeList[0].classify_id || null;
state.nodeId = state.typeList[0].id || null;
if (state.nodeId) {
getTableRows();
}
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
console.log(err);
});
}; // 获取字典分类
const changeSearch = (val) => {
state.filter.search = val;
changePage(1);
}; // 表格关键字筛选
const filterAction = () => {
changePage(1);
}; // 查询按钮
const filterClear = () => {
state.filter = {
time: "",
search: "",
limit: 10,
page: 1,
};
changePage(1);
}; // 重置筛选项
const getTableRows = () => {
let params = { ...state.filter };
params.id = state.nodeId;
axios
.get(`/apaas/system/v5/dictionary/list`, {
params,
})
.then((res) => {
if (res.data.code == 200) {
let data = res.data.data || [];
state.tableRows = data;
state.tableTotal = res.data.total;
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取表格数据
const changePage = (page) => {
state.filter.page = page;
getTableRows();
}; // 改变页码
const changeSize = (size) => {
state.filter.limit = size;
changePage(1);
}; // 改变每页条数
const register = () => {
state.formData = {
name: "",
describe: "",
state: 1,
p_dict_id: state.fatherRow ? state.fatherRow.dict_id : "",
};
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate((valid) => {
if (!valid) {
state.bgForm.clearValidate();
}
});
});
}
state.addType = 1;
state.addDialog = true;
}; // 新增字典按钮
onBeforeMount(() => {
getTypeList();
});
const { tableRows, tableTotal, filter } = toRefs(state);
</script>
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
.main_container {
height: 100%;
.filter-group {
.left-filter {
flex: 1;
display: flex;
justify-content: start;
flex-wrap: wrap;
}
.right-action {
width: 144px;
padding-bottom: 16px;
.el-button {
width: 64px;
}
}
}
.table_container {
height: calc(100% - 70px);
width: 100%;
padding: 0 16px;
.table {
max-height: calc(100% - 64px);
}
}
}
.bg_form {
width: 100%;
box-sizing: border-box;
.el-form-item {
margin-bottom: 24px;
:deep().el-form-item__label {
line-height: 36px;
height: 36px;
}
.el-form-item__content {
width: 100%;
.el-textarea {
:deep().el-input__count {
bottom: -16px;
right: 4px;
font-family: Roboto-Regular;
color: #a9b1c7;
}
}
.bg-switch-ele {
width: 52px;
height: 24px;
:deep().el-switch__core {
width: 100%;
height: 24px;
.el-switch__inner,
.el-switch__action {
top: 3px;
}
}
}
}
}
}
}
.page-filter-group {
position: relative;
.filter-group-item {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 14px;
color: #202531;
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment