update: api配置

This commit is contained in:
easy 2023-01-12 17:39:02 +08:00
parent b0983a1988
commit 6728105539
8 changed files with 224 additions and 26 deletions

7
components.d.ts vendored
View File

@ -10,11 +10,10 @@ declare module '@vue/runtime-core' {
AAlert: typeof import('ant-design-vue/es')['Alert'] AAlert: typeof import('ant-design-vue/es')['Alert']
ABadge: typeof import('ant-design-vue/es')['Badge'] ABadge: typeof import('ant-design-vue/es')['Badge']
AButton: typeof import('ant-design-vue/es')['Button'] AButton: typeof import('ant-design-vue/es')['Button']
ACard: typeof import('ant-design-vue/es')['Card']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox'] ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup'] ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
ACol: typeof import('ant-design-vue/es')['Col'] ACol: typeof import('ant-design-vue/es')['Col']
ACollapse: typeof import('ant-design-vue/es')['Collapse']
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
ADatePicker: typeof import('ant-design-vue/es')['DatePicker'] ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
ADivider: typeof import('ant-design-vue/es')['Divider'] ADivider: typeof import('ant-design-vue/es')['Divider']
AEmpty: typeof import('ant-design-vue/es')['Empty'] AEmpty: typeof import('ant-design-vue/es')['Empty']
@ -29,12 +28,14 @@ declare module '@vue/runtime-core' {
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ARow: typeof import('ant-design-vue/es')['Row'] ARow: typeof import('ant-design-vue/es')['Row']
ASelect: typeof import('ant-design-vue/es')['Select'] ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASpin: typeof import('ant-design-vue/es')['Spin'] ASpin: typeof import('ant-design-vue/es')['Spin']
ASwitch: typeof import('ant-design-vue/es')['Switch'] ASwitch: typeof import('ant-design-vue/es')['Switch']
ATable: typeof import('ant-design-vue/es')['Table'] ATable: typeof import('ant-design-vue/es')['Table']
ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs']
ATimePicker: typeof import('ant-design-vue/es')['TimePicker'] ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
ATooltip: typeof import('ant-design-vue/es')['Tooltip'] ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATree: typeof import('ant-design-vue/es')['Tree']
ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect'] ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect']
AUpload: typeof import('ant-design-vue/es')['Upload'] AUpload: typeof import('ant-design-vue/es')['Upload']
BadgeStatus: typeof import('./src/components/BadgeStatus/index.vue')['default'] BadgeStatus: typeof import('./src/components/BadgeStatus/index.vue')['default']

View File

@ -15,7 +15,7 @@
</div> </div>
</div> </div>
<div class="jtable-content"> <div class="jtable-content">
<div class="jtable-alert" v-if="rowSelection.selectedRowKeys && rowSelection.selectedRowKeys.length"> <div class="jtable-alert" v-if="rowSelection && rowSelection.selectedRowKeys && rowSelection.selectedRowKeys.length">
<a-alert :message="'已选择' + rowSelection.selectedRowKeys.length + '项'" type="info" :afterClose="handleAlertClose"> <a-alert :message="'已选择' + rowSelection.selectedRowKeys.length + '项'" type="info" :afterClose="handleAlertClose">
<template #closeText> <template #closeText>
<a>取消选择</a> <a>取消选择</a>

View File

