fix(all): 修复bugs
This commit is contained in:
parent
9e3799b5f2
commit
a5f51e6866
|
@ -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"
|
||||||
|
|
|
@ -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(() => {
|
||||||
|
|
|
@ -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']);
|
||||||
|
|
|
@ -273,71 +273,73 @@
|
||||||
{{ t('apiTestDebug.introduceSource') }}
|
{{ t('apiTestDebug.introduceSource') }}
|
||||||
</MsButton>
|
</MsButton>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-[8px] text-[var(--color-text-1)]">{{ t('apiTestDebug.sqlScript') }}</div>
|
<template v-if="condition.dataSourceId">
|
||||||
<div class="mb-[8px] h-[300px]">
|
<div class="mb-[8px] text-[var(--color-text-1)]">{{ t('apiTestDebug.sqlScript') }}</div>
|
||||||
<MsCodeEditor
|
<div class="mb-[8px] h-[300px]">
|
||||||
v-model:model-value="condition.script"
|
<MsCodeEditor
|
||||||
:read-only="props.disabled"
|
v-model:model-value="condition.script"
|
||||||
theme="vs"
|
:read-only="props.disabled"
|
||||||
height="120px"
|
theme="vs"
|
||||||
:language="LanguageEnum.SQL"
|
height="120px"
|
||||||
:show-full-screen="false"
|
:language="LanguageEnum.SQL"
|
||||||
:show-theme-change="false"
|
:show-full-screen="false"
|
||||||
@change="() => emit('change')"
|
:show-theme-change="false"
|
||||||
>
|
@change="() => emit('change')"
|
||||||
</MsCodeEditor>
|
>
|
||||||
</div>
|
</MsCodeEditor>
|
||||||
<div class="mb-[8px]">
|
|
||||||
<div class="mb-[8px] flex items-center text-[var(--color-text-1)]">
|
|
||||||
{{ t('apiTestDebug.storageByCol') }}
|
|
||||||
<a-tooltip position="right" :content="t('apiTestDebug.storageColTip')">
|
|
||||||
<icon-question-circle
|
|
||||||
class="ml-[4px] text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-5))]"
|
|
||||||
size="16"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
<a-input
|
<div class="mb-[8px]">
|
||||||
v-model:model-value="condition.variableNames"
|
<div class="mb-[8px] flex items-center text-[var(--color-text-1)]">
|
||||||
:max-length="255"
|
{{ t('apiTestDebug.storageByCol') }}
|
||||||
:disabled="props.disabled"
|
<a-tooltip position="right" :content="t('apiTestDebug.storageColTip')">
|
||||||
:placeholder="
|
<icon-question-circle
|
||||||
t('apiTestDebug.storageByColPlaceholder', { a: 'id', b: 'email', c: '${id_1}', d: '${email_1}' })
|
class="ml-[4px] text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-5))]"
|
||||||
"
|
size="16"
|
||||||
@input="() => emit('change')"
|
/>
|
||||||
/>
|
</a-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="sql-table-container">
|
<a-input
|
||||||
<div class="mb-[8px] text-[var(--color-text-1)]">
|
v-model:model-value="condition.variableNames"
|
||||||
{{ t('apiTestDebug.extractParameter') }}
|
:max-length="255"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
:placeholder="
|
||||||
|
t('apiTestDebug.storageByColPlaceholder', { a: 'id', b: 'email', c: '${id_1}', d: '${email_1}' })
|
||||||
|
"
|
||||||
|
@input="() => emit('change')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<paramTable
|
<div class="sql-table-container">
|
||||||
:params="condition.extractParams"
|
<div class="mb-[8px] text-[var(--color-text-1)]">
|
||||||
:disabled-except-param="props.disabled"
|
{{ t('apiTestDebug.extractParameter') }}
|
||||||
:columns="sqlSourceColumns"
|
</div>
|
||||||
:selectable="false"
|
<paramTable
|
||||||
:default-param-item="defaultKeyValueParamItem"
|
:params="condition.extractParams"
|
||||||
@change="handleSqlSourceParamTableChange"
|
:disabled-except-param="props.disabled"
|
||||||
/>
|
:columns="sqlSourceColumns"
|
||||||
</div>
|
:selectable="false"
|
||||||
<div class="mt-[8px]">
|
:default-param-item="defaultKeyValueParamItem"
|
||||||
<div class="mb-[8px] flex items-center text-[var(--color-text-1)]">
|
@change="handleSqlSourceParamTableChange"
|
||||||
{{ t('apiTestDebug.storageByResult') }}
|
/>
|
||||||
<a-tooltip position="right" :content="t('apiTestDebug.storageResultTip')">
|
|
||||||
<icon-question-circle
|
|
||||||
class="ml-[4px] text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-5))]"
|
|
||||||
size="16"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
<a-input
|
<div class="mt-[8px]">
|
||||||
v-model:model-value="condition.resultVariable"
|
<div class="mb-[8px] flex items-center text-[var(--color-text-1)]">
|
||||||
:disabled="props.disabled"
|
{{ t('apiTestDebug.storageByResult') }}
|
||||||
:max-length="255"
|
<a-tooltip position="right" :content="t('apiTestDebug.storageResultTip')">
|
||||||
:placeholder="t('apiTestDebug.storageByResultPlaceholder', { a: 'result', b: '${result}' })"
|
<icon-question-circle
|
||||||
@input="() => emit('change')"
|
class="ml-[4px] text-[var(--color-text-brand)] hover:text-[rgb(var(--primary-5))]"
|
||||||
/>
|
size="16"
|
||||||
</div>
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
<a-input
|
||||||
|
v-model:model-value="condition.resultVariable"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
:max-length="255"
|
||||||
|
:placeholder="t('apiTestDebug.storageByResultPlaceholder', { a: 'result', b: '${result}' })"
|
||||||
|
@input="() => emit('change')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<!-- 等待时间 -->
|
<!-- 等待时间 -->
|
||||||
<div v-else-if="condition.processorType === RequestConditionProcessor.TIME_WAITING">
|
<div v-else-if="condition.processorType === RequestConditionProcessor.TIME_WAITING">
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
// 如果点击的请求在tab中已经存在,则直接切换到该tab
|
// 如果点击的请求在tab中已经存在,则直接切换到该tab
|
||||||
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, // request里面还有个name但是是null
|
name: res.name, // request里面还有个name但是是null
|
||||||
moduleId: res.moduleId, // request里面还有个moduleId但是是null
|
moduleId: res.moduleId, // request里面还有个moduleId但是是null
|
||||||
...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>
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}>();
|
}>();
|
||||||
|
|
|
@ -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) {
|
await refreshScenarioStepInfo(realStep as ScenarioStepItem, realStep.resourceId);
|
||||||
child.isRefScenarioStep = true;
|
} else {
|
||||||
child.enable = true;
|
realStep.children = mapTree<ScenarioStepItem>(realStep.children || [], (child) => {
|
||||||
} else {
|
// 更新子孙步骤-步骤引用
|
||||||
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 {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
});
|
});
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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',
|
||||||
};
|
};
|
||||||
|
|
|
@ -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': '至少保留一个资源池',
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue