fix(all): 修复bugs

This commit is contained in:
baiqi 2024-04-12 14:54:21 +08:00 committed by Craftsman
parent 9e3799b5f2
commit a5f51e6866
17 changed files with 174 additions and 127 deletions

View File

@ -6,6 +6,7 @@
:footer="true" :footer="true"
unmount-on-close unmount-on-close
:ok-loading="props.confirmLoading" :ok-loading="props.confirmLoading"
:mask-closable="false"
save-continue-text="project.commonScript.saveAsDraft" save-continue-text="project.commonScript.saveAsDraft"
ok-text="project.commonScript.apply" ok-text="project.commonScript.apply"
@confirm="handleDrawerConfirm" @confirm="handleDrawerConfirm"

View File

@ -9,7 +9,7 @@
props.autoHeight ? '' : 'h-full min-h-[500px]', props.autoHeight ? '' : 'h-full min-h-[500px]',
props.noContentPadding ? 'ms-card--noContentPadding' : 'p-[24px]', props.noContentPadding ? 'ms-card--noContentPadding' : 'p-[24px]',
props.noBottomRadius ? 'ms-card--noBottomRadius' : '', props.noBottomRadius ? 'ms-card--noBottomRadius' : '',
!props.hideFooter && !props.simple ? 'pb-[80px]' : '', !props.hideFooter && !props.simple ? 'pb-[24px]' : '',
]" ]"
> >
<a-scrollbar v-if="!props.simple" :style="{ overflow: 'auto' }"> <a-scrollbar v-if="!props.simple" :style="{ overflow: 'auto' }">
@ -151,7 +151,7 @@
// //
return props.noContentPadding ? 66 + _specialHeight : 114 + _specialHeight; return props.noContentPadding ? 66 + _specialHeight : 114 + _specialHeight;
} }
return 250 + _specialHeight; return 230 + _specialHeight;
}); });
const getComputedContentStyle = computed(() => { const getComputedContentStyle = computed(() => {

View File

@ -149,6 +149,7 @@
noTitle?: boolean; // noTitle?: boolean; //
drawerStyle?: Record<string, string>; // drawerStyle?: Record<string, string>; //
showFullScreen?: boolean; // showFullScreen?: boolean; //
maskClosable?: boolean; //
} }
const props = withDefaults(defineProps<DrawerProps>(), { const props = withDefaults(defineProps<DrawerProps>(), {
@ -160,6 +161,7 @@
popupContainer: 'body', popupContainer: 'body',
disabledWidthDrag: false, disabledWidthDrag: false,
showFullScreen: false, showFullScreen: false,
maskClosable: true,
okPermission: () => [], // okPermission: () => [], //
}); });
const emit = defineEmits(['update:visible', 'confirm', 'cancel', 'continue', 'close']); const emit = defineEmits(['update:visible', 'confirm', 'cancel', 'continue', 'close']);

View File

@ -273,6 +273,7 @@
{{ t('apiTestDebug.introduceSource') }} {{ t('apiTestDebug.introduceSource') }}
</MsButton> </MsButton>
</div> </div>
<template v-if="condition.dataSourceId">
<div class="mb-[8px] text-[var(--color-text-1)]">{{ t('apiTestDebug.sqlScript') }}</div> <div class="mb-[8px] text-[var(--color-text-1)]">{{ t('apiTestDebug.sqlScript') }}</div>
<div class="mb-[8px] h-[300px]"> <div class="mb-[8px] h-[300px]">
<MsCodeEditor <MsCodeEditor
@ -339,6 +340,7 @@
/> />
</div> </div>
</template> </template>
</template>
<!-- 等待时间 --> <!-- 等待时间 -->
<div v-else-if="condition.processorType === RequestConditionProcessor.TIME_WAITING"> <div v-else-if="condition.processorType === RequestConditionProcessor.TIME_WAITING">
<div class="mb-[8px] flex items-center"> <div class="mb-[8px] flex items-center">

View File

@ -119,7 +119,6 @@
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import result from '@/views/api-test/components/requestComposition/response/result.vue'; import result from '@/views/api-test/components/requestComposition/response/result.vue';
import loopPagination from '@/views/api-test/scenario/components/common/customApiDrawer.vue';
import { reportCaseStepDetail, reportStepDetail } from '@/api/modules/api-test/report'; import { reportCaseStepDetail, reportStepDetail } from '@/api/modules/api-test/report';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
@ -292,6 +291,7 @@
} }
} }
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} finally { } finally {
loading.value = false; loading.value = false;

View File

@ -97,6 +97,7 @@
/** /**
* @description 接口测试-接口调试 * @description 接口测试-接口调试
*/ */
import { useRoute } from 'vue-router';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import MsCard from '@/components/pure/ms-card/index.vue'; import MsCard from '@/components/pure/ms-card/index.vue';
@ -138,6 +139,7 @@
import { defaultBodyParams, defaultResponse } from '../components/config'; import { defaultBodyParams, defaultResponse } from '../components/config';
import { parseRequestBodyFiles } from '../components/utils'; import { parseRequestBodyFiles } from '../components/utils';
const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const moduleTreeRef = ref<InstanceType<typeof moduleTree>>(); const moduleTreeRef = ref<InstanceType<typeof moduleTree>>();
@ -235,8 +237,9 @@
activeDebug.value = debugTabs.value[debugTabs.value.length - 1]; activeDebug.value = debugTabs.value[debugTabs.value.length - 1];
} }
async function openApiTab(apiInfo: ModuleTreeNode) { async function openApiTab(apiInfo: ModuleTreeNode | string) {
const isLoadedTabIndex = debugTabs.value.findIndex((e) => e.id === apiInfo.id); const id = typeof apiInfo === 'string' ? apiInfo : apiInfo.id;
const isLoadedTabIndex = debugTabs.value.findIndex((e) => e.id === id);
if (isLoadedTabIndex > -1) { if (isLoadedTabIndex > -1) {
// tabtab // tabtab
activeDebug.value = debugTabs.value[isLoadedTabIndex]; activeDebug.value = debugTabs.value[isLoadedTabIndex];
@ -244,17 +247,17 @@
} }
try { try {
loading.value = true; loading.value = true;
const res = await getDebugDetail(apiInfo.id); const res = await getDebugDetail(id);
let parseRequestBodyResult; let parseRequestBodyResult;
if (res.protocol === 'HTTP') { if (res.protocol === 'HTTP') {
parseRequestBodyResult = parseRequestBodyFiles(res.request.body); // id parseRequestBodyResult = parseRequestBodyFiles(res.request.body); // id
} }
addDebugTab({ addDebugTab({
label: apiInfo.name,
...res, ...res,
response: cloneDeep(defaultResponse), response: cloneDeep(defaultResponse),
...res.request, ...res.request,
url: res.path, url: res.path,
label: res.name,
name: res.name, // requestnamenull name: res.name, // requestnamenull
moduleId: res.moduleId, // requestmoduleIdnull moduleId: res.moduleId, // requestmoduleIdnull
...parseRequestBodyResult, ...parseRequestBodyResult,
@ -345,6 +348,12 @@
} }
} }
onMounted(() => {
if (route.query.id) {
openApiTab(route.query.id as string);
}
});
useLeaveTabUnSaveCheck(debugTabs.value, ['PROJECT_API_DEBUG:READ+ADD', 'PROJECT_API_DEBUG:READ+UPDATE']); useLeaveTabUnSaveCheck(debugTabs.value, ['PROJECT_API_DEBUG:READ+ADD', 'PROJECT_API_DEBUG:READ+UPDATE']);
</script> </script>

View File

@ -80,7 +80,7 @@
allow-clear allow-clear
class="w-[200px]" class="w-[200px]"
/> --> /> -->
<a-tooltip v-if="!props.isNew" position="left" :content="t('apiScenario.refreshRefScenario')"> <a-tooltip position="left" :content="t('apiScenario.refreshRefScenario')">
<a-button type="outline" class="arco-btn-outline--secondary !mr-0 !p-[8px]" @click="refreshStepInfo"> <a-button type="outline" class="arco-btn-outline--secondary !mr-0 !p-[8px]" @click="refreshStepInfo">
<template #icon> <template #icon>
<icon-refresh class="text-[var(--color-text-4)]" /> <icon-refresh class="text-[var(--color-text-4)]" />
@ -149,9 +149,6 @@
import { ApiScenarioDebugRequest, Scenario, ScenarioStepItem } from '@/models/apiTest/scenario'; import { ApiScenarioDebugRequest, Scenario, ScenarioStepItem } from '@/models/apiTest/scenario';
import { ScenarioExecuteStatus, ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum'; import { ScenarioExecuteStatus, ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum';
const props = defineProps<{
isNew?: boolean; //
}>();
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'batchDebug', data: Pick<ApiScenarioDebugRequest, 'steps' | 'stepDetails' | 'reportId'>): void; (e: 'batchDebug', data: Pick<ApiScenarioDebugRequest, 'steps' | 'stepDetails' | 'reportId'>): void;
}>(); }>();

View File

@ -527,7 +527,7 @@
getDefinitionDetail, getDefinitionDetail,
getModuleTreeOnlyModules, getModuleTreeOnlyModules,
} from '@/api/modules/api-test/management'; } from '@/api/modules/api-test/management';
import { debugScenario, getScenarioStep } from '@/api/modules/api-test/scenario'; import { debugScenario, getScenarioDetail, getScenarioStep } from '@/api/modules/api-test/scenario';
import { getSocket } from '@/api/modules/project-management/commonScript'; import { getSocket } from '@/api/modules/project-management/commonScript';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal'; import useModal from '@/hooks/useModal';
@ -834,8 +834,36 @@
}; };
} }
/**
* 刷新引用场景的步骤数据
*/
async function refreshScenarioStepInfo(step: ScenarioStepItem, id: string | number) {
try {
loading.value = true;
const res = await getScenarioDetail(id);
if (step.children) {
step.children = mapTree(res.steps || [], (child) => {
child.uniqueId = getGenerateId();
child.isQuoteScenarioStep = true; //
child.isRefScenarioStep = true; //
child.draggable = false; //
if (selectedKeys.value.includes(step.uniqueId) && !selectedKeys.value.includes(child.uniqueId)) {
//
selectedKeys.value.push(child.uniqueId);
}
return child;
}) as ScenarioStepItem[];
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
loading.value = false;
}
}
// //
function saveScenarioConfig() { async function saveScenarioConfig() {
if (activeStep.value) { if (activeStep.value) {
const realStep = findNodeByKey<ScenarioStepItem>(steps.value, activeStep.value.uniqueId, 'uniqueId'); const realStep = findNodeByKey<ScenarioStepItem>(steps.value, activeStep.value.uniqueId, 'uniqueId');
if (realStep) { if (realStep) {
@ -844,16 +872,16 @@
...realStep.config, ...realStep.config,
...scenarioConfigForm.value, ...scenarioConfigForm.value,
}; };
realStep.children = mapTree<ScenarioStepItem>(realStep.children || [], (child) => {
//
if (scenarioConfigForm.value.refType === ScenarioStepRefType.REF) { if (scenarioConfigForm.value.refType === ScenarioStepRefType.REF) {
child.isRefScenarioStep = true; //
child.enable = true; await refreshScenarioStepInfo(realStep as ScenarioStepItem, realStep.resourceId);
} else { } else {
realStep.children = mapTree<ScenarioStepItem>(realStep.children || [], (child) => {
// -
child.isRefScenarioStep = false; child.isRefScenarioStep = false;
}
return child; return child;
}); });
}
Message.success(t('apiScenario.setSuccess')); Message.success(t('apiScenario.setSuccess'));
scenario.value.unSaved = true; scenario.value.unSaved = true;
cancelScenarioConfig(); cancelScenarioConfig();
@ -1138,7 +1166,7 @@
}; };
})[0] })[0]
), ),
name: `copy_${node.name}`, name: `copy_${node.name}`.substring(0, 255),
copyFromStepId: stepDetail ? node.id : node.copyFromStepId, copyFromStepId: stepDetail ? node.id : node.copyFromStepId,
sort: node.sort + 1, sort: node.sort + 1,
isNew: true, isNew: true,
@ -1481,7 +1509,6 @@
delete scenario.value.stepResponses[realStep.uniqueId]; // delete scenario.value.stepResponses[realStep.uniqueId]; //
realStep.reportId = getGenerateId(); realStep.reportId = getGenerateId();
realStep.executeStatus = ScenarioExecuteStatus.EXECUTING; realStep.executeStatus = ScenarioExecuteStatus.EXECUTING;
const stepFileParam = scenario.value.stepFileParam[realStep.id];
request.executeLoading = true; request.executeLoading = true;
scenario.value.executeType = executeType; scenario.value.executeType = executeType;
realExecute({ realExecute({
@ -1491,7 +1518,10 @@
}, },
reportId: realStep.reportId, reportId: realStep.reportId,
stepFileParam: { stepFileParam: {
[realStep.uniqueId]: stepFileParam, [realStep.uniqueId]: {
uploadFileIds: request.uploadFileIds || [],
linkFileIds: request.linkFileIds || [],
},
}, },
}); });
} else { } else {

View File

@ -10,7 +10,6 @@
<step <step
v-if="activeKey === ScenarioCreateComposition.STEP" v-if="activeKey === ScenarioCreateComposition.STEP"
v-model:scenario="scenario" v-model:scenario="scenario"
is-new
@batch-debug="emit('batchDebug', $event)" @batch-debug="emit('batchDebug', $event)"
/> />
</a-tab-pane> </a-tab-pane>

View File

@ -308,7 +308,7 @@
node.executeStatus = ScenarioExecuteStatus.EXECUTING; node.executeStatus = ScenarioExecuteStatus.EXECUTING;
waitingDebugStepDetails[node.id] = activeScenarioTab.value.stepDetails[node.id]; waitingDebugStepDetails[node.id] = activeScenarioTab.value.stepDetails[node.id];
} else { } else {
node.executeStatus = ScenarioExecuteStatus.UN_EXECUTE; node.executeStatus = undefined;
} }
return !!node.enable; return !!node.enable;
}); });

