🔨 重构主机模块.

This commit is contained in:
lijiahang
2024-07-22 19:36:02 +08:00
parent b7608fccb3
commit 4bd2de4ce2
64 changed files with 1062 additions and 603 deletions

View File

@@ -1,20 +1,25 @@
<template>
<a-card class="general-card"
:body-style="{ padding: config.status === EnabledStatus.ENABLED ? '' : '0' }">
<a-card class="general-card" :body-style="{ padding: '0 16px 0 20px'}">
<!-- 标题 -->
<template #title>
<div class="config-title-wrapper">
<span>SSH 配置</span>
<a-switch v-model="config.status"
:disabled="loading"
type="round"
:checked-value="EnabledStatus.ENABLED"
:unchecked-value="EnabledStatus.DISABLED"
:before-change="s => updateStatus(s as number)" />
<span class="title">SSH 配置</span>
<!-- 操作按钮 -->
<a-space>
<a-button size="small"
@click="emits('reset')">
重置
</a-button>
<a-button type="primary"
size="small"
@click="saveConfig">
保存
</a-button>
</a-space>
</div>
</template>
<!-- 表单 -->
<a-spin v-show="config.status" :loading="loading" class="config-form-wrapper">
<div class="config-form-wrapper full">
<!-- 表单 -->
<a-form :model="formModel"
ref="formRef"
@@ -29,14 +34,6 @@
:options="toOptions(sshOsTypeKey)"
placeholder="请选择系统类型" />
</a-form-item>
<!-- SSH 端口 -->
<a-form-item field="port"
label="SSH端口"
:hide-asterisk="true">
<a-input-number v-model="formModel.port"
placeholder="请输入SSH端口"
hide-button />
</a-form-item>
<!-- 用户名 -->
<a-form-item field="username"
label="用户名"
@@ -85,7 +82,8 @@
<host-identity-selector v-model="formModel.identityId" />
</a-form-item>
<!-- 连接超时时间 -->
<a-form-item field="connectTimeout"
<a-form-item class="mt4"
field="connectTimeout"
label="连接超时时间"
:hide-asterisk="true">
<a-input-number v-model="formModel.connectTimeout"
@@ -96,49 +94,26 @@
</template>
</a-input-number>
</a-form-item>
<!-- 其他配置 -->
<a-collapse :bordered="false">
<a-collapse-item key="1">
<template #header>
<span class="usn">其他配置</span>
</template>
<!-- SSH 输出编码 -->
<a-form-item class="mt4"
field="charset"
label="SSH输出编码"
:hide-asterisk="true">
<a-input v-model="formModel.charset" placeholder="请输入 SSH 输出编码" />
</a-form-item>
<!-- 文件名称编码 -->
<a-form-item field="fileNameCharset"
label="文件名称编码"
:hide-asterisk="true">
<a-input v-model="formModel.fileNameCharset" placeholder="请输入 SFTP 文件名称编码" />
</a-form-item>
<!-- 文件内容编码 -->
<a-form-item field="fileContentCharset"
label="文件内容编码"
:hide-asterisk="true">
<a-input v-model="formModel.fileContentCharset" placeholder="请输入 SFTP 文件内容编码" />
</a-form-item>
</a-collapse-item>
</a-collapse>
<!-- SSH 输出编码 -->
<a-form-item field="charset"
label="SSH输出编码"
:hide-asterisk="true">
<a-input v-model="formModel.charset" placeholder="请输入 SSH 输出编码" />
</a-form-item>
<!-- 文件名称编码 -->
<a-form-item field="fileNameCharset"
label="文件名称编码"
:hide-asterisk="true">
<a-input v-model="formModel.fileNameCharset" placeholder="请输入 SFTP 文件名称编码" />
</a-form-item>
<!-- 文件内容编码 -->
<a-form-item field="fileContentCharset"
label="文件内容编码"
:hide-asterisk="true">
<a-input v-model="formModel.fileContentCharset" placeholder="请输入 SFTP 文件内容编码" />
</a-form-item>
</a-form>
<!-- 操作按钮 -->
<div class="config-button-group">
<a-space>
<a-button size="small"
@click="resetConfig">
重置
</a-button>
<a-button type="primary"
size="small"
@click="saveConfig">
保存
</a-button>
</a-space>
</div>
</a-spin>
</div>
</a-card>
</template>
@@ -151,38 +126,26 @@
<script lang="ts" setup>
import type { FieldRule } from '@arco-design/web-vue';
import type { HostSshConfig } from '../types/const';
import { reactive, ref, watch } from 'vue';
import { updateHostConfigStatus, updateHostConfig } from '@/api/asset/host-config';
import { sshAuthTypeKey, sshOsTypeKey, SshAuthType, SshOsType } from '../types/const';
import rules from '../types/ssh-form.rules';
import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import type { HostConfigQueryResponse } from '@/api/asset/host';
import { ref, watch } from 'vue';
import { sshAuthTypeKey, sshOsTypeKey, SshAuthType } from '../types/const';
import { useDictStore } from '@/store';
import { EnabledStatus } from '@/types/const';
import { HostConfigType } from '../types/const';
import rules from '../types/ssh-form.rules';
import HostKeySelector from '@/components/asset/host-key/selector/index.vue';
import HostIdentitySelector from '@/components/asset/host-identity/selector/index.vue';
const { loading, setLoading } = useLoading();
const { toOptions, toRadioOptions } = useDictStore();
const props = defineProps<{
content: any;
hostId: number;
hostConfig: HostConfigQueryResponse;
}>();
const emits = defineEmits(['submitted']);
const config = reactive({
status: undefined,
version: undefined,
});
const emits = defineEmits(['save', 'reset']);
const formRef = ref();
const formModel = ref<HostSshConfig>({
osType: SshOsType.LINUX,
osType: undefined,
username: undefined,
port: undefined,
password: undefined,
authType: SshAuthType.PASSWORD,
keyId: undefined,
@@ -196,10 +159,10 @@
});
// 监听数据变化
watch(() => props.content, (v: any) => {
config.status = v?.status;
config.version = v?.version;
resetConfig();
watch(() => props.hostConfig.current, () => {
formModel.value = Object.assign({}, props.hostConfig.config);
// 使用新密码默认为不包含密码
formModel.value.useNewPassword = !formModel.value.hasPassword;
});
// 用户名验证
@@ -230,77 +193,20 @@
}
}] as FieldRule[];
// 修改状态
const updateStatus = async (e: number) => {
setLoading(true);
return updateHostConfigStatus({
hostId: props?.hostId,
type: HostConfigType.SSH,
status: e,
version: config.version
}).then(({ data }) => {
config.version = data;
setLoading(false);
return true;
}).catch(() => {
setLoading(false);
return false;
});
};
// 重置配置
const resetConfig = () => {
formModel.value = Object.assign({}, props.content?.config);
// 使用新密码默认为不包含密码
formModel.value.useNewPassword = !formModel.value.hasPassword;
};
// 保存配置
const saveConfig = async () => {
try {
// 验证参数
const error = await formRef.value.validate();
if (error) {
return false;
}
setLoading(true);
// 更新
const { data } = await updateHostConfig({
hostId: props?.hostId,
type: HostConfigType.SSH,
version: config.version,
config: JSON.stringify(formModel.value)
});
config.version = data;
setLoading(false);
Message.success('修改成功');
// 回调 props
emits('submitted', { ...props.content, ...config, config: { ...formModel.value } });
} catch (e) {
} finally {
setLoading(false);
// 验证参数
const error = await formRef.value.validate();
if (error) {
return false;
}
// 回调
emits('save', { ...formModel.value });
};
</script>
<style lang="less" scoped>
.config-title-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
}
.config-form-wrapper {
width: 100%;
}
.config-button-group {
display: flex;
align-items: center;
justify-content: flex-end;
}
.auth-type-group {
width: 100%;
display: flex;
@@ -312,13 +218,4 @@
margin-left: 8px;
}
:deep(.arco-collapse-item-content) {
background: unset;
padding: 0;
}
:deep(.arco-collapse-item-header) {
border: none;
}
</style>

