feat: 资源池接口联调&部分组件调整
This commit is contained in:
parent
54640dc32d
commit
4ebc36d5a9
|
@ -1,8 +1,20 @@
|
||||||
import MSR from '@/api/http/index';
|
import MSR from '@/api/http/index';
|
||||||
import { PoolListUrl, UpdatePoolUrl, AddPoolUrl, DetailPoolUrl } from '@/api/requrls/setting/resourcePool';
|
import {
|
||||||
|
PoolListUrl,
|
||||||
|
UpdatePoolUrl,
|
||||||
|
AddPoolUrl,
|
||||||
|
DetailPoolUrl,
|
||||||
|
DeletePoolUrl,
|
||||||
|
EnablePoolUrl,
|
||||||
|
} from '@/api/requrls/setting/resourcePool';
|
||||||
|
|
||||||
import type { LocationQueryValue } from 'vue-router';
|
import type { LocationQueryValue } from 'vue-router';
|
||||||
import type { ResourcePoolItem, AddResourcePoolParams } from '@/models/setting/resourcePool';
|
import type {
|
||||||
|
ResourcePoolItem,
|
||||||
|
AddResourcePoolParams,
|
||||||
|
UpdateResourcePoolParams,
|
||||||
|
ResourcePoolDetail,
|
||||||
|
} from '@/models/setting/resourcePool';
|
||||||
import type { TableQueryParams } from '@/models/common';
|
import type { TableQueryParams } from '@/models/common';
|
||||||
|
|
||||||
// 获取资源池列表
|
// 获取资源池列表
|
||||||
|
@ -11,7 +23,7 @@ export function getPoolList(data: TableQueryParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新资源池信息
|
// 更新资源池信息
|
||||||
export function updatePoolInfo(data: ResourcePoolItem) {
|
export function updatePoolInfo(data: UpdateResourcePoolParams) {
|
||||||
return MSR.post({ url: UpdatePoolUrl, data });
|
return MSR.post({ url: UpdatePoolUrl, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,5 +34,15 @@ export function addPool(data: AddResourcePoolParams) {
|
||||||
|
|
||||||
// 获取资源池详情
|
// 获取资源池详情
|
||||||
export function getPoolInfo(poolId: LocationQueryValue | LocationQueryValue[]) {
|
export function getPoolInfo(poolId: LocationQueryValue | LocationQueryValue[]) {
|
||||||
return MSR.get<ResourcePoolItem>({ url: DetailPoolUrl, params: poolId });
|
return MSR.get<ResourcePoolDetail>({ url: DetailPoolUrl, params: poolId });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除资源池
|
||||||
|
export function delPoolInfo(poolId: string) {
|
||||||
|
return MSR.get({ url: DeletePoolUrl, params: poolId });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启用/禁用资源池
|
||||||
|
export function togglePoolStatus(poolId: string) {
|
||||||
|
return MSR.post({ url: EnablePoolUrl, params: poolId });
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,3 +3,4 @@ export const UpdatePoolUrl = '/test/resource/pool/update';
|
||||||
export const AddPoolUrl = '/test/resource/pool/add';
|
export const AddPoolUrl = '/test/resource/pool/add';
|
||||||
export const DeletePoolUrl = '/test/resource/pool/delete';
|
export const DeletePoolUrl = '/test/resource/pool/delete';
|
||||||
export const DetailPoolUrl = '/test/resource/pool/detail';
|
export const DetailPoolUrl = '/test/resource/pool/detail';
|
||||||
|
export const EnablePoolUrl = '/test/resource/pool/set/enable/';
|
||||||
|
|
|
@ -7,7 +7,13 @@
|
||||||
</div>
|
</div>
|
||||||
<a-divider v-if="!simple" class="mb-[16px]" />
|
<a-divider v-if="!simple" class="mb-[16px]" />
|
||||||
<div class="mr-[-10px]">
|
<div class="mr-[-10px]">
|
||||||
<a-scrollbar class="pr-[10px]" style="overflow-y: auto; height: calc(100vh - 256px)">
|
<a-scrollbar
|
||||||
|
class="pr-[10px]"
|
||||||
|
:style="{
|
||||||
|
overflowY: 'auto',
|
||||||
|
height: `calc(100vh - ${256 + specialHeight}px)`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</a-scrollbar>
|
</a-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,11 +26,11 @@
|
||||||
</div>
|
</div>
|
||||||
<slot name="footerRight">
|
<slot name="footerRight">
|
||||||
<a-button type="secondary" @click="back">{{ t('mscard.defaultCancelText') }}</a-button>
|
<a-button type="secondary" @click="back">{{ t('mscard.defaultCancelText') }}</a-button>
|
||||||
<a-button v-if="!props.hideContinue" type="secondary" @click="emit('saveAndContinue')">
|
<a-button v-if="!props.hideContinue && !props.isEdit" type="secondary" @click="emit('saveAndContinue')">
|
||||||
{{ t('mscard.defaultSaveAndContinueText') }}
|
{{ t('mscard.defaultSaveAndContinueText') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button type="primary" @click="emit('save')">
|
<a-button type="primary" @click="emit('save')">
|
||||||
{{ t(idEdit ? 'mscard.defaultConfirm' : 'mscard.defaultUpdate') }}
|
{{ t(props.isEdit ? 'mscard.defaultUpdate' : 'mscard.defaultConfirm') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,20 +43,24 @@
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<
|
||||||
simple?: boolean;
|
Partial<{
|
||||||
title?: string;
|
simple: boolean;
|
||||||
hideContinue?: boolean;
|
title: string;
|
||||||
handleBack?: () => void;
|
hideContinue: boolean;
|
||||||
hideFooter?: boolean;
|
hideFooter: boolean;
|
||||||
loading?: boolean;
|
loading: boolean;
|
||||||
idEdit?: boolean;
|
isEdit: boolean;
|
||||||
}>(),
|
specialHeight: number; // 特殊高度,例如某些页面有面包屑
|
||||||
|
handleBack: () => void;
|
||||||
|
}>
|
||||||
|
>(),
|
||||||
{
|
{
|
||||||
simple: false,
|
simple: false,
|
||||||
hideContinue: false,
|
hideContinue: false,
|
||||||
hideFooter: false,
|
hideFooter: false,
|
||||||
idEdit: false,
|
isEdit: false,
|
||||||
|
specialHeight: 0,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,10 @@ export const editorProps = {
|
||||||
},
|
},
|
||||||
default: 'vs-dark',
|
default: 'vs-dark',
|
||||||
},
|
},
|
||||||
|
readOnly: {
|
||||||
|
type: Boolean as PropType<boolean>,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
type: Object as PropType<Options>,
|
type: Object as PropType<Options>,
|
||||||
default() {
|
default() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as monaco from 'monaco-editor';
|
import * as monaco from 'monaco-editor';
|
||||||
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
|
// import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
|
||||||
// import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
|
// import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
|
||||||
// import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
|
// import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
|
||||||
// import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
|
// import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
|
||||||
|
@ -26,6 +26,7 @@ self.MonacoEnvironment = {
|
||||||
|
|
||||||
return new TsWorker();
|
return new TsWorker();
|
||||||
}
|
}
|
||||||
|
const EditorWorker = ((await import('monaco-editor/esm/vs/editor/editor.worker?worker')) as any).default;
|
||||||
return new EditorWorker();
|
return new EditorWorker();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,8 +13,17 @@
|
||||||
<div v-else class="ms-upload-icon ms-upload-icon--default"></div>
|
<div v-else class="ms-upload-icon ms-upload-icon--default"></div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="fileList.length === 0">
|
<template v-if="fileList.length === 0">
|
||||||
<div v-if="props.mainText" class="ms-upload-main-text">{{ t(props.mainText) }}</div>
|
<div class="ms-upload-main-text">
|
||||||
<div v-if="props.subText" class="ms-upload-sub-text">{{ t(props.subText) }}</div>
|
{{ t(props.mainText || 'ms.upload.importModalDragtext') }}
|
||||||
|
</div>
|
||||||
|
<div class="ms-upload-sub-text">
|
||||||
|
{{
|
||||||
|
t(props.subText || 'ms.upload.importModalFileTip', {
|
||||||
|
type: UploadAcceptEnum[props.accept],
|
||||||
|
size: props.maxSize || defaultMaxSize,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="ms-upload-main-text">
|
<div class="ms-upload-main-text">
|
||||||
|
@ -31,23 +40,24 @@
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { UploadAcceptEnum } from '@/enums/uploadEnum';
|
import { UploadAcceptEnum } from '@/enums/uploadEnum';
|
||||||
import { formatFileSize, sleep } from '@/utils';
|
import { formatFileSize } from '@/utils';
|
||||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||||
|
|
||||||
import type { FileItem } from '@arco-design/web-vue';
|
import { FileItem, Message } from '@arco-design/web-vue';
|
||||||
import type { UploadType } from './types';
|
import type { UploadType } from './types';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
// 上传 组件 props
|
// 上传 组件 props
|
||||||
type UploadProps = Partial<{
|
type UploadProps = Partial<{
|
||||||
mainText: string;
|
mainText: string; // 主要文案
|
||||||
subText: string;
|
subText: string; // 次要文案
|
||||||
class: string;
|
class: string;
|
||||||
multiple: boolean;
|
multiple: boolean;
|
||||||
imagePreview: boolean;
|
imagePreview: boolean;
|
||||||
showFileList: boolean;
|
showFileList: boolean;
|
||||||
iconType: string;
|
iconType: string;
|
||||||
|
maxSize: number; // 文件大小限制,单位 MB
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}> & {
|
}> & {
|
||||||
accept: UploadType;
|
accept: UploadType;
|
||||||
|
@ -57,6 +67,8 @@
|
||||||
const props = defineProps<UploadProps>();
|
const props = defineProps<UploadProps>();
|
||||||
const emit = defineEmits(['update:fileList']);
|
const emit = defineEmits(['update:fileList']);
|
||||||
|
|
||||||
|
const defaultMaxSize = 50;
|
||||||
|
|
||||||
const fileList = ref<FileItem[]>(props.fileList);
|
const fileList = ref<FileItem[]>(props.fileList);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -80,11 +92,16 @@
|
||||||
jar: 'icon-icon_file-jar_colorful',
|
jar: 'icon-icon_file-jar_colorful',
|
||||||
};
|
};
|
||||||
|
|
||||||
async function beforeUpload() {
|
async function beforeUpload(file: File) {
|
||||||
if (!props.multiple && fileList.value.length > 0) {
|
if (!props.multiple && fileList.value.length > 0) {
|
||||||
// 单文件上传时,清空之前的文件
|
// 单文件上传时,清空之前的文件
|
||||||
fileList.value = [];
|
fileList.value = [];
|
||||||
}
|
}
|
||||||
|
const maxSize = props.maxSize || defaultMaxSize;
|
||||||
|
if (file.size > maxSize * 1024 * 1024) {
|
||||||
|
Message.warning(t('ms.upload.overSize'));
|
||||||
|
return Promise.resolve(false);
|
||||||
|
}
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
export default {
|
export default {
|
||||||
'ms.upload.changeFile': 'Change file',
|
'ms.upload.changeFile': 'Change file',
|
||||||
|
'ms.upload.overSize': 'The file size exceeds the limit, please reselect the file',
|
||||||
|
'ms.upload.importModalDragtext': 'Drag or click this area to select a file',
|
||||||
|
'ms.upload.importModalFileTip': 'Only {type} format files are supported, and the file size does not exceed {size} MB',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
export default {
|
export default {
|
||||||
'ms.upload.changeFile': '更改文件',
|
'ms.upload.changeFile': '更改文件',
|
||||||
|
'ms.upload.overSize': '文件大小超出限制,请重新选择文件',
|
||||||
|
'ms.upload.importModalDragtext': '拖拽或点击此区域选择文件',
|
||||||
|
'ms.upload.importModalFileTip': '只支持 {type} 格式文件,文件大小不超过 {size} MB',
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,4 +9,6 @@ export enum TableModuleEnum {
|
||||||
export enum TableKeyEnum {
|
export enum TableKeyEnum {
|
||||||
API_TEST = 'apiTest',
|
API_TEST = 'apiTest',
|
||||||
USERGROUPUSER = 'userGroupUser',
|
USERGROUPUSER = 'userGroupUser',
|
||||||
|
SYSTEM_USER = 'systemUser',
|
||||||
|
SYSTEM_RESOURCEPOOL = 'systemResourcePool',
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
:style="{
|
:style="{
|
||||||
overflow: 'auto',
|
overflow: 'auto',
|
||||||
width: `calc(100vw - ${menuWidth}px)`,
|
width: `calc(100vw - ${menuWidth}px)`,
|
||||||
height: 'calc(100vh - 72px)',
|
height: 'calc(100vh - 64px)',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<MsBreadCrumb />
|
<MsBreadCrumb />
|
||||||
|
|
|
@ -6,6 +6,12 @@ export interface NodesListItem {
|
||||||
concurrentNumber: number;
|
concurrentNumber: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 应用组织id和name映射对象
|
||||||
|
export interface OrgIdNameMap {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
// 资源池配置信息对象
|
// 资源池配置信息对象
|
||||||
export interface TestResourceDTO {
|
export interface TestResourceDTO {
|
||||||
loadTestImage: string; // 镜像
|
loadTestImage: string; // 镜像
|
||||||
|
@ -22,6 +28,7 @@ export interface TestResourceDTO {
|
||||||
uiGrid: string; // ui测试selenium-grid
|
uiGrid: string; // ui测试selenium-grid
|
||||||
girdConcurrentNumber: number; // ui测试selenium-grid最大并发数
|
girdConcurrentNumber: number; // ui测试selenium-grid最大并发数
|
||||||
orgIds: string[]; // 应用范围选择指定组织时的id集合
|
orgIds: string[]; // 应用范围选择指定组织时的id集合
|
||||||
|
orgIdNameMap: OrgIdNameMap[]; // 应用范围选择指定组织时的id和name映射
|
||||||
}
|
}
|
||||||
|
|
||||||
// 资源池信息对象
|
// 资源池信息对象
|
||||||
|
@ -43,7 +50,18 @@ export interface ResourcePoolItem extends ResourcePoolInfo {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ResourcePoolDetail = Omit<ResourcePoolInfo, 'testResourceDTO'> & {
|
||||||
|
id: string;
|
||||||
|
testResourceReturnDTO: TestResourceDTO;
|
||||||
|
};
|
||||||
|
|
||||||
// 添加资源池参数对象
|
// 添加资源池参数对象
|
||||||
export type AddResourcePoolParams = Omit<ResourcePoolInfo, 'testResourceDTO'> & {
|
export type AddResourcePoolParams = Omit<ResourcePoolInfo, 'testResourceDTO'> & {
|
||||||
testResourceDTO?: Partial<TestResourceDTO>;
|
testResourceDTO?: Partial<TestResourceDTO>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 更新资源池参数对象
|
||||||
|
export type UpdateResourcePoolParams = Omit<ResourcePoolInfo, 'testResourceDTO'> & {
|
||||||
|
id: string;
|
||||||
|
testResourceDTO?: Partial<TestResourceDTO>;
|
||||||
|
};
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<MsDrawer v-model:visible="showJobDrawer" width="680px" :title="t('system.resourcePool.customJobTemplate')">
|
<MsDrawer
|
||||||
|
v-model:visible="showJobDrawer"
|
||||||
|
width="680px"
|
||||||
|
:title="t('system.resourcePool.customJobTemplate')"
|
||||||
|
:footer="false"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
<MsCodeEditor
|
<MsCodeEditor
|
||||||
v-model:model-value="jobDefinition"
|
v-model:model-value="jobDefinition"
|
||||||
title="YAML"
|
title="YAML"
|
||||||
width="100%"
|
width="100%"
|
||||||
height="calc(100vh - 205px)"
|
height="calc(100vh - 205px)"
|
||||||
theme="MS-text"
|
theme="MS-text"
|
||||||
|
:read-only="props.readOnly"
|
||||||
/>
|
/>
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -18,14 +25,16 @@
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
value: string | null;
|
value?: string | null;
|
||||||
|
defaultVal?: string | null;
|
||||||
|
readOnly?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits(['update:value', 'update:visible']);
|
const emit = defineEmits(['update:value', 'update:visible']);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const showJobDrawer = ref(props.visible);
|
const showJobDrawer = ref(props.visible);
|
||||||
const jobDefinition = ref(props.value || '');
|
const jobDefinition = ref(props.defaultVal || props.value || '');
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.visible,
|
() => props.visible,
|
||||||
|
@ -34,12 +43,34 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.defaultVal,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
jobDefinition.value = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
jobDefinition.value = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => showJobDrawer.value,
|
() => showJobDrawer.value,
|
||||||
(val) => {
|
(val) => {
|
||||||
emit('update:visible', val);
|
emit('update:visible', val);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
emit('update:value', jobDefinition.value);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<MsCard :loading="loading" :title="title" @save="beforeSave" @save-and-continue="beforeSave(true)">
|
<MsCard
|
||||||
|
:loading="loading"
|
||||||
|
:title="title"
|
||||||
|
:is-edit="isEdit"
|
||||||
|
:special-height="34"
|
||||||
|
@save="beforeSave"
|
||||||
|
@save-and-continue="beforeSave(true)"
|
||||||
|
>
|
||||||
<a-form ref="formRef" :model="form" layout="vertical">
|
<a-form ref="formRef" :model="form" layout="vertical">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('system.resourcePool.name')"
|
:label="t('system.resourcePool.name')"
|
||||||
|
@ -318,15 +325,15 @@
|
||||||
</template>
|
</template>
|
||||||
</a-form>
|
</a-form>
|
||||||
<template #footerLeft>
|
<template #footerLeft>
|
||||||
<a-button v-if="isCheckedPerformance" type="text" @click="showJobDrawer = true">
|
<MsButton v-if="isCheckedPerformance && isShowK8SResources" @click="showJobDrawer = true">
|
||||||
{{ t('system.resourcePool.customJobTemplate') }}
|
{{ t('system.resourcePool.customJobTemplate') }}
|
||||||
<a-tooltip :content="t('system.resourcePool.jobTemplateTip')" position="tl" mini>
|
<a-tooltip :content="t('system.resourcePool.jobTemplateTip')" position="tl" mini>
|
||||||
<icon-question-circle class="ml-[4px] text-[var(--color-text-4)] hover:text-[rgb(var(--primary-6))]" />
|
<icon-question-circle class="ml-[4px] text-[var(--color-text-4)] hover:text-[rgb(var(--primary-6))]" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-button>
|
</MsButton>
|
||||||
</template>
|
</template>
|
||||||
</MsCard>
|
</MsCard>
|
||||||
<JobTemplateDrawer v-model:visible="showJobDrawer" :value="form.testResourceDTO.jobDefinition" />
|
<JobTemplateDrawer v-model:visible="showJobDrawer" v-model:value="form.testResourceDTO.jobDefinition" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -336,16 +343,17 @@
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useVisit from '@/hooks/useVisit';
|
import useVisit from '@/hooks/useVisit';
|
||||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
import MsBatchForm from '@/components/bussiness/ms-batch-form/index.vue';
|
import MsBatchForm from '@/components/bussiness/ms-batch-form/index.vue';
|
||||||
import MsCodeEditor from '@/components/pure/ms-code-editor/index.vue';
|
import MsCodeEditor from '@/components/pure/ms-code-editor/index.vue';
|
||||||
import JobTemplateDrawer from './components/jobTemplateDrawer.vue';
|
import JobTemplateDrawer from './components/jobTemplateDrawer.vue';
|
||||||
import { getYaml, YamlType, job } from './template';
|
import { getYaml, YamlType, job } from './template';
|
||||||
import { downloadStringFile, sleep } from '@/utils';
|
import { downloadStringFile, sleep } from '@/utils';
|
||||||
import { scrollIntoView } from '@/utils/dom';
|
import { scrollIntoView } from '@/utils/dom';
|
||||||
import { addPool, getPoolInfo } from '@/api/modules/setting/resourcePool';
|
import { addPool, getPoolInfo, updatePoolInfo } from '@/api/modules/setting/resourcePool';
|
||||||
|
|
||||||
import type { MsBatchFormInstance, FormItemModel } from '@/components/bussiness/ms-batch-form/types';
|
import type { MsBatchFormInstance, FormItemModel } from '@/components/bussiness/ms-batch-form/types';
|
||||||
import type { AddResourcePoolParams, NodesListItem } from '@/models/setting/resourcePool';
|
import type { UpdateResourcePoolParams, NodesListItem } from '@/models/setting/resourcePool';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -402,18 +410,19 @@
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await getPoolInfo(route.query.id);
|
const res = await getPoolInfo(route.query.id);
|
||||||
const { testResourceDTO } = res;
|
const { testResourceReturnDTO } = res;
|
||||||
const { girdConcurrentNumber, podThreads, concurrentNumber } = testResourceDTO;
|
const { girdConcurrentNumber, podThreads, concurrentNumber, orgIdNameMap } = testResourceReturnDTO;
|
||||||
form.value = {
|
form.value = {
|
||||||
...res,
|
...res,
|
||||||
addType: 'single',
|
addType: 'single',
|
||||||
orgType: res.allOrg ? 'allOrg' : 'set',
|
orgType: res.allOrg ? 'allOrg' : 'set',
|
||||||
use: [res.loadTest ? 'performance' : '', res.apiTest ? 'API' : '', res.uiTest ? 'UI' : ''].filter((e) => e),
|
use: [res.loadTest ? 'performance' : '', res.apiTest ? 'API' : '', res.uiTest ? 'UI' : ''].filter((e) => e),
|
||||||
testResourceDTO: {
|
testResourceDTO: {
|
||||||
...testResourceDTO,
|
...testResourceReturnDTO,
|
||||||
girdConcurrentNumber: girdConcurrentNumber || 1,
|
girdConcurrentNumber: girdConcurrentNumber || 1,
|
||||||
podThreads: podThreads || 1,
|
podThreads: podThreads || 1,
|
||||||
concurrentNumber: concurrentNumber || 1,
|
concurrentNumber: concurrentNumber || 1,
|
||||||
|
orgIds: orgIdNameMap?.map((e) => e.id) || [],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -558,10 +567,9 @@
|
||||||
* 解析代码编辑器内容
|
* 解析代码编辑器内容
|
||||||
*/
|
*/
|
||||||
function analyzeCode() {
|
function analyzeCode() {
|
||||||
const arr = editorContent.value.split('\r'); // 以回车符分割
|
const arr = editorContent.value.replaceAll('\r', '\n').split('\n'); // 先将回车符替换成换行符,避免粘贴的代码是以回车符分割的,然后以换行符分割
|
||||||
// 将代码编辑器内写的内容抽取出来
|
// 将代码编辑器内写的内容抽取出来
|
||||||
arr.forEach((e, i) => {
|
arr.forEach((e, i) => {
|
||||||
e = e.replaceAll('\n', ''); // 去除换行符
|
|
||||||
if (e.trim() !== '') {
|
if (e.trim() !== '') {
|
||||||
// 排除空串
|
// 排除空串
|
||||||
const line = e.split(',');
|
const line = e.split(',');
|
||||||
|
@ -648,7 +656,7 @@
|
||||||
/**
|
/**
|
||||||
* 拼接添加资源池参数
|
* 拼接添加资源池参数
|
||||||
*/
|
*/
|
||||||
function makeResourcePoolParams(): AddResourcePoolParams {
|
function makeResourcePoolParams(): UpdateResourcePoolParams {
|
||||||
const { type, testResourceDTO } = form.value;
|
const { type, testResourceDTO } = form.value;
|
||||||
const {
|
const {
|
||||||
ip,
|
ip,
|
||||||
|
@ -678,7 +686,6 @@
|
||||||
nameSpaces,
|
nameSpaces,
|
||||||
concurrentNumber,
|
concurrentNumber,
|
||||||
podThreads,
|
podThreads,
|
||||||
jobDefinition,
|
|
||||||
apiTestImage,
|
apiTestImage,
|
||||||
deployName,
|
deployName,
|
||||||
}
|
}
|
||||||
|
@ -706,14 +713,16 @@
|
||||||
girdConcurrentNumber,
|
girdConcurrentNumber,
|
||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
|
|
||||||
|
const jobDTO = isCheckedPerformance.value && isShowK8SResources ? { jobDefinition } : {};
|
||||||
return {
|
return {
|
||||||
...form.value,
|
...form.value,
|
||||||
type: isShowTypeItem.value ? form.value.type : '',
|
type: isShowTypeItem.value ? form.value.type : 'Node', // 默认给 Node,后台需要
|
||||||
allOrg: form.value.orgType === 'allOrg',
|
allOrg: form.value.orgType === 'allOrg',
|
||||||
apiTest: form.value.use.includes('API'), // 是否支持api测试
|
apiTest: form.value.use.includes('API'), // 是否支持api测试
|
||||||
loadTest: form.value.use.includes('performance'), // 是否支持性能测试
|
loadTest: form.value.use.includes('performance'), // 是否支持性能测试
|
||||||
uiTest: form.value.use.includes('UI'), // 是否支持ui测试
|
uiTest: form.value.use.includes('UI'), // 是否支持ui测试
|
||||||
testResourceDTO: { ...performanceDTO, ...apiDTO, ...uiDTO, orgIds: form.value.testResourceDTO.orgIds },
|
testResourceDTO: { ...performanceDTO, ...apiDTO, ...uiDTO, ...jobDTO, orgIds: form.value.testResourceDTO.orgIds },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,8 +730,13 @@
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const params = makeResourcePoolParams();
|
const params = makeResourcePoolParams();
|
||||||
|
if (isEdit.value) {
|
||||||
|
await updatePoolInfo(params);
|
||||||
|
Message.success(t('system.resourcePool.updateSuccess'));
|
||||||
|
} else {
|
||||||
await addPool(params);
|
await addPool(params);
|
||||||
Message.success(t('system.resourcePool.addSuccess'));
|
Message.success(t('system.resourcePool.addSuccess'));
|
||||||
|
}
|
||||||
if (isContinueAdd.value) {
|
if (isContinueAdd.value) {
|
||||||
resetForm();
|
resetForm();
|
||||||
} else {
|
} else {
|
||||||
|
@ -795,4 +809,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@/models/setting/resourcePool @/api/modules/setting/resourcePool
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
<MsCard :loading="loading" simple>
|
||||||
<div class="mb-4 flex items-center justify-between">
|
<div class="mb-4 flex items-center justify-between">
|
||||||
<a-button type="primary" @click="addPool">
|
<a-button type="primary" @click="addPool">
|
||||||
{{ t('system.resourcePool.createPool') }}
|
{{ t('system.resourcePool.createPool') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-input-search
|
<a-input-search
|
||||||
|
v-model:model-value="keyword"
|
||||||
:placeholder="t('system.resourcePool.searchPool')"
|
:placeholder="t('system.resourcePool.searchPool')"
|
||||||
class="w-[230px]"
|
class="w-[230px]"
|
||||||
|
allow-clear
|
||||||
@search="searchPool"
|
@search="searchPool"
|
||||||
|
@press-enter="searchPool"
|
||||||
></a-input-search>
|
></a-input-search>
|
||||||
</div>
|
</div>
|
||||||
<ms-base-table v-bind="propsRes" no-disable v-on="propsEvent">
|
<ms-base-table v-bind="propsRes" no-disable v-on="propsEvent">
|
||||||
|
@ -32,6 +37,7 @@
|
||||||
<MsTableMoreAction :list="tableActions" @select="handleSelect($event, record)"></MsTableMoreAction>
|
<MsTableMoreAction :list="tableActions" @select="handleSelect($event, record)"></MsTableMoreAction>
|
||||||
</template>
|
</template>
|
||||||
</ms-base-table>
|
</ms-base-table>
|
||||||
|
</MsCard>
|
||||||
<MsDrawer
|
<MsDrawer
|
||||||
v-model:visible="showDetailDrawer"
|
v-model:visible="showDetailDrawer"
|
||||||
width="480px"
|
width="480px"
|
||||||
|
@ -48,7 +54,12 @@
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
<JobTemplateDrawer v-model:visible="showJobDrawer" :value="activePool?.testResourceDTO.jobDefinition || ''" />
|
<JobTemplateDrawer
|
||||||
|
v-model:visible="showJobDrawer"
|
||||||
|
:default-val="activePool?.testResourceDTO.jobDefinition || ''"
|
||||||
|
read-only
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -56,14 +67,17 @@
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { getPoolList } from '@/api/modules/setting/resourcePool';
|
import { getPoolList, delPoolInfo, togglePoolStatus } from '@/api/modules/setting/resourcePool';
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||||
import JobTemplateDrawer from './components/jobTemplateDrawer.vue';
|
import JobTemplateDrawer from './components/jobTemplateDrawer.vue';
|
||||||
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
import { useTableStore } from '@/store';
|
||||||
|
|
||||||
import type { Description } from '@/components/pure/ms-description/index.vue';
|
import type { Description } from '@/components/pure/ms-description/index.vue';
|
||||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
|
@ -79,37 +93,46 @@
|
||||||
slotName: 'name',
|
slotName: 'name',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
width: 200,
|
width: 200,
|
||||||
|
showInTable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.resourcePool.tableColunmStatus',
|
title: 'system.resourcePool.tableColunmStatus',
|
||||||
slotName: 'enable',
|
slotName: 'enable',
|
||||||
dataIndex: 'enable',
|
dataIndex: 'enable',
|
||||||
|
showInTable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.resourcePool.tableColunmDescription',
|
title: 'system.resourcePool.tableColunmDescription',
|
||||||
dataIndex: 'description',
|
dataIndex: 'description',
|
||||||
|
showInTable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.resourcePool.tableColunmType',
|
title: 'system.resourcePool.tableColunmType',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
|
showInTable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.resourcePool.tableColunmCreateTime',
|
title: 'system.resourcePool.tableColunmCreateTime',
|
||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
|
showInTable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.resourcePool.tableColunmUpdateTime',
|
title: 'system.resourcePool.tableColunmUpdateTime',
|
||||||
dataIndex: 'updateTime',
|
dataIndex: 'updateTime',
|
||||||
|
showInTable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.resourcePool.tableColunmActions',
|
title: 'system.resourcePool.tableColunmActions',
|
||||||
slotName: 'action',
|
slotName: 'action',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
width: 120,
|
width: 120,
|
||||||
|
showInTable: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
const tableStore = useTableStore();
|
||||||
|
tableStore.initColumn(TableKeyEnum.SYSTEM_RESOURCEPOOL, columns, 'drawer');
|
||||||
const { propsRes, propsEvent, loadList, setKeyword } = useTable(getPoolList, {
|
const { propsRes, propsEvent, loadList, setKeyword } = useTable(getPoolList, {
|
||||||
|
tableKey: TableKeyEnum.SYSTEM_RESOURCEPOOL,
|
||||||
columns,
|
columns,
|
||||||
scroll: { y: 'auto' },
|
scroll: { y: 'auto' },
|
||||||
selectable: false,
|
selectable: false,
|
||||||
|
@ -138,19 +161,25 @@
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启用资源池
|
* 启用资源池
|
||||||
*/
|
*/
|
||||||
function enablePool(record: any) {
|
async function enablePool(record: any) {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
await togglePoolStatus(record.id);
|
||||||
Message.success(t('system.resourcePool.enablePoolSuccess'));
|
Message.success(t('system.resourcePool.enablePoolSuccess'));
|
||||||
return true;
|
loadList();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return false;
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const disableLoading = ref(false);
|
||||||
/**
|
/**
|
||||||
* 禁用资源池
|
* 禁用资源池
|
||||||
*/
|
*/
|
||||||
|
@ -164,19 +193,30 @@
|
||||||
okButtonProps: {
|
okButtonProps: {
|
||||||
status: 'danger',
|
status: 'danger',
|
||||||
},
|
},
|
||||||
|
cancelButtonProps: {
|
||||||
|
disabled: disableLoading.value,
|
||||||
|
},
|
||||||
|
okLoading: disableLoading.value,
|
||||||
|
maskClosable: false,
|
||||||
onBeforeOk: async () => {
|
onBeforeOk: async () => {
|
||||||
try {
|
try {
|
||||||
|
disableLoading.value = true;
|
||||||
|
await togglePoolStatus(record.id);
|
||||||
Message.success(t('system.resourcePool.disablePoolSuccess'));
|
Message.success(t('system.resourcePool.disablePoolSuccess'));
|
||||||
|
loadList();
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
disableLoading.value = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hideCancel: false,
|
hideCancel: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const delLoading = ref(false);
|
||||||
/**
|
/**
|
||||||
* 删除资源池
|
* 删除资源池
|
||||||
*/
|
*/
|
||||||
|
@ -190,13 +230,23 @@
|
||||||
okButtonProps: {
|
okButtonProps: {
|
||||||
status: 'danger',
|
status: 'danger',
|
||||||
},
|
},
|
||||||
|
cancelButtonProps: {
|
||||||
|
disabled: delLoading.value,
|
||||||
|
},
|
||||||
|
maskClosable: false,
|
||||||
|
okLoading: delLoading.value,
|
||||||
onBeforeOk: async () => {
|
onBeforeOk: async () => {
|
||||||
try {
|
try {
|
||||||
|
delLoading.value = true;
|
||||||
|
await delPoolInfo(record.id);
|
||||||
Message.success(t('system.resourcePool.deletePoolSuccess'));
|
Message.success(t('system.resourcePool.deletePoolSuccess'));
|
||||||
|
loadList();
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
delLoading.value = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hideCancel: false,
|
hideCancel: false,
|
||||||
|
@ -242,6 +292,7 @@
|
||||||
podThreads, // k8s 单pod最大线程数
|
podThreads, // k8s 单pod最大线程数
|
||||||
apiTestImage, // k8s api测试镜像
|
apiTestImage, // k8s api测试镜像
|
||||||
deployName, // k8s api测试部署名称
|
deployName, // k8s api测试部署名称
|
||||||
|
girdConcurrentNumber,
|
||||||
nodesList,
|
nodesList,
|
||||||
loadTestImage,
|
loadTestImage,
|
||||||
loadTestHeap,
|
loadTestHeap,
|
||||||
|
@ -290,6 +341,11 @@
|
||||||
label: t('system.resourcePool.testResourceDTO.podThreads'),
|
label: t('system.resourcePool.testResourceDTO.podThreads'),
|
||||||
value: podThreads,
|
value: podThreads,
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
const jobTemplate =
|
||||||
|
loadTest && type === 'Kubernetes'
|
||||||
|
? [
|
||||||
{
|
{
|
||||||
label: t('system.resourcePool.jobTemplate'),
|
label: t('system.resourcePool.jobTemplate'),
|
||||||
value: t('system.resourcePool.customJobTemplate'),
|
value: t('system.resourcePool.customJobTemplate'),
|
||||||
|
@ -324,7 +380,17 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('system.resourcePool.concurrentNumber'),
|
label: t('system.resourcePool.concurrentNumber'),
|
||||||
value: concurrentNumber,
|
value: girdConcurrentNumber,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const detailType =
|
||||||
|
apiTest || loadTest
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
label: t('system.resourcePool.detailType'),
|
||||||
|
value: activePool.value.type,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [];
|
: [];
|
||||||
|
@ -341,7 +407,7 @@
|
||||||
label: t('system.resourcePool.detailRange'),
|
label: t('system.resourcePool.detailRange'),
|
||||||
value: activePool.value.allOrg
|
value: activePool.value.allOrg
|
||||||
? [t('system.resourcePool.orgAll')]
|
? [t('system.resourcePool.orgAll')]
|
||||||
: activePool.value.testResourceDTO.orgIds.join(','),
|
: activePool.value.testResourceDTO.orgIdNameMap.map((e) => e.name),
|
||||||
isTag: true,
|
isTag: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -351,11 +417,9 @@
|
||||||
},
|
},
|
||||||
...performanceDesc,
|
...performanceDesc,
|
||||||
...uiDesc,
|
...uiDesc,
|
||||||
{
|
...detailType,
|
||||||
label: t('system.resourcePool.detailType'),
|
|
||||||
value: activePool.value.type,
|
|
||||||
},
|
|
||||||
...resourceDesc,
|
...resourceDesc,
|
||||||
|
...jobTemplate,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +443,7 @@
|
||||||
* 添加资源池
|
* 添加资源池
|
||||||
* @param record
|
* @param record
|
||||||
*/
|
*/
|
||||||
function addPool(record: any) {
|
function addPool() {
|
||||||
router.push({
|
router.push({
|
||||||
name: 'settingSystemResourcePoolDetail',
|
name: 'settingSystemResourcePoolDetail',
|
||||||
});
|
});
|
||||||
|
@ -387,4 +451,3 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
@/models/setting/resourcePool @/api/modules/setting/resourcePool
|
|
||||||
|
|
Loading…
Reference in New Issue