feat(接口测试): 接口测试文档分享详情页面拆分不展示菜单
This commit is contained in:
parent
946ed7de55
commit
c0f4b89742
|
@ -108,6 +108,7 @@ export enum SettingRouteEnum {
|
|||
export enum ShareEnum {
|
||||
SHARE = 'share',
|
||||
SHARE_REPORT_SCENARIO = 'shareReportScenario',
|
||||
SHARE_DEFINITION_API = 'shareDefinitionApi',
|
||||
SHARE_REPORT_CASE = 'shareReportCase',
|
||||
SHARE_REPORT_TEST_PLAN = 'shareReportTestPlan',
|
||||
}
|
||||
|
|
|
@ -21,6 +21,11 @@ export const WHITE_LIST = [
|
|||
path: '/shareReportTestPlan',
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
name: 'shareDefinitionApi',
|
||||
path: '/shareDefinitionApi',
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -38,6 +43,11 @@ export const WHITE_LIST = [
|
|||
path: '/shareReportTestPlan',
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
name: 'shareDefinitionApi',
|
||||
path: '/shareDefinitionApi',
|
||||
children: [],
|
||||
},
|
||||
];
|
||||
|
||||
// 左侧菜单底部对齐的菜单数组,数组项为一级路由的name
|
||||
|
|
|
@ -46,6 +46,17 @@ const ShareRoute: AppRouteRecordRaw = {
|
|||
isTopMenu: false,
|
||||
},
|
||||
},
|
||||
// 接口文档分享
|
||||
{
|
||||
path: 'shareDefinitionApi',
|
||||
name: ShareEnum.SHARE_DEFINITION_API,
|
||||
component: () => import('@/views/api-test/management/components/management/api/shareApiDocIndex.vue'),
|
||||
meta: {
|
||||
locale: '',
|
||||
roles: ['*'],
|
||||
isTopMenu: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="h-[calc(100%-32px)]">
|
||||
<div class="h-[calc(100%-64px)]">
|
||||
<ApiPreview
|
||||
:detail="activeApiDetail"
|
||||
:protocols="props.selectedProtocols"
|
||||
|
@ -238,7 +238,6 @@
|
|||
bottom: 0;
|
||||
z-index: 99;
|
||||
padding: 16px;
|
||||
height: 22px;
|
||||
|
||||
@apply flex w-full items-center justify-between bg-white;
|
||||
.doc-toggle {
|
||||
|
|
|
@ -0,0 +1,320 @@
|
|||
<template>
|
||||
<MsCard simple no-content-padding auto-height>
|
||||
<div class="h-[calc(100vh-32px)]">
|
||||
<MsSplitBox :size="300" :max="0.5">
|
||||
<template #first>
|
||||
<div class="flex flex-col">
|
||||
<div class="p-[16px]">
|
||||
<moduleTree
|
||||
ref="moduleTreeRef"
|
||||
:active-node-id="activeNodeId"
|
||||
:doc-share-id="docShareId"
|
||||
@init="handleModuleInit"
|
||||
@folder-node-select="handleNodeSelect"
|
||||
@change-protocol="handleProtocolChange"
|
||||
@open-current-node="openCurrentNode"
|
||||
@export-share="handleExportShare"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #second>
|
||||
<ApiSharePreview
|
||||
:selected-protocols="protocols"
|
||||
:api-info="currentNode"
|
||||
:previous-node="previousNode"
|
||||
:next-node="nextNode"
|
||||
@toggle-detail="toggleDetail"
|
||||
@export-share="handleExportShare"
|
||||
/>
|
||||
</template>
|
||||
</MsSplitBox>
|
||||
</div>
|
||||
|
||||
<!-- 分享密码校验 -->
|
||||
<a-modal
|
||||
v-model:visible="checkPsdModal"
|
||||
:mask-closable="false"
|
||||
:closable="false"
|
||||
:mask="true"
|
||||
title-align="start"
|
||||
class="ms-modal-upload ms-modal-medium ms-modal-share"
|
||||
:width="280"
|
||||
unmount-on-close
|
||||
@close="closeShareHandler"
|
||||
>
|
||||
<div class="no-resource-svg"></div>
|
||||
<a-form ref="formRef" :rules="rules" :model="checkForm" layout="vertical">
|
||||
<a-form-item
|
||||
class="password-form mb-0"
|
||||
field="password"
|
||||
:label="t('apiTestManagement.effectiveTime')"
|
||||
hide-asterisk
|
||||
hide-label
|
||||
:validate-trigger="['blur']"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="checkForm.password"
|
||||
:max-length="6"
|
||||
:placeholder="t('apiTestManagement.sharePasswordPlaceholder')"
|
||||
allow-clear
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-button type="primary" :loading="checkLoading" :disabled="!checkForm.password" @click="handleCheckPsd">
|
||||
{{ t('common.confirm') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</a-modal>
|
||||
<ApiExportModal
|
||||
v-model:visible="showExportModal"
|
||||
:batch-params="batchParams"
|
||||
:condition-params="getConditionParams"
|
||||
is-share
|
||||
/>
|
||||
</MsCard>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { FormInstance, Message } from '@arco-design/web-vue';
|
||||
|
||||
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 ApiExportModal from '@/views/api-test/management/components/management/api/apiExportModal.vue';
|
||||
import ApiSharePreview from '@/views/api-test/management/components/management/api/apiSharePreview.vue';
|
||||
import moduleTree from '@/views/api-test/management/components/moduleTree.vue';
|
||||
|
||||
import { getProtocolList } from '@/api/modules/api-test/common';
|
||||
import { checkSharePsd, shareDetail } from '@/api/modules/api-test/management';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { NOT_FOUND_RESOURCE } from '@/router/constants';
|
||||
import { useUserStore } from '@/store';
|
||||
import useDocShareCheckStore from '@/store/modules/api/docShareCheck';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
import { ShareDetailType } from '@/models/apiTest/management';
|
||||
import { ModuleTreeNode } from '@/models/common';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const docCheckStore = useDocShareCheckStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const activeNodeId = ref<string | number>('all');
|
||||
const activeModule = ref<string>('all');
|
||||
const offspringIds = ref<string[]>([]);
|
||||
|
||||
const docShareId = ref<string>(route.query.docShareId as string);
|
||||
|
||||
const folderTree = ref<ModuleTreeNode[]>([]);
|
||||
const selectedProtocols = ref<string[]>([]);
|
||||
const folderTreePathMap = ref<Record<string, any>>({});
|
||||
|
||||
function handleModuleInit(tree: ModuleTreeNode[], _protocols: string[], pathMap: Record<string, any>) {
|
||||
folderTree.value = tree;
|
||||
selectedProtocols.value = _protocols;
|
||||
folderTreePathMap.value = pathMap;
|
||||
}
|
||||
|
||||
function handleNodeSelect(keys: string[], _offspringIds: string[]) {
|
||||
[activeModule.value] = keys;
|
||||
offspringIds.value = _offspringIds;
|
||||
}
|
||||
|
||||
function handleProtocolChange(val: string[]) {
|
||||
selectedProtocols.value = val;
|
||||
}
|
||||
|
||||
const checkLoading = ref<boolean>(false);
|
||||
const checkPsdModal = ref<boolean>(false);
|
||||
const checkForm = ref({
|
||||
docShareId: route.query.docShareId as string,
|
||||
password: '',
|
||||
});
|
||||
|
||||
const validatePassword = (value: string | undefined, callback: (error?: string) => void) => {
|
||||
const sixDigitRegex = /^\d{6}$/;
|
||||
|
||||
if (value === undefined || value === '') {
|
||||
callback(t('apiTestManagement.enterPassword'));
|
||||
} else if (!sixDigitRegex.test(value)) {
|
||||
callback(t('apiTestManagement.enterPassword'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const rules = {
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: t('apiTestManagement.sharePasswordPlaceholder'),
|
||||
},
|
||||
{
|
||||
validator: validatePassword,
|
||||
},
|
||||
],
|
||||
};
|
||||
const moduleTreeRef = ref<InstanceType<typeof moduleTree>>();
|
||||
|
||||
// 上一条|下一条
|
||||
function toggleDetail(type: string) {
|
||||
if (type === 'prev') {
|
||||
moduleTreeRef.value?.previousApi();
|
||||
} else {
|
||||
moduleTreeRef.value?.nextApi();
|
||||
}
|
||||
}
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
// 关闭分享
|
||||
function closeShareHandler() {
|
||||
checkPsdModal.value = false;
|
||||
formRef.value?.resetFields();
|
||||
checkForm.value.password = '';
|
||||
}
|
||||
|
||||
const protocols = ref<any[]>([]);
|
||||
async function initProtocolList() {
|
||||
try {
|
||||
protocols.value = await getProtocolList(appStore.currentOrgId);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
initProtocolList();
|
||||
});
|
||||
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 {
|
||||
shareDetailInfo.value = await shareDetail(docShareId.value);
|
||||
// 资源无效
|
||||
if (shareDetailInfo.value.invalid) {
|
||||
router.push({
|
||||
name: NOT_FOUND_RESOURCE,
|
||||
query: {
|
||||
type: 'EXPIRED',
|
||||
},
|
||||
});
|
||||
}
|
||||
// 限制访问校验
|
||||
if (shareDetailInfo.value.isPrivate && !docCheckStore.isDocVerified(docShareId.value, userStore.id || '')) {
|
||||
checkPsdModal.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
const previousNode = ref<ModuleTreeNode | null>();
|
||||
const nextNode = ref<ModuleTreeNode | null>();
|
||||
|
||||
// 设置当前预览节点
|
||||
function openCurrentNode(node: ModuleTreeNode, apiNodes: ModuleTreeNode[]) {
|
||||
const index = apiNodes.indexOf(node);
|
||||
currentNode.value = node;
|
||||
previousNode.value = index > 0 ? apiNodes[index - 1] : null;
|
||||
nextNode.value = index < apiNodes.length - 1 ? apiNodes[index + 1] : null;
|
||||
}
|
||||
|
||||
// 校验密码
|
||||
function handleCheckPsd() {
|
||||
formRef.value?.validate(async (errors) => {
|
||||
if (!errors) {
|
||||
try {
|
||||
checkLoading.value = true;
|
||||
const res = await checkSharePsd(checkForm.value);
|
||||
if (res) {
|
||||
closeShareHandler();
|
||||
// 标记为已验证
|
||||
docCheckStore.markDocAsVerified(docShareId.value, userStore.id || '');
|
||||
checkPsdModal.value = false;
|
||||
} else {
|
||||
Message.error(t('apiTestManagement.apiSharePsdError'));
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
checkLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (docShareId.value) {
|
||||
getShareDetail();
|
||||
}
|
||||
});
|
||||
|
||||
provide('docShareId', docShareId.value);
|
||||
provide('shareDetailInfo', shareDetailInfo);
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.no-resource-svg {
|
||||
margin: 0 auto 24px;
|
||||
width: 160px;
|
||||
height: 98px;
|
||||
background: url('@/assets/svg/no_resource.svg');
|
||||
background-size: cover;
|
||||
}
|
||||
:deep(.ms-modal-share) {
|
||||
.arco-modal-mask {
|
||||
background: var(--color-text-1) !important;
|
||||
}
|
||||
}
|
||||
:deep(.password-form) {
|
||||
.arco-form-item-message {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -67,11 +67,11 @@
|
|||
import { useAppStore } from '@/store';
|
||||
|
||||
import type { shareItem } from '@/models/apiTest/management';
|
||||
import { RouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const { copy, isSupported } = useClipboard({ legacy: true });
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
@ -133,9 +133,9 @@
|
|||
}
|
||||
if (isSupported) {
|
||||
// 判断路由中是不是有dId参数,有的话只是修改当前的值就可以了
|
||||
const url = window.location.href;
|
||||
const dIdParam = `&docShareId=${item.id}`;
|
||||
copy(`${url}${dIdParam}`);
|
||||
const shareLinkUrl = `${origin}/#/${RouteEnum.SHARE}/${RouteEnum.SHARE_DEFINITION_API}`;
|
||||
const dIdParam = `?orgId=${appStore.currentOrgId}&pId=${appStore.currentProjectId}&docShareId=${item.id}`;
|
||||
copy(`${shareLinkUrl}${dIdParam}`);
|
||||
Message.success(t('apiTestManagement.shareUrlCopied'));
|
||||
} else {
|
||||
Message.error(t('common.copyNotSupport'));
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import type { ShareDetail, shareItem } from '@/models/apiTest/management';
|
||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||
import { ShareEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterRemoteMethodsEnum } from '@/enums/tableFilterEnum';
|
||||
|
||||
|
@ -189,7 +189,7 @@
|
|||
|
||||
// 查看链接
|
||||
function viewLink(record: shareItem) {
|
||||
openNewPage(ApiTestRouteEnum.API_TEST_MANAGEMENT, {
|
||||
openNewPage(ShareEnum.SHARE_DEFINITION_API, {
|
||||
docShareId: record.id,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -268,14 +268,14 @@
|
|||
const virtualListProps = computed(() => {
|
||||
if (props.readOnly || props.isModal) {
|
||||
return {
|
||||
height: props.docShareId ? 'calc(60vh - 150px)' : 'calc(60vh - 190px)',
|
||||
height: 'calc(60vh - 190px)',
|
||||
threshold: 200,
|
||||
fixedSize: true,
|
||||
buffer: 15, // 缓冲区默认 10 的时候,虚拟滚动的底部 padding 计算有问题
|
||||
};
|
||||
}
|
||||
return {
|
||||
height: props.docShareId ? 'calc(100vh - 233px)' : 'calc(100vh - 273px)',
|
||||
height: props.docShareId ? 'calc(100vh - 150px)' : 'calc(100vh - 273px)',
|
||||
threshold: 200,
|
||||
fixedSize: true,
|
||||
buffer: 15, // 缓冲区默认 10 的时候,虚拟滚动的底部 padding 计算有问题
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<moduleTree
|
||||
ref="moduleTreeRef"
|
||||
:active-node-id="activeNodeId"
|
||||
:doc-share-id="docShareId"
|
||||
@init="handleModuleInit"
|
||||
@new-api="newApi"
|
||||
@import="importDrawerVisible = true"
|
||||
|
@ -17,8 +16,6 @@
|
|||
@update-api-node="handleUpdateApiNode"
|
||||
@delete-node="handleDeleteApiFromModuleTree"
|
||||
@execute="handleExecute"
|
||||
@open-current-node="openCurrentNode"
|
||||
@export-share="handleExportShare"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="!docShareId" class="flex-1">
|
||||
|
@ -36,7 +33,6 @@
|
|||
<template #second>
|
||||
<div class="relative flex h-full flex-col">
|
||||
<div
|
||||
v-if="!docShareId"
|
||||
id="managementContainer"
|
||||
:class="['absolute z-[102] h-full w-full', importDrawerVisible ? '' : 'invisible']"
|
||||
style="transition: all 0.3s"
|
||||
|
@ -51,7 +47,6 @@
|
|||
/>
|
||||
</div>
|
||||
<management
|
||||
v-if="!docShareId"
|
||||
ref="managementRef"
|
||||
:module-tree="folderTree"
|
||||
:active-module="activeModule"
|
||||
|
@ -60,62 +55,9 @@
|
|||
@import="importDrawerVisible = true"
|
||||
@handle-adv-search="handleAdvSearch"
|
||||
/>
|
||||
|
||||
<ApiSharePreview
|
||||
v-if="docShareId"
|
||||
:selected-protocols="protocols"
|
||||
:api-info="currentNode"
|
||||
:previous-node="previousNode"
|
||||
:next-node="nextNode"
|
||||
@toggle-detail="toggleDetail"
|
||||
@export-share="handleExportShare"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</MsSplitBox>
|
||||
<!-- 分享密码校验 -->
|
||||
<a-modal
|
||||
v-model:visible="checkPsdModal"
|
||||
:mask-closable="false"
|
||||
:closable="false"
|
||||
:mask="true"
|
||||
title-align="start"
|
||||
class="ms-modal-upload ms-modal-medium ms-modal-share"
|
||||
:width="280"
|
||||
unmount-on-close
|
||||
@close="closeShareHandler"
|
||||
>
|
||||
<div class="no-resource-svg"></div>
|
||||
<a-form ref="formRef" :rules="rules" :model="checkForm" layout="vertical">
|
||||
<a-form-item
|
||||
class="password-form mb-0"
|
||||
field="password"
|
||||
:label="t('apiTestManagement.effectiveTime')"
|
||||
hide-asterisk
|
||||
hide-label
|
||||
:validate-trigger="['blur']"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="checkForm.password"
|
||||
:max-length="6"
|
||||
:placeholder="t('apiTestManagement.sharePasswordPlaceholder')"
|
||||
allow-clear
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-button type="primary" :loading="checkLoading" :disabled="!checkForm.password" @click="handleCheckPsd">
|
||||
{{ t('common.confirm') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</a-modal>
|
||||
<ApiExportModal
|
||||
v-model:visible="showExportModal"
|
||||
:batch-params="batchParams"
|
||||
:condition-params="getConditionParams"
|
||||
is-share
|
||||
/>
|
||||
</MsCard>
|
||||
<importTaskDrawer v-model:visible="taskDrawerVisible" />
|
||||
</template>
|
||||
|
@ -126,28 +68,20 @@
|
|||
*/
|
||||
import { provide } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { FormInstance, Message } from '@arco-design/web-vue';
|
||||
|
||||
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 importTaskDrawer from './components/importTaskDrawer.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';
|
||||
import { checkSharePsd, getTrashModuleCount, shareDetail } from '@/api/modules/api-test/management';
|
||||
import { getTrashModuleCount } from '@/api/modules/api-test/management';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { NOT_FOUND_RESOURCE } from '@/router/constants';
|
||||
import { useUserStore } from '@/store';
|
||||
import useDocShareCheckStore from '@/store/modules/api/docShareCheck';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
import { ApiDefinitionGetModuleParams, ShareDetailType } from '@/models/apiTest/management';
|
||||
import { ApiDefinitionGetModuleParams } from '@/models/apiTest/management';
|
||||
import { ModuleTreeNode } from '@/models/common';
|
||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
|
@ -155,8 +89,6 @@
|
|||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const docCheckStore = useDocShareCheckStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const activeModule = ref<string>('all');
|
||||
const folderTree = ref<ModuleTreeNode[]>([]);
|
||||
|
@ -190,20 +122,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
const protocols = ref<any[]>([]);
|
||||
async function initProtocolList() {
|
||||
try {
|
||||
protocols.value = await getProtocolList(appStore.currentOrgId);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
initProtocolList();
|
||||
});
|
||||
|
||||
function handleProtocolChange(val: string[]) {
|
||||
selectedProtocols.value = val;
|
||||
}
|
||||
|
@ -284,153 +202,8 @@
|
|||
moduleTreeRef.value?.setActiveFolder('all');
|
||||
}
|
||||
|
||||
const checkLoading = ref<boolean>(false);
|
||||
const checkPsdModal = ref<boolean>(false);
|
||||
const checkForm = ref({
|
||||
docShareId: route.query.docShareId as string,
|
||||
password: '',
|
||||
});
|
||||
|
||||
const validatePassword = (value: string | undefined, callback: (error?: string) => void) => {
|
||||
const sixDigitRegex = /^\d{6}$/;
|
||||
|
||||
if (value === undefined || value === '') {
|
||||
callback(t('apiTestManagement.enterPassword'));
|
||||
} else if (!sixDigitRegex.test(value)) {
|
||||
callback(t('apiTestManagement.enterPassword'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const rules = {
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: t('apiTestManagement.sharePasswordPlaceholder'),
|
||||
},
|
||||
{
|
||||
validator: validatePassword,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// 上一条|下一条
|
||||
function toggleDetail(type: string) {
|
||||
if (type === 'prev') {
|
||||
moduleTreeRef.value?.previousApi();
|
||||
} else {
|
||||
moduleTreeRef.value?.nextApi();
|
||||
}
|
||||
}
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
// 关闭分享
|
||||
function closeShareHandler() {
|
||||
checkPsdModal.value = false;
|
||||
formRef.value?.resetFields();
|
||||
checkForm.value.password = '';
|
||||
}
|
||||
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 {
|
||||
shareDetailInfo.value = await shareDetail(docShareId.value);
|
||||
// 资源无效
|
||||
if (shareDetailInfo.value.invalid) {
|
||||
router.push({
|
||||
name: NOT_FOUND_RESOURCE,
|
||||
query: {
|
||||
type: 'EXPIRED',
|
||||
},
|
||||
});
|
||||
}
|
||||
// 限制访问校验
|
||||
if (shareDetailInfo.value.isPrivate && !docCheckStore.isDocVerified(docShareId.value, userStore.id || '')) {
|
||||
checkPsdModal.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
const previousNode = ref<ModuleTreeNode | null>();
|
||||
const nextNode = ref<ModuleTreeNode | null>();
|
||||
|
||||
// 设置当前预览节点
|
||||
function openCurrentNode(node: ModuleTreeNode, apiNodes: ModuleTreeNode[]) {
|
||||
const index = apiNodes.indexOf(node);
|
||||
currentNode.value = node;
|
||||
previousNode.value = index > 0 ? apiNodes[index - 1] : null;
|
||||
nextNode.value = index < apiNodes.length - 1 ? apiNodes[index + 1] : null;
|
||||
}
|
||||
|
||||
// 校验密码
|
||||
function handleCheckPsd() {
|
||||
formRef.value?.validate(async (errors) => {
|
||||
if (!errors) {
|
||||
try {
|
||||
checkLoading.value = true;
|
||||
const res = await checkSharePsd(checkForm.value);
|
||||
if (res) {
|
||||
closeShareHandler();
|
||||
// 标记为已验证
|
||||
docCheckStore.markDocAsVerified(docShareId.value, userStore.id || '');
|
||||
checkPsdModal.value = false;
|
||||
} else {
|
||||
Message.error(t('apiTestManagement.apiSharePsdError'));
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
checkLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const taskDrawerVisible = ref(false);
|
||||
onBeforeMount(() => {
|
||||
if (docShareId.value) {
|
||||
getShareDetail();
|
||||
}
|
||||
if (route.query.taskDrawer) {
|
||||
taskDrawerVisible.value = true;
|
||||
}
|
||||
|
@ -441,8 +214,6 @@
|
|||
provide('refreshModuleTree', refreshModuleTree);
|
||||
provide('refreshModuleTreeCount', refreshModuleTreeCount);
|
||||
provide('folderTreePathMap', folderTreePathMap.value);
|
||||
provide('docShareId', docShareId.value);
|
||||
provide('shareDetailInfo', shareDetailInfo);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -498,21 +269,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.no-resource-svg {
|
||||
margin: 0 auto 24px;
|
||||
width: 160px;
|
||||
height: 98px;
|
||||
background: url('@/assets/svg/no_resource.svg');
|
||||
background-size: cover;
|
||||
}
|
||||
:deep(.ms-modal-share) {
|
||||
.arco-modal-mask {
|
||||
background: var(--color-text-1) !important;
|
||||
}
|
||||
}
|
||||
:deep(.password-form) {
|
||||
.arco-form-item-message {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue