feat(接口测试): 接口测试接口文档导出联调&分享权限补充

This commit is contained in:
xinxin.wu 2024-10-17 10:59:38 +08:00 committed by Craftsman
parent 60c9086f3b
commit 9ac9ff57cd
10 changed files with 390 additions and 244 deletions

View File

@ -45,6 +45,7 @@ import {
diffDataUrl,
ExecuteCaseUrl,
ExportDefinitionUrl,
ExportShareDefinitionUrl,
GetApiDownloadFileUrl,
GetCaseBatchExportParamsUrl,
GetCaseDetailUrl,
@ -62,6 +63,7 @@ import {
GetModuleTreeUrl,
GetPoolId,
GetPoolOptionUrl,
GetShareApiDownloadFileUrl,
GetSharePageUrl,
getSyncedCaseDetailUrl,
GetTrashModuleCountUrl,
@ -84,6 +86,7 @@ import {
SortCaseUrl,
SortDefinitionUrl,
StopApiExportUrl,
StopShareApiExportUrl,
SwitchDefinitionScheduleUrl,
ToggleFollowCaseUrl,
ToggleFollowDefinitionUrl,
@ -684,3 +687,23 @@ export function getShareModuleTree(data: ApiDefinitionGetModuleParams) {
export function getShareModuleCount(data: ApiDefinitionGetModuleParams) {
return MSR.post({ url: shareModuleCountUrl, data });
}
// 导出分享定义文档
export function exportShareApiDefinition(data: ApiDefinitionBatchExportParams, type: string) {
return MSR.post({ url: `${ExportShareDefinitionUrl}/${type}`, data });
}
// 获取分享导出的文件
export function getShareApiDownloadFile(projectId: string, fileId: string) {
return MSR.get(
{
url: `${GetShareApiDownloadFileUrl}/${projectId}/${fileId}`,
responseType: 'blob',
},
{ isTransformResponse: false }
);
}
// 停止分享导出
export function stopShareApiExport(taskId: string) {
return MSR.get({ url: `${StopShareApiExportUrl}/${taskId}` });
}

View File

@ -122,3 +122,6 @@ export const checkSharePsdUrl = '/api/doc/share/check'; // 接口测试-接口
export const shareDetailUrl = '/api/doc/share/detail'; // 接口测试-接口管理-查看链接
export const shareModuleTreeUrl = '/api/doc/share/module/tree'; // 接口测试-接口管理-模块树
export const shareModuleCountUrl = '/api/doc/share/module/count'; // 接口测试-接口管理-模块数量
export const ExportShareDefinitionUrl = '/api/doc/share/export'; // 导入分享接口定义
export const GetShareApiDownloadFileUrl = '/api/doc/share/download/file'; // 下载导出的文档
export const StopShareApiExportUrl = '/api/doc/share/stop'; // 停止分享导出

View File

@ -0,0 +1,258 @@
<template>
<a-modal
v-model:visible="visible"
:title="t('common.export')"
title-align="start"
class="ms-modal-upload ms-modal-medium"
:width="400"
>
<div class="mb-[16px] flex gap-[8px]">
<div
v-for="item of platformList"
:key="item.value"
:class="`import-item ${exportPlatform === item.value ? 'import-item--active' : ''}`"
@click="exportPlatform = item.value"
>
<div class="text-[var(--color-text-1)]">{{ item.name }}</div>
</div>
</div>
<template v-if="exportPlatform === RequestExportFormat.MeterSphere">
<div class="mb-[16px] flex items-center gap-[4px]">
<a-switch v-model:model-value="exportApiCase" size="small" />
{{ t('apiTestManagement.exportCase') }}
</div>
<div class="flex items-center gap-[4px]">
<a-switch v-model:model-value="exportApiMock" size="small" />
{{ t('apiTestManagement.exportMock') }}
</div>
</template>
<div v-else-if="exportPlatform === RequestExportFormat.SWAGGER" class="text-[var(--color-text-4)]">
{{ t('apiTestManagement.exportSwaggerTip') }}
</div>
<template #footer>
<div class="flex justify-end">
<a-button type="secondary" :disabled="exportLoading" @click="cancelExport">
{{ t('common.cancel') }}
</a-button>
<a-button class="ml-3" type="primary" :loading="exportLoading" @click="exportApi">
{{ t('common.export') }}
</a-button>
</div>
</template>
</a-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Message } from '@arco-design/web-vue';
import MsButton from '@/components/pure/ms-button/index.vue';
import type { BatchActionQueryParams } from '@/components/pure/ms-table/type';
import {
exportApiDefinition,
exportShareApiDefinition,
getApiDownloadFile,
getShareApiDownloadFile,
stopApiExport,
stopShareApiExport,
} from '@/api/modules/api-test/management';
import { useI18n } from '@/hooks/useI18n';
import useWebsocket from '@/hooks/useWebsocket';
import useAppStore from '@/store/modules/app';
import { downloadByteFile, getGenerateId } from '@/utils';
import { RequestExportFormat } from '@/enums/apiEnum';
const appStore = useAppStore();
const { t } = useI18n();
const props = defineProps<{
batchParams: BatchActionQueryParams;
conditionParams: Record<string, any> | (() => Record<string, any>);
sorter?: Record<string, any>;
isShare?: boolean; // id
}>();
const visible = defineModel<boolean>('visible', { required: true });
const exportPlatform = ref(RequestExportFormat.SWAGGER);
const exportApiCase = ref(false);
const exportApiMock = ref(false);
const exportLoading = ref(false);
const platformList = [
{
name: 'Swagger',
value: RequestExportFormat.SWAGGER,
},
{
name: 'MeterSphere',
value: RequestExportFormat.MeterSphere,
},
];
function cancelExport() {
visible.value = false;
exportPlatform.value = RequestExportFormat.SWAGGER;
}
const websocket = ref<WebSocket>();
const reportId = ref('');
const isShowExportingMessage = ref(false); //
const exportingMessage = ref();
const getApiDownload = computed(() => (props.isShare ? getShareApiDownloadFile : getApiDownloadFile));
//
async function downloadFile(id: string) {
try {
const response = await getApiDownload.value(appStore.currentProjectId, id);
downloadByteFile(response, 'metersphere-export.json');
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
//
function showExportSuccessfulMessage(id: string, count: number) {
Message.success({
content: () =>
h('div', { class: 'flex flex-col gap-[8px] items-start' }, [
h('div', { class: 'font-medium' }, t('common.exportSuccessful')),
h('div', { class: 'flex items-center gap-[12px]' }, [
h('div', t('caseManagement.featureCase.exportApiCount', { number: count })),
h(
MsButton,
{
type: 'text',
onClick() {
downloadFile(id);
},
},
{ default: () => t('common.downloadFile') }
),
]),
]),
duration: 10000, // 10s
closable: true,
});
}
// websocket
async function startWebsocketGetExportResult() {
const { createSocket, websocket: _websocket } = useWebsocket({
reportId: reportId.value,
socketUrl: '/ws/export',
onMessage: (event) => {
const data = JSON.parse(event.data);
if (data.msgType === 'EXEC_RESULT') {
exportingMessage.value.close();
reportId.value = data.fileId;
// taskId.value = data.taskId;
if (data.isSuccessful) {
showExportSuccessfulMessage(reportId.value, data.count);
} else {
Message.error({
content: t('common.exportFailed'),
duration: 999999999, //
closable: true,
});
}
websocket.value?.close();
}
},
});
await createSocket();
websocket.value = _websocket.value;
}
const stopShareApi = computed(() => (props.isShare ? stopShareApiExport : stopApiExport));
//
async function stopExport(taskId: string) {
try {
await stopShareApi.value(taskId);
exportingMessage.value.close();
websocket.value?.close();
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
//
function showExportingMessage(taskId: string) {
if (isShowExportingMessage.value) return;
isShowExportingMessage.value = true;
exportingMessage.value = Message.loading({
content: () =>
h('div', { class: 'flex items-center gap-[12px]' }, [
h('div', t('common.exporting')),
h(
MsButton,
{
type: 'text',
onClick() {
stopExport(taskId);
},
},
{ default: () => t('common.cancel') }
),
]),
duration: 999999999, //
closable: true,
onClose() {
isShowExportingMessage.value = false;
},
});
}
const exportApiRequest = computed(() => (props.isShare ? exportShareApiDefinition : exportApiDefinition));
/**
* 导出接口
*/
async function exportApi() {
try {
exportLoading.value = true;
reportId.value = getGenerateId();
await startWebsocketGetExportResult();
const batchConditionParams =
typeof props.conditionParams === 'function' ? await props.conditionParams() : props.conditionParams;
const { selectedIds, selectAll, excludeIds } = props.batchParams;
const res = await exportApiRequest.value(
{
selectIds: selectedIds || [],
selectAll: !!selectAll,
excludeIds: excludeIds || [],
...batchConditionParams,
exportApiCase: exportApiCase.value,
exportApiMock: exportApiMock.value,
sort: props.sorter || {},
fileId: reportId.value,
},
exportPlatform.value
);
showExportingMessage(res);
visible.value = false;
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
exportLoading.value = false;
}
}
</script>
<style scoped lang="less">
.import-item {
@apply flex cursor-pointer items-center bg-white;
padding: 8px;
width: 150px;
border: 1px solid var(--color-text-n8);
border-radius: var(--border-radius-small);
gap: 6px;
}
.import-item--active {
border: 1px solid rgb(var(--primary-5));
background-color: rgb(var(--primary-1));
}
</style>

View File

@ -4,6 +4,7 @@
:detail="activeApiDetail"
:protocols="props.selectedProtocols"
@update-follow="activeApiDetail.follow = !activeApiDetail.follow"
@export-share="handlerExportShare"
/>
</div>
<div class="doc-toggle-footer">
@ -91,6 +92,7 @@
const emit = defineEmits<{
(e: 'toggleDetail', type: string): void;
(e: 'exportShare', all: boolean): void;
}>();
const localProtocol = localStorage.getItem(ProtocolKeyEnum.API_NEW_PROTOCOL);
@ -116,6 +118,7 @@
rest: [],
polymorphicName: '',
name: '',
num: '',
path: '',
projectId: '',
uploadFileIds: [],
@ -214,6 +217,10 @@
function toggleApiDetail(type: string) {
emit('toggleDetail', type);
}
//
function handlerExportShare() {
emit('exportShare', false);
}
watch(
() => props.apiInfo,

View File

@ -11,7 +11,11 @@
@refresh="loadApiList(false)"
>
<template #right>
<ShareButton @create="createShare" @show-share-list="showShareList" />
<ShareButton
v-if="hasAnyPermission(['PROJECT_API_DEFINITION_DOC:READ+SHARE'])"
@create="createShare"
@show-share-list="showShareList"
/>
</template>
</MsAdvanceFilter>
<ms-base-table
@ -243,47 +247,12 @@
@folder-node-select="folderNodeSelect"
/>
</a-modal>
<a-modal
<ApiExportModal
v-model:visible="showExportModal"
:title="t('common.export')"
title-align="start"
class="ms-modal-upload ms-modal-medium"
:width="400"
>
<div class="mb-[16px] flex gap-[8px]">
<div
v-for="item of platformList"
:key="item.value"
:class="`import-item ${exportPlatform === item.value ? 'import-item--active' : ''}`"
@click="exportPlatform = item.value"
>
<div class="text-[var(--color-text-1)]">{{ item.name }}</div>
</div>
</div>
<template v-if="exportPlatform === RequestExportFormat.MeterSphere">
<div class="mb-[16px] flex items-center gap-[4px]">
<a-switch v-model:model-value="exportApiCase" size="small" />
{{ t('apiTestManagement.exportCase') }}
</div>
<div class="flex items-center gap-[4px]">
<a-switch v-model:model-value="exportApiMock" size="small" />
{{ t('apiTestManagement.exportMock') }}
</div>
</template>
<div v-else-if="exportPlatform === RequestExportFormat.SWAGGER" class="text-[var(--color-text-4)]">
{{ t('apiTestManagement.exportSwaggerTip') }}
</div>
<template #footer>
<div class="flex justify-end">
<a-button type="secondary" :disabled="exportLoading" @click="cancelExport">
{{ t('common.cancel') }}
</a-button>
<a-button class="ml-3" type="primary" :loading="exportLoading" @click="exportApi">
{{ t('common.export') }}
</a-button>
</div>
</template>
</a-modal>
:batch-params="batchParams"
:condition-params="getBatchConditionParams"
:sorter="propsRes.sorter || {}"
/>
<CreateShareModal
v-model:visible="showShareModal"
:record="editRecord"
@ -313,6 +282,7 @@
import apiMethodName from '@/views/api-test/components/apiMethodName.vue';
import apiMethodSelect from '@/views/api-test/components/apiMethodSelect.vue';
import apiStatus from '@/views/api-test/components/apiStatus.vue';
import ApiExportModal from '@/views/api-test/management/components/management/api/apiExportModal.vue';
import moduleTree from '@/views/api-test/management/components/moduleTree.vue';
import {
@ -320,20 +290,16 @@
batchMoveDefinition,
batchUpdateDefinition,
deleteDefinition,
exportApiDefinition,
getApiDownloadFile,
getDefinitionPage,
sortDefinition,
stopApiExport,
updateDefinition,
} from '@/api/modules/api-test/management';
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import useTableStore from '@/hooks/useTableStore';
import useWebsocket from '@/hooks/useWebsocket';
import useAppStore from '@/store/modules/app';
import useCacheStore from '@/store/modules/cache/cache';
import { characterLimit, downloadByteFile, getGenerateId, operationWidth } from '@/utils';
import { characterLimit, operationWidth } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import { ProtocolItem } from '@/models/apiTest/common';
@ -341,7 +307,7 @@
import { ApiDefinitionDetail, ApiDefinitionGetModuleParams } from '@/models/apiTest/management';
import { DragSortParams, ModuleTreeNode } from '@/models/common';
import { FilterType, ViewTypeEnum } from '@/enums/advancedFilterEnum';
import { RequestDefinitionStatus, RequestExportFormat, RequestMethods } from '@/enums/apiEnum';
import { RequestDefinitionStatus, RequestMethods } from '@/enums/apiEnum';
import { CacheTabTypeEnum } from '@/enums/cacheTabEnum';
import { TagUpdateTypeEnum } from '@/enums/commonEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
@ -1065,164 +1031,6 @@
}
const showExportModal = ref(false);
const platformList = [
{
name: 'Swagger',
value: RequestExportFormat.SWAGGER,
},
{
name: 'MeterSphere',
value: RequestExportFormat.MeterSphere,
},
];
const exportPlatform = ref(RequestExportFormat.SWAGGER);
const exportApiCase = ref(false);
const exportApiMock = ref(false);
const exportLoading = ref(false);
function cancelExport() {
showExportModal.value = false;
exportPlatform.value = RequestExportFormat.SWAGGER;
}
//
async function downloadFile(id: string) {
try {
const response = await getApiDownloadFile(appStore.currentProjectId, id);
downloadByteFile(response, 'metersphere-export.json');
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
//
function showExportSuccessfulMessage(id: string, count: number) {
Message.success({
content: () =>
h('div', { class: 'flex flex-col gap-[8px] items-start' }, [
h('div', { class: 'font-medium' }, t('common.exportSuccessful')),
h('div', { class: 'flex items-center gap-[12px]' }, [
h('div', t('caseManagement.featureCase.exportApiCount', { number: count })),
h(
MsButton,
{
type: 'text',
onClick() {
downloadFile(id);
},
},
{ default: () => t('common.downloadFile') }
),
]),
]),
duration: 10000, // 10s
closable: true,
});
}
const websocket = ref<WebSocket>();
const reportId = ref('');
const isShowExportingMessage = ref(false); //
const exportingMessage = ref();
// websocket
async function startWebsocketGetExportResult() {
const { createSocket, websocket: _websocket } = useWebsocket({
reportId: reportId.value,
socketUrl: '/ws/export',
onMessage: (event) => {
const data = JSON.parse(event.data);
if (data.msgType === 'EXEC_RESULT') {
exportingMessage.value.close();
reportId.value = data.fileId;
// taskId.value = data.taskId;
if (data.isSuccessful) {
showExportSuccessfulMessage(reportId.value, data.count);
} else {
Message.error({
content: t('common.exportFailed'),
duration: 999999999, //
closable: true,
});
}
websocket.value?.close();
}
},
});
await createSocket();
websocket.value = _websocket.value;
}
//
async function stopExport(taskId: string) {
try {
await stopApiExport(taskId);
exportingMessage.value.close();
websocket.value?.close();
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
//
function showExportingMessage(taskId: string) {
if (isShowExportingMessage.value) return;
isShowExportingMessage.value = true;
exportingMessage.value = Message.loading({
content: () =>
h('div', { class: 'flex items-center gap-[12px]' }, [
h('div', t('common.exporting')),
h(
MsButton,
{
type: 'text',
onClick() {
stopExport(taskId);
},
},
{ default: () => t('common.cancel') }
),
]),
duration: 999999999, //
closable: true,
onClose() {
isShowExportingMessage.value = false;
},
});
}
/**
* 导出接口
*/
async function exportApi() {
try {
exportLoading.value = true;
reportId.value = getGenerateId();
await startWebsocketGetExportResult();
const batchConditionParams = await getBatchConditionParams();
const res = await exportApiDefinition(
{
selectIds: tableSelected.value as string[],
selectAll: !!batchParams.value?.selectAll,
excludeIds: batchParams.value?.excludeIds || [],
...batchConditionParams,
exportApiCase: exportApiCase.value,
exportApiMock: exportApiMock.value,
sort: propsRes.value.sorter || {},
fileId: reportId.value,
},
exportPlatform.value
);
showExportingMessage(res);
showExportModal.value = false;
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
exportLoading.value = false;
}
}
/**
* 处理表格选中后批量操作
@ -1323,19 +1131,6 @@
</script>
<style lang="less" scoped>
.import-item {
@apply flex cursor-pointer items-center bg-white;
padding: 8px;
width: 150px;
border: 1px solid var(--color-text-n8);
border-radius: var(--border-radius-small);
gap: 6px;
}
.import-item--active {
border: 1px solid rgb(var(--primary-5));
background-color: rgb(var(--primary-1));
}
:deep(.param-input:not(.arco-input-focus, .arco-select-view-focus)) {
&:not(:hover) {
border-color: transparent !important;

View File

@ -74,11 +74,12 @@
:validate-trigger="['blur']"
:rules="form.isPrivate ? [{ validator: validatePassword }] : []"
>
<a-input
<a-input-password
v-model:model-value="form.password"
class="w-[240px]"
:max-length="6"
:placeholder="t('apiTestManagement.enterPassword')"
autocomplete="new-password"
/>
</a-form-item>
<div class="mb-[16px] flex items-center">

View File

@ -85,7 +85,7 @@
detail: RequestParam;
protocols: ProtocolItem[];
}>();
const emit = defineEmits(['updateFollow']);
const emit = defineEmits(['updateFollow', 'exportShare']);
const { copy, isSupported } = useClipboard({ legacy: true });
const { t } = useI18n();
@ -189,8 +189,10 @@
}
const activeKey = ref('detail');
// TODO
function exportShare() {}
//
function exportShare() {
emit('exportShare');
}
</script>
<style lang="less" scoped>

View File

@ -9,7 +9,12 @@
>
<div class="p-[16px]">
<div class="mb-4 flex items-center justify-between">
<a-button class="w-[84px]" type="primary" @click="emit('editOrCreate')">
<a-button
v-permission="['PROJECT_API_DEFINITION_DOC:READ+SHARE']"
class="w-[84px]"
type="primary"
@click="emit('editOrCreate')"
>
{{ t('apiTestManagement.newCreateShare') }}
</a-button>
<a-input-search
@ -27,19 +32,21 @@
{{ record.isPrivate ? t('apiTestManagement.passwordView') : t('apiTestManagement.publicityView') }}
</template>
<template #operation="{ record }">
<a-tooltip :disabled="!!record.apiShareNum" :content="t('apiTestManagement.apiShareNumberTip')">
<MsButton class="!mx-0" :disabled="!record.apiShareNum" @click="viewLink(record)">
{{ t('apiTestManagement.viewLink') }}
<div v-permission="['PROJECT_API_DEFINITION_DOC:READ+SHARE']" class="flex items-center">
<a-tooltip :disabled="!!record.apiShareNum" :content="t('apiTestManagement.apiShareNumberTip')">
<MsButton class="!mx-0" :disabled="!record.apiShareNum" @click="viewLink(record)">
{{ t('apiTestManagement.viewLink') }}
</MsButton>
</a-tooltip>
<a-divider direction="vertical" :margin="8" />
<MsButton class="!mx-0" @click="editShare(record)">
{{ t('common.edit') }}
</MsButton>
</a-tooltip>
<a-divider direction="vertical" :margin="8" />
<MsButton class="!mx-0" @click="editShare(record)">
{{ t('common.edit') }}
</MsButton>
<a-divider direction="vertical" :margin="8" />
<MsButton class="!mx-0" @click="deleteHandler(record)">
{{ t('common.delete') }}
</MsButton>
<a-divider direction="vertical" :margin="8" />
<MsButton class="!mx-0" @click="deleteHandler(record)">
{{ t('common.delete') }}
</MsButton>
</div>
</template>
</MsBaseTable>
</div>
@ -62,7 +69,8 @@
import useModal from '@/hooks/useModal';
import useOpenNewPage from '@/hooks/useOpenNewPage';
import { useAppStore, useTableStore } from '@/store';
import { characterLimit } from '@/utils';
import { characterLimit, operationWidth } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { ShareDetail, shareItem } from '@/models/apiTest/management';
import { ApiTestRouteEnum } from '@/enums/routeEnum';
@ -131,11 +139,11 @@
showDrag: true,
},
{
title: 'common.operation',
title: hasAnyPermission(['PROJECT_API_DEFINITION_DOC:READ+SHARE']) ? 'common.operation' : '',
slotName: 'operation',
dataIndex: 'operation',
fixed: 'right',
width: 180,
width: operationWidth(215, hasAnyPermission(['PROJECT_API_DEFINITION_DOC:READ+SHARE']) ? 180 : 50),
showInTable: true,
showDrag: false,
},

View File

@ -61,7 +61,7 @@
/>
</MsButton>
</popConfirm>
<a-tooltip v-if="props.docShareId && shareDetailInfo?.allowExport" :content="t('common.export')">
<a-tooltip v-if="props.docShareId && shareDetailInfo.allowExport" :content="t('common.export')">
<MsButton type="icon" status="secondary" class="!mr-[4px] p-[4px]" @click="changeApiExpand">
<MsIcon type="icon-icon_top-align_outlined" :size="16" @click="exportShare" />
</MsButton>
@ -356,7 +356,14 @@
moduleIds: [],
});
//
const shareDetailInfo = inject<Ref<ShareDetailType>>('shareDetailInfo');
const shareDetailInfo = inject<Ref<ShareDetailType>>(
'shareDetailInfo',
ref({
invalid: false,
allowExport: false,
isPrivate: false,
})
);
const apiNodes = ref<TreeNode<ModuleTreeNode>[]>([]);
const currentNode = ref<TreeNode<ModuleTreeNode> | null>(null);
@ -747,7 +754,7 @@
//
function exportShare() {
emit('exportShare');
emit('exportShare', true);
}
onBeforeMount(() => {

View File

@ -18,6 +18,7 @@
@delete-node="handleDeleteApiFromModuleTree"
@execute="handleExecute"
@open-current-node="openCurrentNode"
@export-share="handleExportShare"
/>
</div>
<div v-if="!docShareId" class="flex-1">
@ -66,6 +67,7 @@
:previous-node="previousNode"
:next-node="nextNode"
@toggle-detail="toggleDetail"
@export-share="handleExportShare"
/>
</div>
</template>
@ -107,6 +109,12 @@
</a-button>
</template>
</a-modal>
<ApiExportModal
v-model:visible="showExportModal"
:batch-params="batchParams"
:condition-params="getConditionParams"
is-share
/>
</MsCard>
</template>
@ -120,10 +128,12 @@
import MsCard from '@/components/pure/ms-card/index.vue';
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
import type { BatchActionQueryParams } from '@/components/pure/ms-table/type';
import { RequestParam } from '../components/requestComposition/index.vue';
import importApi from './components/import.vue';
import management from './components/management/index.vue';
import moduleTree from './components/moduleTree.vue';
import ApiExportModal from '@/views/api-test/management/components/management/api/apiExportModal.vue';
import ApiSharePreview from '@/views/api-test/management/components/management/api/apiSharePreview.vue';
import { getProtocolList } from '@/api/modules/api-test/common';
@ -318,10 +328,42 @@
formRef.value?.resetFields();
checkForm.value.password = '';
}
const shareDetailInfo = ref<ShareDetailType>();
const currentNode = ref();
const showExportModal = ref(false);
const batchParams = ref<BatchActionQueryParams>({
selectedIds: [],
selectAll: false,
excludeIds: [],
});
// |
function handleExportShare(all: boolean) {
batchParams.value.selectAll = all;
batchParams.value.selectedIds = all ? [] : [currentNode.value?.id];
showExportModal.value = true;
}
function getConditionParams() {
return {
condition: {
keyword: '',
filter: {},
viewId: '',
},
projectId: appStore.currentProjectId,
protocols: selectedProtocols.value,
moduleIds: [],
shareId: docShareId.value,
};
}
const shareDetailInfo = ref<ShareDetailType>({
invalid: false,
allowExport: false,
isPrivate: false,
});
//
async function getShareDetail() {
try {
@ -393,7 +435,7 @@
provide('refreshModuleTreeCount', refreshModuleTreeCount);
provide('folderTreePathMap', folderTreePathMap.value);
provide('docShareId', docShareId.value);
provide('shareDetailInfo', shareDetailInfo.value);
provide('shareDetailInfo', shareDetailInfo);
</script>
<style lang="less" scoped>