🔨 执行模板主机.
This commit is contained in:
@@ -44,20 +44,13 @@ public class CodeGenerators {
|
|||||||
// .color("blue", "gray", "red", "green", "white")
|
// .color("blue", "gray", "red", "green", "white")
|
||||||
// .valueUseFields()
|
// .valueUseFields()
|
||||||
// .build(),
|
// .build(),
|
||||||
Template.create("exec_job", "计划任务", "exec")
|
// Template.create("exec_template_host", "执行模板主机", "exec")
|
||||||
|
// .disableUnitTest()
|
||||||
|
// .vue("exec", "exec-template-host")
|
||||||
|
// .build(),
|
||||||
|
Template.create("path_bookmark", "路径标签", "host")
|
||||||
.disableUnitTest()
|
.disableUnitTest()
|
||||||
.vue("exec", "exec-job")
|
.vue("host", "path-bookmark")
|
||||||
.enableDrawerForm()
|
|
||||||
.dict("execJobStatus", "status")
|
|
||||||
.comment("计划任务状态")
|
|
||||||
.field("execJobStatus")
|
|
||||||
.fields("DISABLED", "ENABLED")
|
|
||||||
.labels("禁用", "启用")
|
|
||||||
.values(0, 1)
|
|
||||||
.build(),
|
|
||||||
Template.create("exec_job_host", "计划任务主机", "exec")
|
|
||||||
.disableUnitTest()
|
|
||||||
.vue("exec", "exec-job-host")
|
|
||||||
.build(),
|
.build(),
|
||||||
};
|
};
|
||||||
// jdbc 配置 - 使用配置文件
|
// jdbc 配置 - 使用配置文件
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ public class ExecTemplateController {
|
|||||||
return execTemplateService.getExecTemplateById(id);
|
return execTemplateService.getExecTemplateById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreLog(IgnoreLogMode.RET)
|
||||||
|
@GetMapping("/get-with-authorized")
|
||||||
|
@Operation(summary = "查询执行模板 (查询认证的主机)")
|
||||||
|
@Parameter(name = "id", description = "id", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('asset:exec-template:query')")
|
||||||
|
public ExecTemplateVO getExecTemplateWithAuthorized(@RequestParam("id") Long id) {
|
||||||
|
return execTemplateService.getExecTemplateWithAuthorized(id);
|
||||||
|
}
|
||||||
|
|
||||||
@IgnoreLog(IgnoreLogMode.RET)
|
@IgnoreLog(IgnoreLogMode.RET)
|
||||||
@PostMapping("/query")
|
@PostMapping("/query")
|
||||||
@Operation(summary = "分页查询执行模板")
|
@Operation(summary = "分页查询执行模板")
|
||||||
|
|||||||
@@ -31,7 +31,4 @@ public class ExecTemplateQueryRequest extends PageRequest {
|
|||||||
@Schema(description = "命令")
|
@Schema(description = "命令")
|
||||||
private String command;
|
private String command;
|
||||||
|
|
||||||
@Schema(description = "是否查询模板主机")
|
|
||||||
private Boolean queryHost;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,14 @@ public interface ExecTemplateService {
|
|||||||
*/
|
*/
|
||||||
ExecTemplateVO getExecTemplateById(Long id);
|
ExecTemplateVO getExecTemplateById(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询执行模板 (查询认证的主机)
|
||||||
|
*
|
||||||
|
* @param id id
|
||||||
|
* @return row
|
||||||
|
*/
|
||||||
|
ExecTemplateVO getExecTemplateWithAuthorized(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询执行模板
|
* 分页查询执行模板
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ package com.orion.ops.module.asset.service.impl;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.orion.lang.define.wrapper.DataGrid;
|
import com.orion.lang.define.wrapper.DataGrid;
|
||||||
import com.orion.lang.utils.Booleans;
|
import com.orion.lang.utils.collect.Lists;
|
||||||
import com.orion.ops.framework.common.constant.ErrorMessage;
|
import com.orion.ops.framework.common.constant.ErrorMessage;
|
||||||
import com.orion.ops.framework.common.utils.Valid;
|
import com.orion.ops.framework.common.utils.Valid;
|
||||||
|
import com.orion.ops.framework.security.core.utils.SecurityUtils;
|
||||||
import com.orion.ops.module.asset.convert.ExecTemplateConvert;
|
import com.orion.ops.module.asset.convert.ExecTemplateConvert;
|
||||||
import com.orion.ops.module.asset.dao.ExecTemplateDAO;
|
import com.orion.ops.module.asset.dao.ExecTemplateDAO;
|
||||||
import com.orion.ops.module.asset.entity.domain.ExecTemplateDO;
|
import com.orion.ops.module.asset.entity.domain.ExecTemplateDO;
|
||||||
@@ -13,7 +14,9 @@ import com.orion.ops.module.asset.entity.request.exec.ExecTemplateCreateRequest;
|
|||||||
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateQueryRequest;
|
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateQueryRequest;
|
||||||
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateUpdateRequest;
|
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateUpdateRequest;
|
||||||
import com.orion.ops.module.asset.entity.vo.ExecTemplateVO;
|
import com.orion.ops.module.asset.entity.vo.ExecTemplateVO;
|
||||||
|
import com.orion.ops.module.asset.enums.HostConfigTypeEnum;
|
||||||
import com.orion.ops.module.asset.enums.ScriptExecEnum;
|
import com.orion.ops.module.asset.enums.ScriptExecEnum;
|
||||||
|
import com.orion.ops.module.asset.service.AssetAuthorizedDataService;
|
||||||
import com.orion.ops.module.asset.service.ExecTemplateHostService;
|
import com.orion.ops.module.asset.service.ExecTemplateHostService;
|
||||||
import com.orion.ops.module.asset.service.ExecTemplateService;
|
import com.orion.ops.module.asset.service.ExecTemplateService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -21,9 +24,7 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行模板 服务实现类
|
* 执行模板 服务实现类
|
||||||
@@ -42,6 +43,9 @@ public class ExecTemplateServiceImpl implements ExecTemplateService {
|
|||||||
@Resource
|
@Resource
|
||||||
private ExecTemplateHostService execTemplateHostService;
|
private ExecTemplateHostService execTemplateHostService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AssetAuthorizedDataService assetAuthorizedDataService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createExecTemplate(ExecTemplateCreateRequest request) {
|
public Long createExecTemplate(ExecTemplateCreateRequest request) {
|
||||||
log.info("ExecTemplateService-createExecTemplate request: {}", JSON.toJSONString(request));
|
log.info("ExecTemplateService-createExecTemplate request: {}", JSON.toJSONString(request));
|
||||||
@@ -92,28 +96,33 @@ public class ExecTemplateServiceImpl implements ExecTemplateService {
|
|||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecTemplateVO getExecTemplateWithAuthorized(Long id) {
|
||||||
|
// 查询模板
|
||||||
|
ExecTemplateDO record = execTemplateDAO.selectById(id);
|
||||||
|
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||||
|
// 转换
|
||||||
|
ExecTemplateVO template = ExecTemplateConvert.MAPPER.to(record);
|
||||||
|
// 查询模板主机
|
||||||
|
Set<Long> hostIdList = execTemplateHostService.getHostByTemplateId(id);
|
||||||
|
if (Lists.isEmpty(hostIdList)) {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
// 过滤认证的主机
|
||||||
|
List<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(SecurityUtils.getLoginUserId(), HostConfigTypeEnum.SSH);
|
||||||
|
hostIdList.removeIf(s -> !authorizedHostIdList.contains(s));
|
||||||
|
template.setHostIdList(hostIdList);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataGrid<ExecTemplateVO> getExecTemplatePage(ExecTemplateQueryRequest request) {
|
public DataGrid<ExecTemplateVO> getExecTemplatePage(ExecTemplateQueryRequest request) {
|
||||||
// 条件
|
// 条件
|
||||||
LambdaQueryWrapper<ExecTemplateDO> wrapper = this.buildQueryWrapper(request);
|
LambdaQueryWrapper<ExecTemplateDO> wrapper = this.buildQueryWrapper(request);
|
||||||
// 查询模板
|
// 查询模板
|
||||||
DataGrid<ExecTemplateVO> templates = execTemplateDAO.of(wrapper)
|
return execTemplateDAO.of(wrapper)
|
||||||
.page(request)
|
.page(request)
|
||||||
.dataGrid(ExecTemplateConvert.MAPPER::to);
|
.dataGrid(ExecTemplateConvert.MAPPER::to);
|
||||||
if (templates.isEmpty()) {
|
|
||||||
return templates;
|
|
||||||
}
|
|
||||||
// 查询模板主机
|
|
||||||
if (Booleans.isTrue(request.getQueryHost())) {
|
|
||||||
List<Long> idList = templates.stream()
|
|
||||||
.map(ExecTemplateVO::getId)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
Map<Long, Set<Long>> templateHosts = execTemplateHostService.getHostByTemplateIdList(idList);
|
|
||||||
for (ExecTemplateVO template : templates) {
|
|
||||||
template.setHostIdList(templateHosts.get(template.getId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return templates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface ExecTemplateCreateRequest {
|
|||||||
timeout?: number;
|
timeout?: number;
|
||||||
scriptExec?: number;
|
scriptExec?: number;
|
||||||
parameterSchema?: string;
|
parameterSchema?: string;
|
||||||
|
hostIdList?: Array<number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,6 +44,7 @@ export interface ExecTemplateQueryResponse extends TableData {
|
|||||||
updateTime: number;
|
updateTime: number;
|
||||||
creator: string;
|
creator: string;
|
||||||
updater: string;
|
updater: string;
|
||||||
|
hostIdList?: Array<number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +68,13 @@ export function getExecTemplate(id: number) {
|
|||||||
return axios.get<ExecTemplateQueryResponse>('/asset/exec-template/get', { params: { id } });
|
return axios.get<ExecTemplateQueryResponse>('/asset/exec-template/get', { params: { id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询执行模板
|
||||||
|
*/
|
||||||
|
export function getExecTemplateWithAuthorized(id: number) {
|
||||||
|
return axios.get<ExecTemplateQueryResponse>('/asset/exec-template/get-with-authorized', { params: { id } });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询执行模板
|
* 分页查询执行模板
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal v-model:visible="visible"
|
<a-modal v-model:visible="visible"
|
||||||
title-align="start"
|
title-align="start"
|
||||||
title="执行日志"
|
width="96%"
|
||||||
width="94%"
|
:top="24"
|
||||||
:top="44"
|
:body-style="{ padding: '0', height: 'calc(100vh - 48px)', overflow: 'hidden' }"
|
||||||
:body-style="{ padding: '0', height: 'calc(100vh - 138px)', overflow: 'hidden' }"
|
|
||||||
:align-center="false"
|
:align-center="false"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
:mask-closable="false"
|
:mask-closable="true"
|
||||||
:unmount-on-close="true"
|
:unmount-on-close="true"
|
||||||
|
:hide-title="true"
|
||||||
:footer="false"
|
:footer="false"
|
||||||
@close="handleClose">
|
@close="handleClose">
|
||||||
<a-spin v-if="visible"
|
<a-spin v-if="visible"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<!-- 表头 -->
|
<!-- 表头 -->
|
||||||
<div class="host-header">
|
<div class="host-header">
|
||||||
<h3>执行主机</h3>
|
<h3 class="usn">执行主机</h3>
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<a-button v-if="visibleBack"
|
<a-button v-if="visibleBack"
|
||||||
size="small"
|
size="small"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
title="执行模板"
|
title="执行模板"
|
||||||
width="86%"
|
width="86%"
|
||||||
:top="80"
|
:top="80"
|
||||||
:body-style="{padding: '0 8px'}"
|
:body-style="{ padding: '0 8px' }"
|
||||||
:align-center="false"
|
:align-center="false"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
@@ -93,8 +93,8 @@
|
|||||||
import useVisible from '@/hooks/visible';
|
import useVisible from '@/hooks/visible';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { copy } from '@/hooks/copy';
|
import { copy } from '@/hooks/copy';
|
||||||
import columns from './table.columns';
|
|
||||||
import { getExecTemplatePage } from '@/api/exec/exec-template';
|
import { getExecTemplatePage } from '@/api/exec/exec-template';
|
||||||
|
import columns from './table.columns';
|
||||||
|
|
||||||
const emits = defineEmits(['selected']);
|
const emits = defineEmits(['selected']);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,16 @@ import { useUserStore } from '@/store';
|
|||||||
export default function useUser() {
|
export default function useUser() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const logout = async (logoutTo?: string) => {
|
|
||||||
|
// 退出登录
|
||||||
|
const logout = async () => {
|
||||||
|
await userStore.logout();
|
||||||
|
Message.success('已退出登录');
|
||||||
|
await router.push({ name: 'login' });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 退出并重定向
|
||||||
|
const logoutRedirect = async (logoutTo?: string) => {
|
||||||
await userStore.logout();
|
await userStore.logout();
|
||||||
const currentRoute = router.currentRoute.value;
|
const currentRoute = router.currentRoute.value;
|
||||||
Message.success('已退出登录');
|
Message.success('已退出登录');
|
||||||
@@ -18,7 +27,9 @@ export default function useUser() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
logout,
|
logout,
|
||||||
|
logoutRedirect,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,6 +126,7 @@
|
|||||||
import formRules from '../types/form.rules';
|
import formRules from '../types/form.rules';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { batchExecCommand } from '@/api/exec/exec-command';
|
import { batchExecCommand } from '@/api/exec/exec-command';
|
||||||
|
import { getExecTemplateWithAuthorized } from '@/api/exec/exec-template';
|
||||||
import { EnabledStatus } from '@/types/const';
|
import { EnabledStatus } from '@/types/const';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import ExecEditor from '@/components/view/exec-editor/index.vue';
|
import ExecEditor from '@/components/view/exec-editor/index.vue';
|
||||||
@@ -170,15 +171,20 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 从执行模板设置
|
// 从执行模板设置
|
||||||
const setWithTemplate = (record: ExecTemplateQueryResponse) => {
|
const setWithTemplate = async ({ id }: ExecTemplateQueryResponse) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
// 查询模板信息
|
||||||
|
const { data } = await getExecTemplateWithAuthorized(id);
|
||||||
formModel.value = {
|
formModel.value = {
|
||||||
...formModel.value,
|
...formModel.value,
|
||||||
command: record.command,
|
description: data.name,
|
||||||
description: record.name,
|
command: data.command,
|
||||||
timeout: record.timeout,
|
timeout: data.timeout,
|
||||||
scriptExec: record.scriptExec,
|
scriptExec: data.scriptExec,
|
||||||
|
hostIdList: data.hostIdList,
|
||||||
};
|
};
|
||||||
parameterSchema.value = record.parameterSchema ? JSON.parse(record.parameterSchema) : [];
|
parameterSchema.value = data.parameterSchema ? JSON.parse(data.parameterSchema) : [];
|
||||||
if (parameterSchema.value.length) {
|
if (parameterSchema.value.length) {
|
||||||
parameterFormModel.value = parameterSchema.value.reduce((acc, cur) => ({
|
parameterFormModel.value = parameterSchema.value.reduce((acc, cur) => ({
|
||||||
...acc,
|
...acc,
|
||||||
@@ -187,6 +193,10 @@
|
|||||||
} else {
|
} else {
|
||||||
parameterFormModel.value = {};
|
parameterFormModel.value = {};
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 从执行日志设置
|
// 从执行日志设置
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-drawer v-model:visible="visible"
|
<a-drawer v-model:visible="visible"
|
||||||
title="计划任务详情"
|
title="计划任务详情"
|
||||||
width="60%"
|
width="66%"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:unmount-on-close="true"
|
:unmount-on-close="true"
|
||||||
ok-text="关闭"
|
ok-text="关闭"
|
||||||
@@ -146,6 +146,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.command-editor {
|
.command-editor {
|
||||||
height: calc(100vh - 378px);
|
height: calc(100vh - 384px);
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-drawer v-model:visible="visible"
|
<a-drawer v-model:visible="visible"
|
||||||
:title="title"
|
:title="title"
|
||||||
width="60%"
|
width="66%"
|
||||||
|
:esc-to-close="false"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:unmount-on-close="true"
|
:unmount-on-close="true"
|
||||||
:ok-button-props="{ disabled: loading }"
|
:ok-button-props="{ disabled: loading }"
|
||||||
@@ -135,6 +136,7 @@
|
|||||||
import formRules from '../types/form.rules';
|
import formRules from '../types/form.rules';
|
||||||
import { jobBuiltinsParams } from '../types/const';
|
import { jobBuiltinsParams } from '../types/const';
|
||||||
import { createExecJob, getExecJob, updateExecJob } from '@/api/exec/exec-job';
|
import { createExecJob, getExecJob, updateExecJob } from '@/api/exec/exec-job';
|
||||||
|
import { getExecTemplateWithAuthorized } from '@/api/exec/exec-template';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { EnabledStatus } from '@/types/const';
|
import { EnabledStatus } from '@/types/const';
|
||||||
import { useDictStore } from '@/store';
|
import { useDictStore } from '@/store';
|
||||||
@@ -195,9 +197,9 @@
|
|||||||
id: record.id,
|
id: record.id,
|
||||||
name: record.name,
|
name: record.name,
|
||||||
expression: record.expression,
|
expression: record.expression,
|
||||||
|
command: record.command,
|
||||||
timeout: record.timeout,
|
timeout: record.timeout,
|
||||||
scriptExec: record.scriptExec,
|
scriptExec: record.scriptExec,
|
||||||
command: record.command,
|
|
||||||
parameterSchema: record.parameterSchema,
|
parameterSchema: record.parameterSchema,
|
||||||
hostIdList: record.hostIdList,
|
hostIdList: record.hostIdList,
|
||||||
};
|
};
|
||||||
@@ -209,9 +211,24 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 通过模板设置
|
// 通过模板设置
|
||||||
const setWithTemplate = (template: ExecTemplateQueryResponse) => {
|
const setWithTemplate = async ({ id }: ExecTemplateQueryResponse) => {
|
||||||
formModel.value.command = template.command;
|
setLoading(true);
|
||||||
formModel.value.timeout = template.timeout;
|
try {
|
||||||
|
// 查询模板信息
|
||||||
|
const { data } = await getExecTemplateWithAuthorized(id);
|
||||||
|
formModel.value = {
|
||||||
|
...formModel.value,
|
||||||
|
name: data.name,
|
||||||
|
command: data.command,
|
||||||
|
timeout: data.timeout,
|
||||||
|
scriptExec: data.scriptExec,
|
||||||
|
parameterSchema: data.parameterSchema,
|
||||||
|
hostIdList: data.hostIdList,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({ openAdd, openUpdate, setSelectedHost, setWithTemplate });
|
defineExpose({ openAdd, openUpdate, setSelectedHost, setWithTemplate });
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-drawer v-model:visible="visible"
|
<a-drawer v-model:visible="visible"
|
||||||
title="执行命令"
|
title="执行命令"
|
||||||
width="60%"
|
width="66%"
|
||||||
|
:esc-to-close="false"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:unmount-on-close="true"
|
:unmount-on-close="true"
|
||||||
:ok-button-props="{ disabled: loading }"
|
:ok-button-props="{ disabled: loading }"
|
||||||
@@ -137,6 +138,7 @@
|
|||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { EnabledStatus } from '@/types/const';
|
import { EnabledStatus } from '@/types/const';
|
||||||
import { batchExecCommand } from '@/api/exec/exec-command';
|
import { batchExecCommand } from '@/api/exec/exec-command';
|
||||||
|
import { getExecTemplateWithAuthorized } from '@/api/exec/exec-template';
|
||||||
import ExecEditor from '@/components/view/exec-editor/index.vue';
|
import ExecEditor from '@/components/view/exec-editor/index.vue';
|
||||||
|
|
||||||
const emits = defineEmits(['openHost']);
|
const emits = defineEmits(['openHost']);
|
||||||
@@ -151,9 +153,18 @@
|
|||||||
const parameterSchema = ref<Array<TemplateParam>>([]);
|
const parameterSchema = ref<Array<TemplateParam>>([]);
|
||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
const open = (record: ExecTemplateQueryResponse) => {
|
const open = async (id: number) => {
|
||||||
renderForm({ ...record });
|
renderForm({} as ExecTemplateQueryResponse);
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
// 查询模板信息
|
||||||
|
const { data } = await getExecTemplateWithAuthorized(id);
|
||||||
|
renderForm(data);
|
||||||
|
} catch (e) {
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 渲染表单
|
// 渲染表单
|
||||||
@@ -163,7 +174,7 @@
|
|||||||
timeout: record.timeout,
|
timeout: record.timeout,
|
||||||
scriptExec: record.scriptExec,
|
scriptExec: record.scriptExec,
|
||||||
command: record.command,
|
command: record.command,
|
||||||
hostIdList: []
|
hostIdList: record.hostIdList || [],
|
||||||
};
|
};
|
||||||
if (record.parameterSchema) {
|
if (record.parameterSchema) {
|
||||||
parameterSchema.value = JSON.parse(record.parameterSchema);
|
parameterSchema.value = JSON.parse(record.parameterSchema);
|
||||||
@@ -172,7 +183,6 @@
|
|||||||
params[param.name as keyof any] = param.defaultValue;
|
params[param.name as keyof any] = param.defaultValue;
|
||||||
}
|
}
|
||||||
parameterFormModel.value = params;
|
parameterFormModel.value = params;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
parameterSchema.value = [];
|
parameterSchema.value = [];
|
||||||
parameterFormModel.value = {};
|
parameterFormModel.value = {};
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-drawer v-model:visible="visible"
|
<a-drawer v-model:visible="visible"
|
||||||
width="60%"
|
width="66%"
|
||||||
:title="title"
|
:title="title"
|
||||||
|
:esc-to-close="false"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:unmount-on-close="true"
|
:unmount-on-close="true"
|
||||||
:ok-button-props="{ disabled: loading }"
|
:ok-button-props="{ disabled: loading }"
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
:rules="formRules">
|
:rules="formRules">
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<!-- 模板名称 -->
|
<!-- 模板名称 -->
|
||||||
<a-col :span="12">
|
<a-col :span="16">
|
||||||
<a-form-item field="name"
|
<a-form-item field="name"
|
||||||
label="模板名称"
|
label="模板名称"
|
||||||
:hide-asterisk="true">
|
:hide-asterisk="true">
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<!-- 超时时间 -->
|
<!-- 超时时间 -->
|
||||||
<a-col :span="6">
|
<a-col :span="8">
|
||||||
<a-form-item field="timeout"
|
<a-form-item field="timeout"
|
||||||
label="超时时间"
|
label="超时时间"
|
||||||
:hide-asterisk="true">
|
:hide-asterisk="true">
|
||||||
@@ -41,8 +42,24 @@
|
|||||||
</a-input-number>
|
</a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
<!-- 默认主机 -->
|
||||||
|
<a-col :span="16">
|
||||||
|
<a-form-item field="hostIdList"
|
||||||
|
label="默认主机"
|
||||||
|
:hide-asterisk="true">
|
||||||
|
<div class="selected-host">
|
||||||
|
<!-- 已选择数量 -->
|
||||||
|
<span class="usn" v-if="formModel.hostIdList?.length">
|
||||||
|
已选择<span class="selected-host-count span-blue">{{ formModel.hostIdList?.length }}</span>台主机
|
||||||
|
</span>
|
||||||
|
<span class="usn pointer span-blue" @click="openSelectHost">
|
||||||
|
{{ formModel.hostIdList?.length ? '重新选择' : '选择主机' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
<!-- 脚本执行 -->
|
<!-- 脚本执行 -->
|
||||||
<a-col :span="6">
|
<a-col :span="8">
|
||||||
<a-form-item field="scriptExec"
|
<a-form-item field="scriptExec"
|
||||||
label="脚本执行"
|
label="脚本执行"
|
||||||
:hide-asterisk="true">
|
:hide-asterisk="true">
|
||||||
@@ -132,7 +149,7 @@
|
|||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import useVisible from '@/hooks/visible';
|
import useVisible from '@/hooks/visible';
|
||||||
import formRules from '../types/form.rules';
|
import formRules from '../types/form.rules';
|
||||||
import { createExecTemplate, updateExecTemplate } from '@/api/exec/exec-template';
|
import { createExecTemplate, getExecTemplateWithAuthorized, updateExecTemplate } from '@/api/exec/exec-template';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { EnabledStatus } from '@/types/const';
|
import { EnabledStatus } from '@/types/const';
|
||||||
import ExecEditor from '@/components/view/exec-editor/index.vue';
|
import ExecEditor from '@/components/view/exec-editor/index.vue';
|
||||||
@@ -151,6 +168,7 @@
|
|||||||
timeout: 0,
|
timeout: 0,
|
||||||
scriptExec: EnabledStatus.DISABLED,
|
scriptExec: EnabledStatus.DISABLED,
|
||||||
parameterSchema: undefined,
|
parameterSchema: undefined,
|
||||||
|
hostIdList: [],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -158,7 +176,7 @@
|
|||||||
const formModel = ref<ExecTemplateUpdateRequest>({});
|
const formModel = ref<ExecTemplateUpdateRequest>({});
|
||||||
const parameter = ref<Array<TemplateParam>>([]);
|
const parameter = ref<Array<TemplateParam>>([]);
|
||||||
|
|
||||||
const emits = defineEmits(['added', 'updated']);
|
const emits = defineEmits(['added', 'updated', 'openHost']);
|
||||||
|
|
||||||
// 打开新增
|
// 打开新增
|
||||||
const openAdd = () => {
|
const openAdd = () => {
|
||||||
@@ -169,11 +187,20 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 打开修改
|
// 打开修改
|
||||||
const openUpdate = (record: any) => {
|
const openUpdate = async (id: number) => {
|
||||||
title.value = '修改执行模板';
|
title.value = '修改执行模板';
|
||||||
isAddHandle.value = false;
|
isAddHandle.value = false;
|
||||||
renderForm({ ...defaultForm(), ...record });
|
renderForm({ ...defaultForm() });
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
// 查询模板信息
|
||||||
|
const { data } = await getExecTemplateWithAuthorized(id);
|
||||||
|
renderForm({ ...defaultForm(), ...data });
|
||||||
|
} catch (e) {
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 渲染表单
|
// 渲染表单
|
||||||
@@ -186,7 +213,17 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({ openAdd, openUpdate });
|
// 设置选中主机
|
||||||
|
const setSelectedHost = (hosts: Array<number>) => {
|
||||||
|
formModel.value.hostIdList = hosts;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ openAdd, openUpdate, setSelectedHost });
|
||||||
|
|
||||||
|
// 打开选择主机
|
||||||
|
const openSelectHost = () => {
|
||||||
|
emits('openHost', formModel.value.hostIdList || []);
|
||||||
|
};
|
||||||
|
|
||||||
// 添加参数
|
// 添加参数
|
||||||
const addParameter = () => {
|
const addParameter = () => {
|
||||||
@@ -251,6 +288,30 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
.selected-host {
|
||||||
|
width: 100%;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border-radius: 2px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background: var(--color-fill-2);
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&-count {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--color-fill-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.parameter-form-item {
|
.parameter-form-item {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
@@ -316,7 +377,7 @@
|
|||||||
|
|
||||||
.command-editor {
|
.command-editor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 62vh;
|
height: 55vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -79,14 +79,14 @@
|
|||||||
<a-button v-permission="['asset:exec-command:exec']"
|
<a-button v-permission="['asset:exec-command:exec']"
|
||||||
type="text"
|
type="text"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="emits('openExec', record)">
|
@click="emits('openExec', record.id)">
|
||||||
执行
|
执行
|
||||||
</a-button>
|
</a-button>
|
||||||
<!-- 修改 -->
|
<!-- 修改 -->
|
||||||
<a-button v-permission="['asset:exec-template:update']"
|
<a-button v-permission="['asset:exec-template:update']"
|
||||||
type="text"
|
type="text"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="emits('openUpdate', record)">
|
@click="emits('openUpdate', record.id)">
|
||||||
修改
|
修改
|
||||||
</a-button>
|
</a-button>
|
||||||
<!-- 删除 -->
|
<!-- 删除 -->
|
||||||
|
|||||||
@@ -2,19 +2,20 @@
|
|||||||
<div class="layout-container" v-if="render">
|
<div class="layout-container" v-if="render">
|
||||||
<!-- 列表-表格 -->
|
<!-- 列表-表格 -->
|
||||||
<exec-template-table ref="table"
|
<exec-template-table ref="table"
|
||||||
@open-exec="(e) => execModal.open(e)"
|
|
||||||
@open-add="() => drawer.openAdd()"
|
@open-add="() => drawer.openAdd()"
|
||||||
@open-update="(e) => drawer.openUpdate(e)" />
|
@open-update="(e) => drawer.openUpdate(e)"
|
||||||
|
@open-exec="(e) => execModal.open(e)" />
|
||||||
<!-- 添加修改模态框 -->
|
<!-- 添加修改模态框 -->
|
||||||
<exec-template-form-drawer ref="drawer"
|
<exec-template-form-drawer ref="drawer"
|
||||||
@added="modalAddCallback"
|
@added="modalAddCallback"
|
||||||
@updated="modalUpdateCallback" />
|
@updated="modalUpdateCallback"
|
||||||
|
@open-host="(e) => openHostModal('drawer', e)" />
|
||||||
<!-- 执行模态框 -->
|
<!-- 执行模态框 -->
|
||||||
<exec-template-exec-drawer ref="execModal"
|
<exec-template-exec-drawer ref="execModal"
|
||||||
@open-host="(e) => hostModal.open(e)" />
|
@open-host="(e) => openHostModal('exec', e)" />
|
||||||
<!-- 主机模态框 -->
|
<!-- 主机模态框 -->
|
||||||
<authorized-host-modal ref="hostModal"
|
<authorized-host-modal ref="hostModal"
|
||||||
@selected="(e) => execModal.setSelectedHost(e)" />
|
@selected="hostSelected" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -34,8 +35,9 @@
|
|||||||
const render = ref(false);
|
const render = ref(false);
|
||||||
const table = ref();
|
const table = ref();
|
||||||
const drawer = ref();
|
const drawer = ref();
|
||||||
const hostModal = ref();
|
|
||||||
const execModal = ref();
|
const execModal = ref();
|
||||||
|
const hostModal = ref();
|
||||||
|
const lastOpenHostRef = ref();
|
||||||
|
|
||||||
// 添加回调
|
// 添加回调
|
||||||
const modalAddCallback = () => {
|
const modalAddCallback = () => {
|
||||||
@@ -47,6 +49,23 @@
|
|||||||
table.value.updatedCallback();
|
table.value.updatedCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 打开主机模态框
|
||||||
|
const openHostModal = (openRef: string, data: any) => {
|
||||||
|
lastOpenHostRef.value = openRef;
|
||||||
|
hostModal.value.open(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 选中主机
|
||||||
|
const hostSelected = (data: any) => {
|
||||||
|
if (lastOpenHostRef.value === 'drawer') {
|
||||||
|
// 设置选中的主机
|
||||||
|
drawer.value.setSelectedHost(data);
|
||||||
|
} else if (lastOpenHostRef.value === 'exec') {
|
||||||
|
// 设置选中的主机
|
||||||
|
execModal.value.setSelectedHost(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
render.value = true;
|
render.value = true;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user