Merge branch 'main' of ssh://git.jizhiweb.cn:2222/clinic-v2/web

This commit is contained in:
ChenQiuYu 2025-05-28 15:45:51 +08:00
commit 25ddf183a1
3 changed files with 226 additions and 1 deletions

2
.gitignore vendored
View File

@ -13,7 +13,7 @@ dist
dist-ssr
coverage
*.local
test_json
/cypress/videos/
/cypress/screenshots/

View File

@ -11,6 +11,10 @@ const router = createRouter({
path: '/manager/login',
component: () => import('../views/Login.vue'),
},
{
path: '/doc',
component: () => import('../views/doc.vue'),
},
{
path: '/home',
component: () => import('../views/Layout.vue'),

221
src/views/doc.vue Normal file
View File

@ -0,0 +1,221 @@
<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>