View File

@ -21,10 +21,9 @@
<style lang="less" scoped> <style lang="less" scoped>
.banner-wrap { .banner-wrap {
width: 55%;
.img { .img {
width: 100%; width: 100%;
object-fit: fill; object-fit: cover;
} }
} }
</style> </style>

View File

@ -19,13 +19,17 @@
{{ t('system.config.auth.edit') }} {{ t('system.config.auth.edit') }}
</MsButton> </MsButton>
<MsButton <MsButton
v-if="record.enable" v-show="record.enable"
v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE']" v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE']"
@click="disabledAuth(record)" @click="disabledAuth(record)"
> >
{{ t('system.config.auth.disable') }} {{ t('system.config.auth.disable') }}
</MsButton> </MsButton>
<MsButton v-else v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE']" @click="enableAuth(record)"> <MsButton
v-show="!record.enable"
v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE']"
@click="enableAuth(record)"
>
{{ t('system.config.auth.enable') }} {{ t('system.config.auth.enable') }}
</MsButton> </MsButton>
<MsTableMoreAction <MsTableMoreAction
@ -49,7 +53,13 @@
show-description show-description
> >
<template #tbutton> <template #tbutton>
<a-button type="outline" size="mini" :disabled="detailDrawerLoading" @click="editAuth(activeAuthDetail, true)"> <a-button
v-permission="['SYSTEM_PARAMETER_SETTING_AUTH:READ+UPDATE']"
type="outline"
size="mini"
:disabled="detailDrawerLoading"
@click="editAuth(activeAuthDetail, true)"
>
{{ t('system.config.auth.edit') }} {{ t('system.config.auth.edit') }}
</a-button> </a-button>
</template> </template>
@ -584,6 +594,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onBeforeMount, ref } from 'vue'; import { computed, onBeforeMount, ref } from 'vue';
import { useRoute } from 'vue-router';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import MsButton from '@/components/pure/ms-button/index.vue'; import MsButton from '@/components/pure/ms-button/index.vue';
@ -619,6 +630,7 @@
import type { FormInstance, ValidatedError } from '@arco-design/web-vue'; import type { FormInstance, ValidatedError } from '@arco-design/web-vue';
const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const { openModal } = useModal(); const { openModal } = useModal();
const loading = ref(false); const loading = ref(false);
@ -703,6 +715,7 @@
Message.success(t('system.config.auth.enableSuccess')); Message.success(t('system.config.auth.enableSuccess'));
loadList(); loadList();
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} }
}, },
@ -730,6 +743,7 @@
Message.success(t('system.config.auth.disableSuccess')); Message.success(t('system.config.auth.disableSuccess'));
loadList(); loadList();
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} }
}, },
@ -939,7 +953,9 @@
} }
activeAuthDesc.value = description; activeAuthDesc.value = description;
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
showDetailDrawer.value = false;
} finally { } finally {
detailDrawerLoading.value = false; detailDrawerLoading.value = false;
} }
@ -1030,6 +1046,7 @@
}); });
Message.success(t('system.config.auth.testLinkSuccess')); Message.success(t('system.config.auth.testLinkSuccess'));
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} finally { } finally {
LDAPTestLoading.value = false; LDAPTestLoading.value = false;
@ -1056,6 +1073,7 @@
}); });
Message.success(t('system.config.auth.testLinkSuccess')); Message.success(t('system.config.auth.testLinkSuccess'));
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} finally { } finally {
LDAPTestLoading.value = false; LDAPTestLoading.value = false;
@ -1185,21 +1203,12 @@
authFormRef.value?.resetFields(); authFormRef.value?.resetFields();
} }
defineExpose({ onBeforeMount(() => {
openAuthDetail, // ID if (route.query.id) {
openAuthDetail(route.query.id as string);
}
}); });
declare const _default: import('vue').DefineComponent<
unknown,
unknown,
import('vue').ComponentOptionsMixin,
import('vue').ComponentOptionsMixin,
{
openAuthDetail: (id: string) => void;
}
>;
export declare type AuthConfigInstance = InstanceType<typeof _default>;
await tableStore.initColumn(TableKeyEnum.SYSTEM_AUTH, columns, 'drawer'); await tableStore.initColumn(TableKeyEnum.SYSTEM_AUTH, columns, 'drawer');
</script> </script>

