381 lines
11 KiB
Vue
381 lines
11 KiB
Vue
<template>
|
|
<div class="api-does-container">
|
|
<div class="top">
|
|
<h5>{{ selectApi.summary }}</h5>
|
|
<div class="input">
|
|
<InputCard :value="selectApi.method" />
|
|
<a-input :value="selectApi?.url" disabled />
|
|
</div>
|
|
</div>
|
|
|
|
<p>
|
|
<span class="label">请求数据类型</span>
|
|
<span>{{
|
|
getContent(selectApi.requestBody) ||
|
|
'application/x-www-form-urlencoded'
|
|
}}</span>
|
|
<span class="label">响应数据类型</span>
|
|
<span>{{ `["/"]` }}</span>
|
|
</p>
|
|
|
|
<div class="api-card">
|
|
<h5>请求参数</h5>
|
|
<div class="content">
|
|
<JTable
|
|
:columns="requestCard.columns"
|
|
:dataSource="requestCard.tableData"
|
|
noPagination
|
|
model="TABLE"
|
|
>
|
|
<template #required="slotProps">
|
|
<span>{{ Boolean(slotProps.required) + '' }}</span>
|
|
</template>
|
|
<template #type="slotProps">
|
|
<span>{{ slotProps.schema.type }}</span>
|
|
</template>
|
|
</JTable>
|
|
</div>
|
|
</div>
|
|
<div class="api-card">
|
|
<h5>响应状态</h5>
|
|
<div class="content">
|
|
<JTable
|
|
:columns="responseStatusCard.columns"
|
|
:dataSource="responseStatusCard.tableData"
|
|
noPagination
|
|
model="TABLE"
|
|
>
|
|
</JTable>
|
|
|
|
<a-tabs v-model:activeKey="responseStatusCard.activeKey">
|
|
<a-tab-pane
|
|
:key="key"
|
|
:tab="key"
|
|
v-for="key in tabs"
|
|
></a-tab-pane>
|
|
</a-tabs>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="api-card">
|
|
<h5>响应参数</h5>
|
|
<div class="content">
|
|
<JTable
|
|
:columns="respParamsCard.columns"
|
|
:dataSource="respParamsCard.tableData"
|
|
noPagination
|
|
model="TABLE"
|
|
>
|
|
</JTable>
|
|
</div>
|
|
|
|
<MonacoEditor
|
|
v-model:modelValue="codeText"
|
|
style="height: 300px; width: 100%"
|
|
theme="vs"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import MonacoEditor from '@/components/MonacoEditor/index.vue';
|
|
import type { apiDetailsType } from '../typing';
|
|
import InputCard from './InputCard.vue';
|
|
import { PropType } from 'vue';
|
|
|
|
const emit = defineEmits(['update:paramsTable'])
|
|
const props = defineProps({
|
|
selectApi: {
|
|
type: Object as PropType<apiDetailsType>,
|
|
required: true,
|
|
},
|
|
schemas: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
});
|
|
const { selectApi } = toRefs(props);
|
|
|
|
type tableCardType = {
|
|
columns: object[];
|
|
tableData: object[];
|
|
codeText?: any;
|
|
activeKey?: any;
|
|
getData?: any;
|
|
};
|
|
const requestCard = reactive<tableCardType>({
|
|
columns: [
|
|
{
|
|
title: '参数名',
|
|
dataIndex: 'name',
|
|
key: 'name',
|
|
},
|
|
{
|
|
title: '参数说明',
|
|
dataIndex: 'description',
|
|
key: 'description',
|
|
},
|
|
{
|
|
title: '请求类型',
|
|
dataIndex: 'in',
|
|
key: 'in',
|
|
},
|
|
{
|
|
title: '是否必须',
|
|
dataIndex: 'required',
|
|
key: 'required',
|
|
scopedSlots: true,
|
|
},
|
|
{
|
|
title: '参数类型',
|
|
dataIndex: 'type',
|
|
key: 'type',
|
|
scopedSlots: true,
|
|
},
|
|
],
|
|
tableData: [],
|
|
getData: () => {
|
|
requestCard.tableData = props.selectApi.parameters;
|
|
},
|
|
});
|
|
const responseStatusCard = reactive<tableCardType>({
|
|
activeKey: '',
|
|
columns: [
|
|
{
|
|
title: '状态码',
|
|
dataIndex: 'code',
|
|
key: 'code',
|
|
},
|
|
{
|
|
title: '说明',
|
|
dataIndex: 'desc',
|
|
key: 'desc',
|
|
},
|
|
{
|
|
title: 'schema',
|
|
dataIndex: 'schema',
|
|
key: 'schema',
|
|
},
|
|
],
|
|
tableData: [],
|
|
getData: () => {
|
|
if (!Object.keys(props.selectApi.responses).length)
|
|
return (responseStatusCard.tableData = []);
|
|
|
|
const tableData = <any>[];
|
|
Object.entries(props.selectApi.responses || {}).forEach((item: any) => {
|
|
const desc = item[1].description;
|
|
const schema = item[1].content['*/*'].schema.$ref?.split('/') || '';
|
|
|
|
tableData.push({
|
|
code: item[0],
|
|
desc,
|
|
schema: schema && schema.pop(),
|
|
});
|
|
});
|
|
responseStatusCard.activeKey = tableData[0]?.code;
|
|
responseStatusCard.tableData = tableData;
|
|
},
|
|
});
|
|
const tabs = computed(() =>
|
|
responseStatusCard.tableData
|
|
.map((item: any) => item.code + '')
|
|
.filter((code: string) => code !== '400'),
|
|
);
|
|
const respParamsCard = reactive<tableCardType>({
|
|
columns: [
|
|
{
|
|
title: '参数名称',
|
|
dataIndex: 'paramsName',
|
|
},
|
|
{
|
|
title: '参数说明',
|
|
dataIndex: 'desc',
|
|
},
|
|
{
|
|
title: '类型',
|
|
dataIndex: 'paramsType',
|
|
},
|
|
],
|
|
tableData: [],
|
|
codeText: '',
|
|
getData: (code: string) => {
|
|
type schemaObjType = {
|
|
paramsName: string;
|
|
paramsType: string;
|
|
desc?: string;
|
|
children?: schemaObjType[];
|
|
};
|
|
|
|
const schemaName = responseStatusCard.tableData.find(
|
|
(item: any) => item.code === code,
|
|
)?.schema;
|
|
const schemas = toRaw(props.schemas);
|
|
const basicType = ['string', 'integer', 'boolean'];
|
|
|
|
const tableData = findData(schemaName);
|
|
const codeText = getCodeText(tableData, 3);
|
|
|
|
emit('update:paramsTable', tableData)
|
|
respParamsCard.tableData = tableData;
|
|
respParamsCard.codeText = JSON.stringify(codeText);
|
|
|
|
function findData(schemaName: string) {
|
|
if (!schemaName || !schemas[schemaName]) {
|
|
return [];
|
|
}
|
|
const result: schemaObjType[] = [];
|
|
const schema = schemas[schemaName];
|
|
Object.entries(schema.properties).forEach((item: [string, any]) => {
|
|
const paramsType =
|
|
item[1].type ||
|
|
(item[1].$ref && item[1].$ref.split('/').pop()) ||
|
|
(item[1].items && item[1].items.$ref.split('/').pop()) ||
|
|
'';
|
|
const schemaObj: schemaObjType = {
|
|
paramsName: item[0],
|
|
paramsType,
|
|
desc: item[1].description || '',
|
|
};
|
|
if (!basicType.includes(paramsType))
|
|
schemaObj.children = findData(paramsType);
|
|
result.push(schemaObj);
|
|
});
|
|
|
|
return result;
|
|
}
|
|
function getCodeText(arr: schemaObjType[], level: number): object {
|
|
const result = {};
|
|
|
|
arr.forEach((item) => {
|
|
switch (item.paramsType) {
|
|
case 'string':
|
|
result[item.paramsName] = '';
|
|
break;
|
|
case 'integer':
|
|
result[item.paramsName] = 0;
|
|
break;
|
|
case 'boolean':
|
|
result[item.paramsName] = true;
|
|
break;
|
|
case 'array':
|
|
result[item.paramsName] = [];
|
|
break;
|
|
case 'object':
|
|
result[item.paramsName] = {};
|
|
break;
|
|
default: {
|
|
const properties = schemas[item.paramsType]
|
|
.properties as object;
|
|
const newArr = Object.entries(properties).map(
|
|
(item: [string, any]) => ({
|
|
paramsName: item[0],
|
|
paramsType: level
|
|
? (item[1].$ref &&
|
|
item[1].$ref.split('/').pop()) ||
|
|
(item[1].items &&
|
|
item[1].items.$ref
|
|
.split('/')
|
|
.pop()) ||
|
|
item[1].type ||
|
|
''
|
|
: item[1].type,
|
|
}),
|
|
);
|
|
result[item.paramsName] = getCodeText(
|
|
newArr,
|
|
level - 1,
|
|
);
|
|
}
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
},
|
|
});
|
|
|
|
const { codeText } = toRefs(requestCard);
|
|
|
|
const getContent = (data: any) => {
|
|
if (data && data.content) {
|
|
return Object.keys(data.content || {})[0];
|
|
}
|
|
return '';
|
|
};
|
|
onMounted(() => {
|
|
requestCard.getData();
|
|
responseStatusCard.getData();
|
|
});
|
|
watch(
|
|
() => props.selectApi,
|
|
() => {
|
|
requestCard.getData();
|
|
responseStatusCard.getData();
|
|
},
|
|
);
|
|
|
|
watch([() => responseStatusCard.activeKey, () => props.selectApi], (n) => {
|
|
n[0] && respParamsCard.getData(n[0]);
|
|
});
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.api-does-container {
|
|
.top {
|
|
width: 100%;
|
|
|
|
h5 {
|
|
font-weight: bold;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.input {
|
|
display: flex;
|
|
margin: 24px 0;
|
|
}
|
|
}
|
|
p {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-size: 14px;
|
|
|
|
.label {
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
.api-card {
|
|
margin-top: 24px;
|
|
h5 {
|
|
position: relative;
|
|
padding-left: 10px;
|
|
font-weight: 600;
|
|
font-size: 16px;
|
|
|
|
&::before {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 4px;
|
|
height: 100%;
|
|
background-color: #1d39c4;
|
|
border-radius: 0 3px 3px 0;
|
|
content: ' ';
|
|
}
|
|
}
|
|
.content {
|
|
padding-left: 10px;
|
|
|
|
:deep(.jtable-body) {
|
|
padding: 0;
|
|
|
|
.jtable-body-header {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|