You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
7.1 KiB
260 lines
7.1 KiB
<!--
|
|
* @Author: 卜启缘
|
|
* @Date: 2021-06-24 18:36:03
|
|
* @LastEditTime: 2021-06-26 21:34:53
|
|
* @LastEditors: 卜启缘
|
|
* @Description: 接口请求
|
|
* @FilePath: \vite-vue3-lowcode\src\visual-editor\components\left-aside\components\data-source\data-fetch.vue
|
|
-->
|
|
<template>
|
|
<div class="!mb-10px">
|
|
<el-button type="primary" size="small" @click="showModelMoal">添加</el-button>
|
|
<el-button type="warning" size="small" @click="showImportSwaggerJsonModal"
|
|
>导入swagger</el-button
|
|
>
|
|
</div>
|
|
<el-collapse v-model="state.activeNames">
|
|
<template v-for="item in apis" :key="item.key">
|
|
<el-collapse-item :title="item.name" :name="item.key">
|
|
<template #title>
|
|
<div class="model-item-title">
|
|
<span>{{ item.name }}</span>
|
|
<div class="model-actions">
|
|
<i class="el-icon-edit" @click="editApiItem(item)"></i>
|
|
<el-popconfirm
|
|
confirm-button-text="确定"
|
|
cancel-button-text="取消"
|
|
icon="el-icon-info"
|
|
icon-color="red"
|
|
title="确定要删除该接口吗?"
|
|
@confirm="deleteFetchApi(item.key)"
|
|
>
|
|
<template #reference>
|
|
<i class="el-icon-delete"></i>
|
|
</template>
|
|
</el-popconfirm>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div class="low-model-item">
|
|
<pre class="code">{{ JSON.stringify(item, null, 2) }}</pre>
|
|
</div>
|
|
</el-collapse-item>
|
|
</template>
|
|
</el-collapse>
|
|
</template>
|
|
|
|
<script setup lang="tsx">
|
|
import { reactive, computed } from 'vue'
|
|
import {
|
|
ElForm,
|
|
ElFormItem,
|
|
ElInput,
|
|
ElSelect,
|
|
ElOption,
|
|
ElButton,
|
|
ElMessage,
|
|
ElCascader
|
|
} from 'element-plus'
|
|
import { useVisualData, fieldTypes } from '@/visual-editor/hooks/useVisualData'
|
|
import type { FetchApiItem, VisualEditorModel } from '@/visual-editor/visual-editor.utils'
|
|
import { useModal } from '@/visual-editor/hooks/useModal'
|
|
import { cloneDeep } from 'lodash'
|
|
import { generateUUID } from '@/visual-editor/utils/'
|
|
import { RequestEnum, ContentTypeEnum } from '@/enums/httpEnum'
|
|
|
|
interface IState {
|
|
activeNames: string[]
|
|
ruleFormRef: any
|
|
ruleForm: FetchApiItem
|
|
}
|
|
|
|
const { jsonData, incrementFetchApi, updateFetchApi, deleteFetchApi } = useVisualData()
|
|
|
|
/**
|
|
* @description 接口集合
|
|
*/
|
|
const apis = computed(() => cloneDeep(jsonData.actions.fetch.apis))
|
|
|
|
/**
|
|
* @description 模型集合
|
|
*/
|
|
const models = computed(() => cloneDeep(jsonData.models))
|
|
|
|
/**
|
|
* @description 是否处于编辑状态
|
|
*/
|
|
const isEdit = computed(() => apis.value.some((item) => item.key == state.ruleForm.key))
|
|
|
|
/**
|
|
* @description 创建空的数据接口对象
|
|
*/
|
|
const createEmptyApiItem = (): FetchApiItem => ({
|
|
key: generateUUID(),
|
|
name: '',
|
|
options: {
|
|
url: '', // 请求的url
|
|
method: RequestEnum.GET, // 请求的方法
|
|
contentType: 'JSON' // 请求的内容类型
|
|
},
|
|
data: {
|
|
bind: '', // 请求绑定对应的某个实体
|
|
recv: '' // 响应的结果绑定到某个实体上
|
|
}
|
|
})
|
|
|
|
const state = reactive<IState>({
|
|
activeNames: [],
|
|
ruleFormRef: null,
|
|
ruleForm: createEmptyApiItem()
|
|
})
|
|
|
|
const rules = {
|
|
name: [{ required: true, message: '请输入接口名称', trigger: 'change' }],
|
|
'options.url': [{ required: true, message: '请输入接口名称', trigger: 'change' }],
|
|
'options.contentType': [{ required: true, message: '请选择内容类型', trigger: 'change' }]
|
|
}
|
|
|
|
const handleBindChange = (e: VisualEditorModel[]) => {
|
|
console.log(e, 'kkk')
|
|
}
|
|
|
|
/**
|
|
* @description 显示添加接口弹窗
|
|
*/
|
|
const showModelMoal = () => {
|
|
useModal({
|
|
title: `${isEdit.value ? '编辑' : '新增'}接口`,
|
|
props: {
|
|
width: 600
|
|
},
|
|
content: () => (
|
|
<ElForm
|
|
model={state.ruleForm}
|
|
ref={(el) => el && (state.ruleFormRef = el)}
|
|
label-width="100px"
|
|
size={'mini'}
|
|
rules={rules}
|
|
class="demo-ruleForm"
|
|
>
|
|
<ElFormItem label="名称" prop="name">
|
|
<ElInput v-model={state.ruleForm.name} placeholder={'请输入接口名称'}></ElInput>
|
|
</ElFormItem>
|
|
<ElFormItem label="接口" prop={'options.url'}>
|
|
<ElInput v-model={state.ruleForm.options.url} placeholder={'请输入接口地址'}>
|
|
{{
|
|
prepend: () => (
|
|
<ElSelect v-model={state.ruleForm.options.method} class={'w-90px'}>
|
|
{Object.keys(RequestEnum).map((key) => (
|
|
<ElOption key={key} label={key} value={key}></ElOption>
|
|
))}
|
|
</ElSelect>
|
|
)
|
|
}}
|
|
</ElInput>
|
|
</ElFormItem>
|
|
<ElFormItem label="内容类型" prop={'options.contentType'}>
|
|
<ElSelect v-model={state.ruleForm.options.contentType}>
|
|
{Object.keys(ContentTypeEnum).map((key) => (
|
|
<ElOption key={key} label={key} value={key}></ElOption>
|
|
))}
|
|
</ElSelect>
|
|
</ElFormItem>
|
|
<ElFormItem label="请求数据" prop={'data.bind'}>
|
|
<ElCascader
|
|
clearable={true}
|
|
props={{
|
|
checkStrictly: true,
|
|
children: 'entitys',
|
|
label: 'name',
|
|
value: 'key',
|
|
expandTrigger: 'hover'
|
|
}}
|
|
placeholder="请选择绑定的请求数据"
|
|
onChange={handleBindChange}
|
|
v-model={state.ruleForm.data.bind}
|
|
options={models.value}
|
|
></ElCascader>
|
|
</ElFormItem>
|
|
</ElForm>
|
|
),
|
|
onConfirm: () => {
|
|
return new Promise((resolve, reject) => {
|
|
state.ruleFormRef.validate((valid) => {
|
|
if (valid) {
|
|
if (isEdit.value) {
|
|
updateFetchApi(cloneDeep(state.ruleForm))
|
|
} else {
|
|
incrementFetchApi(cloneDeep(state.ruleForm))
|
|
}
|
|
ElMessage.success(`${isEdit.value ? '修改' : '新增'}接口成功!`)
|
|
state.ruleForm = createEmptyApiItem()
|
|
resolve('submit!')
|
|
} else {
|
|
reject()
|
|
console.log('error submit!!')
|
|
return false
|
|
}
|
|
})
|
|
})
|
|
},
|
|
onCancel: () => (state.ruleForm = createEmptyApiItem())
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @description 编辑模型
|
|
*/
|
|
const editApiItem = (apiItem: FetchApiItem) => {
|
|
console.log(apiItem)
|
|
state.ruleForm = cloneDeep(apiItem)
|
|
showModelMoal()
|
|
}
|
|
|
|
/**
|
|
* @description 显示导入swagger JSON模态框
|
|
*/
|
|
const showImportSwaggerJsonModal = () => {
|
|
ElMessage.info('敬请期待!')
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.code {
|
|
padding: 4px 10px;
|
|
font-size: 12px;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.model-item-title {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
|
|
.model-actions {
|
|
i {
|
|
padding: 6px;
|
|
margin: 0 2px;
|
|
font-weight: bold;
|
|
cursor: pointer;
|
|
border-radius: 2px;
|
|
opacity: 0.7;
|
|
transition: all 0.1s;
|
|
|
|
&:hover {
|
|
background-color: #f1f1f1;
|
|
opacity: 1;
|
|
}
|
|
|
|
&.el-icon-delete {
|
|
color: #f44336;
|
|
}
|
|
|
|
&.el-icon-edit {
|
|
color: #2196f3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
|