fix: 【Api配置】修复api响应参数类型展示错误,接口文档添加注释
This commit is contained in:
parent
08c8eda133
commit
bda3e6a4c7
|
@ -24,7 +24,12 @@
|
|||
</div>
|
||||
<div class="api-card" v-if="requestCard.codeText !== undefined">
|
||||
<h5>请求示例</h5>
|
||||
<JsonViewer :value="requestCard.codeText" copyable />
|
||||
<Monaco
|
||||
:tips="requestCard.tips"
|
||||
:codeText="requestCard.codeText"
|
||||
:loading="loading"
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div class="api-card" v-if="requestCard.tableData.length">
|
||||
<h5>请求参数</h5>
|
||||
|
@ -37,10 +42,7 @@
|
|||
size="small"
|
||||
>
|
||||
<template #required="slotProps">
|
||||
<span>{{ Boolean(slotProps.required) + '' }}</span>
|
||||
</template>
|
||||
<template #type="slotProps">
|
||||
<span>{{ slotProps?.schema.type }}</span>
|
||||
<span :style="{ color: Boolean(slotProps.required) ? '#f81d22' : ''}">{{ Boolean(slotProps.required) + '' }}</span>
|
||||
</template>
|
||||
</j-pro-table>
|
||||
</div>
|
||||
|
@ -80,18 +82,23 @@
|
|||
</j-pro-table>
|
||||
</div>
|
||||
|
||||
<JsonViewer :value="respParamsCard.codeText" copyable />
|
||||
<!-- <JsonViewer :value="respParamsCard.codeText" copyable />-->
|
||||
<Monaco
|
||||
:tips="respParamsCard.tips"
|
||||
:codeText="respParamsCard.codeText"
|
||||
:loading="loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { JsonViewer } from 'vue3-json-viewer';
|
||||
import 'vue3-json-viewer/dist/index.css';
|
||||
<script setup lang="ts" name="APIDoes">
|
||||
import type { apiDetailsType } from '../typing';
|
||||
import InputCard from './InputCard.vue';
|
||||
import { PropType } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import { findData, getCodeText, dealNoRef } from '../utils';
|
||||
import {randomString} from "@/utils/utils";
|
||||
import Monaco from './monaco.vue'
|
||||
|
||||
type cardType = {
|
||||
columns: object[];
|
||||
|
@ -112,38 +119,49 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
const { selectApi } = toRefs(props);
|
||||
const loading = ref(false)
|
||||
|
||||
const requestCard = reactive<cardType>({
|
||||
columns: [
|
||||
{
|
||||
title: '参数名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
dataIndex: 'paramsName',
|
||||
key: 'paramsName',
|
||||
width: 320
|
||||
},
|
||||
{
|
||||
title: '参数说明',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
dataIndex: 'desc',
|
||||
key: 'desc',
|
||||
},
|
||||
{
|
||||
title: '请求类型',
|
||||
dataIndex: 'in',
|
||||
key: 'in',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '是否必须',
|
||||
dataIndex: 'required',
|
||||
key: 'required',
|
||||
scopedSlots: true,
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '参数类型',
|
||||
dataIndex: 'paramsType',
|
||||
key: 'paramsType',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: 'schema',
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
scopedSlots: true,
|
||||
width: 200
|
||||
},
|
||||
],
|
||||
tableData: [],
|
||||
tips: [],
|
||||
codeText: undefined,
|
||||
getData: () => {
|
||||
if (!props.selectApi.requestBody)
|
||||
|
@ -159,27 +177,30 @@ const requestCard = reactive<cardType>({
|
|||
const schemaName = _ref?.split('/').pop();
|
||||
const type = schema.type || '';
|
||||
const tableData = findData(props.schemas, schemaName);
|
||||
requestCard.codeText =
|
||||
type === 'array'
|
||||
? [getCodeText(props.schemas, tableData, 3)]
|
||||
: getCodeText(props.schemas, tableData, 3);
|
||||
// requestCard.codeText =
|
||||
// type === 'array'
|
||||
// ? [getCodeText(props.schemas, tableData, 3)]
|
||||
// : getCodeText(props.schemas, tableData, 3);
|
||||
const { codeText, codeTips } = getCodeText(props.schemas, tableData, 3)
|
||||
requestCard.codeText = JSON.stringify(codeText)
|
||||
requestCard.tips = codeTips
|
||||
requestCard.tableData = [
|
||||
{
|
||||
name: schemaName[0].toLowerCase() + schemaName.substring(1),
|
||||
description: schemaName,
|
||||
paramsName: schemaName[0].toLowerCase() + schemaName.substring(1),
|
||||
desc: schemaName,
|
||||
in: 'body',
|
||||
id: randomString(),
|
||||
required: true,
|
||||
schema: { type: type || schemaName },
|
||||
children: tableData.map((item) => ({
|
||||
name: item.paramsName,
|
||||
description: item.desc,
|
||||
required: false,
|
||||
schema: { type: item.paramsType },
|
||||
})),
|
||||
paramsType: type || schemaName,
|
||||
type: type || schemaName,
|
||||
children: tableData,
|
||||
},
|
||||
];
|
||||
// console.log(requestCard,'requestCard')
|
||||
}
|
||||
setTimeout(() => {
|
||||
loading.value = true
|
||||
}, 1000)
|
||||
},
|
||||
});
|
||||
const responseStatusCard = reactive<cardType>({
|
||||
|
@ -189,6 +210,7 @@ const responseStatusCard = reactive<cardType>({
|
|||
title: '状态码',
|
||||
dataIndex: 'code',
|
||||
key: 'code',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '说明',
|
||||
|
@ -199,6 +221,7 @@ const responseStatusCard = reactive<cardType>({
|
|||
title: 'schema',
|
||||
dataIndex: 'schema',
|
||||
key: 'schema',
|
||||
width: 200
|
||||
},
|
||||
],
|
||||
tableData: [],
|
||||
|
@ -231,6 +254,7 @@ const respParamsCard = reactive<cardType>({
|
|||
{
|
||||
title: '参数名称',
|
||||
dataIndex: 'paramsName',
|
||||
width: 320
|
||||
},
|
||||
{
|
||||
title: '参数说明',
|
||||
|
@ -239,9 +263,16 @@ const respParamsCard = reactive<cardType>({
|
|||
{
|
||||
title: '类型',
|
||||
dataIndex: 'paramsType',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: 'schema',
|
||||
dataIndex: 'schema',
|
||||
width: 200
|
||||
},
|
||||
],
|
||||
tableData: [],
|
||||
tips: [],
|
||||
codeText: '',
|
||||
getData: (code: string) => {
|
||||
const schemaName = responseStatusCard.tableData.find(
|
||||
|
@ -249,11 +280,22 @@ const respParamsCard = reactive<cardType>({
|
|||
)?.schema;
|
||||
|
||||
const tableData = findData(props.schemas, schemaName);
|
||||
respParamsCard.codeText = getCodeText(props.schemas, tableData, 3);
|
||||
const { codeText, codeTips } = getCodeText(props.schemas, tableData, 3)
|
||||
respParamsCard.codeText = JSON.stringify(codeText)
|
||||
respParamsCard.tips = codeTips
|
||||
respParamsCard.tableData = tableData;
|
||||
setTimeout(() => {
|
||||
loading.value = true
|
||||
}, 1000)
|
||||
},
|
||||
});
|
||||
|
||||
const options = {
|
||||
minimap: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
const getContent = (data: any) => {
|
||||
if (data && data.content) {
|
||||
return Object.keys(data.content || {})[0];
|
||||
|
@ -263,17 +305,18 @@ const getContent = (data: any) => {
|
|||
onMounted(() => {
|
||||
requestCard.getData();
|
||||
responseStatusCard.getData();
|
||||
watch(
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.selectApi,
|
||||
() => {
|
||||
requestCard.getData();
|
||||
responseStatusCard.getData();
|
||||
},
|
||||
);
|
||||
);
|
||||
|
||||
watch([() => responseStatusCard.activeKey, () => props.selectApi], (n) => {
|
||||
watch([() => responseStatusCard.activeKey, () => props.selectApi], (n) => {
|
||||
n[0] && respParamsCard.getData(n[0]);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div class="input">
|
||||
<InputCard :value="props.selectApi.method" />
|
||||
<j-input :value="props.selectApi?.url" disabled />
|
||||
<span class="send" @click="send">发送</span>
|
||||
<j-button type="primary" @click="send" :loading="loading">发送</j-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -107,14 +107,31 @@
|
|||
<AIcon type="PlusOutlined" />新增
|
||||
</j-button>
|
||||
</div>
|
||||
<j-monaco-editor
|
||||
<a-select v-model:value="bodyType" @change="handleChangeBodyType">
|
||||
<a-select-option value="json">Json</a-select-option>
|
||||
<a-select-option value="text">Text</a-select-option>
|
||||
</a-select>
|
||||
<template
|
||||
v-if="showRequestBody"
|
||||
>
|
||||
<j-monaco-editor
|
||||
v-if="bodyType === 'json'"
|
||||
ref="editorRef"
|
||||
language="json"
|
||||
style="height: 100% ; min-height: 200px;"
|
||||
theme="vs"
|
||||
v-model:modelValue="requestBody.code"
|
||||
/>
|
||||
<j-monaco-editor
|
||||
v-else
|
||||
ref="editorRef"
|
||||
language="text"
|
||||
style="height: 100% ; min-height: 200px;"
|
||||
theme="vs"
|
||||
v-model:modelValue="requestBody.code"
|
||||
/>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="api-card">
|
||||
|
@ -145,6 +162,8 @@ const editorRef = ref();
|
|||
const formRef = ref<FormInstance>();
|
||||
const method = ref()
|
||||
const showRequestBody = ref(!!props.selectApi?.requestBody)
|
||||
const bodyType = ref('text');
|
||||
const loading = ref(false);
|
||||
const requestBody = reactive({
|
||||
tableColumns: [
|
||||
{
|
||||
|
@ -208,6 +227,11 @@ const init = () => {
|
|||
};
|
||||
init();
|
||||
|
||||
const handleChangeBodyType = () => {
|
||||
console.log(editorRef.value)
|
||||
editorRef.value?.setModelLanguage(editorRef.value.getModel(), bodyType.value);
|
||||
}
|
||||
|
||||
const send = () => {
|
||||
if (paramsTable.value.length)
|
||||
formRef.value &&
|
||||
|
@ -240,16 +264,22 @@ const _send = () => {
|
|||
...urlParams,
|
||||
};
|
||||
}else{
|
||||
if(bodyType.value == 'text') {
|
||||
params = requestBody.code
|
||||
} else {
|
||||
params = JSON.parse(requestBody.code || '{}')
|
||||
}
|
||||
|
||||
server[methodObj[methodName]](url, params).then((resp: any) => {
|
||||
}
|
||||
loading.value = true;
|
||||
server[methodObj[methodName]](url, params, {}, bodyType.value === 'text' ? {headers: {'Content-Type': 'text/plain'}} : {}).then((resp: any) => {
|
||||
// 如果用户没填写参数且有body的情况下,给用户展示请求示例
|
||||
if (Object.keys(params).length === 0 && refStr.value) {
|
||||
requestBody.code = JSON.stringify(getDefaultParams());
|
||||
editorRef.value?.editorFormat();
|
||||
}
|
||||
responsesContent.value = resp;
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
:columns="columns"
|
||||
:dataSource="_tableData"
|
||||
:rowSelection="props.mode !== 'home' ? rowSelection : undefined"
|
||||
:style="{padding: 0}"
|
||||
noPagination
|
||||
model="TABLE"
|
||||
>
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<div class="api-example">
|
||||
<j-monaco-editor
|
||||
v-if="loading"
|
||||
language="json"
|
||||
:model-value="codeText"
|
||||
:init="init"
|
||||
/>
|
||||
<div class="api-example-tips" :style="{ transform: `translateY(${scrollTop}px)`}" v-if="loading">
|
||||
<div class="tips-line" v-for="tip in tips">
|
||||
<span v-if="tip">//{{tip}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ApiMonaco">
|
||||
|
||||
defineProps({
|
||||
tips: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
codeText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const scrollTop = ref(0)
|
||||
const init = (editor) => {
|
||||
editor.onDidScrollChange(e => {
|
||||
scrollTop.value = 0 - e.scrollTop
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.api-example {
|
||||
height: 350px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.api-example-tips {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 19px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
pointer-events: none;
|
||||
color: #608b4e;
|
||||
|
||||
.tips-line {
|
||||
height: 19px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -3,23 +3,23 @@
|
|||
<div class="top">
|
||||
<slot name="top" />
|
||||
</div>
|
||||
<j-row class="content" :style="{padding:'24px'}" >
|
||||
<j-col
|
||||
:span="24"
|
||||
<div class="api-page-content" :style="styles">
|
||||
<div
|
||||
v-if="props.showTitle"
|
||||
style="font-size: 16px;margin-bottom: 48px;"
|
||||
>
|
||||
API文档
|
||||
</j-col>
|
||||
<j-col :span="5" class="tree-content">
|
||||
</div>
|
||||
<div class="api-page-body">
|
||||
<div class="tree-content">
|
||||
<LeftTree
|
||||
@select="treeSelect"
|
||||
:mode="props.mode"
|
||||
:has-home="props.hasHome"
|
||||
:code="props.code"
|
||||
/>
|
||||
</j-col>
|
||||
<j-col :span="19">
|
||||
</div>
|
||||
<div class="api-page-detail">
|
||||
<HomePage v-show="showHome" />
|
||||
<div class="url-page" v-show="!showHome">
|
||||
<ChooseApi
|
||||
|
@ -39,9 +39,8 @@
|
|||
>
|
||||
<j-button
|
||||
@click="selectedApi = initSelectedApi"
|
||||
style="margin-bottom: 24px"
|
||||
>返回</j-button
|
||||
>
|
||||
style="margin-bottom: 24px; width: 80px">返回</j-button>
|
||||
<div class="api-details-tabs">
|
||||
<j-tabs v-model:activeKey="activeKey" type="card">
|
||||
<j-tab-pane key="does" tab="文档">
|
||||
<ApiDoes
|
||||
|
@ -58,8 +57,10 @@
|
|||
</j-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -88,6 +89,12 @@ const props = defineProps<{
|
|||
}>();
|
||||
const showHome = ref<boolean>(Boolean(props.hasHome)); // 是否展示home页面
|
||||
const tableData = ref([]);
|
||||
|
||||
const styles = computed(() => {
|
||||
return {
|
||||
padding: props.mode === 'api' ? 0 : '24px'
|
||||
}
|
||||
})
|
||||
const treeSelect = (node: treeNodeTpye, nodeSchemas: object = {}) => {
|
||||
if (node.key === 'home') return (showHome.value = true);
|
||||
schemas.value = nodeSchemas;
|
||||
|
@ -178,15 +185,48 @@ watch(
|
|||
|
||||
<style lang="less" scoped>
|
||||
.api-page-container {
|
||||
.content {
|
||||
height: 100%;
|
||||
|
||||
.api-page-content {
|
||||
background-color: #fff;
|
||||
margin: 0 !important;
|
||||
|
||||
.api-page-body {
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
||||
.tree-content {
|
||||
padding-bottom: 30px;
|
||||
height: calc(100vh - 230px);
|
||||
width: 280px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e9e9e9;
|
||||
}
|
||||
|
||||
.api-page-detail {
|
||||
position: absolute;
|
||||
left: 296px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
|
||||
.url-page {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.api-details {
|
||||
max-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.api-details-tabs {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -34,6 +34,11 @@ export type modeType = 'api'| 'appManger' | 'home'
|
|||
export type schemaObjType = {
|
||||
paramsName: string;
|
||||
paramsType: string;
|
||||
id: string;
|
||||
type?: string;
|
||||
schema?: string;
|
||||
|
||||
required?: boolean
|
||||
desc?: string;
|
||||
children?: schemaObjType[];
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
import { schemaObjType } from "./typing";
|
||||
import {randomString} from "@/utils/utils";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -14,22 +15,32 @@ export function findData(schemas: object, schemaName: string , paths:string[]=[]
|
|||
}
|
||||
const result: schemaObjType[] = [];
|
||||
const schema = schemas[schemaName];
|
||||
const required = schema.required || []
|
||||
|
||||
Object.entries(schema.properties).forEach((item: [string, any]) => {
|
||||
const [paramsName, extra] = item
|
||||
|
||||
const paramsType =
|
||||
(item[1].$ref && item[1].$ref.split('/').pop()) ||
|
||||
(item[1].items?.$ref && item[1].items.$ref.split('/').pop()) ||
|
||||
item[1].item?.type ||
|
||||
item[1].type ||
|
||||
(extra.$ref && extra.$ref.split('/').pop()) ||
|
||||
(extra.items?.$ref && extra.items.$ref.split('/').pop()) ||
|
||||
extra.item?.type ||
|
||||
extra.type ||
|
||||
'';
|
||||
const schema = extra.format ? `${paramsType}(${extra.format})` : ''
|
||||
|
||||
const schemaObj: schemaObjType = {
|
||||
paramsName: item[0],
|
||||
paramsName: paramsName,
|
||||
paramsType,
|
||||
desc: item[1].description || '',
|
||||
required: required.includes(paramsName),
|
||||
desc: extra.description || '',
|
||||
schema: schema,
|
||||
type: !basicType.includes(paramsType) ? paramsType : '',
|
||||
id: randomString()
|
||||
};
|
||||
|
||||
if (!basicType.includes(paramsType) && paths.filter(path=>path === schemaName).length >=2 ){
|
||||
if (!basicType.includes(paramsType) && (paths.filter(path=>path === schemaName).length <=2) ){
|
||||
paths.push(schemaName)
|
||||
schemaObj.children = findData(schemas, paramsType);
|
||||
schemaObj.children = findData(schemas, paramsType, paths);
|
||||
}
|
||||
result.push(schemaObj);
|
||||
});
|
||||
|
@ -47,54 +58,89 @@ export function getCodeText(
|
|||
schemas: object,
|
||||
arr: schemaObjType[],
|
||||
level: number,
|
||||
): object {
|
||||
const result = {};
|
||||
paths: string[] = []
|
||||
): any {
|
||||
const tips: Array<string | undefined> = []
|
||||
let result = {}
|
||||
arr.forEach((item) => {
|
||||
let value: any = ""
|
||||
tips.push(item.desc)
|
||||
switch (item.paramsType) {
|
||||
case 'string':
|
||||
result[item.paramsName] = '';
|
||||
value = ''
|
||||
break;
|
||||
case 'integer':
|
||||
result[item.paramsName] = 0;
|
||||
case 'number':
|
||||
value = 0
|
||||
break;
|
||||
case 'boolean':
|
||||
result[item.paramsName] = true;
|
||||
value = true
|
||||
break;
|
||||
case 'array':
|
||||
result[item.paramsName] = [];
|
||||
value = []
|
||||
break;
|
||||
case 'object':
|
||||
result[item.paramsName] = '';
|
||||
break;
|
||||
case 'number':
|
||||
result[item.paramsName] = 0;
|
||||
value = {}
|
||||
break;
|
||||
default: {
|
||||
if (item.children) {
|
||||
if (paths.filter(path=> path === item.paramsName).length >=2) {
|
||||
break
|
||||
}
|
||||
paths.push(item.paramsName)
|
||||
const _result = getCodeText(
|
||||
schemas,
|
||||
item.children,
|
||||
level - 1,
|
||||
paths
|
||||
)
|
||||
value = _result.codeText
|
||||
tips.push(..._result.codeTips)
|
||||
tips.push(undefined)
|
||||
} else {
|
||||
if (paths.filter(path=> path === item.paramsName).length >=2) {
|
||||
break
|
||||
}
|
||||
paths.push(item.paramsName)
|
||||
const properties = schemas[item.paramsType]?.properties as object || {};
|
||||
const newArr = Object.entries(properties).map(
|
||||
(item: [string, any]) => {
|
||||
const [paramsName, extra] = item
|
||||
|
||||
const paramsType =
|
||||
(extra.$ref && extra.$ref.split('/').pop()) ||
|
||||
(extra.items?.$ref && extra.items.$ref.split('/').pop()) ||
|
||||
extra.item?.type ||
|
||||
extra.type ||
|
||||
'';
|
||||
|
||||
return{
|
||||
paramsName: item[0],
|
||||
paramsType: level
|
||||
? (item[1].$ref && item[1].$ref.split('/').pop()) ||
|
||||
(item[1].items?.$ref &&
|
||||
item[1].items.$ref.split('/').pop()) ||
|
||||
item[1].item?.type ||
|
||||
item[1].type ||
|
||||
''
|
||||
: item[1].type,
|
||||
paramsName: paramsName,
|
||||
desc: extra.description || '',
|
||||
paramsType: paramsType,
|
||||
schema: extra.format ? `${paramsType}(${extra.format})` : ''
|
||||
}},
|
||||
);
|
||||
result[item.paramsName] = getCodeText(
|
||||
|
||||
const _result = getCodeText(
|
||||
schemas,
|
||||
newArr,
|
||||
level - 1,
|
||||
);
|
||||
paths
|
||||
)
|
||||
value = _result.codeText
|
||||
tips.push(..._result.codeTips)
|
||||
tips.push(undefined)
|
||||
}
|
||||
}
|
||||
}
|
||||
result[item.paramsName] = value
|
||||
});
|
||||
return {
|
||||
codeText: result,
|
||||
codeTips: tips
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue