update: api配置
This commit is contained in:
parent
26617fc559
commit
ffc55b91e0
|
@ -28,6 +28,8 @@ declare module '@vue/runtime-core' {
|
||||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||||
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']
|
||||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||||
ATree: typeof import('ant-design-vue/es')['Tree']
|
ATree: typeof import('ant-design-vue/es')['Tree']
|
||||||
AUpload: typeof import('ant-design-vue/es')['Upload']
|
AUpload: typeof import('ant-design-vue/es')['Upload']
|
||||||
|
|
|
@ -30,18 +30,10 @@
|
||||||
重置
|
重置
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
<a-table
|
<JTable :columns="columns">
|
||||||
:columns="columns"
|
|
||||||
:data-source="tableData"
|
</JTable>
|
||||||
:row-selection="{
|
|
||||||
onChange: (selectedRowKeys, selectedRows) =>
|
|
||||||
(selectItem = selectedRows),
|
|
||||||
type: 'radio',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
</a-table>
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a-button key="back" @click="visible = false">取消</a-button>
|
<a-button key="back" @click="visible = false">取消</a-button>
|
||||||
<a-button key="submit" type="primary" @click="handleOk"
|
<a-button key="submit" type="primary" @click="handleOk"
|
||||||
|
@ -90,9 +82,7 @@ const productList = ref<[productItem] | []>([]);
|
||||||
const getOptions = () => {
|
const getOptions = () => {
|
||||||
productList.value = [];
|
productList.value = [];
|
||||||
};
|
};
|
||||||
const clickSearch = ()=>{
|
const clickSearch = () => {};
|
||||||
|
|
||||||
}
|
|
||||||
const clickReset = () => {
|
const clickReset = () => {
|
||||||
Object.entries(form.value).forEach(([prop]) => {
|
Object.entries(form.value).forEach(([prop]) => {
|
||||||
form.value[prop] = '';
|
form.value[prop] = '';
|
||||||
|
@ -102,27 +92,27 @@ const clickReset = () => {
|
||||||
// 表格部分
|
// 表格部分
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
name: 'deviceId',
|
title: '设备Id',
|
||||||
dataIndex: 'deviceId',
|
dataIndex: 'deviceId',
|
||||||
key: 'deviceId',
|
key: 'deviceId',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'deviceName',
|
title: '设备名称',
|
||||||
dataIndex: 'deviceName',
|
dataIndex: 'deviceName',
|
||||||
key: 'deviceName',
|
key: 'deviceName',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'productName',
|
title: '产品名称',
|
||||||
dataIndex: 'productName',
|
dataIndex: 'productName',
|
||||||
key: 'productName',
|
key: 'productName',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'createTime',
|
title: '注册时间',
|
||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
key: 'createTime',
|
key: 'createTime',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'status',
|
title: '状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
key: 'status',
|
key: 'status',
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
<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 style="display: flex; justify-content: space-between">
|
||||||
|
<span class="label">请求数据类型</span>
|
||||||
|
<span class="value">{{
|
||||||
|
getContent(selectApi.requestBody) ||
|
||||||
|
'application/x-www-form-urlencoded'
|
||||||
|
}}</span>
|
||||||
|
<span class="label">响应数据类型</span>
|
||||||
|
<span class="value">{{ `["/"]` }}</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="api-card">
|
||||||
|
<h5>请求参数</h5>
|
||||||
|
<div class="content">
|
||||||
|
<JTable
|
||||||
|
:columns="columns.request"
|
||||||
|
:dataSource="selectApi.parameters"
|
||||||
|
noPagination
|
||||||
|
model="TABLE"
|
||||||
|
>
|
||||||
|
<template #required="slotProps">
|
||||||
|
<span>{{ slotProps.row.required + '' }}</span>
|
||||||
|
</template>
|
||||||
|
<template #type="slotProps">
|
||||||
|
<span>{{ slotProps.row.schema.type }}</span>
|
||||||
|
</template>
|
||||||
|
</JTable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { apiDetailsType } from '../index';
|
||||||
|
import InputCard from './InputCard.vue';
|
||||||
|
import { PropType } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
selectApi: {
|
||||||
|
type: Object as PropType<apiDetailsType>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { selectApi } = toRefs(props);
|
||||||
|
|
||||||
|
const columns = {
|
||||||
|
request: [
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(selectApi.value);
|
||||||
|
const getContent = (data: any) => {
|
||||||
|
if (!data) return '';
|
||||||
|
return Object.keys(data.content)[0];
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.api-does-container {
|
||||||
|
.top {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-card {
|
||||||
|
h5 {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
&::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>
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<div class="api-test-container">
|
||||||
|
<div class="top">
|
||||||
|
<h5>{{ selectApi.summary }}</h5>
|
||||||
|
<div class="input">
|
||||||
|
<InputCard :value="selectApi.method" />
|
||||||
|
<a-input :value="selectApi?.url" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { apiDetailsType } from '../index';
|
||||||
|
import InputCard from './InputCard.vue';
|
||||||
|
import { PropType } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
selectApi: {
|
||||||
|
type: Object as PropType<apiDetailsType>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { selectApi } = toRefs(props);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.api-test-container {
|
||||||
|
.top {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,65 @@
|
||||||
|
<template>
|
||||||
|
<div class="choose-api-container">
|
||||||
|
<JTable
|
||||||
|
:columns="columns"
|
||||||
|
:dataSource="props.tableData"
|
||||||
|
:rowSelection="rowSelection"
|
||||||
|
noPagination
|
||||||
|
model="TABLE"
|
||||||
|
>
|
||||||
|
<template #url="slotProps">
|
||||||
|
<span
|
||||||
|
style="color: #1d39c4; cursor: pointer"
|
||||||
|
@click="jump(slotProps.row)"
|
||||||
|
>{{ slotProps.row.url }}</span
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</JTable>
|
||||||
|
|
||||||
|
<a-button type="primary">保存</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { TableProps } from 'ant-design-vue';
|
||||||
|
|
||||||
|
const emits = defineEmits(['update:clickApi'])
|
||||||
|
const props = defineProps({
|
||||||
|
tableData: Array,
|
||||||
|
clickApi: Object
|
||||||
|
});
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: 'API',
|
||||||
|
dataIndex: 'url',
|
||||||
|
key: 'url',
|
||||||
|
scopedSlots: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '说明',
|
||||||
|
dataIndex: 'summary',
|
||||||
|
key: 'summary',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const rowSelection: TableProps['rowSelection'] = {
|
||||||
|
// onChange: (selectedRowKeys, selectedRows) => {
|
||||||
|
// console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
|
||||||
|
const jump = (row:object) => {
|
||||||
|
emits('update:clickApi',row)
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.choose-api-container {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
:deep(.jtable-body-header) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<template>
|
||||||
|
<span class="input-card-container" :class="props.value">
|
||||||
|
{{ props.value?.toLocaleUpperCase() }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
value: String,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.input-card-container {
|
||||||
|
padding: 4px 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
&.get {
|
||||||
|
background-color: #1890ff;
|
||||||
|
}
|
||||||
|
&.put {
|
||||||
|
background-color: #fa8c16;
|
||||||
|
}
|
||||||
|
&.post {
|
||||||
|
background-color: #52c41a;
|
||||||
|
}
|
||||||
|
&.delete {
|
||||||
|
background-color: #f5222d;
|
||||||
|
}
|
||||||
|
&.patch {
|
||||||
|
background-color: #a0d911;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -81,6 +81,9 @@ const combData = (dataSource: object) => {
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.left-tree-container {
|
.left-tree-container {
|
||||||
|
border-right: 1px solid #e9e9e9;
|
||||||
|
height: calc(100vh - 150px);
|
||||||
|
overflow-y: auto;
|
||||||
.ant-tree-list {
|
.ant-tree-list {
|
||||||
.ant-tree-list-holder-inner {
|
.ant-tree-list-holder-inner {
|
||||||
.ant-tree-switcher-noop {
|
.ant-tree-switcher-noop {
|
||||||
|
|
|
@ -6,9 +6,17 @@ export type treeNodeTpye = {
|
||||||
children?: treeNodeTpye[];
|
children?: treeNodeTpye[];
|
||||||
};
|
};
|
||||||
export type methodType = {
|
export type methodType = {
|
||||||
[key:string]: object
|
[key: string]: object
|
||||||
}
|
}
|
||||||
export type apiObjType = {
|
export type apiObjType = {
|
||||||
url: string,
|
url: string,
|
||||||
method: methodType
|
method: methodType
|
||||||
|
}
|
||||||
|
|
||||||
|
export type apiDetailsType = {
|
||||||
|
url: string;
|
||||||
|
method: string;
|
||||||
|
summary: string;
|
||||||
|
parameters: [];
|
||||||
|
requestBody?: any;
|
||||||
}
|
}
|
|
@ -1,17 +1,47 @@
|
||||||
<template>
|
<template>
|
||||||
<a-card class="api-page-container">
|
<a-card class="api-page-container">
|
||||||
<LeftTree @select="treeSelect" />
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="5">
|
||||||
|
<LeftTree @select="treeSelect" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="19">
|
||||||
|
<ChooseApi
|
||||||
|
v-show="!selectedApi.url"
|
||||||
|
v-model:click-api="selectedApi"
|
||||||
|
:table-data="tableData"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="api-details"
|
||||||
|
v-show="selectedApi.url && tableData.length > 0"
|
||||||
|
>
|
||||||
|
<a-button @click="selectedApi = initSelectedApi"
|
||||||
|
>返回</a-button
|
||||||
|
>
|
||||||
|
<a-tabs v-model:activeKey="activeKey" type="card">
|
||||||
|
<a-tab-pane key="does" tab="文档">
|
||||||
|
<ApiDoes :select-api="selectedApi" />
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="test" tab="调试">
|
||||||
|
<ApiTest :select-api="selectedApi" />
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
</a-card>
|
</a-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts" name="apiPage">
|
||||||
|
import { treeNodeTpye, apiObjType, apiDetailsType } from './index';
|
||||||
import LeftTree from './components/LeftTree.vue';
|
import LeftTree from './components/LeftTree.vue';
|
||||||
import { treeNodeTpye, apiObjType } from './index';
|
import ChooseApi from './components/ChooseApi.vue';
|
||||||
|
import ApiDoes from './components/ApiDoes.vue';
|
||||||
|
import ApiTest from './components/ApiTest.vue';
|
||||||
|
|
||||||
const tableData = ref([]);
|
const tableData = ref([]);
|
||||||
const treeSelect = (node: treeNodeTpye) => {
|
const treeSelect = (node: treeNodeTpye) => {
|
||||||
|
if (!node.apiList) return;
|
||||||
const apiList: apiObjType[] = node.apiList as apiObjType[];
|
const apiList: apiObjType[] = node.apiList as apiObjType[];
|
||||||
const table: any = [];
|
const table: any = [];
|
||||||
// 将对象形式的数据转换为表格需要的形式
|
// 将对象形式的数据转换为表格需要的形式
|
||||||
|
@ -22,12 +52,23 @@ const treeSelect = (node: treeNodeTpye) => {
|
||||||
table.push({
|
table.push({
|
||||||
...method[key],
|
...method[key],
|
||||||
url,
|
url,
|
||||||
|
method: key,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tableData.value = table;
|
tableData.value = table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const activeKey = ref('does');
|
||||||
|
const initSelectedApi = {
|
||||||
|
url: '',
|
||||||
|
method: '',
|
||||||
|
summary: '',
|
||||||
|
};
|
||||||
|
const selectedApi = ref<apiDetailsType>(initSelectedApi);
|
||||||
|
|
||||||
|
watch(tableData, () => (selectedApi.value = initSelectedApi));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
Loading…
Reference in New Issue