View File

@@ -11,15 +11,15 @@
<!-- 标题 -->
<template #title>
<span class="host-title-text">
主机配置 <span class="host-name-title-text">{{ record.name }}</span>
主机配置 <span class="host-name-title-text">{{ record?.name }}</span>
</span>
</template>
<a-spin :loading="loading" class="host-config-container">
<!-- SSH 配置 -->
<ssh-config-form class="host-config-wrapper"
:host-id="record.id"
:content="config.ssh"
@submitted="(e) => config.ssh = e" />
:host-config="hostConfig"
@save="save"
@reset="reset" />
</a-spin>
</a-drawer>
</template>
@@ -31,14 +31,14 @@
</script>
<script lang="ts" setup>
import type { HostConfigWrapper, HostSshConfig } from '../types/const';
import type { HostConfigQueryResponse } from '@/api/asset/host';
import { ref } from 'vue';
import useVisible from '@/hooks/visible';
import useLoading from '@/hooks/loading';
import { Message } from '@arco-design/web-vue';
import { getHostConfigList } from '@/api/asset/host-config';
import { useCacheStore, useDictStore } from '@/store';
import { dictKeys } from '../types/const';
import { getHostConfig, updateHostConfig } from '@/api/asset/host';
import SshConfigForm from '../components/ssh-config-form.vue';
const { visible, setVisible } = useVisible();
@@ -46,13 +46,12 @@
const cacheStore = useCacheStore();
const record = ref({} as any);
const config = ref<HostConfigWrapper>({
ssh: {} as HostSshConfig
});
const hostConfig = ref<HostConfigQueryResponse>({} as HostConfigQueryResponse);
// 打开
const open = async (e: any) => {
record.value = { ...e };
hostConfig.value = { config: {} } as HostConfigQueryResponse;
try {
setLoading(true);
setVisible(true);
@@ -60,10 +59,9 @@
const dictStore = useDictStore();
await dictStore.loadKeys(dictKeys);
// 加载配置
const { data } = await getHostConfigList(record.value.id);
data.forEach(s => {
config.value[s.type] = s;
});
const { data } = await getHostConfig(record.value.id);
data.current = Date.now();
hostConfig.value = data;
} catch ({ message }) {
Message.error(`配置加载失败 ${message}`);
setVisible(false);
@@ -72,14 +70,38 @@
}
};
defineExpose({ open });
// 保存
const save = async (conf: Record<string, any>) => {
try {
setLoading(true);
// 更新
await updateHostConfig({
id: hostConfig.value.id,
config: JSON.stringify(conf)
});
// 设置参数
hostConfig.value.config = conf;
Message.success('修改成功');
} catch (e) {
} finally {
setLoading(false);
}
};
// 重置
const reset = () => {
// 修改 current 让子组件重新渲染
hostConfig.value.current = Date.now();
};
// 关闭
const handleCancel = () => {
setLoading(false);
setVisible(false);
};
defineExpose({ open });
</script>
<style lang="less" scoped>
@@ -120,4 +142,21 @@
margin: 18px;
}
:deep(.config-title-wrapper) {
display: flex;
align-items: center;
justify-content: space-between;
.title{
font-weight: 600;
user-select: none;
}
}
:deep(.config-button-group) {
display: flex;
align-items: center;
justify-content: flex-end;
}
</style>

