feat:插件详情支持动态API调用

This commit is contained in:
jxxghp
2024-04-25 13:28:30 +08:00
parent 75ae7f0c15
commit d5d6bfdc56
3 changed files with 59 additions and 27 deletions

View File

@@ -62,7 +62,7 @@ const pluginInfoDialog = ref(false)
const progressText = ref('正在更新插件...')
// 插件数据页面配置项
let pluginPageItems = reactive([])
let pluginPageItems = ref([])
// 图片是否加载完成
const isImageLoaded = ref(false)
@@ -156,7 +156,7 @@ async function loadPluginForm() {
async function loadPluginPage() {
try {
const result: [] = await api.get(`plugin/page/${props.plugin?.id}`)
if (result) pluginPageItems = result
if (result) pluginPageItems.value = result
} catch (error) {
console.error(error)
}
@@ -443,6 +443,7 @@ watch(
{{ props.plugin?.plugin_desc }}
</VCardText>
</VCard>
<!-- 插件配置页面 -->
<VDialog v-model="pluginConfigDialog" scrollable max-width="60rem" :fullscreen="!display.mdAndUp.value">
<VCard :title="`${props.plugin?.plugin_name} - 配置`" class="rounded-t">
@@ -463,7 +464,7 @@ watch(
<VCard :title="`${props.plugin?.plugin_name}`" class="rounded-t">
<DialogCloseBtn v-model="pluginInfoDialog" />
<VCardText>
<PageRender v-for="(item, index) in pluginPageItems" :key="index" :config="item" />
<PageRender @action="loadPluginPage" v-for="(item, index) in pluginPageItems" :key="index" :config="item" />
</VCardText>
<VCardActions>
<VBtn @click="showPluginConfig"> 配置 </VBtn>
@@ -472,6 +473,7 @@ watch(
</VCardActions>
</VCard>
</VDialog>
<!-- 更新插件进度框 -->
<VDialog v-model="progressDialog" :scrim="false" width="25rem">
<VCard color="primary">
@@ -481,6 +483,7 @@ watch(
</VCardText>
</VCard>
</VDialog>
<!-- 更新日志 -->
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
<VCard>

View File

@@ -1,6 +1,11 @@
<script lang="ts" setup>
import { isNullOrEmptyObject } from '@/@core/utils'
import api from '@/api'
import { type PropType, ref } from 'vue'
// 定议外部事件
const emit = defineEmits(['action'])
// 组件接口
interface RenderProps {
component: string
@@ -9,6 +14,7 @@ interface RenderProps {
content?: any
slots?: any
props?: any
events?: any
}
// 输入参数
@@ -16,43 +22,64 @@ const elementProps = defineProps({
config: Object as PropType<RenderProps>,
})
// 配置元素
const formItem = ref<RenderProps>(elementProps.config ?? {
component: 'div',
text: '',
html: '',
props: {},
content: [],
slots: {},
})
// 元素API事件响应
async function commonAction(api_path: string, method: string, params = {}) {
if (!api_path || !method) return
if (method.toUpperCase() === 'GET') {
await api.get(api_path, {
params: params,
})
} else {
await api.post(api_path, params)
}
emit('action')
}
// 组装事件
let componentEvents: { [key: string]: any } = {}
if (!isNullOrEmptyObject(elementProps.config?.events)) {
for (const key in elementProps.config?.events) {
const attr = elementProps.config?.events[key]
const func = async () => {
await commonAction(attr['api'], attr['method'], attr['params'])
}
componentEvents[key] = func
}
} else {
componentEvents = {}
}
</script>
<template>
<Component
:is="formItem.component"
v-if="!formItem.html"
v-bind="formItem.props"
:is="elementProps.config?.component"
v-if="!elementProps.config?.html"
v-bind="elementProps.config?.props"
v-on="componentEvents"
>
{{ formItem.text }}
<template v-for="(content, name) in (formItem.slots || [])" :key="name" v-slot:[name]="{_props}">
{{ elementProps.config?.text }}
<template v-for="(content, name) in elementProps.config?.slots || []" :key="name" v-slot:[name]="{ _props }">
<slot :name="name" v-bind="_props">
<PageRender
v-for="(slotItem, slotIndex) in (content || [])"
v-for="(slotItem, slotIndex) in content || []"
:key="slotIndex"
:config="slotItem"
@action="emit('action')"
/>
</slot>
</template>
<PageRender
v-for="(innerItem, innerIndex) in (formItem.content || [])"
v-for="(innerItem, innerIndex) in elementProps.config?.content || []"
:key="innerIndex"
:config="innerItem"
@action="emit('action')"
/>
</Component>
<Component
:is="formItem.component"
v-if="formItem.html"
v-bind="formItem.props"
v-html="formItem.html"
:is="elementProps.config?.component"
v-if="elementProps.config?.html"
v-bind="elementProps.config?.props"
v-html="elementProps.config?.html"
v-on="componentEvents"
/>
</template>