diff --git a/frontend/src/assets/icon-font/iconfont.css b/frontend/src/assets/icon-font/iconfont.css
index 8497421bc3..c7c7464d9b 100644
--- a/frontend/src/assets/icon-font/iconfont.css
+++ b/frontend/src/assets/icon-font/iconfont.css
@@ -1,7 +1,7 @@
@font-face {
font-family: iconfont; /* Project id 3462279 */
- src: url('iconfont.woff2?t=1711511079663') format('woff2'), url('iconfont.woff?t=1711511079663') format('woff'),
- url('iconfont.ttf?t=1711511079663') format('truetype'), url('iconfont.svg?t=1711511079663#iconfont') format('svg');
+ src: url('iconfont.woff2?t=1714372635707') format('woff2'), url('iconfont.woff?t=1714372635707') format('woff'),
+ url('iconfont.ttf?t=1714372635707') format('truetype'), url('iconfont.svg?t=1714372635707#iconfont') format('svg');
}
.iconfont {
font-size: 16px;
@@ -10,6 +10,12 @@
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
+.icon-icon_menu_unfold::before {
+ content: '\e7a9';
+}
+.icon-icon_menu_fold::before {
+ content: '\e7aa';
+}
.icon-icon_stop::before {
content: '\e7a8';
}
diff --git a/frontend/src/assets/icon-font/iconfont.js b/frontend/src/assets/icon-font/iconfont.js
index 2a50604748..7622800d00 100644
--- a/frontend/src/assets/icon-font/iconfont.js
+++ b/frontend/src/assets/icon-font/iconfont.js
@@ -1,5 +1,5 @@
(window._iconfont_svg_string_3462279 =
- ''),
+ ''),
(function (h) {
var a = (a = document.getElementsByTagName('script'))[a.length - 1],
l = a.getAttribute('data-injectcss'),
@@ -10,7 +10,7 @@
c,
v,
t,
- z = function (a, l) {
+ m = function (a, l) {
l.parentNode.insertBefore(a, l);
};
if (l && !h.__iconfont__svg__cssinject__) {
@@ -34,7 +34,7 @@
(l.style.height = 0),
(l.style.overflow = 'hidden'),
(l = l),
- (a = document.body).firstChild ? z(l, a.firstChild) : a.appendChild(l));
+ (a = document.body).firstChild ? m(l, a.firstChild) : a.appendChild(l));
}),
document.addEventListener
? ~['complete', 'loaded', 'interactive'].indexOf(document.readyState)
@@ -49,10 +49,10 @@
(t = !1),
d(),
(v.onreadystatechange = function () {
- 'complete' == v.readyState && ((v.onreadystatechange = null), m());
+ 'complete' == v.readyState && ((v.onreadystatechange = null), z());
}));
}
- function m() {
+ function z() {
t || ((t = !0), c());
}
function d() {
@@ -61,6 +61,6 @@
} catch (a) {
return void setTimeout(d, 50);
}
- m();
+ z();
}
})(window);
diff --git a/frontend/src/assets/icon-font/iconfont.json b/frontend/src/assets/icon-font/iconfont.json
index f5cb787bb3..f9c9e2723b 100644
--- a/frontend/src/assets/icon-font/iconfont.json
+++ b/frontend/src/assets/icon-font/iconfont.json
@@ -5,6 +5,20 @@
"css_prefix_text": "icon-",
"description": "DE、MS项目icon管理",
"glyphs": [
+ {
+ "icon_id": "39725024",
+ "name": "icon_menu_unfold",
+ "font_class": "icon_menu_unfold",
+ "unicode": "e7a9",
+ "unicode_decimal": 59305
+ },
+ {
+ "icon_id": "39725023",
+ "name": "icon_menu_fold",
+ "font_class": "icon_menu_fold",
+ "unicode": "e7aa",
+ "unicode_decimal": 59306
+ },
{
"icon_id": "39710057",
"name": "icon_stop",
diff --git a/frontend/src/assets/icon-font/iconfont.svg b/frontend/src/assets/icon-font/iconfont.svg
index 3f8d494349..54e5e744ae 100644
--- a/frontend/src/assets/icon-font/iconfont.svg
+++ b/frontend/src/assets/icon-font/iconfont.svg
@@ -14,6 +14,10 @@
/>
+
+
+
+
diff --git a/frontend/src/assets/icon-font/iconfont.ttf b/frontend/src/assets/icon-font/iconfont.ttf
index 17afa2c478..2b6306f480 100644
Binary files a/frontend/src/assets/icon-font/iconfont.ttf and b/frontend/src/assets/icon-font/iconfont.ttf differ
diff --git a/frontend/src/assets/icon-font/iconfont.woff b/frontend/src/assets/icon-font/iconfont.woff
index 75930ed406..8f5d867605 100644
Binary files a/frontend/src/assets/icon-font/iconfont.woff and b/frontend/src/assets/icon-font/iconfont.woff differ
diff --git a/frontend/src/assets/icon-font/iconfont.woff2 b/frontend/src/assets/icon-font/iconfont.woff2
index 233e7006af..8cbdd60762 100644
Binary files a/frontend/src/assets/icon-font/iconfont.woff2 and b/frontend/src/assets/icon-font/iconfont.woff2 differ
diff --git a/frontend/src/components/business/ms-menu/index.vue b/frontend/src/components/business/ms-menu/index.vue
index 569206ac89..ba9d2b38fb 100644
--- a/frontend/src/components/business/ms-menu/index.vue
+++ b/frontend/src/components/business/ms-menu/index.vue
@@ -20,7 +20,7 @@
import { getFirstRouterNameByCurrentRoute } from '@/utils/permission';
import { listenerRouteChange } from '@/utils/route-listener';
- import { ProjectManagementRouteEnum, SettingRouteEnum } from '@/enums/routeEnum';
+ import { ProjectManagementRouteEnum, RouteEnum, SettingRouteEnum } from '@/enums/routeEnum';
import useMenuTree from './use-menu-tree';
import type { RouteMeta } from 'vue-router';
@@ -123,6 +123,11 @@
selectedKey.value = [activeMenu || menuOpenKeys[menuOpenKeys.length - 1]];
}
+ if (newRoute.fullPath.includes(RouteEnum.SETTING)) {
+ appStore.updateSettings({ menuCollapse: false });
+ } else {
+ appStore.updateSettings({ menuCollapse: true });
+ }
}, true);
const setCollapse = (val: boolean) => {
if (appStore.device === 'desktop') appStore.updateSettings({ menuCollapse: val });
diff --git a/frontend/src/views/api-test/components/requestComposition/index.vue b/frontend/src/views/api-test/components/requestComposition/index.vue
index c393bd6889..7961d83c1a 100644
--- a/frontend/src/views/api-test/components/requestComposition/index.vue
+++ b/frontend/src/views/api-test/components/requestComposition/index.vue
@@ -195,7 +195,7 @@
class="no-content relative mt-[8px] border-b"
/>
-
+
();
const saveLoading = ref(false);
const selectTree = computed(() => {
- if (saveModalVisible.value || (!props.isCase && props.isDefinition && saveModalVisible.value)) {
- // 调试模式打开保存弹窗,或者是接口定义模式下打开保存弹窗才进行计算,避免大数据量导致进入时就计算卡顿 TODO:worker线程处理计算任务
+ if (
+ requestVModel.value.activeTab === RequestComposition.BASE_INFO ||
+ saveModalVisible.value ||
+ (!props.isCase && props.isDefinition && saveModalVisible.value)
+ ) {
+ // 切换到基础信息 tab、调试模式打开保存弹窗,或者是接口定义模式下打开保存弹窗才进行计算,避免大数据量导致进入时就计算卡顿 TODO:worker线程处理计算任务
return filterTree(cloneDeep(props.moduleTree || []), (e) => {
e.draggable = false;
return e.type === 'MODULE';
diff --git a/frontend/src/views/api-test/components/requestComposition/response/edit.vue b/frontend/src/views/api-test/components/requestComposition/response/edit.vue
index 545783d64e..07acfe649e 100644
--- a/frontend/src/views/api-test/components/requestComposition/response/edit.vue
+++ b/frontend/src/views/api-test/components/requestComposition/response/edit.vue
@@ -222,7 +222,6 @@
import { defaultKeyValueParamItem, defaultResponseItem, statusCodes } from '../../config';
const props = defineProps<{
- responseDefinition: ResponseDefinition[];
uploadTempFileApi?: (file: File) => Promise; // 上传临时文件接口
}>();
const emit = defineEmits<{
@@ -240,15 +239,25 @@
const responseTabs = defineModel('responseDefinition', {
required: true,
});
- const activeResponse = ref(responseTabs.value[0] || defaultResponseItem);
+ const activeResponse = ref(responseTabs.value[0] || cloneDeep(defaultResponseItem));
+
+ watch(
+ () => responseTabs.value,
+ (arr) => {
+ if (arr.length > 0) {
+ [activeResponse.value] = arr;
+ }
+ }
+ );
function addResponseTab(defaultProps?: Partial) {
+ const id = new Date().getTime();
responseTabs.value.push({
...cloneDeep(defaultResponseItem),
label: t('apiTestManagement.response', { count: responseTabs.value.length + 1 }),
name: t('apiTestManagement.response', { count: responseTabs.value.length + 1 }),
...defaultProps,
- id: new Date().getTime(),
+ id,
defaultFlag: false,
showPopConfirm: false,
showRenamePopConfirm: false,
diff --git a/frontend/src/views/api-test/components/requestComposition/response/index.vue b/frontend/src/views/api-test/components/requestComposition/response/index.vue
index 428dcdafe7..30ccb260f5 100644
--- a/frontend/src/views/api-test/components/requestComposition/response/index.vue
+++ b/frontend/src/views/api-test/components/requestComposition/response/index.vue
@@ -3,7 +3,7 @@
-
+
{{ t('apiTestDebug.responseContent') }}
emit('changeLayout', val as Direction)"
@@ -62,14 +62,14 @@
:class="[isResponseModel ? 'h-[381px] w-full' : 'h-[calc(100%-35px)] w-full px-[16px] pb-[16px]']"
>
(),
{
isExpanded: true,
- activeLayout: 'vertical',
hideLayoutSwitch: false,
showEmpty: true,
}
@@ -131,21 +127,21 @@
const { t } = useI18n();
- const innerLayout = defineModel('activeLayout', {
+ const activeLayout = defineModel('activeLayout', {
default: 'vertical',
});
- const innerActiveTab = defineModel('activeTab', {
+ const activeTab = defineModel('activeTab', {
required: true,
});
- const innerResponseDefinition = defineModel('responseDefinition', {
+ const responseDefinition = defineModel('responseDefinition', {
default: [],
});
watchEffect(() => {
// 过滤无效数据后的有效响应数据;当接口导入时会存在部分字段为 null 的数据,需要设置默认值
let hasInvalid = false;
let validResponseDefinition: ResponseItem[] = [];
- if (props.responseDefinition && props.responseDefinition.length > 0) {
- validResponseDefinition = props.responseDefinition.map((item, i) => {
+ if (responseDefinition.value.length > 0) {
+ validResponseDefinition = responseDefinition.value.map((item, i) => {
// 某些字段在导入时接口返回 null,需要设置默认值
if (!item.headers) {
item.headers = [];
@@ -189,7 +185,7 @@
});
}
if (hasInvalid) {
- innerResponseDefinition.value = validResponseDefinition;
+ responseDefinition.value = validResponseDefinition;
}
});
diff --git a/frontend/src/views/api-test/components/requestComposition/response/result/body.vue b/frontend/src/views/api-test/components/requestComposition/response/result/body.vue
index 104faf3114..e203f24b24 100644
--- a/frontend/src/views/api-test/components/requestComposition/response/result/body.vue
+++ b/frontend/src/views/api-test/components/requestComposition/response/result/body.vue
@@ -1,18 +1,26 @@
-
+
{{ t('common.download') }}
- {{ t('common.image') }}
+ pdf
+ {{ t('common.image') }}
{{ t('common.text') }}
-
+
+
{
+ if (props.requestResult) {
+ return props.requestResult.responseResult.contentType === 'application/pdf';
+ }
+ return false;
+ });
const imageUrl = computed(() => {
if (props.requestResult) {
return `data:${props.requestResult?.responseResult.contentType};base64,${props.requestResult?.responseResult.imageUrl}`;
@@ -88,10 +102,24 @@
return '';
});
- const showType = ref<'image' | 'text'>('image');
+ const showType = ref<'image' | 'pdf' | 'text'>('image');
+
+ watchEffect(() => {
+ if (props.requestResult) {
+ if (showImg.value) {
+ showType.value = 'image';
+ } else if (isPdf.value) {
+ showType.value = 'pdf';
+ } else {
+ showType.value = 'text';
+ }
+ }
+ });
function handleDownload() {
- if (imageUrl.value) {
+ if (isPdf.value) {
+ downloadUrlFile(imageUrl.value, 'response.pdf');
+ } else if (imageUrl.value) {
downloadUrlFile(imageUrl.value, `response.${props.requestResult?.responseResult.contentType.split('/')[1]}`);
}
}
diff --git a/frontend/src/views/api-test/management/components/management/api/index.vue b/frontend/src/views/api-test/management/components/management/api/index.vue
index 8537637198..b92fe6c78f 100644
--- a/frontend/src/views/api-test/management/components/management/api/index.vue
+++ b/frontend/src/views/api-test/management/components/management/api/index.vue
@@ -105,7 +105,19 @@
:member-options="memberOptions"
/>
-
+
+
+
@@ -115,7 +127,6 @@
import { cloneDeep } from 'lodash-es';
import { TabItem } from '@/components/pure/ms-editable-tab/types';
- import caseTable from '../case/caseTable.vue';
// import MsFormCreate from '@/components/pure/ms-form-create/formCreate.vue';
import apiTable from './apiTable.vue';
import executeButton from '@/views/api-test/components/executeButton.vue';
@@ -156,6 +167,8 @@
() => import('@/views/api-test/components/requestComposition/index.vue')
);
const preview = defineAsyncComponent(() => import('./preview/index.vue'));
+ const mockTable = defineAsyncComponent(() => import('../mock/mockTable.vue'));
+ const caseTable = defineAsyncComponent(() => import('../case/caseTable.vue'));
const props = defineProps<{
activeModule: string;
diff --git a/frontend/src/views/api-test/management/components/management/case/caseTable.vue b/frontend/src/views/api-test/management/components/management/case/caseTable.vue
index 7956cf6886..e67aa2f76a 100644
--- a/frontend/src/views/api-test/management/components/management/case/caseTable.vue
+++ b/frontend/src/views/api-test/management/components/management/case/caseTable.vue
@@ -47,9 +47,9 @@
- {{
- record.num
- }}
+
+ {{ record.num }}
+
handleDeleteApiFromModuleTree(id)"
/>
+
+
+
diff --git a/frontend/src/views/api-test/management/components/management/mock/mockDetailDrawer.vue b/frontend/src/views/api-test/management/components/management/mock/mockDetailDrawer.vue
new file mode 100644
index 0000000000..f94e8d22cd
--- /dev/null
+++ b/frontend/src/views/api-test/management/components/management/mock/mockDetailDrawer.vue
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+ {{ t('common.edit') }}
+
+
+
+ {{ t('common.delete') }}
+
+
+
+
+
+
+
+
{{ t('apiTestManagement.apiType') }}
+
+
+
+
{{ t('apiTestManagement.path') }}
+
+ {{ mockDetail.apiPath }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('mockManagement.matchRule') }}
+
+
+
+ {{ requestBodyTypeMap[item] }}
+
+
+
+
+ {{ t('apiTestDebug.noneBody') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/api-test/management/components/management/mock/mockTable.vue b/frontend/src/views/api-test/management/components/management/mock/mockTable.vue
index 16b5042dc2..bb68559575 100644
--- a/frontend/src/views/api-test/management/components/management/mock/mockTable.vue
+++ b/frontend/src/views/api-test/management/components/management/mock/mockTable.vue
@@ -1,7 +1,15 @@
-
-
-
+
+
+
+ {{ t('mockManagement.createMock') }}
+
+
-
+
+
+ {{ record.num }}
+
+
+
changeDefault(value, record)"
>
+
+
+
+ {{ t('apiTestManagement.debug') }}
+
+
+
+ {{ t('apiTestManagement.tableNoDataAndPlease') }}
+
+ {{ t('mockManagement.createMock') }}
+
+
+
+
+