View File

@@ -1,19 +1,11 @@
// 主机所有配置
export interface HostConfigWrapper {
ssh: HostSshConfig;
[key: string]: unknown;
}
// 主机 SSH 配置
export interface HostSshConfig {
osType?: string;
port?: number;
username?: string;
password?: string;
authType?: string;
identityId?: number;
keyId?: number;
identityId?: number;
connectTimeout?: number;
charset?: string;
fileNameCharset?: string;
@@ -32,17 +24,6 @@ export const SshAuthType = {
IDENTITY: 'IDENTITY'
};
// 主机系统版本
export const SshOsType = {
LINUX: 'LINUX',
WINDOWS: 'WINDOWS',
};
// 主机配置类型
export const HostConfigType = {
SSH: 'ssh'
};
// 主机验证方式 字典项
export const sshAuthTypeKey = 'hostSshAuthType';

View File

@@ -5,16 +5,6 @@ export const osType = [{
message: '请选择系统类型'
}] as FieldRule[];
export const port = [{
required: true,
message: '请输入SSH端口'
}, {
type: 'number',
min: 1,
max: 65535,
message: '输入的端口不合法'
}] as FieldRule[];
export const authType = [{
required: true,
message: '请选择认证方式'
@@ -66,7 +56,6 @@ export const fileContentCharset = [{
export default {
osType,
port,
authType,
keyId,
identityId,