View File

@ -2,7 +2,7 @@
<MsTabCard v-model:active-tab="activeTab" :title="t('system.config.parameterConfig')" :tab-list="tabList" /> <MsTabCard v-model:active-tab="activeTab" :title="t('system.config.parameterConfig')" :tab-list="tabList" />
<baseConfig v-if="activeTab === 'baseConfig'" v-show="activeTab === 'baseConfig'" /> <baseConfig v-if="activeTab === 'baseConfig'" v-show="activeTab === 'baseConfig'" />
<pageConfig v-if="isInitPageConfig" v-show="activeTab === 'pageConfig'" /> <pageConfig v-if="isInitPageConfig" v-show="activeTab === 'pageConfig'" />
<authConfig v-if="isInitAuthConfig" v-show="activeTab === 'authConfig'" ref="authConfigRef" /> <authConfig v-if="isInitAuthConfig" v-show="activeTab === 'authConfig'" />
<memoryCleanup v-if="isInitMemoryCleanup" v-show="activeTab === 'memoryCleanup'" /> <memoryCleanup v-if="isInitMemoryCleanup" v-show="activeTab === 'memoryCleanup'" />
</template> </template>
@ -10,7 +10,6 @@
/** /**
* @description 系统设置-系统参数 * @description 系统设置-系统参数
*/ */
import { onMounted, ref, watch } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import MsTabCard from '@/components/pure/ms-tab-card/index.vue'; import MsTabCard from '@/components/pure/ms-tab-card/index.vue';
@ -19,7 +18,6 @@
import useLicenseStore from '@/store/modules/setting/license'; import useLicenseStore from '@/store/modules/setting/license';
import { hasAnyPermission } from '@/utils/permission'; import { hasAnyPermission } from '@/utils/permission';
import type { AuthConfigInstance } from './components/authConfig.vue';
// //
const baseConfig = defineAsyncComponent(() => import('./components/baseConfig.vue')); const baseConfig = defineAsyncComponent(() => import('./components/baseConfig.vue'));
const pageConfig = defineAsyncComponent(() => import('./components/pageConfig.vue')); const pageConfig = defineAsyncComponent(() => import('./components/pageConfig.vue'));
@ -33,7 +31,6 @@
const isInitPageConfig = ref(activeTab.value === 'pageConfig'); const isInitPageConfig = ref(activeTab.value === 'pageConfig');
const isInitAuthConfig = ref(activeTab.value === 'authConfig'); const isInitAuthConfig = ref(activeTab.value === 'authConfig');
const isInitMemoryCleanup = ref(activeTab.value === 'memoryCleanup'); const isInitMemoryCleanup = ref(activeTab.value === 'memoryCleanup');
const authConfigRef = ref<AuthConfigInstance | null>();
const tabList = ref([ const tabList = ref([
{ key: 'baseConfig', title: t('system.config.baseConfig'), permission: ['SYSTEM_PARAMETER_SETTING_BASE:READ'] }, { key: 'baseConfig', title: t('system.config.baseConfig'), permission: ['SYSTEM_PARAMETER_SETTING_BASE:READ'] },
{ key: 'pageConfig', title: t('system.config.pageConfig'), permission: ['SYSTEM_PARAMETER_SETTING_DISPLAY:READ'] }, { key: 'pageConfig', title: t('system.config.pageConfig'), permission: ['SYSTEM_PARAMETER_SETTING_DISPLAY:READ'] },
@ -73,13 +70,7 @@
onBeforeMount(() => { onBeforeMount(() => {
getXpackTab(); getXpackTab();
const firstHasPermissionTab = tabList.value.find((item: any) => hasAnyPermission(item.permission)); const firstHasPermissionTab = tabList.value.find((item: any) => hasAnyPermission(item.permission));
activeTab.value = firstHasPermissionTab?.key || 'baseConfig'; activeTab.value = (route.query.tab as string) || firstHasPermissionTab?.key || 'baseConfig';
});
onMounted(() => {
if (route.query.tab === 'authConfig' && route.query.id) {
authConfigRef.value?.openAuthDetail(route.query.id as string);
}
}); });
</script> </script>

View File

@ -19,9 +19,9 @@
<a-button type="text" class="px-0" @click="showPoolDetail(record.id)">{{ record.name }}</a-button> <a-button type="text" class="px-0" @click="showPoolDetail(record.id)">{{ record.name }}</a-button>
</template> </template>
<template #action="{ record }"> <template #action="{ record }">
<MsButton v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']" @click="editPool(record)">{{ <MsButton v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']" @click="editPool(record)">
t('system.resourcePool.editPool') {{ t('system.resourcePool.editPool') }}
}}</MsButton> </MsButton>
<MsButton <MsButton
v-if="record.enable" v-if="record.enable"
v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']" v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']"
@ -30,9 +30,9 @@
> >
{{ t('system.resourcePool.tableDisable') }} {{ t('system.resourcePool.tableDisable') }}
</MsButton> </MsButton>
<MsButton v-else v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']" v-xpack @click="enablePool(record)">{{ <MsButton v-else v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+UPDATE']" v-xpack @click="enablePool(record)">
t('system.resourcePool.tableEnable') {{ t('system.resourcePool.tableEnable') }}
}}</MsButton> </MsButton>
<MsTableMoreAction <MsTableMoreAction
v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+DELETE']" v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+DELETE']"
:list="tableActions" :list="tableActions"
@ -215,6 +215,7 @@
Message.success(t('system.resourcePool.disablePoolSuccess')); Message.success(t('system.resourcePool.disablePoolSuccess'));
loadList(); loadList();
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} }
}, },
@ -226,6 +227,10 @@
* 删除资源池 * 删除资源池
*/ */
function deletePool(record: any) { function deletePool(record: any) {
if (propsRes.value.data.length === 1) {
Message.warning(t('system.resourcePool.atLeastOnePool'));
return;
}
openModal({ openModal({
type: 'error', type: 'error',
title: t('system.resourcePool.deletePoolTip', { name: characterLimit(record.name) }), title: t('system.resourcePool.deletePoolTip', { name: characterLimit(record.name) }),
@ -242,6 +247,7 @@
Message.success(t('system.resourcePool.deletePoolSuccess')); Message.success(t('system.resourcePool.deletePoolSuccess'));
loadList(); loadList();
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} }
}, },

View File

@ -121,4 +121,5 @@ export default {
'system.resourcePool.jobTemplateReset': 'Reset Template', 'system.resourcePool.jobTemplateReset': 'Reset Template',
'system.resourcePool.addSuccess': 'Added resource pool successfully', 'system.resourcePool.addSuccess': 'Added resource pool successfully',
'system.resourcePool.updateSuccess': 'Resource pool updated successfully', 'system.resourcePool.updateSuccess': 'Resource pool updated successfully',
'system.resourcePool.atLeastOnePool': 'Reserve at least one resource pool',
}; };

View File

@ -116,4 +116,5 @@ export default {
'system.resourcePool.jobTemplateReset': '重置 Job 模板', 'system.resourcePool.jobTemplateReset': '重置 Job 模板',
'system.resourcePool.addSuccess': '添加资源池成功', 'system.resourcePool.addSuccess': '添加资源池成功',
'system.resourcePool.updateSuccess': '更新资源池成功', 'system.resourcePool.updateSuccess': '更新资源池成功',
'system.resourcePool.atLeastOnePool': '至少保留一个资源池',
}; };