@ -8,22 +8,22 @@
</div> </div>
</div> </div>
<p style="display: flex; justify-content: space-between"> <p>
<span class="label">请求数据类型</span> <span class="label">请求数据类型</span>
<span class="value">{{ <span>{{
getContent(selectApi.requestBody) || getContent(selectApi.requestBody) ||
'application/x-www-form-urlencoded' 'application/x-www-form-urlencoded'
}}</span> }}</span>
<span class="label">响应数据类型</span> <span class="label">响应数据类型</span>
<span class="value">{{ `["/"]` }}</span> <span>{{ `["/"]` }}</span>
</p> </p>
<div class="api-card"> <div class="api-card">
<h5>请求参数</h5> <h5>请求参数</h5>
<div class="content"> <div class="content">
<JTable <JTable
:columns="columns.request" :columns="requestCard.columns"
:dataSource="selectApi.parameters" :dataSource="requestCard.tableData"
noPagination noPagination
model="TABLE" model="TABLE"
> >
@ -36,6 +36,39 @@
</JTable> </JTable>
</div> </div>
</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>
</div>
</div> </div>
</template> </template>
@ -49,11 +82,21 @@ const props = defineProps({
type: Object as PropType<apiDetailsType>, type: Object as PropType<apiDetailsType>,
required: true, required: true,
}, },
schemas: {
type: Object,
required: true,
},
}); });
const { selectApi } = toRefs(props); const { selectApi } = toRefs(props);
const columns = { type tableCardType = {
request: [ columns: object[];
tableData: object[];
activeKey?: any;
getData?: any;
};
const requestCard = reactive<tableCardType>({
columns: [
{ {
title: '参数名', title: '参数名',
dataIndex: 'name', dataIndex: 'name',
@ -82,13 +125,138 @@ const columns = {
scopedSlots: true, 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: 'name',
},
{
title: '参数说明',
dataIndex: 'desc',
},
{
title: '类型',
dataIndex: 'type',
},
],
tableData: [],
getData: (code: string) => {
type schemaObjType = {
paramsName: string;
paramsType: string;
desc: string;
children?: schemaObjType[];
};
const schemaName = responseStatusCard.tableData.find(
(item: any) => item.code === code,
).schema;
console.log(1212, schemaName);
const schemas = toRaw(props.schemas);
function findData(schemaName: string) {
if (!schemaName || schemas[schemaName]) {
console.log(schemaName, schemas);
return [];
}
const result: schemaObjType[] = [];
const schema = schemas[schemaName];
const basicType = ['string', 'integer', 'boolean'];
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);
});
console.log(result);
return result;
}
respParamsCard.tableData = findData(schemaName);
// console.log(respParamsCard.tableData);
},
});
console.log(selectApi.value);
const getContent = (data: any) => { const getContent = (data: any) => {
if (!data) return ''; if (data && data.content) {
return Object.keys(data.content)[0]; 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> </script>
<style lang="less" scoped> <style lang="less" scoped>
@ -103,13 +271,25 @@ const getContent = (data: any) => {
.input { .input {
display: flex; display: flex;
margin: 24px 0;
} }
} }
p {
display: flex;
justify-content: space-between;
font-size: 14px;
.label {
font-weight: bold;
}
}
.api-card { .api-card {
margin-top: 24px;
h5 { h5 {
position: relative; position: relative;
padding-left: 10px; padding-left: 10px;
font-weight: 600;
font-size: 16px;
&::before { &::before {
position: absolute; position: absolute;
@ -125,7 +305,6 @@ const getContent = (data: any) => {
.content { .content {
padding-left: 10px; padding-left: 10px;
:deep(.jtable-body) { :deep(.jtable-body) {
padding: 0; padding: 0;

View File

@ -5,6 +5,7 @@
<div class="input"> <div class="input">
<InputCard :value="selectApi.method" /> <InputCard :value="selectApi.method" />
<a-input :value="selectApi?.url" disabled /> <a-input :value="selectApi?.url" disabled />
<span class="send">发送</span>
</div> </div>
</div> </div>
</div> </div>
@ -36,7 +37,15 @@ const { selectApi } = toRefs(props);
.input { .input {
display: flex; display: flex;
.send {
width: 65px;
padding: 4px 15px;
font-size: 14px;
color: #fff;
background-color: #1890ff;
}
} }
} }
} }
</style> </style>

View File

@ -43,9 +43,9 @@ const columns = [
}, },
]; ];
const rowSelection: TableProps['rowSelection'] = { const rowSelection: TableProps['rowSelection'] = {
// onChange: (selectedRowKeys, selectedRows) => { onChange: (selectedRowKeys, selectedRows) => {
// console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows); console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
// }, },
}; };
const jump = (row:object) => { const jump = (row:object) => {

View File

@ -32,13 +32,14 @@ const getTreeData = () => {
Promise.all(allPromise).then((values) => { Promise.all(allPromise).then((values) => {
values.forEach((item: any, i) => { values.forEach((item: any, i) => {
tree[i].children = combData(item?.paths); tree[i].children = combData(item?.paths);
tree[i].schemas = item.components.schemas
}); });
treeData.value = tree; treeData.value = tree;
}); });
}); });
}; };
const clickSelectItem: TreeProps['onSelect'] = (key, node: any) => { const clickSelectItem: TreeProps['onSelect'] = (key, node: any) => {
emits('select', node.node.dataRef); emits('select', node.node.dataRef, node.node?.parent.node.schemas);
}; };
onMounted(() => { onMounted(() => {

View File

@ -1,9 +1,11 @@
export type treeNodeTpye = { export type treeNodeTpye = {
name: string; name: string;
key: string; key: string;
schemas?:object;
link?: string; link?: string;
apiList?: object[]; apiList?: object[];
children?: treeNodeTpye[]; children?: treeNodeTpye[];
}; };
export type methodType = { export type methodType = {
[key: string]: object [key: string]: object
@ -17,6 +19,7 @@ export type apiDetailsType = {
url: string; url: string;
method: string; method: string;
summary: string; summary: string;
parameters: []; parameters: any[];
requestBody?: any; requestBody?: any;
responses:object;
} }

View File

@ -15,12 +15,12 @@
class="api-details" class="api-details"
v-show="selectedApi.url && tableData.length > 0" v-show="selectedApi.url && tableData.length > 0"
> >
<a-button @click="selectedApi = initSelectedApi" <a-button @click="selectedApi = initSelectedApi" style="margin-bottom: 24px;"
>返回</a-button >返回</a-button
> >
<a-tabs v-model:activeKey="activeKey" type="card"> <a-tabs v-model:activeKey="activeKey" type="card">
<a-tab-pane key="does" tab="文档"> <a-tab-pane key="does" tab="文档">
<ApiDoes :select-api="selectedApi" /> <ApiDoes :select-api="selectedApi" :schemas="schemas" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="test" tab="调试"> <a-tab-pane key="test" tab="调试">
<ApiTest :select-api="selectedApi" /> <ApiTest :select-api="selectedApi" />
@ -40,7 +40,8 @@ import ApiDoes from './components/ApiDoes.vue';
import ApiTest from './components/ApiTest.vue'; import ApiTest from './components/ApiTest.vue';
const tableData = ref([]); const tableData = ref([]);
const treeSelect = (node: treeNodeTpye) => { const treeSelect = (node: treeNodeTpye, nodeSchemas:object = {}) => {
schemas.value = nodeSchemas
if (!node.apiList) return; if (!node.apiList) return;
const apiList: apiObjType[] = node.apiList as apiObjType[]; const apiList: apiObjType[] = node.apiList as apiObjType[];
const table: any = []; const table: any = [];
@ -61,10 +62,14 @@ const treeSelect = (node: treeNodeTpye) => {
}; };
const activeKey = ref('does'); const activeKey = ref('does');
const initSelectedApi = { const schemas = ref({});
const initSelectedApi:apiDetailsType = {
url: '', url: '',
method: '', method: '',
summary: '', summary: '',
parameters: [],
responses: {},
requestBody: {}
}; };
const selectedApi = ref<apiDetailsType>(initSelectedApi); const selectedApi = ref<apiDetailsType>(initSelectedApi);