Compare commits
No commits in common. "f898aa94d57f3f156db7c30be2db8a9cc5ba9878" and "6992ed6331b41993f7f654cc5df0100f9d635c10" have entirely different histories.
f898aa94d5
...
6992ed6331
|
|
@ -13,7 +13,7 @@ dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
coverage
|
coverage
|
||||||
*.local
|
*.local
|
||||||
test_json
|
|
||||||
/cypress/videos/
|
/cypress/videos/
|
||||||
/cypress/screenshots/
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,6 @@ const router = createRouter({
|
||||||
path: '/manager/login',
|
path: '/manager/login',
|
||||||
component: () => import('../views/Login.vue'),
|
component: () => import('../views/Login.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/doc',
|
|
||||||
component: () => import('../views/doc.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/home',
|
path: '/home',
|
||||||
component: () => import('../views/Layout.vue'),
|
component: () => import('../views/Layout.vue'),
|
||||||
|
|
|
||||||
|
|
@ -1,221 +0,0 @@
|
||||||
<script setup lang="ts">
|
|
||||||
import {post} from "@/utils/request.ts";
|
|
||||||
import {ref} from "vue";
|
|
||||||
function convertToTreeData(data: any, parentPath: string = '') {
|
|
||||||
const treeData: any[] = [];
|
|
||||||
|
|
||||||
for (const key in data) {
|
|
||||||
const item = data[key];
|
|
||||||
|
|
||||||
// ✅ 增加类型判断,防止无限递归
|
|
||||||
if (typeof item !== 'object' || item === null || Array.isArray(item)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentPath = parentPath ? `${parentPath}/${key}` : key;
|
|
||||||
|
|
||||||
if (item.path && item.comment) {
|
|
||||||
treeData.push({
|
|
||||||
label: `${item.comment} (${item.path})`,
|
|
||||||
path: item.path,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const children = convertToTreeData(item, currentPath);
|
|
||||||
treeData.push({
|
|
||||||
label: item.comment || key,
|
|
||||||
path: currentPath,
|
|
||||||
children,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return treeData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 使用示例
|
|
||||||
const treeData = ref<any[]>([]);
|
|
||||||
|
|
||||||
post("doc/base/getCatalog").then((response: any) => {
|
|
||||||
let tree=convertToTreeData(response);
|
|
||||||
treeData.value = tree
|
|
||||||
});
|
|
||||||
let requestsList:any[]=[];
|
|
||||||
let responseList:any[]=[];
|
|
||||||
const handleNodeClick = (data: any) => {
|
|
||||||
if (!data.children || data.children.length === 0) {
|
|
||||||
post("doc/base/getApiInfo", {path: data.path}).then((res: any) => {
|
|
||||||
apiInfo.value=res;
|
|
||||||
let requests=res.requests;
|
|
||||||
requestsList=[];
|
|
||||||
getRequestTree(requests)
|
|
||||||
apiInfo.value.requests=requestsList;
|
|
||||||
responseList=[];
|
|
||||||
getResponseTree(res.response,0,data.path)
|
|
||||||
apiInfo.value.response=responseList;
|
|
||||||
|
|
||||||
})
|
|
||||||
// 在这里执行你的业务逻辑,例如跳转、请求详情等
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const getRequestTree = (requests: any[], level: number = 0): void => {
|
|
||||||
requests.forEach((request) => {
|
|
||||||
// 打印当前层级和请求路径或其他信息
|
|
||||||
request.level=level;
|
|
||||||
requestsList.push(request)
|
|
||||||
|
|
||||||
// 如果存在 children 并且是数组,则递归调用,层级 +1
|
|
||||||
if (request.children && Array.isArray(request.children)) {
|
|
||||||
getRequestTree(request.children, level + 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const getResponseTree = (data: any, level: number = 0, parentKey: string = ''): void=> {
|
|
||||||
data.level=level;
|
|
||||||
responseList.push(data)
|
|
||||||
|
|
||||||
if (data.children && Array.isArray(data.children)) {
|
|
||||||
for (let i = 0; i < data.children.length; i++){
|
|
||||||
getResponseTree(data.children[i], level + 1, parentKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const apiInfo:any=ref(null);
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
<el-tree
|
|
||||||
class="tree"
|
|
||||||
:data="treeData"
|
|
||||||
:props="{ children: 'children', label: 'label' }"
|
|
||||||
@node-click="handleNodeClick"
|
|
||||||
/>
|
|
||||||
<div class="api-info-container" v-if="apiInfo">
|
|
||||||
<div class="apiInfo">
|
|
||||||
<div class="name">{{ apiInfo.comment }}</div>
|
|
||||||
<div class="path">{{ apiInfo.path }}</div>
|
|
||||||
<div class="request-wrapper">
|
|
||||||
<div class="tip">请求参数</div>
|
|
||||||
<div class="request" v-for="item in apiInfo.requests">
|
|
||||||
<div class="offset" :key="item.path" :style="{ paddingLeft: item.level * 20 + 'px' }"></div>
|
|
||||||
<div class="name">{{ item.name }}</div>
|
|
||||||
<div class="comment">{{ item.comment }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="responses" v-if="apiInfo.response && apiInfo.response.length">
|
|
||||||
<div class="tip">响应参数</div>
|
|
||||||
<div
|
|
||||||
class="response"
|
|
||||||
v-for="item in apiInfo.response"
|
|
||||||
>
|
|
||||||
<div class="offset" :key="item.path" :style="{ paddingLeft: item.level * 20 + 'px' }"></div>
|
|
||||||
<div class="name">{{ item.name }}</div>
|
|
||||||
<div class="comment">{{ item.comment }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
height: 100vh;
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree {
|
|
||||||
width: 300px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-right: 1px solid #e4e7ed;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
:deep(.el-tree-node__content) {
|
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
padding-left: 10px !important;
|
|
||||||
|
|
||||||
.el-tree-node__label {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-tree-node.is-current > .el-tree-node__content) {
|
|
||||||
background-color: #ecf5ff;
|
|
||||||
border-right: 2px solid #409EFF;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.api-info-container {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.apiInfo {
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
|
||||||
padding: 20px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #1a1a1a;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.path {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #f0f3f6;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.request-wrapper,
|
|
||||||
.responses {
|
|
||||||
margin-top: 20px;
|
|
||||||
|
|
||||||
.tip {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.request,
|
|
||||||
.response {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 8px 0;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
|
|
||||||
.offset {
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
width: 150px;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.comment {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Loading…
Reference in New Issue