✨ 添加主机身份类型.
This commit is contained in:
@@ -7,6 +7,7 @@ import axios from 'axios';
|
||||
*/
|
||||
export interface HostIdentityCreateRequest {
|
||||
name?: string;
|
||||
type?: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
keyId?: number;
|
||||
@@ -27,6 +28,7 @@ export interface HostIdentityQueryRequest extends Pagination {
|
||||
searchValue?: string;
|
||||
id?: number;
|
||||
name?: string;
|
||||
type?: string;
|
||||
username?: string;
|
||||
keyId?: number;
|
||||
}
|
||||
@@ -37,6 +39,7 @@ export interface HostIdentityQueryRequest extends Pagination {
|
||||
export interface HostIdentityQueryResponse extends TableData {
|
||||
id: number;
|
||||
name: string;
|
||||
type: string;
|
||||
username: string;
|
||||
password: string;
|
||||
keyId: number;
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
// 定时查询执行状态
|
||||
if (record.status === execStatus.WAITING ||
|
||||
record.status === execStatus.RUNNING) {
|
||||
// 等待一秒后先查询一下状态
|
||||
setTimeout(fetchTaskStatus, 1000);
|
||||
// 注册状态轮询
|
||||
statusIntervalId.value = setInterval(fetchTaskStatus, 5000);
|
||||
}
|
||||
@@ -92,8 +94,8 @@
|
||||
if (hostStatus) {
|
||||
host.status = hostStatus.status;
|
||||
host.startTime = hostStatus.startTime;
|
||||
// 使用时间
|
||||
host.finishTime = host.finishTime || Date.now();
|
||||
// 结束时间绑定了使用时间 如果未完成则使用当前时间
|
||||
host.finishTime = hostStatus.finishTime || Date.now();
|
||||
host.exitStatus = hostStatus.exitStatus;
|
||||
host.errorMessage = hostStatus.errorMessage;
|
||||
}
|
||||
|
||||
@@ -15,11 +15,24 @@
|
||||
:pagination="false"
|
||||
:bordered="false"
|
||||
@row-click="clickRow">
|
||||
<!-- 类型 -->
|
||||
<template #type="{ record }">
|
||||
<a-tag :color="getDictValue(identityTypeKey, record.type, 'color')">
|
||||
{{ getDictValue(identityTypeKey, record.type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<!-- 秘钥名称 -->
|
||||
<template #keyId="{ record }">
|
||||
<a-tag color="arcoblue" v-if="record.keyId">
|
||||
{{ hostKeys.find(s => s.id === record.keyId)?.name }}
|
||||
</a-tag>
|
||||
<!-- 有秘钥 -->
|
||||
<template v-if="record.keyId && record.type === 'KEY'">
|
||||
<a-tag color="arcoblue" v-if="record.keyId">
|
||||
{{ hostKeys.find(s => s.id === record.keyId)?.name }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<!-- 无秘钥 -->
|
||||
<template v-else>
|
||||
<span>-</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</grant-layout>
|
||||
@@ -38,11 +51,12 @@
|
||||
import type { HostKeyQueryResponse } from '@/api/asset/host-key';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { getAuthorizedHostIdentity, grantHostIdentity } from '@/api/asset/asset-data-grant';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { hostIdentityColumns } from '../types/table.columns';
|
||||
import { useCacheStore } from '@/store';
|
||||
import { useRowSelection } from '@/types/table';
|
||||
import { getAuthorizedHostIdentity, grantHostIdentity } from '@/api/asset/asset-data-grant';
|
||||
import { useCacheStore, useDictStore } from '@/store';
|
||||
import { hostIdentityColumns } from '../types/table.columns';
|
||||
import { identityTypeKey } from '../types/const';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import GrantLayout from './grant-layout.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -51,6 +65,7 @@
|
||||
|
||||
const cacheStore = useCacheStore();
|
||||
const rowSelection = useRowSelection();
|
||||
const { getDictValue } = useDictStore();
|
||||
const { loading, setLoading } = useLoading();
|
||||
|
||||
const selectedKeys = ref<Array<number>>([]);
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeMount, onUnmounted, ref } from 'vue';
|
||||
import { useCacheStore } from '@/store';
|
||||
import { GrantTabs } from './types/const';
|
||||
import { useCacheStore, useDictStore } from '@/store';
|
||||
import { GrantTabs, dictKeys } from './types/const';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
const route = useRoute();
|
||||
@@ -35,9 +35,10 @@
|
||||
|
||||
const activeKey = ref();
|
||||
|
||||
// 卸载时清除 cache
|
||||
onUnmounted(() => {
|
||||
cacheStore.reset('users', 'roles', 'hosts', 'hostGroups', 'hostKeys', 'hostIdentities');
|
||||
// 加载字典项
|
||||
onBeforeMount(async () => {
|
||||
const dictStore = useDictStore();
|
||||
await dictStore.loadKeys(dictKeys);
|
||||
});
|
||||
|
||||
// 跳转到指定页
|
||||
@@ -48,6 +49,11 @@
|
||||
}
|
||||
});
|
||||
|
||||
// 卸载时清除 cache
|
||||
onUnmounted(() => {
|
||||
cacheStore.reset('users', 'roles', 'hosts', 'hostGroups', 'hostKeys', 'hostIdentities');
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -73,3 +73,9 @@ export const GrantTabs = [
|
||||
component: HostIdentityGrant
|
||||
},
|
||||
];
|
||||
|
||||
// 身份类型 字典项
|
||||
export const identityTypeKey = 'hostIdentityType';
|
||||
|
||||
// 加载的字典值
|
||||
export const dictKeys = [identityTypeKey];
|
||||
|
||||
@@ -14,11 +14,14 @@ export const hostKeyColumns = [
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
slotName: 'name',
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
}, {
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
slotName: 'createTime',
|
||||
align: 'center',
|
||||
width: 180,
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.createTime));
|
||||
},
|
||||
@@ -27,6 +30,7 @@ export const hostKeyColumns = [
|
||||
dataIndex: 'updateTime',
|
||||
slotName: 'updateTime',
|
||||
align: 'center',
|
||||
width: 180,
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.updateTime));
|
||||
},
|
||||
@@ -46,23 +50,23 @@ export const hostIdentityColumns = [
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
slotName: 'name',
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
}, {
|
||||
title: '类型',
|
||||
dataIndex: 'type',
|
||||
slotName: 'type',
|
||||
width: 98,
|
||||
}, {
|
||||
title: '用户名',
|
||||
dataIndex: 'username',
|
||||
slotName: 'username',
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
}, {
|
||||
title: '主机秘钥',
|
||||
dataIndex: 'keyId',
|
||||
slotName: 'keyId',
|
||||
}, {
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
slotName: 'createTime',
|
||||
align: 'center',
|
||||
width: 180,
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.createTime));
|
||||
},
|
||||
}, {
|
||||
title: '修改时间',
|
||||
dataIndex: 'updateTime',
|
||||
|
||||
@@ -54,6 +54,13 @@
|
||||
<a-form-item field="name" label="名称">
|
||||
<a-input v-model="formModel.name" placeholder="请输入名称" allow-clear />
|
||||
</a-form-item>
|
||||
<!-- 类型 -->
|
||||
<a-form-item field="type" label="类型">
|
||||
<a-select v-model="formModel.type"
|
||||
placeholder="请选择类型"
|
||||
:options="toOptions(identityTypeKey)"
|
||||
allow-clear />
|
||||
</a-form-item>
|
||||
<!-- 用户名 -->
|
||||
<a-form-item field="username" label="用户名">
|
||||
<a-input v-model="formModel.username" placeholder="请输入用户名" allow-clear />
|
||||
@@ -68,6 +75,12 @@
|
||||
<template #title="{ record }">
|
||||
{{ record.name }}
|
||||
</template>
|
||||
<!-- 类型 -->
|
||||
<template #type="{ record }">
|
||||
<a-tag :color="getDictValue(identityTypeKey, record.type, 'color')">
|
||||
{{ getDictValue(identityTypeKey, record.type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<!-- 用户名 -->
|
||||
<template #username="{ record }">
|
||||
<span class="span-blue text-copy" @click="copy(record.username)">
|
||||
@@ -76,13 +89,14 @@
|
||||
</template>
|
||||
<!-- 秘钥名称 -->
|
||||
<template #keyId="{ record }">
|
||||
<template v-if="record.keyId">
|
||||
<!-- 有秘钥 -->
|
||||
<template v-if="record.keyId && record.type === IdentityType.KEY">
|
||||
<!-- 可查看详情 -->
|
||||
<a-tooltip v-if="hasAnyPermission(['asset:host-key:detail', 'asset:host-key:update'])"
|
||||
content="点击查看详情">
|
||||
<a-tag :checked="true"
|
||||
checkable
|
||||
@click="emits('openKeyView',{id: record.keyId})">
|
||||
@click="emits('openKeyView', { id: record.keyId })">
|
||||
{{ record.keyName }}
|
||||
</a-tag>
|
||||
</a-tooltip>
|
||||
@@ -91,6 +105,10 @@
|
||||
{{ record.keyName }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<!-- 无秘钥 -->
|
||||
<template v-else>
|
||||
<span>-</span>
|
||||
</template>
|
||||
</template>
|
||||
<!-- 拓展操作 -->
|
||||
<template #extra="{ record }">
|
||||
@@ -151,8 +169,10 @@
|
||||
import { deleteHostIdentity, getHostIdentityPage } from '@/api/asset/host-identity';
|
||||
import { Message, Modal } from '@arco-design/web-vue';
|
||||
import usePermission from '@/hooks/permission';
|
||||
import { useDictStore } from '@/store';
|
||||
import { copy } from '@/hooks/copy';
|
||||
import { GrantKey, GrantRouteName } from '@/views/asset/grant/types/const';
|
||||
import { IdentityType, identityTypeKey } from '../types/const';
|
||||
import HostKeySelector from '@/components/asset/host-key/selector/index.vue';
|
||||
|
||||
const emits = defineEmits(['openAdd', 'openUpdate', 'openKeyView']);
|
||||
@@ -161,6 +181,7 @@
|
||||
|
||||
const cardColLayout = useColLayout();
|
||||
const pagination = usePagination();
|
||||
const { toOptions, getDictValue } = useDictStore();
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { hasAnyPermission } = usePermission();
|
||||
|
||||
@@ -168,6 +189,7 @@
|
||||
const formModel = reactive<HostIdentityQueryRequest>({
|
||||
searchValue: undefined,
|
||||
id: undefined,
|
||||
type: undefined,
|
||||
name: undefined,
|
||||
username: undefined,
|
||||
keyId: undefined,
|
||||
|
||||
@@ -23,12 +23,20 @@
|
||||
<a-form-item field="name" label="名称">
|
||||
<a-input v-model="formModel.name" placeholder="请输入名称" />
|
||||
</a-form-item>
|
||||
<!-- 类型 -->
|
||||
<a-form-item field="type" label="类型">
|
||||
<a-radio-group v-model="formModel.type"
|
||||
type="button"
|
||||
class="usn"
|
||||
:options="toRadioOptions(identityTypeKey)" />
|
||||
</a-form-item>
|
||||
<!-- 用户名 -->
|
||||
<a-form-item field="username" label="用户名">
|
||||
<a-input v-model="formModel.username" placeholder="请输入用户名" />
|
||||
</a-form-item>
|
||||
<!-- 用户密码 -->
|
||||
<a-form-item field="password"
|
||||
<a-form-item v-if="formModel.type === IdentityType.PASSWORD"
|
||||
field="password"
|
||||
label="用户密码"
|
||||
:rules="passwordRules">
|
||||
<a-input-password v-model="formModel.password"
|
||||
@@ -42,10 +50,10 @@
|
||||
checked-text="使用新密码"
|
||||
unchecked-text="使用原密码" />
|
||||
</a-form-item>
|
||||
<!-- 秘钥id -->
|
||||
<a-form-item field="keyId"
|
||||
label="主机秘钥"
|
||||
extra="密码和秘钥二选一 优先使用秘钥">
|
||||
<!-- 主机秘钥 -->
|
||||
<a-form-item v-if="formModel.type === IdentityType.KEY"
|
||||
field="keyId"
|
||||
label="主机秘钥">
|
||||
<host-key-selector v-model="formModel.keyId" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -68,8 +76,11 @@
|
||||
import formRules from '../types/form.rules';
|
||||
import { createHostIdentity, updateHostIdentity } from '@/api/asset/host-identity';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { IdentityType, identityTypeKey } from '../types/const';
|
||||
import { useDictStore } from '@/store';
|
||||
import HostKeySelector from '@/components/asset/host-key/selector/index.vue';
|
||||
|
||||
const { toRadioOptions, getDictValue } = useDictStore();
|
||||
const { visible, setVisible } = useVisible();
|
||||
const { loading, setLoading } = useLoading();
|
||||
|
||||
@@ -79,6 +90,7 @@
|
||||
const defaultForm = (): HostIdentityUpdateRequest => {
|
||||
return {
|
||||
id: undefined,
|
||||
type: IdentityType.PASSWORD,
|
||||
name: undefined,
|
||||
username: undefined,
|
||||
password: undefined,
|
||||
@@ -139,15 +151,6 @@
|
||||
return false;
|
||||
}
|
||||
if (isAddHandle.value) {
|
||||
if (!formModel.value.password && !formModel.value.keyId) {
|
||||
formRef.value.setFields({
|
||||
password: {
|
||||
status: 'error',
|
||||
message: '创建时密码和秘钥不能同时为空'
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// 新增
|
||||
await createHostIdentity(formModel.value);
|
||||
Message.success('创建成功');
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
<a-form-item field="name" label="名称">
|
||||
<a-input v-model="formModel.name" placeholder="请输入名称" allow-clear />
|
||||
</a-form-item>
|
||||
<!-- 类型 -->
|
||||
<a-form-item field="type" label="类型">
|
||||
<a-select v-model="formModel.type"
|
||||
placeholder="请选择类型"
|
||||
:options="toOptions(identityTypeKey)"
|
||||
allow-clear />
|
||||
</a-form-item>
|
||||
<!-- 用户名 -->
|
||||
<a-form-item field="username" label="用户名">
|
||||
<a-input v-model="formModel.username" placeholder="请输入用户名" allow-clear />
|
||||
@@ -80,6 +87,12 @@
|
||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
||||
@page-size-change="(size) => fetchTableData(1, size)"
|
||||
:bordered="false">
|
||||
<!-- 类型 -->
|
||||
<template #type="{ record }">
|
||||
<a-tag :color="getDictValue(identityTypeKey, record.type, 'color')">
|
||||
{{ getDictValue(identityTypeKey, record.type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<!-- 用户名 -->
|
||||
<template #username="{ record }">
|
||||
<span class="span-blue text-copy" @click="copy(record.username)">
|
||||
@@ -88,13 +101,14 @@
|
||||
</template>
|
||||
<!-- 秘钥名称 -->
|
||||
<template #keyId="{ record }">
|
||||
<template v-if="record.keyId">
|
||||
<!-- 有秘钥 -->
|
||||
<template v-if="record.keyId && record.type === IdentityType.KEY">
|
||||
<!-- 可查看详情 -->
|
||||
<a-tooltip v-if="hasAnyPermission(['asset:host-key:detail', 'asset:host-key:update'])"
|
||||
content="点击查看详情">
|
||||
<a-tag :checked="true"
|
||||
checkable
|
||||
@click="emits('openKeyView',{id: record.keyId})">
|
||||
@click="emits('openKeyView', { id: record.keyId })">
|
||||
{{ record.keyName }}
|
||||
</a-tag>
|
||||
</a-tooltip>
|
||||
@@ -103,6 +117,10 @@
|
||||
{{ record.keyName }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<!-- 无秘钥 -->
|
||||
<template v-else>
|
||||
<span>-</span>
|
||||
</template>
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<template #handle="{ record }">
|
||||
@@ -147,21 +165,24 @@
|
||||
import useLoading from '@/hooks/loading';
|
||||
import usePermission from '@/hooks/permission';
|
||||
import { copy } from '@/hooks/copy';
|
||||
import { useDictStore } from '@/store';
|
||||
import { usePagination } from '@/types/table';
|
||||
import { GrantKey, GrantRouteName } from '@/views/asset/grant/types/const';
|
||||
import { IdentityType, identityTypeKey } from '../types/const';
|
||||
import HostKeySelector from '@/components/asset/host-key/selector/index.vue';
|
||||
|
||||
const emits = defineEmits(['openAdd', 'openUpdate', 'openKeyView']);
|
||||
|
||||
const tableRenderData = ref<HostIdentityQueryResponse[]>([]);
|
||||
|
||||
const pagination = usePagination();
|
||||
const { toOptions, getDictValue } = useDictStore();
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { hasAnyPermission } = usePermission();
|
||||
|
||||
const tableRenderData = ref<HostIdentityQueryResponse[]>([]);
|
||||
const formModel = reactive<HostIdentityQueryRequest>({
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
type: undefined,
|
||||
username: undefined,
|
||||
keyId: undefined,
|
||||
});
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onUnmounted } from 'vue';
|
||||
import { useAppStore, useCacheStore } from '@/store';
|
||||
import { ref, computed, onUnmounted, onBeforeMount } from 'vue';
|
||||
import { useAppStore, useCacheStore, useDictStore } from '@/store';
|
||||
import { dictKeys } from './types/const';
|
||||
import HostIdentityCardList from './components/host-identity-card-list.vue';
|
||||
import HostIdentityTable from './components/host-identity-table.vue';
|
||||
import HostIdentityFormModal from './components/host-identity-form-modal.vue';
|
||||
@@ -62,6 +63,12 @@
|
||||
}
|
||||
};
|
||||
|
||||
// 加载字典值
|
||||
onBeforeMount(async () => {
|
||||
const dictStore = useDictStore();
|
||||
await dictStore.loadKeys(dictKeys);
|
||||
});
|
||||
|
||||
// 卸载时清除 cache
|
||||
onUnmounted(() => {
|
||||
const cacheStore = useCacheStore();
|
||||
|
||||
@@ -9,6 +9,10 @@ const fieldConfig = {
|
||||
label: 'id',
|
||||
dataIndex: 'id',
|
||||
slotName: 'id',
|
||||
}, {
|
||||
label: '类型',
|
||||
dataIndex: 'type',
|
||||
slotName: 'type',
|
||||
}, {
|
||||
label: '用户名',
|
||||
dataIndex: 'username',
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// 身份类型
|
||||
export const IdentityType = {
|
||||
PASSWORD: 'PASSWORD',
|
||||
KEY: 'KEY',
|
||||
};
|
||||
|
||||
// 身份类型 字典项
|
||||
export const identityTypeKey = 'hostIdentityType';
|
||||
|
||||
// 加载的字典值
|
||||
export const dictKeys = [identityTypeKey];
|
||||
|
||||
@@ -8,6 +8,16 @@ export const name = [{
|
||||
message: '名称长度不能大于64位'
|
||||
}] as FieldRule[];
|
||||
|
||||
export const type = [{
|
||||
required: true,
|
||||
message: '请选择类型'
|
||||
}] as FieldRule[];
|
||||
|
||||
export const keyId = [{
|
||||
required: true,
|
||||
message: '请选择秘钥'
|
||||
}] as FieldRule[];
|
||||
|
||||
export const username = [{
|
||||
required: true,
|
||||
message: '请输入用户名'
|
||||
@@ -18,5 +28,7 @@ export const username = [{
|
||||
|
||||
export default {
|
||||
name,
|
||||
type,
|
||||
keyId,
|
||||
username,
|
||||
} as Record<string, FieldRule | FieldRule[]>;
|
||||
|
||||
@@ -13,6 +13,13 @@ const columns = [
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
slotName: 'name',
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
}, {
|
||||
title: '类型',
|
||||
dataIndex: 'type',
|
||||
slotName: 'type',
|
||||
width: 138,
|
||||
}, {
|
||||
title: '用户名',
|
||||
dataIndex: 'username',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="visible"
|
||||
:title="title"
|
||||
:width="470"
|
||||
:width="520"
|
||||
:mask-closable="false"
|
||||
:unmount-on-close="true"
|
||||
:ok-button-props="{ disabled: loading || isViewHandler }"
|
||||
@@ -241,7 +241,7 @@
|
||||
|
||||
.keygen-alert {
|
||||
margin: 0 0 12px 16px;
|
||||
width: 408px;
|
||||
width: calc(100% - 16px);
|
||||
}
|
||||
|
||||
.password-input {
|
||||
|
||||
@@ -13,11 +13,14 @@ const columns = [
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
slotName: 'name',
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
}, {
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
slotName: 'createTime',
|
||||
align: 'center',
|
||||
width: 198,
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.createTime));
|
||||
},
|
||||
@@ -26,6 +29,7 @@ const columns = [
|
||||
dataIndex: 'updateTime',
|
||||
slotName: 'updateTime',
|
||||
align: 'center',
|
||||
width: 198,
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.updateTime));
|
||||
},
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
{{ getDictValue(execJobStatusKey, record.status) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<!-- 最近任务 -->
|
||||
<!-- 最近执行 -->
|
||||
<template #recentLog="{ record }">
|
||||
<div class="flex-center" v-if="record.recentLogId && record.recentLogStatus">
|
||||
<!-- 执行状态 -->
|
||||
|
||||
@@ -38,7 +38,7 @@ const columns = [
|
||||
align: 'center',
|
||||
width: 112,
|
||||
}, {
|
||||
title: '最近任务',
|
||||
title: '最近执行',
|
||||
dataIndex: 'recentLog',
|
||||
slotName: 'recentLog',
|
||||
align: 'left',
|
||||
|
||||
@@ -245,5 +245,6 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user