View File

@ -322,7 +322,7 @@
import useLocale from '@/locale/useLocale'; import useLocale from '@/locale/useLocale';
import { useTableStore } from '@/store'; import { useTableStore } from '@/store';
import { characterLimit, formatPhoneNumber } from '@/utils'; import { characterLimit, formatPhoneNumber } from '@/utils';
import { hasAnyPermission } from '@/utils/permission'; import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
import { validateEmail, validatePhone } from '@/utils/validate'; import { validateEmail, validatePhone } from '@/utils/validate';
import type { SimpleUserInfo, SystemRole, UserListItem } from '@/models/setting/user'; import type { SimpleUserInfo, SystemRole, UserListItem } from '@/models/setting/user';
@ -387,7 +387,7 @@
{ {
tableKey: TableKeyEnum.SYSTEM_USER, tableKey: TableKeyEnum.SYSTEM_USER,
columns, columns,
selectable: !!hasAnyPermission(['SYSTEM_USER:READ+ADD', 'SYSTEM_USER:READ+UPDATE', 'SYSTEM_USER:READ+DELETE']), selectable: !!hasAnyPermission(['SYSTEM_USER:READ+UPDATE', 'SYSTEM_USER:READ+DELETE']),
showSetting: true, showSetting: true,
heightUsed: 288, heightUsed: 288,
}, },
@ -877,7 +877,7 @@
} }
function handleTagClick(record: UserListItem & Record<string, any>) { function handleTagClick(record: UserListItem & Record<string, any>) {
if (hasAnyPermission(['SYSTEM_USER:READ+UPDATE', 'SYSTEM_USER_ROLE:READ'])) { if (hasAllPermission(['SYSTEM_USER:READ+UPDATE', 'SYSTEM_USER_ROLE:READ'])) {
record.selectUserGroupVisible = true; record.selectUserGroupVisible = true;
} }
} }